use of com.intellij.refactoring.typeMigration.usageInfo.OverriddenUsageInfo in project intellij-community by JetBrains.
the class TypeMigrationLabeler method addMigrationRoot.
boolean addMigrationRoot(PsiElement element, PsiType type, final PsiElement place, boolean alreadyProcessed, final boolean isContraVariantPosition, final boolean userDefinedType) {
if (type.equals(PsiType.NULL)) {
return false;
}
final PsiElement resolved = Util.normalizeElement(element);
if (!canBeRoot(resolved, myRules.getSearchScope())) {
return false;
}
final PsiType originalType = getElementType(resolved);
LOG.assertTrue(originalType != null);
type = userDefinedType ? type : TypeEvaluator.substituteType(type, originalType, isContraVariantPosition);
if (!userDefinedType) {
final Set<PsiTypeParameter> collector;
if (type instanceof PsiClassType) {
collector = type.accept(new PsiExtendedTypeVisitor<Set<PsiTypeParameter>>() {
private final Set<PsiTypeParameter> myResult = new HashSet<>();
@Override
public Set<PsiTypeParameter> visitClassType(PsiClassType classType) {
super.visitClassType(classType);
final PsiClass resolved = classType.resolve();
if (resolved instanceof PsiTypeParameter) {
myResult.add((PsiTypeParameter) resolved);
}
return myResult;
}
});
} else {
collector = Collections.emptySet();
}
if (typeContainsTypeParameters(originalType, collector))
return false;
}
if (type instanceof PsiCapturedWildcardType) {
return false;
}
if (resolved instanceof PsiMethod) {
final PsiMethod method = ((PsiMethod) resolved);
final PsiClass containingClass = method.getContainingClass();
if (containingClass instanceof PsiAnonymousClass) {
final HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature();
final List<HierarchicalMethodSignature> superSignatures = signature.getSuperSignatures();
if (!superSignatures.isEmpty()) {
final HierarchicalMethodSignature superSignature = superSignatures.get(0);
final PsiSubstitutor substitutor = superSignature.getSubstitutor();
if (!substitutor.getSubstitutionMap().isEmpty()) {
final PsiMethod superMethod = superSignature.getMethod();
final PsiType superReturnType = superMethod.getReturnType();
if (superReturnType instanceof PsiClassType) {
final PsiClass resolvedClass = ((PsiClassType) superReturnType).resolve();
if (resolvedClass instanceof PsiTypeParameter) {
final PsiType expectedReturnType = substitutor.substitute((PsiTypeParameter) resolvedClass);
if (Comparing.equal(expectedReturnType, method.getReturnType())) {
final PsiClassType baseClassType = ((PsiAnonymousClass) containingClass).getBaseClassType();
final PsiClassType.ClassResolveResult result = baseClassType.resolveGenerics();
final PsiClass anonymousBaseClass = result.getElement();
final PsiSubstitutor superHierarchySubstitutor = TypeConversionUtil.getClassSubstitutor(superMethod.getContainingClass(), anonymousBaseClass, PsiSubstitutor.EMPTY);
final PsiType maybeTypeParameter = superHierarchySubstitutor.substitute((PsiTypeParameter) resolvedClass);
if (maybeTypeParameter instanceof PsiClassType && ((PsiClassType) maybeTypeParameter).resolve() instanceof PsiTypeParameter) {
final PsiSubstitutor newSubstitutor = result.getSubstitutor().put((PsiTypeParameter) ((PsiClassType) maybeTypeParameter).resolve(), type);
addRoot(new TypeMigrationUsageInfo(((PsiAnonymousClass) containingClass).getBaseClassReference().getParameterList()), new PsiImmediateClassType(anonymousBaseClass, newSubstitutor), place, alreadyProcessed);
}
}
}
}
}
}
}
final PsiMethod[] methods = OverridingMethodsSearch.search(method).toArray(PsiMethod.EMPTY_ARRAY);
final OverriderUsageInfo[] overriders = new OverriderUsageInfo[methods.length];
for (int i = -1; i < methods.length; i++) {
final TypeMigrationUsageInfo m;
if (i < 0) {
final OverriddenUsageInfo overriddenUsageInfo = new OverriddenUsageInfo(method);
m = overriddenUsageInfo;
final String newMethodName = isMethodNameCanBeChanged(method);
if (newMethodName != null) {
final MigrateGetterNameSetting migrateGetterNameSetting = myRules.getConversionSettings(MigrateGetterNameSetting.class);
migrateGetterNameSetting.askUserIfNeed(overriddenUsageInfo, newMethodName, myTypeEvaluator.getType(myCurrentRoot));
}
} else {
overriders[i] = new OverriderUsageInfo(methods[i], method);
m = overriders[i];
}
alreadyProcessed = addRoot(m, type, place, alreadyProcessed);
}
return !alreadyProcessed;
} else if (resolved instanceof PsiParameter && ((PsiParameter) resolved).getDeclarationScope() instanceof PsiMethod) {
final PsiMethod method = (PsiMethod) ((PsiParameter) resolved).getDeclarationScope();
final int index = method.getParameterList().getParameterIndex(((PsiParameter) resolved));
final PsiMethod[] methods = OverridingMethodsSearch.search(method).toArray(PsiMethod.EMPTY_ARRAY);
final OverriderUsageInfo[] overriders = new OverriderUsageInfo[methods.length];
final OverriddenUsageInfo overriddenUsageInfo = new OverriddenUsageInfo(method.getParameterList().getParameters()[index]);
for (int i = -1; i < methods.length; i++) {
final PsiMethod m = i < 0 ? method : methods[i];
final PsiParameter p = m.getParameterList().getParameters()[index];
final TypeMigrationUsageInfo paramUsageInfo;
if (i < 0) {
paramUsageInfo = overriddenUsageInfo;
} else {
overriders[i] = new OverriderUsageInfo(p, method);
paramUsageInfo = overriders[i];
}
alreadyProcessed = addRoot(paramUsageInfo, type, place, alreadyProcessed);
}
return !alreadyProcessed;
} else {
return !addRoot(new TypeMigrationUsageInfo(resolved), type, place, alreadyProcessed);
}
}
Aggregations