diff --git a/checks/src/main/java/com/omegar/lint/checks/LintIssueRegistry.kt b/checks/src/main/java/com/omegar/lint/checks/LintIssueRegistry.kt index 2400a86..126d97b 100644 --- a/checks/src/main/java/com/omegar/lint/checks/LintIssueRegistry.kt +++ b/checks/src/main/java/com/omegar/lint/checks/LintIssueRegistry.kt @@ -3,6 +3,7 @@ package com.omegar.lint.checks import com.android.tools.lint.client.api.IssueRegistry import com.android.tools.lint.detector.api.CURRENT_API import com.android.tools.lint.detector.api.Issue +import com.omegar.lint.checks.detector.code_guidelines.general_recommendations.bind.BindDetector import com.omegar.lint.checks.detector.code_guidelines.general_recommendations.parameter_passing.argument_bundle_for_fragments_creation.ArgumentsBundleKeyPrefixDetector import com.omegar.lint.checks.detector.code_guidelines.general_recommendations.parameter_passing.intent_creation.IntentExtraParametersDetector import com.omegar.lint.checks.detector.code_guidelines.kotlin_rules.exception.ExceptionCatchDetector @@ -63,7 +64,8 @@ class LintIssueRegistry : IssueRegistry() { IntentExtraParametersDetector.ISSUE, ArgumentsBundleKeyPrefixDetector.ISSUE, LambdaDetector.ISSUE, //TODO add lint quick fix for - NameResourceLayoutDetector.ISSUE //TODO add lint quick fix for + NameResourceLayoutDetector.ISSUE, //TODO add lint quick fix for, + BindDetector.ISSUE ) override val api: Int diff --git a/checks/src/main/java/com/omegar/lint/checks/detector/code_guidelines/general_recommendations/bind/BindDetector.kt b/checks/src/main/java/com/omegar/lint/checks/detector/code_guidelines/general_recommendations/bind/BindDetector.kt new file mode 100644 index 0000000..147890a --- /dev/null +++ b/checks/src/main/java/com/omegar/lint/checks/detector/code_guidelines/general_recommendations/bind/BindDetector.kt @@ -0,0 +1,70 @@ +package com.omegar.lint.checks.detector.code_guidelines.general_recommendations.bind + +import com.android.tools.lint.client.api.UElementHandler +import com.android.tools.lint.detector.api.* +import org.jetbrains.uast.UClass +import org.jetbrains.uast.UElement + +@Suppress("UnstableApiUsage") +class BindDetector : Detector(), Detector.UastScanner { + + companion object { + + @JvmField + val ISSUE: Issue = Issue.create( + id = "OMEGA_KEEP_UNIQUE_ID_IN_BINDING", + briefDescription = "Only unique id is allowed for each binding", + explanation = """ + Replace repetitive id in duplicate binding. + """, + category = Category.CORRECTNESS, + severity = Severity.WARNING, + implementation = Implementation( + BindDetector::class.java, + Scope.JAVA_FILE_SCOPE + ) + ) + + private val BIND_PATTERN = Regex("bind *\\( *(R *. *id *\\. *[A-Za-z0-9_]+)( *,.*)?\\)") + + } + + override fun getApplicableUastTypes(): List> = listOf(UClass::class.java) + + override fun createUastHandler(context: JavaContext): UElementHandler? = + object : UElementHandler() { + override fun visitClass(node: UClass) = BIND_PATTERN + .findAll(node.text) + .map { item -> + item.groups[1]?.let { match -> + BindableItem( + match.range.first, + match.value.length, + match.value.filter { !it.isWhitespace() } + ) + } + } + .filterNotNull() + .groupBy { it.content } + .forEach { (_, list) -> + if (list.size > 1) { + context.report( + ISSUE, + node, + context.getRangeLocation( + node as UElement, + list.last().startPosition, + list.last().length + ), + ISSUE.getExplanation(TextFormat.TEXT) + " ${list.last().content}" + ) + } + } + } + + private data class BindableItem( + val startPosition: Int, + val length: Int, + val content: String + ) +} \ No newline at end of file