diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt index 6101458ad02..6a3292e8f79 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt @@ -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 } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/EvaluationMode.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/EvaluationMode.kt index 424e4c1c093..a9a98d5f485 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/EvaluationMode.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/EvaluationMode.kt @@ -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 diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt index ba38b9ff5dc..699112ce93a 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt @@ -32,7 +32,7 @@ class IrCompileTimeChecker( override fun visitElement(element: IrElement, data: Nothing?) = false private fun visitStatements(statements: List, 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 } } }