Revert "Revert [JS IR] commits that failed build"

This reverts commit 740f851a
This commit is contained in:
Nikolay Krasko
2019-11-05 14:54:48 +03:00
committed by Svyatoslav Kuzmich
parent 181d023e3c
commit 155a760ee9
28 changed files with 427 additions and 337 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ buildscript {
extra["defaultSnapshotVersion"] = "1.3-SNAPSHOT" extra["defaultSnapshotVersion"] = "1.3-SNAPSHOT"
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
kotlinBootstrapFrom(BootstrapOption.BintrayBootstrap("1.3.70-dev-1070", cacheRedirectorEnabled)) kotlinBootstrapFrom(BootstrapOption.BintrayBootstrap("1.3.70-dev-1140", cacheRedirectorEnabled))
repositories { repositories {
bootstrapKotlinRepo?.let(::maven) bootstrapKotlinRepo?.let(::maven)
@@ -106,22 +106,24 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
// Advanced options // Advanced options
@Argument(
@Argument(value = "-Xir", description = "Use IR backend") value = "-Xir-produce-klib-dir",
var irBackend: Boolean by FreezableVar(false) description = "Generate unpacked KLIB into parent directory of output JS file.\n" +
"In combination with -meta-info generates both IR and pre-IR versions of library."
)
var irProduceKlibDir: Boolean by FreezableVar(false)
@Argument( @Argument(
value = "-Xir-produce-only", value = "-Xir-produce-klib-file",
valueDescription = "{ klib, js }", description = "Generate packed klib into file specified by -output. Disables pre-IR backend"
description = "Type of output to produce. Overrides -meta-info argument."
) )
var irProduceOnly: String? by NullableStringFreezableVar(null) var irProduceKlibFile: Boolean by FreezableVar(false)
@Argument( @Argument(value = "-Xir-produce-js", description = "Generates JS file using IR backend. Also disables pre-IR backend")
value = "-Xir-legacy-gradle-plugin-compatibility", var irProduceJs: Boolean by FreezableVar(false)
description = "Make KLIB generation compatible with legacy gradle plugin"
) @Argument(value = "-Xir-only", description = "Disables pre-IR backend")
var irLegacyGradlePluginCompatibility: Boolean by FreezableVar(false) var irOnly: Boolean by FreezableVar(false)
@GradleOption(DefaultValues.BooleanTrueDefault::class) @GradleOption(DefaultValues.BooleanTrueDefault::class)
@Argument(value = "-Xtyped-arrays", description = "Translate primitive arrays to JS typed arrays") @Argument(value = "-Xtyped-arrays", description = "Translate primitive arrays to JS typed arrays")
@@ -144,3 +146,9 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
@Argument(value = "-Xenable-js-scripting", description = "Enable experimental support of .kts files using K/JS (with -Xir only)") @Argument(value = "-Xenable-js-scripting", description = "Enable experimental support of .kts files using K/JS (with -Xir only)")
var enableJsScripting: Boolean by FreezableVar(false) var enableJsScripting: Boolean by FreezableVar(false)
} }
fun K2JSCompilerArguments.isPreIrBackendDisabled(): Boolean =
irOnly || irProduceJs || irProduceKlibFile
fun K2JSCompilerArguments.isIrBackendEnabled(): Boolean =
irProduceKlibDir || irProduceJs || irProduceKlibFile
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys;
import org.jetbrains.kotlin.cli.common.CommonCompilerPerformanceManager; import org.jetbrains.kotlin.cli.common.CommonCompilerPerformanceManager;
import org.jetbrains.kotlin.cli.common.ExitCode; import org.jetbrains.kotlin.cli.common.ExitCode;
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments; import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments;
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArgumentsKt;
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants; import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants;
import org.jetbrains.kotlin.cli.common.config.ContentRootsKt; import org.jetbrains.kotlin.cli.common.config.ContentRootsKt;
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport; import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport;
@@ -45,7 +46,6 @@ import org.jetbrains.kotlin.cli.common.messages.MessageUtil;
import org.jetbrains.kotlin.cli.common.output.OutputUtilsKt; import org.jetbrains.kotlin.cli.common.output.OutputUtilsKt;
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles; import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment; import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser;
import org.jetbrains.kotlin.config.*; import org.jetbrains.kotlin.config.*;
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker; import org.jetbrains.kotlin.incremental.components.ExpectActualTracker;
import org.jetbrains.kotlin.incremental.components.LookupTracker; import org.jetbrains.kotlin.incremental.components.LookupTracker;
@@ -186,8 +186,13 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
) { ) {
MessageCollector messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY); MessageCollector messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY);
if (arguments.getIrBackend()) { ExitCode exitCode = OK;
return getIrCompiler().doExecute(arguments, configuration, rootDisposable, paths);
if (K2JSCompilerArgumentsKt.isIrBackendEnabled(arguments)) {
exitCode = getIrCompiler().doExecute(arguments, configuration.copy(), rootDisposable, paths);
}
if (K2JSCompilerArgumentsKt.isPreIrBackendDisabled(arguments)) {
return exitCode;
} }
if (arguments.getFreeArgs().isEmpty() && !IncrementalCompilation.isEnabledForJs()) { if (arguments.getFreeArgs().isEmpty() && !IncrementalCompilation.isEnabledForJs()) {
@@ -388,8 +393,10 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
@NotNull CompilerConfiguration configuration, @NotNull K2JSCompilerArguments arguments, @NotNull CompilerConfiguration configuration, @NotNull K2JSCompilerArguments arguments,
@NotNull Services services @NotNull Services services
) { ) {
if (arguments.getIrBackend()) { if (K2JSCompilerArgumentsKt.isIrBackendEnabled(arguments)) {
getIrCompiler().setupPlatformSpecificArgumentsAndServices(configuration, arguments, services); getIrCompiler().setupPlatformSpecificArgumentsAndServices(configuration, arguments, services);
}
if (K2JSCompilerArgumentsKt.isPreIrBackendDisabled(arguments)) {
return; return;
} }
@@ -9,7 +9,8 @@ import com.intellij.openapi.Disposable
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.cli.common.* import org.jetbrains.kotlin.cli.common.*
import org.jetbrains.kotlin.cli.common.ExitCode.* import org.jetbrains.kotlin.cli.common.ExitCode.COMPILATION_ERROR
import org.jetbrains.kotlin.cli.common.ExitCode.OK
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
@@ -175,17 +176,12 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
it.libraryFile.absolutePath in friendAbsolutePaths it.libraryFile.absolutePath in friendAbsolutePaths
} }
val produceKind = produceMap[arguments.irProduceOnly] if (arguments.irProduceKlibDir || arguments.irProduceKlibFile) {
if (produceKind == null) {
messageCollector.report(ERROR, "Unknown produce kind: ${arguments.irProduceOnly}. Valid values are: js, klib")
}
if (produceKind == ProduceKind.KLIB || (produceKind == ProduceKind.DEFAULT && arguments.metaInfo)) {
val outputKlibPath = val outputKlibPath =
if (arguments.irLegacyGradlePluginCompatibility) if (arguments.irProduceKlibDir)
File(outputFilePath).parent File(outputFilePath).parent
else else
"$outputFilePath.klib" outputFilePath
generateKLib( generateKLib(
project = config.project, project = config.project,
@@ -194,11 +190,11 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
allDependencies = resolvedLibraries, allDependencies = resolvedLibraries,
friendDependencies = friendDependencies, friendDependencies = friendDependencies,
outputKlibPath = outputKlibPath, outputKlibPath = outputKlibPath,
nopack = arguments.irLegacyGradlePluginCompatibility nopack = arguments.irProduceKlibDir
) )
} }
if (produceKind == ProduceKind.JS || produceKind == ProduceKind.DEFAULT) { if (arguments.irProduceJs) {
val phaseConfig = createPhaseConfig(jsPhases, arguments, messageCollector) val phaseConfig = createPhaseConfig(jsPhases, arguments, messageCollector)
val compiledModule = compile( val compiledModule = compile(
@@ -10,10 +10,8 @@ abstract class AbstractIncrementalJsKlibCompilerRunnerTest : AbstractIncremental
libraries = "build/js-ir-runtime/full-runtime.klib" libraries = "build/js-ir-runtime/full-runtime.klib"
outputFile = File(destinationDir, "${testDir.name}.klib").path outputFile = File(destinationDir, "${testDir.name}.klib").path
sourceMap = true sourceMap = true
irBackend = true
irProduceOnly = "klib"
// Don't zip klib content since date on files affect the md5 checksum we compute to check whether output files identical // Don't zip klib content since date on files affect the md5 checksum we compute to check whether output files identical
irLegacyGradlePluginCompatibility = true irProduceKlibDir = true
} }
override val buildLogFinder: BuildLogFinder override val buildLogFinder: BuildLogFinder
+5 -4
View File
@@ -3,10 +3,11 @@ where advanced options include:
-Xenable-js-scripting Enable experimental support of .kts files using K/JS (with -Xir only) -Xenable-js-scripting Enable experimental support of .kts files using K/JS (with -Xir only)
-Xfriend-modules=<path> Paths to friend modules -Xfriend-modules=<path> Paths to friend modules
-Xfriend-modules-disabled Disable internal declaration export -Xfriend-modules-disabled Disable internal declaration export
-Xir Use IR backend -Xir-only Disables pre-IR backend
-Xir-legacy-gradle-plugin-compatibility -Xir-produce-js Generates JS file using IR backend. Also disables pre-IR backend
Make KLIB generation compatible with legacy gradle plugin -Xir-produce-klib-dir Generate unpacked KLIB into parent directory of output JS file.
-Xir-produce-only={ klib, js } Type of output to produce. Overrides -meta-info argument. In combination with -meta-info generates both IR and pre-IR versions of library.
-Xir-produce-klib-file Generate packed klib into file specified by -output. Disables pre-IR backend
-Xmetadata-only Generate *.meta.js and *.kjsm files only -Xmetadata-only Generate *.meta.js and *.kjsm files only
-Xtyped-arrays Translate primitive arrays to JS typed arrays -Xtyped-arrays Translate primitive arrays to JS typed arrays
-Xallow-kotlin-package Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info -Xallow-kotlin-package Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info
-70
View File
@@ -1,70 +0,0 @@
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')
}
def jsCommonDir = "${buildDir}/common-js-sources"
task prepareCommonJsSources(type: Sync) {
from "${projectDir}/../js/src/"
into jsCommonDir
}
compileKotlin2Js {
dependsOn prepareCommonJsSources
kotlinOptions {
moduleKind = "umd"
freeCompilerArgs = [
"-Xir",
"-Xir-produce-only=klib",
"-Xallow-kotlin-package",
"-Xuse-experimental=kotlin.contracts.ExperimentalContracts",
]
}
}
sourceSets {
main {
kotlin {
srcDir jsCommonDir
}
}
}
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)
}
+5 -1
View File
@@ -16,7 +16,11 @@ dependencies {
} }
compileKotlin2Js { compileKotlin2Js {
kotlinOptions.freeCompilerArgs = ["-Xallow-kotlin-package", "-Xuse-experimental=kotlin.contracts.ExperimentalContracts"] kotlinOptions.freeCompilerArgs = [
"-Xallow-kotlin-package",
"-Xuse-experimental=kotlin.contracts.ExperimentalContracts",
"-Xir-produce-klib-dir"
]
kotlinOptions { kotlinOptions {
moduleKind = "umd" moduleKind = "umd"
outputFile = "${buildDir}/classes/main/kotlin-test.js" outputFile = "${buildDir}/classes/main/kotlin-test.js"
+6 -12
View File
@@ -92,7 +92,7 @@ configurations {
dependencies { dependencies {
expectedBy project(":kotlin-stdlib-common") expectedBy project(":kotlin-stdlib-common")
commonSources project(path: ":kotlin-stdlib-common", configuration: "sources") commonSources project(path: ":kotlin-stdlib-common", configuration: "sources")
testCompile project(':kotlin-test:kotlin-test-js-ir') testCompile project(':kotlin-test:kotlin-test-js')
} }
@@ -107,8 +107,8 @@ compileKotlin2Js {
main = "noCall" main = "noCall"
verbose = true verbose = true
freeCompilerArgs += [ freeCompilerArgs += [
"-Xir", "-Xir-produce-klib-dir",
"-Xir-produce-only=klib", "-Xir-only",
"-Xallow-kotlin-package", "-Xallow-kotlin-package",
"-Xallow-result-return-type", "-Xallow-result-return-type",
"-Xuse-experimental=kotlin.Experimental", "-Xuse-experimental=kotlin.Experimental",
@@ -120,7 +120,7 @@ compileKotlin2Js {
} }
def testOutputFile = "${buildDir}/classes/kotlin/test/kotlin-stdlib-js-ir_test.js" 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" def kotlinTestTestOutputFile = "${project(':kotlin-test:kotlin-test-js').buildDir}/classes/kotlin/test/kotlin-test-js-ir_test.js"
compileTestKotlin2Js { compileTestKotlin2Js {
kotlinOptions { kotlinOptions {
@@ -128,8 +128,7 @@ compileTestKotlin2Js {
verbose = true verbose = true
outputFile = testOutputFile outputFile = testOutputFile
freeCompilerArgs += [ freeCompilerArgs += [
"-Xir", "-Xir-produce-js",
"-Xir-produce-only=js",
"-verbose", "-verbose",
"-Xuse-experimental=kotlin.Experimental", "-Xuse-experimental=kotlin.Experimental",
"-Xuse-experimental=kotlin.ExperimentalUnsignedTypes", "-Xuse-experimental=kotlin.ExperimentalUnsignedTypes",
@@ -155,11 +154,6 @@ artifacts {
archives sourcesJar archives sourcesJar
} }
if (project.findProperty("kotlin.stdlib.js.ir.publish")?.toBoolean() == true) {
configurePublishing(project)
}
node { node {
download = true download = true
version = '8.9.4' // The default 6.9.1 has buggy hyperbolic functions implementation version = '8.9.4' // The default 6.9.1 has buggy hyperbolic functions implementation
@@ -177,7 +171,7 @@ task installTeamcityReporter(type: NpmTask) {
task runMocha(type: NodeTask) { task runMocha(type: NodeTask) {
dependsOn compileTestKotlin2Js dependsOn compileTestKotlin2Js
dependsOn installMocha dependsOn installMocha
dependsOn ':kotlin-test:kotlin-test-js-ir:testClasses' dependsOn ':kotlin-test:kotlin-test-js:testClasses'
script = file("${buildDir}/node_modules/mocha/bin/mocha") script = file("${buildDir}/node_modules/mocha/bin/mocha")
+22 -3
View File
@@ -14,6 +14,7 @@ configurations {
commonSources commonSources
distSources distSources
distJs distJs
distLibrary
} }
def builtinsSrcDir = "${buildDir}/builtin-sources" def builtinsSrcDir = "${buildDir}/builtin-sources"
@@ -283,9 +284,10 @@ jar {
enabled false enabled false
} }
task mergedJar(type: Jar, dependsOn: compileJs) { task libraryJarWithoutIr(type: Jar, dependsOn: compileJs) {
classifier = null classifier = null
manifestAttributes(manifest, project, 'Main') manifestAttributes(manifest, project, 'Main')
destinationDirectory = file("$buildDir/lib/dist")
// TODO: Use standard implementation title after js stdlib detector becomes more flexible (KT-17655) // TODO: Use standard implementation title after js stdlib detector becomes more flexible (KT-17655)
Properties properties = new Properties() Properties properties = new Properties()
@@ -307,6 +309,22 @@ task mergedJar(type: Jar, dependsOn: compileJs) {
exclude "${experimentalJsModuleName}.*" exclude "${experimentalJsModuleName}.*"
} }
task libraryJarWithIr(type: Zip, dependsOn: libraryJarWithoutIr) {
def irStdlibJar = tasks.getByPath(":kotlin-stdlib-js-ir:jar")
dependsOn(irStdlibJar)
archiveExtension = "jar"
destinationDirectory = file("$buildDir/libs")
duplicatesStrategy DuplicatesStrategy.FAIL
from zipTree(libraryJarWithoutIr.archiveFile)
from(zipTree(irStdlibJar.archiveFile)) {
exclude 'META-INF/*'
}
}
task sourcesJar(type: Jar, dependsOn: compileJs) { task sourcesJar(type: Jar, dependsOn: compileJs) {
classifier = 'sources' classifier = 'sources'
includeEmptyDirs false includeEmptyDirs false
@@ -352,11 +370,12 @@ task distSourcesJar(type: Jar) {
artifacts { artifacts {
runtime mergedJar runtime libraryJarWithIr
archives mergedJar archives libraryJarWithIr
archives sourcesJar archives sourcesJar
sources sourcesJar sources sourcesJar
distSources distSourcesJar distSources distSourcesJar
distLibrary libraryJarWithoutIr
compileJs.outputs.files.forEach { artifact -> compileJs.outputs.files.forEach { artifact ->
distJs(artifact) { builtBy(compileJs) } distJs(artifact) { builtBy(compileJs) }
@@ -105,8 +105,10 @@ tasks.withType<Test> {
":kotlin-reflect:install", ":kotlin-reflect:install",
":kotlin-annotation-processing-gradle:install", ":kotlin-annotation-processing-gradle:install",
":kotlin-test:kotlin-test-jvm:install", ":kotlin-test:kotlin-test-jvm:install",
":kotlin-test:kotlin-test-js:install",
":kotlin-gradle-subplugin-example:install", ":kotlin-gradle-subplugin-example:install",
":kotlin-stdlib-jdk8:install", ":kotlin-stdlib-jdk8:install",
":kotlin-stdlib-js:install",
":examples:annotation-processor-example:install", ":examples:annotation-processor-example:install",
":kotlin-scripting-common:install", ":kotlin-scripting-common:install",
":kotlin-scripting-jvm:install", ":kotlin-scripting-jvm:install",
@@ -198,6 +198,7 @@ abstract class BaseGradleIT {
val daemonOptionSupported: Boolean = true, val daemonOptionSupported: Boolean = true,
val incremental: Boolean? = null, val incremental: Boolean? = null,
val incrementalJs: Boolean? = null, val incrementalJs: Boolean? = null,
val jsIrBackend: Boolean? = null,
val androidHome: File? = null, val androidHome: File? = null,
val javaHome: File? = null, val javaHome: File? = null,
val androidGradlePluginVersion: AGPVersion? = null, val androidGradlePluginVersion: AGPVersion? = null,
@@ -719,6 +720,7 @@ Finished executing task ':$taskName'|
add("-Pkotlin.incremental=$it") add("-Pkotlin.incremental=$it")
} }
options.incrementalJs?.let { add("-Pkotlin.incremental.js=$it") } options.incrementalJs?.let { add("-Pkotlin.incremental.js=$it") }
options.jsIrBackend?.let { add("-Pkotlin.js.useIrBackend=$it") }
options.usePreciseJavaTracking?.let { add("-Pkotlin.incremental.usePreciseJavaTracking=$it") } options.usePreciseJavaTracking?.let { add("-Pkotlin.incremental.usePreciseJavaTracking=$it") }
options.androidGradlePluginVersion?.let { add("-Pandroid_tools_version=$it") } options.androidGradlePluginVersion?.let { add("-Pandroid_tools_version=$it") }
if (options.debug) { if (options.debug) {
@@ -2,169 +2,20 @@ package org.jetbrains.kotlin.gradle
import org.gradle.api.logging.LogLevel import org.gradle.api.logging.LogLevel
import org.jetbrains.kotlin.gradle.tasks.USING_JS_INCREMENTAL_COMPILATION_MESSAGE import org.jetbrains.kotlin.gradle.tasks.USING_JS_INCREMENTAL_COMPILATION_MESSAGE
import org.jetbrains.kotlin.gradle.tasks.USING_JS_IR_BACKEND_MESSAGE
import org.jetbrains.kotlin.gradle.util.getFileByName import org.jetbrains.kotlin.gradle.util.getFileByName
import org.jetbrains.kotlin.gradle.util.getFilesByNames import org.jetbrains.kotlin.gradle.util.getFilesByNames
import org.jetbrains.kotlin.gradle.util.modify import org.jetbrains.kotlin.gradle.util.modify
import org.junit.Assume.assumeFalse
import org.junit.Test import org.junit.Test
import java.io.File import java.io.File
import java.util.zip.ZipFile import java.util.zip.ZipFile
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
class Kotlin2JsGradlePluginIT : BaseGradleIT() { class Kotlin2JsIrGradlePluginIT : AbstractKotlin2JsGradlePluginIT(true)
@Test
fun testBuildAndClean() {
val project = Project("kotlin2JsProject")
project.build("build") {
assertSuccessful()
assertReportExists()
assertTasksExecuted(
":libraryProject:jarSources",
":mainProject:compileKotlin2Js",
":libraryProject:compileKotlin2Js"
)
listOf(
"mainProject/web/js/app.js",
"mainProject/web/js/lib/kotlin.js",
"libraryProject/build/kotlin2js/main/test-library.js",
"mainProject/web/js/app.js.map"
).forEach { assertFileExists(it) }
}
project.build("build") {
assertSuccessful()
assertTasksUpToDate(":mainProject:compileKotlin2Js")
assertContainsRegex(":libraryProject:compileTestKotlin2Js (UP-TO-DATE|NO-SOURCE)".toRegex())
}
project.build("clean") {
assertSuccessful()
assertReportExists()
// Test that we don't accidentally remove the containing directory
// This would fail if we used the default clean task of the copy task
assertFileExists("mainProject/web/js/lib")
assertNoSuchFile("main/project/web/js/app.js.map")
assertNoSuchFile("main/project/web/js/example/main.kt")
}
project.build("clean") {
assertSuccessful()
assertReportExists()
}
}
@Test
fun testJarIncludesJsDefaultOutput() {
val project = Project("kotlin2JsNoOutputFileProject")
project.build("jar") {
assertSuccessful()
assertTasksExecuted(":compileKotlin2Js")
val jarPath = "build/libs/kotlin2JsNoOutputFileProject.jar"
assertFileExists(jarPath)
val jar = ZipFile(fileInWorkingDir(jarPath))
assertEquals(
1, jar.entries().asSequence().count { it.name == "kotlin2JsNoOutputFileProject.js" },
"The jar should contain an entry `kotlin2JsNoOutputFileProject.js` with no duplicates"
)
}
}
@Test
fun testJarIncludesJsOutputSetExplicitly() {
val project = Project("kotlin2JsModuleKind")
project.build(":jar") {
assertSuccessful()
assertTasksExecuted(":compileKotlin2Js")
val jarPath = "build/libs/kotlin2JsModuleKind.jar"
assertFileExists(jarPath)
val jar = ZipFile(fileInWorkingDir(jarPath))
assertEquals(
1, jar.entries().asSequence().count { it.name == "app.js" },
"The jar should contain an entry `app.js` with no duplicates"
)
}
}
@Test
fun testModuleKind() {
val project = Project("kotlin2JsModuleKind")
project.build("runRhino") {
assertSuccessful()
}
}
@Test
fun testDefaultOutputFile() {
val project = Project("kotlin2JsNoOutputFileProject")
project.build("build") {
assertSuccessful()
assertFileExists(kotlinClassesDir() + "kotlin2JsNoOutputFileProject.js")
assertFileExists(kotlinClassesDir(sourceSet = "test") + "kotlin2JsNoOutputFileProject_test.js")
}
}
@Test
fun testCompileTestCouldAccessProduction() {
val project = Project("kotlin2JsProjectWithTests")
project.build("build") {
assertSuccessful()
assertTasksExecuted(
":compileKotlin2Js",
":compileTestKotlin2Js"
)
assertFileExists("build/kotlin2js/main/module.js")
assertFileExists("build/kotlin2js/test/module-tests.js")
}
}
@Test
fun testCompilerTestAccessInternalProduction() {
val project = Project("kotlin2JsInternalTest")
project.build("runRhino") {
assertSuccessful()
}
}
@Test
fun testJsCustomSourceSet() {
val project = Project("kotlin2JsProjectWithCustomSourceset")
project.build("build") {
assertSuccessful()
assertTasksExecuted(
":compileKotlin2Js",
":compileIntegrationTestKotlin2Js"
)
assertFileExists("build/kotlin2js/main/module.js")
assertFileExists("build/kotlin2js/integrationTest/module-inttests.js")
val jarPath = "build/libs/kotlin2JsProjectWithCustomSourceset-inttests.jar"
assertFileExists(jarPath)
val jar = ZipFile(fileInWorkingDir(jarPath))
assertEquals(
1, jar.entries().asSequence().count { it.name == "module-inttests.js" },
"The jar should contain an entry `module-inttests.js` with no duplicates"
)
}
}
class Kotlin2JsGradlePluginIT : AbstractKotlin2JsGradlePluginIT(false) {
@Test @Test
fun testKotlinJsBuiltins() { fun testKotlinJsBuiltins() {
val project = Project("kotlinBuiltins") val project = Project("kotlinBuiltins")
@@ -180,49 +31,6 @@ class Kotlin2JsGradlePluginIT : BaseGradleIT() {
} }
} }
@Test
fun testKotlinJsSourceMap() {
val project = Project("kotlin2JsNoOutputFileProject")
project.setupWorkingDir()
project.projectDir.getFileByName("build.gradle").modify {
it + "\n" +
"compileKotlin2Js.kotlinOptions.sourceMap = true\n" +
"compileKotlin2Js.kotlinOptions.sourceMapPrefix = \"prefixprefix/\"\n" +
"compileKotlin2Js.kotlinOptions.outputFile = \"\${buildDir}/kotlin2js/main/app.js\"\n"
}
project.build("build") {
assertSuccessful()
val mapFilePath = "build/kotlin2js/main/app.js.map"
assertFileExists(mapFilePath)
val map = fileInWorkingDir(mapFilePath).readText()
val sourceFilePath = "prefixprefix/src/main/kotlin/example/Dummy.kt"
assertTrue("Source map should contain reference to $sourceFilePath") { map.contains("\"$sourceFilePath\"") }
}
}
@Test
fun testKotlinJsSourceMapInline() {
val project = Project("kotlin2JsProjectWithSourceMapInline")
project.build("build") {
assertSuccessful()
val mapFilePath = kotlinClassesDir(subproject = "app") + "app.js.map"
assertFileExists(mapFilePath)
val map = fileInWorkingDir(mapFilePath).readText()
assertTrue("Source map should contain reference to main.kt") { map.contains("\"./src/main/kotlin/main.kt\"") }
assertTrue("Source map should contain reference to foo.kt") { map.contains("\"./src/main/kotlin/foo.kt\"") }
assertTrue("Source map should contain source of main.kt") { map.contains("\"fun main(args: Array<String>) {") }
assertTrue("Source map should contain source of foo.kt") { map.contains("\"inline fun foo(): String {") }
}
}
@Test @Test
fun testDce() { fun testDce() {
val project = Project("kotlin2JsDceProject", minLogLevel = LogLevel.INFO) val project = Project("kotlin2JsDceProject", minLogLevel = LogLevel.INFO)
@@ -305,6 +113,239 @@ class Kotlin2JsGradlePluginIT : BaseGradleIT() {
assertTrue(fileInWorkingDir("$pathPrefix/kotlin.js").length() < 500 * 1000, "Looks like kotlin.js file was not minified by DCE") assertTrue(fileInWorkingDir("$pathPrefix/kotlin.js").length() < 500 * 1000, "Looks like kotlin.js file was not minified by DCE")
} }
} }
}
abstract class AbstractKotlin2JsGradlePluginIT(private val irBackend: Boolean) : BaseGradleIT() {
override fun defaultBuildOptions(): BuildOptions =
super.defaultBuildOptions().copy(jsIrBackend = irBackend)
private fun CompiledProject.checkIrCompilationMessage() {
if (irBackend) {
assertContains(USING_JS_IR_BACKEND_MESSAGE)
} else {
assertNotContains(USING_JS_IR_BACKEND_MESSAGE)
}
}
@Test
fun testBuildAndClean() {
val project = Project("kotlin2JsProject")
project.build("build") {
assertSuccessful()
assertReportExists()
checkIrCompilationMessage()
assertTasksExecuted(
":libraryProject:jarSources",
":mainProject:compileKotlin2Js",
":libraryProject:compileKotlin2Js"
)
assertFileExists("mainProject/web/js/app.js")
if (!irBackend) {
assertFileExists("mainProject/web/js/lib/kotlin.js")
assertFileExists("libraryProject/build/kotlin2js/main/test-library.js")
assertFileExists("mainProject/web/js/app.js.map")
}
}
project.build("build") {
assertSuccessful()
assertTasksUpToDate(":mainProject:compileKotlin2Js")
assertContainsRegex(":libraryProject:compileTestKotlin2Js (UP-TO-DATE|NO-SOURCE)".toRegex())
}
project.build("clean") {
assertSuccessful()
assertReportExists()
// Test that we don't accidentally remove the containing directory
// This would fail if we used the default clean task of the copy task
assertFileExists("mainProject/web/js/lib")
assertNoSuchFile("main/project/web/js/app.js.map")
assertNoSuchFile("main/project/web/js/example/main.kt")
}
project.build("clean") {
assertSuccessful()
assertReportExists()
}
}
@Test
fun testJarIncludesJsDefaultOutput() {
val project = Project("kotlin2JsNoOutputFileProject")
project.build("jar") {
assertSuccessful()
checkIrCompilationMessage()
assertTasksExecuted(":compileKotlin2Js")
val jarPath = "build/libs/kotlin2JsNoOutputFileProject.jar"
assertFileExists(jarPath)
val jar = ZipFile(fileInWorkingDir(jarPath))
assertEquals(
1, jar.entries().asSequence().count { it.name == "kotlin2JsNoOutputFileProject.js" },
"The jar should contain an entry `kotlin2JsNoOutputFileProject.js` with no duplicates"
)
}
}
@Test
fun testJarIncludesJsOutputSetExplicitly() {
val project = Project("kotlin2JsModuleKind")
project.build(":jar") {
assertSuccessful()
checkIrCompilationMessage()
assertTasksExecuted(":compileKotlin2Js")
val jarPath = "build/libs/kotlin2JsModuleKind.jar"
assertFileExists(jarPath)
val jar = ZipFile(fileInWorkingDir(jarPath))
assertEquals(
1, jar.entries().asSequence().count { it.name == "app.js" },
"The jar should contain an entry `app.js` with no duplicates"
)
}
}
@Test
fun testModuleKind() {
val project = Project("kotlin2JsModuleKind")
project.build("runRhino") {
assertSuccessful()
checkIrCompilationMessage()
}
}
@Test
fun testDefaultOutputFile() {
val project = Project("kotlin2JsNoOutputFileProject")
project.build("build") {
assertSuccessful()
checkIrCompilationMessage()
if (irBackend) {
assertFileExists(kotlinClassesDir() + "manifest")
} else {
assertFileExists(kotlinClassesDir() + "kotlin2JsNoOutputFileProject.js")
}
assertFileExists(kotlinClassesDir(sourceSet = "test") + "kotlin2JsNoOutputFileProject_test.js")
}
}
@Test
fun testCompileTestCouldAccessProduction() {
val project = Project("kotlin2JsProjectWithTests")
project.build("build") {
assertSuccessful()
checkIrCompilationMessage()
assertTasksExecuted(
":compileKotlin2Js",
":compileTestKotlin2Js"
)
if (irBackend) {
assertFileExists("build/kotlin2js/main/manifest")
} else {
assertFileExists("build/kotlin2js/main/module.js")
}
assertFileExists("build/kotlin2js/test/module-tests.js")
}
}
@Test
fun testCompilerTestAccessInternalProduction() {
val project = Project("kotlin2JsInternalTest")
project.build("runRhino") {
assertSuccessful()
checkIrCompilationMessage()
}
}
@Test
fun testJsCustomSourceSet() {
val project = Project("kotlin2JsProjectWithCustomSourceset")
project.build("build") {
assertSuccessful()
checkIrCompilationMessage()
assertTasksExecuted(
":compileKotlin2Js",
":compileIntegrationTestKotlin2Js"
)
if (!irBackend) {
assertFileExists("build/kotlin2js/main/module.js")
}
assertFileExists("build/kotlin2js/integrationTest/module-inttests.js")
val jarPath = "build/libs/kotlin2JsProjectWithCustomSourceset-inttests.jar"
assertFileExists(jarPath)
val jar = ZipFile(fileInWorkingDir(jarPath))
assertEquals(
1, jar.entries().asSequence().count { it.name == "module-inttests.js" },
"The jar should contain an entry `module-inttests.js` with no duplicates"
)
}
}
@Test
fun testKotlinJsSourceMap() {
// TODO: Support source maps
assumeFalse(irBackend)
val project = Project("kotlin2JsNoOutputFileProject")
project.setupWorkingDir()
project.projectDir.getFileByName("build.gradle").modify {
it + "\n" +
"compileKotlin2Js.kotlinOptions.sourceMap = true\n" +
"compileKotlin2Js.kotlinOptions.sourceMapPrefix = \"prefixprefix/\"\n" +
"compileKotlin2Js.kotlinOptions.outputFile = \"\${buildDir}/kotlin2js/main/app.js\"\n"
}
project.build("build") {
assertSuccessful()
val mapFilePath = "build/kotlin2js/main/app.js.map"
assertFileExists(mapFilePath)
val map = fileInWorkingDir(mapFilePath).readText()
val sourceFilePath = "prefixprefix/src/main/kotlin/example/Dummy.kt"
assertTrue("Source map should contain reference to $sourceFilePath") { map.contains("\"$sourceFilePath\"") }
}
}
@Test
fun testKotlinJsSourceMapInline() {
// TODO: Support source maps
assumeFalse(irBackend)
val project = Project("kotlin2JsProjectWithSourceMapInline")
project.build("build") {
assertSuccessful()
val mapFilePath = kotlinClassesDir(subproject = "app") + "app.js.map"
assertFileExists(mapFilePath)
val map = fileInWorkingDir(mapFilePath).readText()
assertTrue("Source map should contain reference to main.kt") { map.contains("\"./src/main/kotlin/main.kt\"") }
assertTrue("Source map should contain reference to foo.kt") { map.contains("\"./src/main/kotlin/foo.kt\"") }
assertTrue("Source map should contain source of main.kt") { map.contains("\"fun main(args: Array<String>) {") }
assertTrue("Source map should contain source of foo.kt") { map.contains("\"inline fun foo(): String {") }
}
}
/** Issue: KT-18495 */ /** Issue: KT-18495 */
@Test @Test
@@ -312,6 +353,7 @@ class Kotlin2JsGradlePluginIT : BaseGradleIT() {
val project = Project("kotlin2JsProject") val project = Project("kotlin2JsProject")
project.build("build") { project.build("build") {
assertSuccessful() assertSuccessful()
checkIrCompilationMessage()
assertNotContains("this build assumes a single directory for all classes from a source set") assertNotContains("this build assumes a single directory for all classes from a source set")
} }
} }
@@ -320,8 +362,11 @@ class Kotlin2JsGradlePluginIT : BaseGradleIT() {
fun testIncrementalCompilation() = Project("kotlin2JsICProject").run { fun testIncrementalCompilation() = Project("kotlin2JsICProject").run {
build("build") { build("build") {
assertSuccessful() assertSuccessful()
assertContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE) checkIrCompilationMessage()
assertCompiledKotlinSources(project.relativize(allKotlinFiles)) if (!irBackend) { // TODO: Support incremental compilation
assertContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE)
assertCompiledKotlinSources(project.relativize(allKotlinFiles))
}
} }
build("build") { build("build") {
@@ -334,9 +379,13 @@ class Kotlin2JsGradlePluginIT : BaseGradleIT() {
} }
build("build") { build("build") {
assertSuccessful() assertSuccessful()
assertContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE) checkIrCompilationMessage()
val affectedFiles = project.projectDir.getFilesByNames("A.kt", "useAInLibMain.kt", "useAInAppMain.kt", "useAInAppTest.kt") // TODO: Support incremental compilation in IR backend
assertCompiledKotlinSources(project.relativize(affectedFiles)) if (!irBackend) {
assertContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE)
val affectedFiles = project.projectDir.getFilesByNames("A.kt", "useAInLibMain.kt", "useAInAppMain.kt", "useAInAppTest.kt")
assertCompiledKotlinSources(project.relativize(affectedFiles))
}
} }
} }
@@ -346,12 +395,14 @@ class Kotlin2JsGradlePluginIT : BaseGradleIT() {
build("build", options = options) { build("build", options = options) {
assertSuccessful() assertSuccessful()
checkIrCompilationMessage()
assertNotContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE) assertNotContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE)
} }
} }
@Test @Test
fun testNewKotlinJsPlugin() = with(Project("kotlin-js-plugin-project", GradleVersionRequired.AtLeast("4.10.2"))) { fun testNewKotlinJsPlugin() = with(Project("kotlin-js-plugin-project", GradleVersionRequired.AtLeast("4.10.2"))) {
assumeFalse(irBackend) // TODO: Support IR version of kotlinx.html
setupWorkingDir() setupWorkingDir()
gradleBuildScript().modify(::transformBuildScriptWithPluginsDsl) gradleBuildScript().modify(::transformBuildScriptWithPluginsDsl)
gradleSettingsScript().modify(::transformBuildScriptWithPluginsDsl) gradleSettingsScript().modify(::transformBuildScriptWithPluginsDsl)
@@ -4,3 +4,9 @@ dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
compile project(":lib") compile project(":lib")
} }
def isIrBackend = project.findProperty("kotlin.js.useIrBackend")?.toBoolean() ?: false
if (isIrBackend) {
compileKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-klib-dir", "-Xir-only"]
compileTestKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-js"]
}
@@ -3,3 +3,9 @@ apply plugin: 'kotlin2js'
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
} }
def isIrBackend = project.findProperty("kotlin.js.useIrBackend")?.toBoolean() ?: false
if (isIrBackend) {
compileKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-klib-dir", "-Xir-only"]
compileTestKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-js"]
}
@@ -22,11 +22,22 @@ dependencies {
def classesDir = "${buildDir}/classes/kotlin" def classesDir = "${buildDir}/classes/kotlin"
def isIrBackend = project.findProperty("kotlin.js.useIrBackend")?.toBoolean() ?: false
if (isIrBackend) {
compileKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-klib-dir", "-Xir-only"]
compileTestKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-js"]
}
task runRhino(type: JavaExec) { task runRhino(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath classpath = sourceSets.main.runtimeClasspath
workingDir = classesDir workingDir = classesDir
main = 'org.mozilla.javascript.tools.shell.Main' main = 'org.mozilla.javascript.tools.shell.Main'
args = ["-opt", "-1", "-f", "kotlin.js", "-f", "main/kotlin2JsInternalTest.js", "-f", "test/kotlin2JsInternalTest_test.js", "-f", "check.js"] if (isIrBackend) {
// IR backend produces a single JS file
args = ["-opt", "-1", "test/kotlin2JsInternalTest_test.js", "-f", "check.js"]
} else {
args = ["-opt", "-1", "-f", "kotlin.js", "-f", "main/kotlin2JsInternalTest.js", "-f", "test/kotlin2JsInternalTest_test.js", "-f", "check.js"]
}
} }
build.doLast { build.doLast {
@@ -22,6 +22,7 @@ fun <T> assertEquals(e: T, a: T) {
if (e != a) throw Exception("Expected: $e, actual: $a") if (e != a) throw Exception("Expected: $e, actual: $a")
} }
@JsExport
fun test() { fun test() {
assertEquals("CONST", CONST) assertEquals("CONST", CONST)
@@ -16,6 +16,10 @@ def outDir = "${buildDir}/kotlin2js/main/"
compileKotlin2Js.kotlinOptions.moduleKind = "amd" compileKotlin2Js.kotlinOptions.moduleKind = "amd"
compileKotlin2Js.kotlinOptions.outputFile = outDir + "app.js" compileKotlin2Js.kotlinOptions.outputFile = outDir + "app.js"
if (project.findProperty("kotlin.js.useIrBackend")?.toBoolean() == true) {
compileKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-js"]
}
repositories { repositories {
mavenLocal() mavenLocal()
mavenCentral() mavenCentral()
@@ -16,4 +16,5 @@
package foo package foo
@JsExport
fun bar() = "OK" fun bar() = "OK"
@@ -17,4 +17,9 @@ repositories {
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
}
if (project.findProperty("kotlin.js.useIrBackend")?.toBoolean() == true) {
compileKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-klib-dir", "-Xir-produce-js", "-Xir-only"]
compileTestKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-js"]
} }
@@ -31,12 +31,17 @@ def outDir = "${buildDir}/kotlin2js/main/"
compileKotlin2Js.kotlinOptions.outputFile = outDir + "test-library.js" compileKotlin2Js.kotlinOptions.outputFile = outDir + "test-library.js"
def isIrBackend = project.findProperty("kotlin.js.useIrBackend")?.toBoolean()
if (isIrBackend) {
compileKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-klib-dir"]
}
jar { jar {
from sourceSets.main.allSource from sourceSets.main.allSource
include "**/*.kt" include "**/*.kt"
from outDir from outDir
include "**/*.js" include (isIrBackend ? "**/*" : "**/*.js")
manifest { manifest {
attributes( attributes(
@@ -25,6 +25,10 @@ compileKotlin2Js.kotlinOptions.outputFile = "${projectDir}/web/js/app.js"
compileKotlin2Js.kotlinOptions.suppressWarnings = true compileKotlin2Js.kotlinOptions.suppressWarnings = true
compileKotlin2Js.kotlinOptions.verbose = true compileKotlin2Js.kotlinOptions.verbose = true
if (project.findProperty("kotlin.js.useIrBackend")?.toBoolean() == true) {
compileKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-js"]
}
build.doLast { build.doLast {
configurations.compile.each { File file -> configurations.compile.each { File file ->
copy { copy {
@@ -29,6 +29,12 @@ compileIntegrationTestKotlin2Js.dependsOn compileKotlin2Js
compileKotlin2Js.kotlinOptions.outputFile = "${buildDir}/kotlin2js/main/module.js" compileKotlin2Js.kotlinOptions.outputFile = "${buildDir}/kotlin2js/main/module.js"
compileIntegrationTestKotlin2Js.kotlinOptions.outputFile = "${buildDir}/kotlin2js/integrationTest/module-inttests.js" compileIntegrationTestKotlin2Js.kotlinOptions.outputFile = "${buildDir}/kotlin2js/integrationTest/module-inttests.js"
def isIrBackend = project.findProperty("kotlin.js.useIrBackend")?.toBoolean() ?: false
if (isIrBackend) {
compileKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-klib-dir", "-Xir-only"]
compileIntegrationTestKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-js"]
}
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
integrationTestCompile files(file(compileKotlin2Js.kotlinOptions.outputFile).parent) integrationTestCompile files(file(compileKotlin2Js.kotlinOptions.outputFile).parent)
@@ -30,3 +30,8 @@ artifacts {
compileKotlin2Js.kotlinOptions.outputFile = "${buildDir}/kotlin2js/main/module.js" compileKotlin2Js.kotlinOptions.outputFile = "${buildDir}/kotlin2js/main/module.js"
compileTestKotlin2Js.kotlinOptions.outputFile = "${buildDir}/kotlin2js/test/module-tests.js" compileTestKotlin2Js.kotlinOptions.outputFile = "${buildDir}/kotlin2js/test/module-tests.js"
if (project.findProperty("kotlin.js.useIrBackend")?.toBoolean() == true) {
compileKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-klib-dir", "-Xir-only"]
compileTestKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-js"]
}
@@ -29,8 +29,10 @@ import org.jetbrains.kotlin.gradle.internal.prepareCompilerArguments
import org.jetbrains.kotlin.gradle.internal.tasks.TaskWithLocalState import org.jetbrains.kotlin.gradle.internal.tasks.TaskWithLocalState
import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles
import org.jetbrains.kotlin.gradle.logging.* import org.jetbrains.kotlin.gradle.logging.*
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.COMPILER_CLASSPATH_CONFIGURATION_NAME import org.jetbrains.kotlin.gradle.plugin.COMPILER_CLASSPATH_CONFIGURATION_NAME
import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginWrapper
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformPluginBase
import org.jetbrains.kotlin.gradle.plugin.PLUGIN_CLASSPATH_CONFIGURATION_NAME
import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithTransitiveClosure import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithTransitiveClosure
import org.jetbrains.kotlin.gradle.plugin.mpp.ownModuleName import org.jetbrains.kotlin.gradle.plugin.mpp.ownModuleName
import org.jetbrains.kotlin.gradle.report.BuildReportMode import org.jetbrains.kotlin.gradle.report.BuildReportMode
@@ -49,6 +51,7 @@ import javax.inject.Inject
const val KOTLIN_BUILD_DIR_NAME = "kotlin" const val KOTLIN_BUILD_DIR_NAME = "kotlin"
const val USING_JVM_INCREMENTAL_COMPILATION_MESSAGE = "Using Kotlin/JVM incremental compilation" const val USING_JVM_INCREMENTAL_COMPILATION_MESSAGE = "Using Kotlin/JVM incremental compilation"
const val USING_JS_INCREMENTAL_COMPILATION_MESSAGE = "Using Kotlin/JS incremental compilation" const val USING_JS_INCREMENTAL_COMPILATION_MESSAGE = "Using Kotlin/JS incremental compilation"
const val USING_JS_IR_BACKEND_MESSAGE = "Using Kotlin/JS IR backend"
abstract class AbstractKotlinCompileTool<T : CommonToolArguments> abstract class AbstractKotlinCompileTool<T : CommonToolArguments>
: AbstractCompile(), : AbstractCompile(),
@@ -553,9 +556,34 @@ open class Kotlin2JsCompile : AbstractKotlinCompile<K2JSCompilerArguments>(), Ko
return friendPaths.filter { filter(File(it)) } return friendPaths.filter { filter(File(it)) }
} }
private fun isHybridKotlinJsLibrary(file: File): Boolean =
LibraryUtils.isKotlinJavascriptLibrary(file) && LibraryUtils.isKotlinJavascriptIrLibrary(file)
private fun KotlinJsOptions.isPreIrBackendDisabled(): Boolean =
listOf(
"-Xir-only",
"-Xir-produce-js",
"-Xir-produce-klib-file"
).any(freeCompilerArgs::contains)
private fun KotlinJsOptions.isIrBackendEnabled(): Boolean =
listOf(
"-Xir-produce-klib-dir",
"-Xir-produce-js",
"-Xir-produce-klib-file"
).any(freeCompilerArgs::contains)
// Kotlin/JS can operate in 3 modes:
// 1) purely pre-IR backend
// 2) purely IR backend
// 3) hybrid pre-IR and IR backend. Can only accept libraries with both JS and IR parts.
private val libraryFilter: (File) -> Boolean private val libraryFilter: (File) -> Boolean
get() = if ("-Xir" in kotlinOptions.freeCompilerArgs) { get() = if (kotlinOptions.isIrBackendEnabled()) {
LibraryUtils::isKotlinJavascriptIrLibrary if (kotlinOptions.isPreIrBackendDisabled()) {
LibraryUtils::isKotlinJavascriptIrLibrary
} else {
::isHybridKotlinJsLibrary
}
} else { } else {
LibraryUtils::isKotlinJavascriptLibrary LibraryUtils::isKotlinJavascriptLibrary
} }
@@ -566,10 +594,9 @@ open class Kotlin2JsCompile : AbstractKotlinCompile<K2JSCompilerArguments>(), Ko
logger.debug("Calling compiler") logger.debug("Calling compiler")
destinationDir.mkdirs() destinationDir.mkdirs()
if ("-Xir" in args.freeArgs) { if (kotlinOptions.isIrBackendEnabled()) {
logger.kotlinDebug("Using JS IR backend") logger.info(USING_JS_IR_BACKEND_MESSAGE)
incremental = false incremental = false
args.freeArgs += "-Xir-legacy-gradle-plugin-compatibility"
} }
val dependencies = compileClasspath val dependencies = compileClasspath
@@ -105,8 +105,9 @@ public class K2JSCompilerMojo extends KotlinCompileMojoBase<K2JSCompilerArgument
arguments.setMetaInfo(metaInfo); arguments.setMetaInfo(metaInfo);
arguments.setModuleKind(moduleKind); arguments.setModuleKind(moduleKind);
arguments.setMain(main); arguments.setMain(main);
arguments.setIrBackend(useIrBackend); arguments.setIrOnly(useIrBackend);
arguments.setIrLegacyGradlePluginCompatibility(true); arguments.setIrProduceJs(useIrBackend);
arguments.setIrProduceKlibDir(useIrBackend);
List<String> libraries; List<String> libraries;
try { try {
+1 -3
View File
@@ -91,7 +91,6 @@ val distLibraryProjects = listOfNotNull(
":kotlin-stdlib-js-ir".takeIf { kotlinBuildProperties.jsIrDist }, ":kotlin-stdlib-js-ir".takeIf { kotlinBuildProperties.jsIrDist },
":kotlin-source-sections-compiler-plugin", ":kotlin-source-sections-compiler-plugin",
":kotlin-test:kotlin-test-js", ":kotlin-test:kotlin-test-js",
":kotlin-test:kotlin-test-js-ir".takeIf { kotlinBuildProperties.jsIrDist },
":kotlin-test:kotlin-test-junit", ":kotlin-test:kotlin-test-junit",
":kotlin-test:kotlin-test-junit5", ":kotlin-test:kotlin-test-junit5",
":kotlin-test:kotlin-test-jvm", ":kotlin-test:kotlin-test-jvm",
@@ -114,7 +113,6 @@ val distSourcesProjects = listOfNotNull(
":kotlin-script-runtime", ":kotlin-script-runtime",
":kotlin-stdlib-js-ir".takeIf { kotlinBuildProperties.jsIrDist }, ":kotlin-stdlib-js-ir".takeIf { kotlinBuildProperties.jsIrDist },
":kotlin-test:kotlin-test-js", ":kotlin-test:kotlin-test-js",
":kotlin-test:kotlin-test-js-ir".takeIf { kotlinBuildProperties.jsIrDist },
":kotlin-test:kotlin-test-junit", ":kotlin-test:kotlin-test-junit",
":kotlin-test:kotlin-test-junit5", ":kotlin-test:kotlin-test-junit5",
":kotlin-test:kotlin-test-jvm", ":kotlin-test:kotlin-test-jvm",
@@ -149,7 +147,7 @@ dependencies {
libraries(intellijDep()) { includeIntellijCoreJarDependencies(project) { it.startsWith("trove4j") } } libraries(intellijDep()) { includeIntellijCoreJarDependencies(project) { it.startsWith("trove4j") } }
libraries(commonDep("io.ktor", "ktor-network")) libraries(commonDep("io.ktor", "ktor-network"))
libraries(kotlinStdlib("jdk8")) libraries(kotlinStdlib("jdk8"))
libraries(kotlinStdlib("js")) libraries(kotlinStdlib("js", "distLibrary"))
distLibraryProjects.forEach { distLibraryProjects.forEach {
libraries(project(it)) { isTransitive = false } libraries(project(it)) { isTransitive = false }
-2
View File
@@ -274,7 +274,6 @@ if (flags.inJpsBuildIdeaSync) {
":kotlin-stdlib-common", ":kotlin-stdlib-common",
":kotlin-stdlib", ":kotlin-stdlib",
":kotlin-stdlib-js", ":kotlin-stdlib-js",
":kotlin-test:kotlin-test-js-ir",
":kotlin-stdlib-js-ir", ":kotlin-stdlib-js-ir",
":kotlin-stdlib-jdk7", ":kotlin-stdlib-jdk7",
":kotlin-stdlib-jdk8", ":kotlin-stdlib-jdk8",
@@ -289,7 +288,6 @@ if (flags.inJpsBuildIdeaSync) {
project(':kotlin-stdlib').projectDir = "$rootDir/libraries/stdlib/jvm" 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').projectDir = "$rootDir/libraries/stdlib/js-v1" as File
project(':kotlin-stdlib-js-ir').projectDir = "$rootDir/libraries/stdlib/js-ir" as File project(':kotlin-stdlib-js-ir').projectDir = "$rootDir/libraries/stdlib/js-ir" as File
project(':kotlin-test:kotlin-test-js-ir').projectDir = "$rootDir/libraries/kotlin.test/js-ir" as File
project(':kotlin-stdlib-jdk7').projectDir = "$rootDir/libraries/stdlib/jdk7" 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-jdk8').projectDir = "$rootDir/libraries/stdlib/jdk8" as File
project(':kotlin-stdlib:samples').projectDir = "$rootDir/libraries/stdlib/samples" as File project(':kotlin-stdlib:samples').projectDir = "$rootDir/libraries/stdlib/samples" as File