diff --git a/python/src/com/jetbrains/python/refactoring/classes/PyClassMembersRefactoringSupport.java b/python/src/com/jetbrains/python/refactoring/classes/PyClassMembersRefactoringSupport.java index 71f920c8399e..17588e666e25 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/PyClassMembersRefactoringSupport.java +++ b/python/src/com/jetbrains/python/refactoring/classes/PyClassMembersRefactoringSupport.java @@ -22,6 +22,7 @@ import com.intellij.refactoring.classMembers.DependentMembersCollectorBase; import com.intellij.refactoring.classMembers.MemberInfoBase; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; /** * @author Dennis.Ushakov diff --git a/python/src/com/jetbrains/python/refactoring/classes/PyDependentMembersCollector.java b/python/src/com/jetbrains/python/refactoring/classes/PyDependentMembersCollector.java index 5c51118c0129..5efb3525d5ba 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/PyDependentMembersCollector.java +++ b/python/src/com/jetbrains/python/refactoring/classes/PyDependentMembersCollector.java @@ -29,6 +29,7 @@ public class PyDependentMembersCollector extends DependentMembersCollectorBase

{ - public PyMemberInfo(PyElement member) { - super(member); - final PyClass clazz = PyUtil.getContainingClassOrSelf(member); - assert clazz != null; - - if (member instanceof PyFunction) { - PyFunction function = (PyFunction)member; - displayName = buildDisplayMethodName(function); - for (PyClass aClass : clazz.getSuperClasses()) { - final PyFunction parentMethod = aClass.findMethodByName(function.getName(), true); - if (parentMethod != null) { - overrides = true; - } - } - } else if (member instanceof PyClass) { - displayName = RefactoringBundle.message("member.info.extends.0", PyClassCellRenderer.getClassText((PyClass)member)); - } - } - - private static String buildDisplayMethodName(PyFunction method) { - final StringBuilder builder = new StringBuilder(method.getName()); - builder.append("("); - final PyParameter[] arguments = method.getParameterList().getParameters(); - for (PyParameter parameter : arguments) { - builder.append(parameter.getName()); - if (arguments.length > 1 && parameter != arguments[arguments.length - 1]) { - builder.append(", "); - } - } - builder.append(")"); - return builder.toString(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof PyMemberInfo) { - return getMember().equals(((PyMemberInfo)obj).getMember()); - } - return false; - } - - @Override - public int hashCode() { - return getMember().hashCode(); - } -} diff --git a/python/src/com/jetbrains/python/refactoring/classes/PyMemberInfoStorage.java b/python/src/com/jetbrains/python/refactoring/classes/PyMemberInfoStorage.java index 5c172e63b812..ae6d769f35ab 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/PyMemberInfoStorage.java +++ b/python/src/com/jetbrains/python/refactoring/classes/PyMemberInfoStorage.java @@ -22,6 +22,8 @@ import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.psi.PyFunction; import com.jetbrains.python.refactoring.PyRefactoringUtil; +import com.jetbrains.python.refactoring.classes.membersManager.MembersManager; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import java.util.ArrayList; @@ -60,12 +62,7 @@ public class PyMemberInfoStorage extends AbstractMemberInfoStorage temp) { - for (PyFunction function : aClass.getMethods()) { - temp.add(new PyMemberInfo(function)); - } - for (PyClass pyClass : aClass.getSuperClasses()) { - temp.add(new PyMemberInfo(pyClass)); - } + temp.addAll(MembersManager.getAllMembersCouldBeMoved(aClass)); } @Override diff --git a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassDialog.java b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassDialog.java index c0bc437b9498..05dab4f7aa7f 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassDialog.java +++ b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassDialog.java @@ -34,7 +34,7 @@ import com.jetbrains.python.PyBundle; import com.jetbrains.python.PythonLanguage; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import com.jetbrains.python.refactoring.classes.PyMemberInfoStorage; import com.jetbrains.python.refactoring.classes.ui.UpDirectedMembersMovingDialog; import org.jetbrains.annotations.NotNull; diff --git a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHandler.java b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHandler.java index a68860d6e97f..8ed2fa8aef85 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHandler.java +++ b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHandler.java @@ -28,7 +28,7 @@ import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyUtil; import com.jetbrains.python.refactoring.classes.PyClassMembersRefactoringSupport; import com.jetbrains.python.refactoring.classes.PyClassRefactoringHandler; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import com.jetbrains.python.refactoring.classes.PyMemberInfoStorage; import java.util.Collection; diff --git a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHelper.java b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHelper.java index 0d8033704728..98d016e50fa3 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHelper.java +++ b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHelper.java @@ -37,7 +37,7 @@ import com.jetbrains.python.PythonFileType; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PyPsiUtils; import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java new file mode 100644 index 000000000000..9a64a979e5d1 --- /dev/null +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java @@ -0,0 +1,118 @@ +package com.jetbrains.python.refactoring.classes.membersManager; + +import com.google.common.base.Function; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Collections2; +import com.google.common.collect.Multimap; +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 org.jetbrains.annotations.TestOnly; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +/** + * Moves members between classes via its plugins (managers). + * To move members use {@link #getAllMembersCouldBeMoved(com.jetbrains.python.psi.PyClass)} and {@link #moveMembers(com.jetbrains.python.psi.PyClass, com.jetbrains.python.psi.PyClass, java.util.Collection)} + * To add new manager, extend this class and add it to {@link #MANAGERS} + * + * @author Ilya.Kazakevich + */ +public abstract class MembersManager implements Function { + /** + * List of managers. Class delegates all logic to them. + */ + private static final Collection MANAGERS = Arrays.asList(new MethodsManager(), new SuperClassesManager()); + private static final PyMemberExtractor PY_MEMBER_EXTRACTOR = new PyMemberExtractor(); + + protected MembersManager() { + } + + /** + * Get all members that could be moved out of certain class + * @param pyClass class to find members + * @return list of members could be moved + */ + @NotNull + public static List getAllMembersCouldBeMoved(@NotNull final PyClass pyClass) { + final List result = new ArrayList(); + + for (final MembersManager manager : MANAGERS) { + result.addAll(Collections2.transform(manager.getMembersCouldBeMoved(pyClass), manager)); + } + return result; + } + + + /** + * Moves members from one class to another + * @param from source + * @param to destination + * @param memberInfos members to move + */ + public static void moveAllMembers(@NotNull final PyClass from, + @NotNull final PyClass to, + @NotNull final Collection memberInfos) { + final Multimap managerToMember = ArrayListMultimap.create(); + //Collect map (manager)->(list_of_memebers) + for (final PyMemberInfo memberInfo : memberInfos) { + managerToMember.put(memberInfo.getMembersManager(), memberInfo); + } + //Move members via manager + for (final MembersManager membersManager : managerToMember.keySet()) { + membersManager.moveMembers(from, to, Collections2.transform(managerToMember.get(membersManager), PY_MEMBER_EXTRACTOR)); + } + PyClassRefactoringUtil.insertPassIfNeeded(from); + } + + /** + * Finds member in class. It is here only for backward compatibility with some tests. + */ + //TODO: mark deprecated? + @TestOnly + @NotNull + public static PyMemberInfo findMember(@NotNull final PyClass pyClass, @NotNull final PyElement pyElement) { + for (final PyMemberInfo pyMemberInfo : getAllMembersCouldBeMoved(pyClass)) { + if (pyMemberInfo.getMember().equals(pyElement)) { + return pyMemberInfo; + } + } + throw new IllegalArgumentException(String.format("Element %s not found in class %s or can't be moved", pyElement, pyClass)); + } + + /** + * Get list of elements certain plugin could move out of the class + * @param pyClass class with members + * @return list of members + */ + @NotNull + protected abstract List getMembersCouldBeMoved(@NotNull PyClass pyClass); + + /** + * Moves element from one class to another + * @param from source + * @param to destination + * @param members collection of memebrs to move + */ + protected abstract void moveMembers(@NotNull PyClass from, @NotNull PyClass to, @NotNull Collection members); + + //TODO: Doc + @SuppressWarnings("NullableProblems") //IDEA-120100 + @NotNull + @Override + public abstract PyMemberInfo apply(@NotNull PyElement input); + + private static class PyMemberExtractor implements Function { + @SuppressWarnings("NullableProblems") //IDEA-120100 + @Override + public PyElement apply(@NotNull final PyMemberInfo input) { + return input.getMember(); + } + } +} + + diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java new file mode 100644 index 000000000000..96456cbea225 --- /dev/null +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java @@ -0,0 +1,67 @@ +package com.jetbrains.python.refactoring.classes.membersManager; + +import com.jetbrains.python.psi.*; +import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +/** + * Plugin that moves class methods + * + * @author Ilya.Kazakevich + */ +class MethodsManager extends MembersManager { + @NotNull + @Override + protected List getMembersCouldBeMoved(@NotNull final PyClass pyClass) { + return Arrays.asList(pyClass.getMethods()); + } + + @Override + protected void moveMembers(@NotNull PyClass from, @NotNull PyClass to, @NotNull Collection members) { + //TODO: Use generics to prevent casting in each subclass + Collection members1 = (Collection)members; + PyClassRefactoringUtil.moveMethods(members1, to); + } + + @NotNull + @Override + public PyMemberInfo apply(@NotNull final PyElement input) { + //TODO: Use generics to prevent casting in each subclass + final PyFunction pyFunction = (PyFunction)input; + //TODO: Support static and classmethod functions + return new PyMemberInfo(input, false, buildDisplayMethodName(pyFunction), isOverrides(pyFunction), this); + } + + @Nullable + private static Boolean isOverrides(final PyFunction pyFunction) { + final PyClass clazz = PyUtil.getContainingClassOrSelf(pyFunction); + assert clazz != null : "Refactoring called on function, not method: " + pyFunction; + for (final PyClass parentClass : clazz.getSuperClasses()) { + final PyFunction parentMethod = parentClass.findMethodByName(pyFunction.getName(), true); + if (parentMethod != null) { + return true; + } + } + return null; + } + + @NotNull + private static String buildDisplayMethodName(@NotNull final PyFunction pyFunction) { + final StringBuilder builder = new StringBuilder(pyFunction.getName()); + builder.append('('); + final PyParameter[] arguments = pyFunction.getParameterList().getParameters(); + for (final PyParameter parameter : arguments) { + builder.append(parameter.getName()); + if (arguments.length > 1 && parameter != arguments[arguments.length - 1]) { + builder.append(", "); + } + } + builder.append(')'); + return builder.toString(); + } +} diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyMemberInfo.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyMemberInfo.java new file mode 100644 index 000000000000..210326f28e81 --- /dev/null +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyMemberInfo.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.python.refactoring.classes.membersManager; + +import com.intellij.refactoring.classMembers.MemberInfoBase; +import com.jetbrains.python.psi.PyElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Dennis.Ushakov + */ +public class PyMemberInfo extends MemberInfoBase { + @NotNull + private final MembersManager myMembersManager; + + /** + * @param member element itself + * @param isStatic is it static or not? + * @param displayName element display name + * @param overrides does it overrides something? TRUE if is overriden, FALSE if implemented, null if not implemented or overriden + * TODO: use primitive instead? "Implemeneted" has nothing to do with python duck-typing + * @param membersManager manager that knows how to handle this member + */ + PyMemberInfo(@NotNull final PyElement member, + final boolean isStatic, + @NotNull final String displayName, + @Nullable final Boolean overrides, + @NotNull final MembersManager membersManager) { + super(member); + this.isStatic = isStatic; + this.displayName = displayName; + this.overrides = overrides; + myMembersManager = membersManager; + } + + @NotNull + MembersManager getMembersManager() { + return myMembersManager; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof PyMemberInfo) { + return getMember().equals(((PyMemberInfo)obj).getMember()); + } + return false; + } + + @Override + public int hashCode() { + return getMember().hashCode(); + } +} diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/SuperClassesManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/SuperClassesManager.java new file mode 100644 index 000000000000..3335b1d76373 --- /dev/null +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/SuperClassesManager.java @@ -0,0 +1,69 @@ +package com.jetbrains.python.refactoring.classes.membersManager; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; +import com.google.common.collect.Sets; +import com.intellij.refactoring.RefactoringBundle; +import com.jetbrains.python.psi.PyClass; +import com.jetbrains.python.psi.PyElement; +import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil; +import com.jetbrains.python.refactoring.classes.ui.PyClassCellRenderer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +/** + * Plugin that moves superclasses from one class to another + * + * @author Ilya.Kazakevich + */ +class SuperClassesManager extends MembersManager { + + private static final NameExtractor NAME_EXTRACTOR = new NameExtractor(); + + @NotNull + @Override + protected List getMembersCouldBeMoved(@NotNull final PyClass pyClass) { + return Arrays.asList(pyClass.getSuperClasses()); + } + + @Override + protected void moveMembers(@NotNull final PyClass from, @NotNull final PyClass to, @NotNull final Collection members) { + final Set superClassesToMove = Sets.newHashSet(Collections2.filter(Collections2.transform(members, NAME_EXTRACTOR), NAME_EXTRACTOR)); + + for (final PyElement member : members) { + superClassesToMove.add(member.getName()); + } + + PyClassRefactoringUtil.moveSuperclasses(from, superClassesToMove, to); + //TODO: Use generics! + PyClassRefactoringUtil.insertImport(to, (Collection)members); + } + + @NotNull + @Override + public PyMemberInfo apply(@NotNull final PyElement input) { + final String name = RefactoringBundle.message("member.info.extends.0", PyClassCellRenderer.getClassText((PyClass)input)); + //TODO: Check for "overrides" + return new PyMemberInfo(input, false, name, false, this); + } + + private static class NameExtractor implements Predicate, Function { + @SuppressWarnings("NullableProblems") //We sure collection has no null + @Nullable + @Override + public String apply(@NotNull final PyElement input) { + return input.getName(); + } + + @Override + public boolean apply(@Nullable final String input) { + return input != null; + } + } +} diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/package-info.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/package-info.java new file mode 100644 index 000000000000..b730fd4e3c06 --- /dev/null +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/package-info.java @@ -0,0 +1,12 @@ +/** + * Incapsulates knowledge about class members that could be moved to some other class. + * To use (get list of members to move or actually move them) use {@link com.jetbrains.python.refactoring.classes.membersManager.MembersManager#getAllMembersCouldBeMoved(com.jetbrains.python.psi.PyClass)} + * and {@link com.jetbrains.python.refactoring.classes.membersManager.MembersManager#moveAllMembers(com.jetbrains.python.psi.PyClass, com.jetbrains.python.psi.PyClass, java.util.Collection)} + * + * This class delegates its behaviour to its managers (some kind of plugins). There is one for each member type (one for method, one for field etc). + * You need to extend {@link com.jetbrains.python.refactoring.classes.membersManager.MembersManager} to add some. See its javadoc for more info. + * + * + * @author Ilya.Kazakevich + */ +package com.jetbrains.python.refactoring.classes.membersManager; \ No newline at end of file diff --git a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PullUpViewSwingImpl.java b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PullUpViewSwingImpl.java index 7707faab3f00..b0c38d31c8fa 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PullUpViewSwingImpl.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PullUpViewSwingImpl.java @@ -26,7 +26,7 @@ import com.intellij.refactoring.ui.ConflictsDialog; import com.intellij.util.containers.MultiMap; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import com.jetbrains.python.refactoring.classes.ui.PyClassCellRenderer; import com.jetbrains.python.refactoring.classes.ui.PyMemberSelectionPanel; import com.jetbrains.python.refactoring.classes.ui.PyMemberSelectionTable; diff --git a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpConflictsUtil.java b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpConflictsUtil.java index 8d68255f1a1a..c1f5eeaa4240 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpConflictsUtil.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpConflictsUtil.java @@ -21,7 +21,7 @@ import com.intellij.refactoring.util.RefactoringUIUtil; import com.intellij.util.containers.MultiMap; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyFunction; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import org.jetbrains.annotations.NotNull; import java.util.Collection; diff --git a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpHelper.java b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpHelper.java index 0046ba2eef92..37f3718b84ed 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpHelper.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpHelper.java @@ -17,49 +17,31 @@ package com.jetbrains.python.refactoring.classes.pullUp; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.psi.PsiNamedElement; import com.intellij.refactoring.RefactoringBundle; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.psi.PyFunction; -import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.MembersManager; -import java.util.*; +import java.util.Collection; /** * @author Dennis.Ushakov */ -public class PyPullUpHelper { - private static final Logger LOG = Logger.getInstance(PyPullUpHelper.class.getName()); - private PyPullUpHelper() {} +public final class PyPullUpHelper { + + private PyPullUpHelper() { + } public static PyElement pullUp(final PyClass clazz, final Collection selectedMemberInfos, final PyClass superClass) { - final Set superClasses = new HashSet(); - final Set extractedClasses = new HashSet(); - final List methods = new ArrayList(); - for (PyMemberInfo member : selectedMemberInfos) { - final PyElement element = member.getMember(); - if (element instanceof PyFunction) methods.add((PyFunction)element); - else if (element instanceof PyClass) { - superClasses.add(element.getName()); - extractedClasses.add((PyClass)element); - } - else LOG.error("unmatched member class " + element.getClass()); - } - + CommandProcessor.getInstance().executeCommand(clazz.getProject(), new Runnable() { + @Override public void run() { ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override public void run() { - // move methods - PyClassRefactoringUtil.moveMethods(methods, superClass); - - // move superclasses declarations - PyClassRefactoringUtil.moveSuperclasses(clazz, superClasses, superClass); - PyClassRefactoringUtil.insertImport(superClass, extractedClasses); - PyClassRefactoringUtil.insertPassIfNeeded(clazz); + MembersManager.moveAllMembers(clazz, superClass, selectedMemberInfos); } }); } diff --git a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterImpl.java b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterImpl.java index 8ab80cf5603a..99295d9f607e 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterImpl.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterImpl.java @@ -25,7 +25,7 @@ import com.intellij.util.containers.MultiMap; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.psi.PyUtil; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import com.jetbrains.python.refactoring.classes.PyMemberInfoStorage; import org.jetbrains.annotations.NotNull; diff --git a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpView.java b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpView.java index 1f935ee8de1d..856b072ef236 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpView.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpView.java @@ -21,7 +21,7 @@ import com.intellij.refactoring.classMembers.MemberInfoModel; import com.intellij.util.containers.MultiMap; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import org.jetbrains.annotations.NotNull; import java.util.Collection; diff --git a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownConflicts.java b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownConflicts.java index c159b2f27f00..7e4f93c5493e 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownConflicts.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownConflicts.java @@ -25,7 +25,7 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.resolve.PyResolveContext; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import java.util.ArrayList; import java.util.Collection; diff --git a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownDialog.java b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownDialog.java index 2235c574f9a8..73790938911f 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownDialog.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownDialog.java @@ -23,7 +23,7 @@ import com.intellij.refactoring.classMembers.UsedByDependencyMemberInfoModel; import com.intellij.refactoring.ui.RefactoringDialog; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import com.jetbrains.python.refactoring.classes.PyMemberInfoStorage; import com.jetbrains.python.refactoring.classes.ui.PyMemberSelectionPanel; diff --git a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownProcessor.java b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownProcessor.java index 1164c691eea8..ec321f7f5999 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownProcessor.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownProcessor.java @@ -34,7 +34,7 @@ import com.jetbrains.python.psi.PyFunction; import com.jetbrains.python.psi.impl.PyPsiUtils; import com.jetbrains.python.psi.search.PyClassInheritorsSearch; import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import org.jetbrains.annotations.NotNull; import java.util.*; diff --git a/python/src/com/jetbrains/python/refactoring/classes/ui/PyMemberSelectionPanel.java b/python/src/com/jetbrains/python/refactoring/classes/ui/PyMemberSelectionPanel.java index 7ee075424936..330575b9eabc 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/ui/PyMemberSelectionPanel.java +++ b/python/src/com/jetbrains/python/refactoring/classes/ui/PyMemberSelectionPanel.java @@ -19,7 +19,7 @@ import com.intellij.refactoring.classMembers.MemberInfoModel; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.ScrollPaneFactory; import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import org.jetbrains.annotations.NotNull; import javax.swing.*; diff --git a/python/src/com/jetbrains/python/refactoring/classes/ui/PyMemberSelectionTable.java b/python/src/com/jetbrains/python/refactoring/classes/ui/PyMemberSelectionTable.java index 11d3e4285b7c..e34cd591d343 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/ui/PyMemberSelectionTable.java +++ b/python/src/com/jetbrains/python/refactoring/classes/ui/PyMemberSelectionTable.java @@ -22,7 +22,7 @@ import com.intellij.refactoring.ui.AbstractMemberSelectionTable; import com.intellij.ui.RowIcon; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.psi.PyFunction; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import javax.swing.*; import java.util.List; diff --git a/python/src/com/jetbrains/python/refactoring/classes/ui/UpDirectedMembersMovingDialog.java b/python/src/com/jetbrains/python/refactoring/classes/ui/UpDirectedMembersMovingDialog.java index 7ac313d57101..81794643bb59 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/ui/UpDirectedMembersMovingDialog.java +++ b/python/src/com/jetbrains/python/refactoring/classes/ui/UpDirectedMembersMovingDialog.java @@ -23,7 +23,7 @@ import com.intellij.refactoring.util.CommonRefactoringUtil; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.psi.PyUtil; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import javax.swing.*; import java.awt.*; diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/PyExtractSuperclassTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/PyExtractSuperclassTest.java index baab81cc5062..d143e966e077 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/classes/PyExtractSuperclassTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/classes/PyExtractSuperclassTest.java @@ -24,6 +24,8 @@ import com.jetbrains.python.PyNames; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.refactoring.classes.extractSuperclass.PyExtractSuperclassHelper; +import com.jetbrains.python.refactoring.classes.membersManager.MembersManager; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import java.io.File; import java.util.ArrayList; @@ -53,7 +55,7 @@ public class PyExtractSuperclassTest extends PyClassRefactoringTest { final List members = new ArrayList(); for (String memberName : membersName) { final PyElement member = findMember(className, memberName); - members.add(new PyMemberInfo(member)); + members.add(MembersManager.findMember(clazz, member)); } new WriteCommandAction.Simple(myFixture.getProject()) { @@ -81,7 +83,7 @@ public class PyExtractSuperclassTest extends PyClassRefactoringTest { final PyClass clazz = findClass(className); final List members = new ArrayList(); final PyElement member = findMember(className, ".foo"); - members.add(new PyMemberInfo(member)); + members.add(MembersManager.findMember(clazz, member)); final VirtualFile base_dir = myFixture.getFile().getVirtualFile().getParent(); new WriteCommandAction.Simple(myFixture.getProject()) { @@ -124,7 +126,7 @@ public class PyExtractSuperclassTest extends PyClassRefactoringTest { final PyClass clazz = findClass(className); final List members = new ArrayList(); final PyElement member = findMember(className, ".foo"); - members.add(new PyMemberInfo(member)); + members.add(MembersManager.findMember(clazz, member)); final VirtualFile base_dir = myFixture.getFile().getVirtualFile().getParent(); new WriteCommandAction.Simple(myFixture.getProject()) { diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/PyPullUpTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/PyPullUpTest.java index 881dac2a9766..bd56a2c9fda1 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/classes/PyPullUpTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/classes/PyPullUpTest.java @@ -17,6 +17,7 @@ package com.jetbrains.python.refactoring.classes; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; +import com.jetbrains.python.refactoring.classes.membersManager.MembersManager; import com.jetbrains.python.refactoring.classes.pullUp.PyPullUpHelper; import java.util.Collections; @@ -76,6 +77,6 @@ public class PyPullUpTest extends PyClassRefactoringTest { final PyClass clazz = findClass(className); final PyElement member = findMember(className, memberName); final PyClass superClass = findClass(superClassName); - PyPullUpHelper.pullUp(clazz, Collections.singleton(new PyMemberInfo(member)), superClass); + PyPullUpHelper.pullUp(clazz, Collections.singleton(MembersManager.findMember(clazz, member)), superClass); } } diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/PyPushDownTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/PyPushDownTest.java index 72c3bfded44a..480e3a4b4bf7 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/classes/PyPushDownTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/classes/PyPushDownTest.java @@ -18,6 +18,8 @@ package com.jetbrains.python.refactoring.classes; import com.intellij.openapi.command.WriteCommandAction; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; +import com.jetbrains.python.refactoring.classes.membersManager.MembersManager; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import com.jetbrains.python.refactoring.classes.pushDown.PyPushDownProcessor; import java.util.ArrayList; @@ -55,7 +57,7 @@ public class PyPushDownTest extends PyClassRefactoringTest { final List members = new ArrayList(); for (String memberName : membersName) { final PyElement member = findMember(className, memberName); - members.add(new PyMemberInfo(member)); + members.add(MembersManager.findMember(clazz, member)); } final PyPushDownProcessor processor = new PyPushDownProcessor(myFixture.getProject(), clazz, members); diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java index 02092d208518..a07e1d87dbec 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java @@ -7,7 +7,7 @@ import com.intellij.refactoring.classMembers.MemberInfoModel; import com.jetbrains.python.fixtures.PyTestCase; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import com.jetbrains.python.refactoring.classes.PyMemberInfoStorage; import org.easymock.Capture; import org.easymock.EasyMock;