From 61cca31b6b60c6a6941d0dd1d0bc90f7bb4c1fb9 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Wed, 20 Apr 2022 23:53:04 -0700 Subject: [PATCH] AA: special handling for converted constants --- ...ileTimeConstantEvaluatorTestGenerated.java | 12 ++++++ .../KtFirCompileTimeConstantProvider.kt | 39 +++++++++++++++++-- .../FirCompileTimeConstantEvaluator.kt | 22 +++++------ ...ileTimeConstantEvaluatorTestGenerated.java | 12 ++++++ ...ileTimeConstantEvaluatorTestGenerated.java | 12 ++++++ ...ileTimeConstantEvaluatorTestGenerated.java | 12 ++++++ .../integerLiteral_minusOne_justOne.txt | 4 +- .../evaluate/integerLiteral_plusOne_entire.kt | 4 ++ .../integerLiteral_plusOne_entire.txt | 9 +++++ .../integerLiteral_plusOne_justOne.kt | 4 ++ ...txt => integerLiteral_plusOne_justOne.txt} | 0 11 files changed, 114 insertions(+), 16 deletions(-) create mode 100644 analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_entire.kt create mode 100644 analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_entire.txt create mode 100644 analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/integerLiteral_plusOne_justOne.kt rename analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/{integerLiteral_minusOne_justOne.descriptors.txt => integerLiteral_plusOne_justOne.txt} (100%) 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