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

type annotations are not visible to javac plugins across compilation boundaries

    XMLWordPrintable

Details

    Description

      javac fails to associate type annotations with TypeMirrors for some symbols loaded from the classpath, which prevents plugins from accessing those annotations across compilation boundaries. The annotations are present if the same symbol is compiled from source in the compilation where the plugin runs.

      === ./test/B.java
      abstract class B extends A {}
      === ./test/A.java
      import java.lang.annotation.ElementType;
      import java.util.List;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;

      @Target(ElementType.TYPE_USE)
      @Retention(RetentionPolicy.RUNTIME)
      @interface TypeAnnotation {}

      abstract class A implements List<@TypeAnnotation String> {}
      === ./plugin/p/P.java
      package p;

      import com.sun.source.util.JavacTask;
      import com.sun.source.util.Plugin;
      import com.sun.source.util.TaskEvent;
      import com.sun.source.util.TaskListener;
      import javax.lang.model.element.TypeElement;
      import javax.lang.model.type.DeclaredType;
      import javax.lang.model.type.TypeMirror;

      public class P implements Plugin {

        @Override
        public String getName() {
          return "P";
        }

        @Override
        public void init(JavacTask javacTask, String... strings) {
          javacTask.addTaskListener(
              new TaskListener() {
                @Override
                public void finished(TaskEvent e) {
                  if (e.getKind() != TaskEvent.Kind.ENTER) {
                    return;
                  }
                  TypeElement b = javacTask.getElements().getTypeElement("B");
                  for (TypeMirror i :
                      ((TypeElement) ((DeclaredType) b.getSuperclass()).asElement()).getInterfaces()) {
                    System.err.printf("%s %s\n", i, i.getAnnotationMirrors());
                  }
                }
              });
        }
      }
      === ./plugin/module-info.java
      module p {
        requires transitive jdk.compiler;
        provides com.sun.source.util.Plugin with p.P;
      }
      ===

      $ javac $(find plugin -name '*.java')

      # when both compilation units are compiled from source, the type annotations are visible

      $ javac --processor-module-path plugin -Xplugin:P test/A.java test/B.java
      java.util.List<@TypeAnnotation java.lang.String>
      java.util.List<@TypeAnnotation java.lang.String>

      # when 'A' is loaded from the classpath, the type annotations on its supertype are not visible

      $ javac --processor-module-path plugin -Xplugin:P -classpath test test/B.java
      java.util.List<java.lang.String>

      Attachments

        Issue Links

          Activity

            People

              vromero Vicente Arturo Romero Zaldivar
              cushon Liam Miller-Cushon
              Votes:
              1 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated: