diff -r 000000000000 -r 959103a6100f src/share/classes/javax/annotation/processing/Processor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/javax/annotation/processing/Processor.java Wed Apr 27 01:34:52 2016 +0800 @@ -0,0 +1,441 @@ +/* + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javax.annotation.processing; + +import java.util.Set; +import javax.lang.model.util.Elements; +import javax.lang.model.AnnotatedConstruct; +import javax.lang.model.element.*; +import javax.lang.model.SourceVersion; + +/** + * The interface for an annotation processor. + * + *

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. + * + *

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: + * + *

    + * + *
  1. 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. + * + *
  2. Next, the tool calls the {@link #init init} method with + * an appropriate {@code ProcessingEnvironment}. + * + *
  3. 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. + * + *
  4. As appropriate, the tool calls the {@link #process process} + * method on the {@code Processor} object; a new {@code Processor} + * object is not created for each round. + * + *
+ * + * 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. + * + *

The tool uses a discovery process 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 the types of the annotations {@linkplain AnnotatedConstruct present} + * on the {@linkplain + * RoundEnvironment#getRootElements root elements}, what {@linkplain + * #getSupportedAnnotationTypes annotation types a processor + * supports}, and whether or not a processor {@linkplain #process + * claims the annotation types 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 + * that are present on the elements enclosed within the root elements. + * If there is at least one annotation type present, then as + * processors claim annotation types, they are removed from the set of + * unmatched annotation types. 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 universal processors which support + * processing all annotation types, {@code "*"}, can claim the (empty) + * set of annotation types. + * + *

An annotation type is considered present if there is at least + * one annotation of that type present on an element enclosed within + * the root elements of a round. For this purpose, a type parameter is + * considered to be enclosed by its {@linkplain + * TypeParameterElement#getGenericElement generic + * element}. Annotations on {@linkplain + * java.lang.annotation.ElementType#TYPE_USE type uses}, as opposed to + * annotations on elements, are ignored when computing whether or not + * an annotation type is present. + * + *

An annotation is present if it meets the definition of being + * present given in {@link AnnotatedConstruct}. In brief, an + * annotation is considered present for the purposes of discovery if + * it is directly present or present via inheritance. An annotation is + * not considered present by virtue of being wrapped by a + * container annotation. Operationally, this is equivalent to an + * annotation being present on an element if and only if it would be + * included in the results of {@link + * Elements#getAllAnnotationMirrors(Element)} called on that element. Since + * annotations inside container annotations are not considered + * present, to properly process {@linkplain + * java.lang.annotation.Repeatable repeatable annotation types}, + * processors are advised to include both the repeatable annotation + * type and its containing annotation type in the set of {@linkplain + * #getSupportedAnnotationTypes() supported annotation types} of a + * processor. + * + *

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. + * + *

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. + * + *

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. + * + *

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. + * + *

To be robust when running in different tool implementations, an + * annotation processor should have the following properties: + * + *

    + * + *
  1. The result of processing a given input is not a function of the presence or absence + * of other inputs (orthogonality). + * + *
  2. Processing the same input produces the same output (consistency). + * + *
  3. Processing input A followed by processing input B + * is equivalent to processing B then A + * (commutativity) + * + *
  4. Processing an input does not rely on the presence of the output + * of other annotation processors (independence) + * + *
+ * + *

The {@link Filer} interface discusses restrictions on how + * processors can operate on files. + * + *

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é + * @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}. + * + *

Each string returned in the set must be a period separated + * sequence of {@linkplain + * javax.lang.model.SourceVersion#isIdentifier identifiers}: + * + *

+ *
+ *
SupportedOptionString: + *
Identifiers + * + *
Identifiers: + *
Identifier + *
Identifier {@code .} Identifiers + * + *
Identifier: + *
Syntactic identifier, including keywords and literals + *
+ *
+ * + *

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 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 "name.*" + * representing the set of all annotation types with canonical + * names beginning with "name.". 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. + * + *

Each string returned in the set must be accepted by the + * following grammar: + * + *

+ *
+ *
SupportedAnnotationTypeString: + *
TypeName DotStaropt + *
* + * + *
DotStar: + *
. * + *
+ *
+ * + * where TypeName is as defined in + * The Java™ Language Specification. + * + * @return the names of the annotation types supported by this processor + * @see javax.annotation.processing.SupportedAnnotationTypes + * @jls 3.8 Identifiers + * @jls 6.5.5 Meaning of Type Names + */ + Set 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 annotation types are claimed by this processor. If {@code + * true} is returned, the annotation types are claimed and subsequent + * processors will not be asked to process them; if {@code false} + * is returned, the annotation types 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. + * + *

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 annotation types are claimed by this processor + */ + boolean process(Set 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. + * + *

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. + * + *

Completions are informative and may reflect additional + * validity checks performed by annotation processors. For + * example, consider the simple annotation: + * + *

+ *
+    * @MersennePrime {
+    *    int value();
+    * }
+    * 
+ *
+ * + * (A Mersenne prime is prime number of the form + * 2n - 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}: + * + *
+ *
+    * import static javax.annotation.processing.Completions.*;
+    * ...
+    * return Arrays.asList({@link Completions#of(String) of}("3"),
+    *                      of("7"),
+    *                      of("31"),
+    *                      of("127"),
+    *                      of("8191"),
+    *                      of("131071"),
+    *                      of("524287"),
+    *                      of("2147483647"));
+    * 
+ *
+ * + * A more informative set of completions would include the number + * of each prime: + * + *
+ *
+    * return Arrays.asList({@link Completions#of(String, String) of}("3",          "M2"),
+    *                      of("7",          "M3"),
+    *                      of("31",         "M5"),
+    *                      of("127",        "M7"),
+    *                      of("8191",       "M13"),
+    *                      of("131071",     "M17"),
+    *                      of("524287",     "M19"),
+    *                      of("2147483647", "M31"));
+    * 
+ *
+ * + * 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 + * + *
+ * + * @MersennePrime(1 + * + *
+ * + * the value of {@code userText} will be {@code "1"}; and only + * two of the primes are possible completions: + * + *
+ *
+    * return Arrays.asList(of("127",        "M7"),
+    *                      of("131071",     "M17"));
+    * 
+ *
+ * + * Sometimes no valid completion is possible. For example, there + * is no in-range Mersenne prime starting with 9: + * + *
+ * + * @MersennePrime(9 + * + *
+ * + * An appropriate response in this case is to either return an + * empty list of completions, + * + *
+ *
+    * return Collections.emptyList();
+    * 
+ *
+ * + * or a single empty completion with a helpful message + * + *
+ *
+    * return Arrays.asList(of("", "No in-range Mersenne primes start with 9"));
+    * 
+ *
+ * + * @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 getCompletions(Element element, + AnnotationMirror annotation, + ExecutableElement member, + String userText); +}