25 |
25 |
26 package com.sun.tools.javac.processing; |
26 package com.sun.tools.javac.processing; |
27 |
27 |
28 import java.io.Closeable; |
28 import java.io.Closeable; |
29 import java.io.File; |
29 import java.io.File; |
|
30 import java.io.IOException; |
30 import java.io.PrintWriter; |
31 import java.io.PrintWriter; |
31 import java.io.StringWriter; |
32 import java.io.StringWriter; |
|
33 import java.lang.reflect.Method; |
32 import java.net.MalformedURLException; |
34 import java.net.MalformedURLException; |
33 import java.net.URL; |
35 import java.net.URL; |
34 import java.nio.file.Path; |
36 import java.nio.file.Path; |
35 import java.util.*; |
37 import java.util.*; |
36 import java.util.regex.*; |
38 import java.util.regex.*; |
40 import javax.lang.model.SourceVersion; |
42 import javax.lang.model.SourceVersion; |
41 import javax.lang.model.element.*; |
43 import javax.lang.model.element.*; |
42 import javax.lang.model.util.*; |
44 import javax.lang.model.util.*; |
43 import javax.tools.JavaFileManager; |
45 import javax.tools.JavaFileManager; |
44 import javax.tools.JavaFileObject; |
46 import javax.tools.JavaFileObject; |
|
47 import javax.tools.JavaFileObject.Kind; |
45 import javax.tools.StandardJavaFileManager; |
48 import javax.tools.StandardJavaFileManager; |
46 |
49 |
47 import static javax.tools.StandardLocation.*; |
50 import static javax.tools.StandardLocation.*; |
48 |
51 |
49 import com.sun.source.util.TaskEvent; |
52 import com.sun.source.util.TaskEvent; |
50 import com.sun.tools.javac.api.MultiTaskListener; |
53 import com.sun.tools.javac.api.MultiTaskListener; |
51 import com.sun.tools.javac.code.*; |
54 import com.sun.tools.javac.code.*; |
|
55 import com.sun.tools.javac.code.Scope.WriteableScope; |
52 import com.sun.tools.javac.code.Symbol.*; |
56 import com.sun.tools.javac.code.Symbol.*; |
53 import com.sun.tools.javac.code.Type.ClassType; |
57 import com.sun.tools.javac.code.Type.ClassType; |
54 import com.sun.tools.javac.code.Types; |
58 import com.sun.tools.javac.code.Types; |
55 import com.sun.tools.javac.comp.AttrContext; |
59 import com.sun.tools.javac.comp.AttrContext; |
56 import com.sun.tools.javac.comp.Check; |
60 import com.sun.tools.javac.comp.Check; |
57 import com.sun.tools.javac.comp.Enter; |
61 import com.sun.tools.javac.comp.Enter; |
58 import com.sun.tools.javac.comp.Env; |
62 import com.sun.tools.javac.comp.Env; |
|
63 import com.sun.tools.javac.comp.Modules; |
59 import com.sun.tools.javac.file.JavacFileManager; |
64 import com.sun.tools.javac.file.JavacFileManager; |
60 import com.sun.tools.javac.main.JavaCompiler; |
65 import com.sun.tools.javac.main.JavaCompiler; |
61 import com.sun.tools.javac.model.JavacElements; |
66 import com.sun.tools.javac.model.JavacElements; |
62 import com.sun.tools.javac.model.JavacTypes; |
67 import com.sun.tools.javac.model.JavacTypes; |
63 import com.sun.tools.javac.platform.PlatformDescription; |
68 import com.sun.tools.javac.platform.PlatformDescription; |
64 import com.sun.tools.javac.platform.PlatformDescription.PluginInfo; |
69 import com.sun.tools.javac.platform.PlatformDescription.PluginInfo; |
|
70 import com.sun.tools.javac.resources.CompilerProperties.Errors; |
65 import com.sun.tools.javac.tree.*; |
71 import com.sun.tools.javac.tree.*; |
66 import com.sun.tools.javac.tree.JCTree.*; |
72 import com.sun.tools.javac.tree.JCTree.*; |
67 import com.sun.tools.javac.util.Abort; |
73 import com.sun.tools.javac.util.Abort; |
68 import com.sun.tools.javac.util.Assert; |
74 import com.sun.tools.javac.util.Assert; |
69 import com.sun.tools.javac.util.ClientCodeException; |
75 import com.sun.tools.javac.util.ClientCodeException; |
75 import com.sun.tools.javac.util.JCDiagnostic; |
81 import com.sun.tools.javac.util.JCDiagnostic; |
76 import com.sun.tools.javac.util.JavacMessages; |
82 import com.sun.tools.javac.util.JavacMessages; |
77 import com.sun.tools.javac.util.List; |
83 import com.sun.tools.javac.util.List; |
78 import com.sun.tools.javac.util.Log; |
84 import com.sun.tools.javac.util.Log; |
79 import com.sun.tools.javac.util.MatchingUtils; |
85 import com.sun.tools.javac.util.MatchingUtils; |
|
86 import com.sun.tools.javac.util.ModuleHelper; |
80 import com.sun.tools.javac.util.Name; |
87 import com.sun.tools.javac.util.Name; |
81 import com.sun.tools.javac.util.Names; |
88 import com.sun.tools.javac.util.Names; |
82 import com.sun.tools.javac.util.Options; |
89 import com.sun.tools.javac.util.Options; |
83 import com.sun.tools.javac.util.ServiceLoader; |
|
84 |
90 |
85 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING; |
91 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING; |
86 import static com.sun.tools.javac.code.Kinds.Kind.*; |
92 import static com.sun.tools.javac.code.Kinds.Kind.*; |
87 import static com.sun.tools.javac.main.Option.*; |
93 import static com.sun.tools.javac.main.Option.*; |
88 import static com.sun.tools.javac.comp.CompileStates.CompileState; |
94 import static com.sun.tools.javac.comp.CompileStates.CompileState; |
110 |
116 |
111 private final JavacFiler filer; |
117 private final JavacFiler filer; |
112 private final JavacMessager messager; |
118 private final JavacMessager messager; |
113 private final JavacElements elementUtils; |
119 private final JavacElements elementUtils; |
114 private final JavacTypes typeUtils; |
120 private final JavacTypes typeUtils; |
|
121 private final JavaCompiler compiler; |
|
122 private final Modules modules; |
|
123 private final ModuleHelper moduleHelper; |
115 private final Types types; |
124 private final Types types; |
116 private final JavaCompiler compiler; |
|
117 |
125 |
118 /** |
126 /** |
119 * Holds relevant state history of which processors have been |
127 * Holds relevant state history of which processors have been |
120 * used. |
128 * used. |
121 */ |
129 */ |
165 private final Symtab symtab; |
176 private final Symtab symtab; |
166 private final Names names; |
177 private final Names names; |
167 private final Enter enter; |
178 private final Enter enter; |
168 private final Completer initialCompleter; |
179 private final Completer initialCompleter; |
169 private final Check chk; |
180 private final Check chk; |
|
181 private final ModuleSymbol defaultModule; |
170 |
182 |
171 private final Context context; |
183 private final Context context; |
172 |
184 |
173 /** Get the JavacProcessingEnvironment instance for this context. */ |
185 /** Get the JavacProcessingEnvironment instance for this context. */ |
174 public static JavacProcessingEnvironment instance(Context context) { |
186 public static JavacProcessingEnvironment instance(Context context) { |
194 compiler.shouldStopPolicyIfNoError = CompileState.PROCESS; |
206 compiler.shouldStopPolicyIfNoError = CompileState.PROCESS; |
195 } |
207 } |
196 fatalErrors = options.isSet("fatalEnterError"); |
208 fatalErrors = options.isSet("fatalEnterError"); |
197 showResolveErrors = options.isSet("showResolveErrors"); |
209 showResolveErrors = options.isSet("showResolveErrors"); |
198 werror = options.isSet(WERROR); |
210 werror = options.isSet(WERROR); |
|
211 fileManager = context.get(JavaFileManager.class); |
199 platformAnnotations = initPlatformAnnotations(); |
212 platformAnnotations = initPlatformAnnotations(); |
200 |
213 |
201 // Initialize services before any processors are initialized |
214 // Initialize services before any processors are initialized |
202 // in case processors use them. |
215 // in case processors use them. |
203 filer = new JavacFiler(context); |
216 filer = new JavacFiler(context); |
204 messager = new JavacMessager(context, this); |
217 messager = new JavacMessager(context, this); |
205 elementUtils = JavacElements.instance(context); |
218 elementUtils = JavacElements.instance(context); |
206 typeUtils = JavacTypes.instance(context); |
219 typeUtils = JavacTypes.instance(context); |
|
220 modules = Modules.instance(context); |
207 types = Types.instance(context); |
221 types = Types.instance(context); |
208 processorOptions = initProcessorOptions(); |
222 processorOptions = initProcessorOptions(); |
209 unmatchedProcessorOptions = initUnmatchedProcessorOptions(); |
223 unmatchedProcessorOptions = initUnmatchedProcessorOptions(); |
210 messages = JavacMessages.instance(context); |
224 messages = JavacMessages.instance(context); |
211 taskListener = MultiTaskListener.instance(context); |
225 taskListener = MultiTaskListener.instance(context); |
212 symtab = Symtab.instance(context); |
226 symtab = Symtab.instance(context); |
213 names = Names.instance(context); |
227 names = Names.instance(context); |
214 enter = Enter.instance(context); |
228 enter = Enter.instance(context); |
215 initialCompleter = ClassFinder.instance(context).getCompleter(); |
229 initialCompleter = ClassFinder.instance(context).getCompleter(); |
216 chk = Check.instance(context); |
230 chk = Check.instance(context); |
217 initProcessorClassLoader(); |
231 moduleHelper = ModuleHelper.instance(context); |
|
232 initProcessorLoader(); |
|
233 |
|
234 defaultModule = source.allowModules() && options.isUnset("noModules") |
|
235 ? symtab.unnamedModule : symtab.noModule; |
218 } |
236 } |
219 |
237 |
220 public void setProcessors(Iterable<? extends Processor> processors) { |
238 public void setProcessors(Iterable<? extends Processor> processors) { |
221 Assert.checkNull(discoveredProcs); |
239 Assert.checkNull(discoveredProcs); |
222 initProcessorIterator(processors); |
240 initProcessorIterator(processors); |
232 platformAnnotations.add("java.lang.annotation.Retention"); |
250 platformAnnotations.add("java.lang.annotation.Retention"); |
233 platformAnnotations.add("java.lang.annotation.Target"); |
251 platformAnnotations.add("java.lang.annotation.Target"); |
234 return Collections.unmodifiableSet(platformAnnotations); |
252 return Collections.unmodifiableSet(platformAnnotations); |
235 } |
253 } |
236 |
254 |
237 private void initProcessorClassLoader() { |
255 private void initProcessorLoader() { |
238 JavaFileManager fileManager = context.get(JavaFileManager.class); |
|
239 try { |
256 try { |
240 // If processorpath is not explicitly set, use the classpath. |
257 if (fileManager.hasLocation(ANNOTATION_PROCESSOR_MODULE_PATH)) { |
241 processorClassLoader = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH) |
258 try { |
242 ? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH) |
259 serviceLoader = fileManager.getServiceLoader(ANNOTATION_PROCESSOR_MODULE_PATH, Processor.class); |
243 : fileManager.getClassLoader(CLASS_PATH); |
260 } catch (IOException e) { |
244 |
261 throw new Abort(e); |
245 if (processorClassLoader != null && processorClassLoader instanceof Closeable) { |
262 } |
246 compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader); |
263 } else { |
|
264 // If processorpath is not explicitly set, use the classpath. |
|
265 processorClassLoader = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH) |
|
266 ? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH) |
|
267 : fileManager.getClassLoader(CLASS_PATH); |
|
268 |
|
269 moduleHelper.addExports(processorClassLoader); |
|
270 |
|
271 if (processorClassLoader != null && processorClassLoader instanceof Closeable) { |
|
272 compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader); |
|
273 } |
247 } |
274 } |
248 } catch (SecurityException e) { |
275 } catch (SecurityException e) { |
249 processorClassLoaderException = e; |
276 processorLoaderException = e; |
250 } |
277 } |
251 } |
278 } |
252 |
279 |
253 private void initProcessorIterator(Iterable<? extends Processor> processors) { |
280 private void initProcessorIterator(Iterable<? extends Processor> processors) { |
254 Iterator<? extends Processor> processorIterator; |
281 Iterator<? extends Processor> processorIterator; |
264 throw assertError; |
291 throw assertError; |
265 } |
292 } |
266 } else if (processors != null) { |
293 } else if (processors != null) { |
267 processorIterator = processors.iterator(); |
294 processorIterator = processors.iterator(); |
268 } else { |
295 } else { |
269 String processorNames = options.get(PROCESSOR); |
296 if (processorLoaderException == null) { |
270 if (processorClassLoaderException == null) { |
|
271 /* |
297 /* |
272 * If the "-processor" option is used, search the appropriate |
298 * If the "-processor" option is used, search the appropriate |
273 * path for the named class. Otherwise, use a service |
299 * path for the named class. Otherwise, use a service |
274 * provider mechanism to create the processor iterator. |
300 * provider mechanism to create the processor iterator. |
275 */ |
301 */ |
276 if (processorNames != null) { |
302 String processorNames = options.get(PROCESSOR); |
|
303 if (fileManager.hasLocation(ANNOTATION_PROCESSOR_MODULE_PATH)) { |
|
304 processorIterator = (processorNames == null) ? |
|
305 new ServiceIterator(serviceLoader, log) : |
|
306 new NameServiceIterator(serviceLoader, log, processorNames); |
|
307 } else if (processorNames != null) { |
277 processorIterator = new NameProcessIterator(processorNames, processorClassLoader, log); |
308 processorIterator = new NameProcessIterator(processorNames, processorClassLoader, log); |
278 } else { |
309 } else { |
279 processorIterator = new ServiceIterator(processorClassLoader, log); |
310 processorIterator = new ServiceIterator(processorClassLoader, log); |
280 } |
311 } |
281 } else { |
312 } else { |
284 * Ignore the exception if, with hindsight, we didn't need it anyway |
315 * Ignore the exception if, with hindsight, we didn't need it anyway |
285 * (i.e. no processor was specified either explicitly, or implicitly, |
316 * (i.e. no processor was specified either explicitly, or implicitly, |
286 * in service configuration file.) Otherwise, we cannot continue. |
317 * in service configuration file.) Otherwise, we cannot continue. |
287 */ |
318 */ |
288 processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader", |
319 processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader", |
289 processorClassLoaderException); |
320 processorLoaderException); |
290 } |
321 } |
291 } |
322 } |
292 PlatformDescription platformProvider = context.get(PlatformDescription.class); |
323 PlatformDescription platformProvider = context.get(PlatformDescription.class); |
293 java.util.List<Processor> platformProcessors = Collections.emptyList(); |
324 java.util.List<Processor> platformProcessors = Collections.emptyList(); |
294 if (platformProvider != null) { |
325 if (platformProvider != null) { |
300 List<Iterator<? extends Processor>> iterators = List.of(processorIterator, |
331 List<Iterator<? extends Processor>> iterators = List.of(processorIterator, |
301 platformProcessors.iterator()); |
332 platformProcessors.iterator()); |
302 Iterator<? extends Processor> compoundIterator = |
333 Iterator<? extends Processor> compoundIterator = |
303 Iterators.createCompoundIterator(iterators, i -> i); |
334 Iterators.createCompoundIterator(iterators, i -> i); |
304 discoveredProcs = new DiscoveredProcessors(compoundIterator); |
335 discoveredProcs = new DiscoveredProcessors(compoundIterator); |
|
336 } |
|
337 |
|
338 public <S> ServiceLoader<S> getServiceLoader(Class<S> service) { |
|
339 if (fileManager.hasLocation(ANNOTATION_PROCESSOR_MODULE_PATH)) { |
|
340 try { |
|
341 return fileManager.getServiceLoader(ANNOTATION_PROCESSOR_MODULE_PATH, service); |
|
342 } catch (IOException e) { |
|
343 throw new Abort(e); |
|
344 } |
|
345 } else { |
|
346 return ServiceLoader.load(service, getProcessorClassLoader()); |
|
347 } |
305 } |
348 } |
306 |
349 |
307 /** |
350 /** |
308 * Returns an empty processor iterator if no processors are on the |
351 * Returns an empty processor iterator if no processors are on the |
309 * relevant path, otherwise if processors are present, logs an |
352 * relevant path, otherwise if processors are present, logs an |
314 * |
357 * |
315 * @param key The resource key to use to log an error message |
358 * @param key The resource key to use to log an error message |
316 * @param e If non-null, pass this exception to Abort |
359 * @param e If non-null, pass this exception to Abort |
317 */ |
360 */ |
318 private Iterator<Processor> handleServiceLoaderUnavailability(String key, Exception e) { |
361 private Iterator<Processor> handleServiceLoaderUnavailability(String key, Exception e) { |
319 JavaFileManager fileManager = context.get(JavaFileManager.class); |
|
320 |
|
321 if (fileManager instanceof JavacFileManager) { |
362 if (fileManager instanceof JavacFileManager) { |
322 StandardJavaFileManager standardFileManager = (JavacFileManager) fileManager; |
363 StandardJavaFileManager standardFileManager = (JavacFileManager) fileManager; |
323 Iterable<? extends Path> workingPath = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH) |
364 Iterable<? extends Path> workingPath = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH) |
324 ? standardFileManager.getLocationAsPaths(ANNOTATION_PROCESSOR_PATH) |
365 ? standardFileManager.getLocationAsPaths(ANNOTATION_PROCESSOR_PATH) |
325 : standardFileManager.getLocationAsPaths(CLASS_PATH); |
366 : standardFileManager.getLocationAsPaths(CLASS_PATH); |
353 * Use a service loader appropriate for the platform to provide an |
394 * Use a service loader appropriate for the platform to provide an |
354 * iterator over annotations processors; fails if a loader is |
395 * iterator over annotations processors; fails if a loader is |
355 * needed but unavailable. |
396 * needed but unavailable. |
356 */ |
397 */ |
357 private class ServiceIterator implements Iterator<Processor> { |
398 private class ServiceIterator implements Iterator<Processor> { |
358 private Iterator<Processor> iterator; |
399 Iterator<Processor> iterator; |
359 private Log log; |
400 Log log; |
360 private ServiceLoader<Processor> loader; |
401 ServiceLoader<Processor> loader; |
361 |
402 |
362 ServiceIterator(ClassLoader classLoader, Log log) { |
403 ServiceIterator(ClassLoader classLoader, Log log) { |
363 this.log = log; |
404 this.log = log; |
364 try { |
405 try { |
365 try { |
406 try { |
373 log.error("proc.service.problem"); |
414 log.error("proc.service.problem"); |
374 throw new Abort(t); |
415 throw new Abort(t); |
375 } |
416 } |
376 } |
417 } |
377 |
418 |
|
419 ServiceIterator(ServiceLoader<Processor> loader, Log log) { |
|
420 this.log = log; |
|
421 this.loader = loader; |
|
422 this.iterator = loader.iterator(); |
|
423 } |
|
424 |
|
425 @Override |
378 public boolean hasNext() { |
426 public boolean hasNext() { |
379 try { |
427 try { |
380 return iterator.hasNext(); |
428 return internalHasNext(); |
381 } catch(ServiceConfigurationError sce) { |
429 } catch(ServiceConfigurationError sce) { |
382 log.error("proc.bad.config.file", sce.getLocalizedMessage()); |
430 log.error("proc.bad.config.file", sce.getLocalizedMessage()); |
383 throw new Abort(sce); |
431 throw new Abort(sce); |
384 } catch (Throwable t) { |
432 } catch (Throwable t) { |
385 throw new Abort(t); |
433 throw new Abort(t); |
386 } |
434 } |
387 } |
435 } |
388 |
436 |
|
437 boolean internalHasNext() { |
|
438 return iterator.hasNext(); |
|
439 } |
|
440 |
|
441 @Override |
389 public Processor next() { |
442 public Processor next() { |
390 try { |
443 try { |
391 return iterator.next(); |
444 return internalNext(); |
392 } catch (ServiceConfigurationError sce) { |
445 } catch (ServiceConfigurationError sce) { |
393 log.error("proc.bad.config.file", sce.getLocalizedMessage()); |
446 log.error("proc.bad.config.file", sce.getLocalizedMessage()); |
394 throw new Abort(sce); |
447 throw new Abort(sce); |
395 } catch (Throwable t) { |
448 } catch (Throwable t) { |
396 throw new Abort(t); |
449 throw new Abort(t); |
397 } |
450 } |
398 } |
451 } |
399 |
452 |
|
453 Processor internalNext() { |
|
454 return iterator.next(); |
|
455 } |
|
456 |
|
457 @Override |
400 public void remove() { |
458 public void remove() { |
401 throw new UnsupportedOperationException(); |
459 throw new UnsupportedOperationException(); |
402 } |
460 } |
403 |
461 |
404 public void close() { |
462 public void close() { |
410 } |
468 } |
411 } |
469 } |
412 } |
470 } |
413 } |
471 } |
414 |
472 |
|
473 private class NameServiceIterator extends ServiceIterator { |
|
474 private Map<String, Processor> namedProcessorsMap = new HashMap<>();; |
|
475 private Iterator<String> processorNames = null; |
|
476 private Processor nextProc = null; |
|
477 |
|
478 public NameServiceIterator(ServiceLoader<Processor> loader, Log log, String theNames) { |
|
479 super(loader, log); |
|
480 this.processorNames = Arrays.asList(theNames.split(",")).iterator(); |
|
481 } |
|
482 |
|
483 @Override |
|
484 boolean internalHasNext() { |
|
485 if (nextProc != null) { |
|
486 return true; |
|
487 } |
|
488 if (!processorNames.hasNext()) { |
|
489 namedProcessorsMap = null; |
|
490 return false; |
|
491 } |
|
492 String processorName = processorNames.next(); |
|
493 Processor theProcessor = namedProcessorsMap.get(processorName); |
|
494 if (theProcessor != null) { |
|
495 namedProcessorsMap.remove(processorName); |
|
496 nextProc = theProcessor; |
|
497 return true; |
|
498 } else { |
|
499 while (iterator.hasNext()) { |
|
500 theProcessor = iterator.next(); |
|
501 String name = theProcessor.getClass().getName(); |
|
502 if (name.equals(processorName)) { |
|
503 nextProc = theProcessor; |
|
504 return true; |
|
505 } else { |
|
506 namedProcessorsMap.put(name, theProcessor); |
|
507 } |
|
508 } |
|
509 log.error(Errors.ProcProcessorNotFound(processorName)); |
|
510 return false; |
|
511 } |
|
512 } |
|
513 |
|
514 @Override |
|
515 Processor internalNext() { |
|
516 if (hasNext()) { |
|
517 Processor p = nextProc; |
|
518 nextProc = null; |
|
519 return p; |
|
520 } else { |
|
521 throw new NoSuchElementException(); |
|
522 } |
|
523 } |
|
524 } |
415 |
525 |
416 private static class NameProcessIterator implements Iterator<Processor> { |
526 private static class NameProcessIterator implements Iterator<Processor> { |
417 Processor nextProc = null; |
527 Processor nextProc = null; |
418 Iterator<String> names; |
528 Iterator<String> names; |
419 ClassLoader processorCL; |
529 ClassLoader processorCL; |
435 String processorName = names.next(); |
545 String processorName = names.next(); |
436 |
546 |
437 Processor processor; |
547 Processor processor; |
438 try { |
548 try { |
439 try { |
549 try { |
|
550 Class<?> processorClass = processorCL.loadClass(processorName); |
|
551 ensureReadable(processorClass); |
440 processor = |
552 processor = |
441 (Processor) (processorCL.loadClass(processorName).newInstance()); |
553 (Processor) (processorClass.newInstance()); |
442 } catch (ClassNotFoundException cnfe) { |
554 } catch (ClassNotFoundException cnfe) { |
443 log.error("proc.processor.not.found", processorName); |
555 log.error("proc.processor.not.found", processorName); |
444 return false; |
556 return false; |
445 } catch (ClassCastException cce) { |
557 } catch (ClassCastException cce) { |
446 log.error("proc.processor.wrong.type", processorName); |
558 log.error("proc.processor.wrong.type", processorName); |
471 } |
583 } |
472 |
584 |
473 public void remove () { |
585 public void remove () { |
474 throw new UnsupportedOperationException(); |
586 throw new UnsupportedOperationException(); |
475 } |
587 } |
|
588 |
|
589 /** |
|
590 * Ensures that the module of the given class is readable to this |
|
591 * module. |
|
592 */ |
|
593 private void ensureReadable(Class<?> targetClass) { |
|
594 try { |
|
595 Method getModuleMethod = Class.class.getMethod("getModule"); |
|
596 Object thisModule = getModuleMethod.invoke(this.getClass()); |
|
597 Object targetModule = getModuleMethod.invoke(targetClass); |
|
598 |
|
599 Class<?> moduleClass = getModuleMethod.getReturnType(); |
|
600 Method addReadsMethod = moduleClass.getMethod("addReads", moduleClass); |
|
601 addReadsMethod.invoke(thisModule, targetModule); |
|
602 } catch (NoSuchMethodException e) { |
|
603 // ignore |
|
604 } catch (Exception e) { |
|
605 throw new InternalError(e); |
|
606 } |
|
607 } |
476 } |
608 } |
477 |
609 |
478 public boolean atLeastOneProcessor() { |
610 public boolean atLeastOneProcessor() { |
479 return discoveredProcs.iterator().hasNext(); |
611 return discoveredProcs.iterator().hasNext(); |
480 } |
612 } |
603 } |
735 } |
604 |
736 |
605 // TODO: These two classes can probably be rewritten better... |
737 // TODO: These two classes can probably be rewritten better... |
606 /** |
738 /** |
607 * This class holds information about the processors that have |
739 * This class holds information about the processors that have |
608 * been discoverd so far as well as the means to discover more, if |
740 * been discovered so far as well as the means to discover more, if |
609 * necessary. A single iterator should be used per round of |
741 * necessary. A single iterator should be used per round of |
610 * annotation processing. The iterator first visits already |
742 * annotation processing. The iterator first visits already |
611 * discovered processors then fails over to the service provider |
743 * discovered processors then fails over to the service provider |
612 * mechanism if additional queries are made. |
744 * mechanism if additional queries are made. |
613 */ |
745 */ |
998 Name name = names.fromString(entry.getKey()); |
1130 Name name = names.fromString(entry.getKey()); |
999 JavaFileObject file = entry.getValue(); |
1131 JavaFileObject file = entry.getValue(); |
1000 if (file.getKind() != JavaFileObject.Kind.CLASS) |
1132 if (file.getKind() != JavaFileObject.Kind.CLASS) |
1001 throw new AssertionError(file); |
1133 throw new AssertionError(file); |
1002 ClassSymbol cs; |
1134 ClassSymbol cs; |
|
1135 // TODO: for now, we assume that generated code is in a default module; |
|
1136 // in time, we need a way to be able to specify the module for generated code |
1003 if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) { |
1137 if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) { |
1004 Name packageName = Convert.packagePart(name); |
1138 Name packageName = Convert.packagePart(name); |
1005 PackageSymbol p = symtab.enterPackage(packageName); |
1139 PackageSymbol p = symtab.enterPackage(defaultModule, packageName); |
1006 if (p.package_info == null) |
1140 if (p.package_info == null) |
1007 p.package_info = symtab.enterClass(Convert.shortName(name), p); |
1141 p.package_info = symtab.enterClass(defaultModule, Convert.shortName(name), p); |
1008 cs = p.package_info; |
1142 cs = p.package_info; |
1009 cs.reset(); |
1143 cs.reset(); |
1010 if (cs.classfile == null) |
1144 if (cs.classfile == null) |
1011 cs.classfile = file; |
1145 cs.classfile = file; |
1012 cs.completer = initialCompleter; |
1146 cs.completer = initialCompleter; |
1013 } else { |
1147 } else { |
1014 cs = symtab.enterClass(name); |
1148 cs = symtab.enterClass(defaultModule, name); |
1015 cs.reset(); |
1149 cs.reset(); |
1016 cs.classfile = file; |
1150 cs.classfile = file; |
1017 cs.completer = initialCompleter; |
1151 cs.completer = initialCompleter; |
|
1152 cs.owner.members().enter(cs); //XXX - OverwriteBetweenCompilations; syms.getClass is not sufficient anymore |
1018 } |
1153 } |
1019 list = list.prepend(cs); |
1154 list = list.prepend(cs); |
1020 } |
1155 } |
1021 return list.reverse(); |
1156 return list.reverse(); |
1022 } |
1157 } |
1023 |
1158 |
1024 /** Enter a set of syntax trees. */ |
1159 /** Enter a set of syntax trees. */ |
1025 private void enterTrees(List<JCCompilationUnit> roots) { |
1160 private void enterTrees(List<JCCompilationUnit> roots) { |
1026 compiler.enterTrees(roots); |
1161 compiler.enterTrees(compiler.initModules(roots)); |
1027 } |
1162 } |
1028 |
1163 |
1029 /** Run a processing round. */ |
1164 /** Run a processing round. */ |
1030 void run(boolean lastRound, boolean errorStatus) { |
1165 void run(boolean lastRound, boolean errorStatus) { |
1031 printRoundInfo(lastRound); |
1166 printRoundInfo(lastRound); |
1097 chk.newRound(); |
1232 chk.newRound(); |
1098 enter.newRound(); |
1233 enter.newRound(); |
1099 filer.newRound(); |
1234 filer.newRound(); |
1100 messager.newRound(); |
1235 messager.newRound(); |
1101 compiler.newRound(); |
1236 compiler.newRound(); |
|
1237 modules.newRound(); |
1102 types.newRound(); |
1238 types.newRound(); |
1103 |
1239 |
1104 boolean foundError = false; |
1240 boolean foundError = false; |
1105 |
1241 |
1106 for (ClassSymbol cs : symtab.classes.values()) { |
1242 for (ClassSymbol cs : symtab.getAllClasses()) { |
1107 if (cs.kind == ERR) { |
1243 if (cs.kind == ERR) { |
1108 foundError = true; |
1244 foundError = true; |
1109 break; |
1245 break; |
1110 } |
1246 } |
1111 } |
1247 } |
1112 |
1248 |
1113 if (foundError) { |
1249 if (foundError) { |
1114 for (ClassSymbol cs : symtab.classes.values()) { |
1250 for (ClassSymbol cs : symtab.getAllClasses()) { |
1115 if (cs.classfile != null || cs.kind == ERR) { |
1251 if (cs.classfile != null || cs.kind == ERR) { |
1116 cs.reset(); |
1252 cs.reset(); |
1117 cs.type = new ClassType(cs.type.getEnclosingType(), null, cs); |
1253 cs.type = new ClassType(cs.type.getEnclosingType(), null, cs); |
1118 if (cs.isCompleted()) { |
1254 if (cs.isCompleted()) { |
1119 cs.completer = initialCompleter; |
1255 cs.completer = initialCompleter; |