Experimental fix for capturing anonymous classes inside lambda (JDK-8229862)
B. Blaser
bsrbnd at gmail.com
Tue Oct 20 18:46:29 UTC 2020
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