KT-41456: Incremental KAPT - represent source and class file structure differently

When storing source information needed for type analysis, store
.java file and .class file information separately. This is because
for class files only declared typed is needed.

Tests: updating existing ones

^KT-41456 In Progress
This commit is contained in:
Ivan Gavrilovic
2022-02-19 14:40:17 +00:00
committed by teamcity
parent 570189e833
commit c7e73ce88d
6 changed files with 54 additions and 40 deletions
@@ -26,10 +26,8 @@ class JavaClassCacheManager(val file: File) : Closeable {
// Compilation is fully incremental, record types defined in generated .class files
processors.forEach { processor ->
processor.getGeneratedClassFilesToTypes().forEach { (classFile, type) ->
val typeInformation = SourceFileStructure(classFile.toURI()).also {
it.addDeclaredType(type)
}
javaCache.addSourceStructure(typeInformation)
val classFileStructure = ClassFileStructure(classFile.toURI(), type)
javaCache.addSourceStructure(classFileStructure)
}
}
}
@@ -18,7 +18,7 @@ import java.net.URI
* exists i.e we know all referenced types. For .class files we only know which type is defined in the .class file.
*/
class JavaClassCache() : Serializable {
private var sourceCache = mutableMapOf<URI, SourceFileStructure>()
private var sourceCache = mutableMapOf<URI, JavaFileStructure>()
/** Map from types to files they are mentioned in. */
@Transient
@@ -27,7 +27,7 @@ class JavaClassCache() : Serializable {
@Transient
private var nonTransitiveCache = mutableMapOf<String, MutableSet<URI>>()
fun addSourceStructure(sourceStructure: SourceFileStructure) {
fun addSourceStructure(sourceStructure: JavaFileStructure) {
sourceCache[sourceStructure.sourceFile] = sourceStructure
}
@@ -35,7 +35,7 @@ class JavaClassCache() : Serializable {
fun getTypesForFiles(files: Collection<File>): Set<String> {
val typesFromFiles = HashSet<String>(files.size)
for (file in files) {
sourceCache[file.toURI()]?.getDeclaredTypes()?.let {
sourceCache[file.toURI()]?.declaredTypes?.let {
typesFromFiles.addAll(it)
}
}
@@ -44,10 +44,11 @@ class JavaClassCache() : Serializable {
private fun readObject(input: ObjectInputStream) {
@Suppress("UNCHECKED_CAST")
sourceCache = input.readObject() as MutableMap<URI, SourceFileStructure>
sourceCache = input.readObject() as MutableMap<URI, JavaFileStructure>
dependencyCache = HashMap(sourceCache.size * 4)
for (sourceInfo in sourceCache.values) {
if (sourceInfo !is SourceFileStructure) continue
for (mentionedType in sourceInfo.getMentionedTypes()) {
val dependants = dependencyCache[mentionedType] ?: mutableSetOf()
dependants.add(sourceInfo.sourceFile)
@@ -62,6 +63,7 @@ class JavaClassCache() : Serializable {
}
nonTransitiveCache = HashMap(sourceCache.size * 2)
for (sourceInfo in sourceCache.values) {
if (sourceInfo !is SourceFileStructure) continue
for (privateType in sourceInfo.getPrivateTypes()) {
val dependants = nonTransitiveCache[privateType] ?: mutableSetOf()
dependants.add(sourceInfo.sourceFile)
@@ -104,12 +106,12 @@ class JavaClassCache() : Serializable {
fun findImpactedTypes(changedType: String, transitiveDeps: MutableSet<String>, nonTransitiveDeps: MutableSet<String>) {
dependencyCache[changedType]?.let { impactedSources ->
impactedSources.forEach {
transitiveDeps.addAll(sourceCache.getValue(it).getDeclaredTypes())
transitiveDeps.addAll(sourceCache.getValue(it).declaredTypes)
}
}
nonTransitiveCache[changedType]?.let { impactedSources ->
impactedSources.forEach {
nonTransitiveDeps.addAll(sourceCache.getValue(it).getDeclaredTypes())
nonTransitiveDeps.addAll(sourceCache.getValue(it).declaredTypes)
}
}
}
@@ -139,7 +141,7 @@ class JavaClassCache() : Serializable {
fun getSourceForType(type: String): File {
sourceCache.forEach { (fileUri, typeInfo) ->
if (type in typeInfo.getDeclaredTypes()) {
if (type in typeInfo.declaredTypes) {
return File(fileUri)
}
}
@@ -149,7 +151,7 @@ class JavaClassCache() : Serializable {
fun invalidateDataForTypes(impactedTypes: MutableSet<String>) {
val allSources = mutableSetOf<URI>()
sourceCache.forEach { (fileUri, typeInfo) ->
if (typeInfo.getDeclaredTypes().any { it in impactedTypes }) {
if (typeInfo.declaredTypes.any { it in impactedTypes }) {
allSources.add(fileUri)
}
}
@@ -161,11 +163,23 @@ class JavaClassCache() : Serializable {
private val IGNORE_TYPES = { name: String -> name == "java.lang.Object" }
class SourceFileStructure(
interface JavaFileStructure {
val sourceFile: URI
) : Serializable {
val declaredTypes: Set<String>
}
private val declaredTypes: MutableSet<String> = mutableSetOf()
class ClassFileStructure(
override val sourceFile: URI,
declaredType: String
) : JavaFileStructure, Serializable {
override val declaredTypes: Set<String> = setOf(declaredType)
}
class SourceFileStructure(
override val sourceFile: URI
) : JavaFileStructure, Serializable {
private val _declaredTypes: MutableSet<String> = mutableSetOf()
private val mentionedTypes: MutableSet<String> = mutableSetOf()
private val privateTypes: MutableSet<String> = mutableSetOf()
@@ -173,14 +187,14 @@ class SourceFileStructure(
private val mentionedAnnotations: MutableSet<String> = mutableSetOf()
private val mentionedConstants: MutableMap<String, MutableSet<String>> = mutableMapOf()
fun getDeclaredTypes(): Set<String> = declaredTypes
override val declaredTypes: Set<String> = _declaredTypes
fun getMentionedTypes(): Set<String> = mentionedTypes
fun getPrivateTypes(): Set<String> = privateTypes
fun getMentionedAnnotations(): Set<String> = mentionedAnnotations
fun getMentionedConstants(): Map<String, Set<String>> = mentionedConstants
fun addDeclaredType(declaredType: String) {
declaredTypes.add(declaredType)
_declaredTypes.add(declaredType)
}
fun addMentionedType(mentionedType: String) {
@@ -9,7 +9,6 @@ import com.sun.source.tree.*
import com.sun.source.util.*
import com.sun.tools.javac.code.Symbol
import com.sun.tools.javac.tree.JCTree
import java.io.File
import javax.lang.model.element.ElementKind
import javax.lang.model.element.Modifier
import javax.lang.model.element.TypeElement
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.kapt.base.test.org.jetbrains.kotlin.kapt3.base.incr
import org.jetbrains.kotlin.kapt3.base.incremental.JavaClassCacheManager
import org.jetbrains.kotlin.kapt3.base.incremental.MentionedTypesTaskListener
import org.jetbrains.kotlin.kapt3.base.incremental.SourceFileStructure
import org.junit.Assert.assertEquals
import org.junit.BeforeClass
import org.junit.ClassRule
@@ -51,9 +52,9 @@ class TestInheritedAnnotation {
@Test
fun testAnnotationInherited() {
val shouldInheritAnnotation = cache.javaCache.getStructure(MY_TEST_DIR.resolve("ExtendsBase.java"))!!
val shouldInheritAnnotation = cache.javaCache.getStructure(MY_TEST_DIR.resolve("ExtendsBase.java"))!! as SourceFileStructure
assertEquals(setOf("test.ExtendsBase"), shouldInheritAnnotation.getDeclaredTypes())
assertEquals(setOf("test.ExtendsBase"), shouldInheritAnnotation.declaredTypes)
assertEquals(setOf("test.InheritableAnnotation"), shouldInheritAnnotation.getMentionedAnnotations())
assertEquals(emptySet<String>(), shouldInheritAnnotation.getPrivateTypes())
assertEquals(
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.kapt.base.test.org.jetbrains.kotlin.kapt3.base.incr
import org.jetbrains.kotlin.kapt3.base.incremental.JavaClassCacheManager
import org.jetbrains.kotlin.kapt3.base.incremental.MentionedTypesTaskListener
import org.jetbrains.kotlin.kapt3.base.incremental.SourceFileStructure
import org.junit.Assert.assertEquals
import org.junit.BeforeClass
import org.junit.ClassRule
@@ -54,9 +55,9 @@ class ReferencedConstantsTest {
@Test
fun testConstantInField() {
val klassA = cache.javaCache.getStructure(MY_TEST_DIR.resolve("A.java"))!!
val klassA = cache.javaCache.getStructure(MY_TEST_DIR.resolve("A.java"))!! as SourceFileStructure
assertEquals(setOf("test.A"), klassA.getDeclaredTypes())
assertEquals(setOf("test.A"), klassA.declaredTypes)
assertEquals(emptySet<String>(), klassA.getMentionedAnnotations())
assertEquals(emptySet<String>(), klassA.getPrivateTypes())
assertEquals(setOf("test.A"), klassA.getMentionedTypes())
@@ -70,9 +71,9 @@ class ReferencedConstantsTest {
@Test
fun testConstantInDefaultValue() {
val annotationA = cache.javaCache.getStructure(MY_TEST_DIR.resolve("AnnotationA.java"))!!
val annotationA = cache.javaCache.getStructure(MY_TEST_DIR.resolve("AnnotationA.java"))!! as SourceFileStructure
assertEquals(setOf("test.AnnotationA"), annotationA.getDeclaredTypes())
assertEquals(setOf("test.AnnotationA"), annotationA.declaredTypes)
assertEquals(emptySet<String>(), annotationA.getMentionedAnnotations())
assertEquals(emptySet<String>(), annotationA.getPrivateTypes())
assertEquals(setOf("test.AnnotationA"), annotationA.getMentionedTypes())
@@ -82,9 +83,9 @@ class ReferencedConstantsTest {
@Test
fun testConstantInAnnotationElementValue() {
val annotated = cache.javaCache.getStructure(MY_TEST_DIR.resolve("AnnotatedType.java"))!!
val annotated = cache.javaCache.getStructure(MY_TEST_DIR.resolve("AnnotatedType.java"))!! as SourceFileStructure
assertEquals(setOf("test.AnnotatedType"), annotated.getDeclaredTypes())
assertEquals(setOf("test.AnnotatedType"), annotated.declaredTypes)
assertEquals(setOf("test.AnnotationA"), annotated.getMentionedAnnotations())
assertEquals(emptySet<String>(), annotated.getPrivateTypes())
assertEquals(setOf("test.AnnotatedType", "test.AnnotationA"), annotated.getMentionedTypes())
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.kapt.base.test.org.jetbrains.kotlin.kapt3.base.incr
import org.jetbrains.kotlin.kapt3.base.incremental.JavaClassCacheManager
import org.jetbrains.kotlin.kapt3.base.incremental.MentionedTypesTaskListener
import org.jetbrains.kotlin.kapt3.base.incremental.SourceFileStructure
import org.junit.Assert.assertEquals
import org.junit.BeforeClass
import org.junit.ClassRule
@@ -53,9 +54,9 @@ class TestComplexIncrementalAptCache {
@Test
fun testEnum() {
val myEnum = cache.javaCache.getStructure(MY_TEST_DIR.resolve("MyEnum.java"))!!
val myEnum = cache.javaCache.getStructure(MY_TEST_DIR.resolve("MyEnum.java"))!! as SourceFileStructure
assertEquals(setOf("test.MyEnum"), myEnum.getDeclaredTypes())
assertEquals(setOf("test.MyEnum"), myEnum.declaredTypes)
assertEquals(emptySet<String>(), myEnum.getMentionedAnnotations())
assertEquals(emptySet<String>(), myEnum.getPrivateTypes())
assertEquals(setOf("test.MyEnum", "test.TypeGeneratedByApt"), myEnum.getMentionedTypes())
@@ -63,7 +64,7 @@ class TestComplexIncrementalAptCache {
@Test
fun testMyNumber() {
val myNumber = cache.javaCache.getStructure(MY_TEST_DIR.resolve("MyNumber.java"))!!
val myNumber = cache.javaCache.getStructure(MY_TEST_DIR.resolve("MyNumber.java"))!! as SourceFileStructure
assertEquals(
setOf(
@@ -74,7 +75,7 @@ class TestComplexIncrementalAptCache {
"test.TypeUseAnnotation",
"test.AnotherTypeUseAnnotation",
"test.ThrowTypeUseAnnotation"
), myNumber.getDeclaredTypes()
), myNumber.declaredTypes
)
assertEquals(
setOf(
@@ -116,9 +117,9 @@ class TestComplexIncrementalAptCache {
@Test
fun testAnnotation() {
val numberAnnotation = cache.javaCache.getStructure(MY_TEST_DIR.resolve("NumberAnnotation.java"))!!
val numberAnnotation = cache.javaCache.getStructure(MY_TEST_DIR.resolve("NumberAnnotation.java"))!! as SourceFileStructure
assertEquals(setOf("test.NumberAnnotation", "test.BaseAnnotation"), numberAnnotation.getDeclaredTypes())
assertEquals(setOf("test.NumberAnnotation", "test.BaseAnnotation"), numberAnnotation.declaredTypes)
assertEquals(setOf("test.BaseAnnotation"), numberAnnotation.getMentionedAnnotations())
assertEquals(emptySet<String>(), numberAnnotation.getPrivateTypes())
assertEquals(
@@ -134,9 +135,9 @@ class TestComplexIncrementalAptCache {
@Test
fun testNumberException() {
val numberException = cache.javaCache.getStructure(MY_TEST_DIR.resolve("NumberException.java"))!!
val numberException = cache.javaCache.getStructure(MY_TEST_DIR.resolve("NumberException.java"))!! as SourceFileStructure
assertEquals(setOf("test.NumberException"), numberException.getDeclaredTypes())
assertEquals(setOf("test.NumberException"), numberException.declaredTypes)
assertEquals(emptySet<String>(), numberException.getMentionedAnnotations())
assertEquals(emptySet<String>(), numberException.getPrivateTypes())
assertEquals(setOf("test.NumberException", "java.lang.RuntimeException"), numberException.getMentionedTypes())
@@ -144,9 +145,9 @@ class TestComplexIncrementalAptCache {
@Test
fun testNumberHolder() {
val numberHolder = cache.javaCache.getStructure(MY_TEST_DIR.resolve("NumberHolder.java"))!!
val numberHolder = cache.javaCache.getStructure(MY_TEST_DIR.resolve("NumberHolder.java"))!! as SourceFileStructure
assertEquals(setOf("test.NumberHolder", "test.NumberHolder.MyInnerClass"), numberHolder.getDeclaredTypes())
assertEquals(setOf("test.NumberHolder", "test.NumberHolder.MyInnerClass"), numberHolder.declaredTypes)
assertEquals(setOf("test.NumberAnnotation"), numberHolder.getMentionedAnnotations())
assertEquals(setOf("test.NumberManager"), numberHolder.getPrivateTypes())
assertEquals(
@@ -166,9 +167,9 @@ class TestComplexIncrementalAptCache {
@Test
fun testNumberManager() {
val numberManager = cache.javaCache.getStructure(MY_TEST_DIR.resolve("NumberManager.java"))!!
val numberManager = cache.javaCache.getStructure(MY_TEST_DIR.resolve("NumberManager.java"))!! as SourceFileStructure
assertEquals(setOf("test.NumberManager"), numberManager.getDeclaredTypes())
assertEquals(setOf("test.NumberManager"), numberManager.declaredTypes)
assertEquals(emptySet<String>(), numberManager.getMentionedAnnotations())
assertEquals(setOf("test.MyEnum"), numberManager.getPrivateTypes())
assertEquals(
@@ -182,9 +183,9 @@ class TestComplexIncrementalAptCache {
@Test
fun testGenericNumber() {
val genericNumber = cache.javaCache.getStructure(MY_TEST_DIR.resolve("GenericNumber.java"))!!
val genericNumber = cache.javaCache.getStructure(MY_TEST_DIR.resolve("GenericNumber.java"))!! as SourceFileStructure
assertEquals(setOf("test.GenericNumber"), genericNumber.getDeclaredTypes())
assertEquals(setOf("test.GenericNumber"), genericNumber.declaredTypes)
assertEquals(emptySet<String>(), genericNumber.getMentionedAnnotations())
assertEquals(emptySet<String>(), genericNumber.getPrivateTypes())
assertEquals(