[JS, IR] Make IR default for both mode

This commit is contained in:
Ilya Goncharov
2022-08-02 15:02:20 +02:00
committed by Space Team
parent 9342356c38
commit a3be2c893b
15 changed files with 169 additions and 170 deletions
@@ -299,25 +299,25 @@ abstract class KotlinJsProjectExtension(project: Project) :
val target: KotlinJsTargetDsl = when (compilerOrDefault) { val target: KotlinJsTargetDsl = when (compilerOrDefault) {
KotlinJsCompilerType.LEGACY -> legacyPreset KotlinJsCompilerType.LEGACY -> legacyPreset
.also { .also {
it.irPreset = null it.mixedMode = false
} }
.createTarget("js") .createTarget("js")
KotlinJsCompilerType.IR -> irPreset KotlinJsCompilerType.IR -> irPreset
.also { .also {
it.mixedMode = false it.legacyPreset = null
} }
.createTarget("js") .createTarget("js")
KotlinJsCompilerType.BOTH -> legacyPreset KotlinJsCompilerType.BOTH -> irPreset
.also { .also {
irPreset.mixedMode = true legacyPreset.mixedMode = true
it.irPreset = irPreset it.legacyPreset = legacyPreset
} }
.createTarget( .createTarget(
lowerCamelCaseName( lowerCamelCaseName(
"js", "js",
LEGACY.lowerName IR.lowerName
) )
) )
} }
@@ -141,11 +141,11 @@ class KotlinMultiplatformPlugin : Plugin<Project> {
fun setupDefaultPresets(project: Project) { fun setupDefaultPresets(project: Project) {
with(project.multiplatformExtension.presets) { with(project.multiplatformExtension.presets) {
add(KotlinJvmTargetPreset(project)) add(KotlinJvmTargetPreset(project))
add(KotlinJsTargetPreset(project).apply { irPreset = null }) add(KotlinJsTargetPreset(project).apply { mixedMode = false })
add(KotlinJsIrTargetPreset(project).apply { mixedMode = false }) add(KotlinJsIrTargetPreset(project))
add( add(
KotlinJsTargetPreset(project).apply { KotlinJsIrTargetPreset(project).apply {
irPreset = KotlinJsIrTargetPreset(project).apply { mixedMode = true } legacyPreset = KotlinJsTargetPreset(project).apply { mixedMode = true }
} }
) )
add(KotlinWasmTargetPreset(project)) add(KotlinWasmTargetPreset(project))
@@ -136,12 +136,11 @@ internal class DefaultKotlinSourceSetFactory(
if (sourceSet in notOnlyJsSourceSets) return if (sourceSet in notOnlyJsSourceSets) return
fun chooseCompilerAttribute(target: KotlinTarget): KotlinJsCompilerAttribute { fun chooseCompilerAttribute(target: KotlinTarget): KotlinJsCompilerAttribute {
if (target is KotlinJsIrTarget) { if (target is KotlinJsTarget) {
return KotlinJsCompilerAttribute.ir return KotlinJsCompilerAttribute.legacy
} }
target as KotlinJsTarget return KotlinJsCompilerAttribute.ir
return if (target.irTarget != null) KotlinJsCompilerAttribute.ir else KotlinJsCompilerAttribute.legacy
} }
project.kotlinExtension.targets project.kotlinExtension.targets
@@ -43,7 +43,7 @@ abstract class KotlinJsCompilation @Inject internal constructor(
internal open val defaultExternalsOutputFormat: ExternalsOutputFormat = ExternalsOutputFormat.SOURCE internal open val defaultExternalsOutputFormat: ExternalsOutputFormat = ExternalsOutputFormat.SOURCE
internal val binaries: KotlinJsBinaryContainer = val binaries: KotlinJsBinaryContainer =
target.project.objects.newInstance( target.project.objects.newInstance(
KotlinJsBinaryContainer::class.java, KotlinJsBinaryContainer::class.java,
target, target,
@@ -16,7 +16,7 @@ class KotlinJsCompilationFactory(
get() = KotlinJsCompilation::class.java get() = KotlinJsCompilation::class.java
override fun defaultSourceSetName(compilationName: String): String { override fun defaultSourceSetName(compilationName: String): String {
val classifier = if (target is KotlinJsTarget && target.irTarget != null) val classifier = if (target is KotlinJsTarget && target.mixedMode)
target.disambiguationClassifierInPlatform target.disambiguationClassifierInPlatform
else target.disambiguationClassifier else target.disambiguationClassifier
@@ -34,7 +34,8 @@ abstract class KotlinJsTarget
@Inject @Inject
constructor( constructor(
project: Project, project: Project,
platformType: KotlinPlatformType platformType: KotlinPlatformType,
internal val mixedMode: Boolean
) : ) :
KotlinTargetWithBinaries<KotlinJsCompilation, KotlinJsBinaryContainer>(project, platformType), KotlinTargetWithBinaries<KotlinJsCompilation, KotlinJsBinaryContainer>(project, platformType),
KotlinTargetWithTests<JsAggregatingExecutionSource, KotlinJsReportAggregatingTestRun>, KotlinTargetWithTests<JsAggregatingExecutionSource, KotlinJsReportAggregatingTestRun>,
@@ -53,46 +54,24 @@ constructor(
internal val commonFakeApiElementsConfigurationName: String internal val commonFakeApiElementsConfigurationName: String
get() = lowerCamelCaseName( get() = lowerCamelCaseName(
irTarget?.let { if (mixedMode)
this.disambiguationClassifierInPlatform disambiguationClassifierInPlatform
} ?: disambiguationClassifier, else
disambiguationClassifier,
"commonFakeApiElements" "commonFakeApiElements"
) )
val disambiguationClassifierInPlatform: String? val disambiguationClassifierInPlatform: String?
get() = if (irTarget != null) { get() = if (mixedMode) {
disambiguationClassifier?.removeJsCompilerSuffix(LEGACY) disambiguationClassifier?.removeJsCompilerSuffix(KotlinJsCompilerType.LEGACY)
} else { } else {
disambiguationClassifier disambiguationClassifier
} }
override val kotlinComponents: Set<KotlinTargetComponent> by lazy {
if (irTarget == null)
super.kotlinComponents
else {
val mainCompilation = compilations.getByName(MAIN_COMPILATION_NAME)
val usageContexts = createUsageContexts(mainCompilation) +
irTarget!!.createUsageContexts(irTarget!!.compilations.getByName(MAIN_COMPILATION_NAME))
val componentName =
if (project.kotlinExtension is KotlinMultiplatformExtension)
irTarget?.let { targetName.removeJsCompilerSuffix(LEGACY) } ?: targetName
else PRIMARY_SINGLE_COMPONENT_NAME
val result = createKotlinVariant(componentName, mainCompilation, usageContexts)
result.sourcesArtifacts = setOf(
sourcesJarArtifact(mainCompilation, componentName, dashSeparatedName(targetName.toLowerCase()))
)
setOf(result)
}
}
override fun createUsageContexts(producingCompilation: KotlinCompilation<*>): Set<DefaultKotlinUsageContext> { override fun createUsageContexts(producingCompilation: KotlinCompilation<*>): Set<DefaultKotlinUsageContext> {
val usageContexts = super.createUsageContexts(producingCompilation) val usageContexts = super.createUsageContexts(producingCompilation)
if (isMpp!!) return usageContexts if (isMpp!! || mixedMode) return usageContexts
return usageContexts + return usageContexts +
DefaultKotlinUsageContext( DefaultKotlinUsageContext(
@@ -103,27 +82,12 @@ constructor(
) )
} }
override fun createKotlinVariant(
componentName: String,
compilation: KotlinCompilation<*>,
usageContexts: Set<DefaultKotlinUsageContext>
): KotlinVariant {
return super.createKotlinVariant(componentName, compilation, usageContexts).apply {
irTarget?.let {
artifactTargetName = targetName.removeJsCompilerSuffix(LEGACY)
}
}
}
override val binaries: KotlinJsBinaryContainer override val binaries: KotlinJsBinaryContainer
get() = compilations.withType(KotlinJsCompilation::class.java) get() = compilations.withType(KotlinJsCompilation::class.java)
.named(MAIN_COMPILATION_NAME) .named(MAIN_COMPILATION_NAME)
.map { it.binaries } .map { it.binaries }
.get() .get()
var irTarget: KotlinJsIrTarget? = null
internal set
open var isMpp: Boolean? = null open var isMpp: Boolean? = null
internal set internal set
@@ -144,7 +108,7 @@ constructor(
project.objects.newInstance(KotlinBrowserJs::class.java, this).also { project.objects.newInstance(KotlinBrowserJs::class.java, this).also {
it.configure() it.configure()
if (propertiesProvider.jsGenerateExecutableDefault && irTarget == null) { if (propertiesProvider.jsGenerateExecutableDefault && !mixedMode) {
binaries.executable() binaries.executable()
} }
@@ -164,7 +128,6 @@ constructor(
override fun browser(body: KotlinJsBrowserDsl.() -> Unit) { override fun browser(body: KotlinJsBrowserDsl.() -> Unit) {
body(browser) body(browser)
irTarget?.browser(body)
} }
//node.js //node.js
@@ -172,7 +135,7 @@ constructor(
project.objects.newInstance(KotlinNodeJs::class.java, this).also { project.objects.newInstance(KotlinNodeJs::class.java, this).also {
it.configure() it.configure()
if (propertiesProvider.jsGenerateExecutableDefault && irTarget == null) { if (propertiesProvider.jsGenerateExecutableDefault && !mixedMode) {
binaries.executable() binaries.executable()
} }
@@ -193,7 +156,6 @@ constructor(
override fun nodejs(body: KotlinJsNodeDsl.() -> Unit) { override fun nodejs(body: KotlinJsNodeDsl.() -> Unit) {
body(nodejs) body(nodejs)
irTarget?.nodejs(body)
} }
override fun whenBrowserConfigured(body: KotlinJsBrowserDsl.() -> Unit) { override fun whenBrowserConfigured(body: KotlinJsBrowserDsl.() -> Unit) {
@@ -220,6 +182,5 @@ constructor(
sourceMapEmbedSources = null sourceMapEmbedSources = null
} }
} }
irTarget?.useCommonJs()
} }
} }
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.mapTargetCompilationsToKpmVar
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTargetConfigurator import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTargetConfigurator
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTargetPreset import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTargetPreset
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheckWhenEvaluated import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheckWhenEvaluated
@@ -26,8 +27,7 @@ open class KotlinJsTargetPreset(
) : KotlinOnlyTargetPreset<KotlinJsTarget, KotlinJsCompilation>( ) : KotlinOnlyTargetPreset<KotlinJsTarget, KotlinJsCompilation>(
project project
) { ) {
var irPreset: KotlinJsIrTargetPreset? = null var mixedMode: Boolean? = null
internal set
open val isMpp: Boolean open val isMpp: Boolean
get() = true get() = true
@@ -35,33 +35,20 @@ open class KotlinJsTargetPreset(
override val platformType: KotlinPlatformType override val platformType: KotlinPlatformType
get() = KotlinPlatformType.js get() = KotlinPlatformType.js
override fun useDisambiguationClassifierAsSourceSetNamePrefix() = irPreset == null
override fun overrideDisambiguationClassifierOnIdeImport(name: String): String? =
irPreset?.let {
name.removeJsCompilerSuffix(KotlinJsCompilerType.LEGACY)
}
override fun instantiateTarget(name: String): KotlinJsTarget { override fun instantiateTarget(name: String): KotlinJsTarget {
return project.objects.newInstance( return project.objects.newInstance(
KotlinJsTarget::class.java, KotlinJsTarget::class.java,
project, project,
platformType platformType,
mixedMode
).apply { ).apply {
this.irTarget = irPreset?.createTarget(
lowerCamelCaseName(
name.removeJsCompilerSuffix(KotlinJsCompilerType.LEGACY),
KotlinJsCompilerType.IR.lowerName
)
)?.also {
it.legacyTarget = this
}
this.isMpp = this@KotlinJsTargetPreset.isMpp this.isMpp = this@KotlinJsTargetPreset.isMpp
project.runProjectConfigurationHealthCheckWhenEvaluated { if (!mixedMode) {
if (!isBrowserConfigured && !isNodejsConfigured) { project.runProjectConfigurationHealthCheckWhenEvaluated {
project.logger.warn( if (!isBrowserConfigured && !isNodejsConfigured) {
""" project.logger.warn(
"""
Please choose a JavaScript environment to build distributions and run tests. Please choose a JavaScript environment to build distributions and run tests.
Not choosing any of them will be an error in the future releases. Not choosing any of them will be an error in the future releases.
kotlin { kotlin {
@@ -72,37 +59,23 @@ open class KotlinJsTargetPreset(
} }
} }
""".trimIndent() """.trimIndent()
) )
}
val buildStatsService = KotlinBuildStatsService.getInstance()
when {
isBrowserConfigured && isNodejsConfigured -> buildStatsService?.report(StringMetrics.JS_TARGET_MODE, "both")
isBrowserConfigured -> buildStatsService?.report(StringMetrics.JS_TARGET_MODE, "browser")
isNodejsConfigured -> buildStatsService?.report(StringMetrics.JS_TARGET_MODE, "nodejs")
!isBrowserConfigured && !isNodejsConfigured -> buildStatsService?.report(StringMetrics.JS_TARGET_MODE, "none")
}
Unit
} }
val buildStatsService = KotlinBuildStatsService.getInstance()
when {
isBrowserConfigured && isNodejsConfigured -> buildStatsService?.report(StringMetrics.JS_TARGET_MODE, "both")
isBrowserConfigured -> buildStatsService?.report(StringMetrics.JS_TARGET_MODE, "browser")
isNodejsConfigured -> buildStatsService?.report(StringMetrics.JS_TARGET_MODE, "nodejs")
!isBrowserConfigured && !isNodejsConfigured -> buildStatsService?.report(StringMetrics.JS_TARGET_MODE, "none")
}
Unit
} }
} }
} }
override fun createKotlinTargetConfigurator() = KotlinJsTargetConfigurator() override fun createKotlinTargetConfigurator() = KotlinJsTargetConfigurator()
override fun getName(): String {
return lowerCamelCaseName(
PRESET_NAME,
irPreset?.let { KotlinJsCompilerType.BOTH.lowerName }
)
}
override fun createCompilationFactory(forTarget: KotlinJsTarget): KotlinJsCompilationFactory {
return KotlinJsCompilationFactory(forTarget)
}
companion object {
const val PRESET_NAME = "js"
}
override fun createTarget(name: String): KotlinJsTarget { override fun createTarget(name: String): KotlinJsTarget {
val result = super.createTarget(name) val result = super.createTarget(name)
if (project.hasKpmModel) { if (project.hasKpmModel) {
@@ -110,6 +83,19 @@ open class KotlinJsTargetPreset(
} }
return result return result
} }
override fun getName(): String = JS_PRESET_NAME
public override fun createCompilationFactory(forTarget: KotlinJsTarget): KotlinJsCompilationFactory {
return KotlinJsCompilationFactory(project, forTarget)
}
companion object {
val JS_PRESET_NAME = lowerCamelCaseName(
"js",
KotlinJsCompilerType.LEGACY.lowerName
)
}
} }
class KotlinJsSingleTargetPreset( class KotlinJsSingleTargetPreset(
@@ -120,15 +106,14 @@ class KotlinJsSingleTargetPreset(
override val isMpp: Boolean override val isMpp: Boolean
get() = false get() = false
override fun overrideDisambiguationClassifierOnIdeImport(name: String): String? =
null
// In a Kotlin/JS single-platform project, we don't need any disambiguation suffixes or prefixes in the names: // In a Kotlin/JS single-platform project, we don't need any disambiguation suffixes or prefixes in the names:
override fun provideTargetDisambiguationClassifier(target: KotlinOnlyTarget<KotlinJsCompilation>): String? = override fun provideTargetDisambiguationClassifier(target: KotlinOnlyTarget<KotlinJsCompilation>): String? =
irPreset?.let { if (mixedMode!!) {
super.provideTargetDisambiguationClassifier(target) super.provideTargetDisambiguationClassifier(target)
?.removePrefix(target.name.removeJsCompilerSuffix(KotlinJsCompilerType.LEGACY)) ?.removePrefix(target.name.removeJsCompilerSuffix(KotlinJsCompilerType.LEGACY))
?.decapitalize() ?.decapitalize()
} else {
null
} }
override fun createKotlinTargetConfigurator() = KotlinJsTargetConfigurator() override fun createKotlinTargetConfigurator() = KotlinJsTargetConfigurator()
@@ -11,9 +11,9 @@ import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
fun KotlinJsTargetDsl.calculateJsCompilerType(): KotlinJsCompilerType { fun KotlinJsTargetDsl.calculateJsCompilerType(): KotlinJsCompilerType {
return when { return when {
this is KotlinJsTarget && this.irTarget == null -> KotlinJsCompilerType.LEGACY this is KotlinJsTarget && !this.mixedMode -> KotlinJsCompilerType.LEGACY
this is KotlinJsIrTarget && !this.mixedMode -> KotlinJsCompilerType.IR this is KotlinJsIrTarget && this.legacyTarget == null -> KotlinJsCompilerType.IR
this is KotlinJsTarget && this.irTarget != null -> KotlinJsCompilerType.BOTH this is KotlinJsIrTarget && this.legacyTarget != null -> KotlinJsCompilerType.BOTH
else -> throw IllegalStateException("Unable to find previous Kotlin/JS compiler type for $this") else -> throw IllegalStateException("Unable to find previous Kotlin/JS compiler type for $this")
} }
} }
@@ -36,7 +36,7 @@ internal class DukatCompilationResolverPlugin(
} }
val legacyTargetReuseIrTask by lazy { val legacyTargetReuseIrTask by lazy {
val target = compilation.target val target = compilation.target
target is KotlinJsTarget && (target.irTarget != null && externalsOutputFormat == ExternalsOutputFormat.SOURCE) target is KotlinJsTarget && (target.mixedMode && externalsOutputFormat == ExternalsOutputFormat.SOURCE)
} }
val externalsOutputFormat by lazy { val externalsOutputFormat by lazy {
compilation.externalsOutputFormat compilation.externalsOutputFormat
@@ -137,7 +137,7 @@ internal class DukatCompilationResolverPlugin(
internal fun KotlinJsCompilation.shouldDependOnDukatIntegrationTask(): Boolean = with(target) { internal fun KotlinJsCompilation.shouldDependOnDukatIntegrationTask(): Boolean = with(target) {
this is KotlinJsIrTarget || this is KotlinJsIrTarget ||
(this is KotlinJsTarget && (this is KotlinJsTarget &&
(irTarget == null || externalsOutputFormat != ExternalsOutputFormat.SOURCE) (!mixedMode || externalsOutputFormat != ExternalsOutputFormat.SOURCE)
) )
} }
@@ -68,6 +68,9 @@ constructor(
compilation: KotlinJsCompilation = defaultCompilation compilation: KotlinJsCompilation = defaultCompilation
): List<JsBinary> { ): List<JsBinary> {
if (target is KotlinJsIrTarget) { if (target is KotlinJsIrTarget) {
target.legacyTarget
?.let { throw IllegalStateException("Can't use `executable()` with 'both' compiler type") }
target.whenBrowserConfigured { target.whenBrowserConfigured {
(this as KotlinJsIrSubTarget).produceExecutable() (this as KotlinJsIrSubTarget).produceExecutable()
} }
@@ -84,9 +87,6 @@ constructor(
} }
if (target is KotlinJsTarget) { if (target is KotlinJsTarget) {
target.irTarget
?.let { throw IllegalStateException("Can't use `executable()` with 'both' compiler type") }
target.whenBrowserConfigured { target.whenBrowserConfigured {
(this as KotlinJsSubTarget).produceExecutable() (this as KotlinJsSubTarget).produceExecutable()
} }
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.ir
import org.jetbrains.kotlin.gradle.plugin.mpp.JsIrCompilationDetails import org.jetbrains.kotlin.gradle.plugin.mpp.JsIrCompilationDetails
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCompilationFactory import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCompilationFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.getOrCreateDefaultSourceSet import org.jetbrains.kotlin.gradle.plugin.mpp.getOrCreateDefaultSourceSet
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
@@ -18,7 +19,7 @@ class KotlinJsIrCompilationFactory(
override fun defaultSourceSetName(compilationName: String): String { override fun defaultSourceSetName(compilationName: String): String {
return lowerCamelCaseName( return lowerCamelCaseName(
if (target.mixedMode) if (target.legacyTarget != null)
target.disambiguationClassifierInPlatform target.disambiguationClassifierInPlatform
else else
target.disambiguationClassifier, target.disambiguationClassifier,
@@ -11,11 +11,15 @@ import org.gradle.api.Task
import org.gradle.api.tasks.Copy import org.gradle.api.tasks.Copy
import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.AbstractKotlinTargetConfigurator.Companion.runTaskNameSuffix import org.jetbrains.kotlin.gradle.plugin.AbstractKotlinTargetConfigurator.Companion.runTaskNameSuffix
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinUsageContext import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinUsageContext
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinTargetWithBinaries import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinTargetWithBinaries
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinVariant
import org.jetbrains.kotlin.gradle.plugin.mpp.PRIMARY_SINGLE_COMPONENT_NAME
import org.jetbrains.kotlin.gradle.targets.js.JsAggregatingExecutionSource import org.jetbrains.kotlin.gradle.targets.js.JsAggregatingExecutionSource
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsReportAggregatingTestRun import org.jetbrains.kotlin.gradle.targets.js.KotlinJsReportAggregatingTestRun
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
@@ -27,6 +31,7 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
import org.jetbrains.kotlin.gradle.targets.js.typescript.TypeScriptValidationTask import org.jetbrains.kotlin.gradle.targets.js.typescript.TypeScriptValidationTask
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
import org.jetbrains.kotlin.gradle.tasks.registerTask import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.gradle.utils.setProperty import org.jetbrains.kotlin.gradle.utils.setProperty
import javax.inject.Inject import javax.inject.Inject
@@ -36,7 +41,6 @@ abstract class KotlinJsIrTarget
constructor( constructor(
project: Project, project: Project,
platformType: KotlinPlatformType, platformType: KotlinPlatformType,
internal val mixedMode: Boolean
) : ) :
KotlinTargetWithBinaries<KotlinJsIrCompilation, KotlinJsBinaryContainer>(project, platformType), KotlinTargetWithBinaries<KotlinJsIrCompilation, KotlinJsBinaryContainer>(project, platformType),
KotlinTargetWithTests<JsAggregatingExecutionSource, KotlinJsReportAggregatingTestRun>, KotlinTargetWithTests<JsAggregatingExecutionSource, KotlinJsReportAggregatingTestRun>,
@@ -62,10 +66,33 @@ constructor(
field = value field = value
} }
override val kotlinComponents: Set<KotlinTargetComponent> by lazy {
if (legacyTarget == null)
super.kotlinComponents
else {
val mainCompilation = compilations.getByName(MAIN_COMPILATION_NAME)
val usageContexts = createUsageContexts(mainCompilation) +
legacyTarget!!.createUsageContexts(legacyTarget!!.compilations.getByName(MAIN_COMPILATION_NAME))
val componentName =
if (project.kotlinExtension is KotlinMultiplatformExtension)
legacyTarget?.let { targetName.removeJsCompilerSuffix(KotlinJsCompilerType.IR) } ?: targetName
else PRIMARY_SINGLE_COMPONENT_NAME
val result = createKotlinVariant(componentName, mainCompilation, usageContexts)
result.sourcesArtifacts = setOf(
sourcesJarArtifact(mainCompilation, componentName, dashSeparatedName(targetName.toLowerCase()))
)
setOf(result)
}
}
override fun createUsageContexts(producingCompilation: KotlinCompilation<*>): Set<DefaultKotlinUsageContext> { override fun createUsageContexts(producingCompilation: KotlinCompilation<*>): Set<DefaultKotlinUsageContext> {
val usageContexts = super.createUsageContexts(producingCompilation) val usageContexts = super.createUsageContexts(producingCompilation)
if (isMpp!! || mixedMode) return usageContexts if (isMpp!!) return usageContexts
return usageContexts + return usageContexts +
DefaultKotlinUsageContext( DefaultKotlinUsageContext(
@@ -76,17 +103,28 @@ constructor(
) )
} }
override fun createKotlinVariant(
componentName: String,
compilation: KotlinCompilation<*>,
usageContexts: Set<DefaultKotlinUsageContext>
): KotlinVariant {
return super.createKotlinVariant(componentName, compilation, usageContexts).apply {
legacyTarget?.let {
artifactTargetName = targetName.removeJsCompilerSuffix(KotlinJsCompilerType.IR)
}
}
}
internal val commonFakeApiElementsConfigurationName: String internal val commonFakeApiElementsConfigurationName: String
get() = lowerCamelCaseName( get() = lowerCamelCaseName(
if (mixedMode) legacyTarget?.let {
disambiguationClassifierInPlatform this.disambiguationClassifierInPlatform
else } ?: disambiguationClassifier,
disambiguationClassifier,
"commonFakeApiElements" "commonFakeApiElements"
) )
val disambiguationClassifierInPlatform: String? val disambiguationClassifierInPlatform: String?
get() = if (mixedMode) { get() = if (legacyTarget != null) {
disambiguationClassifier?.removeJsCompilerSuffix(KotlinJsCompilerType.IR) disambiguationClassifier?.removeJsCompilerSuffix(KotlinJsCompilerType.IR)
} else { } else {
disambiguationClassifier disambiguationClassifier
@@ -224,6 +262,7 @@ constructor(
override fun browser(body: KotlinJsBrowserDsl.() -> Unit) { override fun browser(body: KotlinJsBrowserDsl.() -> Unit) {
body(browser) body(browser)
legacyTarget?.browser(body)
} }
//node.js //node.js
@@ -248,6 +287,7 @@ constructor(
override fun nodejs(body: KotlinJsNodeDsl.() -> Unit) { override fun nodejs(body: KotlinJsNodeDsl.() -> Unit) {
body(nodejs) body(nodejs)
legacyTarget?.nodejs(body)
} }
//d8 //d8
@@ -315,6 +355,7 @@ constructor(
} }
} }
} }
legacyTarget?.useCommonJs()
} }
private fun KotlinJsOptions.configureCommonJsOptions() { private fun KotlinJsOptions.configureCommonJsOptions() {
@@ -7,9 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.ir
import org.gradle.api.Project import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCompilationFactory import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTargetPreset
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.PublicationRegistrationMode import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.PublicationRegistrationMode
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.hasKpmModel import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.hasKpmModel
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.mapTargetCompilationsToKpmVariants import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.mapTargetCompilationsToKpmVariants
@@ -23,21 +21,34 @@ open class KotlinJsIrTargetPreset(
) : KotlinOnlyTargetPreset<KotlinJsIrTarget, KotlinJsIrCompilation>( ) : KotlinOnlyTargetPreset<KotlinJsIrTarget, KotlinJsIrCompilation>(
project project
) { ) {
internal var mixedMode: Boolean? = null internal var legacyPreset: KotlinJsTargetPreset? = null
internal set
open val isMpp: Boolean open val isMpp: Boolean
get() = true get() = true
override val platformType: KotlinPlatformType = KotlinPlatformType.js override val platformType: KotlinPlatformType = KotlinPlatformType.js
override fun useDisambiguationClassifierAsSourceSetNamePrefix() = legacyPreset == null
override fun overrideDisambiguationClassifierOnIdeImport(name: String): String? =
legacyPreset?.let {
name.removeJsCompilerSuffix(KotlinJsCompilerType.IR)
}
override fun instantiateTarget(name: String): KotlinJsIrTarget { override fun instantiateTarget(name: String): KotlinJsIrTarget {
return project.objects.newInstance(KotlinJsIrTarget::class.java, project, platformType, mixedMode).apply { return project.objects.newInstance(KotlinJsIrTarget::class.java, project, platformType).apply {
this.isMpp = this@KotlinJsIrTargetPreset.isMpp this.isMpp = this@KotlinJsIrTargetPreset.isMpp
if (!mixedMode) { this.legacyTarget = legacyPreset?.createTarget(
project.runProjectConfigurationHealthCheckWhenEvaluated { lowerCamelCaseName(
if (!isBrowserConfigured && !isNodejsConfigured) { name.removeJsCompilerSuffix(KotlinJsCompilerType.IR),
project.logger.warn( KotlinJsCompilerType.LEGACY.lowerName
""" )
)
project.runProjectConfigurationHealthCheckWhenEvaluated {
if (!isBrowserConfigured && !isNodejsConfigured) {
project.logger.warn(
"""
Please choose a JavaScript environment to build distributions and run tests. Please choose a JavaScript environment to build distributions and run tests.
Not choosing any of them will be an error in the future releases. Not choosing any of them will be an error in the future releases.
kotlin { kotlin {
@@ -48,17 +59,16 @@ open class KotlinJsIrTargetPreset(
} }
} }
""".trimIndent() """.trimIndent()
) )
}
val buildStatsService = KotlinBuildStatsService.getInstance()
when {
isBrowserConfigured && isNodejsConfigured -> buildStatsService?.report(StringMetrics.JS_TARGET_MODE, "both")
isBrowserConfigured -> buildStatsService?.report(StringMetrics.JS_TARGET_MODE, "browser")
isNodejsConfigured -> buildStatsService?.report(StringMetrics.JS_TARGET_MODE, "nodejs")
!isBrowserConfigured && !isNodejsConfigured -> buildStatsService?.report(StringMetrics.JS_TARGET_MODE, "none")
}
Unit
} }
val buildStatsService = KotlinBuildStatsService.getInstance()
when {
isBrowserConfigured && isNodejsConfigured -> buildStatsService?.report(StringMetrics.JS_TARGET_MODE, "both")
isBrowserConfigured -> buildStatsService?.report(StringMetrics.JS_TARGET_MODE, "browser")
isNodejsConfigured -> buildStatsService?.report(StringMetrics.JS_TARGET_MODE, "nodejs")
!isBrowserConfigured && !isNodejsConfigured -> buildStatsService?.report(StringMetrics.JS_TARGET_MODE, "none")
}
Unit
} }
} }
} }
@@ -74,19 +84,19 @@ open class KotlinJsIrTargetPreset(
return result return result
} }
override fun getName(): String = JS_PRESET_NAME override fun getName(): String = lowerCamelCaseName(
PRESET_NAME,
legacyPreset?.let { KotlinJsCompilerType.BOTH.lowerName }
)
//TODO[Ilya Goncharov] remove public morozov override fun createCompilationFactory(
public override fun createCompilationFactory(
forTarget: KotlinJsIrTarget forTarget: KotlinJsIrTarget
): KotlinCompilationFactory<KotlinJsIrCompilation> = ): KotlinCompilationFactory<KotlinJsIrCompilation> {
KotlinJsIrCompilationFactory(forTarget) return KotlinJsIrCompilationFactory(forTarget)
}
companion object { companion object {
val JS_PRESET_NAME = lowerCamelCaseName( const val PRESET_NAME = "js"
"js",
KotlinJsCompilerType.IR.lowerName
)
} }
} }
@@ -98,16 +108,16 @@ class KotlinJsIrSingleTargetPreset(
override val isMpp: Boolean override val isMpp: Boolean
get() = false get() = false
override fun overrideDisambiguationClassifierOnIdeImport(name: String): String? =
null
// In a Kotlin/JS single-platform project, we don't need any disambiguation suffixes or prefixes in the names: // In a Kotlin/JS single-platform project, we don't need any disambiguation suffixes or prefixes in the names:
override fun provideTargetDisambiguationClassifier(target: KotlinOnlyTarget<KotlinJsIrCompilation>): String? { override fun provideTargetDisambiguationClassifier(target: KotlinOnlyTarget<KotlinJsIrCompilation>): String? =
return if (mixedMode!!) { legacyPreset?.let {
super.provideTargetDisambiguationClassifier(target) super.provideTargetDisambiguationClassifier(target)
?.removePrefix(target.name.removeJsCompilerSuffix(KotlinJsCompilerType.IR)) ?.removePrefix(target.name.removeJsCompilerSuffix(KotlinJsCompilerType.IR))
?.decapitalize() ?.decapitalize()
} else {
null
} }
}
override fun createKotlinTargetConfigurator(): KotlinOnlyTargetConfigurator<KotlinJsIrCompilation, KotlinJsIrTarget> = override fun createKotlinTargetConfigurator(): KotlinOnlyTargetConfigurator<KotlinJsIrCompilation, KotlinJsIrTarget> =
KotlinJsIrTargetConfigurator() KotlinJsIrTargetConfigurator()
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
import org.jetbrains.kotlin.gradle.plugin.whenEvaluated import org.jetbrains.kotlin.gradle.plugin.whenEvaluated
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinProjectNpmResolution import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinProjectNpmResolution
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
@@ -103,8 +104,8 @@ internal class KotlinProjectNpmResolver(
} }
// Hack for mixed mode, when target is JS and contain JS-IR // Hack for mixed mode, when target is JS and contain JS-IR
if (target is KotlinJsTarget) { if (target is KotlinJsIrTarget) {
target.irTarget?.compilations?.all { compilation -> target.legacyTarget?.compilations?.all { compilation ->
if (compilation is KotlinJsCompilation) { if (compilation is KotlinJsCompilation) {
addCompilation(compilation) addCompilation(compilation)
} }
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.targets
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertNotNull import kotlin.test.assertNotNull
@@ -133,8 +134,8 @@ class ConfigurationsTest : MultiplatformExtensionTest() {
val project = buildProjectWithMPP { val project = buildProjectWithMPP {
kotlin { kotlin {
js(BOTH) js(BOTH)
targets.withType<KotlinJsTarget> { targets.withType<KotlinJsIrTarget> {
irTarget!!.compilations.getByName("main").dependencies { legacyTarget!!.compilations.getByName("main").dependencies {
api("test:compilation-dependency") api("test:compilation-dependency")
} }
} }