langtools/src/share/classes/javax/annotation/processing/Processor.java
changeset 10 06bc494ca11e
child 5520 86e4b9a9da40
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/javax/annotation/processing/Processor.java	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,409 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.annotation.processing;
+
+import java.util.Set;
+import javax.lang.model.element.*;
+import javax.lang.model.SourceVersion;
+
+/**
+ * The interface for an annotation processor.
+ *
+ * <p>Annotation processing happens in a sequence of {@linkplain
+ * javax.annotation.processing.RoundEnvironment rounds}.  On each
+ * round, a processor may be asked to {@linkplain #process process} a
+ * subset of the annotations found on the source and class files
+ * produced by a prior round.  The inputs to the first round of
+ * processing are the initial inputs to a run of the tool; these
+ * initial inputs can be regarded as the output of a virtual zeroth
+ * round of processing.  If a processor was asked to process on a
+ * given round, it will be asked to process on subsequent rounds,
+ * including the last round, even if there are no annotations for it
+ * to process.  The tool infrastructure may also ask a processor to
+ * process files generated implicitly by the tool's operation.
+ *
+ * <p> Each implementation of a {@code Processor} must provide a
+ * public no-argument constructor to be used by tools to instantiate
+ * the processor.  The tool infrastructure will interact with classes
+ * implementing this interface as follows:
+ *
+ * <ol>
+ *
+ * <li>If an existing {@code Processor} object is not being used, to
+ * create an instance of a processor the tool calls the no-arg
+ * constructor of the processor class.
+ *
+ * <li>Next, the tool calls the {@link #init init} method with
+ * an appropriate {@code ProcessingEnvironment}.
+ *
+ * <li>Afterwards, the tool calls {@link #getSupportedAnnotationTypes
+ * getSupportedAnnotationTypes}, {@link #getSupportedOptions
+ * getSupportedOptions}, and {@link #getSupportedSourceVersion
+ * getSupportedSourceVersion}.  These methods are only called once per
+ * run, not on each round.
+ *
+ * <li>As appropriate, the tool calls the {@link #process process}
+ * method on the {@code Processor} object; a new {@code Processor}
+ * object is <em>not</em> created for each round.
+ *
+ * </ol>
+ *
+ * If a processor object is created and used without the above
+ * protocol being followed, then the processor's behavior is not
+ * defined by this interface specification.
+ *
+ * <p> The tool uses a <i>discovery process</i> to find annotation
+ * processors and decide whether or not they should be run.  By
+ * configuring the tool, the set of potential processors can be
+ * controlled.  For example, for a {@link javax.tools.JavaCompiler
+ * JavaCompiler} the list of candidate processors to run can be
+ * {@linkplain javax.tools.JavaCompiler.CompilationTask#setProcessors
+ * set directly} or controlled by a {@linkplain
+ * javax.tools.StandardLocation#ANNOTATION_PROCESSOR_PATH search path}
+ * used for a {@linkplain java.util.ServiceLoader service-style}
+ * lookup.  Other tool implementations may have different
+ * configuration mechanisms, such as command line options; for
+ * details, refer to the particular tool's documentation.  Which
+ * processors the tool asks to {@linkplain #process run} is a function
+ * of what annotations are present on the {@linkplain
+ * RoundEnvironment#getRootElements root elements}, what {@linkplain
+ * #getSupportedAnnotationTypes annotation types a processor
+ * processes}, and whether or not a processor {@linkplain #process
+ * claims the annotations it processes}.  A processor will be asked to
+ * process a subset of the annotation types it supports, possibly an
+ * empty set.
+ *
+ * For a given round, the tool computes the set of annotation types on
+ * the root elements.  If there is at least one annotation type
+ * present, as processors claim annotation types, they are removed
+ * from the set of unmatched annotations.  When the set is empty or no
+ * more processors are available, the round has run to completion.  If
+ * there are no annotation types present, annotation processing still
+ * occurs but only <i>universal processors</i> which support
+ * processing {@code "*"} can claim the (empty) set of annotation
+ * types.
+ *
+ * <p>Note that if a processor supports {@code "*"} and returns {@code
+ * true}, all annotations are claimed.  Therefore, a universal
+ * processor being used to, for example, implement additional validity
+ * checks should return {@code false} so as to not prevent other such
+ * checkers from being able to run.
+ *
+ * <p>If a processor throws an uncaught exception, the tool may cease
+ * other active annotation processors.  If a processor raises an
+ * error, the current round will run to completion and the subsequent
+ * round will indicate an {@linkplain RoundEnvironment#errorRaised
+ * error was raised}.  Since annotation processors are run in a
+ * cooperative environment, a processor should throw an uncaught
+ * exception only in situations where no error recovery or reporting
+ * is feasible.
+ *
+ * <p>The tool environment is not required to support annotation
+ * processors that access environmental resources, either {@linkplain
+ * RoundEnvironment per round} or {@linkplain ProcessingEnvironment
+ * cross-round}, in a multi-threaded fashion.
+ *
+ * <p>If the methods that return configuration information about the
+ * annotation processor return {@code null}, return other invalid
+ * input, or throw an exception, the tool infrastructure must treat
+ * this as an error condition.
+ *
+ * <p>To be robust when running in different tool implementations, an
+ * annotation processor should have the following properties:
+ *
+ * <ol>
+ *
+ * <li>The result of processing a given input is not a function of the presence or absence
+ * of other inputs (orthogonality).
+ *
+ * <li>Processing the same input produces the same output (consistency).
+ *
+ * <li>Processing input <i>A</i> followed by processing input <i>B</i>
+ * is equivalent to processing <i>B</i> then <i>A</i>
+ * (commutativity)
+ *
+ * <li>Processing an input does not rely on the presence of the output
+ * of other annotation processors (independence)
+ *
+ * </ol>
+ *
+ * <p>The {@link Filer} interface discusses restrictions on how
+ * processors can operate on files.
+ *
+ * <p>Note that implementors of this interface may find it convenient
+ * to extend {@link AbstractProcessor} rather than implementing this
+ * interface directly.
+ *
+ * @author Joseph D. Darcy
+ * @author Scott Seligman
+ * @author Peter von der Ah&eacute;
+ * @since 1.6
+ */
+public interface Processor {
+    /**
+     * Returns the options recognized by this processor.  An
+     * implementation of the processing tool must provide a way to
+     * pass processor-specific options distinctly from options passed
+     * to the tool itself, see {@link ProcessingEnvironment#getOptions
+     * getOptions}.
+     *
+     * <p>Each string returned in the set must be a period separated
+     * sequence of {@linkplain
+     * javax.lang.model.SourceVersion#isIdentifier identifiers}:
+     *
+     * <blockquote>
+     * <dl>
+     * <dt><i>SupportedOptionString:</i>
+     * <dd><i>Identifiers</i>
+     * <p>
+     * <dt><i>Identifiers:</i>
+     * <dd> <i>Identifier</i>
+     * <dd> <i>Identifier</i> {@code .} <i>Identifiers</i>
+     * <p>
+     * <dt><i>Identifier:</i>
+     * <dd>Syntactic identifier, including keywords and literals
+     * </dl>
+     * </blockquote>
+     *
+     * <p> A tool might use this information to determine if any
+     * options provided by a user are unrecognized by any processor,
+     * in which case it may wish to report a warning.
+     *
+     * @return the options recognized by this processor or an
+     *         empty collection if none
+     * @see javax.annotation.processing.SupportedOptions
+     */
+    Set<String> getSupportedOptions();
+
+    /**
+     * Returns the names of the annotation types supported by this
+     * processor.  An element of the result may be the canonical
+     * (fully qualified) name of a supported annotation type.
+     * Alternately it may be of the form &quot;<tt><i>name</i>.*</tt>&quot;
+     * representing the set of all annotation types with canonical
+     * names beginning with &quot;<tt><i>name.</i></tt>&quot;.  Finally, {@code
+     * "*"} by itself represents the set of all annotation types,
+     * including the empty set.  Note that a processor should not
+     * claim {@code "*"} unless it is actually processing all files;
+     * claiming unnecessary annotations may cause a performance
+     * slowdown in some environments.
+     *
+     * <p>Each string returned in the set must be accepted by the
+     * following grammar:
+     *
+     * <blockquote>
+     * <dl>
+     * <dt><i>SupportedAnnotationTypeString:</i>
+     * <dd><i>TypeName</i> <i>DotStar</i><sub><i>opt</i></sub>
+     * <dd><tt>*</tt>
+     * <p>
+     * <dt><i>DotStar:</i>
+     * <dd><tt>.</tt> <tt>*</tt>
+     * </dl>
+     * </blockquote>
+     *
+     * where <i>TypeName</i> is as defined in the <i>Java Language Specification</i>.
+     *
+     * @return the names of the annotation types supported by this processor
+     * @see javax.annotation.processing.SupportedAnnotationTypes
+     * @jls3 3.8 Identifiers
+     * @jls3 6.5.5 Meaning of Type Names
+     */
+    Set<String> getSupportedAnnotationTypes();
+
+    /**
+     * Returns the latest source version supported by this annotation
+     * processor.
+     *
+     * @return the latest source version supported by this annotation
+     * processor.
+     * @see javax.annotation.processing.SupportedSourceVersion
+     * @see ProcessingEnvironment#getSourceVersion
+     */
+    SourceVersion getSupportedSourceVersion();
+
+    /**
+     * Initializes the processor with the processing environment.
+     *
+     * @param processingEnv environment for facilities the tool framework
+     * provides to the processor
+     */
+    void init(ProcessingEnvironment processingEnv);
+
+    /**
+     * Processes a set of annotation types on type elements
+     * originating from the prior round and returns whether or not
+     * these annotations are claimed by this processor.  If {@code
+     * true} is returned, the annotations are claimed and subsequent
+     * processors will not be asked to process them; if {@code false}
+     * is returned, the annotations are unclaimed and subsequent
+     * processors may be asked to process them.  A processor may
+     * always return the same boolean value or may vary the result
+     * based on chosen criteria.
+     *
+     * <p>The input set will be empty if the processor supports {@code
+     * "*"} and the root elements have no annotations.  A {@code
+     * Processor} must gracefully handle an empty set of annotations.
+     *
+     * @param annotations the annotation types requested to be processed
+     * @param roundEnv  environment for information about the current and prior round
+     * @return whether or not the set of annotations are claimed by this processor
+     */
+    boolean process(Set<? extends TypeElement> annotations,
+                    RoundEnvironment roundEnv);
+
+   /**
+    * Returns to the tool infrastructure an iterable of suggested
+    * completions to an annotation.  Since completions are being asked
+    * for, the information provided about the annotation may be
+    * incomplete, as if for a source code fragment. A processor may
+    * return an empty iterable.  Annotation processors should focus
+    * their efforts on providing completions for annotation members
+    * with additional validity constraints known to the processor, for
+    * example an {@code int} member whose value should lie between 1
+    * and 10 or a string member that should be recognized by a known
+    * grammar, such as a regular expression or a URL.
+    *
+    * <p>Since incomplete programs are being modeled, some of the
+    * parameters may only have partial information or may be {@code
+    * null}.  At least one of {@code element} and {@code userText}
+    * must be non-{@code null}.  If {@code element} is non-{@code
+    * null}, {@code annotation} and {@code member} may be {@code
+    * null}.  Processors may not throw a {@code NullPointerException}
+    * if some parameters are {@code null}; if a processor has no
+    * completions to offer based on the provided information, an
+    * empty iterable can be returned.  The processor may also return
+    * a single completion with an empty value string and a message
+    * describing why there are no completions.
+    *
+    * <p>Completions are informative and may reflect additional
+    * validity checks performed by annotation processors.  For
+    * example, consider the simple annotation:
+    *
+    * <blockquote>
+    * <pre>
+    * &#064;MersennePrime {
+    *    int value();
+    * }
+    * </pre>
+    * </blockquote>
+    *
+    * (A Mersenne prime is prime number of the form
+    * 2<sup><i>n</i></sup> - 1.) Given an {@code AnnotationMirror}
+    * for this annotation type, a list of all such primes in the
+    * {@code int} range could be returned without examining any other
+    * arguments to {@code getCompletions}:
+    *
+    * <blockquote>
+    * <pre>
+    * import static javax.annotation.processing.Completions.*;
+    * ...
+    * return Arrays.asList({@link Completions#of(String) of}(&quot;3&quot;),
+    *                      of(&quot;7&quot;),
+    *                      of(&quot;31&quot;),
+    *                      of(&quot;127&quot;),
+    *                      of(&quot;8191&quot;),
+    *                      of(&quot;131071&quot;),
+    *                      of(&quot;524287&quot;),
+    *                      of(&quot;2147483647&quot;));
+    * </pre>
+    * </blockquote>
+    *
+    * A more informative set of completions would include the number
+    * of each prime:
+    *
+    * <blockquote>
+    * <pre>
+    * return Arrays.asList({@link Completions#of(String, String) of}(&quot;3&quot;,          &quot;M2&quot;),
+    *                      of(&quot;7&quot;,          &quot;M3&quot;),
+    *                      of(&quot;31&quot;,         &quot;M5&quot;),
+    *                      of(&quot;127&quot;,        &quot;M7&quot;),
+    *                      of(&quot;8191&quot;,       &quot;M13&quot;),
+    *                      of(&quot;131071&quot;,     &quot;M17&quot;),
+    *                      of(&quot;524287&quot;,     &quot;M19&quot;),
+    *                      of(&quot;2147483647&quot;, &quot;M31&quot;));
+    * </pre>
+    * </blockquote>
+    *
+    * However, if the {@code userText} is available, it can be checked
+    * to see if only a subset of the Mersenne primes are valid.  For
+    * example, if the user has typed
+    *
+    * <blockquote>
+    * <code>
+    * &#064;MersennePrime(1
+    * </code>
+    * </blockquote>
+    *
+    * the value of {@code userText} will be {@code "1"}; and only
+    * two of the primes are possible completions:
+    *
+    * <blockquote>
+    * <pre>
+    * return Arrays.asList(of(&quot;127&quot;,        &quot;M7&quot;),
+    *                      of(&quot;131071&quot;,     &quot;M17&quot;));
+    * </pre>
+    * </blockquote>
+    *
+    * Sometimes no valid completion is possible.  For example, there
+    * is no in-range Mersenne prime starting with 9:
+    *
+    * <blockquote>
+    * <code>
+    * &#064;MersennePrime(9
+    * </code>
+    * </blockquote>
+    *
+    * An appropriate response in this case is to either return an
+    * empty list of completions,
+    *
+    * <blockquote>
+    * <pre>
+    * return Collections.emptyList();
+    * </pre>
+    * </blockquote>
+    *
+    * or a single empty completion with a helpful message
+    *
+    * <blockquote>
+    * <pre>
+    * return Arrays.asList(of(&quot;&quot;, &quot;No in-range Mersenne primes start with 9&quot;));
+    * </pre>
+    * </blockquote>
+    *
+    * @param element the element being annotated
+    * @param annotation the (perhaps partial) annotation being
+    *                   applied to the element
+    * @param member the annotation member to return possible completions for
+    * @param userText source code text to be completed
+    *
+    * @return suggested completions to the annotation
+    */
+    Iterable<? extends Completion> getCompletions(Element element,
+                                                  AnnotationMirror annotation,
+                                                  ExecutableElement member,
+                                                  String userText);
+}