Skip to content

Commit

Permalink
interface: Add to/from interface in scala ast
Browse files Browse the repository at this point in the history
Part of #10810

changelog_begin
changelog_end
  • Loading branch information
sofiafaro-da committed Sep 21, 2021
1 parent 4b4d7a3 commit 7f269c3
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1096,11 +1096,23 @@ private[archive] class DecodeV1(minor: LV.Minor) {
value = decodeExpr(fromAnyException.getExpr, definition),
)

case PLF.Expr.SumCase.TO_INTERFACE => // TODO https://github.com/digital-asset/daml/issues/10810
throw Error.Parsing("to_interface not yet implemented")
case PLF.Expr.SumCase.TO_INTERFACE =>
assertSince(LV.Features.interfaces, "Expr.to_interface")
val toInterface = lfExpr.getToInterface
EToInterface(
iface = decodeTypeConName(toInterface.getInterfaceType),
tpl = decodeTypeConName(toInterface.getTemplateType),
value = decodeExpr(toInterface.getTemplateExpr, definition),
)

case PLF.Expr.SumCase.FROM_INTERFACE => // TODO https://github.com/digital-asset/daml/issues/10810
throw Error.Parsing("from_interface not yet implemented")
case PLF.Expr.SumCase.FROM_INTERFACE =>
assertSince(LV.Features.interfaces, "Expr.from_interface")
val fromInterface = lfExpr.getFromInterface
EFromInterface(
iface = decodeTypeConName(fromInterface.getInterfaceType),
tpl = decodeTypeConName(fromInterface.getTemplateType),
value = decodeExpr(fromInterface.getInterfaceExpr, definition),
)

case PLF.Expr.SumCase.SUM_NOT_SET =>
throw Error.Parsing("Expr.SUM_NOT_SET")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,24 @@ private[daml] class EncodeV1(minor: LV.Minor) {
builder.setFromAnyException(
PLF.Expr.FromAnyException.newBuilder().setType(ty).setExpr(body)
)
case EToInterface(iface, tpl, value) =>
assertSince(LV.Features.interfaces, "Expr.ToInterface")
builder.setToInterface(
PLF.Expr.ToInterface
.newBuilder()
.setInterfaceType(iface)
.setTemplateType(tpl)
.setTemplateExpr(value)
)
case EFromInterface(iface, tpl, value) =>
assertSince(LV.Features.interfaces, "Expr.FromInterface")
builder.setFromInterface(
PLF.Expr.FromInterface
.newBuilder()
.setInterfaceType(iface)
.setTemplateType(tpl)
.setInterfaceExpr(value)
)
case EExperimental(name, ty) =>
assertSince(LV.v1_dev, "Expr.experimental")
builder.setExperimental(PLF.Expr.Experimental.newBuilder().setName(name).setType(ty))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,10 @@ private[lf] final class Compiler(
SBFromAny(ty)(compile(e))
case EThrow(_, ty, e) =>
SBThrow(SBToAny(ty)(compile(e)))
case EToInterface(_, _, _) => // TODO https://github.com/digital-asset/daml/issues/10810
throw CompilationError("EToInterface not yet implemented in speedy compiler")
case EFromInterface(_, _, _) => // TODO https://github.com/digital-asset/daml/issues/10810
throw CompilationError("EFromInterface not yet implemented in speedy compiler")
case EExperimental(name, _) =>
SBExperimental(name)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ object Ast {
/** Extract the payload from an AnyException if it matches the given exception type */
final case class EFromAnyException(typ: Type, value: Expr) extends Expr

/** Convert template payload to interface it implements */
final case class EToInterface(iface: TypeConName, tpl: TypeConName, value: Expr) extends Expr

/** Convert interface back to template payload if possible */
final case class EFromInterface(iface: TypeConName, tpl: TypeConName, value: Expr) extends Expr

//
// Kinds
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ private[daml] class AstRewriter(
EFromAnyException(apply(ty), apply(body))
case EToAnyException(typ, body) =>
EToAnyException(apply(typ), apply(body))
case EToInterface(iface, tpl, value) =>
EToInterface(apply(iface), apply(tpl), apply(value))
case EFromInterface(iface, tpl, value) =>
EFromInterface(apply(iface), apply(tpl), apply(value))
}

def apply(x: TypeConApp): TypeConApp = x match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -931,6 +931,14 @@ private[validation] object Typing {
TUpdate(TTyCon(tpl))
}

private def checkImplements(tpl: TypeConName, iface: TypeConName): Unit = {
handleLookup(ctx, interface.lookupInterface(iface))
val template = handleLookup(ctx, interface.lookupTemplate(tpl))
if (!template.implements.contains(iface))
throw ETemplateDoesNotImplementInterface(ctx, tpl, iface)
()
}

private def checkByKey(tmplId: TypeConName, key: Expr): Unit = {
val tmplKey = handleLookup(ctx, interface.lookupTemplateKey(tmplId))
checkExpr(key, tmplKey.typ)
Expand Down Expand Up @@ -1135,6 +1143,14 @@ private[validation] object Typing {
checkExceptionType(typ)
checkExpr(value, TAnyException)
TOptional(typ)
case EToInterface(iface, tpl, value) =>
checkImplements(tpl, iface)
checkExpr(value, TTyCon(tpl))
TTyCon(iface)
case EFromInterface(iface, tpl, value) =>
checkImplements(tpl, iface)
checkExpr(value, TTyCon(iface))
TOptional(TTyCon(tpl))
case EExperimental(_, typ) =>
typ
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -457,3 +457,12 @@ final case class EBadInterfaceChoiceImplRetType(
override protected def prettyInternal: String =
s"The implementation of the choice $choice of interface $iface in template $template differs from the interface definition in the return type.\nExpected: $ifaceRetType\n But got: $tplRetType"
}

final case class ETemplateDoesNotImplementInterface(
context: Context,
template: TypeConName,
iface: TypeConName,
) extends ValidationError {
override protected def prettyInternal: String =
s"Template $template does not implement interface $iface"
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ private[validation] object ExprIterable {
Iterator(value)
case EFromAnyException(typ @ _, value) =>
Iterator(value)
case EToInterface(iface @ _, tpl @ _, value) =>
Iterator(value)
case EFromInterface(iface @ _, tpl @ _, value) =>
Iterator(value)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ private[validation] object TypeIterable {
case EFromAnyException(typ, value) =>
Iterator(typ) ++
iterator(value)
case EToInterface(iface, tpl, value) =>
Iterator(TTyCon(iface), TTyCon(tpl)) ++ iterator(value)
case EFromInterface(iface, tpl, value) =>
Iterator(TTyCon(iface), TTyCon(tpl)) ++ iterator(value)
case EVar(_) | EVal(_) | EBuiltin(_) | EPrimCon(_) | EPrimLit(_) | EApp(_, _) | ECase(_, _) |
ELocation(_, _) | EStructCon(_) | EStructProj(_, _) | EStructUpd(_, _, _) | ETyAbs(_, _) |
EExperimental(_, _) =>
Expand Down

0 comments on commit 7f269c3

Please sign in to comment.