Skip to content

Commit

Permalink
Update ViewModelInjectionDetector to support a lint option
Browse files Browse the repository at this point in the history
  • Loading branch information
WhosNickDoglio committed Feb 10, 2023
1 parent 4a9dea1 commit 24a815e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,28 @@ import com.android.tools.lint.detector.api.Issue
import com.android.tools.lint.detector.api.JavaContext
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.android.tools.lint.detector.api.StringOption
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtProperty
import slack.lint.compose.util.*
import slack.lint.compose.util.sourceImplementation

class ViewModelInjectionDetector : ComposableFunctionDetector(), SourceCodeScanner {
class ViewModelInjectionDetector
@JvmOverloads
constructor(private val allowedNames: StringSetLintOption = StringSetLintOption(ALLOW_LIST)) :
ComposableFunctionDetector(allowedNames), SourceCodeScanner {

companion object {

internal val ALLOW_LIST =
StringOption(
"allowed-viewmodel-injection",
"A comma-separated list of viewModel factories.",
null,
"This property should define comma-separated list of allowed viewModel factory names."
)

private fun errorMessage(factoryName: String): String =
"""
Implicit dependencies of composables should be made explicit.
Expand All @@ -35,6 +48,7 @@ class ViewModelInjectionDetector : ComposableFunctionDetector(), SourceCodeScann
severity = Severity.ERROR,
implementation = sourceImplementation<ViewModelInjectionDetector>()
)
.setOptions(listOf(ALLOW_LIST))

private val KnownViewModelFactories by lazy {
setOf(
Expand All @@ -57,7 +71,10 @@ class ViewModelInjectionDetector : ComposableFunctionDetector(), SourceCodeScann
.flatMap { property ->
property
.findDirectChildrenByClass<KtCallExpression>()
.filter { KnownViewModelFactories.contains(it.calleeExpression?.text) }
.filter {
KnownViewModelFactories.contains(it.calleeExpression?.text) ||
allowedNames.value.contains(it.calleeExpression?.text)
}
.map { property to it.calleeExpression!!.text }
}
.forEach { (property, viewModelFactoryName) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
package slack.lint.compose

import com.android.tools.lint.checks.infrastructure.TestLintTask
import com.android.tools.lint.checks.infrastructure.TestMode
import com.android.tools.lint.detector.api.Detector
import com.android.tools.lint.detector.api.Issue
Expand All @@ -23,7 +24,8 @@ class ViewModelInjectionDetectorTest(private val viewModel: String) : BaseSlackL
arrayOf("weaverViewModel"),
arrayOf("hiltViewModel"),
arrayOf("injectedViewModel"),
arrayOf("mavericksViewModel")
arrayOf("mavericksViewModel"),
arrayOf("tangleViewModel"),
)
}
}
Expand All @@ -34,7 +36,12 @@ class ViewModelInjectionDetectorTest(private val viewModel: String) : BaseSlackL
// This mode is irrelevant to our test and totally untestable with stringy outputs
override val skipTestModes: Array<TestMode> = arrayOf(TestMode.SUPPRESSIBLE, TestMode.TYPE_ALIAS)

@Test
override fun lint(): TestLintTask {
return super.lint()
.configureOption(ViewModelInjectionDetector.ALLOW_LIST, "tangleViewModel")
}

@Test
fun `passes when a weaverViewModel is used as a default param`() {
@Language("kotlin")
val code =
Expand Down

0 comments on commit 24a815e

Please sign in to comment.