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 2021/06/03 20:34:02 UTC
[groovy] branch master updated: GROOVY-5453: order category methods
before taking first getter/setter
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 445e0f6 GROOVY-5453: order category methods before taking first getter/setter
445e0f6 is described below
commit 445e0f638432a0bdaa9d50a7d5485d9eafdec8aa
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu Jun 3 15:28:00 2021 -0500
GROOVY-5453: order category methods before taking first getter/setter
---
src/main/java/groovy/lang/MetaClassImpl.java | 69 ++++++----------------
.../groovy/runtime/GroovyCategorySupport.java | 24 +++-----
src/test/groovy/CategoryTest.groovy | 34 +++++++----
3 files changed, 50 insertions(+), 77 deletions(-)
diff --git a/src/main/java/groovy/lang/MetaClassImpl.java b/src/main/java/groovy/lang/MetaClassImpl.java
index 639514c..2046b3e 100644
--- a/src/main/java/groovy/lang/MetaClassImpl.java
+++ b/src/main/java/groovy/lang/MetaClassImpl.java
@@ -2187,61 +2187,30 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
return tuple(method, mp);
}
- private static MetaMethod getCategoryMethodMissing(Class sender) {
- List possibleGenericMethods = GroovyCategorySupport.getCategoryMethods(METHOD_MISSING);
- if (possibleGenericMethods != null) {
- for (Object possibleGenericMethod : possibleGenericMethods) {
- MetaMethod mmethod = (MetaMethod) possibleGenericMethod;
- if (!mmethod.getDeclaringClass().getTheClass().isAssignableFrom(sender))
- continue;
-
- CachedClass[] paramTypes = mmethod.getParameterTypes();
- if (paramTypes.length == 2 && paramTypes[0].getTheClass() == String.class) {
- return mmethod;
- }
- }
- }
- return null;
+ private static CategoryMethod getCategoryMethodMissing(final Class<?> sender) {
+ return findCategoryMethod(METHOD_MISSING, sender, params ->
+ params.length == 2 && params[0].getTheClass() == String.class
+ );
}
- private static MetaMethod getCategoryMethodGetter(Class sender, String name, boolean useLongVersion) {
- List possibleGenericMethods = GroovyCategorySupport.getCategoryMethods(name);
- if (possibleGenericMethods != null) {
- for (Object possibleGenericMethod : possibleGenericMethods) {
- MetaMethod mmethod = (MetaMethod) possibleGenericMethod;
- if (!mmethod.getDeclaringClass().getTheClass().isAssignableFrom(sender))
- continue;
-
- CachedClass[] paramTypes = mmethod.getParameterTypes();
- if (useLongVersion) {
- if (paramTypes.length == 1 && paramTypes[0].getTheClass() == String.class) {
- return mmethod;
- }
- } else {
- if (paramTypes.length == 0) return mmethod;
- }
- }
- }
- return null;
+ private static CategoryMethod getCategoryMethodGetter(final Class<?> sender, final String name, final boolean useLongVersion) {
+ return findCategoryMethod(name, sender, params ->
+ useLongVersion ? params.length == 1 && params[0].getTheClass() == String.class : params.length == 0
+ );
}
- private static MetaMethod getCategoryMethodSetter(Class sender, String name, boolean useLongVersion) {
- List possibleGenericMethods = GroovyCategorySupport.getCategoryMethods(name);
- if (possibleGenericMethods != null) {
- for (Object possibleGenericMethod : possibleGenericMethods) {
- MetaMethod mmethod = (MetaMethod) possibleGenericMethod;
- if (!mmethod.getDeclaringClass().getTheClass().isAssignableFrom(sender))
- continue;
+ private static CategoryMethod getCategoryMethodSetter(final Class<?> sender, final String name, final boolean useLongVersion) {
+ return findCategoryMethod(name, sender, params ->
+ useLongVersion ? params.length == 2 && params[0].getTheClass() == String.class : params.length == 1
+ );
+ }
- CachedClass[] paramTypes = mmethod.getParameterTypes();
- if (useLongVersion) {
- if (paramTypes.length == 2 && paramTypes[0].getTheClass() == String.class) {
- return mmethod;
- }
- } else {
- if (paramTypes.length == 1) return mmethod;
- }
- }
+ 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);
}
return null;
}
diff --git a/src/main/java/org/codehaus/groovy/runtime/GroovyCategorySupport.java b/src/main/java/org/codehaus/groovy/runtime/GroovyCategorySupport.java
index 5fb8396..adbfa33 100644
--- a/src/main/java/org/codehaus/groovy/runtime/GroovyCategorySupport.java
+++ b/src/main/java/org/codehaus/groovy/runtime/GroovyCategorySupport.java
@@ -230,28 +230,18 @@ public class GroovyCategorySupport {
/**
* Sort by most specific to least specific.
*
- * @param o the object to compare against
+ * @param that the object to compare against
*/
@Override
- public int compareTo(Object o) {
- CategoryMethod thatMethod = (CategoryMethod) o;
+ public int compareTo(final Object that) {
Class thisClass = metaClass;
- Class thatClass = thatMethod.metaClass;
+ Class thatClass = ((CategoryMethod) that).metaClass;
+
if (thisClass == thatClass) return 0;
- if (isChildOfParent(thisClass, thatClass)) return -1;
- if (isChildOfParent(thatClass, thisClass)) return 1;
- return 0;
- }
+ if (thisClass.isAssignableFrom(thatClass)) return 1;
+ if (thatClass.isAssignableFrom(thisClass)) return -1;
- private boolean isChildOfParent(Class candidateChild, Class candidateParent) {
- Class loop = candidateChild;
- while(loop != null && loop != Object.class) {
- loop = loop.getSuperclass();
- if (loop == candidateParent) {
- return true;
- }
- }
- return false;
+ return 0;
}
}
diff --git a/src/test/groovy/CategoryTest.groovy b/src/test/groovy/CategoryTest.groovy
index 1dbbb99..2a7f73f 100644
--- a/src/test/groovy/CategoryTest.groovy
+++ b/src/test/groovy/CategoryTest.groovy
@@ -180,15 +180,15 @@ final class CategoryTest extends GroovyTestCase {
"""
}
-
def foo(x){x.bar()}
+
void testMethodHiding1() {
def x = new X()
assert foo(x) == 1
use (XCat) {
- assert foo(x) == 2
- def t = Thread.start {assert foo(x)==1}
- t.join()
+ assert foo(x) == 2
+ def t = Thread.start {assert foo(x)==1}
+ t.join()
}
assert foo(x) == 1
def t = Thread.start {use (XCat2){assert foo(x)==3}}
@@ -200,12 +200,12 @@ final class CategoryTest extends GroovyTestCase {
def x = new X()
assert foo(x) == 1
use (XCat) {
- assert foo(x) == 2
- def t = Thread.start {use (XCat2){assert foo(x)==3}}
- t.join()
- assert foo(x) == 2
- t = Thread.start {assert foo(x)==1}
- t.join()
+ assert foo(x) == 2
+ def t = Thread.start {use (XCat2){assert foo(x)==3}}
+ t.join()
+ assert foo(x) == 2
+ t = Thread.start {assert foo(x)==1}
+ t.join()
}
assert foo(x) == 1
def t = Thread.start {use (XCat2){assert foo(x)==3}}
@@ -248,6 +248,20 @@ final class CategoryTest extends GroovyTestCase {
'''
}
+ // GROOVY-5453
+ void testOverloadedGetterMethod() {
+ assertScript '''
+ class Cat {
+ static getFoo(String s) {'String'}
+ static getFoo(CharSequence s) {'CharSequence'}
+ }
+ use (Cat) {
+ assert 'abc'.getFoo() == 'String'
+ assert 'abc'.foo == 'String'
+ }
+ '''
+ }
+
// GROOVY-3867
void testPropertyMissing() {
def x = new X()