[FIR] Load Java annotations named arguments properly (see KT-43584)
This commit is contained in:
@@ -50,7 +50,7 @@ class JavaSymbolProvider(
|
||||
private val searchScope: GlobalSearchScope,
|
||||
) : FirSymbolProvider(session) {
|
||||
companion object {
|
||||
private val VALUE_METHOD_NAME = Name.identifier("value")
|
||||
internal val VALUE_METHOD_NAME = Name.identifier("value")
|
||||
}
|
||||
|
||||
private val classCache = SymbolProviderCache<ClassId, FirRegularClassSymbol>()
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.java.enhancement.readOnlyToMutable
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations
|
||||
import org.jetbrains.kotlin.fir.resolve.bindSymbolToLookupTag
|
||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredCallableSymbols
|
||||
@@ -418,16 +419,48 @@ private fun FirRegularClass.createRawArguments(
|
||||
computeRawProjection(session, typeParameter, position, erasedUpperBound)
|
||||
}
|
||||
|
||||
private fun FirAnnotationCallBuilder.buildArgumentMapping(
|
||||
session: FirSession,
|
||||
javaTypeParameterStack: JavaTypeParameterStack,
|
||||
classId: ClassId,
|
||||
annotationArguments: Collection<JavaAnnotationArgument>
|
||||
): LinkedHashMap<FirExpression, FirValueParameter>? {
|
||||
val lookupTag = ConeClassLikeLookupTagImpl(classId)
|
||||
annotationTypeRef = buildResolvedTypeRef {
|
||||
type = ConeClassLikeTypeImpl(lookupTag, emptyArray(), isNullable = false)
|
||||
}
|
||||
if (annotationArguments.any { it.name != null }) {
|
||||
val mapping = linkedMapOf<FirExpression, FirValueParameter>()
|
||||
val annotationClassSymbol = session.firSymbolProvider.getClassLikeSymbolByFqName(classId).also {
|
||||
lookupTag.bindSymbolToLookupTag(session, it)
|
||||
}
|
||||
if (annotationClassSymbol != null) {
|
||||
val annotationConstructor =
|
||||
(annotationClassSymbol.fir as FirRegularClass).declarations.filterIsInstance<FirConstructor>().first()
|
||||
for (argument in annotationArguments) {
|
||||
mapping[argument.toFirExpression(session, javaTypeParameterStack)] =
|
||||
annotationConstructor.valueParameters.find { it.name == (argument.name ?: JavaSymbolProvider.VALUE_METHOD_NAME) }
|
||||
?: return null
|
||||
}
|
||||
return mapping
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
internal fun JavaAnnotation.toFirAnnotationCall(
|
||||
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
|
||||
): FirAnnotationCall {
|
||||
return buildAnnotationCall {
|
||||
annotationTypeRef = buildResolvedTypeRef {
|
||||
type = ConeClassLikeTypeImpl(FirRegularClassSymbol(classId!!).toLookupTag(), emptyArray(), isNullable = false)
|
||||
}
|
||||
argumentList = buildArgumentList {
|
||||
for (argument in this@toFirAnnotationCall.arguments) {
|
||||
arguments += argument.toFirExpression(session, javaTypeParameterStack)
|
||||
val classId = classId!!
|
||||
val mapping = buildArgumentMapping(session, javaTypeParameterStack, classId, arguments)
|
||||
argumentList = if (mapping != null) {
|
||||
buildResolvedArgumentList(mapping)
|
||||
} else {
|
||||
buildArgumentList {
|
||||
for (argument in this@toFirAnnotationCall.arguments) {
|
||||
arguments += argument.toFirExpression(session, javaTypeParameterStack)
|
||||
}
|
||||
}
|
||||
}
|
||||
calleeReference = FirReferencePlaceholderForResolvedAnnotations
|
||||
|
||||
@@ -44,6 +44,7 @@ inline val FirCall.argumentMapping: LinkedHashMap<FirExpression, FirValueParamet
|
||||
get() = (argumentList as? FirResolvedArgumentList)?.mapping
|
||||
|
||||
fun FirExpression.toResolvedCallableReference(): FirResolvedNamedReference? {
|
||||
if (this is FirWrappedArgumentExpression) return expression.toResolvedCallableReference()
|
||||
return (this as? FirResolvable)?.calleeReference as? FirResolvedNamedReference
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -7,10 +7,10 @@ fun nonConstLong(): Long = TODO()
|
||||
|
||||
annotation class Anno(vararg val value: Long)
|
||||
|
||||
@Anno(value = nonConstArray)
|
||||
@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>value = nonConstArray<!>)
|
||||
fun foo1() {}
|
||||
|
||||
@Anno(value = nonConstFun())
|
||||
@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>value = nonConstFun()<!>)
|
||||
fun foo2() {}
|
||||
|
||||
@Anno(value = longArrayOf(nonConstLong()))
|
||||
@@ -19,8 +19,8 @@ fun foo3() {}
|
||||
@Anno(value = [nonConstLong()])
|
||||
fun foo4() {}
|
||||
|
||||
@Anno(value = *nonConstArray)
|
||||
@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>value = *nonConstArray<!>)
|
||||
fun bar1() {}
|
||||
|
||||
@Anno(*nonConstArray)
|
||||
@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>*nonConstArray<!>)
|
||||
fun bar2() {}
|
||||
|
||||
+4
-4
@@ -7,10 +7,10 @@ fun nonConstLong(): Long = TODO()
|
||||
|
||||
annotation class Anno(vararg val value: Long)
|
||||
|
||||
@Anno(value = nonConstArray)
|
||||
@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>value = nonConstArray<!>)
|
||||
fun foo1() {}
|
||||
|
||||
@Anno(value = nonConstFun())
|
||||
@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>value = nonConstFun()<!>)
|
||||
fun foo2() {}
|
||||
|
||||
@Anno(value = longArrayOf(nonConstLong()))
|
||||
@@ -19,8 +19,8 @@ fun foo3() {}
|
||||
@Anno(value = [nonConstLong()])
|
||||
fun foo4() {}
|
||||
|
||||
@Anno(value = *nonConstArray)
|
||||
@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>value = *nonConstArray<!>)
|
||||
fun bar1() {}
|
||||
|
||||
@Anno(*nonConstArray)
|
||||
@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>*nonConstArray<!>)
|
||||
fun bar2() {}
|
||||
|
||||
Reference in New Issue
Block a user