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 2022/02/18 22:11:14 UTC

[groovy] 02/05: GROOVY-10379: interface default methods in `ClassNode#hasPossibleMethod`

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

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

commit fb0b892158ac8b84fbd3b3a74a6f2f1f07b2aeac
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Nov 23 12:13:14 2021 -0600

    GROOVY-10379: interface default methods in `ClassNode#hasPossibleMethod`
    
    Conflicts:
    	src/test/groovy/bugs/Groovy8964.groovy
---
 .../java/org/codehaus/groovy/ast/ClassNode.java    |  7 +++
 src/test/groovy/bugs/Groovy8964Bug.groovy          | 53 ++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/src/main/java/org/codehaus/groovy/ast/ClassNode.java b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
index f324fdf..48bd454 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
@@ -1244,6 +1244,13 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
                     return true;
                 }
             }
+            for (ClassNode in : cn.getAllInterfaces()) {
+                for (MethodNode mn : in.getDeclaredMethods(name)) {
+                    if (mn.isDefault() && hasCompatibleNumberOfArgs(mn, count)) {
+                        return true;
+                    }
+                }
+            }
         }
 
         return false;
diff --git a/src/test/groovy/bugs/Groovy8964Bug.groovy b/src/test/groovy/bugs/Groovy8964Bug.groovy
index 8222ccb..a5285bb 100644
--- a/src/test/groovy/bugs/Groovy8964Bug.groovy
+++ b/src/test/groovy/bugs/Groovy8964Bug.groovy
@@ -18,6 +18,9 @@
  */
 package groovy.bugs
 
+import org.codehaus.groovy.control.CompilerConfiguration
+import org.codehaus.groovy.tools.javac.JavaAwareCompilationUnit
+
 class Groovy8964Bug extends GroovyTestCase {
 
     void testInstanceVarargMethodNotMaskedByStaticMethodWithSameNumberOfArgs() {
@@ -72,6 +75,56 @@ class Groovy8964Bug extends GroovyTestCase {
         '''
     }
 
+    // GROOVY-10379
+    void testInstanceMethodNotMaskedByStaticMethodWithSameNumberOfArgs3() {
+        def config = new CompilerConfiguration(
+            targetDirectory: File.createTempDir(),
+            jointCompilationOptions: [stubDir: File.createTempDir()]
+        )
+
+        def parentDir = File.createTempDir()
+        try {
+            new File(parentDir, 'p').mkdir()
+
+            def a = new File(parentDir, 'p/A.java')
+            a.write '''
+                package p;
+                public abstract class A implements I {
+                    public static String m(Number n) { return "number"; }
+                }
+            '''
+            def b = new File(parentDir, 'p/I.java')
+            b.write '''
+                package p;
+                public interface I {
+                    default String m(String s) { return "string"; }
+                }
+            '''
+            def c = new File(parentDir, 'Main.groovy')
+            c.write '''
+                @groovy.transform.CompileStatic
+                class C extends p.A {
+                    void test() {
+                        String result = m('') // GroovyCastException: Cannot cast object 'class C' with class 'java.lang.Class' to class 'p.I'
+                        assert result == 'string'
+                    }
+                }
+                new C().test()
+            '''
+
+            def loader = new GroovyClassLoader(this.class.classLoader)
+            def cu = new JavaAwareCompilationUnit(config, loader)
+            cu.addSources(a, b, c)
+            cu.compile()
+
+            loader.loadClass('Main').main()
+        } finally {
+            config.jointCompilationOptions.stubDir.deleteDir()
+            config.targetDirectory.deleteDir()
+            parentDir.deleteDir()
+        }
+    }
+
     static abstract class A {
         static void m(Integer i) {}
         protected void m(String s) {}