evant / kotlin-inject

Dependency injection lib for kotlin
Apache License 2.0
1.29k stars 60 forks source link

StackOverflowError when implementing component on companion object #434

Closed damianw closed 2 months ago

damianw commented 2 months ago

The following compiled with version 0.6.1, but fails with 0.7.1:

@Component
interface BadComponent {

    // ...

    companion object : BadComponent by BadComponent::class.create()
}

Stack trace:

e: java.lang.StackOverflowError
    at com.google.devtools.ksp.processing.impl.ResolverImpl.resolveUserType(ResolverImpl.kt:719)
    at com.google.devtools.ksp.symbol.impl.kotlin.KSTypeReferenceImpl.resolve(KSTypeReferenceImpl.kt:124)
    at com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:57)
    at com.google.devtools.ksp.visitor.KSValidateVisitor.visitTypeReference(KSValidateVisitor.kt:5)
    at com.google.devtools.ksp.symbol.impl.kotlin.KSTypeReferenceImpl.accept(KSTypeReferenceImpl.kt:121)
    at com.google.devtools.ksp.visitor.KSValidateVisitor.visitAnnotation(KSValidateVisitor.kt:47)
    at com.google.devtools.ksp.visitor.KSValidateVisitor.visitAnnotation(KSValidateVisitor.kt:5)
    at com.google.devtools.ksp.symbol.impl.kotlin.KSAnnotationImpl.accept(KSAnnotationImpl.kt:110)
    at com.google.devtools.ksp.visitor.KSValidateVisitor.visitAnnotated(KSValidateVisitor.kt:40)
    at com.google.devtools.ksp.visitor.KSValidateVisitor.visitDeclaration(KSValidateVisitor.kt:23)
    at com.google.devtools.ksp.visitor.KSValidateVisitor.visitClassDeclaration(KSValidateVisitor.kt:67)
    at me.tatarka.inject.compiler.ksp.ProcessInjectKt$validate$1.visitClassDeclaration(ProcessInject.kt:57)
    at me.tatarka.inject.compiler.ksp.ProcessInjectKt$validate$1.visitClassDeclaration(ProcessInject.kt:37)
    at com.google.devtools.ksp.symbol.impl.kotlin.KSClassDeclarationImpl.accept(KSClassDeclarationImpl.kt:135)
    at me.tatarka.inject.compiler.ksp.ProcessInjectKt$validate$1.visitClassDeclaration(ProcessInject.kt:61)
    at me.tatarka.inject.compiler.ksp.ProcessInjectKt$validate$1.visitClassDeclaration(ProcessInject.kt:37)
    at com.google.devtools.ksp.symbol.impl.kotlin.KSClassDeclarationImpl.accept(KSClassDeclarationImpl.kt:135)
    at com.google.devtools.ksp.visitor.KSValidateVisitor.visitDeclarationContainer(KSValidateVisitor.kt:28)
    at com.google.devtools.ksp.visitor.KSValidateVisitor.visitClassDeclaration(KSValidateVisitor.kt:70)
    at me.tatarka.inject.compiler.ksp.ProcessInjectKt$validate$1.visitClassDeclaration(ProcessInject.kt:57)
    at me.tatarka.inject.compiler.ksp.ProcessInjectKt$validate$1.visitClassDeclaration(ProcessInject.kt:37)
    ...

You might ask why you would do this - I've found it to be a handy way to define the component and make it a "true" singleton in an easily-accessible way, particularly in tests. There's an obvious workaround to just not do this though, and instead assign it to a property.

evant commented 2 months ago

Not sure if this is a bug in ksp's validator or our validation implementation, but either way should be able to work around as it looks like it's visiting more than it should.