diff --git a/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java b/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java index 72ce2af64906..80f7b255305a 100644 --- a/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java +++ b/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java @@ -4,10 +4,13 @@ import com.intellij.codeInsight.controlflow.ControlFlow; import com.intellij.codeInsight.controlflow.ControlFlowBuilder; import com.intellij.codeInsight.controlflow.Instruction; import com.intellij.codeInsight.controlflow.impl.InstructionImpl; +import com.intellij.lang.ASTNode; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiElement; +import com.intellij.psi.tree.TokenSet; import com.intellij.psi.util.PsiTreeUtil; +import com.jetbrains.python.PyElementTypes; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PyAugAssignmentStatementNavigator; import com.jetbrains.python.psi.impl.PyImportStatementNavigator; @@ -21,6 +24,8 @@ import java.util.List; */ public class PyControlFlowBuilder extends PyRecursiveElementVisitor { + public static final TokenSet CALL_OR_REF_EXPR = TokenSet.create(PyElementTypes.CALL_EXPRESSION, PyElementTypes.REFERENCE_EXPRESSION); + public static final String SELF_ASSERT_RAISES = "self.assertRaises"; private final ControlFlowBuilder myBuilder = new ControlFlowBuilder(); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -586,4 +591,40 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor { body.accept(this); } } + + @Override + public void visitPyWithStatement(final PyWithStatement node) { + boolean withSelfAssertRaises = false; + final PyWithItem[] items = node.getWithItems(); + if (items.length == 1){ + final PyWithItem item = items[0]; + final ASTNode callNode = item.getNode().findChildByType(CALL_OR_REF_EXPR); + if (callNode != null) { + final PsiElement element = callNode.getPsi(); + if (element instanceof PyCallExpression) { + withSelfAssertRaises = SELF_ASSERT_RAISES.equals(((PyCallExpression)element).getCallee().getText()); + } + if (element instanceof PyReferenceExpression){ + withSelfAssertRaises = SELF_ASSERT_RAISES.equals(element.getText()); + } + } + } + super.visitPyWithStatement(node); + if (withSelfAssertRaises){ + myBuilder.processPending(new ControlFlowBuilder.PendingProcessor() { + public void process(final PsiElement pendingScope, final Instruction instruction) { + final PsiElement element = instruction.getElement(); + if (element == null){ + myBuilder.addPendingEdge(pendingScope, instruction); + } + else if (PsiTreeUtil.getParentOfType(element, PyRaiseStatement.class) != null){ + myBuilder.addPendingEdge(node, instruction); + } + else { + myBuilder.addPendingEdge(pendingScope, instruction); + } + } + }); + } + } } \ No newline at end of file