mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Refactoring (membersManager package introduced) to make PY-3450 Refactoring: pull up class variables/attributes easier
This commit is contained in:
+1
@@ -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
|
||||
|
||||
@@ -29,6 +29,7 @@ public class PyDependentMembersCollector extends DependentMembersCollectorBase<P
|
||||
|
||||
@Override
|
||||
public void collect(PyElement member) {
|
||||
//TODO: Move to MembersManager as well
|
||||
final PyRecursiveElementVisitor visitor = new PyRecursiveElementVisitor() {
|
||||
@Override
|
||||
public void visitPyCallExpression(PyCallExpression node) {
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.classMembers.MemberInfoBase;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.refactoring.classes.ui.PyClassCellRenderer;
|
||||
|
||||
/**
|
||||
* @author Dennis.Ushakov
|
||||
*/
|
||||
public class PyMemberInfo extends MemberInfoBase<PyElement> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -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<PyElement, Py
|
||||
|
||||
@Override
|
||||
protected void extractClassMembers(PyClass aClass, ArrayList<PyMemberInfo> 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
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
|
||||
+118
@@ -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<PyElement, PyMemberInfo> {
|
||||
/**
|
||||
* List of managers. Class delegates all logic to them.
|
||||
*/
|
||||
private static final Collection<MembersManager> 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<PyMemberInfo> getAllMembersCouldBeMoved(@NotNull final PyClass pyClass) {
|
||||
final List<PyMemberInfo> result = new ArrayList<PyMemberInfo>();
|
||||
|
||||
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<PyMemberInfo> memberInfos) {
|
||||
final Multimap<MembersManager, PyMemberInfo> 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<PyElement> 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<PyElement> members);
|
||||
|
||||
//TODO: Doc
|
||||
@SuppressWarnings("NullableProblems") //IDEA-120100
|
||||
@NotNull
|
||||
@Override
|
||||
public abstract PyMemberInfo apply(@NotNull PyElement input);
|
||||
|
||||
private static class PyMemberExtractor implements Function<PyMemberInfo, PyElement> {
|
||||
@SuppressWarnings("NullableProblems") //IDEA-120100
|
||||
@Override
|
||||
public PyElement apply(@NotNull final PyMemberInfo input) {
|
||||
return input.getMember();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+67
@@ -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<PyElement> getMembersCouldBeMoved(@NotNull final PyClass pyClass) {
|
||||
return Arrays.<PyElement>asList(pyClass.getMethods());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void moveMembers(@NotNull PyClass from, @NotNull PyClass to, @NotNull Collection<PyElement> members) {
|
||||
//TODO: Use generics to prevent casting in each subclass
|
||||
Collection<PyFunction> 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();
|
||||
}
|
||||
}
|
||||
@@ -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<PyElement> {
|
||||
@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();
|
||||
}
|
||||
}
|
||||
+69
@@ -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<PyElement> getMembersCouldBeMoved(@NotNull final PyClass pyClass) {
|
||||
return Arrays.<PyElement>asList(pyClass.getSuperClasses());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void moveMembers(@NotNull final PyClass from, @NotNull final PyClass to, @NotNull final Collection<PyElement> members) {
|
||||
final Set<String> 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<String>, Function<PyElement, String> {
|
||||
@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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
@@ -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<PyMemberInfo> selectedMemberInfos, final PyClass superClass) {
|
||||
final Set<String> superClasses = new HashSet<String>();
|
||||
final Set<PsiNamedElement> extractedClasses = new HashSet<PsiNamedElement>();
|
||||
final List<PyFunction> methods = new ArrayList<PyFunction>();
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+1
-1
@@ -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.*;
|
||||
|
||||
@@ -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.*;
|
||||
|
||||
@@ -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;
|
||||
|
||||
+1
-1
@@ -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.*;
|
||||
|
||||
+5
-3
@@ -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<PyMemberInfo> members = new ArrayList<PyMemberInfo>();
|
||||
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<PyMemberInfo> members = new ArrayList<PyMemberInfo>();
|
||||
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<PyMemberInfo> members = new ArrayList<PyMemberInfo>();
|
||||
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()) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<PyMemberInfo> members = new ArrayList<PyMemberInfo>();
|
||||
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);
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user