Skip to content

Commit d10eba0

Browse files
committed
Reject assisted injection in cycles
Partial solution to #286
1 parent b235fc1 commit d10eba0

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

kotlin-inject-compiler/core/src/main/kotlin/me/tatarka/inject/compiler/TypeResultResolver.kt

+4-1
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,10 @@ class TypeResultResolver(private val provider: AstProvider, private val options:
463463
args: List<AstType>,
464464
result: (context: Context) -> TypeResultRef,
465465
): TypeResult {
466-
cycleDetector.delayedConstruction()
466+
// The current cycle resolution does not handle args because it re-uses the same instance.
467+
if (args.isEmpty()) {
468+
cycleDetector.delayedConstruction()
469+
}
467470
val context = context.copyNameAllocator()
468471
val namedArgs = args.mapIndexed { i, arg ->
469472
arg to context.nameAllocator.newName("arg$i")

kotlin-inject-compiler/test/src/test/kotlin/me/tatarka/inject/test/FailureTest.kt

+25
Original file line numberDiff line numberDiff line change
@@ -797,4 +797,29 @@ class FailureTest {
797797
contains("Cannot apply scope: @MyScope to type with @Assisted parameters: [arg: String]")
798798
}
799799
}
800+
801+
@ParameterizedTest
802+
@EnumSource(Target::class)
803+
fun fails_if_assisted_injection_is_used_in_a_cycle(target: Target) {
804+
val projectCompiler = ProjectCompiler(target, workingDir)
805+
806+
assertFailure {
807+
projectCompiler.source(
808+
"MyComponent.kt",
809+
"""
810+
import me.tatarka.inject.annotations.Component
811+
import me.tatarka.inject.annotations.Assisted
812+
import me.tatarka.inject.annotations.Inject
813+
814+
@Inject class Cycle(factory: (Int) -> Cycle, @Assisted arg: Int)
815+
816+
@Component abstract class MyComponent {
817+
abstract val cycleFactory: (Int) -> Cycle
818+
}
819+
""".trimIndent()
820+
).compile()
821+
}.output().all {
822+
contains("Cycle detected")
823+
}
824+
}
800825
}

0 commit comments

Comments
 (0)