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 a53c78a76a08..ef96f251d7c2 100644 --- a/java/java-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteJavaCallerChooser.java +++ b/java/java-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteJavaCallerChooser.java @@ -23,6 +23,7 @@ import com.intellij.openapi.util.Ref; import com.intellij.psi.*; 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.refactoring.changeSignature.MethodNodeBase; import com.intellij.refactoring.changeSignature.inCallers.JavaCallerChooser; @@ -111,37 +112,47 @@ abstract class SafeDeleteJavaCallerChooser extends JavaCallerChooser { final PsiExpression[] expressions = argumentList.getExpressions(); if (expressions.length > parameterIndex) { final PsiExpression expression = PsiUtil.deparenthesizeExpression(expressions[parameterIndex]); - if (expression instanceof PsiReferenceExpression) { - final PsiElement resolve = ((PsiReferenceExpression)expression).resolve(); - if (resolve instanceof PsiParameter && !((PsiParameter)resolve).isVarArgs()) { - final PsiElement scope = ((PsiParameter)resolve).getDeclarationScope(); + if (expression != null) { + final Set paramRefs = new HashSet(); + expression.accept(new JavaRecursiveElementWalkingVisitor() { + @Override + public void visitReferenceExpression(PsiReferenceExpression expression) { + super.visitReferenceExpression(expression); + final PsiElement resolve = expression.resolve(); + if (resolve instanceof PsiParameter) { + paramRefs.add((PsiParameter)resolve); + } + } + }); + + final PsiParameter parameter = ContainerUtil.getFirstItem(paramRefs); + if (parameter != null && !parameter.isVarArgs()) { + final PsiElement scope = parameter.getDeclarationScope(); if (scope instanceof PsiMethod && ((PsiMethod)scope).findDeepestSuperMethods().length == 0) { final Ref ref = new Ref(false); - if (ReferencesSearch.search(resolve, new LocalSearchScope(scope)).forEach(new Processor() { + if (ReferencesSearch.search(parameter, new LocalSearchScope(scope)).forEach(new Processor() { @Override public boolean process(PsiReference reference) { final PsiElement element = reference.getElement(); if (element instanceof PsiReferenceExpression) { - final PsiElement parent = element.getParent(); - if (parent instanceof PsiExpressionList) { - final PsiElement gParent = parent.getParent(); - if (gParent instanceof PsiCallExpression) { - final PsiMethod resolved = ((PsiCallExpression)gParent).resolveMethod(); - if (scope.equals(resolved)) { - return true; - } - if (nodeMethod.equals(resolved)) { - ref.set(true); - return true; - } + PsiElement parent = PsiTreeUtil.getParentOfType(element, PsiCallExpression.class); + while (parent != null) { + final PsiMethod resolved = ((PsiCallExpression)parent).resolveMethod(); + if (scope.equals(resolved)) { + return true; } + if (nodeMethod.equals(resolved)) { + ref.set(true); + return true; + } + parent = PsiTreeUtil.getParentOfType(parent, PsiCallExpression.class, true); } return false; } return true; } }) && ref.get()) { - return (PsiParameter)resolve; + return (PsiParameter)parameter; } } } diff --git a/java/java-tests/testData/refactoring/safeDelete/DeepDeleteParameterOtherTypeInBinaryExpression.java b/java/java-tests/testData/refactoring/safeDelete/DeepDeleteParameterOtherTypeInBinaryExpression.java new file mode 100644 index 000000000000..d39bbaa19d7b --- /dev/null +++ b/java/java-tests/testData/refactoring/safeDelete/DeepDeleteParameterOtherTypeInBinaryExpression.java @@ -0,0 +1,8 @@ +class Test { + void foo(String s) { + bar(s.length()); + bar(s.length() + 1); + } + + void bar(int i){} +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/safeDelete/DeepDeleteParameterOtherTypeInBinaryExpression_after.java b/java/java-tests/testData/refactoring/safeDelete/DeepDeleteParameterOtherTypeInBinaryExpression_after.java new file mode 100644 index 000000000000..d3f5fd3b4214 --- /dev/null +++ b/java/java-tests/testData/refactoring/safeDelete/DeepDeleteParameterOtherTypeInBinaryExpression_after.java @@ -0,0 +1,8 @@ +class Test { + void foo() { + bar(); + bar(); + } + + void bar(){} +} \ 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 819922c4016f..477d15097cd0 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java @@ -80,6 +80,10 @@ public class SafeDeleteTest extends MultiFileTestCase { doSingleFileTest(); } + public void testDeepDeleteParameterOtherTypeInBinaryExpression() throws Exception { + doSingleFileTest(); + } + public void testImpossibleToDeepDeleteParameter() throws Exception { doSingleFileTest(); }