diff --git a/platform/lang-impl/src/com/intellij/analysis/AnalysisActionUtils.java b/platform/lang-impl/src/com/intellij/analysis/AnalysisActionUtils.java new file mode 100644 index 000000000000..7df5c00f467a --- /dev/null +++ b/platform/lang-impl/src/com/intellij/analysis/AnalysisActionUtils.java @@ -0,0 +1,120 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * 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.intellij.analysis; + +import com.intellij.codeInspection.ui.InspectionResultsView; +import com.intellij.ide.highlighter.ArchiveFileType; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashSet; +import java.util.Set; + +final public class AnalysisActionUtils { + private static AnalysisScope getFileScopeFromInspectionView(DataContext dataContext) { + InspectionResultsView inspectionView = dataContext.getData(InspectionResultsView.DATA_KEY); + if (inspectionView != null) { + AnalysisScope scope = inspectionView.getScope(); + int type = scope.getScopeType(); + if (type != AnalysisScope.MODULE && type != AnalysisScope.PROJECT && scope.isValid()) { + return scope; + } + } + return null; + } + + @Nullable + public static AnalysisScope getInspectionScope(@NotNull DataContext dataContext, @NotNull Project project, Boolean acceptNonProjectDirectories) { + AnalysisScope scope = getFileScopeFromInspectionView(dataContext); + if (scope != null) return scope; + scope = getInspectionScopeImpl(dataContext, project, acceptNonProjectDirectories); + return scope.getScopeType() != AnalysisScope.INVALID ? scope : null; + } + + @NotNull + private static AnalysisScope getInspectionScopeImpl(@NotNull DataContext dataContext, @NotNull Project project, Boolean acceptNonProjectDirectories) { + // possible scopes: file, directory, package, project, module. + Project projectContext = PlatformDataKeys.PROJECT_CONTEXT.getData(dataContext); + if (projectContext != null) { + return new AnalysisScope(projectContext); + } + + AnalysisScope analysisScope = AnalysisScopeUtil.KEY.getData(dataContext); + if (analysisScope != null) { + return analysisScope; + } + + PsiFile psiFile = CommonDataKeys.PSI_FILE.getData(dataContext); + if (psiFile != null && psiFile.getManager().isInProject(psiFile)) { + VirtualFile file = psiFile.getVirtualFile(); + if (file != null && file.isValid() && file.getFileType() instanceof ArchiveFileType && acceptNonProjectDirectories) { + VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(file); + if (jarRoot != null) { + PsiDirectory psiDirectory = psiFile.getManager().findDirectory(jarRoot); + if (psiDirectory != null) { + return new AnalysisScope(psiDirectory); + } + } + } + return new AnalysisScope(psiFile); + } + + VirtualFile[] virtualFiles = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); + if (virtualFiles != null) { + // analyze on selection + ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + if (virtualFiles.length == 1) { + PsiDirectory psiDirectory = PsiManager.getInstance(project).findDirectory(virtualFiles[0]); + if (psiDirectory != null && (acceptNonProjectDirectories || psiDirectory.getManager().isInProject(psiDirectory))) { + return new AnalysisScope(psiDirectory); + } + } + Set files = new HashSet<>(); + for (VirtualFile vFile : virtualFiles) { + if (fileIndex.isInContent(vFile)) { + files.add(vFile); + } + } + return new AnalysisScope(project, files); + } + + Module moduleContext = LangDataKeys.MODULE_CONTEXT.getData(dataContext); + if (moduleContext != null) { + return new AnalysisScope(moduleContext); + } + + Module[] modulesArray = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext); + if (modulesArray != null) { + return new AnalysisScope(modulesArray); + } + + return new AnalysisScope(project); + } +} diff --git a/platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java b/platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java index 61b90b9ca2b7..ca29f63456fa 100644 --- a/platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java +++ b/platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java @@ -2,26 +2,16 @@ package com.intellij.analysis; import com.intellij.codeInspection.ui.InspectionResultsView; -import com.intellij.ide.highlighter.ArchiveFileType; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ProjectFileIndex; -import com.intellij.openapi.roots.ProjectRootManager; -import com.intellij.openapi.vfs.JarFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.HashSet; -import java.util.Set; public abstract class BaseAnalysisAction extends AnAction { private static final String DIMENSION_KEY_PREFIX = "ANALYSIS_DLG_"; @@ -96,70 +86,7 @@ public abstract class BaseAnalysisAction extends AnAction { @Nullable private AnalysisScope getInspectionScope(@NotNull DataContext dataContext, @NotNull Project project) { - AnalysisScope scope = getFileScopeFromInspectionView(dataContext); - if (scope != null) return scope; - scope = getInspectionScopeImpl(dataContext, project); - return scope.getScopeType() != AnalysisScope.INVALID ? scope : null; - } - - @NotNull - private AnalysisScope getInspectionScopeImpl(@NotNull DataContext dataContext, @NotNull Project project) { - // possible scopes: file, directory, package, project, module. - Project projectContext = PlatformDataKeys.PROJECT_CONTEXT.getData(dataContext); - if (projectContext != null) { - return new AnalysisScope(projectContext); - } - - AnalysisScope analysisScope = AnalysisScopeUtil.KEY.getData(dataContext); - if (analysisScope != null) { - return analysisScope; - } - - PsiFile psiFile = CommonDataKeys.PSI_FILE.getData(dataContext); - if (psiFile != null && psiFile.getManager().isInProject(psiFile)) { - VirtualFile file = psiFile.getVirtualFile(); - if (file != null && file.isValid() && file.getFileType() instanceof ArchiveFileType && acceptNonProjectDirectories()) { - VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(file); - if (jarRoot != null) { - PsiDirectory psiDirectory = psiFile.getManager().findDirectory(jarRoot); - if (psiDirectory != null) { - return new AnalysisScope(psiDirectory); - } - } - } - return new AnalysisScope(psiFile); - } - - VirtualFile[] virtualFiles = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); - if (virtualFiles != null) { - // analyze on selection - ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); - if (virtualFiles.length == 1) { - PsiDirectory psiDirectory = PsiManager.getInstance(project).findDirectory(virtualFiles[0]); - if (psiDirectory != null && (acceptNonProjectDirectories() || psiDirectory.getManager().isInProject(psiDirectory))) { - return new AnalysisScope(psiDirectory); - } - } - Set files = new HashSet<>(); - for (VirtualFile vFile : virtualFiles) { - if (fileIndex.isInContent(vFile)) { - files.add(vFile); - } - } - return new AnalysisScope(project, files); - } - - Module moduleContext = LangDataKeys.MODULE_CONTEXT.getData(dataContext); - if (moduleContext != null) { - return new AnalysisScope(moduleContext); - } - - Module[] modulesArray = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext); - if (modulesArray != null) { - return new AnalysisScope(modulesArray); - } - - return new AnalysisScope(project); + return AnalysisActionUtils.getInspectionScope(dataContext, project, acceptNonProjectDirectories()); } protected boolean acceptNonProjectDirectories() { @@ -171,18 +98,6 @@ public abstract class BaseAnalysisAction extends AnAction { return null; } - private static AnalysisScope getFileScopeFromInspectionView(DataContext dataContext) { - InspectionResultsView inspectionView = dataContext.getData(InspectionResultsView.DATA_KEY); - if (inspectionView != null) { - AnalysisScope scope = inspectionView.getScope(); - int type = scope.getScopeType(); - if (type != AnalysisScope.MODULE && type != AnalysisScope.PROJECT && scope.isValid()) { - return scope; - } - } - return null; - } - @Nullable private static Module getModuleFromContext(@NotNull DataContext dataContext) { InspectionResultsView inspectionView = dataContext.getData(InspectionResultsView.DATA_KEY); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/actions/SilentCodeCleanupAction.java b/platform/lang-impl/src/com/intellij/codeInspection/actions/SilentCodeCleanupAction.java new file mode 100644 index 000000000000..1454dc3acff8 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInspection/actions/SilentCodeCleanupAction.java @@ -0,0 +1,77 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * 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.intellij.codeInspection.actions; + +import com.intellij.analysis.AnalysisActionUtils; +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.InspectionProfile; +import com.intellij.codeInspection.ex.GlobalInspectionContextBase; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.Project; +import com.intellij.profile.codeInspection.InspectionProjectProfileManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class SilentCodeCleanupAction extends AnAction { + public void update(AnActionEvent e) { + Project project = e.getProject(); + e.getPresentation().setEnabled(project != null && !DumbService.isDumb(project) && getInspectionScope(e.getDataContext(), project) != null); + } + + public void actionPerformed(AnActionEvent e) { + Project project = e.getProject(); + if (project == null) return; + + AnalysisScope analysisScope = getInspectionScope(e.getDataContext(), project); + if (analysisScope == null) + return; + + FileDocumentManager.getInstance().saveAllDocuments(); + + FeatureUsageTracker.getInstance().triggerFeatureUsed("codeassist.inspect.batch"); + runInspections(project, analysisScope); + } + + @SuppressWarnings("WeakerAccess") + protected void runInspections(@NotNull Project project, @NotNull AnalysisScope scope) { + InspectionProfile profile = getProfileForSilentCleanup(project); + if (profile == null) { + return; + } + InspectionManager managerEx = InspectionManager.getInstance(project); + GlobalInspectionContextBase globalContext = (GlobalInspectionContextBase) managerEx.createNewGlobalContext(false); + globalContext.codeCleanup(scope, profile, getTemplatePresentation().getText(), null, false); + } + + @SuppressWarnings("WeakerAccess") + @Nullable + protected InspectionProfile getProfileForSilentCleanup(@NotNull Project project) { + return InspectionProjectProfileManager.getInstance(project).getCurrentProfile(); + } + + @Nullable + @SuppressWarnings("WeakerAccess") + protected AnalysisScope getInspectionScope(@NotNull DataContext dataContext, @NotNull Project project) { + return AnalysisActionUtils.getInspectionScope(dataContext, project, false); + } +} diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index 8f3fb59f8332..038f1581cb3a 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -615,6 +615,8 @@ action.MoveLineUp.description=Move selected lines one line up group.AnalyzeMenu.text=Analy_ze action.CodeCleanup.text=_Code Cleanup... action.CodeCleanup.description=Run cleanup inspections and apply quick fixes +action.SilentCodeCleanup.text=Silent Code Cleanup +action.SilentCodeCleanup.description=Run cleanup inspections and apply quick fixes with current inspection profile action.InspectCode.text=_Inspect Code... action.InspectCode.description=Inspect code action.InferNullity.text=Infer _Nullity... diff --git a/platform/platform-resources/src/idea/PlatformLangActionManager.xml b/platform/platform-resources/src/idea/PlatformLangActionManager.xml index ad5e80316343..6c15d7e123fa 100644 --- a/platform/platform-resources/src/idea/PlatformLangActionManager.xml +++ b/platform/platform-resources/src/idea/PlatformLangActionManager.xml @@ -22,7 +22,6 @@ - @@ -45,6 +44,7 @@ + diff --git a/resources/src/idea/RichPlatformActions.xml b/resources/src/idea/RichPlatformActions.xml index eb105bbb10dc..eabbec42c079 100644 --- a/resources/src/idea/RichPlatformActions.xml +++ b/resources/src/idea/RichPlatformActions.xml @@ -91,6 +91,7 @@ +