move members: support for move dependant members (IDEA-102024)

This commit is contained in:
anna
2013-02-28 15:04:44 +01:00
parent 46f51eb608
commit f00cc9d530
9 changed files with 43 additions and 8 deletions
@@ -244,7 +244,7 @@ public class MoveJavaMemberHandler implements MoveMemberHandler {
@Override
@Nullable
public PsiElement getAnchor(@NotNull final PsiMember member, @NotNull final PsiClass targetClass) {
public PsiElement getAnchor(@NotNull final PsiMember member, @NotNull final PsiClass targetClass, final Set<PsiMember> membersToMove) {
if (member instanceof PsiField && member.hasModifierProperty(PsiModifier.STATIC)) {
final List<PsiField> afterFields = new ArrayList<PsiField>();
final PsiExpression psiExpression = ((PsiField)member).getInitializer();
@@ -256,7 +256,7 @@ public class MoveJavaMemberHandler implements MoveMemberHandler {
final PsiElement psiElement = expression.resolve();
if (psiElement instanceof PsiField) {
final PsiField psiField = (PsiField)psiElement;
if (psiField.getContainingClass() == targetClass && !afterFields.contains(psiField)) {
if ((psiField.getContainingClass() == targetClass || membersToMove.contains(psiField))&& !afterFields.contains(psiField)) {
afterFields.add(psiField);
}
}
@@ -50,7 +50,7 @@ public interface MoveMemberHandler {
@NotNull MultiMap<PsiElement, String> conflicts);
@Nullable
PsiElement getAnchor(@NotNull PsiMember member, @NotNull PsiClass targetClass);
PsiElement getAnchor(@NotNull PsiMember member, @NotNull PsiClass targetClass, Set<PsiMember> membersToMove);
boolean changeExternalUsage(@NotNull MoveMembersOptions options, @NotNull MoveMembersProcessor.MoveMembersUsageInfo usage);
@@ -157,11 +157,16 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor {
// collect anchors to place moved members at
final Map<PsiMember, SmartPsiElementPointer<PsiElement>> anchors = new HashMap<PsiMember, SmartPsiElementPointer<PsiElement>>();
final Map<PsiMember, PsiMember> anchorsInSourceClass = new HashMap<PsiMember, PsiMember>();
for (PsiMember member : myMembersToMove) {
final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(member.getLanguage());
if (handler != null) {
final PsiElement anchor = handler.getAnchor(member, targetClass);
anchors.put(member, anchor == null ? null : SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(anchor));
final PsiElement anchor = handler.getAnchor(member, targetClass, myMembersToMove);
if (anchor instanceof PsiMember && myMembersToMove.contains((PsiMember)anchor)) {
anchorsInSourceClass.put(member, (PsiMember)anchor);
} else {
anchors.put(member, anchor == null ? null : SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(anchor));
}
}
}
@@ -178,6 +183,7 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor {
}
// correct references inside moved members and outer references to Inner Classes
final Map<PsiMember, PsiMember> movedMembers = new HashMap<PsiMember, PsiMember>();
for (PsiMember member : myMembersToMove) {
ArrayList<PsiReference> refsToBeRebind = new ArrayList<PsiReference>();
for (Iterator<MoveMembersUsageInfo> iterator = otherUsages.iterator(); iterator.hasNext();) {
@@ -193,8 +199,21 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor {
final RefactoringElementListener elementListener = getTransaction().getElementListener(member);
final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(member.getLanguage());
if (handler != null) {
final SmartPsiElementPointer<PsiElement> pointer = anchors.get(member);
PsiMember newMember = handler.doMove(myOptions, member, pointer != null ? pointer.getElement() : null, targetClass);
final PsiElement anchor;
if (anchorsInSourceClass.containsKey(member)) {
final PsiMember memberInSourceClass = anchorsInSourceClass.get(member);
//anchor should be already moved as myMembersToMove contains members in order they appear in source class
anchor = memberInSourceClass != null ? movedMembers.get(memberInSourceClass) : null;
}
else {
final SmartPsiElementPointer<PsiElement> pointer = anchors.get(member);
anchor = pointer != null ? pointer.getElement() : null;
}
PsiMember newMember = handler.doMove(myOptions, member, anchor, targetClass);
movedMembers.put(member, newMember);
elementListener.elementMoved(newMember);
fixModifierList(member, newMember, usages);
@@ -0,0 +1,2 @@
public class A {
}
@@ -0,0 +1,4 @@
public class B {
private static final String FOO = "FOO";
static final String BAR = FOO;
}
@@ -0,0 +1,4 @@
public class A {
private static final String FOO = "FOO";
static final String BAR = FOO;
}
@@ -0,0 +1,2 @@
public class B {
}
@@ -53,6 +53,10 @@ public class MoveMembersTest extends MultiFileTestCase {
doTest("Y", "X", false, 0);
}
public void testDependantConstants() throws Exception {
doTest("A", "B", 0, 1);
}
public void testTwoMethods() throws Exception {
doTest("pack1.A", "pack1.C", 0, 1, 2);
}
@@ -225,7 +225,7 @@ public class MoveGroovyMemberHandler implements MoveMemberHandler {
@Override
@Nullable
public PsiElement getAnchor(@NotNull final PsiMember member, @NotNull final PsiClass targetClass) {
public PsiElement getAnchor(@NotNull final PsiMember member, @NotNull final PsiClass targetClass, Set<PsiMember> membersToMove) {
if (member instanceof GrField && member.hasModifierProperty(PsiModifier.STATIC)) {
final List<PsiField> referencedFields = new ArrayList<PsiField>();
final GrExpression psiExpression = ((GrField)member).getInitializerGroovy();