Skip to content

Commit 2220981

Browse files
authored
Generate graph when @Inject is typealiased (#234)
Follow typealias for annotations
1 parent dd92851 commit 2220981

File tree

2 files changed

+93
-6
lines changed

2 files changed

+93
-6
lines changed

ast/ksp/src/main/kotlin/me/tatarka/kotlin/ast/KSUtil.kt

+9-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.google.devtools.ksp.symbol.KSAnnotated
44
import com.google.devtools.ksp.symbol.KSAnnotation
55
import com.google.devtools.ksp.symbol.KSDeclaration
66
import com.google.devtools.ksp.symbol.KSType
7+
import com.google.devtools.ksp.symbol.KSTypeAlias
78
import com.google.devtools.ksp.symbol.KSTypeParameter
89
import com.google.devtools.ksp.symbol.KSTypeReference
910
import me.tatarka.kotlin.ast.internal.HashCollector
@@ -25,12 +26,14 @@ internal fun KSAnnotated.hasAnnotation(packageName: String, simpleName: String):
2526
return annotations.any { it.hasName(packageName, simpleName) }
2627
}
2728

28-
private fun KSAnnotation.hasName(packageName: String, simpleName: String): Boolean {
29-
// we can skip resolving if the short name doesn't match
30-
if (shortName.asString() != simpleName) return false
31-
val declaration = annotationType.resolve().declaration
32-
return declaration.packageName.asString() == packageName
33-
}
29+
private fun KSAnnotation.hasName(packageName: String, simpleName: String): Boolean =
30+
annotationType.resolve().declaration.hasName(packageName, simpleName)
31+
32+
private tailrec fun KSDeclaration.hasName(packageName: String, simpleName: String): Boolean =
33+
when (this) {
34+
is KSTypeAlias -> type.resolve().declaration.hasName(packageName, simpleName)
35+
else -> this.simpleName.asString() == simpleName && this.packageName.asString() == packageName
36+
}
3437

3538
/**
3639
* package name except root is "" instead of "<root>"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package me.tatarka.inject.test
2+
3+
import assertk.assertThat
4+
import assertk.assertions.isNotNull
5+
import me.tatarka.inject.annotations.Component
6+
import me.tatarka.inject.annotations.Inject
7+
import kotlin.test.Test
8+
9+
typealias InjectTypeAlias = Inject
10+
11+
class FooWithPrimaryConstructorInjectTypeAlias @InjectTypeAlias constructor()
12+
13+
class FooWithSecondaryConstructorInjectTypeAlias(private val prop: String) {
14+
15+
@InjectTypeAlias
16+
constructor() : this("prop")
17+
}
18+
19+
@InjectTypeAlias
20+
class FooWithInjectTypeAlias
21+
22+
typealias fooWithPrimaryCreator = () -> FooWithPrimaryConstructorInjectTypeAlias
23+
24+
@InjectTypeAlias
25+
fun fooWithPrimaryCreator(foo: FooWithPrimaryConstructorInjectTypeAlias) = foo
26+
27+
typealias TypeAliasToInjectTypeAlias = InjectTypeAlias
28+
29+
typealias TypeAliasToTypeAliasToInjectTypeAlias = TypeAliasToInjectTypeAlias
30+
31+
@TypeAliasToTypeAliasToInjectTypeAlias
32+
class FooWithTypeAliasToTypeAliasToTypeAlias
33+
34+
@Component
35+
abstract class InjectTypeAliasComponent {
36+
37+
abstract val primaryConstructorWithInjectTypeAlias: FooWithPrimaryConstructorInjectTypeAlias
38+
39+
abstract val secondaryConstructorWithInjectTypeAlias: FooWithSecondaryConstructorInjectTypeAlias
40+
41+
abstract val classWithInjectTypeAlias: FooWithInjectTypeAlias
42+
43+
abstract val functionWithInjectTypeAlias: fooWithPrimaryCreator
44+
45+
abstract val fooWithTypeAliasToTypeAliasToTypeAlias: FooWithTypeAliasToTypeAliasToTypeAlias
46+
}
47+
48+
class TypeAliasInjectTest {
49+
50+
@Test
51+
fun can_generate_for_inject_typealias_on_primary_constructor() {
52+
val component = InjectTypeAliasComponent::class.create()
53+
54+
assertThat(component.primaryConstructorWithInjectTypeAlias).isNotNull()
55+
}
56+
57+
@Test
58+
fun can_generate_for_inject_typealias_on_secondary_constructor() {
59+
val component = InjectTypeAliasComponent::class.create()
60+
61+
assertThat(component.secondaryConstructorWithInjectTypeAlias).isNotNull()
62+
}
63+
64+
@Test
65+
fun can_generate_for_inject_typealias_on_class() {
66+
val component = InjectTypeAliasComponent::class.create()
67+
68+
assertThat(component.classWithInjectTypeAlias).isNotNull()
69+
}
70+
71+
@Test
72+
fun can_generate_for_inject_typealias_on_function() {
73+
val component = InjectTypeAliasComponent::class.create()
74+
75+
assertThat(component.functionWithInjectTypeAlias).isNotNull()
76+
}
77+
78+
@Test
79+
fun can_generate_for_type_alias_to_type_alias_to_inject_type_alias_on_class() {
80+
val component = InjectTypeAliasComponent::class.create()
81+
82+
assertThat(component.fooWithTypeAliasToTypeAliasToTypeAlias).isNotNull()
83+
}
84+
}

0 commit comments

Comments
 (0)