Type Annotations and Lambda
Werner Dietl
wdietl at gmail.com
Sat Feb 9 18:17:00 PST 2013
Maurizio, all,
I implemented type annotations in method references in:
http://hg.openjdk.java.net/type-annotations/type-annotations/langtools/rev/af8a7d00913b
Please have a look at the test cases in:
http://hg.openjdk.java.net/type-annotations/type-annotations/langtools/file/bf5536a0a945/test/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java
and let me know whether I missed any syntax.
This should complete method/constructor reverences and
method/constructor reference type arguments.
> Finally, the spec says that type annotations in the signature or body
> of a lambda expression should appear in the method that results from
> translation.
> I was hoping that this would work without any special effort. However,
> no type annotations appear in a translated method.
> Could somebody point me to the location in the code that translates a
> lambda expression into a method?
>
> This is the place:
>
> http://hg.openjdk.java.net/jdk8/jdk8/langtools/file/tip/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
I experimented with LambdaToMethod and have two big issues:
1. This phase is run after Translate. Therefore, all generics in
lambda bodies are already erased. For example, let's take this simple
code:
static MyLambda1 getOne() {
return (@TA int x) -> {
@TB List<@TC Object> l = new @TB ArrayList<@TC Object>();
System.out.println("x: " + (@TC Object) x);
};
}
In com.sun.tools.javac.comp.LambdaToMethod.visitVarDef(JCVariableDecl)
the JCVariableDecl that I see initially is:
@TB() List l = new @TB ArrayList();
That is, the type arguments are erased, but at least the type
annotation on List is still present.
2. LambdaToMethod does not preserve all type annotations in the tree.
At the end of LambdaToMethod the generated method looks like this:
/*synthetic*/ private static .void lambda$0(/*synthetic*/ final int x) {
/*synthetic*/ final List l = new @TB() ArrayList();
System.out.println("x: " + ( @TC() Object)x);
}
That is, the code is erased and all type annotations in variable
declarations are lost. The type annotations in expressions seem to be
preserved, but the types are of course also erased.
I think the reason why the type arguments are no longer present is
that in visitVarDef the call to "result = make.VarDef" does not
consider any annotations that might have been present in the incoming
tree.
It would probably be easiest if all annotations, declaration or type
annotations, were propagated from the incoming tree.
Is there a reason why declaration annotations are being ignored?
Determining the positions for type annotations in lambdas needs to
happen after conversion to a method.
However, if all the types are already erased, we would lose all these
type annotations.
Would it be possible to move the LambdaToMethod phase earlier in the
compilation phases?
All suggestions and ideas would be very much appreciated.
Thanks,
cu, WMD.
--
http://www.google.com/profiles/wdietl
More information about the type-annotations-dev
mailing list