检测 return 类型注释始终为空

Detekt return type annotations always empty

我正在尝试编写检查以防止返回带有特定注释的类型。

例如,

const val TEST_CONTENT = 
        """
        | package sample.test
        |
        | @Target(AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CLASS)
        | annotation class SampleAnnotation
        | 
        | @SampleAnnotation
        | internal interface ConditionalReturnedType 
        |
        | interface TestCase {
        |   // this is not allowed
        |   fun someFunction(whatever: String): ConditionalReturnedType
        | }
        """.trimIndent()

我目前的规则如下

override fun visitNamedFunction(function: KtNamedFunction) {
    super.visitNamedFunction(function)
    if (BindingContext.EMPTY == bindingContext) {
      return
    }

    val returnType = function.createTypeBindingForReturnType(bindingContext)?.type ?: return

    // HERE Annotations is always EMPTY
    val annotations = returnType.annotations
    val hasRequiredAnnotation = annotations.hasAnnotation(FqName("SampleAnnotation"))
    if (!hasRequiredAnnotation) return

    if (isAnAllowedCondition(function, returnType)) {
      // Allow returning the type for this condition
      return
    }

    report(CodeSmell(/** */))
  }

我可以验证 returnType 是正确的,但是 annotations 类型总是空的。 是否有另一种获取注释的方法,或者我在这里犯了一些菜鸟错误? :)

我的测试如下,

@Test
fun `negative cuz it doesnt match allowed conditions`() {
  val actual = subject.compileAndLintWithContext(ENVIRONMENT.env, TEST_CONTENT)
  assertThat(actual).hasSize(1)
  assertThat(actual[0].message)
      .isEqualTo("Ops. You shouldn't return that.")
}

所以,有 2 个问题。

  1. 我添加了 visitClass 并检查了那里的注释,它总是空的——这很奇怪,让我意识到问题出在测试上。出于某种原因,带有 | 的代码块使注释行在编译时被删除。 | @SampleAnnotation 这根本不存在于编译文件中。删除 | 解决了这个问题。
  2. 出于某种原因,在 KotlinType 中似乎没有为 returnType 填充注释字段。因此,我需要以某种方式访问​​ KtClass 对象,添加以下内容才能获得注释。
val returnType = function.createTypeBindingForReturnType(bindingContext)?.type ?: return
val annotations = returnType.constructor.declarationDescriptor?.annotations ?: return
val isAnnotated = annotations.any { it.type.toString() == "SampleAnnotation" }