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 org.jetbrains.kotlin.utils.keysToMap
import java.lang.invoke.MethodType import java.lang.invoke.MethodType
val intrinsicConstEvaluationAnnotation = FqName("kotlin.internal.IntrinsicConstEvaluation")
val compileTimeAnnotation = FqName("kotlin.CompileTimeCalculation") val compileTimeAnnotation = FqName("kotlin.CompileTimeCalculation")
val evaluateIntrinsicAnnotation = FqName("kotlin.EvaluateIntrinsic") val evaluateIntrinsicAnnotation = FqName("kotlin.EvaluateIntrinsic")
val contractsDslAnnotation = FqName("kotlin.internal.ContractsDsl") val contractsDslAnnotation = FqName("kotlin.internal.ContractsDsl")
@@ -302,5 +303,5 @@ internal fun IrGetValue.isAccessToObject(): Boolean {
} }
internal fun IrFunction.isAccessorOfPropertyWithBackingField(): 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.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.interpreter.* import org.jetbrains.kotlin.ir.interpreter.*
import org.jetbrains.kotlin.ir.interpreter.hasAnnotation 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.isAny
import org.jetbrains.kotlin.ir.types.isPrimitiveType import org.jetbrains.kotlin.ir.types.isPrimitiveType
import org.jetbrains.kotlin.ir.types.isString import org.jetbrains.kotlin.ir.types.isString
@@ -69,6 +68,17 @@ enum class EvaluationMode(protected val mustCheckBody: Boolean) {
else -> fqName in allowedExtensionFunctions 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 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) fun IrDeclaration.isMarkedAsCompileTime() = isMarkedWith(compileTimeAnnotation)
protected fun IrDeclaration.isMarkedAsIntrinsicConst() = isMarkedWith(intrinsicConstEvaluationAnnotation)
private fun IrDeclaration.isContract() = isMarkedWith(contractsDslAnnotation) private fun IrDeclaration.isContract() = isMarkedWith(contractsDslAnnotation)
private fun IrDeclaration.isMarkedAsEvaluateIntrinsic() = isMarkedWith(evaluateIntrinsicAnnotation) private fun IrDeclaration.isMarkedAsEvaluateIntrinsic() = isMarkedWith(evaluateIntrinsicAnnotation)
protected fun IrDeclaration.isCompileTimeTypeAlias() = this.parentClassOrNull?.fqName in compileTimeTypeAliases protected fun IrDeclaration.isCompileTimeTypeAlias() = this.parentClassOrNull?.fqName in compileTimeTypeAliases
@@ -32,7 +32,7 @@ class IrCompileTimeChecker(
override fun visitElement(element: IrElement, data: Nothing?) = false override fun visitElement(element: IrElement, data: Nothing?) = false
private fun visitStatements(statements: List<IrStatement>, data: Nothing?): Boolean { 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 val statement = statements.singleOrNull() ?: return false
return statement.accept(this, data) return statement.accept(this, data)
} }
@@ -203,7 +203,7 @@ class IrCompileTimeChecker(
} }
override fun visitFunctionExpression(expression: IrFunctionExpression, data: Nothing?): Boolean { 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 isLambda = expression.origin == IrStatementOrigin.LAMBDA || expression.origin == IrStatementOrigin.ANONYMOUS_FUNCTION
val isCompileTime = mode.canEvaluateFunction(expression.function) val isCompileTime = mode.canEvaluateFunction(expression.function)
return expression.function.asVisited { return expression.function.asVisited {
@@ -245,7 +245,7 @@ class IrCompileTimeChecker(
} }
override fun visitTry(aTry: IrTry, data: Nothing?): Boolean { 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.tryResult.accept(this, data)) return false
if (aTry.finallyExpression != null && aTry.finallyExpression?.accept(this, data) == false) return false if (aTry.finallyExpression != null && aTry.finallyExpression?.accept(this, data) == false) return false
return aTry.catches.all { it.result.accept(this, data) } return aTry.catches.all { it.result.accept(this, data) }
@@ -273,7 +273,7 @@ class IrCompileTimeChecker(
when (this) { when (this) {
EvaluationMode.FULL -> true EvaluationMode.FULL -> true
EvaluationMode.WITH_ANNOTATIONS -> (expression.symbol.owner as IrClass).isMarkedAsCompileTime() EvaluationMode.WITH_ANNOTATIONS -> (expression.symbol.owner as IrClass).isMarkedAsCompileTime()
EvaluationMode.ONLY_BUILTINS -> false EvaluationMode.ONLY_BUILTINS, EvaluationMode.ONLY_INTRINSIC_CONST -> false
} }
} }
} }