diff --git a/build.gradle.kts b/build.gradle.kts index 35bb7b911ee..79b09461beb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -242,6 +242,7 @@ val coreLibProjects = listOf( ":kotlin-stdlib", ":kotlin-stdlib-common", ":kotlin-stdlib-js", + ":kotlin-stdlib-js-ir", ":kotlin-stdlib-jdk7", ":kotlin-stdlib-jdk8", ":kotlin-test:kotlin-test-common", diff --git a/gradle.properties b/gradle.properties index e8169d3e404..401ee628f35 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,3 +12,6 @@ kotlin.compiler.newInferenceEnabled=true #jpsBuild=true #cidrPluginsEnabled=true + +kotlin.stdlib.js.ir.publish=false +kotlin.stdlib.js.ir.dist=false diff --git a/libraries/kotlin.test/js-ir/build.gradle b/libraries/kotlin.test/js-ir/build.gradle new file mode 100644 index 00000000000..7b66b34e4bf --- /dev/null +++ b/libraries/kotlin.test/js-ir/build.gradle @@ -0,0 +1,69 @@ +description = 'Kotlin Test for JS IR' + +apply plugin: 'kotlin-platform-js' + + +dependencies { + expectedBy project(':kotlin-test:kotlin-test-common') + expectedBy project(':kotlin-test:kotlin-test-annotations-common') + compile project(':kotlin-stdlib-js-ir') +} + +compileKotlin2Js { + kotlinOptions { + moduleKind = "umd" + freeCompilerArgs = [ + "-Xir", + "-Xir-produce-only=klib", + "-Xallow-kotlin-package", + "-Xuse-experimental=kotlin.contracts.ExperimentalContracts", + ] + } +} + +sourceSets { + main { + kotlin { + srcDir "${projectDir}/../js/src" + } + } +} + +compileTestKotlin2Js { + kotlinOptions.freeCompilerArgs = [ + "-Xir", + "-Xir-produce-only=js", + "-Xallow-kotlin-package", + ] + kotlinOptions { + metaInfo = false + moduleKind = "umd" + } +} + +task sourcesJar(type: Jar, dependsOn: classes) { + classifier = 'sources' + from(sourceSets.main.allSource) +} + +archivesBaseName = 'kotlin-test-js-ir' + +jar { + manifestAttributes(manifest, project, 'Test') +} + +artifacts { + archives sourcesJar +} + +if (project.findProperty("kotlin.stdlib.js.ir.publish")?.toBoolean() == true) { + configurePublishing(project) +} + +if (project.findProperty("kotlin.stdlib.js.ir.dist")?.toBoolean() == true) { + configureDist(project) + + dist { + from(jar, sourcesJar) + } +} \ No newline at end of file diff --git a/libraries/stdlib/js-ir/build.gradle b/libraries/stdlib/js-ir/build.gradle new file mode 100644 index 00000000000..951ee07666d --- /dev/null +++ b/libraries/stdlib/js-ir/build.gradle @@ -0,0 +1,205 @@ +plugins { + id "com.moowork.node" version "1.2.0" +} + +description = 'Kotlin Standard Library for JS IR' + +apply plugin: 'kotlin-platform-js' +apply plugin: 'idea' + +def originalBuiltinsDir = "${rootDir}/core/builtins" +def builtinsSrcDir = "${buildDir}/builtin-sources" +def nativeBuiltinsSrcDir = "${buildDir}/native-builtin-sources" + +// Sync native built-ins to separate directory because we don't +// need them all -- some of them are implemented as proper code in 'js-ir/builtins'. +// Also, they don't compile on its own without error suppressing. +task prepareNativeBuiltinsSources(type: Sync) { + from("${originalBuiltinsDir}/native/kotlin") { + include "Annotation.kt" + include "Any.kt" + include "Array.kt" + include "Boolean.kt" + include "CharSequence.kt" + include "Collections.kt" + include "Comparable.kt" + include "Coroutines.kt" + include "Iterator.kt" + include "Nothing.kt" + include "Number.kt" + include "String.kt" + include "Throwable.kt" + } + + into nativeBuiltinsSrcDir + + doLast { + (new File(nativeBuiltinsSrcDir)).list().each { path -> + def file = new File("${nativeBuiltinsSrcDir}/${path}") + def sourceCode = """\ + @file:Suppress( + "NON_ABSTRACT_FUNCTION_WITH_NO_BODY", + "MUST_BE_INITIALIZED_OR_BE_ABSTRACT", + "EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE", + "PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED", + "WRONG_MODIFIER_TARGET" + ) + """.stripIndent() + file.getText() + file.setText(sourceCode) + } + } +} + +task prepareBuiltinsSources(type: Sync) { + from("${originalBuiltinsDir}/src/kotlin/") { + exclude "ArrayIntrinsics.kt" // Used only for JVM + } + into builtinsSrcDir +} + +def jsCommonDir = "${projectDir}/../js" + +sourceSets { + main { + kotlin { + srcDir "${projectDir}/builtins" + srcDir "${projectDir}/runtime" + srcDir "${projectDir}/src" + + // "${jsCommonDir}/src/generated" is used for legacy backend + srcDir "${jsCommonDir}/src/jquery" + srcDir "${jsCommonDir}/src/kotlin" + srcDir "${jsCommonDir}/src/org.w3c" + + srcDir "${jsCommonDir}/runtime" + + srcDir builtinsSrcDir + srcDir nativeBuiltinsSrcDir + } + } + test { + kotlin { + srcDir "${rootDir}/libraries/stdlib/js/test" + srcDir "${jsCommonDir}/test/" + } + } +} + +configurations { + commonSources +} + +dependencies { + expectedBy project(":kotlin-stdlib-common") + commonSources project(path: ":kotlin-stdlib-common", configuration: "sources") + testCompile project(':kotlin-test:kotlin-test-js-ir') +} + + +compileKotlin2Js { + dependsOn prepareNativeBuiltinsSources + dependsOn prepareBuiltinsSources + + kotlinOptions { + outputFile = "${buildDir}/classes/main/kotlin.js" + moduleKind = "umd" + main = "noCall" + verbose = true + freeCompilerArgs += [ + "-Xir", + "-Xir-produce-only=klib", + "-Xallow-kotlin-package", + "-Xallow-result-return-type", + "-Xuse-experimental=kotlin.Experimental", + "-Xuse-experimental=kotlin.ExperimentalMultiplatform", + "-Xuse-experimental=kotlin.contracts.ExperimentalContracts", + "-XXLanguage:+InlineClasses", + ] + } +} + +def testOutputFile = "${buildDir}/classes/kotlin/test/kotlin-stdlib-js-ir_test.js" +def kotlinTestTestOutputFile = "${project(':kotlin-test:kotlin-test-js-ir').buildDir}/classes/kotlin/test/kotlin-test-js-ir_test.js" + +compileTestKotlin2Js { + kotlinOptions { + moduleKind = "umd" + verbose = true + outputFile = testOutputFile + freeCompilerArgs += [ + "-Xir", + "-Xir-produce-only=js", + "-verbose", + "-Xuse-experimental=kotlin.ExperimentalUnsignedTypes" + ] + } +} + +archivesBaseName = 'kotlin-stdlib-js-ir' + +jar { + manifestAttributes(manifest, project, 'Main') +} + +task sourcesJar(type: Jar, dependsOn: classes) { + classifier = 'sources' + from (sourceSets.main.allSource) +} + +artifacts { + archives sourcesJar +} + + +if (project.findProperty("kotlin.stdlib.js.ir.publish")?.toBoolean() == true) { + configurePublishing(project) +} + +if (project.findProperty("kotlin.stdlib.js.ir.dist")?.toBoolean() == true) { + configureDist(project) + dist { + from (jar, sourcesJar) + } +} + +node { + download = true + version = '8.9.4' // The default 6.9.1 has buggy hyperbolic functions implementation + nodeModulesDir = buildDir +} + +task installMocha(type: NpmTask) { + args = ['install', 'mocha'] +} + +task installTeamcityReporter(type: NpmTask) { + args = ['install', 'mocha-teamcity-reporter'] +} + +task runMocha(type: NodeTask) { + dependsOn compileTestKotlin2Js + dependsOn installMocha + dependsOn ':kotlin-test:kotlin-test-js-ir:testClasses' + + script = file("${buildDir}/node_modules/mocha/bin/mocha") + + if (project.hasProperty("teamcity")) { + dependsOn installTeamcityReporter + args = ['--reporter', 'mocha-teamcity-reporter', + '--reporter-options', 'topLevelSuite=stdlib-js-ir'] + } + else { + args = ['--reporter', 'min'] + } + + args += [testOutputFile, kotlinTestTestOutputFile] + + execOverrides { + // Tests are currently failing. Ignore the exit value for now + // TODO: replace with rootProject.ignoreTestFailures when tests are fixed + it.ignoreExitValue = true + it.workingDir = buildDir + } +} + +test.dependsOn runMocha diff --git a/settings.gradle b/settings.gradle index b6682c9a9c2..eb13cb2e307 100644 --- a/settings.gradle +++ b/settings.gradle @@ -124,6 +124,7 @@ include ":kotlin-build-common", ":kotlin-test:kotlin-test-junit5", ":kotlin-test:kotlin-test-testng", ":kotlin-test:kotlin-test-js", + ":kotlin-test:kotlin-test-js-ir", ":kotlin-test:kotlin-test-js:kotlin-test-js-it", ":kotlin-test-nodejs-runner", ":kotlinx-metadata", @@ -236,6 +237,7 @@ if (flags.inJpsBuildIdeaSync) { ":kotlin-stdlib-common", ":kotlin-stdlib", ":kotlin-stdlib-js", + ":kotlin-stdlib-js-ir", ":kotlin-stdlib-jdk7", ":kotlin-stdlib-jdk8", ":kotlin-stdlib:samples", @@ -248,6 +250,7 @@ if (flags.inJpsBuildIdeaSync) { project(':kotlin-stdlib-common').projectDir = "$rootDir/libraries/stdlib/common" as File project(':kotlin-stdlib').projectDir = "$rootDir/libraries/stdlib/jvm" as File project(':kotlin-stdlib-js').projectDir = "$rootDir/libraries/stdlib/js-v1" as File + project(':kotlin-stdlib-js-ir').projectDir = "$rootDir/libraries/stdlib/js-ir" as File project(':kotlin-stdlib-jdk7').projectDir = "$rootDir/libraries/stdlib/jdk7" as File project(':kotlin-stdlib-jdk8').projectDir = "$rootDir/libraries/stdlib/jdk8" as File project(':kotlin-stdlib:samples').projectDir = "$rootDir/libraries/stdlib/samples" as File @@ -268,6 +271,7 @@ project(':kotlin-test:kotlin-test-junit').projectDir = "$rootDir/libraries/kotli project(':kotlin-test:kotlin-test-junit5').projectDir = "$rootDir/libraries/kotlin.test/junit5" as File project(':kotlin-test:kotlin-test-testng').projectDir = "$rootDir/libraries/kotlin.test/testng" as File project(':kotlin-test:kotlin-test-js').projectDir = "$rootDir/libraries/kotlin.test/js" as File +project(':kotlin-test:kotlin-test-js-ir').projectDir = "$rootDir/libraries/kotlin.test/js-ir" as File project(':kotlin-test:kotlin-test-js:kotlin-test-js-it').projectDir = "$rootDir/libraries/kotlin.test/js/it" as File project(':kotlin-test-nodejs-runner').projectDir = "$rootDir/libraries/tools/kotlin-test-nodejs-runner" as File project(':kotlin-reflect').projectDir = "$rootDir/libraries/reflect" as File