Wizard: get rid of reflection: force plugins to specify settings & tasks directly

This commit is contained in:
Ilya Kirillov
2020-06-10 15:33:00 +03:00
committed by Kirill Shmakov
parent eadd3f00f2
commit 3ed11c0491
17 changed files with 130 additions and 13 deletions
@@ -20,12 +20,13 @@ class Context private constructor(
private val propertyContext: PropertyContext,
private val taskContext: TaskContext
) {
private lateinit var plugins: List<Plugin>
private val settingWritingContext = SettingsWriter()
private val pluginSettings by lazy(LazyThreadSafetyMode.NONE) {
plugins.flatMap(Plugin::declaredSettings).distinctBy(PluginSetting<*, *>::path)
plugins.flatMap(Plugin::settings).distinctBy(PluginSetting<*, *>::path)
}
fun <T> read(reader: Reader.() -> T): T =
@@ -107,7 +108,7 @@ class Context private constructor(
private val pipelineLineTasks: List<PipelineTask>
get() = plugins
.flatMap { it.declaredTasks.filterIsInstance<PipelineTask>() }
.flatMap { it.pipelineTasks }
private fun task(reference: PipelineTaskReference) =
taskContext.getEntity(reference) as? PipelineTask ?: error(reference.path)
@@ -251,7 +252,7 @@ class Context private constructor(
fun Reader.getUnspecifiedSettings(phases: Set<GenerationPhase>): List<AnySetting> {
val required = plugins
.flatMap { plugin ->
plugin.declaredSettings.mapNotNull { setting ->
plugin.settings.mapNotNull { setting ->
if (setting.neededAtPhase !in phases) return@mapNotNull null
if (setting.isRequired) setting else null
}
@@ -11,7 +11,6 @@ import java.nio.file.Path
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KClass
import kotlin.reflect.full.isSubclassOf
import kotlin.reflect.full.memberProperties
typealias PluginReference = KClass<out Plugin>
typealias PluginsCreator = (Context) -> List<Plugin>
@@ -33,15 +32,8 @@ abstract class Plugin(override val context: Context) : EntityBase(),
override val path = reference.path
open val title: String = reference.name
val declaredSettings get() = entitiesOfType<PluginSetting<*, *>>().toSet()
val declaredTasks get() = entitiesOfType<Task>()
private inline fun <reified E : Entity> entitiesOfType() =
reference.memberProperties.filter { kProperty ->
kProperty.returnType.classifier.safeAs<KClass<*>>()?.isSubclassOf(E::class) == true
}.mapNotNull { kProperty ->
kProperty.safeAs<EntityReference>()?.getter?.call(this) as? E
}
abstract val settings: List<PluginSetting<*, *>>
abstract val pipelineTasks: List<PipelineTask>
fun pipelineTask(phase: GenerationPhase, init: PipelineTask.Builder.() -> Unit) =
context.pipelineTaskDelegate(phase, init)
@@ -10,6 +10,9 @@ import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.Plugin
import org.jetbrains.kotlin.tools.projectWizard.core.UNIT_SUCCESS
import org.jetbrains.kotlin.tools.projectWizard.core.checker
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.core.entity.Task
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.PluginSetting
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemWizardService
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.AndroidModuleConfigurator
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
@@ -47,4 +50,11 @@ class AndroidPlugin(context: Context) : Plugin(context) {
)
}
}
override val settings: List<PluginSetting<*, *>> = listOf(
androidSdkPath
)
override val pipelineTasks: List<PipelineTask> = listOf(
addAndroidSdkToLocalProperties
)
}
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.tools.projectWizard.WizardRunConfiguration
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.Plugin
import org.jetbrains.kotlin.tools.projectWizard.core.UNIT_SUCCESS
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.PluginSetting
import org.jetbrains.kotlin.tools.projectWizard.core.service.RunConfigurationsService
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemPlugin
@@ -26,4 +28,7 @@ class RunConfigurationsPlugin(context: Context) : Plugin(context) {
UNIT_SUCCESS
}
}
override val settings: List<PluginSetting<*, *>> = emptyList()
override val pipelineTasks: List<PipelineTask> = listOf(createRunConfigurationsTask)
}
@@ -3,8 +3,10 @@ package org.jetbrains.kotlin.tools.projectWizard.plugins
import org.jetbrains.kotlin.tools.projectWizard.KotlinNewProjectWizardBundle
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.core.entity.StringValidators
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.PluginSetting
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.reference
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemWizardService
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.PomIR
@@ -68,6 +70,17 @@ class StructurePlugin(context: Context) : Plugin(context) {
}
}
override val settings: List<PluginSetting<*, *>> =
listOf(
projectPath,
name,
groupId,
artifactId,
version
)
override val pipelineTasks: List<PipelineTask> =
listOf(createProjectDir)
companion object {
private val ALLOWED_SPECIAL_CHARS_IN_GROUP_ID = Module.ALLOWED_SPECIAL_CHARS_IN_MODULE_NAMES + '.'
private val ALLOWED_SPECIAL_CHARS_IN_ARTIFACT_ID = Module.ALLOWED_SPECIAL_CHARS_IN_MODULE_NAMES
@@ -5,7 +5,9 @@ import org.jetbrains.annotations.Nls
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.tools.projectWizard.KotlinNewProjectWizardBundle
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.PluginSetting
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.reference
import org.jetbrains.kotlin.tools.projectWizard.core.service.BuildSystemAvailabilityWizardService
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemWizardService
@@ -110,6 +112,15 @@ abstract class BuildSystemPlugin(context: Context) : Plugin(context) {
BuildSystemPlugin::buildSystemData.addValues(data)
}
}
override val settings: List<PluginSetting<*, *>> = listOf(
type,
)
override val pipelineTasks: List<PipelineTask> = listOf(
takeRepositoriesFromDependencies,
createModules,
importProject,
)
}
data class BuildSystemData(
@@ -3,6 +3,7 @@ package org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.asSuccess
import org.jetbrains.kotlin.tools.projectWizard.core.checker
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.RootFileModuleStructureIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.ModulesDependencyMavenIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.maven.PluginRepositoryMavenIR
@@ -61,4 +62,11 @@ class MavenPlugin(context: Context) : BuildSystemPlugin(context) {
)
)
)
override val pipelineTasks: List<PipelineTask> = super.pipelineTasks +
listOf(
createSettingsFileTask,
addBuildSystemPluginRepositories,
addBuildSystemData
)
}
@@ -3,6 +3,8 @@ package org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.gradle
import org.jetbrains.kotlin.tools.projectWizard.Versions
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.PluginSetting
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.reference
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemWizardService
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
@@ -128,6 +130,15 @@ abstract class GradlePlugin(context: Context) : BuildSystemPlugin(context) {
)
}
}
override val settings: List<PluginSetting<*, *>> = super.settings
override val pipelineTasks: List<PipelineTask> = super.pipelineTasks +
listOf(
createGradlePropertiesFile,
createLocalPropertiesFile,
initGradleWrapperTask,
createSettingsFileTask,
)
}
val Reader.settingsGradleBuildFileData
@@ -1,6 +1,7 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.gradle
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildFileData
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemData
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
@@ -16,4 +17,9 @@ class GroovyDslPlugin(context: Context) : GradlePlugin(context) {
)
)
)
override val pipelineTasks: List<PipelineTask> = super.pipelineTasks +
listOf(
addBuildSystemData,
)
}
@@ -1,6 +1,7 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.gradle
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildFileData
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemData
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
@@ -16,4 +17,8 @@ class KotlinDslPlugin(context: Context) : GradlePlugin(context) {
)
)
)
override val pipelineTasks: List<PipelineTask> = super.pipelineTasks +
listOf(
addBuildSystemData,
)
}
@@ -3,9 +3,11 @@ package org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin
import org.jetbrains.kotlin.tools.projectWizard.KotlinNewProjectWizardBundle
import org.jetbrains.kotlin.tools.projectWizard.Versions
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
import org.jetbrains.kotlin.tools.projectWizard.core.entity.fold
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settingValidator
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.PluginSetting
import org.jetbrains.kotlin.tools.projectWizard.core.service.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildFileIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.RepositoryIR
@@ -159,6 +161,21 @@ class KotlinPlugin(context: Context) : Plugin(context) {
}.fold()
}
}
override val settings: List<PluginSetting<*, *>> =
listOf(
projectKind,
modules,
)
override val pipelineTasks: List<PipelineTask> =
listOf(
initKotlinVersions,
createModules,
createPluginRepositories,
createSourcesetDirectories
)
}
enum class ProjectKind(override val text: String) : DisplayableSettingItem {
@@ -2,6 +2,8 @@ package org.jetbrains.kotlin.tools.projectWizard.plugins.projectTemplates
import org.jetbrains.kotlin.tools.projectWizard.KotlinNewProjectWizardBundle
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.PluginSetting
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin
@@ -19,6 +21,9 @@ class ProjectTemplatesPlugin(context: Context) : Plugin(context) {
values = ProjectTemplate.ALL
isRequired = false
}
override val settings: List<PluginSetting<*, *>> = listOf(template)
override val pipelineTasks: List<PipelineTask> = listOf()
}
fun SettingsWriter.applyProjectTemplate(projectTemplate: ProjectTemplate) {
@@ -1,8 +1,14 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.templates
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.templates.SimpleJsClientTemplate
class JsTemplatesPlugin(context: Context) : TemplatePlugin(context) {
val addTemplate by addTemplateTask(SimpleJsClientTemplate())
override val pipelineTasks: List<PipelineTask> = super.pipelineTasks +
listOf(
addTemplate,
)
}
@@ -1,8 +1,14 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.templates
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.templates.KtorServerTemplate
class KtorTemplatesPlugin(context: Context) : TemplatePlugin(context) {
val addTemplate by addTemplateTask(KtorServerTemplate())
override val pipelineTasks: List<PipelineTask> = super.pipelineTasks +
listOf(
addTemplate,
)
}
@@ -6,8 +6,14 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.templates
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.templates.NativeConsoleApplicationTemplate
class NativeConsoleApplicationTemplatePlugin(context: Context) : TemplatePlugin(context) {
val addTemplate by addTemplateTask(NativeConsoleApplicationTemplate())
override val pipelineTasks: List<PipelineTask> = super.pipelineTasks +
listOf(
addTemplate,
)
}
@@ -2,6 +2,8 @@ package org.jetbrains.kotlin.tools.projectWizard.plugins.templates
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.Plugin
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.PluginSetting
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.templates.Template
@@ -11,4 +13,7 @@ abstract class TemplatePlugin(context: Context) : Plugin(context) {
TemplatesPlugin::addTemplate.execute(template)
}
}
override val settings: List<PluginSetting<*, *>> = emptyList()
override val pipelineTasks: List<PipelineTask> = emptyList()
}
@@ -3,6 +3,8 @@ package org.jetbrains.kotlin.tools.projectWizard.plugins.templates
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.Defaults.SRC_DIR
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.PluginSetting
import org.jetbrains.kotlin.tools.projectWizard.core.service.TemplateEngineService
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.ModuleConfiguratorWithTests
@@ -160,4 +162,12 @@ class TemplatesPlugin(context: Context) : Plugin(context) {
}
}
}
override val settings: List<PluginSetting<*, *>> = listOf()
override val pipelineTasks: List<PipelineTask> =
listOf(
renderFileTemplates,
addTemplatesToModules,
postApplyTemplatesToModules
)
}