[Analysis API FIR] fix constant evaluation for incomplete call when compiler produces IntegerLiteralType

^KTIJ-21531 fixed
This commit is contained in:
Ilya Kirillov
2022-09-28 19:12:28 +02:00
parent b72dbb7819
commit 4ae1cb74dd
14 changed files with 227 additions and 5 deletions
@@ -231,4 +231,38 @@ public class Fe10IdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGe
public void testString_trimIndent() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/string_trimIndent.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode")
@TestDataPath("$PROJECT_ROOT")
public class IncompleteCode {
@Test
public void testAllFilesPresentInIncompleteCode() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("incompleteRange.kt")
public void testIncompleteRange() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode/incompleteRange.kt");
}
@Test
@TestMetadata("noRightOperand.kt")
public void testNoRightOperand() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode/noRightOperand.kt");
}
@Test
@TestMetadata("noRightOperandLong.kt")
public void testNoRightOperandLong() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode/noRightOperandLong.kt");
}
@Test
@TestMetadata("noRightOperandUnsignedLong.kt")
public void testNoRightOperandUnsignedLong() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode/noRightOperandUnsignedLong.kt");
}
}
}
@@ -7,8 +7,8 @@ package org.jetbrains.kotlin.analysis.api.fir.evaluate
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.analysis.api.base.KtConstantValue
import org.jetbrains.kotlin.analysis.api.base.KtConstantValueFactory
import org.jetbrains.kotlin.analysis.api.components.KtConstantEvaluationMode
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
@@ -110,11 +110,42 @@ internal object FirCompileTimeConstantEvaluator {
): KtConstantValue? {
val evaluated = evaluate(fir, mode) ?: return null
val ktConstantValue = KtConstantValueFactory.createConstantValue(evaluated.value, evaluated.psi as? KtElement) ?: return null
check(ktConstantValue.constantValueKind == evaluated.kind) {
"Expected ${evaluated.kind} for created KtConstantValue but ${ktConstantValue.constantValueKind} found"
val value = evaluated.value
val psi = evaluated.psi as? KtElement
return when (evaluated.kind) {
ConstantValueKind.Byte -> KtConstantValue.KtByteConstantValue(value as Byte, psi)
ConstantValueKind.Int -> KtConstantValue.KtIntConstantValue(value as Int, psi)
ConstantValueKind.Long -> KtConstantValue.KtLongConstantValue(value as Long, psi)
ConstantValueKind.Short -> KtConstantValue.KtShortConstantValue(value as Short, psi)
ConstantValueKind.UnsignedByte -> KtConstantValue.KtUnsignedByteConstantValue(value as UByte, psi)
ConstantValueKind.UnsignedInt -> KtConstantValue.KtUnsignedIntConstantValue(value as UInt, psi)
ConstantValueKind.UnsignedLong -> KtConstantValue.KtUnsignedLongConstantValue(value as ULong, psi)
ConstantValueKind.UnsignedShort -> KtConstantValue.KtUnsignedShortConstantValue(value as UShort, psi)
ConstantValueKind.Double -> KtConstantValue.KtDoubleConstantValue(value as Double, psi)
ConstantValueKind.Float -> KtConstantValue.KtFloatConstantValue(value as Float, psi)
ConstantValueKind.Boolean -> KtConstantValue.KtBooleanConstantValue(value as Boolean, psi)
ConstantValueKind.Char -> KtConstantValue.KtCharConstantValue(value as Char, psi)
ConstantValueKind.String -> KtConstantValue.KtStringConstantValue(value as String, psi)
ConstantValueKind.Null -> KtConstantValue.KtNullConstantValue(psi)
ConstantValueKind.IntegerLiteral -> {
val long = value as Long
if (Int.MIN_VALUE < long && long < Int.MAX_VALUE) KtConstantValue.KtIntConstantValue(long.toInt(), psi)
else KtConstantValue.KtLongConstantValue(long, psi)
}
ConstantValueKind.UnsignedIntegerLiteral -> {
val long = value as ULong
if (UInt.MIN_VALUE < long && long < UInt.MAX_VALUE) KtConstantValue.KtUnsignedIntConstantValue(long.toUInt(), psi)
else KtConstantValue.KtUnsignedLongConstantValue(long, psi)
}
ConstantValueKind.Error -> errorWithFirSpecificEntries("Should not be possible to get from FIR tree", fir = fir)
}
return ktConstantValue
}
private fun FirConstExpression<*>.adaptToConstKind(): FirConstExpression<*> {
@@ -231,4 +231,38 @@ public class FirIdeDependentAnalysisSourceModuleCompileTimeConstantEvaluatorTest
public void testString_trimIndent() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/string_trimIndent.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode")
@TestDataPath("$PROJECT_ROOT")
public class IncompleteCode {
@Test
public void testAllFilesPresentInIncompleteCode() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("incompleteRange.kt")
public void testIncompleteRange() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode/incompleteRange.kt");
}
@Test
@TestMetadata("noRightOperand.kt")
public void testNoRightOperand() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode/noRightOperand.kt");
}
@Test
@TestMetadata("noRightOperandLong.kt")
public void testNoRightOperandLong() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode/noRightOperandLong.kt");
}
@Test
@TestMetadata("noRightOperandUnsignedLong.kt")
public void testNoRightOperandUnsignedLong() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode/noRightOperandUnsignedLong.kt");
}
}
}
@@ -231,4 +231,38 @@ public class FirIdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGen
public void testString_trimIndent() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/string_trimIndent.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode")
@TestDataPath("$PROJECT_ROOT")
public class IncompleteCode {
@Test
public void testAllFilesPresentInIncompleteCode() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("incompleteRange.kt")
public void testIncompleteRange() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode/incompleteRange.kt");
}
@Test
@TestMetadata("noRightOperand.kt")
public void testNoRightOperand() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode/noRightOperand.kt");
}
@Test
@TestMetadata("noRightOperandLong.kt")
public void testNoRightOperandLong() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode/noRightOperandLong.kt");
}
@Test
@TestMetadata("noRightOperandUnsignedLong.kt")
public void testNoRightOperandUnsignedLong() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode/noRightOperandUnsignedLong.kt");
}
}
}
@@ -231,4 +231,38 @@ public class FirStandaloneNormalAnalysisSourceModuleCompileTimeConstantEvaluator
public void testString_trimIndent() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/string_trimIndent.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode")
@TestDataPath("$PROJECT_ROOT")
public class IncompleteCode {
@Test
public void testAllFilesPresentInIncompleteCode() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("incompleteRange.kt")
public void testIncompleteRange() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode/incompleteRange.kt");
}
@Test
@TestMetadata("noRightOperand.kt")
public void testNoRightOperand() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode/noRightOperand.kt");
}
@Test
@TestMetadata("noRightOperandLong.kt")
public void testNoRightOperandLong() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode/noRightOperandLong.kt");
}
@Test
@TestMetadata("noRightOperandUnsignedLong.kt")
public void testNoRightOperandUnsignedLong() throws Exception {
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/incompleteCode/noRightOperandUnsignedLong.kt");
}
}
}
@@ -0,0 +1,4 @@
fun main(args: Array<String>) {
for (i in <expr>1</expr>..) {}
}
@@ -0,0 +1,9 @@
expression: 1
CONSTANT_EXPRESSION_EVALUATION
constant: 1
constantValueKind: Int
CONSTANT_LIKE_EXPRESSION_EVALUATION
constantLike: 1
constantLikeValueKind: Int
@@ -0,0 +1,2 @@
const val c = <expr>1</expr> +
@@ -0,0 +1,9 @@
expression: 1
CONSTANT_EXPRESSION_EVALUATION
constant: 1
constantValueKind: Int
CONSTANT_LIKE_EXPRESSION_EVALUATION
constantLike: 1
constantLikeValueKind: Int
@@ -0,0 +1,2 @@
const val c = <expr>2147483648</expr> +
@@ -0,0 +1,9 @@
expression: 2147483648
CONSTANT_EXPRESSION_EVALUATION
constant: 2147483648
constantValueKind: Long
CONSTANT_LIKE_EXPRESSION_EVALUATION
constantLike: 2147483648
constantLikeValueKind: Long
@@ -0,0 +1,9 @@
expression: 4294967296u
CONSTANT_EXPRESSION_EVALUATION
constant: error("Type cannot be resolved. Please make sure you have the required dependencies for unsigned types in the classpath")
constantValueKind: Error
CONSTANT_LIKE_EXPRESSION_EVALUATION
constantLike: error("Type cannot be resolved. Please make sure you have the required dependencies for unsigned types in the classpath")
constantLikeValueKind: Error
@@ -0,0 +1,2 @@
const val c = <expr>4294967296u</expr> +
@@ -0,0 +1,9 @@
expression: 4294967296u
CONSTANT_EXPRESSION_EVALUATION
constant: 4294967296uL
constantValueKind: ULong
CONSTANT_LIKE_EXPRESSION_EVALUATION
constantLike: 4294967296uL
constantLikeValueKind: ULong