AA: introduce KtConstantEvaluationMode

This commit is contained in:
Jinseong Jeon
2022-03-10 00:16:14 -08:00
committed by Ilya Kirillov
parent ee23a52e54
commit 606033e1e6
58 changed files with 350 additions and 63 deletions
@@ -8,11 +8,32 @@ package org.jetbrains.kotlin.analysis.api.components
import org.jetbrains.kotlin.analysis.api.base.KtConstantValue
import org.jetbrains.kotlin.psi.KtExpression
public enum class KtConstantEvaluationMode {
/**
* In this mode, what a compiler views as constants will be evaluated. In other words,
* expressions and properties that are free from runtime behaviors/changes will be evaluated,
* such as `const val` properties or binary expressions whose operands are constants.
*/
CONSTANT_EXPRESSION_EVALUATION,
/**
* In this mode, what a checker can approximate as constants will be evaluated. In other words,
* more expressions and properties that could be composites of other constants will be evaluated,
* such as `val` properties with constant initializers or binary expressions whose operands could be constants.
*
* Note that, as an approximation, the result can be sometimes incorrect or present even though there is an error.
*/
CONSTANT_LIKE_EXPRESSION_EVALUATION;
}
public abstract class KtCompileTimeConstantProvider : KtAnalysisSessionComponent() {
public abstract fun evaluate(expression: KtExpression): KtConstantValue?
public abstract fun evaluate(
expression: KtExpression,
mode: KtConstantEvaluationMode,
): KtConstantValue?
}
public interface KtCompileTimeConstantProviderMixIn : KtAnalysisSessionMixIn {
public fun KtExpression.evaluate(): KtConstantValue? =
analysisSession.compileTimeConstantProvider.evaluate(this)
public fun KtExpression.evaluate(mode: KtConstantEvaluationMode): KtConstantValue? =
analysisSession.compileTimeConstantProvider.evaluate(this, mode)
}
@@ -0,0 +1,3 @@
expression: 42 / d
constant: 42
constantValueKind: Int
@@ -0,0 +1,4 @@
class Test {
val p = <expr>42 / d</expr> // uninitialized d
const val d = 1
}
@@ -0,0 +1,3 @@
expression: 42 / d
constant: NOT_EVALUATED
constantValueKind: NOT_EVALUATED
@@ -0,0 +1,3 @@
expression: 42 / d
constant: error("Division by zero")
constantValueKind: Error
@@ -0,0 +1,5 @@
class Test {
val p = <expr>42 / d</expr> // uninitialized d
val d = 0 // should not raise div-by-zero error
}
@@ -0,0 +1,3 @@
expression: 42 / d
constant: NOT_EVALUATED
constantValueKind: NOT_EVALUATED
@@ -0,0 +1,8 @@
class Test {
const val bar : Int = 42
}
fun box() {
val t = Test()
t.<expr>bar</expr>
}
@@ -0,0 +1,8 @@
class Test {
val bar : Int = 42
}
fun box() {
val t = Test()
t.<expr>bar</expr>
}
@@ -0,0 +1,3 @@
expression: bar
constant: 42
constantValueKind: Int
@@ -0,0 +1,3 @@
expression: bar
constant: NOT_EVALUATED
constantValueKind: NOT_EVALUATED
@@ -0,0 +1,3 @@
expression: 42 / d
constant: 42
constantValueKind: Int
@@ -0,0 +1,2 @@
const val d = 1
val p = <expr>42 / d</expr>
@@ -0,0 +1,3 @@
expression: 42 / d
constant: NOT_EVALUATED
constantValueKind: NOT_EVALUATED
@@ -0,0 +1,3 @@
expression: 42 / d
constant: 42
constantValueKind: Int
@@ -0,0 +1,2 @@
val d = 1
val p = <expr>42 / d</expr>
@@ -0,0 +1,3 @@
expression: 42 / d
constant: NOT_EVALUATED
constantValueKind: NOT_EVALUATED