summaryrefslogtreecommitdiff
path: root/java/java-psi-api/src/com/intellij
diff options
context:
space:
mode:
Diffstat (limited to 'java/java-psi-api/src/com/intellij')
-rw-r--r--java/java-psi-api/src/com/intellij/codeInsight/AnnotationTargetUtil.java136
-rw-r--r--java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java4
-rw-r--r--java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java72
-rw-r--r--java/java-psi-api/src/com/intellij/psi/GenericsUtil.java3
-rw-r--r--java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java8
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java10
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java5
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java499
8 files changed, 497 insertions, 240 deletions
diff --git a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationTargetUtil.java b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationTargetUtil.java
new file mode 100644
index 000000000000..c7d9e303aae3
--- /dev/null
+++ b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationTargetUtil.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.*;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * @author peter
+ */
+public class AnnotationTargetUtil {
+ public static final Set<PsiAnnotation.TargetType> DEFAULT_TARGETS = Collections.unmodifiableSet(ContainerUtil.newHashSet(
+ PsiAnnotation.TargetType.PACKAGE, PsiAnnotation.TargetType.TYPE, PsiAnnotation.TargetType.ANNOTATION_TYPE,
+ PsiAnnotation.TargetType.FIELD, PsiAnnotation.TargetType.METHOD, PsiAnnotation.TargetType.CONSTRUCTOR,
+ PsiAnnotation.TargetType.PARAMETER, PsiAnnotation.TargetType.LOCAL_VARIABLE));
+ private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.AnnotationUtil");
+ private static final PsiAnnotation.TargetType[] PACKAGE_TARGETS = {PsiAnnotation.TargetType.PACKAGE};
+ private static final PsiAnnotation.TargetType[] TYPE_USE_TARGETS = {PsiAnnotation.TargetType.TYPE_USE};
+ private static final PsiAnnotation.TargetType[] ANNOTATION_TARGETS = {PsiAnnotation.TargetType.ANNOTATION_TYPE, PsiAnnotation.TargetType.TYPE, PsiAnnotation.TargetType.TYPE_USE};
+ private static final PsiAnnotation.TargetType[] TYPE_TARGETS = {PsiAnnotation.TargetType.TYPE, PsiAnnotation.TargetType.TYPE_USE};
+ private static final PsiAnnotation.TargetType[] TYPE_PARAMETER_TARGETS = {
+ PsiAnnotation.TargetType.TYPE_PARAMETER, PsiAnnotation.TargetType.TYPE_USE};
+ private static final PsiAnnotation.TargetType[] CONSTRUCTOR_TARGETS = {PsiAnnotation.TargetType.CONSTRUCTOR, PsiAnnotation.TargetType.TYPE_USE};
+ private static final PsiAnnotation.TargetType[] METHOD_TARGETS = {PsiAnnotation.TargetType.METHOD, PsiAnnotation.TargetType.TYPE_USE};
+ private static final PsiAnnotation.TargetType[] FIELD_TARGETS = {PsiAnnotation.TargetType.FIELD, PsiAnnotation.TargetType.TYPE_USE};
+ private static final PsiAnnotation.TargetType[] PARAMETER_TARGETS = {PsiAnnotation.TargetType.PARAMETER, PsiAnnotation.TargetType.TYPE_USE};
+ private static final PsiAnnotation.TargetType[] LOCAL_VARIABLE_TARGETS ={
+ PsiAnnotation.TargetType.LOCAL_VARIABLE, PsiAnnotation.TargetType.TYPE_USE};
+
+ @NotNull
+ public static PsiAnnotation.TargetType[] getTargetsForLocation(@Nullable PsiAnnotationOwner owner) {
+ if (owner == null) {
+ return PsiAnnotation.TargetType.EMPTY_ARRAY;
+ }
+
+ if (owner instanceof PsiType || owner instanceof PsiTypeElement) {
+ return TYPE_USE_TARGETS;
+ }
+
+ if (owner instanceof PsiTypeParameter) {
+ return TYPE_PARAMETER_TARGETS;
+ }
+
+ if (owner instanceof PsiModifierList) {
+ PsiElement element = ((PsiModifierList)owner).getParent();
+ if (element instanceof PsiPackageStatement) {
+ return PACKAGE_TARGETS;
+ }
+ if (element instanceof PsiClass) {
+ if (((PsiClass)element).isAnnotationType()) {
+ return ANNOTATION_TARGETS;
+ }
+ else {
+ return TYPE_TARGETS;
+ }
+ }
+ if (element instanceof PsiMethod) {
+ if (((PsiMethod)element).isConstructor()) {
+ return CONSTRUCTOR_TARGETS;
+ }
+ else {
+ return METHOD_TARGETS;
+ }
+ }
+ if (element instanceof PsiField) {
+ return FIELD_TARGETS;
+ }
+ if (element instanceof PsiParameter) {
+ return PARAMETER_TARGETS;
+ }
+ if (element instanceof PsiLocalVariable) {
+ return LOCAL_VARIABLE_TARGETS;
+ }
+ }
+
+ return PsiAnnotation.TargetType.EMPTY_ARRAY;
+ }
+
+ @Nullable
+ public static Set<PsiAnnotation.TargetType> extractRequiredAnnotationTargets(@Nullable PsiAnnotationMemberValue value) {
+ if (value instanceof PsiReference) {
+ PsiAnnotation.TargetType targetType = translateTargetRef((PsiReference)value);
+ if (targetType != null) {
+ return Collections.singleton(targetType);
+ }
+ }
+ else if (value instanceof PsiArrayInitializerMemberValue) {
+ Set <PsiAnnotation.TargetType> targets = ContainerUtil.newHashSet();
+ for (PsiAnnotationMemberValue initializer : ((PsiArrayInitializerMemberValue)value).getInitializers()) {
+ if (initializer instanceof PsiReference) {
+ PsiAnnotation.TargetType targetType = translateTargetRef((PsiReference)initializer);
+ if (targetType != null) {
+ targets.add(targetType);
+ }
+ }
+ }
+ return targets;
+ }
+
+ return null;
+ }
+
+ @Nullable
+ private static PsiAnnotation.TargetType translateTargetRef(@NotNull PsiReference reference) {
+ PsiElement field = reference.resolve();
+ if (field instanceof PsiEnumConstant) {
+ String name = ((PsiEnumConstant)field).getName();
+ try {
+ return PsiAnnotation.TargetType.valueOf(name);
+ }
+ catch (IllegalArgumentException e) {
+ LOG.warn("Unknown target: " + name);
+ }
+ }
+ return null;
+ }
+}
diff --git a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java
index c2c79a9d9d8a..25034e9ab7ba 100644
--- a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java
+++ b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java
@@ -379,14 +379,14 @@ public class AnnotationUtil {
@NotNull
public static PsiAnnotation[] getAllAnnotations(@NotNull PsiModifierListOwner owner,
boolean inHierarchy,
- Set<PsiModifierListOwner> visited) {
+ @Nullable Set<PsiModifierListOwner> visited) {
return getAllAnnotations(owner, inHierarchy, visited, true);
}
@NotNull
public static PsiAnnotation[] getAllAnnotations(@NotNull PsiModifierListOwner owner,
boolean inHierarchy,
- Set<PsiModifierListOwner> visited, boolean withInferred) {
+ @Nullable Set<PsiModifierListOwner> visited, boolean withInferred) {
final PsiModifierList list = owner.getModifierList();
PsiAnnotation[] annotations = PsiAnnotation.EMPTY_ARRAY;
if (list != null) {
diff --git a/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java b/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java
index 21e014e4aca3..2210e02a080a 100644
--- a/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java
+++ b/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java
@@ -44,10 +44,13 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
public final JDOMExternalizableStringList myNullables = new JDOMExternalizableStringList();
public final JDOMExternalizableStringList myNotNulls = new JDOMExternalizableStringList();
- public static final String[] DEFAULT_NULLABLES = {AnnotationUtil.NULLABLE, "javax.annotation.Nullable",
+ private static final String JAVAX_ANNOTATION_NULLABLE = "javax.annotation.Nullable";
+ private static final String JAVAX_ANNOTATION_NONNULL = "javax.annotation.Nonnull";
+
+ public static final String[] DEFAULT_NULLABLES = {AnnotationUtil.NULLABLE, JAVAX_ANNOTATION_NULLABLE,
"edu.umd.cs.findbugs.annotations.Nullable", "android.support.annotation.Nullable"
};
- public static final String[] DEFAULT_NOT_NULLS = {AnnotationUtil.NOT_NULL, "javax.annotation.Nonnull",
+ public static final String[] DEFAULT_NOT_NULLS = {AnnotationUtil.NOT_NULL, JAVAX_ANNOTATION_NONNULL,
"edu.umd.cs.findbugs.annotations.NonNull", "android.support.annotation.NonNull"
};
@@ -103,6 +106,11 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
return findNullabilityAnnotation(owner, checkBases, true);
}
+ public boolean isContainerAnnotation(@NotNull PsiAnnotation anno) {
+ PsiAnnotation.TargetType[] acceptAnyTarget = PsiAnnotation.TargetType.values();
+ return isNullabilityDefault(anno, true, acceptAnyTarget) || isNullabilityDefault(anno, false, acceptAnyTarget);
+ }
+
public void setDefaultNullable(@NotNull String defaultNullable) {
LOG.assertTrue(getNullables().contains(defaultNullable));
myDefaultNullable = defaultNullable;
@@ -138,15 +146,20 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
return annotation;
}
- if (owner instanceof PsiParameter && !TypeConversionUtil.isPrimitiveAndNotNull(((PsiParameter)owner).getType())) {
- // even if javax.annotation.Nullable is not configured, it should still take precedence over ByDefault annotations
- if (AnnotationUtil.isAnnotated(owner, nullable ? Arrays.asList(DEFAULT_NOT_NULLS) : Arrays.asList(DEFAULT_NULLABLES), checkBases, false)) {
- return null;
- }
- return findContainerAnnotation(owner, nullable
- ? "javax.annotation.ParametersAreNullableByDefault"
- : "javax.annotation.ParametersAreNonnullByDefault");
+ PsiType type = getOwnerType(owner);
+ if (type == null || TypeConversionUtil.isPrimitiveAndNotNull(type)) return null;
+
+ // even if javax.annotation.Nullable is not configured, it should still take precedence over ByDefault annotations
+ if (AnnotationUtil.isAnnotated(owner, nullable ? Arrays.asList(DEFAULT_NOT_NULLS) : Arrays.asList(DEFAULT_NULLABLES), checkBases, false)) {
+ return null;
}
+ return findNullabilityDefaultInHierarchy(owner, nullable);
+ }
+
+ @Nullable
+ private static PsiType getOwnerType(PsiModifierListOwner owner) {
+ if (owner instanceof PsiVariable) return ((PsiVariable)owner).getType();
+ if (owner instanceof PsiMethod) return ((PsiMethod)owner).getReturnType();
return null;
}
@@ -159,11 +172,13 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
}
@Nullable
- private static PsiAnnotation findContainerAnnotation(PsiModifierListOwner owner, String annotationFQN) {
+ private static PsiAnnotation findNullabilityDefaultInHierarchy(PsiModifierListOwner owner, boolean nullable) {
+ PsiAnnotation.TargetType[] placeTargetTypes = AnnotationTargetUtil.getTargetsForLocation(owner.getModifierList());
+
PsiElement element = owner.getParent();
while (element != null) {
if (element instanceof PsiModifierListOwner) {
- PsiAnnotation annotation = AnnotationUtil.findAnnotation((PsiModifierListOwner)element, annotationFQN);
+ PsiAnnotation annotation = getNullabilityDefault((PsiModifierListOwner)element, nullable, placeTargetTypes);
if (annotation != null) {
return annotation;
}
@@ -172,7 +187,7 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
if (element instanceof PsiClassOwner) {
String packageName = ((PsiClassOwner)element).getPackageName();
PsiPackage psiPackage = JavaPsiFacade.getInstance(element.getProject()).findPackage(packageName);
- return AnnotationUtil.findAnnotation(psiPackage, annotationFQN);
+ return psiPackage == null ? null : getNullabilityDefault(psiPackage, nullable, placeTargetTypes);
}
element = element.getContext();
@@ -180,6 +195,37 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
return null;
}
+ private static PsiAnnotation getNullabilityDefault(@NotNull PsiModifierListOwner container, boolean nullable, PsiAnnotation.TargetType[] placeTargetTypes) {
+ PsiModifierList modifierList = container.getModifierList();
+ if (modifierList == null) return null;
+ for (PsiAnnotation annotation : modifierList.getAnnotations()) {
+ if (isNullabilityDefault(annotation, nullable, placeTargetTypes)) {
+ return annotation;
+ }
+ }
+ return null;
+ }
+
+ private static boolean isNullabilityDefault(@NotNull PsiAnnotation annotation, boolean nullable, PsiAnnotation.TargetType[] placeTargetTypes) {
+ PsiJavaCodeReferenceElement element = annotation.getNameReferenceElement();
+ PsiElement declaration = element == null ? null : element.resolve();
+ if (!(declaration instanceof PsiClass)) return false;
+
+ if (!AnnotationUtil.isAnnotated((PsiClass)declaration,
+ nullable ? JAVAX_ANNOTATION_NULLABLE : JAVAX_ANNOTATION_NONNULL,
+ false,
+ true)) {
+ return false;
+ }
+
+ PsiAnnotation tqDefault = AnnotationUtil.findAnnotation((PsiClass)declaration, true, "javax.annotation.meta.TypeQualifierDefault");
+ if (tqDefault == null) return false;
+
+ Set<PsiAnnotation.TargetType> required = AnnotationTargetUtil.extractRequiredAnnotationTargets(tqDefault.findAttributeValue(null));
+ if (required == null) return false;
+ return required.isEmpty() || ContainerUtil.intersects(required, Arrays.asList(placeTargetTypes));
+ }
+
public List<String> getNullables() {
return myNullables;
}
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 7cabc118fc6c..52888f123215 100644
--- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
@@ -476,6 +476,9 @@ public class GenericsUtil {
PsiType substituted = resolveResult.getSubstitutor().substitute(typeParam);
if (substituted instanceof PsiWildcardType) {
substituted = ((PsiWildcardType)substituted).getBound();
+ if (substituted instanceof PsiCapturedWildcardType) {
+ substituted = ((PsiCapturedWildcardType)substituted).getWildcard().getBound();
+ }
if (substituted == null) substituted = TypeConversionUtil.typeParameterErasure(typeParam);
}
map.put(typeParam, substituted);
diff --git a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
index e7506ebd92fd..f43358007eab 100644
--- a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
+++ b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
@@ -180,7 +180,7 @@ public class MethodCandidateInfo extends CandidateInfo{
@NotNull
public PsiSubstitutor getSubstitutor(boolean includeReturnConstraint) {
PsiSubstitutor substitutor = myCalcedSubstitutor;
- if (substitutor == null || !includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
+ if (substitutor == null || !includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) || isOverloadCheck()) {
PsiSubstitutor incompleteSubstitutor = super.getSubstitutor();
PsiMethod method = getElement();
if (myTypeArguments == null) {
@@ -189,7 +189,7 @@ public class MethodCandidateInfo extends CandidateInfo{
final PsiSubstitutor inferredSubstitutor = inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE, includeReturnConstraint);
if (!stackStamp.mayCacheNow() ||
- !ourOverloadGuard.currentStack().isEmpty() ||
+ isOverloadCheck() ||
!includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) ||
getMarkerList() != null && PsiResolveHelper.ourGraphGuard.currentStack().contains(getMarkerList().getParent())) {
return inferredSubstitutor;
@@ -209,6 +209,10 @@ public class MethodCandidateInfo extends CandidateInfo{
return substitutor;
}
+ public static boolean isOverloadCheck() {
+ return !ourOverloadGuard.currentStack().isEmpty();
+ }
+
public boolean isTypeArgumentsApplicable() {
return isTypeArgumentsApplicable(false);
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 622714c6dd61..22591801e32e 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
@@ -114,7 +114,7 @@ public class MethodSignatureUtil {
}
public static boolean areSignaturesEqual(@NotNull PsiMethod method1, @NotNull PsiMethod method2) {
- return method1.getSignature(PsiSubstitutor.EMPTY).equals(method2.getSignature(PsiSubstitutor.EMPTY));
+ return areSignaturesEqual(method1.getSignature(PsiSubstitutor.EMPTY), method2.getSignature(PsiSubstitutor.EMPTY));
}
public static boolean areSignaturesEqual(@NotNull MethodSignature method1, @NotNull MethodSignature method2) {
@@ -172,10 +172,10 @@ public class MethodSignatureUtil {
public static boolean isSuperMethod(@NotNull PsiMethod superMethodCandidate, @NotNull PsiMethod derivedMethod) {
PsiClass superClassCandidate = superMethodCandidate.getContainingClass();
PsiClass derivedClass = derivedMethod.getContainingClass();
- if (derivedClass == null || superClassCandidate == null) return false;
- if (!derivedClass.isInheritor(superClassCandidate, true)) return false;
- final PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClassCandidate, derivedClass,
- PsiSubstitutor.EMPTY);
+ if (derivedClass == null || superClassCandidate == null || derivedClass == superClassCandidate) return false;
+ final PsiSubstitutor superSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(superClassCandidate, derivedClass,
+ PsiSubstitutor.EMPTY, null);
+ if (superSubstitutor == null) return false;
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/PsiUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
index e5493711b7c2..a69e11a9d3cc 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
@@ -1099,6 +1099,11 @@ public final class PsiUtil extends PsiUtilCore {
return true;
}
}
+ else if (parent instanceof PsiConditionalExpression) {
+ if (checkSameExpression(expr, ((PsiConditionalExpression)parent).getCondition())) {
+ return true;
+ }
+ }
return false;
}
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 477a74e64b2e..42f1494bad2e 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,6 +128,9 @@ 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();
@@ -162,7 +165,7 @@ public class TypeConversionUtil {
/**
* see JLS 5.1.5, JLS3 5.1.6
*/
- private static boolean isNarrowingReferenceConversionAllowed(PsiType fromType, PsiType toType) {
+ private static boolean isNarrowingReferenceConversionAllowed(@NotNull PsiType fromType, @NotNull 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;
@@ -280,60 +283,56 @@ public class TypeConversionUtil {
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);
- }
+ else if (!toClass.isInterface()) {
+ if (!toClass.hasModifierProperty(PsiModifier.FINAL)) {
+ return checkSuperTypesWithDifferentTypeArguments(fromResult, toClass, manager, toResult.getSubstitutor(), null, languageLevel);
}
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<HierarchicalMethodSignature> fromClassMethodSignatures = fromClass.getVisibleSignatures();
- Collection<HierarchicalMethodSignature> 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;
- }
- }
+ PsiSubstitutor toSubstitutor = getMaybeSuperClassSubstitutor(fromClass, toClass, toResult.getSubstitutor(), null);
+ 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<HierarchicalMethodSignature> fromClassMethodSignatures = fromClass.getVisibleSignatures();
+ Collection<HierarchicalMethodSignature> 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 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);
}
}
- private static PsiClassType obtainSafeSuperType(final PsiTypeParameter typeParameter) {
+ @NotNull
+ private static PsiClassType obtainSafeSuperType(@NotNull PsiTypeParameter typeParameter) {
final PsiClassType superType = typeParameter.getSuperTypes()[0];
final PsiClassType.ClassResolveResult result = superType.resolveGenerics();
final PsiClass superClass = result.getElement();
@@ -344,12 +343,12 @@ public class TypeConversionUtil {
return superType;
}
- private static boolean checkSuperTypesWithDifferentTypeArguments(PsiClassType.ClassResolveResult baseResult,
- PsiClass derived,
- PsiManager manager,
- PsiSubstitutor derivedSubstitutor,
+ private static boolean checkSuperTypesWithDifferentTypeArguments(@NotNull PsiClassType.ClassResolveResult baseResult,
+ @NotNull PsiClass derived,
+ @NotNull PsiManager manager,
+ @NotNull PsiSubstitutor derivedSubstitutor,
Set<PsiClass> visited,
- final LanguageLevel languageLevel) {
+ @NotNull LanguageLevel languageLevel) {
if (visited != null && visited.contains(derived)) return true;
if (languageLevel.compareTo(LanguageLevel.JDK_1_5) < 0) return true;
@@ -359,10 +358,12 @@ public class TypeConversionUtil {
derivedSubstitutor = getSuperClassSubstitutor(derived, derived, derivedSubstitutor);
return areSameArgumentTypes(derived, baseResult.getSubstitutor(), derivedSubstitutor, 1);
}
- 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;
+ else {
+ PsiSubstitutor baseSubstitutor = getMaybeSuperClassSubstitutor(derived, base, baseResult.getSubstitutor(), null);
+ if (baseSubstitutor != null) {
+ derivedSubstitutor = getSuperClassSubstitutor(derived, derived, derivedSubstitutor);
+ if (!areSameArgumentTypes(derived, baseSubstitutor, derivedSubstitutor)) return false;
+ }
}
if (visited == null) visited = new THashSet<PsiClass>();
@@ -375,7 +376,7 @@ public class TypeConversionUtil {
return true;
}
- private static boolean areSameParameterTypes(PsiClassType type1, PsiClassType type2) {
+ private static boolean areSameParameterTypes(@NotNull PsiClassType type1, @NotNull PsiClassType type2) {
PsiClassType.ClassResolveResult resolveResult1 = type1.resolveGenerics();
PsiClassType.ClassResolveResult resolveResult2 = type2.resolveGenerics();
final PsiClass aClass = resolveResult1.getElement();
@@ -386,13 +387,13 @@ public class TypeConversionUtil {
areSameArgumentTypes(aClass, resolveResult1.getSubstitutor(), resolveResult2.getSubstitutor());
}
- private static boolean areSameArgumentTypes(PsiClass aClass, PsiSubstitutor substitutor1, PsiSubstitutor substitutor2) {
+ private static boolean areSameArgumentTypes(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor1, @NotNull PsiSubstitutor substitutor2) {
return areSameArgumentTypes(aClass, substitutor1, substitutor2, 0);
}
- private static boolean areSameArgumentTypes(PsiClass aClass,
- PsiSubstitutor substitutor1,
- PsiSubstitutor substitutor2,
+ private static boolean areSameArgumentTypes(@NotNull PsiClass aClass,
+ @NotNull PsiSubstitutor substitutor1,
+ @NotNull PsiSubstitutor substitutor2,
int level) {
for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(aClass)) {
PsiType typeArg1 = substitutor1.substitute(typeParameter);
@@ -463,7 +464,7 @@ public class TypeConversionUtil {
* STRING_TYPE for String,
* Integer.MAX_VALUE for others
*/
- public static int getTypeRank(PsiType type) {
+ public static int getTypeRank(@NotNull PsiType type) {
PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(type);
if (unboxedType != null) {
type = unboxedType;
@@ -597,13 +598,13 @@ public class TypeConversionUtil {
return isPrimitiveAndNotNull(type);
}
- public static boolean isUnaryOperatorApplicable(PsiJavaToken token, PsiExpression operand) {
+ public static boolean isUnaryOperatorApplicable(@NotNull PsiJavaToken token, PsiExpression operand) {
if (operand == null) return false;
PsiType type = operand.getType();
return type != null && isUnaryOperatorApplicable(token, type);
}
- public static boolean isUnaryOperatorApplicable(final PsiJavaToken token, final PsiType type) {
+ public static boolean isUnaryOperatorApplicable(@NotNull PsiJavaToken token, @NotNull PsiType type) {
IElementType i = token.getTokenType();
int typeRank = getTypeRank(type);
if (i == JavaTokenType.MINUSMINUS || i == JavaTokenType.PLUSPLUS) {
@@ -672,7 +673,7 @@ public class TypeConversionUtil {
value = ((Number)rValue).longValue();
}
else if (rValue instanceof Character) {
- value = ((Character)rValue).charValue();
+ value = (Character)rValue;
}
else {
return false;
@@ -832,7 +833,7 @@ public class TypeConversionUtil {
return isClassAssignable(leftResult, rightResult, allowUncheckedConversion);
}
- private static boolean isAssignableFromWildcard(PsiType left, PsiWildcardType rightWildcardType) {
+ private static boolean isAssignableFromWildcard(@NotNull PsiType left, @NotNull PsiWildcardType rightWildcardType) {
if (rightWildcardType.isSuper()) {
final PsiClass aClass = PsiUtil.resolveClassInType(rightWildcardType.getSuperBound());
if (aClass instanceof PsiTypeParameter) {
@@ -845,14 +846,14 @@ public class TypeConversionUtil {
return isAssignable(left, rightWildcardType.getExtendsBound());
}
- private static boolean isAssignableToWildcard(PsiWildcardType wildcardType, PsiType right) {
+ private static boolean isAssignableToWildcard(@NotNull PsiWildcardType wildcardType, @NotNull PsiType right) {
if (wildcardType.isSuper()) {
return isAssignable(wildcardType.getSuperBound(), right);
}
return isAssignable(wildcardType.getExtendsBound(), right);
}
- private static boolean isUnboxable(final PsiPrimitiveType left, final PsiClassType right) {
+ private static boolean isUnboxable(@NotNull PsiPrimitiveType left, @NotNull PsiClassType right) {
final PsiPrimitiveType rightUnboxedType = PsiPrimitiveType.getUnboxedType(right);
return rightUnboxedType != null && isAssignable(left, rightUnboxedType);
}
@@ -869,7 +870,7 @@ public class TypeConversionUtil {
private static final Key<CachedValue<Set<String>>> POSSIBLE_BOXED_HOLDER_TYPES = Key.create("Types that may be possibly assigned from primitive ones");
- private static boolean isBoxable(final PsiClassType left, final PsiPrimitiveType right) {
+ private static boolean isBoxable(@NotNull PsiClassType left, @NotNull PsiPrimitiveType right) {
if (!left.getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_5)) return false;
final PsiClass psiClass = left.resolve();
if (psiClass == null) return false;
@@ -883,7 +884,8 @@ public class TypeConversionUtil {
return rightBoxed != null && isAssignable(left, rightBoxed);
}
- private static Set<String> getAllBoxedTypeSupers(PsiClass psiClass) {
+ @NotNull
+ private static Set<String> getAllBoxedTypeSupers(@NotNull PsiClass psiClass) {
PsiManager manager = psiClass.getManager();
final Project project = psiClass.getProject();
CachedValue<Set<String>> boxedHolderTypes = project.getUserData(POSSIBLE_BOXED_HOLDER_TYPES);
@@ -908,12 +910,11 @@ public class TypeConversionUtil {
}, false));
}
- final Set<String> boxedHolders = boxedHolderTypes.getValue();
- return boxedHolders;
+ return boxedHolderTypes.getValue();
}
- private static boolean isClassAssignable(PsiClassType.ClassResolveResult leftResult,
- PsiClassType.ClassResolveResult rightResult,
+ private static boolean isClassAssignable(@NotNull PsiClassType.ClassResolveResult leftResult,
+ @NotNull PsiClassType.ClassResolveResult rightResult,
boolean allowUncheckedConversion) {
final PsiClass leftClass = leftResult.getElement();
final PsiClass rightClass = rightResult.getElement();
@@ -923,8 +924,8 @@ public class TypeConversionUtil {
&& typeParametersAgree(leftResult, rightResult, allowUncheckedConversion);
}
- private static boolean typeParametersAgree(PsiClassType.ClassResolveResult leftResult,
- PsiClassType.ClassResolveResult rightResult,
+ private static boolean typeParametersAgree(@NotNull PsiClassType.ClassResolveResult leftResult,
+ @NotNull PsiClassType.ClassResolveResult rightResult,
boolean allowUncheckedConversion) {
PsiSubstitutor rightSubstitutor = rightResult.getSubstitutor();
PsiClass leftClass = leftResult.getElement();
@@ -962,7 +963,7 @@ public class TypeConversionUtil {
private static final RecursionGuard ourGuard = RecursionManager.createGuard("isAssignable");
- public static boolean typesAgree(PsiType typeLeft, PsiType typeRight, final boolean allowUncheckedConversion) {
+ public static boolean typesAgree(@NotNull PsiType typeLeft, @NotNull PsiType typeRight, final boolean allowUncheckedConversion) {
if (typeLeft instanceof PsiWildcardType) {
final PsiWildcardType leftWildcard = (PsiWildcardType)typeLeft;
final PsiType leftBound = leftWildcard.getBound();
@@ -986,7 +987,7 @@ public class TypeConversionUtil {
return isAssignable(rightWildcard.getBound(), leftBound, allowUncheckedConversion);
}
});
- if (assignable != null && assignable.booleanValue()) {
+ if (assignable != null && assignable) {
return true;
}
}
@@ -1022,7 +1023,7 @@ public class TypeConversionUtil {
@Nullable
public static PsiSubstitutor getClassSubstitutor(@NotNull PsiClass superClassCandidate,
@NotNull PsiClass derivedClassCandidate,
- PsiSubstitutor derivedSubstitutor) {
+ @NotNull PsiSubstitutor derivedSubstitutor) {
if (superClassCandidate.getManager().areElementsEquivalent(superClassCandidate, derivedClassCandidate)) {
PsiTypeParameter[] baseParams = superClassCandidate.getTypeParameters();
PsiTypeParameter[] derivedParams = derivedClassCandidate.getTypeParameters();
@@ -1031,8 +1032,7 @@ public class TypeConversionUtil {
}
return derivedSubstitutor;
}
- if (!derivedClassCandidate.isInheritor(superClassCandidate, true)) return null;
- return getSuperClassSubstitutor(superClassCandidate, derivedClassCandidate, derivedSubstitutor);
+ return getMaybeSuperClassSubstitutor(superClassCandidate, derivedClassCandidate, derivedSubstitutor, null);
}
private static final Set<String> ourReportedSuperClassSubstitutorExceptions = new ConcurrentHashSet<String>();
@@ -1042,52 +1042,61 @@ public class TypeConversionUtil {
* values that they have in <code>derivedClass</code>, given that type parameters in
* <code>derivedClass</code> are bound by <code>derivedSubstitutor</code>.
* <code>superClass</code> must be a super class/interface of <code>derivedClass</code> (as in
- * <code>InheritanceUtil.isInheritor(derivedClass, superClass, true)</code>
+ * <code>InheritanceUtil.isInheritorOrSelf(derivedClass, superClass, true)</code>
*
* @return substitutor (never returns <code>null</code>)
* @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) {
- // [dsl] assertion commented out since we no longer cache isInheritor
- //LOG.assertTrue(derivedClass.isInheritor(superClass, true), "Not inheritor: " + derivedClass + " super: " + superClass);
+ if (!superClass.hasTypeParameters() && superClass.getContainingClass() == null) return PsiSubstitutor.EMPTY; //optimization and protection against EJB queer hierarchy
+
+ Set<PsiClass> visited = new THashSet<PsiClass>();
+ PsiSubstitutor substitutor = getMaybeSuperClassSubstitutor(superClass, derivedClass, derivedSubstitutor, visited);
+
+ if (substitutor == null) {
+ if (ourReportedSuperClassSubstitutorExceptions.add(derivedClass.getQualifiedName() + "/" + superClass.getQualifiedName())) {
+ reportHierarchyInconsistency(superClass, derivedClass, visited);
+ }
+ return PsiSubstitutor.EMPTY;
+ }
+ return substitutor;
+ }
- if (!superClass.hasTypeParameters() && superClass.getContainingClass() == null) return PsiSubstitutor.EMPTY; //optimization
+ // 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,
+ @Nullable Set<PsiClass> visited) {
+ if (!superClass.hasTypeParameters() && superClass.getContainingClass() == null) {
+ return InheritanceUtil.isInheritorOrSelf(derivedClass, superClass, true) ? PsiSubstitutor.EMPTY : null; //optimization
+ }
final PsiManager manager = superClass.getManager();
if (PsiUtil.isRawSubstitutor(derivedClass, derivedSubstitutor)) {
- return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createRawSubstitutor(superClass);
+ return InheritanceUtil.isInheritorOrSelf(derivedClass, superClass, true) ? JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createRawSubstitutor(superClass) : null;
}
- final PsiClass objectClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, superClass.getResolveScope());
- if (manager.areElementsEquivalent(superClass, objectClass)) {
+ if (CommonClassNames.JAVA_LANG_OBJECT_SHORT.equals(superClass.getName()) &&
+ manager.areElementsEquivalent(superClass, JavaPsiFacade.getInstance(manager.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, superClass.getResolveScope()))) {
return PsiSubstitutor.EMPTY;
}
- PsiSubstitutor substitutor;
- final Set<PsiClass> visited = new THashSet<PsiClass>();
if (derivedClass instanceof PsiAnonymousClass) {
final PsiClassType baseType = ((PsiAnonymousClass)derivedClass).getBaseClassType();
final JavaResolveResult result = baseType.resolveGenerics();
if (result.getElement() == null) return PsiSubstitutor.UNKNOWN;
- substitutor = getSuperClassSubstitutorInner(superClass, (PsiClass)result.getElement(),
- derivedSubstitutor.putAll(result.getSubstitutor()), visited, manager);
- }
- else {
- substitutor = getSuperClassSubstitutorInner(superClass, derivedClass, derivedSubstitutor, visited, manager);
+ derivedClass = (PsiClass)result.getElement();
+ derivedSubstitutor = derivedSubstitutor.putAll(result.getSubstitutor());
}
- if (substitutor == null) {
- if (ourReportedSuperClassSubstitutorExceptions.add(derivedClass.getQualifiedName() + "/" + superClass.getQualifiedName())) {
- reportHierarchyInconsistency(superClass, derivedClass, visited);
- }
- return PsiSubstitutor.EMPTY;
- }
- return substitutor;
+ return getSuperClassSubstitutorInner(superClass, derivedClass, derivedSubstitutor, visited == null ? new THashSet<PsiClass>() : visited, manager);
}
- private static void reportHierarchyInconsistency(PsiClass superClass, PsiClass derivedClass, Set<PsiClass> visited) {
+ private static void reportHierarchyInconsistency(@NotNull PsiClass superClass, @NotNull PsiClass derivedClass, @NotNull Set<PsiClass> visited) {
final StringBuilder msg = new StringBuilder("Super: " + classInfo(superClass));
msg.append("visited:\n");
for (PsiClass aClass : visited) {
@@ -1105,7 +1114,8 @@ public class TypeConversionUtil {
LOG.error(msg.toString());
}
- private static String classInfo(PsiClass aClass) {
+ @NotNull
+ private static String classInfo(@NotNull PsiClass aClass) {
String s = aClass.getQualifiedName() + "(" + aClass.getClass().getName() + "; " + PsiUtilCore.getVirtualFile(aClass) + ");\n";
s += "extends: ";
for (PsiClassType type : aClass.getExtendsListTypes()) {
@@ -1124,12 +1134,14 @@ public class TypeConversionUtil {
return getSuperClassSubstitutor(superClass, classResolveResult.getElement(), classResolveResult.getSubstitutor());
}
- private static PsiSubstitutor getSuperClassSubstitutorInner(PsiClass base,
- PsiClass candidate,
- PsiSubstitutor candidateSubstitutor,
- Set<PsiClass> visited,
- PsiManager manager) {
+ @Nullable
+ private static PsiSubstitutor getSuperClassSubstitutorInner(@NotNull PsiClass base,
+ @NotNull PsiClass candidate,
+ @NotNull PsiSubstitutor candidateSubstitutor,
+ @NotNull Set<PsiClass> visited,
+ @NotNull PsiManager manager) {
if (!visited.add(candidate)) return null;
+ assert candidateSubstitutor.isValid();
if (base == candidate) return candidateSubstitutor;
if (manager.areElementsEquivalent(base, candidate)) {
@@ -1148,19 +1160,18 @@ 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(final PsiClassType[] types, PsiSubstitutor candidateSubstitutor,
- PsiClass base,
- Set<PsiClass> set,
- PsiManager manager) {
- assert candidateSubstitutor.isValid();
+ private static PsiSubstitutor checkReferenceList(@NotNull PsiClassType[] types,
+ @NotNull PsiSubstitutor candidateSubstitutor,
+ @NotNull PsiClass base,
+ @NotNull Set<PsiClass> set,
+ @NotNull PsiManager manager) {
for (final PsiClassType type : types) {
final PsiType substitutedType = candidateSubstitutor.substitute(type);
//if (!(substitutedType instanceof PsiClassType)) return null;
@@ -1170,8 +1181,7 @@ 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;
}
@@ -1183,6 +1193,7 @@ 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);
@@ -1194,7 +1205,8 @@ public class TypeConversionUtil {
return PsiType.INT;
}
- private static PsiType unbox(PsiType type) {
+ @NotNull
+ private static PsiType unbox(@NotNull PsiType type) {
if (type instanceof PsiPrimitiveType) return type;
if (type instanceof PsiClassType) {
type = PsiPrimitiveType.getUnboxedType(type);
@@ -1393,6 +1405,7 @@ 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);
@@ -1442,7 +1455,7 @@ public class TypeConversionUtil {
}
@Nullable
- public static PsiType calcTypeForBinaryExpression(PsiType lType, PsiType rType, IElementType sign, boolean accessLType) {
+ public static PsiType calcTypeForBinaryExpression(PsiType lType, PsiType rType, @NotNull 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;
@@ -1512,321 +1525,371 @@ public class TypeConversionUtil {
}
private interface Caster {
- Object cast(Object operand);
+ @NotNull
+ Object cast(@NotNull Object operand);
}
private static final Caster[][] caster = {
{
new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
+ public Object cast(@NotNull Object operand) {
return operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Short.valueOf((short)((Number)operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (short)((Number)operand).intValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Character((char) ((Number) operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (char)((Number)operand).intValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Integer.valueOf(((Number)operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return ((Number)operand).intValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Long.valueOf(((Number)operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (long)((Number)operand).intValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Float(((Number) operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (float)((Number)operand).intValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Double(((Number) operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (double)((Number)operand).intValue();
}
}
}
,
{
new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Byte.valueOf((byte)((Short)operand).shortValue());
+ public Object cast(@NotNull Object operand) {
+ return (byte)((Short)operand).shortValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Short.valueOf(((Short)operand).shortValue());
+ public Object cast(@NotNull Object operand) {
+ return operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Character((char) ((Short) operand).shortValue());
+ public Object cast(@NotNull Object operand) {
+ return (char)((Short)operand).shortValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Integer.valueOf(((Short)operand).shortValue());
+ public Object cast(@NotNull Object operand) {
+ return (int)(Short)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Long.valueOf(((Short)operand).shortValue());
+ public Object cast(@NotNull Object operand) {
+ return (long)(Short)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Float(((Short) operand).shortValue());
+ public Object cast(@NotNull Object operand) {
+ return (float)(Short)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Double(((Short) operand).shortValue());
+ public Object cast(@NotNull Object operand) {
+ return (double)(Short)operand;
}
}
}
,
{
new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Byte.valueOf((byte)((Character)operand).charValue());
+ public Object cast(@NotNull Object operand) {
+ return (byte)((Character)operand).charValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Short.valueOf((short)((Character)operand).charValue());
+ public Object cast(@NotNull Object operand) {
+ return (short)((Character)operand).charValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Character(((Character) operand).charValue());
+ public Object cast(@NotNull Object operand) {
+ return operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Integer.valueOf(((Character)operand).charValue());
+ public Object cast(@NotNull Object operand) {
+ return (int)(Character)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Long.valueOf(((Character)operand).charValue());
+ public Object cast(@NotNull Object operand) {
+ return (long)(Character)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Float(((Character) operand).charValue());
+ public Object cast(@NotNull Object operand) {
+ return (float)(Character)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Double(((Character) operand).charValue());
+ public Object cast(@NotNull Object operand) {
+ return (double)(Character)operand;
}
}
}
,
{
new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Byte.valueOf((byte)((Integer)operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (byte)((Integer)operand).intValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Short.valueOf((short)((Integer)operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (short)((Integer)operand).intValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Character((char) ((Integer) operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (char)((Integer)operand).intValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Integer.valueOf(((Integer)operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Long.valueOf(((Integer)operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (long)(Integer)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Float(((Integer) operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (float)(Integer)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Double(((Integer) operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (double)(Integer)operand;
}
}
}
,
{
new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Byte.valueOf((byte)((Long)operand).longValue());
+ public Object cast(@NotNull Object operand) {
+ return (byte)((Long)operand).longValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Short.valueOf((short)((Long)operand).longValue());
+ public Object cast(@NotNull Object operand) {
+ return (short)((Long)operand).longValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Character((char) ((Long) operand).longValue());
+ public Object cast(@NotNull Object operand) {
+ return (char)((Long)operand).longValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Integer.valueOf((int)((Long)operand).longValue());
+ public Object cast(@NotNull Object operand) {
+ return (int)((Long)operand).longValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Long.valueOf(((Long)operand).longValue());
+ public Object cast(@NotNull Object operand) {
+ return operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Float(((Long) operand).longValue());
+ public Object cast(@NotNull Object operand) {
+ return (float)(Long)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Double(((Long) operand).longValue());
+ public Object cast(@NotNull Object operand) {
+ return (double)(Long)operand;
}
}
}
,
{
new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Byte.valueOf((byte)((Float)operand).floatValue());
+ public Object cast(@NotNull Object operand) {
+ return (byte)((Float)operand).floatValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Short.valueOf((short)((Float)operand).floatValue());
+ public Object cast(@NotNull Object operand) {
+ return (short)((Float)operand).floatValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Character((char) ((Float) operand).floatValue());
+ public Object cast(@NotNull Object operand) {
+ return (char)((Float)operand).floatValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Integer.valueOf((int)((Float)operand).floatValue());
+ public Object cast(@NotNull Object operand) {
+ return (int)((Float)operand).floatValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Long.valueOf((long)((Float)operand).floatValue());
+ public Object cast(@NotNull Object operand) {
+ return (long)((Float)operand).floatValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Float(((Float) operand).floatValue());
+ public Object cast(@NotNull Object operand) {
+ return operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Double(((Float) operand).floatValue());
+ public Object cast(@NotNull Object operand) {
+ return (double)(Float)operand;
}
}
}
,
{
new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Byte.valueOf((byte)((Double)operand).doubleValue());
+ public Object cast(@NotNull Object operand) {
+ return (byte)((Double)operand).doubleValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Short.valueOf((short)((Double)operand).doubleValue());
+ public Object cast(@NotNull Object operand) {
+ return (short)((Double)operand).doubleValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Character((char) ((Double) operand).doubleValue());
+ public Object cast(@NotNull Object operand) {
+ return (char)((Double)operand).doubleValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Integer.valueOf((int)((Double)operand).doubleValue());
+ public Object cast(@NotNull Object operand) {
+ return (int)((Double)operand).doubleValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Long.valueOf((long)((Double)operand).doubleValue());
+ public Object cast(@NotNull Object operand) {
+ return (long)((Double)operand).doubleValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Float(((Double) operand).doubleValue());
+ public Object cast(@NotNull Object operand) {
+ return new Float((Double)operand);
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Double(((Double) operand).doubleValue());
+ public Object cast(@NotNull Object operand) {
+ return operand;
}
}
}
@@ -1844,7 +1907,7 @@ public class TypeConversionUtil {
WRAPPER_TO_PRIMITIVE.put(Double.class, PsiType.DOUBLE);
}
- private static PsiType wrapperToPrimitive(Object o) {
+ private static PsiType wrapperToPrimitive(@NotNull Object o) {
return WRAPPER_TO_PRIMITIVE.get(o.getClass());
}