mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
optimisation: getMaybeSuperClassSubstitutor() allows to avoid extra isInheritor() check
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package com.intellij.psi.util;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.*;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -173,9 +174,9 @@ public class MethodSignatureUtil {
|
||||
PsiClass superClassCandidate = superMethodCandidate.getContainingClass();
|
||||
PsiClass derivedClass = derivedMethod.getContainingClass();
|
||||
if (derivedClass == null || superClassCandidate == null) return false;
|
||||
if (!derivedClass.isInheritor(superClassCandidate, true)) return false;
|
||||
final PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClassCandidate, derivedClass,
|
||||
PsiSubstitutor.EMPTY);
|
||||
final PsiSubstitutor superSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(superClassCandidate, derivedClass,
|
||||
PsiSubstitutor.EMPTY, new THashSet<PsiClass>());
|
||||
if (superSubstitutor == null) return false;
|
||||
final MethodSignature superSignature = superMethodCandidate.getSignature(superSubstitutor);
|
||||
final MethodSignature derivedSignature = derivedMethod.getSignature(PsiSubstitutor.EMPTY);
|
||||
return isSubsignature(superSignature, derivedSignature);
|
||||
|
||||
@@ -285,9 +285,9 @@ public class TypeConversionUtil {
|
||||
return checkSuperTypesWithDifferentTypeArguments(fromResult, toClass, manager, toResult.getSubstitutor(), null, languageLevel);
|
||||
}
|
||||
else {
|
||||
if (!toClass.isInheritor(fromClass, true)) return false;
|
||||
PsiSubstitutor toSubstitutor = getSuperClassSubstitutor(fromClass, toClass, toResult.getSubstitutor());
|
||||
return areSameArgumentTypes(fromClass, fromResult.getSubstitutor(), toSubstitutor);
|
||||
PsiSubstitutor toSubstitutor = getMaybeSuperClassSubstitutor(fromClass, toClass, toResult.getSubstitutor(),
|
||||
new THashSet<PsiClass>());
|
||||
return toSubstitutor != null && areSameArgumentTypes(fromClass, fromResult.getSubstitutor(), toSubstitutor);
|
||||
}
|
||||
}
|
||||
else if (languageLevel.compareTo(LanguageLevel.JDK_1_5) < 0) {
|
||||
@@ -356,10 +356,12 @@ public class TypeConversionUtil {
|
||||
derivedSubstitutor = getSuperClassSubstitutor(derived, derived, derivedSubstitutor);
|
||||
return areSameArgumentTypes(derived, baseResult.getSubstitutor(), derivedSubstitutor, 1);
|
||||
}
|
||||
else if (base.isInheritor(derived, true)) {
|
||||
derivedSubstitutor = getSuperClassSubstitutor(derived, derived, derivedSubstitutor);
|
||||
PsiSubstitutor baseSubstitutor = getSuperClassSubstitutor(derived, base, baseResult.getSubstitutor());
|
||||
if (!areSameArgumentTypes(derived, baseSubstitutor, derivedSubstitutor)) return false;
|
||||
else {
|
||||
PsiSubstitutor baseSubstitutor = getMaybeSuperClassSubstitutor(derived, base, baseResult.getSubstitutor(), new THashSet<PsiClass>());
|
||||
if (baseSubstitutor != null) {
|
||||
derivedSubstitutor = getSuperClassSubstitutor(derived, derived, derivedSubstitutor);
|
||||
if (!areSameArgumentTypes(derived, baseSubstitutor, derivedSubstitutor)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (visited == null) visited = new THashSet<PsiClass>();
|
||||
@@ -1028,8 +1030,7 @@ public class TypeConversionUtil {
|
||||
}
|
||||
return derivedSubstitutor;
|
||||
}
|
||||
if (!derivedClassCandidate.isInheritor(superClassCandidate, true)) return null;
|
||||
return getSuperClassSubstitutor(superClassCandidate, derivedClassCandidate, derivedSubstitutor);
|
||||
return getMaybeSuperClassSubstitutor(superClassCandidate, derivedClassCandidate, derivedSubstitutor, new THashSet<PsiClass>());
|
||||
}
|
||||
|
||||
private static final Set<String> ourReportedSuperClassSubstitutorExceptions = new ConcurrentHashSet<String>();
|
||||
@@ -1039,29 +1040,49 @@ public class TypeConversionUtil {
|
||||
* values that they have in <code>derivedClass</code>, given that type parameters in
|
||||
* <code>derivedClass</code> are bound by <code>derivedSubstitutor</code>.
|
||||
* <code>superClass</code> must be a super class/interface of <code>derivedClass</code> (as in
|
||||
* <code>InheritanceUtil.isInheritor(derivedClass, superClass, true)</code>
|
||||
* <code>InheritanceUtil.isInheritorOrSelf(derivedClass, superClass, true)</code>
|
||||
*
|
||||
* @return substitutor (never returns <code>null</code>)
|
||||
* @see PsiClass#isInheritor(PsiClass, boolean)
|
||||
* @see InheritanceUtil#isInheritorOrSelf(com.intellij.psi.PsiClass, com.intellij.psi.PsiClass, boolean)
|
||||
*/
|
||||
@NotNull
|
||||
public static PsiSubstitutor getSuperClassSubstitutor(@NotNull PsiClass superClass,
|
||||
@NotNull PsiClass derivedClass,
|
||||
@NotNull PsiSubstitutor derivedSubstitutor) {
|
||||
if (!superClass.hasTypeParameters() && superClass.getContainingClass() == null) return PsiSubstitutor.EMPTY; //optimization
|
||||
Set<PsiClass> visited = new THashSet<PsiClass>();
|
||||
PsiSubstitutor substitutor = getMaybeSuperClassSubstitutor(superClass, derivedClass, derivedSubstitutor, visited);
|
||||
|
||||
if (substitutor == null) {
|
||||
if (ourReportedSuperClassSubstitutorExceptions.add(derivedClass.getQualifiedName() + "/" + superClass.getQualifiedName())) {
|
||||
reportHierarchyInconsistency(superClass, derivedClass, visited);
|
||||
}
|
||||
return PsiSubstitutor.EMPTY;
|
||||
}
|
||||
return substitutor;
|
||||
}
|
||||
|
||||
// the same as getSuperClassSubstitutor() but can return null, which means that classes were not inheritors
|
||||
@Nullable
|
||||
public static PsiSubstitutor getMaybeSuperClassSubstitutor(@NotNull PsiClass superClass,
|
||||
@NotNull PsiClass derivedClass,
|
||||
@NotNull PsiSubstitutor derivedSubstitutor,
|
||||
@NotNull Set<PsiClass> visited) {
|
||||
if (!superClass.hasTypeParameters() && superClass.getContainingClass() == null) {
|
||||
return InheritanceUtil.isInheritorOrSelf(derivedClass, superClass, true) ? PsiSubstitutor.EMPTY : null; //optimization
|
||||
}
|
||||
|
||||
final PsiManager manager = superClass.getManager();
|
||||
if (PsiUtil.isRawSubstitutor(derivedClass, derivedSubstitutor)) {
|
||||
return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createRawSubstitutor(superClass);
|
||||
return InheritanceUtil.isInheritorOrSelf(derivedClass, superClass, true) ? JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createRawSubstitutor(superClass) : null;
|
||||
}
|
||||
|
||||
final PsiClass objectClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, superClass.getResolveScope());
|
||||
if (manager.areElementsEquivalent(superClass, objectClass)) {
|
||||
if (CommonClassNames.JAVA_LANG_OBJECT_SHORT.equals(superClass.getName()) &&
|
||||
manager.areElementsEquivalent(superClass, JavaPsiFacade.getInstance(manager.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, superClass.getResolveScope()))) {
|
||||
return PsiSubstitutor.EMPTY;
|
||||
}
|
||||
|
||||
PsiSubstitutor substitutor;
|
||||
final Set<PsiClass> visited = new THashSet<PsiClass>();
|
||||
if (derivedClass instanceof PsiAnonymousClass) {
|
||||
final PsiClassType baseType = ((PsiAnonymousClass)derivedClass).getBaseClassType();
|
||||
final JavaResolveResult result = baseType.resolveGenerics();
|
||||
@@ -1072,12 +1093,6 @@ public class TypeConversionUtil {
|
||||
else {
|
||||
substitutor = getSuperClassSubstitutorInner(superClass, derivedClass, derivedSubstitutor, visited, manager);
|
||||
}
|
||||
if (substitutor == null) {
|
||||
if (ourReportedSuperClassSubstitutorExceptions.add(derivedClass.getQualifiedName() + "/" + superClass.getQualifiedName())) {
|
||||
reportHierarchyInconsistency(superClass, derivedClass, visited);
|
||||
}
|
||||
return PsiSubstitutor.EMPTY;
|
||||
}
|
||||
return substitutor;
|
||||
}
|
||||
|
||||
|
||||
+12
-6
@@ -316,7 +316,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
|
||||
// prefer derived class
|
||||
signatures.put(signature, info);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
final PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(myArgumentsList, PsiMethodCallExpression.class);
|
||||
if (methodCallExpression != null) {
|
||||
final PsiReferenceExpression expression = methodCallExpression.getMethodExpression();
|
||||
@@ -324,14 +325,19 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
PsiClass currentClass;
|
||||
if (qualifierExpression != null) {
|
||||
currentClass = PsiUtil.resolveClassInClassTypeOnly(qualifierExpression.getType());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
currentClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class);
|
||||
}
|
||||
|
||||
if (currentClass != null && InheritanceUtil.isInheritorOrSelf(currentClass, class1, true) && InheritanceUtil.isInheritorOrSelf(currentClass, existingClass, true)) {
|
||||
final PsiSubstitutor eSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(existingClass, currentClass, PsiSubstitutor.EMPTY);
|
||||
final PsiSubstitutor cSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(class1, currentClass, PsiSubstitutor.EMPTY);
|
||||
if (MethodSignatureUtil.areSignaturesEqual(existingMethod.getSignature(eSubstitutor), method.getSignature(cSubstitutor))) {
|
||||
if (currentClass != null) {
|
||||
final PsiSubstitutor eSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(existingClass, currentClass,
|
||||
PsiSubstitutor.EMPTY,
|
||||
new THashSet<PsiClass>());
|
||||
final PsiSubstitutor cSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(class1, currentClass, PsiSubstitutor.EMPTY,
|
||||
new THashSet<PsiClass>());
|
||||
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)) {
|
||||
|
||||
Reference in New Issue
Block a user