PY-12175 Extract superclass: import for existing super class is removed

This commit is contained in:
Ilya.Kazakevich
2014-02-17 21:15:16 +04:00
parent d47bc1eed0
commit 2cc672b113
19 changed files with 77 additions and 10 deletions
@@ -60,7 +60,6 @@ public final class PyExtractSuperclassHelper {
@NotNull Collection<PyMemberInfo<PyElement>> selectedMemberInfos,
final String superBaseName,
final String targetFile) {
//We will need to change it probably while param may be read-only
//noinspection AssignmentToMethodParameter
selectedMemberInfos = new ArrayList<PyMemberInfo<PyElement>>(selectedMemberInfos);
@@ -88,9 +87,12 @@ public final class PyExtractSuperclassHelper {
PyClass newClass = PyElementGenerator.getInstance(project).createFromText(LanguageLevel.getDefault(), PyClass.class, text);
newClass = placeNewClass(project, newClass, clazz, targetFile);
MembersManager.moveAllMembers(selectedMemberInfos, clazz, newClass);
if (! newClass.getContainingFile().equals(clazz.getContainingFile())) {
PyClassRefactoringUtil.optimizeImports(clazz.getContainingFile()); // To remove unneeded imports only if user used different file
}
PyClassRefactoringUtil.addSuperclasses(project, clazz, null, newClass);
}
private static PyClass placeNewClass(final Project project, PyClass newClass, @NotNull final PyClass clazz, final String targetFile) {
@@ -7,6 +7,7 @@ import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyElement;
import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -80,5 +81,6 @@ public abstract class PyMembersRefactoringBaseProcessor extends BaseRefactoringP
destinations.add(((PyUsageInfo)usage).getTo());
}
MembersManager.moveAllMembers(myMembersToMove, myFrom, destinations.toArray(new PyClass[destinations.size()]));
PyClassRefactoringUtil.optimizeImports(myFrom.getContainingFile()); // To remove unneeded imports
}
}
@@ -5,9 +5,7 @@ import com.google.common.collect.Lists;
import com.intellij.refactoring.RefactoringBundle;
import com.jetbrains.NotNullPredicate;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyElement;
import com.jetbrains.python.psi.PyExpression;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil;
import com.jetbrains.python.refactoring.classes.ui.PyClassCellRenderer;
import org.jetbrains.annotations.NotNull;
@@ -47,8 +45,13 @@ class SuperClassesManager extends MembersManager<PyClass> {
}
for (final PyExpression expression : from.getSuperClassExpressions()) {
// Remove all superclass expressions that point to class from memberinfo
if (!(expression instanceof PyQualifiedExpression)) {
continue;
}
final PyReferenceExpression reference = (PyReferenceExpression)expression;
for (final PyClass element : elements) {
if (expression.getText().equals(element.getName())) {
if (reference.getReference().isReferenceTo(element)) {
expression.delete();
}
}
@@ -66,7 +66,5 @@ class TypeSafeMovingStrategy<T extends PyElement> {
for (final PyElement element : newElements) {
PyClassRefactoringUtil.restoreNamedReferences(element);
}
PyClassRefactoringUtil.optimizeImports(myFrom.getContainingFile()); // To remove unneeded imports from source
}
}
@@ -0,0 +1,9 @@
from shared import SharedClass
class DestClass(SharedClass):
pass
class Source(DestClass):
pass
@@ -0,0 +1,5 @@
from shared import SharedClass
class Source(SharedClass):
pass
@@ -0,0 +1,5 @@
from shared_module import SharedClass
class NewParent(SharedClass):
pass
@@ -0,0 +1 @@
class SharedClass(object): pass
@@ -0,0 +1,5 @@
from dest_module import NewParent
class MyClass(NewParent):
pass
@@ -0,0 +1,4 @@
from shared_module import SharedClass
class MyClass(SharedClass):
pass
@@ -1,5 +1,5 @@
from dest_module import NewParent
import shared_module
class MyClass(shared_module.TheParentOfItAll, NewParent):
class MyClass(NewParent):
pass
@@ -0,0 +1,5 @@
from shared_module import TheParentOfItAll
class NewParent(TheParentOfItAll):
pass
@@ -0,0 +1,2 @@
class TheParentOfItAll(object):
pass
@@ -0,0 +1,5 @@
from dest_module import NewParent
class MyClass(NewParent):
pass
@@ -0,0 +1,4 @@
from shared_module import TheParentOfItAll
class MyClass(TheParentOfItAll):
pass
@@ -0,0 +1 @@
class SharedClass: pass
@@ -54,6 +54,11 @@ public class PyExtractSuperclassTest extends PyClassRefactoringTest {
multiFileTestHelper("TheParentOfItAll", false);
}
// Checks that moving methods between files moves superclass expressions regardless import style (q.name or name)
public void testMoveExtendsCheckReference() throws Throwable {
multiFileTestHelper("TheParentOfItAll", false);
}
// Extracts method as abstract
public void testMoveAndMakeAbstract() throws Throwable {
multiFileTestHelper(".foo_method", true);
@@ -105,6 +110,17 @@ public class PyExtractSuperclassTest extends PyClassRefactoringTest {
doSimpleTest("A", "Suppa", null, false, ".foo");
}
// PY-12175
public void testImportNotBroken() throws Exception {
myFixture.copyFileToProject("/refactoring/extractsuperclass/shared.py", "shared.py");
doSimpleTest("Source", "DestClass", null, true, "SharedClass");
}
// PY-12175 but between several files
public void testImportNotBrokenManyFiles() throws Exception {
multiFileTestHelper("SharedClass", false);
}
public void testMoveFields() throws Exception {
doSimpleTest("FromClass", "ToClass", null, true, "#instance_field", "#CLASS_FIELD");
}