6966604: JavacFiler not correctly notified of lastRound

Thu, 29 Jul 2010 19:30:35 -0700

author
jjg
date
Thu, 29 Jul 2010 19:30:35 -0700
changeset 620
2cf925ad67ab
parent 619
8a5c98a695ae
child 621
077eb94c912d

6966604: JavacFiler not correctly notified of lastRound
Reviewed-by: darcy

src/share/classes/com/sun/tools/javac/processing/JavacFiler.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples.not-yet.txt file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/ProcFileCreateLastRound/ProcFileCreateLastRound.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/ProcFileCreateLastRound/processors/AnnoProc.java file | annotate | diff | comparison | revisions
test/tools/javac/processing/filer/TestLastRound.java file | annotate | diff | comparison | revisions
test/tools/javac/processing/filer/TestLastRound.out file | annotate | diff | comparison | revisions
test/tools/javac/processing/werror/WErrorGen.java file | annotate | diff | comparison | revisions
     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  }

mercurial