src/share/classes/javax/tools/JavaCompiler.java

Sat, 01 Dec 2007 00:00:00 +0000

author
duke
date
Sat, 01 Dec 2007 00:00:00 +0000
changeset 1
9a66ca7c79fa
child 375
2ce3597237f0
permissions
-rw-r--r--

Initial load

duke@1 1 /*
duke@1 2 * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
duke@1 7 * published by the Free Software Foundation. Sun designates this
duke@1 8 * particular file as subject to the "Classpath" exception as provided
duke@1 9 * by Sun in the LICENSE file that accompanied this code.
duke@1 10 *
duke@1 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 15 * accompanied this code).
duke@1 16 *
duke@1 17 * You should have received a copy of the GNU General Public License version
duke@1 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 20 *
duke@1 21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
duke@1 22 * CA 95054 USA or visit www.sun.com if you need additional information or
duke@1 23 * have any questions.
duke@1 24 */
duke@1 25
duke@1 26 package javax.tools;
duke@1 27
duke@1 28 import java.io.File;
duke@1 29 import java.io.InputStream;
duke@1 30 import java.io.Writer;
duke@1 31 import java.nio.charset.Charset;
duke@1 32 import java.util.List;
duke@1 33 import java.util.Locale;
duke@1 34 import java.util.concurrent.Callable;
duke@1 35 import javax.annotation.processing.Processor;
duke@1 36
duke@1 37 /**
duke@1 38 * Interface to invoke Java™ programming language compilers from
duke@1 39 * programs.
duke@1 40 *
duke@1 41 * <p>The compiler might generate diagnostics during compilation (for
duke@1 42 * example, error messages). If a diagnostic listener is provided,
duke@1 43 * the diagnostics will be supplied to the listener. If no listener
duke@1 44 * is provided, the diagnostics will be formatted in an unspecified
duke@1 45 * format and written to the default output, which is {@code
duke@1 46 * System.err} unless otherwise specified. Even if a diagnostic
duke@1 47 * listener is supplied, some diagnostics might not fit in a {@code
duke@1 48 * Diagnostic} and will be written to the default output.
duke@1 49 *
duke@1 50 * <p>A compiler tool has an associated standard file manager, which
duke@1 51 * is the file manager that is native to the tool (or built-in). The
duke@1 52 * standard file manager can be obtained by calling {@linkplain
duke@1 53 * #getStandardFileManager getStandardFileManager}.
duke@1 54 *
duke@1 55 * <p>A compiler tool must function with any file manager as long as
duke@1 56 * any additional requirements as detailed in the methods below are
duke@1 57 * met. If no file manager is provided, the compiler tool will use a
duke@1 58 * standard file manager such as the one returned by {@linkplain
duke@1 59 * #getStandardFileManager getStandardFileManager}.
duke@1 60 *
duke@1 61 * <p>An instance implementing this interface must conform to the Java
duke@1 62 * Language Specification and generate class files conforming to the
duke@1 63 * Java Virtual Machine specification. The versions of these
duke@1 64 * specifications are defined in the {@linkplain Tool} interface.
duke@1 65 *
duke@1 66 * Additionally, an instance of this interface supporting {@link
duke@1 67 * javax.lang.model.SourceVersion#RELEASE_6 SourceVersion.RELEASE_6}
duke@1 68 * or higher must also support {@linkplain javax.annotation.processing
duke@1 69 * annotation processing}.
duke@1 70 *
duke@1 71 * <p>The compiler relies on two services: {@linkplain
duke@1 72 * DiagnosticListener diagnostic listener} and {@linkplain
duke@1 73 * JavaFileManager file manager}. Although most classes and
duke@1 74 * interfaces in this package defines an API for compilers (and
duke@1 75 * tools in general) the interfaces {@linkplain DiagnosticListener},
duke@1 76 * {@linkplain JavaFileManager}, {@linkplain FileObject}, and
duke@1 77 * {@linkplain JavaFileObject} are not intended to be used in
duke@1 78 * applications. Instead these interfaces are intended to be
duke@1 79 * implemented and used to provide customized services for a
duke@1 80 * compiler and thus defines an SPI for compilers.
duke@1 81 *
duke@1 82 * <p>There are a number of classes and interfaces in this package
duke@1 83 * which are designed to ease the implementation of the SPI to
duke@1 84 * customize the behavior of a compiler:
duke@1 85 *
duke@1 86 * <dl>
duke@1 87 * <dt>{@link StandardJavaFileManager}</dt>
duke@1 88 * <dd>
duke@1 89 *
duke@1 90 * Every compiler which implements this interface provides a
duke@1 91 * standard file manager for operating on regular {@linkplain
duke@1 92 * java.io.File files}. The StandardJavaFileManager interface
duke@1 93 * defines additional methods for creating file objects from
duke@1 94 * regular files.
duke@1 95 *
duke@1 96 * <p>The standard file manager serves two purposes:
duke@1 97 *
duke@1 98 * <ul>
duke@1 99 * <li>basic building block for customizing how a compiler reads
duke@1 100 * and writes files</li>
duke@1 101 * <li>sharing between multiple compilation tasks</li>
duke@1 102 * </ul>
duke@1 103 *
duke@1 104 * <p>Reusing a file manager can potentially reduce overhead of
duke@1 105 * scanning the file system and reading jar files. Although there
duke@1 106 * might be no reduction in overhead, a standard file manager must
duke@1 107 * work with multiple sequential compilations making the following
duke@1 108 * example a recommended coding pattern:
duke@1 109 *
duke@1 110 * <pre>
duke@1 111 * Files[] files1 = ... ; // input for first compilation task
duke@1 112 * Files[] files2 = ... ; // input for second compilation task
duke@1 113 *
duke@1 114 * JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
duke@1 115 * StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
duke@1 116 *
duke@1 117 * {@code Iterable<? extends JavaFileObject>} compilationUnits1 =
duke@1 118 * fileManager.getJavaFileObjectsFromFiles({@linkplain java.util.Arrays#asList Arrays.asList}(files1));
duke@1 119 * compiler.getTask(null, fileManager, null, null, null, compilationUnits1).call();
duke@1 120 *
duke@1 121 * {@code Iterable<? extends JavaFileObject>} compilationUnits2 =
duke@1 122 * fileManager.getJavaFileObjects(files2); // use alternative method
duke@1 123 * // reuse the same file manager to allow caching of jar files
duke@1 124 * compiler.getTask(null, fileManager, null, null, null, compilationUnits2).call();
duke@1 125 *
duke@1 126 * fileManager.close();</pre>
duke@1 127 *
duke@1 128 * </dd>
duke@1 129 *
duke@1 130 * <dt>{@link DiagnosticCollector}</dt>
duke@1 131 * <dd>
duke@1 132 * Used to collect diagnostics in a list, for example:
duke@1 133 * <pre>
duke@1 134 * {@code Iterable<? extends JavaFileObject>} compilationUnits = ...;
duke@1 135 * JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
duke@1 136 * {@code DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();}
duke@1 137 * StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
duke@1 138 * compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits).call();
duke@1 139 *
duke@1 140 * for (Diagnostic diagnostic : diagnostics.getDiagnostics())
duke@1 141 * System.out.format("Error on line %d in %d%n",
duke@1 142 * diagnostic.getLineNumber()
duke@1 143 * diagnostic.getSource().toUri());
duke@1 144 *
duke@1 145 * fileManager.close();</pre>
duke@1 146 * </dd>
duke@1 147 *
duke@1 148 * <dt>
duke@1 149 * {@link ForwardingJavaFileManager}, {@link ForwardingFileObject}, and
duke@1 150 * {@link ForwardingJavaFileObject}
duke@1 151 * </dt>
duke@1 152 * <dd>
duke@1 153 *
duke@1 154 * Subclassing is not available for overriding the behavior of a
duke@1 155 * standard file manager as it is created by calling a method on a
duke@1 156 * compiler, not by invoking a constructor. Instead forwarding
duke@1 157 * (or delegation) should be used. These classes makes it easy to
duke@1 158 * forward most calls to a given file manager or file object while
duke@1 159 * allowing customizing behavior. For example, consider how to
duke@1 160 * log all calls to {@linkplain JavaFileManager#flush}:
duke@1 161 *
duke@1 162 * <pre>
duke@1 163 * final {@linkplain java.util.logging.Logger Logger} logger = ...;
duke@1 164 * {@code Iterable<? extends JavaFileObject>} compilationUnits = ...;
duke@1 165 * JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
duke@1 166 * StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, null, null);
duke@1 167 * JavaFileManager fileManager = new ForwardingJavaFileManager(stdFileManager) {
duke@1 168 * public void flush() {
duke@1 169 * logger.entering(StandardJavaFileManager.class.getName(), "flush");
duke@1 170 * super.flush();
duke@1 171 * logger.exiting(StandardJavaFileManager.class.getName(), "flush");
duke@1 172 * }
duke@1 173 * };
duke@1 174 * compiler.getTask(null, fileManager, null, null, null, compilationUnits).call();</pre>
duke@1 175 * </dd>
duke@1 176 *
duke@1 177 * <dt>{@link SimpleJavaFileObject}</dt>
duke@1 178 * <dd>
duke@1 179 *
duke@1 180 * This class provides a basic file object implementation which
duke@1 181 * can be used as building block for creating file objects. For
duke@1 182 * example, here is how to define a file object which represent
duke@1 183 * source code stored in a string:
duke@1 184 *
duke@1 185 * <pre>
duke@1 186 * /**
duke@1 187 * * A file object used to represent source coming from a string.
duke@1 188 * {@code *}/
duke@1 189 * public class JavaSourceFromString extends SimpleJavaFileObject {
duke@1 190 * /**
duke@1 191 * * The source code of this "file".
duke@1 192 * {@code *}/
duke@1 193 * final String code;
duke@1 194 *
duke@1 195 * /**
duke@1 196 * * Constructs a new JavaSourceFromString.
duke@1 197 * * {@code @}param name the name of the compilation unit represented by this file object
duke@1 198 * * {@code @}param code the source code for the compilation unit represented by this file object
duke@1 199 * {@code *}/
duke@1 200 * JavaSourceFromString(String name, String code) {
duke@1 201 * super({@linkplain java.net.URI#create URI.create}("string:///" + name.replace('.','/') + Kind.SOURCE.extension),
duke@1 202 * Kind.SOURCE);
duke@1 203 * this.code = code;
duke@1 204 * }
duke@1 205 *
duke@1 206 * {@code @}Override
duke@1 207 * public CharSequence getCharContent(boolean ignoreEncodingErrors) {
duke@1 208 * return code;
duke@1 209 * }
duke@1 210 * }</pre>
duke@1 211 * </dd>
duke@1 212 * </dl>
duke@1 213 *
duke@1 214 * @author Peter von der Ah&eacute;
duke@1 215 * @author Jonathan Gibbons
duke@1 216 * @see DiagnosticListener
duke@1 217 * @see Diagnostic
duke@1 218 * @see JavaFileManager
duke@1 219 * @since 1.6
duke@1 220 */
duke@1 221 public interface JavaCompiler extends Tool, OptionChecker {
duke@1 222
duke@1 223 /**
duke@1 224 * Creates a future for a compilation task with the given
duke@1 225 * components and arguments. The compilation might not have
duke@1 226 * completed as described in the CompilationTask interface.
duke@1 227 *
duke@1 228 * <p>If a file manager is provided, it must be able to handle all
duke@1 229 * locations defined in {@link StandardLocation}.
duke@1 230 *
duke@1 231 * @param out a Writer for additional output from the compiler;
duke@1 232 * use {@code System.err} if {@code null}
duke@1 233 * @param fileManager a file manager; if {@code null} use the
duke@1 234 * compiler's standard filemanager
duke@1 235 * @param diagnosticListener a diagnostic listener; if {@code
duke@1 236 * null} use the compiler's default method for reporting
duke@1 237 * diagnostics
duke@1 238 * @param options compiler options, {@code null} means no options
duke@1 239 * @param classes class names (for annotation processing), {@code
duke@1 240 * null} means no class names
duke@1 241 * @param compilationUnits the compilation units to compile, {@code
duke@1 242 * null} means no compilation units
duke@1 243 * @return an object representing the compilation
duke@1 244 * @throws RuntimeException if an unrecoverable error
duke@1 245 * occurred in a user supplied component. The
duke@1 246 * {@linkplain Throwable#getCause() cause} will be the error in
duke@1 247 * user code.
duke@1 248 * @throws IllegalArgumentException if any of the given
duke@1 249 * compilation units are of other kind than
duke@1 250 * {@linkplain JavaFileObject.Kind#SOURCE source}
duke@1 251 */
duke@1 252 CompilationTask getTask(Writer out,
duke@1 253 JavaFileManager fileManager,
duke@1 254 DiagnosticListener<? super JavaFileObject> diagnosticListener,
duke@1 255 Iterable<String> options,
duke@1 256 Iterable<String> classes,
duke@1 257 Iterable<? extends JavaFileObject> compilationUnits);
duke@1 258
duke@1 259 /**
duke@1 260 * Gets a new instance of the standard file manager implementation
duke@1 261 * for this tool. The file manager will use the given diagnostic
duke@1 262 * listener for producing any non-fatal diagnostics. Fatal errors
duke@1 263 * will be signalled with the appropriate exceptions.
duke@1 264 *
duke@1 265 * <p>The standard file manager will be automatically reopened if
duke@1 266 * it is accessed after calls to {@code flush} or {@code close}.
duke@1 267 * The standard file manager must be usable with other tools.
duke@1 268 *
duke@1 269 * @param diagnosticListener a diagnostic listener for non-fatal
duke@1 270 * diagnostics; if {@code null} use the compiler's default method
duke@1 271 * for reporting diagnostics
duke@1 272 * @param locale the locale to apply when formatting diagnostics;
duke@1 273 * {@code null} means the {@linkplain Locale#getDefault() default locale}.
duke@1 274 * @param charset the character set used for decoding bytes; if
duke@1 275 * {@code null} use the platform default
duke@1 276 * @return the standard file manager
duke@1 277 */
duke@1 278 StandardJavaFileManager getStandardFileManager(
duke@1 279 DiagnosticListener<? super JavaFileObject> diagnosticListener,
duke@1 280 Locale locale,
duke@1 281 Charset charset);
duke@1 282
duke@1 283 /**
duke@1 284 * Interface representing a future for a compilation task. The
duke@1 285 * compilation task has not yet started. To start the task, call
duke@1 286 * the {@linkplain #call call} method.
duke@1 287 *
duke@1 288 * <p>Before calling the call method, additional aspects of the
duke@1 289 * task can be configured, for example, by calling the
duke@1 290 * {@linkplain #setProcessors setProcessors} method.
duke@1 291 */
duke@1 292 interface CompilationTask extends Callable<Boolean> {
duke@1 293
duke@1 294 /**
duke@1 295 * Sets processors (for annotation processing). This will
duke@1 296 * bypass the normal discovery mechanism.
duke@1 297 *
duke@1 298 * @param processors processors (for annotation processing)
duke@1 299 * @throws IllegalStateException if the task has started
duke@1 300 */
duke@1 301 void setProcessors(Iterable<? extends Processor> processors);
duke@1 302
duke@1 303 /**
duke@1 304 * Set the locale to be applied when formatting diagnostics and
duke@1 305 * other localized data.
duke@1 306 *
duke@1 307 * @param locale the locale to apply; {@code null} means apply no
duke@1 308 * locale
duke@1 309 * @throws IllegalStateException if the task has started
duke@1 310 */
duke@1 311 void setLocale(Locale locale);
duke@1 312
duke@1 313 /**
duke@1 314 * Performs this compilation task. The compilation may only
duke@1 315 * be performed once. Subsequent calls to this method throw
duke@1 316 * IllegalStateException.
duke@1 317 *
duke@1 318 * @return true if and only all the files compiled without errors;
duke@1 319 * false otherwise
duke@1 320 *
duke@1 321 * @throws RuntimeException if an unrecoverable error occurred
duke@1 322 * in a user-supplied component. The
duke@1 323 * {@linkplain Throwable#getCause() cause} will be the error
duke@1 324 * in user code.
duke@1 325 * @throws IllegalStateException if called more than once
duke@1 326 */
duke@1 327 Boolean call();
duke@1 328 }
duke@1 329 }

mercurial