check if constructor already contains field assignment before add new one (IDEA-69792)

This commit is contained in:
anna
2011-05-23 20:56:20 +04:00
parent c862b52ae8
commit 81c958ccfd
4 changed files with 51 additions and 9 deletions
@@ -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<PsiMethod> 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<PsiMethodMember> 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<PsiMethod> filterConstructorsIfFieldAlreadyAssigned(PsiMethod[] constructors) {
final ArrayList<PsiMethod> result = new ArrayList<PsiMethod>(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];
@@ -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;
}
@@ -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;
}
}
@@ -0,0 +1,11 @@
// "Add constructor parameter" "true"
class A {
private final String te<caret>xt;
public Foo(String text) {
this.text = text;
}
public Foo(int i) {
}
}