blob: 2cf9efda6d4a5f723417ebd368ce39a7b66221ca [file] [log] [blame]
package com.jetbrains.python.refactoring.classes.membersManager;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyElement;
import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
/**
* Moves members checking types at runtime.
*
* @author Ilya.Kazakevich
*/
class TypeSafeMovingStrategy<T extends PyElement> {
@NotNull private final PyClass myFrom;
@NotNull private final MembersManager<T> myManager;
@NotNull private final Collection<PyMemberInfo<T>> myMemberInfoCollection;
@NotNull private final PyClass[] myTo;
/**
* Move members.
* @param from source
* @param manager manager to be used
* @param memberInfoCollection what to move
* @param to where
*/
@SuppressWarnings({"unchecked", "rawtypes"}) //We check types at runtime
static void moveCheckingTypesAtRunTime(@NotNull final PyClass from,
@NotNull final MembersManager<?> manager,
@NotNull final Collection<PyMemberInfo<PyElement>> memberInfoCollection,
@NotNull final PyClass... to) {
manager.checkElementTypes((Collection)MembersManager.fetchElements(memberInfoCollection));
new TypeSafeMovingStrategy(from, manager, memberInfoCollection, to).moveTyped();
}
private TypeSafeMovingStrategy(@NotNull final PyClass from,
@NotNull final MembersManager<T> manager,
@NotNull final Collection<PyMemberInfo<T>> memberInfoCollection,
@NotNull final PyClass[] to) {
myFrom = from;
myManager = manager;
myMemberInfoCollection = new ArrayList<PyMemberInfo<T>>(memberInfoCollection);
myTo = to.clone();
}
/**
* While types are already checked at runtime, this method could move everything in type-safe manner.
*/
private void moveTyped() {
final Collection<T> elementsCollection = MembersManager.fetchElements(myMemberInfoCollection);
final Collection<? extends PyElement> references = myManager.getElementsToStoreReferences(elementsCollection);
// Store references to add required imports
for (final PyElement element : references) {
PyClassRefactoringUtil.rememberNamedReferences(element, PyNames.CANONICAL_SELF); //"self" is not reference we need to move
}
// Move
final Collection<PyElement> newElements = myManager.moveMembers(myFrom, myMemberInfoCollection, myTo);
// Restore references to add appropriate imports
for (final PyElement element : newElements) {
PyClassRefactoringUtil.restoreNamedReferences(element);
}
}
}