Quantcast

TypeMirror is missing annotation

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

TypeMirror is missing annotation

Marcel Kliemannel

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

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TypeMirror is missing annotation

Alex Buckley-3
On 3/31/2017 11:22 PM, Marcel Kliemannel wrote:

> 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.

I don't recall anything in the JLS or API spec that mandates implicit
transmission of type annotations in this manner.

Alex
Loading...