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

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

XMLWordPrintable

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

      In the following example, using the compiler Tree API to retrieve the type of a new class creation expression returns a type that is missing type annotations.

      The expected output is:

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

      (Also note that the returned type has an extra space in it: 'Test<java.lang. String>', because type annotation metadata is being attached but the list of annotations is empty.)

      I think the issue is that the logic between these two locations is inconsistent:

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

      https://github.com/openjdk/jdk/blob/7c22b814d670deda6c2bb93b1e150975c27a165f/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java#L5242-L5243

      Annotate special-cases _anonymous_ new class creation expressions, because those type annotations have special handling to move them to the superclass of the anonymous class. Attr special-cases all new class creation expressions, not just anonymous ones, and 'annotateTypeSecondStage' never gets called for the non-anonymous case.

      ```
      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>();
        }
      }
      ```

      $ java -fullversion
      openjdk full version "25-ea+12-1311"

      $ java Z Test.java
      Tree: new Test<@TA String>(), Type: Test<java.lang. String>

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

              Created:
              Updated: