AA: special handling for converted constants
This commit is contained in:
committed by
Ilya Kirillov
parent
faf6939515
commit
61cca31b6b
+12
@@ -64,6 +64,18 @@ public class Fe10IdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGe
|
||||
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_minusOne_justOne.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("integerLiteral_plusOne_entire.kt")
|
||||
public void testIntegerLiteral_plusOne_entire() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_entire.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("integerLiteral_plusOne_justOne.kt")
|
||||
public void testIntegerLiteral_plusOne_justOne() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_justOne.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("namedReference_const.kt")
|
||||
public void testNamedReference_const() throws Exception {
|
||||
|
||||
+36
-3
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.analysis.api.fir.components
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.base.KtConstantValue
|
||||
import org.jetbrains.kotlin.analysis.api.base.KtConstantValueFactory
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtCompileTimeConstantProvider
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtConstantEvaluationMode
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||
@@ -15,11 +16,16 @@ import org.jetbrains.kotlin.analysis.api.withValidityAssertion
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenBranch
|
||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtPrefixExpression
|
||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||
|
||||
internal class KtFirCompileTimeConstantProvider(
|
||||
override val analysisSession: KtFirAnalysisSession,
|
||||
@@ -35,17 +41,24 @@ internal class KtFirCompileTimeConstantProvider(
|
||||
|
||||
private fun evaluateFir(
|
||||
fir: FirElement?,
|
||||
context: KtExpression,
|
||||
sourcePsi: KtExpression,
|
||||
mode: KtConstantEvaluationMode,
|
||||
): KtConstantValue? = withValidityAssertion {
|
||||
when (fir) {
|
||||
is FirConstExpression<*> -> {
|
||||
val v = FirCompileTimeConstantEvaluator.evaluateAsKtConstantValue(fir, mode)
|
||||
if (v != null && fir.isConverted(sourcePsi)) {
|
||||
val value = fir.kind.unaryMinus(v.value as? Number) ?: return null
|
||||
KtConstantValueFactory.createConstantValue(value, v.sourcePsi)
|
||||
} else v
|
||||
}
|
||||
is FirPropertyAccessExpression,
|
||||
is FirExpression,
|
||||
is FirNamedReference -> {
|
||||
try {
|
||||
FirCompileTimeConstantEvaluator.evaluateAsKtConstantValue(fir, mode)
|
||||
} catch (e: ArithmeticException) {
|
||||
KtConstantValue.KtErrorConstantValue(e.localizedMessage, context)
|
||||
KtConstantValue.KtErrorConstantValue(e.localizedMessage, sourcePsi)
|
||||
}
|
||||
}
|
||||
// For invalid code like the following,
|
||||
@@ -57,7 +70,27 @@ internal class KtFirCompileTimeConstantProvider(
|
||||
// `false` does not have a corresponding elements on the FIR side and hence the containing `FirWhenBranch` is returned. In this
|
||||
// case, we simply report null since FIR does not know about it.
|
||||
is FirWhenBranch -> null
|
||||
else -> throwUnexpectedFirElementError(fir, context)
|
||||
else -> throwUnexpectedFirElementError(fir, sourcePsi)
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirConstExpression<*>.isConverted(sourcePsi: KtExpression): Boolean {
|
||||
val firSourcePsi = this.source?.psi ?: return false
|
||||
return firSourcePsi is KtPrefixExpression && firSourcePsi.operationToken == KtTokens.MINUS && firSourcePsi != sourcePsi
|
||||
}
|
||||
|
||||
private fun ConstantValueKind<*>.unaryMinus(value: Number?): Any? {
|
||||
if (value == null) {
|
||||
return null
|
||||
}
|
||||
return when (this) {
|
||||
ConstantValueKind.Byte -> value.toByte().unaryMinus()
|
||||
ConstantValueKind.Double -> value.toDouble().unaryMinus()
|
||||
ConstantValueKind.Float -> value.toFloat().unaryMinus()
|
||||
ConstantValueKind.Int -> value.toInt().unaryMinus()
|
||||
ConstantValueKind.Long -> value.toLong().unaryMinus()
|
||||
ConstantValueKind.Short -> value.toShort().unaryMinus()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-11
@@ -258,17 +258,17 @@ internal object FirCompileTimeConstantEvaluator {
|
||||
if (value == null) {
|
||||
return null
|
||||
}
|
||||
return when {
|
||||
this == ConstantValueKind.Byte -> value.toByte()
|
||||
this == ConstantValueKind.Double -> value.toDouble()
|
||||
this == ConstantValueKind.Float -> value.toFloat()
|
||||
this == ConstantValueKind.Int -> value.toInt()
|
||||
this == ConstantValueKind.Long -> value.toLong()
|
||||
this == ConstantValueKind.Short -> value.toShort()
|
||||
this == ConstantValueKind.UnsignedByte -> value.toLong().toUByte()
|
||||
this == ConstantValueKind.UnsignedShort -> value.toLong().toUShort()
|
||||
this == ConstantValueKind.UnsignedInt -> value.toLong().toUInt()
|
||||
this == ConstantValueKind.UnsignedLong -> value.toLong().toULong()
|
||||
return when (this) {
|
||||
ConstantValueKind.Byte -> value.toByte()
|
||||
ConstantValueKind.Double -> value.toDouble()
|
||||
ConstantValueKind.Float -> value.toFloat()
|
||||
ConstantValueKind.Int -> value.toInt()
|
||||
ConstantValueKind.Long -> value.toLong()
|
||||
ConstantValueKind.Short -> value.toShort()
|
||||
ConstantValueKind.UnsignedByte -> value.toLong().toUByte()
|
||||
ConstantValueKind.UnsignedShort -> value.toLong().toUShort()
|
||||
ConstantValueKind.UnsignedInt -> value.toLong().toUInt()
|
||||
ConstantValueKind.UnsignedLong -> value.toLong().toULong()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -64,6 +64,18 @@ public class FirIdeDependentAnalysisSourceModuleCompileTimeConstantEvaluatorTest
|
||||
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_minusOne_justOne.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("integerLiteral_plusOne_entire.kt")
|
||||
public void testIntegerLiteral_plusOne_entire() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_entire.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("integerLiteral_plusOne_justOne.kt")
|
||||
public void testIntegerLiteral_plusOne_justOne() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_justOne.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("namedReference_const.kt")
|
||||
public void testNamedReference_const() throws Exception {
|
||||
|
||||
+12
@@ -64,6 +64,18 @@ public class FirIdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGen
|
||||
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_minusOne_justOne.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("integerLiteral_plusOne_entire.kt")
|
||||
public void testIntegerLiteral_plusOne_entire() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_entire.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("integerLiteral_plusOne_justOne.kt")
|
||||
public void testIntegerLiteral_plusOne_justOne() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_justOne.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("namedReference_const.kt")
|
||||
public void testNamedReference_const() throws Exception {
|
||||
|
||||
+12
@@ -64,6 +64,18 @@ public class FirStandaloneNormalAnalysisSourceModuleCompileTimeConstantEvaluator
|
||||
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_minusOne_justOne.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("integerLiteral_plusOne_entire.kt")
|
||||
public void testIntegerLiteral_plusOne_entire() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_entire.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("integerLiteral_plusOne_justOne.kt")
|
||||
public void testIntegerLiteral_plusOne_justOne() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_justOne.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("namedReference_const.kt")
|
||||
public void testNamedReference_const() throws Exception {
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
expression: 1
|
||||
|
||||
CONSTANT_EXPRESSION_EVALUATION
|
||||
constant: -1
|
||||
constant: 1
|
||||
constantValueKind: Int
|
||||
|
||||
CONSTANT_LIKE_EXPRESSION_EVALUATION
|
||||
constantLike: -1
|
||||
constantLike: 1
|
||||
constantLikeValueKind: Int
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
annotation class Annotation(vararg val values: Int)
|
||||
|
||||
@Annotation(<expr>+1</expr>)
|
||||
class C
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
expression: +1
|
||||
|
||||
CONSTANT_EXPRESSION_EVALUATION
|
||||
constant: 1
|
||||
constantValueKind: Int
|
||||
|
||||
CONSTANT_LIKE_EXPRESSION_EVALUATION
|
||||
constantLike: 1
|
||||
constantLikeValueKind: Int
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
annotation class Annotation(vararg val values: Int)
|
||||
|
||||
@Annotation(+<expr>1</expr>)
|
||||
class C
|
||||
Reference in New Issue
Block a user