Support interpretation for floorDiv and mod functions
This commit is contained in:
committed by
TeamCityServer
parent
f9607292b5
commit
b85a796492
+60
@@ -643,6 +643,66 @@ internal fun interpretBinaryFunction(name: String, typeA: String, typeB: String,
|
||||
"OROR" -> when (typeA) {
|
||||
"Boolean" -> if (typeB == "Boolean") return (a as Boolean) || (b as Boolean)
|
||||
}
|
||||
"mod" -> when (typeA) {
|
||||
"Byte" -> when (typeB) {
|
||||
"Byte" -> return (a as Byte).mod(b as Byte)
|
||||
"Short" -> return (a as Byte).mod(b as Short)
|
||||
"Int" -> return (a as Byte).mod(b as Int)
|
||||
"Long" -> return (a as Byte).mod(b as Long)
|
||||
}
|
||||
"Short" -> when (typeB) {
|
||||
"Byte" -> return (a as Short).mod(b as Byte)
|
||||
"Short" -> return (a as Short).mod(b as Short)
|
||||
"Int" -> return (a as Short).mod(b as Int)
|
||||
"Long" -> return (a as Short).mod(b as Long)
|
||||
}
|
||||
"Int" -> when (typeB) {
|
||||
"Byte" -> return (a as Int).mod(b as Byte)
|
||||
"Short" -> return (a as Int).mod(b as Short)
|
||||
"Int" -> return (a as Int).mod(b as Int)
|
||||
"Long" -> return (a as Int).mod(b as Long)
|
||||
}
|
||||
"Long" -> when (typeB) {
|
||||
"Byte" -> return (a as Long).mod(b as Byte)
|
||||
"Short" -> return (a as Long).mod(b as Short)
|
||||
"Int" -> return (a as Long).mod(b as Int)
|
||||
"Long" -> return (a as Long).mod(b as Long)
|
||||
}
|
||||
"Float" -> when (typeB) {
|
||||
"Float" -> return (a as Float).mod(b as Float)
|
||||
"Double" -> return (a as Float).mod(b as Double)
|
||||
}
|
||||
"Double" -> when (typeB) {
|
||||
"Float" -> return (a as Double).mod(b as Float)
|
||||
"Double" -> return (a as Double).mod(b as Double)
|
||||
}
|
||||
}
|
||||
"floorDiv" -> when (typeA) {
|
||||
"Byte" -> when (typeB) {
|
||||
"Byte" -> return (a as Byte).floorDiv(b as Byte)
|
||||
"Short" -> return (a as Byte).floorDiv(b as Short)
|
||||
"Int" -> return (a as Byte).floorDiv(b as Int)
|
||||
"Long" -> return (a as Byte).floorDiv(b as Long)
|
||||
}
|
||||
"Short" -> when (typeB) {
|
||||
"Byte" -> return (a as Short).floorDiv(b as Byte)
|
||||
"Short" -> return (a as Short).floorDiv(b as Short)
|
||||
"Int" -> return (a as Short).floorDiv(b as Int)
|
||||
"Long" -> return (a as Short).floorDiv(b as Long)
|
||||
}
|
||||
"Int" -> when (typeB) {
|
||||
"Byte" -> return (a as Int).floorDiv(b as Byte)
|
||||
"Short" -> return (a as Int).floorDiv(b as Short)
|
||||
"Int" -> return (a as Int).floorDiv(b as Int)
|
||||
"Long" -> return (a as Int).floorDiv(b as Long)
|
||||
}
|
||||
"Long" -> when (typeB) {
|
||||
"Byte" -> return (a as Long).floorDiv(b as Byte)
|
||||
"Short" -> return (a as Long).floorDiv(b as Short)
|
||||
"Int" -> return (a as Long).floorDiv(b as Int)
|
||||
"Long" -> return (a as Long).floorDiv(b as Long)
|
||||
}
|
||||
}
|
||||
}
|
||||
throw InterpreterMethodNotFoundError("Unknown function: $name($typeA, $typeB)")
|
||||
}
|
||||
|
||||
+6
-3
@@ -51,19 +51,22 @@ enum class EvaluationMode(protected val mustCheckBody: Boolean) {
|
||||
ONLY_BUILTINS(mustCheckBody = false) {
|
||||
private val forbiddenMethodsOnPrimitives = setOf("inc", "dec", "rangeTo", "hashCode")
|
||||
private val forbiddenMethodsOnStrings = setOf("subSequence", "hashCode", "<init>")
|
||||
private val allowedExtensionFunctions = setOf("kotlin.floorDiv", "kotlin.mod", "kotlin.NumbersKt.floorDiv", "kotlin.NumbersKt.mod")
|
||||
|
||||
override fun canEvaluateFunction(function: IrFunction, expression: IrCall?): Boolean {
|
||||
if ((function as? IrSimpleFunction)?.correspondingPropertySymbol?.owner?.isConst == true) return true
|
||||
|
||||
val parent = function.parentClassOrNull ?: return false
|
||||
val parentType = parent.defaultType
|
||||
val fqName = function.fqNameWhenAvailable?.asString()
|
||||
val parent = function.parentClassOrNull
|
||||
val parentType = parent?.defaultType
|
||||
return when {
|
||||
parentType == null -> fqName in allowedExtensionFunctions
|
||||
parentType.isPrimitiveType() -> function.name.asString() !in forbiddenMethodsOnPrimitives
|
||||
parentType.isString() -> function.name.asString() !in forbiddenMethodsOnStrings
|
||||
parentType.isAny() -> function.name.asString() == "toString" && expression?.dispatchReceiver !is IrGetObjectValue
|
||||
parent.isObject -> parent.parentClassOrNull?.defaultType?.let { it.isPrimitiveType() || it.isUnsigned() } == true
|
||||
parentType.isUnsignedType() && function is IrConstructor -> true
|
||||
else -> false
|
||||
else -> fqName in allowedExtensionFunctions
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user