code cleanup available as intentions (IDEA-38653)

This commit is contained in:
Anna Kozlova
2014-05-13 13:23:58 +04:00
parent 60343302c9
commit a6f328b3f8
11 changed files with 458 additions and 134 deletions
@@ -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();
@@ -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;
}
}
@@ -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();
}
@@ -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);
}
}
@@ -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;
}
}
@@ -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