diff --git a/compiler/fir/analysis-tests/testData/resolve/problems/kt42346.kt b/compiler/fir/analysis-tests/testData/resolve/problems/kt42346.kt index a471e801990..045eced24e1 100644 --- a/compiler/fir/analysis-tests/testData/resolve/problems/kt42346.kt +++ b/compiler/fir/analysis-tests/testData/resolve/problems/kt42346.kt @@ -19,5 +19,5 @@ val depth: Int = 42 annotation class KotlinMagicConstant(val intValues: LongArray) -@KotlinMagicConstant(intValues = [StepRequest.STEP_INTO.toLong(), StepRequest.STEP_OVER.toLong(), StepRequest.STEP_OUT.toLong()]) +@KotlinMagicConstant(intValues = [StepRequest.STEP_INTO.toLong(), StepRequest.STEP_OVER.toLong(), StepRequest.STEP_OUT.toLong()]) val kotlinDepth: Int = 42 diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationArgumentChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationArgumentChecker.kt index 133d09265b6..e1b46b82732 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationArgumentChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationArgumentChecker.kt @@ -19,7 +19,10 @@ import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.* +import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.util.OperatorNameConventions.BINARY_OPERATION_NAMES import org.jetbrains.kotlin.util.OperatorNameConventions.PLUS @@ -140,18 +143,19 @@ object FirAnnotationArgumentChecker : FirBasicDeclarationChecker() { } expression is FirFunctionCall -> { val calleeReference = expression.calleeReference - if (calleeReference is FirErrorNamedReference) + if (calleeReference is FirErrorNamedReference) { return null - if (expression.typeRef.coneType.classId == StandardClassIds.KClass) + } + if (expression.typeRef.coneType.classId == StandardClassIds.KClass) { return FirErrors.ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL + } //TODO: UNRESOLVED REFERENCE - if (expression.dispatchReceiver is FirThisReceiverExpression) + if (expression.dispatchReceiver is FirThisReceiverExpression) { return null + } when (calleeReference.name) { - TO_STRING -> - return checkAnnotationArgument(expression.dispatchReceiver, session) in BINARY_OPERATION_NAMES, in UNARY_OPERATION_NAMES -> { val receiverClassId = expression.dispatchReceiver.typeRef.coneType.classId @@ -167,8 +171,18 @@ object FirAnnotationArgumentChecker : FirBasicDeclarationChecker() { checkAnnotationArgument(exp, session)?.let { return it } } } - else -> + else -> { + if (expression.arguments.isNotEmpty() || calleeReference !is FirResolvedNamedReference) { + return FirErrors.ANNOTATION_ARGUMENT_MUST_BE_CONST + } + val symbol = calleeReference.resolvedSymbol as? FirCallableSymbol + if (calleeReference.name == TO_STRING || + calleeReference.name in CONVERSION_NAMES && symbol?.callableId?.packageName?.asString() == "kotlin" + ) { + return checkAnnotationArgument(expression.dispatchReceiver, session) + } return FirErrors.ANNOTATION_ARGUMENT_MUST_BE_CONST + } } } expression is FirQualifiedAccessExpression -> { @@ -242,4 +256,8 @@ object FirAnnotationArgumentChecker : FirBasicDeclarationChecker() { ) { source?.let { report(factory.on(it)) } } + + private val CONVERSION_NAMES = listOf( + "toInt", "toLong", "toShort", "toByte", "toFloat", "toDouble", "toChar", "toBoolean" + ).mapTo(hashSetOf()) { Name.identifier(it) } } \ No newline at end of file