@Override public void visitUnaryExpression(GrUnaryExpression expression) { final GrExpression operand = expression.getOperand(); if (operand == null) return; if (expression.getOperationTokenType() != mLNOT) { operand.accept(this); visitCall(expression); return; } ConditionInstruction cond = new ConditionInstruction(expression); addNodeAndCheckPending(cond); registerCondition(cond); operand.accept(this); visitCall(expression); myConditions.removeFirstOccurrence(cond); List<GotoInstruction> negations = collectAndRemoveAllPendingNegations(expression); InstructionImpl head = myHead; addNodeAndCheckPending(new PositiveGotoInstruction(expression, cond)); handlePossibleReturn(expression); addPendingEdge(expression, myHead); if (negations.isEmpty()) { myHead = head; } else { myHead = reduceAllNegationsIntoInstruction(expression, negations); } }
public void visitAssertStatement(GrAssertStatement assertStatement) { final InstructionImpl assertInstruction = startNode(assertStatement); final GrExpression assertion = assertStatement.getAssertion(); if (assertion != null) { assertion.accept(this); InstructionImpl positiveHead = myHead; List<GotoInstruction> negations = collectAndRemoveAllPendingNegations(assertStatement); if (!negations.isEmpty()) { interruptFlow(); reduceAllNegationsIntoInstruction(assertStatement, negations); } GrExpression errorMessage = assertStatement.getErrorMessage(); if (errorMessage != null) { errorMessage.accept(this); } addNode(new ThrowingInstruction(assertStatement)); final PsiType type = TypesUtil.createTypeByFQClassName( CommonClassNames.JAVA_LANG_ASSERTION_ERROR, assertStatement); ExceptionInfo info = findCatch(type); if (info != null) { info.myThrowers.add(myHead); } else { addPendingEdge(null, myHead); } myHead = positiveHead; } finishNode(assertInstruction); }
@Override public void visitCaseSection(GrCaseSection caseSection) { for (GrCaseLabel label : caseSection.getCaseLabels()) { GrExpression value = label.getValue(); if (value != null) { value.accept(this); } } final GrStatement[] statements = caseSection.getStatements(); // infer 'may be return' position int i; for (i = statements.length - 1; i >= 0 && statements[i] instanceof GrBreakStatement; i--) {} for (int j = 0; j < statements.length; j++) { GrStatement statement = statements[j]; statement.accept(this); if (j == i) handlePossibleReturn(statement); } if (myHead != null) { addPendingEdge(caseSection, myHead); } }
public void visitAssignmentExpression(GrAssignmentExpression expression) { GrExpression lValue = expression.getLValue(); if (expression.getOperationTokenType() != mASSIGN) { if (lValue instanceof GrReferenceExpression && myPolicy.isReferenceAccepted((GrReferenceExpression) lValue)) { String referenceName = ((GrReferenceExpression) lValue).getReferenceName(); if (referenceName != null) { addNodeAndCheckPending(new ReadWriteVariableInstruction(referenceName, lValue, READ)); } } } GrExpression rValue = expression.getRValue(); if (rValue != null) { rValue.accept(this); lValue.accept(this); } }
@Override public void visitElvisExpression(GrElvisExpression expression) { GrExpression condition = expression.getCondition(); GrExpression elseBranch = expression.getElseBranch(); condition.accept(this); List<GotoInstruction> negations = collectAndRemoveAllPendingNegations(expression); InstructionImpl head = myHead; handlePossibleReturn(condition); addPendingEdge(expression, myHead); myHead = head; if (elseBranch != null) { head = reduceAllNegationsIntoInstruction(expression, negations); if (head != null) myHead = head; elseBranch.accept(this); handlePossibleReturn(elseBranch); } }
private void addForLoopBreakingEdge(GrForStatement forStatement, @Nullable GrForClause clause) { if (clause instanceof GrTraditionalForClause) { final GrExpression condition = ((GrTraditionalForClause) clause).getCondition(); if (condition != null) { condition.accept(this); if (!alwaysTrue(condition)) { addPendingEdge(forStatement, myHead); // break cycle } } } else { addPendingEdge(forStatement, myHead); // break cycle } }
public void visitReturnStatement(GrReturnStatement returnStatement) { boolean isNodeNeeded = myHead == null || myHead.getElement() != returnStatement; final GrExpression value = returnStatement.getReturnValue(); if (value != null) value.accept(this); if (isNodeNeeded) { InstructionImpl returnInstruction = startNode(returnStatement); addPendingEdge(null, myHead); finishNode(returnInstruction); } else { addPendingEdge(null, myHead); } interruptFlow(); }
public void visitThrowStatement(GrThrowStatement throwStatement) { final GrExpression exception = throwStatement.getException(); if (exception == null) return; exception.accept(this); final InstructionImpl throwInstruction = new ThrowingInstruction(throwStatement); addNodeAndCheckPending(throwInstruction); interruptFlow(); final PsiType type = getNominalTypeNoRecursion(exception); if (type != null) { ExceptionInfo info = findCatch(type); if (info != null) { info.myThrowers.add(throwInstruction); } else { addPendingEdge(null, throwInstruction); } } else { addPendingEdge(null, throwInstruction); } }
@Override public void visitBinaryExpression(GrBinaryExpression expression) { final GrExpression left = expression.getLeftOperand(); final GrExpression right = expression.getRightOperand(); final IElementType opType = expression.getOperationTokenType(); if (ControlFlowBuilderUtil.isInstanceOfBinary(expression)) { expression.getLeftOperand().accept(this); processInstanceOf(expression); return; } if (opType != mLOR && opType != mLAND && opType != kIN) { left.accept(this); if (right != null) { right.accept(this); } visitCall(expression); return; } ConditionInstruction condition = new ConditionInstruction(expression); addNodeAndCheckPending(condition); registerCondition(condition); left.accept(this); if (right == null) return; final List<GotoInstruction> negations = collectAndRemoveAllPendingNegations(expression); visitCall(expression); if (opType == mLAND) { InstructionImpl head = myHead; if (negations.isEmpty()) { addNode(new NegatingGotoInstruction(expression, condition)); handlePossibleReturn(expression); addPendingEdge(expression, myHead); } else { for (GotoInstruction negation : negations) { myHead = negation; handlePossibleReturn(expression); addPendingEdge(expression, myHead); } } myHead = head; } else /*if (opType == mLOR)*/ { final InstructionImpl instruction = addNodeAndCheckPending( new InstructionImpl(expression)); // collect all pending edges from left argument handlePossibleReturn(expression); addPendingEdge(expression, myHead); myHead = instruction; InstructionImpl head = reduceAllNegationsIntoInstruction(expression, negations); if (head != null) myHead = head; // addNode(new NegatingGotoInstruction(expression, myInstructionNumber++, condition)); } myConditions.removeFirstOccurrence(condition); right.accept(this); }
@Override public void visitParenthesizedExpression(GrParenthesizedExpression expression) { final GrExpression operand = expression.getOperand(); if (operand != null) operand.accept(this); }