From 9b30655d664ba9ec684883975d133d3e14dc4563 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 25 Nov 2020 15:35:01 +0300 Subject: [PATCH] [FIR] Load Java annotations named arguments properly (see KT-43584) --- .../kotlin/fir/java/JavaSymbolProvider.kt | 2 +- .../jetbrains/kotlin/fir/java/JavaUtils.kt | 45 ++++++++++++++++--- .../fir/expressions/FirExpressionUtil.kt | 1 + ...gleArrayElementAsVarargInAnnotation.fir.kt | 8 ++-- ...rayElementAsVarargInAnnotationError.fir.kt | 8 ++-- 5 files changed, 49 insertions(+), 15 deletions(-) diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt index 16f8fd00103..d93fa5c690c 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt @@ -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() diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt index fca29119535..cdb274589ed 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt @@ -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 +): LinkedHashMap? { + val lookupTag = ConeClassLikeLookupTagImpl(classId) + annotationTypeRef = buildResolvedTypeRef { + type = ConeClassLikeTypeImpl(lookupTag, emptyArray(), isNullable = false) + } + if (annotationArguments.any { it.name != null }) { + val mapping = linkedMapOf() + val annotationClassSymbol = session.firSymbolProvider.getClassLikeSymbolByFqName(classId).also { + lookupTag.bindSymbolToLookupTag(session, it) + } + if (annotationClassSymbol != null) { + val annotationConstructor = + (annotationClassSymbol.fir as FirRegularClass).declarations.filterIsInstance().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 diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt index 06956fb6e64..15cd05afed7 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt @@ -44,6 +44,7 @@ inline val FirCall.argumentMapping: LinkedHashMapvalue = nonConstArray) fun foo1() {} -@Anno(value = nonConstFun()) +@Anno(value = nonConstFun()) fun foo2() {} @Anno(value = longArrayOf(nonConstLong())) @@ -19,8 +19,8 @@ fun foo3() {} @Anno(value = [nonConstLong()]) fun foo4() {} -@Anno(value = *nonConstArray) +@Anno(value = *nonConstArray) fun bar1() {} -@Anno(*nonConstArray) +@Anno(*nonConstArray) fun bar2() {} diff --git a/compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotationError.fir.kt b/compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotationError.fir.kt index 0fde992f5d8..2f9fa270f42 100644 --- a/compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotationError.fir.kt +++ b/compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotationError.fir.kt @@ -7,10 +7,10 @@ fun nonConstLong(): Long = TODO() annotation class Anno(vararg val value: Long) -@Anno(value = nonConstArray) +@Anno(value = nonConstArray) fun foo1() {} -@Anno(value = nonConstFun()) +@Anno(value = nonConstFun()) fun foo2() {} @Anno(value = longArrayOf(nonConstLong())) @@ -19,8 +19,8 @@ fun foo3() {} @Anno(value = [nonConstLong()]) fun foo4() {} -@Anno(value = *nonConstArray) +@Anno(value = *nonConstArray) fun bar1() {} -@Anno(*nonConstArray) +@Anno(*nonConstArray) fun bar2() {}