Skip to content

Commit

Permalink
Resolve typealiases and remove lenient mode
Browse files Browse the repository at this point in the history
After some discussion [here](google/dagger#4356) I learned we should be handling this ourselves
  • Loading branch information
ZacSweers committed Jul 17, 2024
1 parent 145a791 commit c9fcda8
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.KSDeclaration
import com.google.devtools.ksp.symbol.KSFunctionDeclaration
import com.google.devtools.ksp.symbol.KSType
import com.google.devtools.ksp.symbol.KSTypeAlias
import com.google.devtools.ksp.symbol.Visibility
import com.squareup.anvil.annotations.ContributesMultibinding
import com.squareup.kotlinpoet.AnnotationSpec
Expand Down Expand Up @@ -128,8 +129,6 @@ private class CircuitSymbolProcessor(
private val platforms: List<PlatformInfo>,
) : SymbolProcessor {

private val lenient = options["circuit.codegen.lenient"]?.toBoolean() ?: false

override fun process(resolver: Resolver): List<KSAnnotated> {
val symbols = CircuitSymbols.create(resolver) ?: return emptyList()
val codegenMode =
Expand Down Expand Up @@ -174,7 +173,7 @@ private class CircuitSymbolProcessor(
codegenMode: CodegenMode,
) {
val circuitInjectAnnotation =
annotatedElement.getKSAnnotationsWithLeniency(CIRCUIT_INJECT_ANNOTATION).single()
annotatedElement.getKSAnnotationsOfType(CIRCUIT_INJECT_ANNOTATION.canonicalName).single()

// If we annotated a class, check that the class isn't using assisted inject. If so, error and
// return
Expand Down Expand Up @@ -269,7 +268,7 @@ private class CircuitSymbolProcessor(
annotation: KClass<out Annotation>
): KSFunctionDeclaration? {
return getConstructors().singleOrNull { constructor ->
constructor.isAnnotationPresentWithLeniency(annotation)
constructor.isAnnotationPresentOfType(annotation)
}
}

Expand All @@ -278,7 +277,7 @@ private class CircuitSymbolProcessor(
if (findConstructorAnnotatedWith(AssistedInject::class) != null) {
val assistedFactory =
declarations.filterIsInstance<KSClassDeclaration>().find {
it.isAnnotationPresentWithLeniency(AssistedFactory::class)
it.isAnnotationPresentOfType(AssistedFactory::class)
}
val suffix =
if (assistedFactory != null) " (${assistedFactory.qualifiedName?.asString()})" else ""
Expand All @@ -291,24 +290,31 @@ private class CircuitSymbolProcessor(
}
}

private fun KSAnnotated.isAnnotationPresentWithLeniency(annotation: KClass<out Annotation>) =
getKSAnnotationsWithLeniency(annotation).any()

private fun KSAnnotated.getKSAnnotationsWithLeniency(annotation: KClass<out Annotation>) =
getKSAnnotationsWithLeniency(annotation.asClassName())

private fun KSAnnotated.getKSAnnotationsWithLeniency(
annotation: ClassName
): Sequence<KSAnnotation> {
val simpleName = annotation.simpleName
return if (lenient) {
annotations.filter { it.shortName.asString() == simpleName }
} else {
val qualifiedName = annotation.canonicalName
this.annotations.filter {
it.shortName.getShortName() == simpleName &&
it.annotationType.resolve().declaration.qualifiedName?.asString() == qualifiedName
private fun KSAnnotated.isAnnotationPresentOfType(annotation: KClass<out Annotation>) =
getKSAnnotationsOfType(annotation).any()

private fun KSAnnotated.getKSAnnotationsOfType(annotation: KClass<out Annotation>) =
getKSAnnotationsOfType(annotation.qualifiedName!!)

private fun KSAnnotated.getKSAnnotationsOfType(qualifiedName: String): Sequence<KSAnnotation> {
return this.annotations.filter {
it.annotationType
.resolve()
.declaration
.resolveKSClassDeclaration()
?.qualifiedName
?.asString() == qualifiedName
}
}

private fun KSDeclaration.resolveKSClassDeclaration(): KSClassDeclaration? {
return when (this) {
is KSClassDeclaration -> this
is KSTypeAlias -> {
// Note: doesn't work for generic aliased types, but we only use this for CircuitInject
type.resolve().declaration.resolveKSClassDeclaration()
}
else -> null
}
}

Expand Down Expand Up @@ -438,7 +444,7 @@ private class CircuitSymbolProcessor(
declaration.checkVisibility(logger) {
return null
}
val isAssisted = declaration.isAnnotationPresentWithLeniency(AssistedFactory::class)
val isAssisted = declaration.isAnnotationPresentOfType(AssistedFactory::class)
val creatorOrConstructor: KSFunctionDeclaration?
val targetClass: KSClassDeclaration
if (isAssisted) {
Expand Down
10 changes: 0 additions & 10 deletions docs/code-gen.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,6 @@ ksp {
}
```

If using Kotlin multiplatform with typealias annotations for Dagger annotations (i.e. expect
annotations in common with actual typealias declarations in JVM source sets), you can match on just
annotation short names alone to support this case via `circuit.codegen.lenient` mode.

```kotlin
ksp {
arg("circuit.codegen.lenient", "true")
}
```

## Usage

The primary entry point is the `CircuitInject` annotation.
Expand Down
2 changes: 0 additions & 2 deletions samples/star/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,6 @@ afterEvaluate {
}
}

ksp { arg("circuit.codegen.lenient", "true") }

dependencies {
for (target in kspTargets) {
val targetConfigSuffix = if (target == "Metadata") "CommonMainMetadata" else target
Expand Down

0 comments on commit c9fcda8

Please sign in to comment.