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 2023/01/16 18:27:49 UTC

[groovy] branch master updated: GROOVY-10897: STC: remove interface equivalent for indirect interface

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 a831581caa GROOVY-10897: STC: remove interface equivalent for indirect interface
a831581caa is described below

commit a831581caaf729e438e22b2407703162b5d3c92f
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Jan 16 11:42:37 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
---
 .../org/codehaus/groovy/util/StringUtil.groovy     | 20 +++++++++++-------
 .../transform/stc/StaticTypeCheckingSupport.java   |  3 ++-
 .../groovy/transform/stc/MethodCallsSTCTest.groovy | 24 ++++++++++++++++++++++
 3 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/src/main/groovy/org/codehaus/groovy/util/StringUtil.groovy b/src/main/groovy/org/codehaus/groovy/util/StringUtil.groovy
index e283826631..00fc6b7aae 100644
--- a/src/main/groovy/org/codehaus/groovy/util/StringUtil.groovy
+++ b/src/main/groovy/org/codehaus/groovy/util/StringUtil.groovy
@@ -25,6 +25,7 @@ import groovy.transform.CompileStatic
  */
 @CompileStatic
 class StringUtil {
+
     /**
      * Provides Groovy with functionality similar to the unix tr command
      * which translates a string replacing characters from a source set
@@ -33,25 +34,30 @@ class StringUtil {
      * @since 1.7.3
      */
     static String tr(String text, String source, String replacement) {
-        if (!text || !source) { return text }
+        if (text == null   || source == null   || replacement == null  ) return text
+        if (text.isEmpty() || source.isEmpty() || replacement.isEmpty()) return text
+
         source = expandHyphen(source)
         replacement = expandHyphen(replacement)
 
         // padding replacement with a last character, if necessary
         replacement = replacement.padRight(source.size(), replacement[-1])
 
-        text.collect { String original ->
-            if (source.contains(original)) {
-                replacement[source.lastIndexOf(original)]
+        text.collect { String character ->
+            if (source.contains(character)) {
+                replacement[source.lastIndexOf(character)]
             } else {
-                original
+                character
             }
         }.join('')
     }
 
     // no expansion for hyphen at start or end of Strings
     private static String expandHyphen(String text) {
-        if (!text.contains('-')) { return text }
-        text.replaceAll(/(.)-(.)/, { all, begin, end -> (begin..end).join('') })
+        if (text.contains('-')) {
+            text.replaceAll(/(.)-(.)/) { _, start, until -> (start..until).join('') }
+        } else {
+            text
+        }
     }
 }
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 c480669090..1d37c913bb 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1204,7 +1204,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
+                                                                                    (!disjoint && !one.isAbstract() && !(two instanceof ExtensionMethodNode))) {
                                 toBeRemoved.add(two);
                             } else if (oneDC.isInterface() ? (disjoint ? twoDC.implementsInterface(oneDC) : 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 7172bb6c17..9fb1c016dd 100644
--- a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
@@ -275,6 +275,30 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // 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-10494
     void testCallToSuperDefault() {
         assertScript '''