private void areExitStatementsTheSame() throws ExitStatementsNotSameException { if (myExitStatements.isEmpty()) { throw new ExitStatementsNotSameException(); } PsiStatement first = null; for (PsiStatement statement : myExitStatements) { if (first == null) { first = statement; continue; } if (!PsiEquivalenceUtil.areElementsEquivalent(first, statement)) { throw new ExitStatementsNotSameException(); } } myFirstExitStatementCopy = (PsiStatement) first.copy(); }
@NotNull public PsiVariable[] getOutputVariables(boolean collectVariablesAtExitPoints) { PsiVariable[] myOutputVariables = ControlFlowUtil.getOutputVariables( myControlFlow, myFlowStart, myFlowEnd, myExitPoints.toArray()); if (collectVariablesAtExitPoints) { // variables declared in selected block used in return statements are to be considered output // variables when extracting guard methods final Set<PsiVariable> outputVariables = new HashSet<>(Arrays.asList(myOutputVariables)); for (PsiStatement statement : myExitStatements) { statement.accept( new JavaRecursiveElementVisitor() { @Override public void visitReferenceExpression(PsiReferenceExpression expression) { super.visitReferenceExpression(expression); final PsiElement resolved = expression.resolve(); if (resolved instanceof PsiVariable) { final PsiVariable variable = (PsiVariable) resolved; if (isWrittenInside(variable)) { outputVariables.add(variable); } } } private boolean isWrittenInside(final PsiVariable variable) { final List<Instruction> instructions = myControlFlow.getInstructions(); for (int i = myFlowStart; i < myFlowEnd; i++) { Instruction instruction = instructions.get(i); if (instruction instanceof WriteVariableInstruction && variable.equals(((WriteVariableInstruction) instruction).variable)) { return true; } } return false; } }); } myOutputVariables = outputVariables.toArray(new PsiVariable[outputVariables.size()]); } Arrays.sort(myOutputVariables, PsiUtil.BY_POSITION); return myOutputVariables; }
public PsiStatement getExitStatementCopy( PsiElement returnStatement, final PsiElement[] elements) { PsiStatement exitStatementCopy = null; // replace all exit-statements such as break's or continue's with appropriate return for (PsiStatement exitStatement : myExitStatements) { if (exitStatement instanceof PsiReturnStatement) { if (!myGenerateConditionalExit) continue; } else if (exitStatement instanceof PsiBreakStatement) { PsiStatement statement = ((PsiBreakStatement) exitStatement).findExitedStatement(); if (statement == null) continue; int startOffset = myControlFlow.getStartOffset(statement); int endOffset = myControlFlow.getEndOffset(statement); if (myFlowStart <= startOffset && endOffset <= myFlowEnd) continue; } else if (exitStatement instanceof PsiContinueStatement) { PsiStatement statement = ((PsiContinueStatement) exitStatement).findContinuedStatement(); if (statement == null) continue; int startOffset = myControlFlow.getStartOffset(statement); int endOffset = myControlFlow.getEndOffset(statement); if (myFlowStart <= startOffset && endOffset <= myFlowEnd) continue; } else { LOG.error(String.valueOf(exitStatement)); continue; } int index = -1; for (int j = 0; j < elements.length; j++) { if (exitStatement.equals(elements[j])) { index = j; break; } } if (exitStatementCopy == null) { if (needExitStatement(exitStatement)) { exitStatementCopy = (PsiStatement) exitStatement.copy(); } } PsiElement result = exitStatement.replace(returnStatement); if (index >= 0) { elements[index] = result; } } return exitStatementCopy; }
private static String wrapInBlock(PsiStatement body) { if (body instanceof PsiExpressionStatement) { return ((PsiExpressionStatement) body).getExpression().getText(); } final String bodyText = body.getText(); if (!(body instanceof PsiBlockStatement)) { return "{" + bodyText + "}"; } return bodyText; }