diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java index ce8d5d733085..8d70438b8d4e 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -57,6 +57,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { private DfaValue myError; private DfaValue myString; private PsiType myNpe; + private PsiType myAssertionError; private Stack myElementStack = new Stack(); /** @@ -75,6 +76,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { myRuntimeException = myFactory.createTypeValue(createClassType(manager, scope, JAVA_LANG_RUNTIME_EXCEPTION), Nullness.NOT_NULL); myError = myFactory.createTypeValue(createClassType(manager, scope, JAVA_LANG_ERROR), Nullness.NOT_NULL); myNpe = createClassType(manager, scope, JAVA_LANG_NULL_POINTER_EXCEPTION); + myAssertionError = createClassType(manager, scope, JAVA_LANG_ASSERTION_ERROR); myString = myFactory.createTypeValue(createClassType(manager, scope, JAVA_LANG_STRING), Nullness.NOT_NULL); PsiParameter mockVar = JavaPsiFacade.getElementFactory(manager.getProject()).createParameter("$exception$", createClassType(manager, scope, JAVA_LANG_OBJECT)); @@ -93,7 +95,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { myCurrentFlow.setFields(myFields.toArray(new DfaVariableValue[myFields.size()])); - addInstruction(new ReturnInstruction()); + addInstruction(new ReturnInstruction(false)); return myCurrentFlow; } @@ -215,7 +217,9 @@ class ControlFlowAnalyzer extends JavaElementVisitor { if (description != null) { description.accept(this); } - addInstruction(new ReturnInstruction()); + + initException(myAssertionError); + addThrowCode(false); } finishElement(statement); } @@ -542,7 +546,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { addInstruction(new GotoInstruction(finallyOffset)); } else { - addInstruction(new ReturnInstruction()); + addInstruction(new ReturnInstruction(false)); } } @@ -657,7 +661,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { if (exception != null) { exception.accept(this); if (myCatchStack.isEmpty()) { - addInstruction(new ReturnInstruction()); + addInstruction(new ReturnInstruction(true)); finishElement(statement); return; } @@ -670,10 +674,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { addInstruction(gotoInstruction); addInstruction(new PopInstruction()); - addInstruction(new PushInstruction(myExceptionHolder, null)); - addInstruction(new PushInstruction(myFactory.createTypeValue(myNpe, Nullness.NOT_NULL), null)); - addInstruction(new AssignInstruction(null)); - addInstruction(new PopInstruction()); + initException(myNpe); addThrowCode(false); gotoInstruction.setOffset(myCurrentFlow.getInstructionCount()); @@ -729,7 +730,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { // the exception object should be in $exception$ variable private void addThrowCode(boolean catchRethrow) { if (myCatchStack.isEmpty()) { - addInstruction(new ReturnInstruction()); + addInstruction(new ReturnInstruction(true)); return; } @@ -742,7 +743,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { i--; } if (i < 0) { - addInstruction(new ReturnInstruction()); + addInstruction(new ReturnInstruction(true)); return; } cd = myCatchStack.get(i); @@ -877,7 +878,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { myCatchStack.pop(); finallyBlock.accept(this); - //if $exception$==null => continue normal exectuion + //if $exception$==null => continue normal execution addInstruction(new PushInstruction(myExceptionHolder, null)); addInstruction(new PushInstruction(myFactory.getConstFactory().getNull(), null)); addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, statement.getProject())); @@ -1301,16 +1302,20 @@ class ControlFlowAnalyzer extends JavaElementVisitor { ConditionalGotoInstruction cond = new ConditionalGotoInstruction(null, false, null); addInstruction(cond); addInstruction(new EmptyStackInstruction()); - addInstruction(new PushInstruction(myExceptionHolder, null)); - addInstruction(new PushInstruction(myFactory.createTypeValue(ref, Nullness.NOT_NULL), null)); - addInstruction(new AssignInstruction(null)); - addInstruction(new PopInstruction()); + initException(ref); addThrowCode(false); cond.setOffset(myCurrentFlow.getInstructionCount()); } } } + private void initException(PsiType ref) { + addInstruction(new PushInstruction(myExceptionHolder, null)); + addInstruction(new PushInstruction(myFactory.createTypeValue(ref, Nullness.NOT_NULL), null)); + addInstruction(new AssignInstruction(null)); + addInstruction(new PopInstruction()); + } + @Override public void visitMethodCallExpression(PsiMethodCallExpression expression) { startElement(expression); @@ -1448,7 +1453,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { returnCheckingFinally(); break; case SYSTEM_EXIT: - addInstruction(new ReturnInstruction()); + addInstruction(new ReturnInstruction(true)); break; } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java index d3c1d87c3ee8..55c00001fc01 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java @@ -27,6 +27,15 @@ package com.intellij.codeInspection.dataFlow.instructions; import com.intellij.codeInspection.dataFlow.*; public class ReturnInstruction extends Instruction { + private final boolean isViaException; + + public ReturnInstruction(boolean isViaException) { + this.isViaException = isViaException; + } + + public boolean isViaException() { + return isViaException; + } @Override public DfaInstructionState[] accept(DataFlowRunner runner, DfaMemoryState stateBefore, InstructionVisitor visitor) {