Repository: evant/kotlin-inject
Pull request #30 (2020-08-02 22:30:57)

Fix obtaining annotations for properties


Patch:
diff --git a/kotlin-inject-compiler-kapt/src/main/kotlin/me/tatarka/inject/compiler/kapt/ModelAst.kt b/kotlin-inject-compiler-kapt/src/main/kotlin/me/tatarka/inject/compiler/kapt/ModelAst.kt
index 83ff1af..0a25f85 100644
--- a/kotlin-inject-compiler-kapt/src/main/kotlin/me/tatarka/inject/compiler/kapt/ModelAst.kt
+++ b/kotlin-inject-compiler-kapt/src/main/kotlin/me/tatarka/inject/compiler/kapt/ModelAst.kt
@@ -333,9 +333,9 @@ private class ModelAstProperty(
         }
 
     private val annotatedElement: Element? by lazy {
-        val javaName = kmProperty.syntheticMethodForAnnotations?.name ?: return@lazy null
+        val signature = kmProperty.syntheticMethodForAnnotations ?: return@lazy null
         for (method in ElementFilter.methodsIn(element.enclosingElement.enclosedElements)) {
-            if (method.simpleName.contentEquals(javaName)) {
+            if (method.matches(signature)) {
                 return@lazy method
             }
         }
diff --git a/kotlin-inject-compiler-kapt/src/main/kotlin/me/tatarka/inject/compiler/kapt/Util.kt b/kotlin-inject-compiler-kapt/src/main/kotlin/me/tatarka/inject/compiler/kapt/Util.kt
index f912682..a8b0887 100644
--- a/kotlin-inject-compiler-kapt/src/main/kotlin/me/tatarka/inject/compiler/kapt/Util.kt
+++ b/kotlin-inject-compiler-kapt/src/main/kotlin/me/tatarka/inject/compiler/kapt/Util.kt
@@ -108,16 +108,82 @@ fun ExecutableElement.matches(function: KmFunction): Boolean {
     return true
 }
 
+fun ExecutableElement.matches(signature: JvmMethodSignature): Boolean {
+    if (!nameMatches(signature)) {
+        return false
+    }
+    //ex: (Lme/tatarka/inject/test/Bar;)V
+    var index = 1 // skip initial (
+    val parameterTypes = mutableListOf<String>()
+    val desc = signature.desc
+    loop@while (true) {
+        when (desc[index]) {
+            'L' -> {
+                index++
+                val className = desc.substring(index, desc.indexOf(';', index))
+                parameterTypes.add(className)
+                index += className.length
+            }
+            'Z' -> {
+                index++
+                parameterTypes.add("Boolean")
+            }
+            'B' -> {
+                index++
+                parameterTypes.add("Byte")
+            }
+            'C' -> {
+                index++
+                parameterTypes.add("Char")
+            }
+            'S' -> {
+                index++
+                parameterTypes.add("Short")
+            }
+            'I' -> {
+                index++
+                parameterTypes.add("Int")
+            }
+            'J' -> {
+                index++
+                parameterTypes.add("Long")
+            }
+            'F' -> {
+                index++
+                parameterTypes.add("Float")
+            }
+            'D' -> {
+                index++
+                parameterTypes.add("Double")
+            }
+            else -> break@loop
+        }
+    }
+    if (parameters.size != parameterTypes.size) {
+        return false
+    }
+    for (i in 0 until parameterTypes.size) {
+        if (!parameters[i].asType().matches(parameterTypes[i])) {
+            return false
+        }
+    }
+    return true
+}
+
 private fun TypeMirror.matches(type: KmType): Boolean {
     return when (val classifier = type.classifier) {
         is KmClassifier.Class -> {
-            asTypeName().javaToKotlinType().toString() == classifier.name.replace("/", ".")
+            matches(classifier.name)
         }
         is KmClassifier.TypeParameter -> false
         is KmClassifier.TypeAlias -> false
     }
 }
 
+private fun TypeMirror.matches(typeName: String): Boolean {
+    return asTypeName().javaToKotlinType().toString() == typeName.replace("/", ".")
+}
+
 private fun ExecutableElement.nameMatches(signature: JvmMemberSignature?): Boolean {
     if (signature == null) return false
     return simpleName.contentEquals(signature.name)


Test patch:
diff --git a/integration-tests/src/test/kotlin/me/tatarka/inject/test/Models.kt b/integration-tests/src/test/kotlin/me/tatarka/inject/test/Models.kt
index 608b631..ca54d50 100644
--- a/integration-tests/src/test/kotlin/me/tatarka/inject/test/Models.kt
+++ b/integration-tests/src/test/kotlin/me/tatarka/inject/test/Models.kt
@@ -19,6 +19,8 @@ var fooConstructorCount = 0
 
 @Inject data class Bar(val foo: Foo) : IFoo
 
+@Inject class Baz: IFoo
+
 class NamedFoo(val name: String)
 
 interface INamedBar {
diff --git a/integration-tests/src/test/kotlin/me/tatarka/inject/test/MultibindsTest.kt b/integration-tests/src/test/kotlin/me/tatarka/inject/test/MultibindsTest.kt
index 6fe178a..6169393 100644
--- a/integration-tests/src/test/kotlin/me/tatarka/inject/test/MultibindsTest.kt
+++ b/integration-tests/src/test/kotlin/me/tatarka/inject/test/MultibindsTest.kt
@@ -1,11 +1,8 @@
 package me.tatarka.inject.test
 
 import assertk.assertThat
-import me.tatarka.inject.annotations.Component
-import me.tatarka.inject.annotations.IntoMap
-import me.tatarka.inject.annotations.IntoSet
-import me.tatarka.inject.annotations.Provides
 import assertk.assertions.containsOnly
+import me.tatarka.inject.annotations.*
 import kotlin.test.Test
 
 data class FooValue(val name: String)
@@ -30,8 +27,7 @@ data class FooValue(val name: String)
 
     @Provides @IntoMap
     val fooValue2
-        get() = "2" to FooValue("2")
-}
+        get() = "2" to FooValue("2") }
 
 @Component abstract class ParentSetComponent {
     @Provides @IntoSet
@@ -41,6 +37,11 @@ data class FooValue(val name: String)
     @Provides @IntoSet
     val Bar.bind: IFoo
         get() = this
+
+    // Should not be in the set
+    @Provides
+    val Baz.bind: IFoo
+        get() = this
 }
 
 @Component abstract class ChildSetComponent(@Component val parent: ParentSetComponent) {