@Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { PsiElement element = descriptor.getStartElement(); if (!(element instanceof PsiLoopStatement)) return; PsiLoopStatement loop = (PsiLoopStatement) element; IteratorDeclaration declaration; declaration = IteratorDeclaration.fromLoop(loop); if (declaration == null) return; PsiStatement body = loop.getBody(); if (!(body instanceof PsiBlockStatement)) return; PsiStatement[] statements = ((PsiBlockStatement) body).getCodeBlock().getStatements(); PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); String replacement = null; CommentTracker ct = new CommentTracker(); if (statements.length == 2 && statements[1] instanceof PsiIfStatement) { PsiVariable variable = declaration.getNextElementVariable(statements[0]); if (variable == null) return; PsiExpression condition = ((PsiIfStatement) statements[1]).getCondition(); if (condition == null) return; replacement = generateRemoveIf(declaration, ct, condition, variable.getName()); } else if (statements.length == 1 && statements[0] instanceof PsiIfStatement) { PsiExpression condition = ((PsiIfStatement) statements[0]).getCondition(); if (condition == null) return; PsiElement ref = declaration.findOnlyIteratorRef(condition); if (ref != null) { PsiElement call = ref.getParent().getParent(); if (!declaration.isIteratorMethodCall(call, "next")) return; PsiType type = ((PsiExpression) call).getType(); JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project); SuggestedNameInfo info = javaCodeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, type); if (info.names.length == 0) { info = javaCodeStyleManager.suggestVariableName( VariableKind.PARAMETER, "value", null, type); } String paramName = javaCodeStyleManager.suggestUniqueVariableName(info, condition, true).names[0]; ct.replace(call, factory.createIdentifier(paramName)); replacement = generateRemoveIf(declaration, ct, condition, paramName); } } if (replacement == null) return; ct.delete(declaration.getIterator()); PsiElement result = ct.replaceAndRestoreComments(loop, replacement); LambdaCanBeMethodReferenceInspection.replaceAllLambdasWithMethodReferences(result); CodeStyleManager.getInstance(project).reformat(result); }
@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; }
@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); }