diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringConflictsUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringConflictsUtil.java index aece13de0764..bc0148ff44f4 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringConflictsUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringConflictsUtil.java @@ -134,11 +134,22 @@ public class RefactoringConflictsUtil { } } + public static void checkUsedElements(PsiMember member, + PsiElement scope, + @NotNull Set membersToMove, + @Nullable Set abstractMethods, + @Nullable PsiClass targetClass, + @NotNull PsiElement context, + MultiMap conflicts) { + checkUsedElements(member, scope, membersToMove, abstractMethods, targetClass, null, context, conflicts); + } + public static void checkUsedElements(PsiMember member, PsiElement scope, @NotNull Set membersToMove, @Nullable Set abstractMethods, @Nullable PsiClass targetClass, + PsiClass accessClass, @NotNull PsiElement context, MultiMap conflicts) { final Set moving = new HashSet(membersToMove); @@ -150,10 +161,10 @@ public class RefactoringConflictsUtil { PsiElement refElement = refExpr.resolve(); if (refElement instanceof PsiMember) { PsiExpression qualifier = refExpr.getQualifierExpression(); - PsiClass accessClass = (PsiClass)(qualifier != null ? PsiUtil.getAccessObjectClass(qualifier).getElement() : null); + PsiClass qualifierAccessClass = (PsiClass)(qualifier != null ? PsiUtil.getAccessObjectClass(qualifier).getElement() : accessClass); if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, moving, targetClass, false) && - (accessClass == null || !RefactoringHierarchyUtil.willBeInTargetClass(accessClass, moving, targetClass, false))) { - checkAccessibility((PsiMember)refElement, context, accessClass, member, conflicts); + (qualifierAccessClass == null || !RefactoringHierarchyUtil.willBeInTargetClass(qualifierAccessClass, moving, targetClass, false))) { + checkAccessibility((PsiMember)refElement, context, qualifierAccessClass, member, conflicts); } } } @@ -169,7 +180,7 @@ public class RefactoringConflictsUtil { final PsiMethod refElement = newExpression.resolveConstructor(); if (refElement != null) { if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, moving, targetClass, false)) { - checkAccessibility(refElement, context, null, member, conflicts); + checkAccessibility(refElement, context, accessClass, member, conflicts); } } } @@ -179,14 +190,14 @@ public class RefactoringConflictsUtil { PsiElement refElement = refExpr.resolve(); if (refElement instanceof PsiMember) { if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, moving, targetClass, false)) { - checkAccessibility((PsiMember)refElement, context, null, member, conflicts); + checkAccessibility((PsiMember)refElement, context, accessClass, member, conflicts); } } } for (PsiElement child : scope.getChildren()) { if (child instanceof PsiWhiteSpace || child instanceof PsiComment) continue; - checkUsedElements(member, child, membersToMove, abstractMethods, targetClass, context, conflicts); + checkUsedElements(member, child, membersToMove, abstractMethods, targetClass, child instanceof PsiClass ? (PsiClass)child : accessClass, context, conflicts); } } diff --git a/java/java-tests/testData/refactoring/pullUp/accessibleViaInheritanceInsideAnonymousClass/after/a/A.java b/java/java-tests/testData/refactoring/pullUp/accessibleViaInheritanceInsideAnonymousClass/after/a/A.java new file mode 100644 index 000000000000..34dee12da94d --- /dev/null +++ b/java/java-tests/testData/refactoring/pullUp/accessibleViaInheritanceInsideAnonymousClass/after/a/A.java @@ -0,0 +1,9 @@ +package a; +import b.B; +public class A extends B { + + protected static void bar(){} + public static class I { + protected void foo(){} + } +} diff --git a/java/java-tests/testData/refactoring/pullUp/accessibleViaInheritanceInsideAnonymousClass/after/b/B.java b/java/java-tests/testData/refactoring/pullUp/accessibleViaInheritanceInsideAnonymousClass/after/b/B.java new file mode 100644 index 000000000000..bf1f35b90535 --- /dev/null +++ b/java/java-tests/testData/refactoring/pullUp/accessibleViaInheritanceInsideAnonymousClass/after/b/B.java @@ -0,0 +1,14 @@ +package b; + +import a.A; + +public class B { + void method2Move() { + new A.I() { + { + foo(); + A.bar(); + } + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/pullUp/accessibleViaInheritanceInsideAnonymousClass/before/a/A.java b/java/java-tests/testData/refactoring/pullUp/accessibleViaInheritanceInsideAnonymousClass/before/a/A.java new file mode 100644 index 000000000000..efa03290b9da --- /dev/null +++ b/java/java-tests/testData/refactoring/pullUp/accessibleViaInheritanceInsideAnonymousClass/before/a/A.java @@ -0,0 +1,17 @@ +package a; +import b.B; +public class A extends B { + void method2Move() { + new I() { + { + foo(); + bar(); + } + } + } + + protected static void bar(){} + public static class I { + protected void foo(){} + } +} diff --git a/java/java-tests/testData/refactoring/pullUp/accessibleViaInheritanceInsideAnonymousClass/before/b/B.java b/java/java-tests/testData/refactoring/pullUp/accessibleViaInheritanceInsideAnonymousClass/before/b/B.java new file mode 100644 index 000000000000..64950f347e93 --- /dev/null +++ b/java/java-tests/testData/refactoring/pullUp/accessibleViaInheritanceInsideAnonymousClass/before/b/B.java @@ -0,0 +1,3 @@ +package b; +public class B { +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/PullUpMultifileTest.java b/java/java-tests/testSrc/com/intellij/refactoring/PullUpMultifileTest.java index a1df6dba3b81..195f91ad62a5 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/PullUpMultifileTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/PullUpMultifileTest.java @@ -100,6 +100,10 @@ public class PullUpMultifileTest extends MultiFileTestCase { "Method method2Move() uses method A.foo(), which is not moved to the superclass"); } + public void testAccessibleViaInheritanceInsideAnonymousClass() throws Exception { + doTest("Method method2Move() uses method A.bar(), which is not accessible from the superclass"); + } + public void testReuseSuperMethod() throws Exception { doTest(); }