Build non-incrementally when input class-file is changed
This commit is contained in:
+10
-3
@@ -307,7 +307,8 @@ open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
|
||||
// TODO: more precise will be not to rebuild unconditionally on classpath changes, but retrieve lookup info and try to find out which sources are affected by cp changes
|
||||
|| isClassPathChanged()
|
||||
// so far considering it not incremental TODO: store java files in the cache and extract removed symbols from it here
|
||||
|| removed.any { it.isJavaFile() }
|
||||
|| removed.any { it.isJavaFile() || it.hasClassFileExtension() }
|
||||
|| modified.any { it.hasClassFileExtension() }
|
||||
|| cacheVersions.any { it.checkVersion() != CacheVersion.Action.DO_NOTHING }
|
||||
) {
|
||||
logger.kotlinInfo(if (!isIncrementalRequested) "clean caches on rebuild" else "classpath changed, rebuilding all kotlin files")
|
||||
@@ -376,7 +377,10 @@ open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
|
||||
it.removeClassfilesBySources(removedAndModified)
|
||||
}}
|
||||
|
||||
logger.kotlinInfo("compile iteration: ${sourcesToCompile.joinToString{ projectRelativePath(it) }}")
|
||||
// can be empty if only removed sources are present
|
||||
if (sourcesToCompile.isNotEmpty()) {
|
||||
logger.kotlinInfo("compile iteration: ${sourcesToCompile.joinToString { projectRelativePath(it) }}")
|
||||
}
|
||||
|
||||
val (existingSource, nonExistingSource) = sourcesToCompile.partition { it.isFile }
|
||||
assert(nonExistingSource.isEmpty()) { "Trying to compile removed files: ${nonExistingSource.map(::projectRelativePath)}" }
|
||||
@@ -710,4 +714,7 @@ internal fun Logger.kotlinDebug(message: ()->String) {
|
||||
}
|
||||
|
||||
internal fun listClassFiles(path: String): Sequence<File> =
|
||||
File(path).walk().filter { it.isFile && it.extension.toLowerCase() == "class" }
|
||||
File(path).walk().filter { it.isFile && it.hasClassFileExtension() }
|
||||
|
||||
private fun File.hasClassFileExtension(): Boolean =
|
||||
extension.toLowerCase() == "class"
|
||||
|
||||
+3
@@ -86,6 +86,9 @@ abstract class BaseGradleIT {
|
||||
copyRecursively(this.resourcesRoot, workingDir)
|
||||
copyDirRecursively(File(resourcesRootFile, "GradleWrapper-$wrapperVersion"), projectDir)
|
||||
}
|
||||
|
||||
fun relativePaths(files: Iterable<File>): List<String> =
|
||||
files.map { it.relativeTo(projectDir).path }
|
||||
}
|
||||
|
||||
class CompiledProject(val project: Project, val output: String, val resultCode: Int) {
|
||||
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import org.jetbrains.kotlin.gradle.util.allKotlinFiles
|
||||
import org.jetbrains.kotlin.gradle.util.getFileByName
|
||||
import org.jetbrains.kotlin.gradle.util.modify
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
|
||||
class TestRootAffectedIT : BaseGradleIT() {
|
||||
@Test
|
||||
fun testSourceRootClassIsModifiedIC() {
|
||||
val project = Project("kotlinProject", "2.10")
|
||||
val buildOptions = defaultBuildOptions().copy(incremental = true)
|
||||
|
||||
project.build("build", options = buildOptions) {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
val kotlinGreetingJoinerFile = project.projectDir.getFileByName("KotlinGreetingJoiner.kt")
|
||||
kotlinGreetingJoinerFile.modify {
|
||||
val replacing = "fun addName(name: String?): Unit"
|
||||
val replacement = "fun addName(name: String): Unit"
|
||||
assert(it.contains(replacing)) { "API has changed!" }
|
||||
it.replace(replacing, replacement)
|
||||
}
|
||||
|
||||
project.build("build", options = buildOptions) {
|
||||
assertSuccessful()
|
||||
val expectedToCompile = project.relativePaths(listOf(kotlinGreetingJoinerFile) + project.allTestKotlinFiles())
|
||||
assertCompiledKotlinSources(expectedToCompile)
|
||||
}
|
||||
|
||||
project.build("build", options = buildOptions) {
|
||||
assertSuccessful()
|
||||
assertCompiledKotlinSources(emptyList())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSourceRootClassIsRemovedIC() {
|
||||
val project = Project("kotlinProject", "2.10")
|
||||
val buildOptions = defaultBuildOptions().copy(incremental = true)
|
||||
|
||||
project.build("build", options = buildOptions) {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
val dummyFile = project.projectDir.getFileByName("Dummy.kt")
|
||||
dummyFile.delete()
|
||||
|
||||
project.build("build", options = buildOptions) {
|
||||
assertSuccessful()
|
||||
val expectedToCompile = project.relativePaths(project.allTestKotlinFiles())
|
||||
assertCompiledKotlinSources(expectedToCompile)
|
||||
}
|
||||
|
||||
project.build("build", options = buildOptions) {
|
||||
assertSuccessful()
|
||||
assertCompiledKotlinSources(emptyList())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTestRootClassIsRemovedIC() {
|
||||
val project = Project("kotlinProject", "2.10")
|
||||
val buildOptions = defaultBuildOptions().copy(incremental = true)
|
||||
|
||||
project.build("build", options = buildOptions) {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
val greeterTestFile = project.projectDir.getFileByName("TestGreeter.kt")
|
||||
greeterTestFile.delete()
|
||||
|
||||
project.build("build", options = buildOptions) {
|
||||
assertSuccessful()
|
||||
assertCompiledKotlinSources(emptyList())
|
||||
}
|
||||
|
||||
project.build("build", options = buildOptions) {
|
||||
assertSuccessful()
|
||||
assertCompiledKotlinSources(emptyList())
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.allTestKotlinFiles(): Iterable<File> =
|
||||
File(projectDir, "src/test").allKotlinFiles()
|
||||
}
|
||||
+3
@@ -8,6 +8,9 @@ fun File.getFileByName(name: String): File =
|
||||
fun File.findFileByName(name: String): File? =
|
||||
walk().filter { it.isFile && it.name.equals(name, ignoreCase = true) }.firstOrNull()
|
||||
|
||||
fun File.allKotlinFiles(): Iterable<File> =
|
||||
walk().filter { it.isFile && it.extension.toLowerCase().equals("kt") }.toList()
|
||||
|
||||
fun File.modify(transform: (String)->String) {
|
||||
writeText(transform(readText()))
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package demo
|
||||
|
||||
open class Greeter(val greeting: String)
|
||||
+3
-7
@@ -1,22 +1,18 @@
|
||||
package demo
|
||||
|
||||
import com.google.common.primitives.Ints
|
||||
import com.google.common.base.Joiner
|
||||
import java.util.ArrayList
|
||||
|
||||
class KotlinGreetingJoiner(val greeter : Greeter) {
|
||||
|
||||
class KotlinGreetingJoiner(val greeter: Greeter) {
|
||||
val names = ArrayList<String?>()
|
||||
|
||||
fun addName(name : String?): Unit{
|
||||
fun addName(name: String?): Unit {
|
||||
names.add(name)
|
||||
}
|
||||
|
||||
fun getJoinedGreeting() : String? {
|
||||
fun getJoinedGreeting(): String? {
|
||||
val joiner = Joiner.on(" and ").skipNulls();
|
||||
return "${greeter.greeting} ${joiner.join(names)}"
|
||||
}
|
||||
}
|
||||
|
||||
public open class Greeter(val greeting : String)
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package demo
|
||||
|
||||
import org.testng.Assert.assertEquals
|
||||
|
||||
class TestGreeter {
|
||||
fun test() {
|
||||
val greeter = Greeter("Hi!")
|
||||
assertEquals("Hi!", greeter.greeting)
|
||||
}
|
||||
}
|
||||
+4
-8
@@ -1,18 +1,14 @@
|
||||
package demo
|
||||
|
||||
import com.google.common.primitives.Ints
|
||||
import com.google.common.base.Joiner
|
||||
import org.testng.Assert.*
|
||||
import org.testng.annotations.AfterMethod
|
||||
import org.testng.annotations.BeforeMethod
|
||||
import org.testng.Assert.assertEquals
|
||||
import org.testng.annotations.Test as test
|
||||
|
||||
class TestSource() {
|
||||
@test fun f() {
|
||||
class TestKotlinGreetingJoiner() {
|
||||
@test
|
||||
fun test() {
|
||||
val example : KotlinGreetingJoiner = KotlinGreetingJoiner(Greeter("Hi"))
|
||||
example.addName("Harry")
|
||||
example.addName("Ron")
|
||||
example.addName(null)
|
||||
example.addName("Hermione")
|
||||
|
||||
assertEquals(example.getJoinedGreeting(), "Hi Harry and Ron and Hermione")
|
||||
Reference in New Issue
Block a user