mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
ambiguity of implicit constructor call (IDEA-160248)
This commit is contained in:
+54
@@ -528,6 +528,11 @@ public class HighlightClassUtil {
|
||||
PsiMethod[] constructors = baseClass.getConstructors();
|
||||
if (constructors.length == 0) return null;
|
||||
|
||||
final HighlightInfo highlightInfo = constructors.length > 1 ? checkAmbiguityOfImplicitConstructorCall(constructors, range) : null;
|
||||
if (highlightInfo != null) {
|
||||
return highlightInfo;
|
||||
}
|
||||
|
||||
for (PsiMethod constructor : constructors) {
|
||||
if (resolveHelper.isAccessible(constructor, aClass, null)) {
|
||||
if (constructor.getParameterList().getParametersCount() == 0 ||
|
||||
@@ -556,6 +561,55 @@ public class HighlightClassUtil {
|
||||
return info;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static HighlightInfo checkAmbiguityOfImplicitConstructorCall(PsiMethod[] constructors, TextRange range) {
|
||||
List<PsiMethod> varargConstructors = new ArrayList<>();
|
||||
for (PsiMethod constructor : constructors) {
|
||||
final PsiParameter[] parameters = constructor.getParameterList().getParameters();
|
||||
if (parameters.length == 0) {
|
||||
varargConstructors.clear();
|
||||
break;
|
||||
}
|
||||
if (parameters.length == 1 && parameters[0].isVarArgs()) {
|
||||
varargConstructors.add(constructor);
|
||||
}
|
||||
}
|
||||
|
||||
if (varargConstructors.size() <= 1) return null;
|
||||
final PsiType[] types = varargConstructors.stream().map(c -> c.getParameterList().getParameters()[0].getType()).toArray(PsiType[]::new);
|
||||
for (int i = 1; i < types.length; i++) {
|
||||
PsiType t1 = types[i];
|
||||
for (int j = 0; j < i; j++) {
|
||||
PsiType t2 = types[j];
|
||||
|
||||
if (t1.isAssignableFrom(t2)) {
|
||||
varargConstructors.remove(i);
|
||||
}
|
||||
else if (t2.isAssignableFrom(t1)) {
|
||||
varargConstructors.remove(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (varargConstructors.size() > 1) {
|
||||
final String m1 = PsiFormatUtil.formatMethod(varargConstructors.get(0), PsiSubstitutor.EMPTY,
|
||||
PsiFormatUtilBase.SHOW_CONTAINING_CLASS |
|
||||
PsiFormatUtilBase.SHOW_NAME |
|
||||
PsiFormatUtilBase.SHOW_PARAMETERS,
|
||||
PsiFormatUtilBase.SHOW_TYPE);
|
||||
final String m2 = PsiFormatUtil.formatMethod(varargConstructors.get(1), PsiSubstitutor.EMPTY,
|
||||
PsiFormatUtilBase.SHOW_CONTAINING_CLASS |
|
||||
PsiFormatUtilBase.SHOW_NAME |
|
||||
PsiFormatUtilBase.SHOW_PARAMETERS,
|
||||
PsiFormatUtilBase.SHOW_TYPE);
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
|
||||
.range(range)
|
||||
.descriptionAndTooltip(JavaErrorMessages.message("ambiguous.method.call", m1, m2))
|
||||
.create();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkInterfaceCannotBeLocal(PsiClass aClass) {
|
||||
if (PsiUtil.isLocalClass(aClass)) {
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
|
||||
class A {
|
||||
A(String... i) {}
|
||||
A(Integer... i) {}
|
||||
}
|
||||
class B extends A {
|
||||
<error descr="Ambiguous method call: both 'A.A(String...)' and 'A.A(Integer...)' match">public B()</error> {}
|
||||
}
|
||||
<error descr="Ambiguous method call: both 'A.A(String...)' and 'A.A(Integer...)' match">class C extends A</error> {}
|
||||
|
||||
class A1 {
|
||||
A1(String... i){}
|
||||
A1(Object... i){}
|
||||
}
|
||||
class B1 extends A1 {
|
||||
public B1() {}
|
||||
}
|
||||
class C1 extends A1 {}
|
||||
|
||||
class A2 {
|
||||
A2(int... i){}
|
||||
A2(Object... i){}
|
||||
}
|
||||
class B2 extends A2 {
|
||||
<error descr="Ambiguous method call: both 'A2.A2(int...)' and 'A2.A2(Object...)' match">public B2()</error> {
|
||||
}
|
||||
}
|
||||
<error descr="Ambiguous method call: both 'A2.A2(int...)' and 'A2.A2(Object...)' match">class C2 extends A2</error> {}
|
||||
+4
@@ -82,4 +82,8 @@ public class LightAdvHighlightingJdk6Test extends LightDaemonAnalyzerTestCase {
|
||||
public void testEnumConstantWithoutInterfaceImplementation() throws Exception {
|
||||
doTest(false, false);
|
||||
}
|
||||
|
||||
public void testAmbiguityChecksForImplicitSuperConstructorCall() {
|
||||
doTest(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user