[Gradle, JS] Move incremental test into non-ir js tests and add module name into 2js plugin

[Gradle, JS] Fix tests for incremental compilation of IR klib dir

[Gradle, JS] Add hack of outputFile into kotlin2js plugin

[Gradle, JS] Remove producing klib-dir

[Gradle, JS] Try to fix outputFileOrNull in JS compile

Because on clean run, file is not yet created, isFile check is incorrect
This commit is contained in:
Ilya Goncharov
2021-01-27 13:29:05 +03:00
parent 7e6abffb62
commit c13949d322
4 changed files with 86 additions and 64 deletions
@@ -127,6 +127,47 @@ class Kotlin2JsGradlePluginIT : AbstractKotlin2JsGradlePluginIT(false) {
return super.defaultBuildOptions().copy(warningMode = WarningMode.Summary)
}
@Test
fun testIncrementalCompilation() = Project("kotlin2JsICProject").run {
setupWorkingDir()
val modules = listOf("app", "lib")
val mainFiles = modules.flatMapTo(LinkedHashSet()) {
projectDir.resolve("$it/src/main").allKotlinFiles()
}
build("build") {
assertSuccessful()
checkIrCompilationMessage()
assertContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE)
if (irBackend) {
assertCompiledKotlinSources(project.relativize(mainFiles))
} else {
assertCompiledKotlinSources(project.relativize(allKotlinFiles))
}
}
build("build") {
assertSuccessful()
assertCompiledKotlinSources(emptyList())
}
projectFile("A.kt").modify {
it.replace("val x = 0", "val x = \"a\"")
}
build("build") {
assertSuccessful()
checkIrCompilationMessage()
assertContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE)
val affectedFiles = project.projectDir.getFilesByNames("A.kt", "useAInLibMain.kt", "useAInAppMain.kt", "useAInAppTest.kt")
if (irBackend) {
// only klib ic is supported for now, so tests are generated non-incrementally with ir backend
assertCompiledKotlinSources(project.relativize(affectedFiles.filter { it in mainFiles }))
} else {
assertCompiledKotlinSources(project.relativize(affectedFiles))
}
}
}
@Test
fun testKotlinJsBuiltins() {
val project = Project("kotlinBuiltins")
@@ -257,7 +298,7 @@ class Kotlin2JsGradlePluginIT : AbstractKotlin2JsGradlePluginIT(false) {
}
}
abstract class AbstractKotlin2JsGradlePluginIT(private val irBackend: Boolean) : BaseGradleIT() {
abstract class AbstractKotlin2JsGradlePluginIT(val irBackend: Boolean) : BaseGradleIT() {
override fun defaultBuildOptions(): BuildOptions =
super.defaultBuildOptions().copy(
jsIrBackend = irBackend,
@@ -284,10 +325,12 @@ abstract class AbstractKotlin2JsGradlePluginIT(private val irBackend: Boolean) :
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"
)
if (!irBackend) {
assertEquals(
1, jar.entries().asSequence().count { it.name == "kotlin2JsNoOutputFileProject.js" },
"The jar should contain an entry `kotlin2JsNoOutputFileProject.js` with no duplicates"
)
}
}
}
@@ -327,9 +370,7 @@ abstract class AbstractKotlin2JsGradlePluginIT(private val irBackend: Boolean) :
project.build("build") {
assertSuccessful()
checkIrCompilationMessage()
if (irBackend) {
assertFileExists(kotlinClassesDir() + "default/manifest")
} else {
if (!irBackend) {
assertFileExists(kotlinClassesDir() + "kotlin2JsNoOutputFileProject.js")
}
assertFileExists(kotlinClassesDir(sourceSet = "test") + "kotlin2JsNoOutputFileProject_test.js")
@@ -445,47 +486,6 @@ abstract class AbstractKotlin2JsGradlePluginIT(private val irBackend: Boolean) :
}
}
@Test
fun testIncrementalCompilation() = Project("kotlin2JsICProject").run {
setupWorkingDir()
val modules = listOf("app", "lib")
val mainFiles = modules.flatMapTo(LinkedHashSet()) {
projectDir.resolve("$it/src/main").allKotlinFiles()
}
build("build") {
assertSuccessful()
checkIrCompilationMessage()
assertContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE)
if (irBackend) {
assertCompiledKotlinSources(project.relativize(mainFiles))
} else {
assertCompiledKotlinSources(project.relativize(allKotlinFiles))
}
}
build("build") {
assertSuccessful()
assertCompiledKotlinSources(emptyList())
}
projectFile("A.kt").modify {
it.replace("val x = 0", "val x = \"a\"")
}
build("build") {
assertSuccessful()
checkIrCompilationMessage()
assertContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE)
val affectedFiles = project.projectDir.getFilesByNames("A.kt", "useAInLibMain.kt", "useAInAppMain.kt", "useAInAppTest.kt")
if (irBackend) {
// only klib ic is supported for now, so tests are generated non-incrementally with ir backend
assertCompiledKotlinSources(project.relativize(affectedFiles.filter { it in mainFiles }))
} else {
assertCompiledKotlinSources(project.relativize(affectedFiles))
}
}
}
@Test
fun testIncrementalCompilationDisabled() = Project("kotlin2JsICProject").run {
val options = defaultBuildOptions().run {
@@ -20,6 +20,6 @@ dependencies {
}
if (project.findProperty("kotlin.js.useIrBackend")?.toBoolean() == true) {
compileKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-klib-dir", "-Xir-produce-js", "-Xir-only"]
compileKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-klib-dir", "-Xir-only"]
compileTestKotlin2Js.kotlinOptions.freeCompilerArgs += ["-Xir-produce-js"]
}
@@ -262,8 +262,13 @@ internal class Kotlin2JsSourceSetProcessor(
// outputFile can be set later during the configuration phase, get it only after the phase:
project.whenEvaluated {
kotlinTask.configure { kotlinTaskInstance ->
kotlinTaskInstance.kotlinOptions.outputFile = kotlinTaskInstance.outputFile.absolutePath
val outputDir = kotlinTaskInstance.outputFile.parentFile
val kotlinOptions = kotlinTaskInstance.kotlinOptions
val outputDir: File = kotlinTaskInstance.outputFile.parentFile
kotlinOptions.outputFile = if (!kotlinOptions.isProduceUnzippedKlib()) {
kotlinTaskInstance.outputFile.absolutePath
} else {
kotlinTaskInstance.outputFile.parentFile.absolutePath
}
if (outputDir.isParentOf(project.rootDir))
throw InvalidUserDataException(
"The output directory '$outputDir' (defined by outputFile of $kotlinTaskInstance) contains or " +
@@ -272,6 +277,20 @@ internal class Kotlin2JsSourceSetProcessor(
"To fix this, consider using the default outputFile location instead of providing it explicitly."
)
kotlinTaskInstance.destinationDir = outputDir
if (
kotlinOptions.freeCompilerArgs.contains(PRODUCE_JS) ||
kotlinOptions.freeCompilerArgs.contains(PRODUCE_UNZIPPED_KLIB) ||
kotlinOptions.freeCompilerArgs.contains(PRODUCE_ZIPPED_KLIB)
) {
// Configure FQ module name to avoid cyclic dependencies in klib manifests (see KT-36721).
val baseName = if (kotlinCompilation.isMain()) {
project.name
} else {
"${project.name}_${kotlinCompilation.name}"
}
kotlinTaskInstance.kotlinOptions.freeCompilerArgs += "$MODULE_NAME=${project.klibModuleName(baseName)}"
}
}
val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinPluginVersion)
@@ -43,6 +43,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithTransitiveClosure
import org.jetbrains.kotlin.gradle.plugin.mpp.ownModuleName
import org.jetbrains.kotlin.gradle.report.ReportingSettings
import org.jetbrains.kotlin.gradle.targets.js.ir.isProduceUnzippedKlib
import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.incremental.ChangedFiles
import org.jetbrains.kotlin.library.impl.isKotlinLibrary
@@ -276,7 +277,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
// Input is needed to force rebuild even if source files are not changed
@get:Input
internal val coroutinesStr: Provider<String> = project.provider {coroutines.get().name}
internal val coroutinesStr: Provider<String> = project.provider { coroutines.get().name }
@get:Input
internal val coroutines: Provider<Coroutines> = project.provider {
@@ -397,7 +398,11 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
internal val isMultiplatform: Boolean by lazy { project.plugins.any { it is KotlinPlatformPluginBase || it is KotlinMultiplatformPluginWrapper } }
@get:Internal
internal val abstractKotlinCompileArgumentsContributor by lazy { AbstractKotlinCompileArgumentsContributor(KotlinCompileArgumentsProvider(this)) }
internal val abstractKotlinCompileArgumentsContributor by lazy {
AbstractKotlinCompileArgumentsContributor(
KotlinCompileArgumentsProvider(this)
)
}
override fun setupCompilerArgs(args: T, defaultsOnly: Boolean, ignoreClasspathResolutionErrors: Boolean) {
abstractKotlinCompileArgumentsContributor.contributeArguments(
@@ -496,10 +501,12 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
K2JVMCompilerArguments()
override fun setupCompilerArgs(args: K2JVMCompilerArguments, defaultsOnly: Boolean, ignoreClasspathResolutionErrors: Boolean) {
compilerArgumentsContributor.contributeArguments(args, compilerArgumentsConfigurationFlags(
defaultsOnly,
ignoreClasspathResolutionErrors
))
compilerArgumentsContributor.contributeArguments(
args, compilerArgumentsConfigurationFlags(
defaultsOnly,
ignoreClasspathResolutionErrors
)
)
}
@get:Internal
@@ -635,23 +642,19 @@ open class Kotlin2JsCompile : AbstractKotlinCompile<K2JSCompilerArguments>(), Ko
@get:Internal
val outputFile: File
get() = outputFilePath?.let(::File) ?: defaultOutputFile
get() = kotlinOptions.outputFile?.let(::File) ?: defaultOutputFile
@get:OutputFile
@get:Optional
val outputFileOrNull: File?
get() = outputFile.let { file ->
if (file.isFile) {
if (!kotlinOptions.isProduceUnzippedKlib()) {
file
} else {
null
}
}
@get:Input
val outputFilePath: String?
get() = kotlinOptions.outputFile
override fun findKotlinCompilerClasspath(project: Project): List<File> =
findKotlinJsCompilerClasspath(project)