From 97042d5a16892aecc881471cdbfea7e20ddfd358 Mon Sep 17 00:00:00 2001 From: Andrew John Hughes Date: Tue, 18 Dec 2012 23:04:06 +0000 Subject: Add remaining javax.tools interfaces. 2012-12-18 Andrew John Hughes * javax/tools/JavaCompiler.java: New interface added. (CompilationTask): New inner interface. (CompilationTask.call()): Added. (CompilationTask.setLocale(Locale)): Likewise. (CompilationTask.setProcessors(Iterable)): Likewise. (getStandardFileManager(DiagnosticListener,Locale,Charset)): Likewise. (getTask(Writer,DiagnosticListener,Iterable,Iterable,Iterable)): Likewise. * javax/tools/StandardJavaFileManager.java: New interface added. (getJavaFileObjects(File...)): Added. (getJavaFileObjects(String...)): Likewise. (getJavaFileObjectsFromFiles(Iterable)): Likewise. (getJavaFileObjectsFromStrings(Iterable)): Likewise. (getLocation(Location)): Likewise. (isSameFile(FileObject,FileObject)): Likewise. (setLocation(Location,Iterable)): Likewise. * javax/tools/Tool.java: New interface added. (getSourceVersions()): Added. (run(InputStream,OutputStream,OutputStream,String...)): Likewise. Signed-off-by: Andrew John Hughes --- ChangeLog | 26 ++++ javax/tools/JavaCompiler.java | 213 +++++++++++++++++++++++++++++++ javax/tools/StandardJavaFileManager.java | 166 ++++++++++++++++++++++++ javax/tools/Tool.java | 84 ++++++++++++ 4 files changed, 489 insertions(+) create mode 100644 javax/tools/JavaCompiler.java create mode 100644 javax/tools/StandardJavaFileManager.java create mode 100644 javax/tools/Tool.java diff --git a/ChangeLog b/ChangeLog index 40e4ce944..cb990468f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2012-12-18 Andrew John Hughes + + * javax/tools/JavaCompiler.java: + New interface added. + (CompilationTask): New inner interface. + (CompilationTask.call()): Added. + (CompilationTask.setLocale(Locale)): Likewise. + (CompilationTask.setProcessors(Iterable)): Likewise. + (getStandardFileManager(DiagnosticListener,Locale,Charset)): + Likewise. + (getTask(Writer,DiagnosticListener,Iterable,Iterable,Iterable)): + Likewise. + * javax/tools/StandardJavaFileManager.java: + New interface added. + (getJavaFileObjects(File...)): Added. + (getJavaFileObjects(String...)): Likewise. + (getJavaFileObjectsFromFiles(Iterable)): Likewise. + (getJavaFileObjectsFromStrings(Iterable)): Likewise. + (getLocation(Location)): Likewise. + (isSameFile(FileObject,FileObject)): Likewise. + (setLocation(Location,Iterable)): Likewise. + * javax/tools/Tool.java: + New interface added. + (getSourceVersions()): Added. + (run(InputStream,OutputStream,OutputStream,String...)): Likewise. + 2012-11-30 Andrew John Hughes * javax/lang/model/type/ArrayType.java: diff --git a/javax/tools/JavaCompiler.java b/javax/tools/JavaCompiler.java new file mode 100644 index 000000000..e1a8430c4 --- /dev/null +++ b/javax/tools/JavaCompiler.java @@ -0,0 +1,213 @@ +/* JavaCompiler.java -- Programmatic interface for a compiler. + Copyright (C) 2012 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.tools; + +import java.io.Writer; + +import java.nio.charset.Charset; + +import java.util.Locale; + +import java.util.concurrent.Callable; + +import javax.annotation.processing.Processor; + +/** + *

+ * Provides a programmatic interface to a compiler for the Java + * programming language. The compiler relies on two services; + * a diagnostic listener for producing textual output including + * warnings or errors from the code, and a file manager for providing + * access to the files to be compiled and the output location. + * More detail on these services and various helper classes related + * to them is provided below. The classes {@link DiagnosticListener}, + * {@link JavaFileManager}, {@link FileObject} and {@link JavaFileObject} + * provide the service provider interface for these services and are not + * intended for user consumption.

+ *

Compilers implementing {@link JavaCompiler} must conform to the Java + * Language Specification and produce class files conforming to the + * Java Virtual Machine Specification. In addition, those compilers + * which claim to support {@link SourceVersion#RELEASE_6} or later + * must support annotation processing.

+ *

Diagnostics

+ *

Where possible, the compiler provides diagnostic output to + * a {@link DiagnosticListener} if provided. If a listener is + * not provided, diagnostics are instead written to the default + * output ({@code{System.err} by default). This may also happen + * where the diagnostics are inappropriate for a {@link Diagnostic} + * object. The class {@link DiagnosticCollector} provides a means + * collate together multiple {@link Diagnostic}s in a list.

+ *

The File Manager

+ *

A compiler tool has an associated standard file manager which + * is native to it. An instance of it can be obtained by calling + * {@link #getStandardFileManager(DiagnosticListener,Locale,Charset)} + * and this is automatically called if no file manager is supplied to + * the compiler. However, the compiler must work with other file + * managers, provided they meet the requirements detailed in the methods + * below. Such file managers allow the user to customise how the compiler + * reads and writes files, and can be shared between multiple compilation + * tasks. Such reuse between different tasks can potentially provide + * a performance improvement.

+ *

The standard file manager returned by this interface is an instance + * of the subinterface, {@link StandardJavaFileManager}, which is intended + * for operating on regular files and provides additional methods to support + * this.

+ *

All file managers return a {@link FileObject} which provides an + * abstraction from the underlying file. The class {@link SimpleJavaFileObject} + * is provided as a means to simplifying implementing this interface.

+ *

Forwarding

+ *

As file managers and file objects are provided as return values from + * the methods of {@link JavaCompiler} and the file manager respectively, + * there is no means to override their behaviour by subclassing. Instead, + * it is necessary to wrap the returned instance in another implementation + * and forward method calls to it as appropriate. The classes + * {@link ForwardingJavaFileManager}, {@link ForwardingFileObject} and + * {@link ForwardingJavaFileObject} facilitate this by providing an + * implementation that simply forwards to another, which can then be subclassed + * to provide additional behaviour.

+ * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.6 + */ +public interface JavaCompiler + extends Tool, OptionChecker +{ + + /** + * Interface representing a compilation task as an asynchronous + * event or {@link java.util.concurrent.Future}. The task may be + * started by invoking {@link #call()}. Prior to this, the task + * may be configured by the user using the other methods of this + * interface. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.6 + */ + public static interface CompilationTask + extends Callable + { + + /** + * Performs the compilation. The compilation may only + * be performed once. Subsequent calls will throw + * an {@link IllegalStateException}. + * + * @return true if all files were successfully compiled. + * @throws RuntimeException if an unrecoverable error occurred + * in a user-supplied component of + * the compilation process. The user + * exception will be provided as the + * cause of this exception. + * @throws IllegalStateException if the compilation has already run. + */ + Boolean call(); + + /** + * Sets the locale to use for outputting diagnostics. + * + * @param locale the locale to use. A value of {@code null} + * means no locale is applied. + * @throws IllegalStateException if the compilation has started. + */ + void setLocale(Locale locale); + + /** + * Explicitly set the annotation processors to be used, + * overriding the usual discovery process. + * + * @param processors the processors to use. + * @throws IllegalStateException if the compilation has started. + */ + void setProcessors(Iterable processors); + + } + + /** + * Returns a new instance of the standard file manager implementation + * used by this tool. Any non-fatal diagnostics produced by the tool + * will be passed to the specified {@link DiagnosticListener}, if + * supplied, using the given locale. Calls to the file manager after + * a {@link JavaFileManager#flush()} or {@link JavaFileManager#close()} + * will cause the file manager to be reopened. The file manager must + * be usable with other tools. + * + * @param listener the diagnostic listener to use or {@code null} if + * the compiler should use its own methods for producing + * diagnostics. + * @param locale the locale to use to format the diagnostics or {@code null} + * to use the default locale. + * @param charset the character set to use for decoding bytes or {@code null} + * to use the platform default. + * @return the standard file manager implementation. + */ + StandardJavaFileManager getStandardFileManager(DiagnosticListener listener, + Locale locale, Charset charset); + + /** + * Returns an asynchrononous task for performing the specified compilation. + * The compilation may not have completed upon return of this method. + * If a file manager is specified, it must supported all locations specified + * in {@link StandardLocation}. + * + * @param out the output stream for compiler output beyond that provided by + * diagnostics; {@code System.err} is used if this is {@code null}. + * @param fileManager the file manager to use or {@code null} to use a new + * instance from + * {@link #getStandardFileManaager(DiagnosticListener,Locale,Charset)} + * @param listener the listener to pass diagnostic output to, or + * {@code null} if the compiler's default method should + * be used instead. + * @param options the options to supply to the compiler or {@code null} if there are none. + * @param classes the names of classes to use for annotation processing or {@code null} + * if there are none. + * @param objects the file objects to compile, or {@code null} if there are none. + * @return a task representing the proposed compilation. + * @throws RuntimeException if an unrecoverable error occurred + * in a user-supplied component of + * the compilation process. The user + * exception will be provided as the + * cause of this exception. + * @throws IllegalArgumentException if the kind of any of the objects is something + * other than {@link JavaFileObject.Kind#SOURCE}. + */ + CompilationTask getTask(Writer out, JavaFileManager fileManager, + DiagnosticListener listener, + Iterable options, Iterable classes, + Iterable objects); + +} diff --git a/javax/tools/StandardJavaFileManager.java b/javax/tools/StandardJavaFileManager.java new file mode 100644 index 000000000..f938469a5 --- /dev/null +++ b/javax/tools/StandardJavaFileManager.java @@ -0,0 +1,166 @@ +/* StandardJavaFileManager.java -- File manager for regular files. + Copyright (C) 2012 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.tools; + +import java.io.File; +import java.io.IOException; + +/** + *

File manager for working with regular files or entries + * within file system containers, such as zip files. An + * implementation of this interface is usually retrieved using the + * {@link javax.tools.JavaCompiler#getStandardFileManager(DiagnosticListener,Locale,Charset)} + * of {@link javax.tools.JavaCompiler}, an instance of which + * is, in turn, returned from + * {@link javax.tools.ToolProvider#getSystemJavaCompiler()}.

+ *

Regular file objects returned from a file manager implementing this + * interface must meet the following criteria:

+ *
    + *
  • {@link FileObject#delete()} is equivalent to + * {@link java.io.File#delete()}.
  • + *
  • {@link FileObject#getLastModified} is equivalent to + * {@link java.io.File#lastModified}.
  • + *
  • Methods for reading input ({@link FileObject#getCharContent(boolean)}, + * {@link FileObject#openInputStream()}, + * {@link FileObject#openReader(boolean)}) must succeed, + * ignoring character encoding issues, if + * {@code new FileInputStream(new File(fileObj.toUri()))}.
  • + *
  • Methods for writing output ({@link FileObject#openOutputStream()}, + * {@link FileObject.openWriter()}) must succeed, + * ignoring character encoding issues, if + * {@code new FileOutputStream(new File(fileObj.toUri()))}.
  • + *
  • The URI returned from {@link FileObject#toUri()} must + * be have a schema and a normalised path component, which can + * be resolved without regard to context (i.e. it must be absolute, + * not relative to a particular directory). For example, the + * URI {@code file:///home/bob/sources} would be valid, while + * {@code file:sources} (not absolute) or + * {@code file:///home/bob/lib/../sources} (not normalised) would + * not.

  • + *
+ *

The file names used by the file objects need not be canonical.

+ * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.6 + */ +public interface StandardJavaFileManager + extends JavaFileManager +{ + + /** + * Returns file objects representing the given files. This is + * a convenience method equivalent to calling + * {@code getJavaFileObjectsFromFiles(Arrays.asList(files))}. + * + * @param files the files to retrieve objects for. + * @return a list of file objects matching the specified array. + * @throws IllegalArgumentException if the array contains a directory. + * @throws NullPointerException if one of the array elements is {@code null}. + */ + Iterable getJavaFileObjects(File... files); + + /** + * Returns file objects representing the given file names. This is + * a convenience method equivalent to calling + * {@code getJavaFileObjectsFromString(Arrays.asList(fileNames))}. + * + * @param fileNames the file names to retrieve objects for. + * @return a list of file objects matching the specified array. + * @throws IllegalArgumentException if the array contains a directory. + * @throws NullPointerException if one of the array elements is {@code null}. + */ + Iterable getJavaFileObjects(String... files); + + /** + * Returns file objects representing the given files. + * + * @param files the files to retrieve objects for. + * @return a list of file objects. + * @throws IllegalArgumentException if the array contains a directory. + */ + Iterable getJavaFileObjectsFromFiles(Iterable files); + + /** + * Returns file objects representing the given file names. + * + * @param fileNames the file names to retrieve objects for. + * @return a list of file objects. + * @throws IllegalArgumentException if the array contains a directory. + */ + Iterable getJavaFileObjectsFromStrings(Iterable files); + + /** + * Returns the list of paths associated with the specified location or + * {@code null} if there is no such mapping. Output locations only + * return a single path, representing the output directory. + * + * @param location the location whose path should be retrieved. + * @return the associated list of paths. + * @see #setLocation(Location,Iterable) + */ + Iterable getLocation(Location location); + + /** + * Returns true if the two file objects represent the same + * file. + * + * @param objA the first file object to compare. + * @param objB the second file object to compare. + * @return true if the two objects represent the same file. + * @throws IllegalArgumentException if either object was created + * by a different implementation. + */ + boolean isSameFile(FileObject objA, FileObject objB); + + /** + * Associates the given list of paths with the specified location, + * discarding any previous mapping. If the list is {@code null}, + * the mapping is reset to the default. + * + * @param location the location which will refer to this list of paths. + * @param paths a list of paths to associate with the location, or + * {@code null} to trigger a reset to the default list. + * @throws IllegalArgumentException if the location is an output location + * and the list contains more than one path. + * @throws IOException if the location is an output location but + * the list contains a path that isn't a directory. + * @see #getLocation(Location) + */ + void setLocation(Location location, Iterable paths) + throws IOException; +} diff --git a/javax/tools/Tool.java b/javax/tools/Tool.java new file mode 100644 index 000000000..a1b707029 --- /dev/null +++ b/javax/tools/Tool.java @@ -0,0 +1,84 @@ +/* Tool.java -- Interface for programatically-invokable tools. + Copyright (C) 2012 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.tools; + +import java.io.InputStream; +import java.io.OutputStream; + +import java.util.Set; + +import javax.lang.model.SourceVersion; + +/** + * Interface for tools than be invoked from a program. Tools + * can be located using {@link java.util.ServiceLoader#load(Class)}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.6 + */ +public interface Tool +{ + + /** + * Returns the set of source language versions that are supported + * by this tool. + * + * @return the set of supported source code versions. + */ + Set getSourceVersions(); + + /** + * Invokes the tool using the specified input/output streams and + * arguments, returning the same exit code it would if called from + * the command line. Traditionally, zero indicates success and non-zero + * is used for errors. Diagnostics from the tool will be written + * to {@code out} or {@code err} in a way specific to the tool. + * + * @param in the standard input for the tool or {@code null} to use + * {@code System.in}. + * @param out the standard output for the tool or {@code null} to use + * {@code System.out} + * @param err the standard error stream for the tool or {@code null} + * to use {@code System.err}. + * @param args the arguments to pass to the tool. + * @return the return code from the tool. + * @throws NullPointerException if any argument is {@code null}. + */ + int run(InputStream in, OutputStream out, OutputStream err, + String... arguments); +} -- cgit v1.2.1