-
Notifications
You must be signed in to change notification settings - Fork 194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type inference problem on sort { }.each { } #387
Comments
The addition of List.sort to the JDK caused a lot of trouble. If you use toSorted(), there should be no problem flow typing this out.
|
Which of these is more applicable? Can you see why there is confusion for the tool? |
I think Greclipse should choose what Groovy runtime does... I don't know how it behaves in this case. |
In both cases there is a closure that is being coerced to the SAM type Comparator. Do what Groovy does is not that easy when it is not stated clearly in a specification document exactly what that is. Groovy-Eclipse has preference for type's own member over category method.
Here are some test cases that had to be written for this when Java 8 came around:
@test // GRECLIPSE-1695 redux
public void testDGM45() throws Throwable {
// Java 8 adds default method sort(Comparator) to List interface...
// TypeInferencingVisitorWithRequestor.lookupExpressionType replaces DGM (from CategoryTypeLookup) with JDK (from SimpleTypeLookup)
String contents = "List<String> myList = new ArrayList<String>()\n" +
"myList.sort { a, b ->\n" +
" a.trim() <=> b.trim()\n" +
"}.each {\n" +
" it\n" +
"}\n";
int start = contents.lastIndexOf("it");
int end = start + "it".length();
assertTypeOneOf(contents, start, end, "java.lang.Void", "java.lang.String");
}
@test
public void testListSort1() {
String contents = "def list = []; list.sort()";
int start = contents.lastIndexOf("sort");
int end = start + "sort".length();
assertType(contents, start, end, "java.util.List<java.lang.Object>");
assertDeclaringType(contents, start, end, "org.codehaus.groovy.runtime.DefaultGroovyMethods");
}
@test
public void testListSort2() {
// Java 8 added sort(Comparator) to the List interface
boolean jdkListSort;
try {
List.class.getDeclaredMethod("sort", Comparator.class);
jdkListSort = true;
} catch (Exception e) {
jdkListSort = false;
}
String contents = "def list = []; list.sort({ o1, o2 -> o1 <=> o2 } as Comparator)";
int start = contents.lastIndexOf("sort");
int end = start + "sort".length();
assertType(contents, start, end, jdkListSort ? "java.lang.Void" : "java.util.List<java.lang.Object>");
assertDeclaringType(contents, start, end, jdkListSort ? "java.util.List<java.lang.Object>" : "org.codehaus.groovy.runtime.DefaultGroovyMethods");
}
|
Here is the selection algorithm for multiple matches. private Object chooseMostSpecificParams(String name, List matchingMethods, Class[] arguments) {
long matchesDistance = -1;
LinkedList matches = new LinkedList();
for (Object method : matchingMethods) {
ParameterTypes paramTypes = (ParameterTypes) method;
long dist = MetaClassHelper.calculateParameterDistance(arguments, paramTypes);
if (dist == 0) return method;
if (matches.isEmpty()) {
matches.add(method);
matchesDistance = dist;
} else if (dist < matchesDistance) {
matchesDistance = dist;
matches.clear();
matches.add(method);
} else if (dist == matchesDistance) {
matches.add(method);
}
} |
So it's actually this DGM that satisfies: |
It is this block in // check if the arguments and parameters are mismatched; a category method may make a better match
if (((MethodNode) declaration).getParameters().length != scope.getMethodCallNumberOfArguments()) {
confidence = TypeConfidence.LOOSELY_INFERRED;
} |
Exactly what I expect: in that code I actually want to invoke the |
ready to test |
Tested with 2.9.2.xx-201711191708-e46, works fine, thank you! 👍 |
This seems to be some sort of regression, because it was fixed with GRECLIPSE-1695.
Consider the following Groovy class:
As you can see, the last
it.trim()
is underlined becauseit
is not recognized asString
. Probably this is because the call tomyList.sort { }
is wrongly recognized as a call to Java 8java.util.List.sort(Comparator<? super E>)
, which returnsvoid
.The text was updated successfully, but these errors were encountered: