mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
use JavaClassSupers to calculate super class substitutor and isInheritor
This commit is contained in:
@@ -1090,28 +1090,7 @@ public class TypeConversionUtil {
|
||||
@NotNull PsiClass derivedClass,
|
||||
@NotNull PsiSubstitutor derivedSubstitutor,
|
||||
@Nullable 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 InheritanceUtil.isInheritorOrSelf(derivedClass, superClass, true) ? JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createRawSubstitutor(superClass) : null;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (derivedClass instanceof PsiAnonymousClass) {
|
||||
final PsiClassType baseType = ((PsiAnonymousClass)derivedClass).getBaseClassType();
|
||||
final JavaResolveResult result = baseType.resolveGenerics();
|
||||
if (result.getElement() == null) return PsiSubstitutor.UNKNOWN;
|
||||
derivedClass = (PsiClass)result.getElement();
|
||||
derivedSubstitutor = derivedSubstitutor.putAll(result.getSubstitutor());
|
||||
}
|
||||
return getSuperClassSubstitutorInner(superClass, derivedClass, derivedSubstitutor, visited == null ? new THashSet<PsiClass>() : visited, manager);
|
||||
return JavaClassSupers.getInstance().getSuperClassSubstitutor(superClass, derivedClass, derivedClass.getResolveScope(), derivedSubstitutor);
|
||||
}
|
||||
|
||||
private static void reportHierarchyInconsistency(@NotNull PsiClass superClass, @NotNull PsiClass derivedClass, @NotNull Set<PsiClass> visited) {
|
||||
@@ -1152,62 +1131,6 @@ public class TypeConversionUtil {
|
||||
return getSuperClassSubstitutor(superClass, classResolveResult.getElement(), classResolveResult.getSubstitutor());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiSubstitutor getSuperClassSubstitutorInner(@NotNull PsiClass base,
|
||||
@NotNull PsiClass candidate,
|
||||
@NotNull PsiSubstitutor candidateSubstitutor,
|
||||
@NotNull Set<PsiClass> visited,
|
||||
@NotNull PsiManager manager) {
|
||||
if (!visited.add(candidate)) return null;
|
||||
assert candidateSubstitutor.isValid();
|
||||
|
||||
if (base == candidate) return candidateSubstitutor;
|
||||
if (manager.areElementsEquivalent(base, candidate)) {
|
||||
PsiTypeParameter[] baseParams = base.getTypeParameters();
|
||||
PsiTypeParameter[] candidateParams = candidate.getTypeParameters();
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(base.getProject()).getElementFactory();
|
||||
if (baseParams.length > 0 && candidateParams.length == 0) {
|
||||
return factory.createRawSubstitutor(base);
|
||||
}
|
||||
else {
|
||||
Map<PsiTypeParameter, PsiType> m = new HashMap<PsiTypeParameter, PsiType>();
|
||||
for (int i = 0; i < candidateParams.length && i < baseParams.length; i++) {
|
||||
m.put(baseParams[i], candidateSubstitutor.substitute(candidateParams[i]));
|
||||
}
|
||||
return factory.createSubstitutor(m);
|
||||
}
|
||||
}
|
||||
|
||||
PsiSubstitutor substitutor = checkReferenceList(candidate.getExtendsListTypes(), candidateSubstitutor, base, visited, manager);
|
||||
if (substitutor == null) {
|
||||
substitutor = checkReferenceList(candidate.getImplementsListTypes(), candidateSubstitutor, base, visited, manager);
|
||||
}
|
||||
return substitutor;
|
||||
}
|
||||
|
||||
private static PsiSubstitutor checkReferenceList(@NotNull PsiClassType[] types,
|
||||
@NotNull PsiSubstitutor candidateSubstitutor,
|
||||
@NotNull PsiClass base,
|
||||
@NotNull Set<PsiClass> set,
|
||||
@NotNull PsiManager manager) {
|
||||
for (final PsiClassType type : types) {
|
||||
final PsiType substitutedType = candidateSubstitutor.substitute(type);
|
||||
//if (!(substitutedType instanceof PsiClassType)) return null;
|
||||
LOG.assertTrue(substitutedType instanceof PsiClassType);
|
||||
|
||||
final JavaResolveResult result = ((PsiClassType)substitutedType).resolveGenerics();
|
||||
final PsiElement newCandidate = result.getElement();
|
||||
if (newCandidate != null) {
|
||||
final PsiSubstitutor substitutor = result.getSubstitutor();
|
||||
final PsiSubstitutor newSubstitutor = getSuperClassSubstitutorInner(base, (PsiClass)newCandidate, substitutor, set, manager);
|
||||
if (newSubstitutor != null) {
|
||||
return type.isRaw() ? JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createRawSubstitutor(base) : newSubstitutor;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* see JLS 5.6.2
|
||||
*/
|
||||
|
||||
@@ -20,45 +20,25 @@ import com.intellij.openapi.progress.ProgressIndicatorProvider;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.psi.util.JavaClassSupers;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class InheritanceImplUtil {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.InheritanceImplUtil");
|
||||
|
||||
public static boolean isInheritor(@NotNull final PsiClass candidateClass, @NotNull PsiClass baseClass, final boolean checkDeep) {
|
||||
if (baseClass instanceof PsiAnonymousClass) return false;
|
||||
if (baseClass instanceof PsiAnonymousClass || baseClass.getManager().areElementsEquivalent(baseClass, candidateClass)) return false;
|
||||
if (!checkDeep) {
|
||||
return isInheritor(candidateClass.getManager(), candidateClass, baseClass, false, null);
|
||||
}
|
||||
|
||||
if (hasObjectQualifiedName(candidateClass)) return false;
|
||||
if (hasObjectQualifiedName(baseClass)) return true;
|
||||
Map<PsiClass, Boolean> map = CachedValuesManager.
|
||||
getCachedValue(candidateClass, new CachedValueProvider<Map<PsiClass, Boolean>>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Result<Map<PsiClass, Boolean>> compute() {
|
||||
final Map<PsiClass, Boolean> map = ContainerUtil.createConcurrentWeakMap();
|
||||
return Result.create(map, candidateClass, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
|
||||
}
|
||||
});
|
||||
|
||||
Boolean computed = map.get(baseClass);
|
||||
if (computed == null) {
|
||||
computed = isInheritor(candidateClass.getManager(), candidateClass, baseClass, true, null);
|
||||
map.put(baseClass, computed);
|
||||
}
|
||||
return computed;
|
||||
GlobalSearchScope scope = candidateClass.getResolveScope();
|
||||
return JavaClassSupers.getInstance().getSuperClassSubstitutor(baseClass, candidateClass, scope, PsiSubstitutor.EMPTY) != null;
|
||||
}
|
||||
|
||||
public static boolean hasObjectQualifiedName(@NotNull PsiClass candidateClass) {
|
||||
|
||||
Reference in New Issue
Block a user