Default function argument support in IR serializer.

This commit is contained in:
Alexander Gorshenev
2017-03-30 04:25:34 +03:00
committed by alexander-gorshenev
parent aa7e3f40fd
commit 5b66a62da5
3 changed files with 66 additions and 34 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.descriptors.contributedMethods
import org.jetbrains.kotlin.backend.konan.llvm.base64Decode
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.expressions.IrLoop
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope
@@ -323,6 +324,14 @@ internal class IrDescriptorDeserializer(val context: Context,
val name = proto.name
when (proto.kind) {
KotlinDescriptor.Kind.CLASS -> {
val parentScope =
parentMemberScopeByFqNameIndex(classOrPackage)
val clazz = parentScope.getContributedClassifier(
Name.identifier(name), NoLookupLocation.FROM_BACKEND)
return listOf(clazz!!)
}
KotlinDescriptor.Kind.CONSTRUCTOR -> {
val parent = parentByFqNameIndex(classOrPackage)
assert(parent is ClassDescriptor)
@@ -332,9 +341,9 @@ internal class IrDescriptorDeserializer(val context: Context,
KotlinDescriptor.Kind.FUNCTION -> {
val parentScope =
parentMemberScopeByFqNameIndex(classOrPackage)
return parentScope.contributedMethods.filter{
it.name == Name.guessByFirstCharacter(name)
}
return parentScope.contributedMethods.filter{
it.name == Name.guessByFirstCharacter(name)
}
}
else -> TODO("Can't find matching names for ${proto.kind}")
}
@@ -394,6 +403,8 @@ internal class IrDescriptorDeserializer(val context: Context,
selectAccessor(matching, proto)
KotlinDescriptor.Kind.CONSTRUCTOR ->
selectConstructor(matching, proto)
KotlinDescriptor.Kind.CLASS ->
matching.single()
else -> TODO("don't know how to select ${proto.kind}")
}
}
@@ -416,6 +427,11 @@ internal class IrDescriptorDeserializer(val context: Context,
substituteAccessor(proto, originalDescriptor)
is ClassConstructorDescriptor ->
substituteConstructor(proto, originalDescriptor)
is ClassDescriptor ->
// TODO: do we really need to ever substitute
// class descriptors here?
//substituteClass(proto, originalDescriptor)
originalDescriptor
else -> error("unexpected type of public function")
}
}
@@ -114,12 +114,12 @@ message IrConst {
message IrDelegatingConstructorCall {
required KotlinDescriptor descriptor = 1;
required MemberAccessCommon member_access = 3;
required MemberAccessCommon member_access = 2;
}
message IrEnumConstructorCall {
required KotlinDescriptor descriptor = 2;
required MemberAccessCommon member_access = 3;
required KotlinDescriptor descriptor = 1;
required MemberAccessCommon member_access = 2;
}
message IrGetEnumValue {
@@ -192,21 +192,20 @@ message IrOperation {
IrCallableReference callable_reference = 4;
IrConst const = 5;
IrDelegatingConstructorCall delegating_constructor_call = 6;
//IrEnumEntry enum_entry = 7;
IrEnumConstructorCall enum_constructor_call = 8;
IrGetEnumValue get_enum_value = 9;
IrGetValue get_value = 10;
IrGetObject get_object = 11;
IrInstanceInitializerCall instance_initializer_call = 12;
IrReturn return = 13;
IrSetVariable set_variable = 14;
IrStringConcat string_concat = 15;
IrThrow throw = 16;
IrTry try = 17;
IrTypeOp type_op = 18;
IrVararg vararg = 19;
IrWhen when = 20;
IrWhile while = 21;
IrEnumConstructorCall enum_constructor_call = 7;
IrGetEnumValue get_enum_value = 8;
IrGetValue get_value = 9;
IrGetObject get_object = 10;
IrInstanceInitializerCall instance_initializer_call = 11;
IrReturn return = 12;
IrSetVariable set_variable = 13;
IrStringConcat string_concat = 14;
IrThrow throw = 15;
IrTry try = 16;
IrTypeOp type_op = 17;
IrVararg vararg = 18;
IrWhen when = 19;
IrWhile while = 20;
}
}
@@ -230,7 +229,12 @@ message IrExpression {
/* ------ Declarations --------------------------------------------- */
message IrFunc {
message DefaultArgument {
required int32 position = 1;
required IrExpression value = 2;
}
optional IrStatement body = 1;
repeated DefaultArgument default_argument = 2;
}
message IrVar {
@@ -171,7 +171,8 @@ internal class IrSerializer(val context: Context,
// Am I observing an IR generation regression?
// I see a lack of arg for an empty vararg,
// rather than an empty vararg node.
assert(it.varargElementType != null)
assert(it.varargElementType != null ||
it.declaresDefaultValue())
} else {
val arg = actual!!
val argProto = serializeExpression(arg)
@@ -441,6 +442,17 @@ internal class IrSerializer(val context: Context,
val proto = KonanIr.IrFunc.newBuilder()
val body = function.body
if (body != null) proto.setBody(serializeStatement(body))
function.descriptor.valueParameters.forEachIndexed { index, it ->
val default = function.getDefault(it)
if (default != null) {
val pair = KonanIr.IrFunc.DefaultArgument.newBuilder()
pair.position = index
pair.value = serializeExpression(default.expression)
proto.addDefaultArgument(pair)
}
}
return proto.build()
}
@@ -594,7 +606,6 @@ internal class IrDeserializer(val context: Context,
fun deserializeStatement(proto: KonanIr.IrStatement): IrElement {
val start = proto.getCoordinates().getStartOffset()
val end = proto.getCoordinates().getEndOffset()
//val statement = proto.getStatement()
val element = when {
proto.hasBlockBody()
-> deserializeBlockBody(proto.getBlockBody(), start, end)
@@ -630,9 +641,11 @@ internal class IrDeserializer(val context: Context,
}
fun deserializeMemberAccessCommon(access: IrMemberAccessExpression, descriptor: CallableDescriptor, proto: KonanIr.MemberAccessCommon) {
descriptor.valueParameters.mapIndexed { i, valueParameterDescriptor ->
access.putValueArgument(i, deserializeExpression(proto.getValueArgument(i)))
proto.valueArgumentList.mapIndexed { i, expr ->
access.putValueArgument(i, deserializeExpression(expr))
}
if (proto.hasDispatchReceiver()) {
access.dispatchReceiver = deserializeExpression(proto.dispatchReceiver)
}
@@ -668,10 +681,8 @@ internal class IrDeserializer(val context: Context,
start: Int, end: Int, type: KotlinType): IrCallableReference {
val descriptor = deserializeDescriptor(proto.getDescriptor()) as CallableDescriptor
//if (descriptor.typeParameters.isNotEmpty()) error("We can't deserialize typa arguments")
val typeMap = deserializeTypeMap(descriptor, proto.typeMap)
val callable = IrCallableReferenceImpl(start, end, type, descriptor, typeMap, null)
//deserializeMemberAccessCommon(callable, descriptor, proto.memberAccess)
return callable
}
@@ -679,19 +690,14 @@ internal class IrDeserializer(val context: Context,
val descriptor = deserializeDescriptor(proto.getDescriptor()) as ClassConstructorDescriptor
val typeArgs = deserializeTypeMap(descriptor, proto.memberAccess.getTypeMap())
// TODO: implement the last three args here.
val call = IrDelegatingConstructorCallImpl(start, end, descriptor, typeArgs)
//descriptor.valueParameters.mapIndexed { i, valueParameterDescriptor ->
// call.putValueArgument(i, deserializeExpression(proto.getValueArgument(i)))
//}
deserializeMemberAccessCommon(call, descriptor, proto.memberAccess)
return call
}
fun deserializeEnumConstructorCall(proto: KonanIr.IrEnumConstructorCall, start: Int, end: Int, type: KotlinType): IrEnumConstructorCall {
val descriptor = deserializeDescriptor(proto.getDescriptor()) as ClassConstructorDescriptor
//val typeArgs = deserializeTypeMap(descriptor, proto.memberAccess.getTypeMap())
val call = IrEnumConstructorCallImpl(start, end, descriptor)
deserializeMemberAccessCommon(call, descriptor, proto.memberAccess)
return call
@@ -708,7 +714,6 @@ internal class IrDeserializer(val context: Context,
val type = deserializeKotlinType(proto.type)
val descriptor = deserializeDescriptor(proto.descriptor) as ClassDescriptor
// TODO: origin!
return IrGetEnumValueImpl(start, end, type, descriptor)
}
@@ -720,7 +725,6 @@ internal class IrDeserializer(val context: Context,
fun deserializeInstanceInitializerCall(proto: KonanIr.IrInstanceInitializerCall, start: Int, end: Int, type: KotlinType): IrInstanceInitializerCall {
val descriptor = deserializeDescriptor(proto.getDescriptor()) as ClassDescriptor
// TODO: implement the last three args here.
return IrInstanceInitializerCallImpl(start, end, descriptor)
}
@@ -932,6 +936,14 @@ internal class IrDeserializer(val context: Context,
val function = IrFunctionImpl(start, end, origin,
descriptor as FunctionDescriptor, body as IrBody)
proto.defaultArgumentList.forEach {
val expr = deserializeExpression(it.value)
function.putDefault(
descriptor.valueParameters.get(it.position),
IrExpressionBodyImpl(start, end, expr))
}
return function
}