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

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


The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
     new 3c96c6f6bb GROOVY-10897: STC: remove interface equivalent for indirect 
interface
3c96c6f6bb is described below

commit 3c96c6f6bb9f94592d34d88f58d0df20c6c6a1ce
Author: Eric Milles <[email protected]>
AuthorDate: Fri Dec 8 14:50:00 2023 -0600

    GROOVY-10897: STC: remove interface equivalent for indirect interface
    
    ```
        A
       / \
      B   C
       \ /
        D
    ```
    
    `A` and `B` are interfaces; `C` and `D` are concrete classes
    
    `B` and `C` both provide method `m()` then drop `B#m()` as equivalent
---
 .../transform/stc/StaticTypeCheckingSupport.java   |   3 +-
 .../groovy/transform/stc/MethodCallsSTCTest.groovy | 296 +++++++++++++++++++++
 .../asm/sc/MethodCallsStaticCompilationTest.groovy | 268 ++-----------------
 3 files changed, 315 insertions(+), 252 deletions(-)

diff --git 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index ea94d53145..2235ec63de 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1209,7 +1209,8 @@ public abstract class StaticTypeCheckingSupport {
                     } else if (!oneDC.equals(twoDC)) {
                         if 
(ParameterUtils.parametersEqual(one.getParameters(), two.getParameters())) {
                             // GROOVY-6882, GROOVY-6970: drop overridden or 
interface equivalent method
-                            if (twoDC.isInterface() ? 
oneDC.implementsInterface(twoDC) : oneDC.isDerivedFrom(twoDC)) {
+                            if (!twoDC.isInterface() ? 
oneDC.isDerivedFrom(twoDC) : oneDC.implementsInterface(twoDC) || // 
GROOVY-10897: concrete vs. abstract
+                                                                               
                   (!one.isAbstract() && !(two instanceof 
ExtensionMethodNode))) {
                                 toBeRemoved.add(two);
                             } else if (oneDC.isInterface() ? 
twoDC.isInterface() : twoDC.isDerivedFrom(oneDC)) {
                                 toBeRemoved.add(one);
diff --git a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy 
b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
index c07168394b..6907fe9afd 100644
--- a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
@@ -18,6 +18,8 @@
  */
 package groovy.transform.stc
 
+import org.codehaus.groovy.control.MultipleCompilationErrorsException
+
 import static 
org.codehaus.groovy.control.customizers.builder.CompilerCustomizationBuilder.withConfig
 
 /**
@@ -148,6 +150,22 @@ class MethodCallsSTCTest extends 
StaticTypeCheckingTestCase {
         '''
     }
 
+    void testPlusStaticMethodCall() {
+        assertScript '''
+            static int foo() { 1 }
+            assert 1+foo() == 2
+        '''
+    }
+
+    void testExplicitTargetMethodWithCast() {
+        assertScript '''
+            String foo(String str) { 'STRING' }
+            String foo(Object o) { 'OBJECT' }
+            assert foo('call') == 'STRING'
+            assert foo((Object)'call') == 'OBJECT'
+        '''
+    }
+
     void testGenericMethodCall() {
         assertScript '''
             C c = new C()
@@ -237,6 +255,99 @@ class MethodCallsSTCTest extends 
StaticTypeCheckingTestCase {
         '''
     }
 
+    void testNullSafeCall() {
+        assertScript '''
+            String str = null
+            assert str?.toString() == null
+        '''
+    }
+
+    void testCallToSuper() {
+        assertScript '''
+            class Foo {
+                int foo() { 1 }
+            }
+            class Bar extends Foo {
+                int foo() { super.foo() }
+            }
+            def bar = new Bar()
+            assert bar.foo() == 1
+        '''
+    }
+
+    // GROOVY-10897
+    void testCallToSuper2() {
+        assertScript '''
+            interface A10897 {
+                def m()
+            }
+            interface B10897 extends A10897 {
+                @Override def m()
+            }
+            class C10897 implements A10897 {
+                @Override def m() { "C" }
+            }
+            class D10897 extends C10897 implements B10897 {
+            }
+            class E10897 extends D10897 {
+                @Override
+                def m() {
+                    "E then " + super.m()
+                }
+            }
+            assert new E10897().m() == 'E then C'
+        '''
+    }
+
+    // GROOVY-11242
+    void testCallToSuper3() {
+        assertScript '''
+            class DirtyCheckingCollection implements Collection {
+                private final @Delegate Collection target
+                DirtyCheckingCollection(Collection target) {
+                    this.target = target
+                }
+                @Override
+                boolean add(Object o) {
+                    target.add(o)
+                }
+            }
+            class DirtyCheckingSet extends DirtyCheckingCollection implements 
Set {
+                DirtyCheckingSet(Set target) {
+                    super(target)
+                }
+            }
+            class MySet extends DirtyCheckingSet {
+                MySet(Set delegate) {
+                    super(delegate)
+                }
+                @Override
+                boolean add(Object o) {
+                    super.add(o) // StackOverflowError
+                }
+            }
+            MySet set = new MySet([] as Set)
+            set.add('myProperty')
+        '''
+    }
+
+    void testCallToSuperDefault() {
+        assertScript '''
+            interface I<T> {
+                default m(T t) {
+                    return t
+                }
+            }
+            class C implements I<String> {
+                @Override m(String s) {
+                    I.super.m(s)
+                }
+            }
+            String result = new C().m('works')
+            assert result == 'works'
+        '''
+    }
+
     // GROOVY-10922
     void testCallToSuperGenerated() {
         assertScript '''
@@ -276,6 +387,152 @@ class MethodCallsSTCTest extends 
StaticTypeCheckingTestCase {
         '''
     }
 
+    void testCallToPrivateInnerClassMethod() {
+        assertScript '''
+            class Outer {
+                static class Inner {
+                    private static void foo() {}
+                }
+                static main(args) { Inner.foo() }
+            }
+        '''
+    }
+
+    void testCallToPrivateOuterClassMethod() {
+        assertScript '''
+            class Outer {
+                private static void foo() {}
+                static class Inner {
+                    private static void bar() { Outer.foo() }
+                }
+            }
+            new Outer.Inner()
+        '''
+    }
+
+    void testCallToPrivateInnerClassConstant() {
+        assertScript '''
+            class Outer {
+                static class Inner {
+                    private static int foo = 42
+                }
+                static main(args) { Inner.foo }
+            }
+        '''
+    }
+
+    void testCallToPrivateOuterClassConstant() {
+        assertScript '''
+            class Outer {
+                private static int foo = 42
+                static class Inner {
+                    private static void bar() { Outer.foo }
+                }
+            }
+            new Outer.Inner()
+        '''
+    }
+
+    void testReferenceToInaccessiblePrivateMethod() {
+        shouldFail(MultipleCompilationErrorsException) {
+            assertScript '''
+                class Main {
+                    static main(args) { Peer.foo() }
+                }
+                class Peer {
+                    private static void foo() {}
+                }
+            '''
+        }
+    }
+
+    // GROOVY-6647
+    void testReferenceToInaccessiblePrivateConstructor() {
+        shouldFailWithMessages '''
+            class Main {
+                private Main() {}
+            }
+            class Peer {
+                def foo() { new Main() }
+            }
+        ''',
+        'Cannot find matching method Main#<init>()'
+    }
+
+    // GROOVY-8509
+    void testCallProtectedFromClassInSamePackage() {
+        assertScript '''
+            class Foo {
+                protected Foo() {}
+                protected int m() { 123 }
+            }
+            class Bar {
+                int test() {
+                    new Foo().m()
+                }
+            }
+            assert new Bar().test() == 123
+        '''
+    }
+
+    // GROOVY-7862
+    void testCallProtectedMethodFromInnerClassInSeparatePackage() {
+        assertScript '''
+            import groovy.transform.stc.MethodCallsSTCTest.BaseWithProtected 
as Foo
+
+            class Bar extends Foo {
+                class Baz {
+                    int test() {
+                        m()
+                    }
+                }
+                int test() {
+                    new Baz().test()
+                }
+            }
+            assert new Bar().test() == 1
+        '''
+    }
+
+    // GROOVY-7063
+    void testCallProtectedMethodFromSubclassClosureInDifferentPackage() {
+        assertScript '''
+            import groovy.transform.stc.MethodCallsSTCTest.BaseWithProtected 
as Foo
+
+            class Bar extends Foo {
+                int baz() {
+                    def c = {
+                        m()
+                    }
+                    c.call()
+                }
+            }
+            def bar = new Bar()
+            assert bar.baz() == 1
+        '''
+    }
+
+    // GROOVY-7264
+    void testCallProtectedMethodWithGenericTypes() {
+        assertScript '''
+            class Foo<T> {
+                protected boolean m(T t) {
+                    true
+                }
+            }
+            class Bar extends Foo<Integer> {
+                int baz() {
+                    def c = {
+                        m(123)
+                    }
+                    c.call() ? 1 : 0
+                }
+            }
+            def bar = new Bar()
+            assert bar.baz() == 1
+        '''
+    }
+
     // GROOVY-5175
     void testCallMethodAcceptingArrayWithNull() {
         assertClass '''
@@ -346,6 +603,17 @@ class MethodCallsSTCTest extends 
StaticTypeCheckingTestCase {
         '''
     }
 
+    void testMethodCallWithDefaultParams() {
+        assertScript '''
+            class Support {
+                Support(String name, String val, List arg=null, Set set = 
null, Date suffix = new Date()) {
+                    "$name$val$suffix"
+                }
+            }
+            new Support(null, null, null, null)
+        '''
+    }
+
     void testMethodCallArgumentUsingInstanceOf() {
         assertScript '''
             void foo(String str) { 'String' }
@@ -490,6 +758,34 @@ class MethodCallsSTCTest extends 
StaticTypeCheckingTestCase {
         'Reference to method is ambiguous'
     }
 
+    // GROOVY-5703
+    void testShouldNotConvertStringToStringArray() {
+        assertScript '''
+            int printMsgs(String ... msgs) {
+                int i = 0
+                for(String s : msgs) { i++ }
+
+                i
+            }
+            assert printMsgs('foo') == 1
+            assert printMsgs('foo','bar') == 2
+        '''
+    }
+
+    // GROOVY-5780
+    void testShouldNotConvertGStringToStringArray() {
+        assertScript '''
+            int printMsgs(String ... msgs) {
+                int i = 0
+                for(String s : msgs) { i++ }
+
+                i
+            }
+            assert printMsgs("f${'o'}o") == 1
+            assert printMsgs("${'foo'}","${'bar'}") == 2
+        '''
+    }
+
     void testInstanceOfOnExplicitParameter() {
         assertScript '''
             1.with { obj ->
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 40d6cd0040..e80c6586e3 100644
--- 
a/src/test/org/codehaus/groovy/classgen/asm/sc/MethodCallsStaticCompilationTest.groovy
+++ 
b/src/test/org/codehaus/groovy/classgen/asm/sc/MethodCallsStaticCompilationTest.groovy
@@ -23,269 +23,35 @@ import 
org.codehaus.groovy.control.MultipleCompilationErrorsException
 
 public class MethodCallsStaticCompilationTest extends MethodCallsSTCTest 
implements StaticCompilationTestSupport {
 
-    void testCallToSuper() {
-        assertScript '''
-            class Foo {
-                int foo() { 1 }
-            }
-            class Bar extends Foo {
-                int foo() { super.foo() }
-            }
-            def bar = new Bar()
-            assert bar.foo() == 1
-        '''
-    }
-    
-    void testNullSafeCall() {
-        assertScript '''
-            String str = null
-            assert str?.toString() == null
-        '''
-    }
-
-    void testCallToPrivateInnerClassMethod() {
-        assertScript '''
-                class A {
-                    static class B { private static void foo() {} }
-                   public static void main(args) { B.foo() }
-                }
-            '''
-    }
-
-    void testCallToPrivateOuterClassMethod() {
-        assertScript '''
-                class A {
-                   private static void foo() {}
-                   static class B { private static void bar() { A.foo() } }
-                }
-                new A.B()
-            '''
-    }
-
-    void testCallToPrivateInnerClassConstant() {
-        assertScript '''
-                class A {
-                   static class B { private static int foo = 333 }
-                   public static void main(args) { B.foo }
-                }
-            '''
-    }
-
-    void testCallToPrivateOuterClassConstant() {
-        assertScript '''
-                class A {
-                   private static int foo = 333
-                   static class B { private static void bar() { A.foo } }
-                }
-                new A.B()
-            '''
-    }
-
-    void testForbiddenCallToPrivateMethod() {
+    void testReferenceToInaccessiblePrivateProperty() {
         shouldFail(MultipleCompilationErrorsException) {
             assertScript '''
-            class A {
-               public static void main(args) { B.foo() }
-            }
-            class B { private static void foo() {} }
-        '''
-        }
-    }
-
-    void testForbiddenCallToPrivateConstant() {
-        shouldFail(MultipleCompilationErrorsException) {
-            assertScript '''
-            class A {
-               public static void main(args) { B.foo }
-            }
-            class B { private static int foo = 666 }
-        '''
-        }
-    }
-
-    void testExplicitTargetMethodWithCast() {
-        assertScript '''
-            String foo(String str) { 'STRING' }
-            String foo(Object o) { 'OBJECT' }
-            assert foo('call') == 'STRING'
-            assert foo((Object)'call') == 'OBJECT'
-        '''
-    }
-
-    void testPlusStaticMethodCall() {
-        assertScript '''
-            static int foo() { 1 }
-            assert 1+foo() == 2
-        '''
-    }
-
-    // GROOVY-5703
-    void testShouldNotConvertStringToStringArray() {
-        assertScript '''
-        int printMsgs(String ... msgs) {
-            int i = 0
-            for(String s : msgs) { i++ }
-
-            i
-        }
-        assert printMsgs('foo') == 1
-        assert printMsgs('foo','bar') == 2
-        '''
-    }
-
-    // GROOVY-5780
-    void testShouldNotConvertGStringToStringArray() {
-        assertScript '''
-        int printMsgs(String ... msgs) {
-            int i = 0
-            for(String s : msgs) { i++ }
-
-            i
-        }
-        assert printMsgs("f${'o'}o") == 1
-        assert printMsgs("${'foo'}","${'bar'}") == 2
-        '''
-    }
-
-    void testMethodCallWithDefaultParams() {
-            assertScript '''import groovy.transform.CompileStatic
-import groovy.transform.TypeCheckingMode//import 
org.codehaus.groovy.classgen.asm.sc.MethodCallsStaticCompilationTest.DefaultParamTestSupport
 as Support
-@CompileStatic(TypeCheckingMode.SKIP)
- class Support {
-        Support(String name, String val, List arg=null, Set set = null, Date 
suffix = new Date()) {
-            "$name$val$suffix"
-        }
-    }
-                new Support(null, null, null, null)
-
-            '''
-    }
-
-    static class DefaultParamTestSupport {
-        DefaultParamTestSupport(String name, String val, List arg=null, Set 
set = null, Date suffix = new Date()) {
-            "$name$val$suffix"
-        }
-    }
-
-    // GROOVY-6647
-    void testInaccessibleConstructor() {
-        shouldFailWithMessages '''
-            class Foo {
-                private Foo(){}
-            }
-
-            class Bar {
-                def foo() {new Foo()}
-            }
-        ''', '[Static type checking] - Cannot find matching method 
Foo#<init>()'
-    }
-
-    // GROOVY-7063
-    void testCallToProtectedMethodFromClosureInSubclassAndDifferentPackage() {
-        assertScript ''' import 
org.codehaus.groovy.classgen.asm.sc.MethodCallsStaticCompilationTest.Base
-
-        class Ext extends Base {
-
-            int doSomething() {
-                def c = {
-                    foo()
+                class Main {
+                   static main(args) { Peer.xxx }
                 }
-                c.call()
-            }
-        }
-        def ext = new Ext()
-        assert ext.doSomething() == 123
-        '''
-    }
-
-    // GROOVY-7264
-    void testCallProtectedMethodWithGenericTypes() {
-        assertScript '''
-            import 
org.codehaus.groovy.classgen.asm.sc.MethodCallsStaticCompilationTest.BaseGeneric
-
-            class Ext extends BaseGeneric<Integer> {
-
-                int doSomething() {
-                    def c = {
-                        foo(123)
-                    }
-                    c.call()?1:0
+                class Peer {
+                    private static int xxx = 666
                 }
-            }
-            def ext = new Ext()
-            assert ext.doSomething() == 1
-        '''
+            '''
+        }
     }
 
-    //GROOVY-7863
+    // GROOVY-7863
     void testDoublyNestedPrivateMethodAccess() {
         assertScript '''
-            class A {
-                private int bar() { 123 }
-
-                class B {
-
-                    int testInner() { new C().barInner() }
-
-                    class C {
-                        int barInner() { bar() }
-                    }
-                }
-
-                int test() {
-                    new B().testInner()
-                }
-            }
-            assert new A().test() == 123
-        '''
-    }
-
-    //GROOVY-7862
-    void testProtectedCallFromInnerClassInSeparatePackage() {
-        assertScript '''
-            import 
org.codehaus.groovy.classgen.asm.sc.MethodCallsStaticCompilationTest.Base
-            class SubBase extends Base {
-                class Inner {
-                    int test() {
-                        foo()
+            class Foo {
+                class Bar {
+                    class Baz {
+                        int c() { d() }
                     }
+                    int b() { new Baz().c() }
                 }
-
-                int innerTest() {
-                    new Inner().test()
+                int a() {
+                    new Bar().b()
                 }
+                private int d() { 123 }
             }
-            assert new SubBase().innerTest() == 123
+            assert new Foo().a() == 123
         '''
     }
-
-    //GROOVY-8509
-    void testProtectedCallFromClassInSamePackage() {
-        assertScript '''
-            package org.foo
-
-            class A {
-                protected A() {}
-                protected int m() { 123 }
-            }
-            class B {
-                int test() {
-                    new A().m()
-                }
-            }
-            assert new B().test() == 123
-        '''
-    }
-
-    public static class Base {
-        protected int foo() {
-            123
-        }
-    }
-
-    public static class BaseGeneric<T> {
-        protected boolean foo(T t) {
-            true
-        }
-    }
 }

Reply via email to