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

Spurious 'enum types may not be instantiated errors with DocTrees#getElement(DocTreePath)

    Details

    • Type: Enhancement
    • Status: Open
    • Priority: P3
    • Resolution: Unresolved
    • Affects Version/s: 13
    • Fix Version/s: 16
    • Component/s: tools
    • Labels:
      None

      Description

      DocTrees#getElement(DocTreePath) uses attribution code in javac that can report diagnostics, so it installs a deferred diagnostic handler to ensure that errors are not actually reported [1]. However, the handler is installed after calling getAttrContext, which can in some cases cause diagnostics to be reported.

      Repro:

      ```
      import com.sun.source.doctree.DocCommentTree;
      import com.sun.source.doctree.LinkTree;
      import com.sun.source.tree.MethodTree;
      import com.sun.source.util.DocTreePath;
      import com.sun.source.util.DocTreePathScanner;
      import com.sun.source.util.DocTrees;
      import com.sun.source.util.TreePathScanner;
      import com.sun.source.util.Trees;
      import java.util.Set;
      import javax.annotation.processing.AbstractProcessor;
      import javax.annotation.processing.RoundEnvironment;
      import javax.annotation.processing.SupportedAnnotationTypes;
      import javax.lang.model.SourceVersion;
      import javax.lang.model.element.Element;
      import javax.lang.model.element.TypeElement;
      import javax.tools.Diagnostic.Kind;

      @SupportedAnnotationTypes("*")
      public class P extends AbstractProcessor {

        @Override
        public SourceVersion getSupportedSourceVersion() {
          return SourceVersion.latestSupported();
        }

        @Override
        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
          Trees trees = Trees.instance(processingEnv);
          DocTrees docTrees = DocTrees.instance(processingEnv);
          for (Element e : roundEnv.getRootElements()) {
            new TreePathScanner<Void, Void>() {
              @Override
              public Void visitMethod(MethodTree node, Void unused) {
                DocCommentTree docTree = docTrees.getDocCommentTree(getCurrentPath());
                if (docTree != null) {
                  new DocTreePathScanner<Void, Void>() {
                    @Override
                    public Void visitLink(LinkTree node, Void unused) {
                      processingEnv
                          .getMessager()
                          .printMessage(
                              Kind.NOTE,
                              String.valueOf(
                                  docTrees.getElement(
                                      new DocTreePath(getCurrentPath(), node.getReference()))));
                      return super.visitLink(node, null);
                    }
                  }.scan(new DocTreePath(getCurrentPath(), docTree), null);
                }
                return super.visitMethod(node, null);
              }
            }.scan(trees.getPath(e), null);
          }
          return false;
        }
      }
      ```

      ```
      @Deprecated
      enum E {
        ONE {
          /** {@link Object} */
          @Override
          void foo() {}
        };

        abstract void foo();
      }
      ```

      ```
      $ javac -fullversion -processor P T.java
      javac full version "13.0.2+8"
      T.java:3: error: enum types may not be instantiated
        ONE {
            ^
      Note: java.lang.Object
      1 error
      ```

      [1] https://hg.openjdk.java.net/jdk/jdk/file/ce082993c9d2/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java#l471

        Attachments

          Activity

            People

            • Assignee:
              jlahoda Jan Lahoda
              Reporter:
              cushon Liam Miller-Cushon
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated: