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

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


The following commit(s) were added to refs/heads/master by this push:
     new 9793c9c2cc GROOVY-5619, GROOVY-5649: SC: remove legacy pathway
9793c9c2cc is described below

commit 9793c9c2cc25f812712ec52b0ff55917804fa729
Author: Eric Milles <[email protected]>
AuthorDate: Fri Sep 20 14:17:38 2024 -0500

    GROOVY-5619, GROOVY-5649: SC: remove legacy pathway
---
 ...icTypesBinaryExpressionMultiTypeDispatcher.java | 139 +++------
 .../groovy/transform/stc/GenericsSTCTest.groovy    |   7 +-
 .../sc/FieldsAndPropertiesStaticCompileTest.groovy | 347 ++++++++++-----------
 .../asm/sc/StaticCompilationTestSupport.groovy     |  56 ++--
 .../asm/sc/StaticCompileConstructorsTest.groovy    |   9 +-
 5 files changed, 239 insertions(+), 319 deletions(-)

diff --git 
a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java
 
b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java
index 325c685814..7e0284cd01 100644
--- 
a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java
+++ 
b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesBinaryExpressionMultiTypeDispatcher.java
@@ -35,7 +35,6 @@ import org.codehaus.groovy.ast.stmt.EmptyStatement;
 import org.codehaus.groovy.ast.stmt.ForStatement;
 import org.codehaus.groovy.ast.tools.WideningCategories;
 import org.codehaus.groovy.classgen.asm.BinaryExpressionMultiTypeDispatcher;
-import org.codehaus.groovy.classgen.asm.BytecodeHelper;
 import org.codehaus.groovy.classgen.asm.CompileStack;
 import org.codehaus.groovy.classgen.asm.OperandStack;
 import org.codehaus.groovy.classgen.asm.VariableSlotLoader;
@@ -46,7 +45,6 @@ import org.objectweb.asm.Label;
 import org.objectweb.asm.MethodVisitor;
 
 import java.util.Map;
-import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import static org.apache.groovy.ast.tools.ExpressionUtils.isThisExpression;
@@ -91,8 +89,6 @@ import static org.objectweb.asm.Opcodes.ISUB;
 import static org.objectweb.asm.Opcodes.LADD;
 import static org.objectweb.asm.Opcodes.LCONST_1;
 import static org.objectweb.asm.Opcodes.LSUB;
-import static org.objectweb.asm.Opcodes.PUTFIELD;
-import static org.objectweb.asm.Opcodes.PUTSTATIC;
 
 /**
  * A specialized version of the multi type binary expression dispatcher which 
is aware of static compilation.
@@ -149,7 +145,8 @@ public class StaticTypesBinaryExpressionMultiTypeDispatcher 
extends BinaryExpres
     @Override
     protected void evaluateBinaryExpressionWithAssignment(final String method, 
final BinaryExpression expression) {
         Expression leftExpression = expression.getLeftExpression();
-        if (leftExpression instanceof PropertyExpression) {
+        if (leftExpression instanceof PropertyExpression
+                && !(leftExpression instanceof AttributeExpression)) {
             PropertyExpression pexp = (PropertyExpression) leftExpression;
 
             BinaryExpression expressionWithoutAssignment = binX(
@@ -171,8 +168,7 @@ public class StaticTypesBinaryExpressionMultiTypeDispatcher 
extends BinaryExpres
                     expressionWithoutAssignment,
                     pexp.isSafe(),
                     pexp.isSpreadSafe(),
-                    pexp.isImplicitThis(),
-                    pexp instanceof AttributeExpression)) {
+                    pexp.isImplicitThis())) {
                 return;
             }
         }
@@ -182,7 +178,8 @@ public class StaticTypesBinaryExpressionMultiTypeDispatcher 
extends BinaryExpres
     @Override
     public void evaluateEqual(final BinaryExpression expression, final boolean 
defineVariable) {
         Expression leftExpression = expression.getLeftExpression();
-        if (leftExpression instanceof PropertyExpression) {
+        if (leftExpression instanceof PropertyExpression
+                && !(leftExpression instanceof AttributeExpression)) {
             PropertyExpression pexp = (PropertyExpression) leftExpression;
             if (!defineVariable && makeSetProperty(
                     pexp.getObjectExpression(),
@@ -190,8 +187,7 @@ public class StaticTypesBinaryExpressionMultiTypeDispatcher 
extends BinaryExpres
                     expression.getRightExpression(),
                     pexp.isSafe(),
                     pexp.isSpreadSafe(),
-                    pexp.isImplicitThis(),
-                    pexp instanceof AttributeExpression)) {
+                    pexp.isImplicitThis())) {
                 return;
             }
             // GROOVY-5620: spread-safe operator on LHS is not supported
@@ -251,93 +247,56 @@ public class 
StaticTypesBinaryExpressionMultiTypeDispatcher extends BinaryExpres
         result.visit(controller.getAcg());
     }
 
-    private boolean makeSetProperty(final Expression receiver, final 
Expression message, final Expression arguments, final boolean safe, final 
boolean spreadSafe, final boolean implicitThis, final boolean isAttribute) {
+    private boolean makeSetProperty(final Expression receiver, final 
Expression message, final Expression arguments, final boolean safe, final 
boolean spreadSafe, final boolean implicitThis) {
         var receiverType = controller.getTypeChooser().resolveType(receiver, 
controller.getClassNode());
         var thisReceiver = isThisExpression(receiver);
         var propertyName = message.getText();
 
-        if (isAttribute || (thisReceiver && 
receiverType.getDeclaredField(propertyName) != null)) {
-            ClassNode current = receiverType;
-            FieldNode fn = null;
-            while (fn == null && current != null) {
-                fn = current.getDeclaredField(propertyName);
-                if (fn == null) {
-                    current = current.getSuperClass();
-                }
+        String setterName = getSetterName(propertyName);
+        MethodNode setterMethod = receiverType.getSetterMethod(setterName, 
false);
+        if (setterMethod != null) {
+            if ((thisReceiver && 
setterMethod.getDeclaringClass().equals(controller.getClassNode()))
+                || (!setterMethod.isPublic() && isOrImplements(receiverType, 
ClassHelper.MAP_TYPE))) {
+                // this.x = ... should not use same-class setter
+                // that.x = ... should not use non-public setter for map
+                setterMethod = null;
+            } else { // GROOVY-11119
+                java.util.List<MethodNode> setters = 
receiverType.getMethods(setterName);
+                setters.removeIf(s -> s.isAbstract() || 
s.getParameters().length != 1);
+                if (setters.size() > 1) setterMethod = null;
             }
-            if (fn != null && receiverType != current && !fn.isPublic()) {
-                // check that direct access is allowed
-                if (!fn.isProtected()) {
-                    return false;
-                }
-                if (!Objects.equals(receiverType.getPackageName(), 
current.getPackageName())) {
-                    return false;
-                }
-                if (!fn.isStatic()) {
-                    receiver.visit(controller.getAcg());
-                }
-                arguments.visit(controller.getAcg());
-                OperandStack operandStack = controller.getOperandStack();
-                operandStack.doGroovyCast(fn.getOriginType());
-                MethodVisitor mv = controller.getMethodVisitor();
-                mv.visitFieldInsn(fn.isStatic() ? PUTSTATIC : PUTFIELD,
-                        BytecodeHelper.getClassInternalName(fn.getOwner()),
-                        propertyName,
-                        BytecodeHelper.getTypeDescription(fn.getOriginType()));
-                operandStack.remove(fn.isStatic() ? 1 : 2);
-                return true;
+        } else {
+            PropertyNode propertyNode = receiverType.getProperty(propertyName);
+            if (propertyNode != null && !propertyNode.isFinal()) {
+                setterMethod = new MethodNode(
+                        setterName,
+                        ACC_PUBLIC,
+                        ClassHelper.VOID_TYPE,
+                        new Parameter[]{new 
Parameter(propertyNode.getOriginType(), "value")},
+                        ClassNode.EMPTY_ARRAY,
+                        EmptyStatement.INSTANCE
+                );
+                setterMethod.setDeclaringClass(receiverType);
+                setterMethod.setSynthetic(true);
             }
         }
+        if (setterMethod != null) {
+            Expression call = StaticPropertyAccessHelper.transformToSetterCall(
+                    receiver,
+                    setterMethod,
+                    arguments,
+                    implicitThis,
+                    safe,
+                    spreadSafe,
+                    true, // to be replaced with a proper test whether a 
return value should be used or not
+                    message
+            );
+            call.visit(controller.getAcg());
+            return true;
+        }
 
-        if (!isAttribute) {
-            String setterName = getSetterName(propertyName);
-            MethodNode setterMethod = receiverType.getSetterMethod(setterName, 
false);
-            if (setterMethod != null) {
-                if ((thisReceiver && 
setterMethod.getDeclaringClass().equals(controller.getClassNode()))
-                    || (!setterMethod.isPublic() && 
isOrImplements(receiverType, ClassHelper.MAP_TYPE))) {
-                    // this.x = ... should not use same-class setter
-                    // that.x = ... should not use non-public setter for map
-                    setterMethod = null;
-                } else { // GROOVY-11119
-                    java.util.List<MethodNode> setters = 
receiverType.getMethods(setterName);
-                    setters.removeIf(s -> s.isAbstract() || 
s.getParameters().length != 1);
-                    if (setters.size() > 1) setterMethod = null;
-                }
-            } else {
-                PropertyNode propertyNode = 
receiverType.getProperty(propertyName);
-                if (propertyNode != null && !propertyNode.isFinal()) {
-                    setterMethod = new MethodNode(
-                            setterName,
-                            ACC_PUBLIC,
-                            ClassHelper.VOID_TYPE,
-                            new Parameter[]{new 
Parameter(propertyNode.getOriginType(), "value")},
-                            ClassNode.EMPTY_ARRAY,
-                            EmptyStatement.INSTANCE
-                    );
-                    setterMethod.setDeclaringClass(receiverType);
-                    setterMethod.setSynthetic(true);
-                }
-            }
-            if (setterMethod != null) {
-                Expression call = 
StaticPropertyAccessHelper.transformToSetterCall(
-                        receiver,
-                        setterMethod,
-                        arguments,
-                        implicitThis,
-                        safe,
-                        spreadSafe,
-                        true, // to be replaced with a proper test whether a 
return value should be used or not
-                        message
-                );
-                call.visit(controller.getAcg());
-                return true;
-            }
-            if (thisReceiver && !controller.isInGeneratedFunction()) {
-                receiverType = controller.getClassNode();
-            }
-            if (makeSetPrivateFieldWithBridgeMethod(receiver, receiverType, 
propertyName, arguments, safe, spreadSafe, implicitThis)) {
-                return true;
-            }
+        if (makeSetPrivateFieldWithBridgeMethod(receiver, (thisReceiver && 
!controller.isInGeneratedFunction()) ? controller.getClassNode() : 
receiverType, propertyName, arguments, safe, spreadSafe, implicitThis)) {
+            return true;
         }
 
         return false;
@@ -365,7 +324,7 @@ public class StaticTypesBinaryExpressionMultiTypeDispatcher 
extends BinaryExpres
         ClassNode classNode = controller.getClassNode();
         if (field != null && field.isPrivate() && 
!receiverType.equals(classNode)
                 && 
(StaticInvocationWriter.isPrivateBridgeMethodsCallAllowed(receiverType, 
classNode)
-                    || 
StaticInvocationWriter.isPrivateBridgeMethodsCallAllowed(classNode,receiverType)))
 {
+                    || 
StaticInvocationWriter.isPrivateBridgeMethodsCallAllowed(classNode, 
receiverType))) {
             Map<String, MethodNode> mutators = 
receiverType.redirect().getNodeMetaData(PRIVATE_FIELDS_MUTATORS);
             if (mutators != null) {
                 MethodNode methodNode = mutators.get(fieldName);
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy 
b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index 2d41d771a6..69d10e1dac 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -419,6 +419,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
             test({k->c} as Input, {k->c} as State)
         '''
 
+        tearDown(); setUp()
         File parentDir = File.createTempDir()
         config.with {
             targetDirectory = File.createTempDir()
@@ -2036,6 +2037,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
             test { Class clazz -> clazz.newInstance() }
         '''
 
+        tearDown(); setUp()
         File parentDir = File.createTempDir()
         config.with {
             targetDirectory = File.createTempDir()
@@ -4149,6 +4151,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
         '''
 
         // GROOVY-9822
+        tearDown(); setUp()
         File parentDir = File.createTempDir()
         config.with {
             targetDirectory = File.createTempDir()
@@ -5151,6 +5154,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
         '''
 
         // GROOVY-9821
+        tearDown(); setUp()
         for (op in ['.', '?.', '*.']) {
             File parentDir = File.createTempDir()
             config.with {
@@ -5216,8 +5220,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
             assert n == 1
         '''
 
-        //
-
+        tearDown(); setUp()
         File parentDir = File.createTempDir()
         config.with {
             targetDirectory = File.createTempDir()
diff --git 
a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
 
b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
index df648e7324..4e2b2d5bd5 100644
--- 
a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
+++ 
b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
@@ -50,11 +50,11 @@ final class FieldsAndPropertiesStaticCompileTest extends 
FieldsAndPropertiesSTCT
 
             assert d.time == 1
         '''
-        assert astTrees.values().any {
-            it.toString().contains 'INVOKEVIRTUAL java/util/Date.setTime (J)V'
-        }
+        String typeName = astTrees.keySet().first()
+        assert astTrees[typeName][1].contains('INVOKEVIRTUAL 
java/util/Date.setTime (J)V')
     }
 
+    // GROOVY-5619
     void testUseDirectWriteFieldAccess() {
         assertScript '''
             class C {
@@ -76,6 +76,7 @@ final class FieldsAndPropertiesStaticCompileTest extends 
FieldsAndPropertiesSTCT
             assert d.isSetterCalled() == false
             assert d.x == 2
         '''
+        assert astTrees['C'][1].contains('PUTFIELD C.x')
         assert astTrees['D'][1].contains('PUTFIELD C.x')
     }
 
@@ -193,7 +194,7 @@ final class FieldsAndPropertiesStaticCompileTest extends 
FieldsAndPropertiesSTCT
     }
 
     void testReadFieldFromSameClass() {
-        ['', 'public', 'private', 'protected', 
'@groovy.transform.PackageScope'].each { mod ->
+        for (mod in ['', 'public', 'private', 'protected', 
'@groovy.transform.PackageScope']) {
             assertScript """
                 class C {
                     $mod int x
@@ -203,13 +204,13 @@ final class FieldsAndPropertiesStaticCompileTest extends 
FieldsAndPropertiesSTCT
                 }
                 assert new C().m() == 0
             """
-            def a = astTrees['C'][1]
-            assert (a =~ 'GETFIELD C.x').collect().size() == mod.empty ? 2 : 1
+            String c = astTrees['C'][1]
+            assert (c =~ 'GETFIELD C.x').collect().size() == mod.empty ? 2 : 1
         }
     }
 
     void testWriteFieldFromSameClass() {
-        ['', 'public', 'private', 'protected', 
'@groovy.transform.PackageScope'].each { mod ->
+        for (mod in ['', 'public', 'private', 'protected', 
'@groovy.transform.PackageScope']) {
             assertScript """
                 class C {
                     $mod int x
@@ -220,13 +221,13 @@ final class FieldsAndPropertiesStaticCompileTest extends 
FieldsAndPropertiesSTCT
                 }
                 new C().m() == 5
             """
-            def a = astTrees['C'][1]
-            assert (a =~ 'PUTFIELD C.x').collect().size() == mod.empty ? 2 : 1
+            String c = astTrees['C'][1]
+            assert (c =~ 'PUTFIELD C.x').collect().size() == mod.empty ? 2 : 1
         }
     }
 
     void testReadFieldFromSuperClass() {
-        ['public', 'protected', '@groovy.transform.PackageScope'].each { mod ->
+        for (mod in ['public', 'protected', '@groovy.transform.PackageScope']) 
{
             assertScript """
                 class C {
                     $mod int x
@@ -238,7 +239,7 @@ final class FieldsAndPropertiesStaticCompileTest extends 
FieldsAndPropertiesSTCT
                 }
                 assert new D().m() == 0
             """
-            def d = astTrees['D'][1]
+            String d = astTrees['D'][1]
             assert d.contains('GETFIELD C.x')
         }
     }
@@ -260,9 +261,9 @@ final class FieldsAndPropertiesStaticCompileTest extends 
FieldsAndPropertiesSTCT
             }
             assert new D().m() == 0
         '''
-        def b = astTrees['D'][1]
-        assert  b.contains('GETFIELD p/C.x')
-        assert !b.contains('INVOKEINTERFACE 
groovy/lang/GroovyObject.getProperty')
+        String  d = astTrees['D'][1]
+        assert  d.contains('GETFIELD p/C.x')
+        assert !d.contains('INVOKEINTERFACE 
groovy/lang/GroovyObject.getProperty')
     }
 
     // GROOVY-9791
@@ -282,13 +283,13 @@ final class FieldsAndPropertiesStaticCompileTest extends 
FieldsAndPropertiesSTCT
             }
             assert D.m() == 0
         '''
-        def d = astTrees['D'][1]
+        String  d = astTrees['D'][1]
         assert  d.contains('GETSTATIC D.x')
         assert !d.contains('INVOKESTATIC 
org/codehaus/groovy/runtime/ScriptBytecodeAdapter.getGroovyObjectProperty')
     }
 
     void testReadPropertyFromSuperClass() {
-        ['', 'public', 'private', 'protected', 
'@groovy.transform.PackageScope'].each { mod ->
+        for (mod in ['', 'public', 'private', 'protected', 
'@groovy.transform.PackageScope']) {
             assertScript """
                 class C {
                     $mod int x
@@ -301,7 +302,7 @@ final class FieldsAndPropertiesStaticCompileTest extends 
FieldsAndPropertiesSTCT
                 }
                 assert new D().m() == 0
             """
-            def d = astTrees['D'][1]
+            String  d = astTrees['D'][1]
             assert !d.contains('GETFIELD C.x') : 'no GETFIELD in D'
             assert  d.contains('INVOKEVIRTUAL D.getX') : 'getX() in D'
         }
@@ -327,7 +328,7 @@ final class FieldsAndPropertiesStaticCompileTest extends 
FieldsAndPropertiesSTCT
             d.m()
             assert d.isGetterCalled() == false
         '''
-        def d = astTrees['D'][1]
+        String d = astTrees['D'][1]
         assert d.contains('GETFIELD C.x')
     }
 
@@ -545,45 +546,36 @@ final class FieldsAndPropertiesStaticCompileTest extends 
FieldsAndPropertiesSTCT
     }
 
     void testCallSetterAsPropertyWithinFinallyBlockShouldNotThrowVerifyError() 
{
-        try {
-            assertScript '''
-                class C {
-                   void setOut(int a) {}
-                }
-                def c = new C()
-                try {
-                } finally {
-                    c.out = 1
-                }
-            '''
-        } finally {
-            assert astTrees.values().any {
-                it.toString().contains 'INVOKEVIRTUAL C.setOut (I)V'
+        assertScript '''
+            class C {
+               void setOut(int a) {}
             }
-        }
+            def c = new C()
+            try {
+            } finally {
+                c.out = 1
+            }
+        '''
+        String typeName = astTrees.keySet().minus('C').first()
+        assert astTrees[typeName][1].contains('INVOKEVIRTUAL C.setOut (I)V')
     }
 
     void 
testCallMultiSetterAsPropertyWithinFinallyBlockShouldNotThrowVerifyError() {
-        try {
-            assertScript '''
-                class C {
-                   void setOut(int a) {}
-                   void setOut(String a) {}
-                }
-                def c = new C()
-                try {
-                } finally {
-                    c.out = 1
-                    c.out = 'foo'
-                }
-            '''
-        } finally {
-            assert astTrees.values().any {
-                def code = it.toString()
-                code.contains('INVOKEVIRTUAL C.setOut (I)V')
-                        && code.contains('INVOKEVIRTUAL C.setOut 
(Ljava/lang/String;)V')
+        assertScript '''
+            class C {
+               void setOut(int a) {}
+               void setOut(String a) {}
             }
-        }
+            def c = new C()
+            try {
+            } finally {
+                c.out = 1
+                c.out = 'foo'
+            }
+        '''
+        String typeName = astTrees.keySet().minus('C').first()
+        assert astTrees[typeName][1].contains('INVOKEVIRTUAL C.setOut (I)V')
+        assert astTrees[typeName][1].contains('INVOKEVIRTUAL C.setOut 
(Ljava/lang/String;)V')
     }
 
     // GROOVY-7698
@@ -624,179 +616,154 @@ final class FieldsAndPropertiesStaticCompileTest 
extends FieldsAndPropertiesSTCT
             }
             new Bar().test()
         '''
-
-        def bar = astTrees['Bar'][1]
+        String bar = astTrees['Bar'][1]
         assert bar.contains('INVOKEVIRTUAL Bar.setX (Ljava/lang/Long;)V')
         assert bar.contains('INVOKEVIRTUAL Bar.setX (Ljava/util/Date;)V')
         assert !bar.contains('INVOKESTATIC 
org/codehaus/groovy/runtime/ScriptBytecodeAdapter.setGroovyObjectProperty ')
     }
 
     void testPrivateFieldMutationInClosureUsesBridgeMethod() {
-        try {
-            assertScript '''
-                class Foo {
-                    private String s
-                    Closure c = { this.s = 'abc' }
-
-                    void test() {
-                        c()
-                        assert s == 'abc'
-                    }
+        assertScript '''
+            class Foo {
+                private String s
+                Closure c = { this.s = 'abc' }
+
+                void test() {
+                    c()
+                    assert s == 'abc'
                 }
-                new Foo().test()
-            '''
-        } finally {
-            assert astTrees['Foo$_closure1'][1].contains('INVOKESTATIC 
Foo.pfaccess$00 (LFoo;Ljava/lang/String;)Ljava/lang/String')
-        }
+            }
+            new Foo().test()
+        '''
+        assert astTrees['Foo$_closure1'][1].contains('INVOKESTATIC 
Foo.pfaccess$00 (LFoo;Ljava/lang/String;)Ljava/lang/String')
     }
 
     void testImplicitPrivateFieldMutationInClosureUsesBridgeMethod() {
-        try {
-            assertScript '''
-                class Foo {
-                    private String s
-                    Closure c = { s = 'abc' }
-
-                    String test() {
-                        c()
-                        assert s == 'abc'
-                    }
+        assertScript '''
+            class Foo {
+                private String s
+                Closure c = { s = 'abc' }
+
+                String test() {
+                    c()
+                    assert s == 'abc'
                 }
-                new Foo().test()
-            '''
-        } finally {
-            assert astTrees['Foo$_closure1'][1].contains('INVOKESTATIC 
Foo.pfaccess$00 (LFoo;Ljava/lang/String;)Ljava/lang/String')
-        }
+            }
+            new Foo().test()
+        '''
+        assert astTrees['Foo$_closure1'][1].contains('INVOKESTATIC 
Foo.pfaccess$00 (LFoo;Ljava/lang/String;)Ljava/lang/String')
     }
 
     void testPrivateStaticFieldMutationInClosureUsesBridgeMethod() {
-        try {
-            assertScript '''
-                class Foo {
-                    private static String s
-                    Closure c = { s = 'abc' }
-
-                    String test() {
-                        c()
-                        assert s == 'abc'
-                    }
+        assertScript '''
+            class Foo {
+                private static String s
+                Closure c = { s = 'abc' }
+
+                String test() {
+                    c()
+                    assert s == 'abc'
                 }
-                new Foo().test()
-            '''
-        } finally {
-            assert astTrees['Foo$_closure1'][1].contains('INVOKESTATIC 
Foo.pfaccess$00 (LFoo;Ljava/lang/String;)Ljava/lang/String')
-        }
+            }
+            new Foo().test()
+        '''
+        assert astTrees['Foo$_closure1'][1].contains('INVOKESTATIC 
Foo.pfaccess$00 (LFoo;Ljava/lang/String;)Ljava/lang/String')
     }
 
     void testPrivateFieldMutationInAICUsesBridgeMethod() {
-        try {
-            assertScript '''
-                class C {
-                    private int x
-                    void test() {
-                        def aic = new Runnable() { void run() { C.this.x = 666 
} }
-                        aic.run()
-                        assert x == 666
-                    }
+        assertScript '''
+            class C {
+                private int x
+                void test() {
+                    def aic = new Runnable() { void run() { C.this.x = 666 } }
+                    aic.run()
+                    assert x == 666
                 }
-                new C().test()
-            '''
-        } finally {
-            assert astTrees['C$1'][1].contains('INVOKESTATIC C.pfaccess$00 
(LC;I)I')
-        }
+            }
+            new C().test()
+        '''
+        assert astTrees['C$1'][1].contains('INVOKESTATIC C.pfaccess$00 
(LC;I)I')
     }
 
     void testImplicitPrivateFieldMutationInAICUsesBridgeMethod() {
-        try {
-            assertScript '''
-                class C {
-                    private int x
-                    void test() {
-                        def aic = new Runnable() { void run() { x = 666 } }
-                        aic.run()
-                        assert x == 666
-                    }
+        assertScript '''
+            class C {
+                private int x
+                void test() {
+                    def aic = new Runnable() { void run() { x = 666 } }
+                    aic.run()
+                    assert x == 666
                 }
-                new C().test()
-            '''
-        } finally {
-            assert astTrees['C$1'][1].contains('INVOKESTATIC C.pfaccess$00 
(LC;I)I')
-        }
+            }
+            new C().test()
+        '''
+        assert astTrees['C$1'][1].contains('INVOKESTATIC C.pfaccess$00 
(LC;I)I')
     }
 
     void testPrivateStaticFieldMutationInAICUsesBridgeMethod() {
-        try {
-            assertScript '''
-                class C {
-                    private static int x
-                    void test() {
-                        def aic = new Runnable() { void run() { x = 666 } }
-                        aic.run()
-                        assert x == 666
-                    }
+        assertScript '''
+            class C {
+                private static int x
+                void test() {
+                    def aic = new Runnable() { void run() { x = 666 } }
+                    aic.run()
+                    assert x == 666
                 }
-                new C().test()
-            '''
-        } finally {
-            assert astTrees['C$1'][1].contains('INVOKESTATIC C.pfaccess$00 
(LC;I)I')
-        }
+            }
+            new C().test()
+        '''
+        assert astTrees['C$1'][1].contains('INVOKESTATIC C.pfaccess$00 
(LC;I)I')
     }
 
     void testMultiplePrivateFieldMutatorBridgeMethods() {
-        try {
-            assertScript '''
-                class C {
-                    private int x
-                    private String y
-                    Closure mutate = { x = 1; y = 'abc' }
-
-                    void test() {
-                        mutate()
-                        assert x == 1
-                        assert y == 'abc'
-                    }
+        assertScript '''
+            class C {
+                private int x
+                private String y
+                Closure mutate = { x = 1; y = 'abc' }
+
+                void test() {
+                    mutate()
+                    assert x == 1
+                    assert y == 'abc'
                 }
-                new C().test()
-            '''
-        } finally {
-            assert astTrees['C$_closure1'][1].contains('INVOKESTATIC 
C.pfaccess$00 (LC;I)I')
-            assert astTrees['C$_closure1'][1].contains('INVOKESTATIC 
C.pfaccess$01 (LC;Ljava/lang/String;)Ljava/lang/String;')
-        }
+            }
+            new C().test()
+        '''
+        assert astTrees['C$_closure1'][1].contains('INVOKESTATIC C.pfaccess$00 
(LC;I)I')
+        assert astTrees['C$_closure1'][1].contains('INVOKESTATIC C.pfaccess$01 
(LC;Ljava/lang/String;)Ljava/lang/String;')
     }
 
     void testPrivateFieldBridgeMethodsAreGeneratedAsNecessary() {
-        try {
-            assertScript '''
-                class C {
-                    private int accessed = 0
-                    private String mutated
-                    private String accessedAndMutated = ''
-                    Closure cl = {
-                        println accessed
-                        mutated = 'abc'
-                        println accessedAndMutated
-                        accessedAndMutated = 'def'
-                    }
-                    void test() {
-                        cl()
-                        assert mutated == 'abc'
-                        assert accessedAndMutated == 'def'
-                    }
+        assertScript '''
+            class C {
+                private int accessed = 0
+                private String mutated
+                private String accessedAndMutated = ''
+                Closure cl = {
+                    println accessed
+                    mutated = 'abc'
+                    println accessedAndMutated
+                    accessedAndMutated = 'def'
                 }
-                new C().test()
-            '''
-        } finally {
-            def dump = astTrees['C'][1]
-            assert dump.contains('pfaccess$0') // accessor bridge method for 
'accessed'
-            assert !dump.contains('pfaccess$00') // no mutator bridge method 
for 'accessed'
-            assert dump.contains('pfaccess$01') // mutator bridge method for 
'mutated'
-            assert dump.contains('pfaccess$1') // accessor bridge method for 
'mutated' -- GROOVY-9385
-            assert dump.contains('pfaccess$2') // accessor bridge method for 
'accessedAndMutated'
-            assert dump.contains('pfaccess$02') // mutator bridge method for 
'accessedAndMutated'
-            dump = astTrees['C$_closure1'][1]
-            assert dump.contains('INVOKESTATIC C.pfaccess$2 
(LC;)Ljava/lang/String;')
-            assert dump.contains('INVOKESTATIC C.pfaccess$02 
(LC;Ljava/lang/String;)Ljava/lang/String;')
-        }
+                void test() {
+                    cl()
+                    assert mutated == 'abc'
+                    assert accessedAndMutated == 'def'
+                }
+            }
+            new C().test()
+        '''
+        String dump = astTrees['C'][1]
+        assert dump.contains('pfaccess$0') // accessor bridge method for 
'accessed'
+        assert !dump.contains('pfaccess$00') // no mutator bridge method for 
'accessed'
+        assert dump.contains('pfaccess$01') // mutator bridge method for 
'mutated'
+        assert dump.contains('pfaccess$1') // accessor bridge method for 
'mutated' -- GROOVY-9385
+        assert dump.contains('pfaccess$2') // accessor bridge method for 
'accessedAndMutated'
+        assert dump.contains('pfaccess$02') // mutator bridge method for 
'accessedAndMutated'
+               dump = astTrees['C$_closure1'][1]
+        assert dump.contains('INVOKESTATIC C.pfaccess$2 
(LC;)Ljava/lang/String;')
+        assert dump.contains('INVOKESTATIC C.pfaccess$02 
(LC;Ljava/lang/String;)Ljava/lang/String;')
     }
 
     // GROOVY-8369
diff --git 
a/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTestSupport.groovy
 
b/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTestSupport.groovy
index 7b67973346..b5de1c6022 100644
--- 
a/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTestSupport.groovy
+++ 
b/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTestSupport.groovy
@@ -27,30 +27,25 @@ import org.codehaus.groovy.control.SourceUnit
 import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer
 import org.codehaus.groovy.control.customizers.CompilationCustomizer
 import org.codehaus.groovy.control.customizers.ImportCustomizer
-import org.codehaus.groovy.tools.GroovyClass
 import org.objectweb.asm.ClassReader
 import org.objectweb.asm.util.CheckClassAdapter
 
 import java.security.CodeSource
 
 /**
- * A mixin class which can be used to transform a static type checking test 
case into a
- * static compilation test case.
- *
- * On the beginning of a test method, it initializes a property which is 
available
- * to the developer for additional tests:
- * <ul>
- *     <li>astTrees: a map which has for key the names of classes generated in 
assertScript and an array of length 2
- *     as a value, for which the first element is the generated AST tree of 
the class, and the second element is
- *     the result of the ASM check class adapter string, which can be used to 
verify generated bytecode.</li>
- * </ul>
+ * A mixin class which can be used to transform a static type checking test 
case
+ * into a static compilation test case.
+ * <p>
+ * For each test method, it initializes the property {@code astTrees}, which is
+ * available to the developer for additional checks. This property provides the
+ * AST and the result of the ASM check class adapter (bytecode) for each class.
  */
 trait StaticCompilationTestSupport {
-    Map<String, Object[]> astTrees
-    CustomCompilationUnit compilationUnit
+    Map<String, Tuple2<ClassNode, String>> astTrees
+    CompilationUnit compilationUnit
 
     void extraSetup() {
-        astTrees = [:]
+        astTrees = new HashMap<>()
         config = new CompilerConfiguration()
         config.addCompilationCustomizers(
                 new ImportCustomizer().tap {
@@ -102,15 +97,7 @@ trait StaticCompilationTestSupport {
 
         @Override
         protected CompilationUnit createCompilationUnit(final 
CompilerConfiguration config, final CodeSource source) {
-            def cu = new CustomCompilationUnit(config, source, this)
-            testCase.compilationUnit = cu
-            return cu
-        }
-    }
-
-    static class CustomCompilationUnit extends CompilationUnit {
-        CustomCompilationUnit(final CompilerConfiguration configuration, final 
CodeSource security, final GroovyClassLoader loader) {
-            super(configuration, security, loader)
+            testCase.compilationUnit = new CompilationUnit(config, source, 
this)
         }
     }
 
@@ -125,17 +112,22 @@ trait StaticCompilationTestSupport {
         @Override
         void call(final SourceUnit source, final GeneratorContext context, 
final ClassNode classNode) {
             def unit = testCase.compilationUnit
-            if (!unit) return
-            unit.classes.each { GroovyClass groovyClass ->
-                StringWriter stringWriter = new StringWriter()
+            if (unit) {
+                def groovyClass = unit.classes.find { it.name == 
classNode.name }
+                def stringWriter = new StringWriter()
                 try {
-                    ClassReader cr = new ClassReader(groovyClass.bytes)
-                    CheckClassAdapter.verify(cr, source.getClassLoader(), 
true, new PrintWriter(stringWriter))
-                } catch (Throwable e)  {
-                    // not a problem
-                    e.printStackTrace(new PrintWriter(stringWriter))
+                    CheckClassAdapter.verify(new 
ClassReader(groovyClass.bytes),
+                        source.classLoader, true, new 
PrintWriter(stringWriter))
+                } catch (Throwable t)  {
+                    t.printStackTrace(new PrintWriter(stringWriter))
+                }
+                testCase.astTrees[groovyClass.name] = new Tuple2<>(classNode, 
stringWriter.toString())
+
+                for (innerClass in classNode.innerClasses) { // collect 
closures, etc.
+                    if 
(context.compileUnit.getGeneratedInnerClass(innerClass.name)) {
+                        this.call(source, context, innerClass)
+                    }
                 }
-                testCase.astTrees[groovyClass.name] = [classNode, 
stringWriter.toString()] as Object[]
             }
         }
     }
diff --git 
a/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileConstructorsTest.groovy
 
b/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileConstructorsTest.groovy
index 3e6d03b2d2..89569cd829 100644
--- 
a/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileConstructorsTest.groovy
+++ 
b/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileConstructorsTest.groovy
@@ -100,10 +100,9 @@ class StaticCompileConstructorsTest extends 
ConstructorsSTCTest implements Stati
     @Override
     void testMapStyleConstructorWithOverloadedSetterName() {
         super.testMapStyleConstructorWithOverloadedSetterName()
-
-        String  bytecode = astTrees.values()[1][1]
-        assert  bytecode.contains('INVOKEVIRTUAL C.setP (Ljava/lang/String;)V')
-        assert  bytecode.contains('INVOKEVIRTUAL C.setP 
(Ljava/util/regex/Pattern;)V')
-        assert !bytecode.contains('INVOKESTATIC 
org/codehaus/groovy/runtime/ScriptBytecodeAdapter.setGroovyObjectProperty')
+        String  asserts = astTrees.find{ it.key != 'C' }.value[1]
+        assert  asserts.contains('INVOKEVIRTUAL C.setP (Ljava/lang/String;)V')
+        assert  asserts.contains('INVOKEVIRTUAL C.setP 
(Ljava/util/regex/Pattern;)V')
+        assert !asserts.contains('INVOKESTATIC 
org/codehaus/groovy/runtime/ScriptBytecodeAdapter.setGroovyObjectProperty')
     }
 }


Reply via email to