Wizard: add MPP mobile application project skeleton

This commit is contained in:
Ilya Kirillov
2020-03-22 21:32:26 +03:00
parent 732154cef5
commit b169d260d3
10 changed files with 209 additions and 53 deletions
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.*
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.buildsystem.ModuleKind import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.ModuleKind
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.htmlText import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.fullTextHtml
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.icon import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.icon
import javax.swing.Icon import javax.swing.Icon
@@ -46,7 +46,7 @@ class CreateModuleOrTargetPopup private constructor(
} }
) { ) {
override fun getIconFor(value: ModuleConfigurator): Icon = value.icon override fun getIconFor(value: ModuleConfigurator): Icon = value.icon
override fun getTextFor(value: ModuleConfigurator): String = value.htmlText override fun getTextFor(value: ModuleConfigurator): String = value.fullTextHtml
override fun onChosen(selectedValue: ModuleConfigurator?, finalChoice: Boolean): PopupStep<*>? = override fun onChosen(selectedValue: ModuleConfigurator?, finalChoice: Boolean): PopupStep<*>? =
when (selectedValue) { when (selectedValue) {
@@ -71,7 +71,7 @@ class CreateModuleOrTargetPopup private constructor(
else -> null else -> null
} }
override fun getTextFor(value: DisplayableSettingItem): String = value.htmlText override fun getTextFor(value: DisplayableSettingItem): String = value.fullTextHtml
override fun onChosen(selectedValue: DisplayableSettingItem?, finalChoice: Boolean): PopupStep<*>? { override fun onChosen(selectedValue: DisplayableSettingItem?, finalChoice: Boolean): PopupStep<*>? {
when { when {
@@ -77,20 +77,6 @@ fun ValidationResult.ValidationError.asHtml() = when (messages.size) {
} }
} }
val DisplayableSettingItem.htmlText
get() = (text + greyText?.let { " <i>($greyText)</i>" }.orEmpty()).asHtml()
fun splitterFor(
vararg components: JComponent,
vertical: Boolean = false
) = components.reduce { left, right ->
JBSplitter(vertical, 1f / components.size).apply {
firstComponent = left
secondComponent = right
dividerWidth = 1
}
}
val ModuleType.icon: Icon val ModuleType.icon: Icon
get() = when (this) { get() = when (this) {
ModuleType.jvm -> KotlinIcons.SMALL_LOGO ModuleType.jvm -> KotlinIcons.SMALL_LOGO
@@ -196,6 +196,10 @@ class Context private constructor(
} }
open inner class Writer : Reader() { open inner class Writer : Reader() {
@Deprecated("Allows to get SettingsWriter where it is not supposed to be")
val unsafeSettingWriter: SettingsWriter
get() = settingWritingContext
val eventManager: EventManager val eventManager: EventManager
get() = settingContext.eventManager get() = settingContext.eventManager
@@ -25,6 +25,14 @@ abstract class Parser<out T : Any> {
abstract fun ParsingContext.parse(value: Any?, path: String): TaskResult<T> abstract fun ParsingContext.parse(value: Any?, path: String): TaskResult<T>
} }
fun <T : Any> alwaysFailingParser(errorMessage: String) = object : Parser<T>() {
override fun ParsingContext.parse(value: Any?, path: String): TaskResult<T> =
Failure(object : Error() {
override val message: String get() = errorMessage
})
}
fun <T : Any> Parser<T>.parse(context: ParsingContext, value: Any?, path: String) = fun <T : Any> Parser<T>.parse(context: ParsingContext, value: Any?, path: String) =
with(context) { parse(value, path) } with(context) { parse(value, path) }
@@ -126,7 +126,7 @@ object AndroidTargetConfigurator : TargetConfigurator,
SingleCoexistenceTargetConfigurator, SingleCoexistenceTargetConfigurator,
ModuleConfiguratorSettings() { ModuleConfiguratorSettings() {
override val moduleSubType = ModuleSubType.android override val moduleSubType = ModuleSubType.android
override val moduleType = ModuleType.jvm override val moduleType = ModuleType.android
override fun Reader.createAndroidPlugin(module: Module): AndroidGradlePlugin = override fun Reader.createAndroidPlugin(module: Module): AndroidGradlePlugin =
withSettingsOf(module) { androidPlugin.reference.settingValue } withSettingsOf(module) { androidPlugin.reference.settingValue }
@@ -6,17 +6,16 @@
package org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators package org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators
import org.jetbrains.kotlin.tools.projectWizard.core.* import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
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.templates.TemplatesPlugin import org.jetbrains.kotlin.tools.projectWizard.plugins.templates.TemplatesPlugin
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.ModuleKind
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplate import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplate
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplateDescriptor import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplateDescriptor
import java.io.File
import java.nio.file.Path import java.nio.file.Path
object IOSSinglePlatformModuleConfigurator : object IOSSinglePlatformModuleConfigurator : SinglePlatformModuleConfigurator, ModuleConfiguratorSettings() {
SinglePlatformModuleConfigurator {
override val id = "IOS Module" override val id = "IOS Module"
override val suggestedModuleName = "ios" override val suggestedModuleName = "ios"
override val moduleKind: ModuleKind = ModuleKind.singleplatformJvm override val moduleKind: ModuleKind = ModuleKind.singleplatformJvm
@@ -25,20 +24,16 @@ object IOSSinglePlatformModuleConfigurator :
override val needCreateBuildFile: Boolean = false override val needCreateBuildFile: Boolean = false
override val requiresRootBuildFile: Boolean = true override val requiresRootBuildFile: Boolean = true
override fun Writer.runArbitraryTask( override fun Reader.createTemplates(
configurationData: ModulesToIrConversionData, configurationData: ModulesToIrConversionData,
module: Module, module: Module,
modulePath: Path modulePath: Path
): TaskResult<Unit> { ): List<FileTemplate> {
val settings = mapOf<String, Any?>( val settings = createTemplatesSettingValues(module, configurationData)
"moduleName" to module.name,
"sharedModuleName" to "SHARED",
"pathToSharedModule" to "../SHARED"
)
fun fileTemplate(path: Path) = FileTemplate(descriptor(path, module.name), modulePath, settings) fun fileTemplate(path: Path) = FileTemplate(descriptor(path, module.name), modulePath, settings)
return TemplatesPlugin::addFileTemplates.execute(buildList { return buildList {
+fileTemplate("$DEFAULT_APP_NAME.xcodeproj" / "project.pbxproj") +fileTemplate("$DEFAULT_APP_NAME.xcodeproj" / "project.pbxproj")
+fileTemplate(DEFAULT_APP_NAME / "AppDelegate.swift") +fileTemplate(DEFAULT_APP_NAME / "AppDelegate.swift")
@@ -56,7 +51,27 @@ object IOSSinglePlatformModuleConfigurator :
+fileTemplate("${DEFAULT_APP_NAME}UITests" / "Info.plist") +fileTemplate("${DEFAULT_APP_NAME}UITests" / "Info.plist")
+fileTemplate("${DEFAULT_APP_NAME}UITests" / "${DEFAULT_APP_NAME}UITests.swift") +fileTemplate("${DEFAULT_APP_NAME}UITests" / "${DEFAULT_APP_NAME}UITests.swift")
}) }
}
private fun Reader.createTemplatesSettingValues(
module: Module,
configurationData: ModulesToIrConversionData
): Map<String, Any?> {
val dependentModule = withSettingsOf(module) {
dependentModule.reference.notRequiredSettingValue?.module
}
val dependentModulePath = dependentModule
?.path
?.considerSingleRootModuleMode(configurationData.isSingleRootModuleMode)
?.asString(separator = File.separator)
?.asPath()
return mapOf(
"moduleName" to module.name,
"sharedModuleName" to dependentModule?.name,
"pathToSharedModule" to dependentModulePath
)
} }
private fun descriptor(path: Path, moduleName: String) = private fun descriptor(path: Path, moduleName: String) =
@@ -66,4 +81,18 @@ object IOSSinglePlatformModuleConfigurator :
) )
private const val DEFAULT_APP_NAME = "moduleName" private const val DEFAULT_APP_NAME = "moduleName"
val dependentModule by valueSetting<DependentModuleReference>(
"",
GenerationPhase.PROJECT_GENERATION,
alwaysFailingParser("Dependent module setting should not be parsed")
) {
defaultValue = value(DependentModuleReference.EMPTY)
}
data class DependentModuleReference(val module: Module?) {
companion object {
val EMPTY = DependentModuleReference(module = null)
}
}
} }
@@ -15,19 +15,21 @@ import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.correspondingStdl
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.buildsystem.ModuleKind import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.ModuleKind
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.ModulePath
import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplate
import java.nio.file.Path import java.nio.file.Path
import kotlin.properties.ReadOnlyProperty import kotlin.properties.ReadOnlyProperty
sealed class ModuleCondifuratorSettingsEnvironment { interface ModuleConfiguratorSettingsEnvironment {
abstract val <V : Any, T : SettingType<V>> ModuleConfiguratorSetting<V, T>.reference: ModuleConfiguratorSettingReference<V, T> val <V : Any, T : SettingType<V>> ModuleConfiguratorSetting<V, T>.reference: ModuleConfiguratorSettingReference<V, T>
} }
class ModuleBasedConfiguratorSettingsEnvironment( class ModuleBasedConfiguratorSettingsEnvironment(
private val configurator: ModuleConfigurator, private val configurator: ModuleConfigurator,
private val module: Module private val module: Module
) : ModuleCondifuratorSettingsEnvironment() { ) : ModuleConfiguratorSettingsEnvironment {
override val <V : Any, T : SettingType<V>> ModuleConfiguratorSetting<V, T>.reference: ModuleConfiguratorSettingReference<V, T> override val <V : Any, T : SettingType<V>> ModuleConfiguratorSetting<V, T>.reference: ModuleConfiguratorSettingReference<V, T>
get() = ModuleBasedConfiguratorSettingReference(configurator, module, this) get() = ModuleBasedConfiguratorSettingReference(configurator, module, this)
} }
@@ -35,7 +37,7 @@ class ModuleBasedConfiguratorSettingsEnvironment(
class IdBasedConfiguratorSettingsEnvironment( class IdBasedConfiguratorSettingsEnvironment(
private val configurator: ModuleConfigurator, private val configurator: ModuleConfigurator,
private val moduleId: Identificator private val moduleId: Identificator
) : ModuleCondifuratorSettingsEnvironment() { ) : ModuleConfiguratorSettingsEnvironment {
override val <V : Any, T : SettingType<V>> ModuleConfiguratorSetting<V, T>.reference: ModuleConfiguratorSettingReference<V, T> override val <V : Any, T : SettingType<V>> ModuleConfiguratorSetting<V, T>.reference: ModuleConfiguratorSettingReference<V, T>
get() = IdBasedConfiguratorSettingReference(configurator, moduleId, this) get() = IdBasedConfiguratorSettingReference(configurator, moduleId, this)
} }
@@ -43,13 +45,13 @@ class IdBasedConfiguratorSettingsEnvironment(
fun <T> withSettingsOf( fun <T> withSettingsOf(
moduleId: Identificator, moduleId: Identificator,
configurator: ModuleConfigurator, configurator: ModuleConfigurator,
function: ModuleCondifuratorSettingsEnvironment.() -> T function: ModuleConfiguratorSettingsEnvironment.() -> T
): T = function(IdBasedConfiguratorSettingsEnvironment(configurator, moduleId)) ): T = function(IdBasedConfiguratorSettingsEnvironment(configurator, moduleId))
fun <T> withSettingsOf( fun <T> withSettingsOf(
module: Module, module: Module,
configurator: ModuleConfigurator = module.configurator, configurator: ModuleConfigurator = module.configurator,
function: ModuleCondifuratorSettingsEnvironment.() -> T function: ModuleConfiguratorSettingsEnvironment.() -> T
): T = function(ModuleBasedConfiguratorSettingsEnvironment(configurator, module)) ): T = function(ModuleBasedConfiguratorSettingsEnvironment(configurator, module))
@@ -231,6 +233,12 @@ interface ModuleConfigurator : DisplayableSettingItem, EntitiesOwnerDescriptor {
modulePath: Path modulePath: Path
): TaskResult<Unit> = UNIT_SUCCESS ): TaskResult<Unit> = UNIT_SUCCESS
fun Reader.createTemplates(
configurationData: ModulesToIrConversionData,
module: Module,
modulePath: Path
): List<FileTemplate> = emptyList()
companion object { companion object {
val ALL = buildList<ModuleConfigurator> { val ALL = buildList<ModuleConfigurator> {
+RealNativeTargetConfigurator.configurators +RealNativeTargetConfigurator.configurators
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.*
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
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.buildSystem.isGradle import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.isGradle
import org.jetbrains.kotlin.tools.projectWizard.plugins.templates.TemplatesPlugin
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.* 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
import java.nio.file.Path import java.nio.file.Path
@@ -106,8 +107,13 @@ class ModulesToIRsConverter(
val to = data.moduleByPath.getValue(dependency.path) val to = data.moduleByPath.getValue(dependency.path)
val (dependencyType) = ModuleDependencyType.getPossibleDependencyType(module, to) val (dependencyType) = ModuleDependencyType.getPossibleDependencyType(module, to)
.toResult { InvalidModuleDependencyError(module, to) } .toResult { InvalidModuleDependencyError(module, to) }
dependencyType.createDependencyIrs(module, to, data)
}.sequence() with(dependencyType) {
@Suppress("DEPRECATION")
with(unsafeSettingWriter) { runArbitraryTask(module, to, data).ensure() }
createDependencyIrs(module, to, data)
}
}.sequence().map { it.flatten() }
mutateProjectStructureByModuleConfigurator(module, modulePath) mutateProjectStructureByModuleConfigurator(module, modulePath)
val buildFileIR = run { val buildFileIR = run {
if (!configurator.needCreateBuildFile) return@run null if (!configurator.needCreateBuildFile) return@run null
@@ -237,6 +243,7 @@ class ModulesToIRsConverter(
compute { compute {
rootBuildFileIrs += createRootBuildFileIrs(data) rootBuildFileIrs += createRootBuildFileIrs(data)
runArbitraryTask(data, module, modulePath).ensure() runArbitraryTask(data, module, modulePath).ensure()
TemplatesPlugin::addFileTemplates.execute(createTemplates(data, module, modulePath)).ensure()
if (this@with is GradleModuleConfigurator) { if (this@with is GradleModuleConfigurator) {
GradlePlugin::settingsGradleFileIRs.addValues(createSettingsGradleIRs(module)).ensure() GradlePlugin::settingsGradleFileIRs.addValues(createSettingsGradleIRs(module)).ensure()
} }
@@ -23,18 +23,22 @@ sealed class ProjectTemplate : DisplayableSettingItem {
private val setsDefaultValues: List<SettingWithValue<*, *>> private val setsDefaultValues: List<SettingWithValue<*, *>>
get() = listOf(KotlinPlugin::projectKind.reference withValue projectKind) get() = listOf(KotlinPlugin::projectKind.reference withValue projectKind)
protected abstract val setsPluginSettings: List<SettingWithValue<*, *>> protected open val setsPluginSettings: List<SettingWithValue<*, *>> = emptyList()
protected open val setsModules: List<Module> = emptyList()
private val setsAdditionalSettingValues = mutableListOf<SettingWithValue<*, *>>() private val setsAdditionalSettingValues = mutableListOf<SettingWithValue<*, *>>()
val setsValues: List<SettingWithValue<*, *>> val setsValues: List<SettingWithValue<*, *>>
get() = buildList { get() = buildList {
setsModules.takeIf { it.isNotEmpty() }?.let { modules ->
+(KotlinPlugin::modules withValue modules)
}
+setsDefaultValues +setsDefaultValues
+setsPluginSettings +setsPluginSettings
+setsAdditionalSettingValues +setsAdditionalSettingValues
} }
fun <T : Template> Module.withTemplate( protected fun <T : Template> Module.withTemplate(
template: T, template: T,
createSettings: TemplateSettingsBuilder<T>.() -> Unit = {} createSettings: TemplateSettingsBuilder<T>.() -> Unit = {}
) = apply { ) = apply {
@@ -45,6 +49,17 @@ sealed class ProjectTemplate : DisplayableSettingItem {
} }
} }
protected fun <C : ModuleConfigurator> Module.withConfiguratorSettings(
configurator: C,
createSettings: ConfiguratorSettingsBuilder<C>.() -> Unit = {}
) = apply {
assert(this.configurator === configurator)
with(ConfiguratorSettingsBuilder(this, configurator)) {
createSettings()
setsAdditionalSettingValues += setsSettings
}
}
companion object { companion object {
val ALL = listOf( val ALL = listOf(
@@ -55,6 +70,7 @@ sealed class ProjectTemplate : DisplayableSettingItem {
MultiplatformLibrary, MultiplatformLibrary,
AndroidApplication, AndroidApplication,
IOSApplication, IOSApplication,
MPPMobileApplication,
MultiplatformMobileLibrary, MultiplatformMobileLibrary,
NativeConsoleApplication, NativeConsoleApplication,
JsBrowserApplication JsBrowserApplication
@@ -77,6 +93,23 @@ class TemplateSettingsBuilder<Q : Template>(
infix fun <V : Any, T : SettingType<V>> TemplateSetting<V, T>.withValue(value: V) { infix fun <V : Any, T : SettingType<V>> TemplateSetting<V, T>.withValue(value: V) {
settings += SettingWithValue(reference, value) settings += SettingWithValue(reference, value)
} }
}
class ConfiguratorSettingsBuilder<C : ModuleConfigurator>(
val module: Module,
val configurator: C
) : ModuleConfiguratorSettingsEnvironment by ModuleBasedConfiguratorSettingsEnvironment(configurator, module) {
init {
assert(module.configurator === configurator)
}
private val settings = mutableListOf<SettingWithValue<*, *>>()
val setsSettings: List<SettingWithValue<*, *>>
get() = settings
infix fun <V : Any, T : SettingType<V>> ModuleConfiguratorSetting<V, T>.withValue(value: V) {
settings += SettingWithValue(reference, value)
}
} }
@@ -89,7 +122,7 @@ inline infix fun <V : Any, reified T : SettingType<V>> PluginSettingPropertyRefe
value: V value: V
): SettingWithValue<V, T> = reference.withValue(value) ): SettingWithValue<V, T> = reference.withValue(value)
private fun ModuleType.createDefaultSourcesets() = private fun createDefaultSourcesets() =
SourcesetType.values().map { sourcesetType -> SourcesetType.values().map { sourcesetType ->
Sourceset( Sourceset(
sourcesetType, sourcesetType,
@@ -110,7 +143,7 @@ object EmptySingleplatformProjectTemplate : ProjectTemplate() {
override val setsPluginSettings: List<SettingWithValue<*, *>> override val setsPluginSettings: List<SettingWithValue<*, *>>
get() = listOf( get() = listOf(
KotlinPlugin::modules withValue listOf( KotlinPlugin::modules withValue listOf(
SingleplatformModule("mainModule", ModuleType.jvm.createDefaultSourcesets()) SingleplatformModule("mainModule", createDefaultSourcesets())
) )
) )
} }
@@ -140,7 +173,7 @@ object JvmConsoleApplication : ProjectTemplate() {
KotlinPlugin::modules withValue listOf( KotlinPlugin::modules withValue listOf(
SingleplatformModule( SingleplatformModule(
"consoleApp", "consoleApp",
ModuleType.jvm.createDefaultSourcesets() createDefaultSourcesets()
).apply { ).apply {
withTemplate(ConsoleJvmApplicationTemplate()) withTemplate(ConsoleJvmApplicationTemplate())
} }
@@ -173,7 +206,7 @@ object MultiplatformLibrary : ProjectTemplate() {
object JvmServerJsClient : ProjectTemplate() { object JvmServerJsClient : ProjectTemplate() {
override val title: String = "Full-Stack Web Application" override val title: String = "Full-Stack Web Application"
override val description: String = "" + override val description: String = "" +
"Create a fully-functional web application using Kotlin/JS for the frontend and Kotlin/JVM for the backend" "Create a fully-functional web application using Kotlin/JS for the frontend and Kotlin/JVM for the backend."
override val suggestedProjectName: String = "myFullStackApplication" override val suggestedProjectName: String = "myFullStackApplication"
override val projectKind: ProjectKind = ProjectKind.Multiplatform override val projectKind: ProjectKind = ProjectKind.Multiplatform
override val setsPluginSettings: List<SettingWithValue<*, *>> = listOf( override val setsPluginSettings: List<SettingWithValue<*, *>> = listOf(
@@ -288,6 +321,57 @@ object IOSApplication : ProjectTemplate() {
) )
} }
object MPPMobileApplication : ProjectTemplate() {
override val title = "Multiplatform Mobile Application"
override val description =
"Create mobile applications for iOS and Android with Kotlin Multiplatform Mobile, which supports sharing common code between platforms."
override val suggestedProjectName = "myIOSApplication"
override val projectKind = ProjectKind.Multiplatform
override val setsModules: List<Module> = buildList {
val shared = MultiplatformModule(
"shared",
listOf(
ModuleType.common.createDefaultTarget(),
Module(
"android",
AndroidTargetConfigurator,
null,
sourcesets = createDefaultSourcesets(),
subModules = emptyList()
).withConfiguratorSettings(AndroidTargetConfigurator) {
configurator.androidPlugin withValue AndroidGradlePlugin.APPLICATION
},
Module(
"ios",
RealNativeTargetConfigurator.configuratorsByModuleType.getValue(ModuleSubType.iosX64),
null,
sourcesets = createDefaultSourcesets(),
subModules = emptyList()
)
)
)
+shared
+Module(
"iosApp",
IOSSinglePlatformModuleConfigurator,
template = null,
sourcesets = createDefaultSourcesets(),
subModules = emptyList(),
dependencies = mutableListOf(ModuleReference.ByModule(shared))
)
+Module(
"androidApp",
AndroidSinglePlatformModuleConfigurator,
template = null,
sourcesets = createDefaultSourcesets(),
subModules = emptyList(),
dependencies = mutableListOf(ModuleReference.ByModule(shared))
)
}
}
object MultiplatformMobileLibrary : ProjectTemplate() { object MultiplatformMobileLibrary : ProjectTemplate() {
override val title = "Multiplatform Mobile Library" override val title = "Multiplatform Mobile Library"
override val description = "Create a library that supports sharing code between iOS and Android." override val description = "Create a library that supports sharing code between iOS and Android."
@@ -309,7 +393,9 @@ object MultiplatformMobileLibrary : ProjectTemplate() {
Sourceset(type, dependencies = emptyList()) Sourceset(type, dependencies = emptyList())
}, },
emptyList() emptyList()
), ).withConfiguratorSettings(AndroidTargetConfigurator) {
configurator.androidPlugin withValue AndroidGradlePlugin.LIBRARY
},
Module( Module(
"ios", "ios",
RealNativeTargetConfigurator.configuratorsByModuleType.getValue(ModuleSubType.iosX64), RealNativeTargetConfigurator.configuratorsByModuleType.getValue(ModuleSubType.iosX64),
@@ -5,12 +5,13 @@
package org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem package org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.asSingletonList
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.DependencyType import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.DependencyType
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.GradleRootProjectDependencyIR import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.GradleRootProjectDependencyIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleDependencyIR import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleDependencyIR
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.JvmSinglePlatformModuleConfigurator import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.*
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.ModuleConfigurator
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.ModulesToIrConversionData import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModulesToIrConversionData
import kotlin.reflect.KClass import kotlin.reflect.KClass
@@ -22,7 +23,7 @@ sealed class ModuleDependencyType(
fun accepts(from: Module, to: Module) = fun accepts(from: Module, to: Module) =
this.from.isInstance(from.configurator) && this.to.isInstance(to.configurator) this.from.isInstance(from.configurator) && this.to.isInstance(to.configurator)
open fun createDependencyIrs(from: Module, to: Module, data: ModulesToIrConversionData): BuildSystemIR { open fun createDependencyIrs(from: Module, to: Module, data: ModulesToIrConversionData): List<BuildSystemIR> {
val path = to.path val path = to.path
val modulePomIr = data.pomIr.copy(artifactId = to.name) val modulePomIr = data.pomIr.copy(artifactId = to.name)
return when { return when {
@@ -34,18 +35,45 @@ sealed class ModuleDependencyType(
modulePomIr, modulePomIr,
DependencyType.MAIN DependencyType.MAIN
) )
} }.asSingletonList()
} }
open fun SettingsWriter.runArbitraryTask(from: Module, to: Module, data: ModulesToIrConversionData): TaskResult<Unit> =
UNIT_SUCCESS
object JVMSinglePlatformToJVMSinglePlatform : ModuleDependencyType( object JVMSinglePlatformToJVMSinglePlatform : ModuleDependencyType(
from = JvmSinglePlatformModuleConfigurator::class, from = JvmSinglePlatformModuleConfigurator::class,
to = JvmSinglePlatformModuleConfigurator::class to = JvmSinglePlatformModuleConfigurator::class
) )
object AndroidSinglePlatformToMPP : ModuleDependencyType(
from = AndroidSinglePlatformModuleConfigurator::class,
to = MppModuleConfigurator::class
)
object IOSToMppSinglePlatformToMPP : ModuleDependencyType(
from = IOSSinglePlatformModuleConfigurator::class,
to = MppModuleConfigurator::class
) {
override fun createDependencyIrs(from: Module, to: Module, data: ModulesToIrConversionData): List<BuildSystemIR> =
emptyList()
override fun SettingsWriter.runArbitraryTask(
from: Module,
to: Module,
data: ModulesToIrConversionData
): TaskResult<Unit> = withSettingsOf(from) {
IOSSinglePlatformModuleConfigurator.dependentModule.reference
.setValue(IOSSinglePlatformModuleConfigurator.DependentModuleReference(to))
UNIT_SUCCESS
}
}
companion object { companion object {
private val ALL = listOf( private val ALL = listOf(
JVMSinglePlatformToJVMSinglePlatform JVMSinglePlatformToJVMSinglePlatform,
AndroidSinglePlatformToMPP,
IOSToMppSinglePlatformToMPP
) )
fun getPossibleDependencyType(from: Module, to: Module): ModuleDependencyType? = fun getPossibleDependencyType(from: Module, to: Module): ModuleDependencyType? =