001: /*
002: * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package javax.tools;
027:
028: import java.io.File;
029: import java.io.InputStream;
030: import java.io.Writer;
031: import java.nio.charset.Charset;
032: import java.util.List;
033: import java.util.Locale;
034: import java.util.concurrent.Callable;
035: import javax.annotation.processing.Processor;
036:
037: /**
038: * Interface to invoke Java™ programming language compilers from
039: * programs.
040: *
041: * <p>The compiler might generate diagnostics during compilation (for
042: * example, error messages). If a diagnostic listener is provided,
043: * the diagnostics will be supplied to the listener. If no listener
044: * is provided, the diagnostics will be formatted in an unspecified
045: * format and written to the default output, which is {@code
046: * System.err} unless otherwise specified. Even if a diagnostic
047: * listener is supplied, some diagnostics might not fit in a {@code
048: * Diagnostic} and will be written to the default output.
049: *
050: * <p>A compiler tool has an associated standard file manager, which
051: * is the file manager that is native to the tool (or built-in). The
052: * standard file manager can be obtained by calling {@linkplain
053: * #getStandardFileManager getStandardFileManager}.
054: *
055: * <p>A compiler tool must function with any file manager as long as
056: * any additional requirements as detailed in the methods below are
057: * met. If no file manager is provided, the compiler tool will use a
058: * standard file manager such as the one returned by {@linkplain
059: * #getStandardFileManager getStandardFileManager}.
060: *
061: * <p>An instance implementing this interface must conform to the Java
062: * Language Specification and generate class files conforming to the
063: * Java Virtual Machine specification. The versions of these
064: * specifications are defined in the {@linkplain Tool} interface.
065: *
066: * Additionally, an instance of this interface supporting {@link
067: * javax.lang.model.SourceVersion#RELEASE_6 SourceVersion.RELEASE_6}
068: * or higher must also support {@linkplain javax.annotation.processing
069: * annotation processing}.
070: *
071: * <p>The compiler relies on two services: {@linkplain
072: * DiagnosticListener diagnostic listener} and {@linkplain
073: * JavaFileManager file manager}. Although most classes and
074: * interfaces in this package defines an API for compilers (and
075: * tools in general) the interfaces {@linkplain DiagnosticListener},
076: * {@linkplain JavaFileManager}, {@linkplain FileObject}, and
077: * {@linkplain JavaFileObject} are not intended to be used in
078: * applications. Instead these interfaces are intended to be
079: * implemented and used to provide customized services for a
080: * compiler and thus defines an SPI for compilers.
081: *
082: * <p>There are a number of classes and interfaces in this package
083: * which are designed to ease the implementation of the SPI to
084: * customize the behavior of a compiler:
085: *
086: * <dl>
087: * <dt>{@link StandardJavaFileManager}</dt>
088: * <dd>
089: *
090: * Every compiler which implements this interface provides a
091: * standard file manager for operating on regular {@linkplain
092: * java.io.File files}. The StandardJavaFileManager interface
093: * defines additional methods for creating file objects from
094: * regular files.
095: *
096: * <p>The standard file manager serves two purposes:
097: *
098: * <ul>
099: * <li>basic building block for customizing how a compiler reads
100: * and writes files</li>
101: * <li>sharing between multiple compilation tasks</li>
102: * </ul>
103: *
104: * <p>Reusing a file manager can potentially reduce overhead of
105: * scanning the file system and reading jar files. Although there
106: * might be no reduction in overhead, a standard file manager must
107: * work with multiple sequential compilations making the following
108: * example a recommended coding pattern:
109: *
110: * <pre>
111: * Files[] files1 = ... ; // input for first compilation task
112: * Files[] files2 = ... ; // input for second compilation task
113: *
114: * JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
115: * StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
116: *
117: * {@code Iterable<? extends JavaFileObject>} compilationUnits1 =
118: * fileManager.getJavaFileObjectsFromFiles({@linkplain java.util.Arrays#asList Arrays.asList}(files1));
119: * compiler.getTask(null, fileManager, null, null, null, compilationUnits1).call();
120: *
121: * {@code Iterable<? extends JavaFileObject>} compilationUnits2 =
122: * fileManager.getJavaFileObjects(files2); // use alternative method
123: * // reuse the same file manager to allow caching of jar files
124: * compiler.getTask(null, fileManager, null, null, null, compilationUnits2).call();
125: *
126: * fileManager.close();</pre>
127: *
128: * </dd>
129: *
130: * <dt>{@link DiagnosticCollector}</dt>
131: * <dd>
132: * Used to collect diagnostics in a list, for example:
133: * <pre>
134: * {@code Iterable<? extends JavaFileObject>} compilationUnits = ...;
135: * JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
136: * {@code DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();}
137: * StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
138: * compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits).call();
139: *
140: * for (Diagnostic diagnostic : diagnostics.getDiagnostics())
141: * System.out.format("Error on line %d in %d%n",
142: * diagnostic.getLineNumber()
143: * diagnostic.getSource().toUri());
144: *
145: * fileManager.close();</pre>
146: * </dd>
147: *
148: * <dt>
149: * {@link ForwardingJavaFileManager}, {@link ForwardingFileObject}, and
150: * {@link ForwardingJavaFileObject}
151: * </dt>
152: * <dd>
153: *
154: * Subclassing is not available for overriding the behavior of a
155: * standard file manager as it is created by calling a method on a
156: * compiler, not by invoking a constructor. Instead forwarding
157: * (or delegation) should be used. These classes makes it easy to
158: * forward most calls to a given file manager or file object while
159: * allowing customizing behavior. For example, consider how to
160: * log all calls to {@linkplain JavaFileManager#flush}:
161: *
162: * <pre>
163: * final {@linkplain java.util.logging.Logger Logger} logger = ...;
164: * {@code Iterable<? extends JavaFileObject>} compilationUnits = ...;
165: * JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
166: * StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, null, null);
167: * JavaFileManager fileManager = new ForwardingJavaFileManager(stdFileManager) {
168: * public void flush() {
169: * logger.entering(StandardJavaFileManager.class.getName(), "flush");
170: * super.flush();
171: * logger.exiting(StandardJavaFileManager.class.getName(), "flush");
172: * }
173: * };
174: * compiler.getTask(null, fileManager, null, null, null, compilationUnits).call();</pre>
175: * </dd>
176: *
177: * <dt>{@link SimpleJavaFileObject}</dt>
178: * <dd>
179: *
180: * This class provides a basic file object implementation which
181: * can be used as building block for creating file objects. For
182: * example, here is how to define a file object which represent
183: * source code stored in a string:
184: *
185: * <pre>
186: * /**
187: * * A file object used to represent source coming from a string.
188: * {@code *}/
189: * public class JavaSourceFromString extends SimpleJavaFileObject {
190: * /**
191: * * The source code of this "file".
192: * {@code *}/
193: * final String code;
194: *
195: * /**
196: * * Constructs a new JavaSourceFromString.
197: * * {@code @}param name the name of the compilation unit represented by this file object
198: * * {@code @}param code the source code for the compilation unit represented by this file object
199: * {@code *}/
200: * JavaSourceFromString(String name, String code) {
201: * super({@linkplain java.net.URI#create URI.create}("string:///" + name.replace('.','/') + Kind.SOURCE.extension),
202: * Kind.SOURCE);
203: * this.code = code;
204: * }
205: *
206: * {@code @}Override
207: * public CharSequence getCharContent(boolean ignoreEncodingErrors) {
208: * return code;
209: * }
210: * }</pre>
211: * </dd>
212: * </dl>
213: *
214: * @author Peter von der Ahé
215: * @author Jonathan Gibbons
216: * @see DiagnosticListener
217: * @see Diagnostic
218: * @see JavaFileManager
219: * @since 1.6
220: */
221: public interface JavaCompiler extends Tool, OptionChecker {
222:
223: /**
224: * Creates a future for a compilation task with the given
225: * components and arguments. The compilation might not have
226: * completed as described in the CompilationTask interface.
227: *
228: * <p>If a file manager is provided, it must be able to handle all
229: * locations defined in {@link StandardLocation}.
230: *
231: * @param out a Writer for additional output from the compiler;
232: * use {@code System.err} if {@code null}
233: * @param fileManager a file manager; if {@code null} use the
234: * compiler's standard filemanager
235: * @param diagnosticListener a diagnostic listener; if {@code
236: * null} use the compiler's default method for reporting
237: * diagnostics
238: * @param options compiler options, {@code null} means no options
239: * @param classes class names (for annotation processing), {@code
240: * null} means no class names
241: * @param compilationUnits the compilation units to compile, {@code
242: * null} means no compilation units
243: * @return an object representing the compilation
244: * @throws RuntimeException if an unrecoverable error
245: * occurred in a user supplied component. The
246: * {@linkplain Throwable#getCause() cause} will be the error in
247: * user code.
248: * @throws IllegalArgumentException if any of the given
249: * compilation units are of other kind than
250: * {@linkplain JavaFileObject.Kind#SOURCE source}
251: */
252: CompilationTask getTask(
253: Writer out,
254: JavaFileManager fileManager,
255: DiagnosticListener<? super JavaFileObject> diagnosticListener,
256: Iterable<String> options, Iterable<String> classes,
257: Iterable<? extends JavaFileObject> compilationUnits);
258:
259: /**
260: * Gets a new instance of the standard file manager implementation
261: * for this tool. The file manager will use the given diagnostic
262: * listener for producing any non-fatal diagnostics. Fatal errors
263: * will be signalled with the appropriate exceptions.
264: *
265: * <p>The standard file manager will be automatically reopened if
266: * it is accessed after calls to {@code flush} or {@code close}.
267: * The standard file manager must be usable with other tools.
268: *
269: * @param diagnosticListener a diagnostic listener for non-fatal
270: * diagnostics; if {@code null} use the compiler's default method
271: * for reporting diagnostics
272: * @param locale the locale to apply when formatting diagnostics;
273: * {@code null} means the {@linkplain Locale#getDefault() default locale}.
274: * @param charset the character set used for decoding bytes; if
275: * {@code null} use the platform default
276: * @return the standard file manager
277: */
278: StandardJavaFileManager getStandardFileManager(
279: DiagnosticListener<? super JavaFileObject> diagnosticListener,
280: Locale locale, Charset charset);
281:
282: /**
283: * Interface representing a future for a compilation task. The
284: * compilation task has not yet started. To start the task, call
285: * the {@linkplain #call call} method.
286: *
287: * <p>Before calling the call method, additional aspects of the
288: * task can be configured, for example, by calling the
289: * {@linkplain #setProcessors setProcessors} method.
290: */
291: interface CompilationTask extends Callable<Boolean> {
292:
293: /**
294: * Sets processors (for annotation processing). This will
295: * bypass the normal discovery mechanism.
296: *
297: * @param processors processors (for annotation processing)
298: * @throws IllegalStateException if the task has started
299: */
300: void setProcessors(Iterable<? extends Processor> processors);
301:
302: /**
303: * Set the locale to be applied when formatting diagnostics and
304: * other localized data.
305: *
306: * @param locale the locale to apply; {@code null} means apply no
307: * locale
308: * @throws IllegalStateException if the task has started
309: */
310: void setLocale(Locale locale);
311:
312: /**
313: * Performs this compilation task. The compilation may only
314: * be performed once. Subsequent calls to this method throw
315: * IllegalStateException.
316: *
317: * @return true if and only all the files compiled without errors;
318: * false otherwise
319: *
320: * @throws RuntimeException if an unrecoverable error occurred
321: * in a user-supplied component. The
322: * {@linkplain Throwable#getCause() cause} will be the error
323: * in user code.
324: * @throws IllegalStateException if called more than once
325: */
326: Boolean call();
327: }
328: }
|