[Analysis API FIR] fix constant evaluation for incomplete call when compiler produces IntegerLiteralType
^KTIJ-21531 fixed
This commit is contained in:
+34
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+36
-5
@@ -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<*> {
|
||||
|
||||
+34
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+34
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+34
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
fun main(args: Array<String>) {
|
||||
for (i in <expr>1</expr>..) {}
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
expression: 1
|
||||
|
||||
CONSTANT_EXPRESSION_EVALUATION
|
||||
constant: 1
|
||||
constantValueKind: Int
|
||||
|
||||
CONSTANT_LIKE_EXPRESSION_EVALUATION
|
||||
constantLike: 1
|
||||
constantLikeValueKind: Int
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
const val c = <expr>1</expr> +
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
expression: 1
|
||||
|
||||
CONSTANT_EXPRESSION_EVALUATION
|
||||
constant: 1
|
||||
constantValueKind: Int
|
||||
|
||||
CONSTANT_LIKE_EXPRESSION_EVALUATION
|
||||
constantLike: 1
|
||||
constantLikeValueKind: Int
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
const val c = <expr>2147483648</expr> +
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
expression: 2147483648
|
||||
|
||||
CONSTANT_EXPRESSION_EVALUATION
|
||||
constant: 2147483648
|
||||
constantValueKind: Long
|
||||
|
||||
CONSTANT_LIKE_EXPRESSION_EVALUATION
|
||||
constantLike: 2147483648
|
||||
constantLikeValueKind: Long
|
||||
+9
@@ -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
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
const val c = <expr>4294967296u</expr> +
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
expression: 4294967296u
|
||||
|
||||
CONSTANT_EXPRESSION_EVALUATION
|
||||
constant: 4294967296uL
|
||||
constantValueKind: ULong
|
||||
|
||||
CONSTANT_LIKE_EXPRESSION_EVALUATION
|
||||
constantLike: 4294967296uL
|
||||
constantLikeValueKind: ULong
|
||||
Reference in New Issue
Block a user