Wizard: introduce mobile mpp module template & allow module templates for mpp modules
This commit is contained in:
+3
-2
@@ -165,13 +165,14 @@ private class ModuleTemplateComponent(
|
|||||||
private object NoneTemplate : Template() {
|
private object NoneTemplate : Template() {
|
||||||
override val title = KotlinNewProjectWizardUIBundle.message("module.settings.template.none")
|
override val title = KotlinNewProjectWizardUIBundle.message("module.settings.template.none")
|
||||||
override val description: String = ""
|
override val description: String = ""
|
||||||
override val moduleTypes: Set<ModuleType> = ModuleType.ALL
|
override fun isSupportedByModuleType(module: Module): Boolean = true
|
||||||
|
|
||||||
override val id: String = "none"
|
override val id: String = "none"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Reader.availableTemplatesFor(module: Module) =
|
fun Reader.availableTemplatesFor(module: Module) =
|
||||||
TemplatesPlugin.templates.propertyValue.values.filter { template ->
|
TemplatesPlugin.templates.propertyValue.values.filter { template ->
|
||||||
module.configurator.moduleType in template.moduleTypes
|
template.isSupportedByModuleType(module)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
@@ -17,6 +17,7 @@ version = '1.0-SNAPSHOT'
|
|||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
|
jcenter()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven { url 'KOTLIN_REPO' }
|
maven { url 'KOTLIN_REPO' }
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -17,6 +17,7 @@ version = "1.0-SNAPSHOT"
|
|||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
|
jcenter()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven { url = uri("KOTLIN_REPO") }
|
maven { url = uri("KOTLIN_REPO") }
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -17,6 +17,7 @@ version = '1.0-SNAPSHOT'
|
|||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
|
jcenter()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven { url 'KOTLIN_REPO' }
|
maven { url 'KOTLIN_REPO' }
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -17,6 +17,7 @@ version = "1.0-SNAPSHOT"
|
|||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
|
jcenter()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven { url = uri("KOTLIN_REPO") }
|
maven { url = uri("KOTLIN_REPO") }
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -150,6 +150,10 @@ project.template.mpp.mobile.lib.description=Library that supports sharing code b
|
|||||||
module.template.console.jvm.title=Console Application
|
module.template.console.jvm.title=Console Application
|
||||||
module.template.console.jvm.description=Simple "Hello World!" Kotlin/JVM application that works in the console
|
module.template.console.jvm.description=Simple "Hello World!" Kotlin/JVM application that works in the console
|
||||||
|
|
||||||
|
module.template.mpp.mobile.title=Mobile Application
|
||||||
|
module.template.mpp.mobile.description=Mobile applications for iOS and Android with Kotlin Multiplatform Mobile, which supports sharing common code between platforms.
|
||||||
|
|
||||||
|
|
||||||
module.template.ktor.server.title=Ktor server
|
module.template.ktor.server.title=Ktor server
|
||||||
module.template.ktor.server.description=Configurable Ktor web server for building web applications
|
module.template.ktor.server.description=Configurable Ktor web server for building web applications
|
||||||
module.template.ktor.server.setting.engine=Ktor server engine
|
module.template.ktor.server.setting.engine=Ktor server engine
|
||||||
|
|||||||
+9
@@ -10,6 +10,10 @@ import org.jetbrains.kotlin.tools.projectWizard.core.service.ServicesManager
|
|||||||
import org.jetbrains.kotlin.tools.projectWizard.core.service.SettingSavingWizardService
|
import org.jetbrains.kotlin.tools.projectWizard.core.service.SettingSavingWizardService
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.core.service.WizardService
|
import org.jetbrains.kotlin.tools.projectWizard.core.service.WizardService
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
|
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.allIRModules
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.ModuleReference
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.path
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
|
||||||
@@ -239,6 +243,11 @@ fun Reader.getUnspecifiedSettings(phases: Set<GenerationPhase>): List<AnySetting
|
|||||||
val provided = pluginSettings.map(PluginSetting<*, *>::path).toSet()
|
val provided = pluginSettings.map(PluginSetting<*, *>::path).toSet()
|
||||||
return required.filterNot { it.path in provided }
|
return required.filterNot { it.path in provided }
|
||||||
}
|
}
|
||||||
|
fun Reader.moduleByReference(reference: ModuleReference): Module = when (reference) {
|
||||||
|
is ModuleReference.ByModule -> reference.module
|
||||||
|
is ModuleReference.ByPath -> allIRModules.first { it.originalModule.path == reference.path }.originalModule
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typealias Reader = Context.Reader
|
typealias Reader = Context.Reader
|
||||||
|
|||||||
+3
@@ -12,6 +12,9 @@ import kotlin.reflect.KProperty
|
|||||||
inline infix fun <A, B, C> ((A) -> B).andThen(crossinline then: (B) -> C): (A) -> C =
|
inline infix fun <A, B, C> ((A) -> B).andThen(crossinline then: (B) -> C): (A) -> C =
|
||||||
{ then(this(it)) }
|
{ then(this(it)) }
|
||||||
|
|
||||||
|
inline fun <A, B, C> compose(crossinline function: (A) -> B, crossinline then: (B) -> C): (A) -> C =
|
||||||
|
{ then(function(it)) }
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Composes two function together like normal composition if first function returns non-null value;
|
* Composes two function together like normal composition if first function returns non-null value;
|
||||||
|
|||||||
+10
@@ -138,6 +138,7 @@ sealed class ModulesStructureIR : BuildSystemIR, IrsOwner {
|
|||||||
|
|
||||||
data class MultiplatformModulesStructureIR(
|
data class MultiplatformModulesStructureIR(
|
||||||
val targets: List<BuildSystemIR>,
|
val targets: List<BuildSystemIR>,
|
||||||
|
val multiplatformModule: FakeMultiplatformModuleIR,
|
||||||
override val modules: List<MultiplatformModuleIR>,
|
override val modules: List<MultiplatformModuleIR>,
|
||||||
override val irs: PersistentList<BuildSystemIR>
|
override val irs: PersistentList<BuildSystemIR>
|
||||||
) : GradleIR, ModulesStructureIR() {
|
) : GradleIR, ModulesStructureIR() {
|
||||||
@@ -173,6 +174,15 @@ fun MultiplatformModulesStructureIR.updateTargets(
|
|||||||
return copy(targets = newTargets)
|
return copy(targets = newTargets)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun MultiplatformModulesStructureIR.updateSourceSets(
|
||||||
|
updater: (ModuleIR) -> ModuleIR
|
||||||
|
): MultiplatformModulesStructureIR {
|
||||||
|
val newModules = modules.map { updater(it) as MultiplatformModuleIR }
|
||||||
|
return copy(modules = newModules)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
data class SingleplatformModulesStructureWithSingleModuleIR(
|
data class SingleplatformModulesStructureWithSingleModuleIR(
|
||||||
val module: SingleplatformModuleIR,
|
val module: SingleplatformModuleIR,
|
||||||
override val irs: PersistentList<BuildSystemIR>
|
override val irs: PersistentList<BuildSystemIR>
|
||||||
|
|||||||
+5
@@ -16,6 +16,11 @@ fun <I : IrsOwner> I.withIrs(irs: List<BuildSystemIR>) = withReplacedIrs(irs = t
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
fun <I : IrsOwner> I.withIrs(vararg irs: BuildSystemIR) = withReplacedIrs(irs = this.irs + irs) as I
|
fun <I : IrsOwner> I.withIrs(vararg irs: BuildSystemIR) = withReplacedIrs(irs = this.irs + irs) as I
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
inline fun <I : IrsOwner> I.withoutIrs(filterNot: (BuildSystemIR) -> Boolean): I =
|
||||||
|
withReplacedIrs(irs = this.irs.filterNot(filterNot).toPersistentList()) as I
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline fun <reified I : BuildSystemIR> IrsOwner.irsOfType(): List<I> =
|
inline fun <reified I : BuildSystemIR> IrsOwner.irsOfType(): List<I> =
|
||||||
irs.filterIsInstance<I>().let { irs ->
|
irs.filterIsInstance<I>().let { irs ->
|
||||||
|
|||||||
+19
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem
|
package org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem
|
||||||
|
|
||||||
import kotlinx.collections.immutable.PersistentList
|
import kotlinx.collections.immutable.PersistentList
|
||||||
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.GradleIR
|
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.GradleIR
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.BuildFilePrinter
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.BuildFilePrinter
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.GradlePrinter
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.GradlePrinter
|
||||||
@@ -16,8 +17,26 @@ sealed class ModuleIR : IrsOwner, BuildSystemIR {
|
|||||||
abstract val template: Template?
|
abstract val template: Template?
|
||||||
abstract val originalModule: Module
|
abstract val originalModule: Module
|
||||||
abstract val sourcesets: List<SourcesetIR>
|
abstract val sourcesets: List<SourcesetIR>
|
||||||
|
|
||||||
|
abstract override fun withReplacedIrs(irs: PersistentList<BuildSystemIR>): ModuleIR
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class FakeMultiplatformModuleIR(
|
||||||
|
override val name: String,
|
||||||
|
override val path: Path,
|
||||||
|
override val template: Template?,
|
||||||
|
val targets: List<MultiplatformModuleIR>,
|
||||||
|
override val originalModule: Module
|
||||||
|
) : ModuleIR() {
|
||||||
|
override val sourcesets: List<SourcesetIR> = emptyList()
|
||||||
|
override val irs: PersistentList<BuildSystemIR> = persistentListOf()
|
||||||
|
|
||||||
|
override fun withReplacedIrs(irs: PersistentList<BuildSystemIR>): FakeMultiplatformModuleIR = this
|
||||||
|
|
||||||
|
override fun BuildFilePrinter.render() {
|
||||||
|
error("Should not be called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data class SingleplatformModuleIR(
|
data class SingleplatformModuleIR(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
|
|||||||
+1
@@ -66,6 +66,7 @@ object AndroidSinglePlatformModuleConfigurator :
|
|||||||
|
|
||||||
override fun createBuildFileIRs(reader: Reader, configurationData: ModulesToIrConversionData, module: Module) = irsList {
|
override fun createBuildFileIRs(reader: Reader, configurationData: ModulesToIrConversionData, module: Module) = irsList {
|
||||||
+super<AndroidModuleConfigurator>.createBuildFileIRs(reader, configurationData, module)
|
+super<AndroidModuleConfigurator>.createBuildFileIRs(reader, configurationData, module)
|
||||||
|
+RepositoryIR((DefaultRepository.JCENTER))
|
||||||
+AndroidConfigIR(
|
+AndroidConfigIR(
|
||||||
javaPackage = when (reader.createAndroidPlugin(module)) {
|
javaPackage = when (reader.createAndroidPlugin(module)) {
|
||||||
AndroidGradlePlugin.APPLICATION -> module.javaPackage(configurationData.pomIr)
|
AndroidGradlePlugin.APPLICATION -> module.javaPackage(configurationData.pomIr)
|
||||||
|
|||||||
+4
-309
@@ -7,31 +7,20 @@ package org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NonNls
|
import org.jetbrains.annotations.NonNls
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.KotlinNewProjectWizardBundle
|
import org.jetbrains.kotlin.tools.projectWizard.KotlinNewProjectWizardBundle
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.core.*
|
import org.jetbrains.kotlin.tools.projectWizard.core.TaskResult
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.core.entity.properties.ModuleConfiguratorProperty
|
import org.jetbrains.kotlin.tools.projectWizard.core.Writer
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.ModuleConfiguratorSetting
|
import org.jetbrains.kotlin.tools.projectWizard.core.compute
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.KotlinBuildSystemPluginIR
|
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.KotlinBuildSystemPluginIR
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
|
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.gradle.GradlePlugin
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.gradle.GradlePlugin
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleSubType
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModulesToIrConversionData
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModulesToIrConversionData
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.projectPath
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.templates.TemplatesPlugin
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.JavaPackage
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.ModuleKind
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.ModuleKind
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.SourcesetType
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.templates.FileDescriptor
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplate
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTextDescriptor
|
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
object MppModuleConfigurator : ModuleConfigurator,
|
object MppModuleConfigurator : ModuleConfigurator,
|
||||||
ModuleConfiguratorWithSettings,
|
ModuleConfiguratorWithSettings,
|
||||||
ModuleConfiguratorSettings(),
|
ModuleConfiguratorSettings() {
|
||||||
ModuleConfiguratorProperties,
|
|
||||||
ModuleConfiguratorWithProperties {
|
|
||||||
|
|
||||||
override val moduleKind = ModuleKind.multiplatform
|
override val moduleKind = ModuleKind.multiplatform
|
||||||
|
|
||||||
@@ -49,11 +38,6 @@ object MppModuleConfigurator : ModuleConfigurator,
|
|||||||
version = configurationData.kotlinVersion
|
version = configurationData.kotlinVersion
|
||||||
)
|
)
|
||||||
|
|
||||||
val mppSources by listProperty<MppSources>()
|
|
||||||
|
|
||||||
override fun getConfiguratorProperties(): List<ModuleConfiguratorProperty<*>> =
|
|
||||||
listOf(mppSources)
|
|
||||||
|
|
||||||
// TODO remove when be removed in KMM wizard
|
// TODO remove when be removed in KMM wizard
|
||||||
val generateTests by booleanSetting("Generate Tests", GenerationPhase.PROJECT_GENERATION) {
|
val generateTests by booleanSetting("Generate Tests", GenerationPhase.PROJECT_GENERATION) {
|
||||||
defaultValue = value(false)
|
defaultValue = value(false)
|
||||||
@@ -64,295 +48,6 @@ object MppModuleConfigurator : ModuleConfigurator,
|
|||||||
module: Module,
|
module: Module,
|
||||||
modulePath: Path,
|
modulePath: Path,
|
||||||
): TaskResult<Unit> = compute {
|
): TaskResult<Unit> = compute {
|
||||||
createMppFiles(module, modulePath).ensure()
|
|
||||||
createSimpleFiles(module, modulePath).ensure()
|
|
||||||
GradlePlugin.gradleProperties.addValues("kotlin.mpp.enableGranularSourceSetsMetadata" to true)
|
GradlePlugin.gradleProperties.addValues("kotlin.mpp.enableGranularSourceSetsMetadata" to true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Writer.createMppFiles(
|
|
||||||
module: Module,
|
|
||||||
modulePath: Path
|
|
||||||
): TaskResult<Unit> = inContextOfModuleConfigurator(module) {
|
|
||||||
val mppFiles = mppSources.reference.propertyValue.flatMap { it.mppFiles }
|
|
||||||
.distinctBy { it.fileNameWithPackage } // todo merge files with the same name here
|
|
||||||
mppFiles.mapSequenceIgnore { file ->
|
|
||||||
module.subModules.mapSequenceIgnore mapTargets@{ target ->
|
|
||||||
val moduleSubType = //TODO handle for non-simple target configurator
|
|
||||||
target.configurator.safeAs<SimpleTargetConfigurator>()?.moduleSubType ?: return@mapTargets UNIT_SUCCESS
|
|
||||||
val path = pathForFileInTarget(modulePath, module, file.javaPackage, file.filename, target, SourcesetType.main)
|
|
||||||
val fileTemplate = FileTemplate(
|
|
||||||
FileTextDescriptor(file.printForModuleSubType(moduleSubType), path),
|
|
||||||
projectPath,
|
|
||||||
)
|
|
||||||
TemplatesPlugin.fileTemplatesToRender.addValues(fileTemplate)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Writer.createSimpleFiles(
|
|
||||||
module: Module,
|
|
||||||
modulePath: Path
|
|
||||||
): TaskResult<Unit> = inContextOfModuleConfigurator(module) {
|
|
||||||
val mppFiles = mppSources.reference.propertyValue
|
|
||||||
val filesWithPaths = module.subModules.flatMap { target ->
|
|
||||||
val moduleSubType = //TODO handle for non-simple target configurator
|
|
||||||
target.configurator.safeAs<SimpleTargetConfigurator>()?.moduleSubType ?: return@flatMap emptyList()
|
|
||||||
mppFiles
|
|
||||||
.flatMap { it.getFilesFor(moduleSubType) }
|
|
||||||
.distinctBy { it.uniqueIdentifier }
|
|
||||||
.map { file ->
|
|
||||||
val path = projectPath / pathForFileInTarget(modulePath, module, file.javaPackage, file.filename, target, file.type)
|
|
||||||
file to path
|
|
||||||
}
|
|
||||||
}.distinctBy { (_, path) -> path }
|
|
||||||
filesWithPaths.mapSequenceIgnore { (file, path) ->
|
|
||||||
val fileTemplate = FileTemplate(file.fileDescriptor, path, mapOf("package" to file.javaPackage?.asCodePackage()))
|
|
||||||
TemplatesPlugin.fileTemplatesToRender.addValues(fileTemplate)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun pathForFileInTarget(
|
|
||||||
mppModulePath: Path,
|
|
||||||
mppModule: Module,
|
|
||||||
javaPackage: JavaPackage?,
|
|
||||||
filename: String,
|
|
||||||
target: Module,
|
|
||||||
sourcesetType: SourcesetType,
|
|
||||||
) = mppModulePath /
|
|
||||||
Defaults.SRC_DIR /
|
|
||||||
"${target.name}${sourcesetType.name.capitalize()}" /
|
|
||||||
mppModule.configurator.kotlinDirectoryName /
|
|
||||||
javaPackage?.asPath() /
|
|
||||||
filename
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@DslMarker
|
|
||||||
annotation class ExpectFileDSL
|
|
||||||
|
|
||||||
data class MppFile(
|
|
||||||
@NonNls val filename: String,
|
|
||||||
@NonNls val javaPackage: JavaPackage? = null,
|
|
||||||
val declarations: List<MppDeclaration>
|
|
||||||
) {
|
|
||||||
|
|
||||||
val fileNameWithPackage
|
|
||||||
get() = javaPackage?.let { "${it.asCodePackage()}." }.orEmpty() + filename
|
|
||||||
|
|
||||||
fun printForModuleSubType(moduleSubType: ModuleSubType): String = buildString {
|
|
||||||
javaPackage?.let { appendLine("package ${it.asCodePackage()}"); appendLine() }
|
|
||||||
if (moduleSubType == ModuleSubType.common) {
|
|
||||||
declarations.joinTo(this, separator = "\n\n") { it.printExpect() }
|
|
||||||
} else {
|
|
||||||
printImports(declarations.flatMap { it.importsFor(moduleSubType) })
|
|
||||||
declarations.joinTo(this, separator = "\n\n") { it.printActualFor(moduleSubType) }
|
|
||||||
}
|
|
||||||
}.trim()
|
|
||||||
|
|
||||||
private fun StringBuilder.printImports(imports: List<String>) {
|
|
||||||
if (imports.isEmpty()) return
|
|
||||||
imports.distinct().joinTo(this, separator = "\n", prefix = "\n", postfix = "\n\n") { import ->
|
|
||||||
"import $import"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ExpectFileDSL
|
|
||||||
class Builder(private val filename: String, val javaPackage: JavaPackage? = null) {
|
|
||||||
private val declarations = mutableListOf<MppDeclaration>()
|
|
||||||
|
|
||||||
fun function(signature: String, init: MppFunction.Builder.() -> Unit = {}) {
|
|
||||||
declarations += MppFunction.Builder(signature).apply(init).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun `class`(name: String, init: MppClass.Builder.() -> Unit = {}) {
|
|
||||||
declarations += MppClass.Builder(name).apply(init).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun build() = MppFile(filename, javaPackage, declarations)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ExpectFileDSL
|
|
||||||
class MppSources(val mppFiles: List<MppFile>, val simpleFiles: List<SimpleFiles>) {
|
|
||||||
|
|
||||||
fun getFilesFor(moduleSubType: ModuleSubType): List<SimpleFile> =
|
|
||||||
simpleFiles.filter { moduleSubType in it.moduleSubTypes }.flatMap { it.files }
|
|
||||||
|
|
||||||
class Builder(val javaPackage: JavaPackage?) {
|
|
||||||
private val mppFiles = mutableListOf<MppFile>()
|
|
||||||
private val simpleFiles = mutableListOf<SimpleFiles>()
|
|
||||||
|
|
||||||
fun mppFile(filename: String, init: MppFile.Builder.() -> Unit) {
|
|
||||||
mppFiles += MppFile.Builder(filename, javaPackage).apply(init).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun filesFor(vararg moduleSubTypes: ModuleSubType, init: SimpleFiles.Builder.() -> Unit) {
|
|
||||||
simpleFiles += SimpleFiles.Builder(moduleSubTypes.toList(), javaPackage).apply(init).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun build() = MppSources(mppFiles, simpleFiles)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
data class SimpleFiles(val moduleSubTypes: List<ModuleSubType>, val files: List<SimpleFile>) {
|
|
||||||
class Builder(private val moduleSubTypes: List<ModuleSubType>, val filesPackage: JavaPackage?) {
|
|
||||||
private val files = mutableListOf<SimpleFile>()
|
|
||||||
|
|
||||||
fun file(fileDescriptor: FileDescriptor, filename: String, type: SourcesetType, init: SimpleFile.Builder.() -> Unit = {}) {
|
|
||||||
files += SimpleFile.Builder(fileDescriptor, filename, type).apply(init).apply {
|
|
||||||
javaPackage = filesPackage
|
|
||||||
}.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun build() = SimpleFiles(moduleSubTypes, files)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class SimpleFile(val fileDescriptor: FileDescriptor, val javaPackage: JavaPackage?, val filename: String, val type: SourcesetType) {
|
|
||||||
val uniqueIdentifier get() = "${type}/${javaPackage}/${filename}"
|
|
||||||
|
|
||||||
class Builder(private val fileDescriptor: FileDescriptor, private val filename: String, private val type: SourcesetType) {
|
|
||||||
var javaPackage: JavaPackage? = null
|
|
||||||
|
|
||||||
fun build() = SimpleFile(fileDescriptor, javaPackage, filename, type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun mppSources(javaPackage: JavaPackage? = null, init: MppSources.Builder.() -> Unit): MppSources =
|
|
||||||
MppSources.Builder(javaPackage).apply(init).build()
|
|
||||||
|
|
||||||
sealed class MppDeclaration {
|
|
||||||
@Suppress("SpellCheckingInspection")
|
|
||||||
abstract val actuals: Actuals
|
|
||||||
|
|
||||||
abstract fun printExpect(): String
|
|
||||||
|
|
||||||
abstract fun printActualFor(moduleSubType: ModuleSubType): String
|
|
||||||
|
|
||||||
fun importsFor(moduleSubType: ModuleSubType): List<String> = actuals.getBodyFor(moduleSubType).imports
|
|
||||||
|
|
||||||
@ExpectFileDSL
|
|
||||||
abstract class Builder {
|
|
||||||
private var defaultActualDeclarationBody = DefaultActualDeclarationBody(text = "", imports = emptyList())
|
|
||||||
|
|
||||||
@Suppress("SpellCheckingInspection")
|
|
||||||
private val actuals = mutableMapOf<ModuleSubType, ActualDeclarationBody>()
|
|
||||||
|
|
||||||
fun default(defaultText: String, init: DefaultActualDeclarationBody.Builder.() -> Unit = {}) {
|
|
||||||
defaultActualDeclarationBody = DefaultActualDeclarationBody.Builder(defaultText).also(init).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun actualFor(vararg moduleSubTypes: ModuleSubType, actualBody: String, init: ActualDeclarationBody.Builder.() -> Unit = {}) {
|
|
||||||
moduleSubTypes.forEach { moduleSubType ->
|
|
||||||
actuals[moduleSubType] = ActualDeclarationBody.Builder(actualBody).apply(init).build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun buildActuals() = Actuals(defaultActualDeclarationBody, actuals)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class MppFunction(
|
|
||||||
val signature: String,
|
|
||||||
@Suppress("SpellCheckingInspection")
|
|
||||||
override val actuals: Actuals,
|
|
||||||
) : MppDeclaration() {
|
|
||||||
override fun printExpect(): String =
|
|
||||||
"expect fun $signature"
|
|
||||||
|
|
||||||
override fun printActualFor(moduleSubType: ModuleSubType): String {
|
|
||||||
val body = actuals.getBodyFor(moduleSubType)
|
|
||||||
return buildString {
|
|
||||||
appendLine("actual fun $signature {")
|
|
||||||
appendLine(body.text.indented(4))
|
|
||||||
append("}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ExpectFileDSL
|
|
||||||
class Builder(private val signature: String) : MppDeclaration.Builder() {
|
|
||||||
fun build(): MppFunction = MppFunction(
|
|
||||||
signature,
|
|
||||||
buildActuals(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class MppClass(
|
|
||||||
val name: String,
|
|
||||||
val expectBody: String?,
|
|
||||||
@Suppress("SpellCheckingInspection")
|
|
||||||
override val actuals: Actuals,
|
|
||||||
) : MppDeclaration() {
|
|
||||||
override fun printExpect(): String = buildString {
|
|
||||||
append("expect class $name()")
|
|
||||||
expectBody?.let { body ->
|
|
||||||
appendLine(" {")
|
|
||||||
appendLine(body.indented(4))
|
|
||||||
append("}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun printActualFor(moduleSubType: ModuleSubType): String {
|
|
||||||
val body = actuals.getBodyFor(moduleSubType)
|
|
||||||
return buildString {
|
|
||||||
appendLine("actual class $name actual constructor() {")
|
|
||||||
appendLine(body.text.indented(4))
|
|
||||||
append("}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ExpectFileDSL
|
|
||||||
class Builder(private val name: String) : MppDeclaration.Builder() {
|
|
||||||
var expectBody: String? = null
|
|
||||||
|
|
||||||
fun build(): MppClass = MppClass(
|
|
||||||
name,
|
|
||||||
expectBody,
|
|
||||||
buildActuals(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun String.indented(indentValue: Int): String {
|
|
||||||
val indent = " ".repeat(indentValue)
|
|
||||||
return split('\n').joinToString(separator = "\n") { line -> indent + line.trim() }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("SpellCheckingInspection")
|
|
||||||
data class Actuals(
|
|
||||||
val defaultActualDeclarationBody: DefaultActualDeclarationBody,
|
|
||||||
val actuals: Map<ModuleSubType, ActualDeclarationBody>,
|
|
||||||
) {
|
|
||||||
fun getBodyFor(moduleSubType: ModuleSubType): DeclarationBody =
|
|
||||||
actuals[moduleSubType] ?: defaultActualDeclarationBody
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed class DeclarationBody {
|
|
||||||
abstract val text: String
|
|
||||||
abstract val imports: List<String>
|
|
||||||
|
|
||||||
abstract class Builder {
|
|
||||||
protected val imports = mutableListOf<String>()
|
|
||||||
|
|
||||||
fun import(import: String) {
|
|
||||||
imports += import
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class ActualDeclarationBody(override val text: String, override val imports: List<String>) : DeclarationBody() {
|
|
||||||
class Builder(private val text: String) : DeclarationBody.Builder() {
|
|
||||||
fun build() = ActualDeclarationBody(text, imports)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class DefaultActualDeclarationBody(override val text: String, override val imports: List<String>) : DeclarationBody() {
|
|
||||||
class Builder(private val text: String) : DeclarationBody.Builder() {
|
|
||||||
fun build() = DefaultActualDeclarationBody(text, imports)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+327
@@ -0,0 +1,327 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.tools.projectWizard.mpp
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.core.*
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.core.safeAs
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.SimpleTargetConfigurator
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.inContextOfModuleConfigurator
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.gradle.GradlePlugin
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleSubType
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModulesToIrConversionData
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.projectPath
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.templates.TemplatesPlugin
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.settings.JavaPackage
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.SourcesetType
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.templates.FileDescriptor
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplate
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTextDescriptor
|
||||||
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
@DslMarker
|
||||||
|
annotation class ExpectFileDSL
|
||||||
|
|
||||||
|
data class MppFile(
|
||||||
|
@NonNls val filename: String,
|
||||||
|
@NonNls val javaPackage: JavaPackage? = null,
|
||||||
|
val declarations: List<MppDeclaration>
|
||||||
|
) {
|
||||||
|
|
||||||
|
val fileNameWithPackage
|
||||||
|
get() = javaPackage?.let { "${it.asCodePackage()}." }.orEmpty() + filename
|
||||||
|
|
||||||
|
fun printForModuleSubType(moduleSubType: ModuleSubType): String = buildString {
|
||||||
|
javaPackage?.let { appendLine("package ${it.asCodePackage()}"); appendLine() }
|
||||||
|
if (moduleSubType == ModuleSubType.common) {
|
||||||
|
declarations.joinTo(this, separator = "\n\n") { it.printExpect() }
|
||||||
|
} else {
|
||||||
|
printImports(declarations.flatMap { it.importsFor(moduleSubType) })
|
||||||
|
declarations.joinTo(this, separator = "\n\n") { it.printActualFor(moduleSubType) }
|
||||||
|
}
|
||||||
|
}.trim()
|
||||||
|
|
||||||
|
private fun StringBuilder.printImports(imports: List<String>) {
|
||||||
|
if (imports.isEmpty()) return
|
||||||
|
imports.distinct().joinTo(this, separator = "\n", prefix = "\n", postfix = "\n\n") { import ->
|
||||||
|
"import $import"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExpectFileDSL
|
||||||
|
class Builder(private val filename: String, val javaPackage: JavaPackage? = null) {
|
||||||
|
private val declarations = mutableListOf<MppDeclaration>()
|
||||||
|
|
||||||
|
fun function(signature: String, init: MppFunction.Builder.() -> Unit = {}) {
|
||||||
|
declarations += MppFunction.Builder(signature).apply(init).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun `class`(name: String, init: MppClass.Builder.() -> Unit = {}) {
|
||||||
|
declarations += MppClass.Builder(name).apply(init).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun build() = MppFile(filename, javaPackage, declarations)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ExpectFileDSL
|
||||||
|
class MppSources(val mppFiles: List<MppFile>, val simpleFiles: List<SimpleFiles>) {
|
||||||
|
|
||||||
|
fun getFilesFor(moduleSubType: ModuleSubType): List<SimpleFile> =
|
||||||
|
simpleFiles.filter { moduleSubType in it.moduleSubTypes }.flatMap { it.files }
|
||||||
|
|
||||||
|
class Builder(val javaPackage: JavaPackage?) {
|
||||||
|
private val mppFiles = mutableListOf<MppFile>()
|
||||||
|
private val simpleFiles = mutableListOf<SimpleFiles>()
|
||||||
|
|
||||||
|
fun mppFile(filename: String, init: MppFile.Builder.() -> Unit) {
|
||||||
|
mppFiles += MppFile.Builder(filename, javaPackage).apply(init).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun filesFor(vararg moduleSubTypes: ModuleSubType, init: SimpleFiles.Builder.() -> Unit) {
|
||||||
|
simpleFiles += SimpleFiles.Builder(moduleSubTypes.toList(), javaPackage).apply(init).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun build() = MppSources(mppFiles, simpleFiles)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
data class SimpleFiles(val moduleSubTypes: List<ModuleSubType>, val files: List<SimpleFile>) {
|
||||||
|
class Builder(private val moduleSubTypes: List<ModuleSubType>, val filesPackage: JavaPackage?) {
|
||||||
|
private val files = mutableListOf<SimpleFile>()
|
||||||
|
|
||||||
|
fun file(fileDescriptor: FileDescriptor, filename: String, type: SourcesetType, init: SimpleFile.Builder.() -> Unit = {}) {
|
||||||
|
files += SimpleFile.Builder(fileDescriptor, filename, type).apply(init).apply {
|
||||||
|
javaPackage = filesPackage
|
||||||
|
}.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun build() = SimpleFiles(moduleSubTypes, files)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class SimpleFile(val fileDescriptor: FileDescriptor, val javaPackage: JavaPackage?, val filename: String, val type: SourcesetType) {
|
||||||
|
val uniqueIdentifier get() = "${type}/${javaPackage}/${filename}"
|
||||||
|
|
||||||
|
class Builder(private val fileDescriptor: FileDescriptor, private val filename: String, private val type: SourcesetType) {
|
||||||
|
var javaPackage: JavaPackage? = null
|
||||||
|
|
||||||
|
fun build() = SimpleFile(fileDescriptor, javaPackage, filename, type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun mppSources(javaPackage: JavaPackage? = null, init: MppSources.Builder.() -> Unit): MppSources =
|
||||||
|
MppSources.Builder(javaPackage).apply(init).build()
|
||||||
|
|
||||||
|
sealed class MppDeclaration {
|
||||||
|
@Suppress("SpellCheckingInspection")
|
||||||
|
abstract val actuals: Actuals
|
||||||
|
|
||||||
|
abstract fun printExpect(): String
|
||||||
|
|
||||||
|
abstract fun printActualFor(moduleSubType: ModuleSubType): String
|
||||||
|
|
||||||
|
fun importsFor(moduleSubType: ModuleSubType): List<String> = actuals.getBodyFor(moduleSubType).imports
|
||||||
|
|
||||||
|
@ExpectFileDSL
|
||||||
|
abstract class Builder {
|
||||||
|
private var defaultActualDeclarationBody = DefaultActualDeclarationBody(text = "", imports = emptyList())
|
||||||
|
|
||||||
|
@Suppress("SpellCheckingInspection")
|
||||||
|
private val actuals = mutableMapOf<ModuleSubType, ActualDeclarationBody>()
|
||||||
|
|
||||||
|
fun default(defaultText: String, init: DefaultActualDeclarationBody.Builder.() -> Unit = {}) {
|
||||||
|
defaultActualDeclarationBody = DefaultActualDeclarationBody.Builder(defaultText).also(init).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun actualFor(vararg moduleSubTypes: ModuleSubType, actualBody: String, init: ActualDeclarationBody.Builder.() -> Unit = {}) {
|
||||||
|
moduleSubTypes.forEach { moduleSubType ->
|
||||||
|
actuals[moduleSubType] = ActualDeclarationBody.Builder(actualBody).apply(init).build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun buildActuals() = Actuals(defaultActualDeclarationBody, actuals)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class MppFunction(
|
||||||
|
val signature: String,
|
||||||
|
@Suppress("SpellCheckingInspection")
|
||||||
|
override val actuals: Actuals,
|
||||||
|
) : MppDeclaration() {
|
||||||
|
override fun printExpect(): String =
|
||||||
|
"expect fun $signature"
|
||||||
|
|
||||||
|
override fun printActualFor(moduleSubType: ModuleSubType): String {
|
||||||
|
val body = actuals.getBodyFor(moduleSubType)
|
||||||
|
return buildString {
|
||||||
|
appendLine("actual fun $signature {")
|
||||||
|
appendLine(body.text.indented(4))
|
||||||
|
append("}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExpectFileDSL
|
||||||
|
class Builder(private val signature: String) : MppDeclaration.Builder() {
|
||||||
|
fun build(): MppFunction = MppFunction(
|
||||||
|
signature,
|
||||||
|
buildActuals(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class MppClass(
|
||||||
|
val name: String,
|
||||||
|
val expectBody: String?,
|
||||||
|
@Suppress("SpellCheckingInspection")
|
||||||
|
override val actuals: Actuals,
|
||||||
|
) : MppDeclaration() {
|
||||||
|
override fun printExpect(): String = buildString {
|
||||||
|
append("expect class $name()")
|
||||||
|
expectBody?.let { body ->
|
||||||
|
appendLine(" {")
|
||||||
|
appendLine(body.indented(4))
|
||||||
|
append("}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun printActualFor(moduleSubType: ModuleSubType): String {
|
||||||
|
val body = actuals.getBodyFor(moduleSubType)
|
||||||
|
return buildString {
|
||||||
|
appendLine("actual class $name actual constructor() {")
|
||||||
|
appendLine(body.text.indented(4))
|
||||||
|
append("}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExpectFileDSL
|
||||||
|
class Builder(private val name: String) : MppDeclaration.Builder() {
|
||||||
|
var expectBody: String? = null
|
||||||
|
|
||||||
|
fun build(): MppClass = MppClass(
|
||||||
|
name,
|
||||||
|
expectBody,
|
||||||
|
buildActuals(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun String.indented(indentValue: Int): String {
|
||||||
|
val indent = " ".repeat(indentValue)
|
||||||
|
return split('\n').joinToString(separator = "\n") { line -> indent + line.trim() }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("SpellCheckingInspection")
|
||||||
|
data class Actuals(
|
||||||
|
val defaultActualDeclarationBody: DefaultActualDeclarationBody,
|
||||||
|
val actuals: Map<ModuleSubType, ActualDeclarationBody>,
|
||||||
|
) {
|
||||||
|
fun getBodyFor(moduleSubType: ModuleSubType): DeclarationBody =
|
||||||
|
actuals[moduleSubType] ?: defaultActualDeclarationBody
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class DeclarationBody {
|
||||||
|
abstract val text: String
|
||||||
|
abstract val imports: List<String>
|
||||||
|
|
||||||
|
abstract class Builder {
|
||||||
|
protected val imports = mutableListOf<String>()
|
||||||
|
|
||||||
|
fun import(import: String) {
|
||||||
|
imports += import
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class ActualDeclarationBody(override val text: String, override val imports: List<String>) : DeclarationBody() {
|
||||||
|
class Builder(private val text: String) : DeclarationBody.Builder() {
|
||||||
|
fun build() = ActualDeclarationBody(text, imports)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class DefaultActualDeclarationBody(override val text: String, override val imports: List<String>) : DeclarationBody() {
|
||||||
|
class Builder(private val text: String) : DeclarationBody.Builder() {
|
||||||
|
fun build() = DefaultActualDeclarationBody(text, imports)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Writer.applyMppStructure(
|
||||||
|
mppSources: List<MppSources>,
|
||||||
|
module: Module,
|
||||||
|
modulePath: Path,
|
||||||
|
): TaskResult<Unit> = compute {
|
||||||
|
createMppFiles(mppSources, module, modulePath).ensure()
|
||||||
|
createSimpleFiles(mppSources, module, modulePath).ensure()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Writer.applyMppStructure(
|
||||||
|
mppSources: MppSources,
|
||||||
|
module: Module,
|
||||||
|
modulePath: Path,
|
||||||
|
): TaskResult<Unit> = applyMppStructure(listOf(mppSources), module, modulePath)
|
||||||
|
|
||||||
|
private fun Writer.createMppFiles(
|
||||||
|
mppSources: List<MppSources>,
|
||||||
|
module: Module,
|
||||||
|
modulePath: Path
|
||||||
|
): TaskResult<Unit> = inContextOfModuleConfigurator(module) {
|
||||||
|
val mppFiles = mppSources.flatMap { it.mppFiles }
|
||||||
|
.distinctBy { it.fileNameWithPackage } // todo merge files with the same name here
|
||||||
|
mppFiles.mapSequenceIgnore { file ->
|
||||||
|
module.subModules.mapSequenceIgnore mapTargets@{ target ->
|
||||||
|
val moduleSubType = //TODO handle for non-simple target configurator
|
||||||
|
target.configurator.safeAs<SimpleTargetConfigurator>()?.moduleSubType ?: return@mapTargets UNIT_SUCCESS
|
||||||
|
val path = pathForFileInTarget(modulePath, module, file.javaPackage, file.filename, target, SourcesetType.main)
|
||||||
|
val fileTemplate = FileTemplate(
|
||||||
|
FileTextDescriptor(file.printForModuleSubType(moduleSubType), path),
|
||||||
|
projectPath,
|
||||||
|
)
|
||||||
|
TemplatesPlugin.fileTemplatesToRender.addValues(fileTemplate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Writer.createSimpleFiles(
|
||||||
|
mppSources: List<MppSources>,
|
||||||
|
module: Module,
|
||||||
|
modulePath: Path
|
||||||
|
): TaskResult<Unit> = inContextOfModuleConfigurator(module) {
|
||||||
|
val mppFiles = mppSources
|
||||||
|
val filesWithPaths = module.subModules.flatMap { target ->
|
||||||
|
val moduleSubType = //TODO handle for non-simple target configurator
|
||||||
|
target.configurator.safeAs<SimpleTargetConfigurator>()?.moduleSubType ?: return@flatMap emptyList()
|
||||||
|
mppFiles
|
||||||
|
.flatMap { it.getFilesFor(moduleSubType) }
|
||||||
|
.distinctBy { it.uniqueIdentifier }
|
||||||
|
.map { file ->
|
||||||
|
val path = projectPath / pathForFileInTarget(modulePath, module, file.javaPackage, file.filename, target, file.type)
|
||||||
|
file to path
|
||||||
|
}
|
||||||
|
}.distinctBy { (_, path) -> path }
|
||||||
|
filesWithPaths.mapSequenceIgnore { (file, path) ->
|
||||||
|
val fileTemplate = FileTemplate(file.fileDescriptor, path, mapOf("package" to file.javaPackage?.asCodePackage()))
|
||||||
|
TemplatesPlugin.fileTemplatesToRender.addValues(fileTemplate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pathForFileInTarget(
|
||||||
|
mppModulePath: Path,
|
||||||
|
mppModule: Module,
|
||||||
|
javaPackage: JavaPackage?,
|
||||||
|
filename: String,
|
||||||
|
target: Module,
|
||||||
|
sourcesetType: SourcesetType,
|
||||||
|
) = mppModulePath /
|
||||||
|
Defaults.SRC_DIR /
|
||||||
|
"${target.name}${sourcesetType.name.capitalize()}" /
|
||||||
|
mppModule.configurator.kotlinDirectoryName /
|
||||||
|
javaPackage?.asPath() /
|
||||||
|
filename
|
||||||
+2
-1
@@ -32,7 +32,8 @@ object Plugins {
|
|||||||
JsTemplatesPlugin(context),
|
JsTemplatesPlugin(context),
|
||||||
ReactJsTemplatesPlugin(context),
|
ReactJsTemplatesPlugin(context),
|
||||||
SimpleNodeJsTemplatesPlugin(context),
|
SimpleNodeJsTemplatesPlugin(context),
|
||||||
NativeConsoleApplicationTemplatePlugin(context)
|
NativeConsoleApplicationTemplatePlugin(context),
|
||||||
|
MobileMppTemplatePlugin(context),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+7
@@ -230,6 +230,13 @@ class ModulesToIRsConverter(
|
|||||||
modulePath,
|
modulePath,
|
||||||
MultiplatformModulesStructureIR(
|
MultiplatformModulesStructureIR(
|
||||||
targetIrs,
|
targetIrs,
|
||||||
|
FakeMultiplatformModuleIR(
|
||||||
|
module.name,
|
||||||
|
modulePath,
|
||||||
|
module.template,
|
||||||
|
targetModuleIrs,
|
||||||
|
module,
|
||||||
|
),
|
||||||
targetModuleIrs,
|
targetModuleIrs,
|
||||||
persistentListOf()
|
persistentListOf()
|
||||||
),
|
),
|
||||||
|
|||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
package org.jetbrains.kotlin.tools.projectWizard.plugins.templates
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.core.Context
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.core.PluginSettingsOwner
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.templates.mpp.MobileMppTemplate
|
||||||
|
|
||||||
|
class MobileMppTemplatePlugin(context: Context) : TemplatePlugin(context) {
|
||||||
|
override val path = pluginPath
|
||||||
|
|
||||||
|
override val pipelineTasks: List<PipelineTask> = super.pipelineTasks +
|
||||||
|
listOf(
|
||||||
|
addTemplate,
|
||||||
|
)
|
||||||
|
|
||||||
|
companion object : PluginSettingsOwner() {
|
||||||
|
override val pluginPath = "template.mobile.mpp"
|
||||||
|
|
||||||
|
val addTemplate by pipelineTask(GenerationPhase.PREPARE) {
|
||||||
|
withAction {
|
||||||
|
TemplatesPlugin.addTemplate.execute(MobileMppTemplate())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
-4
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.PluginSetti
|
|||||||
import org.jetbrains.kotlin.tools.projectWizard.core.service.TemplateEngineService
|
import org.jetbrains.kotlin.tools.projectWizard.core.service.TemplateEngineService
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
|
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.ModuleConfiguratorWithTests
|
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.ModuleConfiguratorWithTests
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.MppModuleConfigurator.runArbitraryTask
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.isPresent
|
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.isPresent
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
|
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemPlugin
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemPlugin
|
||||||
@@ -67,20 +68,31 @@ class TemplatesPlugin(context: Context) : Plugin(context) {
|
|||||||
|
|
||||||
withAction {
|
withAction {
|
||||||
updateBuildFiles { buildFile ->
|
updateBuildFiles { buildFile ->
|
||||||
buildFile.modules.modules.mapSequence { module ->
|
val moduleStructure = buildFile.modules
|
||||||
|
val moduleIRs = buildList<ModuleIR> {
|
||||||
|
if (moduleStructure is MultiplatformModulesStructureIR) {
|
||||||
|
+moduleStructure.multiplatformModule
|
||||||
|
}
|
||||||
|
+moduleStructure.modules
|
||||||
|
}
|
||||||
|
moduleIRs.mapSequence { module ->
|
||||||
applyTemplateToModule(
|
applyTemplateToModule(
|
||||||
module.template,
|
module.template,
|
||||||
module
|
module
|
||||||
).map { result -> module.withIrs(result.librariesToAdd) to result }
|
).map { result -> result.updateModuleIR(module.withIrs(result.librariesToAdd)) to result }
|
||||||
}.map {
|
}.map {
|
||||||
val (moduleIrs, results) = it.unzip()
|
val (moduleIrs, results) = it.unzip()
|
||||||
val foldedResults = results.fold()
|
val foldedResults = results.fold()
|
||||||
buildFile.copy(
|
buildFile.copy(
|
||||||
modules = buildFile.modules.withModules(moduleIrs)
|
modules = buildFile.modules.withModules(moduleIrs.filterNot { it is FakeMultiplatformModuleIR })
|
||||||
).withIrs(foldedResults.irsToAddToBuildFile).let { buildFile ->
|
).withIrs(foldedResults.irsToAddToBuildFile).let { buildFile ->
|
||||||
when (val structure = buildFile.modules) {
|
when (val structure = buildFile.modules) {
|
||||||
is MultiplatformModulesStructureIR ->
|
is MultiplatformModulesStructureIR ->
|
||||||
buildFile.copy(modules = structure.updateTargets(foldedResults.updateTarget))
|
buildFile.copy(
|
||||||
|
modules = structure
|
||||||
|
.updateTargets(foldedResults.updateTarget)
|
||||||
|
.updateSourceSets(foldedResults.updateModuleIR)
|
||||||
|
)
|
||||||
else -> buildFile
|
else -> buildFile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,6 +176,7 @@ class TemplatesPlugin(context: Context) : Plugin(context) {
|
|||||||
}
|
}
|
||||||
SRC_DIR / "${module.name}${filePath.sourcesetType.name.capitalize()}" / directory
|
SRC_DIR / "${module.name}${filePath.sourcesetType.name.capitalize()}" / directory
|
||||||
}
|
}
|
||||||
|
is FakeMultiplatformModuleIR -> error("Not supported for FakeMultiplatformModuleIR")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-5
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ProjectKind
|
|||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
|
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.*
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.*
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.templates.*
|
import org.jetbrains.kotlin.tools.projectWizard.templates.*
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.templates.mpp.MobileMppTemplate
|
||||||
|
|
||||||
sealed class ProjectTemplate : DisplayableSettingItem {
|
sealed class ProjectTemplate : DisplayableSettingItem {
|
||||||
abstract val title: String
|
abstract val title: String
|
||||||
@@ -165,7 +166,7 @@ object MultiplatformApplicationProjectTemplate : ProjectTemplate() {
|
|||||||
override val setsPluginSettings: List<SettingWithValue<*, *>>
|
override val setsPluginSettings: List<SettingWithValue<*, *>>
|
||||||
get() = listOf(
|
get() = listOf(
|
||||||
KotlinPlugin.modules.reference withValue listOf(
|
KotlinPlugin.modules.reference withValue listOf(
|
||||||
MultiplatformModule("mainModule", listOf(ModuleType.common.createDefaultTarget()))
|
MultiplatformModule("mainModule", targets = listOf(ModuleType.common.createDefaultTarget()))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -206,7 +207,7 @@ object MultiplatformLibraryProjectTemplate : ProjectTemplate() {
|
|||||||
KotlinPlugin.modules.reference withValue listOf(
|
KotlinPlugin.modules.reference withValue listOf(
|
||||||
MultiplatformModule(
|
MultiplatformModule(
|
||||||
"library",
|
"library",
|
||||||
listOf(
|
targets = listOf(
|
||||||
ModuleType.common.createDefaultTarget(),
|
ModuleType.common.createDefaultTarget(),
|
||||||
ModuleType.jvm.createDefaultTarget(),
|
ModuleType.jvm.createDefaultTarget(),
|
||||||
ModuleType.js.createDefaultTarget().withConfiguratorSettings(JsBrowserTargetConfigurator) {
|
ModuleType.js.createDefaultTarget().withConfiguratorSettings(JsBrowserTargetConfigurator) {
|
||||||
@@ -231,7 +232,7 @@ object FullStackWebApplicationProjectTemplate : ProjectTemplate() {
|
|||||||
KotlinPlugin.modules.reference withValue listOf(
|
KotlinPlugin.modules.reference withValue listOf(
|
||||||
MultiplatformModule(
|
MultiplatformModule(
|
||||||
"application",
|
"application",
|
||||||
listOf(
|
targets = listOf(
|
||||||
ModuleType.common.createDefaultTarget(),
|
ModuleType.common.createDefaultTarget(),
|
||||||
ModuleType.jvm.createDefaultTarget().apply {
|
ModuleType.jvm.createDefaultTarget().apply {
|
||||||
withTemplate(KtorServerTemplate()) {
|
withTemplate(KtorServerTemplate()) {
|
||||||
@@ -336,7 +337,8 @@ object MultiplatformMobileApplicationProjectTemplate : ProjectTemplate() {
|
|||||||
override val setsModules: List<Module> = buildList {
|
override val setsModules: List<Module> = buildList {
|
||||||
val shared = MultiplatformModule(
|
val shared = MultiplatformModule(
|
||||||
"shared",
|
"shared",
|
||||||
listOf(
|
template = MobileMppTemplate(),
|
||||||
|
targets = listOf(
|
||||||
ModuleType.common.createDefaultTarget(),
|
ModuleType.common.createDefaultTarget(),
|
||||||
Module(
|
Module(
|
||||||
"android",
|
"android",
|
||||||
@@ -390,7 +392,7 @@ object MultiplatformMobileLibraryProjectTemplate : ProjectTemplate() {
|
|||||||
KotlinPlugin.modules.reference withValue listOf(
|
KotlinPlugin.modules.reference withValue listOf(
|
||||||
MultiplatformModule(
|
MultiplatformModule(
|
||||||
"library",
|
"library",
|
||||||
listOf(
|
targets = listOf(
|
||||||
ModuleType.common.createDefaultTarget(),
|
ModuleType.common.createDefaultTarget(),
|
||||||
Module(
|
Module(
|
||||||
"android",
|
"android",
|
||||||
|
|||||||
+2
-2
@@ -185,11 +185,11 @@ fun MultiplatformTargetModule(@NonNls name: String, configurator: ModuleConfigur
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Suppress("FunctionName")
|
@Suppress("FunctionName")
|
||||||
fun MultiplatformModule(@NonNls name: String, targets: List<Module> = emptyList()) =
|
fun MultiplatformModule(@NonNls name: String, template: Template? = null, targets: List<Module> = emptyList()) =
|
||||||
Module(
|
Module(
|
||||||
name,
|
name,
|
||||||
MppModuleConfigurator,
|
MppModuleConfigurator,
|
||||||
null,
|
template,
|
||||||
emptyList(),
|
emptyList(),
|
||||||
targets
|
targets
|
||||||
)
|
)
|
||||||
|
|||||||
+9
-48
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.GradleRootProject
|
|||||||
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleDependencyIR
|
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleDependencyIR
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.*
|
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.*
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.*
|
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.*
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.mpp.mppSources
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.isGradle
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.isGradle
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleSubType
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleSubType
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModulesToIrConversionData
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModulesToIrConversionData
|
||||||
@@ -78,14 +79,12 @@ sealed class ModuleDependencyType(
|
|||||||
object AndroidSinglePlatformToMPP : ModuleDependencyType(
|
object AndroidSinglePlatformToMPP : ModuleDependencyType(
|
||||||
from = AndroidSinglePlatformModuleConfigurator::class,
|
from = AndroidSinglePlatformModuleConfigurator::class,
|
||||||
to = MppModuleConfigurator::class
|
to = MppModuleConfigurator::class
|
||||||
) {
|
)
|
||||||
override fun Writer.runArbitraryTask(
|
|
||||||
from: Module,
|
object JVMSinglePlatformToMPP : ModuleDependencyType(
|
||||||
to: Module,
|
from = JvmSinglePlatformModuleConfigurator::class,
|
||||||
toModulePath: Path,
|
to = MppModuleConfigurator::class
|
||||||
data: ModulesToIrConversionData
|
)
|
||||||
): TaskResult<Unit> = addExpectFilesForMppModuleForAndroidAndIos(to, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
object IOSToMppSinglePlatformToMPP : ModuleDependencyType(
|
object IOSToMppSinglePlatformToMPP : ModuleDependencyType(
|
||||||
from = IOSSinglePlatformModuleConfigurator::class,
|
from = IOSSinglePlatformModuleConfigurator::class,
|
||||||
@@ -100,7 +99,6 @@ sealed class ModuleDependencyType(
|
|||||||
toModulePath: Path,
|
toModulePath: Path,
|
||||||
data: ModulesToIrConversionData
|
data: ModulesToIrConversionData
|
||||||
): TaskResult<Unit> = compute {
|
): TaskResult<Unit> = compute {
|
||||||
addExpectFilesForMppModuleForAndroidAndIos(to, data)
|
|
||||||
inContextOfModuleConfigurator(from) {
|
inContextOfModuleConfigurator(from) {
|
||||||
IOSSinglePlatformModuleConfigurator.dependentModule.reference.update {
|
IOSSinglePlatformModuleConfigurator.dependentModule.reference.update {
|
||||||
IOSSinglePlatformModuleConfigurator.DependentModuleReference(to).asSuccess()
|
IOSSinglePlatformModuleConfigurator.DependentModuleReference(to).asSuccess()
|
||||||
@@ -113,7 +111,7 @@ sealed class ModuleDependencyType(
|
|||||||
to: Module,
|
to: Module,
|
||||||
toModulePath: Path,
|
toModulePath: Path,
|
||||||
): TaskResult<Unit> {
|
): TaskResult<Unit> {
|
||||||
val needDummyFile = inContextOfModuleConfigurator(to) { MppModuleConfigurator.mppSources.reference.propertyValue.isEmpty() }
|
val needDummyFile = false/*TODO*/
|
||||||
return if (needDummyFile) {
|
return if (needDummyFile) {
|
||||||
val dummyFilePath =
|
val dummyFilePath =
|
||||||
Defaults.SRC_DIR / "${to.iosTargetSafe()!!.name}Main" / to.configurator.kotlinDirectoryName / "dummyFile.kt"
|
Defaults.SRC_DIR / "${to.iosTargetSafe()!!.name}Main" / to.configurator.kotlinDirectoryName / "dummyFile.kt"
|
||||||
@@ -184,6 +182,7 @@ sealed class ModuleDependencyType(
|
|||||||
companion object {
|
companion object {
|
||||||
private val ALL = listOf(
|
private val ALL = listOf(
|
||||||
JVMSinglePlatformToJVMSinglePlatform,
|
JVMSinglePlatformToJVMSinglePlatform,
|
||||||
|
JVMSinglePlatformToMPP,
|
||||||
AndroidSinglePlatformToMPP,
|
AndroidSinglePlatformToMPP,
|
||||||
IOSToMppSinglePlatformToMPP
|
IOSToMppSinglePlatformToMPP
|
||||||
)
|
)
|
||||||
@@ -195,41 +194,3 @@ sealed class ModuleDependencyType(
|
|||||||
getPossibleDependencyType(from, to) != null
|
getPossibleDependencyType(from, to) != null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Writer.addExpectFilesForMppModuleForAndroidAndIos(mppModule: Module, data: ModulesToIrConversionData): TaskResult<Unit> {
|
|
||||||
val javaPackage = mppModule.javaPackage(data.pomIr)
|
|
||||||
|
|
||||||
val expectFiles = mppSources(javaPackage) {
|
|
||||||
mppFile("Platform.kt") {
|
|
||||||
`class`("Platform") {
|
|
||||||
expectBody = "val platform: String"
|
|
||||||
actualFor(
|
|
||||||
ModuleSubType.android,
|
|
||||||
actualBody = """actual val platform: String = "Android ${'$'}{android.os.Build.VERSION.SDK_INT}""""
|
|
||||||
)
|
|
||||||
|
|
||||||
actualFor(
|
|
||||||
ModuleSubType.iosArm64, ModuleSubType.iosX64, ModuleSubType.ios,
|
|
||||||
actualBody =
|
|
||||||
"""actual val platform: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion"""
|
|
||||||
) {
|
|
||||||
import("platform.UIKit.UIDevice")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
filesFor(ModuleSubType.common) {
|
|
||||||
file(FileTemplateDescriptor("mppCommon/Greeting.kt.vm", relativePath = null), "Greeting.kt", SourcesetType.main)
|
|
||||||
}
|
|
||||||
|
|
||||||
filesFor(ModuleSubType.android) {
|
|
||||||
file(FileTemplateDescriptor("android/androidTest.kt.vm", relativePath = null), "androidTest.kt", SourcesetType.test)
|
|
||||||
}
|
|
||||||
|
|
||||||
filesFor(ModuleSubType.iosArm64, ModuleSubType.iosX64, ModuleSubType.ios) {
|
|
||||||
file(FileTemplateDescriptor("ios/iosTest.kt.vm", relativePath = null), "iosTest.kt", SourcesetType.test)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return inContextOfModuleConfigurator(mppModule) { MppModuleConfigurator.mppSources.reference.addValues(listOf(expectFiles)) }
|
|
||||||
}
|
|
||||||
+5
-1
@@ -13,6 +13,8 @@ import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
|
|||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.SourcesetType
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.SourcesetType
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.KotlinNewProjectWizardBundle
|
import org.jetbrains.kotlin.tools.projectWizard.KotlinNewProjectWizardBundle
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.core.Reader
|
import org.jetbrains.kotlin.tools.projectWizard.core.Reader
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.moduleType
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
|
||||||
|
|
||||||
class ConsoleJvmApplicationTemplate : Template() {
|
class ConsoleJvmApplicationTemplate : Template() {
|
||||||
@NonNls
|
@NonNls
|
||||||
@@ -21,7 +23,9 @@ class ConsoleJvmApplicationTemplate : Template() {
|
|||||||
override val title: String = KotlinNewProjectWizardBundle.message("module.template.console.jvm.title")
|
override val title: String = KotlinNewProjectWizardBundle.message("module.template.console.jvm.title")
|
||||||
override val description: String = KotlinNewProjectWizardBundle.message("module.template.console.jvm.description")
|
override val description: String = KotlinNewProjectWizardBundle.message("module.template.console.jvm.description")
|
||||||
|
|
||||||
override val moduleTypes: Set<ModuleType> = setOf(ModuleType.jvm)
|
|
||||||
|
override fun isSupportedByModuleType(module: Module): Boolean =
|
||||||
|
module.configurator.moduleType == ModuleType.jvm
|
||||||
|
|
||||||
override fun Writer.getIrsToAddToBuildFile(
|
override fun Writer.getIrsToAddToBuildFile(
|
||||||
module: ModuleIR
|
module: ModuleIR
|
||||||
|
|||||||
+2
-1
@@ -20,7 +20,8 @@ import org.jetbrains.kotlin.tools.projectWizard.transformers.interceptors.Templa
|
|||||||
import org.jetbrains.kotlin.tools.projectWizard.transformers.interceptors.interceptTemplate
|
import org.jetbrains.kotlin.tools.projectWizard.transformers.interceptors.interceptTemplate
|
||||||
|
|
||||||
abstract class JsClientTemplate : Template() {
|
abstract class JsClientTemplate : Template() {
|
||||||
override val moduleTypes: Set<ModuleType> = setOf(ModuleType.js)
|
override fun isSupportedByModuleType(module: Module): Boolean =
|
||||||
|
module.configurator.moduleType == ModuleType.js
|
||||||
|
|
||||||
override fun isApplicableTo(
|
override fun isApplicableTo(
|
||||||
reader: Reader,
|
reader: Reader,
|
||||||
|
|||||||
+5
-5
@@ -18,23 +18,23 @@ import org.jetbrains.kotlin.tools.projectWizard.library.MavenArtifact
|
|||||||
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
|
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
|
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.DefaultRepository
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Repositories
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.SourcesetType
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.transformers.interceptors.InterceptionPoint
|
import org.jetbrains.kotlin.tools.projectWizard.transformers.interceptors.InterceptionPoint
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.KotlinNewProjectWizardBundle
|
import org.jetbrains.kotlin.tools.projectWizard.KotlinNewProjectWizardBundle
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.Versions
|
import org.jetbrains.kotlin.tools.projectWizard.Versions
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.WizardGradleRunConfiguration
|
import org.jetbrains.kotlin.tools.projectWizard.WizardGradleRunConfiguration
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.WizardRunConfiguration
|
import org.jetbrains.kotlin.tools.projectWizard.WizardRunConfiguration
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.core.Reader
|
import org.jetbrains.kotlin.tools.projectWizard.core.Reader
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.moduleType
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.ModuleKind
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.*
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
|
import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
|
||||||
|
|
||||||
class KtorServerTemplate : Template() {
|
class KtorServerTemplate : Template() {
|
||||||
override val title: String = KotlinNewProjectWizardBundle.message("module.template.ktor.server.title")
|
override val title: String = KotlinNewProjectWizardBundle.message("module.template.ktor.server.title")
|
||||||
override val description: String = KotlinNewProjectWizardBundle.message("module.template.ktor.server.description")
|
override val description: String = KotlinNewProjectWizardBundle.message("module.template.ktor.server.description")
|
||||||
override val moduleTypes: Set<ModuleType> = setOf(ModuleType.jvm)
|
|
||||||
|
override fun isSupportedByModuleType(module: Module): Boolean =
|
||||||
|
module.configurator.moduleType == ModuleType.jvm
|
||||||
|
|
||||||
@NonNls
|
@NonNls
|
||||||
override val id: String = "ktorServer"
|
override val id: String = "ktorServer"
|
||||||
|
|||||||
+4
-1
@@ -16,13 +16,16 @@ import org.jetbrains.kotlin.tools.projectWizard.KotlinNewProjectWizardBundle
|
|||||||
import org.jetbrains.kotlin.tools.projectWizard.core.*
|
import org.jetbrains.kotlin.tools.projectWizard.core.*
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.core.safeAs
|
import org.jetbrains.kotlin.tools.projectWizard.core.safeAs
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.NativeTargetConfigurator
|
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.NativeTargetConfigurator
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.moduleType
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
|
||||||
|
|
||||||
class NativeConsoleApplicationTemplate : Template() {
|
class NativeConsoleApplicationTemplate : Template() {
|
||||||
override val title: String = KotlinNewProjectWizardBundle.message("module.template.native.console.title")
|
override val title: String = KotlinNewProjectWizardBundle.message("module.template.native.console.title")
|
||||||
override val description: String = KotlinNewProjectWizardBundle.message("module.template.native.console.description")
|
override val description: String = KotlinNewProjectWizardBundle.message("module.template.native.console.description")
|
||||||
|
|
||||||
override val moduleTypes: Set<ModuleType> = setOf(ModuleType.native)
|
override fun isSupportedByModuleType(module: Module): Boolean =
|
||||||
|
module.configurator.moduleType == ModuleType.native
|
||||||
|
|
||||||
override val id: String = "nativeConsoleApp"
|
override val id: String = "nativeConsoleApp"
|
||||||
|
|
||||||
override fun isApplicableTo(
|
override fun isApplicableTo(
|
||||||
|
|||||||
+4
-1
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
|
|||||||
import org.jetbrains.kotlin.tools.projectWizard.library.MavenArtifact
|
import org.jetbrains.kotlin.tools.projectWizard.library.MavenArtifact
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.JsNodeTargetConfigurator
|
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.JsNodeTargetConfigurator
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.NodeJsSinglePlatformModuleConfigurator
|
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.NodeJsSinglePlatformModuleConfigurator
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.moduleType
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
|
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.DefaultRepository.Companion.JCENTER
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.DefaultRepository.Companion.JCENTER
|
||||||
@@ -26,7 +27,9 @@ class SimpleNodeJsTemplate : Template() {
|
|||||||
|
|
||||||
override val description: String = KotlinNewProjectWizardBundle.message("module.template.simple.nodejs.description")
|
override val description: String = KotlinNewProjectWizardBundle.message("module.template.simple.nodejs.description")
|
||||||
|
|
||||||
override val moduleTypes: Set<ModuleType> = setOf(ModuleType.js)
|
|
||||||
|
override fun isSupportedByModuleType(module: Module): Boolean =
|
||||||
|
module.configurator.moduleType == ModuleType.js
|
||||||
|
|
||||||
@NonNls
|
@NonNls
|
||||||
override val id: String = "simpleNodeJs"
|
override val id: String = "simpleNodeJs"
|
||||||
|
|||||||
+32
-11
@@ -9,15 +9,13 @@ import org.jetbrains.kotlin.tools.projectWizard.core.*
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.*
|
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.*
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.enumSettingImpl
|
import org.jetbrains.kotlin.tools.projectWizard.enumSettingImpl
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
|
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.DependencyIR
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleIR
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.MultiplatformModuleIR
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.multiplatform.TargetConfigurationIR
|
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.multiplatform.TargetConfigurationIR
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
|
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.RunConfigurationsPlugin
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.RunConfigurationsPlugin
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModulesToIrConversionData
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
|
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
|
import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
|
||||||
@@ -73,7 +71,8 @@ abstract class Template : SettingsOwner, EntitiesOwnerDescriptor, DisplayableSet
|
|||||||
|
|
||||||
abstract val title: String
|
abstract val title: String
|
||||||
abstract val description: String
|
abstract val description: String
|
||||||
abstract val moduleTypes: Set<ModuleType>
|
|
||||||
|
abstract fun isSupportedByModuleType(module: Module): Boolean
|
||||||
|
|
||||||
override val text: String get() = title
|
override val text: String get() = title
|
||||||
|
|
||||||
@@ -100,6 +99,10 @@ abstract class Template : SettingsOwner, EntitiesOwnerDescriptor, DisplayableSet
|
|||||||
module: ModuleIR
|
module: ModuleIR
|
||||||
): List<BuildSystemIR> = emptyList()
|
): List<BuildSystemIR> = emptyList()
|
||||||
|
|
||||||
|
open fun Writer.runArbitratyTask(
|
||||||
|
module: ModuleIR
|
||||||
|
): TaskResult<Unit> = UNIT_SUCCESS
|
||||||
|
|
||||||
open fun updateTargetIr(
|
open fun updateTargetIr(
|
||||||
module: ModuleIR,
|
module: ModuleIR,
|
||||||
targetConfigurationIR: TargetConfigurationIR
|
targetConfigurationIR: TargetConfigurationIR
|
||||||
@@ -112,24 +115,39 @@ abstract class Template : SettingsOwner, EntitiesOwnerDescriptor, DisplayableSet
|
|||||||
|
|
||||||
open fun Reader.createRunConfigurations(module: ModuleIR): List<WizardRunConfiguration> = emptyList()
|
open fun Reader.createRunConfigurations(module: ModuleIR): List<WizardRunConfiguration> = emptyList()
|
||||||
|
|
||||||
|
|
||||||
|
open fun Reader.updateModuleIR(module: ModuleIR): ModuleIR = module
|
||||||
|
open fun Reader.updateBuildFileIRs(irs: List<BuildSystemIR>): List<BuildSystemIR> = irs
|
||||||
|
|
||||||
|
open fun createRootBuildFileIrs(): List<BuildSystemIR> = emptyList()
|
||||||
|
|
||||||
fun Writer.applyToSourceset(
|
fun Writer.applyToSourceset(
|
||||||
module: ModuleIR
|
module: ModuleIR
|
||||||
): TaskResult<TemplateApplicationResult> {
|
): TaskResult<TemplateApplicationResult> = compute {
|
||||||
|
|
||||||
val librariesToAdd = getRequiredLibraries(module)
|
val librariesToAdd = getRequiredLibraries(module)
|
||||||
val irsToAddToBuildFile = getIrsToAddToBuildFile(module)
|
val irsToAddToBuildFile = getIrsToAddToBuildFile(module)
|
||||||
|
runArbitratyTask(module).ensure()
|
||||||
|
|
||||||
val targetsUpdater = when (module) {
|
val targetsUpdater = when (module) {
|
||||||
is MultiplatformModuleIR -> { target: TargetConfigurationIR ->
|
is MultiplatformModuleIR -> { target: TargetConfigurationIR ->
|
||||||
if (target.targetName == module.name) updateTargetIr(module, target)
|
if (target.targetName == module.name) updateTargetIr(module, target)
|
||||||
else target
|
else target
|
||||||
}
|
}
|
||||||
|
is FakeMultiplatformModuleIR -> {
|
||||||
|
module.targets.map { expectedTarget ->
|
||||||
|
{ configurationIR: TargetConfigurationIR ->
|
||||||
|
if (configurationIR.targetName == expectedTarget.name) updateTargetIr(expectedTarget, configurationIR)
|
||||||
|
else configurationIR
|
||||||
|
}
|
||||||
|
}.reduce(::compose)
|
||||||
|
}
|
||||||
else -> idFunction()
|
else -> idFunction()
|
||||||
}
|
}
|
||||||
|
|
||||||
RunConfigurationsPlugin.configurations.addValues(createRunConfigurations(module))
|
RunConfigurationsPlugin.configurations.addValues(createRunConfigurations(module))
|
||||||
|
|
||||||
val result = TemplateApplicationResult(librariesToAdd, irsToAddToBuildFile, targetsUpdater)
|
TemplateApplicationResult(librariesToAdd, irsToAddToBuildFile, targetsUpdater) { updateModuleIR(it) }
|
||||||
return result.asSuccess()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Reader.settingsAsMap(module: Module): Map<String, Any> = mutableMapOf<String, Any>().apply {
|
fun Reader.settingsAsMap(module: Module): Map<String, Any> = mutableMapOf<String, Any>().apply {
|
||||||
@@ -290,13 +308,15 @@ fun Writer.applyTemplateToModule(
|
|||||||
data class TemplateApplicationResult(
|
data class TemplateApplicationResult(
|
||||||
val librariesToAdd: List<DependencyIR>,
|
val librariesToAdd: List<DependencyIR>,
|
||||||
val irsToAddToBuildFile: List<BuildSystemIR>,
|
val irsToAddToBuildFile: List<BuildSystemIR>,
|
||||||
val updateTarget: (TargetConfigurationIR) -> TargetConfigurationIR
|
val updateTarget: (TargetConfigurationIR) -> TargetConfigurationIR,
|
||||||
|
val updateModuleIR: (ModuleIR) -> ModuleIR
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
val EMPTY = TemplateApplicationResult(
|
val EMPTY = TemplateApplicationResult(
|
||||||
librariesToAdd = emptyList(),
|
librariesToAdd = emptyList(),
|
||||||
irsToAddToBuildFile = emptyList(),
|
irsToAddToBuildFile = emptyList(),
|
||||||
updateTarget = { it }
|
updateTarget = { it },
|
||||||
|
updateModuleIR = { it },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -308,5 +328,6 @@ operator fun TemplateApplicationResult.plus(other: TemplateApplicationResult) =
|
|||||||
TemplateApplicationResult(
|
TemplateApplicationResult(
|
||||||
librariesToAdd + other.librariesToAdd,
|
librariesToAdd + other.librariesToAdd,
|
||||||
irsToAddToBuildFile + other.irsToAddToBuildFile,
|
irsToAddToBuildFile + other.irsToAddToBuildFile,
|
||||||
updateTarget andThen other.updateTarget
|
updateTarget andThen other.updateTarget,
|
||||||
|
updateModuleIR andThen other.updateModuleIR,
|
||||||
)
|
)
|
||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.tools.projectWizard.templates.mpp
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.KotlinNewProjectWizardBundle
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.core.Reader
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.core.TaskResult
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.core.Writer
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleIR
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.RepositoryIR
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.irsList
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.MppModuleConfigurator
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.mpp.applyMppStructure
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.mpp.mppSources
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleSubType
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.pomIR
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.DefaultRepository
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.SourcesetType
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.settings.javaPackage
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplateDescriptor
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.templates.Template
|
||||||
|
|
||||||
|
class MobileMppTemplate : Template() {
|
||||||
|
@NonNls
|
||||||
|
override val id: String = "mobileMppModule"
|
||||||
|
|
||||||
|
override val title: String = KotlinNewProjectWizardBundle.message("module.template.mpp.mobile.title")
|
||||||
|
override val description: String = KotlinNewProjectWizardBundle.message("module.template.mpp.mobile.description")
|
||||||
|
|
||||||
|
override fun isSupportedByModuleType(module: Module): Boolean =
|
||||||
|
module.configurator == MppModuleConfigurator
|
||||||
|
|
||||||
|
|
||||||
|
override fun Writer.getIrsToAddToBuildFile(module: ModuleIR): List<BuildSystemIR> = irsList {
|
||||||
|
+RepositoryIR(DefaultRepository.JCENTER)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Writer.runArbitratyTask(module: ModuleIR): TaskResult<Unit> {
|
||||||
|
val javaPackage = module.originalModule.javaPackage(pomIR())
|
||||||
|
|
||||||
|
val mpp = mppSources(javaPackage) {
|
||||||
|
mppFile("Platform.kt") {
|
||||||
|
`class`("Platform") {
|
||||||
|
expectBody = "val platform: String"
|
||||||
|
actualFor(
|
||||||
|
ModuleSubType.android,
|
||||||
|
actualBody = """actual val platform: String = "Android ${'$'}{android.os.Build.VERSION.SDK_INT}""""
|
||||||
|
)
|
||||||
|
|
||||||
|
actualFor(
|
||||||
|
ModuleSubType.iosArm64, ModuleSubType.iosX64, ModuleSubType.ios,
|
||||||
|
actualBody =
|
||||||
|
"""actual val platform: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion"""
|
||||||
|
) {
|
||||||
|
import("platform.UIKit.UIDevice")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filesFor(ModuleSubType.common) {
|
||||||
|
file(FileTemplateDescriptor("mppCommon/Greeting.kt.vm", relativePath = null), "Greeting.kt", SourcesetType.main)
|
||||||
|
}
|
||||||
|
|
||||||
|
filesFor(ModuleSubType.android) {
|
||||||
|
file(FileTemplateDescriptor("android/androidTest.kt.vm", relativePath = null), "androidTest.kt", SourcesetType.test)
|
||||||
|
}
|
||||||
|
|
||||||
|
filesFor(ModuleSubType.iosArm64, ModuleSubType.iosX64, ModuleSubType.ios) {
|
||||||
|
file(FileTemplateDescriptor("ios/iosTest.kt.vm", relativePath = null), "iosTest.kt", SourcesetType.test)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return applyMppStructure(mpp, module.originalModule, module.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.tools.projectWizard.core
|
package org.jetbrains.kotlin.tools.projectWizard.core
|
||||||
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.mppSources
|
import org.jetbrains.kotlin.tools.projectWizard.mpp.mppSources
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleSubType
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleSubType
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|||||||
Reference in New Issue
Block a user