mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 04:51:24 +07:00
[java-intentions] IDEA-299075 Additional fixes
1. Map to supertype if expected is a supertype for actual 2. Do not suggest the replacement when type parameter bounds are violated GitOrigin-RevId: 7784f18fcdb7fdd9541e5c92a211808475f62054
This commit is contained in:
committed by
intellij-monorepo-bot
parent
74e77b300e
commit
41cbe227c2
@@ -12,10 +12,7 @@ import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.siyeh.ig.psiutils.MethodCallUtils;
|
||||
@@ -221,6 +218,10 @@ class AdaptExpressionTypeFixUtil {
|
||||
if (methodClass == null) return null;
|
||||
if (methodClass instanceof PsiTypeParameter) {
|
||||
if (!expected.equals(actual) && !(expected instanceof PsiPrimitiveType)) {
|
||||
for (PsiClassType superType : methodClass.getSuperTypes()) {
|
||||
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY.put((PsiTypeParameter)methodClass, expected);
|
||||
if (!substitutor.substitute(superType).isAssignableFrom(expected)) return null;
|
||||
}
|
||||
return Map.entry((PsiTypeParameter)methodClass, expected);
|
||||
}
|
||||
return null;
|
||||
@@ -228,8 +229,12 @@ class AdaptExpressionTypeFixUtil {
|
||||
if (!(expected instanceof PsiClassType) || !(actual instanceof PsiClassType)) return null;
|
||||
PsiClass expectedClass = ((PsiClassType)expected).resolve();
|
||||
PsiClass actualClass = ((PsiClassType)actual).resolve();
|
||||
if (expectedClass == null || actualClass == null) return null;
|
||||
if (!expectedClass.isEquivalentTo(actualClass) || !expectedClass.isEquivalentTo(methodClass)) return null;
|
||||
if (expectedClass == null || actualClass == null || !actualClass.isEquivalentTo(methodClass)) return null;
|
||||
if (!expectedClass.isEquivalentTo(actualClass)) {
|
||||
methodType = trySubstitute(methodType, expectedClass);
|
||||
actual = trySubstitute(actual, expectedClass);
|
||||
if (methodType == null || actual == null) return null;
|
||||
}
|
||||
PsiType[] methodTypeParameters = ((PsiClassType)methodType).getParameters();
|
||||
PsiType[] expectedTypeParameters = ((PsiClassType)expected).getParameters();
|
||||
PsiType[] actualTypeParameters = ((PsiClassType)actual).getParameters();
|
||||
@@ -250,6 +255,16 @@ class AdaptExpressionTypeFixUtil {
|
||||
return existing;
|
||||
}
|
||||
|
||||
private static @Nullable PsiType trySubstitute(@NotNull PsiType type, @NotNull PsiClass superClass) {
|
||||
if (!(type instanceof PsiClassType)) return null;
|
||||
PsiClassType.ClassResolveResult result = ((PsiClassType)type).resolveGenerics();
|
||||
PsiClass psiClass = result.getElement();
|
||||
if (psiClass == null) return null;
|
||||
if (!psiClass.isInheritor(superClass, true)) return null;
|
||||
PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, psiClass, result.getSubstitutor());
|
||||
return JavaPsiFacade.getElementFactory(superClass.getProject()).createType(superClass, substitutor);
|
||||
}
|
||||
|
||||
private static @Nullable PsiTypeParameter getSoleTypeParameter(@Nullable PsiType type) {
|
||||
if (!(type instanceof PsiClassType)) return null;
|
||||
PsiType[] parameters = ((PsiClassType)type).getParameters();
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Replace 'E2.class' with 'E1.class'" "true-preview"
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class Demo {
|
||||
void test2() {
|
||||
Set<E1> set = EnumSet.allOf(E1.class);
|
||||
}
|
||||
|
||||
enum E1 {}
|
||||
enum E2 {}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Replace 'E2.class' with 'E1.class'" "true-preview"
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class Demo {
|
||||
void test2() {
|
||||
Set<E1> set = EnumSet.<caret>allOf(E2.class);
|
||||
}
|
||||
|
||||
enum E1 {}
|
||||
enum E2 {}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// "Replace 'E2.class' with 'String.class'" "false"
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class Demo {
|
||||
void test2() {
|
||||
Set<String> set2 = EnumSet.<caret>allOf(E2.class);
|
||||
}
|
||||
|
||||
enum E2 {}
|
||||
}
|
||||
Reference in New Issue
Block a user