diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt index 1d43253387f..e431bc0ed20 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt @@ -125,6 +125,12 @@ class K2JSCompilerArguments : CommonCompilerArguments() { @Argument(value = "-Xir-only", description = "Disables pre-IR backend") var irOnly: Boolean by FreezableVar(false) + @Argument( + value = "-Xgenerate-dts", + description = "Generate TypeScript declarations .d.ts file alongside JS file. Available in IR backend only." + ) + var generateDts: Boolean by FreezableVar(false) + @GradleOption(DefaultValues.BooleanTrueDefault::class) @Argument(value = "-Xtyped-arrays", description = "Translate primitive arrays to JS typed arrays") var typedArrays: Boolean by FreezableVar(true) diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt index 192d6ea8138..61b45c2e2b0 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt @@ -45,6 +45,7 @@ import org.jetbrains.kotlin.util.Logger import org.jetbrains.kotlin.utils.JsMetadataVersion import org.jetbrains.kotlin.utils.KotlinPaths import org.jetbrains.kotlin.utils.PathUtil +import org.jetbrains.kotlin.utils.fileUtils.withReplacedExtensionOrNull import org.jetbrains.kotlin.utils.join import java.io.File import java.io.IOException @@ -208,6 +209,10 @@ class K2JsIrCompiler : CLICompiler() { ) outputFile.writeText(compiledModule.jsCode) + if (arguments.generateDts) { + val dtsFile = outputFile.withReplacedExtensionOrNull(outputFile.extension, "d.ts")!! + dtsFile.writeText(compiledModule.tsDefinitions ?: error("No ts definitions")) + } } return OK diff --git a/compiler/testData/cli/js/jsExtraHelp.out b/compiler/testData/cli/js/jsExtraHelp.out index beab020e3d9..de7c31c77ec 100644 --- a/compiler/testData/cli/js/jsExtraHelp.out +++ b/compiler/testData/cli/js/jsExtraHelp.out @@ -3,6 +3,7 @@ where advanced options include: -Xenable-js-scripting Enable experimental support of .kts files using K/JS (with -Xir only) -Xfriend-modules= Paths to friend modules -Xfriend-modules-disabled Disable internal declaration export + -Xgenerate-dts Generate TypeScript declarations .d.ts file alongside JS file. Available in IR backend only. -Xir-only Disables pre-IR backend -Xir-produce-js Generates JS file using IR backend. Also disables pre-IR backend -Xir-produce-klib-dir Generate unpacked KLIB into parent directory of output JS file. diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt index 1356a22fb67..34c7e00e4bc 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt @@ -13,7 +13,21 @@ import java.util.zip.ZipFile import kotlin.test.assertEquals import kotlin.test.assertTrue -class Kotlin2JsIrGradlePluginIT : AbstractKotlin2JsGradlePluginIT(true) +class Kotlin2JsIrGradlePluginIT : AbstractKotlin2JsGradlePluginIT(true) { + @Test + fun generateDts() { + val project = Project("kotlin2JsIrDtsGeneration") + project.build("build") { + assertSuccessful() + checkIrCompilationMessage() + + assertFileExists("build/kotlin2js/main/lib.js") + val dts = fileInWorkingDir("build/kotlin2js/main/lib.d.ts") + assert(dts.exists()) + assert(dts.readText().contains("function bar(): string")) + } + } +} class Kotlin2JsGradlePluginIT : AbstractKotlin2JsGradlePluginIT(false) { @Test @@ -119,7 +133,7 @@ abstract class AbstractKotlin2JsGradlePluginIT(private val irBackend: Boolean) : override fun defaultBuildOptions(): BuildOptions = super.defaultBuildOptions().copy(jsIrBackend = irBackend) - private fun CompiledProject.checkIrCompilationMessage() { + protected fun CompiledProject.checkIrCompilationMessage() { if (irBackend) { assertContains(USING_JS_IR_BACKEND_MESSAGE) } else { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin2JsIrDtsGeneration/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin2JsIrDtsGeneration/build.gradle new file mode 100644 index 00000000000..e701bdd8e12 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin2JsIrDtsGeneration/build.gradle @@ -0,0 +1,27 @@ +buildscript { + repositories { + mavenLocal() + mavenCentral() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +apply plugin: "kotlin2js" +apply plugin: 'java' + +def outDir = "${buildDir}/kotlin2js/main/" +compileKotlin2Js.kotlinOptions.moduleKind = "plain" +compileKotlin2Js.kotlinOptions.outputFile = outDir + "lib.js" +compileKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-js", "-Xgenerate-dts"] + +repositories { + mavenLocal() + mavenCentral() +} + +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version" +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin2JsIrDtsGeneration/src/main/kotlin/HelloWorld.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin2JsIrDtsGeneration/src/main/kotlin/HelloWorld.kt new file mode 100644 index 00000000000..0b3797e83be --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin2JsIrDtsGeneration/src/main/kotlin/HelloWorld.kt @@ -0,0 +1,9 @@ +/* + * Copyright 2010-2019 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 foo + +@JsExport +fun bar() = "OK"