diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/AlternativeSourceNotificationProvider.java b/java/debugger/impl/src/com/intellij/debugger/ui/AlternativeSourceNotificationProvider.java
index 5f42a4ab3f61..fb1fbea42811 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/AlternativeSourceNotificationProvider.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/AlternativeSourceNotificationProvider.java
@@ -1,4 +1,4 @@
-// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.debugger.ui;
import com.intellij.debugger.DebuggerManagerEx;
@@ -44,14 +44,14 @@ public final class AlternativeSourceNotificationProvider implements EditorNotifi
private static final Key FILE_PROCESSED_KEY = Key.create("AlternativeSourceCheckDone");
@Override
- public @NotNull Function super @NotNull FileEditor, ? extends @Nullable JComponent> collectNotificationData(@NotNull Project project,
+ public @Nullable Function super @NotNull FileEditor, ? extends @Nullable JComponent> collectNotificationData(@NotNull Project project,
@NotNull VirtualFile file) {
if (!DebuggerSettings.getInstance().SHOW_ALTERNATIVE_SOURCE) {
- return CONST_NULL;
+ return null;
}
if (DumbService.getInstance(project).isDumb()) {
- return CONST_NULL;
+ return null;
}
DebuggerSession javaSession = DebuggerManagerEx.getInstanceEx(project).getContext().getDebuggerSession();
@@ -59,29 +59,29 @@ public final class AlternativeSourceNotificationProvider implements EditorNotifi
if (session == null) {
setFileProcessed(file, false);
- return CONST_NULL;
+ return null;
}
XSourcePosition position = session.getCurrentPosition();
if (position == null || !file.equals(position.getFile())) {
setFileProcessed(file, false);
- return CONST_NULL;
+ return null;
}
final PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
if (!(psiFile instanceof PsiJavaFile)) {
- return CONST_NULL;
+ return null;
}
PsiClass[] classes = ((PsiJavaFile)psiFile).getClasses();
if (classes.length == 0) {
- return CONST_NULL;
+ return null;
}
PsiClass baseClass = classes[0];
String name = baseClass.getQualifiedName();
if (name == null) {
- return CONST_NULL;
+ return null;
}
PsiClass[] altClasses = JavaPsiFacade.getInstance(project).findClasses(name, javaSession.getSearchScope());
@@ -94,7 +94,7 @@ public final class AlternativeSourceNotificationProvider implements EditorNotifi
setFileProcessed(file, true);
if (alts.size() <= 1) {
- return CONST_NULL;
+ return null;
}
for (PsiClass cls : alts) {
diff --git a/java/execution/impl/src/com/intellij/execution/jshell/SnippetEditorDecorator.java b/java/execution/impl/src/com/intellij/execution/jshell/SnippetEditorDecorator.java
index b31ae9caa39a..de7faa4313a7 100644
--- a/java/execution/impl/src/com/intellij/execution/jshell/SnippetEditorDecorator.java
+++ b/java/execution/impl/src/com/intellij/execution/jshell/SnippetEditorDecorator.java
@@ -187,12 +187,12 @@ public final class SnippetEditorDecorator implements EditorNotificationProvider
}
@Override
- public @NotNull Function super @NotNull FileEditor, ? extends @Nullable JComponent> collectNotificationData(@NotNull Project project,
+ public @Nullable Function super @NotNull FileEditor, ? extends @Nullable JComponent> collectNotificationData(@NotNull Project project,
@NotNull VirtualFile file) {
if (ScratchFileService.findRootType(file) instanceof JShellRootType) {
return editor -> new ConfigurationPane(project, file, editor);
}
- return CONST_NULL;
+ return null;
}
}
\ No newline at end of file
diff --git a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java
index e6f6dbb81740..9d16fc9be141 100644
--- a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java
+++ b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java
@@ -80,10 +80,10 @@ final class AttachSourcesNotificationProvider implements EditorNotificationProvi
}
@Override
- public @NotNull Function super @NotNull FileEditor, ? extends @Nullable JComponent> collectNotificationData(@NotNull Project project,
+ public @Nullable Function super @NotNull FileEditor, ? extends @Nullable JComponent> collectNotificationData(@NotNull Project project,
@NotNull VirtualFile file) {
if (!FileTypeRegistry.getInstance().isFileOfType(file, JavaClassFileType.INSTANCE)) {
- return CONST_NULL;
+ return null;
}
String classFileInfo = getTextWithClassFileInfo(file);
diff --git a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/LibrarySourceNotificationProvider.kt b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/LibrarySourceNotificationProvider.kt
index 5539cfc6fc85..855c68c7ecd9 100644
--- a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/LibrarySourceNotificationProvider.kt
+++ b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/LibrarySourceNotificationProvider.kt
@@ -1,4 +1,4 @@
-// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+// Copyright 2000-2022 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.diff.DiffContentFactory
@@ -38,7 +38,7 @@ class LibrarySourceNotificationProvider : EditorNotificationProvider {
override fun collectNotificationData(
project: Project,
file: VirtualFile,
- ): Function {
+ ): Function? {
if (file.fileType is LanguageFileType && ProjectRootManager.getInstance(project).fileIndex.isInLibrarySource(file)) {
val psiFile = PsiManager.getInstance(project).findFile(file)
if (psiFile is PsiJavaFile) {
@@ -69,7 +69,7 @@ class LibrarySourceNotificationProvider : EditorNotificationProvider {
}
}
- return EditorNotificationProvider.CONST_NULL
+ return null
}
private fun differs(src: PsiClass): Boolean {
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/impl/SdkSetupNotificationTestBase.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/impl/SdkSetupNotificationTestBase.java
index ccf776acb6f1..aa5114b13243 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/impl/SdkSetupNotificationTestBase.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/impl/SdkSetupNotificationTestBase.java
@@ -17,11 +17,12 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.testFramework.IdeaTestUtil;
+import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture;
import com.intellij.ui.EditorNotificationPanel;
+import com.intellij.ui.EditorNotifications;
import com.intellij.ui.EditorNotificationsImpl;
-import com.intellij.util.ui.EDT;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -59,20 +60,22 @@ public abstract class SdkSetupNotificationTestBase extends JavaCodeInsightFixtur
@NotNull String fileName,
@NotNull String fileText) {
FileEditor editor = openTextInEditor(fixture, fileName, fileText);
- return (EditorNotificationPanel)EditorNotificationsImpl.getNotificationPanels(editor).get(SdkSetupNotificationProvider.class);
+ EditorNotificationsImpl editorNotifications = (EditorNotificationsImpl)EditorNotifications.getInstance(fixture.getProject());
+ return (EditorNotificationPanel)(editorNotifications.getNotificationPanels(editor).get(SdkSetupNotificationProvider.class));
}
static @NotNull FileEditor openTextInEditor(@NotNull JavaCodeInsightTestFixture fixture,
@NotNull String fileName,
@NotNull String fileText) {
- EDT.dispatchAllInvocationEvents();
- EditorNotificationsImpl.completeAsyncTasks(fixture.getProject());
+ PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue();
+ EditorNotificationsImpl editorNotifications = (EditorNotificationsImpl)EditorNotifications.getInstance(fixture.getProject());
+ editorNotifications.completeAsyncTasks();
- final PsiFile psiFile = fixture.configureByText(fileName, fileText);
+ PsiFile psiFile = fixture.configureByText(fileName, fileText);
FileEditorManager fileEditorManager = FileEditorManager.getInstance(fixture.getProject());
VirtualFile virtualFile = psiFile.getVirtualFile();
- final FileEditor[] editors = fileEditorManager.openFile(virtualFile, true);
+ FileEditor[] editors = fileEditorManager.openFile(virtualFile, true);
Disposer.register(fixture.getTestRootDisposable(), new Disposable() {
@Override
public void dispose() {
@@ -81,8 +84,8 @@ public abstract class SdkSetupNotificationTestBase extends JavaCodeInsightFixtur
});
assertThat(editors).hasSize(1);
- EDT.dispatchAllInvocationEvents();
- EditorNotificationsImpl.completeAsyncTasks(fixture.getProject());
+ PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue();
+ editorNotifications.completeAsyncTasks();
return editors[0];
}
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/impl/UnknownSdkTrackerTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/impl/UnknownSdkTrackerTest.java
index 0feb22df5a97..9160b24fa472 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/impl/UnknownSdkTrackerTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/impl/UnknownSdkTrackerTest.java
@@ -67,21 +67,23 @@ public class UnknownSdkTrackerTest extends JavaCodeInsightFixtureTestCase {
public void testMissingModuleJdk() {
setModuleSdk("missingSDK", JavaSdk.getInstance());
- final List fixes = detectMissingSdks();
+ List fixes = detectMissingSdks();
assertThat(fixes)
.withFailMessage(String.valueOf(fixes))
.hasSize(1)
- .first().asString().startsWith("SdkFixInfo:");
+ .first().asString().matches(s -> s.startsWith("SdkFixInfo:") || s.startsWith("SdkSetupNotification:"));
}
public void testMissingModuleUnknownSdk() {
setModuleSdk("missingSDK", "foo-bar-baz");
- final List fixes = detectMissingSdks();
+ List fixes = detectMissingSdks();
assertThat(fixes)
.withFailMessage(String.valueOf(fixes))
.hasSize(1)
- .first().asString().startsWith("SdkSetupNotification:");
+ .first()
+ .asString()
+ .startsWith("SdkSetupNotification:");
}
public void testNoProjectSdk() {
@@ -106,7 +108,6 @@ public class UnknownSdkTrackerTest extends JavaCodeInsightFixtureTestCase {
public void testNoModuleSdk() {
ModuleRootModificationUtil.setModuleSdk(getModule(), null);
-
final List fixes = detectMissingSdks();
assertThat(fixes)
.withFailMessage(String.valueOf(fixes))
@@ -156,7 +157,6 @@ public class UnknownSdkTrackerTest extends JavaCodeInsightFixtureTestCase {
assertThat(lookupCalls).hasValue(2);
}
-
@TestFor(issues = "IDEA-237884")
public void testShouldNotRantOnCustomSDKType() {
final Sdk broken = ProjectJdkTable.getInstance().createSdk("broken-sdk-123", SimpleJavaSdkType.getInstance());
@@ -267,7 +267,7 @@ public class UnknownSdkTrackerTest extends JavaCodeInsightFixtureTestCase {
private @NotNull List detectMissingSdks() {
UnknownSdkTracker.getInstance(getProject()).updateUnknownSdks();
- ArrayList infos = new ArrayList<>();
+ List infos = new ArrayList<>();
EditorNotificationPanel sdkNotification =
SdkSetupNotificationTestBase.runOnText(myFixture, "Sample.java", "class Sample { java.lang.String foo; }");
if (sdkNotification != null) {
diff --git a/platform/execution-impl/src/com/intellij/execution/impl/RunConfigEditorNotificationProvider.kt b/platform/execution-impl/src/com/intellij/execution/impl/RunConfigEditorNotificationProvider.kt
index fb0e2b63881c..65860cf23ab5 100644
--- a/platform/execution-impl/src/com/intellij/execution/impl/RunConfigEditorNotificationProvider.kt
+++ b/platform/execution-impl/src/com/intellij/execution/impl/RunConfigEditorNotificationProvider.kt
@@ -1,41 +1,43 @@
-// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.execution.impl
import com.intellij.execution.ExecutionBundle
import com.intellij.openapi.fileEditor.FileEditor
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectFileIndex
-import com.intellij.openapi.util.Key
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.ui.EditorNotificationPanel
-import com.intellij.ui.EditorNotifications
+import com.intellij.ui.EditorNotificationProvider
+import java.util.function.Function
+import javax.swing.JComponent
-class RunConfigEditorNotificationProvider : EditorNotifications.Provider() {
- private val KEY: Key = Key.create("RunConfigEditorNotificationProvider")
-
- override fun getKey(): Key = KEY
-
- override fun createNotificationPanel(file: VirtualFile, fileEditor: FileEditor, project: Project): EditorNotificationPanel? {
- if (!file.name.endsWith(".run.xml")) return null
- if (!ProjectFileIndex.getInstance(project).isInContent(file)) return null
-
- val runManager = RunManagerImpl.getInstanceImpl(project)
- if (!runManager.isFileContainsRunConfiguration(file)) return null
-
- val panel = EditorNotificationPanel(fileEditor, EditorNotificationPanel.Status.Warning)
- panel.text = ExecutionBundle.message("manual.editing.of.config.file.not.recommended")
- @Suppress("DialogTitleCapitalization") val message = ExecutionBundle.message("open.run.debug.dialog")
- panel.createActionLabel(message) {
- val oldSelectedConfig = runManager.selectedConfiguration
-
- runManager.selectConfigurationStoredInFile(file)
- val ok = EditConfigurationsDialog(project).showAndGet()
-
- if (!ok) {
- runManager.selectedConfiguration = oldSelectedConfig
- }
+private class RunConfigEditorNotificationProvider : EditorNotificationProvider {
+ override fun collectNotificationData(project: Project, file: VirtualFile): Function? {
+ if (!file.nameSequence.endsWith(".run.xml") || !ProjectFileIndex.getInstance(project).isInContent(file)) {
+ return null
}
- return panel
+ val runManager = RunManagerImpl.getInstanceImpl(project)
+ if (!runManager.isFileContainsRunConfiguration(file)) {
+ return null
+ }
+
+ return Function { fileEditor ->
+ val panel = EditorNotificationPanel(fileEditor, EditorNotificationPanel.Status.Warning)
+ panel.text = ExecutionBundle.message("manual.editing.of.config.file.not.recommended")
+ @Suppress("DialogTitleCapitalization") val message = ExecutionBundle.message("open.run.debug.dialog")
+ panel.createActionLabel(message) {
+ val oldSelectedConfig = runManager.selectedConfiguration
+
+ runManager.selectConfigurationStoredInFile(file)
+ val ok = EditConfigurationsDialog(project).showAndGet()
+
+ if (!ok) {
+ runManager.selectedConfiguration = oldSelectedConfig
+ }
+ }
+
+ panel
+ }
}
}
\ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SdkSetupNotificationProvider.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SdkSetupNotificationProvider.java
index b2c0b0d3d583..e7d8cfaf0024 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SdkSetupNotificationProvider.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SdkSetupNotificationProvider.java
@@ -1,4 +1,4 @@
-// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+// Copyright 2000-2022 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.ProjectSdkSetupValidator;
@@ -22,26 +22,22 @@ import java.util.function.Function;
/**
* @author Danila Ponomarenko
*/
-public final class SdkSetupNotificationProvider implements EditorNotificationProvider,
- DumbAware {
-
+public final class SdkSetupNotificationProvider implements EditorNotificationProvider, DumbAware {
@Override
- public @NotNull Function super @NotNull FileEditor, ? extends @Nullable JComponent> collectNotificationData(@NotNull Project project,
- @NotNull VirtualFile file) {
+ public @Nullable Function super @NotNull FileEditor, ? extends @Nullable JComponent> collectNotificationData(@NotNull Project project,
+ @NotNull VirtualFile file) {
if (!UnknownSdkEditorNotification.getInstance(project).allowProjectSdkNotifications()) {
- return CONST_NULL;
+ return null;
}
for (ProjectSdkSetupValidator validator : ProjectSdkSetupValidator.EP_NAME.getExtensionList()) {
if (validator.isApplicableFor(project, file)) {
String errorMessage = validator.getErrorMessage(project, file);
- return errorMessage != null ?
- fileEditor -> createPanel(errorMessage, fileEditor, validator.getFixHandler(project, file)) :
- CONST_NULL;
+ return errorMessage == null ? null : fileEditor -> createPanel(errorMessage, fileEditor, validator.getFixHandler(project, file));
}
}
- return CONST_NULL;
+ return null;
}
@RequiresEdt
diff --git a/platform/platform-api/src/com/intellij/ui/EditorNotificationProvider.java b/platform/platform-api/src/com/intellij/ui/EditorNotificationProvider.java
index 6879eb533bab..4afd4e48f30c 100644
--- a/platform/platform-api/src/com/intellij/ui/EditorNotificationProvider.java
+++ b/platform/platform-api/src/com/intellij/ui/EditorNotificationProvider.java
@@ -22,13 +22,16 @@ import java.util.function.Function;
*
*/
public interface EditorNotificationProvider {
-
ProjectExtensionPointName EP_NAME =
new ProjectExtensionPointName<>("com.intellij.editorNotificationProvider");
+ /**
+ * @deprecated Use {@code null}.
+ */
+ @Deprecated
Function super @NotNull FileEditor, ? extends @Nullable JComponent> CONST_NULL = __ -> null;
@RequiresReadLock
- @NotNull Function super @NotNull FileEditor, ? extends @Nullable JComponent> collectNotificationData(@NotNull Project project,
- @NotNull VirtualFile file);
+ @Nullable Function super @NotNull FileEditor, ? extends @Nullable JComponent> collectNotificationData(@NotNull Project project,
+ @NotNull VirtualFile file);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.kt b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.kt
index 96bd2a32b549..4a81f045685a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.kt
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.kt
@@ -34,7 +34,7 @@ class PluginAdvertiserEditorNotificationProvider : EditorNotificationProvider,
override fun collectNotificationData(
project: Project,
file: VirtualFile,
- ): Function {
+ ): Function? {
val suggestionData = getSuggestionData(project, ApplicationInfo.getInstance().build.productCode, file.name, file.fileType)
if (suggestionData == null) {
@@ -58,7 +58,7 @@ class PluginAdvertiserEditorNotificationProvider : EditorNotificationProvider,
LOG.debug("Tried to update extensions cache for file '${file.name}'. shouldUpdateNotifications=$shouldUpdateNotifications")
}
- return EditorNotificationProvider.CONST_NULL
+ return null
}
return suggestionData
diff --git a/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.kt b/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.kt
index 68d127415341..8a14fcf94c29 100644
--- a/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.kt
+++ b/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.kt
@@ -6,8 +6,8 @@ package com.intellij.ui
import com.intellij.ProjectTopics
import com.intellij.diagnostic.PluginException
import com.intellij.ide.impl.runUnderModalProgressIfIsEdt
+import com.intellij.openapi.Disposable
import com.intellij.openapi.application.*
-import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.extensions.ExtensionPointListener
import com.intellij.openapi.extensions.PluginDescriptor
@@ -26,11 +26,11 @@ import com.intellij.psi.PsiFile
import com.intellij.refactoring.listeners.RefactoringElementAdapter
import com.intellij.refactoring.listeners.RefactoringElementListener
import com.intellij.refactoring.listeners.RefactoringElementListenerProvider
+import com.intellij.util.SingleAlarm
+import com.intellij.util.childScope
import com.intellij.util.concurrency.annotations.RequiresEdt
import com.intellij.util.containers.CollectionFactory
import com.intellij.util.ui.UIUtil
-import com.intellij.util.ui.update.MergingUpdateQueue
-import com.intellij.util.ui.update.Update
import kotlinx.coroutines.*
import org.jetbrains.annotations.TestOnly
import org.jetbrains.annotations.VisibleForTesting
@@ -39,10 +39,14 @@ import java.util.concurrent.CancellationException
import java.util.function.BiFunction
import javax.swing.JComponent
-class EditorNotificationsImpl(private val project: Project) : EditorNotifications() {
- private val updateMerger = MergingUpdateQueue("EditorNotifications update merger", 100, true, null, project).usePassThroughInUnitTestMode()
+class EditorNotificationsImpl(private val project: Project) : EditorNotifications(), Disposable {
+ private val updateAllAlarm = SingleAlarm(::doUpdateAllNotifications, 100, this)
private val fileToUpdateNotificationJob = CollectionFactory.createConcurrentWeakMap()
+ private val fileEditorToMap =
+ CollectionFactory.createConcurrentWeakMap, JComponent>>()
+
+ private val coroutineScope: CoroutineScope = project.coroutineScope.childScope()
init {
val connection = project.messageBus.connect()
@@ -52,11 +56,11 @@ class EditorNotificationsImpl(private val project: Project) : EditorNotificatio
}
override fun selectionChanged(event: FileEditorManagerEvent) {
- val file = event.newFile
- val editor = event.newEditor
- if (file != null && editor != null && java.lang.Boolean.TRUE == editor.getUserData(PENDING_UPDATE)) {
+ val file = event.newFile ?: return
+ val editor = event.newEditor ?: return
+ if (editor.getUserData(PENDING_UPDATE) == java.lang.Boolean.TRUE) {
editor.putUserData(PENDING_UPDATE, null)
- updateEditor(file, editor)
+ updateEditors(file, listOf(editor))
}
}
})
@@ -87,142 +91,139 @@ class EditorNotificationsImpl(private val project: Project) : EditorNotificatio
}, false, null)
}
+ override fun dispose() {
+ coroutineScope.cancel()
+ // help GC
+ fileToUpdateNotificationJob.clear()
+ fileEditorToMap.clear()
+ }
+
companion object {
- private val EDITOR_NOTIFICATION_PROVIDER =
- Key.create, JComponent?>>("editor.notification.provider")
-
private val PENDING_UPDATE = Key.create("pending.notification.update")
+ }
- @VisibleForTesting
- @JvmStatic
- fun getNotificationPanels(editor: FileEditor): MutableMap, JComponent?> {
- editor.getUserData(EDITOR_NOTIFICATION_PROVIDER)?.let {
- return it
- }
+ @VisibleForTesting
+ fun getNotificationPanels(fileEditor: FileEditor): MutableMap, JComponent> {
+ return fileEditorToMap.computeIfAbsent(fileEditor) { WeakHashMap() }
+ }
- editor.putUserData(EDITOR_NOTIFICATION_PROVIDER, WeakHashMap())
- editor.getUserData(EDITOR_NOTIFICATION_PROVIDER)?.let {
- return it
- }
- val editorClass = editor.javaClass
- val pluginException = PluginException.createByClass(
- "User data is not supported; editorClass='${editorClass.name}'; key='$EDITOR_NOTIFICATION_PROVIDER'",
- null,
- editorClass)
- Logger.getInstance(editorClass).error(pluginException)
- throw pluginException
- }
-
- @TestOnly
- @JvmStatic
- fun completeAsyncTasks(project: Project) {
- runUnderModalProgressIfIsEdt {
+ @TestOnly
+ fun completeAsyncTasks() {
+ runUnderModalProgressIfIsEdt {
+ val parentJob = coroutineScope.coroutineContext[Job]!!
+ while (true) {
+ // process all events in EDT
withContext(Dispatchers.EDT) {
yield()
}
- val editorNotificationManager = getInstance(project) as EditorNotificationsImpl
- for (job in editorNotificationManager.fileToUpdateNotificationJob.values.toList()) {
- try {
- job.join()
- }
- catch (ignore: CancellationException) {
- }
+ val jobs = parentJob.children.toList()
+ if (jobs.isEmpty()) {
+ break
}
+ jobs.joinAll()
+
+ // process all events in EDT
withContext(Dispatchers.EDT) {
yield()
}
}
}
+ check(fileToUpdateNotificationJob.isEmpty())
}
override fun updateNotifications(provider: EditorNotificationProvider) {
for (file in FileEditorManager.getInstance(project).openFilesWithRemotes) {
- for (editor in getEditors(file)) {
- updateNotification(editor, provider, null)
+ for (editor in getEditors(file).toList()) {
+ updateNotification(fileEditor = editor, provider = provider, component = null)
}
}
}
override fun updateNotifications(file: VirtualFile) {
- AppUIExecutor
- .onUiThread(ModalityState.any())
- .expireWith(project)
- .execute {
- if (project.isDisposed || !file.isValid) {
- return@execute
- }
- var editors = getEditors(file)
- if (!ApplicationManager.getApplication().isHeadlessEnvironment) {
- editors = editors.filter { fileEditor ->
- val visible = UIUtil.isShowing(fileEditor.component)
- if (!visible) {
- fileEditor.putUserData(PENDING_UPDATE, java.lang.Boolean.TRUE)
- }
- visible
- }
- }
- for (editor in editors) {
- updateEditor(file, editor)
- }
- }
- }
-
- private fun getEditors(file: VirtualFile): List {
- return FileEditorManager.getInstance(project).getAllEditors(file).filter { it !is TextEditor || isEditorLoaded(it.editor) }
- }
-
- private fun updateEditor(file: VirtualFile, fileEditor: FileEditor) {
- // light project is not disposed in tests
- if (project.isDisposed) {
- return
- }
-
- val job = project.coroutineScope.launch(start = CoroutineStart.LAZY) {
+ coroutineScope.launch(Dispatchers.EDT + ModalityState.any().asContextElement()) {
if (!file.isValid) {
return@launch
}
+ doUpdateNotifications(file)
+ }
+ }
+
+ @RequiresEdt
+ private fun doUpdateNotifications(file: VirtualFile) {
+ var editors = getEditors(file)
+ if (!ApplicationManager.getApplication().isHeadlessEnvironment) {
+ editors = editors.filter { fileEditor ->
+ val visible = UIUtil.isShowing(fileEditor.component)
+ if (!visible) {
+ fileEditor.putUserData(PENDING_UPDATE, java.lang.Boolean.TRUE)
+ }
+ visible
+ }
+ }
+ updateEditors(file, editors.toList())
+ }
+
+ private fun getEditors(file: VirtualFile): Sequence {
+ return FileEditorManager.getInstance(project).getAllEditors(file).asSequence().filter { it !is TextEditor || isEditorLoaded(it.editor) }
+ }
+
+ private fun updateEditors(file: VirtualFile, fileEditors: List) {
+ val job = coroutineScope.launch(start = CoroutineStart.LAZY) {
+ // delay for debounce
+ delay(100)
+
+ if (!file.isValid) {
+ return@launch
+ }
+
+ // light project is not disposed in tests
+ if (project.isDisposed) {
+ return@launch
+ }
+
coroutineContext.ensureActive()
- try {
- val point = EditorNotificationProvider.EP_NAME.getPoint(project) as ExtensionPointImpl
- for (adapter in point.sortedAdapters) {
+ val point = EditorNotificationProvider.EP_NAME.getPoint(project) as ExtensionPointImpl
+ for (adapter in point.sortedAdapters) {
+ coroutineContext.ensureActive()
+
+ try {
+ val provider = adapter.createInstance(project) ?: continue
+
coroutineContext.ensureActive()
- try {
- val provider = adapter.createInstance(project) ?: continue
+ if (DumbService.isDumb(project) && !DumbService.isDumbAware(provider)) {
+ continue
+ }
- coroutineContext.ensureActive()
-
- if (DumbService.isDumb(project) && !DumbService.isDumbAware(provider)) {
- continue
+ val componentProvider = readAction {
+ if (file.isValid) {
+ provider.collectNotificationData(project, file)
+ }
+ else {
+ null
+ }
+ } ?: continue
+ withContext(Dispatchers.EDT + ModalityState.any().asContextElement()) {
+ if (!file.isValid) {
+ return@withContext
}
- val componentProvider = readAction {
- if (file.isValid) {
- provider.collectNotificationData(project, file)
- }
- else {
- null
- }
- } ?: continue
- withContext(Dispatchers.EDT + ModalityState.any().asContextElement()) {
+ for (fileEditor in fileEditors) {
val component = componentProvider.apply(fileEditor)
- updateNotification(fileEditor, provider, component)
+ updateNotification(fileEditor = fileEditor, provider = provider, component = component)
}
}
- catch (e: CancellationException) {
- throw e
- }
- catch (e: Exception) {
- val pluginException = if (e is PluginException) e else PluginException(e, adapter.pluginDescriptor.pluginId)
- logger().error(pluginException)
- }
}
- }
- finally {
- fileToUpdateNotificationJob.remove(file, coroutineContext.job)
+ catch (e: CancellationException) {
+ throw e
+ }
+ catch (e: Exception) {
+ val pluginException = if (e is PluginException) e else PluginException(e, adapter.pluginDescriptor.pluginId)
+ logger().error(pluginException)
+ }
}
}
job.invokeOnCompletion { fileToUpdateNotificationJob.remove(file, job) }
@@ -235,11 +236,11 @@ class EditorNotificationsImpl(private val project: Project) : EditorNotificatio
}
@RequiresEdt
- private fun updateNotification(editor: FileEditor, provider: EditorNotificationProvider, component: JComponent?) {
- val panels = getNotificationPanels(editor)
+ private fun updateNotification(fileEditor: FileEditor, provider: EditorNotificationProvider, component: JComponent?) {
+ val panels = fileEditorToMap.get(fileEditor)
val providerClass = provider.javaClass
- panels.get(providerClass)?.let { old ->
- FileEditorManager.getInstance(project).removeTopComponent(editor, old)
+ panels?.get(providerClass)?.let { old ->
+ FileEditorManager.getInstance(project).removeTopComponent(fileEditor, old)
}
if (component != null) {
if (component is EditorNotificationPanel) {
@@ -248,9 +249,13 @@ class EditorNotificationsImpl(private val project: Project) : EditorNotificatio
}
}
logNotificationShown(project, provider)
- FileEditorManager.getInstance(project).addTopComponent(editor, component)
+ FileEditorManager.getInstance(project).addTopComponent(fileEditor, component)
+
+ (panels ?: getNotificationPanels(fileEditor)).put(providerClass, component)
+ }
+ else {
+ panels?.remove(providerClass)
}
- panels.put(providerClass, component)
}
override fun updateAllNotifications() {
@@ -258,14 +263,20 @@ class EditorNotificationsImpl(private val project: Project) : EditorNotificatio
throw UnsupportedOperationException("Editor notifications aren't supported for default project")
}
+ if (ApplicationManager.getApplication().isUnitTestMode) {
+ doUpdateAllNotifications()
+ }
+ else {
+ updateAllAlarm.cancelAndRequest()
+ }
+ }
+
+ @RequiresEdt
+ private fun doUpdateAllNotifications() {
val fileEditorManager = FileEditorManager.getInstance(project) ?: throw IllegalStateException("No FileEditorManager for $project")
- updateMerger.queue(object : Update("update") {
- override fun run() {
- for (file in fileEditorManager.openFilesWithRemotes) {
- updateNotifications(file)
- }
- }
- })
+ for (file in fileEditorManager.openFilesWithRemotes) {
+ doUpdateNotifications(file)
+ }
}
internal class RefactoringListenerProvider : RefactoringElementListenerProvider {
@@ -277,10 +288,8 @@ class EditorNotificationsImpl(private val project: Project) : EditorNotificatio
return object : RefactoringElementAdapter() {
override fun elementRenamedOrMoved(newElement: PsiElement) {
if (newElement is PsiFile) {
- val vFile = newElement.getContainingFile().virtualFile
- if (vFile != null) {
- getInstance(element.getProject()).updateNotifications(vFile)
- }
+ val vFile = newElement.getContainingFile().virtualFile ?: return
+ getInstance(element.getProject()).updateNotifications(vFile)
}
}
diff --git a/plugins/editorconfig/src/org/editorconfig/configmanagement/editor/EditorConfigEditorNotificationProvider.java b/plugins/editorconfig/src/org/editorconfig/configmanagement/editor/EditorConfigEditorNotificationProvider.java
index da49fdadee87..07704c4be599 100644
--- a/plugins/editorconfig/src/org/editorconfig/configmanagement/editor/EditorConfigEditorNotificationProvider.java
+++ b/plugins/editorconfig/src/org/editorconfig/configmanagement/editor/EditorConfigEditorNotificationProvider.java
@@ -1,4 +1,4 @@
-// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.editorconfig.configmanagement.editor;
import com.intellij.application.options.CodeStyle;
@@ -20,14 +20,12 @@ import javax.swing.*;
import java.util.function.Function;
final class EditorConfigEditorNotificationProvider implements EditorNotificationProvider {
-
@Override
- public @NotNull Function super @NotNull FileEditor, ? extends @Nullable JComponent> collectNotificationData(@NotNull Project project,
+ public @Nullable Function super @NotNull FileEditor, ? extends @Nullable JComponent> collectNotificationData(@NotNull Project project,
@NotNull VirtualFile file) {
- return file.getFileType().equals(EditorConfigFileType.INSTANCE) &&
- !getEditorConfigSettings(project).ENABLED ?
- fileEditor -> new MyPanel(fileEditor, project) :
- CONST_NULL;
+ return file.getFileType().equals(EditorConfigFileType.INSTANCE) && !getEditorConfigSettings(project).ENABLED
+ ? fileEditor -> new MyPanel(fileEditor, project)
+ : null;
}
private static final class MyPanel extends EditorNotificationPanel {
diff --git a/plugins/git4idea/src/git4idea/ui/GitEditorPromo.kt b/plugins/git4idea/src/git4idea/ui/GitEditorPromo.kt
index 0d6efb364cd7..e1d196d86070 100644
--- a/plugins/git4idea/src/git4idea/ui/GitEditorPromo.kt
+++ b/plugins/git4idea/src/git4idea/ui/GitEditorPromo.kt
@@ -1,4 +1,4 @@
-// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package git4idea.ui
import com.intellij.codeInsight.hint.HintUtil
@@ -11,46 +11,46 @@ import com.intellij.openapi.fileEditor.FileEditor
import com.intellij.openapi.help.HelpManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.popup.IconButton
-import com.intellij.openapi.util.Key
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.ui.EditorNotificationPanel
+import com.intellij.ui.EditorNotificationProvider
import com.intellij.ui.EditorNotifications
import com.intellij.ui.InplaceButton
import git4idea.i18n.GitBundle
import git4idea.repo.GitRepositoryFiles
import git4idea.repo.GitRepositoryManager
import java.awt.BorderLayout
+import java.util.function.Function
+import javax.swing.JComponent
-private val KEY: Key = Key.create("GitEditorPromo")
private const val PROMO_DISMISSED_KEY = "git.editor.promo.dismissed"
-class GitEditorPromo : EditorNotifications.Provider() {
- override fun getKey(): Key = KEY
+private class GitEditorPromo : EditorNotificationProvider {
+ override fun collectNotificationData(project: Project, file: VirtualFile): Function? {
+ if (!isEnabled() || !CommandLineWaitingManager.getInstance().hasHookFor(file) || file.name != GitRepositoryFiles.COMMIT_EDITMSG) {
+ return null
+ }
- override fun createNotificationPanel(file: VirtualFile,
- fileEditor: FileEditor,
- project: Project): EditorNotificationPanel? {
- return if (isEnabled() && CommandLineWaitingManager.getInstance().hasHookFor(file)
- && file.name == GitRepositoryFiles.COMMIT_EDITMSG) {
- EditorNotificationPanel(HintUtil.PROMOTION_PANE_KEY, EditorNotificationPanel.Status.Info).apply {
- icon(AllIcons.Ide.Gift)
- text = GitBundle.message("editor.promo.commit.text", ApplicationNamesInfo.getInstance().fullProductName)
- val repository = GitRepositoryManager.getInstance(project).repositories.find { it.repositoryFiles.isCommitMessageFile(file.path) }
- if (repository != null) {
- createActionLabel(GitBundle.message("editor.promo.commit.try.link"), IdeActions.ACTION_CHECKIN_PROJECT, false)
+ return Function {
+ val panel = EditorNotificationPanel(HintUtil.PROMOTION_PANE_KEY, EditorNotificationPanel.Status.Info)
+ panel.icon(AllIcons.Ide.Gift)
+ panel.text = GitBundle.message("editor.promo.commit.text", ApplicationNamesInfo.getInstance().fullProductName)
+ val repository = GitRepositoryManager.getInstance(project).repositories.find { it.repositoryFiles.isCommitMessageFile(file.path) }
+ if (repository == null) {
+ panel.createActionLabel(GitBundle.message("editor.promo.help.link")) {
+ HelpManager.getInstance().invokeHelp("Commit and push changes")
}
- else {
- createActionLabel(GitBundle.message("editor.promo.help.link")) {
- HelpManager.getInstance().invokeHelp("Commit and push changes")
- }
- }
- add(InplaceButton(IconButton(GitBundle.message("editor.promo.close.link"), AllIcons.Actions.Close, AllIcons.Actions.CloseHovered)) {
+ }
+ else {
+ panel.createActionLabel(GitBundle.message("editor.promo.commit.try.link"), IdeActions.ACTION_CHECKIN_PROJECT, false)
+ }
+ panel.add(
+ InplaceButton(IconButton(GitBundle.message("editor.promo.close.link"), AllIcons.Actions.Close, AllIcons.Actions.CloseHovered)) {
PropertiesComponent.getInstance().setValue(PROMO_DISMISSED_KEY, true)
- EditorNotifications.getInstance(project).updateNotifications(this@GitEditorPromo)
+ EditorNotifications.getInstance(project).updateNotifications(this)
}, BorderLayout.EAST)
- }
+ panel
}
- else null
}
private fun isEnabled(): Boolean = !PropertiesComponent.getInstance().getBoolean(PROMO_DISMISSED_KEY)
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/ConfigureGroovyLibraryNotificationProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/ConfigureGroovyLibraryNotificationProvider.java
index dc28980538ad..b368bc00b90f 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/ConfigureGroovyLibraryNotificationProvider.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/ConfigureGroovyLibraryNotificationProvider.java
@@ -1,4 +1,4 @@
-// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.plugins.groovy.config;
import com.intellij.openapi.compiler.CompilerManager;
@@ -30,37 +30,36 @@ import java.util.function.Function;
final class ConfigureGroovyLibraryNotificationProvider implements EditorNotificationProvider {
@Override
- public @NotNull Function super @NotNull FileEditor, ? extends @Nullable JComponent> collectNotificationData(@NotNull Project project,
+ public @Nullable Function super @NotNull FileEditor, ? extends @Nullable JComponent> collectNotificationData(@NotNull Project project,
@NotNull VirtualFile file) {
try {
if (!file.getFileType().equals(GroovyFileType.GROOVY_FILE_TYPE)) {
- return CONST_NULL;
+ return null;
}
// do not show the panel for Gradle build scripts
// expecting groovy library to always be available at the gradle distribution
if (StringUtil.endsWith(file.getName(), ".gradle") ||
CompilerManager.getInstance(project).isExcludedFromCompilation(file)) {
- return CONST_NULL;
+ return null;
}
final Module module = ModuleUtilCore.findModuleForFile(file, project);
- if (module == null ||
- isMavenModule(module)) {
- return CONST_NULL;
+ if (module == null || isMavenModule(module)) {
+ return null;
}
for (GroovyFrameworkConfigNotification configNotification : GroovyFrameworkConfigNotification.EP_NAME.getExtensions()) {
if (configNotification.hasFrameworkStructure(module)) {
return configNotification.hasFrameworkLibrary(module) ?
- CONST_NULL :
+ null :
fileEditor -> createConfigureNotificationPanel(module, fileEditor);
}
}
- return CONST_NULL;
+ return null;
}
catch (ProcessCanceledException | IndexNotReadyException ignored) {
- return CONST_NULL;
+ return null;
}
}
diff --git a/plugins/kotlin/base/fe10/highlighting/src/org/jetbrains/kotlin/idea/base/fe10/highlighting/suspender/KotlinHighlightingSuspendNotificationProvider.kt b/plugins/kotlin/base/fe10/highlighting/src/org/jetbrains/kotlin/idea/base/fe10/highlighting/suspender/KotlinHighlightingSuspendNotificationProvider.kt
index e50837bd698a..26544e0c0751 100644
--- a/plugins/kotlin/base/fe10/highlighting/src/org/jetbrains/kotlin/idea/base/fe10/highlighting/suspender/KotlinHighlightingSuspendNotificationProvider.kt
+++ b/plugins/kotlin/base/fe10/highlighting/src/org/jetbrains/kotlin/idea/base/fe10/highlighting/suspender/KotlinHighlightingSuspendNotificationProvider.kt
@@ -12,12 +12,12 @@ import java.util.function.Function
import javax.swing.JComponent
internal class KotlinHighlightingSuspendNotificationProvider : EditorNotificationProvider {
- override fun collectNotificationData(project: Project, file: VirtualFile): Function {
+ override fun collectNotificationData(project: Project, file: VirtualFile): Function? {
if (!file.isKotlinFileType()) {
- return EditorNotificationProvider.CONST_NULL
+ return null
}
- if (!KotlinHighlightingSuspender.getInstance(project).isSuspended(file)) return EditorNotificationProvider.CONST_NULL
+ if (!KotlinHighlightingSuspender.getInstance(project).isSuspended(file)) return null
return Function {
EditorNotificationPanel(it, EditorNotificationPanel.Status.Warning).apply {
diff --git a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/scripting/GradleScriptNotificationProvider.kt b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/scripting/GradleScriptNotificationProvider.kt
index 9b1a908241a6..12aa9f31f9dc 100644
--- a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/scripting/GradleScriptNotificationProvider.kt
+++ b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/scripting/GradleScriptNotificationProvider.kt
@@ -13,7 +13,6 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.projectImport.ProjectImportProvider
import com.intellij.ui.EditorNotificationPanel
import com.intellij.ui.EditorNotificationProvider
-import com.intellij.ui.EditorNotificationProvider.CONST_NULL
import org.jetbrains.annotations.Nls
import org.jetbrains.kotlin.idea.base.scripting.KotlinBaseScriptingBundle
import org.jetbrains.kotlin.idea.gradle.KotlinIdeaGradleBundle
@@ -34,14 +33,14 @@ internal class GradleScriptNotificationProvider : EditorNotificationProvider {
override fun collectNotificationData(
project: Project,
file: VirtualFile,
- ): Function {
+ ): Function? {
if (!isGradleKotlinScript(file) || !file.isKotlinFileType()) {
- return CONST_NULL
+ return null
}
val standaloneScriptActions = GradleStandaloneScriptActionsManager.getInstance(project)
val rootsManager = GradleBuildRootsManager.getInstance(project)
- val scriptUnderRoot = rootsManager?.findScriptBuildRoot(file) ?: return CONST_NULL
+ val scriptUnderRoot = rootsManager?.findScriptBuildRoot(file) ?: return null
// todo: this actions will be usefull only when gradle fix https://github.com/gradle/gradle/issues/12640
fun EditorNotificationPanel.showActionsToFixNotEvaluated() {
diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/script/configuration/MultipleScriptDefinitionsChecker.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/script/configuration/MultipleScriptDefinitionsChecker.kt
index 0a2723eb5003..0ff9fb2ee324 100644
--- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/script/configuration/MultipleScriptDefinitionsChecker.kt
+++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/script/configuration/MultipleScriptDefinitionsChecker.kt
@@ -1,4 +1,4 @@
-// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.script.configuration
@@ -13,7 +13,6 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiManager
import com.intellij.ui.EditorNotificationPanel
import com.intellij.ui.EditorNotificationProvider
-import com.intellij.ui.EditorNotificationProvider.*
import com.intellij.ui.EditorNotifications
import com.intellij.ui.HyperlinkLabel
import org.jetbrains.annotations.Nls
@@ -33,13 +32,13 @@ import javax.swing.JComponent
class MultipleScriptDefinitionsChecker : EditorNotificationProvider {
- override fun collectNotificationData(project: Project, file: VirtualFile): Function {
- if (!file.isKotlinFileType()) return CONST_NULL
+ override fun collectNotificationData(project: Project, file: VirtualFile): Function? {
+ if (!file.isKotlinFileType()) return null
- val ktFile = PsiManager.getInstance(project).findFile(file).safeAs()?.takeIf(KtFile::isScript) ?: return CONST_NULL
+ val ktFile = PsiManager.getInstance(project).findFile(file).safeAs()?.takeIf(KtFile::isScript) ?: return null
if (KotlinScriptingSettings.getInstance(project).suppressDefinitionsCheck ||
- !ScriptDefinitionsManager.getInstance(project).isReady()) return CONST_NULL
+ !ScriptDefinitionsManager.getInstance(project).isReady()) return null
val allApplicableDefinitions = ScriptDefinitionsManager.getInstance(project)
.getAllDefinitions()
@@ -48,7 +47,7 @@ class MultipleScriptDefinitionsChecker : EditorNotificationProvider {
KotlinScriptingSettings.getInstance(project).isScriptDefinitionEnabled(it)
}
.toList()
- if (allApplicableDefinitions.size < 2 || areDefinitionsForGradleKts(allApplicableDefinitions)) return CONST_NULL
+ if (allApplicableDefinitions.size < 2 || areDefinitionsForGradleKts(allApplicableDefinitions)) return null
return Function { fileEditor: FileEditor ->
createNotification(fileEditor, project, allApplicableDefinitions)
diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/script/configuration/ScriptingSupportChecker.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/script/configuration/ScriptingSupportChecker.kt
index 82a1de5d5f64..e10217d3a462 100644
--- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/script/configuration/ScriptingSupportChecker.kt
+++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/script/configuration/ScriptingSupportChecker.kt
@@ -3,7 +3,6 @@ package org.jetbrains.kotlin.idea.script.configuration
import com.intellij.ide.BrowserUtil
import com.intellij.ide.scratch.ScratchUtil
-import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.fileEditor.FileEditor
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.project.Project
@@ -12,7 +11,6 @@ import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.ui.EditorNotificationPanel
import com.intellij.ui.EditorNotificationProvider
-import org.jetbrains.annotations.Nls
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings
import org.jetbrains.kotlin.idea.util.KOTLIN_AWARE_SOURCE_ROOT_TYPES
@@ -21,14 +19,14 @@ import java.util.function.Function
import javax.swing.JComponent
class ScriptingSupportChecker: EditorNotificationProvider {
- override fun collectNotificationData(project: Project, file: VirtualFile): Function {
+ override fun collectNotificationData(project: Project, file: VirtualFile): Function? {
if (!Registry.`is`("kotlin.scripting.support.warning") || file.isNonScript() || ScratchUtil.isScratch(file)) {
- return EditorNotificationProvider.CONST_NULL
+ return null
}
// warning panel is hidden
if (!KotlinScriptingSettings.getInstance(project).showSupportWarning) {
- return EditorNotificationProvider.CONST_NULL
+ return null
}
val providers = ScriptingSupportCheckerProvider.CHECKER_PROVIDERS.getExtensionList(project)
@@ -70,7 +68,7 @@ class ScriptingSupportChecker: EditorNotificationProvider {
}
}
- return EditorNotificationProvider.CONST_NULL
+ return null
}
}
diff --git a/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/KotlinAlternativeSourceNotificationProvider.kt b/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/KotlinAlternativeSourceNotificationProvider.kt
index e36c7436a184..e6881f68bfa8 100644
--- a/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/KotlinAlternativeSourceNotificationProvider.kt
+++ b/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/KotlinAlternativeSourceNotificationProvider.kt
@@ -20,7 +20,6 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiManager
import com.intellij.ui.EditorNotificationPanel
import com.intellij.ui.EditorNotificationProvider
-import com.intellij.ui.EditorNotificationProvider.CONST_NULL
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil
import org.jetbrains.kotlin.idea.base.facet.platform.platform
import org.jetbrains.kotlin.idea.base.indices.KotlinPackageIndexUtils.findFilesWithExactPackage
@@ -35,33 +34,33 @@ import javax.swing.JComponent
class KotlinAlternativeSourceNotificationProvider : EditorNotificationProvider {
- override fun collectNotificationData(project: Project, file: VirtualFile): Function {
+ override fun collectNotificationData(project: Project, file: VirtualFile): Function? {
if (!DebuggerSettings.getInstance().SHOW_ALTERNATIVE_SOURCE) {
- return CONST_NULL
+ return null
}
val javaSession = DebuggerManagerEx.getInstanceEx(project).context.debuggerSession
val session = javaSession?.xDebugSession
if (session == null) {
AlternativeSourceNotificationProvider.setFileProcessed(file, false)
- return CONST_NULL
+ return null
}
val position = session.currentPosition
if (file != position?.file) {
AlternativeSourceNotificationProvider.setFileProcessed(file, false)
- return CONST_NULL
+ return null
}
- if (DumbService.getInstance(project).isDumb) return CONST_NULL
+ if (DumbService.getInstance(project).isDumb) return null
- val ktFile = PsiManager.getInstance(project).findFile(file) as? KtFile ?: return CONST_NULL
+ val ktFile = PsiManager.getInstance(project).findFile(file) as? KtFile ?: return null
val alternativeKtFiles = findAlternativeKtFiles(ktFile, project, javaSession)
AlternativeSourceNotificationProvider.setFileProcessed(file, true)
if (alternativeKtFiles.size <= 1) {
- return CONST_NULL
+ return null
}
val currentFirstAlternatives: Collection = listOf(ktFile) + alternativeKtFiles.filter { it != ktFile }
diff --git a/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/inspections/JavaOutsideModuleDetector.kt b/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/inspections/JavaOutsideModuleDetector.kt
index 22ffee1b9fa4..65b7bc78c5f5 100644
--- a/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/inspections/JavaOutsideModuleDetector.kt
+++ b/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/inspections/JavaOutsideModuleDetector.kt
@@ -1,4 +1,4 @@
-// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.inspections
@@ -11,7 +11,6 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.ui.EditorNotificationPanel
import com.intellij.ui.EditorNotificationProvider
-import com.intellij.ui.EditorNotificationProvider.CONST_NULL
import org.jetbrains.kotlin.idea.KotlinJvmBundle
import org.jetbrains.kotlin.idea.base.util.isGradleModule
import org.jetbrains.kotlin.idea.facet.KotlinFacet
@@ -21,16 +20,16 @@ import javax.swing.JComponent
class JavaOutsideModuleDetector : EditorNotificationProvider {
- override fun collectNotificationData(project: Project, file: VirtualFile): Function {
+ override fun collectNotificationData(project: Project, file: VirtualFile): Function? {
if (file.extension != JavaFileType.DEFAULT_EXTENSION && !FileTypeRegistry.getInstance().isFileOfType(file, JavaFileType.INSTANCE)) {
- return CONST_NULL
+ return null
}
- val module = ModuleUtilCore.findModuleForFile(file, project)?.takeIf { it.isGradleModule } ?: return CONST_NULL
- val facetSettings = KotlinFacet.get(module)?.configuration?.settings ?: return CONST_NULL
+ val module = ModuleUtilCore.findModuleForFile(file, project)?.takeIf { it.isGradleModule } ?: return null
+ val facetSettings = KotlinFacet.get(module)?.configuration?.settings ?: return null
val filePath = file.path
val nonKotlinPath = module.sourceRoots.map { it.path } - facetSettings.pureKotlinSourceFolders
- if (nonKotlinPath.any { filePath.startsWith(it) }) return CONST_NULL
+ if (nonKotlinPath.any { filePath.startsWith(it) }) return null
return Function {
EditorNotificationPanel(it, EditorNotificationPanel.Status.Warning).apply {
diff --git a/plugins/kotlin/plugin-updater/src/org/jetbrains/kotlin/idea/versions/UnsupportedAbiVersionNotificationPanelProvider.kt b/plugins/kotlin/plugin-updater/src/org/jetbrains/kotlin/idea/versions/UnsupportedAbiVersionNotificationPanelProvider.kt
index 740d2400009d..5a1a6e79b7e3 100644
--- a/plugins/kotlin/plugin-updater/src/org/jetbrains/kotlin/idea/versions/UnsupportedAbiVersionNotificationPanelProvider.kt
+++ b/plugins/kotlin/plugin-updater/src/org/jetbrains/kotlin/idea/versions/UnsupportedAbiVersionNotificationPanelProvider.kt
@@ -7,7 +7,6 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.compiler.CompilerManager
import com.intellij.openapi.fileEditor.FileEditor
import com.intellij.openapi.fileEditor.OpenFileDescriptor
-import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.project.DumbService
@@ -18,7 +17,6 @@ import com.intellij.openapi.ui.popup.JBPopupFactory
import com.intellij.openapi.ui.popup.PopupStep
import com.intellij.openapi.ui.popup.util.BaseListPopupStep
import com.intellij.openapi.util.NlsContexts
-import com.intellij.openapi.util.Ref
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
@@ -27,7 +25,6 @@ import com.intellij.ui.EditorNotificationProvider.*
import org.jetbrains.annotations.Nls
import org.jetbrains.annotations.NotNull
import org.jetbrains.kotlin.idea.*
-import org.jetbrains.kotlin.idea.base.facet.platform.platform
import org.jetbrains.kotlin.idea.base.util.createComponentActionLabel
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinIdePlugin
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinPluginLayout
@@ -39,8 +36,6 @@ import org.jetbrains.kotlin.idea.util.application.invokeLater
import org.jetbrains.kotlin.idea.util.application.isUnitTestMode
import org.jetbrains.kotlin.idea.util.isKotlinFileType
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
-import org.jetbrains.kotlin.platform.js.isJs
-import org.jetbrains.kotlin.platform.jvm.isJvm
import java.awt.event.ComponentAdapter
import java.awt.event.ComponentEvent
import java.util.function.Function
@@ -215,9 +210,9 @@ class UnsupportedAbiVersionNotificationPanelProvider : EditorNotificationProvide
}
}
- override fun collectNotificationData(project: Project, file: VirtualFile): Function {
+ override fun collectNotificationData(project: Project, file: VirtualFile): Function? {
if (!file.isKotlinFileType()) {
- return CONST_NULL
+ return null
}
try {
if (
@@ -226,14 +221,14 @@ class UnsupportedAbiVersionNotificationPanelProvider : EditorNotificationProvide
|| CompilerManager.getInstance(project).isExcludedFromCompilation(file)
|| KotlinNotConfiguredSuppressedModulesState.isSuppressed(project)
) {
- return CONST_NULL
+ return null
}
- val module = ModuleUtilCore.findModuleForFile(file, project) ?: return CONST_NULL
+ val module = ModuleUtilCore.findModuleForFile(file, project) ?: return null
val badRoots: Collection> = getLibraryRootsWithIncompatibleAbi(module)
.takeUnless(Collection>::isEmpty)
- ?: return CONST_NULL
+ ?: return null
return Function { doCreate(it, project, badRoots) }
} catch (e: ProcessCanceledException) {
@@ -242,7 +237,7 @@ class UnsupportedAbiVersionNotificationPanelProvider : EditorNotificationProvide
DumbService.getInstance(project).runWhenSmart { updateNotifications(project) }
}
- return CONST_NULL
+ return null
}
private fun findBadRootsInRuntimeLibraries(
diff --git a/plugins/kotlin/project-configuration/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupEnvironmentNotificationProvider.kt b/plugins/kotlin/project-configuration/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupEnvironmentNotificationProvider.kt
index 89f71fd7f39d..bef750da6bea 100644
--- a/plugins/kotlin/project-configuration/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupEnvironmentNotificationProvider.kt
+++ b/plugins/kotlin/project-configuration/src/org/jetbrains/kotlin/idea/configuration/KotlinSetupEnvironmentNotificationProvider.kt
@@ -20,7 +20,6 @@ import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import com.intellij.ui.EditorNotificationPanel
import com.intellij.ui.EditorNotificationProvider
-import com.intellij.ui.EditorNotificationProvider.CONST_NULL
import com.intellij.ui.EditorNotifications
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.base.facet.platform.platform
@@ -39,19 +38,19 @@ import javax.swing.JComponent
// Code is partially copied from com.intellij.codeInsight.daemon.impl.SetupSDKNotificationProvider
class KotlinSetupEnvironmentNotificationProvider : EditorNotificationProvider {
- override fun collectNotificationData(project: Project, file: VirtualFile): Function {
+ override fun collectNotificationData(project: Project, file: VirtualFile): Function? {
if (!file.isKotlinFileType()) {
- return CONST_NULL
+ return null
}
- val psiFile = PsiManager.getInstance(project).findFile(file) as? KtFile ?: return CONST_NULL
+ val psiFile = PsiManager.getInstance(project).findFile(file) as? KtFile ?: return null
if (psiFile.language !== KotlinLanguage.INSTANCE) {
- return CONST_NULL
+ return null
}
- val module = ModuleUtilCore.findModuleForPsiElement(psiFile) ?: return CONST_NULL
+ val module = ModuleUtilCore.findModuleForPsiElement(psiFile) ?: return null
if (!ModuleRootManager.getInstance(module).fileIndex.isInSourceContent(file)) {
- return CONST_NULL
+ return null
}
if (ModuleRootManager.getInstance(module).sdk == null && psiFile.platform.isJvm()) {
@@ -68,7 +67,7 @@ class KotlinSetupEnvironmentNotificationProvider : EditorNotificationProvider {
return createKotlinNotConfiguredPanel(module, getAbleToRunConfigurators(module).toList())
}
- return CONST_NULL
+ return null
}
companion object {
diff --git a/python/src/com/jetbrains/python/sdk/PyEditorNotificationProvider.java b/python/src/com/jetbrains/python/sdk/PyEditorNotificationProvider.java
index f03af66bf510..be930ecac58f 100644
--- a/python/src/com/jetbrains/python/sdk/PyEditorNotificationProvider.java
+++ b/python/src/com/jetbrains/python/sdk/PyEditorNotificationProvider.java
@@ -100,14 +100,14 @@ public final class PyEditorNotificationProvider implements DumbAware, EditorNoti
}
@Override
- public @NotNull Function super @NotNull FileEditor, ? extends @Nullable JComponent> collectNotificationData(@NotNull Project project,
+ public @Nullable Function super @NotNull FileEditor, ? extends @Nullable JComponent> collectNotificationData(@NotNull Project project,
@NotNull VirtualFile file) {
PyFile node = getPyFile(project, file);
if (node == null) {
- return CONST_NULL;
+ return null;
}
Module module = guessModule(node);
- if (module == null || isFileIgnored(node)) return CONST_NULL;
+ if (module == null || isFileIgnored(node)) return null;
final Sdk sdk = PythonSdkUtil.findPythonSdk(module);
final boolean pyCharm = PythonIdeLanguageCustomization.isMainlyPythonIde();
@@ -165,7 +165,7 @@ public final class PyEditorNotificationProvider implements DumbAware, EditorNoti
}
}
}
- return CONST_NULL;
+ return null;
}
private static Function super @NotNull FileEditor, ? extends @Nullable JComponent> registerProblemWithCommonFixes(PyFile node,
diff --git a/python/testSrc/com/jetbrains/python/sdk/PythonNoSdkEditorNotificationTest.kt b/python/testSrc/com/jetbrains/python/sdk/PythonNoSdkEditorNotificationTest.kt
index 49fdb6740f2b..bdddf36c4ada 100644
--- a/python/testSrc/com/jetbrains/python/sdk/PythonNoSdkEditorNotificationTest.kt
+++ b/python/testSrc/com/jetbrains/python/sdk/PythonNoSdkEditorNotificationTest.kt
@@ -1,14 +1,18 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+@file:Suppress("ReplaceGetOrSet")
+
package com.jetbrains.python.sdk
import com.intellij.openapi.fileEditor.FileEditor
import com.intellij.openapi.fileEditor.FileEditorManager
+import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ModuleRootModificationUtil
import com.intellij.openapi.util.Disposer
import com.intellij.psi.PsiFile
+import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.fixtures.CodeInsightTestFixture
+import com.intellij.ui.EditorNotifications
import com.intellij.ui.EditorNotificationsImpl
-import com.intellij.util.ui.UIUtil
import com.jetbrains.extensions.getSdk
import com.jetbrains.python.fixtures.PyTestCase
import org.assertj.core.api.AssertionsForClassTypes
@@ -32,7 +36,7 @@ class PythonNoSdkEditorNotificationTest : PyTestCase() {
}
val editor = openFileInEditor(fileName, fileText, fixture)
- val notificationPanel = getNotificationPanel(editor)
+ val notificationPanel = getNotificationPanel(editor, fixture.project)
if (!sdkPresent && notificationPanel == null) {
fail("\"No SDK notification\" expected")
}
@@ -45,13 +49,15 @@ class PythonNoSdkEditorNotificationTest : PyTestCase() {
}
}
- private fun getNotificationPanel(fileEditor: FileEditor): JComponent? {
- return EditorNotificationsImpl.getNotificationPanels(fileEditor).get(PyEditorNotificationProvider::class.java)
+ private fun getNotificationPanel(fileEditor: FileEditor, project: Project): JComponent? {
+ return (EditorNotifications.getInstance(project) as EditorNotificationsImpl).getNotificationPanels(fileEditor)
+ .get(PyEditorNotificationProvider::class.java)
}
- fun openFileInEditor(fileName: String, fileText: String, fixture: CodeInsightTestFixture) : FileEditor {
- UIUtil.dispatchAllInvocationEvents()
- EditorNotificationsImpl.completeAsyncTasks(fixture.getProject())
+ private fun openFileInEditor(fileName: String, fileText: String, fixture: CodeInsightTestFixture) : FileEditor {
+ PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue()
+ val editorNotifications = EditorNotifications.getInstance(fixture.project) as EditorNotificationsImpl
+ editorNotifications.completeAsyncTasks()
val psiFile: PsiFile = fixture.configureByText(fileName, fileText)
val fileEditorManager = FileEditorManager.getInstance(fixture.project)
@@ -63,8 +69,8 @@ class PythonNoSdkEditorNotificationTest : PyTestCase() {
val editors = fileEditorManager.openFile(virtualFile, true)
AssertionsForClassTypes.assertThat(editors).hasSize(1)
- UIUtil.dispatchAllInvocationEvents()
- EditorNotificationsImpl.completeAsyncTasks(fixture.getProject())
+ PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue()
+ editorNotifications.completeAsyncTasks()
return editors[0]
}