changeset 1832:9e101aaa2c5c

Fix: Avoid circularity between LambdaToMethod.visitClassDef and LambdaTranslationContext.complete() Simplify logic for handling classes nested within a lambda; Lower always capture 'this' when an inner class is defined in a non-static context - this update to LambdaToMethod reflects the behavior in Lower: any lambda (defined in a non-static context) defining an inner class will indirectly capture 'this'. Lambdas that do not define any inner classes will continue to capture 'this' on-demand.
author mcimadamore
date Tue, 19 Feb 2013 11:33:48 +0000
parents a2b6e71c5b62
children 60ceb785855f
files src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java test/tools/javac/lambda/LambdaExpr15.java
diffstat 3 files changed, 7 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Fri Feb 15 19:52:55 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Tue Feb 19 11:33:48 2013 +0000
@@ -1065,26 +1065,11 @@
                 prevClinits = new HashMap<ClassSymbol, Symbol>();
                 if (directlyEnclosingLambda() != null) {
                     tree.sym.owner = owner();
-                    LambdaTranslationContext lambdaContext = (LambdaTranslationContext)contextMap.get(directlyEnclosingLambda());
-                    lambdaContext.listeners =
-                            lambdaContext.listeners.prepend(new LambdaTranslationContextListener() {
-                        @Override
-                        void onComplete(LambdaTranslationContext context) {
-                            Type encl = context.enclosingType();
-                            if (encl.hasTag(NONE)) {
-                                //if the translated lambda body occurs in a static context,
-                                //any class declaration within it must be made static
-                                //@@@TODO: What about nested classes within lambda?
-                                tree.sym.flags_field |= STATIC;
-                                ((ClassType)tree.sym.type).setEnclosingType(Type.noType);
-                            } else {
-                                //if the translated lambda body is in an instance context
-                                //the enclosing type of any class declaration within it
-                                //must be updated to point to the new enclosing type (if any)
-                                ((ClassType)tree.sym.type).setEnclosingType(encl);
-                            }
-                        }
-                    });
+                    if (tree.sym.hasOuterInstance()) {
+                        //if a class is defined within a lambda, the lambda must capture
+                        //its enclosing instance (if any)
+                        ((LambdaTranslationContext) context()).addSymbol(tree.sym.type.getEnclosingType().tsym, CAPTURED_THIS);
+                    }
                 }
                 frameStack = frameStack.prepend(new Frame(tree));
                 super.visitClassDef(tree);
@@ -1094,11 +1079,6 @@
                 serializableLambdaCounts = prevSerializableLambdaCount;
                 clinits = prevClinits;
             }
-            if (!tree.sym.isStatic() && directlyEnclosingLambda() != null) {
-                // Any (non-static) class defined within a lambda is an implicit 'this' reference
-                // because its constructor will reference the enclosing class
-                ((LambdaTranslationContext) context()).addSymbol(tree.sym.type.getEnclosingType().tsym, CAPTURED_THIS);
-            }
         }
 
         @Override
@@ -1549,8 +1529,6 @@
 
             List<JCVariableDecl> syntheticParams;
 
-            List<LambdaTranslationContextListener> listeners;
-
             LambdaTranslationContext(JCLambda tree) {
                 super(tree);
                 Frame frame = frameStack.head;
@@ -1559,7 +1537,6 @@
                 }
                 Name name = isSerializable() ? serializedLambdaName(owner) : lambdaName();
                 this.translatedSym = makeSyntheticMethod(0, name, null, owner.enclClass());
-                this.listeners = List.nil();
             }
 
             /**
@@ -1670,17 +1647,6 @@
                 translatedSym.type = types.createMethodTypeWithParameters(
                         generatedLambdaSig(),
                         TreeInfo.types(syntheticParams));
-                
-                //notify listeners
-                for (LambdaTranslationContextListener listener : listeners) {
-                    listener.onComplete(this);
-                }
-            }
-
-            Type enclosingType() {
-                return translatedSym.isStatic() ?
-                        Type.noType :
-                        owner.enclClass().type;
             }
 
             Type generatedLambdaSig() {
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Feb 15 19:52:55 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Feb 19 11:33:48 2013 +0000
@@ -903,6 +903,8 @@
     void writePosition(TypeAnnotationPosition p) {
         databuf.appendByte(p.type.targetTypeValue()); // TargetType tag is a byte
         switch (p.type) {
+        // type cast
+        case CAST:
         // instanceof
         case INSTANCEOF:
         // new expression
--- a/test/tools/javac/lambda/LambdaExpr15.java	Fri Feb 15 19:52:55 2013 -0800
+++ b/test/tools/javac/lambda/LambdaExpr15.java	Tue Feb 19 11:33:48 2013 +0000
@@ -23,7 +23,6 @@
 
 /*
  * @test
- * @ignore investigate as to whether code generation fails
  * @bug 8003280
  * @summary Add lambda tests
  *  check that nested inner class in statement lambdas don't get corrupted return statements