From f9d646e862a1193ad6f725b0fbe5ce9ee54488c5 Mon Sep 17 00:00:00 2001 From: Dmitriy Sidukov Date: Mon, 31 Oct 2022 10:24:19 +0300 Subject: [PATCH 1/2] check for same ids in binds added --- .../omegar/lint/checks/LintIssueRegistry.kt | 4 +- .../bind/BindDetector.kt | 76 +++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 checks/src/main/java/com/omegar/lint/checks/detector/code_guidelines/general_recommendations/bind/BindDetector.kt 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..154bbc8 --- /dev/null +++ b/checks/src/main/java/com/omegar/lint/checks/detector/code_guidelines/general_recommendations/bind/BindDetector.kt @@ -0,0 +1,76 @@ +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.).*(\\))") + + // add underscore to regular expression + private val ID_PATTERN = Regex("R.id.[A-Za-z]*") + + } + + override fun getApplicableUastTypes(): List> = listOf(UClass::class.java) + + override fun createUastHandler(context: JavaContext): UElementHandler? = + object : UElementHandler() { + override fun visitClass(node: UClass) { + + val text = node.text + val items = BIND_PATTERN + .findAll(text) + .map { bindItem -> + val match = ID_PATTERN.find(bindItem.value)!! + BindableItem( + bindItem.range.first, + bindItem.value.length, + match.value + ) + } + .groupBy { it.content } + + items.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 From c3790b4318582c24b7f8633c0a4ee8e1d5575f78 Mon Sep 17 00:00:00 2001 From: Dmitriy Sidukov Date: Tue, 1 Nov 2022 11:13:17 +0300 Subject: [PATCH 2/2] detector completed --- .../bind/BindDetector.kt | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) 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 index 154bbc8..147890a 100644 --- 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 @@ -25,10 +25,7 @@ class BindDetector : Detector(), Detector.UastScanner { ) ) - private val BIND_PATTERN = Regex("bind(.*)(\\()(.*)(R.id.).*(\\))") - - // add underscore to regular expression - private val ID_PATTERN = Regex("R.id.[A-Za-z]*") + private val BIND_PATTERN = Regex("bind *\\( *(R *. *id *\\. *[A-Za-z0-9_]+)( *,.*)?\\)") } @@ -36,22 +33,20 @@ class BindDetector : Detector(), Detector.UastScanner { override fun createUastHandler(context: JavaContext): UElementHandler? = object : UElementHandler() { - override fun visitClass(node: UClass) { - - val text = node.text - val items = BIND_PATTERN - .findAll(text) - .map { bindItem -> - val match = ID_PATTERN.find(bindItem.value)!! + override fun visitClass(node: UClass) = BIND_PATTERN + .findAll(node.text) + .map { item -> + item.groups[1]?.let { match -> BindableItem( - bindItem.range.first, - bindItem.value.length, - match.value + match.range.first, + match.value.length, + match.value.filter { !it.isWhitespace() } ) } - .groupBy { it.content } - - items.forEach { (_, list) -> + } + .filterNotNull() + .groupBy { it.content } + .forEach { (_, list) -> if (list.size > 1) { context.report( ISSUE, @@ -65,7 +60,6 @@ class BindDetector : Detector(), Detector.UastScanner { ) } } - } } private data class BindableItem(