Repository: evant/kotlin-inject
Pull request #40 (2020-08-15 23:28:00)

Fix code generation with nested with


Patch:
diff --git a/kotlin-inject-compiler-core/src/main/kotlin/me/tatarka/inject/compiler/InjectGenerator.kt b/kotlin-inject-compiler-core/src/main/kotlin/me/tatarka/inject/compiler/InjectGenerator.kt
index 55ff5cc..9eebb98 100644
--- a/kotlin-inject-compiler-core/src/main/kotlin/me/tatarka/inject/compiler/InjectGenerator.kt
+++ b/kotlin-inject-compiler-core/src/main/kotlin/me/tatarka/inject/compiler/InjectGenerator.kt
@@ -251,16 +251,29 @@ class InjectGenerator(provider: AstProvider, private val options: Options) :
 
             val receiverParamType = method.receiverParameterType
             val changeScope = providesResult.name != null && receiverParamType != null
+            val changeScopeName = providesResult.name?.let {
+                if (context.parentScopeName != null) {
+                    it.removePrefix("${context.parentScopeName}.")
+                } else {
+                    it
+                }
+            }
 
             if (providesResult.name != null) {
                 if (changeScope) {
-                    codeBlock.add("with(%L)", providesResult.name)
+                    codeBlock.add("with(%L)", changeScopeName)
                     codeBlock.beginControlFlow(" {")
                 } else {
-                    codeBlock.add("%L.", providesResult.name)
+                    codeBlock.add("%L.", changeScopeName)
                 }
             }
 
+            val context = if (changeScope) {
+                context.withParentScopeName(providesResult.name)
+            } else {
+                context
+            }
+
             when (method) {
                 is AstProperty -> {
                     if (receiverParamType != null) {
@@ -481,12 +494,18 @@ class InjectGenerator(provider: AstProvider, private val options: Options) :
         val cycleDetector: CycleDetector,
         val scopeInterface: AstClass? = null,
         val args: List<Pair<AstType, String>> = emptyList(),
-        val skipScoped: AstType? = null
+        val skipScoped: AstType? = null,
+        val parentScopeName: String? = null
     ) {
         fun withoutScoped(scoped: AstType) = copy(skipScoped = scoped)
 
         fun withSource(source: AstElement) = copy(source = source)
 
+        fun withParentScopeName(name: String?): Context {
+            if (name == null) return this
+            return copy(parentScopeName = if (parentScopeName == null) name else "$parentScopeName.$name")
+        }
+
         fun withArgs(args: List<Pair<AstType, String>>) = copy(args = args)
 
         fun <T> use(source: AstElement, f: (context: Context) -> T): T {


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 ca54d50..0918ec6 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
@@ -5,6 +5,8 @@ import me.tatarka.inject.annotations.Scope
 
 interface IFoo
 
+interface IBar
+
 var fooConstructorCount = 0
 
 @Inject class Foo : IFoo {
@@ -19,6 +21,8 @@ var fooConstructorCount = 0
 
 @Inject data class Bar(val foo: Foo) : IFoo
 
+@Inject data class BarImpl(val foo: IFoo): IBar
+
 @Inject class Baz: IFoo
 
 class NamedFoo(val name: String)
diff --git a/integration-tests/src/test/kotlin/me/tatarka/inject/test/NestedComponentTest.kt b/integration-tests/src/test/kotlin/me/tatarka/inject/test/NestedComponentTest.kt
index f72dcae..eeba361 100644
--- a/integration-tests/src/test/kotlin/me/tatarka/inject/test/NestedComponentTest.kt
+++ b/integration-tests/src/test/kotlin/me/tatarka/inject/test/NestedComponentTest.kt
@@ -19,6 +19,10 @@ import kotlin.test.Test
 @Component abstract class SimpleChildComponent1(@Component val parent: ParentComponent) {
     abstract val namedFoo: NamedFoo
 
+    @Provides
+    val BarImpl.binds: IBar
+        get() = this
+
     abstract val foo: IFoo
 }
 
@@ -26,6 +30,8 @@ import kotlin.test.Test
     abstract val namedFoo: NamedFoo
 
     abstract val foo: IFoo
+
+    abstract val bar: IBar
 }
 
 class NestedComponentTest {
@@ -46,5 +52,6 @@ class NestedComponentTest {
 
         assertThat(component.namedFoo.name).isEqualTo("parent")
         assertThat(component.foo).isNotNull()
+        assertThat(component.bar).isNotNull()
     }
 }
\ No newline at end of file