after first load project run configurations, we must sort resulting list

This commit is contained in:
Vladimir Krivosheev
2017-08-18 17:49:14 +02:00
parent a9a5843354
commit 4ba795e7a8
4 changed files with 18 additions and 92 deletions
@@ -17,13 +17,9 @@ package com.intellij.execution.impl
import com.intellij.execution.IS_RUN_MANAGER_INITIALIZED
import com.intellij.execution.RunManager
import com.intellij.execution.configurations.UnknownRunConfiguration
import com.intellij.openapi.components.*
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.impl.ProjectLifecycleListener
import com.intellij.openapi.util.Pair
import gnu.trove.THashSet
import org.jdom.Element
internal class ProjectRunConfigurationInitializer(project: Project) {
init {
@@ -45,45 +41,6 @@ internal class ProjectRunConfigurationInitializer(project: Project) {
IS_RUN_MANAGER_INITIALIZED.set(project, true)
// we must not fire beginUpdate here, because message bus will fire queued parent message bus messages (and, so, SOE may occur because all other projectOpened will be processed before us)
// simply, you should not listen changes until project opened
if (isUseProjectSchemeManager()) {
project.service<RunManager>()
}
else {
project.service<ProjectRunConfigurationManager>()
}
project.service<RunManager>()
}
}
@State(name = "ProjectRunConfigurationManager", storages = arrayOf(Storage(value = "runConfigurations", stateSplitter = OldProjectRunConfigurationStateSplitter::class)))
private class ProjectRunConfigurationManager(manager: RunManager) : PersistentStateComponent<Element> {
private val manager = manager as RunManagerImpl
override fun getState(): Element? {
val state = Element("state")
manager.writeConfigurations(state, manager.getSharedConfigurations())
return state
}
override fun loadState(state: Element) {
val existing = THashSet<String>()
state.getChildren(RunManagerImpl.CONFIGURATION).mapTo(existing) {
manager.loadConfiguration(it, true).uniqueID
}
manager.removeNotExistingSharedConfigurations(existing)
manager.requestSort()
if (manager.selectedConfiguration == null) {
for (settings in manager.allSettings) {
if (settings.type !is UnknownRunConfiguration) {
manager.selectedConfiguration = settings
break
}
}
}
}
}
internal class OldProjectRunConfigurationStateSplitter : StateSplitterEx() {
override fun splitState(state: Element): List<Pair<Element, String>> = StateSplitterEx.splitState(state, RunManagerImpl.NAME_ATTR)
}
@@ -129,7 +129,7 @@ open class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persi
private val workspaceSchemeManager = SchemeManagerFactory.getInstance(project).create("workspace", RunConfigurationSchemeManager(this, false), streamProvider = workspaceSchemeManagerProvider, autoSave = false)
@Suppress("LeakingThis")
private var projectSchemeManager = if (isUseProjectSchemeManager()) SchemeManagerFactory.getInstance(project).create("runConfigurations", RunConfigurationSchemeManager(this, true), isUseOldFileNameSanitize = true) else null
private var projectSchemeManager = SchemeManagerFactory.getInstance(project).create("runConfigurations", RunConfigurationSchemeManager(this, true), isUseOldFileNameSanitize = true)
private val isFirstLoadState = AtomicBoolean(true)
@@ -282,7 +282,7 @@ open class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persi
refreshUsagesList(settings)
}
else {
(if (settings.isShared) workspaceSchemeManager else projectSchemeManager)?.removeScheme(settings as RunnerAndConfigurationSettingsImpl)
(if (settings.isShared) workspaceSchemeManager else projectSchemeManager).removeScheme(settings as RunnerAndConfigurationSettingsImpl)
}
// scheme level can be changed (workspace -> project), so, ensure that scheme is added to corresponding scheme manager (if exists, doesn't harm)
@@ -357,7 +357,7 @@ open class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persi
}
// comparator is null if want just to save current order (e.g. if want to keep order even after reload)
// yes, on hot reload, because our ProjectRunConfigurationManager doesn't use SchemeManager and change of some RC file leads to reload of all configurations
// yes, on hot reload, because our DeprecatedProjectRunConfigurationManager doesn't use SchemeManager and change of some RC file leads to reload of all configurations
fun setOrder(comparator: Comparator<RunnerAndConfigurationSettings>?) {
lock.write {
val sorted = idToSettings.values.filterTo(ArrayList(idToSettings.size)) { it.type !is UnknownConfigurationType }
@@ -610,7 +610,8 @@ open class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persi
override fun noStateLoaded() {
isFirstLoadState.set(false)
projectSchemeManager?.loadSchemes()
projectSchemeManager.loadSchemes()
projectRunConfigurationFirstLoaded()
}
override fun loadState(parentNode: Element) {
@@ -649,7 +650,7 @@ open class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persi
customOrder.ensureCapacity(order.size)
order.mapIndexed { index, id -> customOrder.put(id, index) }
// ProjectRunConfigurationManager will not call requestSort if no shared configurations
// DeprecatedProjectRunConfigurationManager will not call requestSort if no shared configurations
requestSort()
recentlyUsedTemporaries.clear()
@@ -670,7 +671,8 @@ open class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persi
}
if (isFirstLoadState) {
projectSchemeManager?.loadSchemes()
projectSchemeManager.loadSchemes()
projectRunConfigurationFirstLoaded()
}
fireBeforeRunTasksUpdated()
@@ -680,6 +682,13 @@ open class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persi
}
}
private fun projectRunConfigurationFirstLoaded() {
requestSort()
if (selectedConfiguration == null) {
selectedConfiguration = allSettings.firstOrNull { it.type !is UnknownRunConfiguration }
}
}
fun readContext(parentNode: Element) {
var selectedConfigurationId = parentNode.getAttributeValue(SELECTED_ATTR)
@@ -828,19 +837,6 @@ open class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persi
}
}
fun getSharedConfigurations(): List<RunnerAndConfigurationSettings> {
var result: MutableList<RunnerAndConfigurationSettings>? = null
for (configuration in allSettings) {
if (configuration.isShared) {
if (result == null) {
result = ArrayList()
}
result.add(configuration)
}
}
return result ?: emptyList()
}
override val tempConfigurationsList: List<RunnerAndConfigurationSettings>
get() = allSettings.filterSmart { it.isTemporary }
@@ -1099,28 +1095,6 @@ open class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persi
}
}
fun removeNotExistingSharedConfigurations(existing: Set<String>) {
var removed: MutableList<RunnerAndConfigurationSettings>? = null
lock.write {
val iterator = idToSettings.values.iterator()
for (settings in iterator) {
if (!settings.isTemplate && settings.isShared && !existing.contains(settings.uniqueID)) {
if (removed == null) {
immutableSortedSettingsList = null
removed = SmartList<RunnerAndConfigurationSettings>()
}
removed!!.add(settings)
iterator.remove()
}
}
}
if (removed != null) {
val publisher = eventPublisher
removed?.forEach { publisher.runConfigurationRemoved(it) }
}
}
fun fireBeginUpdate() {
eventPublisher.beginUpdate()
}
@@ -1198,6 +1172,4 @@ open class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persi
removed.forEach { eventPublisher.runConfigurationRemoved(it) }
changedSettings.forEach { eventPublisher.runConfigurationChanged(it, null) }
}
}
internal fun isUseProjectSchemeManager() = Registry.`is`("runManager.use.schemeManager", false)
}
@@ -353,7 +353,6 @@
serviceImplementation="com.intellij.ide.RemoteDesktopDetector"/>
<projectService serviceInterface="com.intellij.execution.RunManager" serviceImplementation="com.intellij.execution.impl.RunManagerImpl"/>
<projectService serviceImplementation="com.intellij.execution.impl.ProjectRunConfigurationManager"/>
<fileEditorProvider implementation="com.intellij.openapi.fileEditor.impl.http.HttpFileEditorProvider"/>
<editorActionHandler action="EditorEscape" implementationClass="com.intellij.codeInsight.hint.EscapeHandler" id="hide-hints"/>
@@ -1203,8 +1203,6 @@ performance.watcher.sampling.interval.ms.description=If the product is unrespons
JavaScript.Language.Service.truncate.traced.messages=true
JavaScript.Language.Service.truncate.traced.messages.description=Truncate traced JavaScript language Service messages in log
runManager.use.schemeManager=true
vfs.use.nio-based.local.refresh.worker=false
vfs.use.new.jar.handler=true