diff --git a/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/components/compileTimeConstantProvider/Fe10CompileTimeConstantEvaluatorTestGenerated.java b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/components/compileTimeConstantProvider/Fe10CompileTimeConstantEvaluatorTestGenerated.java
index 264961463b7..1543a5346bc 100644
--- a/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/components/compileTimeConstantProvider/Fe10CompileTimeConstantEvaluatorTestGenerated.java
+++ b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/components/compileTimeConstantProvider/Fe10CompileTimeConstantEvaluatorTestGenerated.java
@@ -41,9 +41,39 @@ public class Fe10CompileTimeConstantEvaluatorTestGenerated extends AbstractCompi
}
@Test
- @TestMetadata("namedReference.kt")
- public void testNamedReference() throws Exception {
- runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference.kt");
+ @TestMetadata("namedReference_const.kt")
+ public void testNamedReference_const() throws Exception {
+ runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_const.kt");
+ }
+
+ @Test
+ @TestMetadata("namedReference_val.kt")
+ public void testNamedReference_val() throws Exception {
+ runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_val.kt");
+ }
+
+ @Test
+ @TestMetadata("namedReference_var.kt")
+ public void testNamedReference_var() throws Exception {
+ runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_var.kt");
+ }
+
+ @Test
+ @TestMetadata("propertyInCompanionObject.kt")
+ public void testPropertyInCompanionObject() throws Exception {
+ runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject.kt");
+ }
+
+ @Test
+ @TestMetadata("propertyInCompanionObject_indirect.kt")
+ public void testPropertyInCompanionObject_indirect() throws Exception {
+ runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject_indirect.kt");
+ }
+
+ @Test
+ @TestMetadata("propertyInCompanionObject_indirect_twice.kt")
+ public void testPropertyInCompanionObject_indirect_twice() throws Exception {
+ runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject_indirect_twice.kt");
}
@Test
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 fa6caf865a3..1e7c658a435 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
@@ -5,18 +5,26 @@
package org.jetbrains.kotlin.analysis.api.fir.components
+import org.jetbrains.kotlin.analysis.api.KtConstantInitializerValue
+import org.jetbrains.kotlin.analysis.api.KtInitializerValue
+import org.jetbrains.kotlin.analysis.api.KtNonConstantInitializerValue
import org.jetbrains.kotlin.analysis.api.base.KtConstantValue
import org.jetbrains.kotlin.analysis.api.components.KtCompileTimeConstantProvider
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirCompileTimeConstantEvaluator
+import org.jetbrains.kotlin.analysis.api.fir.symbols.getKtConstantInitializer
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
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.declarations.utils.referredPropertySymbol
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.psi
import org.jetbrains.kotlin.fir.references.FirNamedReference
+import org.jetbrains.kotlin.fir.resolvedSymbol
+import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtExpression
@@ -27,6 +35,9 @@ internal class KtFirCompileTimeConstantProvider(
override fun evaluate(expression: KtExpression): KtConstantValue? = withValidityAssertion {
when (val fir = expression.getOrBuildFir(firResolveState)) {
+ is FirPropertyAccessExpression -> {
+ fir.referredPropertySymbol?.toKtConstantValue()
+ }
is FirExpression -> {
try {
FirCompileTimeConstantEvaluator.evaluateAsKtConstantExpression(fir)
@@ -35,8 +46,10 @@ internal class KtFirCompileTimeConstantProvider(
}
}
is FirNamedReference -> {
- // TODO: but... if it refers to a property with a constant initializer, we can retrieve that technically?
- null
+ when (val resolvedSymbol = fir.resolvedSymbol) {
+ is FirPropertySymbol -> resolvedSymbol.toKtConstantValue()
+ else -> null
+ }
}
// For invalid code like the following,
// ```
@@ -50,4 +63,18 @@ internal class KtFirCompileTimeConstantProvider(
else -> throwUnexpectedFirElementError(fir, expression)
}
}
+
+ private fun FirPropertySymbol.toKtConstantValue(): KtConstantValue? = withValidityAssertion {
+ if (isVal) {
+ getKtConstantInitializer()?.toKtConstantValue()
+ } else null
+ }
+
+ private fun KtInitializerValue?.toKtConstantValue(): KtConstantValue? = withValidityAssertion {
+ when (this) {
+ null -> null
+ is KtConstantInitializerValue -> constant
+ is KtNonConstantInitializerValue -> initializerPsi?.let { evaluate(it) }
+ }
+ }
}
diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/compileTimeConstantProvider/FirCompileTimeConstantEvaluatorTestGenerated.java b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/compileTimeConstantProvider/FirCompileTimeConstantEvaluatorTestGenerated.java
index 4bd49cc4307..2cbc03528b1 100644
--- a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/compileTimeConstantProvider/FirCompileTimeConstantEvaluatorTestGenerated.java
+++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/compileTimeConstantProvider/FirCompileTimeConstantEvaluatorTestGenerated.java
@@ -41,9 +41,39 @@ public class FirCompileTimeConstantEvaluatorTestGenerated extends AbstractCompil
}
@Test
- @TestMetadata("namedReference.kt")
- public void testNamedReference() throws Exception {
- runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference.kt");
+ @TestMetadata("namedReference_const.kt")
+ public void testNamedReference_const() throws Exception {
+ runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_const.kt");
+ }
+
+ @Test
+ @TestMetadata("namedReference_val.kt")
+ public void testNamedReference_val() throws Exception {
+ runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_val.kt");
+ }
+
+ @Test
+ @TestMetadata("namedReference_var.kt")
+ public void testNamedReference_var() throws Exception {
+ runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_var.kt");
+ }
+
+ @Test
+ @TestMetadata("propertyInCompanionObject.kt")
+ public void testPropertyInCompanionObject() throws Exception {
+ runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject.kt");
+ }
+
+ @Test
+ @TestMetadata("propertyInCompanionObject_indirect.kt")
+ public void testPropertyInCompanionObject_indirect() throws Exception {
+ runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject_indirect.kt");
+ }
+
+ @Test
+ @TestMetadata("propertyInCompanionObject_indirect_twice.kt")
+ public void testPropertyInCompanionObject_indirect_twice() throws Exception {
+ runTest("analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject_indirect_twice.kt");
}
@Test
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_const.kt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_const.kt
new file mode 100644
index 00000000000..fd1ee8e96db
--- /dev/null
+++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_const.kt
@@ -0,0 +1,8 @@
+class Test {
+ const val bar : Int = 42
+}
+
+fun box() {
+ val t = Test()
+ t.bar
+}
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_const.txt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_const.txt
new file mode 100644
index 00000000000..9ff5cc75772
--- /dev/null
+++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_const.txt
@@ -0,0 +1,3 @@
+expression: bar
+constant: 42
+constantValueKind: Int
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_val.kt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_val.kt
new file mode 100644
index 00000000000..58ffcfe01e1
--- /dev/null
+++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_val.kt
@@ -0,0 +1,8 @@
+class Test {
+ val bar : Int = 42
+}
+
+fun box() {
+ val t = Test()
+ t.bar
+}
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_val.txt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_val.txt
new file mode 100644
index 00000000000..9ff5cc75772
--- /dev/null
+++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_val.txt
@@ -0,0 +1,3 @@
+expression: bar
+constant: 42
+constantValueKind: Int
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference.kt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_var.kt
similarity index 100%
rename from analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference.kt
rename to analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_var.kt
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference.txt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_var.txt
similarity index 100%
rename from analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference.txt
rename to analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_var.txt
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject.kt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject.kt
new file mode 100644
index 00000000000..86ff6d158ae
--- /dev/null
+++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject.kt
@@ -0,0 +1,11 @@
+package prop.`in`.`companion`
+
+class Test {
+ fun test() {
+ val x = someField
+ }
+ companion object {
+ // effectively constant
+ val someField = "something"
+ }
+}
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject.txt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject.txt
new file mode 100644
index 00000000000..a082d0ce5af
--- /dev/null
+++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject.txt
@@ -0,0 +1,3 @@
+expression: someField
+constant: "something"
+constantValueKind: String
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject_indirect.kt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject_indirect.kt
new file mode 100644
index 00000000000..dba0e6a3d90
--- /dev/null
+++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject_indirect.kt
@@ -0,0 +1,12 @@
+package prop.`in`.`companion`.indirect
+
+class Test {
+ fun test() {
+ val x = indirectPointer
+ }
+ companion object {
+ // effectively constant
+ val someField = "something"
+ val indirectPointer = someField
+ }
+}
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject_indirect.txt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject_indirect.txt
new file mode 100644
index 00000000000..82c273b3976
--- /dev/null
+++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject_indirect.txt
@@ -0,0 +1,3 @@
+expression: indirectPointer
+constant: "something"
+constantValueKind: String
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject_indirect_twice.kt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject_indirect_twice.kt
new file mode 100644
index 00000000000..d5ea18b3ab2
--- /dev/null
+++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject_indirect_twice.kt
@@ -0,0 +1,13 @@
+package prop.`in`.`companion`.indirect.twice
+
+class Test {
+ fun test() {
+ val x = oneMore
+ }
+ companion object {
+ // effectively constant
+ val someField = "something"
+ val indirectPointer = someField
+ val oneMore = indirectPointer
+ }
+}
diff --git a/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject_indirect_twice.txt b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject_indirect_twice.txt
new file mode 100644
index 00000000000..c493fcb415b
--- /dev/null
+++ b/analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/propertyInCompanionObject_indirect_twice.txt
@@ -0,0 +1,3 @@
+expression: oneMore
+constant: "something"
+constantValueKind: String