mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-142002 (Invalid CastConflictsWithInstanceof warning)
This commit is contained in:
+44
-9
@@ -35,6 +35,41 @@ public class InstanceOfUtils {
|
||||
}
|
||||
final PsiClassType rawType = classType.rawType();
|
||||
final InstanceofChecker checker = new InstanceofChecker(operand, rawType, false);
|
||||
PsiStatement sibling = PsiTreeUtil.getParentOfType(context, PsiStatement.class);
|
||||
sibling = PsiTreeUtil.getPrevSiblingOfType(sibling, PsiStatement.class);
|
||||
while (sibling != null) {
|
||||
if (sibling instanceof PsiIfStatement) {
|
||||
final PsiIfStatement ifStatement = (PsiIfStatement)sibling;
|
||||
final PsiExpression condition = ifStatement.getCondition();
|
||||
if (condition != null) {
|
||||
if (!ControlFlowUtils.statementMayCompleteNormally(ifStatement.getThenBranch())) {
|
||||
checker.negate = true;
|
||||
checker.checkExpression(condition);
|
||||
if (checker.hasAgreeingInstanceof()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if (!ControlFlowUtils.statementMayCompleteNormally(ifStatement.getElseBranch())) {
|
||||
checker.negate = false;
|
||||
checker.checkExpression(condition);
|
||||
if (checker.hasAgreeingInstanceof()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sibling instanceof PsiAssertStatement) {
|
||||
final PsiAssertStatement assertStatement = (PsiAssertStatement)sibling;
|
||||
final PsiExpression condition = assertStatement.getAssertCondition();
|
||||
checker.negate = false;
|
||||
checker.checkExpression(condition);
|
||||
if (checker.hasAgreeingInstanceof()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
sibling = PsiTreeUtil.getPrevSiblingOfType(sibling, PsiStatement.class);
|
||||
}
|
||||
checker.negate = false;
|
||||
PsiElement parent = PsiTreeUtil.getParentOfType(context, PsiIfStatement.class, PsiConditionalExpression.class,
|
||||
PsiPolyadicExpression.class);
|
||||
while (parent != null) {
|
||||
@@ -82,7 +117,7 @@ public class InstanceOfUtils {
|
||||
private final PsiReferenceExpression referenceExpression;
|
||||
private final PsiType castType;
|
||||
private final boolean strict;
|
||||
private boolean inElse = false;
|
||||
private boolean negate = false;
|
||||
private PsiInstanceOfExpression conflictingInstanceof = null;
|
||||
private boolean agreeingInstanceof = false;
|
||||
|
||||
@@ -110,21 +145,21 @@ public class InstanceOfUtils {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!inElse && conflictingInstanceof != null) {
|
||||
if (!negate && conflictingInstanceof != null) {
|
||||
agreeingInstanceof = false;
|
||||
}
|
||||
}
|
||||
else if (tokenType == JavaTokenType.OROR) {
|
||||
for (PsiExpression operand : expression.getOperands()) {
|
||||
if (operand instanceof PsiPrefixExpression && ((PsiPrefixExpression)operand).getOperationTokenType() == JavaTokenType.EXCL) {
|
||||
inElse = true;
|
||||
negate = true;
|
||||
}
|
||||
checkExpression(operand);
|
||||
if (agreeingInstanceof) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (inElse && conflictingInstanceof != null) {
|
||||
if (negate && conflictingInstanceof != null) {
|
||||
agreeingInstanceof = false;
|
||||
}
|
||||
}
|
||||
@@ -133,9 +168,9 @@ public class InstanceOfUtils {
|
||||
@Override
|
||||
public void visitIfStatement(PsiIfStatement ifStatement) {
|
||||
final PsiStatement branch = ifStatement.getElseBranch();
|
||||
inElse = branch != null &&
|
||||
negate = branch != null &&
|
||||
PsiTreeUtil.isAncestor(branch, referenceExpression, true);
|
||||
if (inElse) {
|
||||
if (negate) {
|
||||
if (branch instanceof PsiBlockStatement) {
|
||||
final PsiBlockStatement blockStatement =
|
||||
(PsiBlockStatement)branch;
|
||||
@@ -162,13 +197,13 @@ public class InstanceOfUtils {
|
||||
@Override
|
||||
public void visitConditionalExpression(PsiConditionalExpression expression) {
|
||||
final PsiExpression elseExpression = expression.getElseExpression();
|
||||
inElse = elseExpression != null && PsiTreeUtil.isAncestor(elseExpression, referenceExpression, true);
|
||||
negate = elseExpression != null && PsiTreeUtil.isAncestor(elseExpression, referenceExpression, true);
|
||||
checkExpression(expression.getCondition());
|
||||
}
|
||||
|
||||
private void checkExpression(PsiExpression expression) {
|
||||
expression = PsiUtil.deparenthesizeExpression(expression);
|
||||
if (inElse) {
|
||||
if (negate) {
|
||||
if (expression instanceof PsiPrefixExpression) {
|
||||
final PsiPrefixExpression prefixExpression =
|
||||
(PsiPrefixExpression)expression;
|
||||
@@ -202,7 +237,7 @@ public class InstanceOfUtils {
|
||||
agreeingInstanceof = true;
|
||||
conflictingInstanceof = null;
|
||||
}
|
||||
else if (isConflicting(instanceOfExpression)) {
|
||||
else if (isConflicting(instanceOfExpression) && conflictingInstanceof == null) {
|
||||
conflictingInstanceof = instanceOfExpression;
|
||||
}
|
||||
}
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
public class Test {
|
||||
void foo(Object o) {
|
||||
if (o instanceof Number) {
|
||||
assert o instanceof Integer;
|
||||
Integer i = (Integer)o;
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
public class Test {
|
||||
void foo(Object o) {
|
||||
if (o instanceof Number) {
|
||||
assert o instanceof String;
|
||||
Integer i = (Integer)<caret>o;
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
class AssertCheckBefore {
|
||||
void m(Object child, Object parent) {
|
||||
if (parent instanceof Number) {
|
||||
if (child instanceof String) {
|
||||
assert parent instanceof Integer;
|
||||
Integer attribute = (Integer) parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
class IfCheckBefore {
|
||||
void m(Object child, Object parent) {
|
||||
if (parent instanceof Number) {
|
||||
if (child instanceof String) {
|
||||
if (!(parent instanceof Integer)) {
|
||||
return;
|
||||
}
|
||||
Integer attribute = (Integer) parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
class IfCheckBefore {
|
||||
void m(Object child, Object parent) {
|
||||
if (parent instanceof Number) {
|
||||
if (child instanceof String) {
|
||||
if ((parent instanceof Integer)) {
|
||||
System.out.println(parent);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
Integer attribute = (Integer) parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -49,6 +49,18 @@ public class CastConflictsWithInstanceofInspectionTest extends LightInspectionTe
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIfCheckBefore() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIfElseCheckBefore() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testAssertCheckBefore() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
|
||||
+4
@@ -49,6 +49,10 @@ public class CastConflictsWithInstanceofFixesTest extends IGQuickFixesTestCase {
|
||||
assertQuickfixNotAvailable("Replace 'E' with 'String' in cast");
|
||||
}
|
||||
|
||||
public void testReplaceInstanceofInFront() {
|
||||
doTest("replaceInstanceofInFront", "Replace 'String' with 'Integer' in instanceof");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getRelativePath() {
|
||||
return "bugs/castConflicts";
|
||||
|
||||
Reference in New Issue
Block a user