Set<String> (@NotNull PsiJavaFile file, @NotNull Map<String, Boolean> onDemandImports) { List<String> onDemands = new ArrayList<>(Arrays.asList(file.getImplicitlyImportedPackages())); for (String onDemand : onDemandImports.keySet()) { if (!onDemands.contains(onDemand)) { onDemands.add(onDemand); } } if (onDemands.size() < 2) return Collections.emptySet(); // if we have classes x.A, x.B and there is an "import x.*" then classNames = {"x" -> ("A", "B")} GlobalSearchScope resolveScope = file.getResolveScope(); Map<String, Set<String>> classNames = new HashMap<>(); JavaPsiFacade facade = JavaPsiFacade.getInstance(file.getProject()); for (int i = onDemands.size() - 1; i>= 0; i--) { String onDemand = onDemands.get(i); PsiPackage aPackage = facade.findPackage(onDemand); boolean isStatic = ObjectUtils.notNull(onDemandImports.get(onDemand), Boolean.FALSE); PsiClass aClass; if (aPackage != null) { // import foo.package1.*; Set<String> set = Arrays.stream(aPackage.getClasses(resolveScope)).map(PsiClass::getName).collect(toSet()); classNames.put(onDemand, set); } else if ((aClass = facade.findClass(onDemand, resolveScope)) != null) { // import static foo.package1.Class1.*; if (isStatic) { Set<String> set = Arrays.stream(aClass.getInnerClasses()) .filter(member -> member.hasModifierProperty(PsiModifier.STATIC)) .map(PsiMember::getName).collect(toSet()); classNames.put(onDemand, set); } else { classNames.put(onDemand, Arrays.stream(aClass.getInnerClasses()).map(PsiClass::getName).collect(toSet())); } } else { onDemands.remove(i); } } Set<String> conflicts = new HashSet<>(); for (int i = 0; i < onDemands.size(); i++) { String on1 = onDemands.get(i); for (int j = i + 1; j < onDemands.size(); j++) { String on2 = onDemands.get(j); Set<String> intersection = new HashSet<>(classNames.get(on1)); intersection.retainAll(classNames.get(on2)); conflicts.addAll(intersection); } } if (conflicts.isEmpty() || file instanceof PsiCompiledElement) return Collections.emptySet(); Set<String> result = new HashSet<>(); String packageName = file.getPackageName(); for (PsiClass aClass : file.getClasses()) { // do not visit imports aClass.accept(new JavaRecursiveElementVisitor() { @Override public void visitReferenceElement(@NotNull PsiJavaCodeReferenceElement reference) { super.visitReferenceElement(reference); if (reference.getQualifier() != null) return; JavaResolveResult resolveResult = reference.advancedResolve(false); if (resolveResult.getElement() instanceof PsiClass psiClass && conflicts.contains(psiClass.getName())) { if (resolveResult.getCurrentFileResolveScope() instanceof PsiImportStatementBase || isImplicitlyImported(psiClass.getQualifiedName(), file)) { String fqn = psiClass.getQualifiedName(); if (fqn != null && !PsiTreeUtil.isAncestor(file, psiClass, true) && !packageName.equals(StringUtil.getPackageName(fqn))) { result.add(fqn); } } } } }); } return result; }