diff --git a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java index 58c9755830e5..622714c6dd61 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java @@ -18,7 +18,6 @@ package com.intellij.psi.util; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; import com.intellij.psi.*; -import gnu.trove.THashSet; import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -174,9 +173,9 @@ public class MethodSignatureUtil { PsiClass superClassCandidate = superMethodCandidate.getContainingClass(); PsiClass derivedClass = derivedMethod.getContainingClass(); if (derivedClass == null || superClassCandidate == null) return false; - final PsiSubstitutor superSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(superClassCandidate, derivedClass, - PsiSubstitutor.EMPTY, new THashSet()); - if (superSubstitutor == null) return false; + if (!derivedClass.isInheritor(superClassCandidate, true)) return false; + final PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClassCandidate, derivedClass, + PsiSubstitutor.EMPTY); final MethodSignature superSignature = superMethodCandidate.getSignature(superSubstitutor); final MethodSignature derivedSignature = derivedMethod.getSignature(PsiSubstitutor.EMPTY); return isSubsignature(superSignature, derivedSignature); 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 f3e28b9e2dd0..477a74e64b2e 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 @@ -128,9 +128,6 @@ public class TypeConversionUtil { return boxedType != null && areTypesConvertible(boxedType, toType); } if (!fromIsPrimitive) { - // 5.5. Casting Contexts - if ((fromTypeRank == SHORT_RANK || fromTypeRank == BYTE_RANK) && toTypeRank == CHAR_RANK) return false; - if (fromType instanceof PsiClassType) { if (languageLevel == null) { languageLevel = ((PsiClassType)fromType).getLanguageLevel(); @@ -165,7 +162,7 @@ public class TypeConversionUtil { /** * see JLS 5.1.5, JLS3 5.1.6 */ - private static boolean isNarrowingReferenceConversionAllowed(@NotNull PsiType fromType, @NotNull PsiType toType) { + private static boolean isNarrowingReferenceConversionAllowed(PsiType fromType, PsiType toType) { if (toType instanceof PsiPrimitiveType || fromType instanceof PsiPrimitiveType) return fromType.equals(toType); //Done with primitives if (toType instanceof PsiDiamondType || fromType instanceof PsiDiamondType) return false; @@ -283,57 +280,60 @@ public class TypeConversionUtil { return false; } } - else if (!toClass.isInterface()) { - if (!toClass.hasModifierProperty(PsiModifier.FINAL)) { - return checkSuperTypesWithDifferentTypeArguments(fromResult, toClass, manager, toResult.getSubstitutor(), null, languageLevel); - } - else { - PsiSubstitutor toSubstitutor = getMaybeSuperClassSubstitutor(fromClass, toClass, toResult.getSubstitutor(), - new THashSet()); - return toSubstitutor != null && areSameArgumentTypes(fromClass, fromResult.getSubstitutor(), toSubstitutor); - } - } - else if (languageLevel.compareTo(LanguageLevel.JDK_1_5) < 0) { - //In jls2 check for method in both interfaces with the same signature but different return types. - Collection fromClassMethodSignatures = fromClass.getVisibleSignatures(); - Collection toClassMethodSignatures = toClass.getVisibleSignatures(); - - for (HierarchicalMethodSignature fromMethodSignature : fromClassMethodSignatures) { - for (HierarchicalMethodSignature toMethodSignature : toClassMethodSignatures) { - if (fromMethodSignature.equals(toMethodSignature)) { - final PsiType fromClassReturnType = fromMethodSignature.getMethod().getReturnType(); - final PsiType toClassReturnType = toMethodSignature.getMethod().getReturnType(); - if (fromClassReturnType != null - && toClassReturnType != null - && !fromClassReturnType.equals(toClassReturnType)) { - return false; - } - } + else { + if (!toClass.isInterface()) { + if (!toClass.hasModifierProperty(PsiModifier.FINAL)) { + return checkSuperTypesWithDifferentTypeArguments(fromResult, toClass, manager, toResult.getSubstitutor(), null, languageLevel); + } + else { + if (!toClass.isInheritor(fromClass, true)) return false; + PsiSubstitutor toSubstitutor = getSuperClassSubstitutor(fromClass, toClass, toResult.getSubstitutor()); + return areSameArgumentTypes(fromClass, fromResult.getSubstitutor(), toSubstitutor); } } - return true; - } - else { - //In jls3 check for super interface with distinct type arguments - PsiClassType.ClassResolveResult baseResult; - PsiClass derived; - PsiSubstitutor derivedSubstitutor; - if (toClass.isInheritor(fromClass, true)) { - baseResult = fromResult; - derived = toClass; - derivedSubstitutor = toResult.getSubstitutor(); - } else { - baseResult = toResult; - derived = fromClass; - derivedSubstitutor = fromResult.getSubstitutor(); + if (languageLevel.compareTo(LanguageLevel.JDK_1_5) < 0) { + //In jls2 check for method in both interfaces with the same signature but different return types. + Collection fromClassMethodSignatures = fromClass.getVisibleSignatures(); + Collection toClassMethodSignatures = toClass.getVisibleSignatures(); + + for (HierarchicalMethodSignature fromMethodSignature : fromClassMethodSignatures) { + for (HierarchicalMethodSignature toMethodSignature : toClassMethodSignatures) { + if (fromMethodSignature.equals(toMethodSignature)) { + final PsiType fromClassReturnType = fromMethodSignature.getMethod().getReturnType(); + final PsiType toClassReturnType = toMethodSignature.getMethod().getReturnType(); + if (fromClassReturnType != null + && toClassReturnType != null + && !fromClassReturnType.equals(toClassReturnType)) { + return false; + } + } + } + } + return true; + } + else { + //In jls3 check for super interface with distinct type arguments + PsiClassType.ClassResolveResult baseResult; + PsiClass derived; + PsiSubstitutor derivedSubstitutor; + if (toClass.isInheritor(fromClass, true)) { + baseResult = fromResult; + derived = toClass; + derivedSubstitutor = toResult.getSubstitutor(); + } + else { + baseResult = toResult; + derived = fromClass; + derivedSubstitutor = fromResult.getSubstitutor(); + } + return checkSuperTypesWithDifferentTypeArguments(baseResult, derived, manager, derivedSubstitutor, null, languageLevel); + } } - return checkSuperTypesWithDifferentTypeArguments(baseResult, derived, manager, derivedSubstitutor, null, languageLevel); } } - @NotNull - private static PsiClassType obtainSafeSuperType(@NotNull PsiTypeParameter typeParameter) { + private static PsiClassType obtainSafeSuperType(final PsiTypeParameter typeParameter) { final PsiClassType superType = typeParameter.getSuperTypes()[0]; final PsiClassType.ClassResolveResult result = superType.resolveGenerics(); final PsiClass superClass = result.getElement(); @@ -344,12 +344,12 @@ public class TypeConversionUtil { return superType; } - private static boolean checkSuperTypesWithDifferentTypeArguments(@NotNull PsiClassType.ClassResolveResult baseResult, - @NotNull PsiClass derived, - @NotNull PsiManager manager, - @NotNull PsiSubstitutor derivedSubstitutor, + private static boolean checkSuperTypesWithDifferentTypeArguments(PsiClassType.ClassResolveResult baseResult, + PsiClass derived, + PsiManager manager, + PsiSubstitutor derivedSubstitutor, Set visited, - @NotNull LanguageLevel languageLevel) { + final LanguageLevel languageLevel) { if (visited != null && visited.contains(derived)) return true; if (languageLevel.compareTo(LanguageLevel.JDK_1_5) < 0) return true; @@ -359,12 +359,10 @@ public class TypeConversionUtil { derivedSubstitutor = getSuperClassSubstitutor(derived, derived, derivedSubstitutor); return areSameArgumentTypes(derived, baseResult.getSubstitutor(), derivedSubstitutor, 1); } - else { - PsiSubstitutor baseSubstitutor = getMaybeSuperClassSubstitutor(derived, base, baseResult.getSubstitutor(), new THashSet()); - if (baseSubstitutor != null) { - derivedSubstitutor = getSuperClassSubstitutor(derived, derived, derivedSubstitutor); - if (!areSameArgumentTypes(derived, baseSubstitutor, derivedSubstitutor)) return false; - } + else if (base.isInheritor(derived, true)) { + derivedSubstitutor = getSuperClassSubstitutor(derived, derived, derivedSubstitutor); + PsiSubstitutor baseSubstitutor = getSuperClassSubstitutor(derived, base, baseResult.getSubstitutor()); + if (!areSameArgumentTypes(derived, baseSubstitutor, derivedSubstitutor)) return false; } if (visited == null) visited = new THashSet(); @@ -377,7 +375,7 @@ public class TypeConversionUtil { return true; } - private static boolean areSameParameterTypes(@NotNull PsiClassType type1, @NotNull PsiClassType type2) { + private static boolean areSameParameterTypes(PsiClassType type1, PsiClassType type2) { PsiClassType.ClassResolveResult resolveResult1 = type1.resolveGenerics(); PsiClassType.ClassResolveResult resolveResult2 = type2.resolveGenerics(); final PsiClass aClass = resolveResult1.getElement(); @@ -388,13 +386,13 @@ public class TypeConversionUtil { areSameArgumentTypes(aClass, resolveResult1.getSubstitutor(), resolveResult2.getSubstitutor()); } - private static boolean areSameArgumentTypes(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor1, @NotNull PsiSubstitutor substitutor2) { + private static boolean areSameArgumentTypes(PsiClass aClass, PsiSubstitutor substitutor1, PsiSubstitutor substitutor2) { return areSameArgumentTypes(aClass, substitutor1, substitutor2, 0); } - private static boolean areSameArgumentTypes(@NotNull PsiClass aClass, - @NotNull PsiSubstitutor substitutor1, - @NotNull PsiSubstitutor substitutor2, + private static boolean areSameArgumentTypes(PsiClass aClass, + PsiSubstitutor substitutor1, + PsiSubstitutor substitutor2, int level) { for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(aClass)) { PsiType typeArg1 = substitutor1.substitute(typeParameter); @@ -465,7 +463,7 @@ public class TypeConversionUtil { * STRING_TYPE for String, * Integer.MAX_VALUE for others */ - public static int getTypeRank(@NotNull PsiType type) { + public static int getTypeRank(PsiType type) { PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(type); if (unboxedType != null) { type = unboxedType; @@ -599,13 +597,13 @@ public class TypeConversionUtil { return isPrimitiveAndNotNull(type); } - public static boolean isUnaryOperatorApplicable(@NotNull PsiJavaToken token, PsiExpression operand) { + public static boolean isUnaryOperatorApplicable(PsiJavaToken token, PsiExpression operand) { if (operand == null) return false; PsiType type = operand.getType(); return type != null && isUnaryOperatorApplicable(token, type); } - public static boolean isUnaryOperatorApplicable(@NotNull PsiJavaToken token, @NotNull PsiType type) { + public static boolean isUnaryOperatorApplicable(final PsiJavaToken token, final PsiType type) { IElementType i = token.getTokenType(); int typeRank = getTypeRank(type); if (i == JavaTokenType.MINUSMINUS || i == JavaTokenType.PLUSPLUS) { @@ -674,7 +672,7 @@ public class TypeConversionUtil { value = ((Number)rValue).longValue(); } else if (rValue instanceof Character) { - value = (Character)rValue; + value = ((Character)rValue).charValue(); } else { return false; @@ -834,7 +832,7 @@ public class TypeConversionUtil { return isClassAssignable(leftResult, rightResult, allowUncheckedConversion); } - private static boolean isAssignableFromWildcard(@NotNull PsiType left, @NotNull PsiWildcardType rightWildcardType) { + private static boolean isAssignableFromWildcard(PsiType left, PsiWildcardType rightWildcardType) { if (rightWildcardType.isSuper()) { final PsiClass aClass = PsiUtil.resolveClassInType(rightWildcardType.getSuperBound()); if (aClass instanceof PsiTypeParameter) { @@ -847,14 +845,14 @@ public class TypeConversionUtil { return isAssignable(left, rightWildcardType.getExtendsBound()); } - private static boolean isAssignableToWildcard(@NotNull PsiWildcardType wildcardType, @NotNull PsiType right) { + private static boolean isAssignableToWildcard(PsiWildcardType wildcardType, PsiType right) { if (wildcardType.isSuper()) { return isAssignable(wildcardType.getSuperBound(), right); } return isAssignable(wildcardType.getExtendsBound(), right); } - private static boolean isUnboxable(@NotNull PsiPrimitiveType left, @NotNull PsiClassType right) { + private static boolean isUnboxable(final PsiPrimitiveType left, final PsiClassType right) { final PsiPrimitiveType rightUnboxedType = PsiPrimitiveType.getUnboxedType(right); return rightUnboxedType != null && isAssignable(left, rightUnboxedType); } @@ -871,7 +869,7 @@ public class TypeConversionUtil { private static final Key>> POSSIBLE_BOXED_HOLDER_TYPES = Key.create("Types that may be possibly assigned from primitive ones"); - private static boolean isBoxable(@NotNull PsiClassType left, @NotNull PsiPrimitiveType right) { + private static boolean isBoxable(final PsiClassType left, final PsiPrimitiveType right) { if (!left.getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_5)) return false; final PsiClass psiClass = left.resolve(); if (psiClass == null) return false; @@ -885,8 +883,7 @@ public class TypeConversionUtil { return rightBoxed != null && isAssignable(left, rightBoxed); } - @NotNull - private static Set getAllBoxedTypeSupers(@NotNull PsiClass psiClass) { + private static Set getAllBoxedTypeSupers(PsiClass psiClass) { PsiManager manager = psiClass.getManager(); final Project project = psiClass.getProject(); CachedValue> boxedHolderTypes = project.getUserData(POSSIBLE_BOXED_HOLDER_TYPES); @@ -911,11 +908,12 @@ public class TypeConversionUtil { }, false)); } - return boxedHolderTypes.getValue(); + final Set boxedHolders = boxedHolderTypes.getValue(); + return boxedHolders; } - private static boolean isClassAssignable(@NotNull PsiClassType.ClassResolveResult leftResult, - @NotNull PsiClassType.ClassResolveResult rightResult, + private static boolean isClassAssignable(PsiClassType.ClassResolveResult leftResult, + PsiClassType.ClassResolveResult rightResult, boolean allowUncheckedConversion) { final PsiClass leftClass = leftResult.getElement(); final PsiClass rightClass = rightResult.getElement(); @@ -925,8 +923,8 @@ public class TypeConversionUtil { && typeParametersAgree(leftResult, rightResult, allowUncheckedConversion); } - private static boolean typeParametersAgree(@NotNull PsiClassType.ClassResolveResult leftResult, - @NotNull PsiClassType.ClassResolveResult rightResult, + private static boolean typeParametersAgree(PsiClassType.ClassResolveResult leftResult, + PsiClassType.ClassResolveResult rightResult, boolean allowUncheckedConversion) { PsiSubstitutor rightSubstitutor = rightResult.getSubstitutor(); PsiClass leftClass = leftResult.getElement(); @@ -964,7 +962,7 @@ public class TypeConversionUtil { private static final RecursionGuard ourGuard = RecursionManager.createGuard("isAssignable"); - public static boolean typesAgree(@NotNull PsiType typeLeft, @NotNull PsiType typeRight, final boolean allowUncheckedConversion) { + public static boolean typesAgree(PsiType typeLeft, PsiType typeRight, final boolean allowUncheckedConversion) { if (typeLeft instanceof PsiWildcardType) { final PsiWildcardType leftWildcard = (PsiWildcardType)typeLeft; final PsiType leftBound = leftWildcard.getBound(); @@ -988,7 +986,7 @@ public class TypeConversionUtil { return isAssignable(rightWildcard.getBound(), leftBound, allowUncheckedConversion); } }); - if (assignable != null && assignable) { + if (assignable != null && assignable.booleanValue()) { return true; } } @@ -1024,7 +1022,7 @@ public class TypeConversionUtil { @Nullable public static PsiSubstitutor getClassSubstitutor(@NotNull PsiClass superClassCandidate, @NotNull PsiClass derivedClassCandidate, - @NotNull PsiSubstitutor derivedSubstitutor) { + PsiSubstitutor derivedSubstitutor) { if (superClassCandidate.getManager().areElementsEquivalent(superClassCandidate, derivedClassCandidate)) { PsiTypeParameter[] baseParams = superClassCandidate.getTypeParameters(); PsiTypeParameter[] derivedParams = derivedClassCandidate.getTypeParameters(); @@ -1033,7 +1031,8 @@ public class TypeConversionUtil { } return derivedSubstitutor; } - return getMaybeSuperClassSubstitutor(superClassCandidate, derivedClassCandidate, derivedSubstitutor, new THashSet()); + if (!derivedClassCandidate.isInheritor(superClassCandidate, true)) return null; + return getSuperClassSubstitutor(superClassCandidate, derivedClassCandidate, derivedSubstitutor); } private static final Set ourReportedSuperClassSubstitutorExceptions = new ConcurrentHashSet(); @@ -1043,49 +1042,32 @@ public class TypeConversionUtil { * values that they have in derivedClass, given that type parameters in * derivedClass are bound by derivedSubstitutor. * superClass must be a super class/interface of derivedClass (as in - * InheritanceUtil.isInheritorOrSelf(derivedClass, superClass, true) + * InheritanceUtil.isInheritor(derivedClass, superClass, true) * * @return substitutor (never returns null) * @see PsiClass#isInheritor(PsiClass, boolean) - * @see InheritanceUtil#isInheritorOrSelf(com.intellij.psi.PsiClass, com.intellij.psi.PsiClass, boolean) */ @NotNull public static PsiSubstitutor getSuperClassSubstitutor(@NotNull PsiClass superClass, @NotNull PsiClass derivedClass, @NotNull PsiSubstitutor derivedSubstitutor) { - Set visited = new THashSet(); - PsiSubstitutor substitutor = getMaybeSuperClassSubstitutor(superClass, derivedClass, derivedSubstitutor, visited); + // [dsl] assertion commented out since we no longer cache isInheritor + //LOG.assertTrue(derivedClass.isInheritor(superClass, true), "Not inheritor: " + derivedClass + " super: " + superClass); - if (substitutor == null) { - if (ourReportedSuperClassSubstitutorExceptions.add(derivedClass.getQualifiedName() + "/" + superClass.getQualifiedName())) { - reportHierarchyInconsistency(superClass, derivedClass, visited); - } - return PsiSubstitutor.EMPTY; - } - return substitutor; - } - - // the same as getSuperClassSubstitutor() but can return null, which means that classes were not inheritors - @Nullable - public static PsiSubstitutor getMaybeSuperClassSubstitutor(@NotNull PsiClass superClass, - @NotNull PsiClass derivedClass, - @NotNull PsiSubstitutor derivedSubstitutor, - @NotNull Set visited) { - if (!superClass.hasTypeParameters() && superClass.getContainingClass() == null) { - return InheritanceUtil.isInheritorOrSelf(derivedClass, superClass, true) ? PsiSubstitutor.EMPTY : null; //optimization - } + if (!superClass.hasTypeParameters() && superClass.getContainingClass() == null) return PsiSubstitutor.EMPTY; //optimization final PsiManager manager = superClass.getManager(); if (PsiUtil.isRawSubstitutor(derivedClass, derivedSubstitutor)) { - return InheritanceUtil.isInheritorOrSelf(derivedClass, superClass, true) ? JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createRawSubstitutor(superClass) : null; + return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createRawSubstitutor(superClass); } - if (CommonClassNames.JAVA_LANG_OBJECT_SHORT.equals(superClass.getName()) && - manager.areElementsEquivalent(superClass, JavaPsiFacade.getInstance(manager.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, superClass.getResolveScope()))) { + final PsiClass objectClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, superClass.getResolveScope()); + if (manager.areElementsEquivalent(superClass, objectClass)) { return PsiSubstitutor.EMPTY; } PsiSubstitutor substitutor; + final Set visited = new THashSet(); if (derivedClass instanceof PsiAnonymousClass) { final PsiClassType baseType = ((PsiAnonymousClass)derivedClass).getBaseClassType(); final JavaResolveResult result = baseType.resolveGenerics(); @@ -1096,10 +1078,16 @@ public class TypeConversionUtil { else { substitutor = getSuperClassSubstitutorInner(superClass, derivedClass, derivedSubstitutor, visited, manager); } + if (substitutor == null) { + if (ourReportedSuperClassSubstitutorExceptions.add(derivedClass.getQualifiedName() + "/" + superClass.getQualifiedName())) { + reportHierarchyInconsistency(superClass, derivedClass, visited); + } + return PsiSubstitutor.EMPTY; + } return substitutor; } - private static void reportHierarchyInconsistency(@NotNull PsiClass superClass, @NotNull PsiClass derivedClass, @NotNull Set visited) { + private static void reportHierarchyInconsistency(PsiClass superClass, PsiClass derivedClass, Set visited) { final StringBuilder msg = new StringBuilder("Super: " + classInfo(superClass)); msg.append("visited:\n"); for (PsiClass aClass : visited) { @@ -1117,8 +1105,7 @@ public class TypeConversionUtil { LOG.error(msg.toString()); } - @NotNull - private static String classInfo(@NotNull PsiClass aClass) { + private static String classInfo(PsiClass aClass) { String s = aClass.getQualifiedName() + "(" + aClass.getClass().getName() + "; " + PsiUtilCore.getVirtualFile(aClass) + ");\n"; s += "extends: "; for (PsiClassType type : aClass.getExtendsListTypes()) { @@ -1137,14 +1124,12 @@ public class TypeConversionUtil { return getSuperClassSubstitutor(superClass, classResolveResult.getElement(), classResolveResult.getSubstitutor()); } - @Nullable - private static PsiSubstitutor getSuperClassSubstitutorInner(@NotNull PsiClass base, - @NotNull PsiClass candidate, - @NotNull PsiSubstitutor candidateSubstitutor, - @NotNull Set visited, - @NotNull PsiManager manager) { + private static PsiSubstitutor getSuperClassSubstitutorInner(PsiClass base, + PsiClass candidate, + PsiSubstitutor candidateSubstitutor, + Set visited, + PsiManager manager) { if (!visited.add(candidate)) return null; - assert candidateSubstitutor.isValid(); if (base == candidate) return candidateSubstitutor; if (manager.areElementsEquivalent(base, candidate)) { @@ -1163,18 +1148,19 @@ public class TypeConversionUtil { } } - PsiSubstitutor substitutor = checkReferenceList(candidate.getExtendsListTypes(), candidateSubstitutor, base, visited, manager); + PsiSubstitutor substitutor = checkReferenceList(candidate.getExtendsListTypes(), candidateSubstitutor, base, visited, + manager); if (substitutor == null) { substitutor = checkReferenceList(candidate.getImplementsListTypes(), candidateSubstitutor, base, visited, manager); } return substitutor; } - private static PsiSubstitutor checkReferenceList(@NotNull PsiClassType[] types, - @NotNull PsiSubstitutor candidateSubstitutor, - @NotNull PsiClass base, - @NotNull Set set, - @NotNull PsiManager manager) { + private static PsiSubstitutor checkReferenceList(final PsiClassType[] types, PsiSubstitutor candidateSubstitutor, + PsiClass base, + Set set, + PsiManager manager) { + assert candidateSubstitutor.isValid(); for (final PsiClassType type : types) { final PsiType substitutedType = candidateSubstitutor.substitute(type); //if (!(substitutedType instanceof PsiClassType)) return null; @@ -1184,7 +1170,8 @@ public class TypeConversionUtil { final PsiElement newCandidate = result.getElement(); if (newCandidate != null) { final PsiSubstitutor substitutor = result.getSubstitutor(); - final PsiSubstitutor newSubstitutor = getSuperClassSubstitutorInner(base, (PsiClass)newCandidate, substitutor, set, manager); + final PsiSubstitutor newSubstitutor = getSuperClassSubstitutorInner(base, (PsiClass)newCandidate, + substitutor, set, manager); if (newSubstitutor != null) { return type.isRaw() ? JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createRawSubstitutor(base) : newSubstitutor; } @@ -1196,7 +1183,6 @@ public class TypeConversionUtil { /** * see JLS 5.6.2 */ - @NotNull public static PsiType binaryNumericPromotion(PsiType type1, PsiType type2) { if (isDoubleType(type1)) return unbox(type1); if (isDoubleType(type2)) return unbox(type2); @@ -1208,8 +1194,7 @@ public class TypeConversionUtil { return PsiType.INT; } - @NotNull - private static PsiType unbox(@NotNull PsiType type) { + private static PsiType unbox(PsiType type) { if (type instanceof PsiPrimitiveType) return type; if (type instanceof PsiClassType) { type = PsiPrimitiveType.getUnboxedType(type); @@ -1408,7 +1393,6 @@ public class TypeConversionUtil { return value; } - @NotNull public static PsiType unboxAndBalanceTypes(PsiType type1, PsiType type2) { if (type1 instanceof PsiClassType) type1 = PsiPrimitiveType.getUnboxedType(type1); if (type2 instanceof PsiClassType) type2 = PsiPrimitiveType.getUnboxedType(type2); @@ -1458,7 +1442,7 @@ public class TypeConversionUtil { } @Nullable - public static PsiType calcTypeForBinaryExpression(PsiType lType, PsiType rType, @NotNull IElementType sign, boolean accessLType) { + public static PsiType calcTypeForBinaryExpression(PsiType lType, PsiType rType, IElementType sign, boolean accessLType) { if (sign == JavaTokenType.PLUS) { // evaluate right argument first, since '+-/*%' is left associative and left operand tends to be bigger if (rType == null) return null; @@ -1528,371 +1512,321 @@ public class TypeConversionUtil { } private interface Caster { - @NotNull - Object cast(@NotNull Object operand); + Object cast(Object operand); } private static final Caster[][] caster = { { new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { + public Object cast(Object operand) { return operand; } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (short)((Number)operand).intValue(); + public Object cast(Object operand) { + return Short.valueOf((short)((Number)operand).intValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (char)((Number)operand).intValue(); + public Object cast(Object operand) { + return new Character((char) ((Number) operand).intValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return ((Number)operand).intValue(); + public Object cast(Object operand) { + return Integer.valueOf(((Number)operand).intValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (long)((Number)operand).intValue(); + public Object cast(Object operand) { + return Long.valueOf(((Number)operand).intValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (float)((Number)operand).intValue(); + public Object cast(Object operand) { + return new Float(((Number) operand).intValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (double)((Number)operand).intValue(); + public Object cast(Object operand) { + return new Double(((Number) operand).intValue()); } } } , { new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (byte)((Short)operand).shortValue(); + public Object cast(Object operand) { + return Byte.valueOf((byte)((Short)operand).shortValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return operand; + public Object cast(Object operand) { + return Short.valueOf(((Short)operand).shortValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (char)((Short)operand).shortValue(); + public Object cast(Object operand) { + return new Character((char) ((Short) operand).shortValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (int)(Short)operand; + public Object cast(Object operand) { + return Integer.valueOf(((Short)operand).shortValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (long)(Short)operand; + public Object cast(Object operand) { + return Long.valueOf(((Short)operand).shortValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (float)(Short)operand; + public Object cast(Object operand) { + return new Float(((Short) operand).shortValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (double)(Short)operand; + public Object cast(Object operand) { + return new Double(((Short) operand).shortValue()); } } } , { new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (byte)((Character)operand).charValue(); + public Object cast(Object operand) { + return Byte.valueOf((byte)((Character)operand).charValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (short)((Character)operand).charValue(); + public Object cast(Object operand) { + return Short.valueOf((short)((Character)operand).charValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return operand; + public Object cast(Object operand) { + return new Character(((Character) operand).charValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (int)(Character)operand; + public Object cast(Object operand) { + return Integer.valueOf(((Character)operand).charValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (long)(Character)operand; + public Object cast(Object operand) { + return Long.valueOf(((Character)operand).charValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (float)(Character)operand; + public Object cast(Object operand) { + return new Float(((Character) operand).charValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (double)(Character)operand; + public Object cast(Object operand) { + return new Double(((Character) operand).charValue()); } } } , { new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (byte)((Integer)operand).intValue(); + public Object cast(Object operand) { + return Byte.valueOf((byte)((Integer)operand).intValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (short)((Integer)operand).intValue(); + public Object cast(Object operand) { + return Short.valueOf((short)((Integer)operand).intValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (char)((Integer)operand).intValue(); + public Object cast(Object operand) { + return new Character((char) ((Integer) operand).intValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return operand; + public Object cast(Object operand) { + return Integer.valueOf(((Integer)operand).intValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (long)(Integer)operand; + public Object cast(Object operand) { + return Long.valueOf(((Integer)operand).intValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (float)(Integer)operand; + public Object cast(Object operand) { + return new Float(((Integer) operand).intValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (double)(Integer)operand; + public Object cast(Object operand) { + return new Double(((Integer) operand).intValue()); } } } , { new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (byte)((Long)operand).longValue(); + public Object cast(Object operand) { + return Byte.valueOf((byte)((Long)operand).longValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (short)((Long)operand).longValue(); + public Object cast(Object operand) { + return Short.valueOf((short)((Long)operand).longValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (char)((Long)operand).longValue(); + public Object cast(Object operand) { + return new Character((char) ((Long) operand).longValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (int)((Long)operand).longValue(); + public Object cast(Object operand) { + return Integer.valueOf((int)((Long)operand).longValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return operand; + public Object cast(Object operand) { + return Long.valueOf(((Long)operand).longValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (float)(Long)operand; + public Object cast(Object operand) { + return new Float(((Long) operand).longValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (double)(Long)operand; + public Object cast(Object operand) { + return new Double(((Long) operand).longValue()); } } } , { new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (byte)((Float)operand).floatValue(); + public Object cast(Object operand) { + return Byte.valueOf((byte)((Float)operand).floatValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (short)((Float)operand).floatValue(); + public Object cast(Object operand) { + return Short.valueOf((short)((Float)operand).floatValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (char)((Float)operand).floatValue(); + public Object cast(Object operand) { + return new Character((char) ((Float) operand).floatValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (int)((Float)operand).floatValue(); + public Object cast(Object operand) { + return Integer.valueOf((int)((Float)operand).floatValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (long)((Float)operand).floatValue(); + public Object cast(Object operand) { + return Long.valueOf((long)((Float)operand).floatValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return operand; + public Object cast(Object operand) { + return new Float(((Float) operand).floatValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (double)(Float)operand; + public Object cast(Object operand) { + return new Double(((Float) operand).floatValue()); } } } , { new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (byte)((Double)operand).doubleValue(); + public Object cast(Object operand) { + return Byte.valueOf((byte)((Double)operand).doubleValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (short)((Double)operand).doubleValue(); + public Object cast(Object operand) { + return Short.valueOf((short)((Double)operand).doubleValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (char)((Double)operand).doubleValue(); + public Object cast(Object operand) { + return new Character((char) ((Double) operand).doubleValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (int)((Double)operand).doubleValue(); + public Object cast(Object operand) { + return Integer.valueOf((int)((Double)operand).doubleValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return (long)((Double)operand).doubleValue(); + public Object cast(Object operand) { + return Long.valueOf((long)((Double)operand).doubleValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return new Float((Double)operand); + public Object cast(Object operand) { + return new Float(((Double) operand).doubleValue()); } } , new Caster() { - @NotNull @Override - public Object cast(@NotNull Object operand) { - return operand; + public Object cast(Object operand) { + return new Double(((Double) operand).doubleValue()); } } } @@ -1910,7 +1844,7 @@ public class TypeConversionUtil { WRAPPER_TO_PRIMITIVE.put(Double.class, PsiType.DOUBLE); } - private static PsiType wrapperToPrimitive(@NotNull Object o) { + private static PsiType wrapperToPrimitive(Object o) { return WRAPPER_TO_PRIMITIVE.get(o.getClass()); } diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java index d73216ded011..f136c843aa87 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java @@ -316,8 +316,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ // prefer derived class signatures.put(signature, info); - } - else { + } else { final PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(myArgumentsList, PsiMethodCallExpression.class); if (methodCallExpression != null) { final PsiReferenceExpression expression = methodCallExpression.getMethodExpression(); @@ -325,19 +324,14 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ PsiClass currentClass; if (qualifierExpression != null) { currentClass = PsiUtil.resolveClassInClassTypeOnly(qualifierExpression.getType()); - } - else { + } else { currentClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class); } - if (currentClass != null) { - final PsiSubstitutor eSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(existingClass, currentClass, - PsiSubstitutor.EMPTY, - new THashSet()); - final PsiSubstitutor cSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(class1, currentClass, PsiSubstitutor.EMPTY, - new THashSet()); - if (eSubstitutor != null && cSubstitutor != null && - MethodSignatureUtil.areSignaturesEqual(existingMethod.getSignature(eSubstitutor), method.getSignature(cSubstitutor))) { + if (currentClass != null && InheritanceUtil.isInheritorOrSelf(currentClass, class1, true) && InheritanceUtil.isInheritorOrSelf(currentClass, existingClass, true)) { + final PsiSubstitutor eSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(existingClass, currentClass, PsiSubstitutor.EMPTY); + final PsiSubstitutor cSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(class1, currentClass, PsiSubstitutor.EMPTY); + if (MethodSignatureUtil.areSignaturesEqual(existingMethod.getSignature(eSubstitutor), method.getSignature(cSubstitutor))) { final PsiType returnType = eSubstitutor.substitute(existingMethod.getReturnType()); final PsiType returnType1 = cSubstitutor.substitute(method.getReturnType()); if (returnType != null && returnType1 != null && !returnType1.equals(returnType)) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/PolymorphicTypeCast.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/PolymorphicTypeCast.java index 8ba3ea4f8037..8be16fc1db85 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/PolymorphicTypeCast.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/PolymorphicTypeCast.java @@ -94,96 +94,4 @@ class C { void asLongs(Integer i) { long l = (long) i; } - - void foo(Object o) {} - public void cast2(Byte operand) { - foo((byte)operand); - foo((short)operand); - foo((char)operand); - foo((int)operand); - foo((long)operand); - foo((float)operand); - foo((double)operand); - foo((boolean)operand); - } - public void cast2(Short operand) { - foo((byte)operand); - foo((short)operand); - foo((char)operand); - foo((int)operand); - foo((long)operand); - foo((float)operand); - foo((double)operand); - foo((boolean)operand); - } - public void cast2(Character operand) { - foo((byte)operand); - foo((short)operand); - foo((char)operand); - foo((int)operand); - foo((long)operand); - foo((float)operand); - foo((double)operand); - foo((boolean)operand); - } - public void cast2(Integer operand) { - foo((byte)operand); - foo((short)operand); - foo((char)operand); - foo((int)operand); - foo((long)operand); - foo((float)operand); - foo((double)operand); - foo((boolean)operand); - } - public void cast2(Long operand) { - foo((byte)operand); - foo((short)operand); - foo((char)operand); - foo((int)operand); - foo((long)operand); - foo((float)operand); - foo((double)operand); - foo((boolean)operand); - } - public void cast2(Float operand) { - foo((byte)operand); - foo((short)operand); - foo((char)operand); - foo((int)operand); - foo((long)operand); - foo((float)operand); - foo((double)operand); - foo((boolean)operand); - } - public void cast2(Double operand) { - foo((byte)operand); - foo((short)operand); - foo((char)operand); - foo((int)operand); - foo((long)operand); - foo((float)operand); - foo((double)operand); - foo((boolean)operand); - } - public void cast2(Boolean operand) { - foo((byte)operand); - foo((short)operand); - foo((char)operand); - foo((int)operand); - foo((long)operand); - foo((float)operand); - foo((double)operand); - foo((boolean)operand); - } - public void cast2(Object operand) { - foo((byte)operand); - foo((short)operand); - foo((char)operand); - foo((int)operand); - foo((long)operand); - foo((float)operand); - foo((double)operand); - foo((boolean)operand); - } } \ No newline at end of file