diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/PullAsAbstractUpFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/PullAsAbstractUpFix.java index c02aa779e12a..c42829baafef 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/PullAsAbstractUpFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/PullAsAbstractUpFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * 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. @@ -29,7 +29,7 @@ import com.intellij.psi.search.PsiElementProcessor; import com.intellij.refactoring.extractInterface.ExtractInterfaceHandler; import com.intellij.refactoring.extractSuperclass.ExtractSuperclassHandler; import com.intellij.refactoring.memberPullUp.JavaPullUpHandler; -import com.intellij.refactoring.memberPullUp.PullUpHelper; +import com.intellij.refactoring.memberPullUp.PullUpProcessor; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.classMembers.MemberInfo; import org.jetbrains.annotations.NotNull; @@ -127,7 +127,7 @@ public class PullAsAbstractUpFix extends LocalQuickFixAndIntentionActionOnPsiEle final MemberInfo memberInfo = new MemberInfo(method); memberInfo.setChecked(true); memberInfo.setToAbstract(true); - new PullUpHelper(containingClass, baseClass, new MemberInfo[]{memberInfo}, new DocCommentPolicy(DocCommentPolicy.ASIS)).run(); + new PullUpProcessor(containingClass, baseClass, new MemberInfo[]{memberInfo}, new DocCommentPolicy(DocCommentPolicy.ASIS)).run(); } @Override diff --git a/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java b/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java index 061d04e70a58..7dd6ac1e01e6 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -31,7 +31,7 @@ import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.extractSuperclass.ExtractSuperClassUtil; import com.intellij.refactoring.lang.ElementsHandler; -import com.intellij.refactoring.memberPullUp.PullUpHelper; +import com.intellij.refactoring.memberPullUp.PullUpProcessor; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.classMembers.MemberInfo; @@ -144,7 +144,7 @@ public class ExtractInterfaceHandler implements RefactoringActionHandler, Elemen final PsiReferenceList referenceList = aClass.isInterface() ? aClass.getExtendsList() : aClass.getImplementsList(); assert referenceList != null; referenceList.add(ref); - PullUpHelper pullUpHelper = new PullUpHelper(aClass, anInterface, selectedMembers, javaDocPolicy); + PullUpProcessor pullUpHelper = new PullUpProcessor(aClass, anInterface, selectedMembers, javaDocPolicy); pullUpHelper.moveMembersToBase(); return anInterface; } diff --git a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java index 96019d40d59b..b4574437f228 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -27,8 +27,11 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.util.*; -import com.intellij.refactoring.memberPullUp.PullUpHelper; +import com.intellij.psi.util.MethodSignature; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.PsiUtilCore; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.refactoring.memberPullUp.PullUpProcessor; import com.intellij.refactoring.ui.ConflictsDialog; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.RefactoringUtil; @@ -39,7 +42,10 @@ import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; /** * @author dsl @@ -76,7 +82,7 @@ public class ExtractSuperClassUtil { PsiJavaCodeReferenceElement ref = createExtendingReference(superclass, subclass, selectedMemberInfos); subclass.getExtendsList().add(ref); - PullUpHelper pullUpHelper = new PullUpHelper(subclass, superclass, selectedMemberInfos, + PullUpProcessor pullUpHelper = new PullUpProcessor(subclass, superclass, selectedMemberInfos, javaDocPolicy ); diff --git a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperclassDialog.java b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperclassDialog.java index 91e1a36011c2..2848f9d22e0e 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperclassDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperclassDialog.java @@ -24,7 +24,7 @@ import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.classMembers.MemberInfoChange; import com.intellij.refactoring.classMembers.MemberInfoModel; -import com.intellij.refactoring.memberPullUp.PullUpHelper; +import com.intellij.refactoring.memberPullUp.PullUpProcessor; import com.intellij.refactoring.ui.MemberSelectionPanel; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier; @@ -39,7 +39,7 @@ import java.util.List; class ExtractSuperclassDialog extends JavaExtractSuperBaseDialog { private final InterfaceContainmentVerifier myContainmentVerifier = new InterfaceContainmentVerifier() { public boolean checkedInterfacesContain(PsiMethod psiMethod) { - return PullUpHelper.checkedInterfacesContain(myMemberInfos, psiMethod); + return PullUpProcessor.checkedInterfacesContain(myMemberInfos, psiMethod); } }; diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHelper.java similarity index 69% rename from java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java rename to java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHelper.java index bde3f6cfd5f2..39913cdf2a60 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHelper.java @@ -13,222 +13,123 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/* - * Created by IntelliJ IDEA. - * User: dsl - * Date: 14.06.2002 - * Time: 22:35:19 - * To change template for new class use - * Code Style | Class Templates options (Tools | IDE Options). - */ package com.intellij.refactoring.memberPullUp; -import com.intellij.analysis.AnalysisScope; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.ChangeContextUtil; import com.intellij.codeInsight.PsiEquivalenceUtil; import com.intellij.codeInsight.intention.AddAnnotationFix; -import com.intellij.lang.findUsages.DescriptiveNameUtil; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ModalityState; +import com.intellij.lang.Language; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Key; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.search.LocalSearchScope; -import com.intellij.psi.search.searches.ClassInheritorsSearch; import com.intellij.psi.search.searches.OverridingMethodsSearch; import com.intellij.psi.search.searches.ReferencesSearch; -import com.intellij.psi.util.*; -import com.intellij.refactoring.BaseRefactoringProcessor; -import com.intellij.refactoring.RefactoringBundle; -import com.intellij.refactoring.classMembers.MemberInfoBase; -import com.intellij.refactoring.listeners.JavaRefactoringListenerManager; -import com.intellij.refactoring.listeners.impl.JavaRefactoringListenerManagerImpl; -import com.intellij.refactoring.util.*; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.util.DocCommentPolicy; +import com.intellij.refactoring.util.RefactoringChangeUtil; +import com.intellij.refactoring.util.RefactoringHierarchyUtil; +import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.refactoring.util.classMembers.ClassMemberReferencesVisitor; import com.intellij.refactoring.util.classMembers.MemberInfo; -import com.intellij.refactoring.util.duplicates.MethodDuplicatesHandler; -import com.intellij.usageView.UsageInfo; -import com.intellij.usageView.UsageViewDescriptor; import com.intellij.util.IncorrectOperationException; -import com.intellij.util.Query; import com.intellij.util.VisibilityUtil; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; -public class PullUpHelper extends BaseRefactoringProcessor{ - private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.memberPullUp.PullUpHelper"); +/** + * Created by Max Medvedev on 10/3/13 + */ +public class JavaPullUpHelper implements PullUpHelper { + private static final Logger LOG = Logger.getInstance(JavaPullUpHelper.class); + private static final Key PRESERVE_QUALIFIER = Key.create("PRESERVE_QUALIFIER"); + + private final PsiClass mySourceClass; private final PsiClass myTargetSuperClass; private final boolean myIsTargetInterface; - private final MemberInfo[] myMembersToMove; private final DocCommentPolicy myJavaDocPolicy; private Set myMembersAfterMove = null; - private final PsiManager myManager; + private Set myMembersToMove; + private Project myProject; - public PullUpHelper(PsiClass sourceClass, PsiClass targetSuperClass, MemberInfo[] membersToMove, DocCommentPolicy javaDocPolicy) { - super(sourceClass.getProject()); - mySourceClass = sourceClass; - myTargetSuperClass = targetSuperClass; - myMembersToMove = membersToMove; - myJavaDocPolicy = javaDocPolicy; - myIsTargetInterface = targetSuperClass.isInterface(); - myManager = mySourceClass.getManager(); + private final QualifiedThisSuperAdjuster myThisSuperAdjuster; + private final ExplicitSuperDeleter myExplicitSuperDeleter; + + public JavaPullUpHelper(PullUpData data) { + myProject = data.getProject(); + myMembersToMove = data.getMembersToMove(); + myMembersAfterMove = data.getMovedMembers(); + myTargetSuperClass = data.getTargetClass(); + mySourceClass = data.getSourceClass(); + myJavaDocPolicy = data.getDocCommentPolicy(); + myIsTargetInterface = myTargetSuperClass.isInterface(); + + myThisSuperAdjuster = new QualifiedThisSuperAdjuster(); + myExplicitSuperDeleter = new ExplicitSuperDeleter(); } - @NotNull - protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { - return new PullUpUsageViewDescriptor(); + @Override + public void encodeContextInfo(MemberInfo info) { + ChangeContextUtil.encodeContextInfo(info.getMember(), true); } - @NotNull - protected UsageInfo[] findUsages() { - final List result = new ArrayList(); - for (MemberInfo memberInfo : myMembersToMove) { - final PsiMember member = memberInfo.getMember(); - if (member.hasModifierProperty(PsiModifier.STATIC)) { - for (PsiReference reference : ReferencesSearch.search(member)) { - result.add(new UsageInfo(reference)); - } - } + @Override + public void move(MemberInfo info, PsiSubstitutor substitutor) { + if (info.getMember() instanceof PsiMethod) { + doMoveMethod(substitutor, info); + } + else if (info.getMember() instanceof PsiField) { + doMoveField(substitutor, info); + } + else if (info.getMember() instanceof PsiClass) { + doMoveClass(substitutor, info); } - return result.isEmpty() ? UsageInfo.EMPTY_ARRAY : result.toArray(new UsageInfo[result.size()]); } - protected void performRefactoring(UsageInfo[] usages) { - moveMembersToBase(); - moveFieldInitializations(); - for (UsageInfo usage : usages) { - PsiElement element = usage.getElement(); - if (element instanceof PsiReferenceExpression) { - PsiExpression qualifierExpression = ((PsiReferenceExpression)element).getQualifierExpression(); - if (qualifierExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifierExpression).resolve() == mySourceClass) { - ((PsiReferenceExpression)qualifierExpression).bindToElement(myTargetSuperClass); - } - } - } - ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void postProcessMember(PsiMember member) { + member.accept(myExplicitSuperDeleter); + member.accept(myThisSuperAdjuster); + + ChangeContextUtil.decodeContextInfo(member, null, null); + + member.accept(new JavaRecursiveElementWalkingVisitor() { @Override - public void run() { - processMethodsDuplicates(); - } - }, ModalityState.NON_MODAL, myProject.getDisposed()); - } - - private void processMethodsDuplicates() { - if (!myTargetSuperClass.isValid()) return; - ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { - @Override - public void run() { - final Query search = ClassInheritorsSearch.search(myTargetSuperClass); - final Set hierarchyFiles = new HashSet(); - for (PsiClass aClass : search) { - final PsiFile containingFile = aClass.getContainingFile(); - if (containingFile != null) { - final VirtualFile virtualFile = containingFile.getVirtualFile(); - if (virtualFile != null) { - hierarchyFiles.add(virtualFile); - } + public void visitReferenceExpression(PsiReferenceExpression expression) { + final PsiExpression qualifierExpression = expression.getQualifierExpression(); + if (qualifierExpression != null) { + final Boolean preserveQualifier = qualifierExpression.getCopyableUserData(PRESERVE_QUALIFIER); + if (preserveQualifier != null && !preserveQualifier) { + qualifierExpression.delete(); + return; } } - final Set methodsToSearchDuplicates = new HashSet(); - for (PsiMember psiMember : myMembersAfterMove) { - if (psiMember instanceof PsiMethod && ((PsiMethod)psiMember).getBody() != null) { - methodsToSearchDuplicates.add(psiMember); - } - } - - MethodDuplicatesHandler.invokeOnScope(myProject, methodsToSearchDuplicates, new AnalysisScope(myProject, hierarchyFiles), true); + super.visitReferenceExpression(expression); } - }, MethodDuplicatesHandler.REFACTORING_NAME, true, myProject); + }); + } - protected String getCommandName() { - return RefactoringBundle.message("pullUp.command", DescriptiveNameUtil.getDescriptiveName(mySourceClass)); - } - - public void moveMembersToBase() throws IncorrectOperationException { - final Set movedMembers = ContainerUtil.newHashSet(); - myMembersAfterMove = ContainerUtil.newHashSet(); - - // build aux sets - for (MemberInfo info : myMembersToMove) { - movedMembers.add(info.getMember()); - } - - // correct private member visibility - for (MemberInfo info : myMembersToMove) { - if (info.getMember() instanceof PsiClass && info.getOverrides() != null) continue; - setCorrectVisibility(movedMembers, info); - ChangeContextUtil.encodeContextInfo(info.getMember(), true); - } - - final PsiSubstitutor substitutor = upDownSuperClassSubstitutor(); - - // do actual move - for (MemberInfo info : myMembersToMove) { - if (info.getMember() instanceof PsiMethod) { - doMoveMethod(movedMembers, substitutor, info); - } - else if (info.getMember() instanceof PsiField) { - doMoveField(movedMembers, substitutor, info); - } - else if (info.getMember() instanceof PsiClass) { - doMoveClass(movedMembers, substitutor, info); - } - } - - ExplicitSuperDeleter explicitSuperDeleter = new ExplicitSuperDeleter(); - for (PsiMember member : myMembersAfterMove) { - member.accept(explicitSuperDeleter); - } - explicitSuperDeleter.fixSupers(); - - final QualifiedThisSuperAdjuster qualifiedThisSuperAdjuster = new QualifiedThisSuperAdjuster(); - for (PsiMember member : myMembersAfterMove) { - member.accept(qualifiedThisSuperAdjuster); - } - - ChangeContextUtil.decodeContextInfo(myTargetSuperClass, null, null); - - for (final PsiMember movedMember : myMembersAfterMove) { - movedMember.accept(new JavaRecursiveElementWalkingVisitor() { - @Override - public void visitReferenceExpression(PsiReferenceExpression expression) { - final PsiExpression qualifierExpression = expression.getQualifierExpression(); - if (qualifierExpression != null) { - final Boolean preserveQualifier = qualifierExpression.getCopyableUserData(PRESERVE_QUALIFIER); - if (preserveQualifier != null && !preserveQualifier) { - qualifierExpression.delete(); - return; - } - } - super.visitReferenceExpression(expression); - } - }); - final JavaRefactoringListenerManager listenerManager = JavaRefactoringListenerManager.getInstance(movedMember.getProject()); - ((JavaRefactoringListenerManagerImpl)listenerManager).fireMemberMoved(mySourceClass, movedMember); - } - } - - private void setCorrectVisibility(final Set movedMembers, MemberInfo info) { + @Override + public void setCorrectVisibility(MemberInfo info) { PsiModifierListOwner modifierListOwner = info.getMember(); if (myIsTargetInterface) { PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PUBLIC, true); } else if (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE)) { - if (info.isToAbstract() || willBeUsedInSubclass(modifierListOwner, movedMembers, myTargetSuperClass, mySourceClass)) { + if (info.isToAbstract() || willBeUsedInSubclass(modifierListOwner, myTargetSuperClass, mySourceClass)) { PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PROTECTED, true); } if (modifierListOwner instanceof PsiClass) { @@ -251,7 +152,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{ private void check(PsiMember member) { if (member.hasModifierProperty(PsiModifier.PRIVATE)) { - if (willBeUsedInSubclass(member, movedMembers, myTargetSuperClass, mySourceClass)) { + if (willBeUsedInSubclass(member, myTargetSuperClass, mySourceClass)) { PsiUtil.setModifierProperty(member, PsiModifier.PROTECTED, true); } } @@ -261,7 +162,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{ } } - private void doMoveClass(Set movedMembers, PsiSubstitutor substitutor, MemberInfo info) { + private void doMoveClass(PsiSubstitutor substitutor, MemberInfo info) { PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); PsiClass aClass = (PsiClass)info.getMember(); if (Boolean.FALSE.equals(info.getOverrides())) { @@ -273,35 +174,35 @@ public class PullUpHelper extends BaseRefactoringProcessor{ if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) { RefactoringUtil.replaceMovedMemberTypeParameters(ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); final PsiReferenceList referenceList = - myTargetSuperClass.isInterface() ? myTargetSuperClass.getExtendsList() : myTargetSuperClass.getImplementsList(); + myIsTargetInterface ? myTargetSuperClass.getExtendsList() : myTargetSuperClass.getImplementsList(); assert referenceList != null; referenceList.add(ref); } } else { RefactoringUtil.replaceMovedMemberTypeParameters(aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); - fixReferencesToStatic(aClass, movedMembers); - final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(aClass); + fixReferencesToStatic(aClass); + final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(convertClassToLanguage(aClass, myTargetSuperClass.getLanguage())); myMembersAfterMove.add(movedElement); aClass.delete(); } } - private void doMoveField(Set movedMembers, PsiSubstitutor substitutor, MemberInfo info) { + private void doMoveField(PsiSubstitutor substitutor, MemberInfo info) { PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); PsiField field = (PsiField)info.getMember(); field.normalizeDeclaration(); RefactoringUtil.replaceMovedMemberTypeParameters(field, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); - fixReferencesToStatic(field, movedMembers); + fixReferencesToStatic(field); if (myIsTargetInterface) { PsiUtil.setModifierProperty(field, PsiModifier.PUBLIC, true); } - final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(field); + final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(convertFieldToLanguage(field, myTargetSuperClass.getLanguage())); myMembersAfterMove.add(movedElement); field.delete(); } - private void doMoveMethod(Set movedMembers, PsiSubstitutor substitutor, MemberInfo info) { + private void doMoveMethod(PsiSubstitutor substitutor, MemberInfo info) { PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); PsiMethod method = (PsiMethod)info.getMember(); PsiMethod sibling = method; @@ -340,11 +241,11 @@ public class PullUpHelper extends BaseRefactoringProcessor{ final PsiMember movedElement = anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy); CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(method.getProject()); if (styleSettings.INSERT_OVERRIDE_ANNOTATION) { - if (PsiUtil.isLanguageLevel5OrHigher(mySourceClass) && !myTargetSuperClass.isInterface() || PsiUtil.isLanguageLevel6OrHigher(mySourceClass)) { + if (PsiUtil.isLanguageLevel5OrHigher(mySourceClass) && !myIsTargetInterface || PsiUtil.isLanguageLevel6OrHigher(mySourceClass)) { new AddAnnotationFix(Override.class.getName(), method).invoke(method.getProject(), null, mySourceClass.getContainingFile()); } } - if (!PsiUtil.isLanguageLevel6OrHigher(mySourceClass) && myTargetSuperClass.isInterface()) { + if (!PsiUtil.isLanguageLevel6OrHigher(mySourceClass) && myIsTargetInterface) { if (isOriginalMethodAbstract) { for (PsiMethod oMethod : OverridingMethodsSearch.search(method)) { deleteOverrideAnnotationIfFound(oMethod); @@ -362,35 +263,45 @@ public class PullUpHelper extends BaseRefactoringProcessor{ PsiUtil.setModifierProperty(myTargetSuperClass, PsiModifier.ABSTRACT, true); } RefactoringUtil.replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); - fixReferencesToStatic(methodCopy, movedMembers); + fixReferencesToStatic(methodCopy); + + Language language = myTargetSuperClass.getLanguage(); final PsiMethod superClassMethod = myTargetSuperClass.findMethodBySignature(methodCopy, false); if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { - superClassMethod.replace(methodCopy); + superClassMethod.replace(convertMethodToLanguage(methodCopy, language)); } else { final PsiMember movedElement = - anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy); + anchor != null ? (PsiMember)myTargetSuperClass.addBefore(convertMethodToLanguage(methodCopy, + language), anchor) : (PsiMember)myTargetSuperClass.add( + convertMethodToLanguage( + methodCopy, language)); myMembersAfterMove.add(movedElement); } method.delete(); } } - private PsiSubstitutor upDownSuperClassSubstitutor() { - PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; - for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(mySourceClass)) { - substitutor = substitutor.put(parameter, null); + private static PsiMethod convertMethodToLanguage(PsiMethod method, Language language) { + if (method.getLanguage().equals(language)) { + return method; } - final Map substitutionMap = - TypeConversionUtil.getSuperClassSubstitutor(myTargetSuperClass, mySourceClass, PsiSubstitutor.EMPTY).getSubstitutionMap(); - for (PsiTypeParameter parameter : substitutionMap.keySet()) { - final PsiType type = substitutionMap.get(parameter); - final PsiClass resolvedClass = PsiUtil.resolveClassInType(type); - if (resolvedClass instanceof PsiTypeParameter) { - substitutor = substitutor.put((PsiTypeParameter)resolvedClass, JavaPsiFacade.getElementFactory(myProject).createType(parameter)); - } + return JVMElementFactories.getFactory(language, method.getProject()).createMethodFromText(method.getText(), null); + } + + private static PsiField convertFieldToLanguage(PsiField field, Language language) { + if (field.getLanguage().equals(language)) { + return field; } - return substitutor; + return JVMElementFactories.getFactory(language, field.getProject()).createField(field.getName(), field.getType()); + } + + private static PsiClass convertClassToLanguage(PsiClass clazz, Language language) { + //if (clazz.getLanguage().equals(language)) { + // return clazz; + //} + //PsiClass newClass = JVMElementFactories.getFactory(language, clazz.getProject()).createClass(clazz.getName()); + return clazz; } private static void deleteOverrideAnnotationIfFound(PsiMethod oMethod) { @@ -400,17 +311,8 @@ public class PullUpHelper extends BaseRefactoringProcessor{ } } - public void moveFieldInitializations() throws IncorrectOperationException { - LOG.assertTrue(myMembersAfterMove != null); - - final LinkedHashSet movedFields = new LinkedHashSet(); - for (PsiMember member : myMembersAfterMove) { - if (member instanceof PsiField) { - movedFields.add((PsiField)member); - } - } - - if (movedFields.isEmpty()) return; + @Override + public void moveFieldInitializations(LinkedHashSet movedFields) { PsiMethod[] constructors = myTargetSuperClass.getConstructors(); if (constructors.length == 0) { @@ -424,6 +326,16 @@ public class PullUpHelper extends BaseRefactoringProcessor{ } } + @Override + public void updateUsage(PsiElement element) { + if (element instanceof PsiReferenceExpression) { + PsiExpression qualifierExpression = ((PsiReferenceExpression)element).getQualifierExpression(); + if (qualifierExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifierExpression).resolve() == mySourceClass) { + ((PsiReferenceExpression)qualifierExpression).bindToElement(myTargetSuperClass); + } + } + } + private static class Initializer { public final PsiStatement initializer; public final Set movedFieldsUsed; @@ -486,7 +398,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{ } } - final PsiElementFactory factory = JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory(); + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(myProject); if (constructor == null) { constructor = (PsiMethod) myTargetSuperClass.add(factory.createConstructor()); @@ -522,8 +434,8 @@ public class PullUpHelper extends BaseRefactoringProcessor{ PsiStatement assignmentStatement = (PsiStatement)constructor.getBody().add(initializer.initializer); - ChangeContextUtil.decodeContextInfo(assignmentStatement, - myTargetSuperClass, RefactoringChangeUtil.createThisExpression(myManager, null)); + PsiManager manager = PsiManager.getInstance(myProject); + ChangeContextUtil.decodeContextInfo(assignmentStatement, myTargetSuperClass, RefactoringChangeUtil.createThisExpression(manager, null)); for (PsiElement psiElement : initializer.statementsToRemove) { psiElement.delete(); } @@ -768,8 +680,8 @@ public class PullUpHelper extends BaseRefactoringProcessor{ return constructorsToSubConstructors; } - private void fixReferencesToStatic(PsiElement classMember, Set movedMembers) throws IncorrectOperationException { - final StaticReferencesCollector collector = new StaticReferencesCollector(movedMembers); + private void fixReferencesToStatic(PsiElement classMember) throws IncorrectOperationException { + final StaticReferencesCollector collector = new StaticReferencesCollector(); classMember.accept(collector); ArrayList refs = collector.getReferences(); ArrayList members = collector.getReferees(); @@ -799,11 +711,9 @@ public class PullUpHelper extends BaseRefactoringProcessor{ private ArrayList myReferences; private ArrayList myReferees; private ArrayList myRefereeClasses; - private final Set myMovedMembers; - private StaticReferencesCollector(Set movedMembers) { + private StaticReferencesCollector() { super(mySourceClass); - myMovedMembers = movedMembers; myReferees = new ArrayList(); myRefereeClasses = new ArrayList(); myReferences = new ArrayList(); @@ -823,13 +733,13 @@ public class PullUpHelper extends BaseRefactoringProcessor{ protected void visitClassMemberReferenceElement(PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) { if (classMember.hasModifierProperty(PsiModifier.STATIC)) { - if (!myMovedMembers.contains(classMember) && + if (!myMembersToMove.contains(classMember) && RefactoringHierarchyUtil.isMemberBetween(myTargetSuperClass, mySourceClass, classMember)) { myReferences.add(classMemberReference); myReferees.add(classMember); myRefereeClasses.add(classMember.getContainingClass()); } - else if (myMovedMembers.contains(classMember) || myMembersAfterMove.contains(classMember)) { + else if (myMembersToMove.contains(classMember) || myMembersAfterMove.contains(classMember)) { myReferences.add(classMemberReference); myReferees.add(classMember); myRefereeClasses.add(myTargetSuperClass); @@ -857,7 +767,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{ final PsiJavaCodeReferenceElement qualifier = expression.getQualifier(); if (qualifier != null && qualifier.isReferenceTo(mySourceClass)) { try { - expression.replace(JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory().createExpressionFromText(myTargetSuperClass.getName() + ".this", null)); + expression.replace(JavaPsiFacade.getElementFactory(myProject).createExpressionFromText(myTargetSuperClass.getName() + ".this", null)); } catch (IncorrectOperationException e) { LOG.error(e); @@ -867,23 +777,25 @@ public class PullUpHelper extends BaseRefactoringProcessor{ } private class ExplicitSuperDeleter extends JavaRecursiveElementWalkingVisitor { - private final ArrayList mySupersToDelete = new ArrayList(); - private final ArrayList mySupersToChangeToThis = new ArrayList(); + private final PsiExpression myThisExpression = JavaPsiFacade.getElementFactory(myProject).createExpressionFromText("this", null); - @Override public void visitReferenceExpression(PsiReferenceExpression expression) { + @Override + public void visitReferenceExpression(PsiReferenceExpression expression) { if(expression.getQualifierExpression() instanceof PsiSuperExpression) { PsiElement resolved = expression.resolve(); if (resolved == null || resolved instanceof PsiMethod && shouldFixSuper((PsiMethod) resolved)) { - mySupersToDelete.add(expression.getQualifierExpression()); + expression.getQualifierExpression().delete(); } } } - @Override public void visitSuperExpression(PsiSuperExpression expression) { - mySupersToChangeToThis.add(expression); + @Override + public void visitSuperExpression(PsiSuperExpression expression) { + expression.replace(myThisExpression); } - @Override public void visitClass(PsiClass aClass) { + @Override + public void visitClass(PsiClass aClass) { // do nothing } @@ -904,59 +816,15 @@ public class PullUpHelper extends BaseRefactoringProcessor{ final PsiMethod methodFromSuper = myTargetSuperClass.findMethodBySignature(method, false); return methodFromSuper == null; } - - public void fixSupers() throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory(); - PsiThisExpression thisExpression = (PsiThisExpression) factory.createExpressionFromText("this", null); - for (PsiExpression psiExpression : mySupersToDelete) { - psiExpression.delete(); - } - - for (PsiSuperExpression psiSuperExpression : mySupersToChangeToThis) { - psiSuperExpression.replace(thisExpression); - } - } } - private static boolean willBeUsedInSubclass(PsiElement member, Set movedMembers, PsiClass superclass, PsiClass subclass) { + private boolean willBeUsedInSubclass(PsiElement member, PsiClass superclass, PsiClass subclass) { for (PsiReference ref : ReferencesSearch.search(member, new LocalSearchScope(subclass), false)) { PsiElement element = ref.getElement(); - if (!RefactoringHierarchyUtil.willBeInTargetClass(element, movedMembers, superclass, false)) { + if (!RefactoringHierarchyUtil.willBeInTargetClass(element, myMembersToMove, superclass, false)) { return true; } } return false; } - - public static boolean checkedInterfacesContain(Collection> memberInfos, PsiMethod psiMethod) { - for (MemberInfoBase memberInfo : memberInfos) { - if (memberInfo.isChecked() && - memberInfo.getMember() instanceof PsiClass && - Boolean.FALSE.equals(memberInfo.getOverrides())) { - if (((PsiClass)memberInfo.getMember()).findMethodBySignature(psiMethod, true) != null) { - return true; - } - } - } - return false; - } - - private class PullUpUsageViewDescriptor implements UsageViewDescriptor { - public String getProcessedElementsHeader() { - return "Pull up members from"; - } - - @NotNull - public PsiElement[] getElements() { - return new PsiElement[]{mySourceClass}; - } - - public String getCodeReferencesText(int usagesCount, int filesCount) { - return "Class to pull up members to \"" + RefactoringUIUtil.getDescription(myTargetSuperClass, true) + "\""; - } - - public String getCommentReferencesText(int usagesCount, int filesCount) { - return null; - } - } } diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHelperFactory.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHelperFactory.java new file mode 100644 index 000000000000..cf945c7735bf --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHelperFactory.java @@ -0,0 +1,26 @@ +/* + * 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.intellij.refactoring.memberPullUp; + +/** +* Created by Max Medvedev on 10/4/13 +*/ +public class JavaPullUpHelperFactory implements PullUpHelperFactory { + @Override + public PullUpHelper createPullUpHelper(PullUpData data) { + return new JavaPullUpHelper(data); + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java index 53bcbf041d2f..0110c55d74bc 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java @@ -58,7 +58,7 @@ public class PullUpDialog extends PullUpDialogBase infos = getSelectedMemberInfos(); - invokeRefactoring(new PullUpHelper(myClass, superClass, infos.toArray(new MemberInfo[infos.size()]), + invokeRefactoring(new PullUpProcessor(myClass, superClass, infos.toArray(new MemberInfo[infos.size()]), new DocCommentPolicy(getJavaDocPolicy()))); close(OK_EXIT_CODE); } diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpProcessor.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpProcessor.java new file mode 100644 index 000000000000..310d5919cf71 --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpProcessor.java @@ -0,0 +1,292 @@ +/* + * 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. + */ + +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 14.06.2002 + * Time: 22:35:19 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.memberPullUp; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.lang.Language; +import com.intellij.lang.findUsages.DescriptiveNameUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.search.searches.ClassInheritorsSearch; +import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.classMembers.MemberInfoBase; +import com.intellij.refactoring.listeners.JavaRefactoringListenerManager; +import com.intellij.refactoring.listeners.impl.JavaRefactoringListenerManagerImpl; +import com.intellij.refactoring.util.DocCommentPolicy; +import com.intellij.refactoring.util.RefactoringUIUtil; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.refactoring.util.duplicates.MethodDuplicatesHandler; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.Query; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +public class PullUpProcessor extends BaseRefactoringProcessor implements PullUpData { + private static final Logger LOG = Logger.getInstance(PullUpProcessor.class); + + private final PsiClass mySourceClass; + private final PsiClass myTargetSuperClass; + private final MemberInfo[] myMembersToMove; + private final DocCommentPolicy myJavaDocPolicy; + private Set myMembersAfterMove = null; + private Set myMovedMembers = null; + private Map> myProcessors = ContainerUtil.newHashMap(); + + public PullUpProcessor(PsiClass sourceClass, PsiClass targetSuperClass, MemberInfo[] membersToMove, DocCommentPolicy javaDocPolicy) { + super(sourceClass.getProject()); + mySourceClass = sourceClass; + myTargetSuperClass = targetSuperClass; + myMembersToMove = membersToMove; + myJavaDocPolicy = javaDocPolicy; + } + + @NotNull + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { + return new PullUpUsageViewDescriptor(); + } + + @NotNull + protected UsageInfo[] findUsages() { + final List result = new ArrayList(); + for (MemberInfo memberInfo : myMembersToMove) { + final PsiMember member = memberInfo.getMember(); + if (member.hasModifierProperty(PsiModifier.STATIC)) { + for (PsiReference reference : ReferencesSearch.search(member)) { + result.add(new UsageInfo(reference)); + } + } + } + return result.isEmpty() ? UsageInfo.EMPTY_ARRAY : result.toArray(new UsageInfo[result.size()]); + } + + protected void performRefactoring(UsageInfo[] usages) { + moveMembersToBase(); + moveFieldInitializations(); + for (UsageInfo usage : usages) { + PsiElement element = usage.getElement(); + if (element == null) continue; + + PullUpHelper processor = getProcessor(element); + processor.updateUsage(element); + } + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + processMethodsDuplicates(); + } + }, ModalityState.NON_MODAL, myProject.getDisposed()); + } + + private void processMethodsDuplicates() { + if (!myTargetSuperClass.isValid()) return; + ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { + @Override + public void run() { + final Query search = ClassInheritorsSearch.search(myTargetSuperClass); + final Set hierarchyFiles = new HashSet(); + for (PsiClass aClass : search) { + final PsiFile containingFile = aClass.getContainingFile(); + if (containingFile != null) { + final VirtualFile virtualFile = containingFile.getVirtualFile(); + if (virtualFile != null) { + hierarchyFiles.add(virtualFile); + } + } + } + final Set methodsToSearchDuplicates = new HashSet(); + for (PsiMember psiMember : myMembersAfterMove) { + if (psiMember instanceof PsiMethod && psiMember.isValid() && ((PsiMethod)psiMember).getBody() != null) { + methodsToSearchDuplicates.add(psiMember); + } + } + + MethodDuplicatesHandler.invokeOnScope(myProject, methodsToSearchDuplicates, new AnalysisScope(myProject, hierarchyFiles), true); + } + }, MethodDuplicatesHandler.REFACTORING_NAME, true, myProject); + } + + protected String getCommandName() { + return RefactoringBundle.message("pullUp.command", DescriptiveNameUtil.getDescriptiveName(mySourceClass)); + } + + public void moveMembersToBase() throws IncorrectOperationException { + myMovedMembers = ContainerUtil.newHashSet(); + myMembersAfterMove = ContainerUtil.newHashSet(); + + // build aux sets + for (MemberInfo info : myMembersToMove) { + myMovedMembers.add(info.getMember()); + } + + final PsiSubstitutor substitutor = upDownSuperClassSubstitutor(); + + for (MemberInfo info : myMembersToMove) { + PullUpHelper processor = getProcessor(info); + + if (!(info.getMember() instanceof PsiClass) || info.getOverrides() == null) { + processor.setCorrectVisibility(info); + processor.encodeContextInfo(info); + } + + processor.move(info, substitutor); + } + + for (PsiMember member : myMembersAfterMove) { + getProcessor(member).postProcessMember(member); + + final JavaRefactoringListenerManager listenerManager = JavaRefactoringListenerManager.getInstance(myProject); + ((JavaRefactoringListenerManagerImpl)listenerManager).fireMemberMoved(mySourceClass, member); + } + } + + private PullUpHelper getProcessor(@NotNull PsiElement element) { + Language language = element.getLanguage(); + return getProcessor(language); + } + + private PullUpHelper getProcessor(Language language) { + PullUpHelper helper = myProcessors.get(language); + if (helper == null) { + helper = PullUpHelper.INSTANCE.forLanguage(language).createPullUpHelper(this); + myProcessors.put(language, helper); + } + return helper; + } + + private PullUpHelper getProcessor(@NotNull MemberInfo info) { + PsiReferenceList refList = info.getSourceReferenceList(); + if (refList != null) { + return getProcessor(refList.getLanguage()); + } + return getProcessor(info.getMember()); + } + + private PsiSubstitutor upDownSuperClassSubstitutor() { + PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; + for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(mySourceClass)) { + substitutor = substitutor.put(parameter, null); + } + final Map substitutionMap = + TypeConversionUtil.getSuperClassSubstitutor(myTargetSuperClass, mySourceClass, PsiSubstitutor.EMPTY).getSubstitutionMap(); + for (PsiTypeParameter parameter : substitutionMap.keySet()) { + final PsiType type = substitutionMap.get(parameter); + final PsiClass resolvedClass = PsiUtil.resolveClassInType(type); + if (resolvedClass instanceof PsiTypeParameter) { + substitutor = substitutor.put((PsiTypeParameter)resolvedClass, JavaPsiFacade.getElementFactory(myProject).createType(parameter)); + } + } + return substitutor; + } + + public void moveFieldInitializations() throws IncorrectOperationException { + LOG.assertTrue(myMembersAfterMove != null); + + final LinkedHashSet movedFields = new LinkedHashSet(); + for (PsiMember member : myMembersAfterMove) { + if (member instanceof PsiField) { + movedFields.add((PsiField)member); + } + } + + if (movedFields.isEmpty()) return; + + getProcessor(myTargetSuperClass).moveFieldInitializations(movedFields); + } + + public static boolean checkedInterfacesContain(Collection> memberInfos, PsiMethod psiMethod) { + for (MemberInfoBase memberInfo : memberInfos) { + if (memberInfo.isChecked() && + memberInfo.getMember() instanceof PsiClass && + Boolean.FALSE.equals(memberInfo.getOverrides())) { + if (((PsiClass)memberInfo.getMember()).findMethodBySignature(psiMethod, true) != null) { + return true; + } + } + } + return false; + } + + @Override + public PsiClass getSourceClass() { + return mySourceClass; + } + + @Override + public PsiClass getTargetClass() { + return myTargetSuperClass; + } + + @Override + public DocCommentPolicy getDocCommentPolicy() { + return myJavaDocPolicy; + } + + @Override + public Set getMembersToMove() { + return myMovedMembers; + } + + @Override + public Set getMovedMembers() { + return myMembersAfterMove; + } + + @Override + public Project getProject() { + return myProject; + } + + private class PullUpUsageViewDescriptor implements UsageViewDescriptor { + public String getProcessedElementsHeader() { + return "Pull up members from"; + } + + @NotNull + public PsiElement[] getElements() { + return new PsiElement[]{mySourceClass}; + } + + public String getCodeReferencesText(int usagesCount, int filesCount) { + return "Class to pull up members to \"" + RefactoringUIUtil.getDescription(myTargetSuperClass, true) + "\""; + } + + public String getCommentReferencesText(int usagesCount, int filesCount) { + return null; + } + } +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractSuperClassTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractSuperClassTest.java index 732ead78deb1..0e211e172ab7 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractSuperClassTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractSuperClassTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * 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. @@ -26,7 +26,7 @@ import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.psi.search.ProjectScope; import com.intellij.refactoring.extractSuperclass.ExtractSuperClassProcessor; import com.intellij.refactoring.memberPullUp.PullUpConflictsUtil; -import com.intellij.refactoring.memberPullUp.PullUpHelper; +import com.intellij.refactoring.memberPullUp.PullUpProcessor; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier; import com.intellij.refactoring.util.classMembers.MemberInfo; @@ -183,7 +183,7 @@ public class ExtractSuperClassTest extends RefactoringTestCase { PullUpConflictsUtil.checkConflicts(members, psiClass, superClass, targetPackage, targetDirectory, new InterfaceContainmentVerifier() { @Override public boolean checkedInterfacesContain(PsiMethod psiMethod) { - return PullUpHelper.checkedInterfacesContain(Arrays.asList(members), psiMethod); + return PullUpProcessor.checkedInterfacesContain(Arrays.asList(members), psiMethod); } }, false); if (conflicts != null) { diff --git a/java/java-tests/testSrc/com/intellij/refactoring/PullUpMultifileTest.java b/java/java-tests/testSrc/com/intellij/refactoring/PullUpMultifileTest.java index a432ce2bc132..2d3864b664f3 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/PullUpMultifileTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/PullUpMultifileTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * 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. @@ -25,7 +25,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.memberPullUp.PullUpConflictsUtil; -import com.intellij.refactoring.memberPullUp.PullUpHelper; +import com.intellij.refactoring.memberPullUp.PullUpProcessor; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier; import com.intellij.refactoring.util.classMembers.MemberInfo; @@ -70,11 +70,11 @@ public class PullUpMultifileTest extends MultiFileTestCase { PullUpConflictsUtil.checkConflicts(membersToMove, srcClass, targetClass, targetPackage, targetDirectory, new InterfaceContainmentVerifier() { @Override public boolean checkedInterfacesContain(PsiMethod psiMethod) { - return PullUpHelper.checkedInterfacesContain(Arrays.asList(membersToMove), psiMethod); + return PullUpProcessor.checkedInterfacesContain(Arrays.asList(membersToMove), psiMethod); } })); - new PullUpHelper(srcClass, targetClass, membersToMove, new DocCommentPolicy(DocCommentPolicy.ASIS)).run(); + new PullUpProcessor(srcClass, targetClass, membersToMove, new DocCommentPolicy(DocCommentPolicy.ASIS)).run(); } }); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java b/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java index 8abdb3b0b34b..aa539bd4d801 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java @@ -21,7 +21,7 @@ import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.listeners.JavaRefactoringListenerManager; import com.intellij.refactoring.listeners.MoveMemberListener; -import com.intellij.refactoring.memberPullUp.PullUpHelper; +import com.intellij.refactoring.memberPullUp.PullUpProcessor; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.classMembers.MemberInfo; import com.intellij.util.ui.UIUtil; @@ -176,7 +176,7 @@ public class PullUpTest extends LightRefactoringTestCase { } }; JavaRefactoringListenerManager.getInstance(getProject()).addMoveMembersListener(listener); - final PullUpHelper helper = new PullUpHelper(sourceClass, targetClass, infos, new DocCommentPolicy(DocCommentPolicy.ASIS)); + final PullUpProcessor helper = new PullUpProcessor(sourceClass, targetClass, infos, new DocCommentPolicy(DocCommentPolicy.ASIS)); helper.run(); UIUtil.dispatchAllInvocationEvents(); JavaRefactoringListenerManager.getInstance(getProject()).removeMoveMembersListener(listener); diff --git a/java/openapi/src/com/intellij/refactoring/memberPullUp/PullUpData.java b/java/openapi/src/com/intellij/refactoring/memberPullUp/PullUpData.java new file mode 100644 index 000000000000..3bda82064f84 --- /dev/null +++ b/java/openapi/src/com/intellij/refactoring/memberPullUp/PullUpData.java @@ -0,0 +1,40 @@ +/* + * 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.intellij.refactoring.memberPullUp; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMember; +import com.intellij.refactoring.util.DocCommentPolicy; + +import java.util.Set; + +/** + * Created by Max Medvedev on 10/3/13 + */ +public interface PullUpData { + PsiClass getSourceClass(); + + PsiClass getTargetClass(); + + DocCommentPolicy getDocCommentPolicy(); + + Set getMembersToMove(); + + Set getMovedMembers(); + + Project getProject(); +} diff --git a/java/openapi/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java b/java/openapi/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java new file mode 100644 index 000000000000..943de7ad9fa6 --- /dev/null +++ b/java/openapi/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java @@ -0,0 +1,44 @@ +/* + * 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.intellij.refactoring.memberPullUp; + +import com.intellij.lang.LanguageExtension; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiMember; +import com.intellij.psi.PsiSubstitutor; +import com.intellij.refactoring.classMembers.MemberInfoBase; + +import java.util.LinkedHashSet; + +/** + * Created by Max Medvedev on 10/4/13 + */ +public interface PullUpHelper> { + LanguageExtension INSTANCE = new LanguageExtension("com.intellij.refactoring.pullUpHelperFactory"); + + void encodeContextInfo(T info); + + void move(T info, PsiSubstitutor substitutor); + + void postProcessMember(PsiMember member); + + void setCorrectVisibility(T info); + + void moveFieldInitializations(LinkedHashSet movedFields); + + void updateUsage(PsiElement element); +} diff --git a/java/openapi/src/com/intellij/refactoring/memberPullUp/PullUpHelperFactory.java b/java/openapi/src/com/intellij/refactoring/memberPullUp/PullUpHelperFactory.java new file mode 100644 index 000000000000..e20090ec3b03 --- /dev/null +++ b/java/openapi/src/com/intellij/refactoring/memberPullUp/PullUpHelperFactory.java @@ -0,0 +1,23 @@ +/* + * 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.intellij.refactoring.memberPullUp; + +/** +* Created by Max Medvedev on 10/4/13 +*/ +public interface PullUpHelperFactory { + PullUpHelper createPullUpHelper(PullUpData data); +} diff --git a/platform/lang-impl/src/com/intellij/refactoring/util/DocCommentPolicy.java b/platform/lang-api/src/com/intellij/refactoring/util/DocCommentPolicy.java similarity index 98% rename from platform/lang-impl/src/com/intellij/refactoring/util/DocCommentPolicy.java rename to platform/lang-api/src/com/intellij/refactoring/util/DocCommentPolicy.java index 308e147dd79a..ffb582d5d0e3 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/util/DocCommentPolicy.java +++ b/platform/lang-api/src/com/intellij/refactoring/util/DocCommentPolicy.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. diff --git a/platform/lang-impl/src/com/intellij/refactoring/classMembers/MemberDependenciesStorage.java b/platform/lang-impl/src/com/intellij/refactoring/classMembers/MemberDependenciesStorage.java index 705bf0d0c6fb..d01dc0f51e9e 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/classMembers/MemberDependenciesStorage.java +++ b/platform/lang-impl/src/com/intellij/refactoring/classMembers/MemberDependenciesStorage.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -41,7 +41,7 @@ public class MemberDependenciesStorage getMemberDependencies(T member) { Set result = myDependencyGraph.get(member); if (result == null) { - DependentMembersCollectorBase collector = getCollector(); + DependentMembersCollectorBase collector = getCollector(member); if (collector != null) { collector.collect(member); result = collector.getCollection(); @@ -51,8 +51,8 @@ public class MemberDependenciesStorage getCollector() { - final ClassMembersRefactoringSupport factory = LanguageDependentMembersRefactoringSupport.INSTANCE.forLanguage(myClass.getLanguage()); + private DependentMembersCollectorBase getCollector(T member) { + final ClassMembersRefactoringSupport factory = LanguageDependentMembersRefactoringSupport.INSTANCE.forLanguage(member.getLanguage()); return factory != null ? factory.createDependentMembersCollector(myClass, mySuperClass) : null; } } diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 2141b63c15c3..e4d8b5428e70 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -1445,6 +1445,8 @@ + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java index b8b2857fb551..f072652b6a90 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java @@ -25,6 +25,7 @@ import com.intellij.psi.search.SearchScope; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.changeSignature.ChangeSignatureHandler; +import com.intellij.refactoring.memberPullUp.JavaPullUpHandler; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; @@ -41,7 +42,6 @@ import org.jetbrains.plugins.groovy.refactoring.introduce.constant.GrIntroduceCo import org.jetbrains.plugins.groovy.refactoring.introduce.field.GrIntroduceFieldHandler; import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GrIntroduceParameterHandler; import org.jetbrains.plugins.groovy.refactoring.introduce.variable.GrIntroduceVariableHandler; -import org.jetbrains.plugins.groovy.refactoring.memberPullUp.GrPullUpHandler; /** * @author ilyas @@ -134,7 +134,7 @@ public class GroovyRefactoringSupportProvider extends RefactoringSupportProvider @Nullable @Override public RefactoringActionHandler getPullUpHandler() { - return new GrPullUpHandler(); + return new JavaPullUpHandler(); } @Nullable diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extractInterface/GrExtractInterfaceHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extractInterface/GrExtractInterfaceHandler.java index 1b7a112e49f5..657bfc1d2511 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extractInterface/GrExtractInterfaceHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extractInterface/GrExtractInterfaceHandler.java @@ -30,7 +30,7 @@ import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.extractInterface.ExtractClassUtil; import com.intellij.refactoring.extractSuperclass.ExtractSuperClassUtil; import com.intellij.refactoring.lang.ElementsHandler; -import com.intellij.refactoring.memberPullUp.PullUpHelper; +import com.intellij.refactoring.memberPullUp.PullUpProcessor; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.classMembers.MemberInfo; @@ -140,7 +140,7 @@ public class GrExtractInterfaceHandler implements RefactoringActionHandler, Elem final PsiReferenceList referenceList = aClass.isInterface() ? aClass.getExtendsList() : aClass.getImplementsList(); assert referenceList != null; referenceList.add(ref); - PullUpHelper pullUpHelper = new PullUpHelper(aClass, anInterface, selectedMembers, javaDocPolicy); + PullUpProcessor pullUpHelper = new PullUpProcessor(aClass, anInterface, selectedMembers, javaDocPolicy); pullUpHelper.moveMembersToBase(); return anInterface; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpDialog.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpDialog.java index f61413bd809d..f5e3646821bf 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpDialog.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpDialog.java @@ -29,11 +29,10 @@ import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.classMembers.MemberInfoModel; import com.intellij.refactoring.memberPullUp.PullUpDialogBase; -import com.intellij.refactoring.memberPullUp.PullUpHelper; +import com.intellij.refactoring.memberPullUp.PullUpProcessor; import com.intellij.refactoring.ui.AbstractMemberSelectionTable; import com.intellij.refactoring.ui.ClassCellRenderer; import com.intellij.refactoring.ui.DocCommentPanel; -import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.RefactoringHierarchyUtil; import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier; import com.intellij.refactoring.util.classMembers.UsesAndInterfacesDependencyMemberInfoModel; @@ -58,7 +57,7 @@ class GrPullUpDialog extends PullUpDialogBase infos = getSelectedMemberInfos(); - GrPullUpHelper processor = new GrPullUpHelper(myClass, superClass, infos.toArray(new GrMemberInfo[infos.size()]), new DocCommentPolicy(getJavaDocPolicy())); - invokeRefactoring(processor); + //GrPullUpProcessor processor = new GrPullUpProcessor(myClass, superClass, infos.toArray(new GrMemberInfo[infos.size()]), new DocCommentPolicy(getJavaDocPolicy())); + //invokeRefactoring(processor); close(OK_EXIT_CODE); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelper.java index e06ee0e3e2c9..6e98ba813cf3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelper.java @@ -17,8 +17,9 @@ package org.jetbrains.plugins.groovy.refactoring.memberPullUp; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.intention.AddAnnotationFix; -import com.intellij.lang.findUsages.DescriptiveNameUtil; +import com.intellij.lang.Language; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettings; @@ -30,19 +31,13 @@ import com.intellij.psi.util.MethodSignatureUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; -import com.intellij.refactoring.BaseRefactoringProcessor; -import com.intellij.refactoring.RefactoringBundle; -import com.intellij.refactoring.listeners.JavaRefactoringListenerManager; -import com.intellij.refactoring.listeners.impl.JavaRefactoringListenerManagerImpl; +import com.intellij.refactoring.memberPullUp.PullUpData; +import com.intellij.refactoring.memberPullUp.PullUpHelper; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.RefactoringHierarchyUtil; -import com.intellij.refactoring.util.RefactoringUIUtil; import com.intellij.refactoring.util.RefactoringUtil; -import com.intellij.usageView.UsageInfo; -import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.refactoring.util.classMembers.MemberInfo; import com.intellij.util.IncorrectOperationException; -import com.intellij.util.containers.ContainerUtil; -import org.codehaus.groovy.runtime.DefaultGroovyMethods; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocComment; import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocCommentOwner; @@ -64,215 +59,106 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.refactoring.GroovyChangeContextUtil; import org.jetbrains.plugins.groovy.refactoring.classMembers.GrClassMemberReferenceVisitor; -import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfo; import java.util.*; /** - * @author Max Medvedev + * Created by Max Medvedev on 10/4/13 */ -public class GrPullUpHelper extends BaseRefactoringProcessor { +public class GrPullUpHelper implements PullUpHelper { private static final Logger LOG = Logger.getInstance(GrPullUpHelper.class); + private static final Key SUPER_REF = Key.create("SUPER_REF"); private static final Key THIS_REF = Key.create("THIS_REF"); private static final Key PRESERVE_QUALIFIER = Key.create("PRESERVE_QUALIFIER"); - private PsiClass mySourceClass; - private GrTypeDefinition myTargetSuperClass; - private GrMemberInfo[] myMembersToMove; + private final PsiClass myTargetSuperClass; + private final Set myMembersToMove; + private final PsiClass mySourceClass; + private Project myProject; private DocCommentPolicy myDocCommentPolicy; private Set myMembersAfterMove; + final ExplicitSuperDeleter myExplicitSuperDeleter; + final QualifiedThisSuperAdjuster myThisSuperAdjuster; + private QualifiedThisSuperSearcher myQualifiedSearcher; - public GrPullUpHelper(PsiClass aClass, PsiClass superClass, GrMemberInfo[] infos, DocCommentPolicy policy) { - super(aClass.getProject()); + public GrPullUpHelper(PullUpData data) { + myTargetSuperClass = data.getTargetClass(); + myMembersToMove = data.getMembersToMove(); + mySourceClass = data.getSourceClass(); + myProject = data.getProject(); + myDocCommentPolicy = data.getDocCommentPolicy(); + myMembersAfterMove = data.getMovedMembers(); + myExplicitSuperDeleter = new ExplicitSuperDeleter(); + myThisSuperAdjuster = new QualifiedThisSuperAdjuster(); - mySourceClass = aClass; - myTargetSuperClass = (GrTypeDefinition)superClass; - myMembersToMove = infos; - myDocCommentPolicy = policy; + myQualifiedSearcher = new QualifiedThisSuperSearcher(); } - @NotNull @Override - protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { - return new UsageViewDescriptor() { - public String getProcessedElementsHeader() { - return "Pull up members from"; - } + public void encodeContextInfo(MemberInfo info) { + GroovyChangeContextUtil.encodeContextInfo(info.getMember()); - @NotNull - public PsiElement[] getElements() { - return new PsiClass[]{mySourceClass}; - } - - public String getCodeReferencesText(int usagesCount, int filesCount) { - return "Class to pull up members to \"" + RefactoringUIUtil.getDescription(myTargetSuperClass, true) + "\""; - } - - public String getCommentReferencesText(int usagesCount, int filesCount) { - return null; - } - }; + ((GroovyPsiElement)info.getMember()).accept(myQualifiedSearcher); } - @NotNull @Override - protected UsageInfo[] findUsages() { - final List result = new ArrayList(); - for (GrMemberInfo info : myMembersToMove) { - final PsiMember member = info.getMember(); - if (member.hasModifierProperty(PsiModifier.STATIC)) { - for (PsiReference reference : ReferencesSearch.search(member)) { - result.add(new UsageInfo(reference)); - } - } + public void move(MemberInfo info, PsiSubstitutor substitutor) { + if (info.getMember() instanceof PsiMethod) { + doMoveMethod(substitutor, info); + } + else if (info.getMember() instanceof PsiField) { + doMoveField(substitutor, info); + } + else if (info.getMember() instanceof PsiClass) { + doMoveClass(substitutor, info); } - - return DefaultGroovyMethods.asType(result, UsageInfo[].class); } @Override - protected void performRefactoring(UsageInfo[] usages) { - moveMembersToBase(); - //moveFieldInitializations(); todo - for (UsageInfo usage : usages) { - PsiElement element = usage.getElement(); - if (element instanceof GrReferenceExpression) { - GrExpression qualifier = ((GrReferenceExpression)element).getQualifier(); - if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).resolve().equals(mySourceClass)) { - ((GrReferenceExpression)qualifier).bindToElement(myTargetSuperClass); - } - } - } + public void postProcessMember(PsiMember member) { + ((GrMember)member).accept(myExplicitSuperDeleter); + ((GrMember)member).accept(myThisSuperAdjuster); - /* - todo - ApplicationManager.application.invokeLater(new Runnable() { + GroovyChangeContextUtil.decodeContextInfo(member, null, null); + + ((GroovyPsiElement)member).accept(new GroovyRecursiveElementVisitor() { @Override - public void run() { - processMethodsDuplicates(); + public void visitReferenceExpression(GrReferenceExpression referenceExpression) { + if (processRef(referenceExpression)) return; + super.visitReferenceExpression(referenceExpression); } - }, ModalityState.NON_MODAL, myProject.getDisposed());*/ + + @Override + public void visitCodeReferenceElement(GrCodeReferenceElement refElement) { + if (processRef(refElement)) return; + super.visitCodeReferenceElement(refElement); + } + + private boolean processRef(@NotNull GrReferenceElement refElement) { + final PsiElement qualifier = refElement.getQualifier(); + if (qualifier != null) { + final Boolean preserveQualifier = qualifier.getCopyableUserData(PRESERVE_QUALIFIER); + if (preserveQualifier != null && !preserveQualifier) { + refElement.setQualifier(null); + return true; + } + } + return false; + } + }); } @Override - protected String getCommandName() { - return RefactoringBundle.message("pullUp.command", DescriptiveNameUtil.getDescriptiveName(mySourceClass)); - } - - public void moveMembersToBase() throws IncorrectOperationException { - final HashSet movedMembers = ContainerUtil.newHashSet(); - myMembersAfterMove = ContainerUtil.newHashSet(); - - // build aux sets - for (GrMemberInfo info : myMembersToMove) { - movedMembers.add(info.getMember()); - } - - - // correct private member visibility - for (GrMemberInfo info : myMembersToMove) { - if (info.getMember() instanceof PsiClass && info.getOverrides() != null) continue; - setCorrectVisibility(movedMembers, info); - GroovyChangeContextUtil.encodeContextInfo(info.getMember()); - info.getMember().accept(new QualifiedThisSuperSearcher()); - fixReferencesToStatic(info.getMember(), movedMembers); - } - - - - - final PsiSubstitutor substitutor = upDownSuperClassSubstitutor(); - - // do actual move - for (GrMemberInfo info : myMembersToMove) { - if (info.getMember() instanceof PsiMethod) { - doMoveMethod(substitutor, info); - } - else if (info.getMember() instanceof GrField) { - doMoveField(substitutor, info); - } - else if (info.getMember() instanceof PsiClass) { - doMoveClass(substitutor, info); - } - } - - - ExplicitSuperDeleter explicitSuperDeleter = new ExplicitSuperDeleter(); - for (PsiMember member : myMembersAfterMove) { - ((GrMember)member).accept(explicitSuperDeleter); - } - explicitSuperDeleter.fixSupers(); - - final QualifiedThisSuperAdjuster qualifiedThisSuperAdjuster = new QualifiedThisSuperAdjuster(); - for (PsiMember member : myMembersAfterMove) { - ((GrMember)member).accept(qualifiedThisSuperAdjuster); - } - - for (PsiMember member : myMembersAfterMove) { - GroovyChangeContextUtil.decodeContextInfo(member, null, null); - } - - - final JavaRefactoringListenerManagerImpl listenerManager = (JavaRefactoringListenerManagerImpl)JavaRefactoringListenerManager.getInstance(myProject); - for (final PsiMember movedMember : myMembersAfterMove) { - ((GroovyPsiElement)movedMember).accept(new GroovyRecursiveElementVisitor() { - @Override - public void visitReferenceExpression(GrReferenceExpression referenceExpression) { - if (processRef(referenceExpression)) return; - super.visitReferenceExpression(referenceExpression); - } - - @Override - public void visitCodeReferenceElement(GrCodeReferenceElement refElement) { - if (processRef(refElement)) return; - super.visitCodeReferenceElement(refElement); - } - - private boolean processRef(@NotNull GrReferenceElement refElement) { - final PsiElement qualifier = refElement.getQualifier(); - if (qualifier != null) { - final Boolean preserveQualifier = qualifier.getCopyableUserData(PRESERVE_QUALIFIER); - if (preserveQualifier != null && !preserveQualifier) { - refElement.setQualifier(null); - return true; - } - } - return false; - } - }); - listenerManager.fireMemberMoved(mySourceClass, movedMember); - } - } - - private PsiSubstitutor upDownSuperClassSubstitutor() { - PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; - for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(mySourceClass)) { - substitutor = substitutor.put(parameter, null); - } - - final Map substitutionMap = - TypeConversionUtil.getSuperClassSubstitutor(myTargetSuperClass, mySourceClass, PsiSubstitutor.EMPTY).getSubstitutionMap(); - for (PsiTypeParameter parameter : substitutionMap.keySet()) { - final PsiType type = substitutionMap.get(parameter); - final PsiClass resolvedClass = PsiUtil.resolveClassInType(type); - if (resolvedClass instanceof PsiTypeParameter) { - substitutor = substitutor.put((PsiTypeParameter)resolvedClass, JavaPsiFacade.getElementFactory(myProject).createType(parameter)); - } - } - - return substitutor; - } - - public void setCorrectVisibility(final HashSet movedMembers, GrMemberInfo info) { + public void setCorrectVisibility(MemberInfo info) { PsiModifierListOwner modifierListOwner = info.getMember(); if (myTargetSuperClass.isInterface()) { PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PUBLIC, true); } else if (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE)) { - if (info.isToAbstract() || willBeUsedInSubclass(modifierListOwner, movedMembers, myTargetSuperClass, mySourceClass)) { + if (info.isToAbstract() || willBeUsedInSubclass(modifierListOwner, myMembersToMove, myTargetSuperClass, mySourceClass)) { PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PROTECTED, true); } @@ -296,7 +182,7 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { private void check(PsiMember member) { if (member.hasModifierProperty(PsiModifier.PRIVATE)) { - if (willBeUsedInSubclass(member, movedMembers, myTargetSuperClass, mySourceClass)) { + if (willBeUsedInSubclass(member, myMembersToMove, myTargetSuperClass, mySourceClass)) { PsiUtil.setModifierProperty(member, PsiModifier.PROTECTED, true); } } @@ -304,6 +190,22 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { }); } } + + } + + @Override + public void moveFieldInitializations(LinkedHashSet movedFields) { + //todo + } + + @Override + public void updateUsage(PsiElement element) { + if (element instanceof GrReferenceExpression) { + GrExpression qualifierExpression = ((GrReferenceExpression)element).getQualifierExpression(); + if (qualifierExpression instanceof GrReferenceExpression && ((GrReferenceExpression)qualifierExpression).resolve() == mySourceClass) { + ((GrReferenceExpression)qualifierExpression).bindToElement(myTargetSuperClass); + } + } } private static boolean willBeUsedInSubclass(PsiElement member, Set movedMembers, PsiClass superclass, PsiClass subclass) { @@ -317,7 +219,7 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { return false; } - private void doMoveMethod(PsiSubstitutor substitutor, GrMemberInfo info) { + private void doMoveMethod(PsiSubstitutor substitutor, MemberInfo info) { GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject); GrMethod method = (GrMethod)info.getMember(); PsiMethod sibling = method; @@ -376,20 +278,25 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { PsiUtil.setModifierProperty(myTargetSuperClass, PsiModifier.ABSTRACT, true); } - //fixReferencesToStatic(methodCopy, movedMembers); + fixReferencesToStatic(methodCopy); replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); final PsiMethod superClassMethod = myTargetSuperClass.findMethodBySignature(methodCopy, false); - final GrMethod movedElement; + + Language language = myTargetSuperClass.getLanguage(); + final PsiMethod movedElement; if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { - movedElement = (GrMethod)superClassMethod.replace(methodCopy); + movedElement = (PsiMethod)superClassMethod.replace(convertMethodToLanguage(methodCopy, language)); } else { - movedElement = - anchor != null ? (GrMethod)myTargetSuperClass.addBefore(methodCopy, anchor) : (GrMethod)myTargetSuperClass.add(methodCopy); + movedElement = anchor != null + ? (PsiMethod)myTargetSuperClass.addBefore(convertMethodToLanguage(methodCopy, language), anchor) + : (PsiMethod)myTargetSuperClass.add(convertMethodToLanguage(methodCopy, language)); myMembersAfterMove.add(movedElement); } - GrDocCommentUtil.setDocComment(movedElement, method.getDocComment()); + if (movedElement instanceof GrMethod) { + GrDocCommentUtil.setDocComment((GrDocCommentOwner)movedElement, method.getDocComment()); + } deleteMemberWithDocComment(method); } @@ -447,8 +354,8 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { } } - private void fixReferencesToStatic(GroovyPsiElement classMember, Set movedMembers) throws IncorrectOperationException { - final StaticReferencesCollector collector = new StaticReferencesCollector(movedMembers); + private void fixReferencesToStatic(GroovyPsiElement classMember) throws IncorrectOperationException { + final StaticReferencesCollector collector = new StaticReferencesCollector(myMembersToMove); classMember.accept(collector); ArrayList refs = collector.getReferences(); ArrayList members = collector.getReferees(); @@ -515,20 +422,18 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { } private class ExplicitSuperDeleter extends GroovyRecursiveElementVisitor { - private final ArrayList mySupersToDelete = ContainerUtil.newArrayList(); - private final ArrayList mySupersToChangeToThis = ContainerUtil.newArrayList(); + private final GrExpression myThisExpression = GroovyPsiElementFactory.getInstance(myProject).createExpressionFromText("this", null); @Override public void visitReferenceExpression(GrReferenceExpression expression) { - super.visitReferenceExpression(expression); if(org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isSuperReference(expression.getQualifierExpression())) { PsiElement resolved = expression.resolve(); if (resolved == null || resolved instanceof PsiMethod && shouldFixSuper((PsiMethod) resolved)) { - mySupersToDelete.add(expression.getQualifierExpression()); + expression.setQualifier(null); } } else if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isSuperReference(expression)) { - mySupersToChangeToThis.add(expression); + expression.replaceWithExpression(myThisExpression, true); } } @@ -554,20 +459,6 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { final PsiMethod methodFromSuper = myTargetSuperClass.findMethodBySignature(method, false); return methodFromSuper == null; } - - public void fixSupers() throws IncorrectOperationException { - final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject); - GrReferenceExpression thisExpression = (GrReferenceExpression) factory.createExpressionFromText("this", null); - for (GrExpression expression : mySupersToDelete) { - if (expression.getParent() instanceof GrReferenceExpression) { - ((GrReferenceExpression)expression.getParent()).setQualifier(null); - } - } - - for (GrReferenceExpression superExpression : mySupersToChangeToThis) { - superExpression.replace(thisExpression); - } - } } private class QualifiedThisSuperAdjuster extends GroovyRecursiveElementVisitor { @@ -604,70 +495,102 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { } } - private void doMoveField(PsiSubstitutor substitutor, GrMemberInfo info) { + private void doMoveField(PsiSubstitutor substitutor, MemberInfo info) { GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject); GrField field = (GrField)info.getMember(); field.normalizeDeclaration(); replaceMovedMemberTypeParameters(field, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); - //fixReferencesToStatic(field, movedMembers); + fixReferencesToStatic(field); if (myTargetSuperClass.isInterface()) { PsiUtil.setModifierProperty(field, PsiModifier.PUBLIC, true); } - final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(field); + final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(convertFieldToLanguage(field, myTargetSuperClass.getLanguage())); myMembersAfterMove.add(movedElement); deleteMemberWithDocComment(field); } - private void doMoveClass(PsiSubstitutor substitutor, GrMemberInfo info) { - GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject); - GrTypeDefinition aClass = (GrTypeDefinition)info.getMember(); + private void doMoveClass(PsiSubstitutor substitutor, MemberInfo info) { if (Boolean.FALSE.equals(info.getOverrides())) { - final GrReferenceList sourceReferenceList = info.getSourceReferenceList(); - LOG.assertTrue(sourceReferenceList != null); - GrCodeReferenceElement ref = mySourceClass.equals(sourceReferenceList.getParent()) ? - removeFromReferenceList(sourceReferenceList, aClass) : - findReferenceToClass(sourceReferenceList, aClass); - if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) { - replaceMovedMemberTypeParameters(ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); - GrReferenceList referenceList; - if (myTargetSuperClass.isInterface()) { - referenceList = myTargetSuperClass.getExtendsClause(); - if (referenceList == null) { - GrExtendsClause newClause = GroovyPsiElementFactory.getInstance(myProject).createExtendsClause(); - PsiElement anchor = myTargetSuperClass.getTypeParameterList() != null ? myTargetSuperClass.getTypeParameterList(): - myTargetSuperClass.getNameIdentifierGroovy(); - referenceList = (GrReferenceList)myTargetSuperClass.addAfter(newClause, anchor); - addSpacesAround(referenceList); - } - } - else { - referenceList = myTargetSuperClass.getImplementsClause(); - - if (referenceList == null) { - GrImplementsClause newClause = GroovyPsiElementFactory.getInstance(myProject).createImplementsClause(); - PsiElement anchor = myTargetSuperClass.getExtendsClause() != null ? myTargetSuperClass.getExtendsClause() : - myTargetSuperClass.getTypeParameterList() != null ? myTargetSuperClass.getTypeParameterList() : - myTargetSuperClass.getNameIdentifierGroovy(); - referenceList = (GrReferenceList)myTargetSuperClass.addAfter(newClause, anchor); - addSpacesAround(referenceList); - } - - } - - assert referenceList != null; - referenceList.add(ref); + PsiClass aClass = (PsiClass)info.getMember(); + if (myTargetSuperClass instanceof GrTypeDefinition) { + addClassToSupers(info, aClass, substitutor, (GrTypeDefinition)myTargetSuperClass); } + } else { + GrTypeDefinition aClass = (GrTypeDefinition)info.getMember(); + GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject); replaceMovedMemberTypeParameters(aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); - //fixReferencesToStatic(aClass, movedMembers); - PsiMember movedElement = (PsiMember)myTargetSuperClass.addAfter(aClass, null); - //movedElement = (PsiMember)CodeStyleManager.getInstance(myProject).reformat(movedElement); + fixReferencesToStatic(aClass); + PsiMember movedElement = (PsiMember)myTargetSuperClass.addAfter(convertClassToLanguage(aClass, myTargetSuperClass.getLanguage()), null); myMembersAfterMove.add(movedElement); deleteMemberWithDocComment(aClass); } } + private static PsiMethod convertMethodToLanguage(PsiMethod method, Language language) { + if (method.getLanguage().equals(language)) { + return method; + } + return JVMElementFactories.getFactory(language, method.getProject()).createMethodFromText(method.getText(), null); + } + + private static PsiField convertFieldToLanguage(PsiField field, Language language) { + if (field.getLanguage().equals(language)) { + return field; + } + return JVMElementFactories.getFactory(language, field.getProject()).createField(field.getName(), field.getType()); + } + + private static PsiClass convertClassToLanguage(PsiClass clazz, Language language) { + //if (clazz.getLanguage().equals(language)) { + // return clazz; + //} + //PsiClass newClass = JVMElementFactories.getFactory(language, clazz.getProject()).createClass(clazz.getName()); + return clazz; + } + + + private void addClassToSupers(MemberInfo info, PsiClass aClass, PsiSubstitutor substitutor, GrTypeDefinition targetSuperClass) { + final PsiReferenceList sourceReferenceList = info.getSourceReferenceList(); + LOG.assertTrue(sourceReferenceList != null); + PsiQualifiedReferenceElement ref = mySourceClass.equals(sourceReferenceList.getParent()) ? + removeFromReferenceList(sourceReferenceList, aClass) : + findReferenceToClass(sourceReferenceList, aClass); + if (ref != null && !targetSuperClass.isInheritor(aClass, false)) { + GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject); + + replaceMovedMemberTypeParameters(ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); + GrReferenceList referenceList; + if (targetSuperClass.isInterface()) { + referenceList = targetSuperClass.getExtendsClause(); + if (referenceList == null) { + GrExtendsClause newClause = GroovyPsiElementFactory.getInstance(myProject).createExtendsClause(); + PsiElement anchor = targetSuperClass.getTypeParameterList() != null ? targetSuperClass.getTypeParameterList(): + targetSuperClass.getNameIdentifierGroovy(); + referenceList = (GrReferenceList)targetSuperClass.addAfter(newClause, anchor); + addSpacesAround(referenceList); + } + } + else { + referenceList = targetSuperClass.getImplementsClause(); + + if (referenceList == null) { + GrImplementsClause newClause = GroovyPsiElementFactory.getInstance(myProject).createImplementsClause(); + PsiElement anchor = targetSuperClass.getExtendsClause() != null ? targetSuperClass.getExtendsClause() : + targetSuperClass.getTypeParameterList() != null ? targetSuperClass.getTypeParameterList() : + targetSuperClass.getNameIdentifierGroovy(); + referenceList = (GrReferenceList)targetSuperClass.addAfter(newClause, anchor); + addSpacesAround(referenceList); + } + + } + + assert referenceList != null; + referenceList.add(ref); + } + } + private static void addSpacesAround(@NotNull GrReferenceList list) { PsiElement prev = list.getPrevSibling(); if (!PsiImplUtil.isWhiteSpace(prev)) { @@ -680,13 +603,16 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { } } - public static GrCodeReferenceElement findReferenceToClass(GrReferenceList refList, PsiClass aClass) { - GrCodeReferenceElement[] refs = refList.getReferenceElementsGroovy(); - for (GrCodeReferenceElement ref : refs) { + public static PsiQualifiedReferenceElement findReferenceToClass(PsiReferenceList refList, PsiClass aClass) { + PsiQualifiedReferenceElement[] refs = refList instanceof GrReferenceList ? ((GrReferenceList)refList).getReferenceElementsGroovy() + : refList.getReferenceElements(); + + for (PsiQualifiedReferenceElement ref : refs) { if (ref.isReferenceTo(aClass)) { return ref; } } + return null; } @@ -696,11 +622,13 @@ public class GrPullUpHelper extends BaseRefactoringProcessor { * * @return if removed - a reference to the class or null if there were no references to this class in the reference list */ - public static GrCodeReferenceElement removeFromReferenceList(GrReferenceList refList, PsiClass aClass) throws IncorrectOperationException { - GrCodeReferenceElement[] refs = refList.getReferenceElementsGroovy(); - for (GrCodeReferenceElement ref : refs) { + public static PsiQualifiedReferenceElement removeFromReferenceList(PsiReferenceList refList, PsiClass aClass) throws IncorrectOperationException { + List refs = Arrays.asList( + refList instanceof GrReferenceList ? ((GrReferenceList)refList).getReferenceElementsGroovy() : refList.getReferenceElements()); + + for (PsiQualifiedReferenceElement ref : refs) { if (ref.isReferenceTo(aClass)) { - GrCodeReferenceElement refCopy = (GrCodeReferenceElement)ref.copy(); + PsiQualifiedReferenceElement refCopy = (PsiQualifiedReferenceElement)ref.copy(); ref.delete(); return refCopy; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelperFactory.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelperFactory.java new file mode 100644 index 000000000000..b43588812ccf --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpHelperFactory.java @@ -0,0 +1,30 @@ +/* + * 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 org.jetbrains.plugins.groovy.refactoring.memberPullUp; + +import com.intellij.refactoring.memberPullUp.PullUpData; +import com.intellij.refactoring.memberPullUp.PullUpHelper; +import com.intellij.refactoring.memberPullUp.PullUpHelperFactory; + +/** + * Created by Max Medvedev on 10/4/13 + */ +public class GrPullUpHelperFactory implements PullUpHelperFactory{ + @Override + public PullUpHelper createPullUpHelper(PullUpData data) { + return new GrPullUpHelper(data); + } +} diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpTest.groovy index 9813355df7ce..844743fdd2fd 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/memberPullUp/GrPullUpTest.groovy @@ -19,14 +19,15 @@ import com.intellij.psi.* import com.intellij.psi.util.PsiTreeUtil import com.intellij.refactoring.listeners.JavaRefactoringListenerManager import com.intellij.refactoring.listeners.MoveMemberListener +import com.intellij.refactoring.memberPullUp.PullUpProcessor import com.intellij.refactoring.util.DocCommentPolicy +import com.intellij.refactoring.util.classMembers.MemberInfo import com.intellij.util.ui.UIUtil import junit.framework.Assert import org.jetbrains.plugins.groovy.LightGroovyTestCase import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember -import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfo import org.jetbrains.plugins.groovy.util.TestUtils /** * Created by Max Medvedev on 8/17/13 @@ -46,9 +47,9 @@ class GrPullUpTest extends LightGroovyTestCase { } public void testQualifiedReference() { // IDEADEV-25008 - doTest(new MemberDescriptor("x", PsiField), - new MemberDescriptor("getX", PsiMethod), - new MemberDescriptor("setX", PsiMethod)); + doTest(new MemberDescriptor("getX", PsiMethod), + new MemberDescriptor("setX", PsiMethod), + new MemberDescriptor("x", PsiField)); } public void testPullUpInheritedStaticClasses() { @@ -179,7 +180,7 @@ class GrPullUpTest extends LightGroovyTestCase { assertTrue(interfaces[0].isWritable()); targetClass = interfaces[0]; } - GrMemberInfo[] infos = findMembers(sourceClass, membersToFind); + MemberInfo[] infos = findMembers(sourceClass, membersToFind); final int[] countMoved = [0]; final MoveMemberListener listener = new MoveMemberListener() { @@ -190,7 +191,7 @@ class GrPullUpTest extends LightGroovyTestCase { } }; JavaRefactoringListenerManager.getInstance(getProject()).addMoveMembersListener(listener); - final GrPullUpHelper helper = new GrPullUpHelper(sourceClass, targetClass, infos, new DocCommentPolicy(DocCommentPolicy.ASIS)); + final PullUpProcessor helper = new PullUpProcessor(sourceClass, targetClass, infos, new DocCommentPolicy(DocCommentPolicy.ASIS)); helper.run(); UIUtil.dispatchAllInvocationEvents(); JavaRefactoringListenerManager.getInstance(getProject()).removeMoveMembersListener(listener); @@ -217,8 +218,8 @@ class GrPullUpTest extends LightGroovyTestCase { } } - public static GrMemberInfo[] findMembers(final PsiClass sourceClass, final MemberDescriptor... membersToFind) { - GrMemberInfo[] infos = new GrMemberInfo[membersToFind.length] + public static MemberInfo[] findMembers(final PsiClass sourceClass, final MemberDescriptor... membersToFind) { + MemberInfo[] infos = new MemberInfo[membersToFind.length] for (int i = 0; i < membersToFind.length; i++) { final Class clazz = membersToFind[i].myClass final String name = membersToFind[i].myName @@ -251,7 +252,7 @@ class GrPullUpTest extends LightGroovyTestCase { assertNotNull(member) assertInstanceOf(member, GrMember) - infos[i] = new GrMemberInfo(member as GrMember, overrides, refList) + infos[i] = new MemberInfo(member as GrMember, overrides, refList) infos[i].setToAbstract(membersToFind[i].myAbstract) } return infos diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 2366313a121f..8c43e986b24a 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -169,6 +169,10 @@ + + + + @@ -1473,6 +1477,8 @@ + +