Thu, 29 Jul 2010 19:30:35 -0700
6966604: JavacFiler not correctly notified of lastRound
Reviewed-by: darcy
1.1 --- a/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java Thu Jul 29 19:27:11 2010 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java Thu Jul 29 19:30:35 2010 -0700 1.3 @@ -539,11 +539,14 @@ 1.4 /** 1.5 * Update internal state for a new round. 1.6 */ 1.7 - public void newRound(Context context, boolean lastRound) { 1.8 + public void newRound(Context context) { 1.9 this.context = context; 1.10 this.log = Log.instance(context); 1.11 + clearRoundState(); 1.12 + } 1.13 + 1.14 + void setLastRound(boolean lastRound) { 1.15 this.lastRound = lastRound; 1.16 - clearRoundState(); 1.17 } 1.18 1.19 public void close() {
2.1 --- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Thu Jul 29 19:27:11 2010 -0700 2.2 +++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Thu Jul 29 19:30:35 2010 -0700 2.3 @@ -68,7 +68,6 @@ 2.4 import com.sun.tools.javac.util.Context; 2.5 import com.sun.tools.javac.util.Convert; 2.6 import com.sun.tools.javac.util.List; 2.7 -import com.sun.tools.javac.util.ListBuffer; 2.8 import com.sun.tools.javac.util.Log; 2.9 import com.sun.tools.javac.util.JavacMessages; 2.10 import com.sun.tools.javac.util.Name; 2.11 @@ -759,7 +758,7 @@ 2.12 } 2.13 2.14 @Override 2.15 - public Set<TypeElement> scan(Element e, Set<TypeElement> p) { 2.16 + public Set<TypeElement> scan(Element e, Set<TypeElement> p) { 2.17 for (AnnotationMirror annotationMirror : 2.18 elements.getAllAnnotationMirrors(e) ) { 2.19 Element e2 = annotationMirror.getAnnotationType().asElement(); 2.20 @@ -784,6 +783,237 @@ 2.21 } 2.22 } 2.23 2.24 + /** 2.25 + * Helper object for a single round of annotation processing. 2.26 + */ 2.27 + class Round { 2.28 + /** The round number. */ 2.29 + final int number; 2.30 + /** The context for the round. */ 2.31 + final Context context; 2.32 + /** The compiler for the round. */ 2.33 + final JavaCompiler compiler; 2.34 + /** The log for the round. */ 2.35 + final Log log; 2.36 + 2.37 + /** The set of annotations to be processed this round. */ 2.38 + Set<TypeElement> annotationsPresent; 2.39 + /** The set of top level classes to be processed this round. */ 2.40 + List<ClassSymbol> topLevelClasses; 2.41 + /** The set of package-info files to be processed this round. */ 2.42 + List<PackageSymbol> packageInfoFiles; 2.43 + 2.44 + /** Create a round. */ 2.45 + Round(Context context, int number) { 2.46 + this.context = context; 2.47 + this.number = number; 2.48 + compiler = JavaCompiler.instance(context); 2.49 + log = Log.instance(context); 2.50 + 2.51 + // the following is for the benefit of JavacProcessingEnvironment.getContext() 2.52 + JavacProcessingEnvironment.this.context = context; 2.53 + 2.54 + // the following will be populated as needed 2.55 + annotationsPresent = new LinkedHashSet<TypeElement>(); 2.56 + topLevelClasses = List.nil(); 2.57 + packageInfoFiles = List.nil(); 2.58 + } 2.59 + 2.60 + /** Create the next round to be used. */ 2.61 + Round next() { 2.62 + compiler.close(false); 2.63 + return new Round(contextForNextRound(), number + 1); 2.64 + } 2.65 + 2.66 + /** Return the number of errors found so far in this round. 2.67 + * This may include uncoverable errors, such as parse errors, 2.68 + * and transient errors, such as missing symbols. */ 2.69 + int errorCount() { 2.70 + return compiler.errorCount(); 2.71 + } 2.72 + 2.73 + /** Return the number of warnings found so far in this round. */ 2.74 + int warningCount() { 2.75 + return compiler.warningCount(); 2.76 + } 2.77 + 2.78 + /** Return whether or not an unrecoverable error has occurred. */ 2.79 + boolean unrecoverableError() { 2.80 + return log.unrecoverableError; 2.81 + } 2.82 + 2.83 + /** Find the set of annotations present in the set of top level 2.84 + * classes and package info files to be processed this round. */ 2.85 + void findAnnotationsPresent(ComputeAnnotationSet annotationComputer) { 2.86 + // Use annotation processing to compute the set of annotations present 2.87 + annotationsPresent = new LinkedHashSet<TypeElement>(); 2.88 + for (ClassSymbol classSym : topLevelClasses) 2.89 + annotationComputer.scan(classSym, annotationsPresent); 2.90 + for (PackageSymbol pkgSym : packageInfoFiles) 2.91 + annotationComputer.scan(pkgSym, annotationsPresent); 2.92 + } 2.93 + 2.94 + /** 2.95 + * Parse the latest set of generated source files created by the filer. 2.96 + */ 2.97 + List<JCCompilationUnit> parseNewSourceFiles() 2.98 + throws IOException { 2.99 + List<JavaFileObject> fileObjects = List.nil(); 2.100 + for (JavaFileObject jfo : filer.getGeneratedSourceFileObjects() ) { 2.101 + fileObjects = fileObjects.prepend(jfo); 2.102 + } 2.103 + 2.104 + return compiler.parseFiles(fileObjects); 2.105 + } 2.106 + 2.107 + /** Enter the latest set of generated class files created by the filer. */ 2.108 + List<ClassSymbol> enterNewClassFiles() { 2.109 + ClassReader reader = ClassReader.instance(context); 2.110 + Names names = Names.instance(context); 2.111 + List<ClassSymbol> list = List.nil(); 2.112 + 2.113 + for (Map.Entry<String,JavaFileObject> entry : filer.getGeneratedClasses().entrySet()) { 2.114 + Name name = names.fromString(entry.getKey()); 2.115 + JavaFileObject file = entry.getValue(); 2.116 + if (file.getKind() != JavaFileObject.Kind.CLASS) 2.117 + throw new AssertionError(file); 2.118 + ClassSymbol cs; 2.119 + if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) { 2.120 + Name packageName = Convert.packagePart(name); 2.121 + PackageSymbol p = reader.enterPackage(packageName); 2.122 + if (p.package_info == null) 2.123 + p.package_info = reader.enterClass(Convert.shortName(name), p); 2.124 + cs = p.package_info; 2.125 + if (cs.classfile == null) 2.126 + cs.classfile = file; 2.127 + } else 2.128 + cs = reader.enterClass(name, file); 2.129 + list = list.prepend(cs); 2.130 + } 2.131 + return list.reverse(); 2.132 + } 2.133 + 2.134 + /** Enter a set of syntax trees. */ 2.135 + void enterTrees(List<JCCompilationUnit> roots) { 2.136 + compiler.enterTrees(roots); 2.137 + } 2.138 + 2.139 + /** Run a processing round. */ 2.140 + void run(boolean lastRound, boolean errorStatus) { 2.141 + assert lastRound 2.142 + ? (topLevelClasses.size() == 0 && annotationsPresent.size() == 0) 2.143 + : (errorStatus == false); 2.144 + 2.145 + printRoundInfo(topLevelClasses, annotationsPresent, lastRound); 2.146 + 2.147 + TaskListener taskListener = context.get(TaskListener.class); 2.148 + if (taskListener != null) 2.149 + taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); 2.150 + 2.151 + try { 2.152 + if (lastRound) { 2.153 + filer.setLastRound(true); 2.154 + Set<Element> emptyRootElements = Collections.emptySet(); // immutable 2.155 + RoundEnvironment renv = new JavacRoundEnvironment(true, 2.156 + errorStatus, 2.157 + emptyRootElements, 2.158 + JavacProcessingEnvironment.this); 2.159 + discoveredProcs.iterator().runContributingProcs(renv); 2.160 + } else { 2.161 + discoverAndRunProcs(context, annotationsPresent, topLevelClasses, packageInfoFiles); 2.162 + } 2.163 + } finally { 2.164 + if (taskListener != null) 2.165 + taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); 2.166 + } 2.167 + } 2.168 + 2.169 + /** Update the processing state for the current context. */ 2.170 + // Question: should this not be part of next()? 2.171 + // Note: Calling it from next() breaks some tests. There is an issue 2.172 + // whether the annotationComputer is using elementUtils with the 2.173 + // correct context. 2.174 + void updateProcessingState() { 2.175 + filer.newRound(context); 2.176 + messager.newRound(context); 2.177 + 2.178 + elementUtils.setContext(context); 2.179 + typeUtils.setContext(context); 2.180 + } 2.181 + 2.182 + /** Print info about this round. */ 2.183 + private void printRoundInfo(List<ClassSymbol> topLevelClasses, 2.184 + Set<TypeElement> annotationsPresent, 2.185 + boolean lastRound) { 2.186 + if (printRounds || verbose) { 2.187 + log.printNoteLines("x.print.rounds", 2.188 + number, 2.189 + "{" + topLevelClasses.toString(", ") + "}", 2.190 + annotationsPresent, 2.191 + lastRound); 2.192 + } 2.193 + } 2.194 + 2.195 + /** Get the context for the next round of processing. 2.196 + * Important values are propogated from round to round; 2.197 + * other values are implicitly reset. 2.198 + */ 2.199 + private Context contextForNextRound() { 2.200 + Context next = new Context(); 2.201 + 2.202 + Options options = Options.instance(context); 2.203 + assert options != null; 2.204 + next.put(Options.optionsKey, options); 2.205 + 2.206 + PrintWriter out = context.get(Log.outKey); 2.207 + assert out != null; 2.208 + next.put(Log.outKey, out); 2.209 + 2.210 + final boolean shareNames = true; 2.211 + if (shareNames) { 2.212 + Names names = Names.instance(context); 2.213 + assert names != null; 2.214 + next.put(Names.namesKey, names); 2.215 + } 2.216 + 2.217 + DiagnosticListener<?> dl = context.get(DiagnosticListener.class); 2.218 + if (dl != null) 2.219 + next.put(DiagnosticListener.class, dl); 2.220 + 2.221 + TaskListener tl = context.get(TaskListener.class); 2.222 + if (tl != null) 2.223 + next.put(TaskListener.class, tl); 2.224 + 2.225 + JavaFileManager jfm = context.get(JavaFileManager.class); 2.226 + assert jfm != null; 2.227 + next.put(JavaFileManager.class, jfm); 2.228 + if (jfm instanceof JavacFileManager) { 2.229 + ((JavacFileManager)jfm).setContext(next); 2.230 + } 2.231 + 2.232 + Names names = Names.instance(context); 2.233 + assert names != null; 2.234 + next.put(Names.namesKey, names); 2.235 + 2.236 + Keywords keywords = Keywords.instance(context); 2.237 + assert(keywords != null); 2.238 + next.put(Keywords.keywordsKey, keywords); 2.239 + 2.240 + JavaCompiler oldCompiler = JavaCompiler.instance(context); 2.241 + JavaCompiler nextCompiler = JavaCompiler.instance(next); 2.242 + nextCompiler.initRound(oldCompiler); 2.243 + 2.244 + JavacTaskImpl task = context.get(JavacTaskImpl.class); 2.245 + if (task != null) { 2.246 + next.put(JavacTaskImpl.class, task); 2.247 + task.updateContext(next); 2.248 + } 2.249 + 2.250 + context.clear(); 2.251 + return next; 2.252 + } 2.253 + } 2.254 + 2.255 2.256 // TODO: internal catch clauses?; catch and rethrow an annotation 2.257 // processing error 2.258 @@ -794,60 +1024,37 @@ 2.259 throws IOException { 2.260 2.261 log = Log.instance(context); 2.262 - TaskListener taskListener = context.get(TaskListener.class); 2.263 2.264 - JavaCompiler compiler = JavaCompiler.instance(context); 2.265 - compiler.todo.clear(); // free the compiler's resources 2.266 + Round round = new Round(context, 1); 2.267 + round.compiler.todo.clear(); // free the compiler's resources 2.268 2.269 - int round = 0; 2.270 + // The reverse() in the following line is to maintain behavioural 2.271 + // compatibility with the previous revision of the code. Strictly speaking, 2.272 + // it should not be necessary, but a javah golden file test fails without it. 2.273 + round.topLevelClasses = 2.274 + getTopLevelClasses(roots).prependList(classSymbols.reverse()); 2.275 2.276 - // List<JCAnnotation> annotationsPresentInSource = collector.findAnnotations(roots); 2.277 - List<ClassSymbol> topLevelClasses = getTopLevelClasses(roots); 2.278 - 2.279 - for (ClassSymbol classSym : classSymbols) 2.280 - topLevelClasses = topLevelClasses.prepend(classSym); 2.281 - List<PackageSymbol> packageInfoFiles = 2.282 - getPackageInfoFiles(roots); 2.283 + round.packageInfoFiles = getPackageInfoFiles(roots); 2.284 2.285 Set<PackageSymbol> specifiedPackages = new LinkedHashSet<PackageSymbol>(); 2.286 for (PackageSymbol psym : pckSymbols) 2.287 specifiedPackages.add(psym); 2.288 this.specifiedPackages = Collections.unmodifiableSet(specifiedPackages); 2.289 2.290 - // Use annotation processing to compute the set of annotations present 2.291 - Set<TypeElement> annotationsPresent = new LinkedHashSet<TypeElement>(); 2.292 ComputeAnnotationSet annotationComputer = new ComputeAnnotationSet(elementUtils); 2.293 - for (ClassSymbol classSym : topLevelClasses) 2.294 - annotationComputer.scan(classSym, annotationsPresent); 2.295 - for (PackageSymbol pkgSym : packageInfoFiles) 2.296 - annotationComputer.scan(pkgSym, annotationsPresent); 2.297 + round.findAnnotationsPresent(annotationComputer); 2.298 2.299 - Context currentContext = context; 2.300 - 2.301 - int roundNumber = 0; 2.302 boolean errorStatus = false; 2.303 2.304 runAround: 2.305 - while(true) { 2.306 - if ((fatalErrors && compiler.errorCount() != 0) 2.307 - || (werror && compiler.warningCount() != 0)) { 2.308 + while (true) { 2.309 + if ((fatalErrors && round.errorCount() != 0) 2.310 + || (werror && round.warningCount() != 0)) { 2.311 errorStatus = true; 2.312 break runAround; 2.313 } 2.314 2.315 - this.context = currentContext; 2.316 - roundNumber++; 2.317 - printRoundInfo(roundNumber, topLevelClasses, annotationsPresent, false); 2.318 - 2.319 - if (taskListener != null) 2.320 - taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); 2.321 - 2.322 - try { 2.323 - discoverAndRunProcs(currentContext, annotationsPresent, topLevelClasses, packageInfoFiles); 2.324 - } finally { 2.325 - if (taskListener != null) 2.326 - taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); 2.327 - } 2.328 + round.run(false, false); 2.329 2.330 /* 2.331 * Processors for round n have run to completion. Prepare 2.332 @@ -858,65 +1065,54 @@ 2.333 if (messager.errorRaised()) { 2.334 errorStatus = true; 2.335 break runAround; 2.336 - } else { 2.337 - if (moreToDo()) { 2.338 - // annotationsPresentInSource = List.nil(); 2.339 - annotationsPresent = new LinkedHashSet<TypeElement>(); 2.340 - topLevelClasses = List.nil(); 2.341 - packageInfoFiles = List.nil(); 2.342 + } 2.343 2.344 - compiler.close(false); 2.345 - currentContext = contextForNextRound(currentContext, true); 2.346 + if (!moreToDo()) 2.347 + break runAround; // No new files 2.348 2.349 - JavaFileManager fileManager = currentContext.get(JavaFileManager.class); 2.350 + round = round.next(); 2.351 2.352 - compiler = JavaCompiler.instance(currentContext); 2.353 - List<JCCompilationUnit> parsedFiles = sourcesToParsedFiles(compiler); 2.354 - roots = cleanTrees(roots).appendList(parsedFiles); 2.355 + List<JCCompilationUnit> parsedFiles = round.parseNewSourceFiles(); 2.356 + roots = cleanTrees(roots).appendList(parsedFiles); 2.357 2.358 - // Check for errors after parsing 2.359 - if (log.unrecoverableError) { 2.360 - errorStatus = true; 2.361 - break runAround; 2.362 - } else { 2.363 - List<ClassSymbol> newClasses = enterNewClassFiles(currentContext); 2.364 - compiler.enterTrees(roots); 2.365 + // Check for errors after parsing 2.366 + if (round.unrecoverableError()) { 2.367 + errorStatus = true; 2.368 + break runAround; 2.369 + } 2.370 2.371 - // annotationsPresentInSource = 2.372 - // collector.findAnnotations(parsedFiles); 2.373 - ListBuffer<ClassSymbol> tlc = new ListBuffer<ClassSymbol>(); 2.374 - tlc.appendList(getTopLevelClasses(parsedFiles)); 2.375 - tlc.appendList(getTopLevelClassesFromClasses(newClasses)); 2.376 - topLevelClasses = tlc.toList(); 2.377 + List<ClassSymbol> newClasses = round.enterNewClassFiles(); 2.378 + round.enterTrees(roots); 2.379 2.380 - ListBuffer<PackageSymbol> pif = new ListBuffer<PackageSymbol>(); 2.381 - pif.appendList(getPackageInfoFiles(parsedFiles)); 2.382 - pif.appendList(getPackageInfoFilesFromClasses(newClasses)); 2.383 - packageInfoFiles = pif.toList(); 2.384 + round.topLevelClasses = join( 2.385 + getTopLevelClasses(parsedFiles), 2.386 + getTopLevelClassesFromClasses(newClasses)); 2.387 2.388 - annotationsPresent = new LinkedHashSet<TypeElement>(); 2.389 - for (ClassSymbol classSym : topLevelClasses) 2.390 - annotationComputer.scan(classSym, annotationsPresent); 2.391 - for (PackageSymbol pkgSym : packageInfoFiles) 2.392 - annotationComputer.scan(pkgSym, annotationsPresent); 2.393 + round.packageInfoFiles = join( 2.394 + getPackageInfoFiles(parsedFiles), 2.395 + getPackageInfoFilesFromClasses(newClasses)); 2.396 2.397 - updateProcessingState(currentContext, false); 2.398 - } 2.399 - } else 2.400 - break runAround; // No new files 2.401 - } 2.402 + round.findAnnotationsPresent(annotationComputer); 2.403 + round.updateProcessingState(); 2.404 } 2.405 - roots = runLastRound(roundNumber, errorStatus, compiler, roots, taskListener); 2.406 + 2.407 + // run last round 2.408 + round.run(true, errorStatus); 2.409 + 2.410 + // Add any sources generated during the last round to the set 2.411 + // of files to be compiled. 2.412 + if (moreToDo()) { 2.413 + List<JCCompilationUnit> parsedFiles = round.parseNewSourceFiles(); 2.414 + roots = cleanTrees(roots).appendList(parsedFiles); 2.415 + } 2.416 + 2.417 // Set error status for any files compiled and generated in 2.418 // the last round 2.419 - if (log.unrecoverableError || (werror && compiler.warningCount() != 0)) 2.420 + if (round.unrecoverableError() || (werror && round.warningCount() != 0)) 2.421 errorStatus = true; 2.422 2.423 - compiler.close(false); 2.424 - currentContext = contextForNextRound(currentContext, true); 2.425 - compiler = JavaCompiler.instance(currentContext); 2.426 + round = round.next(); 2.427 2.428 - filer.newRound(currentContext, true); 2.429 filer.warnIfUnclosedFiles(); 2.430 warnIfUnmatchedOptions(); 2.431 2.432 @@ -933,142 +1129,43 @@ 2.433 */ 2.434 errorStatus = errorStatus || messager.errorRaised(); 2.435 2.436 - 2.437 // Free resources 2.438 this.close(); 2.439 2.440 + TaskListener taskListener = this.context.get(TaskListener.class); 2.441 if (taskListener != null) 2.442 taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING)); 2.443 2.444 + JavaCompiler compiler; 2.445 + 2.446 if (errorStatus) { 2.447 + compiler = round.compiler; 2.448 compiler.log.nwarnings += messager.warningCount(); 2.449 compiler.log.nerrors += messager.errorCount(); 2.450 if (compiler.errorCount() == 0) 2.451 compiler.log.nerrors++; 2.452 } else if (procOnly && !foundTypeProcessors) { 2.453 + compiler = round.compiler; 2.454 compiler.todo.clear(); 2.455 } else { // Final compilation 2.456 - compiler.close(false); 2.457 - currentContext = contextForNextRound(currentContext, true); 2.458 - this.context = currentContext; 2.459 - updateProcessingState(currentContext, true); 2.460 - compiler = JavaCompiler.instance(currentContext); 2.461 + round = round.next(); 2.462 + round.updateProcessingState(); 2.463 + compiler = round.compiler; 2.464 if (procOnly && foundTypeProcessors) 2.465 compiler.shouldStopPolicy = CompileState.FLOW; 2.466 2.467 - if (true) { 2.468 - compiler.enterTrees(cleanTrees(roots)); 2.469 - } else { 2.470 - List<JavaFileObject> fileObjects = List.nil(); 2.471 - for (JCCompilationUnit unit : roots) 2.472 - fileObjects = fileObjects.prepend(unit.getSourceFile()); 2.473 - roots = null; 2.474 - compiler.enterTrees(compiler.parseFiles(fileObjects.reverse())); 2.475 - } 2.476 + compiler.enterTrees(cleanTrees(roots)); 2.477 } 2.478 2.479 return compiler; 2.480 } 2.481 2.482 - private List<JCCompilationUnit> sourcesToParsedFiles(JavaCompiler compiler) 2.483 - throws IOException { 2.484 - List<JavaFileObject> fileObjects = List.nil(); 2.485 - for (JavaFileObject jfo : filer.getGeneratedSourceFileObjects() ) { 2.486 - fileObjects = fileObjects.prepend(jfo); 2.487 - } 2.488 - 2.489 - return compiler.parseFiles(fileObjects); 2.490 - } 2.491 - 2.492 - // Call the last round of annotation processing 2.493 - private List<JCCompilationUnit> runLastRound(int roundNumber, 2.494 - boolean errorStatus, 2.495 - JavaCompiler compiler, 2.496 - List<JCCompilationUnit> roots, 2.497 - TaskListener taskListener) throws IOException { 2.498 - roundNumber++; 2.499 - List<ClassSymbol> noTopLevelClasses = List.nil(); 2.500 - Set<TypeElement> noAnnotations = Collections.emptySet(); 2.501 - printRoundInfo(roundNumber, noTopLevelClasses, noAnnotations, true); 2.502 - 2.503 - Set<Element> emptyRootElements = Collections.emptySet(); // immutable 2.504 - RoundEnvironment renv = new JavacRoundEnvironment(true, 2.505 - errorStatus, 2.506 - emptyRootElements, 2.507 - JavacProcessingEnvironment.this); 2.508 - if (taskListener != null) 2.509 - taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); 2.510 - 2.511 - try { 2.512 - discoveredProcs.iterator().runContributingProcs(renv); 2.513 - } finally { 2.514 - if (taskListener != null) 2.515 - taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); 2.516 - } 2.517 - 2.518 - // Add any sources generated during the last round to the set 2.519 - // of files to be compiled. 2.520 - if (moreToDo()) { 2.521 - List<JCCompilationUnit> parsedFiles = sourcesToParsedFiles(compiler); 2.522 - roots = cleanTrees(roots).appendList(parsedFiles); 2.523 - } 2.524 - 2.525 - return roots; 2.526 - } 2.527 - 2.528 - private void updateProcessingState(Context currentContext, boolean lastRound) { 2.529 - filer.newRound(currentContext, lastRound); 2.530 - messager.newRound(currentContext); 2.531 - 2.532 - elementUtils.setContext(currentContext); 2.533 - typeUtils.setContext(currentContext); 2.534 - } 2.535 - 2.536 private void warnIfUnmatchedOptions() { 2.537 if (!unmatchedProcessorOptions.isEmpty()) { 2.538 log.warning("proc.unmatched.processor.options", unmatchedProcessorOptions.toString()); 2.539 } 2.540 } 2.541 2.542 - private void printRoundInfo(int roundNumber, 2.543 - List<ClassSymbol> topLevelClasses, 2.544 - Set<TypeElement> annotationsPresent, 2.545 - boolean lastRound) { 2.546 - if (printRounds || verbose) { 2.547 - log.printNoteLines("x.print.rounds", 2.548 - roundNumber, 2.549 - "{" + topLevelClasses.toString(", ") + "}", 2.550 - annotationsPresent, 2.551 - lastRound); 2.552 - } 2.553 - } 2.554 - 2.555 - private List<ClassSymbol> enterNewClassFiles(Context currentContext) { 2.556 - ClassReader reader = ClassReader.instance(currentContext); 2.557 - Names names = Names.instance(currentContext); 2.558 - List<ClassSymbol> list = List.nil(); 2.559 - 2.560 - for (Map.Entry<String,JavaFileObject> entry : filer.getGeneratedClasses().entrySet()) { 2.561 - Name name = names.fromString(entry.getKey()); 2.562 - JavaFileObject file = entry.getValue(); 2.563 - if (file.getKind() != JavaFileObject.Kind.CLASS) 2.564 - throw new AssertionError(file); 2.565 - ClassSymbol cs; 2.566 - if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) { 2.567 - Name packageName = Convert.packagePart(name); 2.568 - PackageSymbol p = reader.enterPackage(packageName); 2.569 - if (p.package_info == null) 2.570 - p.package_info = reader.enterClass(Convert.shortName(name), p); 2.571 - cs = p.package_info; 2.572 - if (cs.classfile == null) 2.573 - cs.classfile = file; 2.574 - } else 2.575 - cs = reader.enterClass(name, file); 2.576 - list = list.prepend(cs); 2.577 - } 2.578 - return list.reverse(); 2.579 - } 2.580 - 2.581 /** 2.582 * Free resources related to annotation processing. 2.583 */ 2.584 @@ -1123,6 +1220,11 @@ 2.585 return packages.reverse(); 2.586 } 2.587 2.588 + // avoid unchecked warning from use of varargs 2.589 + private static <T> List<T> join(List<T> list1, List<T> list2) { 2.590 + return list1.appendList(list2); 2.591 + } 2.592 + 2.593 private boolean isPkgInfo(JavaFileObject fo, JavaFileObject.Kind kind) { 2.594 return fo.isNameCompatible("package-info", kind); 2.595 } 2.596 @@ -1131,62 +1233,6 @@ 2.597 return isPkgInfo(sym.classfile, JavaFileObject.Kind.CLASS) && (sym.packge().package_info == sym); 2.598 } 2.599 2.600 - private Context contextForNextRound(Context context, boolean shareNames) 2.601 - throws IOException 2.602 - { 2.603 - Context next = new Context(); 2.604 - 2.605 - Options options = Options.instance(context); 2.606 - assert options != null; 2.607 - next.put(Options.optionsKey, options); 2.608 - 2.609 - PrintWriter out = context.get(Log.outKey); 2.610 - assert out != null; 2.611 - next.put(Log.outKey, out); 2.612 - 2.613 - if (shareNames) { 2.614 - Names names = Names.instance(context); 2.615 - assert names != null; 2.616 - next.put(Names.namesKey, names); 2.617 - } 2.618 - 2.619 - DiagnosticListener<?> dl = context.get(DiagnosticListener.class); 2.620 - if (dl != null) 2.621 - next.put(DiagnosticListener.class, dl); 2.622 - 2.623 - TaskListener tl = context.get(TaskListener.class); 2.624 - if (tl != null) 2.625 - next.put(TaskListener.class, tl); 2.626 - 2.627 - JavaFileManager jfm = context.get(JavaFileManager.class); 2.628 - assert jfm != null; 2.629 - next.put(JavaFileManager.class, jfm); 2.630 - if (jfm instanceof JavacFileManager) { 2.631 - ((JavacFileManager)jfm).setContext(next); 2.632 - } 2.633 - 2.634 - Names names = Names.instance(context); 2.635 - assert names != null; 2.636 - next.put(Names.namesKey, names); 2.637 - 2.638 - Keywords keywords = Keywords.instance(context); 2.639 - assert(keywords != null); 2.640 - next.put(Keywords.keywordsKey, keywords); 2.641 - 2.642 - JavaCompiler oldCompiler = JavaCompiler.instance(context); 2.643 - JavaCompiler nextCompiler = JavaCompiler.instance(next); 2.644 - nextCompiler.initRound(oldCompiler); 2.645 - 2.646 - JavacTaskImpl task = context.get(JavacTaskImpl.class); 2.647 - if (task != null) { 2.648 - next.put(JavacTaskImpl.class, task); 2.649 - task.updateContext(next); 2.650 - } 2.651 - 2.652 - context.clear(); 2.653 - return next; 2.654 - } 2.655 - 2.656 /* 2.657 * Called retroactively to determine if a class loader was required, 2.658 * after we have failed to create one.
3.1 --- a/test/tools/javac/diags/examples.not-yet.txt Thu Jul 29 19:27:11 2010 -0700 3.2 +++ b/test/tools/javac/diags/examples.not-yet.txt Thu Jul 29 19:30:35 2010 -0700 3.3 @@ -108,7 +108,6 @@ 3.4 compiler.warn.invalid.archive.file 3.5 compiler.warn.override.bridge 3.6 compiler.warn.position.overflow # CRTable: caused by files with long lines >= 1024 chars 3.7 -compiler.warn.proc.file.create.last.round # See CR 6966604 3.8 compiler.warn.proc.type.already.exists # JavacFiler: just mentioned in TODO 3.9 compiler.warn.unchecked.assign # DEAD, replaced by compiler.misc.unchecked.assign 3.10 compiler.warn.unchecked.cast.to.type # DEAD, replaced by compiler.misc.unchecked.cast.to.type
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/tools/javac/diags/examples/ProcFileCreateLastRound/ProcFileCreateLastRound.java Thu Jul 29 19:30:35 2010 -0700 4.3 @@ -0,0 +1,27 @@ 4.4 +/* 4.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. 4.11 + * 4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 + * version 2 for more details (a copy is included in the LICENSE file that 4.16 + * accompanied this code). 4.17 + * 4.18 + * You should have received a copy of the GNU General Public License version 4.19 + * 2 along with this work; if not, write to the Free Software Foundation, 4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 + * 4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.23 + * or visit www.oracle.com if you need additional information or have any 4.24 + * questions. 4.25 + */ 4.26 + 4.27 +// key: compiler.warn.proc.file.create.last.round 4.28 +// options: -Xlint:processing -processor AnnoProc 4.29 + 4.30 +class ProcFileCreateLastRound { }
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/tools/javac/diags/examples/ProcFileCreateLastRound/processors/AnnoProc.java Thu Jul 29 19:30:35 2010 -0700 5.3 @@ -0,0 +1,52 @@ 5.4 +/* 5.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.7 + * 5.8 + * This code is free software; you can redistribute it and/or modify it 5.9 + * under the terms of the GNU General Public License version 2 only, as 5.10 + * published by the Free Software Foundation. 5.11 + * 5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.15 + * version 2 for more details (a copy is included in the LICENSE file that 5.16 + * accompanied this code). 5.17 + * 5.18 + * You should have received a copy of the GNU General Public License version 5.19 + * 2 along with this work; if not, write to the Free Software Foundation, 5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.21 + * 5.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 5.23 + * or visit www.oracle.com if you need additional information or have any 5.24 + * questions. 5.25 + */ 5.26 + 5.27 +import java.io.*; 5.28 +import java.util.*; 5.29 +import javax.annotation.processing.*; 5.30 +import javax.lang.model.*; 5.31 +import javax.lang.model.element.*; 5.32 +import javax.tools.*; 5.33 + 5.34 +@SupportedAnnotationTypes("*") 5.35 +public class AnnoProc extends AbstractProcessor { 5.36 + public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv) { 5.37 + if (renv.processingOver()) { 5.38 + Filer filer = processingEnv.getFiler(); 5.39 + Messager messager = processingEnv.getMessager(); 5.40 + try { 5.41 + JavaFileObject fo = filer.createSourceFile("Gen"); 5.42 + Writer out = fo.openWriter(); 5.43 + out.write("class Gen { }"); 5.44 + out.close(); 5.45 + } catch (IOException e) { 5.46 + messager.printMessage(Diagnostic.Kind.ERROR, e.toString()); 5.47 + } 5.48 + } 5.49 + return false; 5.50 + } 5.51 + 5.52 + public SourceVersion getSupportedSourceVersion() { 5.53 + return SourceVersion.latest(); 5.54 + } 5.55 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/tools/javac/processing/filer/TestLastRound.java Thu Jul 29 19:30:35 2010 -0700 6.3 @@ -0,0 +1,60 @@ 6.4 +/* 6.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. 6.11 + * 6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.15 + * version 2 for more details (a copy is included in the LICENSE file that 6.16 + * accompanied this code). 6.17 + * 6.18 + * You should have received a copy of the GNU General Public License version 6.19 + * 2 along with this work; if not, write to the Free Software Foundation, 6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.21 + * 6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 6.23 + * or visit www.oracle.com if you need additional information or have any 6.24 + * questions. 6.25 + */ 6.26 + 6.27 +/* 6.28 + * @test 6966604 6.29 + * @summary JavacFiler not correctly notified of lastRound 6.30 + * @compile TestLastRound.java 6.31 + * @compile/fail/ref=TestLastRound.out -XDrawDiagnostics -Werror -proc:only -processor TestLastRound TestLastRound.java 6.32 + */ 6.33 + 6.34 +import java.io.*; 6.35 +import java.util.*; 6.36 +import javax.annotation.processing.*; 6.37 +import javax.lang.model.*; 6.38 +import javax.lang.model.element.*; 6.39 +import javax.tools.*; 6.40 + 6.41 +@SupportedAnnotationTypes("*") 6.42 +public class TestLastRound extends AbstractProcessor { 6.43 + @Override 6.44 + public boolean process(Set<? extends TypeElement> annotations, 6.45 + RoundEnvironment roundEnv) { 6.46 + Filer filer = processingEnv.getFiler(); 6.47 + if (roundEnv.processingOver()) { 6.48 + try { 6.49 + JavaFileObject fo = filer.createSourceFile("LastRound.java"); 6.50 + Writer out = fo.openWriter(); 6.51 + out.write("class LastRound { }"); 6.52 + out.close(); 6.53 + } catch (IOException e) { 6.54 + } 6.55 + } 6.56 + return true; 6.57 + } 6.58 + 6.59 + @Override 6.60 + public SourceVersion getSupportedSourceVersion() { 6.61 + return SourceVersion.latest(); 6.62 + } 6.63 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/test/tools/javac/processing/filer/TestLastRound.out Thu Jul 29 19:30:35 2010 -0700 7.3 @@ -0,0 +1,3 @@ 7.4 +- compiler.warn.proc.file.create.last.round: LastRound.java 7.5 +- compiler.err.warnings.and.werror 7.6 +1 error
8.1 --- a/test/tools/javac/processing/werror/WErrorGen.java Thu Jul 29 19:27:11 2010 -0700 8.2 +++ b/test/tools/javac/processing/werror/WErrorGen.java Thu Jul 29 19:30:35 2010 -0700 8.3 @@ -42,7 +42,7 @@ 8.4 public boolean process(Set<? extends TypeElement> annotations, 8.5 RoundEnvironment roundEnv) { 8.6 Filer filer = processingEnv.getFiler(); 8.7 - if (roundEnv.processingOver()) { 8.8 + if (++round == 1) { 8.9 try { 8.10 JavaFileObject fo = filer.createSourceFile("Gen"); 8.11 Writer out = fo.openWriter(); 8.12 @@ -58,4 +58,6 @@ 8.13 public SourceVersion getSupportedSourceVersion() { 8.14 return SourceVersion.latest(); 8.15 } 8.16 + 8.17 + int round = 0; 8.18 }