[space] IDEA-260768: Fix memory leak in SpaceReviewToolWindowFactory

SpaceReviewToolWindowFactory shouldn't be disposable

GitOrigin-RevId: 6e137524bf96d1e0732d8302d01b810e46b46ee3
This commit is contained in:
Aleksandr Krasilnikov
2021-02-03 19:52:52 +00:00
committed by intellij-monorepo-bot
parent 85fd4be0f7
commit c02fe09398
2 changed files with 44 additions and 54 deletions
@@ -1,12 +1,12 @@
// Copyright 2000-2021 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.space.vcs.review
import circlet.workspaces.Workspace
import com.intellij.openapi.Disposable
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import com.intellij.space.components.SpaceWorkspaceComponent
import com.intellij.openapi.wm.ToolWindow
import com.intellij.openapi.wm.ToolWindowManager
import com.intellij.space.utils.LifetimedDisposable
import com.intellij.space.utils.LifetimedDisposableImpl
import com.intellij.space.vcs.Context
@@ -23,10 +23,24 @@ import runtime.reactive.Property
import runtime.reactive.property.mapInit
@Service
internal class SpaceCodeReviewTabManager(private val project: Project): LifetimedDisposable by LifetimedDisposableImpl() {
internal class SpaceCodeReviewTabManager(private val project: Project) : LifetimedDisposable by LifetimedDisposableImpl() {
private var myReviewTabContentManager: SpaceCodeReviewTabContentManager? = null
init {
project.service<SpaceProjectContext>().context.forEach(lifetime) { context ->
val toolWindow: ToolWindow = ToolWindowManager
.getInstance(project)
.getToolWindow(SpaceReviewToolWindowFactory.ID) ?: return@forEach
val isAvailable = context.isAssociatedWithSpaceRepository
if (isAvailable && !toolWindow.isAvailable) {
toolWindow.isShowStripeButton = true
}
toolWindow.isAvailable = isAvailable
}
}
companion object {
fun getInstance(project: Project): SpaceCodeReviewTabManager = project.service()
}
@@ -38,40 +52,39 @@ internal class SpaceCodeReviewTabManager(private val project: Project): Lifetime
}
}
internal class SpaceCodeReviewTabContentManager(private val project: Project, private val cm: ContentManager, lifetime: Lifetime) {
private val workspace: Property<Workspace?> = SpaceWorkspaceComponent.getInstance().workspace
internal class SpaceCodeReviewTabContentManager(private val project: Project,
private val contentManager: ContentManager,
lifetime: Lifetime) {
private val context: Property<Context> = SpaceProjectContext.getInstance(project).context
private val contents: Property<MutableMap<SpaceProjectInfo, Content>> =
lifetime.mapInit(workspace, context, mutableMapOf()) { ws, context ->
if (ws == null) {
return@mapInit mutableMapOf<SpaceProjectInfo, Content>()
}
if (!context.isAssociatedWithSpaceRepository) {
return@mapInit mutableMapOf<SpaceProjectInfo, Content>()
}
val result = HashMap<SpaceProjectInfo, Content>()
context.reposInProject.forEach {
val content = createContent(project, it.key, it.value)
result[it.key] = content
}
result
private val contents: Property<MutableMap<SpaceProjectInfo, Content>> = lifetime.mapInit(context, mutableMapOf()) { context ->
if (!context.isAssociatedWithSpaceRepository) {
return@mapInit mutableMapOf<SpaceProjectInfo, Content>()
}
val result = HashMap<SpaceProjectInfo, Content>()
context.reposInProject.forEach {
val content = createContent(project, it.key, it.value)
result[it.key] = content
}
result
}
init {
contents.forEachWithPrevious(lifetime) { prev, next ->
prev?.keys
?.filter { key -> !next.keys.contains(key) }.orEmpty()
contents.forEachWithPrevious(lifetime) { prev: MutableMap<SpaceProjectInfo, Content>?, next: MutableMap<SpaceProjectInfo, Content> ->
val previous = prev ?: emptyMap()
previous.keys
.filter { key -> !next.keys.contains(key) }
.forEach {
cm.removeContent(prev?.get(it)!!, true)
val content = previous[it]!!
contentManager.removeContent(content, true)
}
next.keys.filter { key -> !(prev?.contains(key) ?: false) }
next.keys.filter { key -> !previous.contains(key) }
.forEach {
cm.addContent(next[it]!!)
cm.setSelectedContent(next[it]!!)
val content = next[it]!!
contentManager.addContent(content)
contentManager.setSelectedContent(content)
}
}
}
@@ -7,32 +7,10 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.wm.ToolWindow
import com.intellij.openapi.wm.ToolWindowFactory
import com.intellij.openapi.wm.ex.ToolWindowEx
import com.intellij.space.components.SpaceWorkspaceComponent
import com.intellij.space.utils.LifetimedDisposable
import com.intellij.space.utils.LifetimedDisposableImpl
import com.intellij.space.vcs.SpaceProjectContext
import runtime.reactive.property.mapInit
internal class SpaceReviewToolWindowFactory : ToolWindowFactory, DumbAware, LifetimedDisposable by LifetimedDisposableImpl() {
internal class SpaceReviewToolWindowFactory : ToolWindowFactory, DumbAware {
override fun init(toolWindow: ToolWindow) {
super.init(toolWindow)
val project = (toolWindow as ToolWindowEx).project
val workspace = SpaceWorkspaceComponent.getInstance().workspace
val spaceProjectContext = SpaceProjectContext.getInstance(project).context
val isToolwindowAvailable = lifetime.mapInit(workspace, spaceProjectContext, false) { ws, context ->
ws ?: return@mapInit false
return@mapInit context.isAssociatedWithSpaceRepository
}
isToolwindowAvailable.forEach(lifetime) { isAvailable ->
if (isAvailable && !toolWindow.isAvailable) {
toolWindow.isShowStripeButton = true
}
toolWindow.isAvailable = isAvailable
}
(toolWindow as ToolWindowEx).project.service<SpaceCodeReviewTabManager>()
}
override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) {
@@ -41,8 +19,7 @@ internal class SpaceReviewToolWindowFactory : ToolWindowFactory, DumbAware, Life
spaceCodeReviewTabManager.showReviews(toolWindow.contentManager)
}
override fun shouldBeAvailable(project: Project): Boolean =
SpaceProjectContext.getInstance(project).context.value.isAssociatedWithSpaceRepository
override fun shouldBeAvailable(project: Project): Boolean = false
override fun isDoNotActivateOnStart(): Boolean = true