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/04/22 21:03:56 UTC

[groovy] 01/02: GROOVY-10214, GROOVY-5453: order category methods by self-type distances

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

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

commit cd8d531a2f42bcfbd50456af4867fb5bf2b1b4f2
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Apr 22 15:44:22 2022 -0500

    GROOVY-10214, GROOVY-5453: order category methods by self-type distances
---
 src/main/java/groovy/lang/MetaClassImpl.java | 17 ++++++++++---
 src/test/groovy/CategoryTest.groovy          | 38 ++++++++++++++++++++++++++--
 2 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/src/main/java/groovy/lang/MetaClassImpl.java b/src/main/java/groovy/lang/MetaClassImpl.java
index 97de3f7c23..19c4aebc8f 100644
--- a/src/main/java/groovy/lang/MetaClassImpl.java
+++ b/src/main/java/groovy/lang/MetaClassImpl.java
@@ -2291,9 +2291,20 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
     private static CategoryMethod findCategoryMethod(final String name, final Class<?> sender, final java.util.function.Predicate<CachedClass[]> paramFilter) {
         List<CategoryMethod> categoryMethods = GroovyCategorySupport.getCategoryMethods(name);
         if (categoryMethods != null) {
-            return categoryMethods.stream().filter(categoryMethod ->
-                categoryMethod.getDeclaringClass().isAssignableFrom(sender) && paramFilter.test(categoryMethod.getParameterTypes())
-            ).sorted().findFirst().orElse(null);
+            List<CategoryMethod> choices = new ArrayList<>();
+            for (CategoryMethod categoryMethod : categoryMethods) {
+                if (categoryMethod.getOwnerClass().isAssignableFrom(sender)
+                        && paramFilter.test(categoryMethod.getParameterTypes())) {
+                    choices.add(categoryMethod);
+                }
+            }
+            if (!choices.isEmpty()) {
+                if (choices.size() > 1) { // GROOVY-5453, GROOVY-10214: order by self-type distance
+                    choices.sort(Comparator.comparingLong(m -> MetaClassHelper.calculateParameterDistance(
+                            new Class[]{sender}, new ParameterTypes(new CachedClass[]{m.getOwnerClass()}))));
+                }
+                return choices.get(0);
+            }
         }
         return null;
     }
diff --git a/src/test/groovy/CategoryTest.groovy b/src/test/groovy/CategoryTest.groovy
index a4d7ba588c..92a734668c 100644
--- a/src/test/groovy/CategoryTest.groovy
+++ b/src/test/groovy/CategoryTest.groovy
@@ -22,7 +22,8 @@ import groovy.test.GroovyTestCase
 
 final class CategoryTest extends GroovyTestCase {
 
-    void setUp() {
+    @Override
+    protected void setUp() {
         def dummy = null
         CategoryTestPropertyCategory.setSomething(dummy, 'hello')
         CategoryTestHelperPropertyReplacer.setaProperty(dummy, 'anotherValue')
@@ -280,7 +281,7 @@ final class CategoryTest extends GroovyTestCase {
     }
 
     // GROOVY-5453
-    void testOverloadedGetterMethod() {
+    void testOverloadedGetterMethod1() {
         assertScript '''
             class Cat {
                 static getFoo(String s) {'String'}
@@ -293,6 +294,39 @@ final class CategoryTest extends GroovyTestCase {
         '''
     }
 
+    // GROOVY-10214
+    void testOverloadedGetterMethod2() {
+        assertScript '''
+            class Cat {
+                static String getFoo(Boolean self) {
+                    'Boolean'
+                }
+                static String getFoo(Byte    self) {
+                    'Byte'
+                }
+                static String getFoo(Short   self) {
+                    'Short'
+                }
+                static String getFoo(Integer self) {
+                    'Integer'
+                }
+                static String getFoo(Long    self) {
+                    'Long'
+                }
+                static String getFoo(Float   self) {
+                    'Float'
+                }
+                static String getFoo(Double  self) {
+                    'Double'
+                }
+            }
+            use (Cat) {
+                assert 123.foo == 'Integer'
+                assert 4.5d.foo == 'Double'
+            }
+        '''
+    }
+
     // GROOVY-3867
     void testPropertyMissing() {
         def x = new X()