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/01/15 13:31:53 UTC

(groovy) branch master updated: GROOVY-11254: SC: describe method via `ClassNode` not `Class`

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 3acb6395a8 GROOVY-11254: SC: describe method via `ClassNode` not `Class`
3acb6395a8 is described below

commit 3acb6395a802b8eb68481b104ff5b328178c4acb
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Jan 15 07:11:05 2024 -0600

    GROOVY-11254: SC: describe method via `ClassNode` not `Class`
---
 .../asm/sc/AbstractFunctionalInterfaceWriter.java      |  7 +------
 .../transform/stc/StaticTypeCheckingVisitor.java       |  3 ++-
 .../groovy/transform/stc/MethodReferenceTest.groovy    | 18 ++++++++++++++++++
 3 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/AbstractFunctionalInterfaceWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/AbstractFunctionalInterfaceWriter.java
index 277f802349..4292491afa 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/AbstractFunctionalInterfaceWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/AbstractFunctionalInterfaceWriter.java
@@ -27,7 +27,6 @@ import org.objectweb.asm.Handle;
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
 
-import java.util.Arrays;
 import java.util.List;
 
 import static org.codehaus.groovy.ast.ClassHelper.getUnwrapper;
@@ -44,11 +43,7 @@ import static org.codehaus.groovy.classgen.asm.BytecodeHelper.getMethodDescripto
 public interface AbstractFunctionalInterfaceWriter {
 
     default String createMethodDescriptor(final MethodNode method) {
-        Class<?> returnType = method.getReturnType().getTypeClass();
-        Class<?>[] parameterTypes = Arrays.stream(method.getParameters())
-                .map(p -> p.getType().getTypeClass()).toArray(Class[]::new);
-
-        return getMethodDescriptor(returnType, parameterTypes);
+        return getMethodDescriptor(method.getReturnType(), method.getParameters());
     }
 
     default Handle createBootstrapMethod(final boolean isInterface, final boolean serializable) {
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 ee48bfc698..ee93f90787 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -5608,7 +5608,8 @@ out:                if (mn.size() != 1) {
                     Variable variable = ((VariableExpression) source.getExpression()).getAccessedVariable();
                     if (variable instanceof ASTNode) objectExprType = ((ASTNode) variable).getNodeMetaData(INFERRED_TYPE);
                 }
-                Map<GenericsTypeName,GenericsType> spec = extractPlaceHolders(objectExprType, target.getDeclaringClass());
+                if (objectExprType == null) objectExprType = source.getExpression().getType();
+                var spec = extractPlaceHolders(objectExprType, target.getDeclaringClass());
                 return applyGenericsContext(spec, extractTypesFromParameters(params));
             }
         }
diff --git a/src/test/groovy/transform/stc/MethodReferenceTest.groovy b/src/test/groovy/transform/stc/MethodReferenceTest.groovy
index 7d05bd3ed9..2cf1bc77ae 100644
--- a/src/test/groovy/transform/stc/MethodReferenceTest.groovy
+++ b/src/test/groovy/transform/stc/MethodReferenceTest.groovy
@@ -1414,6 +1414,24 @@ final class MethodReferenceTest {
         assert err =~ /The argument is a method reference, but the parameter type is not a functional interface/
     }
 
+    @Test // GROOVY-11254
+    void testLocalFunctionalInterface() {
+        assertScript shell, '''
+            class C { String s }
+            @FunctionalInterface
+            interface I<T> { T m(C c) }
+
+            @CompileStatic
+            def test(I<String> i_string) {
+                I<String> i = i_string::m
+                i.m(new C(s:'something'))
+            }
+
+            String result = test(c -> c.s)
+            assert result == 'something'
+        '''
+    }
+
     @Test // GROOVY-10635
     void testRecordComponentMethodReference() {
         assertScript shell, '''