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 166784dddf GROOVY-11872: SC: propagate `STATIC_COMPILE_NODE` metadata 
in `Verifier`
166784dddf is described below

commit 166784dddf521f21c26d04a338dbc52040b4da8a
Author: Eric Milles <[email protected]>
AuthorDate: Wed Mar 11 10:39:35 2026 -0500

    GROOVY-11872: SC: propagate `STATIC_COMPILE_NODE` metadata in `Verifier`
---
 .../org/codehaus/groovy/classgen/Verifier.java     |   8 +-
 .../sc/CombinedIndyAndStaticCompilationTest.groovy | 160 ++++++++++++++-------
 2 files changed, 117 insertions(+), 51 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/Verifier.java 
b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
index 9f1d13c74e..4300c57743 100644
--- a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
@@ -124,6 +124,8 @@ import static 
org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpec;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.createGenericsSpec;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.parameterizeType;
 import static 
org.codehaus.groovy.ast.tools.PropertyNodeUtils.adjustPropertyModifiersForMethod;
+import static 
org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.STATIC_COMPILE_NODE;
+import static 
org.codehaus.groovy.transform.stc.StaticTypesMarker.DIRECT_METHOD_CALL_TARGET;
 
 /**
  * Verifies the AST node and adds any default AST code before bytecode 
generation occurs.
@@ -1020,6 +1022,7 @@ public class Verifier implements GroovyClassVisitor, 
Opcodes {
 
             addPropertyMethod(newMethod);
             newMethod.putNodeMetaData(DEFAULT_PARAMETER_GENERATED, 
Boolean.TRUE);
+            newMethod.putNodeMetaData(STATIC_COMPILE_NODE, 
method.getNodeMetaData(STATIC_COMPILE_NODE));
         });
     }
 
@@ -1064,7 +1067,9 @@ public class Verifier implements GroovyClassVisitor, 
Opcodes {
             ConstructorNode old = type.getDeclaredConstructor(params);
             if (old == null || isGenerated(old)) { type.removeConstructor(old);
                 // delegate to original constructor using arguments derived 
from defaults
-                addConstructor(params, (ConstructorNode) method, 
stmt(ctorThisX(arguments)), type);
+                ConstructorCallExpression call = ctorThisX(arguments);
+                call.putNodeMetaData(DIRECT_METHOD_CALL_TARGET, method);
+                addConstructor(params, (ConstructorNode) method, stmt(call), 
type);
             } else {
                 String warning = "Default argument(s) specify duplicate 
constructor: " +
                     
MethodNodeUtils.methodDescriptor(old,true).replace("<init>",type.getNameWithoutPackage());
@@ -1075,6 +1080,7 @@ public class Verifier implements GroovyClassVisitor, 
Opcodes {
 
     protected void addConstructor(final Parameter[] newParams, final 
ConstructorNode ctor, final Statement code, final ClassNode type) {
         ConstructorNode newConstructor = 
type.addConstructor(ctor.getModifiers(), newParams, ctor.getExceptions(), code);
+        newConstructor.putNodeMetaData(STATIC_COMPILE_NODE, 
ctor.getNodeMetaData(STATIC_COMPILE_NODE));
         newConstructor.putNodeMetaData(DEFAULT_PARAMETER_GENERATED, 
Boolean.TRUE);
         markAsGenerated(type, newConstructor);
         // TODO: Copy annotations, etc.?
diff --git 
a/src/test/groovy/org/codehaus/groovy/classgen/asm/sc/CombinedIndyAndStaticCompilationTest.groovy
 
b/src/test/groovy/org/codehaus/groovy/classgen/asm/sc/CombinedIndyAndStaticCompilationTest.groovy
index def803299d..ffdc43183b 100644
--- 
a/src/test/groovy/org/codehaus/groovy/classgen/asm/sc/CombinedIndyAndStaticCompilationTest.groovy
+++ 
b/src/test/groovy/org/codehaus/groovy/classgen/asm/sc/CombinedIndyAndStaticCompilationTest.groovy
@@ -20,73 +20,133 @@ package org.codehaus.groovy.classgen.asm.sc
 
 import org.codehaus.groovy.classgen.asm.AbstractBytecodeTestCase
 import org.junit.jupiter.api.Test
+import org.junit.jupiter.params.ParameterizedTest
+import org.junit.jupiter.params.provider.ValueSource
 
 import static org.codehaus.groovy.control.CompilerConfiguration.DEFAULT as 
config
 import static org.junit.jupiter.api.Assumptions.assumeTrue
 
 /**
- * Tests for combined static compilation and indy code
+ * Tests for combined static compilation and indy code.
  */
 final class CombinedIndyAndStaticCompilationTest extends 
AbstractBytecodeTestCase {
 
+    @ParameterizedTest
+    
@ValueSource(strings=['byte','short','int','long','float','double','boolean','char'])
+    void testArrayRead(String type) {
+        assumeTrue config.indyEnabled
+
+        def bytecode = compile method:'test', """
+            @groovy.transform.CompileStatic
+            void test() {
+                ${type}[] array = new ${type}[10]
+                ${type} x = array[0]
+            }
+        """
+        int offset = bytecode.indexOf('--BEGIN--') + 4
+        assert bytecode.indexOf('INVOKEDYNAMIC', offset) > offset
+        assert bytecode.indexOf('INVOKEDYNAMIC', offset) < 
bytecode.indexOf('--END--')
+    }
+
+    @ParameterizedTest
+    
@ValueSource(strings=['byte','short','int','long','float','double','boolean','char'])
+    void testArrayWrite(String type) {
+        assumeTrue config.indyEnabled
+
+        def bytecode = compile method:'test', """
+            @groovy.transform.CompileStatic
+            void test() {
+                ${type}[] array = new ${type}[10]
+                array[0] = 1
+            }
+        """
+        int offset = bytecode.indexOf('--BEGIN--') + 4
+        assert bytecode.indexOf('INVOKEDYNAMIC', offset) > offset
+        assert bytecode.indexOf('INVOKEDYNAMIC', offset) < 
bytecode.indexOf('--END--')
+    }
+
+    @ParameterizedTest
+    @ValueSource(strings=['byte','short','int','long','float','double','char'])
+    void testNegativeIndex(String type) {
+        assertScript """
+            @groovy.transform.CompileStatic
+            void test() {
+                ${type}[] array = [0,1,2]
+                assert array[0] == 0
+                assert array[1] == 1
+                assert array[2] == 2
+                assert array[-1] == 2
+                assert array[-2] == 1
+                array[0] = 9
+                assert array[0] == 9
+                array[-1] = 8
+                assert array[2] == 8
+            }
+            test()
+        """
+    }
+
+    @Test
+    void testNegativeIndexPrimitiveBoolean() {
+        assertScript '''
+            @groovy.transform.CompileStatic
+            void test() {
+                boolean[] array = [false, false, true]
+                assert array[0] == false
+                assert array[1] == false
+                assert array[2] == true
+                assert array[-1] == true
+                assert array[-2] == false
+                array[0] = true
+                assert array[0] == true
+                array[-1] = false
+                assert array[2] == false
+            }
+            test()
+        '''
+    }
+
+    // GROOVY-11872
     @Test
-    void testArrayAccess() {
-        assumeTrue(config.indyEnabled)
-        ["byte", "short", "int", "long", "float", "double", "boolean", 
"char"].each { type->
-            //array get
-            compile ("""
+    void testCompileStaticAndMethodWithDefaultParameter() {
+        def bytecode = compile '''
+            class Foo {
                 @groovy.transform.CompileStatic
-                def foo() {
-                    ${type}[] array = new ${type}[10]
-                    $type x = array[0]
+                void bar(List list = baz()) {
+                    for (item in list) {
+                        println item
+                    }
                 }
-            """).hasSequence(["INVOKEDYNAMIC"])
-            //array set
-            compile ("""
-                @groovy.transform.CompileStatic
-                def foo() {
-                    ${type}[] array = new ${type}[10]
-                    array[0] = 1
+                List baz() {
+                    ['fizz','buzz']
                 }
-            """).hasSequence(["INVOKEDYNAMIC"])
-        }
+            }
+        '''
+        int offset = bytecode.indexOf('public bar()')
+        assert bytecode.indexOf('INVOKEDYNAMIC', offset) < 0
+        assert bytecode.indexOf('INVOKEVIRTUAL', offset) > offset
+        assert bytecode.indexOf('INVOKEVIRTUAL', offset) < 
bytecode.indexOf('RETURN', offset)
     }
 
+    // GROOVY-11872
     @Test
-    void testNegativeAccess() {
-        ["byte", "short", "int", "long", "float", "double", "char"].each { 
type ->
-            assertScript """
+    void testCompileStaticAndConstructorWithDefaultParameter() {
+        def bytecode = compile '''
+            class Foo {
                 @groovy.transform.CompileStatic
-                def foo() {
-                    ${type}[] array = [0,1,2]
-                    assert array[0] == 0
-                    assert array[1] == 1
-                    assert array[2] == 2
-                    assert array[-1] == 2
-                    assert array[-2] == 1
-                    array[0] = 9
-                    assert array[0] == 9
-                    array[-1] = 8
-                    assert array[2] == 8
+                Foo(List list = bar()) {
+                    for (item in list) {
+                        println item
+                    }
                 }
-                foo()
-            """
-        }
-        assertScript """
-                @groovy.transform.CompileStatic
-                def foo() {
-                    boolean[] array = [false, false, true]
-                    assert array[0] == false
-                    assert array[1] == false
-                    assert array[2] == true
-                    assert array[-1] == true
-                    assert array[-2] == false
-                    array[0] = true
-                    assert array[0] == true
-                    array[-1] = false
-                    assert array[2] == false
+                static List bar() {
+                    ['fizz','buzz']
                 }
-                foo()
-            """
+            }
+        '''
+        int offset = bytecode.indexOf('public <init>()')
+        assert bytecode.indexOf('INVOKEDYNAMIC', offset) < 0
+        assert bytecode.indexOf('INVOKESTATIC ', offset) > offset
+        assert bytecode.indexOf('INVOKESTATIC ', offset) < 
bytecode.indexOf('RETURN', offset)
     }
 }

Reply via email to