switch context when get to anonymous class so access to the inherited members should not be raised as a conflict

This commit is contained in:
Anna Kozlova
2015-01-20 11:13:06 +01:00
parent 0bec748d2f
commit 64894391ea
6 changed files with 64 additions and 6 deletions
@@ -134,11 +134,22 @@ public class RefactoringConflictsUtil {
}
}
public static void checkUsedElements(PsiMember member,
PsiElement scope,
@NotNull Set<PsiMember> membersToMove,
@Nullable Set<PsiMethod> abstractMethods,
@Nullable PsiClass targetClass,
@NotNull PsiElement context,
MultiMap<PsiElement, String> conflicts) {
checkUsedElements(member, scope, membersToMove, abstractMethods, targetClass, null, context, conflicts);
}
public static void checkUsedElements(PsiMember member,
PsiElement scope,
@NotNull Set<PsiMember> membersToMove,
@Nullable Set<PsiMethod> abstractMethods,
@Nullable PsiClass targetClass,
PsiClass accessClass,
@NotNull PsiElement context,
MultiMap<PsiElement, String> conflicts) {
final Set<PsiMember> moving = new HashSet<PsiMember>(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);
}
}
@@ -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(){}
}
}
@@ -0,0 +1,14 @@
package b;
import a.A;
public class B {
void method2Move() {
new A.I() {
{
foo();
A.bar();
}
}
}
}
@@ -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(){}
}
}
@@ -0,0 +1,3 @@
package b;
public class B {
}
@@ -100,6 +100,10 @@ public class PullUpMultifileTest extends MultiFileTestCase {
"Method <b><code>method2Move()</code></b> uses method <b><code>A.foo()</code></b>, which is not moved to the superclass");
}
public void testAccessibleViaInheritanceInsideAnonymousClass() throws Exception {
doTest("Method <b><code>method2Move()</code></b> uses method <b><code>A.bar()</code></b>, which is not accessible from the superclass");
}
public void testReuseSuperMethod() throws Exception {
doTest();
}