mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-111571 (boxing and unboxing with a cast not reported by inspections)
This commit is contained in:
+9
-3
@@ -111,7 +111,7 @@ public class AutoBoxingInspection extends BaseInspection {
|
||||
@Override
|
||||
public void doFix(Project project, ProblemDescriptor descriptor) {
|
||||
final PsiExpression expression = (PsiExpression)descriptor.getPsiElement();
|
||||
final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, false);
|
||||
final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, false, true);
|
||||
if (expectedType == null) {
|
||||
return;
|
||||
}
|
||||
@@ -146,7 +146,13 @@ public class AutoBoxingInspection extends BaseInspection {
|
||||
else {
|
||||
newExpression = classToConstruct + ".valueOf(" + expressionText + ')';
|
||||
}
|
||||
replaceExpression(expression, newExpression);
|
||||
final PsiElement parent = expression.getParent();
|
||||
if (parent instanceof PsiTypeCastExpression) {
|
||||
final PsiTypeCastExpression typeCastExpression = (PsiTypeCastExpression)parent;
|
||||
replaceExpression(typeCastExpression, newExpression);
|
||||
} else {
|
||||
replaceExpression(expression, newExpression);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shortcutReplace(PsiExpression expression, String classToConstruct) {
|
||||
@@ -303,7 +309,7 @@ public class AutoBoxingInspection extends BaseInspection {
|
||||
if (boxedType == null) {
|
||||
return;
|
||||
}
|
||||
final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, false);
|
||||
final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, false, true);
|
||||
if (expectedType == null || ClassUtils.isPrimitive(expectedType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
+37
-16
@@ -37,9 +37,7 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class AutoUnboxingInspection extends BaseInspection {
|
||||
|
||||
@@ -59,6 +57,19 @@ public class AutoUnboxingInspection extends BaseInspection {
|
||||
s_unboxingMethods.put("char", "charValue");
|
||||
}
|
||||
|
||||
@NonNls static final Set<String> unboxableTypes = new HashSet(9);
|
||||
static {
|
||||
unboxableTypes.add(CommonClassNames.JAVA_LANG_BYTE);
|
||||
unboxableTypes.add(CommonClassNames.JAVA_LANG_SHORT);
|
||||
unboxableTypes.add(CommonClassNames.JAVA_LANG_INTEGER);
|
||||
unboxableTypes.add(CommonClassNames.JAVA_LANG_LONG);
|
||||
unboxableTypes.add(CommonClassNames.JAVA_LANG_FLOAT);
|
||||
unboxableTypes.add(CommonClassNames.JAVA_LANG_DOUBLE);
|
||||
unboxableTypes.add(CommonClassNames.JAVA_LANG_BOOLEAN);
|
||||
unboxableTypes.add(CommonClassNames.JAVA_LANG_CHARACTER);
|
||||
unboxableTypes.add(CommonClassNames.JAVA_LANG_OBJECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
@@ -131,7 +142,7 @@ public class AutoUnboxingInspection extends BaseInspection {
|
||||
if (type == null) {
|
||||
return;
|
||||
}
|
||||
final PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(type);
|
||||
final PsiPrimitiveType unboxedType = (PsiPrimitiveType)ExpectedTypeUtils.findExpectedType(expression, false, true);
|
||||
if (unboxedType == null) {
|
||||
return;
|
||||
}
|
||||
@@ -140,7 +151,11 @@ public class AutoUnboxingInspection extends BaseInspection {
|
||||
final PsiElementFactory factory = psiFacade.getElementFactory();
|
||||
final PsiElement parent = expression.getParent();
|
||||
final String expressionText = expression.getText();
|
||||
if (parent instanceof PsiPrefixExpression && !unboxedType.equalsToText("boolean")) {
|
||||
if (parent instanceof PsiTypeCastExpression) {
|
||||
final PsiTypeCastExpression typeCastExpression = (PsiTypeCastExpression)parent;
|
||||
replaceExpression(typeCastExpression, newExpressionText);
|
||||
}
|
||||
else if (parent instanceof PsiPrefixExpression && !unboxedType.equalsToText("boolean")) {
|
||||
final PsiPrefixExpression prefixExpression = (PsiPrefixExpression)parent;
|
||||
final IElementType tokenType = prefixExpression.getOperationTokenType();
|
||||
if (JavaTokenType.PLUSPLUS.equals(tokenType)) {
|
||||
@@ -205,7 +220,7 @@ public class AutoUnboxingInspection extends BaseInspection {
|
||||
}
|
||||
}
|
||||
|
||||
private static String buildNewExpressionText(PsiExpression expression, PsiType unboxedType) {
|
||||
private static String buildNewExpressionText(PsiExpression expression, PsiPrimitiveType unboxedType) {
|
||||
final String unboxedTypeText = unboxedType.getCanonicalText();
|
||||
final String expressionText = expression.getText();
|
||||
final String boxMethodName = s_unboxingMethods.get(unboxedTypeText);
|
||||
@@ -225,6 +240,10 @@ public class AutoUnboxingInspection extends BaseInspection {
|
||||
return argument.getText();
|
||||
}
|
||||
}
|
||||
final PsiType type = expression.getType();
|
||||
if (type != null && type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
|
||||
return "((" + unboxedType.getBoxedTypeName() + ')' + expressionText + ")." + boxMethodName + "()";
|
||||
}
|
||||
return expressionText + '.' + boxMethodName + "()";
|
||||
}
|
||||
|
||||
@@ -365,21 +384,23 @@ public class AutoUnboxingInspection extends BaseInspection {
|
||||
if (TypeConversionUtil.isPrimitiveAndNotNull(expressionType)) {
|
||||
return;
|
||||
}
|
||||
final PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(expressionType);
|
||||
if (unboxedType == null) {
|
||||
if (!isUnboxable(expressionType)) {
|
||||
return;
|
||||
}
|
||||
final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, false);
|
||||
if (expectedType == null) {
|
||||
return;
|
||||
}
|
||||
if (!TypeConversionUtil.isPrimitiveAndNotNull(expectedType)) {
|
||||
return;
|
||||
}
|
||||
if (!expectedType.isAssignableFrom(unboxedType)) {
|
||||
final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, false, true);
|
||||
if (expectedType == null || !TypeConversionUtil.isPrimitiveAndNotNull(expectedType)) {
|
||||
return;
|
||||
}
|
||||
registerError(expression, expression);
|
||||
}
|
||||
|
||||
private static boolean isUnboxable(PsiType type) {
|
||||
if (!(type instanceof PsiClassType)) {
|
||||
return false;
|
||||
}
|
||||
final PsiClassType classType = (PsiClassType)type;
|
||||
final PsiClass aClass = classType.resolve();
|
||||
return aClass != null && unboxableTypes.contains(aClass.getQualifiedName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-2
@@ -33,6 +33,10 @@ public class ExpectedTypeUtils {
|
||||
|
||||
@Nullable
|
||||
public static PsiType findExpectedType(@NotNull PsiExpression expression, boolean calculateTypeForComplexReferences) {
|
||||
return findExpectedType(expression, calculateTypeForComplexReferences, false);
|
||||
}
|
||||
|
||||
public static PsiType findExpectedType(PsiExpression expression, boolean calculateTypeForComplexReferences, boolean reportCasts) {
|
||||
PsiElement context = expression.getParent();
|
||||
PsiExpression wrappedExpression = expression;
|
||||
while (context instanceof PsiParenthesizedExpression) {
|
||||
@@ -42,7 +46,7 @@ public class ExpectedTypeUtils {
|
||||
if (context == null) {
|
||||
return null;
|
||||
}
|
||||
final ExpectedTypeVisitor visitor = new ExpectedTypeVisitor(wrappedExpression, calculateTypeForComplexReferences);
|
||||
final ExpectedTypeVisitor visitor = new ExpectedTypeVisitor(wrappedExpression, calculateTypeForComplexReferences, reportCasts);
|
||||
context.accept(visitor);
|
||||
return visitor.getExpectedType();
|
||||
}
|
||||
@@ -92,11 +96,13 @@ public class ExpectedTypeUtils {
|
||||
|
||||
@NotNull private final PsiExpression wrappedExpression;
|
||||
private final boolean calculateTypeForComplexReferences;
|
||||
private final boolean reportCasts;
|
||||
private PsiType expectedType = null;
|
||||
|
||||
ExpectedTypeVisitor(@NotNull PsiExpression wrappedExpression, boolean calculateTypeForComplexReferences) {
|
||||
ExpectedTypeVisitor(@NotNull PsiExpression wrappedExpression, boolean calculateTypeForComplexReferences, boolean reportCasts) {
|
||||
this.wrappedExpression = wrappedExpression;
|
||||
this.calculateTypeForComplexReferences = calculateTypeForComplexReferences;
|
||||
this.reportCasts = reportCasts;
|
||||
}
|
||||
|
||||
public PsiType getExpectedType() {
|
||||
@@ -295,6 +301,13 @@ public class ExpectedTypeUtils {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeCastExpression(PsiTypeCastExpression expression) {
|
||||
if (reportCasts) {
|
||||
expectedType = expression.getType();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWhileStatement(@NotNull PsiWhileStatement whileStatement) {
|
||||
expectedType = PsiType.BOOLEAN;
|
||||
|
||||
@@ -53,4 +53,9 @@ public class AutoBoxing {
|
||||
void doInstanceof(Object o) {
|
||||
Boolean b = o instanceof String;
|
||||
}
|
||||
|
||||
void m(boolean b) {
|
||||
System.out.println((Boolean)b);
|
||||
final Object o1 = (Object) b;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,4 +93,18 @@
|
||||
<description>Auto-boxing <code>o instanceof String</code> #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>AutoBoxing.java</file>
|
||||
<line>58</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Auto-boxing</problem_class>
|
||||
<description>Auto-boxing <code>b</code> #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>AutoBoxing.java</file>
|
||||
<line>59</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Auto-boxing</problem_class>
|
||||
<description>Auto-boxing <code>b</code> #loc</description>
|
||||
</problem>
|
||||
|
||||
</problems>
|
||||
@@ -53,4 +53,9 @@ public class AutoUnboxing {
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
void m(Object o, Boolean b) {
|
||||
if ((boolean) o) {}
|
||||
if ((boolean) b) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,4 +85,17 @@
|
||||
<description>Auto-unboxing <code>i</code> #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>AutoUnboxing.java</file>
|
||||
<line>58</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Auto-unboxing</problem_class>
|
||||
<description>Auto-unboxing <code>o</code> #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>AutoUnboxing.java</file>
|
||||
<line>59</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Auto-unboxing</problem_class>
|
||||
<description>Auto-unboxing <code>b</code> #loc</description>
|
||||
</problem>
|
||||
</problems>
|
||||
Reference in New Issue
Block a user