[groovy] prefer overload with 0 distance instead of -1, because -1 means mismatch

This fixes overload resolution for null argument.
This commit is contained in:
Daniil Ovchinnikov
2019-01-31 17:56:34 +03:00
parent 04913fe696
commit 6d13de38dc
4 changed files with 52 additions and 20 deletions
@@ -41,10 +41,13 @@ fun compare(left: ArgumentMapping, right: ArgumentMapping): Int {
return -1
}
// prefer one will less distance
val leftDistance = (left as PositionalArgumentMapping).distance
val rightDistance = (right as PositionalArgumentMapping).distance
return leftDistance.compareTo(rightDistance)
return when {
leftDistance == 0L -> -1
rightDistance == 0L -> 1
else -> leftDistance.compareTo(rightDistance) // prefer one with less distance
}
}
fun positionalParametersDistance(map: Map<Argument, PsiParameter>, context: PsiElement): Long {
@@ -0,0 +1,42 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.lang.resolve
import com.intellij.psi.PsiMethod
import groovy.transform.CompileStatic
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod
import org.jetbrains.plugins.groovy.util.GroovyLatestTest
import org.jetbrains.plugins.groovy.util.ResolveTest
import org.junit.Test
import static com.intellij.psi.CommonClassNames.JAVA_LANG_OBJECT
import static com.intellij.psi.CommonClassNames.JAVA_UTIL_LIST
@CompileStatic
class ResolveMethodOverloadsTest extends GroovyLatestTest implements ResolveTest {
@Test
void 'void argument List vs Object'() {
def method = resolveTest 'def foo(Object o); def foo(List l); void bar(); <caret>foo(bar())', GrMethod
assert method.parameterList.parameters.first().type.equalsToText(JAVA_LANG_OBJECT)
}
@Test
void 'null argument List vs Object'() {
def method = resolveTest 'def foo(Object o); def foo(List l); <caret>foo(null)', GrMethod
assert method.parameterList.parameters.first().type.equalsToText(JAVA_LANG_OBJECT)
}
@Test
void 'list equals null'() {
def method = resolveTest 'void usage(List<String> l) { l.<caret>equals(null) }', PsiMethod
assert method.containingClass.qualifiedName == JAVA_UTIL_LIST
assert method.parameterList.parameters.last().type.equalsToText(JAVA_LANG_OBJECT)
}
@Test
void 'list == null'() {
def method = resolveTest 'void usage(List<String> l) { l <caret>== null }', PsiMethod
assert method.containingClass.qualifiedName == JAVA_UTIL_LIST
assert method.parameterList.parameters.last().type.equalsToText(JAVA_LANG_OBJECT)
}
}
@@ -2108,20 +2108,6 @@ class Fo {
assertEquals('C', clazz.qualifiedName)
}
void 'test list equals null'() {
def method = resolveByText '''\
void usage(List<String> l) { l.<caret>equals(null) }
''', GrGdkMethod
assert method.staticMethod.parameterList.parameters.last().type.equalsToText("java.util.List")
}
void 'test list == null'() {
def method = resolveByText '''\
void usage(List<String> l) { l <caret>== null }
''', GrGdkMethod
assert method.staticMethod.parameterList.parameters.last().type.equalsToText("java.util.List")
}
void testSuperReferenceWithTraitQualifier() {
def method = resolveByText('''
trait A {
@@ -35,18 +35,19 @@ public interface ResolveTest extends BaseTest {
return referenceByText(text).resolve(false);
}
default <T extends PsiElement> void resolveTest(@NotNull String text, @Nullable Class<T> clazz) {
resolveTest(referenceByText(text), clazz);
default <T extends PsiElement> T resolveTest(@NotNull String text, @Nullable Class<T> clazz) {
return resolveTest(referenceByText(text), clazz);
}
default <T extends PsiElement> void resolveTest(@NotNull GroovyReference reference, @Nullable Class<T> clazz) {
default <T extends PsiElement> T resolveTest(@NotNull GroovyReference reference, @Nullable Class<T> clazz) {
Collection<? extends GroovyResolveResult> results = reference.resolve(false);
if (clazz == null) {
assertEmpty(results);
return null;
}
else {
PsiElement resolved = assertOneElement(results).getElement();
assertInstanceOf(resolved, clazz);
return assertInstanceOf(resolved, clazz);
}
}
}