Repository: evant/kotlin-inject (kotlin)

Issue:
Support injecting companion object
This generates incorrect code

```kotlin
interface IFoo {
  @Inject
  companion object : IFoo
}

@Component
abstract class MyComponent {
   abstract val foo: IFoo
   val IFoo.Companion.bind: IFoo @Provides get() = this
}
```

expected:

```kotlin
class InjectMyComponent : MyComponent {
  override val foo: IFoo get() = IFoo.bind
}
```

actual:

```kotlin
class InjectMyComponent : MyComponent {
  override val foo: IFoo get() = IFoo.Companion().bind
}
```

Pull request:
Fixes #106

Patch:
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 03618e4a..74848dc5 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
@@ -315,7 +315,7 @@ inline fun KmClass.isAbstract() = Flag.Common.IS_ABSTRACT(flags)
 
 inline fun KmClass.isInterface() = Flag.Class.IS_INTERFACE(flags)
 
-inline fun KmClass.isObject() = Flag.Class.IS_OBJECT(flags)
+inline fun KmClass.isObject() = Flag.Class.IS_OBJECT(flags) or Flag.Class.IS_COMPANION_OBJECT(flags)
 
 inline fun KmFunction.isAbstract() = Flag.Common.IS_ABSTRACT(flags)
 


Test patch:
diff --git a/integration-tests/common/src/test/kotlin/me/tatarka/inject/test/InjectObjectTest.kt b/integration-tests/common/src/test/kotlin/me/tatarka/inject/test/InjectObjectTest.kt
index badae871..bd568c05 100644
--- a/integration-tests/common/src/test/kotlin/me/tatarka/inject/test/InjectObjectTest.kt
+++ b/integration-tests/common/src/test/kotlin/me/tatarka/inject/test/InjectObjectTest.kt
@@ -1,41 +1,76 @@
 package me.tatarka.inject.test
 
 import assertk.assertThat
-import assertk.assertions.isEqualTo
+import assertk.assertions.isSameAs
 import me.tatarka.inject.annotations.Component
 import me.tatarka.inject.annotations.Inject
+import me.tatarka.inject.annotations.Provides
 import me.tatarka.inject.test.different.DifferentPackageFoo
 import org.junit.Test
 
-@Inject object MyInjectObject
+@Inject
+object FooObject
 
-@Inject class DependsOnMyInjectObject(val myInjectObject: MyInjectObject)
+@Inject
+class DependsOnFooObject(val foo: FooObject)
 
-@Component interface MyComponent {
-    val injectObject: MyInjectObject
-    val differentPackageObject: DifferentPackageFoo.MyObject
-    fun injectObject(): MyInjectObject
-    fun dependsOnMyInjectObject(): DependsOnMyInjectObject
+@Component
+abstract class ObjectComponent {
+    abstract val injectObject: FooObject
+    abstract val differentPackageObject: DifferentPackageFoo.MyObject
+    abstract fun injectObject(): FooObject
+    abstract fun dependsOnFooObject(): DependsOnFooObject
+}
+
+interface CompanionFooInterface
+
+interface CompanionFoo {
+    @Inject
+    companion object : CompanionFooInterface
+}
+
+@Inject
+class DependOnCompanionFoo(val foo: CompanionFooInterface)
+
+@Component
+abstract class CompanionObjectComponent {
+    abstract val foo: CompanionFooInterface
+    abstract val dependsOnFoo: DependOnCompanionFoo
+
+    val CompanionFoo.Companion.bind: CompanionFooInterface
+        @Provides get() = this
 }
 
 class InjectObjectTest {
     @Test
     fun inject_annotated_object_can_be_provided_in_component_function() {
-        assertThat(InjectMyComponent().injectObject()).isEqualTo(MyInjectObject)
+        val component = ObjectComponent::class.create()
+        assertThat(component.injectObject()).isSameAs(FooObject)
     }
 
     @Test
     fun inject_annotated_object_can_be_provided_in_component_property() {
-        assertThat(InjectMyComponent().injectObject).isEqualTo(MyInjectObject)
+        val component = ObjectComponent::class.create()
+        assertThat(component.injectObject).isSameAs(FooObject)
     }
 
     @Test
     fun inject_annotated_object_can_be_provided_to_class_constructors() {
-        assertThat(InjectMyComponent().dependsOnMyInjectObject().myInjectObject).isEqualTo(MyInjectObject)
+        val component = ObjectComponent::class.create()
+        assertThat(component.dependsOnFooObject().foo).isSameAs(FooObject)
     }
 
     @Test
     fun inject_annotated_object_can_be_provided_from_a_different_package() {
-        assertThat(InjectMyComponent().differentPackageObject).isEqualTo(DifferentPackageFoo.MyObject)
+        val component = ObjectComponent::class.create()
+        assertThat(component.differentPackageObject).isSameAs(DifferentPackageFoo.MyObject)
+    }
+
+    @Test
+    fun binds_a_companion_object_to_an_interface() {
+        val component = CompanionObjectComponent::class.create()
+
+        assertThat(component.foo).isSameAs(CompanionFoo)
+        assertThat(component.dependsOnFoo.foo).isSameAs(CompanionFoo)
     }
 }
\ No newline at end of file