Skip to content

Commit

Permalink
Add DataBindingAdapter 중복 생성 탐지 Lint
Browse files Browse the repository at this point in the history
  • Loading branch information
Pluu committed Mar 23, 2024
1 parent 5e7ab36 commit 734314f
Show file tree
Hide file tree
Showing 7 changed files with 244 additions and 1 deletion.
5 changes: 5 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
}

android {
Expand Down Expand Up @@ -30,6 +31,10 @@ android {
kotlinOptions {
jvmTarget = '17'
}

buildFeatures {
dataBinding = true
}
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.pluu.lintstudy.databinding_duplication

import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.databinding.BindingAdapter

class SampleView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0
) : View(context, attrs, defStyle) {

companion object {
@JvmStatic
@BindingAdapter("android:paddingLeft")
fun setPaddingLeft(view: View, padding: Int) {
// TBD
}

@BindingAdapter("android:paddingStart")
fun setPaddingStart(view: SampleView, padding: Int) {
// TBD
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.pluu.lintstudy.databinding_duplication

import android.view.View
import androidx.databinding.BindingAdapter

object ViewBindingAdapter {
@JvmStatic
@BindingAdapter("test1")
fun setTest1(view: View, value: Int) {
// TBD
}

@BindingAdapter("test2")
fun setTest2(view: View, value: Int) {
// TBD
}
}

@BindingAdapter("test3")
fun setTest3(view: View, value: Int) {
// TBD
}
69 changes: 69 additions & 0 deletions lint/src/main/java/com/pluu/lint/DataBindingDuplicationDetector.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.pluu.lint

import com.android.tools.lint.client.api.UElementHandler
import com.android.tools.lint.detector.api.Category
import com.android.tools.lint.detector.api.Detector
import com.android.tools.lint.detector.api.Implementation
import com.android.tools.lint.detector.api.Issue
import com.android.tools.lint.detector.api.JavaContext
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.isKotlin
import org.jetbrains.kotlin.psi.KtObjectDeclaration
import org.jetbrains.uast.UClass
import java.util.EnumSet

class DataBindingDuplicationDetector : Detector(), Detector.UastScanner {

override fun getApplicableUastTypes() = listOf(UClass::class.java)

override fun createUastHandler(context: JavaContext): UElementHandler? {
if (!isKotlin(context.psiFile)) return null
return object : UElementHandler() {
override fun visitClass(node: UClass) {
val element = node.sourceElement ?: return
if (element is KtObjectDeclaration && element.isCompanion()) {
node.methods
.filter { method ->
detectAnnotation.any { annotation ->
method.hasAnnotation(annotation)
} && method.hasAnnotation(jvmStaticAnnotation)
}.forEach { method ->
context.report(
ISSUE,
method,
context.getLocation(method),
message
)
}
}
}
}
}


companion object {
private val detectAnnotation = arrayOf(
"androidx.databinding.BindingAdapter"
)

private val jvmStaticAnnotation = "kotlin.jvm.JvmStatic"

private const val message = "복수 DataBinding 생성으로 IDE 경고가 발생합니다."

@JvmField
val ISSUE = Issue.create(
id = DataBindingDuplicationDetector::class.java.simpleName,
briefDescription = "DataBindingDuplicationDetector",
explanation = message,
category = Category.CORRECTNESS,
priority = 6,
severity = Severity.WARNING,
implementation = Implementation(
DataBindingDuplicationDetector::class.java,
EnumSet.of(Scope.JAVA_FILE),
Scope.JAVA_FILE_SCOPE
)
)
}
}
3 changes: 2 additions & 1 deletion lint/src/main/java/com/pluu/lint/MyIssueRegistry.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class MyIssueRegistry : IssueRegistry() {
RequiredCustomViewAttributeDetector.ISSUE,
TypoMethodInComponentDetector.ISSUE,
LiveDataObserveNotNullDetector.ISSUE,
LazyBundleDetector.ISSUE
LazyBundleDetector.ISSUE,
DataBindingDuplicationDetector.ISSUE
)
}
102 changes: 102 additions & 0 deletions lint/src/test/java/com/pluu/lint/DataBindingDuplicationDetectorTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.pluu.lint

import com.android.tools.lint.checks.infrastructure.LintDetectorTest
import com.android.tools.lint.detector.api.Detector
import com.pluu.lint.stubs.DataBindingStub
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

@RunWith(JUnit4::class)
class DataBindingDuplicationDetectorTest : LintDetectorTest() {
override fun getDetector(): Detector = DataBindingDuplicationDetector()

override fun getIssues() = listOf(DataBindingDuplicationDetector.ISSUE)

@Test
fun testDetectCase() {
lint()
.files(
DataBindingStub.BindingAdapterStub,
kotlin(
"""
import androidx.databinding.BindingAdapter
class SampleView {
companion object {
@JvmStatic
@BindingAdapter("test")
fun setTest(view: View, value: Int) {
}
}
}
"""
)
.indented(),
)
.run()
.expect(
"""
src/SampleView.kt:5: Warning: 복수 DataBinding 생성으로 IDE 경고가 발생합니다. [DataBindingDuplicationDetector]
@JvmStatic
^
0 errors, 1 warnings
""".trimIndent()
)
}

@Test
fun testNonDetectCase_NonJvmStatic() {
lint()
.files(
DataBindingStub.BindingAdapterStub,
kotlin(
"""
import androidx.databinding.BindingAdapter
class SampleView {
companion object {
@BindingAdapter("test")
fun setTest(view: View, value: Int) {
}
}
}
"""
)
.indented(),
)
.run()
.expectClean()
}

@Test
fun testNonDetectCase_AnotherClass() {
lint()
.files(
DataBindingStub.BindingAdapterStub,
kotlin(
"""
import androidx.databinding.BindingAdapter
object ViewBindingAdapter {
@JvmStatic
@BindingAdapter("test1")
fun setTest1(view: View, value: Int) {
}
@BindingAdapter("test2")
fun setTest2(view: View, value: Int) {
}
}
@BindingAdapter("test3")
fun setTest3(view: View, value: Int) {
}
"""
)
.indented(),
)
.run()
.expectClean()
}
}
17 changes: 17 additions & 0 deletions lint/src/test/java/com/pluu/lint/stubs/DataBindingStub.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.pluu.lint.stubs

import com.android.tools.lint.checks.infrastructure.TestFiles.java

object DataBindingStub {

val BindingAdapterStub = java(
"""
package androidx.databinding;
public @interface BindingAdapter {
String[] value();
boolean requireAll() default true;
}
""".trimIndent()
)

}

0 comments on commit 734314f

Please sign in to comment.