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 642a7532d7 GROOVY-10687: SC: replace access bridge methods with direct 
method calls
642a7532d7 is described below

commit 642a7532d71a7bce3eba411c7fa865c57195ccca
Author: Eric Milles <[email protected]>
AuthorDate: Tue Sep 24 14:12:57 2024 -0500

    GROOVY-10687: SC: replace access bridge methods with direct method calls
---
 .../groovy/classgen/asm/InvocationWriter.java      |   7 +-
 .../classgen/asm/sc/StaticInvocationWriter.java    | 136 ++++++---------------
 .../transform/sc/StaticCompilationVisitor.java     |  18 ++-
 .../transform/stc/StaticTypeCheckingVisitor.java   |  17 +--
 .../classgen/asm/sc/BugsStaticCompileTest.groovy   |   2 +-
 .../asm/sc/MethodCallsStaticCompilationTest.groovy |   1 +
 .../groovy/classgen/asm/sc/bugs/Groovy7276.groovy  |  37 ++++--
 7 files changed, 88 insertions(+), 130 deletions(-)

diff --git 
a/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java 
b/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java
index 89eac79c99..7d5141f870 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java
@@ -331,11 +331,8 @@ public class InvocationWriter {
                 }
             }
         }
-        if (containsSpreadExpression) return false;
-        if (origin instanceof MethodCallExpression) {
-            MethodCallExpression mce = (MethodCallExpression) origin;
-            if (mce.getMethodTarget() != null)
-                return writeDirectMethodCall(mce.getMethodTarget(), 
implicitThis, receiver, makeArgumentList(arguments));
+        if (!containsSpreadExpression && origin instanceof 
MethodCallExpression) {
+            return writeDirectMethodCall(((MethodCallExpression) 
origin).getMethodTarget(), implicitThis, receiver, makeArgumentList(arguments));
         }
         return false;
     }
diff --git 
a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java 
b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
index e9198ca39e..cffa427daa 100644
--- 
a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
+++ 
b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
@@ -54,7 +54,6 @@ import org.codehaus.groovy.classgen.asm.OperandStack;
 import org.codehaus.groovy.classgen.asm.TypeChooser;
 import org.codehaus.groovy.classgen.asm.VariableSlotLoader;
 import org.codehaus.groovy.classgen.asm.WriterController;
-import org.codehaus.groovy.runtime.InvokerHelper;
 import org.codehaus.groovy.syntax.SyntaxException;
 import org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys;
 import org.codehaus.groovy.transform.sc.StaticCompilationVisitor;
@@ -75,9 +74,9 @@ import java.util.stream.Collectors;
 
 import static org.apache.groovy.ast.tools.ClassNodeUtils.formatTypeName;
 import static org.apache.groovy.ast.tools.ClassNodeUtils.isSubtype;
-import static org.apache.groovy.ast.tools.ClassNodeUtils.samePackageName;
 import static org.apache.groovy.ast.tools.ExpressionUtils.isNullConstant;
 import static org.apache.groovy.ast.tools.ExpressionUtils.isSuperExpression;
+import static org.apache.groovy.ast.tools.ExpressionUtils.isThisExpression;
 import static org.apache.groovy.ast.tools.ExpressionUtils.isThisOrSuper;
 import static org.codehaus.groovy.ast.ClassHelper.isGStringType;
 import static org.codehaus.groovy.ast.ClassHelper.isGeneratedFunction;
@@ -88,8 +87,8 @@ import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.attrX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.classX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.inSamePackage;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.nullX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.propX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
@@ -105,24 +104,6 @@ import static org.objectweb.asm.Opcodes.INVOKESTATIC;
 
 public class StaticInvocationWriter extends InvocationWriter {
 
-    private static final ClassNode INVOKERHELPER_CLASSNODE = 
ClassHelper.make(InvokerHelper.class);
-    private static final MethodNode INVOKERHELPER_INVOKEMETHOD = 
INVOKERHELPER_CLASSNODE.getMethod(
-            "invokeMethodSafe",
-            new Parameter[]{
-                    new Parameter(ClassHelper.OBJECT_TYPE, "object"),
-                    new Parameter(ClassHelper.STRING_TYPE, "name"),
-                    new Parameter(ClassHelper.OBJECT_TYPE, "args")
-            }
-    );
-    private static final MethodNode INVOKERHELPER_INVOKESTATICMETHOD = 
INVOKERHELPER_CLASSNODE.getMethod(
-            "invokeStaticMethod",
-            new Parameter[]{
-                    new Parameter(ClassHelper.CLASS_Type, "clazz"),
-                    new Parameter(ClassHelper.STRING_TYPE, "name"),
-                    new Parameter(ClassHelper.OBJECT_TYPE, "args")
-            }
-    );
-
     private final AtomicInteger labelCounter = new AtomicInteger();
 
     private MethodCallExpression currentCall;
@@ -166,7 +147,7 @@ public class StaticInvocationWriter extends 
InvocationWriter {
                 MethodNode bridge = null;
                 if (call.getNodeMetaData(StaticTypesMarker.PV_METHODS_ACCESS) 
!= null) {
                     Map<MethodNode, MethodNode> bridgeMethods = 
declaringClass.getNodeMetaData(StaticCompilationMetadataKeys.PRIVATE_BRIDGE_METHODS);
-                    bridge = bridgeMethods != null ? bridgeMethods.get(cn) : 
null;
+                    if (bridgeMethods != null) bridge = bridgeMethods.get(cn);
                 }
                 if (bridge instanceof ConstructorNode) {
                     ArgumentListExpression newArgs = args(nullX());
@@ -293,14 +274,15 @@ public class StaticInvocationWriter extends 
InvocationWriter {
     protected boolean writeDirectMethodCall(final MethodNode target, final 
boolean implicitThis, final Expression receiver, final TupleExpression args) {
         if (target == null) return false;
 
-        ClassNode classNode = controller.getClassNode();
+        ClassNode enclosingClass = controller.getClassNode();
+        ClassNode declaringClass = target.getDeclaringClass();
 
         if (target instanceof ExtensionMethodNode) {
             ExtensionMethodNode emn = (ExtensionMethodNode) target;
             MethodVisitor mv = controller.getMethodVisitor();
-            MethodNode node = emn.getExtensionMethodNode();
-            Parameter[] parameters = node.getParameters();
-            ClassNode returnType = node.getReturnType();
+            MethodNode mn = emn.getExtensionMethodNode();
+            Parameter[] parameters = mn.getParameters();
+            ClassNode returnType = mn.getReturnType();
 
             List<Expression> argumentList = new ArrayList<>();
             if (emn.isStaticExtension()) {
@@ -308,12 +290,12 @@ public class StaticInvocationWriter extends 
InvocationWriter {
             } else if (!isThisOrSuper(receiver) || 
!controller.isInGeneratedFunction()) {
                 argumentList.add(receiver);
             } else {
-                argumentList.add(thisObjectExpression(classNode, 
target.getDeclaringClass()));
+                argumentList.add(thisObjectExpression(enclosingClass, 
declaringClass));
             }
             argumentList.addAll(args.getExpressions());
             loadArguments(argumentList, parameters);
 
-            String owner = 
BytecodeHelper.getClassInternalName(node.getDeclaringClass());
+            String owner = 
BytecodeHelper.getClassInternalName(mn.getDeclaringClass());
             String desc = BytecodeHelper.getMethodDescriptor(returnType, 
parameters);
             mv.visitMethodInsn(INVOKESTATIC, owner, target.getName(), desc, 
false);
             controller.getOperandStack().remove(argumentList.size());
@@ -326,65 +308,42 @@ public class StaticInvocationWriter extends 
InvocationWriter {
             return true;
         }
 
-        if (target == StaticTypeCheckingVisitor.CLOSURE_CALL_VARGS) {
-            // wrap arguments into an array
-            Expression arr = new ArrayExpression(ClassHelper.OBJECT_TYPE, 
args.getExpressions());
-            return super.writeDirectMethodCall(target, implicitThis, receiver, 
args(arr));
+        if (target == StaticTypeCheckingVisitor.CLOSURE_CALL_VARGS) { // wrap 
arguments in an array
+            Expression array = new ArrayExpression(ClassHelper.OBJECT_TYPE, 
args.getExpressions());
+            return super.writeDirectMethodCall(target, implicitThis, receiver, 
args(array));
         }
 
-        if (!target.isPublic()
-                && controller.isInGeneratedFunction()
-                && target.getDeclaringClass() != classNode) {
-            if (!tryBridgeMethod(target, receiver, implicitThis, args, 
classNode)) {
-                // replace call with an invoker helper call
-                MethodNode methodNode = target.isStatic() ? 
INVOKERHELPER_INVOKESTATICMETHOD : INVOKERHELPER_INVOKEMETHOD;
-                MethodCallExpression mce = callX(
-                        classX(INVOKERHELPER_CLASSNODE),
-                        methodNode.getName(),
-                        args(
-                                target.isStatic() ? 
classX(target.getDeclaringClass()) : receiver,
-                                constX(target.getName()),
-                                new ArrayExpression(ClassHelper.OBJECT_TYPE, 
args.getExpressions())
-                        )
-                );
-                mce.setMethodTarget(methodNode);
-                mce.visit(controller.getAcg());
-            }
-            return true;
-        }
-
-        if (target.isPrivate() && tryPrivateMethod(target, implicitThis, 
receiver, args, classNode)) {
-            return true;
-        }
+        ClassNode receiverType = receiver == null ? ClassHelper.OBJECT_TYPE : 
controller.getTypeChooser().resolveType(receiver, controller.getThisType());
 
-        Expression fixedReceiver = receiver;
-        boolean    fixedImplicitThis = implicitThis;
-        if (target.isPackageScope()) { // GROOVY-11373
-            if (!samePackageName(target.getDeclaringClass(), classNode)) {
-                writeMethodAccessError(target, receiver != null ? receiver : 
args);
-            }
-        } else if (target.isProtected()) {
-            ClassNode node = receiver == null ? ClassHelper.OBJECT_TYPE : 
controller.getTypeChooser().resolveType(receiver, classNode);
-            if (!implicitThis && !isThisOrSuper(receiver) && 
!samePackageName(node, classNode)
-                    && 
StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(node, 
target.getDeclaringClass())) {
-                writeMethodAccessError(target, receiver != null ? receiver : 
args);
-            } else if (!isSubtype(target.getDeclaringClass(), node) && 
tryBridgeMethod(target, receiver, implicitThis, args, classNode)) {
-                return true;
+        if 
(AsmClassGenerator.isMemberDirectlyAccessible(target.getModifiers(), 
declaringClass, enclosingClass)
+                && !(target.isProtected() && !inSamePackage(declaringClass, 
enclosingClass) && !isSubtype(receiverType, enclosingClass))) { // GROOVY-7325
+            boolean isThisImplicit = implicitThis;
+            Expression theReceiver = receiver;
+            if (implicitThis && isThisExpression(receiver)
+                    && !isSubtype(declaringClass, enclosingClass)) {
+                if (target.isStatic()) {
+                    theReceiver = classX(declaringClass);
+                } else if (!controller.isInGeneratedFunction()) {
+                    theReceiver = propX(classX(declaringClass), "this");
+                } else {
+                    theReceiver = thisObjectExpression(enclosingClass, 
declaringClass);
+                }
+                if (!(theReceiver instanceof VariableExpression)) 
isThisImplicit = false;
+                theReceiver.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, 
declaringClass);
             }
-        } else if (target.isPublic() && receiver != null) {
-            if (implicitThis
-                    && controller.isInGeneratedFunction()
-                    && !isSubtype(target.getDeclaringClass(), classNode)) {
-                fixedReceiver = thisObjectExpression(classNode, 
target.getDeclaringClass());
-                if (!(fixedReceiver instanceof VariableExpression)) 
fixedImplicitThis = false;
+            if (theReceiver != null && !isSuperExpression(receiver) && 
!isClassWithSuper(receiver)
+                    && 
currentCall.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER) == null) {
+                // call CHECKCAST in order to avoid calls to castToType (aka 
dynamic behaviour)
+                theReceiver = new CheckcastReceiverExpression(theReceiver, 
target);
             }
+            return super.writeDirectMethodCall(target, isThisImplicit, 
theReceiver, args);
+
+        } else if (tryBridgeMethod(target, receiver, implicitThis, args, 
enclosingClass)) {
+            return true;
+        } else {
+            writeMethodAccessError(target, receiver != null ? receiver : args);
+            return false;
         }
-        if (receiver != null && !isSuperExpression(receiver) && 
!isClassWithSuper(receiver)) {
-            // in order to avoid calls to castToType, which is the dynamic 
behaviour, make sure that we call CHECKCAST instead then replace the top 
operand type
-            if 
(currentCall.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER) == null) 
fixedReceiver = new CheckcastReceiverExpression(fixedReceiver, target);
-            return super.writeDirectMethodCall(target, fixedImplicitThis, 
fixedReceiver, args);
-        }
-        return super.writeDirectMethodCall(target, implicitThis, receiver, 
args);
     }
 
     private void writeMethodAccessError(final MethodNode target, final 
Expression origin) {
@@ -405,21 +364,6 @@ public class StaticInvocationWriter extends 
InvocationWriter {
         return false;
     }
 
-    private boolean tryPrivateMethod(final MethodNode target, final boolean 
implicitThis, final Expression receiver, final TupleExpression args, final 
ClassNode classNode) {
-        ClassNode declaringClass = target.getDeclaringClass();
-        if ((isPrivateBridgeMethodsCallAllowed(declaringClass, classNode) || 
isPrivateBridgeMethodsCallAllowed(classNode, declaringClass))
-                && 
declaringClass.getNodeMetaData(StaticCompilationMetadataKeys.PRIVATE_BRIDGE_METHODS)
 != null
-                && !declaringClass.equals(classNode)) {
-            if (tryBridgeMethod(target, receiver, implicitThis, args, 
classNode)) {
-                return true;
-            }
-        }
-        if (declaringClass != classNode) {
-            writeMethodAccessError(target, receiver);
-        }
-        return false;
-    }
-
     protected static boolean isPrivateBridgeMethodsCallAllowed(final ClassNode 
receiver, final ClassNode caller) {
         if (receiver == null) return false;
         if (receiver.redirect() == caller) return true;
diff --git 
a/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java 
b/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java
index 462e49c3d0..5b05fcc0ba 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java
@@ -483,11 +483,9 @@ public class StaticCompilationVisitor extends 
StaticTypeCheckingVisitor {
     }
 
     /**
-     * Adds "bridge" methods for private methods of an inner/outer class so 
that
-     * the outer class is capable of calling them.  It does basically the same
-     * job as access$000 like methods in Java.
-     *
-     * @param node an inner/outer class node for which to generate bridge 
methods
+     * Adds bridge methods for private or protected methods of a class so that
+     * any nestmate is capable of calling them. It does basically the same job
+     * as access$000 like methods in Java.
      */
     private static void addPrivateBridgeMethods(final ClassNode node) {
         Set<ASTNode> accessedMethods = node.getNodeMetaData(PV_METHODS_ACCESS);
@@ -496,20 +494,19 @@ public class StaticCompilationVisitor extends 
StaticTypeCheckingVisitor {
         methods.addAll(node.getDeclaredConstructors());
         Map<MethodNode, MethodNode> privateBridgeMethods = 
node.getNodeMetaData(PRIVATE_BRIDGE_METHODS);
         if (privateBridgeMethods != null) {
-            // private bridge methods already added
+            // bridge methods already added
             return;
         }
         privateBridgeMethods = new HashMap<>();
         int i = -1;
-        final int access = ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC;
         for (MethodNode method : methods) {
             if (accessedMethods.contains(method)) {
-                List<String> methodSpecificGenerics = 
methodSpecificGenerics(method);
                 i += 1;
                 ClassNode declaringClass = method.getDeclaringClass();
                 Map<String, ClassNode> genericsSpec = createGenericsSpec(node);
                 genericsSpec = addMethodGenerics(method, genericsSpec);
                 extractSuperClassGenerics(node, declaringClass, genericsSpec);
+                List<String> methodSpecificGenerics = 
methodSpecificGenerics(method);
                 Parameter[] methodParameters = method.getParameters();
                 Parameter[] newParams = new Parameter[methodParameters.length 
+ 1];
                 for (int j = 1; j < newParams.length; j += 1) {
@@ -520,7 +517,7 @@ public class StaticCompilationVisitor extends 
StaticTypeCheckingVisitor {
                     );
                 }
                 Expression arguments;
-                if (method.getParameters() == null || 
method.getParameters().length == 0) {
+                if (methodParameters.length == 0) {
                     arguments = ArgumentListExpression.EMPTY_ARGUMENTS;
                 } else {
                     List<Expression> args = new ArrayList<>();
@@ -553,7 +550,8 @@ public class StaticCompilationVisitor extends 
StaticTypeCheckingVisitor {
                     ExpressionStatement body = new ExpressionStatement(call);
 
                     bridge = node.addMethod(
-                            "access$" + i, access,
+                            "access$" + i,
+                            ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC,
                             correctToGenericsSpecRecurse(genericsSpec, 
method.getReturnType(), methodSpecificGenerics),
                             newParams,
                             method.getExceptions(),
diff --git 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 87ed4596a2..9bec90bd6e 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -579,11 +579,6 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
         }
     }
 
-    private static void addPrivateFieldOrMethodAccess(final Expression source, 
final ClassNode cn, final StaticTypesMarker key, final ASTNode accessedMember) {
-        cn.getNodeMetaData(key, x -> new 
LinkedHashSet<>()).add(accessedMember);
-        source.putNodeMetaData(key, accessedMember);
-    }
-
     /**
      * Checks for private field access from closure or nestmate.
      */
@@ -604,17 +599,17 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
         ClassNode declaringClass = mn.getDeclaringClass();
         ClassNode enclosingClass = typeCheckingContext.getEnclosingClassNode();
         if (declaringClass != enclosingClass || 
typeCheckingContext.getEnclosingClosure() != null) {
-            if (mn.isPrivate()
-                    && declaringClass.getModule() == 
enclosingClass.getModule()) {
-                addPrivateFieldOrMethodAccess(source, declaringClass, 
PV_METHODS_ACCESS, mn);
-            } else if (mn.isProtected()
-                    && !inSamePackage(enclosingClass, declaringClass)
+            if (mn.isPrivate() && getNestHost(declaringClass) == 
getNestHost(enclosingClass)) {
+                if (mn.isConstructor()) 
declaringClass.getNodeMetaData(PV_METHODS_ACCESS, k -> new 
LinkedHashSet<MethodNode>()).add(mn);
+                source.putNodeMetaData(PV_METHODS_ACCESS, mn);
+            } else if (mn.isProtected() && !inSamePackage(enclosingClass, 
declaringClass)
                     && (!implementsInterfaceOrIsSubclassOf(enclosingClass, 
declaringClass)
                                     || 
typeCheckingContext.getEnclosingClosure() != null)) {
                 ClassNode cn = enclosingClass;
                 do {
                     if (implementsInterfaceOrIsSubclassOf(cn, declaringClass)) 
{
-                        addPrivateFieldOrMethodAccess(source, cn, 
PV_METHODS_ACCESS, mn);
+                        cn.getNodeMetaData(PV_METHODS_ACCESS, k -> new 
LinkedHashSet<MethodNode>()).add(mn);
+                        source.putNodeMetaData(PV_METHODS_ACCESS, mn);
                         break;
                     }
                 } while ((cn = cn.getOuterClass()) != null);
diff --git 
a/src/test/org/codehaus/groovy/classgen/asm/sc/BugsStaticCompileTest.groovy 
b/src/test/org/codehaus/groovy/classgen/asm/sc/BugsStaticCompileTest.groovy
index 4e99b8c489..0c4b08bb26 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/BugsStaticCompileTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/BugsStaticCompileTest.groovy
@@ -680,7 +680,7 @@ final class BugsStaticCompileTest extends BugsSTCTest 
implements StaticCompilati
             class Bottom extends Top {
                 private int bar = 666
                 private class InnerBottom {
-                    int bar() { bar } // name clash for fpaccess$0
+                    int bar() { bar }
                 }
             }
             new Bottom()
diff --git 
a/src/test/org/codehaus/groovy/classgen/asm/sc/MethodCallsStaticCompilationTest.groovy
 
b/src/test/org/codehaus/groovy/classgen/asm/sc/MethodCallsStaticCompilationTest.groovy
index e80c6586e3..18c8fac981 100644
--- 
a/src/test/org/codehaus/groovy/classgen/asm/sc/MethodCallsStaticCompilationTest.groovy
+++ 
b/src/test/org/codehaus/groovy/classgen/asm/sc/MethodCallsStaticCompilationTest.groovy
@@ -53,5 +53,6 @@ public class MethodCallsStaticCompilationTest extends 
MethodCallsSTCTest impleme
             }
             assert new Foo().a() == 123
         '''
+        assert astTrees['Foo$Bar$Baz'][1].contains('INVOKEVIRTUAL Foo.d ()I')
     }
 }
diff --git 
a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7276.groovy 
b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7276.groovy
index e2d46247c1..bb11fb4892 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7276.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7276.groovy
@@ -23,7 +23,7 @@ import 
org.codehaus.groovy.classgen.asm.sc.StaticCompilationTestSupport
 
 final class Groovy7276 extends StaticTypeCheckingTestCase implements 
StaticCompilationTestSupport {
 
-    void testShouldGoThroughPrivateBridgeMethod1() {
+    void testNoPrivateAccessMethod1() {
         for (it in ['i', 'i++']) {
             assertScript """
                 class Foo {
@@ -32,11 +32,14 @@ final class Groovy7276 extends StaticTypeCheckingTestCase 
implements StaticCompi
                 }
                 assert new Foo().m() == 1
             """
+            String  closure = astTrees['Foo$_m_closure1'][1]
+            assert  closure.contains('GETFIELD Foo.i')
+            assert !closure.contains('pfaccess$')
         }
     }
 
     // GROOVY-7304
-    void testShouldGoThroughPrivateBridgeMethod2() {
+    void testNoPrivateAccessMethod2() {
         for (it in ['i', 'i++']) {
             assertScript """
                 class Foo {
@@ -47,10 +50,13 @@ final class Groovy7276 extends StaticTypeCheckingTestCase 
implements StaticCompi
                 }
                 assert new Bar().m() == 1
             """
+            String  closure = astTrees['Foo$_m_closure1'][1]
+            assert  closure.contains('GETFIELD Foo.i')
+            assert !closure.contains('pfaccess$')
         }
     }
 
-    void testShouldGoThroughPrivateBridgeMethod3() {
+    void testNoPrivateAccessMethod3() {
         for (it in ['++i', 'i+=1', 'i=i+1']) {
             assertScript """
                 class Foo {
@@ -59,11 +65,14 @@ final class Groovy7276 extends StaticTypeCheckingTestCase 
implements StaticCompi
                 }
                 assert new Foo().m() == 2
             """
+            String  closure = astTrees['Foo$_m_closure1'][1]
+            assert  closure.contains('GETFIELD Foo.i')
+            assert !closure.contains('pfaccess$')
         }
     }
 
     // GROOVY-7304
-    void testShouldGoThroughPrivateBridgeMethod4() {
+    void testNoPrivateAccessMethod4() {
         for (it in ['++i', 'i+=1', 'i=i+1']) {
             assertScript """
                 class Foo {
@@ -74,10 +83,14 @@ final class Groovy7276 extends StaticTypeCheckingTestCase 
implements StaticCompi
                 }
                 assert new Bar().m() == 2
             """
+            String  closure = astTrees['Foo$_m_closure1'][1]
+            assert  closure.contains('GETFIELD Foo.i')
+            assert !closure.contains('pfaccess$')
         }
     }
 
-    void testShouldGoThroughPrivateBridgeMethod5() {
+    // GROOVY-10687
+    void testNoPrivateAccessMethod5() {
         assertScript '''
             class Foo {
                 private int i = 1
@@ -86,9 +99,13 @@ final class Groovy7276 extends StaticTypeCheckingTestCase 
implements StaticCompi
             }
             assert new Foo().m() == 1
         '''
+        String  closure = astTrees['Foo$_m_closure1'][1]
+        assert  closure.contains('INVOKEVIRTUAL Foo.pvI ()I')
+        assert !closure.contains('access$')
     }
 
-    void testShouldGoThroughPrivateBridgeMethod6() {
+    // GROOVY-10687
+    void testNoPrivateAccessMethod6() {
         assertScript '''
             class Foo {
                 private int i = 1
@@ -99,15 +116,19 @@ final class Groovy7276 extends StaticTypeCheckingTestCase 
implements StaticCompi
             }
             assert new Bar().m() == 1
         '''
+        String  closure = astTrees['Foo$_m_closure1'][1]
+        assert  closure.contains('INVOKEVIRTUAL Foo.pvI ()I')
+        assert !closure.contains('access$')
     }
 
+    // GROOVY-10687
     void testPrivateAccessInInnerClass() {
         assertScript '''
             class Outer {
                 private static class Inner {
                     private Set<String> variablesToCheck = []
                     private void checkAssertions(String name) {
-                        Runnable r = {
+                        Runnable r = { ->
                             def candidates = variablesToCheck.findAll { it == 
name }
                         }
                         r.run()
@@ -119,5 +140,7 @@ final class Groovy7276 extends StaticTypeCheckingTestCase 
implements StaticCompi
             }
             Outer.test()
         '''
+        assert astTrees['Outer'][1].contains('INVOKEVIRTUAL 
Outer$Inner.checkAssertions (Ljava/lang/String;)V')
+        assert 
astTrees['Outer$Inner$_checkAssertions_closure1'][1].contains('GETFIELD 
Outer$Inner.variablesToCheck')
     }
 }

Reply via email to