Skip to content

Commit 6cbe464

Browse files
committed
support multiple depth search for annotated symbols
1 parent ae98b8c commit 6cbe464

File tree

6 files changed

+102
-16
lines changed

6 files changed

+102
-16
lines changed

api/src/main/kotlin/com/google/devtools/ksp/processing/Resolver.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@ interface Resolver {
3434
/**
3535
* Get all symbols with specified annotation.
3636
*
37-
* @param annotationName is the full qualified name of the annotation; using '.' as separator.
37+
* @param annotationName is the fully qualified name of the annotation; using '.' as separator.
38+
* @param inDepth whether to check symbols in depth, i.e. check symbols from local declarations. Operation can be expensive if true.
3839
* @return Elements annotated with the specified annotation.
3940
*/
40-
fun getSymbolsWithAnnotation(annotationName: String): List<KSAnnotated>
41+
fun getSymbolsWithAnnotation(annotationName: String, inDepth: Boolean = false): List<KSAnnotated>
4142

4243
/**
4344
* Find a class in the compilation classpath for the given name.

compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt

+28-13
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,10 @@ class ResolverImpl(
176176
}
177177
}
178178

179-
override fun getSymbolsWithAnnotation(annotationName: String): List<KSAnnotated> {
179+
override fun getSymbolsWithAnnotation(annotationName: String, inDepth: Boolean): List<KSAnnotated> {
180180
val ksName = KSNameImpl.getCached(annotationName)
181181

182-
val visitor = object : BaseVisitor() {
182+
val visitor = object : KSVisitorVoid() {
183183
val symbols = mutableSetOf<KSAnnotated>()
184184
override fun visitAnnotated(annotated: KSAnnotated, data: Unit) {
185185
if (annotated.annotations.any {
@@ -192,31 +192,46 @@ class ResolverImpl(
192192
}
193193
}
194194

195-
override fun visitClassDeclaration(type: KSClassDeclaration, data: Unit) {
196-
visitAnnotated(type, data)
197-
super.visitClassDeclaration(type, data)
195+
override fun visitFile(file: KSFile, data: Unit) {
196+
visitAnnotated(file, data)
197+
file.declarations.map { it.accept(this, data) }
198+
}
199+
200+
override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) {
201+
visitAnnotated(classDeclaration, data)
202+
classDeclaration.typeParameters.map { it.accept(this, data) }
203+
classDeclaration.declarations.map { it.accept(this, data) }
204+
classDeclaration.primaryConstructor?.let { it.accept(this, data) }
205+
}
206+
207+
override fun visitPropertyGetter(getter: KSPropertyGetter, data: Unit) {
208+
visitAnnotated(getter, data)
209+
}
210+
211+
override fun visitPropertySetter(setter: KSPropertySetter, data: Unit) {
212+
visitAnnotated(setter, data)
198213
}
199214

200215
override fun visitFunctionDeclaration(function: KSFunctionDeclaration, data: Unit) {
201216
visitAnnotated(function, data)
202-
super.visitFunctionDeclaration(function, data)
217+
function.typeParameters.map { it.accept(this, data) }
218+
function.parameters.map { it.accept(this, data) }
219+
if (inDepth) {
220+
function.declarations.map { it.accept(this, data) }
221+
}
203222
}
204223

205224
override fun visitPropertyDeclaration(property: KSPropertyDeclaration, data: Unit) {
206225
visitAnnotated(property, data)
207-
super.visitPropertyDeclaration(property, data)
226+
property.typeParameters.map { it.accept(this, data) }
227+
property.getter?.let { it.accept(this, data) }
228+
property.setter?.let { it.accept(this, data) }
208229
}
209230

210231
override fun visitTypeParameter(typeParameter: KSTypeParameter, data: Unit) {
211232
visitAnnotated(typeParameter, data)
212233
super.visitTypeParameter(typeParameter, data)
213234
}
214-
215-
override fun visitTypeReference(typeReference: KSTypeReference, data: Unit) {
216-
visitAnnotated(typeReference, data)
217-
super.visitTypeReference(typeReference, data)
218-
}
219-
220235
}
221236

222237
for (file in ksFiles) {

compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processor/AnnotationArgumentProcessor.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class AnnotationArgumentProcessor : AbstractTestProcessor() {
2929
val visitor = ArgumentVisitor()
3030

3131
override fun process(resolver: Resolver) {
32-
val symbol = resolver.getSymbolsWithAnnotation("Bar").single()
32+
val symbol = resolver.getSymbolsWithAnnotation("Bar", true).single()
3333
val annotation = (symbol as KSClassDeclaration).annotations.single()
3434
annotation.arguments.map { it.accept(visitor, Unit) }
3535
val C = resolver.getClassDeclarationByName("C")!!
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.google.devtools.ksp.processor
2+
3+
import com.google.devtools.ksp.processing.Resolver
4+
5+
class GetSymbolsFromAnnotationProcessor : AbstractTestProcessor() {
6+
val result = mutableListOf<String>()
7+
override fun toResult(): List<String> = result
8+
9+
override fun process(resolver: Resolver) {
10+
result.add("==== Anno superficial====")
11+
resolver.getSymbolsWithAnnotation("Anno").map { result.add(it.toString()) }
12+
result.add("==== Anno in depth ====")
13+
resolver.getSymbolsWithAnnotation("Anno", true).map { result.add(it.toString()) }
14+
result.add("==== Bnno superficial====")
15+
resolver.getSymbolsWithAnnotation("Bnno").map { result.add(it.toString()) }
16+
result.add("==== Bnno in depth ====")
17+
resolver.getSymbolsWithAnnotation("Bnno", true).map { result.add(it.toString()) }
18+
}
19+
}

compiler-plugin/src/test/java/com/google/devtools/ksp/test/KotlinKSPTestGenerated.java

+5
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ public void testFunctionTypeAlias() throws Exception {
9797
runTest("testData/api/functionTypeAlias.kt");
9898
}
9999

100+
@TestMetadata("getSymbolsFromAnnotation.kt")
101+
public void testGetSymbolsFromAnnotation() throws Exception {
102+
runTest("testData/api/getSymbolsFromAnnotation.kt");
103+
}
104+
100105
@TestMetadata("hello.kt")
101106
public void testHello() throws Exception {
102107
runTest("testData/api/hello.kt");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// TEST PROCESSOR: GetSymbolsFromAnnotationProcessor
2+
// EXPECTED:
3+
// ==== Anno superficial====
4+
// Foo
5+
// propertyFoo
6+
// functionFoo
7+
// constructorParameterFoo
8+
// Foo
9+
// ==== Anno in depth ====
10+
// Foo
11+
// propertyFoo
12+
// functionFoo
13+
// local
14+
// constructorParameterFoo
15+
// Foo
16+
// ==== Bnno superficial====
17+
// File: Foo.kt
18+
// Foo
19+
// propertyFoo.getter()
20+
// ==== Bnno in depth ====
21+
// File: Foo.kt
22+
// Foo
23+
// propertyFoo.getter()
24+
// END
25+
//FILE: annotations.kt
26+
annotation class Anno
27+
annotation class Bnno
28+
29+
//FILE: Foo.kt
30+
@file:Bnno
31+
32+
@Anno
33+
class Foo @Anno constructor(@Anno val constructorParameterFoo: Int){
34+
@Bnno constructor() {
35+
36+
}
37+
38+
@Anno
39+
val propertyFoo: String
40+
@Bnno get() = TODO()
41+
42+
@Anno
43+
fun functionFoo(@Anno p1: Int, @Bnno p2: Int) {
44+
@Anno val local = 1
45+
}
46+
}

0 commit comments

Comments
 (0)