From d46f76eda19b2d733a9145cda278ca165f6cebf5 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 9 Feb 2015 18:31:38 +0100 Subject: [PATCH] deep delete parameter: ensure parameter used in the same call passed to another params is not suggested --- .../safeDelete/SafeDeleteJavaCallerChooser.java | 17 ++++++++++++----- ...teParameterUsedInNextArgumentExpression.java | 7 +++++++ ...meterUsedInNextArgumentExpression_after.java | 7 +++++++ .../intellij/refactoring/SafeDeleteTest.java | 4 ++++ 4 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 java/java-tests/testData/refactoring/safeDelete/NoDeepDeleteParameterUsedInNextArgumentExpression.java create mode 100644 java/java-tests/testData/refactoring/safeDelete/NoDeepDeleteParameterUsedInNextArgumentExpression_after.java diff --git a/java/java-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteJavaCallerChooser.java b/java/java-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteJavaCallerChooser.java index 7a3ec7efc825..85bbd0fe4436 100644 --- a/java/java-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteJavaCallerChooser.java +++ b/java/java-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteJavaCallerChooser.java @@ -105,7 +105,7 @@ abstract class SafeDeleteJavaCallerChooser extends JavaCallerChooser { /** * @return parameter if it is used inside method only as argument in nodeMethod call at parameterIndex */ - static PsiParameter isTheOnlyOneParameterUsage(PsiElement call, int parameterIndex, final PsiMethod nodeMethod) { + static PsiParameter isTheOnlyOneParameterUsage(PsiElement call, final int parameterIndex, final PsiMethod nodeMethod) { if (call instanceof PsiCallExpression) { final PsiExpressionList argumentList = ((PsiCallExpression)call).getArgumentList(); if (argumentList != null) { @@ -129,6 +129,7 @@ abstract class SafeDeleteJavaCallerChooser extends JavaCallerChooser { if (parameter != null && !parameter.isVarArgs()) { final PsiElement scope = parameter.getDeclarationScope(); if (scope instanceof PsiMethod && ((PsiMethod)scope).findDeepestSuperMethods().length == 0) { + final int scopeParamIdx = ((PsiMethod)scope).getParameterList().getParameterIndex(parameter); final Ref ref = new Ref(false); if (ReferencesSearch.search(parameter, new LocalSearchScope(scope)).forEach(new Processor() { @Override @@ -139,11 +140,11 @@ abstract class SafeDeleteJavaCallerChooser extends JavaCallerChooser { while (parent != null) { final PsiMethod resolved = parent.resolveMethod(); if (scope.equals(resolved)) { - if (usedInQualifier(element, parent)) return false; + if (usedInQualifier(element, parent, scopeParamIdx)) return false; return true; } if (nodeMethod.equals(resolved)) { - if (usedInQualifier(element, parent)) return false; + if (usedInQualifier(element, parent, parameterIndex)) return false; ref.set(true); return true; } @@ -154,7 +155,7 @@ abstract class SafeDeleteJavaCallerChooser extends JavaCallerChooser { return true; } - private boolean usedInQualifier(PsiElement element, PsiCallExpression parent) { + private boolean usedInQualifier(PsiElement element, PsiCallExpression parent, int parameterIndex) { PsiExpression qualifier = null; if (parent instanceof PsiMethodCallExpression) { qualifier = ((PsiMethodCallExpression)parent).getMethodExpression(); @@ -162,7 +163,13 @@ abstract class SafeDeleteJavaCallerChooser extends JavaCallerChooser { else if (parent instanceof PsiNewExpression) { qualifier = ((PsiNewExpression)parent).getQualifier(); } - return PsiTreeUtil.isAncestor(qualifier, element, true); + + if (PsiTreeUtil.isAncestor(qualifier, element, true)) { + return true; + } + + final PsiExpressionList list = parent.getArgumentList(); + return list != null && !PsiTreeUtil.isAncestor(list.getExpressions()[parameterIndex], element, false); } }) && ref.get()) { return parameter; diff --git a/java/java-tests/testData/refactoring/safeDelete/NoDeepDeleteParameterUsedInNextArgumentExpression.java b/java/java-tests/testData/refactoring/safeDelete/NoDeepDeleteParameterUsedInNextArgumentExpression.java new file mode 100644 index 000000000000..2d8c46d19ae2 --- /dev/null +++ b/java/java-tests/testData/refactoring/safeDelete/NoDeepDeleteParameterUsedInNextArgumentExpression.java @@ -0,0 +1,7 @@ +class Test { + void foo(String s, String p) {} + + void bar(String s, String p) { + foo(s, s.substring(0)); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/safeDelete/NoDeepDeleteParameterUsedInNextArgumentExpression_after.java b/java/java-tests/testData/refactoring/safeDelete/NoDeepDeleteParameterUsedInNextArgumentExpression_after.java new file mode 100644 index 000000000000..4c649c4dc527 --- /dev/null +++ b/java/java-tests/testData/refactoring/safeDelete/NoDeepDeleteParameterUsedInNextArgumentExpression_after.java @@ -0,0 +1,7 @@ +class Test { + void foo(String p) {} + + void bar(String s, String p) { + foo(s.substring(0)); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java b/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java index 6d24883fad47..5cf1fc5876df 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java @@ -92,6 +92,10 @@ public class SafeDeleteTest extends MultiFileTestCase { doSingleFileTest(); } + public void testNoDeepDeleteParameterUsedInNextArgumentExpression() throws Exception { + doSingleFileTest(); + } + public void testToDeepDeleteParameterOverriders() throws Exception { doSingleFileTest(); }