Skip to content

Commit c9fcda8

Browse files
committed
Resolve typealiases and remove lenient mode
After some discussion [here](google/dagger#4356) I learned we should be handling this ourselves
1 parent 145a791 commit c9fcda8

File tree

3 files changed

+29
-35
lines changed

3 files changed

+29
-35
lines changed

circuit-codegen/src/main/kotlin/com/slack/circuit/codegen/CircuitSymbolProcessorProvider.kt

+29-23
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import com.google.devtools.ksp.symbol.KSClassDeclaration
2626
import com.google.devtools.ksp.symbol.KSDeclaration
2727
import com.google.devtools.ksp.symbol.KSFunctionDeclaration
2828
import com.google.devtools.ksp.symbol.KSType
29+
import com.google.devtools.ksp.symbol.KSTypeAlias
2930
import com.google.devtools.ksp.symbol.Visibility
3031
import com.squareup.anvil.annotations.ContributesMultibinding
3132
import com.squareup.kotlinpoet.AnnotationSpec
@@ -128,8 +129,6 @@ private class CircuitSymbolProcessor(
128129
private val platforms: List<PlatformInfo>,
129130
) : SymbolProcessor {
130131

131-
private val lenient = options["circuit.codegen.lenient"]?.toBoolean() ?: false
132-
133132
override fun process(resolver: Resolver): List<KSAnnotated> {
134133
val symbols = CircuitSymbols.create(resolver) ?: return emptyList()
135134
val codegenMode =
@@ -174,7 +173,7 @@ private class CircuitSymbolProcessor(
174173
codegenMode: CodegenMode,
175174
) {
176175
val circuitInjectAnnotation =
177-
annotatedElement.getKSAnnotationsWithLeniency(CIRCUIT_INJECT_ANNOTATION).single()
176+
annotatedElement.getKSAnnotationsOfType(CIRCUIT_INJECT_ANNOTATION.canonicalName).single()
178177

179178
// If we annotated a class, check that the class isn't using assisted inject. If so, error and
180179
// return
@@ -269,7 +268,7 @@ private class CircuitSymbolProcessor(
269268
annotation: KClass<out Annotation>
270269
): KSFunctionDeclaration? {
271270
return getConstructors().singleOrNull { constructor ->
272-
constructor.isAnnotationPresentWithLeniency(annotation)
271+
constructor.isAnnotationPresentOfType(annotation)
273272
}
274273
}
275274

@@ -278,7 +277,7 @@ private class CircuitSymbolProcessor(
278277
if (findConstructorAnnotatedWith(AssistedInject::class) != null) {
279278
val assistedFactory =
280279
declarations.filterIsInstance<KSClassDeclaration>().find {
281-
it.isAnnotationPresentWithLeniency(AssistedFactory::class)
280+
it.isAnnotationPresentOfType(AssistedFactory::class)
282281
}
283282
val suffix =
284283
if (assistedFactory != null) " (${assistedFactory.qualifiedName?.asString()})" else ""
@@ -291,24 +290,31 @@ private class CircuitSymbolProcessor(
291290
}
292291
}
293292

294-
private fun KSAnnotated.isAnnotationPresentWithLeniency(annotation: KClass<out Annotation>) =
295-
getKSAnnotationsWithLeniency(annotation).any()
296-
297-
private fun KSAnnotated.getKSAnnotationsWithLeniency(annotation: KClass<out Annotation>) =
298-
getKSAnnotationsWithLeniency(annotation.asClassName())
299-
300-
private fun KSAnnotated.getKSAnnotationsWithLeniency(
301-
annotation: ClassName
302-
): Sequence<KSAnnotation> {
303-
val simpleName = annotation.simpleName
304-
return if (lenient) {
305-
annotations.filter { it.shortName.asString() == simpleName }
306-
} else {
307-
val qualifiedName = annotation.canonicalName
308-
this.annotations.filter {
309-
it.shortName.getShortName() == simpleName &&
310-
it.annotationType.resolve().declaration.qualifiedName?.asString() == qualifiedName
293+
private fun KSAnnotated.isAnnotationPresentOfType(annotation: KClass<out Annotation>) =
294+
getKSAnnotationsOfType(annotation).any()
295+
296+
private fun KSAnnotated.getKSAnnotationsOfType(annotation: KClass<out Annotation>) =
297+
getKSAnnotationsOfType(annotation.qualifiedName!!)
298+
299+
private fun KSAnnotated.getKSAnnotationsOfType(qualifiedName: String): Sequence<KSAnnotation> {
300+
return this.annotations.filter {
301+
it.annotationType
302+
.resolve()
303+
.declaration
304+
.resolveKSClassDeclaration()
305+
?.qualifiedName
306+
?.asString() == qualifiedName
307+
}
308+
}
309+
310+
private fun KSDeclaration.resolveKSClassDeclaration(): KSClassDeclaration? {
311+
return when (this) {
312+
is KSClassDeclaration -> this
313+
is KSTypeAlias -> {
314+
// Note: doesn't work for generic aliased types, but we only use this for CircuitInject
315+
type.resolve().declaration.resolveKSClassDeclaration()
311316
}
317+
else -> null
312318
}
313319
}
314320

@@ -438,7 +444,7 @@ private class CircuitSymbolProcessor(
438444
declaration.checkVisibility(logger) {
439445
return null
440446
}
441-
val isAssisted = declaration.isAnnotationPresentWithLeniency(AssistedFactory::class)
447+
val isAssisted = declaration.isAnnotationPresentOfType(AssistedFactory::class)
442448
val creatorOrConstructor: KSFunctionDeclaration?
443449
val targetClass: KSClassDeclaration
444450
if (isAssisted) {

docs/code-gen.md

-10
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,6 @@ ksp {
2424
}
2525
```
2626

27-
If using Kotlin multiplatform with typealias annotations for Dagger annotations (i.e. expect
28-
annotations in common with actual typealias declarations in JVM source sets), you can match on just
29-
annotation short names alone to support this case via `circuit.codegen.lenient` mode.
30-
31-
```kotlin
32-
ksp {
33-
arg("circuit.codegen.lenient", "true")
34-
}
35-
```
36-
3727
## Usage
3828

3929
The primary entry point is the `CircuitInject` annotation.

samples/star/build.gradle.kts

-2
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,6 @@ afterEvaluate {
291291
}
292292
}
293293

294-
ksp { arg("circuit.codegen.lenient", "true") }
295-
296294
dependencies {
297295
for (target in kspTargets) {
298296
val targetConfigSuffix = if (target == "Metadata") "CommonMainMetadata" else target

0 commit comments

Comments
 (0)