mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-06 06:21:16 +07:00
66 lines
3.0 KiB
Kotlin
66 lines
3.0 KiB
Kotlin
package com.intellij.configurationScript
|
|
|
|
import com.intellij.execution.configurations.ConfigurationFactory
|
|
import com.intellij.execution.configurations.RunConfigurationBase
|
|
import com.intellij.execution.impl.RunConfigurationTemplateProvider
|
|
import com.intellij.execution.impl.RunManagerImpl
|
|
import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl
|
|
import com.intellij.openapi.components.BaseState
|
|
import com.intellij.openapi.components.service
|
|
import com.intellij.openapi.project.Project
|
|
import gnu.trove.THashMap
|
|
import org.yaml.snakeyaml.nodes.MappingNode
|
|
import org.yaml.snakeyaml.nodes.ScalarNode
|
|
|
|
private class FactoryEntry(state: Any) {
|
|
var state: Any? = state
|
|
var settings: RunnerAndConfigurationSettingsImpl? = null
|
|
}
|
|
|
|
private class MyRunConfigurationTemplateProvider(private val project: Project) : RunConfigurationTemplateProvider {
|
|
private val map = SynchronizedClearableLazy<Map<ConfigurationFactory, FactoryEntry>> {
|
|
val node = project.service<ConfigurationFileManager>().getConfigurationNode() ?: return@SynchronizedClearableLazy emptyMap()
|
|
val map = THashMap<ConfigurationFactory, FactoryEntry>()
|
|
readRunConfigurations(node, isTemplatesOnly = true) { factory, state ->
|
|
map.put(factory, FactoryEntry(state))
|
|
}
|
|
map
|
|
}
|
|
|
|
init {
|
|
project.service<ConfigurationFileManager>().registerClearableLazyValue(map)
|
|
}
|
|
|
|
override fun getRunConfigurationTemplate(factory: ConfigurationFactory, runManager: RunManagerImpl): RunnerAndConfigurationSettingsImpl? {
|
|
val item = map.value.get(factory) ?: return null
|
|
synchronized(item) {
|
|
var settings = item.settings
|
|
if (settings != null) {
|
|
return settings
|
|
}
|
|
|
|
val configuration = factory.createTemplateConfiguration(runManager.project, runManager)
|
|
// see readRunConfiguration about how do we set isAllowRunningInParallel
|
|
(configuration as RunConfigurationBase).setState(item.state as BaseState)
|
|
settings = RunnerAndConfigurationSettingsImpl(runManager, configuration, isTemplate = true)
|
|
item.state = null
|
|
item.settings = settings
|
|
return settings
|
|
}
|
|
}
|
|
}
|
|
|
|
// we cannot use the same approach as we generate JSON scheme because we should load option classes only in a lazy manner
|
|
// that's why we don't use snakeyaml TypeDescription approach to load
|
|
internal fun readRunConfigurations(rootNode: MappingNode, isTemplatesOnly: Boolean, processor: (factory: ConfigurationFactory, state: Any) -> Unit) {
|
|
// later we can avoid full node graph building, but for now just use simple implementation (problem is that Yaml supports references and merge - proper support of it can be tricky)
|
|
// "load" under the hood uses "compose" - i.e. Yaml itself doesn't use stream API to build object model.
|
|
val dataReader = RunConfigurationListReader(processor)
|
|
for (tuple in rootNode.value) {
|
|
val keyNode = tuple.keyNode
|
|
if (keyNode is ScalarNode && keyNode.value == Keys.runConfigurations) {
|
|
val valueNode = tuple.valueNode as? MappingNode ?: continue
|
|
dataReader.read(valueNode, isTemplatesOnly)
|
|
}
|
|
}
|
|
} |