pull up conflicts if moved method uses members from outer class not accessible in the super (IDEA-151942)

This commit is contained in:
Anna.Kozlova
2016-04-27 11:10:23 +02:00
parent 1dc6f156cf
commit 0936ad00fd
7 changed files with 65 additions and 17 deletions
@@ -156,19 +156,10 @@ public class PullUpConflictsUtil {
}
RefactoringConflictsUtil.analyzeModuleConflicts(subclass.getProject(), checkModuleConflictsList,
new UsageInfo[0], targetRepresentativeElement, conflicts);
final String fqName = subclass.getQualifiedName();
final String packageName;
if (fqName != null) {
packageName = StringUtil.getPackageName(fqName);
} else {
final PsiFile psiFile = PsiTreeUtil.getParentOfType(subclass, PsiFile.class);
if (psiFile instanceof PsiClassOwner) {
packageName = ((PsiClassOwner)psiFile).getPackageName();
} else {
packageName = null;
}
}
final boolean toDifferentPackage = !Comparing.strEqual(targetPackage.getQualifiedName(), packageName);
final PsiFile psiFile = PsiTreeUtil.getParentOfType(subclass, PsiClassOwner.class);
final boolean toDifferentPackage = !Comparing.strEqual(targetPackage.getQualifiedName(),
psiFile != null ? ((PsiClassOwner)psiFile).getPackageName() : null);
for (final PsiMethod abstractMethod : abstractMethods) {
abstractMethod.accept(new ClassMemberReferencesVisitor(subclass) {
@Override
@@ -31,6 +31,7 @@ import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.search.PsiElementProcessorAdapter;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -160,8 +161,10 @@ public class RefactoringHierarchyUtil {
if (elementClass == null) return false;
if (superClass != null) {
return !superClass.getManager().areElementsEquivalent(superClass, elementClass) &&
elementClass.isInheritor(superClass, true);
if (elementClass.isInheritor(superClass, true)) {
return !superClass.getManager().areElementsEquivalent(superClass, elementClass);
}
return PsiTreeUtil.isAncestor(elementClass, subClass, false) && !PsiTreeUtil.isAncestor(elementClass, superClass, false);
}
else {
return subClass.getManager().areElementsEquivalent(subClass, elementClass);
@@ -59,7 +59,7 @@ public abstract class ClassMemberReferencesVisitor extends JavaRecursiveElementW
if (elementClass.equals(containingClass) || elementClass.isInheritor(containingClass, true)) {
return true;
} else {
return false;
return PsiTreeUtil.isAncestor(containingClass, elementClass, true);
}
}
@@ -0,0 +1,14 @@
class BaseInner {
}
class Outer {
public int x = 0;
public void foo(){};
public class Inner extends BaseInner {
void b<caret>ar() {
System.out.println(x);
Outer.this.foo();
}
}
}
@@ -0,0 +1,14 @@
class BaseInner {
}
class Outer {
public int x = 0;
public void foo(){};
public class Inner extends BaseInner {
void b<caret>ar() {
System.out.println(x);
Outer.this.foo();
}
}
}
@@ -0,0 +1,16 @@
abstract class BaseInner {
abstract void bar();
}
class Outer {
public int x = 0;
public void foo(){};
public class Inner extends BaseInner {
@Override
void bar() {
System.out.println(x);
Outer.this.foo();
}
}
}
@@ -32,6 +32,7 @@ import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.TreeSet;
/**
* @author ven
@@ -178,6 +179,14 @@ public class PullUpTest extends LightRefactoringTestCase {
doTest(false, "Class <b><code>Test.Printer</code></b> already contains a method <b><code>foo()</code></b>", new RefactoringTestUtil.MemberDescriptor("foo", PsiMethod.class));
}
public void testOuterClassRefsNoConflictIfAsAbstract() throws Exception {
doTest(false, new RefactoringTestUtil.MemberDescriptor("bar", PsiMethod.class, true));
}
public void testOuterClassRefs() throws Exception {
doTest(false, "Method <b><code>bar()</code></b> uses field <b><code>Outer.x</code></b>, which is not moved to the superclass", new RefactoringTestUtil.MemberDescriptor("bar", PsiMethod.class));
}
public void testDefaultMethodAsAbstract() throws Exception {
doTest(false, new RefactoringTestUtil.MemberDescriptor("foo", PsiMethod.class, true));
}
@@ -252,7 +261,8 @@ public class PullUpTest extends LightRefactoringTestCase {
}
if (conflictMessage != null && !IGNORE_CONFLICTS.equals(conflictMessage)) {
assertEquals(conflictMessage, conflictsMap.values().iterator().next());
TreeSet<String> conflicts = new TreeSet<>(conflictsMap.values());
assertEquals(conflictMessage, conflicts.iterator().next());
return;
}