Hey I would need a bit of help building a custom r...
# detekt
c
Hey I would need a bit of help building a custom rule. So far I came really close to getting it running. I have send the closest code as an image and text
Copy code
import io.github.detekt.psi.basePath
import io.gitlab.arturbosch.detekt.api.CodeSmell
import io.gitlab.arturbosch.detekt.api.Config
import io.gitlab.arturbosch.detekt.api.Debt
import io.gitlab.arturbosch.detekt.api.Entity
import io.gitlab.arturbosch.detekt.api.Issue
import io.gitlab.arturbosch.detekt.api.Rule
import io.gitlab.arturbosch.detekt.api.Severity
import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault
import io.gitlab.arturbosch.detekt.api.internal.RequiresTypeResolution
import org.jetbrains.kotlin.com.intellij.psi.PsiFile
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.KotlinType
import kotlin.io.path.name

@RequiresTypeResolution
@ActiveByDefault(since = "1.21.0")
class ViewModelScopeOwnerRetention(
    config: Config = Config.empty
) : Rule(config) {

    private companion object {
        const val RULE_ID = "ViewModelScopeOwnerRetention"
        const val RULE_DESCRIPTION = "Don't retain the viewModelScopeOwner inside a value. (Memory leak)"
    }

    private var isInTestPath: Boolean = false

    override val issue = Issue(
        id = RULE_ID,
        severity = Severity.Maintainability,
        description = RULE_DESCRIPTION,
        debt = Debt.TWENTY_MINS,
    )

    override fun visitFile(file: PsiFile) {
        isInTestPath = file.basePath()?.name?.contains("/src/test/") ?: false
        super.visitFile(file)
    }

    override fun visitProperty(property: KtProperty) {
        if (isInTestPath) return
        if (!property.type.isViewModelScopeOwner) return
        report(CodeSmell(issue, Entity.atName(property), issue.description))
        super.visitProperty(property)
    }

    private val KotlinType?.isViewModelScopeOwner: Boolean
        get() = (this.toString() == "ViewModelStoreOwner")

    private val KtProperty.type: KotlinType?
        get() = (bindingContext[BindingContext.VARIABLE, this])?.type.also {
            println("Test: ${it.toString()}")
        }
}
This runs perfectly in cases where we do not have a ViewModelScopeOwner variable. When we do, the code does detect it but gives a error like the one attached.
Test: [Error type: Unresolved type for ViewModelStoreOwner]?
I have added the dependency in compileOnly and implementation and still the same outcome. The problem is purely the type else wise the logic would run fine. I have tried to search for something similar without luck. Is this just not possible in detekt?
g
Could you put this in a repo using our template and add tests for it? It would be easier to take a look at it
c
@gammax Thank you for the reply. I got it working with lint for now. Going to investigate this over the weekend while I play around with it.