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