Search in sources :

Example 1 with TextEditorHighlightingPass

use of com.intellij.codeHighlighting.TextEditorHighlightingPass 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();
    }
}
Also used : FileEditor(com.intellij.openapi.fileEditor.FileEditor) THashMap(gnu.trove.THashMap) FileTypeManagerImpl(com.intellij.openapi.fileTypes.impl.FileTypeManagerImpl) HighlightingPass(com.intellij.codeHighlighting.HighlightingPass) TextEditorHighlightingPass(com.intellij.codeHighlighting.TextEditorHighlightingPass) TextEditorHighlightingPass(com.intellij.codeHighlighting.TextEditorHighlightingPass) Project(com.intellij.openapi.project.Project) TextEditor(com.intellij.openapi.fileEditor.TextEditor) ApplicationEx(com.intellij.openapi.application.ex.ApplicationEx) TextEditorImpl(com.intellij.openapi.fileEditor.impl.text.TextEditorImpl) TextEditor(com.intellij.openapi.fileEditor.TextEditor) FileEditor(com.intellij.openapi.fileEditor.FileEditor) Editor(com.intellij.openapi.editor.Editor) TestOnly(org.jetbrains.annotations.TestOnly) NotNull(org.jetbrains.annotations.NotNull)

Example 2 with TextEditorHighlightingPass

use of com.intellij.codeHighlighting.TextEditorHighlightingPass in project intellij-community by JetBrains.

the class DaemonCodeAnalyzerImpl method runMainPasses.

@Override
@NotNull
public List<HighlightInfo> runMainPasses(@NotNull PsiFile psiFile, @NotNull Document document, @NotNull final ProgressIndicator progress) {
    if (ApplicationManager.getApplication().isDispatchThread()) {
        throw new IllegalStateException("Must not run highlighting from under EDT");
    }
    if (!ApplicationManager.getApplication().isReadAccessAllowed()) {
        throw new IllegalStateException("Must run highlighting from under read action");
    }
    ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
    if (!(indicator instanceof DaemonProgressIndicator)) {
        throw new IllegalStateException("Must run highlighting under progress with DaemonProgressIndicator");
    }
    // clear status maps to run passes from scratch so that refCountHolder won't conflict and try to restart itself on partially filled maps
    myFileStatusMap.markAllFilesDirty("prepare to run main passes");
    stopProcess(false, "disable background daemon");
    myPassExecutorService.cancelAll(true);
    final List<HighlightInfo> result;
    try {
        result = new ArrayList<>();
        final VirtualFile virtualFile = psiFile.getVirtualFile();
        if (virtualFile != null && !virtualFile.getFileType().isBinary()) {
            List<TextEditorHighlightingPass> passes = TextEditorHighlightingPassRegistrarEx.getInstanceEx(myProject).instantiateMainPasses(psiFile, document, HighlightInfoProcessor.getEmpty());
            Collections.sort(passes, (o1, o2) -> {
                if (o1 instanceof GeneralHighlightingPass)
                    return -1;
                if (o2 instanceof GeneralHighlightingPass)
                    return 1;
                return 0;
            });
            try {
                for (TextEditorHighlightingPass pass : passes) {
                    pass.doCollectInformation(progress);
                    result.addAll(pass.getInfos());
                }
            } catch (ProcessCanceledException e) {
                LOG.debug("Canceled: " + progress);
                throw e;
            }
        }
    } finally {
        stopProcess(true, "re-enable background daemon after main passes run");
    }
    return result;
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) TextEditorHighlightingPass(com.intellij.codeHighlighting.TextEditorHighlightingPass) ProgressIndicator(com.intellij.openapi.progress.ProgressIndicator) ProcessCanceledException(com.intellij.openapi.progress.ProcessCanceledException) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with TextEditorHighlightingPass

use of com.intellij.codeHighlighting.TextEditorHighlightingPass in project intellij-community by JetBrains.

the class PassExecutorService method findOrCreatePredecessorPass.

private ScheduledPass findOrCreatePredecessorPass(@NotNull FileEditor fileEditor, @NotNull Map<Pair<FileEditor, Integer>, ScheduledPass> toBeSubmitted, @NotNull List<TextEditorHighlightingPass> textEditorHighlightingPasses, @NotNull List<ScheduledPass> freePasses, @NotNull List<ScheduledPass> dependentPasses, @NotNull DaemonProgressIndicator updateProgress, @NotNull AtomicInteger myThreadsToStartCountdown, final int predecessorId) {
    Pair<FileEditor, Integer> predKey = Pair.create(fileEditor, predecessorId);
    ScheduledPass predecessor = toBeSubmitted.get(predKey);
    if (predecessor == null) {
        TextEditorHighlightingPass textEditorPass = findPassById(predecessorId, textEditorHighlightingPasses);
        predecessor = textEditorPass == null ? null : createScheduledPass(fileEditor, textEditorPass, toBeSubmitted, textEditorHighlightingPasses, freePasses, dependentPasses, updateProgress, myThreadsToStartCountdown);
    }
    return predecessor;
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TextEditorHighlightingPass(com.intellij.codeHighlighting.TextEditorHighlightingPass) FileEditor(com.intellij.openapi.fileEditor.FileEditor)

Example 4 with TextEditorHighlightingPass

use of com.intellij.codeHighlighting.TextEditorHighlightingPass in project intellij-community by JetBrains.

the class TrafficLightRenderer method getDaemonCodeAnalyzerStatus.

@NotNull
protected DaemonCodeAnalyzerStatus getDaemonCodeAnalyzerStatus(@NotNull SeverityRegistrar severityRegistrar) {
    DaemonCodeAnalyzerStatus status = new DaemonCodeAnalyzerStatus();
    if (myFile == null) {
        status.reasonWhyDisabled = "No file";
        status.errorAnalyzingFinished = true;
        return status;
    }
    if (myProject != null && myProject.isDisposed()) {
        status.reasonWhyDisabled = "Project is disposed";
        status.errorAnalyzingFinished = true;
        return status;
    }
    if (!myDaemonCodeAnalyzer.isHighlightingAvailable(myFile)) {
        if (!myFile.isPhysical()) {
            status.reasonWhyDisabled = "File is generated";
            status.errorAnalyzingFinished = true;
            return status;
        } else if (myFile instanceof PsiCompiledElement) {
            status.reasonWhyDisabled = "File is decompiled";
            status.errorAnalyzingFinished = true;
            return status;
        }
        final FileType fileType = myFile.getFileType();
        if (fileType.isBinary()) {
            status.reasonWhyDisabled = "File is binary";
            status.errorAnalyzingFinished = true;
            return status;
        }
        status.reasonWhyDisabled = "Highlighting is disabled for this file";
        status.errorAnalyzingFinished = true;
        return status;
    }
    FileViewProvider provider = myFile.getViewProvider();
    Set<Language> languages = provider.getLanguages();
    HighlightingSettingsPerFile levelSettings = HighlightingSettingsPerFile.getInstance(myProject);
    boolean shouldHighlight = languages.isEmpty();
    for (Language language : languages) {
        PsiFile root = provider.getPsi(language);
        FileHighlightingSetting level = levelSettings.getHighlightingSettingForRoot(root);
        shouldHighlight |= level != FileHighlightingSetting.SKIP_HIGHLIGHTING;
    }
    if (!shouldHighlight) {
        status.reasonWhyDisabled = "Highlighting level is None";
        status.errorAnalyzingFinished = true;
        return status;
    }
    if (HeavyProcessLatch.INSTANCE.isRunning()) {
        status.reasonWhySuspended = StringUtil.defaultIfEmpty(HeavyProcessLatch.INSTANCE.getRunningOperationName(), "Heavy operation is running");
        status.errorAnalyzingFinished = true;
        return status;
    }
    status.errorCount = errorCount.clone();
    List<TextEditorHighlightingPass> passes = myDaemonCodeAnalyzer.getPassesToShowProgressFor(myDocument);
    status.passStati = passes.isEmpty() ? Collections.emptyList() : new ArrayList<>(passes.size());
    //noinspection ForLoopReplaceableByForEach
    for (int i = 0; i < passes.size(); i++) {
        TextEditorHighlightingPass tepass = passes.get(i);
        if (!(tepass instanceof ProgressableTextEditorHighlightingPass))
            continue;
        ProgressableTextEditorHighlightingPass pass = (ProgressableTextEditorHighlightingPass) tepass;
        if (pass.getProgress() < 0)
            continue;
        status.passStati.add(pass);
    }
    status.errorAnalyzingFinished = myDaemonCodeAnalyzer.isAllAnalysisFinished(myFile);
    status.reasonWhySuspended = myDaemonCodeAnalyzer.isUpdateByTimerEnabled() ? null : "Highlighting is paused temporarily";
    fillDaemonCodeAnalyzerErrorsStatus(status, severityRegistrar);
    return status;
}
Also used : HighlightingSettingsPerFile(com.intellij.codeInsight.daemon.impl.analysis.HighlightingSettingsPerFile) TIntArrayList(gnu.trove.TIntArrayList) PsiCompiledElement(com.intellij.psi.PsiCompiledElement) FileHighlightingSetting(com.intellij.codeInsight.daemon.impl.analysis.FileHighlightingSetting) TextEditorHighlightingPass(com.intellij.codeHighlighting.TextEditorHighlightingPass) FileViewProvider(com.intellij.psi.FileViewProvider) Language(com.intellij.lang.Language) FileType(com.intellij.openapi.fileTypes.FileType) PsiFile(com.intellij.psi.PsiFile) NotNull(org.jetbrains.annotations.NotNull)

Example 5 with TextEditorHighlightingPass

use of com.intellij.codeHighlighting.TextEditorHighlightingPass in project intellij-community by JetBrains.

the class DaemonCodeAnalyzerImpl method getPassesToShowProgressFor.

@NotNull
List<TextEditorHighlightingPass> getPassesToShowProgressFor(Document document) {
    List<TextEditorHighlightingPass> allPasses = myPassExecutorService.getAllSubmittedPasses();
    List<TextEditorHighlightingPass> result = new ArrayList<>(allPasses.size());
    for (TextEditorHighlightingPass pass : allPasses) {
        if (pass.getDocument() == document || pass.getDocument() == null) {
            result.add(pass);
        }
    }
    return result;
}
Also used : TextEditorHighlightingPass(com.intellij.codeHighlighting.TextEditorHighlightingPass) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

TextEditorHighlightingPass (com.intellij.codeHighlighting.TextEditorHighlightingPass)8 NotNull (org.jetbrains.annotations.NotNull)6 FileEditor (com.intellij.openapi.fileEditor.FileEditor)3 HighlightingPass (com.intellij.codeHighlighting.HighlightingPass)2 Editor (com.intellij.openapi.editor.Editor)2 TextEditor (com.intellij.openapi.fileEditor.TextEditor)2 ProgressIndicator (com.intellij.openapi.progress.ProgressIndicator)2 VirtualFile (com.intellij.openapi.vfs.VirtualFile)2 THashMap (gnu.trove.THashMap)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 EditorBoundHighlightingPass (com.intellij.codeHighlighting.EditorBoundHighlightingPass)1 TextEditorHighlightingPassRegistrarEx (com.intellij.codeInsight.daemon.impl.TextEditorHighlightingPassRegistrarEx)1 FileHighlightingSetting (com.intellij.codeInsight.daemon.impl.analysis.FileHighlightingSetting)1 HighlightingSettingsPerFile (com.intellij.codeInsight.daemon.impl.analysis.HighlightingSettingsPerFile)1 EditorWindow (com.intellij.injected.editor.EditorWindow)1 Language (com.intellij.lang.Language)1 ApplicationEx (com.intellij.openapi.application.ex.ApplicationEx)1 Document (com.intellij.openapi.editor.Document)1 FileEditorManagerEx (com.intellij.openapi.fileEditor.ex.FileEditorManagerEx)1 TextEditorImpl (com.intellij.openapi.fileEditor.impl.text.TextEditorImpl)1