/* * Copyright 2013-2016 Sergey Ignatov, Alexander Zolotov, Florin Patan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.goide.inspections; import com.goide.codeInsight.imports.GoImportOptimizer; import com.goide.psi.GoFile; import com.goide.psi.GoImportSpec; import com.goide.psi.GoRecursiveVisitor; import com.goide.psi.impl.GoElementFactory; import com.goide.quickfix.GoRenameQuickFix; import com.intellij.codeInspection.*; import com.intellij.find.FindManager; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.Iterator; import java.util.Map; import java.util.Set; public class GoUnusedImportInspection extends GoInspectionBase { @Nullable private final static LocalQuickFix OPTIMIZE_QUICK_FIX = new LocalQuickFixBase("Optimize imports") { @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { PsiElement element = descriptor.getPsiElement(); if (element == null) { return; } PsiFile file = element.getContainingFile(); WriteCommandAction.runWriteCommandAction(project, new GoImportOptimizer().processFile(file)); } }; @Nullable private final static LocalQuickFix IMPORT_FOR_SIDE_EFFECTS_QUICK_FIX = new LocalQuickFixBase("Import for side-effects") { @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { PsiElement element = descriptor.getPsiElement(); if (!(element instanceof GoImportSpec)) { return; } element.replace(GoElementFactory.createImportSpec(project, ((GoImportSpec)element).getPath(), "_")); } }; private static void resolveAllReferences(@NotNull GoFile file) { file.accept(new GoRecursiveVisitor() { @Override public void visitElement(@NotNull PsiElement o) { for (PsiReference reference : o.getReferences()) { reference.resolve(); } } }); } @Override protected void checkFile(@NotNull GoFile file, @NotNull ProblemsHolder problemsHolder) { MultiMap<String, GoImportSpec> importMap = file.getImportMap(); for (PsiElement importIdentifier : GoImportOptimizer.findRedundantImportIdentifiers(importMap)) { problemsHolder.registerProblem(importIdentifier, "Redundant alias", ProblemHighlightType.LIKE_UNUSED_SYMBOL, OPTIMIZE_QUICK_FIX); } Set<GoImportSpec> duplicatedEntries = GoImportOptimizer.findDuplicatedEntries(importMap); for (GoImportSpec duplicatedImportSpec : duplicatedEntries) { problemsHolder.registerProblem(duplicatedImportSpec, "Redeclared import", ProblemHighlightType.GENERIC_ERROR, OPTIMIZE_QUICK_FIX); } for (Map.Entry<String, Collection<GoImportSpec>> specs : importMap.entrySet()) { Iterator<GoImportSpec> imports = specs.getValue().iterator(); GoImportSpec originalImport = imports.next(); if (originalImport.isDot() || originalImport.isForSideEffects()) { continue; } while (imports.hasNext()) { GoImportSpec redeclaredImport = imports.next(); if (!duplicatedEntries.contains(redeclaredImport)) { LocalQuickFix[] quickFixes = FindManager.getInstance(redeclaredImport.getProject()).canFindUsages(redeclaredImport) ? new LocalQuickFix[]{new GoRenameQuickFix(redeclaredImport)} : LocalQuickFix.EMPTY_ARRAY; problemsHolder.registerProblem(redeclaredImport, "Redeclared import", ProblemHighlightType.GENERIC_ERROR, quickFixes); } } } if (importMap.containsKey(".")) { if (!problemsHolder.isOnTheFly() || ApplicationManager.getApplication().isUnitTestMode()) resolveAllReferences(file); } MultiMap<String, GoImportSpec> unusedImportsMap = GoImportOptimizer.filterUnusedImports(file, importMap); Set<GoImportSpec> unusedImportSpecs = ContainerUtil.newHashSet(unusedImportsMap.values()); for (PsiElement importEntry : unusedImportSpecs) { GoImportSpec spec = GoImportOptimizer.getImportSpec(importEntry); if (spec != null && spec.getImportString().resolve() != null) { problemsHolder.registerProblem(spec, "Unused import", ProblemHighlightType.GENERIC_ERROR, OPTIMIZE_QUICK_FIX, IMPORT_FOR_SIDE_EFFECTS_QUICK_FIX); } } } }