Uploaded image for project: 'CCC Migration Project'
  1. CCC Migration Project
  2. CCC-8163315

Implement an API to identify an implicitly declared annotation (or declaration)

XMLWordPrintable

    • source
    • minimal
    • Default methods defined for methods added to an interface.
    • Java API
    • SE

      Summary

      Add API support to model the "origin" of a construct described by the javax.lang.model API.

      Problem

      The javax.lang.model API does not provide a way to distinguish between constructs (elements, annotation mirrors, etc.) that are

      • explicitly declared (the most common case)
      • implicitly declared (not present in the source code, but mandated by the JLS)
      • synthetic (wholly the creation of the compiler)

      Making such distinctions is needed by javadoc and the new javadoc implementation (8042809) has internal methods for that purpose. Both to ease long-term maintenance and to make the javax.lang.model API more complete, this functionality should be added as a utility in the javax.lang.model API.

      The functionality can also be used to expose analogous information about Jigsaw module directives.

      Solution

      Add an enum and a set of method to the utility interface javax.lang.model.util.Elements.

      Specification

      Full webrev at
      
      http://cr.openjdk.java.net/~darcy/8163315.7
      
      Patch file below. The changes to the package-info file are informative.
      --- old/src/java.compiler/share/classes/javax/lang/model/element/package-info.java  2016-10-05 17:34:37.511715807 -0700
      +++ new/src/java.compiler/share/classes/javax/lang/model/element/package-info.java  2016-10-05 17:34:37.347715800 -0700
      @@ -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
      --- old/src/java.compiler/share/classes/javax/lang/model/util/Elements.java 2016-10-05 17:34:37.943715828 -0700
      +++ new/src/java.compiler/share/classes/javax/lang/model/util/Elements.java 2016-10-05 17:34:37.843715823 -0700
      @@ -29,6 +29,7 @@
       import java.util.List;
       import java.util.Map;
      
      +import javax.lang.model.AnnotatedConstruct;
       import javax.lang.model.element.*;
      
      
      @@ -136,6 +137,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

            darcy Joe Darcy
            darcy Joe Darcy
            Jan Lahoda
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved: