Type Annotations and Lambda

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Feb 11 03:33:02 PST 2013

On 10/02/13 02:17, Werner Dietl wrote:
> 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.
I think your tests cover all the syntax for unbound references where you 
have a type qualifier - good.

About your points on LambdaToMethod;  annotations on declarations are 
ignored yes, that's a bug. It is very possible that some of the details 
of the original source are being ignored/not preserved by the lambda 
translation step. Those are all bugs that have been caused by the fact 
that our #1 priority has been to get the code to in a stable shape. It 
is very likely we will do a second pass on the code, as there are many 
issues with it, especially in terms of dependencies that LambdaToMethod 
has from other translation passes - there are things that, as you say, 
would be easily modeled if LambdaToMethod was a pre-erasure pass; other 
things would be easier if LambdaToMethod was folded as a part of Lower. 
At some point we even had LambdaToMethod before Lower, but then I 
changed it (about 1 year ago) as the generation logic was defined 
entirely in terms of erased types, so full generic type information was 
an hindrance rather than a bonus. Plus, all the advantages we had from 
it being a pre-erasure pass (in terms of bridge generation) have been 
lost when we moved away from the original anonymous inner class 
translator to the current 292 translator.

By all means, I don't want to completely shut the door to the 
possibility of moving LambdaToMethod before TransTypes  - but on the 
other hand there has to be a compelling need for doing that. I think the 
problem you are describing (position of type annotations within lambda) 
could be fixed by having a pass before erasure (probably the one you do 
have now) that determines position of all type annotation, and then have 
LambdaToMethod revisit that info and replace old positions with new ones.

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

More information about the type-annotations-dev mailing list