TypeMirror is missing annotation

Marcel Kliemannel dev at marcelkliemannel.com
Sat Apr 1 06:22:24 UTC 2017


Hello,

 

I am writing a compiler plugin for code analyzation. The bug JDK-8031744 (https://bugs.openjdk.java.net/browse/JDK-8031744) seems to fix some problems in jdk 9 with missing annotations in the types of some kinds of elements. I found a case where the annotation is still missing. Maybe someone can say whether this is a compiler bug related to JDK-8031744, or I am doing something totally wrong?

 

The annotation:

-----------------------------------------

import java.lang.annotation.*;

import static java.lang.annotation.RetentionPolicy.CLASS;

 

@Retention(CLASS)

@Target({ElementType.TYPE_USE})

public @interface R {}

-----------------------------------------

 

and the class to analyse:

-----------------------------------------

import java.util.function.Consumer;

 

public class Test {

    public void test() {

        Consumer<@R String> consumer = input -> {};

    }

}

-----------------------------------------

 

I am expecting that the parameter ‘input’ of the lambda expression is of type ‘@R() java.lang.String’, but the TypeMirror of the Element ‘input’ just gives me ‘java.lang.String’ without the annotation.

 

Below is a compiler plugin to reproduce this behaviour with jdk 9 build 163 and the annotation and class above. I invoke the plugin with the command:

javac -processorpath CompilerPlugin.jar -Xplugin:CompilerPlugin Test.java R.java

 

-----------------------------------------

import com.sun.source.tree.*;

import com.sun.source.util.*;

import javax.lang.model.element.Element;

 

public class CompilerPlugin implements Plugin {

  @Override

  public String getName() {

    return "CompilerPlugin";

  }

 

  @Override

  public void init(JavacTask javacTask, String[] args) {

    javacTask.addTaskListener(new TaskListener() {

      @Override

      public void started(TaskEvent e) {}

 

      @Override

      public void finished(TaskEvent taskEvent) {

        if (TaskEvent.Kind.ANALYZE.equals(taskEvent.getKind())) {

          taskEvent.getCompilationUnit().getTypeDecls().forEach(typeDecl -> {

            ClassTree classTree = (ClassTree) typeDecl;

 

            classTree.getMembers().forEach(member -> {

              MethodTree methodTree = (MethodTree) member;

              methodTree.getBody().getStatements().forEach(statement -> {

                if (Tree.Kind.VARIABLE.equals(statement.getKind())) {

                  // Consumer<@R String> consumer = input -> {};

                  VariableTree variableTree = (VariableTree) statement;

 

                  LambdaExpressionTree lambdaExpressionTree =

                      (LambdaExpressionTree) variableTree.getInitializer(); // input -> {}

 

                  Tree firstParameter = lambdaExpressionTree.getParameters().get(0); // input

 

                  TreePath path = TreePath.getPath(taskEvent.getCompilationUnit(), firstParameter);

                  Element element = Trees.instance(javacTask).getElement(path);

                  System.out.println(element.asType()); // java.lang.String

                  System.out.println(element.asType().getAnnotationMirrors()); // nothing :(

                }

              });

            });

          });

        }

      }

    });

  }

}

-----------------------------------------

 

Thank you for your time and best regards,

Marcel

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20170401/e28a8b2f/attachment.html>


More information about the compiler-dev mailing list