public static String buildCollectionText(PsiForStatement forStatement) { PsiStatement body = forStatement.getBody(); while (body instanceof PsiBlockStatement) { final PsiBlockStatement blockStatement = (PsiBlockStatement) body; final PsiCodeBlock codeBlock = blockStatement.getCodeBlock(); final PsiStatement[] statements = codeBlock.getStatements(); if (statements.length == 2) { body = statements[1]; } else if (statements.length == 1) { body = statements[0]; } else { return null; } } if (!(body instanceof PsiExpressionStatement)) { return null; } final PsiExpressionStatement expressionStatement = (PsiExpressionStatement) body; final PsiExpression expression = expressionStatement.getExpression(); if (!(expression instanceof PsiMethodCallExpression)) { return null; } final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) expression; final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); final PsiElement qualifier = methodExpression.getQualifier(); if (qualifier == null) { // fixme for when the array is added to 'this' return null; } return qualifier.getText(); }
@Nullable private static PsiStatement getBody(PsiLoopStatement forStatement) { PsiStatement body = forStatement.getBody(); while (body instanceof PsiBlockStatement) { final PsiBlockStatement blockStatement = (PsiBlockStatement) body; final PsiCodeBlock codeBlock = blockStatement.getCodeBlock(); final PsiStatement[] statements = codeBlock.getStatements(); body = statements.length == 0 ? null : statements[0]; } return body; }
@Nullable private PsiStatement getFirstStatement(PsiStatement body) { if (!(body instanceof PsiBlockStatement)) { return body; } final PsiBlockStatement block = (PsiBlockStatement) body; final PsiCodeBlock codeBlock = block.getCodeBlock(); final PsiStatement[] statements = codeBlock.getStatements(); if (statements.length <= 0) { return null; } return statements[0]; }
private void surroundWithCodeBlock(@NotNull final MoveInfo info, final boolean down) { try { final Document document = PsiDocumentManager.getInstance(statementToSurroundWithCodeBlock.getProject()) .getDocument(statementToSurroundWithCodeBlock.getContainingFile()); int startOffset = document.getLineStartOffset(info.toMove.startLine); int endOffset = getLineStartSafeOffset(document, info.toMove.endLine); if (document.getText().charAt(endOffset - 1) == '\n') endOffset--; final RangeMarker lineRangeMarker = document.createRangeMarker(startOffset, endOffset); final PsiElementFactory factory = JavaPsiFacade.getInstance(statementToSurroundWithCodeBlock.getProject()) .getElementFactory(); PsiCodeBlock codeBlock = factory.createCodeBlock(); codeBlock.add(statementToSurroundWithCodeBlock); final PsiBlockStatement blockStatement = (PsiBlockStatement) factory.createStatementFromText("{}", statementToSurroundWithCodeBlock); blockStatement.getCodeBlock().replace(codeBlock); PsiBlockStatement newStatement = (PsiBlockStatement) statementToSurroundWithCodeBlock.replace(blockStatement); newStatement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(newStatement); info.toMove = new LineRange( document.getLineNumber(lineRangeMarker.getStartOffset()), document.getLineNumber(lineRangeMarker.getEndOffset()) + 1); PsiCodeBlock newCodeBlock = newStatement.getCodeBlock(); if (down) { PsiElement blockChild = firstNonWhiteElement(newCodeBlock.getFirstBodyElement(), true); if (blockChild == null) blockChild = newCodeBlock.getRBrace(); info.toMove2 = new LineRange( info.toMove2 .startLine, // document.getLineNumber(newCodeBlock.getParent().getTextRange().getStartOffset()), document.getLineNumber(blockChild.getTextRange().getStartOffset())); } else { int start = document.getLineNumber(newCodeBlock.getRBrace().getTextRange().getStartOffset()); int end = info.toMove.startLine; if (start > end) end = start; info.toMove2 = new LineRange(start, end); } } catch (IncorrectOperationException e) { LOG.error(e); } }
@Override public void visitBlockStatement(PsiBlockStatement statement) { final PsiElement parent = statement.getParent(); final boolean isAlreadyCounted = parent instanceof PsiDoWhileStatement || parent instanceof PsiWhileStatement || parent instanceof PsiForStatement || parent instanceof PsiIfStatement || parent instanceof PsiSynchronizedStatement; if (!isAlreadyCounted) { enterScope(statement); } super.visitBlockStatement(statement); }
private static boolean bodyIsArrayToCollectionCopy( PsiStatement body, PsiVariable variable, boolean shouldBeOffsetArrayAccess) { if (body instanceof PsiExpressionStatement) { final PsiExpressionStatement expressionStatement = (PsiExpressionStatement) body; final PsiExpression expression = expressionStatement.getExpression(); return expressionIsArrayToCollectionCopy(expression, variable, shouldBeOffsetArrayAccess); } else if (body instanceof PsiBlockStatement) { final PsiBlockStatement blockStatement = (PsiBlockStatement) body; final PsiCodeBlock codeBlock = blockStatement.getCodeBlock(); final PsiStatement[] statements = codeBlock.getStatements(); if (statements.length == 1) { return bodyIsArrayToCollectionCopy(statements[0], variable, shouldBeOffsetArrayAccess); } else if (statements.length == 2) { final PsiStatement statement = statements[0]; if (!(statement instanceof PsiDeclarationStatement)) { return false; } final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement) statement; final PsiElement[] declaredElements = declarationStatement.getDeclaredElements(); if (declaredElements.length != 1) { return false; } final PsiElement declaredElement = declaredElements[0]; if (!(declaredElement instanceof PsiVariable)) { return false; } final PsiVariable localVariable = (PsiVariable) declaredElement; final PsiExpression initializer = localVariable.getInitializer(); if (!ExpressionUtils.isOffsetArrayAccess(initializer, variable)) { return false; } return bodyIsArrayToCollectionCopy(statements[1], localVariable, false); } } return false; }
public static boolean statementsAreEquivalent( @Nullable PsiStatement statement1, @Nullable PsiStatement statement2) { if (statement1 == null) { return statement2 == null; } else if (statement2 == null) { return false; } if (statement1.getClass() != statement2.getClass()) { if (statement1 instanceof PsiBlockStatement && !(statement2 instanceof PsiBlockStatement)) { final PsiBlockStatement blockStatement = (PsiBlockStatement) statement1; final PsiStatement[] statements = blockStatement.getCodeBlock().getStatements(); if (statements.length != 1) { return false; } statement1 = statements[0]; } else if (!(statement1 instanceof PsiBlockStatement) && statement2 instanceof PsiBlockStatement) { final PsiBlockStatement blockStatement = (PsiBlockStatement) statement2; final PsiStatement[] statements = blockStatement.getCodeBlock().getStatements(); if (statements.length != 1) { return false; } statement2 = statements[0]; } else { return false; } if (statement1.getClass() != statement2.getClass()) { return false; } } if (statement1 instanceof PsiAssertStatement) { return assertStatementsAreEquivalent( (PsiAssertStatement) statement1, (PsiAssertStatement) statement2); } if (statement1 instanceof PsiBlockStatement) { return blockStatementsAreEquivalent( (PsiBlockStatement) statement1, (PsiBlockStatement) statement2); } if (statement1 instanceof PsiBreakStatement) { return breakStatementsAreEquivalent( (PsiBreakStatement) statement1, (PsiBreakStatement) statement2); } if (statement1 instanceof PsiContinueStatement) { return continueStatementsAreEquivalent( (PsiContinueStatement) statement1, (PsiContinueStatement) statement2); } if (statement1 instanceof PsiDeclarationStatement) { return declarationStatementsAreEquivalent( (PsiDeclarationStatement) statement1, (PsiDeclarationStatement) statement2); } if (statement1 instanceof PsiDoWhileStatement) { return doWhileStatementsAreEquivalent( (PsiDoWhileStatement) statement1, (PsiDoWhileStatement) statement2); } if (statement1 instanceof PsiEmptyStatement) { return true; } if (statement1 instanceof PsiExpressionListStatement) { return expressionListStatementsAreEquivalent( (PsiExpressionListStatement) statement1, (PsiExpressionListStatement) statement2); } if (statement1 instanceof PsiExpressionStatement) { return expressionStatementsAreEquivalent( (PsiExpressionStatement) statement1, (PsiExpressionStatement) statement2); } if (statement1 instanceof PsiForStatement) { return forStatementsAreEquivalent((PsiForStatement) statement1, (PsiForStatement) statement2); } if (statement1 instanceof PsiForeachStatement) { return forEachStatementsAreEquivalent( (PsiForeachStatement) statement1, (PsiForeachStatement) statement2); } if (statement1 instanceof PsiIfStatement) { return ifStatementsAreEquivalent((PsiIfStatement) statement1, (PsiIfStatement) statement2); } if (statement1 instanceof PsiLabeledStatement) { return labeledStatementsAreEquivalent( (PsiLabeledStatement) statement1, (PsiLabeledStatement) statement2); } if (statement1 instanceof PsiReturnStatement) { return returnStatementsAreEquivalent( (PsiReturnStatement) statement1, (PsiReturnStatement) statement2); } if (statement1 instanceof PsiSwitchStatement) { return switchStatementsAreEquivalent( (PsiSwitchStatement) statement1, (PsiSwitchStatement) statement2); } if (statement1 instanceof PsiSwitchLabelStatement) { return switchLabelStatementsAreEquivalent( (PsiSwitchLabelStatement) statement1, (PsiSwitchLabelStatement) statement2); } if (statement1 instanceof PsiSynchronizedStatement) { return synchronizedStatementsAreEquivalent( (PsiSynchronizedStatement) statement1, (PsiSynchronizedStatement) statement2); } if (statement1 instanceof PsiThrowStatement) { return throwStatementsAreEquivalent( (PsiThrowStatement) statement1, (PsiThrowStatement) statement2); } if (statement1 instanceof PsiTryStatement) { return tryStatementsAreEquivalent((PsiTryStatement) statement1, (PsiTryStatement) statement2); } if (statement1 instanceof PsiWhileStatement) { return whileStatementsAreEquivalent( (PsiWhileStatement) statement1, (PsiWhileStatement) statement2); } final String text1 = statement1.getText(); final String text2 = statement2.getText(); return text1.equals(text2); }
private static boolean blockStatementsAreEquivalent( @NotNull PsiBlockStatement statement1, @NotNull PsiBlockStatement statement2) { final PsiCodeBlock block1 = statement1.getCodeBlock(); final PsiCodeBlock block2 = statement2.getCodeBlock(); return codeBlocksAreEquivalent(block1, block2); }
@Override public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiReferenceExpression parameterReference = (PsiReferenceExpression) descriptor.getPsiElement(); final PsiElement target = parameterReference.resolve(); if (!(target instanceof PsiParameter)) { return; } final PsiParameter parameter = (PsiParameter) target; final PsiElement declarationScope = parameter.getDeclarationScope(); final PsiElement body; if (declarationScope instanceof PsiMethod) { final PsiMethod method = (PsiMethod) declarationScope; body = method.getBody(); } else if (declarationScope instanceof PsiCatchSection) { final PsiCatchSection catchSection = (PsiCatchSection) declarationScope; body = catchSection.getCatchBlock(); } else if (declarationScope instanceof PsiLoopStatement) { final PsiLoopStatement forStatement = (PsiLoopStatement) declarationScope; final PsiStatement forBody = forStatement.getBody(); if (forBody instanceof PsiBlockStatement) { final PsiBlockStatement blockStatement = (PsiBlockStatement) forBody; body = blockStatement.getCodeBlock(); } else { body = forBody; } } else { return; } if (body == null) { return; } final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); final String parameterName = parameterReference.getText(); final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project); final String variableName = javaCodeStyleManager.suggestUniqueVariableName(parameterName, parameterReference, true); final SearchScope scope = parameter.getUseScope(); final Query<PsiReference> search = ReferencesSearch.search(parameter, scope); final PsiReference reference = search.findFirst(); if (reference == null) { return; } final PsiElement element = reference.getElement(); if (!(element instanceof PsiReferenceExpression)) { return; } final PsiReferenceExpression firstReference = (PsiReferenceExpression) element; final PsiElement[] children = body.getChildren(); final int startIndex; final int endIndex; if (body instanceof PsiCodeBlock) { startIndex = 1; endIndex = children.length - 1; } else { startIndex = 0; endIndex = children.length; } boolean newDeclarationCreated = false; final StringBuilder buffer = new StringBuilder(); for (int i = startIndex; i < endIndex; i++) { final PsiElement child = children[i]; newDeclarationCreated |= replaceVariableName(child, firstReference, variableName, parameterName, buffer); } final String replacementText; if (newDeclarationCreated) { replacementText = "{" + buffer + '}'; } else { final PsiType type = parameterReference.getType(); if (type == null) { return; } final String className = type.getCanonicalText(); replacementText = '{' + className + ' ' + variableName + " = " + parameterName + ';' + buffer + '}'; } final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory(); final PsiCodeBlock block = elementFactory.createCodeBlockFromText(replacementText, null); body.replace(block); codeStyleManager.reformat(declarationScope); }