Introduce a compiler option to store generic type information about a lambda expression using the Signature Attribute
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Wed Jan 7 16:31:08 UTC 2015
One thing that worries me is that, while this would work generally well
in simple cases, there will always be the bad corner case in which you
need a bridge (generated dynamically by the lambda metafactory) and that
bridge will not have the signature attribute (since it's not javac
generated). Now, when we require bridging, lambda capture goes through
the slow path (altMetafactory) - so maybe it's not too much of a concern
if we added some logic there to regenerate the signature attribute on
the bridge (although, I must note, not even ordinary javac bridges have
signature attributes)...
Maurizio
On 07/01/15 16:21, Remi Forax wrote:
> We (the lambda EG) discusses that issue last year,
> as far as I remember, it was decided to not support generic signature
> in lambda proxy by default,
> now I see no problem to make this information accessible through a flag.
>
> cheers,
> Rémi
>
> On 01/07/2015 04:47 PM, Maurizio Cimadamore wrote:
>> Hi Timo,
>> thanks for the patch - if I'm not mistaken, this would be the very
>> first case in which a method marked with ACC_SYNTHETIC also gets a
>> signature attribute. I will consult with the rest of the team and see
>> if there's any objection.
>>
>> Cheers
>> Maurizio
>>
>> On 07/01/15 15:22, Timo Walther wrote:
>>> Hi all,
>>>
>>> the Java Reflection API allows to access the generic signature of
>>> methods through the java.lang.reflect.Method#getGenericReturnType()
>>> method. However, this is not yet supported for Lambda expressions.
>>>
>>> Given the following classes:
>>>
>>> class Tuple2<F0,F1> {
>>> F0 field0;
>>> F1 field1;
>>>
>>> public Tuple2(F0 f0, F1 f1) {
>>> this.field0 = f0;
>>> this.field1 = f1;
>>> }
>>> }
>>>
>>> interface Map<IN, OUT> {
>>> OUT map(IN in);
>>> }
>>>
>>> Currently, there is no solution that allows to get further type
>>> information about expressions like:
>>>
>>> Map<String, Tuple2<String, Integer>> map = (str) -> new
>>> Tuple2<>(str, 1);
>>> System.out.println(getReturnType(map)) // can only print Tuple2 =>
>>> information about the Tuple2's fields are always lost
>>>
>>> Especially data-intensive runtimes (like Apache Flink[0] where I am
>>> working on) need as much type information as possible to be
>>> efficient. Therefore, we searched for a way to also extract type
>>> information from lambda expressions. Adding a generic signature to
>>> the generated "lambda$XXX" static methods (at least by using a
>>> compiler option) would be the perfect solution. It seems that the
>>> JVM Specification does not prohibit such an implementation. An
>>> implementation of a later extraction is described here[1].
>>>
>>> The Eclipse JDT compiler team is introducing a compiler option
>>> "-genericsignature" with version 4.5 M4[2].
>>>
>>> I have implemented a patch prototype. It can be found at:
>>> http://people.apache.org/~twalthr/patches/lambdaSignature.patch
>>>
>>> The patch postpones the type erasure of the lambda function's
>>> parameters after the generic descriptor has been saved in a newly
>>> introduced variable in MethodSymbol (if compiler option
>>> "-lambdasignature" is set). The contents of the variable is read in
>>> ClassWriter and written to method's Signature attribute in the
>>> classfile. Tests are also included.
>>>
>>> No change to the class file format is required. The change is
>>> guarded by a compiler option, so without that addition, nothing
>>> should behave differently.
>>>
>>>
>>> [0] http://flink.apache.org/
>>> [1]
>>> http://stackoverflow.com/questions/21887358/reflection-type-inference-on-java-8-lambdas
>>> [2] https://bugs.eclipse.org/bugs/show_bug.cgi?id=449063
>>>
>>>
>>> Regards,
>>> Timo Walther
>>
>
More information about the compiler-dev
mailing list