diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java index d0aa4f960005..2cbde604dc7d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java @@ -27,6 +27,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.JavaVersionService; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; @@ -59,49 +60,24 @@ public class GenericsHighlightUtil { public static HighlightInfo checkInferredTypeArguments(PsiMethod genericMethod, PsiMethodCallExpression call, PsiSubstitutor substitutor) { - PsiTypeParameter[] typeParameters = genericMethod.getTypeParameters(); - for (PsiTypeParameter typeParameter : typeParameters) { - PsiType substituted = substitutor.substitute(typeParameter); - if (substituted == null) return null; - substituted = PsiUtil.captureToplevelWildcards(substituted, call); - PsiClassType[] extendsTypes = typeParameter.getExtendsListTypes(); - for (PsiClassType type : extendsTypes) { - PsiType extendsType = substitutor.substitute(type); - if (substituted instanceof PsiWildcardType) { - if (((PsiWildcardType)substituted).isSuper()) { - continue; - } - final PsiType extendsBound = ((PsiWildcardType)substituted).getExtendsBound(); - if (TypeConversionUtil.erasure(extendsType).equals(TypeConversionUtil.erasure(extendsBound))) { - if (extendsBound instanceof PsiClassType) { - PsiType[] parameters = ((PsiClassType)extendsBound).getParameters(); - if (parameters.length == 1) { - PsiType argType = parameters[0]; - if (argType instanceof PsiCapturedWildcardType) { - argType = ((PsiCapturedWildcardType)argType).getWildcard(); - } - if (argType instanceof PsiWildcardType && !((PsiWildcardType)argType).isBounded()) continue; - } - } - } - } - if (!TypeConversionUtil.isAssignable(extendsType, substituted, false)) { - PsiClass boundClass = extendsType instanceof PsiClassType ? ((PsiClassType)extendsType).resolve() : null; + final Pair inferredTypeArgument = + GenericsUtil.findTypeParameterWithBoundError(genericMethod.getTypeParameters(), substitutor, call, false); + if (inferredTypeArgument != null) { + final PsiType extendsType = inferredTypeArgument.second; + final PsiTypeParameter typeParameter = inferredTypeArgument.first; + PsiClass boundClass = extendsType instanceof PsiClassType ? ((PsiClassType)extendsType).resolve() : null; - @NonNls String messageKey = boundClass == null || typeParameter.isInterface() == boundClass.isInterface() - ? "generics.inferred.type.for.type.parameter.is.not.within.its.bound.extend" - : "generics.inferred.type.for.type.parameter.is.not.within.its.bound.implement"; + @NonNls String messageKey = boundClass == null || typeParameter.isInterface() == boundClass.isInterface() + ? "generics.inferred.type.for.type.parameter.is.not.within.its.bound.extend" + : "generics.inferred.type.for.type.parameter.is.not.within.its.bound.implement"; - String description = JavaErrorMessages.message( - messageKey, - HighlightUtil.formatClass(typeParameter), - JavaHighlightUtil.formatType(extendsType), - JavaHighlightUtil.formatType(substituted) - ); - - return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(call).descriptionAndTooltip(description).create(); - } - } + String description = JavaErrorMessages.message( + messageKey, + HighlightUtil.formatClass(typeParameter), + JavaHighlightUtil.formatType(extendsType), + JavaHighlightUtil.formatType(substitutor.substitute(typeParameter)) + ); + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(call).descriptionAndTooltip(description).create(); } return null; diff --git a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java index c09660c4af08..4132f2389d43 100644 --- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java @@ -249,10 +249,17 @@ public class GenericsUtil { final PsiSubstitutor substitutor, final PsiElement context, final boolean allowUncheckedConversion) { + return findTypeParameterWithBoundError(typeParams, substitutor, context, allowUncheckedConversion) == null; + } + + public static Pair findTypeParameterWithBoundError(final PsiTypeParameter[] typeParams, + final PsiSubstitutor substitutor, + final PsiElement context, + final boolean allowUncheckedConversion) { nextTypeParam: for (PsiTypeParameter typeParameter : typeParams) { PsiType substituted = substitutor.substitute(typeParameter); - if (substituted == null) return true; + if (substituted == null) return null; substituted = PsiUtil.captureToplevelWildcards(substituted, context); PsiClassType[] extendsTypes = typeParameter.getExtendsListTypes(); @@ -263,7 +270,7 @@ public class GenericsUtil { continue; } final PsiType extendsBound = ((PsiWildcardType)substituted).getExtendsBound(); - if (TypeConversionUtil.erasure(extendsType).equals(TypeConversionUtil.erasure(extendsBound))) { + if (Comparing.equal(TypeConversionUtil.erasure(extendsType), TypeConversionUtil.erasure(extendsBound))) { if (extendsBound instanceof PsiClassType) { if (acceptExtendsBound((PsiClassType)extendsBound, 0)) continue; } else if (extendsBound instanceof PsiIntersectionType) { @@ -275,12 +282,12 @@ public class GenericsUtil { } } } - if (!TypeConversionUtil.isAssignable(extendsType, substituted, allowUncheckedConversion)) { - return false; + if (extendsType != null && !TypeConversionUtil.isAssignable(extendsType, substituted, allowUncheckedConversion)) { + return Pair.create(typeParameter, extendsType); } } } - return true; + return null; } private static boolean acceptExtendsBound(PsiClassType extendsBound, int depth) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEADEV15534.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEADEV15534.java index d4042a575841..0fc7639c49c2 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEADEV15534.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEADEV15534.java @@ -18,7 +18,7 @@ class SortTest> implements Comparable> { list.add(t1); SortTest t2 = new SortTest(0); list.add(t2); - Collections.sort(list); + Collections.sort(list); t1.compareTo(t2); //this should be OK