6966604: JavacFiler not correctly notified of lastRound

Reviewed-by: darcy
This commit is contained in:
Jonathan Gibbons 2010-07-29 19:30:35 -07:00
parent 75b1007388
commit eff5854b96
8 changed files with 450 additions and 258 deletions

View file

@ -539,13 +539,16 @@ public class JavacFiler implements Filer, Closeable {
/** /**
* Update internal state for a new round. * Update internal state for a new round.
*/ */
public void newRound(Context context, boolean lastRound) { public void newRound(Context context) {
this.context = context; this.context = context;
this.log = Log.instance(context); this.log = Log.instance(context);
this.lastRound = lastRound;
clearRoundState(); clearRoundState();
} }
void setLastRound(boolean lastRound) {
this.lastRound = lastRound;
}
public void close() { public void close() {
clearRoundState(); clearRoundState();
// Cross-round state // Cross-round state

View file

@ -68,7 +68,6 @@ import com.sun.tools.javac.util.Abort;
import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Convert; import com.sun.tools.javac.util.Convert;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.JavacMessages; import com.sun.tools.javac.util.JavacMessages;
import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Name;
@ -759,7 +758,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
} }
@Override @Override
public Set<TypeElement> scan(Element e, Set<TypeElement> p) { public Set<TypeElement> scan(Element e, Set<TypeElement> p) {
for (AnnotationMirror annotationMirror : for (AnnotationMirror annotationMirror :
elements.getAllAnnotationMirrors(e) ) { elements.getAllAnnotationMirrors(e) ) {
Element e2 = annotationMirror.getAnnotationType().asElement(); Element e2 = annotationMirror.getAnnotationType().asElement();
@ -784,6 +783,237 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
} }
} }
/**
* Helper object for a single round of annotation processing.
*/
class Round {
/** The round number. */
final int number;
/** The context for the round. */
final Context context;
/** The compiler for the round. */
final JavaCompiler compiler;
/** The log for the round. */
final Log log;
/** The set of annotations to be processed this round. */
Set<TypeElement> annotationsPresent;
/** The set of top level classes to be processed this round. */
List<ClassSymbol> topLevelClasses;
/** The set of package-info files to be processed this round. */
List<PackageSymbol> packageInfoFiles;
/** Create a round. */
Round(Context context, int number) {
this.context = context;
this.number = number;
compiler = JavaCompiler.instance(context);
log = Log.instance(context);
// the following is for the benefit of JavacProcessingEnvironment.getContext()
JavacProcessingEnvironment.this.context = context;
// the following will be populated as needed
annotationsPresent = new LinkedHashSet<TypeElement>();
topLevelClasses = List.nil();
packageInfoFiles = List.nil();
}
/** Create the next round to be used. */
Round next() {
compiler.close(false);
return new Round(contextForNextRound(), number + 1);
}
/** Return the number of errors found so far in this round.
* This may include uncoverable errors, such as parse errors,
* and transient errors, such as missing symbols. */
int errorCount() {
return compiler.errorCount();
}
/** Return the number of warnings found so far in this round. */
int warningCount() {
return compiler.warningCount();
}
/** Return whether or not an unrecoverable error has occurred. */
boolean unrecoverableError() {
return log.unrecoverableError;
}
/** Find the set of annotations present in the set of top level
* classes and package info files to be processed this round. */
void findAnnotationsPresent(ComputeAnnotationSet annotationComputer) {
// Use annotation processing to compute the set of annotations present
annotationsPresent = new LinkedHashSet<TypeElement>();
for (ClassSymbol classSym : topLevelClasses)
annotationComputer.scan(classSym, annotationsPresent);
for (PackageSymbol pkgSym : packageInfoFiles)
annotationComputer.scan(pkgSym, annotationsPresent);
}
/**
* Parse the latest set of generated source files created by the filer.
*/
List<JCCompilationUnit> parseNewSourceFiles()
throws IOException {
List<JavaFileObject> fileObjects = List.nil();
for (JavaFileObject jfo : filer.getGeneratedSourceFileObjects() ) {
fileObjects = fileObjects.prepend(jfo);
}
return compiler.parseFiles(fileObjects);
}
/** Enter the latest set of generated class files created by the filer. */
List<ClassSymbol> enterNewClassFiles() {
ClassReader reader = ClassReader.instance(context);
Names names = Names.instance(context);
List<ClassSymbol> list = List.nil();
for (Map.Entry<String,JavaFileObject> entry : filer.getGeneratedClasses().entrySet()) {
Name name = names.fromString(entry.getKey());
JavaFileObject file = entry.getValue();
if (file.getKind() != JavaFileObject.Kind.CLASS)
throw new AssertionError(file);
ClassSymbol cs;
if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) {
Name packageName = Convert.packagePart(name);
PackageSymbol p = reader.enterPackage(packageName);
if (p.package_info == null)
p.package_info = reader.enterClass(Convert.shortName(name), p);
cs = p.package_info;
if (cs.classfile == null)
cs.classfile = file;
} else
cs = reader.enterClass(name, file);
list = list.prepend(cs);
}
return list.reverse();
}
/** Enter a set of syntax trees. */
void enterTrees(List<JCCompilationUnit> roots) {
compiler.enterTrees(roots);
}
/** Run a processing round. */
void run(boolean lastRound, boolean errorStatus) {
assert lastRound
? (topLevelClasses.size() == 0 && annotationsPresent.size() == 0)
: (errorStatus == false);
printRoundInfo(topLevelClasses, annotationsPresent, lastRound);
TaskListener taskListener = context.get(TaskListener.class);
if (taskListener != null)
taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
try {
if (lastRound) {
filer.setLastRound(true);
Set<Element> emptyRootElements = Collections.emptySet(); // immutable
RoundEnvironment renv = new JavacRoundEnvironment(true,
errorStatus,
emptyRootElements,
JavacProcessingEnvironment.this);
discoveredProcs.iterator().runContributingProcs(renv);
} else {
discoverAndRunProcs(context, annotationsPresent, topLevelClasses, packageInfoFiles);
}
} finally {
if (taskListener != null)
taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
}
}
/** Update the processing state for the current context. */
// Question: should this not be part of next()?
// Note: Calling it from next() breaks some tests. There is an issue
// whether the annotationComputer is using elementUtils with the
// correct context.
void updateProcessingState() {
filer.newRound(context);
messager.newRound(context);
elementUtils.setContext(context);
typeUtils.setContext(context);
}
/** Print info about this round. */
private void printRoundInfo(List<ClassSymbol> topLevelClasses,
Set<TypeElement> annotationsPresent,
boolean lastRound) {
if (printRounds || verbose) {
log.printNoteLines("x.print.rounds",
number,
"{" + topLevelClasses.toString(", ") + "}",
annotationsPresent,
lastRound);
}
}
/** Get the context for the next round of processing.
* Important values are propogated from round to round;
* other values are implicitly reset.
*/
private Context contextForNextRound() {
Context next = new Context();
Options options = Options.instance(context);
assert options != null;
next.put(Options.optionsKey, options);
PrintWriter out = context.get(Log.outKey);
assert out != null;
next.put(Log.outKey, out);
final boolean shareNames = true;
if (shareNames) {
Names names = Names.instance(context);
assert names != null;
next.put(Names.namesKey, names);
}
DiagnosticListener<?> dl = context.get(DiagnosticListener.class);
if (dl != null)
next.put(DiagnosticListener.class, dl);
TaskListener tl = context.get(TaskListener.class);
if (tl != null)
next.put(TaskListener.class, tl);
JavaFileManager jfm = context.get(JavaFileManager.class);
assert jfm != null;
next.put(JavaFileManager.class, jfm);
if (jfm instanceof JavacFileManager) {
((JavacFileManager)jfm).setContext(next);
}
Names names = Names.instance(context);
assert names != null;
next.put(Names.namesKey, names);
Keywords keywords = Keywords.instance(context);
assert(keywords != null);
next.put(Keywords.keywordsKey, keywords);
JavaCompiler oldCompiler = JavaCompiler.instance(context);
JavaCompiler nextCompiler = JavaCompiler.instance(next);
nextCompiler.initRound(oldCompiler);
JavacTaskImpl task = context.get(JavacTaskImpl.class);
if (task != null) {
next.put(JavacTaskImpl.class, task);
task.updateContext(next);
}
context.clear();
return next;
}
}
// TODO: internal catch clauses?; catch and rethrow an annotation // TODO: internal catch clauses?; catch and rethrow an annotation
// processing error // processing error
@ -794,60 +1024,37 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
throws IOException { throws IOException {
log = Log.instance(context); log = Log.instance(context);
TaskListener taskListener = context.get(TaskListener.class);
JavaCompiler compiler = JavaCompiler.instance(context); Round round = new Round(context, 1);
compiler.todo.clear(); // free the compiler's resources round.compiler.todo.clear(); // free the compiler's resources
int round = 0; // The reverse() in the following line is to maintain behavioural
// compatibility with the previous revision of the code. Strictly speaking,
// it should not be necessary, but a javah golden file test fails without it.
round.topLevelClasses =
getTopLevelClasses(roots).prependList(classSymbols.reverse());
// List<JCAnnotation> annotationsPresentInSource = collector.findAnnotations(roots); round.packageInfoFiles = getPackageInfoFiles(roots);
List<ClassSymbol> topLevelClasses = getTopLevelClasses(roots);
for (ClassSymbol classSym : classSymbols)
topLevelClasses = topLevelClasses.prepend(classSym);
List<PackageSymbol> packageInfoFiles =
getPackageInfoFiles(roots);
Set<PackageSymbol> specifiedPackages = new LinkedHashSet<PackageSymbol>(); Set<PackageSymbol> specifiedPackages = new LinkedHashSet<PackageSymbol>();
for (PackageSymbol psym : pckSymbols) for (PackageSymbol psym : pckSymbols)
specifiedPackages.add(psym); specifiedPackages.add(psym);
this.specifiedPackages = Collections.unmodifiableSet(specifiedPackages); this.specifiedPackages = Collections.unmodifiableSet(specifiedPackages);
// Use annotation processing to compute the set of annotations present
Set<TypeElement> annotationsPresent = new LinkedHashSet<TypeElement>();
ComputeAnnotationSet annotationComputer = new ComputeAnnotationSet(elementUtils); ComputeAnnotationSet annotationComputer = new ComputeAnnotationSet(elementUtils);
for (ClassSymbol classSym : topLevelClasses) round.findAnnotationsPresent(annotationComputer);
annotationComputer.scan(classSym, annotationsPresent);
for (PackageSymbol pkgSym : packageInfoFiles)
annotationComputer.scan(pkgSym, annotationsPresent);
Context currentContext = context;
int roundNumber = 0;
boolean errorStatus = false; boolean errorStatus = false;
runAround: runAround:
while(true) { while (true) {
if ((fatalErrors && compiler.errorCount() != 0) if ((fatalErrors && round.errorCount() != 0)
|| (werror && compiler.warningCount() != 0)) { || (werror && round.warningCount() != 0)) {
errorStatus = true; errorStatus = true;
break runAround; break runAround;
} }
this.context = currentContext; round.run(false, false);
roundNumber++;
printRoundInfo(roundNumber, topLevelClasses, annotationsPresent, false);
if (taskListener != null)
taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
try {
discoverAndRunProcs(currentContext, annotationsPresent, topLevelClasses, packageInfoFiles);
} finally {
if (taskListener != null)
taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
}
/* /*
* Processors for round n have run to completion. Prepare * Processors for round n have run to completion. Prepare
@ -858,65 +1065,54 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
if (messager.errorRaised()) { if (messager.errorRaised()) {
errorStatus = true; errorStatus = true;
break runAround; break runAround;
} else {
if (moreToDo()) {
// annotationsPresentInSource = List.nil();
annotationsPresent = new LinkedHashSet<TypeElement>();
topLevelClasses = List.nil();
packageInfoFiles = List.nil();
compiler.close(false);
currentContext = contextForNextRound(currentContext, true);
JavaFileManager fileManager = currentContext.get(JavaFileManager.class);
compiler = JavaCompiler.instance(currentContext);
List<JCCompilationUnit> parsedFiles = sourcesToParsedFiles(compiler);
roots = cleanTrees(roots).appendList(parsedFiles);
// Check for errors after parsing
if (log.unrecoverableError) {
errorStatus = true;
break runAround;
} else {
List<ClassSymbol> newClasses = enterNewClassFiles(currentContext);
compiler.enterTrees(roots);
// annotationsPresentInSource =
// collector.findAnnotations(parsedFiles);
ListBuffer<ClassSymbol> tlc = new ListBuffer<ClassSymbol>();
tlc.appendList(getTopLevelClasses(parsedFiles));
tlc.appendList(getTopLevelClassesFromClasses(newClasses));
topLevelClasses = tlc.toList();
ListBuffer<PackageSymbol> pif = new ListBuffer<PackageSymbol>();
pif.appendList(getPackageInfoFiles(parsedFiles));
pif.appendList(getPackageInfoFilesFromClasses(newClasses));
packageInfoFiles = pif.toList();
annotationsPresent = new LinkedHashSet<TypeElement>();
for (ClassSymbol classSym : topLevelClasses)
annotationComputer.scan(classSym, annotationsPresent);
for (PackageSymbol pkgSym : packageInfoFiles)
annotationComputer.scan(pkgSym, annotationsPresent);
updateProcessingState(currentContext, false);
}
} else
break runAround; // No new files
} }
if (!moreToDo())
break runAround; // No new files
round = round.next();
List<JCCompilationUnit> parsedFiles = round.parseNewSourceFiles();
roots = cleanTrees(roots).appendList(parsedFiles);
// Check for errors after parsing
if (round.unrecoverableError()) {
errorStatus = true;
break runAround;
}
List<ClassSymbol> newClasses = round.enterNewClassFiles();
round.enterTrees(roots);
round.topLevelClasses = join(
getTopLevelClasses(parsedFiles),
getTopLevelClassesFromClasses(newClasses));
round.packageInfoFiles = join(
getPackageInfoFiles(parsedFiles),
getPackageInfoFilesFromClasses(newClasses));
round.findAnnotationsPresent(annotationComputer);
round.updateProcessingState();
} }
roots = runLastRound(roundNumber, errorStatus, compiler, roots, taskListener);
// run last round
round.run(true, errorStatus);
// Add any sources generated during the last round to the set
// of files to be compiled.
if (moreToDo()) {
List<JCCompilationUnit> parsedFiles = round.parseNewSourceFiles();
roots = cleanTrees(roots).appendList(parsedFiles);
}
// Set error status for any files compiled and generated in // Set error status for any files compiled and generated in
// the last round // the last round
if (log.unrecoverableError || (werror && compiler.warningCount() != 0)) if (round.unrecoverableError() || (werror && round.warningCount() != 0))
errorStatus = true; errorStatus = true;
compiler.close(false); round = round.next();
currentContext = contextForNextRound(currentContext, true);
compiler = JavaCompiler.instance(currentContext);
filer.newRound(currentContext, true);
filer.warnIfUnclosedFiles(); filer.warnIfUnclosedFiles();
warnIfUnmatchedOptions(); warnIfUnmatchedOptions();
@ -933,142 +1129,43 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
*/ */
errorStatus = errorStatus || messager.errorRaised(); errorStatus = errorStatus || messager.errorRaised();
// Free resources // Free resources
this.close(); this.close();
TaskListener taskListener = this.context.get(TaskListener.class);
if (taskListener != null) if (taskListener != null)
taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING)); taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING));
JavaCompiler compiler;
if (errorStatus) { if (errorStatus) {
compiler = round.compiler;
compiler.log.nwarnings += messager.warningCount(); compiler.log.nwarnings += messager.warningCount();
compiler.log.nerrors += messager.errorCount(); compiler.log.nerrors += messager.errorCount();
if (compiler.errorCount() == 0) if (compiler.errorCount() == 0)
compiler.log.nerrors++; compiler.log.nerrors++;
} else if (procOnly && !foundTypeProcessors) { } else if (procOnly && !foundTypeProcessors) {
compiler = round.compiler;
compiler.todo.clear(); compiler.todo.clear();
} else { // Final compilation } else { // Final compilation
compiler.close(false); round = round.next();
currentContext = contextForNextRound(currentContext, true); round.updateProcessingState();
this.context = currentContext; compiler = round.compiler;
updateProcessingState(currentContext, true);
compiler = JavaCompiler.instance(currentContext);
if (procOnly && foundTypeProcessors) if (procOnly && foundTypeProcessors)
compiler.shouldStopPolicy = CompileState.FLOW; compiler.shouldStopPolicy = CompileState.FLOW;
if (true) { compiler.enterTrees(cleanTrees(roots));
compiler.enterTrees(cleanTrees(roots));
} else {
List<JavaFileObject> fileObjects = List.nil();
for (JCCompilationUnit unit : roots)
fileObjects = fileObjects.prepend(unit.getSourceFile());
roots = null;
compiler.enterTrees(compiler.parseFiles(fileObjects.reverse()));
}
} }
return compiler; return compiler;
} }
private List<JCCompilationUnit> sourcesToParsedFiles(JavaCompiler compiler)
throws IOException {
List<JavaFileObject> fileObjects = List.nil();
for (JavaFileObject jfo : filer.getGeneratedSourceFileObjects() ) {
fileObjects = fileObjects.prepend(jfo);
}
return compiler.parseFiles(fileObjects);
}
// Call the last round of annotation processing
private List<JCCompilationUnit> runLastRound(int roundNumber,
boolean errorStatus,
JavaCompiler compiler,
List<JCCompilationUnit> roots,
TaskListener taskListener) throws IOException {
roundNumber++;
List<ClassSymbol> noTopLevelClasses = List.nil();
Set<TypeElement> noAnnotations = Collections.emptySet();
printRoundInfo(roundNumber, noTopLevelClasses, noAnnotations, true);
Set<Element> emptyRootElements = Collections.emptySet(); // immutable
RoundEnvironment renv = new JavacRoundEnvironment(true,
errorStatus,
emptyRootElements,
JavacProcessingEnvironment.this);
if (taskListener != null)
taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
try {
discoveredProcs.iterator().runContributingProcs(renv);
} finally {
if (taskListener != null)
taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
}
// Add any sources generated during the last round to the set
// of files to be compiled.
if (moreToDo()) {
List<JCCompilationUnit> parsedFiles = sourcesToParsedFiles(compiler);
roots = cleanTrees(roots).appendList(parsedFiles);
}
return roots;
}
private void updateProcessingState(Context currentContext, boolean lastRound) {
filer.newRound(currentContext, lastRound);
messager.newRound(currentContext);
elementUtils.setContext(currentContext);
typeUtils.setContext(currentContext);
}
private void warnIfUnmatchedOptions() { private void warnIfUnmatchedOptions() {
if (!unmatchedProcessorOptions.isEmpty()) { if (!unmatchedProcessorOptions.isEmpty()) {
log.warning("proc.unmatched.processor.options", unmatchedProcessorOptions.toString()); log.warning("proc.unmatched.processor.options", unmatchedProcessorOptions.toString());
} }
} }
private void printRoundInfo(int roundNumber,
List<ClassSymbol> topLevelClasses,
Set<TypeElement> annotationsPresent,
boolean lastRound) {
if (printRounds || verbose) {
log.printNoteLines("x.print.rounds",
roundNumber,
"{" + topLevelClasses.toString(", ") + "}",
annotationsPresent,
lastRound);
}
}
private List<ClassSymbol> enterNewClassFiles(Context currentContext) {
ClassReader reader = ClassReader.instance(currentContext);
Names names = Names.instance(currentContext);
List<ClassSymbol> list = List.nil();
for (Map.Entry<String,JavaFileObject> entry : filer.getGeneratedClasses().entrySet()) {
Name name = names.fromString(entry.getKey());
JavaFileObject file = entry.getValue();
if (file.getKind() != JavaFileObject.Kind.CLASS)
throw new AssertionError(file);
ClassSymbol cs;
if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) {
Name packageName = Convert.packagePart(name);
PackageSymbol p = reader.enterPackage(packageName);
if (p.package_info == null)
p.package_info = reader.enterClass(Convert.shortName(name), p);
cs = p.package_info;
if (cs.classfile == null)
cs.classfile = file;
} else
cs = reader.enterClass(name, file);
list = list.prepend(cs);
}
return list.reverse();
}
/** /**
* Free resources related to annotation processing. * Free resources related to annotation processing.
*/ */
@ -1123,6 +1220,11 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
return packages.reverse(); return packages.reverse();
} }
// avoid unchecked warning from use of varargs
private static <T> List<T> join(List<T> list1, List<T> list2) {
return list1.appendList(list2);
}
private boolean isPkgInfo(JavaFileObject fo, JavaFileObject.Kind kind) { private boolean isPkgInfo(JavaFileObject fo, JavaFileObject.Kind kind) {
return fo.isNameCompatible("package-info", kind); return fo.isNameCompatible("package-info", kind);
} }
@ -1131,62 +1233,6 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
return isPkgInfo(sym.classfile, JavaFileObject.Kind.CLASS) && (sym.packge().package_info == sym); return isPkgInfo(sym.classfile, JavaFileObject.Kind.CLASS) && (sym.packge().package_info == sym);
} }
private Context contextForNextRound(Context context, boolean shareNames)
throws IOException
{
Context next = new Context();
Options options = Options.instance(context);
assert options != null;
next.put(Options.optionsKey, options);
PrintWriter out = context.get(Log.outKey);
assert out != null;
next.put(Log.outKey, out);
if (shareNames) {
Names names = Names.instance(context);
assert names != null;
next.put(Names.namesKey, names);
}
DiagnosticListener<?> dl = context.get(DiagnosticListener.class);
if (dl != null)
next.put(DiagnosticListener.class, dl);
TaskListener tl = context.get(TaskListener.class);
if (tl != null)
next.put(TaskListener.class, tl);
JavaFileManager jfm = context.get(JavaFileManager.class);
assert jfm != null;
next.put(JavaFileManager.class, jfm);
if (jfm instanceof JavacFileManager) {
((JavacFileManager)jfm).setContext(next);
}
Names names = Names.instance(context);
assert names != null;
next.put(Names.namesKey, names);
Keywords keywords = Keywords.instance(context);
assert(keywords != null);
next.put(Keywords.keywordsKey, keywords);
JavaCompiler oldCompiler = JavaCompiler.instance(context);
JavaCompiler nextCompiler = JavaCompiler.instance(next);
nextCompiler.initRound(oldCompiler);
JavacTaskImpl task = context.get(JavacTaskImpl.class);
if (task != null) {
next.put(JavacTaskImpl.class, task);
task.updateContext(next);
}
context.clear();
return next;
}
/* /*
* Called retroactively to determine if a class loader was required, * Called retroactively to determine if a class loader was required,
* after we have failed to create one. * after we have failed to create one.

View file

@ -108,7 +108,6 @@ compiler.warn.illegal.char.for.encoding
compiler.warn.invalid.archive.file compiler.warn.invalid.archive.file
compiler.warn.override.bridge compiler.warn.override.bridge
compiler.warn.position.overflow # CRTable: caused by files with long lines >= 1024 chars compiler.warn.position.overflow # CRTable: caused by files with long lines >= 1024 chars
compiler.warn.proc.file.create.last.round # See CR 6966604
compiler.warn.proc.type.already.exists # JavacFiler: just mentioned in TODO compiler.warn.proc.type.already.exists # JavacFiler: just mentioned in TODO
compiler.warn.unchecked.assign # DEAD, replaced by compiler.misc.unchecked.assign compiler.warn.unchecked.assign # DEAD, replaced by compiler.misc.unchecked.assign
compiler.warn.unchecked.cast.to.type # DEAD, replaced by compiler.misc.unchecked.cast.to.type compiler.warn.unchecked.cast.to.type # DEAD, replaced by compiler.misc.unchecked.cast.to.type

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// key: compiler.warn.proc.file.create.last.round
// options: -Xlint:processing -processor AnnoProc
class ProcFileCreateLastRound { }

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.*;
import java.util.*;
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
import javax.tools.*;
@SupportedAnnotationTypes("*")
public class AnnoProc extends AbstractProcessor {
public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv) {
if (renv.processingOver()) {
Filer filer = processingEnv.getFiler();
Messager messager = processingEnv.getMessager();
try {
JavaFileObject fo = filer.createSourceFile("Gen");
Writer out = fo.openWriter();
out.write("class Gen { }");
out.close();
} catch (IOException e) {
messager.printMessage(Diagnostic.Kind.ERROR, e.toString());
}
}
return false;
}
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test 6966604
* @summary JavacFiler not correctly notified of lastRound
* @compile TestLastRound.java
* @compile/fail/ref=TestLastRound.out -XDrawDiagnostics -Werror -proc:only -processor TestLastRound TestLastRound.java
*/
import java.io.*;
import java.util.*;
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
import javax.tools.*;
@SupportedAnnotationTypes("*")
public class TestLastRound extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
Filer filer = processingEnv.getFiler();
if (roundEnv.processingOver()) {
try {
JavaFileObject fo = filer.createSourceFile("LastRound.java");
Writer out = fo.openWriter();
out.write("class LastRound { }");
out.close();
} catch (IOException e) {
}
}
return true;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
}

View file

@ -0,0 +1,3 @@
- compiler.warn.proc.file.create.last.round: LastRound.java
- compiler.err.warnings.and.werror
1 error

View file

@ -42,7 +42,7 @@ public class WErrorGen extends AbstractProcessor {
public boolean process(Set<? extends TypeElement> annotations, public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) { RoundEnvironment roundEnv) {
Filer filer = processingEnv.getFiler(); Filer filer = processingEnv.getFiler();
if (roundEnv.processingOver()) { if (++round == 1) {
try { try {
JavaFileObject fo = filer.createSourceFile("Gen"); JavaFileObject fo = filer.createSourceFile("Gen");
Writer out = fo.openWriter(); Writer out = fo.openWriter();
@ -58,4 +58,6 @@ public class WErrorGen extends AbstractProcessor {
public SourceVersion getSupportedSourceVersion() { public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest(); return SourceVersion.latest();
} }
int round = 0;
} }