IDEA-92833 Type inference doesn't update type after assert instanceof

This commit is contained in:
Max Medvedev
2012-10-17 15:29:34 +04:00
parent dca6846a6a
commit 53283e2322
7 changed files with 101 additions and 39 deletions
@@ -89,4 +89,5 @@ public interface CommonClassNames {
String TARGET_ANNOTATION_FQ_NAME = "java.lang.annotation.Target";
@NonNls String JAVA_LANG_RUNNABLE = "java.lang.Runnable";
@NonNls String JAVA_IO_FILE = "java.io.File";
String JAVA_LANG_ASSERTION_ERROR = "java.lang.AssertionError";
}
@@ -61,7 +61,7 @@ class IfStatementPredicate implements PsiElementPredicate {
}
final PsiClass aClass = (PsiClass)target;
final String qualifiedName = aClass.getQualifiedName();
return "java.lang.AssertionError".equals(qualifiedName);
return CommonClassNames.JAVA_LANG_ASSERTION_ERROR.equals(qualifiedName);
}
else if (element instanceof PsiBlockStatement) {
final PsiBlockStatement blockStatement =
@@ -378,25 +378,34 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
}
public void visitAssertStatement(GrAssertStatement assertStatement) {
final InstructionImpl assertInstruction = startNode(assertStatement);
final GrExpression assertion = assertStatement.getAssertion();
if (assertion != null) {
myConditions.push(addNodeAndCheckPending(new ConditionInstruction(assertion)));
assertion.accept(this);
final InstructionImpl assertInstruction = startNode(assertStatement);
InstructionImpl positiveHead = myHead;
interruptFlow();
List<GotoInstruction> negations = collectAndRemoveAllPendingNegations(assertStatement);
reduceAllNegationsIntoInstruction(assertStatement, negations);
GrExpression errorMessage = assertStatement.getErrorMessage();
if (errorMessage != null) {
errorMessage.accept(this);
}
final PsiType type = TypesUtil.createTypeByFQClassName("java.lang.AssertionError", assertStatement);
final PsiType type = TypesUtil.createTypeByFQClassName(CommonClassNames.JAVA_LANG_ASSERTION_ERROR, assertStatement);
ExceptionInfo info = findCatch(type);
if (info != null) {
info.myThrowers.add(assertInstruction);
info.myThrowers.add(myHead);
}
else {
addPendingEdge(null, assertInstruction);
addPendingEdge(null, myHead);
}
finishNode(assertInstruction);
myHead = positiveHead;
}
finishNode(assertInstruction);
}
public void visitThrowStatement(GrThrowStatement throwStatement) {
@@ -525,7 +534,9 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
return instruction;
}
else if (negations.size() == 1) {
return negations.get(0);
GotoInstruction instruction = negations.get(0);
myHead = instruction;
return instruction;
}
return null;
}
@@ -17,37 +17,37 @@ import org.jetbrains.plugins.groovy.util.TestUtils
public class ControlFlowTest extends LightCodeInsightFixtureTestCase {
final String basePath = TestUtils.testDataPath + "groovy/controlFlow/"
public void testAssignment() throws Throwable { doTest(); }
public void testClosure1() throws Throwable { doTest(); }
public void testComplexAssign() throws Throwable { doTest(); }
public void testFor1() throws Throwable { doTest(); }
public void testForeach1() throws Throwable { doTest(); }
public void testGrvy1497() throws Throwable { doTest(); }
public void testIf1() throws Throwable { doTest(); }
public void testMultipleAssignment() throws Throwable { doTest(); }
public void testNested() throws Throwable { doTest(); }
public void testReturn() throws Throwable { doTest(); }
public void testSwitch1() throws Throwable { doTest(); }
public void testSwitch2() throws Throwable { doTest(); }
public void testSwitch3() throws Throwable { doTest(); }
public void testSwitch4() throws Throwable { doTest(); }
public void testSwitch5() throws Throwable { doTest(); }
public void testThrow1() throws Throwable { doTest(); }
public void testThrowInCatch() throws Throwable { doTest(); }
public void testTry1() throws Throwable { doTest(); }
public void testTry2() throws Throwable { doTest(); }
public void testTry3() throws Throwable { doTest(); }
public void testTry4() throws Throwable { doTest(); }
public void testTry5() throws Throwable { doTest(); }
public void testTry6() throws Throwable { doTest(); }
public void testTry7() throws Throwable { doTest(); }
public void testTry8() throws Throwable { doTest(); }
public void testTry9() throws Throwable { doTest(); }
public void testTry10() throws Throwable { doTest(); }
public void testWhile1() throws Throwable { doTest(); }
public void testWhile2() throws Throwable { doTest(); }
public void testWhileNonConstant() throws Throwable { doTest(); }
public void testIfInstanceofElse() throws Throwable { doTest(); }
public void testAssignment() { doTest(); }
public void testClosure1() { doTest(); }
public void testComplexAssign() { doTest(); }
public void testFor1() { doTest(); }
public void testForeach1() { doTest(); }
public void testGrvy1497() { doTest(); }
public void testIf1() { doTest(); }
public void testMultipleAssignment() { doTest(); }
public void testNested() { doTest(); }
public void testReturn() { doTest(); }
public void testSwitch1() { doTest(); }
public void testSwitch2() { doTest(); }
public void testSwitch3() { doTest(); }
public void testSwitch4() { doTest(); }
public void testSwitch5() { doTest(); }
public void testThrow1() { doTest(); }
public void testThrowInCatch() { doTest(); }
public void testTry1() { doTest(); }
public void testTry2() { doTest(); }
public void testTry3() { doTest(); }
public void testTry4() { doTest(); }
public void testTry5() { doTest(); }
public void testTry6() { doTest(); }
public void testTry7() { doTest(); }
public void testTry8() { doTest(); }
public void testTry9() { doTest(); }
public void testTry10() { doTest(); }
public void testWhile1() { doTest(); }
public void testWhile2() { doTest(); }
public void testWhileNonConstant() { doTest(); }
public void testIfInstanceofElse() { doTest(); }
public void testReturnMapFromClosure() {doTest();}
public void testSwitchInTryWithThrows() {doTest();}
public void testClosure() {doTest();}
@@ -56,6 +56,8 @@ public class ControlFlowTest extends LightCodeInsightFixtureTestCase {
public void testOrInReturn() {doTest();}
public void testVarInString() {doTest();}
public void testMayBeStaticWithCondition() {doTest()}
public void testAssert0() { doTest() }
public void testAssert1() { doTest() }
public void doTest() {
final List<String> input = TestUtils.readInput(testDataPath + getTestName(true) + ".test");
@@ -568,6 +568,15 @@ def method(List<? extends Tx> t) {
''', 'Tx')
}
void testAssert() {
doTest('''\
def foo(def var) {
assert var instanceof String
va<caret>r.isEmpty()
}
''', 'java.lang.String')
}
private void doTest(String text, String type) {
def file = myFixture.configureByText('_.groovy', text)
def ref = file.findReferenceAt(myFixture.editor.caretModel.offset) as GrReferenceExpression
+14
View File
@@ -0,0 +1,14 @@
assert x instanceof String : bar()
return x.isEmpty()
-----
0(1) element: null
1(2) element: ASSERT statement
2(3) READ x
3(4,6) Condition Instanceof expression
4(5) instanceof: x instanceof String
5(7) Negating goto instruction, condition=3Instanceof expression
6(8) instanceof: x instanceof String
7(10) READ bar
8(9) READ x
9(10) element: RETURN statement
10() element: null
+25
View File
@@ -0,0 +1,25 @@
try {
assert x instanceof String : bar()
}
catch (java.lang.AssertionError e) {
return true
}
return x.isEmpty()
-----
0(1) element: null
1(2) element: Open block
2(3) element: ASSERT statement
3(4) READ x
4(5,7) Condition Instanceof expression
5(6) instanceof: x instanceof String
6(8) Negating goto instruction, condition=4Instanceof expression
7(13) instanceof: x instanceof String
8(9) READ bar
9(10) THROW. element: Method call
10(11) element: Catch clause
11(12) WRITE e
12(15) element: RETURN statement
13(14) READ x
14(15) element: RETURN statement
15() element: null