diff options
Diffstat (limited to 'java/java-impl/src/com/intellij/refactoring')
23 files changed, 542 insertions, 332 deletions
diff --git a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassDialog.java b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassDialog.java index 5460ee36e1f3..02ff65e14b2d 100644 --- a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassDialog.java @@ -17,7 +17,7 @@ package com.intellij.refactoring.copy; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.roots.JavaProjectRootsUtil; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Pass; @@ -38,7 +38,6 @@ import com.intellij.util.ui.FormBuilder; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes; import javax.swing.*; import java.awt.*; @@ -115,7 +114,7 @@ class CopyClassDialog extends DialogWrapper{ } final JLabel label = new JLabel(RefactoringBundle.message("target.destination.folder")); - final boolean isMultipleSourceRoots = ProjectRootManager.getInstance(myProject).getModuleSourceRoots(JavaModuleSourceRootTypes.SOURCES).size() > 1; + final boolean isMultipleSourceRoots = JavaProjectRootsUtil.getSuitableDestinationSourceRoots(myProject).size() > 1; myDestinationCB.setVisible(!myDoClone && isMultipleSourceRoots); label.setVisible(!myDoClone && isMultipleSourceRoots); label.setLabelFor(myDestinationCB); diff --git a/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceDialog.java b/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceDialog.java index c94321e00223..b07cb31c92b0 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceDialog.java @@ -17,6 +17,7 @@ package com.intellij.refactoring.extractInterface; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.RefactoringBundle; @@ -37,6 +38,9 @@ class ExtractInterfaceDialog extends JavaExtractSuperBaseDialog { public ExtractInterfaceDialog(Project project, PsiClass sourceClass) { super(project, sourceClass, collectMembers(sourceClass), ExtractInterfaceHandler.REFACTORING_NAME); + for (MemberInfo memberInfo : myMemberInfos) { + memberInfo.setToAbstract(true); + } init(); } @@ -85,7 +89,7 @@ class ExtractInterfaceDialog extends JavaExtractSuperBaseDialog { protected JComponent createCenterPanel() { JPanel panel = new JPanel(new BorderLayout()); final MemberSelectionPanel memberSelectionPanel = new MemberSelectionPanel(RefactoringBundle.message("members.to.form.interface"), - myMemberInfos, null); + myMemberInfos, RefactoringBundle.message("make.abstract")); memberSelectionPanel.getTable() .setMemberInfoModel(new DelegatingMemberInfoModel<PsiMember, MemberInfo>(memberSelectionPanel.getTable().getMemberInfoModel()) { public Boolean isFixedAbstract(MemberInfo member) { 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/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java index cf428c752d63..701d6bf49970 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java @@ -40,14 +40,16 @@ import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Pass; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.WindowManager; import com.intellij.psi.*; -import com.intellij.psi.codeStyle.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.controlFlow.ControlFlowUtil; import com.intellij.psi.impl.source.codeStyle.JavaCodeStyleManagerImpl; import com.intellij.psi.search.GlobalSearchScope; @@ -327,7 +329,6 @@ public class ExtractMethodProcessor implements MatchProvider { } private boolean isNotNull(PsiVariable outputVariable) { - final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner(); final PsiCodeBlock block = myElementFactory.createCodeBlock(); for (PsiElement element : myElements) { block.add(element); @@ -335,18 +336,15 @@ public class ExtractMethodProcessor implements MatchProvider { final PsiIfStatement statementFromText = (PsiIfStatement)myElementFactory.createStatementFromText("if (" + outputVariable.getName() + " == null);", null); block.add(statementFromText); + final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner(block); final StandardInstructionVisitor visitor = new StandardInstructionVisitor(); final RunnerResult rc = dfaRunner.analyzeMethod(block, visitor); if (rc == RunnerResult.OK) { - if (dfaRunner.problemsDetected(visitor)) { - final Pair<Set<Instruction>,Set<Instruction>> - conditionalExpressions = dfaRunner.getConstConditionalExpressions(); - final Set<Instruction> falseSet = conditionalExpressions.getSecond(); - for (Instruction instruction : falseSet) { - if (instruction instanceof BranchingInstruction) { - if (((BranchingInstruction)instruction).getPsiAnchor().getText().equals(statementFromText.getCondition().getText())) { - return true; - } + final Set<Instruction> falseSet = dfaRunner.getConstConditionalExpressions().getSecond(); + for (Instruction instruction : falseSet) { + if (instruction instanceof BranchingInstruction) { + if (((BranchingInstruction)instruction).getPsiAnchor().getText().equals(statementFromText.getCondition().getText())) { + return true; } } } 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/extractSuperclass/JavaExtractSuperBaseDialog.java b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/JavaExtractSuperBaseDialog.java index 59349c39a2b0..817b6846f6ca 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/JavaExtractSuperBaseDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/JavaExtractSuperBaseDialog.java @@ -17,6 +17,7 @@ package com.intellij.refactoring.extractSuperclass; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.JavaProjectRootsUtil; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.ComponentWithBrowseButton; @@ -36,7 +37,6 @@ import com.intellij.refactoring.util.classMembers.MemberInfo; import com.intellij.ui.EditorComboBox; import com.intellij.ui.components.JBLabel; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes; import javax.swing.*; import java.awt.*; @@ -72,7 +72,7 @@ public abstract class JavaExtractSuperBaseDialog extends ExtractSuperBaseDialog< @Override protected JPanel createDestinationRootPanel() { - final List<VirtualFile> sourceRoots = ProjectRootManager.getInstance(myProject).getModuleSourceRoots(JavaModuleSourceRootTypes.SOURCES); + final List<VirtualFile> sourceRoots = JavaProjectRootsUtil.getSuitableDestinationSourceRoots(myProject); if (sourceRoots.size() <= 1) return super.createDestinationRootPanel(); final JPanel panel = new JPanel(new BorderLayout()); panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); diff --git a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.java b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.java index ca324a02a25f..18e53fb6ece5 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassDialog.java @@ -18,7 +18,7 @@ package com.intellij.refactoring.extractclass; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.roots.JavaProjectRootsUtil; import com.intellij.openapi.ui.Messages; import com.intellij.psi.*; import com.intellij.psi.presentation.java.SymbolPresentationUtil; @@ -42,7 +42,6 @@ import com.intellij.util.ui.FormBuilder; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes; import javax.swing.*; import javax.swing.event.DocumentEvent; @@ -252,7 +251,7 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi .addLabeledComponent(new JLabel(), extractAsEnum) .addLabeledComponent(RefactorJBundle.message("package.for.new.class.label"), packageTextField); - if (ProjectRootManager.getInstance(myProject).getModuleSourceRoots(JavaModuleSourceRootTypes.SOURCES).size() > 1) { + if (JavaProjectRootsUtil.getSuitableDestinationSourceRoots(myProject).size() > 1) { builder.addLabeledComponent(RefactoringBundle.message("target.destination.folder"), myDestinationFolderComboBox); } diff --git a/java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java b/java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java index 28650c7d769f..a21680ee30a8 100644 --- a/java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java @@ -90,7 +90,7 @@ public class InheritanceToDelegationProcessor extends BaseRefactoringProcessor { public InheritanceToDelegationProcessor(Project project, PsiClass aClass, - PsiClass targetBaseClass, + @NotNull PsiClass targetBaseClass, String fieldName, String innerClassName, PsiClass[] delegatedInterfaces, @@ -107,9 +107,8 @@ public class InheritanceToDelegationProcessor extends BaseRefactoringProcessor { myBaseClass = targetBaseClass; LOG.assertTrue( - myBaseClass != null // && !myBaseClass.isInterface() - && (myBaseClass.getQualifiedName() == null || !myBaseClass.getQualifiedName().equals(CommonClassNames.JAVA_LANG_OBJECT)) - ); + // && !myBaseClass.isInterface() + myBaseClass.getQualifiedName() == null || !myBaseClass.getQualifiedName().equals(CommonClassNames.JAVA_LANG_OBJECT), myBaseClass); myBaseClassMembers = getAllBaseClassMembers(); myBaseClassBases = getAllBases(); myBaseClassType = myFactory.createType(myBaseClass, getSuperSubstitutor (myBaseClass)); diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java b/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<MemberInfo> { + private static final Logger LOG = Logger.getInstance(JavaPullUpHelper.class); + private static final Key<Boolean> 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<PsiMember> myMembersAfterMove = null; - private final PsiManager myManager; - - 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 Set<PsiMember> myMembersToMove; + private Project myProject; + + 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<UsageInfo> result = new ArrayList<UsageInfo>(); - 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); } - 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); - } - } + else if (info.getMember() instanceof PsiField) { + doMoveField(substitutor, info); + } + else if (info.getMember() instanceof PsiClass) { + doMoveClass(substitutor, info); } - 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 postProcessMember(PsiMember member) { + member.accept(myExplicitSuperDeleter); + member.accept(myThisSuperAdjuster); + + ChangeContextUtil.decodeContextInfo(member, null, null); + + member.accept(new JavaRecursiveElementWalkingVisitor() { @Override - public void run() { - final Query<PsiClass> search = ClassInheritorsSearch.search(myTargetSuperClass); - final Set<VirtualFile> hierarchyFiles = new HashSet<VirtualFile>(); - 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<PsiMember> methodsToSearchDuplicates = new HashSet<PsiMember>(); - for (PsiMember psiMember : myMembersAfterMove) { - if (psiMember instanceof PsiMethod && ((PsiMethod)psiMember).getBody() != null) { - methodsToSearchDuplicates.add(psiMember); + 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; } } - - 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<PsiMember> 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<PsiMember> 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<PsiMember> 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<PsiMember> 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<PsiMember> 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<PsiTypeParameter, PsiType> 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<PsiField> movedFields = new LinkedHashSet<PsiField>(); - for (PsiMember member : myMembersAfterMove) { - if (member instanceof PsiField) { - movedFields.add((PsiField)member); - } - } - - if (movedFields.isEmpty()) return; + @Override + public void moveFieldInitializations(LinkedHashSet<PsiField> 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<PsiField> 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<PsiMember> 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<PsiJavaCodeReferenceElement> refs = collector.getReferences(); ArrayList<PsiElement> members = collector.getReferees(); @@ -799,11 +711,9 @@ public class PullUpHelper extends BaseRefactoringProcessor{ private ArrayList<PsiJavaCodeReferenceElement> myReferences; private ArrayList<PsiElement> myReferees; private ArrayList<PsiClass> myRefereeClasses; - private final Set<PsiMember> myMovedMembers; - private StaticReferencesCollector(Set<PsiMember> movedMembers) { + private StaticReferencesCollector() { super(mySourceClass); - myMovedMembers = movedMembers; myReferees = new ArrayList<PsiElement>(); myRefereeClasses = new ArrayList<PsiClass>(); myReferences = new ArrayList<PsiJavaCodeReferenceElement>(); @@ -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<PsiExpression> mySupersToDelete = new ArrayList<PsiExpression>(); - private final ArrayList<PsiSuperExpression> mySupersToChangeToThis = new ArrayList<PsiSuperExpression>(); + 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<PsiMember> 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<? extends MemberInfoBase<? extends PsiMember>> memberInfos, PsiMethod psiMethod) { - for (MemberInfoBase<? extends PsiMember> 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<MemberInfoStorage, MemberInfo private final InterfaceContainmentVerifier myInterfaceContainmentVerifier = new InterfaceContainmentVerifier() { public boolean checkedInterfacesContain(PsiMethod psiMethod) { - return PullUpHelper.checkedInterfacesContain(myMemberInfos, psiMethod); + return PullUpProcessor.checkedInterfacesContain(myMemberInfos, psiMethod); } }; @@ -139,7 +139,7 @@ public class PullUpDialog extends PullUpDialogBase<MemberInfoStorage, MemberInfo } List<MemberInfo> 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<PsiMember> myMembersAfterMove = null; + private Set<PsiMember> myMovedMembers = null; + private Map<Language, PullUpHelper<MemberInfo>> 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<UsageInfo> result = new ArrayList<UsageInfo>(); + 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<MemberInfo> 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<PsiClass> search = ClassInheritorsSearch.search(myTargetSuperClass); + final Set<VirtualFile> hierarchyFiles = new HashSet<VirtualFile>(); + 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<PsiMember> methodsToSearchDuplicates = new HashSet<PsiMember>(); + 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<MemberInfo> 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<MemberInfo> getProcessor(@NotNull PsiElement element) { + Language language = element.getLanguage(); + return getProcessor(language); + } + + private PullUpHelper<MemberInfo> getProcessor(Language language) { + PullUpHelper<MemberInfo> helper = myProcessors.get(language); + if (helper == null) { + helper = PullUpHelper.INSTANCE.forLanguage(language).createPullUpHelper(this); + myProcessors.put(language, helper); + } + return helper; + } + + private PullUpHelper<MemberInfo> 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<PsiTypeParameter, PsiType> 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<PsiField> movedFields = new LinkedHashSet<PsiField>(); + 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<? extends MemberInfoBase<? extends PsiMember>> memberInfos, PsiMethod psiMethod) { + for (MemberInfoBase<? extends PsiMember> 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<PsiMember> getMembersToMove() { + return myMovedMembers; + } + + @Override + public Set<PsiMember> 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-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java index bb9379add0b1..9aa1b3125af4 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java @@ -21,6 +21,7 @@ import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.JavaProjectRootsUtil; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.ComboBoxWithWidePopup; @@ -34,7 +35,6 @@ import com.intellij.refactoring.MoveDestination; import com.intellij.refactoring.PackageWrapper; import com.intellij.ui.*; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes; import javax.swing.*; import java.awt.*; @@ -81,7 +81,7 @@ public abstract class DestinationFolderComboBox extends ComboboxWithBrowseButton final PsiDirectory initialTargetDirectory, final Pass<String> errorMessageUpdater, final EditorComboBox editorComboBox) { myInitialTargetDirectory = initialTargetDirectory; - mySourceRoots = ProjectRootManager.getInstance(project).getModuleSourceRoots(JavaModuleSourceRootTypes.SOURCES); + mySourceRoots = JavaProjectRootsUtil.getSuitableDestinationSourceRoots(project); new ComboboxSpeedSearch(getComboBox()) { @Override protected String getElementText(Object element) { diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java index f9e1a9ad87c3..905e3713197c 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java @@ -44,7 +44,6 @@ import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes; import javax.swing.*; import java.awt.*; @@ -301,7 +300,7 @@ public class JavaMoveClassesOrPackagesHandler extends MoveHandlerDelegate { private static boolean canMoveOrRearrangePackages(PsiElement[] elements) { if (elements.length == 0) return false; final Project project = elements[0].getProject(); - if (ProjectRootManager.getInstance(project).getModuleSourceRoots(JavaModuleSourceRootTypes.SOURCES).size() == 1) { + if (JavaProjectRootsUtil.getSuitableDestinationSourceRoots(project).size() == 1) { return false; } for (PsiElement element : elements) { diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java index 424eae716012..30cef8b1273f 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java @@ -25,6 +25,7 @@ import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.JavaProjectRootsUtil; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.Messages; @@ -54,7 +55,6 @@ import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes; import javax.swing.*; import java.awt.*; @@ -506,6 +506,6 @@ public class MoveClassesOrPackagesDialog extends RefactoringDialog { } private List<VirtualFile> getSourceRoots() { - return ProjectRootManager.getInstance(myProject).getModuleSourceRoots(JavaModuleSourceRootTypes.SOURCES); + return JavaProjectRootsUtil.getSuitableDestinationSourceRoots(myProject); } } diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java index 2a5f6396a482..6d333e9cb54b 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java @@ -28,7 +28,7 @@ import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.roots.JavaProjectRootsUtil; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Ref; @@ -44,7 +44,6 @@ import com.intellij.usageView.UsageInfo; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes; import java.util.ArrayList; import java.util.Arrays; @@ -368,7 +367,7 @@ public class MoveClassesOrPackagesImpl { } private static List<PsiDirectory> buildRearrangeTargetsList(final Project project, final PsiDirectory[] directories) { - final List<VirtualFile> sourceRoots = ProjectRootManager.getInstance(project).getModuleSourceRoots(JavaModuleSourceRootTypes.SOURCES); + final List<VirtualFile> sourceRoots = JavaProjectRootsUtil.getSuitableDestinationSourceRoots(project); List<PsiDirectory> sourceRootDirectories = new ArrayList<PsiDirectory>(); sourceRoots: for (final VirtualFile sourceRoot : sourceRoots) { diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java index 2f3e93382199..03540a97e749 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java @@ -20,6 +20,7 @@ import com.intellij.lang.java.JavaFindUsagesProvider; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.JavaProjectRootsUtil; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Computable; @@ -40,7 +41,6 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.HashMap; import com.intellij.psi.util.FileTypeUtils; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes; import java.io.File; import java.util.*; @@ -284,8 +284,7 @@ public class MoveClassesOrPackagesUtil { directory = directories[0]; } else { - final List<VirtualFile> contentSourceRoots = ProjectRootManager.getInstance(project).getModuleSourceRoots( - JavaModuleSourceRootTypes.SOURCES); + final List<VirtualFile> contentSourceRoots = JavaProjectRootsUtil.getSuitableDestinationSourceRoots(project); if (contentSourceRoots.size() == 1 && (baseDirVirtualFile == null || fileIndex.isInTestSourceContent(contentSourceRoots.get(0)) == isBaseDirInTestSources)) { directory = ApplicationManager.getApplication().runWriteAction(new Computable<PsiDirectory>() { @Override diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java index b10af008c89f..dd87120c6770 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java @@ -23,6 +23,7 @@ package com.intellij.refactoring.move.moveInner; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.JavaProjectRootsUtil; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.NullableComputable; @@ -49,7 +50,6 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes; import javax.swing.*; import java.awt.event.ItemEvent; @@ -198,7 +198,7 @@ public class MoveInnerDialog extends RefactoringDialog { final String targetName = myPackageNameField.getText(); if (!Comparing.equal(name, targetName)) { final ProjectRootManager projectRootManager = ProjectRootManager.getInstance(myProject); - final List<VirtualFile> contentSourceRoots = projectRootManager.getModuleSourceRoots(JavaModuleSourceRootTypes.SOURCES); + final List<VirtualFile> contentSourceRoots = JavaProjectRootsUtil.getSuitableDestinationSourceRoots(myProject); final PackageWrapper newPackage = new PackageWrapper(PsiManager.getInstance(myProject), targetName); final VirtualFile targetSourceRoot; if (contentSourceRoots.size() > 1) { diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java index 4dda4d75a304..e24c40dbfe32 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java @@ -58,7 +58,7 @@ public class MoveJavaMemberHandler implements MoveMemberHandler { else { if (qualifier instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifier).isReferenceTo(member.getContainingClass())) { - return new MoveMembersProcessor.MoveMembersUsageInfo(member, refExpr, null, qualifier, psiReference); // change qualifier + return new MoveMembersProcessor.MoveMembersUsageInfo(member, refExpr, targetClass, qualifier, psiReference); // change qualifier } } } diff --git a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaClassProcessor.java b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaClassProcessor.java index 8f8b7770beba..3a4526101285 100644 --- a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaClassProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaClassProcessor.java @@ -38,7 +38,7 @@ import com.intellij.refactoring.util.MoveRenameUsageInfo; import com.intellij.refactoring.util.RefactoringUIUtil; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.usageView.UsageInfo; -import com.intellij.util.ArrayUtil; +import com.intellij.util.ArrayUtilRt; import com.intellij.util.IncorrectOperationException; import com.intellij.util.Processor; import com.intellij.util.containers.MultiMap; @@ -72,7 +72,11 @@ public class RenameJavaClassProcessor extends RenamePsiElementProcessor { if (usage instanceof CollidingClassImportUsageInfo) { ((CollidingClassImportUsageInfo)usage).getImportStatement().delete(); } else if (usage instanceof MemberHidesOuterMemberUsageInfo) { - hidesOut.add((MemberHidesOuterMemberUsageInfo)usage); + final PsiElement usageElement = usage.getElement(); + final PsiJavaCodeReferenceElement collidingRef = (PsiJavaCodeReferenceElement)usageElement; + if (collidingRef != null) { + hidesOut.add(new MemberHidesOuterMemberUsageInfo(usageElement, (PsiClass)collidingRef.resolve())); + } } else { postponedCollisions.add(usage); @@ -105,13 +109,25 @@ public class RenameJavaClassProcessor extends RenamePsiElementProcessor { collision.resolveCollision(); } - /*for (MemberHidesOuterMemberUsageInfo usage : hidesOut) { + for (MemberHidesOuterMemberUsageInfo usage : hidesOut) { PsiJavaCodeReferenceElement collidingRef = (PsiJavaCodeReferenceElement)usage.getElement(); - PsiReferenceExpression ref = RenameJavaMemberProcessor.createQualifiedMemberReference(aClass, collidingRef); - collidingRef.replace(ref); - }*/ - - + PsiMember member = (PsiMember)usage.getReferencedElement(); + if (collidingRef != null && collidingRef.isValid() && member != null && member.isValid()) { + final PsiManager manager = member.getManager(); + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(member.getProject()); + final String name = member.getName(); + final PsiClass containingClass = member.getContainingClass(); + if (name != null && containingClass != null) { + if (manager.areElementsEquivalent(factory.createReferenceFromText(name, collidingRef).resolve(), member)) continue; + final PsiJavaCodeReferenceElement ref = factory.createReferenceFromText("A." + name, collidingRef); + final PsiJavaCodeReferenceElement qualifier = (PsiJavaCodeReferenceElement)ref.getQualifier(); + LOG.assertTrue(qualifier != null); + final PsiJavaCodeReferenceElement classReference = factory.createClassReferenceElement(containingClass); + qualifier.replace(classReference); + collidingRef.replace(ref); + } + } + } if (listener != null) { listener.elementRenamed(aClass); } @@ -252,7 +268,7 @@ public class RenameJavaClassProcessor extends RenamePsiElementProcessor { final PsiTypeParameterListOwner member = PsiTreeUtil.getParentOfType(referenceElement, PsiTypeParameterListOwner.class); if (member != null) { final PsiTypeParameterList typeParameterList = member.getTypeParameterList(); - if (typeParameterList != null && ArrayUtil.find(typeParameterList.getTypeParameters(), myRenamedClass) > -1) { + if (typeParameterList != null && ArrayUtilRt.find(typeParameterList.getTypeParameters(), myRenamedClass) > -1) { if (member.hasModifierProperty(PsiModifier.STATIC)) return; } } diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/rules/RootTypeConversionRule.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/rules/RootTypeConversionRule.java index c32b873207fa..052d27ab66c0 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeMigration/rules/RootTypeConversionRule.java +++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/rules/RootTypeConversionRule.java @@ -84,8 +84,9 @@ public class RootTypeConversionRule extends TypeConversionRule { type = superClassSubstitutor.substitute(type); } - if (!originalType.equals(type)) { - labeler.migrateExpressionType(actualParams[i], methodTypeParamsSubstitutor.substitute(type), context, false, true); + final PsiType migrationType = methodTypeParamsSubstitutor.substitute(type); + if (!originalType.equals(migrationType) && !TypeConversionUtil.areTypesAssignmentCompatible(migrationType, actualParams[i])) { + labeler.migrateExpressionType(actualParams[i], migrationType, context, false, true); } } } diff --git a/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java b/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java index 527c0309c628..2f80b2c651a1 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java @@ -228,7 +228,12 @@ public class InlineUtil { if (lastInitializerSibling.getNode().getElementType() == JavaTokenType.COMMA) { lastInitializerSibling = lastInitializerSibling.getPrevSibling(); } - argumentList.addRange(initializers[0], lastInitializerSibling); + PsiElement firstElement = initializers[0]; + final PsiElement leadingComment = PsiTreeUtil.skipSiblingsBackward(firstElement, PsiWhiteSpace.class); + if (leadingComment instanceof PsiComment) { + firstElement = leadingComment; + } + argumentList.addRange(firstElement, lastInitializerSibling); } args[args.length - 1].delete(); } |