mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 13:31:28 +07:00
overload resolution: same signatures should not check return types, etc already processed in hierarchical signatures (IDEA-172129)
This commit is contained in:
@@ -22,7 +22,6 @@ import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiSuperMethodImplUtil;
|
||||
import com.intellij.psi.impl.source.PsiImmediateClassType;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
|
||||
@@ -240,8 +239,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
}
|
||||
}
|
||||
}
|
||||
nextConflict:
|
||||
for (int i=0; i<conflicts.size();i++) {
|
||||
for (int i = 0; i < conflicts.size(); i++) {
|
||||
ProgressManager.checkCanceled();
|
||||
CandidateInfo info = conflicts.get(i);
|
||||
PsiMethod method = (PsiMethod)info.getElement();
|
||||
@@ -267,7 +265,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
if (class1.isInterface() && CommonClassNames.JAVA_LANG_OBJECT.equals(existingClass.getQualifiedName())) {
|
||||
signatures.put(signature, info);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (existingClass.isInterface() && CommonClassNames.JAVA_LANG_OBJECT.equals(class1.getQualifiedName())) {
|
||||
conflicts.remove(info);
|
||||
i--;
|
||||
@@ -282,85 +280,6 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
PsiTreeUtil.isAncestor(scope1, scope2, true) &&
|
||||
!existing.isAccessible()) { //prefer methods from outer class to inaccessible base class methods
|
||||
signatures.put(signature, info);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// filter out methods with incorrect inferred bounds (for unrelated methods only)
|
||||
boolean existingTypeParamAgree = areTypeParametersAgree(existing);
|
||||
boolean infoTypeParamAgree = areTypeParametersAgree(info);
|
||||
if (existingTypeParamAgree && !infoTypeParamAgree && !PsiSuperMethodImplUtil.isSuperMethodSmart(method, existingMethod)) {
|
||||
conflicts.remove(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
if (!existingTypeParamAgree && infoTypeParamAgree && !PsiSuperMethodImplUtil.isSuperMethodSmart(existingMethod, method)) {
|
||||
signatures.put(signature, info);
|
||||
int index = conflicts.indexOf(existing);
|
||||
conflicts.remove(index);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (InheritanceUtil.isInheritorOrSelf(class1, existingClass, true) ||
|
||||
InheritanceUtil.isInheritorOrSelf(existingClass, class1, true)) {
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
final PsiParameter[] existingParameters = existingMethod.getParameterList().getParameters();
|
||||
for (int i1 = 0, parametersLength = parameters.length; i1 < parametersLength; i1++) {
|
||||
if (parameters[i1].getType() instanceof PsiArrayType &&
|
||||
!(existingParameters[i1].getType() instanceof PsiArrayType)) {//prefer more specific type
|
||||
signatures.put(signature, info);
|
||||
continue nextConflict;
|
||||
}
|
||||
}
|
||||
PsiType returnType1 = method.getReturnType();
|
||||
PsiType returnType2 = existingMethod.getReturnType();
|
||||
if (returnType1 != null && returnType2 != null) {
|
||||
returnType1 = infoSubstitutor.substitute(returnType1);
|
||||
returnType2 = getSubstitutor((MethodCandidateInfo)existing, map).substitute(returnType2);
|
||||
if (!returnType1.equals(returnType2) && returnType1.isAssignableFrom(returnType2)) {
|
||||
conflicts.remove(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// prefer derived class
|
||||
signatures.put(signature, info);
|
||||
}
|
||||
else {
|
||||
final PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(myArgumentsList, PsiMethodCallExpression.class);
|
||||
if (methodCallExpression != null) {
|
||||
final PsiReferenceExpression expression = methodCallExpression.getMethodExpression();
|
||||
final PsiExpression qualifierExpression = expression.getQualifierExpression();
|
||||
PsiClass currentClass;
|
||||
if (qualifierExpression != null) {
|
||||
currentClass = PsiUtil.resolveClassInClassTypeOnly(qualifierExpression.getType());
|
||||
}
|
||||
else {
|
||||
currentClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class);
|
||||
}
|
||||
|
||||
if (currentClass != null && existingClass != null && class1 != null) {
|
||||
final PsiSubstitutor eSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(existingClass, currentClass, PsiSubstitutor.EMPTY, null);
|
||||
final PsiSubstitutor cSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(class1, currentClass, PsiSubstitutor.EMPTY, null);
|
||||
if (eSubstitutor != null && cSubstitutor != null &&
|
||||
MethodSignatureUtil.areSignaturesEqual(existingMethod.getSignature(eSubstitutor), method.getSignature(cSubstitutor))) {
|
||||
final PsiType returnType = eSubstitutor.substitute(existingMethod.getReturnType());
|
||||
final PsiType returnType1 = cSubstitutor.substitute(method.getReturnType());
|
||||
if (returnType != null && returnType1 != null && !returnType1.equals(returnType)) {
|
||||
if (TypeConversionUtil.isAssignable(returnType, returnType1, false)) {
|
||||
if (class1.isInterface() && !existingClass.isInterface()) continue;
|
||||
conflicts.remove(existing);
|
||||
} else {
|
||||
if (!TypeConversionUtil.isAssignable(returnType1, returnType, false)) continue;
|
||||
conflicts.remove(i);
|
||||
}
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import java.util.function.Consumer;
|
||||
class Foo {
|
||||
private static Consumer<Object> consumer = Foo::vaMethod;
|
||||
|
||||
private static <T> T vaMethod(Object... varargs) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -252,6 +252,11 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
public void testDontSkipInapplicableMethodsDuringSameSignatureCheck() throws Exception {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
|
||||
private void doTest() {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user