Implement inter-project JS IC with Gradle
#KT-25025 fixed
This commit is contained in:
+4
-1
@@ -529,7 +529,10 @@ abstract class BaseGradleIT {
|
||||
}
|
||||
|
||||
add("-Pkotlin_version=" + options.kotlinVersion)
|
||||
options.incremental?.let { add("-Pkotlin.incremental=$it") }
|
||||
options.incremental?.let {
|
||||
add("-Pkotlin.incremental=$it")
|
||||
add("-Pkotlin.incremental.js=$it")
|
||||
}
|
||||
options.usePreciseJavaTracking?.let { add("-Pkotlin.incremental.usePreciseJavaTracking=$it") }
|
||||
options.androidGradlePluginVersion?.let { add("-Pandroid_tools_version=$it") }
|
||||
if (options.debug) {
|
||||
|
||||
+201
-166
@@ -8,10 +8,35 @@ import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
|
||||
class IncrementalCompilationMultiProjectIT : BaseGradleIT() {
|
||||
override fun defaultBuildOptions(): BuildOptions =
|
||||
super.defaultBuildOptions().copy(withDaemon = true, incremental = true)
|
||||
class IncrementalCompilationJsMultiProjectIT : BaseIncrementalCompilationMultiProjectIT() {
|
||||
override fun defaultProject(): Project {
|
||||
val project = Project("incrementalMultiproject")
|
||||
project.setupWorkingDir()
|
||||
|
||||
for (subProject in arrayOf("app", "lib")) {
|
||||
val subProjectDir = project.projectDir.resolve(subProject)
|
||||
subProjectDir.resolve("src/main/java").deleteRecursively()
|
||||
val buildGradle = subProjectDir.resolve("build.gradle")
|
||||
val buildJsGradle = subProjectDir.resolve("build-js.gradle")
|
||||
buildJsGradle.copyTo(buildGradle, overwrite = true)
|
||||
buildJsGradle.delete()
|
||||
}
|
||||
|
||||
return project
|
||||
}
|
||||
|
||||
override val additionalLibDependencies: String =
|
||||
"implementation \"org.jetbrains.kotlin:kotlin-test-js:${'$'}kotlin_version\""
|
||||
}
|
||||
|
||||
class IncrementalCompilationJvmMultiProjectIT : BaseIncrementalCompilationMultiProjectIT() {
|
||||
override val additionalLibDependencies: String =
|
||||
"implementation \"org.jetbrains.kotlin:kotlin-stdlib:${'$'}kotlin_version\""
|
||||
|
||||
override fun defaultProject(): Project =
|
||||
Project("incrementalMultiproject")
|
||||
|
||||
// todo: do the same for js backend
|
||||
@Test
|
||||
fun testDuplicatedClass() {
|
||||
val project = Project("duplicatedClass")
|
||||
@@ -28,174 +53,12 @@ class IncrementalCompilationMultiProjectIT : BaseGradleIT() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMoveFunctionFromLib() {
|
||||
val project = Project("incrementalMultiproject")
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
val barUseABKt = project.projectDir.getFileByName("barUseAB.kt")
|
||||
val barInApp = File(project.projectDir, "app/src/main/java/bar").apply { mkdirs() }
|
||||
barUseABKt.copyTo(File(barInApp, barUseABKt.name))
|
||||
barUseABKt.delete()
|
||||
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
val affectedSources = project.projectDir.getFilesByNames("fooCallUseAB.kt", "barUseAB.kt")
|
||||
val relativePaths = project.relativize(affectedSources)
|
||||
assertCompiledKotlinSources(relativePaths, weakTesting = false)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAddNewMethodToLib() {
|
||||
val project = Project("incrementalMultiproject")
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
val aKt = project.projectDir.getFileByName("A.kt")
|
||||
aKt.writeText(
|
||||
"""
|
||||
package bar
|
||||
|
||||
open class A {
|
||||
fun a() {}
|
||||
fun newA() {}
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
val affectedSources = project.projectDir.getFilesByNames("A.kt", "B.kt", "AA.kt", "BB.kt")
|
||||
val relativePaths = project.relativize(affectedSources)
|
||||
assertCompiledKotlinSources(relativePaths, weakTesting = false)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLibClassBecameFinal() {
|
||||
val project = Project("incrementalMultiproject")
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
val bKt = project.projectDir.getFileByName("B.kt")
|
||||
bKt.modify { it.replace("open class", "class") }
|
||||
|
||||
project.build("build") {
|
||||
assertFailed()
|
||||
val affectedSources = project.projectDir.getFilesByNames(
|
||||
"B.kt", "barUseAB.kt", "barUseB.kt",
|
||||
"BB.kt", "fooCallUseAB.kt", "fooUseB.kt"
|
||||
)
|
||||
val relativePaths = project.relativize(affectedSources)
|
||||
assertCompiledKotlinSources(relativePaths, weakTesting = false)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCleanBuildLib() {
|
||||
val project = Project("incrementalMultiproject")
|
||||
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
project.build(":lib:clean") {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
// Change file so Gradle won't skip :app:compile
|
||||
project.projectFile("BarDummy.kt").modify {
|
||||
it.replace("class BarDummy", "open class BarDummy")
|
||||
}
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
val affectedSources = project.projectDir.allKotlinFiles()
|
||||
val relativePaths = project.relativize(affectedSources)
|
||||
assertCompiledKotlinSources(relativePaths, weakTesting = false)
|
||||
}
|
||||
|
||||
val aaKt = project.projectFile("AA.kt")
|
||||
aaKt.modify { "$it " }
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
assertCompiledKotlinSources(project.relativize(aaKt), weakTesting = false)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAddDependencyToLib() {
|
||||
val project = Project("incrementalMultiproject")
|
||||
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
val libBuildGradle = File(project.projectDir, "lib/build.gradle")
|
||||
Assert.assertTrue("$libBuildGradle does not exist", libBuildGradle.exists())
|
||||
libBuildGradle.modify {
|
||||
"""
|
||||
$it
|
||||
|
||||
dependencies {
|
||||
implementation 'junit:junit:4.12'
|
||||
}
|
||||
""".trimIndent()
|
||||
}
|
||||
// Change file so Gradle won't skip :app:compile
|
||||
project.projectFile("BarDummy.kt").modify {
|
||||
it.replace("class BarDummy", "open class BarDummy")
|
||||
}
|
||||
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
val affectedSources = project.projectDir.allKotlinFiles()
|
||||
val relativePaths = project.relativize(affectedSources)
|
||||
assertCompiledKotlinSources(relativePaths, weakTesting = false)
|
||||
}
|
||||
|
||||
val aaKt = project.projectFile("AA.kt")
|
||||
aaKt.modify { "$it " }
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
assertCompiledKotlinSources(project.relativize(aaKt), weakTesting = false)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCompileErrorInLib() {
|
||||
val project = Project("incrementalMultiproject")
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
val bKt = project.projectDir.getFileByName("B.kt")
|
||||
bKt.delete()
|
||||
|
||||
project.build("build") {
|
||||
assertFailed()
|
||||
}
|
||||
|
||||
project.projectDir.getFileByName("barUseB.kt").delete()
|
||||
project.projectDir.getFileByName("barUseAB.kt").delete()
|
||||
|
||||
project.build("build") {
|
||||
assertFailed()
|
||||
val affectedSources = project.projectDir.allKotlinFiles()
|
||||
val relativePaths = project.relativize(affectedSources)
|
||||
assertCompiledKotlinSources(relativePaths, weakTesting = false)
|
||||
}
|
||||
}
|
||||
|
||||
// checks that multi-project ic is disabled when there is a task that outputs to javaDestination dir
|
||||
// that is not JavaCompile or KotlinCompile
|
||||
@Test
|
||||
fun testCompileLibWithGroovy() {
|
||||
val project = Project("incrementalMultiproject")
|
||||
val project = defaultProject()
|
||||
project.setupWorkingDir()
|
||||
val lib = File(project.projectDir, "lib")
|
||||
val libBuildGradle = File(lib, "build.gradle")
|
||||
@@ -234,3 +97,175 @@ open class A {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class BaseIncrementalCompilationMultiProjectIT : BaseGradleIT() {
|
||||
override fun defaultBuildOptions(): BuildOptions =
|
||||
super.defaultBuildOptions().copy(withDaemon = true, incremental = true)
|
||||
|
||||
protected abstract fun defaultProject(): Project
|
||||
|
||||
@Test
|
||||
fun testMoveFunctionFromLib() {
|
||||
val project = defaultProject()
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
val barUseABKt = project.projectDir.getFileByName("barUseAB.kt")
|
||||
val barInApp = File(project.projectDir, "app/src/main/kotlin/bar").apply { mkdirs() }
|
||||
barUseABKt.copyTo(File(barInApp, barUseABKt.name))
|
||||
barUseABKt.delete()
|
||||
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
val affectedSources = project.projectDir.getFilesByNames("fooCallUseAB.kt", "barUseAB.kt")
|
||||
val relativePaths = project.relativize(affectedSources)
|
||||
assertCompiledKotlinSources(relativePaths, weakTesting = false)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAddNewMethodToLib() {
|
||||
val project = defaultProject()
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
val aKt = project.projectDir.getFileByName("A.kt")
|
||||
aKt.writeText(
|
||||
"""
|
||||
package bar
|
||||
|
||||
open class A {
|
||||
fun a() {}
|
||||
fun newA() {}
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
val affectedSources = project.projectDir.getFilesByNames("A.kt", "B.kt", "AA.kt", "BB.kt")
|
||||
val relativePaths = project.relativize(affectedSources)
|
||||
assertCompiledKotlinSources(relativePaths, weakTesting = false)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLibClassBecameFinal() {
|
||||
val project = defaultProject()
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
val bKt = project.projectDir.getFileByName("B.kt")
|
||||
bKt.modify { it.replace("open class", "class") }
|
||||
|
||||
project.build("build") {
|
||||
assertFailed()
|
||||
val affectedSources = project.projectDir.getFilesByNames(
|
||||
"B.kt", "barUseAB.kt", "barUseB.kt",
|
||||
"BB.kt", "fooCallUseAB.kt", "fooUseB.kt"
|
||||
)
|
||||
val relativePaths = project.relativize(affectedSources)
|
||||
assertCompiledKotlinSources(relativePaths, weakTesting = false)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCleanBuildLib() {
|
||||
val project = defaultProject()
|
||||
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
project.build(":lib:clean") {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
// Change file so Gradle won't skip :app:compile
|
||||
project.projectFile("BarDummy.kt").modify {
|
||||
it.replace("class BarDummy", "open class BarDummy")
|
||||
}
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
val affectedSources = project.projectDir.allKotlinFiles()
|
||||
val relativePaths = project.relativize(affectedSources)
|
||||
assertCompiledKotlinSources(relativePaths, weakTesting = false)
|
||||
}
|
||||
|
||||
val aaKt = project.projectFile("AA.kt")
|
||||
aaKt.modify { "$it " }
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
assertCompiledKotlinSources(project.relativize(aaKt), weakTesting = false)
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract val additionalLibDependencies: String
|
||||
|
||||
@Test
|
||||
fun testAddDependencyToLib() {
|
||||
val project = defaultProject()
|
||||
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
val libBuildGradle = File(project.projectDir, "lib/build.gradle")
|
||||
Assert.assertTrue("$libBuildGradle does not exist", libBuildGradle.exists())
|
||||
libBuildGradle.modify {
|
||||
"""
|
||||
$it
|
||||
|
||||
dependencies {
|
||||
$additionalLibDependencies
|
||||
}
|
||||
""".trimIndent()
|
||||
}
|
||||
// Change file so Gradle won't skip :app:compile
|
||||
project.projectFile("BarDummy.kt").modify {
|
||||
it.replace("class BarDummy", "open class BarDummy")
|
||||
}
|
||||
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
val affectedSources = project.projectDir.allKotlinFiles()
|
||||
val relativePaths = project.relativize(affectedSources)
|
||||
assertCompiledKotlinSources(relativePaths, weakTesting = false)
|
||||
}
|
||||
|
||||
val aaKt = project.projectFile("AA.kt")
|
||||
aaKt.modify { "$it " }
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
assertCompiledKotlinSources(project.relativize(aaKt), weakTesting = false)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCompileErrorInLib() {
|
||||
val project = defaultProject()
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
val bKt = project.projectDir.getFileByName("B.kt")
|
||||
bKt.delete()
|
||||
|
||||
project.build("build") {
|
||||
assertFailed()
|
||||
}
|
||||
|
||||
project.projectDir.getFileByName("barUseB.kt").delete()
|
||||
project.projectDir.getFileByName("barUseAB.kt").delete()
|
||||
|
||||
project.build("build") {
|
||||
assertFailed()
|
||||
val affectedSources = project.projectDir.allKotlinFiles()
|
||||
val relativePaths = project.relativize(affectedSources)
|
||||
assertCompiledKotlinSources(relativePaths, weakTesting = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -3,6 +3,7 @@ package org.jetbrains.kotlin.gradle
|
||||
import org.gradle.api.logging.LogLevel
|
||||
import org.jetbrains.kotlin.gradle.tasks.USING_EXPERIMENTAL_JS_INCREMENTAL_COMPILATION_MESSAGE
|
||||
import org.jetbrains.kotlin.gradle.util.getFileByName
|
||||
import org.jetbrains.kotlin.gradle.util.getFilesByNames
|
||||
import org.jetbrains.kotlin.gradle.util.modify
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
@@ -334,7 +335,8 @@ class Kotlin2JsGradlePluginIT : BaseGradleIT() {
|
||||
build("build") {
|
||||
assertSuccessful()
|
||||
assertContains(USING_EXPERIMENTAL_JS_INCREMENTAL_COMPILATION_MESSAGE)
|
||||
assertCompiledKotlinSources(project.relativize(allKotlinFiles - projectFile("DummyInLibMain.kt")))
|
||||
val affectedFiles = project.projectDir.getFilesByNames("A.kt", "useAInLibMain.kt", "useAInAppMain.kt", "useAInAppTest.kt")
|
||||
assertCompiledKotlinSources(project.relativize(affectedFiles))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
apply plugin: 'kotlin2js'
|
||||
|
||||
dependencies {
|
||||
compile project(':lib')
|
||||
// do not remove until KT-25488 is fixed
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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
|
||||
|
||||
import bar.*
|
||||
|
||||
class AAA : A() {
|
||||
fun aa() {}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
apply plugin: 'kotlin2js'
|
||||
|
||||
dependencies {
|
||||
// do not remove until KT-25488 is fixed
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
|
||||
}
|
||||
+1
@@ -1,5 +1,6 @@
|
||||
package bar
|
||||
|
||||
fun useAB(b: B) {
|
||||
// todo b.a()
|
||||
b.b()
|
||||
}
|
||||
Reference in New Issue
Block a user