1 /* |
1 /* |
2 * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
31 import java.util.concurrent.Callable; |
31 import java.util.concurrent.Callable; |
32 import java.util.concurrent.atomic.AtomicBoolean; |
32 import java.util.concurrent.atomic.AtomicBoolean; |
33 |
33 |
34 import javax.annotation.processing.Processor; |
34 import javax.annotation.processing.Processor; |
35 import javax.lang.model.element.Element; |
35 import javax.lang.model.element.Element; |
|
36 import javax.lang.model.element.ElementKind; |
36 import javax.lang.model.element.TypeElement; |
37 import javax.lang.model.element.TypeElement; |
|
38 import javax.lang.model.util.ElementFilter; |
37 import javax.tools.*; |
39 import javax.tools.*; |
|
40 import javax.tools.JavaFileObject.Kind; |
38 |
41 |
39 import com.sun.source.tree.*; |
42 import com.sun.source.tree.*; |
40 import com.sun.tools.javac.code.*; |
43 import com.sun.tools.javac.code.*; |
41 import com.sun.tools.javac.code.Symbol.ClassSymbol; |
44 import com.sun.tools.javac.code.Symbol.ClassSymbol; |
|
45 import com.sun.tools.javac.code.Symbol.ModuleSymbol; |
|
46 import com.sun.tools.javac.code.Symbol.PackageSymbol; |
42 import com.sun.tools.javac.comp.*; |
47 import com.sun.tools.javac.comp.*; |
43 import com.sun.tools.javac.file.BaseFileManager; |
48 import com.sun.tools.javac.file.BaseFileManager; |
44 import com.sun.tools.javac.main.*; |
49 import com.sun.tools.javac.main.*; |
45 import com.sun.tools.javac.main.JavaCompiler; |
50 import com.sun.tools.javac.main.JavaCompiler; |
46 import com.sun.tools.javac.parser.Parser; |
51 import com.sun.tools.javac.parser.Parser; |
47 import com.sun.tools.javac.parser.ParserFactory; |
52 import com.sun.tools.javac.parser.ParserFactory; |
48 import com.sun.tools.javac.processing.AnnotationProcessingError; |
53 import com.sun.tools.javac.processing.AnnotationProcessingError; |
49 import com.sun.tools.javac.tree.*; |
54 import com.sun.tools.javac.tree.*; |
50 import com.sun.tools.javac.tree.JCTree.JCClassDecl; |
55 import com.sun.tools.javac.tree.JCTree.JCClassDecl; |
51 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; |
56 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; |
|
57 import com.sun.tools.javac.tree.JCTree.JCModuleDecl; |
|
58 import com.sun.tools.javac.tree.JCTree.Tag; |
52 import com.sun.tools.javac.util.*; |
59 import com.sun.tools.javac.util.*; |
53 import com.sun.tools.javac.util.DefinedBy.Api; |
60 import com.sun.tools.javac.util.DefinedBy.Api; |
54 import com.sun.tools.javac.util.List; |
61 import com.sun.tools.javac.util.List; |
55 import com.sun.tools.javac.util.Log.PrefixKind; |
62 import com.sun.tools.javac.util.Log.PrefixKind; |
56 import com.sun.tools.javac.util.Log.WriterKind; |
63 import com.sun.tools.javac.util.Log.WriterKind; |
251 * Translate all the abstract syntax trees to elements. |
258 * Translate all the abstract syntax trees to elements. |
252 * |
259 * |
253 * @return a list of elements corresponding to the top level |
260 * @return a list of elements corresponding to the top level |
254 * classes in the abstract syntax trees |
261 * classes in the abstract syntax trees |
255 */ |
262 */ |
256 public Iterable<? extends TypeElement> enter() { |
263 public Iterable<? extends Element> enter() { |
257 return enter(null); |
264 return enter(null); |
258 } |
265 } |
259 |
266 |
260 /** |
267 /** |
261 * Translate the given abstract syntax trees to elements. |
268 * Translate the given abstract syntax trees to elements. |
262 * |
269 * |
263 * @param trees a list of abstract syntax trees. |
270 * @param trees a list of abstract syntax trees. |
264 * @return a list of elements corresponding to the top level |
271 * @return a list of elements corresponding to the top level |
265 * classes in the abstract syntax trees |
272 * classes in the abstract syntax trees |
266 */ |
273 */ |
267 public Iterable<? extends TypeElement> enter(Iterable<? extends CompilationUnitTree> trees) |
274 public Iterable<? extends Element> enter(Iterable<? extends CompilationUnitTree> trees) |
268 { |
275 { |
269 if (trees == null && notYetEntered != null && notYetEntered.isEmpty()) |
276 if (trees == null && notYetEntered != null && notYetEntered.isEmpty()) |
270 return List.nil(); |
277 return List.nil(); |
|
278 |
|
279 boolean wasInitialized = compiler != null; |
271 |
280 |
272 prepareCompiler(true); |
281 prepareCompiler(true); |
273 |
282 |
274 ListBuffer<JCCompilationUnit> roots = null; |
283 ListBuffer<JCCompilationUnit> roots = null; |
275 |
284 |
303 else |
312 else |
304 throw new IllegalArgumentException(cu.toString()); |
313 throw new IllegalArgumentException(cu.toString()); |
305 } |
314 } |
306 } |
315 } |
307 |
316 |
308 if (roots == null) |
317 if (roots == null) { |
|
318 if (trees == null && !wasInitialized) { |
|
319 compiler.initModules(List.nil()); |
|
320 } |
309 return List.nil(); |
321 return List.nil(); |
310 |
322 } |
311 try { |
323 |
312 List<JCCompilationUnit> units = compiler.enterTrees(roots.toList()); |
324 List<JCCompilationUnit> units = compiler.initModules(roots.toList()); |
|
325 |
|
326 try { |
|
327 units = compiler.enterTrees(units); |
313 |
328 |
314 if (notYetEntered.isEmpty()) |
329 if (notYetEntered.isEmpty()) |
315 compiler.processAnnotations(units); |
330 compiler.processAnnotations(units); |
316 |
331 |
317 ListBuffer<TypeElement> elements = new ListBuffer<>(); |
332 ListBuffer<Element> elements = new ListBuffer<>(); |
318 for (JCCompilationUnit unit : units) { |
333 for (JCCompilationUnit unit : units) { |
319 for (JCTree node : unit.defs) { |
334 boolean isPkgInfo = unit.sourcefile.isNameCompatible("package-info", |
320 if (node.hasTag(JCTree.Tag.CLASSDEF)) { |
335 JavaFileObject.Kind.SOURCE); |
321 JCClassDecl cdef = (JCClassDecl) node; |
336 if (isPkgInfo) { |
322 if (cdef.sym != null) // maybe null if errors in anno processing |
337 elements.append(unit.packge); |
323 elements.append(cdef.sym); |
338 } else { |
|
339 for (JCTree node : unit.defs) { |
|
340 if (node.hasTag(JCTree.Tag.CLASSDEF)) { |
|
341 JCClassDecl cdef = (JCClassDecl) node; |
|
342 if (cdef.sym != null) // maybe null if errors in anno processing |
|
343 elements.append(cdef.sym); |
|
344 } else if (node.hasTag(JCTree.Tag.MODULEDEF)) { |
|
345 JCModuleDecl mdef = (JCModuleDecl) node; |
|
346 if (mdef.sym != null) |
|
347 elements.append(mdef.sym); |
|
348 } |
324 } |
349 } |
325 } |
350 } |
326 } |
351 } |
327 return elements.toList(); |
352 return elements.toList(); |
328 } |
353 } |
351 * @return the elements that were analyzed |
376 * @return the elements that were analyzed |
352 */ |
377 */ |
353 // This implementation requires that we open up privileges on JavaCompiler. |
378 // This implementation requires that we open up privileges on JavaCompiler. |
354 // An alternative implementation would be to move this code to JavaCompiler and |
379 // An alternative implementation would be to move this code to JavaCompiler and |
355 // wrap it here |
380 // wrap it here |
356 public Iterable<? extends Element> analyze(Iterable<? extends TypeElement> classes) { |
381 public Iterable<? extends Element> analyze(Iterable<? extends Element> classes) { |
357 enter(null); // ensure all classes have been entered |
382 enter(null); // ensure all classes have been entered |
358 |
383 |
359 final ListBuffer<Element> results = new ListBuffer<>(); |
384 final ListBuffer<Element> results = new ListBuffer<>(); |
360 try { |
385 try { |
361 if (classes == null) { |
386 if (classes == null) { |
381 case CLASSDEF: |
406 case CLASSDEF: |
382 JCClassDecl cdef = (JCClassDecl) env.tree; |
407 JCClassDecl cdef = (JCClassDecl) env.tree; |
383 if (cdef.sym != null) |
408 if (cdef.sym != null) |
384 elems.append(cdef.sym); |
409 elems.append(cdef.sym); |
385 break; |
410 break; |
386 case TOPLEVEL: |
411 case MODULEDEF: |
387 JCCompilationUnit unit = (JCCompilationUnit) env.tree; |
412 JCModuleDecl mod = (JCModuleDecl) env.tree; |
|
413 if (mod.sym != null) |
|
414 elems.append(mod.sym); |
|
415 break; |
|
416 case PACKAGEDEF: |
|
417 JCCompilationUnit unit = env.toplevel; |
388 if (unit.packge != null) |
418 if (unit.packge != null) |
389 elems.append(unit.packge); |
419 elems.append(unit.packge); |
390 break; |
420 break; |
391 } |
421 } |
392 } |
422 } |
411 * If null is specified, code will be generated for all outstanding classes. |
441 * If null is specified, code will be generated for all outstanding classes. |
412 * |
442 * |
413 * @param classes a list of class elements |
443 * @param classes a list of class elements |
414 * @return the files that were generated |
444 * @return the files that were generated |
415 */ |
445 */ |
416 public Iterable<? extends JavaFileObject> generate(Iterable<? extends TypeElement> classes) { |
446 public Iterable<? extends JavaFileObject> generate(Iterable<? extends Element> classes) { |
417 final ListBuffer<JavaFileObject> results = new ListBuffer<>(); |
447 final ListBuffer<JavaFileObject> results = new ListBuffer<>(); |
418 try { |
448 try { |
419 analyze(null); // ensure all classes have been parsed, entered, and analyzed |
449 analyze(null); // ensure all classes have been parsed, entered, and analyzed |
420 |
450 |
421 if (classes == null) { |
451 if (classes == null) { |
445 |
475 |
446 public Iterable<? extends Tree> pathFor(CompilationUnitTree unit, Tree node) { |
476 public Iterable<? extends Tree> pathFor(CompilationUnitTree unit, Tree node) { |
447 return TreeInfo.pathFor((JCTree) node, (JCTree.JCCompilationUnit) unit).reverse(); |
477 return TreeInfo.pathFor((JCTree) node, (JCTree.JCCompilationUnit) unit).reverse(); |
448 } |
478 } |
449 |
479 |
|
480 public void ensureEntered() { |
|
481 args.allowEmpty(); |
|
482 enter(null); |
|
483 } |
|
484 |
450 abstract class Filter { |
485 abstract class Filter { |
451 void run(Queue<Env<AttrContext>> list, Iterable<? extends TypeElement> classes) { |
486 void run(Queue<Env<AttrContext>> list, Iterable<? extends Element> elements) { |
452 Set<TypeElement> set = new HashSet<>(); |
487 Set<Element> set = new HashSet<>(); |
453 for (TypeElement item: classes) |
488 for (Element item: elements) { |
454 set.add(item); |
489 set.add(item); |
|
490 } |
455 |
491 |
456 ListBuffer<Env<AttrContext>> defer = new ListBuffer<>(); |
492 ListBuffer<Env<AttrContext>> defer = new ListBuffer<>(); |
457 while (list.peek() != null) { |
493 while (list.peek() != null) { |
458 Env<AttrContext> env = list.remove(); |
494 Env<AttrContext> env = list.remove(); |
459 ClassSymbol csym = env.enclClass.sym; |
495 Symbol test = null; |
460 if (csym != null && set.contains(csym.outermostClass())) |
496 |
|
497 if (env.tree.hasTag(Tag.MODULEDEF)) { |
|
498 test = ((JCModuleDecl) env.tree).sym; |
|
499 } else if (env.tree.hasTag(Tag.PACKAGEDEF)) { |
|
500 test = env.toplevel.packge; |
|
501 } else { |
|
502 ClassSymbol csym = env.enclClass.sym; |
|
503 if (csym != null) |
|
504 test = csym.outermostClass(); |
|
505 } |
|
506 if (test != null && set.contains(test)) |
461 process(env); |
507 process(env); |
462 else |
508 else |
463 defer = defer.append(env); |
509 defer = defer.append(env); |
464 } |
510 } |
465 |
511 |