post highlighting: IDEA-73813

This commit is contained in:
Alexey Kudravtsev
2011-10-12 18:32:22 +04:00
parent edd94b80aa
commit 7cd2d524a5
6 changed files with 92 additions and 78 deletions
@@ -95,7 +95,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
private Collection<HighlightInfo> myHighlights;
private boolean myHasRedundantImports;
private final JavaCodeStyleManager myStyleManager;
private int myCurentEntryIndex;
private int myCurrentEntryIndex;
private boolean myHasMissortedImports;
private final ImplicitUsageProvider[] myImplicitUsageProviders;
private UnusedDeclarationInspection myDeadCodeInspection;
@@ -110,17 +110,15 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
PostHighlightingPass(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull Document document,
int startOffset,
int endOffset) {
@NotNull Document document) {
super(project, document, true);
myFile = file;
myEditor = editor;
myStartOffset = startOffset;
myEndOffset = endOffset;
myStartOffset = 0;
myEndOffset = file.getTextLength();
myStyleManager = JavaCodeStyleManager.getInstance(myProject);
myCurentEntryIndex = -1;
myCurrentEntryIndex = -1;
myImplicitUsageProviders = Extensions.getExtensions(ImplicitUsageProvider.EP_NAME);
}
@@ -146,13 +144,10 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
myRefCountHolder = RefCountHolder.getInstance(myFile);
if (!myRefCountHolder.retrieveUnusedReferencesInfo(new Runnable() {
public void run() {
collectHighlights(elementSet, highlights, progress);
boolean errorFound = collectHighlights(elementSet, highlights, progress);
myHighlights = highlights;
for (HighlightInfo info : highlights) {
if (info.getSeverity() == HighlightSeverity.ERROR) {
fileStatusMap.setErrorFoundFlag(myDocument, true);
break;
}
if (errorFound) {
fileStatusMap.setErrorFoundFlag(myDocument, true);
}
}
})) {
@@ -169,9 +164,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
public void doApplyInformationToEditor() {
if (myHighlights == null) return;
UpdateHighlightersUtil.setHighlightersToEditor(myProject, myDocument, myStartOffset, myEndOffset, myHighlights, getColorsScheme(), Pass.POST_UPDATE_ALL);
DaemonCodeAnalyzer daemonCodeAnalyzer = DaemonCodeAnalyzer.getInstance(myProject);
((DaemonCodeAnalyzerImpl)daemonCodeAnalyzer).getFileStatusMap().markFileUpToDate(myDocument, myFile, getId());
PostHighlightingPassFactory.markFileUpToDate(myFile);
Editor editor = myEditor;
if (editor != null && timeToOptimizeImports()) {
@@ -212,7 +205,8 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
});
}
private void collectHighlights(@NotNull Collection<PsiElement> elements, @NotNull final List<HighlightInfo> result, @NotNull ProgressIndicator progress) throws ProcessCanceledException {
// returns true if error highlight was created
private boolean collectHighlights(@NotNull Collection<PsiElement> elements, @NotNull final List<HighlightInfo> result, @NotNull ProgressIndicator progress) throws ProcessCanceledException {
ApplicationManager.getApplication().assertReadAccessAllowed();
InspectionProfile profile = InspectionProjectProfileManager.getInstance(myProject).getInspectionProfile();
@@ -241,30 +235,36 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
myDeadCodeInfoType = myDeadCodeKey == null ? null : new HighlightInfoType.HighlightInfoTypeImpl(profile.getErrorLevel(myDeadCodeKey, myFile).getSeverity(), HighlightInfoType.UNUSED_SYMBOL.getAttributesKey());
if (!unusedSymbolEnabled && !unusedImportEnabled) {
return;
}
for (PsiElement element : elements) {
progress.checkCanceled();
if (unusedSymbolEnabled && element instanceof PsiIdentifier) {
PsiIdentifier identifier = (PsiIdentifier)element;
HighlightInfo info = processIdentifier(identifier, progress);
if (info != null) {
result.add(info);
}
}
else if (unusedImportEnabled && element instanceof PsiImportList) {
final PsiImportStatementBase[] imports = ((PsiImportList)element).getAllImportStatements();
for (PsiImportStatementBase statement : imports) {
progress.checkCanceled();
final HighlightInfo info = processImport(statement, unusedImportKey);
boolean errorFound = false;
if (unusedSymbolEnabled) {
for (PsiElement element : elements) {
progress.checkCanceled();
if (element instanceof PsiIdentifier) {
PsiIdentifier identifier = (PsiIdentifier)element;
HighlightInfo info = processIdentifier(identifier, progress);
if (info != null) {
errorFound |= info.getSeverity() == HighlightSeverity.ERROR;
result.add(info);
}
}
}
}
if (unusedImportEnabled && myFile instanceof PsiJavaFile) {
PsiImportList importList = ((PsiJavaFile)myFile).getImportList();
if (importList != null) {
final PsiImportStatementBase[] imports = importList.getAllImportStatements();
for (PsiImportStatementBase statement : imports) {
progress.checkCanceled();
final HighlightInfo info = processImport(statement, unusedImportKey);
if (info != null) {
errorFound |= info.getSeverity() == HighlightSeverity.ERROR;
result.add(info);
}
}
}
}
return errorFound;
}
@Nullable
@@ -689,10 +689,10 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
}
int entryIndex = myStyleManager.findEntryIndex(importStatement);
if (entryIndex < myCurentEntryIndex) {
if (entryIndex < myCurrentEntryIndex) {
myHasMissortedImports = true;
}
myCurentEntryIndex = entryIndex;
myCurrentEntryIndex = entryIndex;
return null;
}
@@ -15,13 +15,18 @@
*/
package com.intellij.codeInsight.daemon.impl;
import com.intellij.codeHighlighting.*;
import com.intellij.codeHighlighting.MainHighlightingPassFactory;
import com.intellij.codeHighlighting.Pass;
import com.intellij.codeHighlighting.TextEditorHighlightingPass;
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiModificationTracker;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -30,6 +35,7 @@ import org.jetbrains.annotations.Nullable;
* @author cdr
*/
public class PostHighlightingPassFactory extends AbstractProjectComponent implements MainHighlightingPassFactory {
private static final Key<Long> LAST_POST_PASS_TIMESTAMP = Key.create("LAST_POST_PASS_TIMESTAMP");
public PostHighlightingPassFactory(Project project, TextEditorHighlightingPassRegistrar highlightingPassRegistrar) {
super(project);
highlightingPassRegistrar.registerTextEditorHighlightingPass(this, new int[]{Pass.UPDATE_ALL,}, null, true, Pass.POST_UPDATE_ALL);
@@ -44,17 +50,24 @@ public class PostHighlightingPassFactory extends AbstractProjectComponent implem
@Nullable
public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull final Editor editor) {
TextRange textRange = FileStatusMap.getDirtyTextRange(editor, Pass.UPDATE_ALL);
if (textRange == null) return null;
int startOffset = 0;
int endOffset = editor.getDocument().getTextLength();
if (textRange == null) {
Long lastStamp = file.getUserData(LAST_POST_PASS_TIMESTAMP);
long currentStamp = PsiModificationTracker.SERVICE.getInstance(myProject).getModificationCount();
if (lastStamp != null && lastStamp == currentStamp) {
return null;
}
}
return new PostHighlightingPass(myProject, file, editor, editor.getDocument(), startOffset, endOffset);
return new PostHighlightingPass(myProject, file, editor, editor.getDocument());
}
@Override
public TextEditorHighlightingPass createMainHighlightingPass(@NotNull PsiFile file, @NotNull Document document) {
int startOffset = 0;
int endOffset = document.getTextLength();
return new PostHighlightingPass(myProject, file, null, document, startOffset, endOffset);
return new PostHighlightingPass(myProject, file, null, document);
}
public static void markFileUpToDate(@NotNull PsiFile file) {
long lastStamp = PsiModificationTracker.SERVICE.getInstance(file.getProject()).getModificationCount();
file.putUserData(LAST_POST_PASS_TIMESTAMP, lastStamp);
}
}
@@ -97,8 +97,7 @@ import java.util.List;
import java.util.Map;
public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
private final Map<String, LocalInspectionTool> myAvailableTools = new THashMap<String, LocalInspectionTool>();
private final Map<String, LocalInspectionToolWrapper> myAvailableLocalTools = new THashMap<String, LocalInspectionToolWrapper>();
private final Map<String, InspectionProfileEntry> myAvailableTools = new THashMap<String, InspectionProfileEntry>();
private final FileTreeAccessFilter myFileTreeAccessFilter = new FileTreeAccessFilter();
@Override
@@ -127,8 +126,13 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
@Override
@NotNull
public InspectionProfileEntry[] getInspectionTools(PsiElement element) {
final Collection<LocalInspectionToolWrapper> tools = myAvailableLocalTools.values();
return tools.toArray(new LocalInspectionToolWrapper[tools.size()]);
Collection<InspectionProfileEntry> values = myAvailableTools.values();
List<InspectionTool> result = new ArrayList<InspectionTool>();
for (InspectionProfileEntry value : values) {
InspectionTool tool = value instanceof InspectionTool ? (InspectionTool)value : new LocalInspectionToolWrapper((LocalInspectionTool)value);
result.add(tool);
}
return result.toArray(new InspectionTool[result.size()]);
}
@Override
@@ -147,13 +151,14 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
@Override
public HighlightDisplayLevel getErrorLevel(@NotNull HighlightDisplayKey key, PsiElement element) {
final LocalInspectionTool localInspectionTool = myAvailableTools.get(key.toString());
final InspectionProfileEntry localInspectionTool = myAvailableTools.get(key.toString());
return localInspectionTool != null ? localInspectionTool.getDefaultLevel() : HighlightDisplayLevel.WARNING;
}
@Override
public InspectionTool getInspectionTool(@NotNull String shortName, @NotNull PsiElement element) {
return myAvailableLocalTools.get(shortName);
InspectionProfileEntry entry = myAvailableTools.get(shortName);
return entry == null ? null : entry instanceof InspectionTool ? (InspectionTool)entry : new LocalInspectionToolWrapper((LocalInspectionTool)entry);
}
};
final InspectionProfileManager inspectionProfileManager = InspectionProfileManager.getInstance();
@@ -199,14 +204,14 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
((VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance()).assertPointersDisposed();
}
protected void enableInspectionTool(LocalInspectionTool tool){
protected void enableInspectionTool(InspectionProfileEntry tool){
final String shortName = tool.getShortName();
final HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
if (key == null){
HighlightDisplayKey.register(shortName, tool.getDisplayName(), tool.getID());
if (key == null) {
assert tool instanceof LocalInspectionTool;
HighlightDisplayKey.register(shortName, tool.getDisplayName(), ((LocalInspectionTool)tool).getID());
}
myAvailableTools.put(shortName, tool);
myAvailableLocalTools.put(shortName, new LocalInspectionToolWrapper(tool));
}
protected void enableInspectionToolsFromProvider(InspectionToolProvider toolProvider){
@@ -222,7 +227,6 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
protected void disableInspectionTool(String shortName){
myAvailableTools.remove(shortName);
myAvailableLocalTools.remove(shortName);
}
protected LocalInspectionTool[] configureLocalInspectionTools() {
@@ -19,7 +19,6 @@ import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiModificationTrackerImpl;
import com.intellij.psi.search.ProjectScope;
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture;
@@ -64,13 +63,6 @@ public class JavaCodeInsightTestFixtureImpl extends CodeInsightTestFixtureImpl i
return ((PsiJavaFile)psiFile).getClasses()[0];
}
@Override
protected PsiFile addFileToProject(String rootPath, String relativePath, String fileText) {
PsiFile file = super.addFileToProject(rootPath, relativePath, fileText);
((PsiModificationTrackerImpl)PsiManager.getInstance(getProject()).getModificationTracker()).incCounter();
return file;
}
@Override
@NotNull
public PsiClass findClass(@NotNull @NonNls final String name) {
@@ -22,11 +22,13 @@ import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory;
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar;
import com.intellij.codeInsight.daemon.DaemonBundle;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.ex.InspectionManagerEx;
import com.intellij.codeInspection.ex.InspectionProfileWrapper;
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.TextRange;
@@ -59,6 +61,7 @@ public class WholeFileLocalInspectionsPassFactory extends AbstractProjectCompone
myProfileManager = profileManager;
}
@Override
@NonNls
@NotNull
public String getComponentName() {
@@ -80,6 +83,7 @@ public class WholeFileLocalInspectionsPassFactory extends AbstractProjectCompone
};
myProfileManager.addProfilesListener(myProfilesListener);
Disposer.register(myProject, new Disposable() {
@Override
public void dispose() {
myProfileManager.removeProfilesListener(myProfilesListener);
myFileTools.clear();
@@ -87,6 +91,7 @@ public class WholeFileLocalInspectionsPassFactory extends AbstractProjectCompone
});
}
@Override
@Nullable
public TextEditorHighlightingPass createHighlightingPass(@NotNull final PsiFile file, @NotNull final Editor editor) {
TextRange textRange = FileStatusMap.getDirtyTextRange(editor, Pass.LOCAL_INSPECTIONS);
@@ -97,6 +102,7 @@ public class WholeFileLocalInspectionsPassFactory extends AbstractProjectCompone
}
return new LocalInspectionsPass(file, editor.getDocument(), 0, file.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true) {
@Override
List<LocalInspectionToolWrapper> getInspectionTools(InspectionProfileWrapper profile) {
List<LocalInspectionToolWrapper> tools = super.getInspectionTools(profile);
List<LocalInspectionToolWrapper> result = new ArrayList<LocalInspectionToolWrapper>(tools.size());
@@ -112,8 +118,14 @@ public class WholeFileLocalInspectionsPassFactory extends AbstractProjectCompone
return DaemonBundle.message("pass.whole.inspections");
}
void inspectInjectedPsi(PsiElement[] elements, List<LocalInspectionTool> tools) {
// inspected in LIP already
@Override
void inspectInjectedPsi(@NotNull List<PsiElement> elements,
@NotNull List<LocalInspectionTool> tools,
boolean onTheFly,
@NotNull ProgressIndicator indicator,
@NotNull InspectionManagerEx iManager,
boolean inVisibleRange) {
// already inspected in LIP
}
};
}
@@ -25,10 +25,7 @@ import com.intellij.codeInsight.completion.CompletionType;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInsight.daemon.impl.ShowIntentionsPass;
import com.intellij.codeInsight.daemon.impl.*;
import com.intellij.codeInsight.folding.CodeFoldingManager;
import com.intellij.codeInsight.highlighting.actions.HighlightUsagesAction;
import com.intellij.codeInsight.intention.IntentionAction;
@@ -50,7 +47,6 @@ import com.intellij.ide.startup.impl.StartupManagerImpl;
import com.intellij.ide.structureView.StructureViewBuilder;
import com.intellij.ide.structureView.newStructureView.StructureViewComponent;
import com.intellij.lang.LanguageStructureViewBuilder;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
@@ -91,6 +87,7 @@ import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.impl.PsiManagerImpl;
import com.intellij.psi.impl.PsiModificationTrackerImpl;
import com.intellij.psi.impl.cache.CacheManager;
import com.intellij.psi.impl.cache.impl.todo.TodoIndex;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
@@ -153,7 +150,6 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
@NonNls private static final String XXX = "XXX";
private final FileTreeAccessFilter myJavaFilesFilter = new FileTreeAccessFilter();
private boolean myAllowDirt;
private boolean toInitializeDaemon;
public CodeInsightTestFixtureImpl(IdeaProjectTestFixture projectFixture, TempDirTestFixture tempDirTestFixture) {
myProjectFixture = projectFixture;
@@ -810,7 +806,6 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
@Override
@Nullable
public GutterIconRenderer findGutter(final String filePath) {
assertInitialized();
configureByFilesInner(filePath);
int offset = myEditor.getCaretModel().getOffset();
@@ -838,7 +833,6 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
@Override
@NotNull
public Collection<GutterIconRenderer> findAllGutters(final String filePath) {
assertInitialized();
final Project project = getProject();
final SortedMap<Integer, List<GutterIconRenderer>> result = new TreeMap<Integer, List<GutterIconRenderer>>();
configureByFilesInner(filePath);
@@ -885,6 +879,9 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
catch (IOException e) {
throw new RuntimeException(e);
}
finally {
((PsiModificationTrackerImpl)PsiManager.getInstance(getProject()).getModificationTracker()).incCounter();
}
}
public <T> void registerExtension(final ExtensionsArea area, final ExtensionPointName<T> epName, final T extension) {
@@ -1060,9 +1057,6 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
for (VirtualFile openFile : openFiles) {
editorManager.closeFile(openFile);
}
if (toInitializeDaemon) {
((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).cleanupAfterTest(!LightPlatformTestCase.isLight(getProject()));
}
myEditor = null;
myFile = null;
@@ -1166,7 +1160,6 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
@Override
public PsiFile configureByFile(final String file) {
assertInitialized();
configureByFilesInner(file);
return myFile;
}