Я пытаюсь написать свое первое правило Lint. На данный момент я просто хочу обнаружить использование аннотации @AnyThread
.
. Я создал модуль для реализации моего пользовательского правила. Файл Gradle для этого модуля (я использую плагин Gradle версии 3.6.1):
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_1_8
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
compileOnly 'com.android.tools.lint:lint-api:26.6.1'
compileOnly 'com.android.tools.lint:lint-checks:26.6.1'
testImplementation "com.android.tools.lint:lint:26.6.1"
testImplementation "com.android.tools.lint:lint-tests:26.6.1"
testImplementation "com.android.tools:testutils:26.6.1"
testImplementation "junit:junit:4.12"
}
jar {
manifest {
attributes("Lint-Registry-v2": "com.test.lint.MyIssueRegistry")
}
}
Мой детектор:
package com.test.lint
//...
class AnyThreadAnnotationDetector: AbstractAnnotationDetector(), Detector.UastScanner {
companion object {
private const val AnyThreadId = "AnyThreadId"
const val AnyThreadDescription = "This is an attempt to find AnyThread annotation in code"
const val AnyThreadExplanation = "AnyThread annotation found!"
val ANYTHREAD_ANNOTATION_ISSUE = Issue.create(
id = AnyThreadId,
briefDescription = AnyThreadDescription,
explanation = AnyThreadExplanation,
category = Category.CORRECTNESS,
priority = 4,
severity = Severity.INFORMATIONAL,
implementation = Implementation(
AnyThreadAnnotationDetector::class.java,
Scope.JAVA_FILE_SCOPE
)
)
}
override fun applicableAnnotations(): List<String>? = listOf("androidx.annotation.AnyThread")
override fun visitAnnotationUsage(
context: JavaContext,
usage: UElement,
type: AnnotationUsageType,
annotation: UAnnotation,
qualifiedName: String,
method: PsiMethod?,
annotations: List<UAnnotation>,
allMemberAnnotations: List<UAnnotation>,
allClassAnnotations: List<UAnnotation>,
allPackageAnnotations: List<UAnnotation>
) {
context.report(
issue = ANYTHREAD_ANNOTATION_ISSUE,
scope = usage,
location = context.getNameLocation(usage),
message = "A message"
)
}
}
My IssueRegistry
is:
class MyIssueRegistry : IssueRegistry() {
override val issues: List<Issue>
get() = listOf(
AnyThreadAnnotationDetector.ANYTHREAD_ANNOTATION_ISSUE)
override val api: Int = CURRENT_API
}
Я написал несколько тестов:
class AnyThreadAnnotationDetectorTest {
@Test
fun noAnnotatedFileKotlin() {
TestLintTask.lint()
.files(
LintDetectorTest.kotlin(
"""
|package foo;
|
|class XmlHttpRequest {
|}""".trimMargin()
)
)
.allowMissingSdk()
.issues(AnyThreadAnnotationDetector.ANYTHREAD_ANNOTATION_ISSUE)
.run()
.expectClean()
}
@Test
fun annotatedKotlinMethod() {
TestLintTask.lint()
.files(
LintDetectorTest.kotlin(
"""
|package foo;
|
|import androidx.annotation.AnyThread
|
|class XmlHttpRequest {
|@AnyThread
|fun test(){}
|}""".trimMargin()
)
)
.allowMissingSdk()
.issues(AnyThreadAnnotationDetector.ANYTHREAD_ANNOTATION_ISSUE)
.run()
.expect(
"""
Just a test to find annotations
0 errors, 0 warnings
""".trimIndent()
)
}
@Test
fun testNoisyDetector() {
TestLintTask.lint().files(Stubs.ANYTHREAD_EXPERIMENT)
.allowMissingSdk()
.issues(AnyThreadAnnotationDetector.ANYTHREAD_ANNOTATION_ISSUE)
.run()
.expect(
"""
Just a test to find annotations
0 errors, 0 warnings
""".trimIndent()
)
}
}
Где Stubs.ANYTHREAD_EXPERIMENT
:
object Stubs {
val ANYTHREAD_EXPERIMENT = kotlin(
"com/test/applicationlintdemoapp/AnythreadAnnotationStubs.kt",
"""
package com.test.applicationlintdemoapp
import androidx.annotation.AnyThread
class AnythreadClassExperiment {
@AnyThread
fun setTimeToNow() {
TimeTravelProvider().setTime(System.currentTimeMillis())
}
@AnyThread
fun setTimeToEpoch() {
TimeTravelProvider().setTime(0)
}
fun violateTimeTravelAccords() {
TimeTravelProvider().setTime(-1)
}
}
"""
).indented().within("src")
}
Все мои тесты не пройдены (кроме noAnnotatedFileKotlin
), на самом деле, если я поставьте точку останова на вызов context.report
, тест, выполненный в режиме отладки, никогда не приостанавливается, это означает, что аннотация androidx.annotation.AnyThread
никогда не обнаруживается.
Что может go не так? что я пропустил?
Я видел и читал несколько документов:
И я контролировал конфигурацию, применяя NoisyDetector
, приведенный в докладе Кодирование в стиле: Stati c Анализ с использованием пользовательских правил Lint , результат теста хорошо.