@Override public boolean processDeclarations( @NotNull PsiScopeProcessor processor, @NotNull ResolveState state, PsiElement lastParent, @NotNull PsiElement place) { GlobalSearchScope scope = place.getResolveScope(); processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); ElementClassHint classHint = processor.getHint(ElementClassHint.KEY); final JavaPsiFacade facade = getFacade(); final Condition<String> prefixMatcher = processor.getHint(JavaCompletionHints.NAME_FILTER); if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) { NameHint nameHint = processor.getHint(NameHint.KEY); if (nameHint != null) { final String shortName = nameHint.getName(state); if (containsClassNamed(shortName) && processClassesByName(processor, state, scope, shortName)) return false; } else if (prefixMatcher != null) { for (String className : getClassNamesCache()) { if (prefixMatcher.value(className)) { if (processClassesByName(processor, state, scope, className)) return false; } } } else { PsiClass[] classes = getClasses(scope); if (!processClasses(processor, state, classes)) return false; } } if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.PACKAGE)) { NameHint nameHint = processor.getHint(NameHint.KEY); if (nameHint != null) { PsiPackage aPackage = findSubPackageByName(nameHint.getName(state)); if (aPackage != null) { if (!processor.execute(aPackage, state)) return false; } } else { PsiPackage[] packs = getSubPackages(scope); for (PsiPackage pack : packs) { final String packageName = pack.getName(); if (packageName == null) continue; if (!facade.getNameHelper().isIdentifier(packageName, PsiUtil.getLanguageLevel(this))) { continue; } if (!processor.execute(pack, state)) { return false; } } } } return true; }
@Override public boolean processDeclarations( @NotNull PsiScopeProcessor processor, @NotNull ResolveState state, PsiElement lastParent, @NotNull PsiElement place) { GlobalSearchScope scope = place.getResolveScope(); processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this); ElementClassHint classHint = processor.getHint(ElementClassHint.KEY); final Condition<String> nameCondition = processor.getHint(JavaCompletionHints.NAME_FILTER); if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) { NameHint nameHint = processor.getHint(NameHint.KEY); if (nameHint != null) { final String shortName = nameHint.getName(state); final PsiClass[] classes = findClassByShortName(shortName, scope); if (!processClasses(processor, state, classes, Conditions.<String>alwaysTrue())) return false; } else { PsiClass[] classes = getClasses(scope); if (!processClasses( processor, state, classes, nameCondition != null ? nameCondition : Conditions.<String>alwaysTrue())) return false; } } if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.PACKAGE)) { NameHint nameHint = processor.getHint(NameHint.KEY); if (nameHint != null) { PsiPackage aPackage = findSubPackageByName(nameHint.getName(state)); if (aPackage != null) { if (!processor.execute(aPackage, state)) return false; } } else { PsiPackage[] packs = getSubPackages(scope); for (PsiPackage pack : packs) { final String packageName = pack.getName(); if (packageName == null) continue; if (!PsiNameHelper.getInstance(myManager.getProject()) .isIdentifier(packageName, PsiUtil.getLanguageLevel(this))) { continue; } if (!processor.execute(pack, state)) { return false; } } } } return true; }
public static boolean hasJavaLangImportConflict(String fqName, PsiJavaFile file) { final String shortName = ClassUtil.extractClassName(fqName); final String packageName = ClassUtil.extractPackageName(fqName); if (HardcodedMethodConstants.JAVA_LANG.equals(packageName)) { return false; } final Project project = file.getProject(); final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); final PsiPackage javaLangPackage = psiFacade.findPackage(HardcodedMethodConstants.JAVA_LANG); if (javaLangPackage == null) { return false; } return javaLangPackage.containsClassNamed(shortName); }
public static boolean hasDefaultImportConflict(String fqName, PsiJavaFile file) { final String shortName = ClassUtil.extractClassName(fqName); final String packageName = ClassUtil.extractPackageName(fqName); final String filePackageName = file.getPackageName(); if (filePackageName.equals(packageName)) { return false; } final Project project = file.getProject(); final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); final PsiPackage filePackage = psiFacade.findPackage(filePackageName); if (filePackage == null) { return false; } return filePackage.containsClassNamed(shortName); }
/** * @param strict if strict is true this method checks if the conflicting class which is imported * is actually used in the file. If it isn't the on demand import can be overridden with an * exact import for the fqName without breaking stuff. */ private static boolean hasOnDemandImportConflict( @NotNull String fqName, @NotNull PsiJavaFile file, boolean strict) { final PsiImportList imports = file.getImportList(); if (imports == null) { return false; } final PsiImportStatement[] importStatements = imports.getImportStatements(); final String shortName = ClassUtil.extractClassName(fqName); final String packageName = ClassUtil.extractPackageName(fqName); for (final PsiImportStatement importStatement : importStatements) { if (!importStatement.isOnDemand()) { continue; } final PsiJavaCodeReferenceElement importReference = importStatement.getImportReference(); if (importReference == null) { continue; } final String packageText = importReference.getText(); if (packageText.equals(packageName)) { continue; } final PsiElement element = importReference.resolve(); if (element == null || !(element instanceof PsiPackage)) { continue; } final PsiPackage aPackage = (PsiPackage) element; final PsiClass[] classes = aPackage.getClasses(); for (final PsiClass aClass : classes) { final String className = aClass.getName(); if (!shortName.equals(className)) { continue; } if (!strict) { return true; } final String qualifiedClassName = aClass.getQualifiedName(); if (qualifiedClassName == null || fqName.equals(qualifiedClassName)) { continue; } return containsReferenceToConflictingClass(file, qualifiedClassName); } } return hasJavaLangImportConflict(fqName, file); }
public static boolean hasDefaultImportConflict(String fqName, PsiJavaFile file) { final String shortName = ClassUtil.extractClassName(fqName); final String packageName = ClassUtil.extractPackageName(fqName); final String filePackageName = file.getPackageName(); if (filePackageName.equals(packageName)) { return false; } final Project project = file.getProject(); final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); final PsiPackage filePackage = psiFacade.findPackage(filePackageName); if (filePackage == null) { return false; } final PsiClass[] classes = filePackage.getClasses(); for (PsiClass aClass : classes) { final String className = aClass.getName(); if (shortName.equals(className)) { return true; } } return false; }
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; }