Experimental fix for capturing anonymous classes inside lambda (JDK-8229862)

Jan Lahoda jan.lahoda at oracle.com
Mon Nov 16 10:33:35 UTC 2020


Hi Bernard,

Sorry for belated answer.

I've filled:
https://github.com/openjdk/jdk/pull/1221

based on your patch. Hope that is fine. Any feedback is welcome!

Thanks,
     Jan

On 20. 10. 20 20:46, B. Blaser wrote:
> Hi,
> 
> JDK-8229862 reveals that capturing anonymous classes inside lambda
> seem not to be properly implemented yet, although the opposite
> currently works fine in JDK-16 (see [1] or [2], for example).
> 
> The following experimental fix (on jdk14u) searches for local
> variables captured by anonymous classes inside lambda (in
> LambdaToMethod) and translates them according to corresponding proxies
> (in Lower).
> 
> What do you think (langtools:tier1 is OK)?
> 
> Thanks,
> Bernard
> 
> [1] test/langtools/tools/javac/lambda/T8209407/VerifierErrorInnerPlusLambda.java
> [2] test/langtools/tools/javac/lambda/methodReference/ProtectedInaccessibleMethodRefTest.java
> 
> diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
> @@ -1380,9 +1380,18 @@
>               super.visitIdent(tree);
>           }
> 
> +        boolean inLambda = false;
> +
>           @Override
>           public void visitLambda(JCLambda tree) {
> -            analyzeLambda(tree, "lambda.stat");
> +            boolean prevInLambda = inLambda;
> +            try {
> +                inLambda = true;
> +                analyzeLambda(tree, "lambda.stat");
> +            }
> +            finally {
> +                inLambda = prevInLambda;
> +            }
>           }
> 
>           private void analyzeLambda(JCLambda tree, JCExpression
> methodReferenceReceiver) {
> @@ -1430,6 +1439,16 @@
> 
>           @Override
>           public void visitNewClass(JCNewClass tree) {
> +            if (tree.def != null && inLambda) {
> +                try {
> +                    inLambda = false;
> +                    visitClassDef(tree.def);
> +                }
> +                finally {
> +                    inLambda = true;
> +                }
> +            }
> +
>               TypeSymbol def = tree.type.tsym;
>               boolean inReferencedClass = currentlyInClass(def);
>               boolean isLocal = def.isLocal();
> diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
> @@ -2812,7 +2812,14 @@
>           // If we have an anonymous class, create its flat version, rather
>           // than the class or interface following new.
>           if (tree.def != null) {
> -            translate(tree.def);
> +            Map<Symbol, Symbol> prevLambdaTranslationMap =
> lambdaTranslationMap;
> +            try {
> +                lambdaTranslationMap = null;
> +                translate(tree.def);
> +            } finally {
> +                lambdaTranslationMap = prevLambdaTranslationMap;
> +            }
> +
>               tree.clazz = access(make_at(tree.clazz.pos()).Ident(tree.def.sym));
>               tree.def = null;
>           } else {
> 


More information about the compiler-dev mailing list