[AA-FIR] Add support for constant evaluation of string templates.

Support FirStringConcatenationCall in FirCompileTimeConstantEvaluator.
This allows string templates ("foo${bar}") to be evaluated as constants,
assuming the interpolated expressions are themselves constant.

In addition, fixes some handling bugs with KtConstantEvaluationMode,
where some expressions that are not valid in a `const val` declaration
were being supported for `CONSTANT_EXPRESSION_EVALUATION`, including
non-static final Java fields in FIR, and composite expressions of
non-const properties in FE1.0.
This commit is contained in:
Justin Paupore
2023-02-13 20:16:15 -08:00
committed by Ilya Kirillov
parent 0193c83b05
commit fa517180b7
12 changed files with 100 additions and 23 deletions
@@ -31,18 +31,11 @@ internal class KtFe10CompileTimeConstantProvider(
): KtConstantValue? {
val bindingContext = analysisContext.analyze(expression)
if (mode == KtConstantEvaluationMode.CONSTANT_EXPRESSION_EVALUATION) {
// TODO: how to _not_ evaluate composite expression with a non-const property?
// TODO: how to _not_ evaluate expressions with a compilation error, e.g., uninitialized property access
when (expression) {
is KtNameReferenceExpression -> {
val reference = bindingContext[BindingContext.REFERENCE_TARGET, expression]
if (reference is PropertyDescriptor && !reference.isConst) return null
}
}
}
val constant = ConstantExpressionEvaluator.getPossiblyErrorConstant(expression, bindingContext)
if (mode == KtConstantEvaluationMode.CONSTANT_EXPRESSION_EVALUATION) {
// TODO: how to _not_ evaluate expressions with a compilation error, e.g., uninitialized property access
if (constant?.usesNonConstValAsConstant == true) return null
}
return constant?.toConstantValue(TypeUtils.NO_EXPECTED_TYPE)?.toKtConstantValue()
}
}
@@ -232,6 +232,18 @@ public class Fe10IdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGe
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/string_plusTwice.kt");
}
@Test
@TestMetadata("string_templateConst.kt")
public void testString_templateConst() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/string_templateConst.kt");
}
@Test
@TestMetadata("string_templateNonConst.kt")
public void testString_templateNonConst() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/string_templateNonConst.kt");
}
@Test
@TestMetadata("string_toString.kt")
public void testString_toString() throws Exception {