782 } catch (Throwable t) { |
781 } catch (Throwable t) { |
783 throw new AnnotationProcessingError(t); |
782 throw new AnnotationProcessingError(t); |
784 } |
783 } |
785 } |
784 } |
786 |
785 |
|
786 /** |
|
787 * Helper object for a single round of annotation processing. |
|
788 */ |
|
789 class Round { |
|
790 /** The round number. */ |
|
791 final int number; |
|
792 /** The context for the round. */ |
|
793 final Context context; |
|
794 /** The compiler for the round. */ |
|
795 final JavaCompiler compiler; |
|
796 /** The log for the round. */ |
|
797 final Log log; |
|
798 |
|
799 /** The set of annotations to be processed this round. */ |
|
800 Set<TypeElement> annotationsPresent; |
|
801 /** The set of top level classes to be processed this round. */ |
|
802 List<ClassSymbol> topLevelClasses; |
|
803 /** The set of package-info files to be processed this round. */ |
|
804 List<PackageSymbol> packageInfoFiles; |
|
805 |
|
806 /** Create a round. */ |
|
807 Round(Context context, int number) { |
|
808 this.context = context; |
|
809 this.number = number; |
|
810 compiler = JavaCompiler.instance(context); |
|
811 log = Log.instance(context); |
|
812 |
|
813 // the following is for the benefit of JavacProcessingEnvironment.getContext() |
|
814 JavacProcessingEnvironment.this.context = context; |
|
815 |
|
816 // the following will be populated as needed |
|
817 annotationsPresent = new LinkedHashSet<TypeElement>(); |
|
818 topLevelClasses = List.nil(); |
|
819 packageInfoFiles = List.nil(); |
|
820 } |
|
821 |
|
822 /** Create the next round to be used. */ |
|
823 Round next() { |
|
824 compiler.close(false); |
|
825 return new Round(contextForNextRound(), number + 1); |
|
826 } |
|
827 |
|
828 /** Return the number of errors found so far in this round. |
|
829 * This may include uncoverable errors, such as parse errors, |
|
830 * and transient errors, such as missing symbols. */ |
|
831 int errorCount() { |
|
832 return compiler.errorCount(); |
|
833 } |
|
834 |
|
835 /** Return the number of warnings found so far in this round. */ |
|
836 int warningCount() { |
|
837 return compiler.warningCount(); |
|
838 } |
|
839 |
|
840 /** Return whether or not an unrecoverable error has occurred. */ |
|
841 boolean unrecoverableError() { |
|
842 return log.unrecoverableError; |
|
843 } |
|
844 |
|
845 /** Find the set of annotations present in the set of top level |
|
846 * classes and package info files to be processed this round. */ |
|
847 void findAnnotationsPresent(ComputeAnnotationSet annotationComputer) { |
|
848 // Use annotation processing to compute the set of annotations present |
|
849 annotationsPresent = new LinkedHashSet<TypeElement>(); |
|
850 for (ClassSymbol classSym : topLevelClasses) |
|
851 annotationComputer.scan(classSym, annotationsPresent); |
|
852 for (PackageSymbol pkgSym : packageInfoFiles) |
|
853 annotationComputer.scan(pkgSym, annotationsPresent); |
|
854 } |
|
855 |
|
856 /** |
|
857 * Parse the latest set of generated source files created by the filer. |
|
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); |
|
872 Names names = Names.instance(context); |
|
873 List<ClassSymbol> list = List.nil(); |
|
874 |
|
875 for (Map.Entry<String,JavaFileObject> entry : filer.getGeneratedClasses().entrySet()) { |
|
876 Name name = names.fromString(entry.getKey()); |
|
877 JavaFileObject file = entry.getValue(); |
|
878 if (file.getKind() != JavaFileObject.Kind.CLASS) |
|
879 throw new AssertionError(file); |
|
880 ClassSymbol cs; |
|
881 if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) { |
|
882 Name packageName = Convert.packagePart(name); |
|
883 PackageSymbol p = reader.enterPackage(packageName); |
|
884 if (p.package_info == null) |
|
885 p.package_info = reader.enterClass(Convert.shortName(name), p); |
|
886 cs = p.package_info; |
|
887 if (cs.classfile == null) |
|
888 cs.classfile = file; |
|
889 } else |
|
890 cs = reader.enterClass(name, file); |
|
891 list = list.prepend(cs); |
|
892 } |
|
893 return list.reverse(); |
|
894 } |
|
895 |
|
896 /** Enter a set of syntax trees. */ |
|
897 void enterTrees(List<JCCompilationUnit> roots) { |
|
898 compiler.enterTrees(roots); |
|
899 } |
|
900 |
|
901 /** Run a processing round. */ |
|
902 void run(boolean lastRound, boolean errorStatus) { |
|
903 assert lastRound |
|
904 ? (topLevelClasses.size() == 0 && annotationsPresent.size() == 0) |
|
905 : (errorStatus == false); |
|
906 |
|
907 printRoundInfo(topLevelClasses, annotationsPresent, lastRound); |
|
908 |
|
909 TaskListener taskListener = context.get(TaskListener.class); |
|
910 if (taskListener != null) |
|
911 taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); |
|
912 |
|
913 try { |
|
914 if (lastRound) { |
|
915 filer.setLastRound(true); |
|
916 Set<Element> emptyRootElements = Collections.emptySet(); // immutable |
|
917 RoundEnvironment renv = new JavacRoundEnvironment(true, |
|
918 errorStatus, |
|
919 emptyRootElements, |
|
920 JavacProcessingEnvironment.this); |
|
921 discoveredProcs.iterator().runContributingProcs(renv); |
|
922 } else { |
|
923 discoverAndRunProcs(context, annotationsPresent, topLevelClasses, packageInfoFiles); |
|
924 } |
|
925 } finally { |
|
926 if (taskListener != null) |
|
927 taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); |
|
928 } |
|
929 } |
|
930 |
|
931 /** Update the processing state for the current context. */ |
|
932 // Question: should this not be part of next()? |
|
933 // Note: Calling it from next() breaks some tests. There is an issue |
|
934 // whether the annotationComputer is using elementUtils with the |
|
935 // correct context. |
|
936 void updateProcessingState() { |
|
937 filer.newRound(context); |
|
938 messager.newRound(context); |
|
939 |
|
940 elementUtils.setContext(context); |
|
941 typeUtils.setContext(context); |
|
942 } |
|
943 |
|
944 /** Print info about this round. */ |
|
945 private void printRoundInfo(List<ClassSymbol> topLevelClasses, |
|
946 Set<TypeElement> annotationsPresent, |
|
947 boolean lastRound) { |
|
948 if (printRounds || verbose) { |
|
949 log.printNoteLines("x.print.rounds", |
|
950 number, |
|
951 "{" + topLevelClasses.toString(", ") + "}", |
|
952 annotationsPresent, |
|
953 lastRound); |
|
954 } |
|
955 } |
|
956 |
|
957 /** Get the context for the next round of processing. |
|
958 * Important values are propogated from round to round; |
|
959 * other values are implicitly reset. |
|
960 */ |
|
961 private Context contextForNextRound() { |
|
962 Context next = new Context(); |
|
963 |
|
964 Options options = Options.instance(context); |
|
965 assert options != null; |
|
966 next.put(Options.optionsKey, options); |
|
967 |
|
968 PrintWriter out = context.get(Log.outKey); |
|
969 assert out != null; |
|
970 next.put(Log.outKey, out); |
|
971 |
|
972 final boolean shareNames = true; |
|
973 if (shareNames) { |
|
974 Names names = Names.instance(context); |
|
975 assert names != null; |
|
976 next.put(Names.namesKey, names); |
|
977 } |
|
978 |
|
979 DiagnosticListener<?> dl = context.get(DiagnosticListener.class); |
|
980 if (dl != null) |
|
981 next.put(DiagnosticListener.class, dl); |
|
982 |
|
983 TaskListener tl = context.get(TaskListener.class); |
|
984 if (tl != null) |
|
985 next.put(TaskListener.class, tl); |
|
986 |
|
987 JavaFileManager jfm = context.get(JavaFileManager.class); |
|
988 assert jfm != null; |
|
989 next.put(JavaFileManager.class, jfm); |
|
990 if (jfm instanceof JavacFileManager) { |
|
991 ((JavacFileManager)jfm).setContext(next); |
|
992 } |
|
993 |
|
994 Names names = Names.instance(context); |
|
995 assert names != null; |
|
996 next.put(Names.namesKey, names); |
|
997 |
|
998 Keywords keywords = Keywords.instance(context); |
|
999 assert(keywords != null); |
|
1000 next.put(Keywords.keywordsKey, keywords); |
|
1001 |
|
1002 JavaCompiler oldCompiler = JavaCompiler.instance(context); |
|
1003 JavaCompiler nextCompiler = JavaCompiler.instance(next); |
|
1004 nextCompiler.initRound(oldCompiler); |
|
1005 |
|
1006 JavacTaskImpl task = context.get(JavacTaskImpl.class); |
|
1007 if (task != null) { |
|
1008 next.put(JavacTaskImpl.class, task); |
|
1009 task.updateContext(next); |
|
1010 } |
|
1011 |
|
1012 context.clear(); |
|
1013 return next; |
|
1014 } |
|
1015 } |
|
1016 |
787 |
1017 |
788 // TODO: internal catch clauses?; catch and rethrow an annotation |
1018 // TODO: internal catch clauses?; catch and rethrow an annotation |
789 // processing error |
1019 // processing error |
790 public JavaCompiler doProcessing(Context context, |
1020 public JavaCompiler doProcessing(Context context, |
791 List<JCCompilationUnit> roots, |
1021 List<JCCompilationUnit> roots, |
792 List<ClassSymbol> classSymbols, |
1022 List<ClassSymbol> classSymbols, |
793 Iterable<? extends PackageSymbol> pckSymbols) |
1023 Iterable<? extends PackageSymbol> pckSymbols) |
794 throws IOException { |
1024 throws IOException { |
795 |
1025 |
796 log = Log.instance(context); |
1026 log = Log.instance(context); |
797 TaskListener taskListener = context.get(TaskListener.class); |
1027 |
798 |
1028 Round round = new Round(context, 1); |
799 JavaCompiler compiler = JavaCompiler.instance(context); |
1029 round.compiler.todo.clear(); // free the compiler's resources |
800 compiler.todo.clear(); // free the compiler's resources |
1030 |
801 |
1031 // The reverse() in the following line is to maintain behavioural |
802 int round = 0; |
1032 // compatibility with the previous revision of the code. Strictly speaking, |
803 |
1033 // it should not be necessary, but a javah golden file test fails without it. |
804 // List<JCAnnotation> annotationsPresentInSource = collector.findAnnotations(roots); |
1034 round.topLevelClasses = |
805 List<ClassSymbol> topLevelClasses = getTopLevelClasses(roots); |
1035 getTopLevelClasses(roots).prependList(classSymbols.reverse()); |
806 |
1036 |
807 for (ClassSymbol classSym : classSymbols) |
1037 round.packageInfoFiles = getPackageInfoFiles(roots); |
808 topLevelClasses = topLevelClasses.prepend(classSym); |
|
809 List<PackageSymbol> packageInfoFiles = |
|
810 getPackageInfoFiles(roots); |
|
811 |
1038 |
812 Set<PackageSymbol> specifiedPackages = new LinkedHashSet<PackageSymbol>(); |
1039 Set<PackageSymbol> specifiedPackages = new LinkedHashSet<PackageSymbol>(); |
813 for (PackageSymbol psym : pckSymbols) |
1040 for (PackageSymbol psym : pckSymbols) |
814 specifiedPackages.add(psym); |
1041 specifiedPackages.add(psym); |
815 this.specifiedPackages = Collections.unmodifiableSet(specifiedPackages); |
1042 this.specifiedPackages = Collections.unmodifiableSet(specifiedPackages); |
816 |
1043 |
817 // Use annotation processing to compute the set of annotations present |
|
818 Set<TypeElement> annotationsPresent = new LinkedHashSet<TypeElement>(); |
|
819 ComputeAnnotationSet annotationComputer = new ComputeAnnotationSet(elementUtils); |
1044 ComputeAnnotationSet annotationComputer = new ComputeAnnotationSet(elementUtils); |
820 for (ClassSymbol classSym : topLevelClasses) |
1045 round.findAnnotationsPresent(annotationComputer); |
821 annotationComputer.scan(classSym, annotationsPresent); |
1046 |
822 for (PackageSymbol pkgSym : packageInfoFiles) |
|
823 annotationComputer.scan(pkgSym, annotationsPresent); |
|
824 |
|
825 Context currentContext = context; |
|
826 |
|
827 int roundNumber = 0; |
|
828 boolean errorStatus = false; |
1047 boolean errorStatus = false; |
829 |
1048 |
830 runAround: |
1049 runAround: |
831 while(true) { |
1050 while (true) { |
832 if ((fatalErrors && compiler.errorCount() != 0) |
1051 if ((fatalErrors && round.errorCount() != 0) |
833 || (werror && compiler.warningCount() != 0)) { |
1052 || (werror && round.warningCount() != 0)) { |
834 errorStatus = true; |
1053 errorStatus = true; |
835 break runAround; |
1054 break runAround; |
836 } |
1055 } |
837 |
1056 |
838 this.context = currentContext; |
1057 round.run(false, false); |
839 roundNumber++; |
|
840 printRoundInfo(roundNumber, topLevelClasses, annotationsPresent, false); |
|
841 |
|
842 if (taskListener != null) |
|
843 taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); |
|
844 |
|
845 try { |
|
846 discoverAndRunProcs(currentContext, annotationsPresent, topLevelClasses, packageInfoFiles); |
|
847 } finally { |
|
848 if (taskListener != null) |
|
849 taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); |
|
850 } |
|
851 |
1058 |
852 /* |
1059 /* |
853 * Processors for round n have run to completion. Prepare |
1060 * Processors for round n have run to completion. Prepare |
854 * for round (n+1) by checked for errors raised by |
1061 * for round (n+1) by checked for errors raised by |
855 * annotation processors and then checking for syntax |
1062 * annotation processors and then checking for syntax |
856 * errors on any generated source files. |
1063 * errors on any generated source files. |
857 */ |
1064 */ |
858 if (messager.errorRaised()) { |
1065 if (messager.errorRaised()) { |
859 errorStatus = true; |
1066 errorStatus = true; |
860 break runAround; |
1067 break runAround; |
861 } else { |
1068 } |
862 if (moreToDo()) { |
1069 |
863 // annotationsPresentInSource = List.nil(); |
1070 if (!moreToDo()) |
864 annotationsPresent = new LinkedHashSet<TypeElement>(); |
1071 break runAround; // No new files |
865 topLevelClasses = List.nil(); |
1072 |
866 packageInfoFiles = List.nil(); |
1073 round = round.next(); |
867 |
1074 |
868 compiler.close(false); |
1075 List<JCCompilationUnit> parsedFiles = round.parseNewSourceFiles(); |
869 currentContext = contextForNextRound(currentContext, true); |
1076 roots = cleanTrees(roots).appendList(parsedFiles); |
870 |
1077 |
871 JavaFileManager fileManager = currentContext.get(JavaFileManager.class); |
1078 // Check for errors after parsing |
872 |
1079 if (round.unrecoverableError()) { |
873 compiler = JavaCompiler.instance(currentContext); |
1080 errorStatus = true; |
874 List<JCCompilationUnit> parsedFiles = sourcesToParsedFiles(compiler); |
1081 break runAround; |
875 roots = cleanTrees(roots).appendList(parsedFiles); |
1082 } |
876 |
1083 |
877 // Check for errors after parsing |
1084 List<ClassSymbol> newClasses = round.enterNewClassFiles(); |
878 if (log.unrecoverableError) { |
1085 round.enterTrees(roots); |
879 errorStatus = true; |
1086 |
880 break runAround; |
1087 round.topLevelClasses = join( |
881 } else { |
1088 getTopLevelClasses(parsedFiles), |
882 List<ClassSymbol> newClasses = enterNewClassFiles(currentContext); |
1089 getTopLevelClassesFromClasses(newClasses)); |
883 compiler.enterTrees(roots); |
1090 |
884 |
1091 round.packageInfoFiles = join( |
885 // annotationsPresentInSource = |
1092 getPackageInfoFiles(parsedFiles), |
886 // collector.findAnnotations(parsedFiles); |
1093 getPackageInfoFilesFromClasses(newClasses)); |
887 ListBuffer<ClassSymbol> tlc = new ListBuffer<ClassSymbol>(); |
1094 |
888 tlc.appendList(getTopLevelClasses(parsedFiles)); |
1095 round.findAnnotationsPresent(annotationComputer); |
889 tlc.appendList(getTopLevelClassesFromClasses(newClasses)); |
1096 round.updateProcessingState(); |
890 topLevelClasses = tlc.toList(); |
1097 } |
891 |
1098 |
892 ListBuffer<PackageSymbol> pif = new ListBuffer<PackageSymbol>(); |
1099 // run last round |
893 pif.appendList(getPackageInfoFiles(parsedFiles)); |
1100 round.run(true, errorStatus); |
894 pif.appendList(getPackageInfoFilesFromClasses(newClasses)); |
1101 |
895 packageInfoFiles = pif.toList(); |
1102 // Add any sources generated during the last round to the set |
896 |
1103 // of files to be compiled. |
897 annotationsPresent = new LinkedHashSet<TypeElement>(); |
1104 if (moreToDo()) { |
898 for (ClassSymbol classSym : topLevelClasses) |
1105 List<JCCompilationUnit> parsedFiles = round.parseNewSourceFiles(); |
899 annotationComputer.scan(classSym, annotationsPresent); |
1106 roots = cleanTrees(roots).appendList(parsedFiles); |
900 for (PackageSymbol pkgSym : packageInfoFiles) |
1107 } |
901 annotationComputer.scan(pkgSym, annotationsPresent); |
1108 |
902 |
|
903 updateProcessingState(currentContext, false); |
|
904 } |
|
905 } else |
|
906 break runAround; // No new files |
|
907 } |
|
908 } |
|
909 roots = runLastRound(roundNumber, errorStatus, compiler, roots, taskListener); |
|
910 // Set error status for any files compiled and generated in |
1109 // Set error status for any files compiled and generated in |
911 // the last round |
1110 // the last round |
912 if (log.unrecoverableError || (werror && compiler.warningCount() != 0)) |
1111 if (round.unrecoverableError() || (werror && round.warningCount() != 0)) |
913 errorStatus = true; |
1112 errorStatus = true; |
914 |
1113 |
915 compiler.close(false); |
1114 round = round.next(); |
916 currentContext = contextForNextRound(currentContext, true); |
1115 |
917 compiler = JavaCompiler.instance(currentContext); |
|
918 |
|
919 filer.newRound(currentContext, true); |
|
920 filer.warnIfUnclosedFiles(); |
1116 filer.warnIfUnclosedFiles(); |
921 warnIfUnmatchedOptions(); |
1117 warnIfUnmatchedOptions(); |
922 |
1118 |
923 /* |
1119 /* |
924 * If an annotation processor raises an error in a round, |
1120 * If an annotation processor raises an error in a round, |
931 * second to last round; errorRaised() gives the error status |
1127 * second to last round; errorRaised() gives the error status |
932 * of the last round. |
1128 * of the last round. |
933 */ |
1129 */ |
934 errorStatus = errorStatus || messager.errorRaised(); |
1130 errorStatus = errorStatus || messager.errorRaised(); |
935 |
1131 |
936 |
|
937 // Free resources |
1132 // Free resources |
938 this.close(); |
1133 this.close(); |
939 |
1134 |
|
1135 TaskListener taskListener = this.context.get(TaskListener.class); |
940 if (taskListener != null) |
1136 if (taskListener != null) |
941 taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING)); |
1137 taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING)); |
942 |
1138 |
|
1139 JavaCompiler compiler; |
|
1140 |
943 if (errorStatus) { |
1141 if (errorStatus) { |
|
1142 compiler = round.compiler; |
944 compiler.log.nwarnings += messager.warningCount(); |
1143 compiler.log.nwarnings += messager.warningCount(); |
945 compiler.log.nerrors += messager.errorCount(); |
1144 compiler.log.nerrors += messager.errorCount(); |
946 if (compiler.errorCount() == 0) |
1145 if (compiler.errorCount() == 0) |
947 compiler.log.nerrors++; |
1146 compiler.log.nerrors++; |
948 } else if (procOnly && !foundTypeProcessors) { |
1147 } else if (procOnly && !foundTypeProcessors) { |
|
1148 compiler = round.compiler; |
949 compiler.todo.clear(); |
1149 compiler.todo.clear(); |
950 } else { // Final compilation |
1150 } else { // Final compilation |
951 compiler.close(false); |
1151 round = round.next(); |
952 currentContext = contextForNextRound(currentContext, true); |
1152 round.updateProcessingState(); |
953 this.context = currentContext; |
1153 compiler = round.compiler; |
954 updateProcessingState(currentContext, true); |
|
955 compiler = JavaCompiler.instance(currentContext); |
|
956 if (procOnly && foundTypeProcessors) |
1154 if (procOnly && foundTypeProcessors) |
957 compiler.shouldStopPolicy = CompileState.FLOW; |
1155 compiler.shouldStopPolicy = CompileState.FLOW; |
958 |
1156 |
959 if (true) { |
1157 compiler.enterTrees(cleanTrees(roots)); |
960 compiler.enterTrees(cleanTrees(roots)); |
|
961 } else { |
|
962 List<JavaFileObject> fileObjects = List.nil(); |
|
963 for (JCCompilationUnit unit : roots) |
|
964 fileObjects = fileObjects.prepend(unit.getSourceFile()); |
|
965 roots = null; |
|
966 compiler.enterTrees(compiler.parseFiles(fileObjects.reverse())); |
|
967 } |
|
968 } |
1158 } |
969 |
1159 |
970 return compiler; |
1160 return compiler; |
971 } |
|
972 |
|
973 private List<JCCompilationUnit> sourcesToParsedFiles(JavaCompiler compiler) |
|
974 throws IOException { |
|
975 List<JavaFileObject> fileObjects = List.nil(); |
|
976 for (JavaFileObject jfo : filer.getGeneratedSourceFileObjects() ) { |
|
977 fileObjects = fileObjects.prepend(jfo); |
|
978 } |
|
979 |
|
980 return compiler.parseFiles(fileObjects); |
|
981 } |
|
982 |
|
983 // Call the last round of annotation processing |
|
984 private List<JCCompilationUnit> runLastRound(int roundNumber, |
|
985 boolean errorStatus, |
|
986 JavaCompiler compiler, |
|
987 List<JCCompilationUnit> roots, |
|
988 TaskListener taskListener) throws IOException { |
|
989 roundNumber++; |
|
990 List<ClassSymbol> noTopLevelClasses = List.nil(); |
|
991 Set<TypeElement> noAnnotations = Collections.emptySet(); |
|
992 printRoundInfo(roundNumber, noTopLevelClasses, noAnnotations, true); |
|
993 |
|
994 Set<Element> emptyRootElements = Collections.emptySet(); // immutable |
|
995 RoundEnvironment renv = new JavacRoundEnvironment(true, |
|
996 errorStatus, |
|
997 emptyRootElements, |
|
998 JavacProcessingEnvironment.this); |
|
999 if (taskListener != null) |
|
1000 taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); |
|
1001 |
|
1002 try { |
|
1003 discoveredProcs.iterator().runContributingProcs(renv); |
|
1004 } finally { |
|
1005 if (taskListener != null) |
|
1006 taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); |
|
1007 } |
|
1008 |
|
1009 // Add any sources generated during the last round to the set |
|
1010 // of files to be compiled. |
|
1011 if (moreToDo()) { |
|
1012 List<JCCompilationUnit> parsedFiles = sourcesToParsedFiles(compiler); |
|
1013 roots = cleanTrees(roots).appendList(parsedFiles); |
|
1014 } |
|
1015 |
|
1016 return roots; |
|
1017 } |
|
1018 |
|
1019 private void updateProcessingState(Context currentContext, boolean lastRound) { |
|
1020 filer.newRound(currentContext, lastRound); |
|
1021 messager.newRound(currentContext); |
|
1022 |
|
1023 elementUtils.setContext(currentContext); |
|
1024 typeUtils.setContext(currentContext); |
|
1025 } |
1161 } |
1026 |
1162 |
1027 private void warnIfUnmatchedOptions() { |
1163 private void warnIfUnmatchedOptions() { |
1028 if (!unmatchedProcessorOptions.isEmpty()) { |
1164 if (!unmatchedProcessorOptions.isEmpty()) { |
1029 log.warning("proc.unmatched.processor.options", unmatchedProcessorOptions.toString()); |
1165 log.warning("proc.unmatched.processor.options", unmatchedProcessorOptions.toString()); |
1030 } |
1166 } |
1031 } |
|
1032 |
|
1033 private void printRoundInfo(int roundNumber, |
|
1034 List<ClassSymbol> topLevelClasses, |
|
1035 Set<TypeElement> annotationsPresent, |
|
1036 boolean lastRound) { |
|
1037 if (printRounds || verbose) { |
|
1038 log.printNoteLines("x.print.rounds", |
|
1039 roundNumber, |
|
1040 "{" + topLevelClasses.toString(", ") + "}", |
|
1041 annotationsPresent, |
|
1042 lastRound); |
|
1043 } |
|
1044 } |
|
1045 |
|
1046 private List<ClassSymbol> enterNewClassFiles(Context currentContext) { |
|
1047 ClassReader reader = ClassReader.instance(currentContext); |
|
1048 Names names = Names.instance(currentContext); |
|
1049 List<ClassSymbol> list = List.nil(); |
|
1050 |
|
1051 for (Map.Entry<String,JavaFileObject> entry : filer.getGeneratedClasses().entrySet()) { |
|
1052 Name name = names.fromString(entry.getKey()); |
|
1053 JavaFileObject file = entry.getValue(); |
|
1054 if (file.getKind() != JavaFileObject.Kind.CLASS) |
|
1055 throw new AssertionError(file); |
|
1056 ClassSymbol cs; |
|
1057 if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) { |
|
1058 Name packageName = Convert.packagePart(name); |
|
1059 PackageSymbol p = reader.enterPackage(packageName); |
|
1060 if (p.package_info == null) |
|
1061 p.package_info = reader.enterClass(Convert.shortName(name), p); |
|
1062 cs = p.package_info; |
|
1063 if (cs.classfile == null) |
|
1064 cs.classfile = file; |
|
1065 } else |
|
1066 cs = reader.enterClass(name, file); |
|
1067 list = list.prepend(cs); |
|
1068 } |
|
1069 return list.reverse(); |
|
1070 } |
1167 } |
1071 |
1168 |
1072 /** |
1169 /** |
1073 * Free resources related to annotation processing. |
1170 * Free resources related to annotation processing. |
1074 */ |
1171 */ |