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