From a9cdd39dc326eb25f347e9b2b60cdbb4bdf5ee7c Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 5 Oct 2009 19:59:13 +0400 Subject: [PATCH] pull up/push down with references to locals --- .../impl/quickfix/CreateFromUsageBaseFix.java | 4 +- .../generation/GenerateMembersUtil.java | 4 +- .../ChangeSignatureProcessor.java | 4 +- .../ConvertToInstanceMethodProcessor.java | 9 +- .../memberPullUp/PullUpConflictsUtil.java | 18 +- .../memberPushDown/PushDownConflicts.java | 2 + ...eatingSingleSourceRootMoveDestination.java | 3 +- .../SingleSourceRootMoveDestination.java | 4 +- .../MoveInstanceMethodProcessor.java | 10 +- .../moveMembers/MoveJavaMemberHandler.java | 3 +- .../moveMembers/MoveMembersProcessor.java | 117 +-------- .../util/RefactoringConflictsUtil.java | 247 ++++++++++++++++++ .../refactoring/util/RefactoringUtil.java | 115 -------- .../move/MoveGroovyMemberHandler.java | 6 +- 14 files changed, 283 insertions(+), 263 deletions(-) create mode 100644 java/java-impl/src/com/intellij/refactoring/util/RefactoringConflictsUtil.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java index 7d5942c812fd..14c3a7b3ee51 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java @@ -20,7 +20,7 @@ import com.intellij.openapi.ui.popup.PopupChooserBuilder; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.RefactoringConflictsUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -140,7 +140,7 @@ public abstract class CreateFromUsageBaseFix extends BaseIntentionAction { list.deleteChildRange(list.getFirstChild(), list.getLastChild()); return; } - RefactoringUtil.setVisibility(list, getVisibility(parentClass, targetClass)); + RefactoringConflictsUtil.setVisibility(list, getVisibility(parentClass, targetClass)); } protected String getVisibility(PsiClass parentClass, PsiClass targetClass) { diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java index 6b39a8c1a694..1074b2bf7b16 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java @@ -14,7 +14,7 @@ import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; -import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.RefactoringConflictsUtil; import com.intellij.util.VisibilityUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.HashMap; @@ -197,7 +197,7 @@ public class GenerateMembersUtil { newMethod = factory.createMethod(method.getName(), substituteType(substitutor, returnType)); } - RefactoringUtil.setVisibility(newMethod.getModifierList(), VisibilityUtil.getVisibilityModifier(method.getModifierList())); + RefactoringConflictsUtil.setVisibility(newMethod.getModifierList(), VisibilityUtil.getVisibilityModifier(method.getModifierList())); PsiElement navigationElement = method.getNavigationElement(); PsiDocComment docComment = ((PsiDocCommentOwner)navigationElement).getDocComment(); diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java index 0e1f7bd4fede..a41e04e69f82 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java @@ -375,7 +375,7 @@ public class ChangeSignatureProcessor extends BaseRefactoringProcessor { private void addInaccessibilityDescriptions(Set usages, MultiMap conflictDescriptions) throws IncorrectOperationException { PsiMethod method = myChangeInfo.getMethod(); PsiModifierList modifierList = (PsiModifierList)method.getModifierList().copy(); - RefactoringUtil.setVisibility(modifierList, myNewVisibility); + RefactoringConflictsUtil.setVisibility(modifierList, myNewVisibility); for (Iterator iterator = usages.iterator(); iterator.hasNext();) { UsageInfo usageInfo = iterator.next(); @@ -1019,7 +1019,7 @@ public class ChangeSignatureProcessor extends BaseRefactoringProcessor { final String highestVisibility = isOriginal ? myNewVisibility : VisibilityUtil.getHighestVisibility(myNewVisibility, VisibilityUtil.getVisibilityModifier(modifierList)); - RefactoringUtil.setVisibility(modifierList, highestVisibility); + RefactoringConflictsUtil.setVisibility(modifierList, highestVisibility); } if (myChangeInfo.isNameChanged) { diff --git a/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java index 020236bcb200..7b9ee99496aa 100644 --- a/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java @@ -18,7 +18,6 @@ import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.move.moveInstanceMethod.MoveInstanceMethodViewDescriptor; -import com.intellij.refactoring.move.moveMembers.MoveMembersProcessor; import com.intellij.refactoring.util.*; import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewDescriptor; @@ -122,12 +121,12 @@ public class ConvertToInstanceMethodProcessor extends BaseRefactoringProcessor { final Set methods = Collections.singleton((PsiMember)myMethod); if (!myTargetClass.isInterface()) { final String original = VisibilityUtil.getVisibilityModifier(myMethod.getModifierList()); - MoveMembersProcessor.analyzeAccessibilityConflicts(methods, myTargetClass, conflicts, original); + RefactoringConflictsUtil.analyzeAccessibilityConflicts(methods, myTargetClass, conflicts, original); } else { for (final UsageInfo usage : usagesIn) { if (usage instanceof ImplementingClassUsageInfo) { - MoveMembersProcessor + RefactoringConflictsUtil .analyzeAccessibilityConflicts(methods, ((ImplementingClassUsageInfo)usage).getPsiClass(), conflicts, PsiModifier.PUBLIC); } } @@ -165,10 +164,10 @@ public class ConvertToInstanceMethodProcessor extends BaseRefactoringProcessor { final PsiModifierList copy = (PsiModifierList)myMethod.getModifierList().copy(); if (myNewVisibility != null) { if (myNewVisibility.equals(VisibilityUtil.ESCALATE_VISIBILITY)) { - RefactoringUtil.setVisibility(copy, PsiModifier.PUBLIC); + RefactoringConflictsUtil.setVisibility(copy, PsiModifier.PUBLIC); } else { - RefactoringUtil.setVisibility(copy, myNewVisibility); + RefactoringConflictsUtil.setVisibility(copy, myNewVisibility); } } diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java index d105ec6d1eb5..ba48c8f406d8 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java @@ -14,10 +14,7 @@ import com.intellij.psi.util.MethodSignatureUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.RefactoringBundle; -import com.intellij.refactoring.util.CommonRefactoringUtil; -import com.intellij.refactoring.util.RefactoringHierarchyUtil; -import com.intellij.refactoring.util.RefactoringUIUtil; -import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.*; import com.intellij.refactoring.util.classMembers.ClassMemberReferencesVisitor; import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier; import com.intellij.refactoring.util.classMembers.MemberInfo; @@ -35,7 +32,7 @@ public class PullUpConflictsUtil { PsiPackage targetPackage, PsiDirectory targetDirectory, final InterfaceContainmentVerifier interfaceContainmentVerifier) { - final Set movedMembers = new HashSet(); + final Set movedMembers = new HashSet(); final Set abstractMethods = new HashSet(); final boolean isInterfaceTarget; final PsiElement targetRepresentativeElement; @@ -48,7 +45,7 @@ public class PullUpConflictsUtil { targetRepresentativeElement = targetDirectory; } for (MemberInfo info : infos) { - PsiElement member = info.getMember(); + PsiMember member = info.getMember(); if (member instanceof PsiMethod) { if (!info.isToAbstract() && !isInterfaceTarget) { movedMembers.add(member); @@ -62,6 +59,7 @@ public class PullUpConflictsUtil { } } final MultiMap conflicts = new MultiMap(); + RefactoringConflictsUtil.analyzeAccessibilityConflicts(movedMembers, superClass, conflicts, null); if (superClass != null) { checkSuperclassMembers(superClass, infos, conflicts); if (isInterfaceTarget) { @@ -70,7 +68,7 @@ public class PullUpConflictsUtil { } // check if moved methods use other members in the classes between Subclass and Superclass List checkModuleConflictsList = new ArrayList(); - for (PsiElement member : movedMembers) { + for (PsiMember member : movedMembers) { if (member instanceof PsiMethod || member instanceof PsiClass) { ConflictingUsagesOfSubClassMembers visitor = new ConflictingUsagesOfSubClassMembers(member, movedMembers, abstractMethods, subclass, superClass, @@ -85,7 +83,7 @@ public class PullUpConflictsUtil { checkModuleConflictsList.add(method.getReturnTypeElement()); checkModuleConflictsList.add(method.getTypeParameterList()); } - RefactoringUtil.analyzeModuleConflicts(subclass.getProject(), checkModuleConflictsList, + RefactoringConflictsUtil.analyzeModuleConflicts(subclass.getProject(), checkModuleConflictsList, new UsageInfo[0], targetRepresentativeElement, conflicts); return conflicts; } @@ -144,7 +142,7 @@ public class PullUpConflictsUtil { private static class ConflictingUsagesOfSubClassMembers extends ClassMemberReferencesVisitor { private final PsiElement myScope; - private final Set myMovedMembers; + private final Set myMovedMembers; private final Set myAbstractMethods; private final PsiClass mySubclass; private final PsiClass mySuperClass; @@ -153,7 +151,7 @@ public class PullUpConflictsUtil { private final InterfaceContainmentVerifier myInterfaceContainmentVerifier; ConflictingUsagesOfSubClassMembers(PsiElement scope, - Set movedMembers, Set abstractMethods, + Set movedMembers, Set abstractMethods, PsiClass subclass, PsiClass superClass, PsiPackage targetPackage, MultiMap conflictsList, InterfaceContainmentVerifier interfaceContainmentVerifier) { diff --git a/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownConflicts.java b/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownConflicts.java index d4ec65f3d0bc..3552c3960089 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownConflicts.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownConflicts.java @@ -5,6 +5,7 @@ import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.InheritanceUtil; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.util.CommonRefactoringUtil; +import com.intellij.refactoring.util.RefactoringConflictsUtil; import com.intellij.refactoring.util.RefactoringUIUtil; import com.intellij.refactoring.util.classMembers.ClassMemberReferencesVisitor; import com.intellij.refactoring.util.classMembers.MemberInfo; @@ -79,6 +80,7 @@ public class PushDownConflicts { } } } + RefactoringConflictsUtil.analyzeAccessibilityConflicts(myMovedMembers, targetClass, myConflicts, null); } public void checkMemberPlacementInTargetClassConflict(final PsiClass targetClass, final PsiMember movedMember) { diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java index fe25b04c6e70..66c663bbd822 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java @@ -6,6 +6,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiPackage; import com.intellij.refactoring.PackageWrapper; +import com.intellij.refactoring.util.RefactoringConflictsUtil; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.usageView.UsageInfo; import com.intellij.util.IncorrectOperationException; @@ -61,7 +62,7 @@ public class AutocreatingSingleSourceRootMoveDestination extends AutocreatingMov public void analyzeModuleConflicts(final Collection elements, MultiMap conflicts, final UsageInfo[] usages) { - RefactoringUtil.analyzeModuleConflicts(getTargetPackage().getManager().getProject(), elements, usages, mySourceRoot, conflicts); + RefactoringConflictsUtil.analyzeModuleConflicts(getTargetPackage().getManager().getProject(), elements, usages, mySourceRoot, conflicts); } PsiDirectory myTargetDirectory = null; diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/SingleSourceRootMoveDestination.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/SingleSourceRootMoveDestination.java index 4306a3f9fcd8..c3359d44d1b8 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/SingleSourceRootMoveDestination.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/SingleSourceRootMoveDestination.java @@ -4,7 +4,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; import com.intellij.refactoring.MoveDestination; import com.intellij.refactoring.PackageWrapper; -import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.RefactoringConflictsUtil; import com.intellij.usageView.UsageInfo; import com.intellij.util.containers.MultiMap; @@ -55,7 +55,7 @@ public class SingleSourceRootMoveDestination implements MoveDestination { public void analyzeModuleConflicts(final Collection elements, MultiMap conflicts, final UsageInfo[] usages) { - RefactoringUtil.analyzeModuleConflicts(myPackage.getManager().getProject(), elements, usages, myTargetDirectory, conflicts); + RefactoringConflictsUtil.analyzeModuleConflicts(myPackage.getManager().getProject(), elements, usages, myTargetDirectory, conflicts); } public PsiDirectory getTargetDirectory(PsiFile source) { diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java index b084bff35c3b..a2b0de8fa110 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java @@ -14,11 +14,7 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.move.MoveInstanceMembersUtil; -import com.intellij.refactoring.move.moveMembers.MoveMembersProcessor; -import com.intellij.refactoring.util.CommonRefactoringUtil; -import com.intellij.refactoring.util.ConflictsUtil; -import com.intellij.refactoring.util.RefactoringUIUtil; -import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.refactoring.util.*; import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewDescriptor; import com.intellij.util.IncorrectOperationException; @@ -78,12 +74,12 @@ public class MoveInstanceMethodProcessor extends BaseRefactoringProcessor{ members.add(myMethod); if (myTargetVariable instanceof PsiField) members.add((PsiMember)myTargetVariable); if (!myTargetClass.isInterface()) { - MoveMembersProcessor.analyzeAccessibilityConflicts(members, myTargetClass, conflicts, myNewVisibility); + RefactoringConflictsUtil.analyzeAccessibilityConflicts(members, myTargetClass, conflicts, myNewVisibility); } else { for (final UsageInfo usage : usages) { if (usage instanceof InheritorUsageInfo) { - MoveMembersProcessor.analyzeAccessibilityConflicts( + RefactoringConflictsUtil.analyzeAccessibilityConflicts( members, ((InheritorUsageInfo)usage).getInheritor(), conflicts, myNewVisibility); } } 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 ee80c762befc..95af12897019 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 @@ -7,6 +7,7 @@ import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilBase; import com.intellij.refactoring.util.EnumConstantsUtil; +import com.intellij.refactoring.util.RefactoringConflictsUtil; import com.intellij.refactoring.util.RefactoringHierarchyUtil; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.util.IncorrectOperationException; @@ -109,7 +110,7 @@ public class MoveJavaMemberHandler implements MoveMemberHandler { assert list != null; list.setModifierProperty(PsiModifier.STATIC, member.hasModifierProperty(PsiModifier.STATIC)); list.setModifierProperty(PsiModifier.FINAL, member.hasModifierProperty(PsiModifier.FINAL)); - RefactoringUtil.setVisibility(list, VisibilityUtil.getVisibilityModifier(member.getModifierList())); + RefactoringConflictsUtil.setVisibility(list, VisibilityUtil.getVisibilityModifier(member.getModifierList())); } } member.delete(); diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java index 40dcb89357db..e539facf081b 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java @@ -219,7 +219,7 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor { } } } else { - RefactoringUtil.setVisibility(modifierList, myNewVisibility); + RefactoringConflictsUtil.setVisibility(modifierList, myNewVisibility); } } @@ -233,7 +233,7 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor { LOG.error(e); } analyzeMoveConflicts(myMembersToMove, myTargetClass, myNewVisibility, conflicts); - RefactoringUtil.analyzeModuleConflicts(myProject, myMembersToMove, usages, myTargetClass, conflicts); + RefactoringConflictsUtil.analyzeModuleConflicts(myProject, myMembersToMove, usages, myTargetClass, conflicts); return showConflicts(conflicts); } @@ -248,7 +248,7 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor { PsiModifierList copy = member.getModifierList(); if (copy!=null) copy= (PsiModifierList)copy.copy(); if (newVisibility != null) { - if (copy!=null) RefactoringUtil.setVisibility(copy, newVisibility); + if (copy!=null) RefactoringConflictsUtil.setVisibility(copy, newVisibility); } modifierListCopies.put(member, copy); } @@ -318,116 +318,7 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor { } } } - analyzeAccessibilityConflicts(membersToMove, targetClass, conflicts, newVisibility); - } - - public static void analyzeAccessibilityConflicts(@NotNull Set membersToMove, - final PsiClass targetClass, - final MultiMap conflicts, String newVisibility) { - if (VisibilityUtil.ESCALATE_VISIBILITY.equals(newVisibility)) { //Still need to check for access object - newVisibility = PsiModifier.PUBLIC; - } - - for (PsiMember member : membersToMove) { - checkUsedElements(member, member, membersToMove, targetClass, conflicts); - - PsiModifierList modifierList = member.getModifierList(); - if (modifierList!=null) modifierList= (PsiModifierList)modifierList.copy(); - - if (newVisibility != null) { - try { - if (modifierList!=null) RefactoringUtil.setVisibility(modifierList, newVisibility); - } - catch (IncorrectOperationException ex) { - /* do nothing and hope for the best */ - } - } - JavaPsiFacade manager = JavaPsiFacade.getInstance(member.getProject()); - for (PsiReference psiReference : ReferencesSearch.search(member)) { - PsiElement ref = psiReference.getElement(); - if (!RefactoringHierarchyUtil.willBeInTargetClass(ref, membersToMove, targetClass, false)) { - //Check for target class accessibility - if (!manager.getResolveHelper().isAccessible(targetClass, targetClass.getModifierList(), ref, null, null)) { - String message = RefactoringBundle.message("0.is.1.and.will.not.be.accessible.from.2.in.the.target.class", - RefactoringUIUtil.getDescription(targetClass, true), - VisibilityUtil.getVisibilityStringToDisplay(targetClass), - RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(ref), true)); - message = CommonRefactoringUtil.capitalize(message); - conflicts.putValue(targetClass, message); - } - //check for member accessibility - else if (!manager.getResolveHelper().isAccessible(member, modifierList, ref, null, null)) { - String message = RefactoringBundle.message("0.is.1.and.will.not.be.accessible.from.2.in.the.target.class", - RefactoringUIUtil.getDescription(member, true), - VisibilityUtil.getVisibilityStringToDisplay(member), - RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(ref), true)); - message = CommonRefactoringUtil.capitalize(message); - conflicts.putValue(member, message); - } - } - } - } - } - - private static void checkUsedElements(PsiMember member, PsiElement scope, @NotNull Set membersToMove, PsiClass newContext, MultiMap conflicts) { - if(scope instanceof PsiReferenceExpression) { - PsiReferenceExpression refExpr = (PsiReferenceExpression)scope; - PsiElement refElement = refExpr.resolve(); - if (refElement instanceof PsiMember) { - if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, membersToMove, newContext, false)){ - PsiExpression qualifier = refExpr.getQualifierExpression(); - PsiClass accessClass = (PsiClass)(qualifier != null ? PsiUtil.getAccessObjectClass(qualifier).getElement() : null); - checkAccessibility((PsiMember)refElement, newContext, accessClass, member, conflicts); - } - } - } - else if (scope instanceof PsiNewExpression) { - final PsiNewExpression newExpression = (PsiNewExpression)scope; - final PsiAnonymousClass anonymousClass = newExpression.getAnonymousClass(); - if (anonymousClass != null) { - if (!RefactoringHierarchyUtil.willBeInTargetClass(anonymousClass, membersToMove, newContext, false)){ - checkAccessibility(anonymousClass, newContext, anonymousClass, member, conflicts); - } - } else { - final PsiMethod refElement = newExpression.resolveConstructor(); - if (refElement != null) { - if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, membersToMove, newContext, false)) { - checkAccessibility(refElement, newContext, null, member, conflicts); - } - } - } - } - else if (scope instanceof PsiJavaCodeReferenceElement) { - PsiJavaCodeReferenceElement refExpr = (PsiJavaCodeReferenceElement)scope; - PsiElement refElement = refExpr.resolve(); - if (refElement instanceof PsiMember) { - if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, membersToMove, newContext, false)){ - checkAccessibility((PsiMember)refElement, newContext, null, member, conflicts); - } - } - } - - PsiElement[] children = scope.getChildren(); - for (PsiElement child : children) { - if (!(child instanceof PsiWhiteSpace)) { - checkUsedElements(member, child, membersToMove, newContext, conflicts); - } - } - } - - private static void checkAccessibility(PsiMember refMember, - PsiClass newContext, - PsiClass accessClass, - PsiMember member, - MultiMap conflicts) { - if (!PsiUtil.isAccessible(refMember, newContext, accessClass)) { - String message = RefactoringBundle.message("0.is.1.and.will.not.be.accessible.from.2.in.the.target.class", - RefactoringUIUtil.getDescription(refMember, true), - VisibilityUtil.getVisibilityStringToDisplay(refMember), - RefactoringUIUtil.getDescription(member, false)); - message = CommonRefactoringUtil.capitalize(message); - conflicts.putValue(refMember, message); - } + RefactoringConflictsUtil.analyzeAccessibilityConflicts(membersToMove, targetClass, conflicts, newVisibility); } private static boolean hasMethod(PsiClass targetClass, PsiMethod method) { diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringConflictsUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringConflictsUtil.java new file mode 100644 index 000000000000..4ece32dfe95e --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringConflictsUtil.java @@ -0,0 +1,247 @@ +/* + * User: anna + * Date: 05-Oct-2009 + */ +package com.intellij.refactoring.util; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchScopeUtil; +import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.PsiUtilBase; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.usageView.UsageInfo; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.VisibilityUtil; +import com.intellij.util.containers.HashSet; +import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.Set; + +public class RefactoringConflictsUtil { + public static void setVisibility(PsiModifierList modifierList, @Modifier String newVisibility) throws IncorrectOperationException { + modifierList.setModifierProperty(PsiModifier.PRIVATE, false); + modifierList.setModifierProperty(PsiModifier.PUBLIC, false); + modifierList.setModifierProperty(PsiModifier.PROTECTED, false); + modifierList.setModifierProperty(newVisibility, true); + } + + public static void analyzeAccessibilityConflicts(@NotNull Set membersToMove, + final PsiClass targetClass, + final MultiMap conflicts, String newVisibility) { + if (VisibilityUtil.ESCALATE_VISIBILITY.equals(newVisibility)) { //Still need to check for access object + newVisibility = PsiModifier.PUBLIC; + } + + for (PsiMember member : membersToMove) { + checkUsedElements(member, member, membersToMove, targetClass, conflicts); + + PsiModifierList modifierList = member.getModifierList(); + if (modifierList!=null) modifierList= (PsiModifierList)modifierList.copy(); + + if (newVisibility != null) { + try { + if (modifierList!=null) setVisibility(modifierList, newVisibility); + } + catch (IncorrectOperationException ex) { + /* do nothing and hope for the best */ + } + } + JavaPsiFacade manager = JavaPsiFacade.getInstance(member.getProject()); + for (PsiReference psiReference : ReferencesSearch.search(member)) { + PsiElement ref = psiReference.getElement(); + if (!RefactoringHierarchyUtil.willBeInTargetClass(ref, membersToMove, targetClass, false)) { + //Check for target class accessibility + if (!manager.getResolveHelper().isAccessible(targetClass, targetClass.getModifierList(), ref, null, null)) { + String message = RefactoringBundle.message("0.is.1.and.will.not.be.accessible.from.2.in.the.target.class", + RefactoringUIUtil.getDescription(targetClass, true), + VisibilityUtil.getVisibilityStringToDisplay(targetClass), + RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(ref), true)); + message = CommonRefactoringUtil.capitalize(message); + conflicts.putValue(targetClass, message); + } + //check for member accessibility + else if (!manager.getResolveHelper().isAccessible(member, modifierList, ref, null, null)) { + String message = RefactoringBundle.message("0.is.1.and.will.not.be.accessible.from.2.in.the.target.class", + RefactoringUIUtil.getDescription(member, true), + VisibilityUtil.getVisibilityStringToDisplay(member), + RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(ref), true)); + message = CommonRefactoringUtil.capitalize(message); + conflicts.putValue(member, message); + } + } + } + } + } + + public static void checkUsedElements(PsiMember member, PsiElement scope, @NotNull Set membersToMove, PsiClass newContext, MultiMap conflicts) { + if(scope instanceof PsiReferenceExpression) { + PsiReferenceExpression refExpr = (PsiReferenceExpression)scope; + PsiElement refElement = refExpr.resolve(); + if (refElement instanceof PsiMember) { + if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, membersToMove, newContext, false)){ + PsiExpression qualifier = refExpr.getQualifierExpression(); + PsiClass accessClass = (PsiClass)(qualifier != null ? PsiUtil.getAccessObjectClass(qualifier).getElement() : null); + checkAccessibility((PsiMember)refElement, newContext, accessClass, member, conflicts); + } + } + } + else if (scope instanceof PsiNewExpression) { + final PsiNewExpression newExpression = (PsiNewExpression)scope; + final PsiAnonymousClass anonymousClass = newExpression.getAnonymousClass(); + if (anonymousClass != null) { + if (!RefactoringHierarchyUtil.willBeInTargetClass(anonymousClass, membersToMove, newContext, false)){ + checkAccessibility(anonymousClass, newContext, anonymousClass, member, conflicts); + } + } else { + final PsiMethod refElement = newExpression.resolveConstructor(); + if (refElement != null) { + if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, membersToMove, newContext, false)) { + checkAccessibility(refElement, newContext, null, member, conflicts); + } + } + } + } + else if (scope instanceof PsiJavaCodeReferenceElement) { + PsiJavaCodeReferenceElement refExpr = (PsiJavaCodeReferenceElement)scope; + PsiElement refElement = refExpr.resolve(); + if (refElement instanceof PsiMember) { + if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, membersToMove, newContext, false)){ + checkAccessibility((PsiMember)refElement, newContext, null, member, conflicts); + } + } + } + + PsiElement[] children = scope.getChildren(); + for (PsiElement child : children) { + if (!(child instanceof PsiWhiteSpace)) { + checkUsedElements(member, child, membersToMove, newContext, conflicts); + } + } + } + + public static void checkAccessibility(PsiMember refMember, + PsiClass newContext, + PsiClass accessClass, + PsiMember member, + MultiMap conflicts) { + if (!PsiUtil.isAccessible(refMember, newContext, accessClass)) { + String message = RefactoringBundle.message("0.is.1.and.will.not.be.accessible.from.2.in.the.target.class", + RefactoringUIUtil.getDescription(refMember, true), + VisibilityUtil.getVisibilityStringToDisplay(refMember), + RefactoringUIUtil.getDescription(member, false)); + message = CommonRefactoringUtil.capitalize(message); + conflicts.putValue(refMember, message); + } + } + + public static void analyzeModuleConflicts(Project project, + Collection scope, + final UsageInfo[] usages, + PsiElement target, + final MultiMap conflicts) { + if (scope == null) return; + final VirtualFile vFile = PsiUtilBase.getVirtualFile(target); + if (vFile == null) return; + analyzeModuleConflicts(project, scope, usages, vFile, conflicts); + } + + public static void analyzeModuleConflicts(Project project, + final Collection scopes, + final UsageInfo[] usages, + final VirtualFile vFile, + final MultiMap conflicts) { + if (scopes == null) return; + + for (final PsiElement scope : scopes) { + if (scope instanceof PsiPackage || scope instanceof PsiDirectory) return; + } + + final Module targetModule = ModuleUtil.findModuleForFile(vFile, project); + if (targetModule == null) return; + final GlobalSearchScope resolveScope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(targetModule); + final HashSet reported = new HashSet(); + for (final PsiElement scope : scopes) { + scope.accept(new JavaRecursiveElementWalkingVisitor() { + @Override public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { + super.visitReferenceElement(reference); + final PsiElement resolved = reference.resolve(); + if (resolved != null && !reported.contains(resolved) && !CommonRefactoringUtil.isAncestor(resolved, scopes) && + !PsiSearchScopeUtil.isInScope(resolveScope, resolved)) { + final String scopeDescription = + RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(reference), true); + final String message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.in.module.2", + CommonRefactoringUtil.capitalize( + RefactoringUIUtil.getDescription(resolved, true)), scopeDescription, + CommonRefactoringUtil.htmlEmphasize( + targetModule.getName())); + conflicts.putValue(resolved, message); + reported.add(resolved); + } + } + }); + } + + boolean isInTestSources = ModuleRootManager.getInstance(targetModule).getFileIndex().isInTestSourceContent(vFile); + NextUsage: + for (UsageInfo usage : usages) { + if (usage instanceof MoveRenameUsageInfo) { + final MoveRenameUsageInfo moveRenameUsageInfo = (MoveRenameUsageInfo)usage; + final PsiElement element = usage.getElement(); + if (element != null && PsiTreeUtil.getParentOfType(element, PsiImportStatement.class, false) == null) { + + for (PsiElement scope : scopes) { + if (PsiTreeUtil.isAncestor(scope, element, false)) continue NextUsage; + } + + final GlobalSearchScope resolveScope1 = element.getResolveScope(); + if (!resolveScope1.isSearchInModuleContent(targetModule, isInTestSources)) { + final PsiFile usageFile = element.getContainingFile(); + PsiElement container; + if (usageFile instanceof PsiJavaFile) { + container = ConflictsUtil.getContainer(element); + if (container == null) container = usageFile; + } + else { + container = usageFile; + } + final String scopeDescription = RefactoringUIUtil.getDescription(container, true); + final VirtualFile usageVFile = usageFile.getVirtualFile(); + if (usageVFile != null) { + Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(usageVFile); + if (module != null) { + final String message; + final PsiElement referencedElement = moveRenameUsageInfo.getReferencedElement(); + if (module == targetModule && isInTestSources) { + message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.from.production.of.module.2", + CommonRefactoringUtil.capitalize( + RefactoringUIUtil.getDescription(referencedElement, true)), + scopeDescription, + CommonRefactoringUtil.htmlEmphasize(module.getName())); + } + else { + message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.from.module.2", + CommonRefactoringUtil.capitalize( + RefactoringUIUtil.getDescription(referencedElement, true)), + scopeDescription, + CommonRefactoringUtil.htmlEmphasize(module.getName())); + } + conflicts.putValue(referencedElement, message); + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java index bec5c5a7fc71..4bafb5720d55 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java @@ -11,10 +11,7 @@ import com.intellij.openapi.editor.colors.EditorColors; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.editor.markup.TextAttributes; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; @@ -29,25 +26,20 @@ import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.controlFlow.ControlFlowUtil; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.javadoc.PsiDocTag; -import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.LocalSearchScope; -import com.intellij.psi.search.PsiSearchScopeUtil; import com.intellij.psi.search.SearchScope; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; -import com.intellij.psi.util.PsiUtilBase; import com.intellij.refactoring.PackageWrapper; -import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.introduceField.ElementToWorkOn; import com.intellij.refactoring.introduceVariable.IntroduceVariableBase; import com.intellij.usageView.UsageInfo; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.HashMap; import com.intellij.util.containers.HashSet; -import com.intellij.util.containers.MultiMap; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -576,13 +568,6 @@ public class RefactoringUtil { return anchor; } - public static void setVisibility(PsiModifierList modifierList, @Modifier String newVisibility) throws IncorrectOperationException { - modifierList.setModifierProperty(PsiModifier.PRIVATE, false); - modifierList.setModifierProperty(PsiModifier.PUBLIC, false); - modifierList.setModifierProperty(PsiModifier.PROTECTED, false); - modifierList.setModifierProperty(newVisibility, true); - } - public static boolean isMethodUsage(PsiElement element) { if (element instanceof PsiEnumConstant) return true; if (!(element instanceof PsiJavaCodeReferenceElement)) return false; @@ -1089,106 +1074,6 @@ public class RefactoringUtil { } } - public static void analyzeModuleConflicts(Project project, - Collection scope, - final UsageInfo[] usages, - PsiElement target, - final MultiMap conflicts) { - if (scope == null) return; - final VirtualFile vFile = PsiUtilBase.getVirtualFile(target); - if (vFile == null) return; - analyzeModuleConflicts(project, scope, usages, vFile, conflicts); - } - - public static void analyzeModuleConflicts(Project project, - final Collection scopes, - final UsageInfo[] usages, - final VirtualFile vFile, - final MultiMap conflicts) { - if (scopes == null) return; - - for (final PsiElement scope : scopes) { - if (scope instanceof PsiPackage || scope instanceof PsiDirectory) return; - } - - final Module targetModule = ModuleUtil.findModuleForFile(vFile, project); - if (targetModule == null) return; - final GlobalSearchScope resolveScope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(targetModule); - final HashSet reported = new HashSet(); - for (final PsiElement scope : scopes) { - scope.accept(new JavaRecursiveElementWalkingVisitor() { - @Override public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { - super.visitReferenceElement(reference); - final PsiElement resolved = reference.resolve(); - if (resolved != null && !reported.contains(resolved) && !CommonRefactoringUtil.isAncestor(resolved, scopes) && - !PsiSearchScopeUtil.isInScope(resolveScope, resolved)) { - final String scopeDescription = - RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(reference), true); - final String message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.in.module.2", - CommonRefactoringUtil.capitalize( - RefactoringUIUtil.getDescription(resolved, true)), scopeDescription, - CommonRefactoringUtil.htmlEmphasize( - targetModule.getName())); - conflicts.putValue(resolved, message); - reported.add(resolved); - } - } - }); - } - - boolean isInTestSources = ModuleRootManager.getInstance(targetModule).getFileIndex().isInTestSourceContent(vFile); - NextUsage: - for (UsageInfo usage : usages) { - if (usage instanceof MoveRenameUsageInfo) { - final MoveRenameUsageInfo moveRenameUsageInfo = (MoveRenameUsageInfo)usage; - final PsiElement element = usage.getElement(); - if (element != null && PsiTreeUtil.getParentOfType(element, PsiImportStatement.class, false) == null) { - - for (PsiElement scope : scopes) { - if (PsiTreeUtil.isAncestor(scope, element, false)) continue NextUsage; - } - - final GlobalSearchScope resolveScope1 = element.getResolveScope(); - if (!resolveScope1.isSearchInModuleContent(targetModule, isInTestSources)) { - final PsiFile usageFile = element.getContainingFile(); - PsiElement container; - if (usageFile instanceof PsiJavaFile) { - container = ConflictsUtil.getContainer(element); - if (container == null) container = usageFile; - } - else { - container = usageFile; - } - final String scopeDescription = RefactoringUIUtil.getDescription(container, true); - final VirtualFile usageVFile = usageFile.getVirtualFile(); - if (usageVFile != null) { - Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(usageVFile); - if (module != null) { - final String message; - final PsiElement referencedElement = moveRenameUsageInfo.getReferencedElement(); - if (module == targetModule && isInTestSources) { - message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.from.production.of.module.2", - CommonRefactoringUtil.capitalize( - RefactoringUIUtil.getDescription(referencedElement, true)), - scopeDescription, - CommonRefactoringUtil.htmlEmphasize(module.getName())); - } - else { - message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.from.module.2", - CommonRefactoringUtil.capitalize( - RefactoringUIUtil.getDescription(referencedElement, true)), - scopeDescription, - CommonRefactoringUtil.htmlEmphasize(module.getName())); - } - conflicts.putValue(referencedElement, message); - } - } - } - } - } - } - } - @Nullable public static PsiTypeParameterList createTypeParameterListWithUsedTypeParameters(@NotNull final PsiElement... elements) { return createTypeParameterListWithUsedTypeParameters(null, elements); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyMemberHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyMemberHandler.java index 5171c26d70d4..00653a06b299 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyMemberHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyMemberHandler.java @@ -25,8 +25,8 @@ import com.intellij.refactoring.move.moveMembers.MoveMemberHandler; import com.intellij.refactoring.move.moveMembers.MoveMembersOptions; import com.intellij.refactoring.move.moveMembers.MoveMembersProcessor; import com.intellij.refactoring.util.EnumConstantsUtil; +import com.intellij.refactoring.util.RefactoringConflictsUtil; import com.intellij.refactoring.util.RefactoringHierarchyUtil; -import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.VisibilityUtil; import org.jetbrains.annotations.Nullable; @@ -155,7 +155,7 @@ public class MoveGroovyMemberHandler implements MoveMemberHandler { //might need to make modifiers explicit, see IDEADEV-11416 final PsiModifierList list = memberCopy.getModifierList(); assert list != null; - RefactoringUtil.setVisibility(list, VisibilityUtil.getVisibilityModifier(member.getModifierList())); + RefactoringConflictsUtil.setVisibility(list, VisibilityUtil.getVisibilityModifier(member.getModifierList())); list.setModifierProperty(PsiModifier.STATIC, member.hasModifierProperty(PsiModifier.STATIC)); list.setModifierProperty(PsiModifier.FINAL, member.hasModifierProperty(PsiModifier.FINAL)); } @@ -172,7 +172,7 @@ public class MoveGroovyMemberHandler implements MoveMemberHandler { assert list != null; list.setModifierProperty(PsiModifier.STATIC, member.hasModifierProperty(PsiModifier.STATIC)); list.setModifierProperty(PsiModifier.FINAL, member.hasModifierProperty(PsiModifier.FINAL)); - RefactoringUtil.setVisibility(list, VisibilityUtil.getVisibilityModifier(member.getModifierList())); + RefactoringConflictsUtil.setVisibility(list, VisibilityUtil.getVisibilityModifier(member.getModifierList())); } member.delete();