Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8272106

Access JavaFileObject from Element(s)

    XMLWordPrintable

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P3
    • Resolution: Approved
    • Fix Version/s: 18
    • Component/s: core-libs
    • Labels:
      None
    • Subcomponent:
    • Compatibility Kind:
      source, behavioral
    • Compatibility Risk:
      minimal
    • Compatibility Risk Description:
      New default method added to an interface.
    • Interface Kind:
      Java API
    • Scope:
      SE

      Description

      Summary

      Add a default method to Elements to map from an element to its file object.

      Problem

      Using the existing javax.lang.model and javax.annotation.processing API, it is not possible to map from an element to its file object.

      Solution

      Add the necessary functionality to Elements with a default method that throws an exception and other supporting changes.

      Specification

       diff --git a/src/java.compiler/share/classes/javax/annotation/processing/Filer.java b/src/java.compiler/share/classes/javax/annotation/processing/Filer.java
      index 257b0085e6d..80c01228ed6 100644
      --- a/src/java.compiler/share/classes/javax/annotation/processing/Filer.java
      +++ b/src/java.compiler/share/classes/javax/annotation/processing/Filer.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2005, 2021, 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
      @@ -69,7 +69,13 @@
        * originating elements are the classes or interfaces or packages
        * (representing {@code package-info} files) or modules (representing
        * {@code module-info} files) which caused an annotation processor to
      - * attempt to create a new file.  For example, if an annotation
      + * attempt to create a new file.
      + * In other words, the originating elements are intended to have the
      + * granularity of <em>compilation units</em> (JLS section {@jls 7.3}),
      + * essentially file-level granularity, rather than finer-scale
      + * granularity of, say, a method or field declaration.
      + *
      + * <p>For example, if an annotation
        * processor tries to create a source file, {@code
        * GeneratedFromUserSource}, in response to processing
        *
      diff --git a/src/java.compiler/share/classes/javax/lang/model/element/ExecutableElement.java b/src/java.compiler/share/classes/javax/lang/model/element/ExecutableElement.java
      index 9f8e3997781..882917b21b5 100644
      --- a/src/java.compiler/share/classes/javax/lang/model/element/ExecutableElement.java
      +++ b/src/java.compiler/share/classes/javax/lang/model/element/ExecutableElement.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2005, 2021, 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
      @@ -131,6 +131,12 @@
            */
           AnnotationValue getDefaultValue();
      
      +    /**
      +     * {@return the class or interface defining the executable}
      +     */
      +    @Override
      +    Element getEnclosingElement();
      +
           /**
            * {@return the simple name of a constructor, method, or
            * initializer}  For a constructor, the name {@code "<init>"} is
      diff --git a/src/java.compiler/share/classes/javax/lang/model/element/package-info.java b/src/java.compiler/share/classes/javax/lang/model/element/package-info.java
      index 094dd1825bd..6c52de63c5b 100644
      --- a/src/java.compiler/share/classes/javax/lang/model/element/package-info.java
      +++ b/src/java.compiler/share/classes/javax/lang/model/element/package-info.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2005, 2021, 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
      @@ -36,7 +36,7 @@
        * appearing inside method bodies, such as local variables and
        * anonymous classes.
        *
      - * <p>When used in the context of annotation processing, an accurate
      + * <p><a id="accurate_model">When used in the context of annotation processing, an accurate
        * model of the element being represented must be returned.  As this
        * is a language model, the source code provides the fiducial
        * (reference) representation of the construct in question rather than
      @@ -48,7 +48,7 @@
        * {@linkplain java.lang.annotation.RetentionPolicy#SOURCE source}
        * {@linkplain java.lang.annotation.Retention retention} cannot be
        * recovered from class files and class files might not be able to
      - * provide source position information.
      + * provide source position information.</a>
        *
        * Names of {@linkplain
        * javax.lang.model.element.ExecutableElement#getParameters()
      diff --git a/src/java.compiler/share/classes/javax/lang/model/util/Elements.java b/src/java.compiler/share/classes/javax/lang/model/util/Elements.java
      index f8071dd9844..e1448f82594 100644
      --- a/src/java.compiler/share/classes/javax/lang/model/util/Elements.java
      +++ b/src/java.compiler/share/classes/javax/lang/model/util/Elements.java
      @@ -761,4 +761,100 @@ default RecordComponentElement recordComponentFor(ExecutableElement accessor) {
               }
               return null;
           }
      +
      +
      +    /**
      +     * {@return the file object for this element or {@code null} if
      +     * there is no such file object}
      +     *
      +     * <p>The returned file object is for the <a
      +     * href="../element/package-summary.html#accurate_model">reference
      +     * representation</a> of the information used to construct the
      +     * element. For example, if during compilation or annotation
      +     * processing, a source file for class {@code Foo} is compiled
      +     * into a class file, the file object returned for the element
      +     * representing {@code Foo} would be for the source file and
      +     * <em>not</em> for the class file.
      +     *
      +     * <p>An implementation may choose to not support the
      +     * functionality of this method, in which case {@link
      +     * UnsupportedOperationException} is thrown.
      +     *
      +     * <p>In the context of annotation processing, a non-{@code null}
      +     * value is returned if the element was included as part of the
      +     * initial inputs or the containing file was created during the
      +     * run of the annotation processing tool. Otherwise, a {@code
      +     * null} may be returned. In annotation processing, if a
      +     * {@linkplain javax.annotation.processing.Filer#createClassFile
      +     * class file is created}, that class file can serve as the
      +     * reference representation for elements.
      +     *
      +     * <p>If it has a file object, the file object for a package will
      +     * be a {@code package-info} file. A package may exist and not
      +     * have any {@code package-info} file even if the package is
      +     * (implicitly) created during an annotation processing run from
      +     * the creation of source or class files in that package.  An
      +     * {@linkplain PackageElement#isUnnamed unnamed package} will have
      +     * a null file since it cannot be declared in a compilation unit.
      +     *
      +     * <p>If it has a file object, the file object for a module will
      +     * be a {@code module-info} file.  An {@linkplain
      +     * ModuleElement#isUnnamed unnamed module} will have a null file
      +     * since it cannot be declared in a compilation unit.  An
      +     * {@linkplain #isAutomaticModule automatic module} will have a
      +     * null file since it is implicitly declared.
      +     *
      +     * <p>If it has a file object, the file object for a top-level
      +     * {@code public} class or interface will be a source or class
      +     * file corresponding to that class or interface. In this case,
      +     * typically the leading portion of the name of the file will
      +     * match the name of the class or interface. A single compilation
      +     * unit can define multiple top-level classes and interfaces, such
      +     * as a primary {@code public} class or interfaces whose name
      +     * corresponds to the file name and one or more <em>auxiliary</em>
      +     * classes or interfaces whose names do not correspond to the file
      +     * name. If a source file is providing the reference
      +     * representation of an auxiliary class or interface, the file for
      +     * the primary class is returned. (An auxiliary class or interface
      +     * can also be defined in a {@code package-info} source file, in
      +     * which case the file for the {@code package-info} file is
      +     * returned.)  If a class file is providing the reference
      +     * representation of an auxiliary class or interface, the separate
      +     * class file for the auxiliary class is returned.
      +     *
      +     * <p>For a nested class or interface, if it has a file object:
      +     *
      +     * <ul>
      +     *
      +     * <li>if a source file is providing the reference representation,
      +     * the file object will be that of the {@linkplain
      +     * #getOutermostTypeElement(Element) outermost enclosing} class or
      +     * interface
      +     *
      +     * <li>if a class file is providing the reference representation,
      +     * the file object will be that of the nested class or interface
      +     * itself
      +     *
      +     * </ul>
      +     *
      +     * <p>For other lexically enclosed elements, such as {@linkplain
      +     * VariableElement#getEnclosingElement() variables}, {@linkplain
      +     * ExecutableElement#getEnclosingElement() methods, and
      +     * constructors}, if they have a file object, the file object will
      +     * be the object associated with the {@linkplain
      +     * Element#getEnclosingElement() enclosing element} of the
      +     * lexically enclosed element.
      +     *
      +     * @implSpec The default implementation unconditionally throws
      +     * {@link UnsupportedOperationException}.
      +     *
      +     * @throws UnsupportedOperationException if this functionality is
      +     * not supported
      +     *
      +     * @param e the element to find a file object for
      +     * @since 18
      +     */
      +    default javax.tools.JavaFileObject getFileObjectOf(Element e) {
      +        throw new UnsupportedOperationException();
      +    }
       }

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              darcy Joe Darcy
              Reporter:
              jjg Jonathan Gibbons
              Reviewed By:
              Jan Lahoda
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: