mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
code cleanup available as intentions (IDEA-38653)
This commit is contained in:
@@ -727,6 +727,7 @@ public class HighlightInfo implements Segment {
|
||||
private final ProblemGroup myProblemGroup;
|
||||
private final String myDisplayName;
|
||||
private final Icon myIcon;
|
||||
private Boolean myCanCleanup;
|
||||
|
||||
public IntentionActionDescriptor(@NotNull IntentionAction action, final List<IntentionAction> options, final String displayName) {
|
||||
this(action, options, displayName, null);
|
||||
@@ -762,6 +763,20 @@ public class HighlightInfo implements Segment {
|
||||
return myAction;
|
||||
}
|
||||
|
||||
public boolean canCleanup(PsiElement element) {
|
||||
if (myCanCleanup == null) {
|
||||
InspectionProfile profile = InspectionProjectProfileManager.getInstance(element.getProject()).getInspectionProfile();
|
||||
final HighlightDisplayKey key = myKey;
|
||||
if (key == null) {
|
||||
myCanCleanup = false;
|
||||
} else {
|
||||
InspectionToolWrapper toolWrapper = profile.getInspectionTool(key.toString(), element);
|
||||
myCanCleanup = toolWrapper != null && toolWrapper.isCleanupTool();
|
||||
}
|
||||
}
|
||||
return myCanCleanup;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<IntentionAction> getOptions(@NotNull PsiElement element, @Nullable Editor editor) {
|
||||
if (editor != null && Boolean.FALSE.equals(editor.getUserData(IntentionManager.SHOW_INTENTION_OPTIONS_KEY))) {
|
||||
@@ -789,6 +804,9 @@ public class HighlightInfo implements Segment {
|
||||
}
|
||||
}
|
||||
if (toolWrapper != null) {
|
||||
|
||||
myCanCleanup = toolWrapper.isCleanupTool();
|
||||
|
||||
InspectionProfileEntry wrappedTool;
|
||||
if (toolWrapper instanceof LocalInspectionToolWrapper) {
|
||||
wrappedTool = ((LocalInspectionToolWrapper)toolWrapper).getTool();
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.AnalysisScope;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class CleanupAllIntention extends CleanupIntention {
|
||||
|
||||
public static final CleanupAllIntention INSTANCE = new CleanupAllIntention();
|
||||
|
||||
private CleanupAllIntention() {}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return InspectionsBundle.message("cleanup.in.file");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected AnalysisScope getScope(Project project, PsiFile file) {
|
||||
return new AnalysisScope(file);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.AnalysisScope;
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.LowPriorityAction;
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.codeInspection.InspectionProfile;
|
||||
import com.intellij.codeInspection.InspectionsBundle;
|
||||
import com.intellij.codeInspection.ex.GlobalInspectionContextBase;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class CleanupIntention implements IntentionAction, LowPriorityAction {
|
||||
|
||||
protected CleanupIntention() {}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getText() {
|
||||
return getFamilyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return InspectionsBundle.message("cleanup.in.scope");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
|
||||
if (!FileModificationService.getInstance().preparePsiElementForWrite(file)) return;
|
||||
final InspectionManager managerEx = InspectionManager.getInstance(project);
|
||||
final GlobalInspectionContextBase globalContext = (GlobalInspectionContextBase)managerEx.createNewGlobalContext(false);
|
||||
final AnalysisScope scope = getScope(project, file);
|
||||
if (scope != null) {
|
||||
final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
|
||||
globalContext.codeCleanup(project, scope, profile, getText());
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract AnalysisScope getScope(Project project, PsiFile file);
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -402,7 +402,12 @@ public class GlobalInspectionContextBase extends UserDataHolderBase implements G
|
||||
}
|
||||
}
|
||||
|
||||
public void close(boolean noSuspisiousCodeFound) {
|
||||
public void codeCleanup(final Project project,
|
||||
final AnalysisScope scope,
|
||||
final InspectionProfile profile,
|
||||
final String commandName) {}
|
||||
|
||||
public void close(boolean noSuspisiousCodeFound) {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.codeInsight.daemon.impl;
|
||||
|
||||
import com.intellij.analysis.AnalysisScope;
|
||||
import com.intellij.analysis.AnalysisScopeBundle;
|
||||
import com.intellij.analysis.AnalysisUIOptions;
|
||||
import com.intellij.analysis.BaseAnalysisActionDialog;
|
||||
import com.intellij.codeInspection.InspectionsBundle;
|
||||
import com.intellij.codeInspection.actions.CleanupIntention;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by anna on 5/13/2014.
|
||||
*/
|
||||
class CleanupOnScopeIntention extends CleanupIntention {
|
||||
static final CleanupOnScopeIntention INSTANCE = new CleanupOnScopeIntention();
|
||||
|
||||
private CleanupOnScopeIntention() {}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected AnalysisScope getScope(final Project project, final PsiFile file) {
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement(file);
|
||||
AnalysisScope analysisScope = new AnalysisScope(file);
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (file.isPhysical() || virtualFile == null || !virtualFile.isInLocalFileSystem()) {
|
||||
analysisScope = new AnalysisScope(project);
|
||||
}
|
||||
final BaseAnalysisActionDialog dlg = new BaseAnalysisActionDialog(
|
||||
AnalysisScopeBundle.message("specify.analysis.scope", InspectionsBundle.message("inspection.action.title")),
|
||||
AnalysisScopeBundle.message("analysis.scope.title", InspectionsBundle.message("inspection.action.noun")),
|
||||
project,
|
||||
analysisScope,
|
||||
module != null ? module.getName() : null,
|
||||
true, AnalysisUIOptions.getInstance(project), file);
|
||||
dlg.show();
|
||||
if (!dlg.isOK()) return null;
|
||||
final AnalysisUIOptions uiOptions = AnalysisUIOptions.getInstance(project);
|
||||
return dlg.getScope(uiOptions, analysisScope, project, module);
|
||||
}
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.codeInsight.daemon.impl;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInspection.InspectionProfile;
|
||||
import com.intellij.codeInspection.ex.InspectionToolWrapper;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.options.ShowSettingsUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.profile.codeInspection.InspectionProfileManager;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.profile.codeInspection.ui.IDEInspectionToolsConfigurable;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by anna on 5/13/2014.
|
||||
*/
|
||||
class EditCleanupProfileIntentionAction implements IntentionAction {
|
||||
static final EditCleanupProfileIntentionAction INSTANCE = new EditCleanupProfileIntentionAction();
|
||||
private EditCleanupProfileIntentionAction() {}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getText() {
|
||||
return getFamilyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return "Edit cleanup profile settings";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
final InspectionProjectProfileManager profileManager = InspectionProjectProfileManager.getInstance(project);
|
||||
final InspectionProfile inspectionProfile = profileManager.getInspectionProfile();
|
||||
final IDEInspectionToolsConfigurable configurable =
|
||||
new IDEInspectionToolsConfigurable(profileManager,
|
||||
InspectionProfileManager.getInstance()) {
|
||||
@Override
|
||||
protected boolean acceptTool(InspectionToolWrapper entry) {
|
||||
return super.acceptTool(entry) && entry.isCleanupTool();
|
||||
}
|
||||
};
|
||||
ShowSettingsUtil.getInstance().editConfigurable(project, configurable, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
configurable.selectProfile(inspectionProfile.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import com.intellij.codeInsight.intention.impl.config.IntentionManagerSettings;
|
||||
import com.intellij.codeInsight.lookup.LookupManager;
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
import com.intellij.codeInspection.actions.CleanupAllIntention;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
@@ -230,6 +231,19 @@ public class ShowIntentionsPass extends TextEditorHighlightingPass {
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean appendCleanupCode(final List<HighlightInfo.IntentionActionDescriptor> actionDescriptors, PsiFile file) {
|
||||
for (HighlightInfo.IntentionActionDescriptor descriptor : actionDescriptors) {
|
||||
if (descriptor.canCleanup(file)) {
|
||||
final ArrayList<IntentionAction> options = new ArrayList<IntentionAction>();
|
||||
options.add(EditCleanupProfileIntentionAction.INSTANCE);
|
||||
options.add(CleanupOnScopeIntention.INSTANCE);
|
||||
actionDescriptors.add(new HighlightInfo.IntentionActionDescriptor(CleanupAllIntention.INSTANCE, options, "Code Cleanup Options"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updateActions(@NotNull DaemonCodeAnalyzerImpl codeAnalyzer) {
|
||||
IntentionHintComponent hintComponent = codeAnalyzer.getLastIntentionHint();
|
||||
if (!myShowBulb || hintComponent == null) {
|
||||
@@ -326,6 +340,11 @@ public class ShowIntentionsPass extends TextEditorHighlightingPass {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
boolean cleanup = appendCleanupCode(intentions.inspectionFixesToShow, hostFile);
|
||||
if (!cleanup) {
|
||||
appendCleanupCode(intentions.errorFixesToShow, hostFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,33 +17,18 @@
|
||||
package com.intellij.codeInspection.actions;
|
||||
|
||||
import com.intellij.analysis.AnalysisScope;
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoProcessor;
|
||||
import com.intellij.codeInsight.daemon.impl.LocalInspectionsPass;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.ex.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.codeInspection.InspectionProfile;
|
||||
import com.intellij.codeInspection.ex.GlobalInspectionContextBase;
|
||||
import com.intellij.codeInspection.ex.GlobalInspectionContextImpl;
|
||||
import com.intellij.codeInspection.ex.InspectionManagerEx;
|
||||
import com.intellij.codeInspection.ex.InspectionToolWrapper;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.profile.codeInspection.InspectionProfileManager;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.profile.codeInspection.ui.IDEInspectionToolsConfigurable;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.SequentialModalProgressTask;
|
||||
import com.intellij.util.SequentialTask;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CodeCleanupAction extends CodeInspectionAction {
|
||||
public CodeCleanupAction() {
|
||||
super("Code Cleanup", "Code Cleanup");
|
||||
@@ -52,66 +37,9 @@ public class CodeCleanupAction extends CodeInspectionAction {
|
||||
@Override
|
||||
protected void analyze(@NotNull final Project project, @NotNull final AnalysisScope scope) {
|
||||
final InspectionProfile profile = myExternalProfile != null ? myExternalProfile : InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
|
||||
final List<LocalInspectionToolWrapper> lTools = new ArrayList<LocalInspectionToolWrapper>();
|
||||
final InspectionManagerEx managerEx = (InspectionManagerEx)InspectionManager.getInstance(project);
|
||||
final GlobalInspectionContextImpl context = managerEx.createNewGlobalContext(false);
|
||||
|
||||
final LinkedHashMap<PsiFile, List<HighlightInfo>> results = new LinkedHashMap<PsiFile, List<HighlightInfo>>();
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(project, "Inspect code...", true) {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
scope.accept(new PsiElementVisitor() {
|
||||
@Override
|
||||
public void visitFile(PsiFile file) {
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile == null) return;
|
||||
for (final Tools tools : profile.getAllEnabledInspectionTools(project)) {
|
||||
if (tools.getTool().getTool() instanceof CleanupLocalInspectionTool) {
|
||||
final InspectionToolWrapper tool = tools.getEnabledTool(file);
|
||||
if (tool instanceof LocalInspectionToolWrapper) {
|
||||
lTools.add((LocalInspectionToolWrapper)tool);
|
||||
tool.initialize(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!lTools.isEmpty()) {
|
||||
final LocalInspectionsPass pass = new LocalInspectionsPass(file, PsiDocumentManager.getInstance(project).getDocument(file), 0,
|
||||
file.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true,
|
||||
HighlightInfoProcessor.getEmpty());
|
||||
Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
pass.doInspectInBatch(context, managerEx, lTools);
|
||||
}
|
||||
};
|
||||
ApplicationManager.getApplication().runReadAction(runnable);
|
||||
results.put(file, pass.getInfos());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
if (!FileModificationService.getInstance().preparePsiElementsForWrite(results.keySet())) return;
|
||||
|
||||
final SequentialModalProgressTask progressTask = new SequentialModalProgressTask(project, "Code Cleanup", true);
|
||||
progressTask.setMinIterationTime(200);
|
||||
progressTask.setTask(new SequentialCleanupTask(project, results, progressTask));
|
||||
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ProgressManager.getInstance().run(progressTask);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, getTemplatePresentation().getText(), null);
|
||||
}
|
||||
});
|
||||
final InspectionManager managerEx = InspectionManager.getInstance(project);
|
||||
final GlobalInspectionContextBase globalContext = (GlobalInspectionContextBase)managerEx.createNewGlobalContext(false);
|
||||
globalContext.codeCleanup(project, scope, profile, getTemplatePresentation().getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -125,49 +53,3 @@ public class CodeCleanupAction extends CodeInspectionAction {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class SequentialCleanupTask implements SequentialTask {
|
||||
|
||||
private final Project myProject;
|
||||
private final LinkedHashMap<PsiFile, List<HighlightInfo>> myResults;
|
||||
private Iterator<PsiFile> myFileIterator;
|
||||
private final SequentialModalProgressTask myProgressTask;
|
||||
private int myCount = 0;
|
||||
|
||||
public SequentialCleanupTask(Project project, LinkedHashMap<PsiFile, List<HighlightInfo>> results, SequentialModalProgressTask task) {
|
||||
myProject = project;
|
||||
myResults = results;
|
||||
myProgressTask = task;
|
||||
myFileIterator = myResults.keySet().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare() {}
|
||||
|
||||
@Override
|
||||
public boolean isDone() {
|
||||
return myFileIterator == null || !myFileIterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean iteration() {
|
||||
final ProgressIndicator indicator = myProgressTask.getIndicator();
|
||||
if (indicator != null) {
|
||||
indicator.setFraction((double) myCount++/myResults.size());
|
||||
}
|
||||
final PsiFile file = myFileIterator.next();
|
||||
final List<HighlightInfo> infos = myResults.get(file);
|
||||
Collections.reverse(infos); //sort bottom - top
|
||||
for (HighlightInfo info : infos) {
|
||||
for (final Pair<HighlightInfo.IntentionActionDescriptor, TextRange> actionRange : info.quickFixActionRanges) {
|
||||
actionRange.getFirst().getAction().invoke(myProject, null, file);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
myFileIterator = null;
|
||||
}
|
||||
}
|
||||
|
||||
+71
-6
@@ -19,6 +19,8 @@ package com.intellij.codeInspection.ex;
|
||||
import com.intellij.analysis.AnalysisScope;
|
||||
import com.intellij.analysis.AnalysisUIOptions;
|
||||
import com.intellij.analysis.PerformAnalysisInBackgroundOption;
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoProcessor;
|
||||
import com.intellij.codeInsight.daemon.impl.LocalInspectionsPass;
|
||||
import com.intellij.codeInspection.*;
|
||||
@@ -36,10 +38,10 @@ import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.notification.NotificationGroup;
|
||||
import com.intellij.openapi.actionSystem.ToggleAction;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.components.PathMacroManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.PerformInBackgroundOption;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.*;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectUtilCore;
|
||||
@@ -56,6 +58,7 @@ import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.ui.content.*;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.SequentialModalProgressTask;
|
||||
import com.intellij.util.TripleFunction;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
@@ -71,10 +74,7 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
public class GlobalInspectionContextImpl extends GlobalInspectionContextBase implements GlobalInspectionContext {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.GlobalInspectionContextImpl");
|
||||
@@ -606,4 +606,69 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
|
||||
}
|
||||
return presentation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void codeCleanup(final Project project,
|
||||
final AnalysisScope scope,
|
||||
final InspectionProfile profile,
|
||||
final String commandName) {
|
||||
final List<LocalInspectionToolWrapper> lTools = new ArrayList<LocalInspectionToolWrapper>();
|
||||
|
||||
final LinkedHashMap<PsiFile, List<HighlightInfo>> results = new LinkedHashMap<PsiFile, List<HighlightInfo>>();
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(project, "Inspect code...", true) {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
scope.accept(new PsiElementVisitor() {
|
||||
@Override
|
||||
public void visitFile(PsiFile file) {
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile == null) return;
|
||||
for (final Tools tools : profile.getAllEnabledInspectionTools(project)) {
|
||||
if (tools.getTool().getTool() instanceof CleanupLocalInspectionTool) {
|
||||
final InspectionToolWrapper tool = tools.getEnabledTool(file);
|
||||
if (tool instanceof LocalInspectionToolWrapper) {
|
||||
lTools.add((LocalInspectionToolWrapper)tool);
|
||||
tool.initialize(GlobalInspectionContextImpl.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!lTools.isEmpty()) {
|
||||
final LocalInspectionsPass pass = new LocalInspectionsPass(file, PsiDocumentManager.getInstance(project).getDocument(file), 0,
|
||||
file.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true,
|
||||
HighlightInfoProcessor.getEmpty());
|
||||
Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
pass.doInspectInBatch(GlobalInspectionContextImpl.this, (InspectionManagerEx)InspectionManager.getInstance(project), lTools);
|
||||
}
|
||||
};
|
||||
ApplicationManager.getApplication().runReadAction(runnable);
|
||||
results.put(file, pass.getInfos());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
if (!FileModificationService.getInstance().preparePsiElementsForWrite(results.keySet())) return;
|
||||
|
||||
final SequentialModalProgressTask progressTask = new SequentialModalProgressTask(project, "Code Cleanup", true);
|
||||
progressTask.setMinIterationTime(200);
|
||||
progressTask.setTask(new SequentialCleanupTask(project, results, progressTask));
|
||||
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ProgressManager.getInstance().run(progressTask);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, commandName, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.ex;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.SequentialModalProgressTask;
|
||||
import com.intellij.util.SequentialTask;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
class SequentialCleanupTask implements SequentialTask {
|
||||
|
||||
private final Project myProject;
|
||||
private final LinkedHashMap<PsiFile, List<HighlightInfo>> myResults;
|
||||
private Iterator<PsiFile> myFileIterator;
|
||||
private final SequentialModalProgressTask myProgressTask;
|
||||
private int myCount = 0;
|
||||
|
||||
public SequentialCleanupTask(Project project, LinkedHashMap<PsiFile, List<HighlightInfo>> results, SequentialModalProgressTask task) {
|
||||
myProject = project;
|
||||
myResults = results;
|
||||
myProgressTask = task;
|
||||
myFileIterator = myResults.keySet().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare() {}
|
||||
|
||||
@Override
|
||||
public boolean isDone() {
|
||||
return myFileIterator == null || !myFileIterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean iteration() {
|
||||
final ProgressIndicator indicator = myProgressTask.getIndicator();
|
||||
if (indicator != null) {
|
||||
indicator.setFraction((double) myCount++/myResults.size());
|
||||
}
|
||||
final PsiFile file = myFileIterator.next();
|
||||
final List<HighlightInfo> infos = myResults.get(file);
|
||||
Collections.reverse(infos); //sort bottom - top
|
||||
for (HighlightInfo info : infos) {
|
||||
for (final Pair<HighlightInfo.IntentionActionDescriptor, TextRange> actionRange : info.quickFixActionRanges) {
|
||||
actionRange.getFirst().getAction().invoke(myProject, null, file);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
myFileIterator = null;
|
||||
}
|
||||
}
|
||||
@@ -664,6 +664,8 @@ unused.library.backward.analysis.job.description=Perform backward analysis
|
||||
inspection.duplicates.option.report.propertykey.expressions=&Ignore @PropertyKey expressions
|
||||
inspection.same.parameter.fix.name=Inline value ''{1}'' for parameter ''{0}''
|
||||
fix.all.inspection.problems.in.file=Fix all ''{0}'' problems
|
||||
cleanup.in.file=Cleanup code
|
||||
cleanup.in.scope=Cleanup code on...
|
||||
severities.default.settings.message=Edit Settings|Colors \\& Fonts
|
||||
unsupported.character.for.the.charset=Unsupported characters for the charset ''{0}''
|
||||
lossy.encoding=Lossy encoding
|
||||
|
||||
Reference in New Issue
Block a user