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