Repository: evant/kotlin-inject
Pull request #114 (2021-04-16 18:33:38)

Bugfix/java handling


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 bd7b237..bdd9e17 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
@@ -309,9 +309,7 @@ private class ModelAstClass(
 
     override val constructors: List<AstConstructor>
         get() {
-            if (kmClass == null) return emptyList()
-
-            val kmCtors = kmClass.constructors.associateBy { it.signature?.simpleSig }
+            val kmCtors = kmClass?.constructors?.associateBy { it.signature?.simpleSig } ?: emptyMap()
             return ElementFilter.constructorsIn(element.enclosedElements).map { constructor ->
                 ModelAstConstructor(
                     this,
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 fb5c4ba..03618e4 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
@@ -279,6 +279,7 @@ fun KmType.eqv(other: KmType): Boolean {
     }
     return classifier == other.classifier &&
             isNullable() == other.isNullable() &&
+            isPlatformType() == other.isPlatformType() &&
             arguments.eqvItr(other.arguments) { a, b ->
                 a.variance == b.variance &&
                         a.type.eqv(b.type, KmType::eqv)
@@ -328,4 +329,6 @@ inline fun KmConstructor.isPrimary() = Flag.Constructor.IS_PRIMARY(flags)
 
 inline fun KmValueParameter.hasDefault() = Flag.ValueParameter.DECLARES_DEFAULT_VALUE(flags)
 
-inline fun KmType.isNullable() = Flag.Type.IS_NULLABLE(flags)
\ No newline at end of file
+inline fun KmType.isNullable() = Flag.Type.IS_NULLABLE(flags)
+
+inline fun KmType.isPlatformType() = flexibleTypeUpperBound?.typeFlexibilityId == "kotlin.jvm.PlatformType"
\ No newline at end of file


Test patch:
diff --git a/compiler-tests/src/test/kotlin/me/tatarka/inject/test/FailureTest.kt b/compiler-tests/src/test/kotlin/me/tatarka/inject/test/FailureTest.kt
index ae2088f..341fc39 100644
--- a/compiler-tests/src/test/kotlin/me/tatarka/inject/test/FailureTest.kt
+++ b/compiler-tests/src/test/kotlin/me/tatarka/inject/test/FailureTest.kt
@@ -401,6 +401,28 @@ class FailureTest(private val target: Target) {
             )
         }
     }
+
+    @Test
+    fun fails_with_missing_binding_with_platform_provides_and_non_nullable_usage() {
+        assertThat {
+            projectCompiler.source(
+                "MyComponent.kt",
+                """
+               import me.tatarka.inject.annotations.Component
+               import me.tatarka.inject.annotations.Provides
+               
+               @Component abstract class MyComponent() {
+                 abstract val foo: String
+                 @Provides fun provideFoo() = System.lineSeparator()
+               }
+                """.trimIndent()
+            ).compile()
+        }.isFailure().output().all {
+            contains(
+                "Cannot find an @Inject constructor or provider for: String"
+            )
+        }
+    }
 }
 
 private fun Target.sourceExt() = when (this) {
diff --git a/integration-tests/common/src/test/java/me/tatarka/inject/test/JavaFoo.java b/integration-tests/common/src/test/java/me/tatarka/inject/test/JavaFoo.java
new file mode 100644
index 0000000..6f42ee0
--- /dev/null
+++ b/integration-tests/common/src/test/java/me/tatarka/inject/test/JavaFoo.java
@@ -0,0 +1,17 @@
+package me.tatarka.inject.test;
+
+import me.tatarka.inject.annotations.Inject;
+
+public class JavaFoo {
+
+    private final Foo foo;
+
+    @Inject
+    public JavaFoo(Foo foo) {
+        this.foo = foo;
+    }
+
+    public Foo getFoo() {
+        return foo;
+    }
+}
\ No newline at end of file
diff --git a/integration-tests/common/src/test/java/me/tatarka/inject/test/JavaJavaXFoo.java b/integration-tests/common/src/test/java/me/tatarka/inject/test/JavaJavaXFoo.java
new file mode 100644
index 0000000..7c8f48b
--- /dev/null
+++ b/integration-tests/common/src/test/java/me/tatarka/inject/test/JavaJavaXFoo.java
@@ -0,0 +1,16 @@
+package me.tatarka.inject.test;
+
+import javax.inject.Inject;
+
+public class JavaJavaXFoo {
+    private final Foo foo;
+
+    @Inject
+    public JavaJavaXFoo(Foo foo) {
+        this.foo = foo;
+    }
+
+    public Foo getFoo() {
+        return foo;
+    }
+}
\ No newline at end of file
diff --git a/integration-tests/common/src/test/kotlin/me/tatarka/inject/test/JavaTest.kt b/integration-tests/common/src/test/kotlin/me/tatarka/inject/test/JavaTest.kt
new file mode 100644
index 0000000..f0e43be
--- /dev/null
+++ b/integration-tests/common/src/test/kotlin/me/tatarka/inject/test/JavaTest.kt
@@ -0,0 +1,45 @@
+package me.tatarka.inject.test
+
+import assertk.assertThat
+import assertk.assertions.isNotNull
+import me.tatarka.inject.annotations.Component
+import me.tatarka.inject.annotations.Inject
+import org.junit.Test
+
+@Component
+abstract class JavaInjectConstructorComponent {
+    abstract val foo: JavaFoo
+
+    abstract val foo2: JavaJavaXFoo
+}
+
+@Inject
+class JavaBar(val foo: JavaFoo)
+
+@Inject
+class JavaJavaXBar(val foo: JavaJavaXFoo)
+
+@Component
+abstract class JavaProvidesComponent {
+    abstract val bar: JavaBar
+
+    abstract val bar2: JavaJavaXBar
+}
+
+class JavaTest {
+    @Test
+    fun generates_a_component_that_provides_a_class_declared_in_java() {
+        val component = JavaInjectConstructorComponent::class.create()
+
+        assertThat(component.foo).isNotNull()
+        assertThat(component.foo2).isNotNull()
+    }
+
+    @Test
+    fun generates_a_component_that_provides_a_class_that_depends_on_a_class_declared_in_java() {
+        val component = JavaProvidesComponent::class.create()
+
+        assertThat(component.bar.foo).isNotNull()
+        assertThat(component.bar2.foo).isNotNull()
+    }
+}
\ No newline at end of file
diff --git a/integration-tests/kapt/build.gradle b/integration-tests/kapt/build.gradle
index e031a3c..bd8762a 100644
--- a/integration-tests/kapt/build.gradle
+++ b/integration-tests/kapt/build.gradle
@@ -25,6 +25,7 @@ dependencies {
 sourceSets {
     test {
         kotlin.srcDir '../common/src/test/kotlin'
+        java.srcDir '../common/src/test/java'
     }
 }
 
diff --git a/integration-tests/ksp/build.gradle b/integration-tests/ksp/build.gradle
index e3267ff..6e42648 100644
--- a/integration-tests/ksp/build.gradle
+++ b/integration-tests/ksp/build.gradle
@@ -22,6 +22,7 @@ dependencies {
 sourceSets {
     test {
         kotlin.srcDir '../common/src/test/kotlin'
+        java.srcDir '../common/src/test/java'
     }
 }