[daemon] IJPL-206895 Autoreparse delay is set to 0 without a user action

(cherry picked from commit ee112910b742836ee4dba68b43b5b5b3ad6c1d14)
IJ-CR-176136

GitOrigin-RevId: 11b7b4bfaeb7d95bd548ccbeaa25c12957e37e5d
This commit is contained in:
Yuriy Artamonov
2025-09-17 10:15:26 +02:00
committed by intellij-monorepo-bot
parent a16ad506d8
commit 13b2ac3ef8
10 changed files with 91 additions and 9 deletions

View File

@@ -19,6 +19,8 @@ com.intellij.codeInsight.completion.CompletionLookupArranger
- a:addElement(com.intellij.codeInsight.lookup.LookupElement,com.intellij.codeInsight.completion.CompletionSorter,com.intellij.codeInsight.completion.PrefixMatcher,com.intellij.codeInsight.lookup.LookupElementPresentation):V
- a:arrangeItems():com.intellij.openapi.util.Pair
- a:itemMatcher(com.intellij.codeInsight.lookup.LookupElement):com.intellij.codeInsight.completion.PrefixMatcher
c:com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings
- sf:AUTOREPARSE_DELAY_DEFAULT:I
com.intellij.codeInsight.daemon.ReferenceImporter
- sf:EP_NAME:com.intellij.openapi.extensions.ExtensionPointName
- autoImportReferenceAtCursor(com.intellij.openapi.editor.Editor,com.intellij.psi.PsiFile):Z

View File

@@ -4,15 +4,21 @@ package com.intellij.codeInsight.daemon;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.util.xmlb.annotations.OptionTag;
import com.intellij.util.xmlb.annotations.Transient;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NonNls;
public class DaemonCodeAnalyzerSettings {
public static final int AUTOREPARSE_DELAY_DEFAULT = 300;
private boolean myNextErrorActionGoesToErrorsFirst = true;
private int myAutoReparseDelay = 300;
private int myAutoReparseDelay = AUTOREPARSE_DELAY_DEFAULT;
private int myErrorStripeMarkMinHeight = 2;
private boolean mySuppressWarnings = true;
@Transient
private volatile boolean myForceZeroAutoReparseDelay = false;
public static DaemonCodeAnalyzerSettings getInstance() {
return ApplicationManager.getApplication().getService(DaemonCodeAnalyzerSettings.class);
}
@@ -36,6 +42,19 @@ public class DaemonCodeAnalyzerSettings {
myAutoReparseDelay = millis;
}
@ApiStatus.Internal
public void forceUseZeroAutoReparseDelay(boolean useZeroAutoReparseDelay) {
myForceZeroAutoReparseDelay = useZeroAutoReparseDelay;
}
@Transient
@ApiStatus.Internal
public int getEffectiveAutoReparseDelay() {
if (myForceZeroAutoReparseDelay) return 0;
return myAutoReparseDelay;
}
@OptionTag("ERROR_STRIPE_MARK_MIN_HEIGHT")
public int getErrorStripeMarkMinHeight() {
return myErrorStripeMarkMinHeight;

View File

@@ -105,6 +105,7 @@ com.intellij.ide.wizard.Step
com.intellij.ide.wizard.StepListener
- java.util.EventListener
- a:stateChanged():V
c:com.intellij.notification.Notification
com.intellij.notification.NotificationGroupManager
- s:getInstance():com.intellij.notification.NotificationGroupManager
- a:getNotificationGroup(java.lang.String):com.intellij.notification.NotificationGroup

View File

@@ -622,3 +622,6 @@ language.services.service.stopped.notification.content=The service will restart
unscramble.progress.title.analyzing.stacktrace=Analyzing stacktrace\u2026
tooltip.unable.to.proceed.document.was.changed=Unable to proceed: document was changed
shared.target.presentation.label=[shared]
notification.content.editor.autoreparse.delay.has.been.restored=Editor autoreparse delay has been restored to the default value {0}ms. 0 value is associated with potential UI freezes and not recommended.
action.open.settings.text=Open Settings

View File

@@ -982,7 +982,7 @@ public final class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx
* reset {@link #myScheduledUpdateTimestamp} always, but re-schedule {@link #myUpdateRunnable} only rarely because of thread scheduling overhead
*/
private synchronized void scheduleIfNotRunning() {
long autoReparseDelayNanos = TimeUnit.MILLISECONDS.toNanos(mySettings.getAutoReparseDelay());
long autoReparseDelayNanos = TimeUnit.MILLISECONDS.toNanos(mySettings.getEffectiveAutoReparseDelay());
myScheduledUpdateTimestamp = System.nanoTime() + autoReparseDelayNanos;
// optimisation: this check is to avoid too many re-schedules in case of thousands of event spikes
boolean isDone = myUpdateRunnableFuture.isDone();

View File

@@ -206,10 +206,9 @@ public final class MainPassesRunner {
// repeat several times when accidental background activity cancels highlighting
int retries = 100;
for (int i = 0; i < retries; i++) {
int oldDelay = settings.getAutoReparseDelay();
try {
InspectionProfile currentProfile = myInspectionProfile;
settings.setAutoReparseDelay(0);
settings.forceUseZeroAutoReparseDelay(true);
Function<InspectionProfile, InspectionProfileWrapper> profileProvider =
p -> currentProfile == null
? new InspectionProfileWrapper((InspectionProfileImpl)p)
@@ -230,7 +229,7 @@ public final class MainPassesRunner {
exception = e;
}
finally {
settings.setAutoReparseDelay(oldDelay);
settings.forceUseZeroAutoReparseDelay(false);
}
}
if (exception != null) {

View File

@@ -0,0 +1,58 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings.AUTOREPARSE_DELAY_DEFAULT
import com.intellij.ide.actions.ShowSettingsUtilImpl
import com.intellij.ide.util.runOnceForApp
import com.intellij.lang.LangBundle
import com.intellij.notification.NotificationAction
import com.intellij.notification.NotificationGroupManager
import com.intellij.notification.NotificationType
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.backgroundWriteAction
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.openapi.extensions.ExtensionNotApplicableException
import com.intellij.openapi.options.ShowSettingsUtil
import com.intellij.openapi.options.ex.ConfigurableVisitor
import com.intellij.openapi.project.Project
import com.intellij.openapi.startup.ProjectActivity
internal class ResetAutoReparseSettingsActivity : ProjectActivity {
init {
val app = ApplicationManager.getApplication()
if (app.isUnitTestMode || app.isHeadlessEnvironment || app.isCommandLine) {
throw ExtensionNotApplicableException.create()
}
}
override suspend fun execute(project: Project) {
runOnceForApp("reset.auto.reparse.settings.to.default") {
val didChange = backgroundWriteAction {
val settings = DaemonCodeAnalyzerSettings.getInstance()
if (settings.autoReparseDelay == 0) {
settings.autoReparseDelay = AUTOREPARSE_DELAY_DEFAULT
thisLogger().info("Setting AUTOREPARSE_DELAY default value as suspicious value 0 was stored in settings")
return@backgroundWriteAction true
}
false
}
if (didChange) {
val notification = NotificationGroupManager.getInstance().getNotificationGroup("System Messages")
.createNotification(LangBundle.message("notification.content.editor.autoreparse.delay.has.been.restored", AUTOREPARSE_DELAY_DEFAULT),
NotificationType.INFORMATION)
notification.setDisplayId("reset.auto.reparse.settings.to.default")
notification.setSuppressShowingPopup(true)
notification.addAction(NotificationAction.create(LangBundle.message("action.open.settings.text")) {
val groups = ShowSettingsUtilImpl.getConfigurableGroups(project, withIdeSettings = true)
val configurable = ConfigurableVisitor.findById("preferences.editor.code.editing", groups.toList())
ShowSettingsUtil.getInstance().showSettingsDialog(project, configurable)
})
notification.notify(project)
}
}
}
}

View File

@@ -1537,7 +1537,7 @@
<notificationGroup id="Test Hidden Notification" displayType="NONE" hideFromSettings="true"/>
<notificationGroup id="Test Notification" displayType="BALLOON" hideFromSettings="true"/>
<notificationGroup id="System Messages" displayType="BALLOON" bundle="messages.IdeBundle" key="notification.group.system.messages"
notificationIds="cloud.config.alert;glibc.incompatible"/>
notificationIds="cloud.config.alert;glibc.incompatible;reset.auto.reparse.settings.to.default"/>
<notificationGroup id="Merge Internal Error" displayType="BALLOON" hideFromSettings="true"/>
<notificationGroup id="Diff Changes Loading Error" displayType="BALLOON" hideFromSettings="true"/>
<notificationGroup id="System shortcuts conflicts" displayType="STICKY_BALLOON" bundle="messages.KeyMapBundle"

View File

@@ -31,6 +31,7 @@
serviceImplementation="com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl"
/>
<postStartupActivity implementation="com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerStatusBarUpdater"/>
<backgroundPostStartupActivity implementation="com.intellij.codeInsight.daemon.impl.ResetAutoReparseSettingsActivity"/>
<vfs.asyncListener implementation="com.intellij.workspaceModel.ide.impl.WorkspaceModelRootWatcher"/>
<projectService

View File

@@ -297,9 +297,8 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
Throwable exception = null;
int retries = 1000;
for (int i = 0; i < retries; i++) {
int oldDelay = settings.getAutoReparseDelay();
try {
settings.setAutoReparseDelay(0);
settings.forceUseZeroAutoReparseDelay(true);
List<HighlightInfo> infos = new ArrayList<>();
EdtTestUtil.runInEdtAndWait(() -> {
PsiFile file = filePointer.getElement();
@@ -345,7 +344,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
exception = e;
}
finally {
settings.setAutoReparseDelay(oldDelay);
settings.forceUseZeroAutoReparseDelay(false);
}
}
ExceptionUtil.rethrow(exception);