use of com.intellij.codeHighlighting.HighlightingPass in project intellij-community by JetBrains.
the class DomUIFactoryImpl method createDomHighlighter.
@Override
public BackgroundEditorHighlighter createDomHighlighter(final Project project, final PerspectiveFileEditor editor, final DomElement element) {
return new BackgroundEditorHighlighter() {
@Override
@NotNull
public HighlightingPass[] createPassesForEditor() {
if (!element.isValid())
return HighlightingPass.EMPTY_ARRAY;
final XmlFile psiFile = DomUtil.getFile(element);
final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
final Document document = psiDocumentManager.getDocument(psiFile);
if (document == null)
return HighlightingPass.EMPTY_ARRAY;
editor.commit();
GeneralHighlightingPass ghp = new GeneralHighlightingPass(project, psiFile, document, 0, document.getTextLength(), true, new ProperTextRange(0, document.getTextLength()), null, new DefaultHighlightInfoProcessor());
LocalInspectionsPass lip = new LocalInspectionsPass(psiFile, document, 0, document.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true, new DefaultHighlightInfoProcessor());
return new HighlightingPass[] { ghp, lip };
}
@Override
@NotNull
public HighlightingPass[] createPassesForVisibleArea() {
return createPassesForEditor();
}
};
}
use of com.intellij.codeHighlighting.HighlightingPass in project intellij-community by JetBrains.
the class DaemonCodeAnalyzerImpl method runPasses.
@NotNull
@TestOnly
List<HighlightInfo> runPasses(@NotNull PsiFile file, @NotNull Document document, @NotNull List<TextEditor> textEditors, @NotNull int[] toIgnore, boolean canChangeDocument, @Nullable final Runnable callbackWhileWaiting) throws ProcessCanceledException {
assert myInitialized;
assert !myDisposed;
ApplicationEx application = ApplicationManagerEx.getApplicationEx();
application.assertIsDispatchThread();
if (application.isWriteAccessAllowed()) {
throw new AssertionError("Must not start highlighting from within write action, or deadlock is imminent");
}
DaemonProgressIndicator.setDebug(!ApplicationInfoImpl.isInStressTest());
((FileTypeManagerImpl) FileTypeManager.getInstance()).drainReDetectQueue();
// pump first so that queued event do not interfere
UIUtil.dispatchAllInvocationEvents();
// refresh will fire write actions interfering with highlighting
while (RefreshQueueImpl.isRefreshInProgress() || HeavyProcessLatch.INSTANCE.isRunning()) {
UIUtil.dispatchAllInvocationEvents();
}
long dstart = System.currentTimeMillis();
while (mustWaitForSmartMode && DumbService.getInstance(myProject).isDumb()) {
if (System.currentTimeMillis() > dstart + 100000) {
throw new IllegalStateException("Timeout waiting for smart mode. If you absolutely want to be dumb, please use DaemonCodeAnalyzerImpl.mustWaitForSmartMode(false).");
}
UIUtil.dispatchAllInvocationEvents();
}
UIUtil.dispatchAllInvocationEvents();
Project project = file.getProject();
FileStatusMap fileStatusMap = getFileStatusMap();
fileStatusMap.allowDirt(canChangeDocument);
Map<FileEditor, HighlightingPass[]> map = new HashMap<>();
for (TextEditor textEditor : textEditors) {
if (textEditor instanceof TextEditorImpl) {
try {
((TextEditorImpl) textEditor).waitForLoaded(10, TimeUnit.SECONDS);
} catch (TimeoutException e) {
throw new RuntimeException(textEditor + " has not completed loading in 10 seconds");
}
}
TextEditorBackgroundHighlighter highlighter = (TextEditorBackgroundHighlighter) textEditor.getBackgroundHighlighter();
if (highlighter == null) {
Editor editor = textEditor.getEditor();
throw new RuntimeException("Null highlighter from " + textEditor + "; loaded: " + AsyncEditorLoader.isEditorLoaded(editor));
}
final List<TextEditorHighlightingPass> passes = highlighter.getPasses(toIgnore);
HighlightingPass[] array = passes.toArray(new HighlightingPass[passes.size()]);
assert array.length != 0 : "Highlighting is disabled for the file " + file;
map.put(textEditor, array);
}
for (int ignoreId : toIgnore) {
fileStatusMap.markFileUpToDate(document, ignoreId);
}
myUpdateRunnableFuture.cancel(false);
final DaemonProgressIndicator progress = createUpdateProgress();
myPassExecutorService.submitPasses(map, progress);
try {
long start = System.currentTimeMillis();
while (progress.isRunning() && System.currentTimeMillis() < start + 5 * 60 * 1000) {
wrap(() -> {
progress.checkCanceled();
if (callbackWhileWaiting != null) {
callbackWhileWaiting.run();
}
waitInOtherThread(50, canChangeDocument);
UIUtil.dispatchAllInvocationEvents();
Throwable savedException = PassExecutorService.getSavedException(progress);
if (savedException != null)
throw savedException;
});
}
if (progress.isRunning() && !progress.isCanceled()) {
throw new RuntimeException("Highlighting still running after " + (System.currentTimeMillis() - start) / 1000 + " seconds.\n" + ThreadDumper.dumpThreadsToString());
}
final HighlightingSessionImpl session = (HighlightingSessionImpl) HighlightingSessionImpl.getOrCreateHighlightingSession(file, textEditors.get(0).getEditor(), progress, null);
wrap(() -> {
if (!waitInOtherThread(60000, canChangeDocument)) {
throw new TimeoutException("Unable to complete in 60s");
}
session.waitForHighlightInfosApplied();
});
UIUtil.dispatchAllInvocationEvents();
UIUtil.dispatchAllInvocationEvents();
assert progress.isCanceled() && progress.isDisposed();
return getHighlights(document, null, project);
} finally {
DaemonProgressIndicator.setDebug(false);
fileStatusMap.allowDirt(true);
waitForTermination();
}
}
use of com.intellij.codeHighlighting.HighlightingPass in project intellij-community by JetBrains.
the class PassExecutorService method submitPasses.
void submitPasses(@NotNull Map<FileEditor, HighlightingPass[]> passesMap, @NotNull DaemonProgressIndicator updateProgress) {
if (isDisposed())
return;
// null keys are ok
MultiMap<Document, FileEditor> documentToEditors = MultiMap.createSet();
MultiMap<FileEditor, TextEditorHighlightingPass> documentBoundPasses = MultiMap.createSmart();
MultiMap<FileEditor, EditorBoundHighlightingPass> editorBoundPasses = MultiMap.createSmart();
List<Pair<FileEditor, TextEditorHighlightingPass>> passesWithNoDocuments = new ArrayList<>();
Set<VirtualFile> vFiles = new HashSet<>();
for (Map.Entry<FileEditor, HighlightingPass[]> entry : passesMap.entrySet()) {
FileEditor fileEditor = entry.getKey();
HighlightingPass[] passes = entry.getValue();
Document document;
if (fileEditor instanceof TextEditor) {
Editor editor = ((TextEditor) fileEditor).getEditor();
LOG.assertTrue(!(editor instanceof EditorWindow));
document = editor.getDocument();
} else {
VirtualFile virtualFile = ((FileEditorManagerEx) FileEditorManager.getInstance(myProject)).getFile(fileEditor);
document = virtualFile == null ? null : FileDocumentManager.getInstance().getDocument(virtualFile);
}
if (document != null) {
vFiles.add(FileDocumentManager.getInstance().getFile(document));
}
int prevId = 0;
for (final HighlightingPass pass : passes) {
if (pass instanceof EditorBoundHighlightingPass) {
EditorBoundHighlightingPass editorPass = (EditorBoundHighlightingPass) pass;
// have to make ids unique for this document
editorPass.setId(nextPassId.incrementAndGet());
editorBoundPasses.putValue(fileEditor, editorPass);
} else {
TextEditorHighlightingPass textEditorHighlightingPass = convertToTextHighlightingPass(pass, document, nextPassId, prevId);
document = textEditorHighlightingPass.getDocument();
documentBoundPasses.putValue(fileEditor, textEditorHighlightingPass);
if (document == null) {
passesWithNoDocuments.add(Pair.create(fileEditor, textEditorHighlightingPass));
} else {
documentToEditors.putValue(document, fileEditor);
}
prevId = textEditorHighlightingPass.getId();
}
}
}
List<ScheduledPass> freePasses = new ArrayList<>(documentToEditors.size() * 5);
List<ScheduledPass> dependentPasses = new ArrayList<>(documentToEditors.size() * 10);
// (fileEditor, passId) -> created pass
Map<Pair<FileEditor, Integer>, ScheduledPass> toBeSubmitted = new THashMap<>(passesMap.size());
final AtomicInteger threadsToStartCountdown = new AtomicInteger(0);
for (Map.Entry<Document, Collection<FileEditor>> entry : documentToEditors.entrySet()) {
Collection<FileEditor> fileEditors = entry.getValue();
Document document = entry.getKey();
FileEditor preferredFileEditor = getPreferredFileEditor(document, fileEditors);
List<TextEditorHighlightingPass> passes = (List<TextEditorHighlightingPass>) documentBoundPasses.get(preferredFileEditor);
if (passes.isEmpty()) {
continue;
}
sortById(passes);
for (TextEditorHighlightingPass currentPass : passes) {
createScheduledPass(preferredFileEditor, currentPass, toBeSubmitted, passes, freePasses, dependentPasses, updateProgress, threadsToStartCountdown);
}
}
for (Map.Entry<FileEditor, Collection<EditorBoundHighlightingPass>> entry : editorBoundPasses.entrySet()) {
FileEditor fileEditor = entry.getKey();
Collection<EditorBoundHighlightingPass> createdEditorBoundPasses = entry.getValue();
List<TextEditorHighlightingPass> createdDocumentBoundPasses = (List<TextEditorHighlightingPass>) documentBoundPasses.get(fileEditor);
List<TextEditorHighlightingPass> allCreatedPasses = new ArrayList<>(createdDocumentBoundPasses);
allCreatedPasses.addAll(createdEditorBoundPasses);
for (EditorBoundHighlightingPass pass : createdEditorBoundPasses) {
createScheduledPass(fileEditor, pass, toBeSubmitted, allCreatedPasses, freePasses, dependentPasses, updateProgress, threadsToStartCountdown);
}
}
for (Pair<FileEditor, TextEditorHighlightingPass> pair : passesWithNoDocuments) {
FileEditor fileEditor = pair.first;
TextEditorHighlightingPass pass = pair.second;
createScheduledPass(fileEditor, pass, toBeSubmitted, ContainerUtil.emptyList(), freePasses, dependentPasses, updateProgress, threadsToStartCountdown);
}
if (CHECK_CONSISTENCY && !ApplicationInfoImpl.isInStressTest()) {
assertConsistency(freePasses, toBeSubmitted, threadsToStartCountdown);
}
log(updateProgress, null, vFiles + " ----- starting " + threadsToStartCountdown.get(), freePasses);
for (ScheduledPass dependentPass : dependentPasses) {
mySubmittedPasses.put(dependentPass, Job.NULL_JOB);
}
for (ScheduledPass freePass : freePasses) {
submit(freePass);
}
}
Aggregations