Incremental KAPT - track constants usage

This commit adds support for tracking of used constants in
source files. For every constant used in a source file, class
that defines the constant and the constant name are tracked.

Value of the constant can be obtained using
annotation processing APIs, so if the constant value changes, a source file
using it has to be reprocessed.

 #KT-23880
This commit is contained in:
Ivan Gavrilovic
2019-03-21 11:29:41 +00:00
committed by Alexey Tsvetkov
parent 57dca2ada5
commit 0c09f56118
13 changed files with 212 additions and 17 deletions
@@ -44,7 +44,7 @@ class TestInheritedAnnotation {
srcFiles,
listOf(processor),
generatedSources
) { trees -> MentionedTypesTaskListener(cache.javaCache, trees) }
) { elementUtils, trees -> MentionedTypesTaskListener(cache.javaCache, elementUtils, trees) }
cache.updateCache(listOf(processor))
}
}
@@ -0,0 +1,100 @@
/*
* Copyright 2010-2019 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 org.jetbrains.kotlin.kapt.base.test.org.jetbrains.kotlin.kapt3.base.incremental
import org.jetbrains.kotlin.kapt3.base.incremental.JavaClassCacheManager
import org.jetbrains.kotlin.kapt3.base.incremental.MentionedTypesTaskListener
import org.junit.Assert.assertEquals
import org.junit.BeforeClass
import org.junit.ClassRule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import java.io.File
private val MY_TEST_DIR = File("plugins/kapt3/kapt3-base/testData/runner/incremental/constants")
class ReferencedConstantsTest {
companion object {
@ClassRule
@JvmField
var tmp = TemporaryFolder()
private lateinit var cache: JavaClassCacheManager
private lateinit var generatedSources: File
@JvmStatic
@BeforeClass
fun setUp() {
val compiledClasses = tmp.newFolder()
compileSources(listOf(MY_TEST_DIR.resolve("CKlass.java")), compiledClasses)
val classpathHistory = tmp.newFolder()
cache = JavaClassCacheManager(tmp.newFolder(), classpathHistory)
generatedSources = tmp.newFolder()
cache.close()
classpathHistory.resolve("0").createNewFile()
val processor = SimpleProcessor().toAggregating()
val srcFiles = listOf(
"A.java",
"B.java",
"AnnotationA.java",
"AnnotatedType.java"
).map { File(MY_TEST_DIR, it) }
runAnnotationProcessing(
srcFiles,
listOf(processor),
generatedSources,
listOf(compiledClasses)
) { elements, trees -> MentionedTypesTaskListener(cache.javaCache, elements, trees) }
cache.updateCache(listOf(processor))
}
}
@Test
fun testConstantInField() {
val klassA = cache.javaCache.getStructure(MY_TEST_DIR.resolve("A.java"))!!
assertEquals(setOf("test.A"), klassA.getDeclaredTypes())
assertEquals(emptySet<String>(), klassA.getMentionedAnnotations())
assertEquals(emptySet<String>(), klassA.getPrivateTypes())
assertEquals(setOf("test.A"), klassA.getMentionedTypes())
assertEquals(
mapOf(
"test.B" to setOf("INT_VALUE"),
"test.CKlass" to setOf("INT_VALUE")
), klassA.getMentionedConstants()
)
}
@Test
fun testConstantInDefaultValue() {
val annotationA = cache.javaCache.getStructure(MY_TEST_DIR.resolve("AnnotationA.java"))!!
assertEquals(setOf("test.AnnotationA"), annotationA.getDeclaredTypes())
assertEquals(emptySet<String>(), annotationA.getMentionedAnnotations())
assertEquals(emptySet<String>(), annotationA.getPrivateTypes())
assertEquals(setOf("test.AnnotationA"), annotationA.getMentionedTypes())
assertEquals(mapOf("test.B" to setOf("INT_VALUE")), annotationA.getMentionedConstants()
)
}
@Test
fun testConstantInAnnotationElementValue() {
val annotated = cache.javaCache.getStructure(MY_TEST_DIR.resolve("AnnotatedType.java"))!!
assertEquals(setOf("test.AnnotatedType"), annotated.getDeclaredTypes())
assertEquals(setOf("test.AnnotationA"), annotated.getMentionedAnnotations())
assertEquals(emptySet<String>(), annotated.getPrivateTypes())
assertEquals(setOf("test.AnnotatedType", "test.AnnotationA"), annotated.getMentionedTypes())
assertEquals(
mapOf(
"test.B" to setOf("INT_VALUE"),
"test.CKlass" to setOf("INT_VALUE")
), annotated.getMentionedConstants()
)
}
}
@@ -48,7 +48,7 @@ class TestComplexIncrementalAptCache {
srcFiles,
listOf(processor),
generatedSources
) { trees -> MentionedTypesTaskListener(cache.javaCache, trees) }
) { elements, trees -> MentionedTypesTaskListener(cache.javaCache, elements, trees) }
cache.updateCache(listOf(processor))
}
}
@@ -73,7 +73,7 @@ class TestSimpleIncrementalAptCache {
srcFiles,
listOf(processor),
generatedSources
) { elementUtils -> MentionedTypesTaskListener(cache.javaCache, elementUtils) }
) { elementUtils, trees -> MentionedTypesTaskListener(cache.javaCache, elementUtils, trees) }
cache.updateCache(listOf(processor))
}
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.kapt.base.test.org.jetbrains.kotlin.kapt3.base.incremental
import com.sun.source.util.TaskListener
import com.sun.source.util.Trees
import com.sun.tools.javac.api.JavacTaskImpl
import org.jetbrains.kotlin.kapt3.base.incremental.DeclaredProcType
import org.jetbrains.kotlin.kapt3.base.incremental.IncrementalProcessor
@@ -27,7 +28,8 @@ fun runAnnotationProcessing(
srcFiles: List<File>,
processor: List<IncrementalProcessor>,
generatedSources: File,
listener: (Elements) -> TaskListener? = { null }
classpath: List<File> = emptyList(),
listener: (Elements, Trees) -> TaskListener? = { _, _ -> null }
) {
val compiler = ToolProvider.getSystemJavaCompiler()
compiler.getStandardFileManager(null, null, null).use { fileManager ->
@@ -37,12 +39,12 @@ fun runAnnotationProcessing(
null,
fileManager,
null,
listOf("-proc:only", "-s", generatedSources.absolutePath, "-d", generatedSources.absolutePath),
listOf("-proc:only", "-s", generatedSources.absolutePath, "-d", generatedSources.absolutePath, "-cp", classpath.joinToString(separator = File.pathSeparator)),
null,
javaSrcs
) as JavacTaskImpl
val taskListener = listener(compilationTask.elements)
val taskListener = listener(compilationTask.elements, Trees.instance(compilationTask))
taskListener?.let { compilationTask.addTaskListener(it) }
compilationTask.setProcessors(processor)