Sun, 26 Jul 2009 21:27:11 -0700
6381698: Warn of decommissioning of apt
Reviewed-by: jjg
1 /*
2 * Copyright 2004-2009 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
26 package com.sun.tools.apt.main;
28 import java.io.*;
29 import java.util.Map;
31 import javax.tools.JavaFileManager;
32 import javax.tools.JavaFileObject;
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.*;
39 import com.sun.tools.javac.code.Symbol.*;
40 import com.sun.tools.javac.tree.JCTree.*;
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;
47 /**
48 * <p><b>This is NOT part of any API supported by Sun Microsystems.
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>();
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 }
68 java.util.Set<String> genSourceFileNames;
69 java.util.Set<String> genClassFileNames;
71 public java.util.Set<String> getSourceFileNames() {
72 return genSourceFileNames;
73 }
75 /** List of names of generated class files.
76 */
77 public java.util.Set<String> getClassFileNames() {
78 return genClassFileNames;
79 }
81 java.util.Set<java.io.File> aggregateGenFiles = java.util.Collections.emptySet();
83 public java.util.Set<java.io.File> getAggregateGenFiles() {
84 return aggregateGenFiles;
85 }
87 /** The bark to be used for error reporting.
88 */
89 Bark bark;
91 /** The log to be used for error reporting.
92 */
93 Log log;
95 /** The annotation framework
96 */
97 Apt apt;
99 private static Context preRegister(Context context) {
100 Bark.preRegister(context);
102 // force the use of the scanner that captures Javadoc comments
103 DocCommentScanner.Factory.preRegister(context);
105 if (context.get(JavaFileManager.class) == null)
106 JavacFileManager.preRegister(context);
108 return context;
109 }
111 /** Construct a new compiler from a shared context.
112 */
113 public JavaCompiler(Context context) {
114 super(preRegister(context));
116 context.put(compilerKey, this);
117 apt = Apt.instance(context);
119 ClassReader classReader = ClassReader.instance(context);
120 classReader.preferSource = true;
122 // TEMPORARY NOTE: bark==log, but while refactoring, we maintain their
123 // original identities, to remember the original intent.
124 log = Log.instance(context);
125 bark = Bark.instance(context);
127 Options options = Options.instance(context);
128 classOutput = options.get("-retrofit") == null;
129 nocompile = options.get("-nocompile") != null;
130 print = options.get("-print") != null;
131 classesAsDecls= options.get("-XclassesAsDecls") != null;
133 genSourceFileNames = new java.util.LinkedHashSet<String>();
134 genClassFileNames = new java.util.LinkedHashSet<String>();
136 // this forces a copy of the line map to be kept in the tree,
137 // for use by com.sun.mirror.util.SourcePosition.
138 lineDebugInfo = true;
139 }
141 /* Switches:
142 */
144 /** Emit class files. This switch is always set, except for the first
145 * phase of retrofitting, where signatures are parsed.
146 */
147 public boolean classOutput;
149 /** The internal printing annotation processor should be used.
150 */
151 public boolean print;
153 /** Compilation should not be done after annotation processing.
154 */
155 public boolean nocompile;
157 /** Are class files being treated as declarations
158 */
159 public boolean classesAsDecls;
161 /** Try to open input stream with given name.
162 * Report an error if this fails.
163 * @param filename The file name of the input stream to be opened.
164 */
165 // PROVIDED FOR EXTREME BACKWARDS COMPATIBILITY
166 // There are some very obscure errors that can arise while translating
167 // the contents of a file from bytes to characters. In Tiger, these
168 // diagnostics were ignored. This method provides compatibility with
169 // that behavior. It would be better to honor those diagnostics, in which
170 // case, this method can be deleted.
171 @Override
172 public CharSequence readSource(JavaFileObject filename) {
173 try {
174 inputFiles.add(filename);
175 boolean prev = bark.setDiagnosticsIgnored(true);
176 try {
177 return filename.getCharContent(false);
178 }
179 finally {
180 bark.setDiagnosticsIgnored(prev);
181 }
182 } catch (IOException e) {
183 bark.error(Position.NOPOS, "cant.read.file", filename);
184 return null;
185 }
186 }
188 /** Parse contents of input stream.
189 * @param filename The name of the file from which input stream comes.
190 * @param input The input stream to be parsed.
191 */
192 // PROVIDED FOR BACKWARDS COMPATIBILITY
193 // In Tiger, diagnostics from the scanner and parser were ignored.
194 // This method provides compatibility with that behavior.
195 // It would be better to honor those diagnostics, in which
196 // case, this method can be deleted.
197 @Override
198 protected JCCompilationUnit parse(JavaFileObject filename, CharSequence content) {
199 boolean prev = bark.setDiagnosticsIgnored(true);
200 try {
201 return super.parse(filename, content);
202 }
203 finally {
204 bark.setDiagnosticsIgnored(prev);
205 }
206 }
208 @Override
209 protected boolean keepComments() {
210 return true; // make doc comments available to mirror API impl.
211 }
213 /** Track when the JavaCompiler has been used to compile something. */
214 private boolean hasBeenUsed = false;
216 /** Main method: compile a list of files, return all compiled classes
217 * @param filenames The names of all files to be compiled.
218 */
219 public List<ClassSymbol> compile(List<String> filenames,
220 Map<String, String> origOptions,
221 ClassLoader aptCL,
222 AnnotationProcessorFactory providedFactory,
223 java.util.Set<Class<? extends AnnotationProcessorFactory> > productiveFactories,
224 java.util.Set<java.io.File> aggregateGenFiles)
225 throws Throwable {
226 // as a JavaCompiler can only be used once, throw an exception if
227 // it has been used before.
228 assert !hasBeenUsed : "attempt to reuse JavaCompiler";
229 hasBeenUsed = true;
231 this.aggregateGenFiles = aggregateGenFiles;
233 long msec = System.currentTimeMillis();
235 ListBuffer<ClassSymbol> classes = new ListBuffer<ClassSymbol>();
236 try {
237 JavacFileManager fm = (JavacFileManager)fileManager;
238 //parse all files
239 ListBuffer<JCCompilationUnit> trees = new ListBuffer<JCCompilationUnit>();
240 for (List<String> l = filenames; l.nonEmpty(); l = l.tail) {
241 if (classesAsDecls) {
242 if (! l.head.endsWith(".java") ) { // process as class file
243 ClassSymbol cs = reader.enterClass(names.fromString(l.head));
244 try {
245 cs.complete();
246 } catch(Symbol.CompletionFailure cf) {
247 bark.aptError("CantFindClass", l);
248 continue;
249 }
251 classes.append(cs); // add to list of classes
252 continue;
253 }
254 }
255 JavaFileObject fo = fm.getJavaFileObjectsFromStrings(List.of(l.head)).iterator().next();
256 trees.append(parse(fo));
257 }
259 //enter symbols for all files
260 List<JCCompilationUnit> roots = trees.toList();
262 if (errorCount() == 0) {
263 boolean prev = bark.setDiagnosticsIgnored(true);
264 try {
265 enter.main(roots);
266 }
267 finally {
268 bark.setDiagnosticsIgnored(prev);
269 }
270 }
272 if (errorCount() == 0) {
273 apt.main(roots,
274 classes,
275 origOptions, aptCL,
276 providedFactory,
277 productiveFactories);
278 genSourceFileNames.addAll(apt.getSourceFileNames());
279 genClassFileNames.addAll(apt.getClassFileNames());
280 }
282 } catch (Abort ex) {
283 }
285 if (verbose)
286 printVerbose("total", Long.toString(System.currentTimeMillis() - msec));
288 chk.reportDeferredDiagnostics();
290 printCount("error", errorCount());
291 printCount("warn", warningCount());
293 return classes.toList();
294 }
295 }