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;
@ -784,193 +783,80 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
} }
} }
/**
// TODO: internal catch clauses?; catch and rethrow an annotation * Helper object for a single round of annotation processing.
// processing error
public JavaCompiler doProcessing(Context context,
List<JCCompilationUnit> roots,
List<ClassSymbol> classSymbols,
Iterable<? extends PackageSymbol> pckSymbols)
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;
// List<JCAnnotation> annotationsPresentInSource = collector.findAnnotations(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>();
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);
Context currentContext = context;
int roundNumber = 0;
boolean errorStatus = false;
runAround:
while(true) {
if ((fatalErrors && compiler.errorCount() != 0)
|| (werror && compiler.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));
}
/*
* Processors for round n have run to completion. Prepare
* for round (n+1) by checked for errors raised by
* annotation processors and then checking for syntax
* errors on any generated source files.
*/ */
if (messager.errorRaised()) { class Round {
errorStatus = true; /** The round number. */
break runAround; final int number;
} else { /** The context for the round. */
if (moreToDo()) { final Context context;
// annotationsPresentInSource = List.nil(); /** 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>(); annotationsPresent = new LinkedHashSet<TypeElement>();
topLevelClasses = List.nil(); topLevelClasses = List.nil();
packageInfoFiles = List.nil(); packageInfoFiles = List.nil();
}
/** Create the next round to be used. */
Round next() {
compiler.close(false); compiler.close(false);
currentContext = contextForNextRound(currentContext, true); return new Round(contextForNextRound(), number + 1);
}
JavaFileManager fileManager = currentContext.get(JavaFileManager.class); /** 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();
}
compiler = JavaCompiler.instance(currentContext); /** Return the number of warnings found so far in this round. */
List<JCCompilationUnit> parsedFiles = sourcesToParsedFiles(compiler); int warningCount() {
roots = cleanTrees(roots).appendList(parsedFiles); return compiler.warningCount();
}
// Check for errors after parsing /** Return whether or not an unrecoverable error has occurred. */
if (log.unrecoverableError) { boolean unrecoverableError() {
errorStatus = true; return log.unrecoverableError;
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();
/** 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>(); annotationsPresent = new LinkedHashSet<TypeElement>();
for (ClassSymbol classSym : topLevelClasses) for (ClassSymbol classSym : topLevelClasses)
annotationComputer.scan(classSym, annotationsPresent); annotationComputer.scan(classSym, annotationsPresent);
for (PackageSymbol pkgSym : packageInfoFiles) for (PackageSymbol pkgSym : packageInfoFiles)
annotationComputer.scan(pkgSym, annotationsPresent); annotationComputer.scan(pkgSym, annotationsPresent);
updateProcessingState(currentContext, false);
} }
} else
break runAround; // No new files
}
}
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))
errorStatus = true;
compiler.close(false); /**
currentContext = contextForNextRound(currentContext, true); * Parse the latest set of generated source files created by the filer.
compiler = JavaCompiler.instance(currentContext);
filer.newRound(currentContext, true);
filer.warnIfUnclosedFiles();
warnIfUnmatchedOptions();
/*
* If an annotation processor raises an error in a round,
* that round runs to completion and one last round occurs.
* The last round may also occur because no more source or
* class files have been generated. Therefore, if an error
* was raised on either of the last *two* rounds, the compile
* should exit with a nonzero exit code. The current value of
* errorStatus holds whether or not an error was raised on the
* second to last round; errorRaised() gives the error status
* of the last round.
*/ */
errorStatus = errorStatus || messager.errorRaised(); List<JCCompilationUnit> parseNewSourceFiles()
// Free resources
this.close();
if (taskListener != null)
taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING));
if (errorStatus) {
compiler.log.nwarnings += messager.warningCount();
compiler.log.nerrors += messager.errorCount();
if (compiler.errorCount() == 0)
compiler.log.nerrors++;
} else if (procOnly && !foundTypeProcessors) {
compiler.todo.clear();
} else { // Final compilation
compiler.close(false);
currentContext = contextForNextRound(currentContext, true);
this.context = currentContext;
updateProcessingState(currentContext, true);
compiler = JavaCompiler.instance(currentContext);
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()));
}
}
return compiler;
}
private List<JCCompilationUnit> sourcesToParsedFiles(JavaCompiler compiler)
throws IOException { throws IOException {
List<JavaFileObject> fileObjects = List.nil(); List<JavaFileObject> fileObjects = List.nil();
for (JavaFileObject jfo : filer.getGeneratedSourceFileObjects() ) { for (JavaFileObject jfo : filer.getGeneratedSourceFileObjects() ) {
@ -980,72 +866,10 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
return compiler.parseFiles(fileObjects); return compiler.parseFiles(fileObjects);
} }
// Call the last round of annotation processing /** Enter the latest set of generated class files created by the filer. */
private List<JCCompilationUnit> runLastRound(int roundNumber, List<ClassSymbol> enterNewClassFiles() {
boolean errorStatus, ClassReader reader = ClassReader.instance(context);
JavaCompiler compiler, Names names = Names.instance(context);
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(); List<ClassSymbol> list = List.nil();
for (Map.Entry<String,JavaFileObject> entry : filer.getGeneratedClasses().entrySet()) { for (Map.Entry<String,JavaFileObject> entry : filer.getGeneratedClasses().entrySet()) {
@ -1069,6 +893,279 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
return list.reverse(); 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
public JavaCompiler doProcessing(Context context,
List<JCCompilationUnit> roots,
List<ClassSymbol> classSymbols,
Iterable<? extends PackageSymbol> pckSymbols)
throws IOException {
log = Log.instance(context);
Round round = new Round(context, 1);
round.compiler.todo.clear(); // free the compiler's resources
// 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());
round.packageInfoFiles = getPackageInfoFiles(roots);
Set<PackageSymbol> specifiedPackages = new LinkedHashSet<PackageSymbol>();
for (PackageSymbol psym : pckSymbols)
specifiedPackages.add(psym);
this.specifiedPackages = Collections.unmodifiableSet(specifiedPackages);
ComputeAnnotationSet annotationComputer = new ComputeAnnotationSet(elementUtils);
round.findAnnotationsPresent(annotationComputer);
boolean errorStatus = false;
runAround:
while (true) {
if ((fatalErrors && round.errorCount() != 0)
|| (werror && round.warningCount() != 0)) {
errorStatus = true;
break runAround;
}
round.run(false, false);
/*
* Processors for round n have run to completion. Prepare
* for round (n+1) by checked for errors raised by
* annotation processors and then checking for syntax
* errors on any generated source files.
*/
if (messager.errorRaised()) {
errorStatus = true;
break runAround;
}
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();
}
// 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
// the last round
if (round.unrecoverableError() || (werror && round.warningCount() != 0))
errorStatus = true;
round = round.next();
filer.warnIfUnclosedFiles();
warnIfUnmatchedOptions();
/*
* If an annotation processor raises an error in a round,
* that round runs to completion and one last round occurs.
* The last round may also occur because no more source or
* class files have been generated. Therefore, if an error
* was raised on either of the last *two* rounds, the compile
* should exit with a nonzero exit code. The current value of
* errorStatus holds whether or not an error was raised on the
* second to last round; errorRaised() gives the error status
* of the last round.
*/
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
round = round.next();
round.updateProcessingState();
compiler = round.compiler;
if (procOnly && foundTypeProcessors)
compiler.shouldStopPolicy = CompileState.FLOW;
compiler.enterTrees(cleanTrees(roots));
}
return compiler;
}
private void warnIfUnmatchedOptions() {
if (!unmatchedProcessorOptions.isEmpty()) {
log.warning("proc.unmatched.processor.options", unmatchedProcessorOptions.toString());
}
}
/** /**
* 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;
} }