From 5d77379fd36bc2b6e4913d2a154e1ee0f1759eb6 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 29 May 2018 20:51:26 +0300 Subject: [PATCH] create field from parameter even if parameter is already used in assignment IDEA-192896 --- .../impl/CreateFieldFromParameterAction.java | 2 +- .../impl/FieldFromParameterUtils.java | 27 ++++++++++++++++--- .../afterAlreadyAssigned.java | 13 +++++++++ .../beforeAlreadyAssigned.java | 9 +++++++ 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter/afterAlreadyAssigned.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter/beforeAlreadyAssigned.java diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterAction.java index c41da34b4a38..21b62a0f1df9 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterAction.java @@ -32,7 +32,7 @@ public class CreateFieldFromParameterAction extends CreateFieldFromParameterActi protected boolean isAvailable(PsiParameter psiParameter) { final PsiType type = getSubstitutedType(psiParameter); final PsiClass targetClass = PsiTreeUtil.getParentOfType(psiParameter, PsiClass.class); - return FieldFromParameterUtils.isAvailable(psiParameter, type, targetClass) && + return FieldFromParameterUtils.isAvailable(psiParameter, type, targetClass, false) && psiParameter.getLanguage().isKindOf(JavaLanguage.INSTANCE); } 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 8168ae2fe60a..2f5e3e4e7415 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 @@ -109,10 +109,22 @@ public final class FieldFromParameterUtils { @Nullable public static PsiField getParameterAssignedToField(final PsiParameter parameter) { + return getParameterAssignedToField(parameter, true); + } + + @Nullable + public static PsiField getParameterAssignedToField(final PsiParameter parameter, boolean findIndirectAssignments) { for (PsiReference reference : ReferencesSearch.search(parameter, new LocalSearchScope(parameter.getDeclarationScope()), false)) { if (!(reference instanceof PsiReferenceExpression)) continue; final PsiReferenceExpression expression = (PsiReferenceExpression)reference; - PsiAssignmentExpression assignmentExpression = PsiTreeUtil.getParentOfType(expression, PsiAssignmentExpression.class, true, PsiClass.class); + PsiAssignmentExpression assignmentExpression; + if (findIndirectAssignments) { + assignmentExpression = PsiTreeUtil.getParentOfType(expression, PsiAssignmentExpression.class, true, PsiClass.class); + } + else { + PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent()); + assignmentExpression = parent instanceof PsiAssignmentExpression ? (PsiAssignmentExpression)parent : null; + } if (assignmentExpression == null) continue; if (!PsiTreeUtil.isAncestor(assignmentExpression.getRExpression(), expression, false)) continue; final PsiExpression lExpression = assignmentExpression.getLExpression(); @@ -256,7 +268,16 @@ public final class FieldFromParameterUtils { } } - public static boolean isAvailable(@Nullable PsiParameter myParameter, @Nullable PsiType type, @Nullable PsiClass targetClass) { + public static boolean isAvailable(@Nullable PsiParameter myParameter, + @Nullable PsiType type, + @Nullable PsiClass targetClass) { + return isAvailable(myParameter, type, targetClass, true); + } + + public static boolean isAvailable(@Nullable PsiParameter myParameter, + @Nullable PsiType type, + @Nullable PsiClass targetClass, + boolean findIndirectAssignments) { return myParameter != null && myParameter.isValid() && myParameter.getManager().isInProject(myParameter) @@ -266,7 +287,7 @@ public final class FieldFromParameterUtils { && type.isValid() && targetClass != null && !targetClass.isInterface() - && getParameterAssignedToField(myParameter) == null; + && getParameterAssignedToField(myParameter, findIndirectAssignments) == null; } private FieldFromParameterUtils() { } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter/afterAlreadyAssigned.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter/afterAlreadyAssigned.java new file mode 100644 index 000000000000..09f7020a5315 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter/afterAlreadyAssigned.java @@ -0,0 +1,13 @@ +// "Create field for parameter 'p1'" "true" + +class Test{ + int b; + @org.jetbrains.annotations.NotNull + private final String myP1; + + Test(String p1){ + b = p1.length(); + myP1 = p1; + } +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter/beforeAlreadyAssigned.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter/beforeAlreadyAssigned.java new file mode 100644 index 000000000000..be50296fbff5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter/beforeAlreadyAssigned.java @@ -0,0 +1,9 @@ +// "Create field for parameter 'p1'" "true" + +class Test{ + int b; + Test(String p1){ + b = p1.length(); + } +} +