103 Iterable<? extends JavaFileObject> fileObjects) { |
103 Iterable<? extends JavaFileObject> fileObjects) { |
104 this(compilerMain, toArray(args), toArray(classes), context, toList(fileObjects)); |
104 this(compilerMain, toArray(args), toArray(classes), context, toList(fileObjects)); |
105 } |
105 } |
106 |
106 |
107 static private String[] toArray(Iterable<String> iter) { |
107 static private String[] toArray(Iterable<String> iter) { |
108 ListBuffer<String> result = new ListBuffer<String>(); |
108 ListBuffer<String> result = new ListBuffer<>(); |
109 if (iter != null) |
109 if (iter != null) |
110 for (String s : iter) |
110 for (String s : iter) |
111 result.append(s); |
111 result.append(s); |
112 return result.toArray(new String[result.length()]); |
112 return result.toArray(new String[result.length()]); |
113 } |
113 } |
114 |
114 |
115 static private List<JavaFileObject> toList(Iterable<? extends JavaFileObject> fileObjects) { |
115 static private List<JavaFileObject> toList(Iterable<? extends JavaFileObject> fileObjects) { |
116 if (fileObjects == null) |
116 if (fileObjects == null) |
117 return List.nil(); |
117 return List.nil(); |
118 ListBuffer<JavaFileObject> result = new ListBuffer<JavaFileObject>(); |
118 ListBuffer<JavaFileObject> result = new ListBuffer<>(); |
119 for (JavaFileObject fo : fileObjects) |
119 for (JavaFileObject fo : fileObjects) |
120 result.append(fo); |
120 result.append(fo); |
121 return result.toList(); |
121 return result.toList(); |
122 } |
122 } |
123 |
123 |
124 public Main.Result doCall() { |
124 public Main.Result doCall() { |
125 if (!used.getAndSet(true)) { |
125 if (!used.getAndSet(true)) { |
126 initContext(); |
126 initContext(); |
127 notYetEntered = new HashMap<JavaFileObject, JCCompilationUnit>(); |
127 notYetEntered = new HashMap<>(); |
128 compilerMain.setAPIMode(true); |
128 compilerMain.setAPIMode(true); |
129 result = compilerMain.compile(args, classNames, context, fileObjects, processors); |
129 result = compilerMain.compile(args, classNames, context, fileObjects, processors); |
130 cleanup(); |
130 cleanup(); |
131 return result; |
131 return result; |
132 } else { |
132 } else { |
158 throw new IllegalStateException(); |
158 throw new IllegalStateException(); |
159 } else { |
159 } else { |
160 initContext(); |
160 initContext(); |
161 compilerMain.log = Log.instance(context); |
161 compilerMain.log = Log.instance(context); |
162 compilerMain.setOptions(Options.instance(context)); |
162 compilerMain.setOptions(Options.instance(context)); |
163 compilerMain.filenames = new LinkedHashSet<File>(); |
163 compilerMain.filenames = new LinkedHashSet<>(); |
164 Collection<File> filenames = compilerMain.processArgs(CommandLine.parse(args), classNames); |
164 Collection<File> filenames = compilerMain.processArgs(CommandLine.parse(args), classNames); |
165 if (filenames != null && !filenames.isEmpty()) |
165 if (filenames != null && !filenames.isEmpty()) |
166 throw new IllegalArgumentException("Malformed arguments " + toString(filenames, " ")); |
166 throw new IllegalArgumentException("Malformed arguments " + toString(filenames, " ")); |
167 compiler = JavaCompiler.instance(context); |
167 compiler = JavaCompiler.instance(context); |
168 compiler.keepComments = true; |
168 compiler.keepComments = true; |
169 compiler.genEndPos = true; |
169 compiler.genEndPos = true; |
170 // NOTE: this value will be updated after annotation processing |
170 // NOTE: this value will be updated after annotation processing |
171 compiler.initProcessAnnotations(processors); |
171 compiler.initProcessAnnotations(processors); |
172 notYetEntered = new HashMap<JavaFileObject, JCCompilationUnit>(); |
172 notYetEntered = new HashMap<>(); |
173 for (JavaFileObject file: fileObjects) |
173 for (JavaFileObject file: fileObjects) |
174 notYetEntered.put(file, null); |
174 notYetEntered.put(file, null); |
175 genList = new ListBuffer<Env<AttrContext>>(); |
175 genList = new ListBuffer<>(); |
176 // endContext will be called when all classes have been generated |
176 // endContext will be called when all classes have been generated |
177 // TODO: should handle the case after each phase if errors have occurred |
177 // TODO: should handle the case after each phase if errors have occurred |
178 args = null; |
178 args = null; |
179 classNames = null; |
179 classNames = null; |
180 } |
180 } |
287 parse(); // TODO would be nice to specify files needed to be parsed |
287 parse(); // TODO would be nice to specify files needed to be parsed |
288 for (JavaFileObject file: fileObjects) { |
288 for (JavaFileObject file: fileObjects) { |
289 JCCompilationUnit unit = notYetEntered.remove(file); |
289 JCCompilationUnit unit = notYetEntered.remove(file); |
290 if (unit != null) { |
290 if (unit != null) { |
291 if (roots == null) |
291 if (roots == null) |
292 roots = new ListBuffer<JCCompilationUnit>(); |
292 roots = new ListBuffer<>(); |
293 roots.append(unit); |
293 roots.append(unit); |
294 } |
294 } |
295 } |
295 } |
296 notYetEntered.clear(); |
296 notYetEntered.clear(); |
297 } |
297 } |
298 } |
298 } |
299 else { |
299 else { |
300 for (CompilationUnitTree cu : trees) { |
300 for (CompilationUnitTree cu : trees) { |
301 if (cu instanceof JCCompilationUnit) { |
301 if (cu instanceof JCCompilationUnit) { |
302 if (roots == null) |
302 if (roots == null) |
303 roots = new ListBuffer<JCCompilationUnit>(); |
303 roots = new ListBuffer<>(); |
304 roots.append((JCCompilationUnit)cu); |
304 roots.append((JCCompilationUnit)cu); |
305 notYetEntered.remove(cu.getSourceFile()); |
305 notYetEntered.remove(cu.getSourceFile()); |
306 } |
306 } |
307 else |
307 else |
308 throw new IllegalArgumentException(cu.toString()); |
308 throw new IllegalArgumentException(cu.toString()); |
316 List<JCCompilationUnit> units = compiler.enterTrees(roots.toList()); |
316 List<JCCompilationUnit> units = compiler.enterTrees(roots.toList()); |
317 |
317 |
318 if (notYetEntered.isEmpty()) |
318 if (notYetEntered.isEmpty()) |
319 compiler = compiler.processAnnotations(units); |
319 compiler = compiler.processAnnotations(units); |
320 |
320 |
321 ListBuffer<TypeElement> elements = new ListBuffer<TypeElement>(); |
321 ListBuffer<TypeElement> elements = new ListBuffer<>(); |
322 for (JCCompilationUnit unit : units) { |
322 for (JCCompilationUnit unit : units) { |
323 for (JCTree node : unit.defs) { |
323 for (JCTree node : unit.defs) { |
324 if (node.hasTag(JCTree.Tag.CLASSDEF)) { |
324 if (node.hasTag(JCTree.Tag.CLASSDEF)) { |
325 JCClassDecl cdef = (JCClassDecl) node; |
325 JCClassDecl cdef = (JCClassDecl) node; |
326 if (cdef.sym != null) // maybe null if errors in anno processing |
326 if (cdef.sym != null) // maybe null if errors in anno processing |
356 // An alternative implementation would be to move this code to JavaCompiler and |
356 // An alternative implementation would be to move this code to JavaCompiler and |
357 // wrap it here |
357 // wrap it here |
358 public Iterable<? extends Element> analyze(Iterable<? extends TypeElement> classes) throws IOException { |
358 public Iterable<? extends Element> analyze(Iterable<? extends TypeElement> classes) throws IOException { |
359 enter(null); // ensure all classes have been entered |
359 enter(null); // ensure all classes have been entered |
360 |
360 |
361 final ListBuffer<Element> results = new ListBuffer<Element>(); |
361 final ListBuffer<Element> results = new ListBuffer<>(); |
362 try { |
362 try { |
363 if (classes == null) { |
363 if (classes == null) { |
364 handleFlowResults(compiler.flow(compiler.attribute(compiler.todo)), results); |
364 handleFlowResults(compiler.flow(compiler.attribute(compiler.todo)), results); |
365 } else { |
365 } else { |
366 Filter f = new Filter() { |
366 Filter f = new Filter() { |
412 * If null is specified, code will be generated for all outstanding classes. |
412 * If null is specified, code will be generated for all outstanding classes. |
413 * |
413 * |
414 * @param classes a list of class elements |
414 * @param classes a list of class elements |
415 */ |
415 */ |
416 public Iterable<? extends JavaFileObject> generate(Iterable<? extends TypeElement> classes) throws IOException { |
416 public Iterable<? extends JavaFileObject> generate(Iterable<? extends TypeElement> classes) throws IOException { |
417 final ListBuffer<JavaFileObject> results = new ListBuffer<JavaFileObject>(); |
417 final ListBuffer<JavaFileObject> results = new ListBuffer<>(); |
418 try { |
418 try { |
419 analyze(null); // ensure all classes have been parsed, entered, and analyzed |
419 analyze(null); // ensure all classes have been parsed, entered, and analyzed |
420 |
420 |
421 if (classes == null) { |
421 if (classes == null) { |
422 compiler.generate(compiler.desugar(genList), results); |
422 compiler.generate(compiler.desugar(genList), results); |
466 return TreeInfo.pathFor((JCTree) node, (JCTree.JCCompilationUnit) unit).reverse(); |
466 return TreeInfo.pathFor((JCTree) node, (JCTree.JCCompilationUnit) unit).reverse(); |
467 } |
467 } |
468 |
468 |
469 abstract class Filter { |
469 abstract class Filter { |
470 void run(Queue<Env<AttrContext>> list, Iterable<? extends TypeElement> classes) { |
470 void run(Queue<Env<AttrContext>> list, Iterable<? extends TypeElement> classes) { |
471 Set<TypeElement> set = new HashSet<TypeElement>(); |
471 Set<TypeElement> set = new HashSet<>(); |
472 for (TypeElement item: classes) |
472 for (TypeElement item: classes) |
473 set.add(item); |
473 set.add(item); |
474 |
474 |
475 ListBuffer<Env<AttrContext>> defer = new ListBuffer<>(); |
475 ListBuffer<Env<AttrContext>> defer = new ListBuffer<>(); |
476 while (list.peek() != null) { |
476 while (list.peek() != null) { |