8163315: Implement an API to identify an implicitly declared annotation (or declaration)
authordarcy
Fri, 16 Dec 2016 12:04:32 +0100
changeset 42825 c22877f68145
parent 42824 89b14017e8d6
child 42826 563b42fc70ba
8163315: Implement an API to identify an implicitly declared annotation (or declaration) Summary: Adding javax.lang.model.util.Elements.getOrigin Reviewed-by: jjg
langtools/src/java.compiler/share/classes/javax/lang/model/element/package-info.java
langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/package-info.java	Fri Dec 16 12:02:30 2016 +0100
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/package-info.java	Fri Dec 16 12:04:32 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -53,7 +53,9 @@
  * Names of parameters may not be recoverable from class files.
  *
  * The {@linkplain javax.lang.model.element.Modifier modifiers} on an
- * element may differ in some cases including:
+ * element created from a class file may differ in some cases from an
+ * element for the same declaration created from a source file
+ * including:
  *
  * <ul>
  * <li> {@code strictfp} on a class or interface
@@ -61,10 +63,19 @@
  * <li> {@code protected}, {@code private}, and {@code static} on classes and interfaces
  * </ul>
  *
- * Additionally, synthetic constructs in a class file, such as
- * accessor methods used in implementing nested classes and bridge
- * methods used in implementing covariant returns, are translation
- * artifacts outside of this model.
+ * Some elements which are {@linkplain
+ * javax.lang.model.util.Elements.Origin#MANDATED mandated} may not be
+ * marked as such when created from class files.
+ *
+ * Additionally, {@linkplain
+ * javax.lang.model.util.Elements.Origin#SYNTHETIC synthetic}
+ * constructs in a class file, such as accessor methods used in
+ * implementing nested classes and {@linkplain
+ * javax.lang.model.util.Elements.Origin#isBridge(ExecutableElement)
+ * bridge methods} used in implementing covariant returns, are
+ * translation artifacts strictly outside of this model. However, when
+ * operating on class files, it is helpful be able to operate on such
+ * elements, screening them out when appropriate.
  *
  * <p>During annotation processing, operating on incomplete or
  * erroneous programs is necessary; however, there are fewer
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java	Fri Dec 16 12:02:30 2016 +0100
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java	Fri Dec 16 12:04:32 2016 +0100
@@ -29,6 +29,7 @@
 import java.util.List;
 import java.util.Map;
 
+import javax.lang.model.AnnotatedConstruct;
 import javax.lang.model.element.*;
 
 
@@ -143,6 +144,167 @@
     boolean isDeprecated(Element e);
 
     /**
+     * Returns the <em>origin</em> of the given element.
+     *
+     * <p>Note that if this method returns {@link Origin#EXPLICIT
+     * EXPLICIT} and the element was created from a class file, then
+     * the element may not, in fact, correspond to an explicitly
+     * declared construct in source code. This is due to limitations
+     * of the fidelity of the class file format in preserving
+     * information from source code. For example, at least some
+     * versions of the class file format do not preserve whether a
+     * constructor was explicitly declared by the programmer or was
+     * implicitly declared as the <em>default constructor</em>.
+     *
+     * @implSpec The default implementation of this method returns
+     * {@link Origin#EXPLICIT EXPLICIT}.
+     *
+     * @param e  the element being examined
+     * @return the origin of the given element
+     * @since 9
+     */
+    default Origin getOrigin(Element e) {
+        return Origin.EXPLICIT;
+    }
+
+    /**
+     * Returns the <em>origin</em> of the given annotation mirror.
+     *
+     * An annotation mirror is {@linkplain Origin#MANDATED mandated}
+     * if it is an implicitly declared <em>container annotation</em>
+     * used to hold repeated annotations of a repeatable annotation
+     * type.
+     *
+     * <p>Note that if this method returns {@link Origin#EXPLICIT
+     * EXPLICIT} and the annotation mirror was created from a class
+     * file, then the element may not, in fact, correspond to an
+     * explicitly declared construct in source code. This is due to
+     * limitations of the fidelity of the class file format in
+     * preserving information from source code. For example, at least
+     * some versions of the class file format do not preserve whether
+     * an annotation was explicitly declared by the programmer or was
+     * implicitly declared as a <em>container annotation</em>.
+     *
+     * @implSpec The default implementation of this method returns
+     * {@link Origin#EXPLICIT EXPLICIT}.
+     *
+     * @param c the construct the annotation mirror modifies
+     * @param a the annotation mirror being examined
+     * @return the origin of the given annotation mirror
+     * @jls 9.6.3 Repeatable Annotation Types
+     * @jls 9.7.5 Multiple Annotations of the Same Type
+     * @since 9
+     */
+    default Origin getOrigin(AnnotatedConstruct c,
+                             AnnotationMirror a) {
+        return Origin.EXPLICIT;
+    }
+
+    /**
+     * Returns the <em>origin</em> of the given module directive.
+     *
+     * <p>Note that if this method returns {@link Origin#EXPLICIT
+     * EXPLICIT} and the module directive was created from a class
+     * file, then the module directive may not, in fact, correspond to
+     * an explicitly declared construct in source code. This is due to
+     * limitations of the fidelity of the class file format in
+     * preserving information from source code. For example, at least
+     * some versions of the class file format do not preserve whether
+     * a {@code uses} directive was explicitly declared by the
+     * programmer or was added as a synthetic construct.
+     *
+     * <p>Note that an implementation may not be able to reliably
+     * determine the origin status of the directive if the directive
+     * is created from a class file due to limitations of the fidelity
+     * of the class file format in preserving information from source
+     * code.
+     *
+     * @implSpec The default implementation of this method returns
+     * {@link Origin#EXPLICIT EXPLICIT}.
+     *
+     * @param m the module of the directive
+     * @param directive  the module directive being examined
+     * @return the origin of the given directive
+     * @since 9
+     */
+    default Origin getOrigin(ModuleElement m,
+                             ModuleElement.Directive directive) {
+        return Origin.EXPLICIT;
+    }
+
+    /**
+     * The <em>origin</em> of an element or other language model
+     * item. The origin of an element or item models how a construct
+     * in a program is declared in the source code, explicitly,
+     * implicitly, etc.
+     *
+     * <p>Note that it is possible additional kinds of origin values
+     * will be added in future versions of the platform.
+     *
+     * @jls 13.1 The Form of a Binary
+     * @since 9
+     */
+    public enum Origin {
+        /**
+         * Describes a construct explicitly declared in source code.
+         */
+        EXPLICIT,
+
+       /**
+         * A mandated construct is one that is not explicitly declared
+         * in the source code, but whose presence is mandated by the
+         * specification. Such a construct is said to be implicitly
+         * declared.
+         *
+         * One example of a mandated element is a <em>default
+         * constructor</em> in a class that contains no explicit
+         * constructor declarations.
+         *
+         * Another example of a mandated construct is an implicitly
+         * declared <em>container annotation</em> used to hold
+         * multiple annotations of a repeatable annotation type.
+         *
+         * @jls 8.8.9 Default Constructor
+         * @jls 9.6.3 Repeatable Annotation Types
+         * @jls 9.7.5 Multiple Annotations of the Same Type
+         */
+        MANDATED,
+
+       /**
+         * A synthetic construct is one that is neither implicitly nor
+         * explicitly declared in the source code. Such a construct is
+         * typically a translation artifact created by a compiler.
+         */
+        SYNTHETIC;
+
+        /**
+         * Returns {@code true} for values corresponding to constructs
+         * that are implicitly or explicitly declared, {@code false}
+         * otherwise.
+         * @return {@code true} for {@link EXPLICIT} and {@link
+         * MANDATED}, {@code false} otherwise.
+         */
+        public boolean isDeclared() {
+            return this != SYNTHETIC;
+        }
+    }
+
+    /**
+     * Returns {@code true} if the executable element is a bridge
+     * method, {@code false} otherwise.
+     *
+     * @implSpec The default implementation of this method returns {@code false}.
+     *
+     * @param e  the executable being examined
+     * @return {@code true} if the executable element is a bridge
+     * method, {@code false} otherwise
+     * @since 9
+     */
+    default boolean isBridge(ExecutableElement e) {
+        return false;
+    }
+
+    /**
      * Returns the <i>binary name</i> of a type element.
      *
      * @param type  the type element being examined