Implement interop integer conversions to be used with type inference

This commit is contained in:
Svyatoslav Scherbina
2017-03-27 21:49:06 +03:00
committed by SvyatoslavScherbina
parent 757c306341
commit f65044c7bb
5 changed files with 100 additions and 3 deletions
@@ -132,6 +132,10 @@ internal class InteropBuiltIns(builtIns: KonanBuiltIns) {
fun isTriviallyAdaptedFunctionType(type: KotlinType): Boolean =
type.isSubtypeOf(trivallyAdaptedFunctionTypeType)
val signExtend = packageScope.getContributedFunctions("signExtend").single()
val narrow = packageScope.getContributedFunctions("narrow").single()
}
private fun MemberScope.getContributedVariables(name: String) =
@@ -7,6 +7,7 @@ import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.ValueType
import org.jetbrains.kotlin.backend.konan.isRepresentedAs
import org.jetbrains.kotlin.backend.konan.reportCompilationError
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.builders.IrBuilder
@@ -239,6 +240,50 @@ private class InteropTransformer(val context: Context, val irFile: IrFile) : IrB
}
}
interop.signExtend, interop.narrow -> {
val integerTypePredicates = arrayOf(
KotlinBuiltIns::isByte, KotlinBuiltIns::isShort, KotlinBuiltIns::isInt, KotlinBuiltIns::isLong
)
val receiver = expression.extensionReceiver!!
val typeOperand = expression.getSingleTypeArgument()
val receiverTypeIndex = integerTypePredicates.indexOfFirst { it(receiver.type) }
val typeOperandIndex = integerTypePredicates.indexOfFirst { it(typeOperand) }
if (receiverTypeIndex == -1) {
context.reportCompilationError("Receiver's type ${receiver.type} is not an integer type",
irFile, receiver)
}
if (typeOperandIndex == -1) {
context.reportCompilationError("Type argument $typeOperand is not an integer type",
irFile, expression)
}
when (descriptor) {
interop.signExtend -> if (receiverTypeIndex > typeOperandIndex) {
context.reportCompilationError("unable to sign extend ${receiver.type} to $typeOperand",
irFile, expression)
}
interop.narrow -> if (receiverTypeIndex < typeOperandIndex) {
context.reportCompilationError("unable to narrow ${receiver.type} to $typeOperand",
irFile, expression)
}
else -> throw Error()
}
val conversionDescriptor = receiver.type.memberScope.getContributedFunctions(
Name.identifier("to$typeOperand"), NoLookupLocation.FROM_BACKEND).single()
builder.irCall(conversionDescriptor).apply {
dispatchReceiver = receiver
}
}
else -> expression
}
}
@@ -20,7 +20,7 @@ fun main(args: Array<String>) {
with(serverAddr) {
memset(this.ptr, 0, sockaddr_in.size)
sin_family.value = AF_INET.toByte()
sin_family.value = AF_INET.narrow()
sin_addr.s_addr.value = htons(0).toInt()
sin_port.value = htons(port)
}