AA: evaluate constant property initializers
This commit is contained in:
committed by
Ilya Kirillov
parent
7ec7cc47a9
commit
1f93630a9c
+33
-3
@@ -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
|
||||
|
||||
+29
-2
@@ -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) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+33
-3
@@ -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
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class Test {
|
||||
const val bar : Int = 42
|
||||
}
|
||||
|
||||
fun box() {
|
||||
val t = Test()
|
||||
t.<expr>bar</expr>
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
expression: bar
|
||||
constant: 42
|
||||
constantValueKind: Int
|
||||
analysis/analysis-api/testData/components/compileTimeConstantProvider/evaluate/namedReference_val.kt
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
class Test {
|
||||
val bar : Int = 42
|
||||
}
|
||||
|
||||
fun box() {
|
||||
val t = Test()
|
||||
t.<expr>bar</expr>
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
expression: bar
|
||||
constant: 42
|
||||
constantValueKind: Int
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package prop.`in`.`companion`
|
||||
|
||||
class Test {
|
||||
fun test() {
|
||||
val x = <expr>someField</expr>
|
||||
}
|
||||
companion object {
|
||||
// effectively constant
|
||||
val someField = "something"
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
expression: someField
|
||||
constant: "something"
|
||||
constantValueKind: String
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package prop.`in`.`companion`.indirect
|
||||
|
||||
class Test {
|
||||
fun test() {
|
||||
val x = <expr>indirectPointer</expr>
|
||||
}
|
||||
companion object {
|
||||
// effectively constant
|
||||
val someField = "something"
|
||||
val indirectPointer = someField
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
expression: indirectPointer
|
||||
constant: "something"
|
||||
constantValueKind: String
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package prop.`in`.`companion`.indirect.twice
|
||||
|
||||
class Test {
|
||||
fun test() {
|
||||
val x = <expr>oneMore</expr>
|
||||
}
|
||||
companion object {
|
||||
// effectively constant
|
||||
val someField = "something"
|
||||
val indirectPointer = someField
|
||||
val oneMore = indirectPointer
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
expression: oneMore
|
||||
constant: "something"
|
||||
constantValueKind: String
|
||||
Reference in New Issue
Block a user