diff --git a/idea/idea-gradle-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativeABICompatibilityChecker.kt b/idea/idea-gradle-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativeABICompatibilityChecker.kt index deff2522ad4..8d52a0a7331 100644 --- a/idea/idea-gradle-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativeABICompatibilityChecker.kt +++ b/idea/idea-gradle-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativeABICompatibilityChecker.kt @@ -12,11 +12,13 @@ import com.intellij.openapi.Disposable import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ModalityState import com.intellij.openapi.application.ReadAction.nonBlocking -import com.intellij.openapi.components.ProjectComponent import com.intellij.openapi.project.Project import com.intellij.openapi.project.guessProjectDir import com.intellij.openapi.roots.ModuleRootEvent import com.intellij.openapi.roots.ModuleRootListener +import com.intellij.openapi.startup.StartupActivity +import com.intellij.openapi.util.Disposer +import com.intellij.openapi.util.Ref import com.intellij.openapi.util.text.StringUtilRt import com.intellij.util.PathUtilRt import com.intellij.util.concurrency.AppExecutorUtil @@ -29,8 +31,9 @@ import org.jetbrains.kotlin.idea.versions.UnsupportedAbiVersionNotificationPanel import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME +// BUNCH: 192 /** TODO: merge [KotlinNativeABICompatibilityChecker] in the future with [UnsupportedAbiVersionNotificationPanelProvider], KT-34525 */ -class KotlinNativeABICompatibilityChecker(private val project: Project) : ProjectComponent, Disposable { +class KotlinNativeABICompatibilityChecker : StartupActivity { private sealed class LibraryGroup(private val ordinal: Int) : Comparable { @@ -47,46 +50,46 @@ class KotlinNativeABICompatibilityChecker(private val project: Project) : Projec private val cachedIncompatibleLibraries = HashSet() - @Volatile - private var backgroundJob: CancellablePromise<*>? = null - - init { + override fun runActivity(project: Project) { project.messageBus.connect().subscribe(ProjectTopics.PROJECT_ROOTS, object : ModuleRootListener { override fun rootsChanged(event: ModuleRootEvent) { // run when project roots are changes, e.g. on project import - validateKotlinNativeLibraries() + validateKotlinNativeLibraries(project) } }) + + validateKotlinNativeLibraries(project) } - override fun projectOpened() { - // run when project is opened - validateKotlinNativeLibraries() - } - - private fun validateKotlinNativeLibraries() { + private fun validateKotlinNativeLibraries(project: Project) { if (ApplicationManager.getApplication().isUnitTestMode || project.isDisposed) return - backgroundJob = nonBlocking> { - val librariesToNotify = getLibrariesToNotifyAbout() - prepareNotifications(librariesToNotify) - } - .finishOnUiThread(ModalityState.defaultModalityState()) { notifications -> - notifications.forEach { - it.notify(project) + val backgroundJob: Ref> = Ref() + val disposable = Disposable { backgroundJob.get()?.let(CancellablePromise<*>::cancel) } + Disposer.register(project, disposable) + + backgroundJob.set( + nonBlocking> { + val librariesToNotify = getLibrariesToNotifyAbout(project) + prepareNotifications(project, librariesToNotify) + } + .finishOnUiThread(ModalityState.defaultModalityState()) { notifications -> + notifications.forEach { + it.notify(project) + } } - } - .expireWith(project) // cancel job when project is disposed - .coalesceBy(this@KotlinNativeABICompatibilityChecker) // cancel previous job when new one is submitted - .withDocumentsCommitted(project) - .submit(AppExecutorUtil.getAppExecutorService()) - .onProcessed { - backgroundJob = null - } + .expireWith(project) // cancel job when project is disposed + .coalesceBy(this@KotlinNativeABICompatibilityChecker) // cancel previous job when new one is submitted + .withDocumentsCommitted(project) + .submit(AppExecutorUtil.getAppExecutorService()) + .onProcessed { + backgroundJob.set(null) + Disposer.dispose(disposable) + }) } - private fun getLibrariesToNotifyAbout(): Map { + private fun getLibrariesToNotifyAbout(project: Project): Map { val incompatibleLibraries = getModuleInfosFromIdeaModel(project) .filterIsInstance() .filter { !it.compatibilityInfo.isCompatible } @@ -103,7 +106,7 @@ class KotlinNativeABICompatibilityChecker(private val project: Project) : Projec return newEntries } - private fun prepareNotifications(librariesToNotify: Map): List { + private fun prepareNotifications(project: Project, librariesToNotify: Map): List { if (librariesToNotify.isEmpty()) return emptyList() @@ -201,13 +204,6 @@ class KotlinNativeABICompatibilityChecker(private val project: Project) : Projec return (ideLibraryName ?: PathUtilRt.getFileName(libraryInfo.libraryRoot)) to LibraryGroup.User } - override fun dispose() { - backgroundJob?.let(CancellablePromise<*>::cancel) - backgroundJob = null - - cachedIncompatibleLibraries.clear() - } - companion object { private val LIBRARY_NAME_COMPARATOR = Comparator { libraryName1, libraryName2 -> when { diff --git a/idea/idea-gradle-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativeABICompatibilityChecker.kt.192 b/idea/idea-gradle-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativeABICompatibilityChecker.kt.192 index 971426eaddd..83a3cb99ccf 100644 --- a/idea/idea-gradle-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativeABICompatibilityChecker.kt.192 +++ b/idea/idea-gradle-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativeABICompatibilityChecker.kt.192 @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME import org.jetbrains.kotlin.idea.klib.KlibCompatibilityInfo.IncompatibleMetadata +// BUNCH: 192 /** TODO: merge [KotlinNativeABICompatibilityChecker] in the future with [UnsupportedAbiVersionNotificationPanelProvider], KT-34525 */ class KotlinNativeABICompatibilityChecker(private val project: Project) : ProjectComponent, Disposable {