diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/BindFieldsFromParametersAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/BindFieldsFromParametersAction.java index f8e0c6b07fc4..0c0e6bde9a65 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/BindFieldsFromParametersAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/BindFieldsFromParametersAction.java @@ -29,7 +29,10 @@ import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.Key; import com.intellij.psi.*; import com.intellij.psi.codeStyle.*; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; @@ -302,9 +305,12 @@ public class BindFieldsFromParametersAction extends BaseIntentionAction implemen String name = names[0]; if (targetClass != null) { for (String curName : names) { - if (!usedNames.contains(curName) && targetClass.findFieldByName(curName, false) != null) { - name = curName; - break; + if (!usedNames.contains(curName)) { + final PsiField fieldByName = targetClass.findFieldByName(curName, false); + if (fieldByName != null && (!method.isConstructor() || !isFieldAssigned(fieldByName, method)) && fieldByName.getType().isAssignableFrom(parameter.getType())) { + name = curName; + break; + } } } } @@ -339,6 +345,15 @@ public class BindFieldsFromParametersAction extends BaseIntentionAction implemen }); } + private static boolean isFieldAssigned(PsiField field, PsiMethod method) { + for (PsiReference reference : ReferencesSearch.search(field, new LocalSearchScope(method))) { + if (reference instanceof PsiReferenceExpression && PsiUtil.isOnAssignmentLeftHand((PsiReferenceExpression)reference)) { + return true; + } + } + return false; + } + @Override public boolean startInWriteAction() { return false; diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/FieldFromParameterUtils.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/FieldFromParameterUtils.java index 826264793908..aa644cd96a20 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/FieldFromParameterUtils.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/FieldFromParameterUtils.java @@ -193,7 +193,8 @@ public final class FieldFromParameterUtils { final boolean isStatic, final boolean isFinal) throws IncorrectOperationException { PsiManager psiManager = PsiManager.getInstance(project); - PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory(); + final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(psiManager.getProject()); + PsiElementFactory factory = psiFacade.getElementFactory(); PsiField field = factory.createField(fieldName, fieldType); @@ -216,7 +217,9 @@ public final class FieldFromParameterUtils { Pair fieldAnchor = anchorRef.get(); String stmtText = fieldName + " = " + parameter.getName() + ";"; - if (fieldName.equals(parameter.getName())) { + + final PsiVariable variable = psiFacade.getResolveHelper().resolveReferencedVariable(fieldName, methodBody); + if (variable != null && !(variable instanceof PsiField)) { String prefix = isStatic ? targetClass.getName() == null ? "" : targetClass.getName() + "." : "this."; stmtText = prefix + stmtText; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterSameNamedFieldWithIncompatibleTYpe.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterSameNamedFieldWithIncompatibleTYpe.java new file mode 100644 index 000000000000..7742c745ee5c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterSameNamedFieldWithIncompatibleTYpe.java @@ -0,0 +1,11 @@ +// "Bind constructor parameters to fields" "true" +class BindField { + private final String myAgent; + private final Integer myInstrumentAgent; + + public BindField(String agent, Integer instrumentAgent) { + + myAgent = agent; + myInstrumentAgent = instrumentAgent; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeSameNamedFieldWithIncompatibleTYpe.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeSameNamedFieldWithIncompatibleTYpe.java new file mode 100644 index 000000000000..7db27463e7a5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeSameNamedFieldWithIncompatibleTYpe.java @@ -0,0 +1,8 @@ +// "Bind constructor parameters to fields" "true" +class BindField { + private final String myAgent; + + public BindField(String agent, Integer instrumentAgent) { + + } +} \ No newline at end of file