首页 > 解决方案 > 如何从 Java 源代码中获取 UAnnotation 的限定名称?

问题描述

我正在尝试编写一个简单的 Android lint 检查,以确保您使用特定的可空性注释。但由于某种原因,我无法获得注释的完全限定名称。

这是测试用例:

val input = """
    package foo;

    import org.jetbrains.annotations.NotNull;

    public class Bar {
        @NotNull String text;

        Bar(@NotNull String text) {
            this.text = text;
        }
    }
""".trimIndent()

lint().files(java(input))
    .issues(NullAnnotationDetector.ISSUE)
    .run()
    // expect and all the info

这是检测器中的逻辑:

class NullAnnotationDetector: Detector(), SourceCodeScanner {

    // companion object with the Issue itself

    private lateinit var uastHandler: UElementHandler

    override fun getApplicableUastTypes(): List<Class<out UElement>>? =
        listOf(UAnnotation::class.java)

    override fun createUastHandler(context: JavaContext): UElementHandler? {
        uastHandler = NullHandler(context)
        return uastHandler
    }

    private class NullHandler(val context: JavaContext) : UElementHandler() {
        override fun visitAnnotation(node: UAnnotation) {
            val x = node.qualifiedName  // for some reason this is just "NotNull"

            // context.report and all those kind of stuff
        }
    }
}

问题是,如果我将输入转换为 kotlin,则node.qualifiedName返回完全限定名称 ( org.jetbrains.annotations.NotNull)。我怎样才能得到相同的结果java()

标签: androidlintandroid-lint

解决方案


我换了

node.qualifiedName

node.javaPsi?.qualifiedName

在我的测试中,我必须添加我正在测试的类的完整定义,在你的情况下是这样的:

   lint()
       .files(
          notNullClass(),
          java( """
             package foo;

             import org.jetbrains.annotations.NotNull;

             public class Bar {
                @NotNull String text;

                Bar(@NotNull String text) {
                   this.text = text;
                }
             }
             """.trimIndent()
             )
          )
       .run()
       .expectErrorCount(1)

notNullClass() 定义为:

companion object {

        fun notNullClass(): TestFile = java(
            "src/org/jetbrains/annotations/NotNull.java",
            """

package org.jetbrains.annotations;

import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})
public @interface NotNull {

  String value() default "";

  Class<? extends Exception> exception() default Exception.class;
}


                """.trimIndent()
        )
    }

推荐阅读