36 |
36 |
37 import javax.annotation.processing.*; |
37 import javax.annotation.processing.*; |
38 import javax.lang.model.SourceVersion; |
38 import javax.lang.model.SourceVersion; |
39 import javax.lang.model.element.*; |
39 import javax.lang.model.element.*; |
40 import javax.lang.model.util.*; |
40 import javax.lang.model.util.*; |
41 import javax.tools.DiagnosticListener; |
|
42 import javax.tools.JavaFileManager; |
41 import javax.tools.JavaFileManager; |
43 import javax.tools.JavaFileObject; |
42 import javax.tools.JavaFileObject; |
44 import javax.tools.StandardJavaFileManager; |
43 import javax.tools.StandardJavaFileManager; |
45 import static javax.tools.StandardLocation.*; |
44 import static javax.tools.StandardLocation.*; |
46 |
45 |
47 import com.sun.source.util.JavacTask; |
|
48 import com.sun.source.util.TaskEvent; |
46 import com.sun.source.util.TaskEvent; |
49 import com.sun.tools.javac.api.BasicJavacTask; |
|
50 import com.sun.tools.javac.api.JavacTrees; |
|
51 import com.sun.tools.javac.api.MultiTaskListener; |
47 import com.sun.tools.javac.api.MultiTaskListener; |
52 import com.sun.tools.javac.code.*; |
48 import com.sun.tools.javac.code.*; |
53 import com.sun.tools.javac.code.Symbol.*; |
49 import com.sun.tools.javac.code.Symbol.*; |
54 import com.sun.tools.javac.file.FSInfo; |
50 import com.sun.tools.javac.code.Type.ClassType; |
|
51 import com.sun.tools.javac.code.Types; |
|
52 import com.sun.tools.javac.comp.AttrContext; |
|
53 import com.sun.tools.javac.comp.Check; |
|
54 import com.sun.tools.javac.comp.Enter; |
|
55 import com.sun.tools.javac.comp.Env; |
55 import com.sun.tools.javac.file.JavacFileManager; |
56 import com.sun.tools.javac.file.JavacFileManager; |
56 import com.sun.tools.javac.jvm.*; |
57 import com.sun.tools.javac.jvm.*; |
57 import com.sun.tools.javac.jvm.ClassReader.BadClassFile; |
58 import com.sun.tools.javac.jvm.ClassReader.BadClassFile; |
58 import com.sun.tools.javac.main.JavaCompiler; |
59 import com.sun.tools.javac.main.JavaCompiler; |
59 import com.sun.tools.javac.model.JavacElements; |
60 import com.sun.tools.javac.model.JavacElements; |
60 import com.sun.tools.javac.model.JavacTypes; |
61 import com.sun.tools.javac.model.JavacTypes; |
61 import com.sun.tools.javac.parser.*; |
|
62 import com.sun.tools.javac.tree.*; |
62 import com.sun.tools.javac.tree.*; |
63 import com.sun.tools.javac.tree.JCTree.*; |
63 import com.sun.tools.javac.tree.JCTree.*; |
64 import com.sun.tools.javac.util.Abort; |
64 import com.sun.tools.javac.util.Abort; |
65 import com.sun.tools.javac.util.Assert; |
65 import com.sun.tools.javac.util.Assert; |
66 import com.sun.tools.javac.util.ClientCodeException; |
66 import com.sun.tools.javac.util.ClientCodeException; |
171 options = Options.instance(context); |
178 options = Options.instance(context); |
172 printProcessorInfo = options.isSet(XPRINTPROCESSORINFO); |
179 printProcessorInfo = options.isSet(XPRINTPROCESSORINFO); |
173 printRounds = options.isSet(XPRINTROUNDS); |
180 printRounds = options.isSet(XPRINTROUNDS); |
174 verbose = options.isSet(VERBOSE); |
181 verbose = options.isSet(VERBOSE); |
175 lint = Lint.instance(context).isEnabled(PROCESSING); |
182 lint = Lint.instance(context).isEnabled(PROCESSING); |
|
183 compiler = JavaCompiler.instance(context); |
176 if (options.isSet(PROC, "only") || options.isSet(XPRINT)) { |
184 if (options.isSet(PROC, "only") || options.isSet(XPRINT)) { |
177 JavaCompiler compiler = JavaCompiler.instance(context); |
|
178 compiler.shouldStopPolicyIfNoError = CompileState.PROCESS; |
185 compiler.shouldStopPolicyIfNoError = CompileState.PROCESS; |
179 } |
186 } |
180 fatalErrors = options.isSet("fatalEnterError"); |
187 fatalErrors = options.isSet("fatalEnterError"); |
181 showResolveErrors = options.isSet("showResolveErrors"); |
188 showResolveErrors = options.isSet("showResolveErrors"); |
182 werror = options.isSet(WERROR); |
189 werror = options.isSet(WERROR); |
186 // in case processors use them. |
193 // in case processors use them. |
187 filer = new JavacFiler(context); |
194 filer = new JavacFiler(context); |
188 messager = new JavacMessager(context, this); |
195 messager = new JavacMessager(context, this); |
189 elementUtils = JavacElements.instance(context); |
196 elementUtils = JavacElements.instance(context); |
190 typeUtils = JavacTypes.instance(context); |
197 typeUtils = JavacTypes.instance(context); |
191 processorOptions = initProcessorOptions(context); |
198 types = Types.instance(context); |
|
199 processorOptions = initProcessorOptions(); |
192 unmatchedProcessorOptions = initUnmatchedProcessorOptions(); |
200 unmatchedProcessorOptions = initUnmatchedProcessorOptions(); |
193 messages = JavacMessages.instance(context); |
201 messages = JavacMessages.instance(context); |
194 taskListener = MultiTaskListener.instance(context); |
202 taskListener = MultiTaskListener.instance(context); |
|
203 symtab = Symtab.instance(context); |
|
204 names = Names.instance(context); |
|
205 enter = Enter.instance(context); |
|
206 initialCompleter = ClassReader.instance(context).getCompleter(); |
|
207 chk = Check.instance(context); |
195 initProcessorClassLoader(); |
208 initProcessorClassLoader(); |
196 } |
209 } |
197 |
210 |
198 public void setProcessors(Iterable<? extends Processor> processors) { |
211 public void setProcessors(Iterable<? extends Processor> processors) { |
199 Assert.checkNull(discoveredProcs); |
212 Assert.checkNull(discoveredProcs); |
200 initProcessorIterator(context, processors); |
213 initProcessorIterator(processors); |
201 } |
214 } |
202 |
215 |
203 private Set<String> initPlatformAnnotations() { |
216 private Set<String> initPlatformAnnotations() { |
204 Set<String> platformAnnotations = new HashSet<>(); |
217 Set<String> platformAnnotations = new HashSet<>(); |
205 platformAnnotations.add("java.lang.Deprecated"); |
218 platformAnnotations.add("java.lang.Deprecated"); |
219 processorClassLoader = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH) |
232 processorClassLoader = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH) |
220 ? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH) |
233 ? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH) |
221 : fileManager.getClassLoader(CLASS_PATH); |
234 : fileManager.getClassLoader(CLASS_PATH); |
222 |
235 |
223 if (processorClassLoader != null && processorClassLoader instanceof Closeable) { |
236 if (processorClassLoader != null && processorClassLoader instanceof Closeable) { |
224 JavaCompiler compiler = JavaCompiler.instance(context); |
|
225 compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader); |
237 compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader); |
226 } |
238 } |
227 } catch (SecurityException e) { |
239 } catch (SecurityException e) { |
228 processorClassLoaderException = e; |
240 processorClassLoaderException = e; |
229 } |
241 } |
230 } |
242 } |
231 |
243 |
232 private void initProcessorIterator(Context context, Iterable<? extends Processor> processors) { |
244 private void initProcessorIterator(Iterable<? extends Processor> processors) { |
233 Log log = Log.instance(context); |
|
234 Iterator<? extends Processor> processorIterator; |
245 Iterator<? extends Processor> processorIterator; |
235 |
246 |
236 if (options.isSet(XPRINT)) { |
247 if (options.isSet(XPRINT)) { |
237 try { |
248 try { |
238 Processor processor = PrintingProcessor.class.newInstance(); |
249 Processor processor = PrintingProcessor.class.newInstance(); |
810 * Helper object for a single round of annotation processing. |
818 * Helper object for a single round of annotation processing. |
811 */ |
819 */ |
812 class Round { |
820 class Round { |
813 /** The round number. */ |
821 /** The round number. */ |
814 final int number; |
822 final int number; |
815 /** The context for the round. */ |
|
816 final Context context; |
|
817 /** The compiler for the round. */ |
|
818 final JavaCompiler compiler; |
|
819 /** The log for the round. */ |
|
820 final Log log; |
|
821 /** The diagnostic handler for the round. */ |
823 /** The diagnostic handler for the round. */ |
822 final Log.DeferredDiagnosticHandler deferredDiagnosticHandler; |
824 final Log.DeferredDiagnosticHandler deferredDiagnosticHandler; |
823 |
825 |
824 /** The ASTs to be compiled. */ |
826 /** The ASTs to be compiled. */ |
825 List<JCCompilationUnit> roots; |
827 List<JCCompilationUnit> roots; |
|
828 /** The trees that need to be cleaned - includes roots and implicitly parsed trees. */ |
|
829 Set<JCCompilationUnit> treesToClean; |
826 /** The classes to be compiler that have were generated. */ |
830 /** The classes to be compiler that have were generated. */ |
827 Map<String, JavaFileObject> genClassFiles; |
831 Map<String, JavaFileObject> genClassFiles; |
828 |
832 |
829 /** The set of annotations to be processed this round. */ |
833 /** The set of annotations to be processed this round. */ |
830 Set<TypeElement> annotationsPresent; |
834 Set<TypeElement> annotationsPresent; |
832 List<ClassSymbol> topLevelClasses; |
836 List<ClassSymbol> topLevelClasses; |
833 /** The set of package-info files to be processed this round. */ |
837 /** The set of package-info files to be processed this round. */ |
834 List<PackageSymbol> packageInfoFiles; |
838 List<PackageSymbol> packageInfoFiles; |
835 |
839 |
836 /** Create a round (common code). */ |
840 /** Create a round (common code). */ |
837 private Round(Context context, int number, int priorErrors, int priorWarnings, |
841 private Round(int number, Set<JCCompilationUnit> treesToClean, |
838 Log.DeferredDiagnosticHandler deferredDiagnosticHandler) { |
842 Log.DeferredDiagnosticHandler deferredDiagnosticHandler) { |
839 this.context = context; |
|
840 this.number = number; |
843 this.number = number; |
841 |
844 |
842 compiler = JavaCompiler.instance(context); |
|
843 log = Log.instance(context); |
|
844 log.nerrors = priorErrors; |
|
845 log.nwarnings = priorWarnings; |
|
846 if (number == 1) { |
845 if (number == 1) { |
847 Assert.checkNonNull(deferredDiagnosticHandler); |
846 Assert.checkNonNull(deferredDiagnosticHandler); |
848 this.deferredDiagnosticHandler = deferredDiagnosticHandler; |
847 this.deferredDiagnosticHandler = deferredDiagnosticHandler; |
849 } else { |
848 } else { |
850 this.deferredDiagnosticHandler = new Log.DeferredDiagnosticHandler(log); |
849 this.deferredDiagnosticHandler = new Log.DeferredDiagnosticHandler(log); |
851 } |
850 compiler.setDeferredDiagnosticHandler(this.deferredDiagnosticHandler); |
852 |
851 } |
853 // the following is for the benefit of JavacProcessingEnvironment.getContext() |
|
854 JavacProcessingEnvironment.this.context = context; |
|
855 |
852 |
856 // the following will be populated as needed |
853 // the following will be populated as needed |
857 topLevelClasses = List.nil(); |
854 topLevelClasses = List.nil(); |
858 packageInfoFiles = List.nil(); |
855 packageInfoFiles = List.nil(); |
|
856 this.treesToClean = treesToClean; |
859 } |
857 } |
860 |
858 |
861 /** Create the first round. */ |
859 /** Create the first round. */ |
862 Round(Context context, List<JCCompilationUnit> roots, List<ClassSymbol> classSymbols, |
860 Round(List<JCCompilationUnit> roots, |
863 Log.DeferredDiagnosticHandler deferredDiagnosticHandler) { |
861 List<ClassSymbol> classSymbols, |
864 this(context, 1, 0, 0, deferredDiagnosticHandler); |
862 Set<JCCompilationUnit> treesToClean, |
|
863 Log.DeferredDiagnosticHandler deferredDiagnosticHandler) { |
|
864 this(1, treesToClean, deferredDiagnosticHandler); |
865 this.roots = roots; |
865 this.roots = roots; |
866 genClassFiles = new HashMap<>(); |
866 genClassFiles = new HashMap<>(); |
867 |
|
868 compiler.todo.clear(); // free the compiler's resources |
|
869 |
867 |
870 // The reverse() in the following line is to maintain behavioural |
868 // The reverse() in the following line is to maintain behavioural |
871 // compatibility with the previous revision of the code. Strictly speaking, |
869 // compatibility with the previous revision of the code. Strictly speaking, |
872 // it should not be necessary, but a javah golden file test fails without it. |
870 // it should not be necessary, but a javah golden file test fails without it. |
873 topLevelClasses = |
871 topLevelClasses = |
879 } |
877 } |
880 |
878 |
881 /** Create a new round. */ |
879 /** Create a new round. */ |
882 private Round(Round prev, |
880 private Round(Round prev, |
883 Set<JavaFileObject> newSourceFiles, Map<String,JavaFileObject> newClassFiles) { |
881 Set<JavaFileObject> newSourceFiles, Map<String,JavaFileObject> newClassFiles) { |
884 this(prev.nextContext(), |
882 this(prev.number+1, prev.treesToClean, null); |
885 prev.number+1, |
883 prev.newRound(); |
886 prev.compiler.log.nerrors, |
|
887 prev.compiler.log.nwarnings, |
|
888 null); |
|
889 this.genClassFiles = prev.genClassFiles; |
884 this.genClassFiles = prev.genClassFiles; |
890 |
885 |
891 List<JCCompilationUnit> parsedFiles = compiler.parseFiles(newSourceFiles); |
886 List<JCCompilationUnit> parsedFiles = compiler.parseFiles(newSourceFiles); |
892 roots = cleanTrees(prev.roots).appendList(parsedFiles); |
887 roots = prev.roots.appendList(parsedFiles); |
893 |
888 |
894 // Check for errors after parsing |
889 // Check for errors after parsing |
895 if (unrecoverableError()) |
890 if (unrecoverableError()) |
896 return; |
891 return; |
897 |
892 |
914 findAnnotationsPresent(); |
909 findAnnotationsPresent(); |
915 } |
910 } |
916 |
911 |
917 /** Create the next round to be used. */ |
912 /** Create the next round to be used. */ |
918 Round next(Set<JavaFileObject> newSourceFiles, Map<String, JavaFileObject> newClassFiles) { |
913 Round next(Set<JavaFileObject> newSourceFiles, Map<String, JavaFileObject> newClassFiles) { |
919 try { |
914 return new Round(this, newSourceFiles, newClassFiles); |
920 return new Round(this, newSourceFiles, newClassFiles); |
915 } |
921 } finally { |
916 |
922 compiler.close(false); |
917 /** Prepare the compiler for the final compilation. */ |
923 } |
918 void finalCompiler() { |
924 } |
919 newRound(); |
925 |
|
926 /** Create the compiler to be used for the final compilation. */ |
|
927 JavaCompiler finalCompiler() { |
|
928 try { |
|
929 Context nextCtx = nextContext(); |
|
930 JavacProcessingEnvironment.this.context = nextCtx; |
|
931 JavaCompiler c = JavaCompiler.instance(nextCtx); |
|
932 c.log.initRound(compiler.log); |
|
933 return c; |
|
934 } finally { |
|
935 compiler.close(false); |
|
936 } |
|
937 } |
920 } |
938 |
921 |
939 /** Return the number of errors found so far in this round. |
922 /** Return the number of errors found so far in this round. |
940 * This may include uncoverable errors, such as parse errors, |
923 * This may include uncoverable errors, such as parse errors, |
941 * and transient errors, such as missing symbols. */ |
924 * and transient errors, such as missing symbols. */ |
1029 errorStatus, |
1016 errorStatus, |
1030 emptyRootElements, |
1017 emptyRootElements, |
1031 JavacProcessingEnvironment.this); |
1018 JavacProcessingEnvironment.this); |
1032 discoveredProcs.iterator().runContributingProcs(renv); |
1019 discoveredProcs.iterator().runContributingProcs(renv); |
1033 } else { |
1020 } else { |
1034 discoverAndRunProcs(context, annotationsPresent, topLevelClasses, packageInfoFiles); |
1021 discoverAndRunProcs(annotationsPresent, topLevelClasses, packageInfoFiles); |
1035 } |
1022 } |
1036 } catch (Throwable t) { |
1023 } catch (Throwable t) { |
1037 // we're specifically expecting Abort here, but if any Throwable |
1024 // we're specifically expecting Abort here, but if any Throwable |
1038 // comes by, we should flush all deferred diagnostics, rather than |
1025 // comes by, we should flush all deferred diagnostics, rather than |
1039 // drop them on the ground. |
1026 // drop them on the ground. |
1040 deferredDiagnosticHandler.reportDeferredDiagnostics(); |
1027 deferredDiagnosticHandler.reportDeferredDiagnostics(); |
1041 log.popDiagnosticHandler(deferredDiagnosticHandler); |
1028 log.popDiagnosticHandler(deferredDiagnosticHandler); |
|
1029 compiler.setDeferredDiagnosticHandler(null); |
1042 throw t; |
1030 throw t; |
1043 } finally { |
1031 } finally { |
1044 if (!taskListener.isEmpty()) |
1032 if (!taskListener.isEmpty()) |
1045 taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); |
1033 taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); |
1046 } |
1034 } |
1067 ap, |
1056 ap, |
1068 lastRound); |
1057 lastRound); |
1069 } |
1058 } |
1070 } |
1059 } |
1071 |
1060 |
1072 /** Get the context for the next round of processing. |
1061 /** Prepare for new round of annotation processing. Cleans trees, resets symbols, and |
1073 * Important values are propagated from round to round; |
1062 * asks selected services to prepare to a new round of annotation processing. |
1074 * other values are implicitly reset. |
|
1075 */ |
1063 */ |
1076 private Context nextContext() { |
1064 private void newRound() { |
1077 Context next = new Context(context); |
1065 //ensure treesToClean contains all trees, including implicitly parsed ones |
1078 |
1066 for (Env<AttrContext> env : enter.getEnvs()) { |
1079 Options options = Options.instance(context); |
1067 treesToClean.add(env.toplevel); |
1080 Assert.checkNonNull(options); |
1068 } |
1081 next.put(Options.optionsKey, options); |
1069 for (JCCompilationUnit node : treesToClean) { |
1082 |
1070 treeCleaner.scan(node); |
1083 Locale locale = context.get(Locale.class); |
1071 } |
1084 if (locale != null) |
1072 chk.newRound(); |
1085 next.put(Locale.class, locale); |
1073 enter.newRound(); |
1086 |
1074 filer.newRound(); |
1087 Assert.checkNonNull(messages); |
1075 messager.newRound(); |
1088 next.put(JavacMessages.messagesKey, messages); |
1076 compiler.newRound(); |
1089 |
1077 types.newRound(); |
1090 final boolean shareNames = true; |
1078 |
1091 if (shareNames) { |
1079 boolean foundError = false; |
1092 Names names = Names.instance(context); |
1080 |
1093 Assert.checkNonNull(names); |
1081 for (ClassSymbol cs : symtab.classes.values()) { |
1094 next.put(Names.namesKey, names); |
1082 if (cs.kind == Kinds.ERR) { |
1095 } |
1083 foundError = true; |
1096 |
1084 break; |
1097 DiagnosticListener<?> dl = context.get(DiagnosticListener.class); |
1085 } |
1098 if (dl != null) |
1086 } |
1099 next.put(DiagnosticListener.class, dl); |
1087 |
1100 |
1088 if (foundError) { |
1101 MultiTaskListener mtl = context.get(MultiTaskListener.taskListenerKey); |
1089 for (ClassSymbol cs : symtab.classes.values()) { |
1102 if (mtl != null) |
1090 if (cs.classfile != null || cs.kind == Kinds.ERR) { |
1103 next.put(MultiTaskListener.taskListenerKey, mtl); |
1091 cs.reset(); |
1104 |
1092 cs.type = new ClassType(cs.type.getEnclosingType(), null, cs); |
1105 FSInfo fsInfo = context.get(FSInfo.class); |
1093 if (cs.completer == null) { |
1106 if (fsInfo != null) |
1094 cs.completer = initialCompleter; |
1107 next.put(FSInfo.class, fsInfo); |
1095 } |
1108 |
1096 } |
1109 JavaFileManager jfm = context.get(JavaFileManager.class); |
1097 } |
1110 Assert.checkNonNull(jfm); |
1098 } |
1111 next.put(JavaFileManager.class, jfm); |
|
1112 if (jfm instanceof JavacFileManager) { |
|
1113 ((JavacFileManager)jfm).setContext(next); |
|
1114 } |
|
1115 |
|
1116 Names names = Names.instance(context); |
|
1117 Assert.checkNonNull(names); |
|
1118 next.put(Names.namesKey, names); |
|
1119 |
|
1120 Tokens tokens = Tokens.instance(context); |
|
1121 Assert.checkNonNull(tokens); |
|
1122 next.put(Tokens.tokensKey, tokens); |
|
1123 |
|
1124 Log nextLog = Log.instance(next); |
|
1125 nextLog.initRound(log); |
|
1126 |
|
1127 JavaCompiler oldCompiler = JavaCompiler.instance(context); |
|
1128 JavaCompiler nextCompiler = JavaCompiler.instance(next); |
|
1129 nextCompiler.initRound(oldCompiler); |
|
1130 |
|
1131 filer.newRound(next); |
|
1132 messager.newRound(next); |
|
1133 elementUtils.setContext(next); |
|
1134 typeUtils.setContext(next); |
|
1135 |
|
1136 JavacTask task = context.get(JavacTask.class); |
|
1137 if (task != null) { |
|
1138 next.put(JavacTask.class, task); |
|
1139 if (task instanceof BasicJavacTask) |
|
1140 ((BasicJavacTask) task).updateContext(next); |
|
1141 } |
|
1142 |
|
1143 JavacTrees trees = context.get(JavacTrees.class); |
|
1144 if (trees != null) { |
|
1145 next.put(JavacTrees.class, trees); |
|
1146 trees.updateContext(next); |
|
1147 } |
|
1148 |
|
1149 context.clear(); |
|
1150 return next; |
|
1151 } |
1099 } |
1152 } |
1100 } |
1153 |
1101 |
1154 |
1102 |
1155 // TODO: internal catch clauses?; catch and rethrow an annotation |
1103 // TODO: internal catch clauses?; catch and rethrow an annotation |
1156 // processing error |
1104 // processing error |
1157 public JavaCompiler doProcessing(Context context, |
1105 public boolean doProcessing(List<JCCompilationUnit> roots, |
1158 List<JCCompilationUnit> roots, |
1106 List<ClassSymbol> classSymbols, |
1159 List<ClassSymbol> classSymbols, |
1107 Iterable<? extends PackageSymbol> pckSymbols, |
1160 Iterable<? extends PackageSymbol> pckSymbols, |
1108 Log.DeferredDiagnosticHandler deferredDiagnosticHandler) { |
1161 Log.DeferredDiagnosticHandler deferredDiagnosticHandler) { |
1109 final Set<JCCompilationUnit> treesToClean = |
1162 log = Log.instance(context); |
1110 Collections.newSetFromMap(new IdentityHashMap<JCCompilationUnit, Boolean>()); |
|
1111 |
|
1112 //fill already attributed implicit trees: |
|
1113 for (Env<AttrContext> env : enter.getEnvs()) { |
|
1114 treesToClean.add(env.toplevel); |
|
1115 } |
1163 |
1116 |
1164 Set<PackageSymbol> specifiedPackages = new LinkedHashSet<>(); |
1117 Set<PackageSymbol> specifiedPackages = new LinkedHashSet<>(); |
1165 for (PackageSymbol psym : pckSymbols) |
1118 for (PackageSymbol psym : pckSymbols) |
1166 specifiedPackages.add(psym); |
1119 specifiedPackages.add(psym); |
1167 this.specifiedPackages = Collections.unmodifiableSet(specifiedPackages); |
1120 this.specifiedPackages = Collections.unmodifiableSet(specifiedPackages); |
1168 |
1121 |
1169 Round round = new Round(context, roots, classSymbols, deferredDiagnosticHandler); |
1122 Round round = new Round(roots, classSymbols, treesToClean, deferredDiagnosticHandler); |
1170 |
1123 |
1171 boolean errorStatus; |
1124 boolean errorStatus; |
1172 boolean moreToDo; |
1125 boolean moreToDo; |
1173 do { |
1126 do { |
1174 // Run processors for round n |
1127 // Run processors for round n |
1340 } |
1296 } |
1341 |
1297 |
1342 return false; |
1298 return false; |
1343 } |
1299 } |
1344 |
1300 |
1345 private static <T extends JCTree> List<T> cleanTrees(List<T> nodes) { |
1301 class ImplicitCompleter implements Completer { |
1346 for (T node : nodes) |
1302 |
1347 treeCleaner.scan(node); |
1303 private final JCCompilationUnit topLevel; |
1348 return nodes; |
1304 |
1349 } |
1305 public ImplicitCompleter(JCCompilationUnit topLevel) { |
1350 |
1306 this.topLevel = topLevel; |
1351 private static final TreeScanner treeCleaner = new TreeScanner() { |
1307 } |
|
1308 |
|
1309 @Override public void complete(Symbol sym) throws CompletionFailure { |
|
1310 compiler.complete(topLevel, (ClassSymbol) sym); |
|
1311 } |
|
1312 } |
|
1313 |
|
1314 private final TreeScanner treeCleaner = new TreeScanner() { |
1352 public void scan(JCTree node) { |
1315 public void scan(JCTree node) { |
1353 super.scan(node); |
1316 super.scan(node); |
1354 if (node != null) |
1317 if (node != null) |
1355 node.type = null; |
1318 node.type = null; |
1356 } |
1319 } |
|
1320 JCCompilationUnit topLevel; |
1357 public void visitTopLevel(JCCompilationUnit node) { |
1321 public void visitTopLevel(JCCompilationUnit node) { |
|
1322 if (node.packge != null) { |
|
1323 if (node.packge.package_info != null) { |
|
1324 node.packge.package_info.reset(); |
|
1325 } |
|
1326 node.packge.reset(); |
|
1327 } |
1358 node.packge = null; |
1328 node.packge = null; |
1359 super.visitTopLevel(node); |
1329 topLevel = node; |
|
1330 try { |
|
1331 super.visitTopLevel(node); |
|
1332 } finally { |
|
1333 topLevel = null; |
|
1334 } |
1360 } |
1335 } |
1361 public void visitClassDef(JCClassDecl node) { |
1336 public void visitClassDef(JCClassDecl node) { |
|
1337 if (node.sym != null) { |
|
1338 node.sym.reset(); |
|
1339 node.sym.completer = new ImplicitCompleter(topLevel); |
|
1340 } |
1362 node.sym = null; |
1341 node.sym = null; |
1363 super.visitClassDef(node); |
1342 super.visitClassDef(node); |
1364 } |
1343 } |
1365 public void visitMethodDef(JCMethodDecl node) { |
1344 public void visitMethodDef(JCMethodDecl node) { |
1366 node.sym = null; |
1345 node.sym = null; |