--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java Thu Jul 29 19:27:11 2010 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java Thu Jul 29 19:30:35 2010 -0700
@@ -539,11 +539,14 @@
/**
* Update internal state for a new round.
*/
- public void newRound(Context context, boolean lastRound) {
+ public void newRound(Context context) {
this.context = context;
this.log = Log.instance(context);
+ clearRoundState();
+ }
+
+ void setLastRound(boolean lastRound) {
this.lastRound = lastRound;
- clearRoundState();
}
public void close() {
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Thu Jul 29 19:27:11 2010 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Thu Jul 29 19:30:35 2010 -0700
@@ -68,7 +68,6 @@
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Convert;
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.JavacMessages;
import com.sun.tools.javac.util.Name;
@@ -759,7 +758,7 @@
}
@Override
- public Set<TypeElement> scan(Element e, Set<TypeElement> p) {
+ public Set<TypeElement> scan(Element e, Set<TypeElement> p) {
for (AnnotationMirror annotationMirror :
elements.getAllAnnotationMirrors(e) ) {
Element e2 = annotationMirror.getAnnotationType().asElement();
@@ -784,6 +783,237 @@
}
}
+ /**
+ * 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
// processing error
@@ -794,60 +1024,37 @@
throws IOException {
log = Log.instance(context);
- TaskListener taskListener = context.get(TaskListener.class);
- JavaCompiler compiler = JavaCompiler.instance(context);
- compiler.todo.clear(); // free the compiler's resources
-
- int round = 0;
+ Round round = new Round(context, 1);
+ round.compiler.todo.clear(); // free the compiler's resources
- // List<JCAnnotation> annotationsPresentInSource = collector.findAnnotations(roots);
- List<ClassSymbol> topLevelClasses = getTopLevelClasses(roots);
+ // 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());
- for (ClassSymbol classSym : classSymbols)
- topLevelClasses = topLevelClasses.prepend(classSym);
- List<PackageSymbol> packageInfoFiles =
- getPackageInfoFiles(roots);
+ round.packageInfoFiles = getPackageInfoFiles(roots);
Set<PackageSymbol> specifiedPackages = new LinkedHashSet<PackageSymbol>();
for (PackageSymbol psym : pckSymbols)
specifiedPackages.add(psym);
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);
- for (ClassSymbol classSym : topLevelClasses)
- annotationComputer.scan(classSym, annotationsPresent);
- for (PackageSymbol pkgSym : packageInfoFiles)
- annotationComputer.scan(pkgSym, annotationsPresent);
+ round.findAnnotationsPresent(annotationComputer);
- Context currentContext = context;
-
- int roundNumber = 0;
boolean errorStatus = false;
runAround:
- while(true) {
- if ((fatalErrors && compiler.errorCount() != 0)
- || (werror && compiler.warningCount() != 0)) {
+ while (true) {
+ if ((fatalErrors && round.errorCount() != 0)
+ || (werror && round.warningCount() != 0)) {
errorStatus = true;
break runAround;
}
- this.context = currentContext;
- 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));
- }
+ round.run(false, false);
/*
* Processors for round n have run to completion. Prepare
@@ -858,65 +1065,54 @@
if (messager.errorRaised()) {
errorStatus = true;
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);
+ if (!moreToDo())
+ break runAround; // No new files
- JavaFileManager fileManager = currentContext.get(JavaFileManager.class);
+ round = round.next();
- compiler = JavaCompiler.instance(currentContext);
- List<JCCompilationUnit> parsedFiles = sourcesToParsedFiles(compiler);
- roots = cleanTrees(roots).appendList(parsedFiles);
+ List<JCCompilationUnit> parsedFiles = round.parseNewSourceFiles();
+ 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);
+ // Check for errors after parsing
+ if (round.unrecoverableError()) {
+ errorStatus = true;
+ break runAround;
+ }
+
+ List<ClassSymbol> newClasses = round.enterNewClassFiles();
+ round.enterTrees(roots);
- // annotationsPresentInSource =
- // collector.findAnnotations(parsedFiles);
- ListBuffer<ClassSymbol> tlc = new ListBuffer<ClassSymbol>();
- tlc.appendList(getTopLevelClasses(parsedFiles));
- tlc.appendList(getTopLevelClassesFromClasses(newClasses));
- topLevelClasses = tlc.toList();
+ round.topLevelClasses = join(
+ getTopLevelClasses(parsedFiles),
+ getTopLevelClassesFromClasses(newClasses));
- ListBuffer<PackageSymbol> pif = new ListBuffer<PackageSymbol>();
- pif.appendList(getPackageInfoFiles(parsedFiles));
- pif.appendList(getPackageInfoFilesFromClasses(newClasses));
- packageInfoFiles = pif.toList();
+ round.packageInfoFiles = join(
+ getPackageInfoFiles(parsedFiles),
+ getPackageInfoFilesFromClasses(newClasses));
- annotationsPresent = new LinkedHashSet<TypeElement>();
- for (ClassSymbol classSym : topLevelClasses)
- annotationComputer.scan(classSym, annotationsPresent);
- for (PackageSymbol pkgSym : packageInfoFiles)
- annotationComputer.scan(pkgSym, annotationsPresent);
+ round.findAnnotationsPresent(annotationComputer);
+ round.updateProcessingState();
+ }
+
+ // run last round
+ round.run(true, errorStatus);
- updateProcessingState(currentContext, false);
- }
- } else
- break runAround; // No new files
- }
+ // 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);
}
- roots = runLastRound(roundNumber, errorStatus, compiler, roots, taskListener);
+
// Set error status for any files compiled and generated in
// the last round
- if (log.unrecoverableError || (werror && compiler.warningCount() != 0))
+ if (round.unrecoverableError() || (werror && round.warningCount() != 0))
errorStatus = true;
- compiler.close(false);
- currentContext = contextForNextRound(currentContext, true);
- compiler = JavaCompiler.instance(currentContext);
+ round = round.next();
- filer.newRound(currentContext, true);
filer.warnIfUnclosedFiles();
warnIfUnmatchedOptions();
@@ -933,142 +1129,43 @@
*/
errorStatus = errorStatus || messager.errorRaised();
-
// Free resources
this.close();
+ TaskListener taskListener = this.context.get(TaskListener.class);
if (taskListener != null)
taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING));
+ JavaCompiler compiler;
+
if (errorStatus) {
+ compiler = round.compiler;
compiler.log.nwarnings += messager.warningCount();
compiler.log.nerrors += messager.errorCount();
if (compiler.errorCount() == 0)
compiler.log.nerrors++;
} else if (procOnly && !foundTypeProcessors) {
+ compiler = round.compiler;
compiler.todo.clear();
} else { // Final compilation
- compiler.close(false);
- currentContext = contextForNextRound(currentContext, true);
- this.context = currentContext;
- updateProcessingState(currentContext, true);
- compiler = JavaCompiler.instance(currentContext);
+ round = round.next();
+ round.updateProcessingState();
+ compiler = round.compiler;
if (procOnly && foundTypeProcessors)
compiler.shouldStopPolicy = CompileState.FLOW;
- if (true) {
- 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()));
- }
+ compiler.enterTrees(cleanTrees(roots));
}
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() {
if (!unmatchedProcessorOptions.isEmpty()) {
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.
*/
@@ -1123,6 +1220,11 @@
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) {
return fo.isNameCompatible("package-info", kind);
}
@@ -1131,62 +1233,6 @@
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,
* after we have failed to create one.
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt Thu Jul 29 19:27:11 2010 -0700
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Thu Jul 29 19:30:35 2010 -0700
@@ -108,7 +108,6 @@
compiler.warn.invalid.archive.file
compiler.warn.override.bridge
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.unchecked.assign # DEAD, replaced by compiler.misc.unchecked.assign
compiler.warn.unchecked.cast.to.type # DEAD, replaced by compiler.misc.unchecked.cast.to.type
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ProcFileCreateLastRound/ProcFileCreateLastRound.java Thu Jul 29 19:30:35 2010 -0700
@@ -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 { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ProcFileCreateLastRound/processors/AnnoProc.java Thu Jul 29 19:30:35 2010 -0700
@@ -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();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/filer/TestLastRound.java Thu Jul 29 19:30:35 2010 -0700
@@ -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();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/filer/TestLastRound.out Thu Jul 29 19:30:35 2010 -0700
@@ -0,0 +1,3 @@
+- compiler.warn.proc.file.create.last.round: LastRound.java
+- compiler.err.warnings.and.werror
+1 error
--- a/langtools/test/tools/javac/processing/werror/WErrorGen.java Thu Jul 29 19:27:11 2010 -0700
+++ b/langtools/test/tools/javac/processing/werror/WErrorGen.java Thu Jul 29 19:30:35 2010 -0700
@@ -42,7 +42,7 @@
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
Filer filer = processingEnv.getFiler();
- if (roundEnv.processingOver()) {
+ if (++round == 1) {
try {
JavaFileObject fo = filer.createSourceFile("Gen");
Writer out = fo.openWriter();
@@ -58,4 +58,6 @@
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
+
+ int round = 0;
}