public static boolean nameCanBeImported(@NotNull String fqName, @NotNull PsiElement context) { final PsiClass containingClass = PsiTreeUtil.getParentOfType(context, PsiClass.class); if (containingClass != null) { if (fqName.equals(containingClass.getQualifiedName())) { return true; } final String shortName = ClassUtil.extractClassName(fqName); final PsiClass[] innerClasses = containingClass.getAllInnerClasses(); for (PsiClass innerClass : innerClasses) { if (innerClass.hasModifierProperty(PsiModifier.PRIVATE)) { continue; } if (innerClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) { if (!ClassUtils.inSamePackage(innerClass, containingClass)) { continue; } } final String className = innerClass.getName(); if (shortName.equals(className)) { return false; } } PsiField field = containingClass.findFieldByName(shortName, false); if (field != null) { return false; } field = containingClass.findFieldByName(shortName, true); if (field != null && PsiUtil.isAccessible(containingClass.getProject(), field, containingClass, null)) { return false; } } final PsiJavaFile file = PsiTreeUtil.getParentOfType(context, PsiJavaFile.class); if (file == null) { return false; } if (hasExactImportConflict(fqName, file)) { return false; } if (hasOnDemandImportConflict(fqName, file, true)) { return false; } if (containsConflictingReference(file, fqName)) { return false; } if (containsConflictingClass(fqName, file)) { return false; } return !containsConflictingClassName(fqName, file); }
@NotNull public static SearchScope getClassUseScope(@NotNull PsiClass aClass) { if (aClass instanceof PsiAnonymousClass) { return new LocalSearchScope(aClass); } final GlobalSearchScope maximalUseScope = ResolveScopeManager.getElementUseScope(aClass); PsiFile file = aClass.getContainingFile(); if (PsiImplUtil.isInServerPage(file)) return maximalUseScope; final PsiClass containingClass = aClass.getContainingClass(); if (aClass.hasModifierProperty(PsiModifier.PUBLIC) || aClass.hasModifierProperty(PsiModifier.PROTECTED)) { return containingClass == null ? maximalUseScope : containingClass.getUseScope(); } else if (aClass.hasModifierProperty(PsiModifier.PRIVATE) || aClass instanceof PsiTypeParameter) { PsiClass topClass = PsiUtil.getTopLevelClass(aClass); return new LocalSearchScope(topClass == null ? aClass.getContainingFile() : topClass); } else { PsiPackage aPackage = null; if (file instanceof PsiJavaFile) { aPackage = JavaPsiFacade.getInstance(aClass.getProject()) .findPackage(((PsiJavaFile) file).getPackageName()); } if (aPackage == null) { PsiDirectory dir = file.getContainingDirectory(); if (dir != null) { aPackage = JavaDirectoryService.getInstance().getPackage(dir); } } if (aPackage != null) { SearchScope scope = PackageScope.packageScope(aPackage, false); scope = scope.intersectWith(maximalUseScope); return scope; } return new LocalSearchScope(file); } }
public static MultiMap<PsiElement, String> checkConflicts( final MemberInfoBase<? extends PsiMember>[] infos, @NotNull final PsiClass subclass, @Nullable PsiClass superClass, @NotNull final PsiPackage targetPackage, @NotNull PsiDirectory targetDirectory, final InterfaceContainmentVerifier interfaceContainmentVerifier, boolean movedMembers2Super) { final Set<PsiMember> movedMembers = new HashSet<PsiMember>(); final Set<PsiMethod> abstractMethods = new HashSet<PsiMethod>(); final boolean isInterfaceTarget; final PsiElement targetRepresentativeElement; if (superClass != null) { isInterfaceTarget = superClass.isInterface(); targetRepresentativeElement = superClass; } else { isInterfaceTarget = false; targetRepresentativeElement = targetDirectory; } for (MemberInfoBase<? extends PsiMember> info : infos) { PsiMember member = info.getMember(); if (member instanceof PsiMethod) { if (!info.isToAbstract() && !isInterfaceTarget) { movedMembers.add(member); } else { abstractMethods.add((PsiMethod) member); } } else { movedMembers.add(member); } } final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>(); final Set<PsiMethod> abstrMethods = new HashSet<PsiMethod>(abstractMethods); if (superClass != null) { for (PsiMethod method : subclass.getMethods()) { if (!movedMembers.contains(method) && !method.hasModifierProperty(PsiModifier.PRIVATE)) { if (method.findSuperMethods(superClass).length > 0) { abstrMethods.add(method); } } } } RefactoringConflictsUtil.analyzeAccessibilityConflicts( movedMembers, superClass, conflicts, VisibilityUtil.ESCALATE_VISIBILITY, targetRepresentativeElement, abstrMethods); if (superClass != null) { if (movedMembers2Super) { checkSuperclassMembers(superClass, infos, conflicts); if (isInterfaceTarget) { checkInterfaceTarget(infos, conflicts); } } else { final String qualifiedName = superClass.getQualifiedName(); assert qualifiedName != null; if (superClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) { if (!Comparing.strEqual( StringUtil.getPackageName(qualifiedName), targetPackage.getQualifiedName())) { conflicts.putValue( superClass, RefactoringUIUtil.getDescription(superClass, true) + " won't be accessible from " + RefactoringUIUtil.getDescription(targetPackage, true)); } } } } // check if moved methods use other members in the classes between Subclass and Superclass List<PsiElement> checkModuleConflictsList = new ArrayList<PsiElement>(); for (PsiMember member : movedMembers) { if (member instanceof PsiMethod || member instanceof PsiClass && !(member instanceof PsiCompiledElement)) { ClassMemberReferencesVisitor visitor = movedMembers2Super ? new ConflictingUsagesOfSubClassMembers( member, movedMembers, abstractMethods, subclass, superClass, superClass != null ? null : targetPackage, conflicts, interfaceContainmentVerifier) : new ConflictingUsagesOfSuperClassMembers( member, subclass, targetPackage, movedMembers, conflicts); member.accept(visitor); } ContainerUtil.addIfNotNull(checkModuleConflictsList, member); } for (final PsiMethod method : abstractMethods) { ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getParameterList()); ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getReturnTypeElement()); ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getTypeParameterList()); } RefactoringConflictsUtil.analyzeModuleConflicts( subclass.getProject(), checkModuleConflictsList, new UsageInfo[0], targetRepresentativeElement, conflicts); final String fqName = subclass.getQualifiedName(); final String packageName; if (fqName != null) { packageName = StringUtil.getPackageName(fqName); } else { final PsiFile psiFile = PsiTreeUtil.getParentOfType(subclass, PsiFile.class); if (psiFile instanceof PsiClassOwner) { packageName = ((PsiClassOwner) psiFile).getPackageName(); } else { packageName = null; } } final boolean toDifferentPackage = !Comparing.strEqual(targetPackage.getQualifiedName(), packageName); for (final PsiMethod abstractMethod : abstractMethods) { abstractMethod.accept( new ClassMemberReferencesVisitor(subclass) { @Override protected void visitClassMemberReferenceElement( PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) { if (classMember != null && willBeMoved(classMember, movedMembers)) { boolean isAccessible = false; if (classMember.hasModifierProperty(PsiModifier.PRIVATE)) { isAccessible = true; } else if (classMember.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && toDifferentPackage) { isAccessible = true; } if (isAccessible) { String message = RefactoringUIUtil.getDescription(abstractMethod, false) + " uses " + RefactoringUIUtil.getDescription(classMember, true) + " which won't be accessible from the subclass."; message = CommonRefactoringUtil.capitalize(message); conflicts.putValue(classMember, message); } } } }); if (abstractMethod.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && toDifferentPackage) { if (!isInterfaceTarget) { String message = "Can't make " + RefactoringUIUtil.getDescription(abstractMethod, false) + " abstract as it won't be accessible from the subclass."; message = CommonRefactoringUtil.capitalize(message); conflicts.putValue(abstractMethod, message); } } } return conflicts; }