From 5d30576d28e2b824afa6bdf0658850487d002fee Mon Sep 17 00:00:00 2001 From: Andrey Zinovyev Date: Tue, 11 May 2021 19:03:08 +0300 Subject: [PATCH] [FIR] Report not-a-constant diagnostics inside function calls When function calls are not fully resolved --- .../FirAnnotationArgumentChecker.kt | 40 +++++++++++-------- .../array.fir.kt | 2 +- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAnnotationArgumentChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAnnotationArgumentChecker.kt index 6d6f96a5f76..9f304d5e2fa 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAnnotationArgumentChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAnnotationArgumentChecker.kt @@ -59,26 +59,30 @@ object FirAnnotationArgumentChecker : FirAnnotationCallChecker() { reporter: DiagnosticReporter, context: CheckerContext ): FirDiagnosticFactory0? { - when (expression) { - is FirArrayOfCall -> { - var usedNonConst = false - for (arg in expression.argumentList.arguments) { - val sourceForReport = arg.source + fun checkArgumentList(args: FirArgumentList): FirDiagnosticFactory0? { + var usedNonConst = false - when (val err = checkAnnotationArgumentWithSubElements(arg, fqName, session, reporter, context)) { - null -> { - //DO NOTHING - } - else -> { - if (err != FirErrors.ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL) usedNonConst = true - reporter.reportOn(sourceForReport, err, context) - } + for (arg in args.arguments) { + val sourceForReport = arg.source + + when (val err = checkAnnotationArgumentWithSubElements(arg, fqName, session, reporter, context)) { + null -> { + //DO NOTHING + } + else -> { + if (err != FirErrors.ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL) usedNonConst = true + reporter.reportOn(sourceForReport, err, context) } } - - if (usedNonConst) return FirErrors.NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION } + + return if (usedNonConst) FirErrors.NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION + else null + } + + when (expression) { + is FirArrayOfCall -> return checkArgumentList(expression.argumentList) is FirVarargArgumentsExpression -> { for (arg in expression.arguments) { val unwrappedArg = if (arg is FirSpreadArgumentExpression) arg.expression else arg @@ -93,7 +97,11 @@ object FirAnnotationArgumentChecker : FirAnnotationCallChecker() { ConstantArgumentKind.NOT_KCLASS_LITERAL -> FirErrors.ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL ConstantArgumentKind.KCLASS_LITERAL_OF_TYPE_PARAMETER_ERROR -> FirErrors.ANNOTATION_ARGUMENT_KCLASS_LITERAL_OF_TYPE_PARAMETER_ERROR ConstantArgumentKind.NOT_CONST_VAL_IN_CONST_EXPRESSION -> FirErrors.NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION - null -> null + null -> + //try to go deeper if we are not sure about this function call + //to report non-constant val in not fully resolved calls + if (expression is FirFunctionCall) checkArgumentList(expression.argumentList) + else null } if (error != null) { return error diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.fir.kt index e4cc980f080..e97514f7769 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.fir.kt @@ -6,7 +6,7 @@ annotation class Ann(val i: IntArray) @Ann(intArrayOf(i2)) @Ann(intArrayOf(i3)) @Ann(intArrayOf(i, i2, i3)) -@Ann(intArrayOf(intArrayOf(i, i2, i3))) +@Ann(intArrayOf(intArrayOf(i, i2, i3))) class Test var i = 1