[jvm] Introduce flattenAttributeValues API

GitOrigin-RevId: de8f4e75bce5812f00f535e64fc374f96be47729
This commit is contained in:
Bart van Helvert
2023-10-20 13:51:16 +02:00
committed by intellij-monorepo-bot
parent db91e334f8
commit 39f0274f34
2 changed files with 35 additions and 15 deletions

View File

@@ -1,8 +1,7 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection
import com.intellij.psi.LambdaUtil
import com.intellij.psi.PsiType
import com.intellij.psi.*
import com.intellij.psi.util.InheritanceUtil
import org.jetbrains.uast.*
@@ -24,6 +23,33 @@ fun ULambdaExpression.getLambdaType(): PsiType? =
fun UAnnotated.findAnnotations(vararg fqNames: String) = uAnnotations.filter { ann -> fqNames.contains(ann.qualifiedName) }
annotation class X(vararg val value: String)
/**
* Gets all attribute values, ignore whether these are written as array initializer.
*
* Example:
* ```
* @Z("X")
* ```
* Will return "X" as [PsiAnnotationMemberValue]
*```
* @Z("X", 'Y")
* @Z(value = ["X", 'Y"])
*```
* Will return "X", "Y" as [PsiAnnotationMemberValue]s instead of returning a [PsiArrayInitializerMemberValue] that contains both "X" and
* "Y".
*/
fun PsiAnnotation.flattenedAttributeValues(attributeName: String): List<PsiAnnotationMemberValue> {
fun PsiAnnotationMemberValue.flatten(): List<PsiAnnotationMemberValue> = if (this is PsiArrayInitializerMemberValue) {
initializers.flatMap { it.flatten() }
} else listOf(this)
val annotationArgument = findDeclaredAttributeValue(attributeName)
if (annotationArgument == null) return emptyList()
return annotationArgument.flatten()
}
/**
* Gets all classes in this file, including inner classes.
*/

View File

@@ -230,7 +230,7 @@ private class JUnitMalformedSignatureVisitor(
val hasAnnotation = MetaAnnotationUtil.findMetaAnnotationsInHierarchy(this, listOf(ORG_JUNIT_JUPITER_API_EXTENSION_EXTEND_WITH))
.asSequence()
.any { annotation ->
annotation?.nestedAttributeValues("value")?.any {
annotation?.flattenedAttributeValues("value")?.any {
val uClassLiteral = it.toUElementOfType<UClassLiteralExpression>()
uClassLiteral != null && InheritanceUtil.isInheritor(uClassLiteral.type, ORG_JUNIT_JUPITER_API_EXTENSION_PARAMETER_RESOLVER)
} == true
@@ -532,8 +532,8 @@ private class JUnitMalformedSignatureVisitor(
private fun checkMethodSource(method: UMethod, methodSource: PsiAnnotation) {
val psiMethod = method.javaPsi
val containingClass = psiMethod.containingClass ?: return
val annotationMemberValue = methodSource.findDeclaredAttributeValue("value")
if (annotationMemberValue == null) {
val annotationMemberValue = methodSource.flattenedAttributeValues("value")
if (annotationMemberValue.isEmpty()) {
if (methodSource.findAttributeValue(PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME) == null) return
val foundMethod = containingClass.findMethodsByName(method.name, true).singleOrNull { it.parameters.isEmpty() }
val uFoundMethod = foundMethod.toUElementOfType<UMethod>()
@@ -545,7 +545,7 @@ private class JUnitMalformedSignatureVisitor(
}
}
else {
annotationMemberValue.nestedValues().forEach { attributeValue ->
annotationMemberValue.forEach { attributeValue ->
for (reference in attributeValue.references) {
if (reference is MethodSourceReference) {
val resolve = reference.resolve()
@@ -800,7 +800,7 @@ private class JUnitMalformedSignatureVisitor(
)
possibleValues.keys.forEach { valueKey ->
valuesSource.nestedAttributeValues(valueKey)?.forEach { value ->
valuesSource.flattenedAttributeValues(valueKey).forEach { value ->
possibleValues[valueKey]?.let { checkSourceTypeAndParameterTypeAgree(method, value, it) }
}
}
@@ -833,7 +833,7 @@ private class JUnitMalformedSignatureVisitor(
.map { it.name }
.toSet()
val definedConstants = mutableSetOf<String>()
enumSource.nestedAttributeValues("names")?.forEach { name ->
enumSource.flattenedAttributeValues("names").forEach { name ->
if (name is PsiLiteralExpression) {
val value = name.value
if (value is String) {
@@ -854,7 +854,7 @@ private class JUnitMalformedSignatureVisitor(
}
private fun checkCsvSource(methodSource: PsiAnnotation) {
methodSource.nestedAttributeValues("resources")?.forEach { attributeValue ->
methodSource.flattenedAttributeValues("resources").forEach { attributeValue ->
for (ref in attributeValue.references) {
if (ref.isSoft) continue
if (ref is FileReference && ref.multiResolve(false).isEmpty()) {
@@ -865,12 +865,6 @@ private class JUnitMalformedSignatureVisitor(
}
}
private fun PsiAnnotation.nestedAttributeValues(value: String) = findAttributeValue(value)?.nestedValues()
private fun PsiAnnotationMemberValue.nestedValues(): List<PsiAnnotationMemberValue> {
return if (this is PsiArrayInitializerMemberValue) initializers.flatMap { it.nestedValues() } else listOf(this)
}
class AnnotatedSignatureProblem(
private val annotations: List<String>,
private val shouldBeStatic: Boolean? = null,