diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/impl/DaemonRespondToChangesTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/impl/DaemonRespondToChangesTest.java index 3e502deada9b..0267b9bbc2ce 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/impl/DaemonRespondToChangesTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/impl/DaemonRespondToChangesTest.java @@ -2719,8 +2719,17 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase { public void testAddAnnotationToHolderEntailsCreatingCorrespondingRangeHighlighterMoreOrLessImmediately() { ensureEnoughParallelism(); useAnnotatorsIn(JavaFileType.INSTANCE.getLanguage(), new MyRecordingAnnotator[]{new MyInfoAnnotator(), new MySleepyAnnotator(), new MyFastAnnotator(), }, this::checkSwearingAnnotationIsVisibleImmediately); + } + public void testAddAnnotationToHolderEntailsCreatingCorrespondingRangeHighlighterMoreOrLessImmediately1() { + ensureEnoughParallelism(); useAnnotatorsIn(JavaFileType.INSTANCE.getLanguage(), new MyRecordingAnnotator[]{new MySleepyAnnotator(), new MyInfoAnnotator(), new MyFastAnnotator(), }, this::checkSwearingAnnotationIsVisibleImmediately); + } + public void testAddAnnotationToHolderEntailsCreatingCorrespondingRangeHighlighterMoreOrLessImmediately2() { + ensureEnoughParallelism(); useAnnotatorsIn(JavaFileType.INSTANCE.getLanguage(), new MyRecordingAnnotator[]{new MySleepyAnnotator(), new MyFastAnnotator(), new MyInfoAnnotator(), }, this::checkSwearingAnnotationIsVisibleImmediately); + } + public void testAddAnnotationToHolderEntailsCreatingCorrespondingRangeHighlighterMoreOrLessImmediately3() { + ensureEnoughParallelism(); // also check in the opposite order in case the order of annotators is important useAnnotatorsIn(JavaFileType.INSTANCE.getLanguage(), new MyRecordingAnnotator[]{new MyFastAnnotator(), new MyInfoAnnotator(), new MySleepyAnnotator(), }, this::checkSwearingAnnotationIsVisibleImmediately); } @@ -2841,7 +2850,7 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase { } private static void ensureEnoughParallelism() { - if (ForkJoinPool.commonPool().getParallelism() <= 2) { + if (ForkJoinPool.commonPool().getParallelism() <= 3) { throw new AssumptionViolatedException("Too low parallelism, I will not even bother, it's hopeless: " + ForkJoinPool.commonPool().getParallelism()); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java index d7124b157e27..dbbe84008256 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java @@ -41,6 +41,7 @@ import com.intellij.openapi.fileTypes.impl.FileTypeManagerImpl; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.impl.CoreProgressManager; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.DumbServiceImpl; import com.intellij.openapi.project.Project; @@ -375,55 +376,66 @@ public final class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implement fileStatusMap.markFileUpToDate(document, ignoreId); } - HighlightingSession session = queuePassesCreation(textEditors, passesToIgnore); + ((CoreProgressManager)ProgressManager.getInstance()).suppressAllDeprioritizationsDuringLongTestsExecutionIn(() -> { + HighlightingSession session = queuePassesCreation(textEditors, passesToIgnore); - DaemonProgressIndicator progress = getUpdateProgress(); - // there can be PCE in FJP during queuePassesCreation - // no PCE guarantees session is not null - progress.checkCanceled(); + DaemonProgressIndicator progress = getUpdateProgress(); + // there can be PCE in FJP during queuePassesCreation + // no PCE guarantees session is not null + progress.checkCanceled(); - try { - long start = System.currentTimeMillis(); - while (progress.isRunning() && System.currentTimeMillis() < start + 10*60*1000) { - progress.checkCanceled(); - if (callbackWhileWaiting != null) { - callbackWhileWaiting.run(); + try { + long start = System.currentTimeMillis(); + while (progress.isRunning() && System.currentTimeMillis() < start + 10 * 60 * 1000) { + progress.checkCanceled(); + if (callbackWhileWaiting != null) { + callbackWhileWaiting.run(); + } + waitInOtherThread(50, canChangeDocument); + EDT.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." + + " Still submitted passes: " + + myPassExecutorService.getAllSubmittedPasses() + + " ForkJoinPool.commonPool(): " + + ForkJoinPool.commonPool() + + "\n" + + ", ForkJoinPool.commonPool() active thread count: " + + ForkJoinPool.commonPool().getActiveThreadCount() + + ", ForkJoinPool.commonPool() has queued submissions: " + + ForkJoinPool.commonPool().hasQueuedSubmissions() + + "\n" + + ThreadDumper.dumpThreadsToString()); } - waitInOtherThread(50, canChangeDocument); - EDT.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." + - " Still submitted passes: "+myPassExecutorService.getAllSubmittedPasses()+ - " ForkJoinPool.commonPool(): "+ForkJoinPool.commonPool()+"\n"+ - ", ForkJoinPool.commonPool() active thread count: "+ ForkJoinPool.commonPool().getActiveThreadCount()+ - ", ForkJoinPool.commonPool() has queued submissions: "+ ForkJoinPool.commonPool().hasQueuedSubmissions()+ - "\n"+ ThreadDumper.dumpThreadsToString()); - } - if (!waitInOtherThread(60000, canChangeDocument)) { - throw new TimeoutException("Unable to complete in 60s. Thread dump:\n"+ThreadDumper.dumpThreadsToString()); + if (!waitInOtherThread(60000, canChangeDocument)) { + throw new TimeoutException("Unable to complete in 60s. Thread dump:\n" + ThreadDumper.dumpThreadsToString()); + } + ((HighlightingSessionImpl)session).waitForHighlightInfosApplied(); + EDT.dispatchAllInvocationEvents(); + EDT.dispatchAllInvocationEvents(); + assert progress.isCanceled() && progress.isDisposed(); } - ((HighlightingSessionImpl)session).waitForHighlightInfosApplied(); - EDT.dispatchAllInvocationEvents(); - EDT.dispatchAllInvocationEvents(); - assert progress.isCanceled() && progress.isDisposed(); - } - catch (Throwable e) { - Throwable unwrapped = ExceptionUtilRt.unwrapException(e, ExecutionException.class); - if (progress.isCanceled() && progress.isRunning()) { - unwrapped.addSuppressed(new RuntimeException("Daemon progress was canceled unexpectedly: " + progress)); + catch (Throwable e) { + Throwable unwrapped = ExceptionUtilRt.unwrapException(e, ExecutionException.class); + if (progress.isCanceled() && progress.isRunning()) { + unwrapped.addSuppressed(new RuntimeException("Daemon progress was canceled unexpectedly: " + progress)); + } + ExceptionUtil.rethrow(unwrapped); } - ExceptionUtil.rethrow(unwrapped); - } - finally { - DaemonProgressIndicator.setDebug(false); - fileStatusMap.allowDirt(true); - progress.cancel(); - waitForTermination(); - } + finally { + DaemonProgressIndicator.setDebug(false); + fileStatusMap.allowDirt(true); + progress.cancel(); + waitForTermination(); + } + return null; + }); } @TestOnly diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 77138cfe4a28..fc0fae47659e 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -84,8 +84,6 @@ import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.progress.ProcessCanceledException; -import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.progress.impl.CoreProgressManager; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootManager; @@ -259,50 +257,48 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig DaemonCodeAnalyzerSettings settings = DaemonCodeAnalyzerSettings.getInstance(); ProjectInspectionProfileManager.getInstance(project); // avoid "severities changed, restart" event - return ((CoreProgressManager)ProgressManager.getInstance()).suppressAllDeprioritizationsDuringLongTestsExecutionIn(() -> { - ProcessCanceledException exception = null; - int retries = 1000; - for (int i = 0; i < retries; i++) { - int oldDelay = settings.getAutoReparseDelay(); - try { - settings.setAutoReparseDelay(0); - List infos = new ArrayList<>(); - EdtTestUtil.runInEdtAndWait(() -> { - codeAnalyzer.runPasses(file, editor.getDocument(), Collections.singletonList(textEditor), toIgnore, canChangeDocument, null); - IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current(); - if (policy != null) { - policy.waitForHighlighting(project, editor); - } - IdentifierHighlighterPassFactory.waitForIdentifierHighlighting(); - infos.addAll(DaemonCodeAnalyzerImpl.getHighlights(editor.getDocument(), null, project)); - if (readEditorMarkupModel) { - MarkupModelEx markupModel = (MarkupModelEx)editor.getMarkupModel(); - DaemonCodeAnalyzerEx.processHighlights(markupModel, project, null, 0, editor.getDocument().getTextLength(), - Processors.cancelableCollectProcessor(infos)); - } - }); - infos.addAll(DaemonCodeAnalyzerEx.getInstanceEx(project).getFileLevelHighlights(project, file)); - return infos; - } - catch (ProcessCanceledException e) { - Throwable cause = e.getCause(); - if (cause != null && cause.getClass() != Throwable.class) { - // canceled because of an exception, no need to repeat the same - throw e; + ProcessCanceledException exception = null; + int retries = 1000; + for (int i = 0; i < retries; i++) { + int oldDelay = settings.getAutoReparseDelay(); + try { + settings.setAutoReparseDelay(0); + List infos = new ArrayList<>(); + EdtTestUtil.runInEdtAndWait(() -> { + codeAnalyzer.runPasses(file, editor.getDocument(), Collections.singletonList(textEditor), toIgnore, canChangeDocument, null); + IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current(); + if (policy != null) { + policy.waitForHighlighting(project, editor); } - - EdtTestUtil.runInEdtAndWait(() -> { - PsiDocumentManager.getInstance(project).commitAllDocuments(); - UIUtil.dispatchAllInvocationEvents(); - }); - exception = e; - } - finally { - settings.setAutoReparseDelay(oldDelay); - } + IdentifierHighlighterPassFactory.waitForIdentifierHighlighting(); + infos.addAll(DaemonCodeAnalyzerImpl.getHighlights(editor.getDocument(), null, project)); + if (readEditorMarkupModel) { + MarkupModelEx markupModel = (MarkupModelEx)editor.getMarkupModel(); + DaemonCodeAnalyzerEx.processHighlights(markupModel, project, null, 0, editor.getDocument().getTextLength(), + Processors.cancelableCollectProcessor(infos)); + } + }); + infos.addAll(DaemonCodeAnalyzerEx.getInstanceEx(project).getFileLevelHighlights(project, file)); + return infos; } - throw new AssertionError("Unable to highlight after " + retries + " retries", exception); - }); + catch (ProcessCanceledException e) { + Throwable cause = e.getCause(); + if (cause != null && cause.getClass() != Throwable.class) { + // canceled because of an exception, no need to repeat the same + throw e; + } + + EdtTestUtil.runInEdtAndWait(() -> { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + UIUtil.dispatchAllInvocationEvents(); + }); + exception = e; + } + finally { + settings.setAutoReparseDelay(oldDelay); + } + } + throw new AssertionError("Unable to highlight after " + retries + " retries", exception); } public static void ensureIndexesUpToDate(@NotNull Project project) {