Default function argument support in IR serializer.
This commit is contained in:
committed by
alexander-gorshenev
parent
aa7e3f40fd
commit
5b66a62da5
+19
-3
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
+22
-18
@@ -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 {
|
||||
|
||||
+25
-13
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user