1 /* |
|
2 * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
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 |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 package com.sun.tools.apt.main; |
|
27 |
|
28 import java.io.*; |
|
29 import java.util.Map; |
|
30 |
|
31 import javax.tools.JavaFileManager; |
|
32 import javax.tools.JavaFileObject; |
|
33 |
|
34 import com.sun.tools.javac.file.JavacFileManager; |
|
35 import com.sun.tools.javac.util.*; |
|
36 import com.sun.tools.javac.code.*; |
|
37 import com.sun.tools.javac.jvm.*; |
|
38 |
|
39 import com.sun.tools.javac.code.Symbol.*; |
|
40 import com.sun.tools.javac.tree.JCTree.*; |
|
41 |
|
42 import com.sun.tools.apt.comp.*; |
|
43 import com.sun.tools.apt.util.Bark; |
|
44 import com.sun.mirror.apt.AnnotationProcessorFactory; |
|
45 |
|
46 /** |
|
47 * <p><b>This is NOT part of any supported API. |
|
48 * If you write code that depends on this, you do so at your own |
|
49 * risk. This code and its internal interfaces are subject to change |
|
50 * or deletion without notice.</b> |
|
51 */ |
|
52 @SuppressWarnings("deprecation") |
|
53 public class AptJavaCompiler extends com.sun.tools.javac.main.JavaCompiler { |
|
54 /** The context key for the compiler. */ |
|
55 protected static final Context.Key<AptJavaCompiler> compilerKey = |
|
56 new Context.Key<AptJavaCompiler>(); |
|
57 |
|
58 /** Get the JavaCompiler instance for this context. */ |
|
59 public static AptJavaCompiler instance(Context context) { |
|
60 AptJavaCompiler instance = context.get(compilerKey); |
|
61 if (instance == null) |
|
62 instance = new AptJavaCompiler(context); |
|
63 return instance; |
|
64 } |
|
65 |
|
66 |
|
67 java.util.Set<String> genSourceFileNames; |
|
68 java.util.Set<String> genClassFileNames; |
|
69 |
|
70 public java.util.Set<String> getSourceFileNames() { |
|
71 return genSourceFileNames; |
|
72 } |
|
73 |
|
74 /** List of names of generated class files. |
|
75 */ |
|
76 public java.util.Set<String> getClassFileNames() { |
|
77 return genClassFileNames; |
|
78 } |
|
79 |
|
80 java.util.Set<java.io.File> aggregateGenFiles = java.util.Collections.emptySet(); |
|
81 |
|
82 public java.util.Set<java.io.File> getAggregateGenFiles() { |
|
83 return aggregateGenFiles; |
|
84 } |
|
85 |
|
86 /** The bark to be used for error reporting. |
|
87 */ |
|
88 Bark bark; |
|
89 |
|
90 /** The log to be used for error reporting. |
|
91 */ |
|
92 Log log; |
|
93 |
|
94 /** The annotation framework |
|
95 */ |
|
96 Apt apt; |
|
97 |
|
98 private static Context preRegister(Context context) { |
|
99 Bark.preRegister(context); |
|
100 |
|
101 if (context.get(JavaFileManager.class) == null) |
|
102 JavacFileManager.preRegister(context); |
|
103 |
|
104 return context; |
|
105 } |
|
106 |
|
107 /** Construct a new compiler from a shared context. |
|
108 */ |
|
109 public AptJavaCompiler(Context context) { |
|
110 super(preRegister(context)); |
|
111 |
|
112 context.put(compilerKey, this); |
|
113 apt = Apt.instance(context); |
|
114 |
|
115 ClassReader classReader = ClassReader.instance(context); |
|
116 classReader.preferSource = true; |
|
117 |
|
118 // TEMPORARY NOTE: bark==log, but while refactoring, we maintain their |
|
119 // original identities, to remember the original intent. |
|
120 log = Log.instance(context); |
|
121 bark = Bark.instance(context); |
|
122 |
|
123 Options options = Options.instance(context); |
|
124 classOutput = options.get("-retrofit") == null; |
|
125 nocompile = options.get("-nocompile") != null; |
|
126 print = options.get("-print") != null; |
|
127 classesAsDecls= options.get("-XclassesAsDecls") != null; |
|
128 |
|
129 genSourceFileNames = new java.util.LinkedHashSet<String>(); |
|
130 genClassFileNames = new java.util.LinkedHashSet<String>(); |
|
131 |
|
132 // this forces a copy of the line map to be kept in the tree, |
|
133 // for use by com.sun.mirror.util.SourcePosition. |
|
134 lineDebugInfo = true; |
|
135 } |
|
136 |
|
137 /* Switches: |
|
138 */ |
|
139 |
|
140 /** Emit class files. This switch is always set, except for the first |
|
141 * phase of retrofitting, where signatures are parsed. |
|
142 */ |
|
143 public boolean classOutput; |
|
144 |
|
145 /** The internal printing annotation processor should be used. |
|
146 */ |
|
147 public boolean print; |
|
148 |
|
149 /** Compilation should not be done after annotation processing. |
|
150 */ |
|
151 public boolean nocompile; |
|
152 |
|
153 /** Are class files being treated as declarations |
|
154 */ |
|
155 public boolean classesAsDecls; |
|
156 |
|
157 /** Try to open input stream with given name. |
|
158 * Report an error if this fails. |
|
159 * @param filename The file name of the input stream to be opened. |
|
160 */ |
|
161 // PROVIDED FOR EXTREME BACKWARDS COMPATIBILITY |
|
162 // There are some very obscure errors that can arise while translating |
|
163 // the contents of a file from bytes to characters. In Tiger, these |
|
164 // diagnostics were ignored. This method provides compatibility with |
|
165 // that behavior. It would be better to honor those diagnostics, in which |
|
166 // case, this method can be deleted. |
|
167 @Override |
|
168 public CharSequence readSource(JavaFileObject filename) { |
|
169 try { |
|
170 inputFiles.add(filename); |
|
171 boolean prev = bark.setDiagnosticsIgnored(true); |
|
172 try { |
|
173 return filename.getCharContent(false); |
|
174 } |
|
175 finally { |
|
176 bark.setDiagnosticsIgnored(prev); |
|
177 } |
|
178 } catch (IOException e) { |
|
179 bark.error(Position.NOPOS, "cant.read.file", filename); |
|
180 return null; |
|
181 } |
|
182 } |
|
183 |
|
184 /** Parse contents of input stream. |
|
185 * @param filename The name of the file from which input stream comes. |
|
186 * @param input The input stream to be parsed. |
|
187 */ |
|
188 // PROVIDED FOR BACKWARDS COMPATIBILITY |
|
189 // In Tiger, diagnostics from the scanner and parser were ignored. |
|
190 // This method provides compatibility with that behavior. |
|
191 // It would be better to honor those diagnostics, in which |
|
192 // case, this method can be deleted. |
|
193 @Override |
|
194 protected JCCompilationUnit parse(JavaFileObject filename, CharSequence content) { |
|
195 boolean prev = bark.setDiagnosticsIgnored(true); |
|
196 try { |
|
197 return super.parse(filename, content); |
|
198 } |
|
199 finally { |
|
200 bark.setDiagnosticsIgnored(prev); |
|
201 } |
|
202 } |
|
203 |
|
204 @Override |
|
205 protected boolean keepComments() { |
|
206 return true; // make doc comments available to mirror API impl. |
|
207 } |
|
208 |
|
209 /** Track when the JavaCompiler has been used to compile something. */ |
|
210 private boolean hasBeenUsed = false; |
|
211 |
|
212 /** Main method: compile a list of files, return all compiled classes |
|
213 * @param filenames The names of all files to be compiled. |
|
214 */ |
|
215 public List<ClassSymbol> compile(List<String> filenames, |
|
216 Map<String, String> origOptions, |
|
217 ClassLoader aptCL, |
|
218 AnnotationProcessorFactory providedFactory, |
|
219 java.util.Set<Class<? extends AnnotationProcessorFactory> > productiveFactories, |
|
220 java.util.Set<java.io.File> aggregateGenFiles) |
|
221 throws Throwable { |
|
222 // as a JavaCompiler can only be used once, throw an exception if |
|
223 // it has been used before. |
|
224 assert !hasBeenUsed : "attempt to reuse JavaCompiler"; |
|
225 hasBeenUsed = true; |
|
226 |
|
227 this.aggregateGenFiles = aggregateGenFiles; |
|
228 |
|
229 long msec = System.currentTimeMillis(); |
|
230 |
|
231 ListBuffer<ClassSymbol> classes = new ListBuffer<ClassSymbol>(); |
|
232 try { |
|
233 JavacFileManager fm = (JavacFileManager)fileManager; |
|
234 //parse all files |
|
235 ListBuffer<JCCompilationUnit> trees = new ListBuffer<JCCompilationUnit>(); |
|
236 for (List<String> l = filenames; l.nonEmpty(); l = l.tail) { |
|
237 if (classesAsDecls) { |
|
238 if (! l.head.endsWith(".java") ) { // process as class file |
|
239 ClassSymbol cs = reader.enterClass(names.fromString(l.head)); |
|
240 try { |
|
241 cs.complete(); |
|
242 } catch(Symbol.CompletionFailure cf) { |
|
243 bark.aptError("CantFindClass", l); |
|
244 continue; |
|
245 } |
|
246 |
|
247 classes.append(cs); // add to list of classes |
|
248 continue; |
|
249 } |
|
250 } |
|
251 JavaFileObject fo = fm.getJavaFileObjectsFromStrings(List.of(l.head)).iterator().next(); |
|
252 trees.append(parse(fo)); |
|
253 } |
|
254 |
|
255 //enter symbols for all files |
|
256 List<JCCompilationUnit> roots = trees.toList(); |
|
257 |
|
258 if (errorCount() == 0) { |
|
259 boolean prev = bark.setDiagnosticsIgnored(true); |
|
260 try { |
|
261 enter.main(roots); |
|
262 } |
|
263 finally { |
|
264 bark.setDiagnosticsIgnored(prev); |
|
265 } |
|
266 } |
|
267 |
|
268 if (errorCount() == 0) { |
|
269 apt.main(roots, |
|
270 classes, |
|
271 origOptions, aptCL, |
|
272 providedFactory, |
|
273 productiveFactories); |
|
274 genSourceFileNames.addAll(apt.getSourceFileNames()); |
|
275 genClassFileNames.addAll(apt.getClassFileNames()); |
|
276 } |
|
277 |
|
278 } catch (Abort ex) { |
|
279 } |
|
280 |
|
281 if (verbose) |
|
282 log.printVerbose("total", Long.toString(System.currentTimeMillis() - msec)); |
|
283 |
|
284 chk.reportDeferredDiagnostics(); |
|
285 |
|
286 printCount("error", errorCount()); |
|
287 printCount("warn", warningCount()); |
|
288 |
|
289 return classes.toList(); |
|
290 } |
|
291 } |
|