[Gradle] Introduce compilerOptions for Kotlin js target

KotlinJsIrTarget now exposes experimental compiler options DSL that
are passed as a convention into target compilations compiler options.

^KT-57292 In Progress
This commit is contained in:
Yahor Berdnikau
2023-07-30 22:56:46 +02:00
committed by Space Team
parent a158d09768
commit a40e59306a
7 changed files with 133 additions and 28 deletions
@@ -5,9 +5,8 @@
package org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptionsHelper
import org.jetbrains.kotlin.gradle.dsl.KotlinNativeCompilerOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinNativeCompilerOptionsHelper
import org.jetbrains.kotlin.gradle.plugin.mpp.DecoratedKotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory
@@ -50,3 +49,22 @@ internal class KotlinCompilationNativeCompilerOptionsFromTargetConfigurator(
)
}
}
internal class KotlinCompilationJsCompilerOptionsFromTargetConfigurator(
private val targetCompilerOptions: KotlinJsCompilerOptions
) : KotlinCompilationImplFactory.PostConfigure {
override fun configure(compilation: DecoratedKotlinCompilation<*>) {
val jsCompilerOptions = compilation.compilerOptions.options as KotlinJsCompilerOptions
KotlinJsCompilerOptionsHelper.syncOptionsAsConvention(
targetCompilerOptions,
jsCompilerOptions
)
jsCompilerOptions.moduleName.convention(
moduleNameForCompilation(
compilation.compilationName,
targetCompilerOptions.moduleName
).orElse(compilation.moduleNameForCompilation())
)
}
}
@@ -9,8 +9,7 @@ import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.AbstractKotlinTargetConfigurator.Companion.runTaskNameSuffix
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
@@ -32,6 +31,7 @@ import org.jetbrains.kotlin.gradle.testing.internal.KotlinTestReport
import org.jetbrains.kotlin.gradle.testing.testTaskName
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.gradle.utils.newInstance
import org.jetbrains.kotlin.gradle.utils.setProperty
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
import org.jetbrains.kotlin.utils.addIfNotNull
@@ -249,4 +249,7 @@ constructor(
override fun generateTypeScriptDefinitions() {
project.logger.warn("Legacy compiler does not support generation of TypeScript Definitions")
}
override val compilerOptions: KotlinJsCompilerOptions =
project.objects.newInstance<KotlinJsCompilerOptionsDefault>()
}
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.gradle.targets.js.dsl
import org.gradle.api.Action
import org.gradle.api.GradleException
import org.gradle.api.NamedDomainObjectContainer
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompilerOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinJsDce
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
@@ -64,6 +66,19 @@ interface KotlinJsTargetDsl : KotlinTarget, KotlinTargetWithNodeJsDsl {
// Need to compatibility when users use KotlinJsCompilation specific in build script
override val compilations: NamedDomainObjectContainer<out KotlinJsCompilation>
@ExperimentalKotlinGradlePluginApi
override val compilerOptions: KotlinJsCompilerOptions
@ExperimentalKotlinGradlePluginApi
fun compilerOptions(configure: KotlinJsCompilerOptions.() -> Unit) {
configure(compilerOptions)
}
@ExperimentalKotlinGradlePluginApi
fun compilerOptions(configure: Action<KotlinJsCompilerOptions>) {
configure.execute(compilerOptions)
}
}
interface KotlinTargetWithNodeJsDsl {
@@ -7,16 +7,21 @@ package org.jetbrains.kotlin.gradle.targets.js.ir
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCompilationFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationFriendPathsResolver
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationPreConfigure
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.*
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
import org.jetbrains.kotlin.gradle.plugin.mpp.sourcesJarTask
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.JsIrCompilationSourceSetsContainerFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.JsKotlinCompilationDependencyConfigurationsFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationPostConfigure
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationJsCompilerOptionsFromTargetConfigurator
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinJsCompilerOptionsFactory
class KotlinJsIrCompilationFactory internal constructor(
override val target: KotlinOnlyTarget<KotlinJsIrCompilation>,
override val target: KotlinJsIrTarget,
) : KotlinCompilationFactory<KotlinJsIrCompilation> {
override val itemClass: Class<KotlinJsIrCompilation>
get() = KotlinJsIrCompilation::class.java
@@ -24,7 +29,7 @@ class KotlinJsIrCompilationFactory internal constructor(
private val compilationImplFactory: KotlinCompilationImplFactory = KotlinCompilationImplFactory(
compilerOptionsFactory = KotlinJsCompilerOptionsFactory,
compilationFriendPathsResolver = DefaultKotlinCompilationFriendPathsResolver(
friendArtifactResolver = DefaultKotlinCompilationFriendPathsResolver.FriendArtifactResolver { _ ->
friendArtifactResolver = { _ ->
target.project.files()
}
),
@@ -36,7 +41,11 @@ class KotlinJsIrCompilationFactory internal constructor(
?: compilation.target.targetName.toLowerCaseAsciiOnly()
sourcesJarTask(compilation, compilation.target.targetName, artifactNameAppendix)
}
}
},
postConfigureAction = KotlinCompilationImplFactory.PostConfigure.composite(
DefaultKotlinCompilationPostConfigure,
KotlinCompilationJsCompilerOptionsFromTargetConfigurator(target.compilerOptions)
)
)
override fun create(name: String): KotlinJsIrCompilation = target.project.objects.newInstance(
@@ -13,6 +13,9 @@ 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.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompilerOptionsDefault
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.PropertiesProvider
@@ -23,15 +26,18 @@ import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType
import org.jetbrains.kotlin.gradle.targets.js.binaryen.BinaryenExec
import org.jetbrains.kotlin.gradle.targets.js.dsl.*
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTargetConfigurator.Companion.configureJsDefaultOptions
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmResolverPlugin
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
import org.jetbrains.kotlin.gradle.targets.js.typescript.TypeScriptValidationTask
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
import org.jetbrains.kotlin.gradle.utils.decamelize
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.gradle.utils.newInstance
import org.jetbrains.kotlin.gradle.utils.setProperty
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
@@ -389,6 +395,20 @@ constructor(
}
}
}
@ExperimentalKotlinGradlePluginApi
override val compilerOptions: KotlinJsCompilerOptions = project.objects
.newInstance<KotlinJsCompilerOptionsDefault>()
.configureExperimentalTryK2(project)
.apply {
configureJsDefaultOptions()
if (platformType == KotlinPlatformType.wasm) {
freeCompilerArgs.add(WASM_BACKEND)
}
freeCompilerArgs.add(DISABLE_PRE_IR)
}
}
fun KotlinJsIrTarget.wasmDecamelizedDefaultNameOrNull(): String? = if (platformType == KotlinPlatformType.wasm) {
@@ -14,15 +14,12 @@ import org.jetbrains.kotlin.gradle.dsl.JsSourceMapEmbedMode
import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompilerOptions
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.libsDirectory
import org.jetbrains.kotlin.gradle.plugin.mpp.sourcesJarTask
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsReportAggregatingTestRun
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
import org.jetbrains.kotlin.gradle.testing.testTaskName
import org.jetbrains.kotlin.gradle.utils.decamelize
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
open class KotlinJsIrTargetConfigurator :
KotlinOnlyTargetConfigurator<KotlinJsIrCompilation, KotlinJsIrTarget>(true),
@@ -91,33 +88,18 @@ open class KotlinJsIrTargetConfigurator :
override fun configureCompilations(target: KotlinJsIrTarget) {
super.configureCompilations(target)
target.compilations.all { compilation ->
compilation.compilerOptions.configure {
configureOptions()
if (target.platformType == KotlinPlatformType.wasm) {
freeCompilerArgs.add(WASM_BACKEND)
}
freeCompilerArgs.add(DISABLE_PRE_IR)
}
compilation.binaries
.withType(JsIrBinary::class.java)
.all { binary ->
binary.linkTask.configure { linkTask ->
linkTask.compilerOptions.configureOptions()
linkTask.compilerOptions.configureJsDefaultOptions()
}
}
}
}
private fun KotlinJsCompilerOptions.configureOptions() {
moduleKind.set(JsModuleKind.MODULE_UMD)
sourceMap.set(true)
sourceMapEmbedSources.set(JsSourceMapEmbedMode.SOURCE_MAP_SOURCE_CONTENT_NEVER)
}
override fun defineConfigurationsForTarget(target: KotlinJsIrTarget) {
super.defineConfigurationsForTarget(target)
@@ -134,4 +116,12 @@ open class KotlinJsIrTargetConfigurator :
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.common)
}
}
internal companion object {
internal fun KotlinJsCompilerOptions.configureJsDefaultOptions() {
moduleKind.set(JsModuleKind.MODULE_UMD)
sourceMap.set(true)
sourceMapEmbedSources.set(JsSourceMapEmbedMode.SOURCE_MAP_SOURCE_CONTENT_NEVER)
}
}
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.gradle.unitTests
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompilerOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinNativeCompilerOptions
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
@@ -74,7 +75,56 @@ class ProjectCompilerOptionsTests {
assertEquals(false, project.kotlinNativeTask("compileKotlinLinuxX64").compilerOptions.progressiveMode.get())
}
@Test
fun jsTargetCompilerOptionsDsl() {
val project = buildProjectWithMPP {
with(multiplatformExtension) {
js {
compilerOptions {
suppressWarnings.set(true)
}
}
applyDefaultHierarchyTemplate()
}
}
project.evaluate()
assertEquals(true, project.kotlinJsTask("compileKotlinJs").compilerOptions.suppressWarnings.get())
assertEquals(true, project.kotlinJsTask("compileTestKotlinJs").compilerOptions.suppressWarnings.get())
}
@Test
fun jsTaskOptionsOverridesTargetOptions() {
val project = buildProjectWithMPP {
tasks.withType<KotlinCompilationTask<*>>().configureEach {
if (it.name == "compileKotlinJs") {
it.compilerOptions.suppressWarnings.set(false)
}
}
with(multiplatformExtension) {
js {
compilerOptions {
suppressWarnings.set(true)
}
}
applyDefaultHierarchyTemplate()
}
}
project.evaluate()
assertEquals(false, project.kotlinJsTask("compileKotlinJs").compilerOptions.suppressWarnings.get())
}
private fun Project.kotlinNativeTask(name: String): KotlinCompilationTask<KotlinNativeCompilerOptions> = tasks
.named<KotlinCompilationTask<KotlinNativeCompilerOptions>>(name)
.get()
private fun Project.kotlinJsTask(name: String): KotlinCompilationTask<KotlinJsCompilerOptions> = tasks
.named<KotlinCompilationTask<KotlinJsCompilerOptions>>(name)
.get()
}