This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 3c0bf68a30524ac8b1b3f4f2ae5fd875bda625fa
Author: Eric Milles <eric.mil...@thomsonreuters.com>
AuthorDate: Sat May 23 11:34:20 2020 -0500

    GROOVY-5259: refactor handling of "this" reference in special ctor call
    
    (cherry picked from commit ba576edfd82e557658224685564d0dfba8f5c43b)
---
 .../groovy/classgen/AsmClassGenerator.java         | 65 ++++++++++------------
 src/test/gls/innerClass/InnerClassTest.groovy      | 28 +++++-----
 2 files changed, 43 insertions(+), 50 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java 
b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
index 2afa7a1..15fe90d 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -28,7 +28,6 @@ import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.ast.ConstructorNode;
 import org.codehaus.groovy.ast.FieldNode;
-import org.codehaus.groovy.ast.GenericsType;
 import org.codehaus.groovy.ast.InnerClassNode;
 import org.codehaus.groovy.ast.InterfaceHelperClassNode;
 import org.codehaus.groovy.ast.MethodNode;
@@ -1079,7 +1078,7 @@ public class AsmClassGenerator extends ClassGenerator {
                 } else {
                     field = classNode.getDeclaredField(name);
                     if (field == null && 
!isValidFieldNodeForByteCodeAccess(classNode.getField(name), classNode)) {
-                        // GROOVY-5259, GROOVY-9501, GROOVY-9569
+                        // GROOVY-9501, GROOVY-9569
                         if (checkStaticOuterField(expression, name)) return;
                     }
                 }
@@ -1276,28 +1275,29 @@ public class AsmClassGenerator extends ClassGenerator {
 
     @Override
     public void visitVariableExpression(final VariableExpression expression) {
-        String variableName = expression.getName();
-
-        
//-----------------------------------------------------------------------
-        // SPECIAL CASES
-
-        // "this" for static methods is the Class instance
-        ClassNode classNode = controller.getClassNode();
+        final String variableName = expression.getName();
 
         if (expression.isThisExpression()) {
-            if (controller.isStaticMethod() || 
(!controller.getCompileStack().isImplicitThis() && 
controller.isStaticContext())) {
-                if (controller.isInGeneratedFunction()) classNode = 
controller.getOutermostClass();
-                visitClassExpression(new ClassExpression(classNode));
+            // "this" in static context is Class instance
+            if (controller.isStaticMethod() || 
controller.getCompileStack().isInSpecialConstructorCall()
+                    || (!controller.getCompileStack().isImplicitThis() && 
controller.isStaticContext())) {
+                ClassNode thisType = controller.getClassNode();
+                if (controller.isInGeneratedFunction()) {
+                    do { thisType = thisType.getOuterClass();
+                    } while (ClassHelper.isGeneratedFunction(thisType));
+                }
+                classX(thisType).visit(this);
             } else {
                 loadThis(expression);
             }
             return;
         }
 
-        // "super" also requires special handling
         if (expression.isSuperExpression()) {
+            // "super" in static context is Class instance
             if (controller.isStaticMethod()) {
-                visitClassExpression(new 
ClassExpression(classNode.getSuperClass()));
+                ClassNode superType = 
controller.getClassNode().getSuperClass();
+                classX(superType).visit(this);
             } else {
                 loadThis(expression);
             }
@@ -1305,11 +1305,22 @@ public class AsmClassGenerator extends ClassGenerator {
         }
 
         BytecodeVariable variable = 
controller.getCompileStack().getVariable(variableName, false);
-        if (variable == null) {
-            processClassVariable(expression);
-        } else {
+        if (variable != null) {
             controller.getOperandStack().loadOrStoreVariable(variable, 
expression.isUseReferenceDirectly());
+        } else if (passingParams && controller.isInScriptBody()) {
+            MethodVisitor mv = controller.getMethodVisitor();
+            mv.visitTypeInsn(NEW, 
"org/codehaus/groovy/runtime/ScriptReference");
+            mv.visitInsn(DUP);
+            loadThisOrOwner();
+            mv.visitLdcInsn(variableName);
+            mv.visitMethodInsn(INVOKESPECIAL, 
"org/codehaus/groovy/runtime/ScriptReference", "<init>", 
"(Lgroovy/lang/Script;Ljava/lang/String;)V", false);
+        } else {
+            PropertyExpression pexp = thisPropX(true, variableName);
+            pexp.getObjectExpression().setSourcePosition(expression);
+            pexp.getProperty().setSourcePosition(expression);
+            pexp.visit(this);
         }
+
         if (!controller.getCompileStack().isLHS()) {
             controller.getAssertionWriter().record(expression);
         }
@@ -1332,26 +1343,6 @@ public class AsmClassGenerator extends ClassGenerator {
         }
     }
 
-    private void processClassVariable(final VariableExpression expression) {
-        if (passingParams && controller.isInScriptBody()) {
-            // TODO: check if this part is actually used
-            MethodVisitor mv = controller.getMethodVisitor();
-            // create a ScriptReference to pass into the closure
-            mv.visitTypeInsn(NEW, 
"org/codehaus/groovy/runtime/ScriptReference");
-            mv.visitInsn(DUP);
-
-            loadThisOrOwner();
-            mv.visitLdcInsn(expression.getName());
-
-            mv.visitMethodInsn(INVOKESPECIAL, 
"org/codehaus/groovy/runtime/ScriptReference", "<init>", 
"(Lgroovy/lang/Script;Ljava/lang/String;)V", false);
-        } else {
-            PropertyExpression pexp = thisPropX(true, expression.getName());
-            pexp.getObjectExpression().setSourcePosition(expression);
-            pexp.getProperty().setSourcePosition(expression);
-            visitPropertyExpression(pexp);
-        }
-    }
-
     protected void createInterfaceSyntheticStaticFields() {
         ClassNode icl =  controller.getInterfaceClassLoadingClass();
 
diff --git a/src/test/gls/innerClass/InnerClassTest.groovy 
b/src/test/gls/innerClass/InnerClassTest.groovy
index ee7c0d7..c07bcbc 100644
--- a/src/test/gls/innerClass/InnerClassTest.groovy
+++ b/src/test/gls/innerClass/InnerClassTest.groovy
@@ -592,31 +592,33 @@ final class InnerClassTest {
         '''
     }
 
-    /*@Test
+    @Test
     void testUsageOfOuterField_WrongCallToSuper() {
         shouldFail '''
-            class InnerAccessOuter {
+            class Outer {
                 protected static final String OUTER_CONSTANT = 'Constant Value'
 
-                class InnerClass {
-                    InnerClass() {
-                        // there's no Object#<init>(String) method, but it 
throws a VerifyError when a new instance
-                        // is created, meaning a wrong super call is generated
+                class Inner {
+                    Inner() {
+                        // there is no Object#<init>(String) method, but it 
throws a VerifyError for uninitialized this
                         super(OUTER_CONSTANT)
                     }
-                    String m() {
-                         OUTER_CONSTANT
+
+                    String access() {
+                        return OUTER_CONSTANT
                     }
                 }
 
-                void testInnerClassAccessOuter() {
-                    def inner = new InnerClass()
-                    inner.m()
+                void testInnerClassAccessOuterConst() {
+                    def inner = new Inner()
+                    inner.access()
                 }
             }
-            new InnerAccessOuter().testInnerClassAccessOuter()
+
+            def outer = new Outer()
+            outer.testInnerClassAccessOuterConst()
         '''
-    }*/
+    }
 
     @Test
     void testUsageOfOuterFieldOverridden() {

Reply via email to