[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,
|
private val searchScope: GlobalSearchScope,
|
||||||
) : FirSymbolProvider(session) {
|
) : FirSymbolProvider(session) {
|
||||||
companion object {
|
companion object {
|
||||||
private val VALUE_METHOD_NAME = Name.identifier("value")
|
internal val VALUE_METHOD_NAME = Name.identifier("value")
|
||||||
}
|
}
|
||||||
|
|
||||||
private val classCache = SymbolProviderCache<ClassId, FirRegularClassSymbol>()
|
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.buildErrorNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations
|
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.defaultType
|
||||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredCallableSymbols
|
import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredCallableSymbols
|
||||||
@@ -418,16 +419,48 @@ private fun FirRegularClass.createRawArguments(
|
|||||||
computeRawProjection(session, typeParameter, position, erasedUpperBound)
|
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(
|
internal fun JavaAnnotation.toFirAnnotationCall(
|
||||||
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
|
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
|
||||||
): FirAnnotationCall {
|
): FirAnnotationCall {
|
||||||
return buildAnnotationCall {
|
return buildAnnotationCall {
|
||||||
annotationTypeRef = buildResolvedTypeRef {
|
val classId = classId!!
|
||||||
type = ConeClassLikeTypeImpl(FirRegularClassSymbol(classId!!).toLookupTag(), emptyArray(), isNullable = false)
|
val mapping = buildArgumentMapping(session, javaTypeParameterStack, classId, arguments)
|
||||||
}
|
argumentList = if (mapping != null) {
|
||||||
argumentList = buildArgumentList {
|
buildResolvedArgumentList(mapping)
|
||||||
for (argument in this@toFirAnnotationCall.arguments) {
|
} else {
|
||||||
arguments += argument.toFirExpression(session, javaTypeParameterStack)
|
buildArgumentList {
|
||||||
|
for (argument in this@toFirAnnotationCall.arguments) {
|
||||||
|
arguments += argument.toFirExpression(session, javaTypeParameterStack)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
calleeReference = FirReferencePlaceholderForResolvedAnnotations
|
calleeReference = FirReferencePlaceholderForResolvedAnnotations
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ inline val FirCall.argumentMapping: LinkedHashMap<FirExpression, FirValueParamet
|
|||||||
get() = (argumentList as? FirResolvedArgumentList)?.mapping
|
get() = (argumentList as? FirResolvedArgumentList)?.mapping
|
||||||
|
|
||||||
fun FirExpression.toResolvedCallableReference(): FirResolvedNamedReference? {
|
fun FirExpression.toResolvedCallableReference(): FirResolvedNamedReference? {
|
||||||
|
if (this is FirWrappedArgumentExpression) return expression.toResolvedCallableReference()
|
||||||
return (this as? FirResolvable)?.calleeReference as? FirResolvedNamedReference
|
return (this as? FirResolvable)?.calleeReference as? FirResolvedNamedReference
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -7,10 +7,10 @@ fun nonConstLong(): Long = TODO()
|
|||||||
|
|
||||||
annotation class Anno(vararg val value: Long)
|
annotation class Anno(vararg val value: Long)
|
||||||
|
|
||||||
@Anno(value = nonConstArray)
|
@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>value = nonConstArray<!>)
|
||||||
fun foo1() {}
|
fun foo1() {}
|
||||||
|
|
||||||
@Anno(value = nonConstFun())
|
@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>value = nonConstFun()<!>)
|
||||||
fun foo2() {}
|
fun foo2() {}
|
||||||
|
|
||||||
@Anno(value = longArrayOf(nonConstLong()))
|
@Anno(value = longArrayOf(nonConstLong()))
|
||||||
@@ -19,8 +19,8 @@ fun foo3() {}
|
|||||||
@Anno(value = [nonConstLong()])
|
@Anno(value = [nonConstLong()])
|
||||||
fun foo4() {}
|
fun foo4() {}
|
||||||
|
|
||||||
@Anno(value = *nonConstArray)
|
@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>value = *nonConstArray<!>)
|
||||||
fun bar1() {}
|
fun bar1() {}
|
||||||
|
|
||||||
@Anno(*nonConstArray)
|
@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>*nonConstArray<!>)
|
||||||
fun bar2() {}
|
fun bar2() {}
|
||||||
|
|||||||
+4
-4
@@ -7,10 +7,10 @@ fun nonConstLong(): Long = TODO()
|
|||||||
|
|
||||||
annotation class Anno(vararg val value: Long)
|
annotation class Anno(vararg val value: Long)
|
||||||
|
|
||||||
@Anno(value = nonConstArray)
|
@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>value = nonConstArray<!>)
|
||||||
fun foo1() {}
|
fun foo1() {}
|
||||||
|
|
||||||
@Anno(value = nonConstFun())
|
@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>value = nonConstFun()<!>)
|
||||||
fun foo2() {}
|
fun foo2() {}
|
||||||
|
|
||||||
@Anno(value = longArrayOf(nonConstLong()))
|
@Anno(value = longArrayOf(nonConstLong()))
|
||||||
@@ -19,8 +19,8 @@ fun foo3() {}
|
|||||||
@Anno(value = [nonConstLong()])
|
@Anno(value = [nonConstLong()])
|
||||||
fun foo4() {}
|
fun foo4() {}
|
||||||
|
|
||||||
@Anno(value = *nonConstArray)
|
@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>value = *nonConstArray<!>)
|
||||||
fun bar1() {}
|
fun bar1() {}
|
||||||
|
|
||||||
@Anno(*nonConstArray)
|
@Anno(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>*nonConstArray<!>)
|
||||||
fun bar2() {}
|
fun bar2() {}
|
||||||
|
|||||||
Reference in New Issue
Block a user