[JS_IR] Use new plugin to build Kotlin/JS stdlib with IR compiler
- Switch to building stdlib with bootstrap compiler since IR is stable enough - Build stdlib with coreLibs by default - Include JS IR stdlib to kotlin distribution
This commit is contained in:
@@ -1,49 +1,19 @@
|
||||
import com.moowork.gradle.node.npm.NpmTask
|
||||
import com.moowork.gradle.node.task.NodeTask
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType.IR
|
||||
|
||||
plugins {
|
||||
base
|
||||
id("com.github.node-gradle.node") version "2.2.0"
|
||||
kotlin("multiplatform")
|
||||
}
|
||||
|
||||
// A simple CLI for creating JS IR klibs.
|
||||
// Does not depend on backend lowerings and JS codegen.
|
||||
val jsIrKlibCli: Configuration by configurations.creating
|
||||
|
||||
// Full JS IR compiler CLI
|
||||
val fullJsIrCli: Configuration by configurations.creating
|
||||
|
||||
dependencies {
|
||||
jsIrKlibCli(project(":compiler:cli-js-klib"))
|
||||
|
||||
fullJsIrCli(project(":compiler:cli-js"))
|
||||
fullJsIrCli(project(":compiler:util"))
|
||||
fullJsIrCli(project(":compiler:cli-common"))
|
||||
fullJsIrCli(project(":compiler:cli"))
|
||||
fullJsIrCli(project(":compiler:frontend"))
|
||||
fullJsIrCli(project(":compiler:backend-common"))
|
||||
fullJsIrCli(project(":compiler:backend"))
|
||||
fullJsIrCli(project(":compiler:ir.backend.common"))
|
||||
fullJsIrCli(project(":compiler:ir.serialization.js"))
|
||||
fullJsIrCli(project(":compiler:backend.js"))
|
||||
fullJsIrCli(project(":js:js.translator"))
|
||||
fullJsIrCli(project(":js:js.serializer"))
|
||||
fullJsIrCli(project(":js:js.dce"))
|
||||
fullJsIrCli(project(":kotlin-reflect"))
|
||||
fullJsIrCli(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
if (Platform[193].orLower()) {
|
||||
fullJsIrCli(intellijDep()) {
|
||||
includeJars("picocontainer", rootProject = rootProject)
|
||||
}
|
||||
}
|
||||
fullJsIrCli(intellijDep()) {
|
||||
includeJars("trove4j", "guava", "jdom", "asm-all", rootProject = rootProject)
|
||||
kotlin {
|
||||
js(IR) {
|
||||
nodejs()
|
||||
}
|
||||
}
|
||||
|
||||
val unimplementedNativeBuiltIns =
|
||||
(file("$rootDir/core/builtins/native/kotlin/").list().toSortedSet() - file("$rootDir/libraries/stdlib/js-ir/builtins/").list())
|
||||
.map { "core/builtins/native/kotlin/$it" }
|
||||
(file("$rootDir/core/builtins/native/kotlin/").list().toSortedSet() - file("$rootDir/libraries/stdlib/js-ir/builtins/").list())
|
||||
.map { "core/builtins/native/kotlin/$it" }
|
||||
|
||||
// Required to compile native builtins with the rest of runtime
|
||||
val builtInsHeader = """@file:Suppress(
|
||||
@@ -55,13 +25,25 @@ val builtInsHeader = """@file:Suppress(
|
||||
)
|
||||
"""
|
||||
|
||||
val fullRuntimeSources by task<Sync> {
|
||||
|
||||
val commonMainSources by task<Sync> {
|
||||
val sources = listOf(
|
||||
"core/builtins/src/kotlin/",
|
||||
"libraries/stdlib/common/src/",
|
||||
"libraries/stdlib/src/kotlin/",
|
||||
"libraries/stdlib/unsigned/",
|
||||
"libraries/stdlib/unsigned/"
|
||||
)
|
||||
|
||||
sources.forEach { path ->
|
||||
from("$rootDir/$path") {
|
||||
into(path.dropLastWhile { it != '/' })
|
||||
}
|
||||
}
|
||||
|
||||
into("$buildDir/commonMainSources")
|
||||
}
|
||||
|
||||
val jsMainSources by task<Sync> {
|
||||
val sources = listOf(
|
||||
"core/builtins/src/kotlin/",
|
||||
"libraries/stdlib/js/src/",
|
||||
"libraries/stdlib/js/runtime/",
|
||||
"libraries/stdlib/js-ir/builtins/",
|
||||
@@ -89,276 +71,88 @@ val fullRuntimeSources by task<Sync> {
|
||||
}
|
||||
}
|
||||
|
||||
into("$buildDir/fullRuntime/src")
|
||||
into("$buildDir/jsMainSources")
|
||||
|
||||
doLast {
|
||||
unimplementedNativeBuiltIns.forEach { path ->
|
||||
val file = File("$buildDir/fullRuntime/src/$path")
|
||||
val file = File("$buildDir/jsMainSources/$path")
|
||||
val sourceCode = builtInsHeader + file.readText()
|
||||
file.writeText(sourceCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val reducedRuntimeSources by task<Sync> {
|
||||
dependsOn(fullRuntimeSources)
|
||||
|
||||
from(fullRuntimeSources.get().outputs.files.singleFile) {
|
||||
exclude(
|
||||
listOf(
|
||||
"libraries/stdlib/unsigned/**",
|
||||
"libraries/stdlib/common/src/generated/_Arrays.kt",
|
||||
"libraries/stdlib/common/src/generated/_Collections.kt",
|
||||
"libraries/stdlib/common/src/generated/_Comparisons.kt",
|
||||
"libraries/stdlib/common/src/generated/_Maps.kt",
|
||||
"libraries/stdlib/common/src/generated/_Sequences.kt",
|
||||
"libraries/stdlib/common/src/generated/_Sets.kt",
|
||||
"libraries/stdlib/common/src/generated/_Strings.kt",
|
||||
"libraries/stdlib/common/src/generated/_UArrays.kt",
|
||||
"libraries/stdlib/common/src/generated/_URanges.kt",
|
||||
"libraries/stdlib/common/src/generated/_UCollections.kt",
|
||||
"libraries/stdlib/common/src/generated/_UComparisons.kt",
|
||||
"libraries/stdlib/common/src/generated/_USequences.kt",
|
||||
"libraries/stdlib/common/src/kotlin/SequencesH.kt",
|
||||
"libraries/stdlib/common/src/kotlin/TextH.kt",
|
||||
"libraries/stdlib/common/src/kotlin/UMath.kt",
|
||||
"libraries/stdlib/common/src/kotlin/collections/**",
|
||||
"libraries/stdlib/common/src/kotlin/ioH.kt",
|
||||
"libraries/stdlib/js-ir/runtime/collectionsHacks.kt",
|
||||
"libraries/stdlib/js-ir/src/generated/**",
|
||||
"libraries/stdlib/js-ir/src/kotlin/text/**",
|
||||
"libraries/stdlib/js/src/jquery/**",
|
||||
"libraries/stdlib/js/src/org.w3c/**",
|
||||
"libraries/stdlib/js/src/kotlin/char.kt",
|
||||
"libraries/stdlib/js/src/kotlin/collections.kt",
|
||||
"libraries/stdlib/js/src/kotlin/collections/**",
|
||||
"libraries/stdlib/js/src/kotlin/time/**",
|
||||
"libraries/stdlib/js/src/kotlin/console.kt",
|
||||
"libraries/stdlib/js/src/kotlin/coreDeprecated.kt",
|
||||
"libraries/stdlib/js/src/kotlin/date.kt",
|
||||
"libraries/stdlib/js/src/kotlin/debug.kt",
|
||||
"libraries/stdlib/js/src/kotlin/grouping.kt",
|
||||
"libraries/stdlib/js/src/kotlin/json.kt",
|
||||
"libraries/stdlib/js/src/kotlin/promise.kt",
|
||||
"libraries/stdlib/js/src/kotlin/regexp.kt",
|
||||
"libraries/stdlib/js/src/kotlin/sequence.kt",
|
||||
"libraries/stdlib/js/src/kotlin/throwableExtensions.kt",
|
||||
"libraries/stdlib/js/src/kotlin/text/**",
|
||||
"libraries/stdlib/js/src/kotlin/reflect/KTypeHelpers.kt",
|
||||
"libraries/stdlib/js/src/kotlin/reflect/KTypeParameterImpl.kt",
|
||||
"libraries/stdlib/js/src/kotlin/reflect/KTypeImpl.kt",
|
||||
"libraries/stdlib/src/kotlin/collections/**",
|
||||
"libraries/stdlib/src/kotlin/experimental/bitwiseOperations.kt",
|
||||
"libraries/stdlib/src/kotlin/properties/Delegates.kt",
|
||||
"libraries/stdlib/src/kotlin/random/URandom.kt",
|
||||
"libraries/stdlib/src/kotlin/text/**",
|
||||
"libraries/stdlib/src/kotlin/time/**",
|
||||
"libraries/stdlib/src/kotlin/util/KotlinVersion.kt",
|
||||
"libraries/stdlib/src/kotlin/util/Tuples.kt",
|
||||
"libraries/stdlib/js/src/kotlin/dom/**",
|
||||
"libraries/stdlib/js/src/kotlin/browser/**"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
from("$rootDir/libraries/stdlib/js-ir/smallRuntime") {
|
||||
into("libraries/stdlib/js-ir/runtime/")
|
||||
}
|
||||
|
||||
into("$buildDir/reducedRuntime/src")
|
||||
}
|
||||
|
||||
fun JavaExec.buildKLib(
|
||||
moduleName: String,
|
||||
sources: List<File>,
|
||||
dependencies: List<File>,
|
||||
outDir: File,
|
||||
commonSources: List<File>
|
||||
) {
|
||||
inputs.files(sources)
|
||||
.withPathSensitivity(PathSensitivity.RELATIVE)
|
||||
|
||||
outputs.dir(file(outDir))
|
||||
outputs.cacheIf { true }
|
||||
|
||||
classpath = jsIrKlibCli
|
||||
main = "org.jetbrains.kotlin.ir.backend.js.GenerateJsIrKlibKt"
|
||||
workingDir = rootDir
|
||||
args = sources.map(::pathRelativeToWorkingDir) +
|
||||
listOf("-n", moduleName, "-o", pathRelativeToWorkingDir(outDir)) +
|
||||
dependencies.flatMap { listOf("-d", pathRelativeToWorkingDir(it)) } +
|
||||
commonSources.flatMap { listOf("-c", pathRelativeToWorkingDir(it)) }
|
||||
|
||||
dependsOn(":compiler:cli-js-klib:jar")
|
||||
passClasspathInJar()
|
||||
}
|
||||
|
||||
val fullRuntimeDir = buildDir.resolve("fullRuntime/klib")
|
||||
|
||||
val generateFullRuntimeKLib by eagerTask<NoDebugJavaExec> {
|
||||
dependsOn(fullRuntimeSources)
|
||||
|
||||
buildKLib(moduleName = "kotlin",
|
||||
sources = listOf(fullRuntimeSources.get().outputs.files.singleFile),
|
||||
dependencies = emptyList(),
|
||||
outDir = fullRuntimeDir,
|
||||
commonSources = listOf("common", "src", "unsigned").map { file("$buildDir/fullRuntime/src/libraries/stdlib/$it") }
|
||||
val commonTestSources by task<Sync> {
|
||||
val sources = listOf(
|
||||
"libraries/stdlib/test/",
|
||||
"libraries/stdlib/common/test/"
|
||||
)
|
||||
|
||||
sources.forEach { path ->
|
||||
from("$rootDir/$path") {
|
||||
into(path.dropLastWhile { it != '/' })
|
||||
}
|
||||
}
|
||||
|
||||
into("$buildDir/commonTestSources")
|
||||
}
|
||||
|
||||
val jsTestSources by task<Sync> {
|
||||
from("$rootDir/libraries/stdlib/js/test/")
|
||||
into("$buildDir/jsTestSources")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
val commonMain by getting {
|
||||
kotlin.srcDir(commonMainSources.get().destinationDir)
|
||||
}
|
||||
val jsMain by getting {
|
||||
kotlin.srcDir(jsMainSources.get().destinationDir)
|
||||
}
|
||||
val commonTest by getting {
|
||||
dependencies {
|
||||
api(project(":kotlin-test:kotlin-test-js-ir"))
|
||||
}
|
||||
kotlin.srcDir(commonTestSources.get().destinationDir)
|
||||
}
|
||||
val jsTest by getting {
|
||||
dependencies {
|
||||
api(project(":kotlin-test:kotlin-test-js-ir"))
|
||||
}
|
||||
kotlin.srcDir(jsTestSources.get().destinationDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile<*>>().configureEach {
|
||||
kotlinOptions.freeCompilerArgs += listOf(
|
||||
"-Xallow-kotlin-package",
|
||||
"-Xallow-result-return-type",
|
||||
"-Xuse-experimental=kotlin.Experimental",
|
||||
"-Xuse-experimental=kotlin.ExperimentalMultiplatform",
|
||||
"-Xuse-experimental=kotlin.contracts.ExperimentalContracts",
|
||||
"-Xinline-classes",
|
||||
"-Xopt-in=kotlin.RequiresOptIn",
|
||||
"-Xopt-in=kotlin.ExperimentalUnsignedTypes",
|
||||
"-Xopt-in=kotlin.ExperimentalStdlibApi"
|
||||
)
|
||||
}
|
||||
|
||||
tasks.named("compileKotlinJs") {
|
||||
(this as KotlinCompile<*>).kotlinOptions.freeCompilerArgs += "-Xir-module-name=kotlin"
|
||||
dependsOn(commonMainSources)
|
||||
dependsOn(jsMainSources)
|
||||
}
|
||||
|
||||
tasks.named("compileTestKotlinJs") {
|
||||
dependsOn(commonTestSources)
|
||||
dependsOn(jsTestSources)
|
||||
}
|
||||
|
||||
val packFullRuntimeKLib by tasks.registering(Jar::class) {
|
||||
dependsOn(generateFullRuntimeKLib)
|
||||
from(fullRuntimeDir)
|
||||
dependsOn(tasks.named("compileKotlinJs"))
|
||||
from(buildDir.resolve("classes/kotlin/js/main"))
|
||||
destinationDirectory.set(rootProject.buildDir.resolve("js-ir-runtime"))
|
||||
archiveFileName.set("full-runtime.klib")
|
||||
}
|
||||
|
||||
val generateReducedRuntimeKLib by eagerTask<NoDebugJavaExec> {
|
||||
dependsOn(reducedRuntimeSources)
|
||||
|
||||
buildKLib(moduleName = "kotlin",
|
||||
sources = listOf(reducedRuntimeSources.get().outputs.files.singleFile),
|
||||
dependencies = emptyList(),
|
||||
outDir = buildDir.resolve("reducedRuntime/klib"),
|
||||
commonSources = listOf("common", "src", "unsigned").map { file("$buildDir/reducedRuntime/src/libraries/stdlib/$it") }
|
||||
)
|
||||
}
|
||||
|
||||
val generateWasmRuntimeKLib by eagerTask<NoDebugJavaExec> {
|
||||
buildKLib(moduleName = "kotlin",
|
||||
sources = listOf(file("$rootDir/libraries/stdlib/wasm")),
|
||||
dependencies = emptyList(),
|
||||
outDir = file("$buildDir/wasmRuntime/klib"),
|
||||
commonSources = emptyList()
|
||||
)
|
||||
}
|
||||
|
||||
val kotlinTestCommonSources = listOf(
|
||||
"$rootDir/libraries/kotlin.test/annotations-common/src/main",
|
||||
"$rootDir/libraries/kotlin.test/common/src/main"
|
||||
)
|
||||
|
||||
val generateKotlinTestKLib by eagerTask<NoDebugJavaExec> {
|
||||
dependsOn(generateFullRuntimeKLib)
|
||||
|
||||
buildKLib(
|
||||
moduleName = "kotlin-test",
|
||||
sources = (listOf("$rootDir/libraries/kotlin.test/js/src/main") + kotlinTestCommonSources).map(::file),
|
||||
dependencies = listOf(generateFullRuntimeKLib.outputs.files.singleFile),
|
||||
outDir = file("$buildDir/kotlin.test/klib"),
|
||||
commonSources = kotlinTestCommonSources.map(::file)
|
||||
)
|
||||
}
|
||||
|
||||
val jsTestDir = "${buildDir}/testSrc"
|
||||
|
||||
val prepareStdlibTestSources by task<Sync> {
|
||||
from("$rootDir/libraries/stdlib/test") {
|
||||
exclude("src/generated/**")
|
||||
into("test")
|
||||
}
|
||||
from("$rootDir/libraries/stdlib/common/test") {
|
||||
exclude("src/generated/**")
|
||||
into("common")
|
||||
}
|
||||
from("$rootDir/libraries/stdlib/js/test") {
|
||||
into("js")
|
||||
}
|
||||
into(jsTestDir)
|
||||
}
|
||||
|
||||
fun JavaExec.buildJs(sources: List<String>, dependencies: List<String>, outPath: String, commonSources: List<String>) {
|
||||
inputs.files(sources)
|
||||
outputs.dir(file(outPath).parent)
|
||||
classpath = fullJsIrCli
|
||||
main = "org.jetbrains.kotlin.cli.js.K2JsIrCompiler"
|
||||
workingDir = rootDir
|
||||
|
||||
val libraryString: String = dependencies.joinToString(File.pathSeparator)
|
||||
val libraryArgs: List<String> = if (libraryString.isEmpty()) emptyList() else listOf<String>("-libraries", libraryString, "-Xfriend-modules=$libraryString")
|
||||
val allArgs =
|
||||
sources.toList() + listOf("-output", outPath) + libraryArgs + listOf(
|
||||
"-Xir-produce-js",
|
||||
"-Xmulti-platform",
|
||||
"-Xopt-in=kotlin.RequiresOptIn",
|
||||
"-Xopt-in=kotlin.contracts.ExperimentalContracts",
|
||||
"-Xopt-in=kotlin.ExperimentalMultiplatform",
|
||||
"-Xopt-in=kotlin.ExperimentalStdlibApi",
|
||||
"-Xopt-in=kotlin.ExperimentalUnsignedTypes"
|
||||
)
|
||||
args = allArgs
|
||||
|
||||
dependsOn(":compiler:cli-js:jar")
|
||||
passClasspathInJar()
|
||||
}
|
||||
|
||||
val testOutputFile = "$buildDir/kotlin-stdlib-js-ir_test.js"
|
||||
|
||||
val tryRunFullCli by eagerTask<NoDebugJavaExec> {
|
||||
dependsOn(prepareStdlibTestSources)
|
||||
dependsOn(generateFullRuntimeKLib)
|
||||
dependsOn(generateKotlinTestKLib)
|
||||
|
||||
buildJs(
|
||||
sources = listOf(jsTestDir),
|
||||
dependencies = listOf(
|
||||
generateFullRuntimeKLib.outputs.files.singleFile.path,
|
||||
generateKotlinTestKLib.outputs.files.singleFile.path
|
||||
),
|
||||
outPath = testOutputFile,
|
||||
commonSources = emptyList()
|
||||
)
|
||||
}
|
||||
|
||||
node {
|
||||
download = true
|
||||
version = "10.16.2"
|
||||
nodeModulesDir = buildDir
|
||||
}
|
||||
|
||||
val installMocha by task<NpmTask> {
|
||||
setArgs(listOf("install", "mocha"))
|
||||
}
|
||||
|
||||
val installTeamcityReporter by task<NpmTask> {
|
||||
setArgs(listOf("install", "mocha-teamcity-reporter"))
|
||||
}
|
||||
|
||||
// TODO: TEST OUTPUT FILE
|
||||
// val kotlinTestTestOutputFile = "${project(':kotlin-test:kotlin-test-js').buildDir}/classes/kotlin/test/kotlin-test-js-ir_test.js"
|
||||
|
||||
val runMocha by task<NodeTask> {
|
||||
dependsOn(installMocha)
|
||||
dependsOn(tryRunFullCli)
|
||||
|
||||
script = file("${buildDir}/node_modules/mocha/bin/mocha")
|
||||
|
||||
if (project.hasProperty("teamcity")) {
|
||||
dependsOn(installTeamcityReporter)
|
||||
setArgs(
|
||||
listOf(
|
||||
"--reporter",
|
||||
"mocha-teamcity-reporter",
|
||||
"--reporter-options",
|
||||
"topLevelSuite=stdlib-js-ir"
|
||||
)
|
||||
)
|
||||
}
|
||||
else {
|
||||
setArgs(listOf("--reporter", "min"))
|
||||
}
|
||||
|
||||
val allArgs = getArgs().toList() + listOf(testOutputFile/*, kotlinTestTestOutputFile*/)
|
||||
setArgs(allArgs)
|
||||
|
||||
setIgnoreExitValue(kotlinBuildProperties.ignoreTestFailures)
|
||||
setWorkingDir(buildDir)
|
||||
}
|
||||
|
||||
tasks {
|
||||
val test by registering { dependsOn(runMocha) }
|
||||
val check by existing { dependsOn(test) }
|
||||
|
||||
// dummy task to make coreLibsInstall aggregate task not fail
|
||||
val install by registering
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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 kotlin
|
||||
|
||||
/**
|
||||
* Returns `true` if this char sequence is empty (contains no characters).
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun CharSequence.isEmpty(): Boolean = length == 0
|
||||
|
||||
/**
|
||||
* Accumulates value starting with [initial] value and applying [operation] from left to right to current accumulator value and each element.
|
||||
*/
|
||||
public inline fun <T, R> Array<out T>.fold(initial: R, operation: (acc: R, T) -> R): R {
|
||||
var accumulator = initial
|
||||
for (element in this) accumulator = operation(accumulator, element)
|
||||
return accumulator
|
||||
}
|
||||
|
||||
|
||||
public actual fun Throwable.stackTraceToString(): String = toString()
|
||||
|
||||
public actual fun Throwable.printStackTrace() {
|
||||
TODO("Not implemented in reduced runtime")
|
||||
}
|
||||
|
||||
public actual fun Throwable.addSuppressed(exception: Throwable) {
|
||||
TODO("Not implemented in reduced runtime")
|
||||
}
|
||||
|
||||
public actual val Throwable.suppressedExceptions: List<Throwable>
|
||||
get() = TODO("Not implemented in reduced runtime")
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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 kotlin.test
|
||||
|
||||
// This file plugs some declaration from "kotlin.test" library used in tests.
|
||||
|
||||
fun <T> assertEquals(a: T, b: T) {
|
||||
if (a != b) throw Exception("")
|
||||
}
|
||||
|
||||
fun assertTrue(x: Boolean) {
|
||||
if (!x) throw Exception("")
|
||||
}
|
||||
|
||||
fun assertFalse(x: Boolean) {
|
||||
if (x) throw Exception("")
|
||||
}
|
||||
|
||||
fun <T : Any> assertNotNull(actual: T?, message: String? = null): T {
|
||||
if (actual == null) throw Exception("")
|
||||
return actual
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user