convert field to local: clear final modifier when used for write (IDEA-192735)

This commit is contained in:
Anna Kozlova
2018-05-28 17:26:12 +03:00
parent 038384a6e3
commit 323a164d0c
5 changed files with 53 additions and 16 deletions

View File

@@ -176,6 +176,12 @@ public abstract class BaseConvertToLocalQuickFix<V extends PsiVariable> implemen
NotNullFunction<PsiDeclarationStatement, PsiElement> action,
Collection<PsiReference> references) {
final PsiDeclarationStatement declaration = elementFactory.createVariableDeclarationStatement(localName, variable.getType(), initializer);
if (references.stream()
.map(PsiReference::getElement)
.anyMatch(element -> element instanceof PsiExpression &&
PsiUtil.isAccessedForWriting((PsiExpression)element))) {
PsiUtil.setModifierProperty((PsiLocalVariable)declaration.getDeclaredElements()[0], PsiModifier.FINAL, false);
}
final PsiElement newDeclaration = action.fun(declaration);
retargetReferences(elementFactory, localName, references);
return newDeclaration;

View File

@@ -20,13 +20,14 @@ import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.codeInspection.util.SpecialAnnotationsUtil;
import com.intellij.lang.java.JavaCommenter;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.PsiCodeBlock;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiReference;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.util.RefactoringUtil;
@@ -132,18 +133,5 @@ public class FieldCanBeLocalInspection extends FieldCanBeLocalInspectionBase {
final String localName = styleManager.propertyNameToVariableName(propertyName, VariableKind.LOCAL_VARIABLE);
return RefactoringUtil.suggestUniqueVariableName(localName, scope, field);
}
private static void moveDocCommentToDeclaration(@NotNull Project project, @NotNull PsiDocComment docComment, @NotNull PsiElement declaration) {
final StringBuilder buf = new StringBuilder();
for (PsiElement psiElement : docComment.getDescriptionElements()) {
buf.append(psiElement.getText());
}
if (buf.length() > 0) {
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
final JavaCommenter commenter = new JavaCommenter();
final PsiComment comment = elementFactory.createCommentFromText(commenter.getBlockCommentPrefix() + buf.toString() + commenter.getBlockCommentSuffix(), declaration);
declaration.getParent().addBefore(comment, declaration);
}
}
}
}

View File

@@ -0,0 +1,9 @@
// "Convert to local" "true"
class Test {
int getFoo1() {
int myFoo = 1;
myFoo = 5;
return myFoo;
}
}

View File

@@ -0,0 +1,10 @@
// "Convert to local" "true"
class Test {
private int my<caret>Foo;
int getFoo1() {
myFoo = 1;
myFoo = 5;
return myFoo;
}
}

View File

@@ -15,13 +15,19 @@
*/
package com.intellij.java.codeInsight.daemon.quickFix;
import com.intellij.application.options.CodeStyle;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.varScopeCanBeNarrowed.FieldCanBeLocalInspection;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
import org.jetbrains.annotations.NotNull;
public class ConvertFieldToLocalTest extends LightQuickFixParameterizedTestCase {
private boolean myGenerateFinalLocals;
@NotNull
@Override
protected LocalInspectionTool[] configureLocalInspectionTools() {
@@ -32,6 +38,24 @@ public class ConvertFieldToLocalTest extends LightQuickFixParameterizedTestCase
public void test() { doAllTests(); }
@Override
protected void setUp() throws Exception {
super.setUp();
JavaCodeStyleSettings settings = CodeStyle.getSettings(getProject()).getCustomSettings(JavaCodeStyleSettings.class);
myGenerateFinalLocals = settings.GENERATE_FINAL_LOCALS;
settings.GENERATE_FINAL_LOCALS = StringUtil.containsIgnoreCase(getTestName(true), "final");
}
@Override
protected void tearDown() throws Exception {
try {
CodeStyle.getSettings(getProject()).getCustomSettings(JavaCodeStyleSettings.class).GENERATE_FINAL_LOCALS = myGenerateFinalLocals;
}
finally {
super.tearDown();
}
}
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/convert2Local";