Add ONLY_INTRINSIC_CONST evaluation mode

This commit is contained in:
Ivan Kylchik
2021-11-12 19:25:15 +03:00
parent 761424b131
commit 3bf678a011
3 changed files with 18 additions and 6 deletions
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
import org.jetbrains.kotlin.utils.keysToMap
import java.lang.invoke.MethodType
val intrinsicConstEvaluationAnnotation = FqName("kotlin.internal.IntrinsicConstEvaluation")
val compileTimeAnnotation = FqName("kotlin.CompileTimeCalculation")
val evaluateIntrinsicAnnotation = FqName("kotlin.EvaluateIntrinsic")
val contractsDslAnnotation = FqName("kotlin.internal.ContractsDsl")
@@ -302,5 +303,5 @@ internal fun IrGetValue.isAccessToObject(): Boolean {
}
internal fun IrFunction.isAccessorOfPropertyWithBackingField(): Boolean {
return this is IrSimpleFunction && this.correspondingPropertySymbol?.owner?.backingField != null
return this is IrSimpleFunction && this.correspondingPropertySymbol?.owner?.backingField?.initializer != null
}
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.interpreter.*
import org.jetbrains.kotlin.ir.interpreter.hasAnnotation
import org.jetbrains.kotlin.ir.interpreter.isUnsigned
import org.jetbrains.kotlin.ir.types.isAny
import org.jetbrains.kotlin.ir.types.isPrimitiveType
import org.jetbrains.kotlin.ir.types.isString
@@ -69,6 +68,17 @@ enum class EvaluationMode(protected val mustCheckBody: Boolean) {
else -> fqName in allowedExtensionFunctions
}
}
},
ONLY_INTRINSIC_CONST(mustCheckBody = false) {
override fun canEvaluateFunction(function: IrFunction, expression: IrCall?): Boolean {
return function.isCompileTimeProperty() || function.isMarkedAsIntrinsicConst()
}
private fun IrDeclaration?.isCompileTimeProperty(): Boolean {
val property = (this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner ?: return false
return property.isConst || property.isMarkedAsIntrinsicConst()
}
};
abstract fun canEvaluateFunction(function: IrFunction, expression: IrCall? = null): Boolean
@@ -83,6 +93,7 @@ enum class EvaluationMode(protected val mustCheckBody: Boolean) {
)
fun IrDeclaration.isMarkedAsCompileTime() = isMarkedWith(compileTimeAnnotation)
protected fun IrDeclaration.isMarkedAsIntrinsicConst() = isMarkedWith(intrinsicConstEvaluationAnnotation)
private fun IrDeclaration.isContract() = isMarkedWith(contractsDslAnnotation)
private fun IrDeclaration.isMarkedAsEvaluateIntrinsic() = isMarkedWith(evaluateIntrinsicAnnotation)
protected fun IrDeclaration.isCompileTimeTypeAlias() = this.parentClassOrNull?.fqName in compileTimeTypeAliases
@@ -32,7 +32,7 @@ class IrCompileTimeChecker(
override fun visitElement(element: IrElement, data: Nothing?) = false
private fun visitStatements(statements: List<IrStatement>, data: Nothing?): Boolean {
if (mode == EvaluationMode.ONLY_BUILTINS) {
if (mode == EvaluationMode.ONLY_BUILTINS || mode == EvaluationMode.ONLY_INTRINSIC_CONST) {
val statement = statements.singleOrNull() ?: return false
return statement.accept(this, data)
}
@@ -203,7 +203,7 @@ class IrCompileTimeChecker(
}
override fun visitFunctionExpression(expression: IrFunctionExpression, data: Nothing?): Boolean {
if (mode == EvaluationMode.ONLY_BUILTINS) return false
if (mode == EvaluationMode.ONLY_BUILTINS || mode == EvaluationMode.ONLY_INTRINSIC_CONST) return false
val isLambda = expression.origin == IrStatementOrigin.LAMBDA || expression.origin == IrStatementOrigin.ANONYMOUS_FUNCTION
val isCompileTime = mode.canEvaluateFunction(expression.function)
return expression.function.asVisited {
@@ -245,7 +245,7 @@ class IrCompileTimeChecker(
}
override fun visitTry(aTry: IrTry, data: Nothing?): Boolean {
if (mode == EvaluationMode.ONLY_BUILTINS) return false
if (mode == EvaluationMode.ONLY_BUILTINS || mode == EvaluationMode.ONLY_INTRINSIC_CONST) return false
if (!aTry.tryResult.accept(this, data)) return false
if (aTry.finallyExpression != null && aTry.finallyExpression?.accept(this, data) == false) return false
return aTry.catches.all { it.result.accept(this, data) }
@@ -273,7 +273,7 @@ class IrCompileTimeChecker(
when (this) {
EvaluationMode.FULL -> true
EvaluationMode.WITH_ANNOTATIONS -> (expression.symbol.owner as IrClass).isMarkedAsCompileTime()
EvaluationMode.ONLY_BUILTINS -> false
EvaluationMode.ONLY_BUILTINS, EvaluationMode.ONLY_INTRINSIC_CONST -> false
}
}
}