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

Type annotations on anonymous new class creation expressions can't be retrieved

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • 26
    • tools

      This is closely related to https://bugs.openjdk.org/browse/JDK-8351431.

      The repro is the same as the previous bug except it is an anonymous new class expression: `new Test<@TA String>() {}` instead of `new Test<@TA String>()`

      The expected output is:

      Tree: new Test<@TA String>(){...}, Type: <anonymous Test<java.lang.@Test.TA String>>

      The actual output is:

      Tree: new Test<@TA String>(){...}, Type: <anonymous Test<java.lang. String>>

      I think the issue is that as part of the fix for JDK-8198945, Annotate doesn't process type annotations on anonymous class types when visited through NewClassTrees. That successfully prevents Annotate from attaching those annotations to the enclosing method of the NewClassTree, which would be incorrect. However it also prevents them from being entered, and means they aren't present on the type for the NewClassTree, as the repro shows.

      https://github.com/openjdk/jdk/blame/7c22b814d670deda6c2bb93b1e150975c27a165f/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java#L1162-L1164

      ```
      import com.sun.source.tree.NewClassTree;
      import com.sun.source.util.JavacTask;
      import com.sun.source.util.TaskEvent;
      import com.sun.source.util.TaskListener;
      import com.sun.source.util.TreePathScanner;
      import com.sun.source.util.Trees;
      import java.io.IOException;
      import java.nio.charset.StandardCharsets;
      import java.util.Locale;
      import javax.lang.model.type.TypeMirror;
      import javax.tools.JavaCompiler;
      import javax.tools.StandardJavaFileManager;
      import javax.tools.ToolProvider;

      public final class Z {

        public static void main(final String[] args) throws IOException {
          final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
          StandardJavaFileManager fileManager =
              compiler.getStandardFileManager(null, Locale.ENGLISH, StandardCharsets.UTF_8);
          final JavacTask task =
              (JavacTask)
                  compiler.getTask(null, null, null, null, null, fileManager.getJavaFileObjects(args));
          task.addTaskListener(
              new TaskListener() {
                @Override
                public void finished(TaskEvent e) {
                  if (e.getKind() == TaskEvent.Kind.ANALYZE) {
                    new TreePathScanner<Void, Void>() {
                      @Override
                      public Void visitNewClass(NewClassTree tree, Void unused) {
                        TypeMirror type = Trees.instance(task).getTypeMirror(getCurrentPath());
                        System.err.printf("Tree: %s, Type: %s\n", tree, type);
                        return super.visitNewClass(tree, unused);
                      }
                    }.scan(e.getCompilationUnit(), null);
                  }
                }
              });
          task.analyze();
        }
      }
      ```

      ```
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;

      class Test<T> {
        @Target(ElementType.TYPE_USE)
        @Retention(RetentionPolicy.RUNTIME)
        @interface TA {}

        public void testMethod() {
          new Test<@TA String>() {};
        }
      }
      ```

            cushon Liam Miller-Cushon
            cushon Liam Miller-Cushon
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: