From 6806c16bfd29db0f778081121c5b2cfcc25682be Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 21 May 2010 20:13:20 +0400 Subject: [PATCH] method duplicates: qualify match in order to prevent name conflict ( IDEA-24764 ) --- .../duplicates/MethodDuplicatesHandler.java | 29 +++++++++++++++---- .../DetectNameConflicts.java | 17 +++++++++++ .../DetectNameConflicts.java.after | 17 +++++++++++ .../DetectNameConflictsWithStatic.java | 17 +++++++++++ .../DetectNameConflictsWithStatic.java.after | 17 +++++++++++ .../NoDetectNameConflicts.java | 17 +++++++++++ .../NoDetectNameConflicts.java.after | 17 +++++++++++ .../FindMethodDuplicatesMiscTest.java | 12 ++++++++ 8 files changed, 137 insertions(+), 6 deletions(-) create mode 100644 java/java-tests/testData/refactoring/methodDuplicatesMisc/DetectNameConflicts.java create mode 100644 java/java-tests/testData/refactoring/methodDuplicatesMisc/DetectNameConflicts.java.after create mode 100644 java/java-tests/testData/refactoring/methodDuplicatesMisc/DetectNameConflictsWithStatic.java create mode 100644 java/java-tests/testData/refactoring/methodDuplicatesMisc/DetectNameConflictsWithStatic.java.after create mode 100644 java/java-tests/testData/refactoring/methodDuplicatesMisc/NoDetectNameConflicts.java create mode 100644 java/java-tests/testData/refactoring/methodDuplicatesMisc/NoDetectNameConflicts.java.after diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesHandler.java b/java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesHandler.java index 4aef1e9d0784..546b6f4606c9 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesHandler.java @@ -232,7 +232,9 @@ public class MethodDuplicatesHandler implements RefactoringActionHandler { final PsiElementFactory factory = JavaPsiFacade.getInstance(myMethod.getProject()).getElementFactory(); final boolean needQualifier = match.getInstanceExpression() != null; final boolean needStaticQualifier = isExternal(match); - @NonNls final String text = needQualifier || needStaticQualifier ? "q." + myMethod.getName() + "()": myMethod.getName() + "()"; + final boolean nameConflicts = nameConflicts(match); + @NonNls final String text = needQualifier || needStaticQualifier || nameConflicts + ? "q." + myMethod.getName() + "()": myMethod.getName() + "()"; PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)factory.createExpressionFromText(text, null); methodCallExpression = (PsiMethodCallExpression)CodeStyleManager.getInstance(myMethod.getManager()).reformat(methodCallExpression); final PsiParameter[] parameters = myMethod.getParameterList().getParameters(); @@ -247,13 +249,15 @@ public class MethodDuplicatesHandler implements RefactoringActionHandler { methodCallExpression.getArgumentList().add(factory.createExpressionFromText(PsiTypesUtil.getDefaultValueOfType(parameter.getType()), parameter)); } } - if (needQualifier || needStaticQualifier) { + if (needQualifier || needStaticQualifier || nameConflicts) { final PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression(); LOG.assertTrue(qualifierExpression != null); if (needQualifier) { qualifierExpression.replace(match.getInstanceExpression()); - } else { + } else if (needStaticQualifier || myMethod.hasModifierProperty(PsiModifier.STATIC)) { qualifierExpression.replace(factory.createReferenceExpression(containingClass)); + } else { + qualifierExpression.replace(RefactoringUtil.createThisExpression(containingClass.getManager(), containingClass)); } } VisibilityUtil.escalateVisibility(myMethod, match.getMatchStart()); @@ -276,16 +280,29 @@ public class MethodDuplicatesHandler implements RefactoringActionHandler { private boolean isExternal(final Match match) { - if (PsiTreeUtil.isAncestor(myMethod.getContainingClass(), match.getMatchStart(), false)) { + final PsiElement matchStart = match.getMatchStart(); + final PsiClass containingClass = myMethod.getContainingClass(); + if (PsiTreeUtil.isAncestor(containingClass, matchStart, false)) { return false; } - final PsiClass psiClass = PsiTreeUtil.getParentOfType(match.getMatchStart(), PsiClass.class); + final PsiClass psiClass = PsiTreeUtil.getParentOfType(matchStart, PsiClass.class); if (psiClass != null) { - if (InheritanceUtil.isInheritorOrSelf(psiClass, myMethod.getContainingClass(), true)) return false; + if (InheritanceUtil.isInheritorOrSelf(psiClass, containingClass, true)) return false; } return true; } + private boolean nameConflicts(Match match) { + PsiClass matchClass = PsiTreeUtil.getParentOfType(match.getMatchStart(), PsiClass.class); + while (matchClass != null && matchClass != myMethod.getContainingClass()) { + if (matchClass.findMethodsBySignature(myMethod, false).length > 0) { + return true; + } + matchClass = PsiTreeUtil.getParentOfType(matchClass, PsiClass.class); + } + return false; + } + private boolean isEssentialStaticContextAbsent(final Match match) { if (!myMethod.hasModifierProperty(PsiModifier.STATIC)) { final PsiExpression instanceExpression = match.getInstanceExpression(); diff --git a/java/java-tests/testData/refactoring/methodDuplicatesMisc/DetectNameConflicts.java b/java/java-tests/testData/refactoring/methodDuplicatesMisc/DetectNameConflicts.java new file mode 100644 index 000000000000..809873a59ce0 --- /dev/null +++ b/java/java-tests/testData/refactoring/methodDuplicatesMisc/DetectNameConflicts.java @@ -0,0 +1,17 @@ +class Test { + public Foo createFoo() { + return new Foo() { + public void bar() { + System.out.println(1); + } + }; + } + + public void bar() { + System.out.println(1); + } + + public interface Foo { + void bar(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/methodDuplicatesMisc/DetectNameConflicts.java.after b/java/java-tests/testData/refactoring/methodDuplicatesMisc/DetectNameConflicts.java.after new file mode 100644 index 000000000000..f7bc96068446 --- /dev/null +++ b/java/java-tests/testData/refactoring/methodDuplicatesMisc/DetectNameConflicts.java.after @@ -0,0 +1,17 @@ +class Test { + public Foo createFoo() { + return new Foo() { + public void bar() { + Test.this.bar(); + } + }; + } + + public void bar() { + System.out.println(1); + } + + public interface Foo { + void bar(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/methodDuplicatesMisc/DetectNameConflictsWithStatic.java b/java/java-tests/testData/refactoring/methodDuplicatesMisc/DetectNameConflictsWithStatic.java new file mode 100644 index 000000000000..8e1cd0135542 --- /dev/null +++ b/java/java-tests/testData/refactoring/methodDuplicatesMisc/DetectNameConflictsWithStatic.java @@ -0,0 +1,17 @@ +class Test { + public Foo createFoo() { + return new Foo() { + public void bar() { + System.out.println(1); + } + }; + } + + public static void bar() { + System.out.println(1); + } + + public interface Foo { + void bar(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/methodDuplicatesMisc/DetectNameConflictsWithStatic.java.after b/java/java-tests/testData/refactoring/methodDuplicatesMisc/DetectNameConflictsWithStatic.java.after new file mode 100644 index 000000000000..d7a1e5cdf89b --- /dev/null +++ b/java/java-tests/testData/refactoring/methodDuplicatesMisc/DetectNameConflictsWithStatic.java.after @@ -0,0 +1,17 @@ +class Test { + public Foo createFoo() { + return new Foo() { + public void bar() { + Test.bar(); + } + }; + } + + public static void bar() { + System.out.println(1); + } + + public interface Foo { + void bar(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/methodDuplicatesMisc/NoDetectNameConflicts.java b/java/java-tests/testData/refactoring/methodDuplicatesMisc/NoDetectNameConflicts.java new file mode 100644 index 000000000000..6698ea48fd4c --- /dev/null +++ b/java/java-tests/testData/refactoring/methodDuplicatesMisc/NoDetectNameConflicts.java @@ -0,0 +1,17 @@ +class Test { + public Foo createFoo() { + return new Foo() { + public void bar() { + System.out.println(1); + } + }; + } + + public void bar(int i) { + System.out.println(i); + } + + public interface Foo { + void bar(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/methodDuplicatesMisc/NoDetectNameConflicts.java.after b/java/java-tests/testData/refactoring/methodDuplicatesMisc/NoDetectNameConflicts.java.after new file mode 100644 index 000000000000..8cc0c817ef84 --- /dev/null +++ b/java/java-tests/testData/refactoring/methodDuplicatesMisc/NoDetectNameConflicts.java.after @@ -0,0 +1,17 @@ +class Test { + public Foo createFoo() { + return new Foo() { + public void bar() { + bar(1); + } + }; + } + + public void bar(int i) { + System.out.println(i); + } + + public interface Foo { + void bar(); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/FindMethodDuplicatesMiscTest.java b/java/java-tests/testSrc/com/intellij/refactoring/FindMethodDuplicatesMiscTest.java index 3fc5b8ea7990..147c3e6c6ed7 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/FindMethodDuplicatesMiscTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/FindMethodDuplicatesMiscTest.java @@ -37,4 +37,16 @@ public class FindMethodDuplicatesMiscTest extends FindMethodDuplicatesBaseTest { public void testPassArray2VarargMethodCall() throws Exception { doTest(); } + + public void testDetectNameConflicts() throws Exception { + doTest(); + } + + public void testNoDetectNameConflicts() throws Exception { + doTest(); + } + + public void testDetectNameConflictsWithStatic() throws Exception { + doTest(); + } } \ No newline at end of file