AA: avoid NPE while evaluating operations with non-numbers

This commit is contained in:
Jinseong Jeon
2022-02-24 13:53:27 -08:00
committed by Ilya Kirillov
parent 6f64aedaf0
commit e36bf55807
5 changed files with 40 additions and 14 deletions
@@ -34,6 +34,12 @@ public class Fe10CompileTimeConstantEvaluatorTestGenerated extends AbstractCompi
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate"), Pattern.compile("^(.+)\\.kt$"), null, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate"), Pattern.compile("^(.+)\\.kt$"), null, true);
} }
@Test
@TestMetadata("binaryExpressionWithString.kt")
public void testBinaryExpressionWithString() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/binaryExpressionWithString.kt");
}
@Test @Test
@TestMetadata("propertyInit_Byte.kt") @TestMetadata("propertyInit_Byte.kt")
public void testPropertyInit_Byte() throws Exception { public void testPropertyInit_Byte() throws Exception {
@@ -115,14 +115,17 @@ internal object FirCompileTimeConstantEvaluator {
// Unary operators // Unary operators
private fun FirConstExpression<*>.evaluate(function: FirSimpleFunction): FirConstExpression<*>? { private fun FirConstExpression<*>.evaluate(function: FirSimpleFunction): FirConstExpression<*>? {
if (value == null) return null if (value == null) return null
return evalUnaryOp( // TODO: there are a couple operations on String, such as .length and .toString
return kind.convertToNumber(value as? Number)?.let { opr ->
evalUnaryOp(
function.name.asString(), function.name.asString(),
kind.toCompileTimeType(), kind.toCompileTimeType(),
kind.convertToNumber(value as? Number)!! opr
)?.let { )?.let {
it.toConstantValueKind().toConstExpression(source, it) it.toConstantValueKind().toConstExpression(source, it)
} }
} }
}
// Binary operators // Binary operators
private fun FirConstExpression<*>.evaluate( private fun FirConstExpression<*>.evaluate(
@@ -130,16 +133,21 @@ internal object FirCompileTimeConstantEvaluator {
other: FirConstExpression<*> other: FirConstExpression<*>
): FirConstExpression<*>? { ): FirConstExpression<*>? {
if (value == null || other.value == null) return null if (value == null || other.value == null) return null
return evalBinaryOp( // TODO: there are a couple operations on Strings, such as .compareTo, .equals, or .plus
return kind.convertToNumber(value as? Number)?.let { opr1 ->
other.kind.convertToNumber(other.value as? Number)?.let { opr2 ->
evalBinaryOp(
function.name.asString(), function.name.asString(),
kind.toCompileTimeType(), kind.toCompileTimeType(),
kind.convertToNumber(value as? Number)!!, opr1,
other.kind.toCompileTimeType(), other.kind.toCompileTimeType(),
other.kind.convertToNumber(other.value as? Number)!! opr2
)?.let { )?.let {
it.toConstantValueKind().toConstExpression(source, it) it.toConstantValueKind().toConstExpression(source, it)
} }
} }
}
}
////// KINDS ////// KINDS
@@ -34,6 +34,12 @@ public class FirCompileTimeConstantEvaluatorTestGenerated extends AbstractCompil
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate"), Pattern.compile("^(.+)\\.kt$"), null, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate"), Pattern.compile("^(.+)\\.kt$"), null, true);
} }
@Test
@TestMetadata("binaryExpressionWithString.kt")
public void testBinaryExpressionWithString() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/binaryExpressionWithString.kt");
}
@Test @Test
@TestMetadata("propertyInit_Byte.kt") @TestMetadata("propertyInit_Byte.kt")
public void testPropertyInit_Byte() throws Exception { public void testPropertyInit_Byte() throws Exception {
@@ -0,0 +1,3 @@
fun box(msg: String): String {
return <expr>"message" + msg</expr>
}
@@ -0,0 +1,3 @@
expression: "message" + msg
constant: NOT_EVALUATED
constantValueKind: NOT_EVALUATED