KT-41456: Incremental KAPT - check compiled sources before running incrementally

Because incremental KAPT tries to reuse .class files produced by kotlinc
and javac, it should check for their existence before starting
an incremental run. Otherwise, annotation processors that perform type
validation will fail to run.

Current check counts the number of declared types in processed .java
sources, and it makes sure the total number of .class files in compiled
sources dirs is equal or higher. Otherwise, KAPT runs non-incrementally.

Tests: KaptIncrementalWithIsolatingApt.testMissingKotlinOutputForcesNonIncrementalRun

^KT-41456 In Progress
This commit is contained in:
Ivan Gavrilovic
2022-02-19 15:06:35 +00:00
committed by teamcity
parent c7e73ce88d
commit 0074e0209c
7 changed files with 112 additions and 18 deletions
@@ -129,7 +129,10 @@ class IncrementalKaptTest {
val classesOutput = tmp.newFolder()
compileSources(sourcesDir.listFiles().asIterable(), classesOutput)
compileSources(listOf(outputDir.resolve("test/UserGenerated.java")), classesOutput)
compileSources(
listOf(outputDir.resolve("test/UserGenerated.java"), outputDir.resolve("test/AddressGenerated.java")),
classesOutput
)
val optionsForSecondRun = KaptOptions.Builder().apply {
projectBaseDir = tmp.newFolder()
@@ -21,10 +21,12 @@ class JavaClassCacheManagerTest {
private lateinit var cache: JavaClassCacheManager
private lateinit var cacheDir: File
private lateinit var compiledSources: List<File>
@Before
fun setUp() {
cacheDir = tmp.newFolder()
compiledSources = listOf(tmp.newFolder().also { it.resolve(TEST_PACKAGE_NAME).mkdir() })
cache = JavaClassCacheManager(cacheDir)
}
@@ -42,21 +44,24 @@ class JavaClassCacheManagerTest {
SourceFileStructure(File("Mentioned.java").toURI()).also {
it.addDeclaredType("test.Mentioned")
cache.javaCache.addSourceStructure(it)
compiledSources.single().resolve("test/Mentioned.class").createNewFile()
}
SourceFileStructure(File("Src.java").toURI()).also {
it.addDeclaredType("test.Src")
it.addMentionedType("test.Mentioned")
cache.javaCache.addSourceStructure(it)
compiledSources.single().resolve("test/Src.class").createNewFile()
}
SourceFileStructure(File("ReferencesSrc.java").toURI()).also {
it.addDeclaredType("test.ReferencesSrc")
it.addPrivateType("test.Src")
cache.javaCache.addSourceStructure(it)
compiledSources.single().resolve("test/ReferencesSrc.class").createNewFile()
}
prepareForIncremental()
val dirtyFiles =
cache.invalidateAndGetDirtyFiles(listOf(File("Mentioned.java").absoluteFile), emptyList()) as SourcesToReprocess.Incremental
cache.invalidateAndGetDirtyFiles(listOf(File("Mentioned.java").absoluteFile), emptyList(), compiledSources) as SourcesToReprocess.Incremental
assertEquals(
listOf(
File("Mentioned.java").absoluteFile,
@@ -71,21 +76,24 @@ class JavaClassCacheManagerTest {
SourceFileStructure(File("Mentioned.java").toURI()).also {
it.addDeclaredType("test.Mentioned")
cache.javaCache.addSourceStructure(it)
compiledSources.single().resolve("test/Mentioned.class").createNewFile()
}
SourceFileStructure(File("Src.java").toURI()).also {
it.addDeclaredType("test.Src")
it.addPrivateType("test.Mentioned")
cache.javaCache.addSourceStructure(it)
compiledSources.single().resolve("test/Src.class").createNewFile()
}
SourceFileStructure(File("ReferencesSrc.java").toURI()).also {
it.addDeclaredType("test.ReferencesSrc")
it.addPrivateType("test.Src")
cache.javaCache.addSourceStructure(it)
compiledSources.single().resolve("test/ReferencesSrc.class").createNewFile()
}
prepareForIncremental()
val dirtyFiles =
cache.invalidateAndGetDirtyFiles(listOf(File("Mentioned.java").absoluteFile), emptyList()) as SourcesToReprocess.Incremental
cache.invalidateAndGetDirtyFiles(listOf(File("Mentioned.java").absoluteFile), emptyList(), compiledSources) as SourcesToReprocess.Incremental
assertEquals(
listOf(
File("Mentioned.java").absoluteFile,
@@ -100,21 +108,25 @@ class JavaClassCacheManagerTest {
it.addDeclaredType("test.TwoTypes")
it.addDeclaredType("test.AnotherType")
cache.javaCache.addSourceStructure(it)
compiledSources.single().resolve("test/TwoTypes.class").createNewFile()
compiledSources.single().resolve("test/AnotherType.class").createNewFile()
}
SourceFileStructure(File("ReferencesTwoTypes.java").toURI()).also {
it.addDeclaredType("test.ReferencesTwoTypes")
it.addPrivateType("test.TwoTypes")
cache.javaCache.addSourceStructure(it)
compiledSources.single().resolve("test/ReferencesTwoTypes.class").createNewFile()
}
SourceFileStructure(File("ReferencesAnotherType.java").toURI()).also {
it.addDeclaredType("test.ReferencesAnotherType")
it.addPrivateType("test.AnotherType")
cache.javaCache.addSourceStructure(it)
compiledSources.single().resolve("test/ReferencesAnotherType.class").createNewFile()
}
prepareForIncremental()
val dirtyFiles =
cache.invalidateAndGetDirtyFiles(listOf(File("TwoTypes.java").absoluteFile), emptyList()) as SourcesToReprocess.Incremental
cache.invalidateAndGetDirtyFiles(listOf(File("TwoTypes.java").absoluteFile), emptyList(), compiledSources) as SourcesToReprocess.Incremental
assertEquals(
listOf(
File("TwoTypes.java").absoluteFile,
@@ -130,10 +142,11 @@ class JavaClassCacheManagerTest {
it.addDeclaredType("test.Src")
it.addMentionedType("test.Mentioned")
cache.javaCache.addSourceStructure(it)
compiledSources.single().resolve("test/Src.class").createNewFile()
}
prepareForIncremental()
val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(), listOf("test/Mentioned")) as SourcesToReprocess.Incremental
val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(), listOf("test/Mentioned"), compiledSources) as SourcesToReprocess.Incremental
assertEquals(listOf(File("Src.java").absoluteFile), dirtyFiles.toReprocess)
}
@@ -142,22 +155,25 @@ class JavaClassCacheManagerTest {
SourceFileStructure(File("Constants.java").toURI()).also {
it.addDeclaredType("test.Constants")
cache.javaCache.addSourceStructure(it)
compiledSources.single().resolve("test/Constants.class").createNewFile()
}
SourceFileStructure(File("MentionsConst.java").toURI()).also {
it.addDeclaredType("test.MentionsConst")
it.addMentionedConstant("test.Constants", "CONST")
cache.javaCache.addSourceStructure(it)
compiledSources.single().resolve("test/MentionsConst.class").createNewFile()
}
SourceFileStructure(File("MentionsOtherConst.java").toURI()).also {
it.addDeclaredType("test.MentionsOtherConst")
it.addMentionedConstant("test.OtherConstants", "CONST")
cache.javaCache.addSourceStructure(it)
compiledSources.single().resolve("test/MentionsOtherConst.class").createNewFile()
}
prepareForIncremental()
val dirtyFiles =
cache.invalidateAndGetDirtyFiles(
listOf(File("Constants.java").absoluteFile), emptyList()
listOf(File("Constants.java").absoluteFile), emptyList(), compiledSources
) as SourcesToReprocess.Incremental
assertEquals(
listOf(File("Constants.java").absoluteFile, File("MentionsConst.java").absoluteFile),
@@ -170,3 +186,5 @@ class JavaClassCacheManagerTest {
cache = JavaClassCacheManager(cacheDir)
}
}
private const val TEST_PACKAGE_NAME = "test"
@@ -5,10 +5,7 @@
package org.jetbrains.kotlin.kapt.base.test.org.jetbrains.kotlin.kapt3.base.incremental
import org.jetbrains.kotlin.kapt3.base.incremental.IncrementalProcessor
import org.jetbrains.kotlin.kapt3.base.incremental.JavaClassCacheManager
import org.jetbrains.kotlin.kapt3.base.incremental.MentionedTypesTaskListener
import org.jetbrains.kotlin.kapt3.base.incremental.SourcesToReprocess
import org.jetbrains.kotlin.kapt3.base.incremental.*
import org.junit.Assert.*
import org.junit.Before
import org.junit.Rule
@@ -24,11 +21,13 @@ class TestSimpleIncrementalAptCache {
private lateinit var cache: JavaClassCacheManager
private lateinit var generatedSources: File
private lateinit var compiledSources: List<File>
@Before
fun setUp() {
cache = JavaClassCacheManager(tmp.newFolder())
generatedSources = tmp.newFolder()
compiledSources = listOf(tmp.newFolder().also { it.resolve(TEST_PACKAGE_NAME).mkdir() })
cache.close()
}
@@ -36,7 +35,11 @@ class TestSimpleIncrementalAptCache {
fun testAggregatingAnnotations() {
runProcessor(SimpleProcessor().toAggregating())
val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(TEST_DATA_DIR.resolve("User.java").absoluteFile), emptyList()) as SourcesToReprocess.Incremental
val dirtyFiles = cache.invalidateAndGetDirtyFiles(
listOf(TEST_DATA_DIR.resolve("User.java").absoluteFile),
emptyList(),
compiledSources
) as SourcesToReprocess.Incremental
assertEquals(
listOf(TEST_DATA_DIR.resolve("User.java").absoluteFile, TEST_DATA_DIR.resolve("Address.java").absoluteFile),
dirtyFiles.toReprocess
@@ -49,7 +52,11 @@ class TestSimpleIncrementalAptCache {
fun testIsolatingAnnotations() {
runProcessor(SimpleProcessor().toIsolating())
val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(TEST_DATA_DIR.resolve("User.java").absoluteFile), emptyList()) as SourcesToReprocess.Incremental
val dirtyFiles = cache.invalidateAndGetDirtyFiles(
listOf(TEST_DATA_DIR.resolve("User.java").absoluteFile),
emptyList(),
compiledSources
) as SourcesToReprocess.Incremental
assertFalse(generatedSources.resolve("test/UserGenerated.java").exists())
assertEquals(
listOf(TEST_DATA_DIR.resolve("User.java").absoluteFile),
@@ -61,7 +68,7 @@ class TestSimpleIncrementalAptCache {
fun testNonIncremental() {
runProcessor(SimpleProcessor().toNonIncremental())
val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(TEST_DATA_DIR.resolve("User.java").absoluteFile), emptyList())
val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(TEST_DATA_DIR.resolve("User.java").absoluteFile), emptyList(), compiledSources)
assertTrue(dirtyFiles is SourcesToReprocess.FullRebuild)
}
@@ -73,5 +80,14 @@ class TestSimpleIncrementalAptCache {
generatedSources
) { elementUtils, trees -> MentionedTypesTaskListener(cache.javaCache, elementUtils, trees) }
cache.updateCache(listOf(processor), false)
// add mock compiled source files
compiledSources.single().resolve("test/User.class").createNewFile()
compiledSources.single().resolve("test/Address.class").createNewFile()
compiledSources.single().resolve("test/Observable.class").createNewFile()
compiledSources.single().resolve("test/UserGenerated.class").createNewFile()
compiledSources.single().resolve("test/AddressGenerated.class").createNewFile()
}
}
}
private const val TEST_PACKAGE_NAME = "test"