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 6c4e7876128a..4775d872a5a4 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 @@ -1079,10 +1079,9 @@ public class GenericsHighlightUtil { if (((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.STATIC)) return null; PsiClass containingClass = ((PsiMember)element).getContainingClass(); if (containingClass != null && PsiUtil.isRawSubstitutor(containingClass, resolveResult.getSubstitutor())) { - final String message; - message = element instanceof PsiClass - ? JavaErrorMessages.message("generics.type.arguments.on.raw.type") - : JavaErrorMessages.message("generics.type.arguments.on.raw.method"); + final String message = element instanceof PsiClass + ? JavaErrorMessages.message("generics.type.arguments.on.raw.type") + : JavaErrorMessages.message("generics.type.arguments.on.raw.method"); return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, refParamList, message); } @@ -1192,33 +1191,5 @@ public class GenericsHighlightUtil { } return null; } - - public static HighlightInfo checkTopLevelMethodCallIntersectionTypeMaximalUpperBound(PsiMethodCallExpression methodCall, - PsiReferenceExpression expression) { - PsiElement parent = methodCall.getParent(); - if (parent instanceof PsiExpression) return null; - PsiType type = expression.getType(); - if (!(type instanceof PsiIntersectionType)) { - return null; - } - PsiType[] conjuncts = ((PsiIntersectionType)type).getConjuncts(); - PsiType lub = conjuncts[0]; - for (int i = 1; i < conjuncts.length; i++) { - PsiType conjunct = conjuncts[i]; - PsiType bound = GenericsUtil.getLeastUpperBound(lub, conjunct, methodCall.getManager()); - if (bound == null || !TypeConversionUtil.isAssignable(lub, bound) || !TypeConversionUtil.isAssignable(conjunct, bound)) { - PsiMethod method = methodCall.resolveMethod(); - if (method == null) return null; - String message = JavaErrorMessages.message("failed.to.find.unique.maximal.instance", - HighlightUtil.formatMethod(method), - HighlightUtil.formatType(lub), HighlightUtil.formatType(conjunct)); - - - return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, expression, message); - } - lub = bound; - } - return null; - } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index 34b34e1344d0..aabd791320d6 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -548,7 +548,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh myHolder.add(HighlightNamesUtil.highlightMethodName(method, element, false)); } } - catch (IndexNotReadyException e) { + catch (IndexNotReadyException ignored) { } } else if (parent instanceof PsiImportStatement && ((PsiImportStatement)parent).isOnDemand()) { @@ -772,7 +772,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh if (parent instanceof PsiMethodCallExpression && (methodCall = (PsiMethodCallExpression)parent).getMethodExpression() == expression) { myHolder.addAll(HighlightMethodUtil.checkMethodCall(methodCall, myResolveHelper)); - if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkTopLevelMethodCallIntersectionTypeMaximalUpperBound(methodCall, expression)); } } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java index d4c8f8c19e44..67abae3ba884 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java @@ -123,13 +123,12 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { return processor.getCandidates(); } - private static Pair inferTypeForMethodTypeParameterInner( - final PsiTypeParameter typeParameter, - final PsiParameter[] parameters, - PsiExpression[] arguments, - PsiSubstitutor partialSubstitutor, - PsiElement parent, - final boolean forCompletion) { + private static Pair inferTypeForMethodTypeParameterInner(final PsiTypeParameter typeParameter, + final PsiParameter[] parameters, + PsiExpression[] arguments, + PsiSubstitutor partialSubstitutor, + PsiElement parent, + final boolean forCompletion) { PsiWildcardType wildcardToCapture = null; PsiType lowerBound = PsiType.NULL; PsiType upperBound = PsiType.NULL; @@ -418,50 +417,47 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { isContraVariantPosition, languageLevel); } - if (param instanceof PsiClassType) { - PsiManager manager = typeParam.getManager(); - if (arg instanceof PsiPrimitiveType) { - arg = ((PsiPrimitiveType)arg).getBoxedType(typeParam); - if (arg == null) return null; - } - - JavaResolveResult paramResult = ((PsiClassType)param).resolveGenerics(); - PsiClass paramClass = (PsiClass)paramResult.getElement(); - if (typeParam == paramClass) { - if (arg == null || - arg.getDeepComponentType() instanceof PsiPrimitiveType || - arg instanceof PsiIntersectionType || - PsiUtil.resolveClassInType(arg) != null) { - PsiType bound = intersectAllExtends(typeParam, arg); - return new Pair(bound, ConstraintType.SUPERTYPE); - } - return null; - } - if (paramClass == null) return null; - - if (arg instanceof PsiClassType) { - JavaResolveResult argResult = ((PsiClassType)arg).resolveGenerics(); - PsiClass argClass = (PsiClass)argResult.getElement(); - if (argClass == null) return null; - - PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); - PsiType patternType = factory.createType(typeParam); - if (isContraVariantPosition) { - PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(paramClass, argClass, argResult.getSubstitutor()); - if (substitutor == null) return null; - arg = factory.createType(paramClass, substitutor, languageLevel); - } - else { - PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(argClass, paramClass, paramResult.getSubstitutor()); - if (substitutor == null) return null; - param = factory.createType(argClass, substitutor, languageLevel); - } - - return getSubstitutionForTypeParameterInner(param, arg, patternType, ConstraintType.SUPERTYPE, 0); - } + if (!(param instanceof PsiClassType)) return null; + PsiManager manager = typeParam.getManager(); + if (arg instanceof PsiPrimitiveType) { + arg = ((PsiPrimitiveType)arg).getBoxedType(typeParam); + if (arg == null) return null; } - return null; + JavaResolveResult paramResult = ((PsiClassType)param).resolveGenerics(); + PsiClass paramClass = (PsiClass)paramResult.getElement(); + if (typeParam == paramClass) { + if (arg == null || + arg.getDeepComponentType() instanceof PsiPrimitiveType || + arg instanceof PsiIntersectionType || + PsiUtil.resolveClassInType(arg) != null) { + PsiType bound = intersectAllExtends(typeParam, arg); + return new Pair(bound, ConstraintType.SUPERTYPE); + } + return null; + } + if (paramClass == null) return null; + + if (!(arg instanceof PsiClassType)) return null; + + JavaResolveResult argResult = ((PsiClassType)arg).resolveGenerics(); + PsiClass argClass = (PsiClass)argResult.getElement(); + if (argClass == null) return null; + + PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); + PsiType patternType = factory.createType(typeParam); + if (isContraVariantPosition) { + PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(paramClass, argClass, argResult.getSubstitutor()); + if (substitutor == null) return null; + arg = factory.createType(paramClass, substitutor, languageLevel); + } + else { + PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(argClass, paramClass, paramResult.getSubstitutor()); + if (substitutor == null) return null; + param = factory.createType(argClass, substitutor, languageLevel); + } + + return getSubstitutionForTypeParameterInner(param, arg, patternType, ConstraintType.SUPERTYPE, 0); } private static PsiType intersectAllExtends(PsiTypeParameter typeParam, PsiType arg) { @@ -594,10 +590,10 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { } private static Pair inferMethodTypeParameterFromParent(PsiElement parent, - PsiMethodCallExpression methodCall, - final PsiTypeParameter typeParameter, - PsiSubstitutor substitutor, - final boolean forCompletion) { + PsiMethodCallExpression methodCall, + final PsiTypeParameter typeParameter, + PsiSubstitutor substitutor, + final boolean forCompletion) { Pair constraint = null; PsiType expectedType = null; @@ -633,6 +629,17 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { returnType = ((PsiMethod)typeParameter.getOwner()).getReturnType(); constraint = getSubstitutionForTypeParameterConstraint(typeParameter, returnType, expectedType, false, PsiUtil.getLanguageLevel(parent)); + + if (constraint != null) { + PsiType guess = constraint.getFirst(); + if (guess != null && !guess.equals(PsiType.NULL) && constraint.getSecond() == ConstraintType.SUPERTYPE && guess instanceof PsiIntersectionType) { + for (PsiType conjuct : ((PsiIntersectionType)guess).getConjuncts()) { + if (!conjuct.isAssignableFrom(expectedType)) { + return FAILED_INFERENCE; + } + } + } + } } final Pair result; diff --git a/resources-en/src/messages/JavaErrorMessages.properties b/resources-en/src/messages/JavaErrorMessages.properties index fea81d6a3e6f..873273529801 100644 --- a/resources-en/src/messages/JavaErrorMessages.properties +++ b/resources-en/src/messages/JavaErrorMessages.properties @@ -288,7 +288,6 @@ javadoc.value.field.with.initializer.required=@value tag must reference a field expected.identifier=Identifier expected expected.comma.or.semicolon=',' or ';' expected unexpected.token=Unexpected token -unexpected.eof=Unexpected end of file expected.class.or.interface='class' or 'interface' expected expected.identifier.or.type=Identifier or type expected expected.rbracket=']' expected @@ -335,4 +334,4 @@ illegal.initializer=Illegal initializer for ''{0}'' class.cannot.inherit.from.its.type.parameter=Class cannot inherit from its type parameter cannot.resolve.package=Cannot resolve package {0} override.not.allowed.in.interfaces=@Override is not allowed when implementing interface method -failed.to.find.unique.maximal.instance=Cannot determine type parameters for ''{0}'': no unique maximal instance of upper bounds ''{1}'' and ''{2}'' +