langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java
changeset 6355 f01ebbf5a5f7
parent 6162 9d0f96b4befa
child 6581 f58f0ce45802
equal deleted inserted replaced
6354:f50c012cd1f0 6355:f01ebbf5a5f7
   793         final Context context;
   793         final Context context;
   794         /** The compiler for the round. */
   794         /** The compiler for the round. */
   795         final JavaCompiler compiler;
   795         final JavaCompiler compiler;
   796         /** The log for the round. */
   796         /** The log for the round. */
   797         final Log log;
   797         final Log log;
       
   798         /** The number of warnings in the previous round. */
       
   799         final int priorWarnings;
       
   800 
       
   801         /** The ASTs to be compiled. */
       
   802         List<JCCompilationUnit> roots;
       
   803         /** The classes to be compiler that have were generated. */
       
   804         Map<String, JavaFileObject> genClassFiles;
   798 
   805 
   799         /** The set of annotations to be processed this round. */
   806         /** The set of annotations to be processed this round. */
   800         Set<TypeElement> annotationsPresent;
   807         Set<TypeElement> annotationsPresent;
   801         /** The set of top level classes to be processed this round. */
   808         /** The set of top level classes to be processed this round. */
   802         List<ClassSymbol> topLevelClasses;
   809         List<ClassSymbol> topLevelClasses;
   803         /** The set of package-info files to be processed this round. */
   810         /** The set of package-info files to be processed this round. */
   804         List<PackageSymbol> packageInfoFiles;
   811         List<PackageSymbol> packageInfoFiles;
   805 
   812 
   806         /** Create a round. */
   813         /** Create a round (common code). */
   807         Round(Context context, int number) {
   814         private Round(Context context, int number, int priorWarnings) {
   808             this.context = context;
   815             this.context = context;
   809             this.number = number;
   816             this.number = number;
       
   817             this.priorWarnings = priorWarnings;
       
   818 
   810             compiler = JavaCompiler.instance(context);
   819             compiler = JavaCompiler.instance(context);
   811             log = Log.instance(context);
   820             log = Log.instance(context);
   812 
   821 
   813             // the following is for the benefit of JavacProcessingEnvironment.getContext()
   822             // the following is for the benefit of JavacProcessingEnvironment.getContext()
   814             JavacProcessingEnvironment.this.context = context;
   823             JavacProcessingEnvironment.this.context = context;
   815 
   824 
   816             // the following will be populated as needed
   825             // the following will be populated as needed
   817             annotationsPresent = new LinkedHashSet<TypeElement>();
       
   818             topLevelClasses  = List.nil();
   826             topLevelClasses  = List.nil();
   819             packageInfoFiles = List.nil();
   827             packageInfoFiles = List.nil();
   820         }
   828         }
   821 
   829 
       
   830         /** Create the first round. */
       
   831         Round(Context context, List<JCCompilationUnit> roots, List<ClassSymbol> classSymbols) {
       
   832             this(context, 1, 0);
       
   833             this.roots = roots;
       
   834             genClassFiles = new HashMap<String,JavaFileObject>();
       
   835 
       
   836             compiler.todo.clear(); // free the compiler's resources
       
   837 
       
   838             // The reverse() in the following line is to maintain behavioural
       
   839             // compatibility with the previous revision of the code. Strictly speaking,
       
   840             // it should not be necessary, but a javah golden file test fails without it.
       
   841             topLevelClasses =
       
   842                 getTopLevelClasses(roots).prependList(classSymbols.reverse());
       
   843 
       
   844             packageInfoFiles = getPackageInfoFiles(roots);
       
   845 
       
   846             findAnnotationsPresent();
       
   847         }
       
   848 
       
   849         /** Create a new round. */
       
   850         private Round(Round prev,
       
   851                 Set<JavaFileObject> newSourceFiles, Map<String,JavaFileObject> newClassFiles)
       
   852                 throws IOException {
       
   853             this(prev.nextContext(), prev.number+1, prev.compiler.log.nwarnings);
       
   854             this.genClassFiles = prev.genClassFiles;
       
   855 
       
   856             updateProcessingState();
       
   857 
       
   858             List<JCCompilationUnit> parsedFiles = compiler.parseFiles(newSourceFiles);
       
   859             roots = cleanTrees(prev.roots).appendList(parsedFiles);
       
   860 
       
   861             // Check for errors after parsing
       
   862             if (unrecoverableError())
       
   863                 return;
       
   864 
       
   865             enterClassFiles(genClassFiles);
       
   866             List<ClassSymbol> newClasses = enterClassFiles(newClassFiles);
       
   867             genClassFiles.putAll(newClassFiles);
       
   868             enterTrees(roots);
       
   869 
       
   870             if (unrecoverableError())
       
   871                 return;
       
   872 
       
   873             topLevelClasses = join(
       
   874                     getTopLevelClasses(parsedFiles),
       
   875                     getTopLevelClassesFromClasses(newClasses));
       
   876 
       
   877             packageInfoFiles = join(
       
   878                     getPackageInfoFiles(parsedFiles),
       
   879                     getPackageInfoFilesFromClasses(newClasses));
       
   880 
       
   881             findAnnotationsPresent();
       
   882         }
       
   883 
   822         /** Create the next round to be used. */
   884         /** Create the next round to be used. */
   823         Round next() {
   885         Round next(Set<JavaFileObject> newSourceFiles, Map<String, JavaFileObject> newClassFiles)
   824             compiler.close(false);
   886                 throws IOException {
   825             return new Round(contextForNextRound(), number + 1);
   887             try {
       
   888                 return new Round(this, newSourceFiles, newClassFiles);
       
   889             } finally {
       
   890                 compiler.close(false);
       
   891             }
       
   892         }
       
   893 
       
   894         /** Create the compiler to be used for the final compilation. */
       
   895         JavaCompiler finalCompiler(boolean errorStatus) {
       
   896             try {
       
   897                 JavaCompiler c = JavaCompiler.instance(nextContext());
       
   898                 if (errorStatus) {
       
   899                     c.log.nwarnings += priorWarnings + compiler.log.nwarnings;
       
   900                     c.log.nerrors += compiler.log.nerrors;
       
   901                 }
       
   902                 return c;
       
   903             } finally {
       
   904                 compiler.close(false);
       
   905             }
   826         }
   906         }
   827 
   907 
   828         /** Return the number of errors found so far in this round.
   908         /** Return the number of errors found so far in this round.
   829          * This may include uncoverable errors, such as parse errors,
   909          * This may include uncoverable errors, such as parse errors,
   830          * and transient errors, such as missing symbols. */
   910          * and transient errors, such as missing symbols. */
   837             return compiler.warningCount();
   917             return compiler.warningCount();
   838         }
   918         }
   839 
   919 
   840         /** Return whether or not an unrecoverable error has occurred. */
   920         /** Return whether or not an unrecoverable error has occurred. */
   841         boolean unrecoverableError() {
   921         boolean unrecoverableError() {
   842             return log.unrecoverableError;
   922             return log.unrecoverableError
       
   923                     || messager.errorRaised()
       
   924                     || (werror && log.nwarnings > 0)
       
   925                     || (fatalErrors && log.nerrors > 0);
   843         }
   926         }
   844 
   927 
   845         /** Find the set of annotations present in the set of top level
   928         /** Find the set of annotations present in the set of top level
   846          * classes and package info files to be processed this round. */
   929          *  classes and package info files to be processed this round. */
   847         void findAnnotationsPresent(ComputeAnnotationSet annotationComputer) {
   930         void findAnnotationsPresent() {
       
   931             ComputeAnnotationSet annotationComputer = new ComputeAnnotationSet(elementUtils);
   848             // Use annotation processing to compute the set of annotations present
   932             // Use annotation processing to compute the set of annotations present
   849             annotationsPresent = new LinkedHashSet<TypeElement>();
   933             annotationsPresent = new LinkedHashSet<TypeElement>();
   850             for (ClassSymbol classSym : topLevelClasses)
   934             for (ClassSymbol classSym : topLevelClasses)
   851                 annotationComputer.scan(classSym, annotationsPresent);
   935                 annotationComputer.scan(classSym, annotationsPresent);
   852             for (PackageSymbol pkgSym : packageInfoFiles)
   936             for (PackageSymbol pkgSym : packageInfoFiles)
   853                 annotationComputer.scan(pkgSym, annotationsPresent);
   937                 annotationComputer.scan(pkgSym, annotationsPresent);
   854         }
   938         }
   855 
   939 
   856         /**
   940         /** Enter a set of generated class files. */
   857          * Parse the latest set of generated source files created by the filer.
   941         List<ClassSymbol> enterClassFiles(Map<String, JavaFileObject> classFiles) {
   858          */
       
   859         List<JCCompilationUnit> parseNewSourceFiles()
       
   860             throws IOException {
       
   861             List<JavaFileObject> fileObjects = List.nil();
       
   862             for (JavaFileObject jfo : filer.getGeneratedSourceFileObjects() ) {
       
   863                 fileObjects = fileObjects.prepend(jfo);
       
   864             }
       
   865 
       
   866            return compiler.parseFiles(fileObjects);
       
   867         }
       
   868 
       
   869         /** Enter the latest set of generated class files created by the filer. */
       
   870         List<ClassSymbol> enterNewClassFiles() {
       
   871             ClassReader reader = ClassReader.instance(context);
   942             ClassReader reader = ClassReader.instance(context);
   872             Names names = Names.instance(context);
   943             Names names = Names.instance(context);
   873             List<ClassSymbol> list = List.nil();
   944             List<ClassSymbol> list = List.nil();
   874 
   945 
   875             for (Map.Entry<String,JavaFileObject> entry : filer.getGeneratedClasses().entrySet()) {
   946             for (Map.Entry<String,JavaFileObject> entry : classFiles.entrySet()) {
   876                 Name name = names.fromString(entry.getKey());
   947                 Name name = names.fromString(entry.getKey());
   877                 JavaFileObject file = entry.getValue();
   948                 JavaFileObject file = entry.getValue();
   878                 if (file.getKind() != JavaFileObject.Kind.CLASS)
   949                 if (file.getKind() != JavaFileObject.Kind.CLASS)
   879                     throw new AssertionError(file);
   950                     throw new AssertionError(file);
   880                 ClassSymbol cs;
   951                 ClassSymbol cs;
   898             compiler.enterTrees(roots);
   969             compiler.enterTrees(roots);
   899         }
   970         }
   900 
   971 
   901         /** Run a processing round. */
   972         /** Run a processing round. */
   902         void run(boolean lastRound, boolean errorStatus) {
   973         void run(boolean lastRound, boolean errorStatus) {
   903 //            assert lastRound
   974             printRoundInfo(lastRound);
   904 //                ? (topLevelClasses.size() == 0 && annotationsPresent.size() == 0)
       
   905 //                : (errorStatus == false);
       
   906 //
       
   907 //            printRoundInfo(topLevelClasses, annotationsPresent, lastRound);
       
   908 
   975 
   909             TaskListener taskListener = context.get(TaskListener.class);
   976             TaskListener taskListener = context.get(TaskListener.class);
   910             if (taskListener != null)
   977             if (taskListener != null)
   911                 taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
   978                 taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
   912 
   979 
   913             try {
   980             try {
   914                 if (lastRound) {
   981                 if (lastRound) {
   915                     printRoundInfo(List.<ClassSymbol>nil(), Collections.<TypeElement>emptySet(), lastRound);
       
   916                     filer.setLastRound(true);
   982                     filer.setLastRound(true);
   917                     Set<Element> emptyRootElements = Collections.emptySet(); // immutable
   983                     Set<Element> emptyRootElements = Collections.emptySet(); // immutable
   918                     RoundEnvironment renv = new JavacRoundEnvironment(true,
   984                     RoundEnvironment renv = new JavacRoundEnvironment(true,
   919                             errorStatus,
   985                             errorStatus,
   920                             emptyRootElements,
   986                             emptyRootElements,
   921                             JavacProcessingEnvironment.this);
   987                             JavacProcessingEnvironment.this);
   922                     discoveredProcs.iterator().runContributingProcs(renv);
   988                     discoveredProcs.iterator().runContributingProcs(renv);
   923                 } else {
   989                 } else {
   924                     printRoundInfo(topLevelClasses, annotationsPresent, lastRound);
       
   925                     discoverAndRunProcs(context, annotationsPresent, topLevelClasses, packageInfoFiles);
   990                     discoverAndRunProcs(context, annotationsPresent, topLevelClasses, packageInfoFiles);
   926                 }
   991                 }
   927             } finally {
   992             } finally {
   928                 if (taskListener != null)
   993                 if (taskListener != null)
   929                     taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
   994                     taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
   930             }
   995             }
   931         }
   996         }
   932 
   997 
   933         /** Update the processing state for the current context. */
   998         /** Update the processing state for the current context. */
   934         // Question: should this not be part of next()?
   999         private void updateProcessingState() {
   935         // Note: Calling it from next() breaks some tests. There is an issue
       
   936         // whether the annotationComputer is using elementUtils with the
       
   937         // correct context.
       
   938         void updateProcessingState() {
       
   939             filer.newRound(context);
  1000             filer.newRound(context);
   940             messager.newRound(context);
  1001             messager.newRound(context);
   941 
  1002 
   942             elementUtils.setContext(context);
  1003             elementUtils.setContext(context);
   943             typeUtils.setContext(context);
  1004             typeUtils.setContext(context);
   944         }
  1005         }
   945 
  1006 
   946         /** Print info about this round. */
  1007         /** Print info about this round. */
   947         private void printRoundInfo(List<ClassSymbol> topLevelClasses,
  1008         private void printRoundInfo(boolean lastRound) {
   948                 Set<TypeElement> annotationsPresent,
       
   949                 boolean lastRound) {
       
   950             if (printRounds || verbose) {
  1009             if (printRounds || verbose) {
       
  1010                 List<ClassSymbol> tlc = lastRound ? List.<ClassSymbol>nil() : topLevelClasses;
       
  1011                 Set<TypeElement> ap = lastRound ? Collections.<TypeElement>emptySet() : annotationsPresent;
   951                 log.printNoteLines("x.print.rounds",
  1012                 log.printNoteLines("x.print.rounds",
   952                         (!lastRound ? number : number + 1),
  1013                         number,
   953                         "{" + topLevelClasses.toString(", ") + "}",
  1014                         "{" + tlc.toString(", ") + "}",
   954                         annotationsPresent,
  1015                         ap,
   955                         lastRound);
  1016                         lastRound);
   956             }
  1017             }
   957         }
  1018         }
   958 
  1019 
   959         /** Get the context for the next round of processing.
  1020         /** Get the context for the next round of processing.
   960          * Important values are propogated from round to round;
  1021          * Important values are propogated from round to round;
   961          * other values are implicitly reset.
  1022          * other values are implicitly reset.
   962          */
  1023          */
   963         private Context contextForNextRound() {
  1024         private Context nextContext() {
   964             Context next = new Context();
  1025             Context next = new Context();
   965 
  1026 
   966             Options options = Options.instance(context);
  1027             Options options = Options.instance(context);
   967             assert options != null;
  1028             assert options != null;
   968             next.put(Options.optionsKey, options);
  1029             next.put(Options.optionsKey, options);
  1023                                      List<JCCompilationUnit> roots,
  1084                                      List<JCCompilationUnit> roots,
  1024                                      List<ClassSymbol> classSymbols,
  1085                                      List<ClassSymbol> classSymbols,
  1025                                      Iterable<? extends PackageSymbol> pckSymbols)
  1086                                      Iterable<? extends PackageSymbol> pckSymbols)
  1026         throws IOException {
  1087         throws IOException {
  1027 
  1088 
       
  1089         TaskListener taskListener = context.get(TaskListener.class);
  1028         log = Log.instance(context);
  1090         log = Log.instance(context);
  1029 
       
  1030         Round round = new Round(context, 1);
       
  1031         round.compiler.todo.clear(); // free the compiler's resources
       
  1032 
       
  1033         // The reverse() in the following line is to maintain behavioural
       
  1034         // compatibility with the previous revision of the code. Strictly speaking,
       
  1035         // it should not be necessary, but a javah golden file test fails without it.
       
  1036         round.topLevelClasses =
       
  1037                 getTopLevelClasses(roots).prependList(classSymbols.reverse());
       
  1038 
       
  1039         round.packageInfoFiles = getPackageInfoFiles(roots);
       
  1040 
  1091 
  1041         Set<PackageSymbol> specifiedPackages = new LinkedHashSet<PackageSymbol>();
  1092         Set<PackageSymbol> specifiedPackages = new LinkedHashSet<PackageSymbol>();
  1042         for (PackageSymbol psym : pckSymbols)
  1093         for (PackageSymbol psym : pckSymbols)
  1043             specifiedPackages.add(psym);
  1094             specifiedPackages.add(psym);
  1044         this.specifiedPackages = Collections.unmodifiableSet(specifiedPackages);
  1095         this.specifiedPackages = Collections.unmodifiableSet(specifiedPackages);
  1045 
  1096 
  1046         ComputeAnnotationSet annotationComputer = new ComputeAnnotationSet(elementUtils);
  1097         Round round = new Round(context, roots, classSymbols);
  1047         round.findAnnotationsPresent(annotationComputer);
  1098 
  1048 
  1099         boolean errorStatus;
  1049         boolean errorStatus = false;
  1100         boolean moreToDo;
  1050 
  1101         do {
  1051         runAround:
  1102             // Run processors for round n
  1052         while (true) {
  1103             round.run(false, false);
  1053             if ((fatalErrors && round.errorCount() != 0)
  1104 
  1054                     || (werror && round.warningCount() != 0)) {
  1105             // Processors for round n have run to completion.
       
  1106             // Check for errors and whether there is more work to do.
       
  1107             errorStatus = round.unrecoverableError();
       
  1108             moreToDo = moreToDo();
       
  1109 
       
  1110             // Set up next round.
       
  1111             // Copy mutable collections returned from filer.
       
  1112             round = round.next(
       
  1113                     new LinkedHashSet<JavaFileObject>(filer.getGeneratedSourceFileObjects()),
       
  1114                     new LinkedHashMap<String,JavaFileObject>(filer.getGeneratedClasses()));
       
  1115 
       
  1116              // Check for errors during setup.
       
  1117             if (round.unrecoverableError())
  1055                 errorStatus = true;
  1118                 errorStatus = true;
  1056                 break runAround;
  1119 
  1057             }
  1120         } while (moreToDo && !errorStatus);
  1058 
       
  1059             round.run(false, false);
       
  1060 
       
  1061             /*
       
  1062              * Processors for round n have run to completion.  Prepare
       
  1063              * for round (n+1) by checked for errors raised by
       
  1064              * annotation processors and then checking for syntax
       
  1065              * errors on any generated source files.
       
  1066              */
       
  1067             if (messager.errorRaised()) {
       
  1068                 errorStatus = true;
       
  1069                 break runAround;
       
  1070             }
       
  1071 
       
  1072             if (!moreToDo())
       
  1073                 break runAround; // No new files
       
  1074 
       
  1075             round = round.next();
       
  1076 
       
  1077             List<JCCompilationUnit> parsedFiles = round.parseNewSourceFiles();
       
  1078             roots = cleanTrees(roots).appendList(parsedFiles);
       
  1079 
       
  1080             // Check for errors after parsing
       
  1081             if (round.unrecoverableError()) {
       
  1082                 errorStatus = true;
       
  1083                 break runAround;
       
  1084             }
       
  1085 
       
  1086             List<ClassSymbol> newClasses = round.enterNewClassFiles();
       
  1087             round.enterTrees(roots);
       
  1088 
       
  1089             round.topLevelClasses = join(
       
  1090                     getTopLevelClasses(parsedFiles),
       
  1091                     getTopLevelClassesFromClasses(newClasses));
       
  1092 
       
  1093             round.packageInfoFiles = join(
       
  1094                     getPackageInfoFiles(parsedFiles),
       
  1095                     getPackageInfoFilesFromClasses(newClasses));
       
  1096 
       
  1097             round.findAnnotationsPresent(annotationComputer);
       
  1098             round.updateProcessingState();
       
  1099         }
       
  1100 
  1121 
  1101         // run last round
  1122         // run last round
  1102         round.run(true, errorStatus);
  1123         round.run(true, errorStatus);
  1103 
  1124 
  1104         // Add any sources generated during the last round to the set
       
  1105         // of files to be compiled.
       
  1106         if (moreToDo()) {
       
  1107             List<JCCompilationUnit> parsedFiles = round.parseNewSourceFiles();
       
  1108             roots = cleanTrees(roots).appendList(parsedFiles);
       
  1109         }
       
  1110 
       
  1111         // Set error status for any files compiled and generated in
       
  1112         // the last round
       
  1113         if (round.unrecoverableError() || (werror && round.warningCount() != 0))
       
  1114             errorStatus = true;
       
  1115 
       
  1116         round = round.next();
       
  1117 
       
  1118         filer.warnIfUnclosedFiles();
  1125         filer.warnIfUnclosedFiles();
  1119         warnIfUnmatchedOptions();
  1126         warnIfUnmatchedOptions();
  1120 
  1127 
  1121        /*
  1128         /*
  1122         * If an annotation processor raises an error in a round,
  1129          * If an annotation processor raises an error in a round,
  1123         * that round runs to completion and one last round occurs.
  1130          * that round runs to completion and one last round occurs.
  1124         * The last round may also occur because no more source or
  1131          * The last round may also occur because no more source or
  1125         * class files have been generated.  Therefore, if an error
  1132          * class files have been generated.  Therefore, if an error
  1126         * was raised on either of the last *two* rounds, the compile
  1133          * was raised on either of the last *two* rounds, the compile
  1127         * should exit with a nonzero exit code.  The current value of
  1134          * should exit with a nonzero exit code.  The current value of
  1128         * errorStatus holds whether or not an error was raised on the
  1135          * errorStatus holds whether or not an error was raised on the
  1129         * second to last round; errorRaised() gives the error status
  1136          * second to last round; errorRaised() gives the error status
  1130         * of the last round.
  1137          * of the last round.
  1131         */
  1138          */
  1132         errorStatus = errorStatus || messager.errorRaised();
  1139         if (messager.errorRaised()
       
  1140                 || werror && round.warningCount() > 0 && round.errorCount() > 0)
       
  1141             errorStatus = true;
       
  1142 
       
  1143         Set<JavaFileObject> newSourceFiles =
       
  1144                 new LinkedHashSet<JavaFileObject>(filer.getGeneratedSourceFileObjects());
       
  1145         roots = cleanTrees(round.roots);
       
  1146 
       
  1147         JavaCompiler compiler = round.finalCompiler(errorStatus);
       
  1148 
       
  1149         if (newSourceFiles.size() > 0)
       
  1150             roots = roots.appendList(compiler.parseFiles(newSourceFiles));
       
  1151 
       
  1152         errorStatus = errorStatus || (compiler.errorCount() > 0);
  1133 
  1153 
  1134         // Free resources
  1154         // Free resources
  1135         this.close();
  1155         this.close();
  1136 
  1156 
  1137         TaskListener taskListener = this.context.get(TaskListener.class);
       
  1138         if (taskListener != null)
  1157         if (taskListener != null)
  1139             taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING));
  1158             taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING));
  1140 
  1159 
  1141         JavaCompiler compiler;
       
  1142 
       
  1143         if (errorStatus) {
  1160         if (errorStatus) {
  1144             compiler = round.compiler;
       
  1145             compiler.log.nwarnings += messager.warningCount();
       
  1146             compiler.log.nerrors += messager.errorCount();
       
  1147             if (compiler.errorCount() == 0)
  1161             if (compiler.errorCount() == 0)
  1148                 compiler.log.nerrors++;
  1162                 compiler.log.nerrors++;
  1149         } else if (procOnly && !foundTypeProcessors) {
  1163             return compiler;
  1150             compiler = round.compiler;
  1164         }
       
  1165 
       
  1166         if (procOnly && !foundTypeProcessors) {
  1151             compiler.todo.clear();
  1167             compiler.todo.clear();
  1152         } else { // Final compilation
  1168         } else {
  1153             round = round.next();
       
  1154             round.updateProcessingState();
       
  1155             compiler = round.compiler;
       
  1156             if (procOnly && foundTypeProcessors)
  1169             if (procOnly && foundTypeProcessors)
  1157                 compiler.shouldStopPolicy = CompileState.FLOW;
  1170                 compiler.shouldStopPolicy = CompileState.FLOW;
  1158 
  1171 
  1159             compiler.enterTrees(cleanTrees(roots));
  1172             compiler.enterTrees(roots);
  1160         }
  1173         }
  1161 
  1174 
  1162         return compiler;
  1175         return compiler;
  1163     }
  1176     }
  1164 
  1177 
  1183     private List<ClassSymbol> getTopLevelClasses(List<? extends JCCompilationUnit> units) {
  1196     private List<ClassSymbol> getTopLevelClasses(List<? extends JCCompilationUnit> units) {
  1184         List<ClassSymbol> classes = List.nil();
  1197         List<ClassSymbol> classes = List.nil();
  1185         for (JCCompilationUnit unit : units) {
  1198         for (JCCompilationUnit unit : units) {
  1186             for (JCTree node : unit.defs) {
  1199             for (JCTree node : unit.defs) {
  1187                 if (node.getTag() == JCTree.CLASSDEF) {
  1200                 if (node.getTag() == JCTree.CLASSDEF) {
  1188                     classes = classes.prepend(((JCClassDecl) node).sym);
  1201                     ClassSymbol sym = ((JCClassDecl) node).sym;
       
  1202                     assert sym != null;
       
  1203                     classes = classes.prepend(sym);
  1189                 }
  1204                 }
  1190             }
  1205             }
  1191         }
  1206         }
  1192         return classes.reverse();
  1207         return classes.reverse();
  1193     }
  1208     }