From b357f878a5980e9a0f69d3e62edbf4a446aa512d Mon Sep 17 00:00:00 2001 From: Mikhail Pyltsin Date: Wed, 1 Feb 2023 19:06:40 +0100 Subject: [PATCH] IJ-CR-102080 [java-highlighting] IDEA-311833. Support for nested classes GitOrigin-RevId: 5b6abb10000191f337228408363abc3bb3f6e64c --- .../impl/analysis/JavaGenericsUtil.java | 2 +- .../intellij/psi/util/TypeConversionUtil.java | 38 +++++++------------ ...yUncheckedWarningCastWithInnerClasses.java | 14 +++++++ .../daemon/GenericsHighlightingTest.java | 1 + 4 files changed, 29 insertions(+), 26 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/OnlyUncheckedWarningCastWithInnerClasses.java diff --git a/java/java-psi-api/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java b/java/java-psi-api/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java index be2f8a71eb1a..4e56bec0b86f 100644 --- a/java/java-psi-api/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java +++ b/java/java-psi-api/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java @@ -172,7 +172,7 @@ public final class JavaGenericsUtil { return true; } boolean operandHasWildcard = false; - for (PsiTypeParameter parameter : superClass.getTypeParameters()) { + for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(operandClass)) { PsiType operandParameterType = operandSubstitutor.substitute(parameter); if (operandParameterType instanceof PsiCapturedWildcardType) { operandHasWildcard = true; diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java index 13cda28192a0..30b24a0b335e 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java @@ -17,6 +17,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.util.SmartList; import com.intellij.util.containers.*; import org.intellij.lang.annotations.MagicConstant; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -25,6 +26,7 @@ import java.util.*; import java.util.function.BiPredicate; import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import static com.intellij.psi.CommonClassNames.*; @@ -1261,10 +1263,8 @@ public final class TypeConversionUtil { * } * */ + @ApiStatus.Experimental public static boolean existSuperPathWithoutRepetitiveArguments(PsiClass psiClass, PsiClass superClass) { - if (!psiClass.hasTypeParameters() || !superClass.hasTypeParameters()) { - return false; - } final Map map = CachedValuesManager.getCachedValue(psiClass, () -> { HashingStrategy strategy = new HashingStrategy() { @Override @@ -1280,11 +1280,6 @@ public final class TypeConversionUtil { if (o1 == null || o2 == null) { return false; } - - String qname1 = o1.getQualifiedName(); - if (qname1 != null) { - return qname1.equals(o2.getQualifiedName()); - } return o1.getManager().areElementsEquivalent(o1, o2); } }; @@ -1292,29 +1287,22 @@ public final class TypeConversionUtil { final Object dummyValue = new Object(); ArrayDeque queue = new ArrayDeque<>(); Function> collectPsiTypeParameters = aClass -> { - PsiTypeParameter[] typeParameters = aClass.getTypeParameters(); - return Arrays.stream(typeParameters) + return StreamSupport.stream(PsiUtil.typeParametersIterable(aClass).spliterator(), false) .filter(t -> t.getBounds().length == 0) .collect(Collectors.toSet()); }; BiPredicate, PsiClassType> isPossibleWay = (sourceTypeParameters, superType) -> { - Map count = new HashMap<>(); - PsiType[] superTypeParameters = superType.getParameters(); - if (superTypeParameters.length == 0) { + Map count = new HashMap<>(); + PsiClass resolved = superType.resolve(); + if (resolved == null) { return false; } - for (PsiType type : superTypeParameters) { - if (!(type instanceof PsiClassType)) { - continue; - } - PsiClassType currentClassType = (PsiClassType)type; - JvmTypeResolveResult resolvedType = currentClassType.resolveType(); - if (resolvedType == null) { - continue; - } - JvmTypeDeclaration declaration = resolvedType.getDeclaration(); - if (declaration instanceof PsiTypeParameter && sourceTypeParameters.contains(declaration)) { - count.merge((PsiTypeParameter)declaration, 1, (oldValue, newValue) -> oldValue + newValue); + Set sourceTypes = sourceTypeParameters.stream().map(t -> PsiSubstitutor.EMPTY.substitute(t)) + .collect(Collectors.toSet()); + Map substitutionMap = superType.resolveGenerics().getSubstitutor().getSubstitutionMap(); + for (PsiType type : substitutionMap.values()) { + if (sourceTypes.contains(type)) { + count.merge(type, 1, (oldValue, newValue) -> oldValue + newValue); } } return ContainerUtil.and(count.values(), t -> t <= 1); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/OnlyUncheckedWarningCastWithInnerClasses.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/OnlyUncheckedWarningCastWithInnerClasses.java new file mode 100644 index 000000000000..57dcd2ae10a3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/OnlyUncheckedWarningCastWithInnerClasses.java @@ -0,0 +1,14 @@ + +public class OnlyUncheckedWarningCastWithInnerClasses { + public abstract class Mapper extends UnaryOperator { + } + public abstract class UnaryOperator implements Function {} + + void test(OnlyUncheckedWarningCastWithInnerClasses.UnaryOperator op) { + OnlyUncheckedWarningCastWithInnerClasses.Mapper op1 = (OnlyUncheckedWarningCastWithInnerClasses.Mapper) op; + } +} + +interface Function { + R apply(T t); +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/GenericsHighlightingTest.java index fe3a8998e65c..8083243331c6 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/GenericsHighlightingTest.java @@ -451,5 +451,6 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIDEA139214() { doTest(LanguageLevel.JDK_1_6, JavaSdkVersion.JDK_1_8, false); } public void testUnboxingWildcards() { doTest(LanguageLevel.JDK_1_6, JavaSdkVersion.JDK_1_8, false); } public void testOnlyUncheckedWarningWithCast(){doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, true);} + public void testOnlyUncheckedWarningCastWithInnerClasses(){doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, true);} public void testOnlyUncheckedWarningCastWithDuplicatedArguments(){doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, true);} } \ No newline at end of file