[
https://issues.apache.org/jira/browse/GROOVY-8045?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17542251#comment-17542251
]
ASF GitHub Bot commented on GROOVY-8045:
----------------------------------------
sonatype-lift[bot] commented on code in PR #1722:
URL: https://github.com/apache/groovy/pull/1722#discussion_r882143891
##########
src/main/java/org/codehaus/groovy/reflection/ParameterTypes.java:
##########
@@ -292,77 +290,72 @@ public boolean isValidExactMethod(Class[] args) {
return true;
}
- private static boolean testComponentAssignable(Class toTestAgainst, Class
toTest) {
- Class component = toTest.getComponentType();
- if (component == null) return false;
- return MetaClassHelper.isAssignableFrom(toTestAgainst, component);
- }
-
- private static boolean isValidVarargsMethod(Class[] arguments, int size,
CachedClass[] pt, int paramMinus1) {
- // first check normal number of parameters
- for (int i = 0; i < paramMinus1; i++) {
- if (pt[i].isAssignableFrom(arguments[i])) continue;
- return false;
+ private static boolean isValidVargsMethod(Class[] argumentTypes,
CachedClass[] parameterTypes, int nthParameter) {
+ for (int i = 0; i < nthParameter; i += 1) {
+ if (!parameterTypes[i].isAssignableFrom(argumentTypes[i])) {
+ return false;
+ }
}
+ CachedClass arrayType = parameterTypes[nthParameter];
+ CachedClass componentType =
ReflectionCache.getCachedClass(arrayType.getTheClass().getComponentType());
+
// check direct match
- CachedClass varg = pt[paramMinus1];
- Class clazz = varg.getTheClass().getComponentType();
- if (size == pt.length &&
- (varg.isAssignableFrom(arguments[paramMinus1]) ||
- testComponentAssignable(clazz,
arguments[paramMinus1]))) {
- return true;
+ if (argumentTypes.length == parameterTypes.length) {
+ Class argumentType = argumentTypes[nthParameter];
+ if (arrayType.isAssignableFrom(argumentType) ||
(argumentType.isArray()
+ &&
componentType.isAssignableFrom(argumentType.getComponentType()))) {
Review Comment:
*NULL_DEREFERENCE:* object `componentType` last assigned on line 301 could
be null and is dereferenced at line 307.
(at-me [in a reply](https://help.sonatype.com/lift/talking-to-lift) with
`help` or `ignore`)
---
Was this a good recommendation?
[ [🙁 Not
relevant](https://www.sonatype.com/lift-comment-rating?comment=243425071&lift_comment_rating=1)
] - [ [😕 Won't
fix](https://www.sonatype.com/lift-comment-rating?comment=243425071&lift_comment_rating=2)
] - [ [😑 Not critical, will
fix](https://www.sonatype.com/lift-comment-rating?comment=243425071&lift_comment_rating=3)
] - [ [🙂 Critical, will
fix](https://www.sonatype.com/lift-comment-rating?comment=243425071&lift_comment_rating=4)
] - [ [😊 Critical, fixing
now](https://www.sonatype.com/lift-comment-rating?comment=243425071&lift_comment_rating=5)
]
##########
src/main/java/org/codehaus/groovy/reflection/ParameterTypes.java:
##########
@@ -292,77 +290,72 @@ public boolean isValidExactMethod(Class[] args) {
return true;
}
- private static boolean testComponentAssignable(Class toTestAgainst, Class
toTest) {
- Class component = toTest.getComponentType();
- if (component == null) return false;
- return MetaClassHelper.isAssignableFrom(toTestAgainst, component);
- }
-
- private static boolean isValidVarargsMethod(Class[] arguments, int size,
CachedClass[] pt, int paramMinus1) {
- // first check normal number of parameters
- for (int i = 0; i < paramMinus1; i++) {
- if (pt[i].isAssignableFrom(arguments[i])) continue;
- return false;
+ private static boolean isValidVargsMethod(Class[] argumentTypes,
CachedClass[] parameterTypes, int nthParameter) {
+ for (int i = 0; i < nthParameter; i += 1) {
+ if (!parameterTypes[i].isAssignableFrom(argumentTypes[i])) {
+ return false;
+ }
}
+ CachedClass arrayType = parameterTypes[nthParameter];
+ CachedClass componentType =
ReflectionCache.getCachedClass(arrayType.getTheClass().getComponentType());
+
// check direct match
- CachedClass varg = pt[paramMinus1];
- Class clazz = varg.getTheClass().getComponentType();
- if (size == pt.length &&
- (varg.isAssignableFrom(arguments[paramMinus1]) ||
- testComponentAssignable(clazz,
arguments[paramMinus1]))) {
- return true;
+ if (argumentTypes.length == parameterTypes.length) {
+ Class argumentType = argumentTypes[nthParameter];
+ if (arrayType.isAssignableFrom(argumentType) ||
(argumentType.isArray()
+ &&
componentType.isAssignableFrom(argumentType.getComponentType()))) {
+ return true;
+ }
}
- // check varged
- for (int i = paramMinus1; i < size; i++) {
- if (MetaClassHelper.isAssignableFrom(clazz, arguments[i]))
continue;
- return false;
+ // check vararg match
+ for (int i = nthParameter; i < argumentTypes.length; i += 1) {
+ if (!componentType.isAssignableFrom(argumentTypes[i])) {
Review Comment:
*NULL_DEREFERENCE:* object `componentType` last assigned on line 301 could
be null and is dereferenced at line 314.
(at-me [in a reply](https://help.sonatype.com/lift/talking-to-lift) with
`help` or `ignore`)
---
Was this a good recommendation?
[ [🙁 Not
relevant](https://www.sonatype.com/lift-comment-rating?comment=243425264&lift_comment_rating=1)
] - [ [😕 Won't
fix](https://www.sonatype.com/lift-comment-rating?comment=243425264&lift_comment_rating=2)
] - [ [😑 Not critical, will
fix](https://www.sonatype.com/lift-comment-rating?comment=243425264&lift_comment_rating=3)
] - [ [🙂 Critical, will
fix](https://www.sonatype.com/lift-comment-rating?comment=243425264&lift_comment_rating=4)
] - [ [😊 Critical, fixing
now](https://www.sonatype.com/lift-comment-rating?comment=243425264&lift_comment_rating=5)
]
##########
src/main/java/org/codehaus/groovy/reflection/ParameterTypes.java:
##########
@@ -292,77 +290,72 @@ public boolean isValidExactMethod(Class[] args) {
return true;
}
- private static boolean testComponentAssignable(Class toTestAgainst, Class
toTest) {
- Class component = toTest.getComponentType();
- if (component == null) return false;
- return MetaClassHelper.isAssignableFrom(toTestAgainst, component);
- }
-
- private static boolean isValidVarargsMethod(Class[] arguments, int size,
CachedClass[] pt, int paramMinus1) {
- // first check normal number of parameters
- for (int i = 0; i < paramMinus1; i++) {
- if (pt[i].isAssignableFrom(arguments[i])) continue;
- return false;
+ private static boolean isValidVargsMethod(Class[] argumentTypes,
CachedClass[] parameterTypes, int nthParameter) {
+ for (int i = 0; i < nthParameter; i += 1) {
+ if (!parameterTypes[i].isAssignableFrom(argumentTypes[i])) {
+ return false;
+ }
}
+ CachedClass arrayType = parameterTypes[nthParameter];
+ CachedClass componentType =
ReflectionCache.getCachedClass(arrayType.getTheClass().getComponentType());
+
// check direct match
- CachedClass varg = pt[paramMinus1];
- Class clazz = varg.getTheClass().getComponentType();
- if (size == pt.length &&
- (varg.isAssignableFrom(arguments[paramMinus1]) ||
- testComponentAssignable(clazz,
arguments[paramMinus1]))) {
- return true;
+ if (argumentTypes.length == parameterTypes.length) {
+ Class argumentType = argumentTypes[nthParameter];
+ if (arrayType.isAssignableFrom(argumentType) ||
(argumentType.isArray()
+ &&
componentType.isAssignableFrom(argumentType.getComponentType()))) {
+ return true;
+ }
}
- // check varged
- for (int i = paramMinus1; i < size; i++) {
- if (MetaClassHelper.isAssignableFrom(clazz, arguments[i]))
continue;
- return false;
+ // check vararg match
+ for (int i = nthParameter; i < argumentTypes.length; i += 1) {
+ if (!componentType.isAssignableFrom(argumentTypes[i])) {
+ return false;
+ }
}
+
return true;
}
public boolean isValidMethod(Object[] arguments) {
if (arguments == null) return true;
-
- final int size = arguments.length;
- CachedClass[] paramTypes = getParameterTypes();
- final int paramMinus1 = paramTypes.length - 1;
-
- if (size >= paramMinus1 && paramTypes.length > 0 &&
- paramTypes[(paramMinus1)].isArray) {
- // first check normal number of parameters
- for (int i = 0; i < paramMinus1; i++) {
- if (paramTypes[i].isAssignableFrom(getArgClass(arguments[i])))
continue;
- return false;
+ final CachedClass[] parameterTypes = getParameterTypes();
+ final int nArguments = arguments.length, nParameters =
parameterTypes.length, nthParameter = nParameters - 1;
Review Comment:
*NULL_DEREFERENCE:* object `parameterTypes` last assigned on line 324 could
be null and is dereferenced at line 325.
(at-me [in a reply](https://help.sonatype.com/lift/talking-to-lift) with
`help` or `ignore`)
---
Was this a good recommendation?
[ [🙁 Not
relevant](https://www.sonatype.com/lift-comment-rating?comment=243425289&lift_comment_rating=1)
] - [ [😕 Won't
fix](https://www.sonatype.com/lift-comment-rating?comment=243425289&lift_comment_rating=2)
] - [ [😑 Not critical, will
fix](https://www.sonatype.com/lift-comment-rating?comment=243425289&lift_comment_rating=3)
] - [ [🙂 Critical, will
fix](https://www.sonatype.com/lift-comment-rating?comment=243425289&lift_comment_rating=4)
] - [ [😊 Critical, fixing
now](https://www.sonatype.com/lift-comment-rating?comment=243425289&lift_comment_rating=5)
]
> Implicit closure coercion doesn't work for elements of array of functional
> objects
> ----------------------------------------------------------------------------------
>
> Key: GROOVY-8045
> URL: https://issues.apache.org/jira/browse/GROOVY-8045
> Project: Groovy
> Issue Type: Bug
> Components: Compiler
> Affects Versions: 2.4.7
> Reporter: Dimitar Dimitrov
> Assignee: Eric Milles
> Priority: Major
> Labels: varargs
>
> Implicit closure coercion is described
> [here|http://groovy-lang.org/releasenotes/groovy-2.2.html] - it assumes that
> the closures don't need to be casted to functional types and the generic
> types will be inferred by the compiler.
> Here is one contrived case that works from Java (this is not production code
> and is writen explicitly for illustration purposes):
> {code}
> public class GroovyAccDemo {
> @SafeVarargs
> public static <T, R> Function<T, R> ensemble(Function<T, R>...
> hypotheses) {
> return t -> Arrays.stream(hypotheses)
> .map(v -> v.apply(t))
> .collect(Collectors.groupingBy(e -> e,
> Collectors.counting()))
> .entrySet()
> .stream()
> .max(Comparator.comparingLong(Map.Entry::getValue))
> .map(Map.Entry::getKey).orElseGet(() -> null);
> }
> public static void main(String[] args) {
> Function<Integer, Integer> foo = ensemble(
> i -> i*i,
> i -> i+i,
> i -> i*i - (i+i)
> );
> }
> }
> {code}
> Here the {{ensemble()}} method accepts a number of compatible functions and
> returns a single function that calls all hypotheses and returns the most
> popular result.
> The main method illustrates that we can use the {{ensemble()}} function with
> Java Lambdas without any explicit casts.
> If we try to do the same in Groovy, we'll get runtime error (or compile error
> if static compilation is enabled):
> {code}
> foo = GroovyAccDemo.<Integer, Integer> ensemble(
> { i -> i * i },
> { i -> i + i },
> { i -> i * i - (i + i) }
> );
> {code}
> We can make it work by explicitly coercing the closures like this:
> {code}
> foo = GroovyAccDemo.ensemble(
> { i -> i*i } as Function,
> { i -> i+i } as Function,
> { i -> i*i - (i+i ) } as Function
> );
> {code}
> This may seem as contrived use case, but it makes the use of certain API's
> more tedious from Groovy than from Java, which just feels wrong ;-)
--
This message was sent by Atlassian Jira
(v8.20.7#820007)