From 81c958ccfd127a57e1e612b0d1822fe58c49be84 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 23 May 2011 19:26:15 +0400 Subject: [PATCH] check if constructor already contains field assignment before add new one (IDEA-69792) --- ...reateConstructorParameterFromFieldFix.java | 35 ++++++++++++++----- .../impl/AssignFieldFromParameterAction.java | 2 +- .../afterAlreadyAssigned.java | 12 +++++++ .../beforeAlreadyAssigned.java | 11 ++++++ 4 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createConstructorParameterFromField/afterAlreadyAssigned.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createConstructorParameterFromField/beforeAlreadyAssigned.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorParameterFromFieldFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorParameterFromFieldFix.java index 1b5f3a8b0518..b3e2d6f19d01 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorParameterFromFieldFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorParameterFromFieldFix.java @@ -15,7 +15,6 @@ */ package com.intellij.codeInsight.daemon.impl.quickfix; -import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.CodeInsightUtilBase; import com.intellij.codeInsight.daemon.QuickFixBundle; import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil; @@ -30,12 +29,17 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.psi.*; import com.intellij.psi.impl.source.jsp.jspJava.JspClass; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTypesUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; @@ -99,11 +103,12 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction { } } }); - if (constructors.length > 1) { - - final PsiMethodMember[] members = new PsiMethodMember[constructors.length]; - for (int i = 0, constructorsLength = constructors.length; i < constructorsLength; i++) { - members[i] = new PsiMethodMember(constructors[i]); + final ArrayList constrs = filterConstructorsIfFieldAlreadyAssigned(constructors); + if (constrs.size() > 1) { + final PsiMethodMember[] members = new PsiMethodMember[constrs.size()]; + int i = 0; + for (PsiMethod constructor : constrs) { + members[i++] = new PsiMethodMember(constructor); } final List elements; if (ApplicationManager.getApplication().isUnitTestMode()) { @@ -120,11 +125,25 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction { if (!addParameterToConstructor(project, file, editor, member.getElement())) break; } - } else { - addParameterToConstructor(project, file, editor, constructors[0]); + } else if (!constrs.isEmpty()) { + addParameterToConstructor(project, file, editor, constrs.get(0)); } } + private ArrayList filterConstructorsIfFieldAlreadyAssigned(PsiMethod[] constructors) { + final ArrayList result = new ArrayList(Arrays.asList(constructors)); + for (PsiReference reference : ReferencesSearch.search(getField(), new LocalSearchScope(constructors))) { + final PsiElement element = reference.getElement(); + if (element instanceof PsiReferenceExpression && PsiUtil.isOnAssignmentLeftHand((PsiExpression)element)) { + final PsiExpression rExpression = ((PsiAssignmentExpression)element.getParent()).getRExpression(); + if (rExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression)rExpression).resolve() instanceof PsiParameter) { + result.remove(PsiTreeUtil.getParentOfType(element, PsiMethod.class)); + } + } + } + return result; + } + private boolean addParameterToConstructor(final Project project, final PsiFile file, final Editor editor, PsiMethod constructor) throws IncorrectOperationException { final PsiParameter[] parameters = constructor.getParameterList().getParameters(); PsiExpression[] expressions = new PsiExpression[parameters.length+1]; diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AssignFieldFromParameterAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AssignFieldFromParameterAction.java index b6989557af17..d38aa38b6d86 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AssignFieldFromParameterAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AssignFieldFromParameterAction.java @@ -102,7 +102,7 @@ public class AssignFieldFromParameterAction extends BaseIntentionAction { PsiClass targetClass = method.getContainingClass(); String stmtText = fieldName + " = " + parameterName + ";"; - if (Comparing.strEqual(fieldName, parameterName)) { + if (Comparing.strEqual(fieldName, parameterName) || JavaPsiFacade.getInstance(project).getResolveHelper().resolveReferencedVariable(fieldName, methodBody) != field) { @NonNls String prefix = isMethodStatic ? targetClass.getName() == null ? "" : targetClass.getName() + "." : "this."; stmtText = prefix + stmtText; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createConstructorParameterFromField/afterAlreadyAssigned.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createConstructorParameterFromField/afterAlreadyAssigned.java new file mode 100644 index 000000000000..19947eecde6c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createConstructorParameterFromField/afterAlreadyAssigned.java @@ -0,0 +1,12 @@ +// "Add constructor parameter" "true" +class A { + private final String text; + + public Foo(String text) { + this.text = text; + } + + public Foo(int i, String text) { + this.text = text; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createConstructorParameterFromField/beforeAlreadyAssigned.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createConstructorParameterFromField/beforeAlreadyAssigned.java new file mode 100644 index 000000000000..fd698dc023ea --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createConstructorParameterFromField/beforeAlreadyAssigned.java @@ -0,0 +1,11 @@ +// "Add constructor parameter" "true" +class A { + private final String text; + + public Foo(String text) { + this.text = text; + } + + public Foo(int i) { + } +} \ No newline at end of file