Repository: evant/kotlin-inject (kotlin)

Issue:
Print full name of nested types in error messages
When `kotlin-inject` is unable to find a provider for a type that's nested inside another type, it only prints its simple name. For example, `Factory` instead of `SomeClass.Factory`. This makes it slightly difficult to immediately recognize the type's name. Can the name of nested types prefixed with their parent class(es)?

```diff
- e: [ksp] Cannot find an @Inject constructor or provider for: Factory
+ e: [ksp] Cannot find an @Inject constructor or provider for: SomeClass.Factory
```

Pull request:
This makes it easier to find what class error messages are referring too
as well as fixes an incorrect cache hit when 2 inner classes in the root
package share a name.

Fixes #166, #192

Patch:
diff --git a/ast/core/src/main/kotlin/me/tatarka/kotlin/ast/Ast.kt b/ast/core/src/main/kotlin/me/tatarka/kotlin/ast/Ast.kt
index 13f5c2d7..2bc0518e 100644
--- a/ast/core/src/main/kotlin/me/tatarka/kotlin/ast/Ast.kt
+++ b/ast/core/src/main/kotlin/me/tatarka/kotlin/ast/Ast.kt
@@ -83,7 +83,7 @@ abstract class AstClass : AstElement(), AstAnnotated, AstHasModifiers {
     abstract override fun hashCode(): Int
 
     override fun toString(): String {
-        return if (packageName.isEmpty() || packageName == "kotlin") name else type.toString()
+        return type.toString()
     }
 
     abstract fun toClassName(): ClassName


Test patch:
diff --git a/integration-tests/common/src/test/kotlin/me/tatarka/inject/test/InnerClassComponentTest.kt b/integration-tests/common/src/test/kotlin/me/tatarka/inject/test/InnerClassComponentTest.kt
index 483d071c..512a60e7 100644
--- a/integration-tests/common/src/test/kotlin/me/tatarka/inject/test/InnerClassComponentTest.kt
+++ b/integration-tests/common/src/test/kotlin/me/tatarka/inject/test/InnerClassComponentTest.kt
@@ -1,16 +1,25 @@
-package me.tatarka.inject.test
+// package is omitted to place this in the root to catch issues where inner class of the same name were not seen as
+// district. See https://github.com/evant/kotlin-inject/issues/192
 
+import assertk.assertThat
+import assertk.assertions.isNotNull
 import me.tatarka.inject.annotations.Component
+import me.tatarka.inject.test.Baz
+import me.tatarka.inject.test.Foo
 import kotlin.test.Test
 
 class Inner1 {
     @Component
-    abstract class InnerClassComponent
+    abstract class InnerClassComponent {
+        abstract val foo: Foo
+    }
 }
 
 class Inner2 {
     @Component
-    abstract class InnerClassComponent
+    abstract class InnerClassComponent {
+        abstract val baz: Baz
+    }
 }
 
 class InnerClassComponentTest {
@@ -18,5 +27,8 @@ class InnerClassComponentTest {
     fun generates_components_in_an_inner_class_with_a_unique_name() {
         val component1 = Inner1.InnerClassComponent::class.create()
         val component2 = Inner2.InnerClassComponent::class.create()
+
+        assertThat(component1.foo).isNotNull()
+        assertThat(component2.baz).isNotNull()
     }
 }
\ No newline at end of file
diff --git a/kotlin-inject-compiler/test/src/test/kotlin/me/tatarka/inject/test/FailureTest.kt b/kotlin-inject-compiler/test/src/test/kotlin/me/tatarka/inject/test/FailureTest.kt
index 8f0f455f..a7512eb6 100644
--- a/kotlin-inject-compiler/test/src/test/kotlin/me/tatarka/inject/test/FailureTest.kt
+++ b/kotlin-inject-compiler/test/src/test/kotlin/me/tatarka/inject/test/FailureTest.kt
@@ -149,6 +149,25 @@ class FailureTest {
             .contains("Cannot find an @Inject constructor or provider for: String")
     }
 
+    @ParameterizedTest
+    @EnumSource(Target::class)
+    fun fails_if_inner_type_is_missing_inject(target: Target) {
+        val projectCompiler = ProjectCompiler(target, workingDir)
+        assertThat {
+            projectCompiler.source(
+                "MyComponent.kt",
+                """
+                import me.tatarka.inject.annotations.Component
+                class Foo { class Factory } 
+                @Component abstract class MyComponent {
+                    abstract fun provideFoo(): Foo.Factory
+                }
+                """.trimIndent()
+            ).compile()
+        }.isFailure().output()
+            .contains("Cannot find an @Inject constructor or provider for: Foo.Factory")
+    }
+
     @ParameterizedTest
     @EnumSource(Target::class)
     fun fails_if_type_cannot_be_provided_to_constructor(target: Target) {