GenericsUtil#simplifyExtendsFinalClass (IDEA-24201)

GitOrigin-RevId: 758c1e9c3be3c016093d84bf0617ef0b030161b1
This commit is contained in:
Tagir Valeev
2020-06-26 07:29:05 +03:00
committed by intellij-monorepo-bot
parent 14fa0849cd
commit 2d1a6a067b
4 changed files with 70 additions and 1 deletions
@@ -1232,7 +1232,7 @@ public class ExpectedTypesProvider {
LOG.error("Vararg parameter with non-array type. Class=" + parameter.getClass() + "; type=" + parameter.getType());
}
}
PsiType parameterType = substitutor.substitute(type);
PsiType parameterType = GenericsUtil.simplifyExtendsFinalClass(substitutor.substitute(type));
if (parameterType instanceof PsiCapturedWildcardType) {
parameterType = ((PsiCapturedWildcardType)parameterType).getWildcard();
}
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.*;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
@@ -635,4 +636,50 @@ public class GenericsUtil {
}
return false;
}
/**
* @param type
* @return type where "? extends FinalClass" components are replaced with "FinalClass" components.
*/
public static @NotNull PsiType simplifyExtendsFinalClass(@NotNull PsiType type) {
return type.accept(new PsiTypeVisitor<PsiType>() {
@Override
public PsiType visitType(@NotNull PsiType type) {
return type;
}
@Override
public PsiType visitArrayType(@NotNull PsiArrayType arrayType) {
return arrayType.getComponentType().accept(this).createArrayType().annotate(arrayType.getAnnotationProvider());
}
@Override
public PsiType visitClassType(@NotNull PsiClassType classType) {
PsiType[] parameters = classType.getParameters();
if (parameters.length == 0) return classType;
PsiClass target = classType.resolve();
if (target == null) return classType;
parameters = ContainerUtil.map2Array(parameters, PsiType.class, p -> p.accept(this));
return JavaPsiFacade.getElementFactory(target.getProject())
.createType(target, parameters).annotate(classType.getAnnotationProvider());
}
@Override
public PsiType visitWildcardType(@NotNull PsiWildcardType wildcardType) {
PsiClassType bound = ObjectUtils.tryCast(wildcardType.getBound(), PsiClassType.class);
if (bound != null) {
bound = (PsiClassType)bound.accept(this);
if (wildcardType.isExtends()) {
PsiClass boundClass = PsiUtil.resolveClassInClassTypeOnly(bound);
if (boundClass != null && boundClass.hasModifierProperty(PsiModifier.FINAL)) {
return bound;
}
return PsiWildcardType.createExtends(wildcardType.getManager(), bound);
}
return PsiWildcardType.createSuper(wildcardType.getManager(), bound);
}
return wildcardType;
}
});
}
}
@@ -0,0 +1,13 @@
// "Create method 'getPreloadKeys'" "true"
import java.util.*;
class X {
void test() {
Set<String> keys = new HashSet<String>();
keys.addAll(getPreloadKeys());
}
private Collection<String> getPreloadKeys() {
return null;
}
}
@@ -0,0 +1,9 @@
// "Create method 'getPreloadKeys'" "true"
import java.util.*;
class X {
void test() {
Set<String> keys = new HashSet<String>();
keys.addAll(<caret>getPreloadKeys());
}
}