📄 javactaskimpl.java
字号:
public Iterable<? extends TypeElement> enter() throws IOException { return enter(null); } /** * Translate the given abstract syntax trees to elements. * * @param trees a list of abstract syntax trees. * @throws java.io.IOException TODO * @return a list of elements corresponding to the top level * classes in the abstract syntax trees */ public Iterable<? extends TypeElement> enter(Iterable<? extends CompilationUnitTree> trees) throws IOException { prepareCompiler(); ListBuffer<JCCompilationUnit> roots = null; if (trees == null) { // If there are still files which were specified to be compiled // (i.e. in fileObjects) but which have not yet been entered, // then we make sure they have been parsed and add them to the // list to be entered. if (notYetEntered.size() > 0) { if (!parsed) parse(); // TODO would be nice to specify files needed to be parsed for (JavaFileObject file: fileObjects) { JCCompilationUnit unit = notYetEntered.remove(file); if (unit != null) { if (roots == null) roots = new ListBuffer<JCCompilationUnit>(); roots.append(unit); } } notYetEntered.clear(); } } else { for (CompilationUnitTree cu : trees) { if (cu instanceof JCCompilationUnit) { if (roots == null) roots = new ListBuffer<JCCompilationUnit>(); roots.append((JCCompilationUnit)cu); notYetEntered.remove(cu.getSourceFile()); } else throw new IllegalArgumentException(cu.toString()); } } if (roots == null) return List.nil(); try { List<JCCompilationUnit> units = compiler.enterTrees(roots.toList()); if (notYetEntered.isEmpty()) compiler = compiler.processAnnotations(units); ListBuffer<TypeElement> elements = new ListBuffer<TypeElement>(); for (JCCompilationUnit unit : units) { for (JCTree node : unit.defs) if (node.getTag() == JCTree.CLASSDEF) elements.append(((JCTree.JCClassDecl) node).sym); } return elements.toList(); } finally { compiler.log.flush(); } } /** * Complete all analysis. * @throws IOException TODO */ @Override public Iterable<? extends Element> analyze() throws IOException { return analyze(null); } /** * Complete all analysis on the given classes. * This can be used to ensure that all compile time errors are reported. * The classes must have previously been returned from {@link #enter}. * If null is specified, all outstanding classes will be analyzed. * * @param classes a list of class elements */ // This implementation requires that we open up privileges on JavaCompiler. // An alternative implementation would be to move this code to JavaCompiler and // wrap it here public Iterable<? extends Element> analyze(Iterable<? extends TypeElement> classes) throws IOException { enter(null); // ensure all classes have been entered final ListBuffer<Element> results = new ListBuffer<Element>(); try { if (classes == null) { handleFlowResults(compiler.flow(compiler.attribute(compiler.todo)), results); } else { Filter f = new Filter() { public void process(Env<AttrContext> env) { handleFlowResults(compiler.flow(compiler.attribute(env)), results); } }; f.run(compiler.todo, classes); } } finally { compiler.log.flush(); } return results; } // where private void handleFlowResults(List<Env<AttrContext>> list, ListBuffer<Element> elems) { for (Env<AttrContext> env: list) { switch (env.tree.getTag()) { case JCTree.CLASSDEF: JCClassDecl cdef = (JCClassDecl) env.tree; if (cdef.sym != null) elems.append(cdef.sym); break; case JCTree.TOPLEVEL: JCCompilationUnit unit = (JCCompilationUnit) env.tree; if (unit.packge != null) elems.append(unit.packge); break; } } genList.appendList(list); } /** * Generate code. * @throws IOException TODO */ @Override public Iterable<? extends JavaFileObject> generate() throws IOException { return generate(null); } /** * Generate code corresponding to the given classes. * The classes must have previously been returned from {@link #enter}. * If there are classes outstanding to be analyzed, that will be done before * any classes are generated. * If null is specified, code will be generated for all outstanding classes. * * @param classes a list of class elements */ public Iterable<? extends JavaFileObject> generate(Iterable<? extends TypeElement> classes) throws IOException { final ListBuffer<JavaFileObject> results = new ListBuffer<JavaFileObject>(); try { analyze(null); // ensure all classes have been parsed, entered, and analyzed if (classes == null) { compiler.generate(compiler.desugar(genList.toList()), results); genList.clear(); } else { Filter f = new Filter() { public void process(Env<AttrContext> env) { compiler.generate(compiler.desugar(List.of(env)), results); } }; f.run(genList, classes); } if (genList.isEmpty()) { compiler.reportDeferredDiagnostics(); compiler.log.flush(); endContext(); } } finally { compiler.log.flush(); } return results; } public TypeMirror getTypeMirror(Iterable<? extends Tree> path) { // TODO: Should complete attribution if necessary Tree last = null; for (Tree node : path) last = node; return ((JCTree)last).type; } public JavacElements getElements() { if (context == null) throw new IllegalStateException(); return JavacElements.instance(context); } public JavacTypes getTypes() { if (context == null) throw new IllegalStateException(); return JavacTypes.instance(context); } public Iterable<? extends Tree> pathFor(CompilationUnitTree unit, Tree node) { return TreeInfo.pathFor((JCTree) node, (JCTree.JCCompilationUnit) unit).reverse(); } abstract class Filter { void run(ListBuffer<Env<AttrContext>> list, Iterable<? extends TypeElement> classes) { Set<TypeElement> set = new HashSet<TypeElement>(); for (TypeElement item: classes) set.add(item); List<Env<AttrContext>> defer = List.<Env<AttrContext>>nil(); while (list.nonEmpty()) { Env<AttrContext> env = list.next(); ClassSymbol csym = env.enclClass.sym; if (csym != null && set.contains(csym.outermostClass())) process(env); else defer = defer.prepend(env); } for (List<Env<AttrContext>> l = defer; l.nonEmpty(); l = l.tail) list.prepend(l.head); } abstract void process(Env<AttrContext> env); } /** * For internal use by Sun Microsystems only. This method will be * removed without warning. */ public Context getContext() { return context; } /** * For internal use by Sun Microsystems only. This method will be * removed without warning. */ public void updateContext(Context newContext) { context = newContext; } /** * For internal use by Sun Microsystems only. This method will be * removed without warning. */ public Type parseType(String expr, TypeElement scope) { if (expr == null || expr.equals("")) throw new IllegalArgumentException(); compiler = JavaCompiler.instance(context); JavaFileObject prev = compiler.log.useSource(null); Scanner.Factory scannerFactory = Scanner.Factory.instance(context); Parser.Factory parserFactory = Parser.Factory.instance(context); Attr attr = Attr.instance(context); try { Scanner scanner = scannerFactory.newScanner((expr+"\u0000").toCharArray(), expr.length()); Parser parser = parserFactory.newParser(scanner, false, false); JCTree tree = parser.type(); return attr.attribType(tree, (Symbol.TypeSymbol)scope); } finally { compiler.log.useSource(prev); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -