src/main/java/org/jetbrains/plugins/spotbugs/actions/AnalyzePackageFiles.java (117 lines of code) (raw):

/* * Copyright 2020 SpotBugs plugin contributors * * This file is part of IntelliJ SpotBugs plugin. * * IntelliJ SpotBugs plugin is free software: you can redistribute it * and/or modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * IntelliJ SpotBugs plugin is distributed in the hope that it will * be useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with IntelliJ SpotBugs plugin. * If not, see <http://www.gnu.org/licenses/>. */ package org.jetbrains.plugins.spotbugs.actions; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.compiler.CompileScope; import com.intellij.openapi.compiler.CompilerManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.CompilerModuleExtension; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.ToolWindow; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiManager; import com.intellij.psi.impl.file.PsiDirectoryFactory; import com.intellij.util.Consumer; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.spotbugs.collectors.RecurseFileCollector; import org.jetbrains.plugins.spotbugs.common.util.IdeaUtilImpl; import org.jetbrains.plugins.spotbugs.core.FindBugsProject; import org.jetbrains.plugins.spotbugs.core.FindBugsProjects; import org.jetbrains.plugins.spotbugs.core.FindBugsStarter; import org.jetbrains.plugins.spotbugs.core.FindBugsState; import java.io.File; public final class AnalyzePackageFiles extends AbstractAnalyzeAction { @Override void updateImpl( @NotNull final AnActionEvent e, @NotNull final Project project, @NotNull final ToolWindow toolWindow, @NotNull final FindBugsState state ) { boolean enable = false; if (state.isIdle()) { final VirtualFile directory = getDirectory(e, project); enable = directory != null && ModuleUtilCore.findModuleForFile(directory, project) != null; } e.getPresentation().setEnabled(enable); e.getPresentation().setVisible(true); } @SuppressFBWarnings("SIC_INNER_SHOULD_BE_STATIC_ANON") @Override void analyze( @NotNull final AnActionEvent e, @NotNull final Project project, @NotNull final ToolWindow toolWindow, @NotNull final FindBugsState state ) { final VirtualFile directory = getDirectory(e, project); final Module module = ModuleUtilCore.findModuleForFile(directory, project); if (module == null) { throw new IllegalStateException("No module found for " + directory); } final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); final String packageName = fileIndex.getPackageNameByDirectory(directory); final boolean isTest = fileIndex.isInTestSourceContent(directory); new FindBugsStarter(project, "Running SpotBugs analysis for package '" + packageName + "'...") { @Override protected void createCompileScope(@NotNull final CompilerManager compilerManager, @NotNull final Consumer<CompileScope> consumer) { consumer.consume(compilerManager.createProjectCompileScope(project)); } @Override protected boolean configure(@NotNull final ProgressIndicator indicator, @NotNull final FindBugsProjects projects, final boolean justCompiled) { final CompilerModuleExtension extension = CompilerModuleExtension.getInstance(module); if (extension == null) { throw new IllegalStateException("No compiler extension for module " + module.getName()); } final VirtualFile compilerOutputPath = isTest ? extension.getCompilerOutputPathForTests() : extension.getCompilerOutputPath(); if (compilerOutputPath == null) { showWarning("Source is not compiled."); return false; } final File outputPath = new File(compilerOutputPath.getCanonicalPath(), packageName.replace(".", File.separator)); if (!outputPath.exists()) { showWarning("Source is not compiled (" + outputPath + ")."); return false; } indicator.setText("Collecting files for analysis..."); final FindBugsProject findBugsProject = projects.get(module, isTest); final int[] count = new int[1]; RecurseFileCollector.addFiles(project, indicator, findBugsProject, outputPath, count); return true; } }.start(); } @Nullable private static VirtualFile getDirectory( @NotNull final AnActionEvent e, @NotNull final Project project ) { final VirtualFile[] selectedFiles = IdeaUtilImpl.getVirtualFiles(e.getDataContext()); if (selectedFiles == null || selectedFiles.length != 1) { return null; } VirtualFile directory = selectedFiles[0]; if (!directory.isDirectory()) { directory = directory.getParent(); if (directory == null) { return null; } if (!directory.isDirectory()) { return null; } } final PsiDirectory psiDirectory = PsiManager.getInstance(project).findDirectory(directory); if (psiDirectory == null) { return null; } if (!PsiDirectoryFactory.getInstance(project).isPackage(psiDirectory)) { return null; } return directory; } }