diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/compileTimeConstantProvider/Fe10IdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/compileTimeConstantProvider/Fe10IdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java
index c30afc27280..d6dd8430e8b 100644
--- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/compileTimeConstantProvider/Fe10IdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java
+++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/compileTimeConstantProvider/Fe10IdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java
@@ -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 {
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCompileTimeConstantProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCompileTimeConstantProvider.kt
index 95e426c02d2..a717b4b5ea3 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCompileTimeConstantProvider.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCompileTimeConstantProvider.kt
@@ -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
}
}
}
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/evaluate/FirCompileTimeConstantEvaluator.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/evaluate/FirCompileTimeConstantEvaluator.kt
index 134bea1bdfc..5ae310a66e7 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/evaluate/FirCompileTimeConstantEvaluator.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/evaluate/FirCompileTimeConstantEvaluator.kt
@@ -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
}
}
diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirIdeDependentAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirIdeDependentAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java
index b0cd22324ba..03e8014d450 100644
--- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirIdeDependentAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java
+++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirIdeDependentAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java
@@ -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 {
diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirIdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirIdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java
index f36546f4047..e25c0c476d1 100644
--- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirIdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java
+++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirIdeNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java
@@ -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 {
diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirStandaloneNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirStandaloneNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java
index 8276d88c7ed..18b1e966fe6 100644
--- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirStandaloneNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java
+++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/compileTimeConstantProvider/FirStandaloneNormalAnalysisSourceModuleCompileTimeConstantEvaluatorTestGenerated.java
@@ -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 {
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_minusOne_justOne.txt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_minusOne_justOne.txt
index 03ae6018d67..ef2899c8865 100644
--- a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_minusOne_justOne.txt
+++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_minusOne_justOne.txt
@@ -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
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_entire.kt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_entire.kt
new file mode 100644
index 00000000000..164ae2daf6d
--- /dev/null
+++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_entire.kt
@@ -0,0 +1,4 @@
+annotation class Annotation(vararg val values: Int)
+
+@Annotation(+1)
+class C
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_entire.txt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_entire.txt
new file mode 100644
index 00000000000..9cacb7b0e6d
--- /dev/null
+++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_entire.txt
@@ -0,0 +1,9 @@
+expression: +1
+
+CONSTANT_EXPRESSION_EVALUATION
+constant: 1
+constantValueKind: Int
+
+CONSTANT_LIKE_EXPRESSION_EVALUATION
+constantLike: 1
+constantLikeValueKind: Int
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_justOne.kt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_justOne.kt
new file mode 100644
index 00000000000..e4f4e4d5655
--- /dev/null
+++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_justOne.kt
@@ -0,0 +1,4 @@
+annotation class Annotation(vararg val values: Int)
+
+@Annotation(+1)
+class C
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_minusOne_justOne.descriptors.txt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_justOne.txt
similarity index 100%
rename from analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_minusOne_justOne.descriptors.txt
rename to analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_justOne.txt