pull up/push down with references to locals

This commit is contained in:
anna
2009-10-05 20:00:26 +04:00
parent 38fc589f24
commit a9cdd39dc3
14 changed files with 283 additions and 263 deletions
@@ -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) {
@@ -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();
@@ -375,7 +375,7 @@ public class ChangeSignatureProcessor extends BaseRefactoringProcessor {
private void addInaccessibilityDescriptions(Set<UsageInfo> usages, MultiMap<PsiElement, String> conflictDescriptions) throws IncorrectOperationException {
PsiMethod method = myChangeInfo.getMethod();
PsiModifierList modifierList = (PsiModifierList)method.getModifierList().copy();
RefactoringUtil.setVisibility(modifierList, myNewVisibility);
RefactoringConflictsUtil.setVisibility(modifierList, myNewVisibility);
for (Iterator<UsageInfo> 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) {
@@ -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<PsiMember> 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);
}
}
@@ -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<PsiElement> movedMembers = new HashSet<PsiElement>();
final Set<PsiMember> movedMembers = new HashSet<PsiMember>();
final Set<PsiMethod> abstractMethods = new HashSet<PsiMethod>();
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<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
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<PsiElement> checkModuleConflictsList = new ArrayList<PsiElement>();
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<PsiElement> myMovedMembers;
private final Set<PsiMember> myMovedMembers;
private final Set<PsiMethod> myAbstractMethods;
private final PsiClass mySubclass;
private final PsiClass mySuperClass;
@@ -153,7 +151,7 @@ public class PullUpConflictsUtil {
private final InterfaceContainmentVerifier myInterfaceContainmentVerifier;
ConflictingUsagesOfSubClassMembers(PsiElement scope,
Set<PsiElement> movedMembers, Set<PsiMethod> abstractMethods,
Set<PsiMember> movedMembers, Set<PsiMethod> abstractMethods,
PsiClass subclass, PsiClass superClass,
PsiPackage targetPackage, MultiMap<PsiElement, String> conflictsList,
InterfaceContainmentVerifier interfaceContainmentVerifier) {
@@ -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) {
@@ -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<PsiElement> elements,
MultiMap<PsiElement,String> 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;
@@ -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<PsiElement> elements,
MultiMap<PsiElement,String> 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) {
@@ -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);
}
}
@@ -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();
@@ -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<PsiMember> membersToMove,
final PsiClass targetClass,
final MultiMap<PsiElement, String> 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<PsiMember> membersToMove, PsiClass newContext, MultiMap<PsiElement, String> 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<PsiElement, String> 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) {
@@ -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<PsiMember> membersToMove,
final PsiClass targetClass,
final MultiMap<PsiElement, String> 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<PsiMember> membersToMove, PsiClass newContext, MultiMap<PsiElement, String> 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<PsiElement, String> 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<? extends PsiElement> scope,
final UsageInfo[] usages,
PsiElement target,
final MultiMap<PsiElement,String> 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<? extends PsiElement> scopes,
final UsageInfo[] usages,
final VirtualFile vFile,
final MultiMap<PsiElement, String> 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<PsiElement> reported = new HashSet<PsiElement>();
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);
}
}
}
}
}
}
}
}
@@ -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<? extends PsiElement> scope,
final UsageInfo[] usages,
PsiElement target,
final MultiMap<PsiElement,String> 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<? extends PsiElement> scopes,
final UsageInfo[] usages,
final VirtualFile vFile,
final MultiMap<PsiElement, String> 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<PsiElement> reported = new HashSet<PsiElement>();
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);
@@ -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();