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;