[rider]: added SilentCodeCleanup action to run code cleanup inspections with current profile

This commit is contained in:
vadim.lomshakov
2017-12-24 06:11:25 +07:00
parent 7254cdd6dc
commit 400fc92dbc
6 changed files with 202 additions and 87 deletions
@@ -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<VirtualFile> 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);
}
}
@@ -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<VirtualFile> 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);
@@ -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);
}
}
@@ -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...
@@ -22,7 +22,6 @@
<action id="EditorLookupUp" class="com.intellij.codeInsight.lookup.impl.LookupActionHandler$UpAction"/>
<action id="EditorLookupDown" class="com.intellij.codeInsight.lookup.impl.LookupActionHandler$DownAction"/>
</actions>
<xi:include href="/idea/PlatformActions.xml" xpointer="xpointer(/idea-plugin/*)"/>
@@ -45,6 +44,7 @@
<separator/>
<action id="InspectCode" class="com.intellij.codeInspection.actions.CodeInspectionAction"/>
<action id="CodeCleanup" class="com.intellij.codeInspection.actions.CodeCleanupAction"/>
<action id="SilentCodeCleanup" class="com.intellij.codeInspection.actions.SilentCodeCleanupAction" />
<action id="RunInspection" class="com.intellij.codeInspection.actions.RunInspectionAction" />
<action id="PopupHector" class="com.intellij.codeInsight.daemon.impl.PopupHectorAction"/>
<action id="ViewOfflineInspection" class="com.intellij.codeInspection.actions.ViewOfflineResultsAction"/>
@@ -91,6 +91,7 @@
<group id="InspectCodeGroup" text="Inspect Code Actions">
<action id="InspectCode" class="com.intellij.codeInspection.actions.CodeInspectionAction"/>
<action id="CodeCleanup" class="com.intellij.codeInspection.actions.CodeCleanupAction"/>
<action id="SilentCodeCleanup" class="com.intellij.codeInspection.actions.SilentCodeCleanupAction" />
<action id="RunInspection" class="com.intellij.codeInspection.actions.RunInspectionAction"/>
<action id="PopupHector" class="com.intellij.codeInsight.daemon.impl.PopupHectorAction"/>
<action id="ViewOfflineInspection" class="com.intellij.codeInspection.actions.ViewOfflineResultsAction"/>