You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2024/09/24 21:09:46 UTC

(groovy) branch master updated: GROOVY-10687: SC: replace access bridge methods with direct construction

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 0c2ed94544 GROOVY-10687: SC: replace access bridge methods with direct construction
0c2ed94544 is described below

commit 0c2ed94544df0e30795d317533816436d07fc7b2
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Sep 24 15:51:19 2024 -0500

    GROOVY-10687: SC: replace access bridge methods with direct construction
---
 .../classgen/asm/sc/StaticInvocationWriter.java    | 44 ++++++++++------------
 .../transform/stc/StaticTypeCheckingVisitor.java   |  4 +-
 .../asm/sc/StaticCompileConstructorsTest.groovy    |  4 +-
 3 files changed, 26 insertions(+), 26 deletions(-)

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 cffa427daa..ab190ee44b 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
@@ -139,35 +139,31 @@ public class StaticInvocationWriter extends InvocationWriter {
             cn = new ConstructorNode(mn.getModifiers(), mn.getParameters(), mn.getExceptions(), mn.getCode());
             cn.setDeclaringClass(mn.getDeclaringClass());
         }
-        TupleExpression args = makeArgumentList(call.getArguments());
-        if (cn.isPrivate()) {
-            ClassNode classNode = controller.getClassNode();
-            ClassNode declaringClass = cn.getDeclaringClass();
-            if (declaringClass != classNode) {
-                MethodNode bridge = null;
-                if (call.getNodeMetaData(StaticTypesMarker.PV_METHODS_ACCESS) != null) {
-                    Map<MethodNode, MethodNode> bridgeMethods = declaringClass.getNodeMetaData(StaticCompilationMetadataKeys.PRIVATE_BRIDGE_METHODS);
-                    if (bridgeMethods != null) bridge = bridgeMethods.get(cn);
-                }
-                if (bridge instanceof ConstructorNode) {
-                    ArgumentListExpression newArgs = args(nullX());
-                    for (Expression arg: args) {
-                        newArgs.addExpression(arg);
-                    }
-                    cn = (ConstructorNode) bridge;
-                    args = newArgs;
-                } else {
-                    controller.getSourceUnit().addError(new SyntaxException(
-                            "Cannot call private constructor for " + declaringClass.toString(false) + " from class " + classNode.toString(false),
-                            call
-                    ));
-                }
+        ClassNode declaringClass = cn.getDeclaringClass();
+        ClassNode enclosingClass = controller.getClassNode();
+        List<Expression> argList = call.getArguments() instanceof TupleExpression
+                ? ((TupleExpression) call.getArguments()).getExpressions() : List.of(call.getArguments());
+        if (!AsmClassGenerator.isMemberDirectlyAccessible(cn.getModifiers(), declaringClass, enclosingClass)) {
+            MethodNode bridge = null;
+            if (call.getNodeMetaData(StaticTypesMarker.PV_METHODS_ACCESS) != null) {
+                Map<MethodNode, MethodNode> bridgeMethods = declaringClass.getNodeMetaData(StaticCompilationMetadataKeys.PRIVATE_BRIDGE_METHODS);
+                if (bridgeMethods != null) bridge = bridgeMethods.get(cn);
+            }
+            if (bridge instanceof ConstructorNode) {
+                cn = (ConstructorNode) bridge;
+                argList = new ArrayList<>(argList);
+                argList.add(0, nullX());
+            } else {
+                controller.getSourceUnit().addError(new SyntaxException(
+                        "Cannot call private constructor for " + declaringClass.toString(false) + " from class " + enclosingClass.toString(false),
+                        call
+                ));
             }
         }
 
         String ownerDescriptor = prepareConstructorCall(cn);
         int before = controller.getOperandStack().getStackLength();
-        loadArguments(args.getExpressions(), cn.getParameters());
+        loadArguments(argList, cn.getParameters());
         finnishConstructorCall(cn, ownerDescriptor, controller.getOperandStack().getStackLength() - before);
     }
 
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 9bec90bd6e..db5446a4e5 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -600,7 +600,9 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         ClassNode enclosingClass = typeCheckingContext.getEnclosingClassNode();
         if (declaringClass != enclosingClass || typeCheckingContext.getEnclosingClosure() != null) {
             if (mn.isPrivate() && getNestHost(declaringClass) == getNestHost(enclosingClass)) {
-                if (mn.isConstructor()) declaringClass.getNodeMetaData(PV_METHODS_ACCESS, k -> new LinkedHashSet<MethodNode>()).add(mn);
+                if (source instanceof MethodReferenceExpression // GROOVY-11301: access bridge for lambda
+                        && Float.parseFloat(getSourceUnit().getConfiguration().getTargetBytecode()) < 15)
+                    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)
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 89569cd829..c9d8050965 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileConstructorsTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileConstructorsTest.groovy
@@ -71,10 +71,12 @@ class StaticCompileConstructorsTest extends ConstructorsSTCTest implements Stati
                 static class Bar {
                     static Foo makeFoo(String s) { new Foo(s) }
                 }
-
             }
             assert Foo.Bar.makeFoo('pls').s == 'pls'
         '''
+        String bar = astTrees['Foo$Bar'][1]
+        assert bar.contains('NEW Foo')
+        assert bar.contains('INVOKESPECIAL Foo.<init> (Ljava/lang/String;)V')
     }
 
     void testPrivateConstructorFromAnonymousInnerClass() {