mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 04:51:24 +07:00
check for duplicate methods made linear down from quadratic
This commit is contained in:
@@ -41,9 +41,14 @@ public abstract class MethodSignatureBase implements MethodSignature {
|
||||
myTypeParameters = typeParameters;
|
||||
}
|
||||
|
||||
protected MethodSignatureBase(@NotNull PsiSubstitutor substitutor, PsiParameterList parameterList, @Nullable PsiTypeParameterList typeParameterList) {
|
||||
protected MethodSignatureBase(@NotNull PsiSubstitutor substitutor,
|
||||
@Nullable PsiParameterList parameterList,
|
||||
@Nullable PsiTypeParameterList typeParameterList) {
|
||||
mySubstitutor = substitutor;
|
||||
if (parameterList != null) {
|
||||
if (parameterList == null) {
|
||||
myParameterTypes = PsiType.EMPTY_ARRAY;
|
||||
}
|
||||
else {
|
||||
final PsiParameter[] parameters = parameterList.getParameters();
|
||||
myParameterTypes = parameters.length == 0 ? PsiType.EMPTY_ARRAY : new PsiType[parameters.length];
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
@@ -52,9 +57,6 @@ public abstract class MethodSignatureBase implements MethodSignature {
|
||||
myParameterTypes[i] = substitutor.substitute(type);
|
||||
}
|
||||
}
|
||||
else {
|
||||
myParameterTypes = PsiType.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
myTypeParameters = typeParameterList == null ? PsiTypeParameter.EMPTY_ARRAY : typeParameterList.getTypeParameters();
|
||||
}
|
||||
@@ -74,7 +76,7 @@ public abstract class MethodSignatureBase implements MethodSignature {
|
||||
public PsiType[] getErasedParameterTypes() {
|
||||
PsiType[] result = myErasedParameterTypes;
|
||||
if (result == null) {
|
||||
myErasedParameterTypes = result = MethodSignatureUtil.getErasedParameterTypes(this);
|
||||
myErasedParameterTypes = result = MethodSignatureUtil.calcErasedParameterTypes(this);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -54,19 +54,20 @@ public class MethodSignatureUtil {
|
||||
|
||||
@Override
|
||||
public boolean equals(MethodSignature method1, MethodSignature method2) {
|
||||
return areSignaturesEqualLightweight(method1, method2) && checkErasedParametersEqual(method1, method2);
|
||||
return areSignaturesEqualLightweight(method1, method2) && areErasedParametersEqual(method1, method2);
|
||||
}
|
||||
};
|
||||
|
||||
private static boolean checkErasedParametersEqual(MethodSignature method1, MethodSignature method2) {
|
||||
private static boolean areErasedParametersEqual(@NotNull MethodSignature method1, @NotNull MethodSignature method2) {
|
||||
PsiType[] erased1 = method1 instanceof MethodSignatureBase
|
||||
? ((MethodSignatureBase)method1).getErasedParameterTypes() : getErasedParameterTypes(method1);
|
||||
PsiType[] erased2 = method2 instanceof MethodSignatureBase
|
||||
? ((MethodSignatureBase)method2).getErasedParameterTypes() : getErasedParameterTypes(method2);
|
||||
? ((MethodSignatureBase)method1).getErasedParameterTypes() : calcErasedParameterTypes(method1);
|
||||
PsiType[] erased2 = method2 instanceof MethodSignatureBase
|
||||
? ((MethodSignatureBase)method2).getErasedParameterTypes() : calcErasedParameterTypes(method2);
|
||||
return Arrays.equals(erased1, erased2);
|
||||
}
|
||||
|
||||
public static PsiType[] getErasedParameterTypes(MethodSignature signature) {
|
||||
@NotNull
|
||||
public static PsiType[] calcErasedParameterTypes(@NotNull MethodSignature signature) {
|
||||
PsiType[] parameterTypes = signature.getParameterTypes();
|
||||
if (parameterTypes.length == 0) return PsiType.EMPTY_ARRAY;
|
||||
|
||||
@@ -78,6 +79,7 @@ public class MethodSignatureUtil {
|
||||
return erasedTypes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static MethodSignature createMethodSignature(@NonNls @NotNull String name,
|
||||
@Nullable PsiParameterList parameterTypes,
|
||||
@Nullable PsiTypeParameterList typeParameterList,
|
||||
@@ -85,6 +87,7 @@ public class MethodSignatureUtil {
|
||||
return createMethodSignature(name, parameterTypes, typeParameterList, substitutor, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static MethodSignature createMethodSignature(@NonNls @NotNull String name,
|
||||
@Nullable PsiParameterList parameterTypes,
|
||||
@Nullable PsiTypeParameterList typeParameterList,
|
||||
@@ -93,6 +96,7 @@ public class MethodSignatureUtil {
|
||||
return new MethodSignatureHandMade(name, parameterTypes, typeParameterList, substitutor, isConstructor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static MethodSignature createMethodSignature(@NonNls @NotNull String name,
|
||||
@NotNull PsiType[] parameterTypes,
|
||||
@NotNull PsiTypeParameter[] typeParameterList,
|
||||
@@ -100,6 +104,7 @@ public class MethodSignatureUtil {
|
||||
return createMethodSignature(name, parameterTypes, typeParameterList, substitutor, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static MethodSignature createMethodSignature(@NonNls @NotNull String name,
|
||||
@NotNull PsiType[] parameterTypes,
|
||||
@NotNull PsiTypeParameter[] typeParameterList,
|
||||
@@ -108,22 +113,22 @@ public class MethodSignatureUtil {
|
||||
return new MethodSignatureHandMade(name, parameterTypes, typeParameterList, substitutor, isConstructor);
|
||||
}
|
||||
|
||||
public static boolean areSignaturesEqual(PsiMethod method1, PsiMethod method2) {
|
||||
public static boolean areSignaturesEqual(@NotNull PsiMethod method1, @NotNull PsiMethod method2) {
|
||||
return method1.getSignature(PsiSubstitutor.EMPTY).equals(method2.getSignature(PsiSubstitutor.EMPTY));
|
||||
}
|
||||
|
||||
public static boolean areSignaturesEqual(MethodSignature method1, MethodSignature method2) {
|
||||
public static boolean areSignaturesEqual(@NotNull MethodSignature method1, @NotNull MethodSignature method2) {
|
||||
if (method2 == method1) return true;
|
||||
if (!areSignaturesEqualLightweight(method1, method2)) return false;
|
||||
PsiSubstitutor unifyingSubstitutor = getSuperMethodSignatureSubstitutor(method1, method2);
|
||||
return checkSignaturesEqualInner(method1, method2, unifyingSubstitutor);
|
||||
return checkSignaturesEqualInner(method1, method2, getSuperMethodSignatureSubstitutor(method1, method2))
|
||||
|| checkSignaturesEqualInner(method2, method1, getSuperMethodSignatureSubstitutor(method2, method1));
|
||||
}
|
||||
|
||||
private static boolean checkSignaturesEqualInner(final MethodSignature subSignature,
|
||||
final MethodSignature superSignature,
|
||||
private static boolean checkSignaturesEqualInner(@NotNull MethodSignature subSignature,
|
||||
@NotNull MethodSignature superSignature,
|
||||
final PsiSubstitutor unifyingSubstitutor) {
|
||||
if (unifyingSubstitutor == null) return false;
|
||||
if (!checkErasedParametersEqual(subSignature, superSignature)) return false;
|
||||
if (!areErasedParametersEqual(subSignature, superSignature)) return false;
|
||||
|
||||
final PsiType[] subParameterTypes = subSignature.getParameterTypes();
|
||||
final PsiType[] superParameterTypes = superSignature.getParameterTypes();
|
||||
@@ -138,12 +143,12 @@ public class MethodSignatureUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean areSignaturesEqualLightweight(final MethodSignature sig1, final MethodSignature sig2) {
|
||||
public static boolean areSignaturesEqualLightweight(@NotNull MethodSignature sig1, @NotNull MethodSignature sig2) {
|
||||
final boolean isConstructor1 = sig1.isConstructor();
|
||||
final boolean isConstructor2 = sig2.isConstructor();
|
||||
if (isConstructor1 != isConstructor2) return false;
|
||||
|
||||
if (!isConstructor1 && !isConstructor2 || !(sig1 instanceof HierarchicalMethodSignature || sig2 instanceof HierarchicalMethodSignature)) {
|
||||
if (!isConstructor1 || !(sig1 instanceof HierarchicalMethodSignature || sig2 instanceof HierarchicalMethodSignature)) {
|
||||
final String name1 = sig1.getName();
|
||||
final String name2 = sig2.getName();
|
||||
if (!name1.equals(name2)) return false;
|
||||
@@ -164,7 +169,7 @@ public class MethodSignatureUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isSuperMethod(final PsiMethod superMethodCandidate, final PsiMethod derivedMethod) {
|
||||
public static boolean isSuperMethod(@NotNull PsiMethod superMethodCandidate, @NotNull PsiMethod derivedMethod) {
|
||||
PsiClass superClassCandidate = superMethodCandidate.getContainingClass();
|
||||
PsiClass derivedClass = derivedMethod.getContainingClass();
|
||||
if (derivedClass == null || superClassCandidate == null) return false;
|
||||
@@ -179,16 +184,16 @@ public class MethodSignatureUtil {
|
||||
@Nullable
|
||||
public static PsiMethod findMethodInSuperClassBySignatureInDerived(@NotNull final PsiClass aClass,
|
||||
@NotNull final PsiClass superClass,
|
||||
final MethodSignature signature,
|
||||
@NotNull MethodSignature signature,
|
||||
final boolean checkDeep) {
|
||||
PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY);
|
||||
return doFindMethodInSuperClassBySignatureInDerived(superClass, superSubstitutor, signature, checkDeep);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiMethod doFindMethodInSuperClassBySignatureInDerived(final PsiClass superClass,
|
||||
final PsiSubstitutor superSubstitutor,
|
||||
final MethodSignature signature,
|
||||
private static PsiMethod doFindMethodInSuperClassBySignatureInDerived(@NotNull PsiClass superClass,
|
||||
@NotNull PsiSubstitutor superSubstitutor,
|
||||
@NotNull MethodSignature signature,
|
||||
final boolean checkDeep) {
|
||||
final String name = signature.getName();
|
||||
final PsiMethod[] methods = superClass.findMethodsByName(name, false);
|
||||
@@ -210,12 +215,12 @@ public class MethodSignatureUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiMethod findMethodBySignature(final PsiClass aClass, final PsiMethod pattenMethod, boolean checkBases) {
|
||||
public static PsiMethod findMethodBySignature(@NotNull PsiClass aClass, @NotNull PsiMethod pattenMethod, boolean checkBases) {
|
||||
return findMethodBySignature(aClass, pattenMethod.getSignature(PsiSubstitutor.EMPTY), checkBases);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiMethod findMethodBySignature(final PsiClass aClass, final MethodSignature methodSignature, boolean checkBases) {
|
||||
public static PsiMethod findMethodBySignature(@NotNull PsiClass aClass, @NotNull MethodSignature methodSignature, boolean checkBases) {
|
||||
String name = methodSignature.isConstructor() ? aClass.getName() : methodSignature.getName();
|
||||
List<Pair<PsiMethod, PsiSubstitutor>> pairs = aClass.findMethodsAndTheirSubstitutorsByName(name, checkBases);
|
||||
for (Pair<PsiMethod, PsiSubstitutor> pair : pairs) {
|
||||
@@ -228,7 +233,7 @@ public class MethodSignatureUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiMethod findMethodBySuperSignature(final PsiClass aClass, final MethodSignature methodSignature, final boolean checkBases) {
|
||||
public static PsiMethod findMethodBySuperSignature(@NotNull PsiClass aClass, @NotNull MethodSignature methodSignature, final boolean checkBases) {
|
||||
String name = methodSignature.isConstructor() ? aClass.getName() : methodSignature.getName();
|
||||
List<Pair<PsiMethod, PsiSubstitutor>> pairs = aClass.findMethodsAndTheirSubstitutorsByName(name, checkBases);
|
||||
for (Pair<PsiMethod, PsiSubstitutor> pair : pairs) {
|
||||
@@ -241,7 +246,7 @@ public class MethodSignatureUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiMethod findMethodBySuperMethod(final PsiClass aClass, final PsiMethod method, final boolean checkBases) {
|
||||
public static PsiMethod findMethodBySuperMethod(@NotNull PsiClass aClass, @NotNull PsiMethod method, final boolean checkBases) {
|
||||
List<Pair<PsiMethod, PsiSubstitutor>> pairs = aClass.findMethodsAndTheirSubstitutorsByName(method.getName(), checkBases);
|
||||
for (Pair<PsiMethod, PsiSubstitutor> pair : pairs) {
|
||||
PsiMethod candidate = pair.first;
|
||||
@@ -258,22 +263,23 @@ public class MethodSignatureUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean hasOverloads(PsiMethod method) {
|
||||
public static boolean hasOverloads(@NotNull PsiMethod method) {
|
||||
return getOverloads(method).length > 1;
|
||||
}
|
||||
|
||||
public static PsiMethod[] getOverloads(PsiMethod method) {
|
||||
@NotNull
|
||||
public static PsiMethod[] getOverloads(@NotNull PsiMethod method) {
|
||||
PsiClass aClass = method.getContainingClass();
|
||||
if (aClass == null) return new PsiMethod[]{method};
|
||||
return aClass.findMethodsByName(method.getName(), false);
|
||||
}
|
||||
|
||||
public static boolean areParametersErasureEqual(PsiMethod method1, PsiMethod method2) {
|
||||
public static boolean areParametersErasureEqual(@NotNull PsiMethod method1, @NotNull PsiMethod method2) {
|
||||
if (method1.getParameterList().getParametersCount() != method2.getParameterList().getParametersCount()) return false;
|
||||
return areSignaturesErasureEqual(method1.getSignature(PsiSubstitutor.EMPTY), method2.getSignature(PsiSubstitutor.EMPTY));
|
||||
}
|
||||
|
||||
public static boolean areSignaturesErasureEqual(MethodSignature signature1, MethodSignature signature2) {
|
||||
public static boolean areSignaturesErasureEqual(@NotNull MethodSignature signature1, @NotNull MethodSignature signature2) {
|
||||
return METHOD_PARAMETERS_ERASURE_EQUALITY.equals(signature1, signature2);
|
||||
}
|
||||
|
||||
@@ -283,7 +289,7 @@ public class MethodSignatureUtil {
|
||||
* @return null if signatures do not match
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiSubstitutor getSuperMethodSignatureSubstitutor(MethodSignature methodSignature, MethodSignature superMethodSignature) {
|
||||
public static PsiSubstitutor getSuperMethodSignatureSubstitutor(@NotNull MethodSignature methodSignature, @NotNull MethodSignature superMethodSignature) {
|
||||
PsiSubstitutor result = getSuperMethodSignatureSubstitutorImpl(methodSignature, superMethodSignature);
|
||||
if (result == null) return null;
|
||||
|
||||
@@ -313,7 +319,7 @@ public class MethodSignatureUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiSubstitutor getSuperMethodSignatureSubstitutorImpl(MethodSignature methodSignature, MethodSignature superSignature) {
|
||||
private static PsiSubstitutor getSuperMethodSignatureSubstitutorImpl(@NotNull MethodSignature methodSignature, @NotNull MethodSignature superSignature) {
|
||||
// normalize generic method declarations: correlate type parameters
|
||||
// todo: correlate type params by name?
|
||||
PsiTypeParameter[] methodTypeParameters = methodSignature.getTypeParameters();
|
||||
@@ -332,7 +338,8 @@ public class MethodSignatureUtil {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static PsiSubstitutor combineSubstitutors(PsiSubstitutor substitutor1, PsiSubstitutor substitutor2) {
|
||||
@NotNull
|
||||
public static PsiSubstitutor combineSubstitutors(@NotNull PsiSubstitutor substitutor1, @NotNull PsiSubstitutor substitutor2) {
|
||||
if (substitutor1 == PsiSubstitutor.EMPTY) return substitutor2;
|
||||
Set<PsiTypeParameter> parameters1 = substitutor1.getSubstitutionMap().keySet();
|
||||
final PsiTypeParameter[] typeParameters = parameters1.toArray(new PsiTypeParameter[parameters1.size()]);
|
||||
@@ -353,7 +360,7 @@ public class MethodSignatureUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiMethod[] convertMethodSignaturesToMethods(List<? extends MethodSignatureBackedByPsiMethod> sameNameMethodList) {
|
||||
public static PsiMethod[] convertMethodSignaturesToMethods(@NotNull List<? extends MethodSignatureBackedByPsiMethod> sameNameMethodList) {
|
||||
final PsiMethod[] methods = new PsiMethod[sameNameMethodList.size()];
|
||||
for (int i = 0; i < sameNameMethodList.size(); i++) {
|
||||
methods[i] = sameNameMethodList.get(i).getMethod();
|
||||
@@ -361,7 +368,7 @@ public class MethodSignatureUtil {
|
||||
return methods;
|
||||
}
|
||||
|
||||
public static boolean isSubsignature(MethodSignature superSignature, MethodSignature subSignature) {
|
||||
public static boolean isSubsignature(@NotNull MethodSignature superSignature, @NotNull MethodSignature subSignature) {
|
||||
if (subSignature == superSignature) return true;
|
||||
if (!areSignaturesEqualLightweight(superSignature, subSignature)) return false;
|
||||
PsiSubstitutor unifyingSubstitutor = getSuperMethodSignatureSubstitutor(subSignature, superSignature);
|
||||
|
||||
Reference in New Issue
Block a user