From d7930acdcaa8b139c67afb4e19ae6102bb9464d7 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 24 Apr 2020 13:23:27 +0200 Subject: [PATCH] get rid of alien lifetime extension functions for disposable - rd module exposed to the whole API, so, get rid of it GitOrigin-RevId: e50d801c1c392f3675f158c755beb09175a61404 --- .../com/intellij/openapi/rd/DisposableEx.kt | 77 ++++++++----------- .../intellij/openapi/rd/DisposableExKt.java | 7 +- .../openapi/rd/LifetimeDisposableEx.kt | 7 +- .../util/ui/cloneDialog/VcsCloneDialog.kt | 6 +- .../LegacyBridgeFilePointerProviderImpl.kt | 6 +- .../module/RootModelViaTypedEntityImpl.kt | 11 ++- .../GHCloneDialogExtensionComponent.kt | 4 +- 7 files changed, 56 insertions(+), 62 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/rd/DisposableEx.kt b/platform/platform-api/src/com/intellij/openapi/rd/DisposableEx.kt index 22aff12ec043..2cc80f6360c8 100644 --- a/platform/platform-api/src/com/intellij/openapi/rd/DisposableEx.kt +++ b/platform/platform-api/src/com/intellij/openapi/rd/DisposableEx.kt @@ -1,75 +1,62 @@ // 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. @file:JvmName("DisposableEx") + package com.intellij.openapi.rd import com.intellij.openapi.Disposable import com.intellij.openapi.util.Disposer -import com.intellij.openapi.util.use import com.jetbrains.rd.util.lifetime.Lifetime import com.jetbrains.rd.util.lifetime.LifetimeDefinition import com.jetbrains.rd.util.lifetime.isAlive import com.jetbrains.rd.util.lifetime.onTermination import org.jetbrains.annotations.ApiStatus - -@Deprecated("Use implementation from `intellij.platform.util.ex` instead.", ReplaceWith("disposable.use(block)")) -inline fun using(disposable: Disposable, block: () -> Unit): Unit = disposable.use { block() } - @ApiStatus.ScheduledForRemoval(inVersion = "2020.2") @Deprecated("Use version from `LifetimeDisposableEx`") -internal fun Disposable.defineNestedLifetime(): LifetimeDefinition { - val lifetimeDefinition = Lifetime.Eternal.createNested() - if (Disposer.isDisposing(this) || Disposer.isDisposed(this)) { - lifetimeDefinition.terminate() - return lifetimeDefinition - } - - this.attach { if (lifetimeDefinition.lifetime.isAlive) lifetimeDefinition.terminate() } +fun defineNestedLifetime(disposable: Disposable): LifetimeDefinition { + val lifetimeDefinition = Lifetime.Eternal.createNested() + if (Disposer.isDisposing(disposable) || Disposer.isDisposed(disposable)) { + lifetimeDefinition.terminate() return lifetimeDefinition + } + + disposable.attach { if (lifetimeDefinition.lifetime.isAlive) lifetimeDefinition.terminate() } + return lifetimeDefinition } @ApiStatus.ScheduledForRemoval(inVersion = "2020.2") @Deprecated("Use version from `LifetimeDisposableEx`") -internal fun Disposable.createLifetime(): Lifetime = this.defineNestedLifetime().lifetime +internal fun doIfAlive(disposable: Disposable, action: (Lifetime) -> Unit) { + val disposableLifetime: Lifetime? + if (Disposer.isDisposed(disposable)) { + return + } + try { + disposableLifetime = defineNestedLifetime(disposable).lifetime + } + catch (t: Throwable) { + //do nothing, there is no other way to handle disposables + return + } - -@ApiStatus.ScheduledForRemoval(inVersion = "2020.2") -@Deprecated("Use version from `LifetimeDisposableEx`") -internal fun Disposable.doIfAlive(action: (Lifetime) -> Unit) { - val disposableLifetime: Lifetime? - if (Disposer.isDisposed(this)) return - - try { - disposableLifetime = this.createLifetime() - } - catch (t: Throwable) { - //do nothing, there is no other way to handle disposables - return - } - - action(disposableLifetime) + action(disposableLifetime) } @ApiStatus.ScheduledForRemoval(inVersion = "2020.2") @Deprecated("Use version from `LifetimeDisposableEx`") internal fun Lifetime.createNestedDisposable(debugName: String = "lifetimeToDisposable"): Disposable { - val d = Disposer.newDisposable(debugName) - - this.onTermination { - Disposer.dispose(d) - } - return d -} - -fun Disposable.attachChild(disposable: Disposable) { - Disposer.register(this, disposable) + val d = Disposer.newDisposable(debugName) + this.onTermination { + Disposer.dispose(d) + } + return d } @Suppress("ObjectLiteralToLambda") // non-object lambdas fuck up the disposer fun Disposable.attach(disposable: () -> Unit) { - Disposer.register(this, object : Disposable { - override fun dispose() { - disposable() - } - }) + Disposer.register(this, object : Disposable { + override fun dispose() { + disposable() + } + }) } \ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/openapi/rd/DisposableExKt.java b/platform/platform-api/src/com/intellij/openapi/rd/DisposableExKt.java index f7309fa67ed7..dd88b102ce97 100644 --- a/platform/platform-api/src/com/intellij/openapi/rd/DisposableExKt.java +++ b/platform/platform-api/src/com/intellij/openapi/rd/DisposableExKt.java @@ -2,6 +2,7 @@ package com.intellij.openapi.rd; import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.Disposer; import com.jetbrains.rd.util.lifetime.Lifetime; import com.jetbrains.rd.util.lifetime.LifetimeDefinition; import kotlin.Unit; @@ -27,11 +28,11 @@ public final class DisposableExKt { @ApiStatus.ScheduledForRemoval(inVersion = "2020.2") @Deprecated public static Lifetime createLifetime(Disposable disposable) { - return DisposableEx.createLifetime(disposable); + return DisposableEx.defineNestedLifetime(disposable).getLifetime(); } /** - * @deprecated Use version from `LifetimeDisposableEx` + * @deprecated Use version from `LifetimeDisposableEx` */ @ApiStatus.ScheduledForRemoval(inVersion = "2020.2") @Deprecated @@ -74,7 +75,7 @@ public final class DisposableExKt { @ApiStatus.ScheduledForRemoval(inVersion = "2020.3") @Deprecated public static void attachChild(Disposable parent, Disposable child) { - DisposableEx.attachChild(parent, child); + Disposer.register(parent, child); } /** diff --git a/platform/rd-platform-community/src/com/intellij/openapi/rd/LifetimeDisposableEx.kt b/platform/rd-platform-community/src/com/intellij/openapi/rd/LifetimeDisposableEx.kt index 3cbe3e505fb1..68ae28c61de6 100644 --- a/platform/rd-platform-community/src/com/intellij/openapi/rd/LifetimeDisposableEx.kt +++ b/platform/rd-platform-community/src/com/intellij/openapi/rd/LifetimeDisposableEx.kt @@ -19,15 +19,14 @@ fun Disposable.defineNestedLifetime(): LifetimeDefinition { return lifetimeDefinition } -fun Disposable.createLifetime(): Lifetime = this.defineNestedLifetime().lifetime - fun Disposable.doIfAlive(action: (Lifetime) -> Unit) { val disposableLifetime: Lifetime? if(Disposer.isDisposed(this)) return try { - disposableLifetime = this.createLifetime() - } catch(t : Throwable){ + disposableLifetime = defineNestedLifetime(this).lifetime + } + catch(t : Throwable){ //do nothing, there is no other way to handle disposables return } diff --git a/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialog.kt b/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialog.kt index e91ca9d710c0..b72d88e00d37 100644 --- a/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialog.kt +++ b/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialog.kt @@ -1,11 +1,11 @@ -// Copyright 2000-2019 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-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. package com.intellij.util.ui.cloneDialog import com.intellij.openapi.application.ModalityState import com.intellij.openapi.project.Project -import com.intellij.openapi.rd.attachChild import com.intellij.openapi.ui.DialogWrapper import com.intellij.openapi.ui.ValidationInfo +import com.intellij.openapi.util.Disposer import com.intellij.openapi.vcs.CheckoutProvider import com.intellij.openapi.vcs.VcsBundle import com.intellij.openapi.vcs.ui.cloneDialog.VcsCloneDialogComponentStateListener @@ -91,7 +91,7 @@ class VcsCloneDialog private constructor(private val project: Project, val mainComponent = extensionComponents.getOrPut(extensionId, { val component = extension.createMainComponent(project, ModalityState.stateForComponent(window)) mainPanel.add(component.getView(), extensionId) - disposable.attachChild(component) + Disposer.register(disposable, component) component.addComponentStateListener(listener) component }) diff --git a/platform/workspaceModel-ide/src/com/intellij/workspace/legacyBridge/intellij/LegacyBridgeFilePointerProviderImpl.kt b/platform/workspaceModel-ide/src/com/intellij/workspace/legacyBridge/intellij/LegacyBridgeFilePointerProviderImpl.kt index 20ceb8831512..61be7abc4b90 100644 --- a/platform/workspaceModel-ide/src/com/intellij/workspace/legacyBridge/intellij/LegacyBridgeFilePointerProviderImpl.kt +++ b/platform/workspaceModel-ide/src/com/intellij/workspace/legacyBridge/intellij/LegacyBridgeFilePointerProviderImpl.kt @@ -1,8 +1,8 @@ +// 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. package com.intellij.workspace.legacyBridge.intellij import com.intellij.openapi.Disposable import com.intellij.openapi.project.Project -import com.intellij.openapi.rd.attachChild import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.Pair import com.intellij.openapi.vfs.AsyncFileListener @@ -121,7 +121,9 @@ internal class LegacyBridgeFilePointerProviderImpl(project: Project) : LegacyBri } } - private fun nextDisposable() = Disposer.newDisposable().also { this.attachChild(it) } + private fun nextDisposable() = Disposer.newDisposable().also { + Disposer.register(this, it) + } private class ReadonlyFilePointerContainer(val container: VirtualFilePointerContainer) : VirtualFilePointerContainer { private fun throwReadonly(): Nothing = throw NotImplementedError("Read-Only File Pointer Container") diff --git a/platform/workspaceModel-ide/src/com/intellij/workspace/legacyBridge/typedModel/module/RootModelViaTypedEntityImpl.kt b/platform/workspaceModel-ide/src/com/intellij/workspace/legacyBridge/typedModel/module/RootModelViaTypedEntityImpl.kt index 1ff82d7433fa..294dc3d76bc8 100644 --- a/platform/workspaceModel-ide/src/com/intellij/workspace/legacyBridge/typedModel/module/RootModelViaTypedEntityImpl.kt +++ b/platform/workspaceModel-ide/src/com/intellij/workspace/legacyBridge/typedModel/module/RootModelViaTypedEntityImpl.kt @@ -1,9 +1,9 @@ +// 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. package com.intellij.workspace.legacyBridge.typedModel.module import com.intellij.configurationStore.deserializeAndLoadState import com.intellij.openapi.Disposable import com.intellij.openapi.components.PersistentStateComponent -import com.intellij.openapi.rd.attachChild import com.intellij.openapi.roots.CompilerModuleExtension import com.intellij.openapi.roots.ModuleExtension import com.intellij.openapi.roots.OrderEntry @@ -13,6 +13,7 @@ import com.intellij.openapi.roots.impl.RootConfigurationAccessor import com.intellij.openapi.roots.impl.RootModelBase import com.intellij.openapi.roots.libraries.LibraryTable import com.intellij.openapi.util.Comparing +import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.JDOMUtil import com.intellij.workspace.api.* import com.intellij.workspace.legacyBridge.intellij.LegacyBridgeCompilerModuleExtension @@ -149,7 +150,9 @@ internal class RootModelViaTypedEntityImpl(internal val moduleEntityId: Persiste val readOnlyExtension = loadExtension(extension, parentDisposable, rootManagerElement) if (writable) { - val modifiableExtension = readOnlyExtension.getModifiableModel(true).also { parentDisposable.attachChild(it) } + val modifiableExtension = readOnlyExtension.getModifiableModel(true).also { + Disposer.register(parentDisposable, it) + } result.add(modifiableExtension) } else { result.add(readOnlyExtension) @@ -162,7 +165,9 @@ internal class RootModelViaTypedEntityImpl(internal val moduleEntityId: Persiste internal fun loadExtension(extension: ModuleExtension, parentDisposable: Disposable, rootManagerElement: @NotNull Element?): @NotNull ModuleExtension { - val readOnlyExtension = extension.getModifiableModel(false).also { parentDisposable.attachChild(it) } + val readOnlyExtension = extension.getModifiableModel(false).also { + Disposer.register(parentDisposable, it) + } if (rootManagerElement != null) { if (readOnlyExtension is PersistentStateComponent<*>) { diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/cloneDialog/GHCloneDialogExtensionComponent.kt b/plugins/github/src/org/jetbrains/plugins/github/ui/cloneDialog/GHCloneDialogExtensionComponent.kt index 8497e2eadafc..bbd5b39378fc 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/cloneDialog/GHCloneDialogExtensionComponent.kt +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/cloneDialog/GHCloneDialogExtensionComponent.kt @@ -19,9 +19,9 @@ import com.intellij.openapi.progress.Task import com.intellij.openapi.project.DumbAwareAction import com.intellij.openapi.project.Project import com.intellij.openapi.project.ProjectManager -import com.intellij.openapi.rd.attachChild import com.intellij.openapi.ui.DialogPanel import com.intellij.openapi.ui.ValidationInfo +import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.vcs.CheckoutProvider import com.intellij.openapi.vcs.ui.cloneDialog.VcsCloneDialogExtensionComponent @@ -151,7 +151,7 @@ internal class GHCloneDialogExtensionComponent( override fun getModalityState() = ModalityState.any() } - this.attachChild(progressManager) + Disposer.register(this, progressManager) ApplicationManager.getApplication().messageBus.connect(this).apply { subscribe(GithubAccountManager.ACCOUNT_REMOVED_TOPIC, object : AccountRemovedListener {