@NotNull private static MultiMap<String, GoImportSpec> collectImportsWithSameString( @NotNull Collection<GoImportSpec> importsWithSameName) { MultiMap<String, GoImportSpec> importsWithSameString = MultiMap.create(); for (PsiElement duplicateCandidate : importsWithSameName) { GoImportSpec importSpec = getImportSpec(duplicateCandidate); if (importSpec != null) { importsWithSameString.putValue(importSpec.getPath(), importSpec); } } return importsWithSameString; }
@NotNull public static Set<PsiElement> findRedundantImportIdentifiers( @NotNull MultiMap<String, GoImportSpec> importMap) { Set<PsiElement> importIdentifiersToDelete = ContainerUtil.newLinkedHashSet(); for (PsiElement importEntry : importMap.values()) { GoImportSpec importSpec = getImportSpec(importEntry); if (importSpec != null) { String localPackageName = importSpec.getLocalPackageName(); if (!StringUtil.isEmpty(localPackageName)) { if (Comparing.equal(importSpec.getAlias(), localPackageName)) { importIdentifiersToDelete.add(importSpec.getIdentifier()); } } } } return importIdentifiersToDelete; }
private static boolean hasImportUsers(@NotNull GoImportSpec spec) { //noinspection SynchronizationOnLocalVariableOrMethodParameter synchronized (spec) { List<PsiElement> list = spec.getUserData(GoReferenceBase.IMPORT_USERS); if (list != null) { for (PsiElement e : list) { if (e.isValid()) { return true; } ProgressManager.checkCanceled(); } } } return false; }
public static MultiMap<String, GoImportSpec> filterUnusedImports( @NotNull PsiFile file, @NotNull MultiMap<String, GoImportSpec> importMap) { MultiMap<String, GoImportSpec> result = MultiMap.create(); result.putAllValues(importMap); result.remove("_"); // imports for side effects are always used Collection<GoImportSpec> implicitImports = ContainerUtil.newArrayList(result.get(".")); for (GoImportSpec importEntry : implicitImports) { GoImportSpec spec = getImportSpec(importEntry); if (spec != null && spec.isDot() && hasImportUsers(spec)) { result.remove(".", importEntry); } } file.accept( new GoRecursiveVisitor() { @Override public void visitTypeReferenceExpression(@NotNull GoTypeReferenceExpression o) { GoTypeReferenceExpression lastQualifier = o.getQualifier(); if (lastQualifier != null) { GoTypeReferenceExpression previousQualifier; while ((previousQualifier = lastQualifier.getQualifier()) != null) { lastQualifier = previousQualifier; } markAsUsed(lastQualifier.getIdentifier(), lastQualifier.getReference()); } } @Override public void visitReferenceExpression(@NotNull GoReferenceExpression o) { GoReferenceExpression lastQualifier = o.getQualifier(); if (lastQualifier != null) { GoReferenceExpression previousQualifier; while ((previousQualifier = lastQualifier.getQualifier()) != null) { lastQualifier = previousQualifier; } markAsUsed(lastQualifier.getIdentifier(), lastQualifier.getReference()); } } private void markAsUsed(@NotNull PsiElement qualifier, @NotNull PsiReference reference) { String qualifierText = qualifier.getText(); if (!result.containsKey(qualifierText)) { // already marked return; } PsiElement resolve = reference.resolve(); if (!(resolve instanceof PsiDirectory || resolve instanceof GoImportSpec || resolve instanceof PsiDirectoryContainer)) { return; } Collection<String> qualifiersToDelete = ContainerUtil.newHashSet(); for (GoImportSpec spec : result.get(qualifierText)) { for (Map.Entry<String, Collection<GoImportSpec>> entry : result.entrySet()) { for (GoImportSpec importSpec : entry.getValue()) { if (importSpec == spec) { qualifiersToDelete.add(entry.getKey()); } } } } for (String qualifierToDelete : qualifiersToDelete) { result.remove(qualifierToDelete); } } }); return result; }