Daml-script: Use curly braces notation for records in ledger export (#13634)

instead of `with` notation

fixes #13620

CHANGELOG_BEGIN
- [Daml-script] fix a bug in daml-script export formatting
  See https://github.com/digital-asset/daml/issues/13620
CHANGELOG_END
This commit is contained in:
Remy 2022-04-26 16:36:18 +02:00 committed by GitHub
parent aeda7159cf
commit 7dfbf58147
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 87 additions and 61 deletions

View File

@ -59,9 +59,8 @@ private[export] object Encode {
def primInstance(name: String, parms: Doc): Doc = {
val cls = Doc.text(s"Has${name.capitalize}")
val fun = Doc.text(s"_$name")
val prim = Doc.text(s"E${name.capitalize}")
(Doc.text("instance") & cls & parms & Doc.text("where") /
fun & Doc.text("= GHC.Types.primitive @") + quotes(prim)).nested(2)
fun & Doc.text("= GHC.Types.primitive @") + quotes(s"E${name.capitalize}")).nested(2)
}
val header =
(Doc.text("{-") &
@ -105,7 +104,7 @@ private[export] object Encode {
}
private def encodePartyBinding(party: Party, binding: String): Doc =
s"let $binding = lookupParty" &: quotes(Doc.text(Party.unwrap(party))) :& "parties"
s"let $binding = lookupParty" &: quotes(Party.unwrap(party)) :& "parties"
private def encodeTestExport(): Doc =
Doc.text("-- | Test 'export' with freshly allocated parties and") /
@ -151,7 +150,7 @@ private[export] object Encode {
("[" &: Doc.intercalate(
Doc.hardLine :+ ", ",
partyMap.keys.map { case Party(p) =>
val party = quotes(Doc.text(p))
val party = quotes(p)
tuple(Seq(party, party))
},
) :& "])").indent(2)
@ -320,23 +319,28 @@ private[export] object Encode {
}
}
private def quotes(v: Doc) =
"\"" +: v :+ "\""
private def quotes(v: String) =
"\"" +: Doc.text(v) :+ "\""
private def parens(v: Doc) =
Doc.text("(") + v + Doc.text(")")
private def tuple(xs: Seq[Doc]) =
parens(Doc.intercalate(Doc.text(", "), xs))
Doc.char('(') + v.nested(2) + Doc.char(')')
private def brackets(v: Doc) =
Doc.text("[") + v + Doc.text("]")
Doc.char('[') + v.nested(2) + Doc.char(']')
private def braces(v: Doc) =
Doc.char('{') + v.nested(2) + Doc.char('}')
private[this] val comma = Doc.comma + Doc.lineOrSpace
private def tuple(xs: Seq[Doc]) =
parens(Doc.intercalate(comma, xs))
private def list(xs: Seq[Doc]) =
brackets(Doc.intercalate(Doc.text(", "), xs))
brackets(Doc.intercalate(comma, xs))
private def pair(v1: Doc, v2: Doc) =
parens(v1 + Doc.text(", ") + v2)
parens(v1 + comma + v2)
private def stackNonEmpty(docs: Seq[Doc]): Doc =
Doc.stack(docs.filter(_.nonEmpty))
@ -346,12 +350,14 @@ private[export] object Encode {
cidMap: Map[ContractId, String],
r: Record,
): Doc = {
if (r.fields.isEmpty) {
if (r.fields.isEmpty)
qualifyId(r.getRecordId)
} else {
(qualifyId(r.getRecordId) + Doc.text(" with") /
Doc.stack(r.fields.map(f => encodeField(partyMap, cidMap, f)))).nested(2)
}
else
parens(
qualifyId(r.getRecordId) &
braces(Doc.intercalate(comma, r.fields.map(encodeField(partyMap, cidMap, _))))
)
}
private def encodeField(
@ -372,7 +378,7 @@ private[export] object Encode {
// LedgerStrings are strings that match the regexp ``[A-Za-z0-9#:\-_/ ]+
cidMap.get(cid) match {
case Some(value) => Doc.text(value)
case None => parens("lookupContract" &: quotes(Doc.text(cid.toString)) :& "contracts")
case None => parens("lookupContract" &: quotes(cid.toString) :& "contracts")
}
}
@ -391,7 +397,7 @@ private[export] object Encode {
qualifyId(TemplateId.unwrap(id))
private def encodeChoice(choice: Choice): Doc =
quotes(Doc.text(Choice.unwrap(choice)))
quotes(Choice.unwrap(choice))
private def encodeCmd(
partyMap: Map[Party, String],

View File

@ -18,37 +18,45 @@ class EncodeValueSpec extends AnyFreeSpec with Matchers {
import Encode._
"encodeValue" - {
"record" in {
val id1 = v.Identifier("pkg-id", "M", "R1")
val id2 = v.Identifier("pkg-id", "M", "R2")
val id3 = v.Identifier("pkg-id", "M", "R3")
val r = v.Value.Sum.Record(
v.Record(
Some(id1),
Seq(
v.RecordField("a", Some(v.Value().withInt64(1))),
v.RecordField(
"b",
Some(
v.Value()
.withRecord(
v.Record(Some(id2), Seq(v.RecordField("c", Some(v.Value().withInt64(42)))))
)
),
),
v.RecordField(
"c",
Some(v.Value().withRecord(v.Record(Some(id3)))),
),
val record = v.Record(
Some(v.Identifier("pkg-id", "M", "R1")),
Seq(
v.RecordField("a", Some(v.Value().withInt64(1))),
v.RecordField(
"b",
Some(
v.Value()
.withRecord(
v.Record(
Some(v.Identifier("pkg-id", "M", "R2")),
Seq(v.RecordField("c", Some(v.Value().withInt64(42)))),
)
)
),
)
)
encodeValue(Map.empty, Map.empty, r).render(80) shouldBe
"""M.R1 with
| a = 1
| b = M.R2 with
| c = 42
| c = M.R3""".stripMargin.replace("\r\n", "\n")
),
v.RecordField(
"c",
Some(v.Value().withRecord(v.Record(Some(v.Identifier("pkg-id", "M", "R3"))))),
),
),
)
"record" in {
encodeValue(
Map.empty,
Map.empty,
v.Value.Sum.Record(record),
).render(
80
) shouldBe "(M.R1 {a = 1, b = (M.R2 {c = 42}), c = M.R3})"
encodeValue(
Map.empty,
Map.empty,
v.Value.Sum.Record(record),
).render(30) shouldBe
"""(M.R1 {a = 1,
| b = (M.R2 {c = 42}),
| c = M.R3})""".stripMargin.replace("\r\n", "\n")
}
"tuple" in {
def tupleId(n: Int): v.Identifier = v
@ -86,9 +94,25 @@ class EncodeValueSpec extends AnyFreeSpec with Matchers {
encodeValue(Map.empty, Map(ContractId("my-contract-id") -> "mapped_cid"), cid.sum)
.render(80) shouldBe "mapped_cid"
}
"list" in {
val l = v.Value().withList(v.List(Seq(v.Value().withInt64(0), v.Value().withInt64(1))))
encodeValue(Map.empty, Map.empty, l.sum).render(80) shouldBe "[0, 1]"
"simple list" in {
val l = List(0L, 1L).map(v.Value().withInt64(_))
val value = v.Value().withList(v.List(l))
encodeValue(Map.empty, Map.empty, value.sum).render(80) shouldBe "[0, 1]"
}
"list of record" in {
val l = List(record, record).map(v.Value().withRecord(_))
val value = v.Value().withList(v.List(l))
encodeValue(Map.empty, Map.empty, value.sum).render(
100
) shouldBe "[(M.R1 {a = 1, b = (M.R2 {c = 42}), c = M.R3}), (M.R1 {a = 1, b = (M.R2 {c = 42}), c = M.R3})]"
encodeValue(Map.empty, Map.empty, value.sum).render(
30
) shouldBe """[(M.R1 {a = 1,
| b = (M.R2 {c = 42}),
| c = M.R3}),
| (M.R1 {a = 1,
| b = (M.R2 {c = 42}),
| c = M.R3})]""".stripMargin.replace("\r\n", "\n")
}
"int64" in {
encodeValue(Map.empty, Map.empty, v.Value().withInt64(42).sum).render(80) shouldBe "42"

View File

@ -70,14 +70,10 @@ export Args{parties, contracts} = do
-- EXPORT_PARTIES_END
-- EXPORT_PROPOSALS_BEGIN
(coinProposal_1_0, coinProposal_1_1) <- submit bank_0 do
coinProposal_1_0 <- createCmd ScriptExample.CoinProposal with
coin = ScriptExample.Coin with
issuer = bank_0
owner = alice_0
coinProposal_1_1 <- createCmd ScriptExample.CoinProposal with
coin = ScriptExample.Coin with
issuer = bank_0
owner = bob_0
coinProposal_1_0 <- createCmd (ScriptExample.CoinProposal {coin = (ScriptExample.Coin {issuer = bank_0,
owner = alice_0})})
coinProposal_1_1 <- createCmd (ScriptExample.CoinProposal {coin = (ScriptExample.Coin {issuer = bank_0,
owner = bob_0})})
pure (coinProposal_1_0, coinProposal_1_1)
-- EXPORT_PROPOSALS_END
-- EXPORT_ACCEPT_BEGIN