diff --git a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/core/TaskResult.kt b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/core/TaskResult.kt
index b24332225d5..39f1e964280 100644
--- a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/core/TaskResult.kt
+++ b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/core/TaskResult.kt
@@ -52,6 +52,9 @@ inline fun TaskResult.mappendM(
infix fun TaskResult<*>.andThen(other: TaskResult): TaskResult =
mappendM(other) { _, _ -> other }
+infix fun TaskResult.andThenIgnoring(other: TaskResult): TaskResult =
+ mappendM(other) { _, _ -> this }
+
operator fun TaskResult>.plus(other: TaskResult>): TaskResult =
mappend(other) { _, _ -> Unit }
diff --git a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/core/errors.kt b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/core/errors.kt
index ddcc5fd41bc..f8a4a5e8858 100644
--- a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/core/errors.kt
+++ b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/core/errors.kt
@@ -58,7 +58,7 @@ data class ValidationError(val validationMessage: String) : Error() {
data class ProjectImportingError(override val message: String) : Error()
-data class InvalidModuleDependencyError(val from: Module, val to: Module) : Error() {
+data class InvalidModuleDependencyError(val from: Module, val to: Module, val reason: String? = null) : Error() {
override val message: String
- get() = "Invalid module dependency from module ${from.name} to ${to.name}"
+ get() = "Invalid module dependency from module ${from.name} to ${to.name}" + reason?.let { ": $it" }
}
\ No newline at end of file
diff --git a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/ir/buildsystem/BuildFileIR.kt b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/ir/buildsystem/BuildFileIR.kt
index 361739a5b6e..2552589a64a 100644
--- a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/ir/buildsystem/BuildFileIR.kt
+++ b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/ir/buildsystem/BuildFileIR.kt
@@ -12,6 +12,7 @@ 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.MavenPrinter
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.DefaultRepository
+import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
import java.nio.file.Path
interface FileIR : BuildSystemIR, IrsOwner
@@ -20,6 +21,7 @@ data class BuildFileIR(
val name: String,
val directoryPath: Path,
val modules: ModulesStructureIR,
+ val fromModules: List,
val pom: PomIR,
override val irs: PersistentList
) : FileIR {
diff --git a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/ir/buildsystem/gradle/GradleIR.kt b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/ir/buildsystem/gradle/GradleIR.kt
index 3f83e400d96..8a99501ed38 100644
--- a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/ir/buildsystem/gradle/GradleIR.kt
+++ b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/ir/buildsystem/gradle/GradleIR.kt
@@ -22,7 +22,15 @@ data class RawGradleIR(
override fun GradlePrinter.renderGradle() = renderer()
}
-data class CreateGradleValueIR(val name: String, val body: GradleIR) : GradleIR {
+fun rawIR(ir: String) = RawGradleIR { +ir }
+fun rawIR(ir: GradlePrinter.() -> String) = RawGradleIR { +ir() }
+
+fun MutableList.addRawIR(ir: GradlePrinter.() -> String) {
+ add(RawGradleIR { +ir() })
+}
+
+
+class CreateGradleValueIR(val name: String, val body: GradleIR) : GradleIR {
override fun GradlePrinter.renderGradle() {
when (dsl) {
GradlePrinter.GradleDsl.KOTLIN -> {
@@ -46,6 +54,8 @@ data class GradleCallIr(
val name: String,
val parameters: List = emptyList()
) : GradleIR {
+ constructor(name: String, vararg parameters: BuildSystemIR) : this(name, parameters.toList())
+
override fun GradlePrinter.renderGradle() {
call(name, forceBrackets = true) {
parameters.list { it.render(this) }
@@ -68,8 +78,6 @@ data class GradleNewInstanceCall(
}
-
-
data class GradleSectionIR(
val name: String,
val body: BodyIR
@@ -136,6 +144,14 @@ data class GradleImportIR(val import: String) : GradleIR {
}
}
+data class GradleBinaryExpressionIR(val left: BuildSystemIR, val op: String, val right: BuildSystemIR) : GradleIR {
+ override fun GradlePrinter.renderGradle() {
+ left.render(this)
+ +" $op "
+ right.render(this)
+ }
+}
+
interface BuildScriptIR : BuildSystemIR
data class BuildScriptDependencyIR(val dependencyIR: GradleIR) : BuildScriptIR, BuildSystemIR by dependencyIR
diff --git a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/ir/buildsystem/gradle/GradleTaskIR.kt b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/ir/buildsystem/gradle/GradleTaskIR.kt
index 14a0746f697..2ceb4f7a3a6 100644
--- a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/ir/buildsystem/gradle/GradleTaskIR.kt
+++ b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/ir/buildsystem/gradle/GradleTaskIR.kt
@@ -40,11 +40,34 @@ data class GradleByClassTasksAccessIR(
}
}
+data class GradleByClassTasksCreateIR(
+ val taskName: String,
+ val taskClass: String
+) : GradleTaskAccessIR {
+ override fun GradlePrinter.renderGradle() {
+ when (dsl) {
+ GradlePrinter.GradleDsl.KOTLIN -> {
+ +"val $taskName by tasks.creating($taskClass::class)"
+ }
+ GradlePrinter.GradleDsl.GROOVY -> {
+ +"task($taskName, type: $taskClass)"
+ }
+ }
+ }
+}
+
+
data class GradleConfigureTaskIR(
val taskAccess: GradleTaskAccessIR,
val dependsOn: List = emptyList(),
val irs: List = emptyList()
) : GradleIR, FreeIR {
+ constructor(
+ taskAccess: GradleTaskAccessIR,
+ dependsOn: List = emptyList(),
+ createIrs: MutableList.() -> Unit = {}
+ ) : this(taskAccess, dependsOn, mutableListOf().apply(createIrs))
+
override fun GradlePrinter.renderGradle() {
taskAccess.render(this)
+" "
diff --git a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/plugins/kotlin/ModuleType.kt b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/plugins/kotlin/ModuleType.kt
index bf669b4a508..4e7966f10e3 100644
--- a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/plugins/kotlin/ModuleType.kt
+++ b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/plugins/kotlin/ModuleType.kt
@@ -1,6 +1,7 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.StdlibType
+import java.util.*
//TODO maybe split into interfaces like it made with module configurators
@Suppress("EnumEntryName")
@@ -33,6 +34,9 @@ enum class ModuleSubType(val moduleType: ModuleType) {
common(ModuleType.common)
}
+val ModuleSubType.isIOS: Boolean
+ get() = this in EnumSet.of(ModuleSubType.iosX64, ModuleSubType.iosArm32, ModuleSubType.iosArm64)
+
fun ModuleType.correspondingStdlib(): StdlibType? = when (this) {
ModuleType.jvm -> StdlibType.StdlibJdk8
ModuleType.js -> StdlibType.StdlibJs
diff --git a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/plugins/kotlin/ModulesToIRsConverter.kt b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/plugins/kotlin/ModulesToIRsConverter.kt
index 21b6604d74f..ba6098433ff 100644
--- a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/plugins/kotlin/ModulesToIRsConverter.kt
+++ b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/plugins/kotlin/ModulesToIRsConverter.kt
@@ -58,6 +58,9 @@ class ModulesToIRsConverter(
return data.isSingleRootModuleMode
}
+ private val irsToAddToModules = hashMapOf>()
+ private val moduleToBuildFile = hashMapOf()
+
private fun calculatePathForModule(module: Module, rootPath: Path) = when {
needFlattening && module.isRootModule -> data.projectPath
else -> rootPath / module.name
@@ -75,6 +78,11 @@ class ModulesToIRsConverter(
}.map { it.flatten() }.map { buildFiles ->
if (needExplicitRootBuildFile) buildFiles + createRootBuildFile()
else buildFiles
+ }.map { buildFiles ->
+ buildFiles.map { buildFile ->
+ val irs = buildFile.fromModules.flatMap { irsToAddToModules[it]?.toList() ?: emptyList() }
+ buildFile.withIrs(irs)
+ }
}
}
@@ -83,6 +91,7 @@ class ModulesToIRsConverter(
projectName,
projectPath,
RootFileModuleStructureIR(persistentListOf()),
+ emptyList(),
pomIr,
rootBuildFileIrs.toPersistentList()
)
@@ -112,6 +121,7 @@ class ModulesToIRsConverter(
with(dependencyType) {
@Suppress("DEPRECATION")
with(unsafeSettingWriter) { runArbitraryTask(module, to, data).ensure() }
+ irsToAddToModules.getOrPut(to) { mutableListOf() } += createToIRs(module, to, data).get()
createDependencyIrs(module, to, data)
}
}.sequence().map { it.flatten() }
@@ -155,9 +165,12 @@ class ModulesToIRsConverter(
moduleIr,
persistentListOf()
),
+ listOf(module),
data.pomIr.copy(artifactId = module.name),
createBuildFileIRs(module, state)
- )
+ ).also {
+ moduleToBuildFile[module] = it
+ }
}
module.subModules.mapSequence { subModule ->
@@ -193,12 +206,19 @@ class ModulesToIRsConverter(
targetModuleIrs,
persistentListOf()
),
+ module.subModules + module,
pomIr,
buildPersistenceList {
+createBuildFileIRs(module, state)
module.subModules.forEach { +createBuildFileIRs(it, state) }
}
- ).asSingletonList().asSuccess()
+ ).also { buildFile ->
+ moduleToBuildFile[module] = buildFile
+ module.subModules.forEach { subModule ->
+ moduleToBuildFile[subModule] = buildFile
+ }
+ }.asSingletonList().asSuccess()
+
}
private fun Writer.createTargetModule(target: Module, modulePath: Path): MultiplatformModuleIR {
diff --git a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/settings/buildsystem/ModuleDependency.kt b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/settings/buildsystem/ModuleDependency.kt
index c56c3808138..c42adc9d135 100644
--- a/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/settings/buildsystem/ModuleDependency.kt
+++ b/libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/settings/buildsystem/ModuleDependency.kt
@@ -11,9 +11,13 @@ 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.GradleRootProjectDependencyIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleDependencyIR
+import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.*
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.*
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.isIOS
+import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.GradlePrinter
+import kotlin.collections.buildList
import kotlin.reflect.KClass
sealed class ModuleDependencyType(
@@ -41,6 +45,9 @@ sealed class ModuleDependencyType(
open fun SettingsWriter.runArbitraryTask(from: Module, to: Module, data: ModulesToIrConversionData): TaskResult =
UNIT_SUCCESS
+ open fun Reader.createToIRs(from: Module, to: Module, data: ModulesToIrConversionData): TaskResult> =
+ Success(emptyList())
+
object JVMSinglePlatformToJVMSinglePlatform : ModuleDependencyType(
from = JvmSinglePlatformModuleConfigurator::class,
to = JvmSinglePlatformModuleConfigurator::class
@@ -67,6 +74,65 @@ sealed class ModuleDependencyType(
.setValue(IOSSinglePlatformModuleConfigurator.DependentModuleReference(to))
UNIT_SUCCESS
}
+
+ @OptIn(ExperimentalStdlibApi::class)
+ override fun Reader.createToIRs(from: Module, to: Module, data: ModulesToIrConversionData): TaskResult> {
+ val iosTargetName = to.subModules.firstOrNull { module ->
+ module.configurator.safeAs()?.moduleSubType?.isIOS == true
+ }?.name ?: return Failure(InvalidModuleDependencyError(from, to, "Module ${to.name} should contain at least one iOS target"))
+
+ val packForXcodeTask = GradleConfigureTaskIR(GradleByClassTasksCreateIR("packForXcode", "Sync")) {
+ add(GradleAssignmentIR("group", GradleStringConstIR("build")))
+ add(
+ CreateGradleValueIR(
+ "mode",
+ GradleBinaryExpressionIR(
+ RawGradleIR { +"System.getenv("; +"CONFIGURATION".quotified; +")" },
+ "?:",
+ GradleStringConstIR("DEBUG")
+ )
+ )
+ )
+
+ add(
+ CreateGradleValueIR(
+ "framework",
+ RawGradleIR {
+ +"kotlin.targets"
+ when (dsl) {
+ GradlePrinter.GradleDsl.KOTLIN -> +""".getByName("$iosTargetName")"""
+ GradlePrinter.GradleDsl.GROOVY -> +"['$iosTargetName']"
+ }
+ +".binaries.getFramework(mode)"
+
+ }
+ )
+ )
+ addRawIR { "inputs.property(${"mode".quotified}, mode)" }
+ addRawIR { "dependsOn(framework.linkTask)" }
+ add(
+ CreateGradleValueIR(
+ "targetDir",
+ GradleCallIr("File", rawIR("buildDir"), GradleStringConstIR("xcode-frameworks"))
+ )
+ )
+ addRawIR { "from({ framework.outputDirectory })" }
+ addRawIR { "into(targetDir)" }
+ }
+
+ val dependency = rawIR {
+ when (dsl) {
+ GradlePrinter.GradleDsl.KOTLIN -> """tasks.getByName("build").dependsOn(packForXcode)"""
+ GradlePrinter.GradleDsl.GROOVY -> "tasks['build'].dependsOn(packForXcode)"
+ }
+ }
+
+ return buildList {
+ add(packForXcodeTask)
+ add(dependency)
+ add(GradleImportIR("org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget"))
+ }.asSuccess()
+ }
}
companion object {