src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java

changeset 620
2cf925ad67ab
parent 614
ed354a00f76b
child 623
6318230cdb82
equal deleted inserted replaced
619:8a5c98a695ae 620:2cf925ad67ab
66 import com.sun.tools.javac.tree.JCTree.*; 66 import com.sun.tools.javac.tree.JCTree.*;
67 import com.sun.tools.javac.util.Abort; 67 import com.sun.tools.javac.util.Abort;
68 import com.sun.tools.javac.util.Context; 68 import com.sun.tools.javac.util.Context;
69 import com.sun.tools.javac.util.Convert; 69 import com.sun.tools.javac.util.Convert;
70 import com.sun.tools.javac.util.List; 70 import com.sun.tools.javac.util.List;
71 import com.sun.tools.javac.util.ListBuffer;
72 import com.sun.tools.javac.util.Log; 71 import com.sun.tools.javac.util.Log;
73 import com.sun.tools.javac.util.JavacMessages; 72 import com.sun.tools.javac.util.JavacMessages;
74 import com.sun.tools.javac.util.Name; 73 import com.sun.tools.javac.util.Name;
75 import com.sun.tools.javac.util.Names; 74 import com.sun.tools.javac.util.Names;
76 import com.sun.tools.javac.util.Options; 75 import com.sun.tools.javac.util.Options;
757 // Don't scan enclosed elements of a package 756 // Don't scan enclosed elements of a package
758 return p; 757 return p;
759 } 758 }
760 759
761 @Override 760 @Override
762 public Set<TypeElement> scan(Element e, Set<TypeElement> p) { 761 public Set<TypeElement> scan(Element e, Set<TypeElement> p) {
763 for (AnnotationMirror annotationMirror : 762 for (AnnotationMirror annotationMirror :
764 elements.getAllAnnotationMirrors(e) ) { 763 elements.getAllAnnotationMirrors(e) ) {
765 Element e2 = annotationMirror.getAnnotationType().asElement(); 764 Element e2 = annotationMirror.getAnnotationType().asElement();
766 p.add((TypeElement) e2); 765 p.add((TypeElement) e2);
767 } 766 }
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 */
1121 } 1218 }
1122 } 1219 }
1123 return packages.reverse(); 1220 return packages.reverse();
1124 } 1221 }
1125 1222
1223 // avoid unchecked warning from use of varargs
1224 private static <T> List<T> join(List<T> list1, List<T> list2) {
1225 return list1.appendList(list2);
1226 }
1227
1126 private boolean isPkgInfo(JavaFileObject fo, JavaFileObject.Kind kind) { 1228 private boolean isPkgInfo(JavaFileObject fo, JavaFileObject.Kind kind) {
1127 return fo.isNameCompatible("package-info", kind); 1229 return fo.isNameCompatible("package-info", kind);
1128 } 1230 }
1129 1231
1130 private boolean isPkgInfo(ClassSymbol sym) { 1232 private boolean isPkgInfo(ClassSymbol sym) {
1131 return isPkgInfo(sym.classfile, JavaFileObject.Kind.CLASS) && (sym.packge().package_info == sym); 1233 return isPkgInfo(sym.classfile, JavaFileObject.Kind.CLASS) && (sym.packge().package_info == sym);
1132 }
1133
1134 private Context contextForNextRound(Context context, boolean shareNames)
1135 throws IOException
1136 {
1137 Context next = new Context();
1138
1139 Options options = Options.instance(context);
1140 assert options != null;
1141 next.put(Options.optionsKey, options);
1142
1143 PrintWriter out = context.get(Log.outKey);
1144 assert out != null;
1145 next.put(Log.outKey, out);
1146
1147 if (shareNames) {
1148 Names names = Names.instance(context);
1149 assert names != null;
1150 next.put(Names.namesKey, names);
1151 }
1152
1153 DiagnosticListener<?> dl = context.get(DiagnosticListener.class);
1154 if (dl != null)
1155 next.put(DiagnosticListener.class, dl);
1156
1157 TaskListener tl = context.get(TaskListener.class);
1158 if (tl != null)
1159 next.put(TaskListener.class, tl);
1160
1161 JavaFileManager jfm = context.get(JavaFileManager.class);
1162 assert jfm != null;
1163 next.put(JavaFileManager.class, jfm);
1164 if (jfm instanceof JavacFileManager) {
1165 ((JavacFileManager)jfm).setContext(next);
1166 }
1167
1168 Names names = Names.instance(context);
1169 assert names != null;
1170 next.put(Names.namesKey, names);
1171
1172 Keywords keywords = Keywords.instance(context);
1173 assert(keywords != null);
1174 next.put(Keywords.keywordsKey, keywords);
1175
1176 JavaCompiler oldCompiler = JavaCompiler.instance(context);
1177 JavaCompiler nextCompiler = JavaCompiler.instance(next);
1178 nextCompiler.initRound(oldCompiler);
1179
1180 JavacTaskImpl task = context.get(JavacTaskImpl.class);
1181 if (task != null) {
1182 next.put(JavacTaskImpl.class, task);
1183 task.updateContext(next);
1184 }
1185
1186 context.clear();
1187 return next;
1188 } 1234 }
1189 1235
1190 /* 1236 /*
1191 * Called retroactively to determine if a class loader was required, 1237 * Called retroactively to determine if a class loader was required,
1192 * after we have failed to create one. 1238 * after we have failed to create one.

mercurial