mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 01:07:18 +03:00
Drop support for Daml-LF party literals from the Scala side (#11922)
* Drop support for Daml-LF party literals from the Scala side This PR enforces that forbidPartyLiterals is always `true` and drops the corresponding literals from the AST. Haskell side is in #11930 fixes #11581 changelog_begin changelog_end * Update daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/ComparisonSBuiltinTest.scala Co-authored-by: Remy <remy.haemmerle@daml.com> * Revert "Update daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/ComparisonSBuiltinTest.scala" This reverts commit 55e542ce4e3a7fd15544ee703de3277ffc309b17. Co-authored-by: Remy <remy.haemmerle@daml.com>
This commit is contained in:
parent
18dc85680a
commit
8179c73763
@ -1636,12 +1636,8 @@ message DefValue {
|
||||
|
||||
Expr expr = 2;
|
||||
|
||||
// If true, the value must not contain any party literals and not reference
|
||||
// values which contain party literals.
|
||||
// This flag is used to simplify package validation by not requiring an
|
||||
// inference but only a check. Such a check must validate that this flag is
|
||||
// set correctly and that templates do not reference values which have this
|
||||
// flag set to false.
|
||||
// Always true for SDK > 1.18. Setting it to false
|
||||
// will result in the package being rejected.
|
||||
bool no_party_literals = 3;
|
||||
|
||||
bool is_test = 4;
|
||||
|
@ -349,19 +349,17 @@ private[archive] class DecodeV1(minor: LV.Minor) {
|
||||
getInternedDottedName(internedDName)
|
||||
}
|
||||
|
||||
private[this] def decodeFeatureFlags(flags: PLF.FeatureFlags): FeatureFlags = {
|
||||
private[lf] def decodeFeatureFlags(flags: PLF.FeatureFlags): FeatureFlags = {
|
||||
// NOTE(JM, #157): We disallow loading packages with these flags because they impact the Ledger API in
|
||||
// ways that would currently make it quite complicated to support them.
|
||||
if (
|
||||
!flags.getDontDivulgeContractIdsInCreateArguments || !flags.getDontDiscloseNonConsumingChoicesToObservers
|
||||
!flags.getDontDivulgeContractIdsInCreateArguments || !flags.getDontDiscloseNonConsumingChoicesToObservers || !flags.getForbidPartyLiterals
|
||||
) {
|
||||
throw Error.Parsing(
|
||||
"Deprecated feature flag settings detected, refusing to parse package"
|
||||
)
|
||||
}
|
||||
FeatureFlags(
|
||||
forbidPartyLiterals = flags.getForbidPartyLiterals
|
||||
)
|
||||
FeatureFlags.default
|
||||
}
|
||||
|
||||
private[this] def decodeDefDataType(lfDataType: PLF.DefDataType): DDataType = {
|
||||
@ -472,7 +470,10 @@ private[archive] class DecodeV1(minor: LV.Minor) {
|
||||
"EnumConstructors.constructors",
|
||||
)
|
||||
|
||||
private[this] def decodeDefValue(lfValue: PLF.DefValue): DValue = {
|
||||
private[lf] def decodeDefValue(lfValue: PLF.DefValue): DValue = {
|
||||
if (!lfValue.getNoPartyLiterals) {
|
||||
throw Error.Parsing("DefValue must have no_party_literals set to true")
|
||||
}
|
||||
val name = handleDottedName(
|
||||
lfValue.getNameWithType.getNameDnameList.asScala,
|
||||
lfValue.getNameWithType.getNameInternedDname,
|
||||
@ -480,7 +481,6 @@ private[archive] class DecodeV1(minor: LV.Minor) {
|
||||
)
|
||||
DValue(
|
||||
typ = decodeType(lfValue.getNameWithType.getType),
|
||||
noPartyLiterals = lfValue.getNoPartyLiterals,
|
||||
body = decodeExpr(lfValue.getExpr, name.toString),
|
||||
isTest = lfValue.getIsTest,
|
||||
)
|
||||
@ -1462,9 +1462,6 @@ private[archive] class DecodeV1(minor: LV.Minor) {
|
||||
case PLF.PrimLit.SumCase.TEXT_STR =>
|
||||
assertUntil(LV.Features.internedStrings, "PrimLit.text_str")
|
||||
PLText(lfPrimLit.getTextStr)
|
||||
case PLF.PrimLit.SumCase.PARTY_STR =>
|
||||
assertUntil(LV.Features.internedStrings, "PrimLit.party_str")
|
||||
toPLParty(lfPrimLit.getPartyStr)
|
||||
case PLF.PrimLit.SumCase.TIMESTAMP =>
|
||||
val t = Time.Timestamp.fromLong(lfPrimLit.getTimestamp)
|
||||
t.fold(e => throw Error.Parsing("error decoding timestamp: " + e), PLTimestamp)
|
||||
@ -1477,12 +1474,11 @@ private[archive] class DecodeV1(minor: LV.Minor) {
|
||||
case PLF.PrimLit.SumCase.NUMERIC_INTERNED_STR =>
|
||||
assertSince(LV.Features.numeric, "PrimLit.numeric")
|
||||
toPLNumeric(getInternedStr(lfPrimLit.getNumericInternedStr))
|
||||
case PLF.PrimLit.SumCase.PARTY_INTERNED_STR =>
|
||||
assertSince(LV.Features.internedStrings, "PrimLit.party_interned_str")
|
||||
toPLParty(getInternedStr(lfPrimLit.getPartyInternedStr))
|
||||
case PLF.PrimLit.SumCase.ROUNDING_MODE =>
|
||||
assertSince(LV.Features.bigNumeric, "Expr.rounding_mode")
|
||||
PLRoundingMode(java.math.RoundingMode.valueOf(lfPrimLit.getRoundingModeValue))
|
||||
case PLF.PrimLit.SumCase.PARTY_STR | PLF.PrimLit.SumCase.PARTY_INTERNED_STR =>
|
||||
throw Error.Parsing("Party literals are not supported")
|
||||
case PLF.PrimLit.SumCase.SUM_NOT_SET =>
|
||||
throw Error.Parsing("PrimLit.SUM_NOT_SET")
|
||||
}
|
||||
@ -1515,9 +1511,6 @@ private[archive] class DecodeV1(minor: LV.Minor) {
|
||||
private[this] def toPLDecimal(s: String) =
|
||||
PLNumeric(eitherToParseError(Decimal.fromString(s)))
|
||||
|
||||
private[this] def toPLParty(s: String) =
|
||||
PLParty(eitherToParseError(Party.fromString(s)))
|
||||
|
||||
// maxVersion excluded
|
||||
private[this] def assertUntil(maxVersion: LV, description: => String): Unit =
|
||||
if (!versionIsOlderThan(maxVersion))
|
||||
|
@ -956,9 +956,8 @@ class DecodeV1Spec
|
||||
pkg
|
||||
.modules(Ref.DottedName.assertFromString("DarReaderTest"))
|
||||
.definitions(Ref.DottedName.assertFromString("reverseCopy"))
|
||||
) {
|
||||
case Ast.DValue(_, _, Ast.ELocation(_, Ast.EVal(Ref.Identifier(resolvedExtId, _))), _) =>
|
||||
(resolvedExtId: String) should ===(extId: String)
|
||||
) { case Ast.DValue(_, Ast.ELocation(_, Ast.EVal(Ref.Identifier(resolvedExtId, _))), _) =>
|
||||
(resolvedExtId: String) should ===(extId: String)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1244,4 +1243,40 @@ class DecodeV1Spec
|
||||
}
|
||||
}
|
||||
|
||||
s"reject DefValue with no_party_literals = false" in {
|
||||
val defValue =
|
||||
DamlLf1.DefValue
|
||||
.newBuilder()
|
||||
.setNoPartyLiterals(false)
|
||||
.build()
|
||||
forEveryVersion { version =>
|
||||
val decoder = moduleDecoder(version)
|
||||
val ex = the[Error.Parsing] thrownBy decoder.decodeDefValue(defValue)
|
||||
ex.msg shouldBe "DefValue must have no_party_literals set to true"
|
||||
}
|
||||
}
|
||||
|
||||
s"reject Feature flags set to false" in {
|
||||
def featureFlags(
|
||||
forbidPartyLits: Boolean,
|
||||
dontDivulgeCids: Boolean,
|
||||
dontDiscloseNonConsuming: Boolean,
|
||||
) = DamlLf1.FeatureFlags
|
||||
.newBuilder()
|
||||
.setForbidPartyLiterals(forbidPartyLits)
|
||||
.setDontDivulgeContractIdsInCreateArguments(dontDivulgeCids)
|
||||
.setDontDiscloseNonConsumingChoicesToObservers(dontDiscloseNonConsuming)
|
||||
.build()
|
||||
forEveryVersion { version =>
|
||||
val decoder = moduleDecoder(version)
|
||||
decoder.decodeFeatureFlags(featureFlags(true, true, true)) shouldBe Ast.FeatureFlags.default
|
||||
Seq(
|
||||
featureFlags(false, true, true),
|
||||
featureFlags(true, false, true),
|
||||
featureFlags(true, true, false),
|
||||
).foreach { flags =>
|
||||
an[Error.Parsing] shouldBe thrownBy(decoder.decodeFeatureFlags(flags))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ private[daml] class EncodeV1(minor: LV.Minor) {
|
||||
builder.setFlags(
|
||||
PLF.FeatureFlags
|
||||
.newBuilder()
|
||||
.setForbidPartyLiterals(module.featureFlags.forbidPartyLiterals)
|
||||
.setForbidPartyLiterals(true)
|
||||
.setDontDivulgeContractIdsInCreateArguments(true)
|
||||
.setDontDiscloseNonConsumingChoicesToObservers(true)
|
||||
)
|
||||
@ -467,8 +467,6 @@ private[daml] class EncodeV1(minor: LV.Minor) {
|
||||
setString(value, builder.setTextStr, builder.setTextInternedStr)
|
||||
case PLTimestamp(value) =>
|
||||
builder.setTimestamp(value.micros)
|
||||
case PLParty(party) =>
|
||||
setString(party, builder.setPartyStr, builder.setPartyInternedStr)
|
||||
case PLDate(date) =>
|
||||
builder.setDate(date.days)
|
||||
case PLRoundingMode(rounding) =>
|
||||
@ -772,7 +770,7 @@ private[daml] class EncodeV1(minor: LV.Minor) {
|
||||
.newBuilder()
|
||||
.setNameWithType(dottedName -> value.typ)
|
||||
.setExpr(value.body)
|
||||
.setNoPartyLiterals(value.noPartyLiterals)
|
||||
.setNoPartyLiterals(true)
|
||||
.setIsTest(value.isTest)
|
||||
.build()
|
||||
}
|
||||
|
@ -12,19 +12,19 @@ module DecimalMod {
|
||||
agreement "Agreement for DecimalMod:Box";
|
||||
};
|
||||
|
||||
val build0: DecimalMod:Box = DecimalMod:Box {
|
||||
val build0: Party -> DecimalMod:Box = \(p : Party) -> DecimalMod:Box {
|
||||
x = 0.0000000000 ,
|
||||
party = 'Alice'
|
||||
party = p
|
||||
};
|
||||
|
||||
val buildMax: DecimalMod:Box = DecimalMod:Box {
|
||||
val buildMax: Party -> DecimalMod:Box = \(p : Party) -> DecimalMod:Box {
|
||||
x = 9999999999999999999999999999.9999999999 ,
|
||||
party = 'Alice'
|
||||
party = p
|
||||
};
|
||||
|
||||
val buildMin: DecimalMod:Box = DecimalMod:Box {
|
||||
val buildMin: Party -> DecimalMod:Box = \(p : Party) -> DecimalMod:Box {
|
||||
x = -9999999999999999999999999999.9999999999 ,
|
||||
party = 'Alice'
|
||||
party = p
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,10 @@ module EnumMod {
|
||||
};
|
||||
|
||||
val createColoredContract: EnumMod:Color -> Scenario (ContractId EnumMod:Box) = \ (color: EnumMod:Color) ->
|
||||
commit @(ContractId EnumMod:Box) 'Bob' (create @EnumMod:Box (EnumMod:Box { x = color, party = 'Bob' }));
|
||||
sbind
|
||||
bob : Party <- sget_party "Bob"
|
||||
in
|
||||
commit @(ContractId EnumMod:Box) bob (create @EnumMod:Box (EnumMod:Box { x = color, party = bob }));
|
||||
|
||||
enum Nothing = ;
|
||||
|
||||
|
@ -26,7 +26,10 @@ module GenMapMod {
|
||||
GenMap (RecordMod:Pair Int64 (Numeric 10)) (VariantMod:Either Int64 (Numeric 10))->
|
||||
Scenario (ContractId GenMapMod:Box)
|
||||
= \ (x: GenMap (RecordMod:Pair Int64 (Numeric 10)) (VariantMod:Either Int64 (Numeric 10))) ->
|
||||
commit @(ContractId GenMapMod:Box) 'Bob' (create @GenMapMod:Box (GenMapMod:Box { x = x, party = 'Bob' }));
|
||||
sbind
|
||||
bob : Party <- sget_party "Bob"
|
||||
in
|
||||
commit @(ContractId GenMapMod:Box) bob (create @GenMapMod:Box (GenMapMod:Box { x = x, party = bob }));
|
||||
|
||||
val map0: GenMap (RecordMod:Pair Int64 (Numeric 10)) (VariantMod:Either Int64 (Numeric 10)) =
|
||||
GENMAP_EMPTY @(RecordMod:Pair Int64 (Numeric 10)) @(VariantMod:Either Int64 (Numeric 10));
|
||||
|
@ -18,28 +18,28 @@ module NumericMod {
|
||||
agreement "Agreement for NumericMod:Box";
|
||||
};
|
||||
|
||||
val build0: NumericMod:Box = NumericMod:Box {
|
||||
val build0: Party -> NumericMod:Box = \(p : Party) -> NumericMod:Box {
|
||||
x0 = 0. ,
|
||||
x10 = 0.0000000000 ,
|
||||
x17 = 0.00000000000000000 ,
|
||||
x37 = 0.0000000000000000000000000000000000000 ,
|
||||
party = 'Alice'
|
||||
party = p
|
||||
};
|
||||
|
||||
val buildMax: NumericMod:Box = NumericMod:Box {
|
||||
val buildMax: Party -> NumericMod:Box = \(p : Party) -> NumericMod:Box {
|
||||
x0 = 99999999999999999999999999999999999999. ,
|
||||
x10 = 9999999999999999999999999999.9999999999 ,
|
||||
x17 = 999999999999999999999.99999999999999999 ,
|
||||
x37 = 9.9999999999999999999999999999999999999 ,
|
||||
party = 'Alice'
|
||||
party = p
|
||||
};
|
||||
|
||||
val buildMin: NumericMod:Box = NumericMod:Box {
|
||||
val buildMin: Party -> NumericMod:Box = \(p : Party) -> NumericMod:Box {
|
||||
x0 = -99999999999999999999999999999999999999. ,
|
||||
x10 = -9999999999999999999999999999.9999999999 ,
|
||||
x17 = -999999999999999999999.99999999999999999 ,
|
||||
x37 = -9.9999999999999999999999999999999999999 ,
|
||||
party = 'Alice'
|
||||
party = p
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ module PartyMod {
|
||||
agreement "Agreement for PartyMod:Box";
|
||||
};
|
||||
|
||||
val @noPartyLiterals one: Party -> List Party =
|
||||
val one: Party -> List Party =
|
||||
\(x: Party) -> Cons @Party [x] (Nil @Party);
|
||||
|
||||
}
|
||||
|
@ -18,7 +18,10 @@ module RecordMod {
|
||||
RecordMod:Pair Int64 (Numeric 10)->
|
||||
Scenario (ContractId RecordMod:Box)
|
||||
= \ (x: RecordMod:Pair Int64 (Numeric 10)) ->
|
||||
commit @(ContractId RecordMod:Box) 'Bob' (create @RecordMod:Box (RecordMod:Box { x = x, party = 'Bob' }));
|
||||
sbind
|
||||
bob : Party <- sget_party "Bob"
|
||||
in
|
||||
commit @(ContractId RecordMod:Box) bob (create @RecordMod:Box (RecordMod:Box { x = x, party = bob }));
|
||||
|
||||
val pair1: RecordMod:Pair Int64 (Numeric 10) =
|
||||
RecordMod:Pair @Int64 @(Numeric 10) {
|
||||
|
@ -12,9 +12,10 @@ module TextMod {
|
||||
agreement "Agreement for TextMod:Box";
|
||||
};
|
||||
|
||||
val build: TextMod:Box = TextMod:Box {
|
||||
x = "some text",
|
||||
party = 'Alice'
|
||||
};
|
||||
val build: Party -> TextMod:Box = \(p : Party) ->
|
||||
TextMod:Box {
|
||||
x = "some text",
|
||||
party = p
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -18,7 +18,10 @@ module VariantMod {
|
||||
VariantMod:Either Int64 (Numeric 10)->
|
||||
Scenario (ContractId VariantMod:Box)
|
||||
= \ (x: VariantMod:Either Int64 (Numeric 10)) ->
|
||||
commit @(ContractId VariantMod:Box) 'Bob' (create @VariantMod:Box (VariantMod:Box { x = x, party = 'Bob' }));
|
||||
sbind
|
||||
bob : Party <- sget_party "Bob"
|
||||
in
|
||||
commit @(ContractId VariantMod:Box) bob (create @VariantMod:Box (VariantMod:Box { x = x, party = bob }));
|
||||
|
||||
val either1: VariantMod:Either Int64 (Numeric 10) =
|
||||
VariantMod:Either:Left @Int64 @(Numeric 10) 0;
|
||||
|
@ -70,7 +70,6 @@ class EncodeV1Spec extends AnyWordSpec with Matchers with TableDrivenPropertyChe
|
||||
val aDecimal: Numeric 10 = 2.2000000000;
|
||||
val aDate: Date = 1879-03-14;
|
||||
val aTimestamp: Timestamp = 1970-01-01T00:00:00.000001Z;
|
||||
val aParty: Party = 'party';
|
||||
val aString: Text = "a string";
|
||||
val aStruct: forall (a:*) (b:*). a -> b -> < x1: a, x2: b > = /\ (a:*) (b:*). \ (x1: a) (x2: b) ->
|
||||
<x1 = x1, x2 = x2>;
|
||||
|
@ -41,11 +41,11 @@ class ValueEnricherSpec extends AnyWordSpec with Matchers with TableDrivenProper
|
||||
cids: List (ContractId Mod:Contract)
|
||||
};
|
||||
|
||||
val @noPartyLiterals keyParties: (Mod:Key -> List Party) =
|
||||
val keyParties: (Mod:Key -> List Party) =
|
||||
\(key: Mod:Key) ->
|
||||
Cons @Party [Mod:Key {party} key] (Nil @Party);
|
||||
|
||||
val @noPartyLiterals contractParties : (Mod:Contract -> List Party) =
|
||||
val contractParties : (Mod:Contract -> List Party) =
|
||||
\(contract: Mod:Contract) ->
|
||||
Mod:keyParties (Mod:Contract {key} contract);
|
||||
|
||||
|
@ -376,7 +376,7 @@ private[lf] final class Compiler(
|
||||
}
|
||||
|
||||
module.definitions.foreach {
|
||||
case (defName, DValue(_, _, body, _)) =>
|
||||
case (defName, DValue(_, body, _)) =>
|
||||
val ref = t.LfDefRef(Identifier(pkgId, QualifiedName(module.name, defName)))
|
||||
builder += (ref -> SDefinition(withLabelT(ref, unsafeCompile(body))))
|
||||
case _ =>
|
||||
@ -724,7 +724,6 @@ private[lf] final class Compiler(
|
||||
case PLNumeric(d) => SNumeric(d)
|
||||
case PLText(t) => SText(t)
|
||||
case PLTimestamp(ts) => STimestamp(ts)
|
||||
case PLParty(p) => SParty(p)
|
||||
case PLDate(d) => SDate(d)
|
||||
case PLRoundingMode(roundingMode) => SInt64(roundingMode.ordinal.toLong)
|
||||
})
|
||||
|
@ -114,7 +114,9 @@ class ComparisonSBuiltinTest extends AnyWordSpec with Matchers with TableDrivenP
|
||||
e"1970-01-01T00:00:00.000000Z",
|
||||
e"2020-02-02T20:20:02.020000Z",
|
||||
),
|
||||
t"Party" -> List(e"'alice'", e"'bob'", e"'carol'"),
|
||||
// Parties cannot be built from expressions.
|
||||
// We map at runtime the `party1`, `party2` and, `party3` two 3 party IDS in increasing order.
|
||||
t"Party" -> List(e"party1", e"party2", e"party3"),
|
||||
t"Mod:Color" -> List(e"Mod:Color:Red", e"Mod:Color:Green", e"Mod:Color:Blue"),
|
||||
t"Mod:MyUnit" -> List(e"Mod:MyUnit {}"),
|
||||
// Contract IDs cannot be built from expressions.
|
||||
@ -619,37 +621,69 @@ class ComparisonSBuiltinTest extends AnyWordSpec with Matchers with TableDrivenP
|
||||
private[this] val compiledPackages =
|
||||
PureCompiledPackages.assertBuild(Map(pkgId1 -> pkg1, pkgId2 -> pkg2))
|
||||
|
||||
private[this] val binderType = {
|
||||
private[this] val cidBinderType = {
|
||||
implicit def parserParameters: ParserParameters[this.type] = parserParameters1
|
||||
t"ContractId Mod:Template"
|
||||
}
|
||||
|
||||
private[this] val binder1 = Ref.Name.assertFromString("cid1") -> binderType
|
||||
private[this] val binder2 = Ref.Name.assertFromString("cid2") -> binderType
|
||||
private[this] val binder3 = Ref.Name.assertFromString("cid3") -> binderType
|
||||
private[this] val partyBinderType = {
|
||||
implicit def parserParameters: ParserParameters[this.type] = parserParameters1
|
||||
t"Party"
|
||||
}
|
||||
|
||||
private[this] val cidBinder1 = Ref.Name.assertFromString("cid1") -> cidBinderType
|
||||
private[this] val cidBinder2 = Ref.Name.assertFromString("cid2") -> cidBinderType
|
||||
private[this] val cidBinder3 = Ref.Name.assertFromString("cid3") -> cidBinderType
|
||||
|
||||
private[this] val partyBinder1 = Ref.Name.assertFromString("party1") -> partyBinderType
|
||||
private[this] val partyBinder2 = Ref.Name.assertFromString("party2") -> partyBinderType
|
||||
private[this] val partyBinder3 = Ref.Name.assertFromString("party3") -> partyBinderType
|
||||
|
||||
private[this] val contractIds =
|
||||
Array(
|
||||
Seq(
|
||||
ContractId.V1.assertFromString("00" * 32 + "0000"),
|
||||
ContractId.V1.assertFromString("00" * 32 + "0001"),
|
||||
ContractId.V1.assertFromString("00" + "ff" * 32),
|
||||
).map(cid => SEValue(SValue.SContractId(cid)): SExpr)
|
||||
|
||||
private[this] val parties =
|
||||
Seq(
|
||||
Ref.Party.assertFromString("alice"),
|
||||
Ref.Party.assertFromString("bob"),
|
||||
Ref.Party.assertFromString("carol"),
|
||||
).map(p => SEValue(SValue.SParty(p)): SExpr)
|
||||
|
||||
private[this] def eval(bi: Ast.BuiltinFunction, t: Ast.Type, x: Ast.Expr, y: Ast.Expr) = {
|
||||
final case class Goodbye(e: SError) extends RuntimeException("", null, false, false)
|
||||
val sexpr = compiledPackages.compiler.unsafeCompile(
|
||||
Ast.EAbs(
|
||||
binder1,
|
||||
partyBinder1,
|
||||
Ast.EAbs(
|
||||
binder2,
|
||||
Ast.EAbs(binder3, Ast.EApp(Ast.EApp(Ast.ETyApp(Ast.EBuiltin(bi), t), x), y), None),
|
||||
partyBinder2,
|
||||
Ast.EAbs(
|
||||
partyBinder3,
|
||||
Ast.EAbs(
|
||||
cidBinder1,
|
||||
Ast.EAbs(
|
||||
cidBinder2,
|
||||
Ast.EAbs(
|
||||
cidBinder3,
|
||||
Ast.EApp(Ast.EApp(Ast.ETyApp(Ast.EBuiltin(bi), t), x), y),
|
||||
None,
|
||||
),
|
||||
None,
|
||||
),
|
||||
None,
|
||||
),
|
||||
None,
|
||||
),
|
||||
None,
|
||||
),
|
||||
None,
|
||||
)
|
||||
)
|
||||
val machine =
|
||||
Speedy.Machine.fromPureSExpr(compiledPackages, SEApp(sexpr, contractIds))
|
||||
Speedy.Machine.fromPureSExpr(compiledPackages, SEApp(sexpr, (parties ++ contractIds).toArray))
|
||||
try {
|
||||
machine.run() match {
|
||||
case SResult.SResultFinalValue(v) => Right(v)
|
||||
|
@ -12,7 +12,8 @@ import com.daml.lf.language.{LanguageVersion, PackageInterface}
|
||||
import com.daml.lf.speedy.Compiler.FullStackTrace
|
||||
import com.daml.lf.speedy.SResult.{SResultError, SResultFinalValue}
|
||||
import com.daml.lf.speedy.SError.SErrorDamlException
|
||||
import com.daml.lf.speedy.SValue.SUnit
|
||||
import com.daml.lf.speedy.SExpr._
|
||||
import com.daml.lf.speedy.SValue.{SUnit, SParty}
|
||||
import com.daml.lf.testing.parser.Implicits._
|
||||
import com.daml.lf.testing.parser.ParserParameters
|
||||
import com.daml.lf.validation.Validation
|
||||
@ -24,6 +25,11 @@ import org.scalatest.wordspec.AnyWordSpec
|
||||
// TEST_EVIDENCE: Semantics: Exceptions, throw/catch.
|
||||
class ExceptionTest extends AnyWordSpec with Matchers with TableDrivenPropertyChecks {
|
||||
|
||||
private def applyToParty(pkgs: CompiledPackages, e: Expr, p: Party): SExpr = {
|
||||
val se = pkgs.compiler.unsafeCompile(e)
|
||||
SEApp(se, Array(SEValue(SParty(p))))
|
||||
}
|
||||
|
||||
"unhandled throw" should {
|
||||
|
||||
// Behaviour when no handler catches a throw:
|
||||
@ -464,12 +470,14 @@ class ExceptionTest extends AnyWordSpec with Matchers with TableDrivenPropertyCh
|
||||
"rollback of creates" should {
|
||||
|
||||
val party = Party.assertFromString("Alice")
|
||||
val example: Expr = EApp(e"M:causeRollback", EPrimLit(PLParty(party)))
|
||||
val example: Expr = e"M:causeRollback"
|
||||
def transactionSeed: crypto.Hash = crypto.Hash.hashPrivateKey("transactionSeed")
|
||||
|
||||
"works as expected for a contract version POST-dating exceptions" in {
|
||||
val pkgs = mkPackagesAtVersion(LanguageVersion.v1_dev)
|
||||
val res = Speedy.Machine.fromUpdateExpr(pkgs, transactionSeed, example, party).run()
|
||||
val res = Speedy.Machine
|
||||
.fromUpdateSExpr(pkgs, transactionSeed, applyToParty(pkgs, example, party), party)
|
||||
.run()
|
||||
res shouldBe SResultFinalValue(SUnit)
|
||||
}
|
||||
|
||||
@ -482,7 +490,9 @@ class ExceptionTest extends AnyWordSpec with Matchers with TableDrivenPropertyCh
|
||||
IE.UnhandledException(TTyCon(tyCon), ValueRecord(Some(tyCon), data.ImmArray.Empty))
|
||||
|
||||
val pkgs = mkPackagesAtVersion(LanguageVersion.v1_11)
|
||||
val res = Speedy.Machine.fromUpdateExpr(pkgs, transactionSeed, example, party).run()
|
||||
val res = Speedy.Machine
|
||||
.fromUpdateSExpr(pkgs, transactionSeed, applyToParty(pkgs, example, party), party)
|
||||
.run()
|
||||
res shouldBe SResultError(SErrorDamlException(anException))
|
||||
}
|
||||
|
||||
@ -683,22 +693,23 @@ class ExceptionTest extends AnyWordSpec with Matchers with TableDrivenPropertyCh
|
||||
|
||||
def transactionSeed: crypto.Hash = crypto.Hash.hashPrivateKey("transactionSeed")
|
||||
|
||||
val causeRollback: Expr = EApp(e"NewM:causeRollback", EPrimLit(PLParty(party)))
|
||||
val causeUncatchable: Expr = EApp(e"NewM:causeUncatchable", EPrimLit(PLParty(party)))
|
||||
val causeUncatchable2: Expr = EApp(e"NewM:causeUncatchable2", EPrimLit(PLParty(party)))
|
||||
val causeRollback: SExpr = applyToParty(pkgs, e"NewM:causeRollback", party)
|
||||
val causeUncatchable: SExpr = applyToParty(pkgs, e"NewM:causeUncatchable", party)
|
||||
val causeUncatchable2: SExpr = applyToParty(pkgs, e"NewM:causeUncatchable2", party)
|
||||
|
||||
"create rollback when old contacts are not within try-catch context" in {
|
||||
val res = Speedy.Machine.fromUpdateExpr(pkgs, transactionSeed, causeRollback, party).run()
|
||||
val res = Speedy.Machine.fromUpdateSExpr(pkgs, transactionSeed, causeRollback, party).run()
|
||||
res shouldBe SResultFinalValue(SUnit)
|
||||
}
|
||||
|
||||
"causes uncatchable exception when an old contract is within a new-exercise within a try-catch" in {
|
||||
val res = Speedy.Machine.fromUpdateExpr(pkgs, transactionSeed, causeUncatchable, party).run()
|
||||
val res = Speedy.Machine.fromUpdateSExpr(pkgs, transactionSeed, causeUncatchable, party).run()
|
||||
res shouldBe SResultError(SErrorDamlException(anException))
|
||||
}
|
||||
|
||||
"causes uncatchable exception when an old contract is within a new-exercise which aborts" in {
|
||||
val res = Speedy.Machine.fromUpdateExpr(pkgs, transactionSeed, causeUncatchable2, party).run()
|
||||
val res =
|
||||
Speedy.Machine.fromUpdateSExpr(pkgs, transactionSeed, causeUncatchable2, party).run()
|
||||
res shouldBe SResultError(SErrorDamlException(anException))
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ class InterpreterTest extends AnyWordSpec with Matchers with TableDrivenProperty
|
||||
name = modName,
|
||||
definitions = Map(
|
||||
DottedName.assertFromString("bar") ->
|
||||
DValue(TBuiltin(BTBool), true, ETrue, false)
|
||||
DValue(TBuiltin(BTBool), ETrue, false)
|
||||
),
|
||||
templates = Map.empty,
|
||||
exceptions = Map.empty,
|
||||
|
@ -8,6 +8,7 @@ import com.daml.lf.data._
|
||||
import com.daml.lf.language.Ast._
|
||||
import com.daml.lf.speedy.PartialTransaction._
|
||||
import com.daml.lf.speedy.SExpr._
|
||||
import com.daml.lf.speedy.SValue._
|
||||
import com.daml.lf.speedy.SResult._
|
||||
import com.daml.lf.testing.parser.Implicits._
|
||||
|
||||
@ -66,10 +67,9 @@ class ProfilerTest extends AnyWordSpec with Matchers with ScalaCheckDrivenProper
|
||||
def profile(e: Expr): Seq[(Boolean, Profile.Label)] = {
|
||||
val transactionSeed: crypto.Hash = crypto.Hash.hashPrivateKey("foobar")
|
||||
val party = Ref.Party.assertFromString("Alice")
|
||||
val lit: PrimLit = PLParty(party)
|
||||
val arg: Expr = EPrimLit(lit)
|
||||
val example: Expr = EApp(e, arg)
|
||||
val machine = Speedy.Machine.fromUpdateExpr(compiledPackages, transactionSeed, example, party)
|
||||
val se = compiledPackages.compiler.unsafeCompile(e)
|
||||
val example: SExpr = SEApp(se, Array(SEValue(SParty(party))))
|
||||
val machine = Speedy.Machine.fromUpdateSExpr(compiledPackages, transactionSeed, example, party)
|
||||
val res = machine.run()
|
||||
res match {
|
||||
case _: SResultFinalValue =>
|
||||
|
@ -7,11 +7,13 @@ package speedy
|
||||
import com.daml.lf.data.ImmArray
|
||||
import com.daml.lf.data.Ref
|
||||
import com.daml.lf.data.Ref.Party
|
||||
import com.daml.lf.language.Ast.{Package, Expr, PrimLit, PLParty, EPrimLit, EApp}
|
||||
import com.daml.lf.language.Ast.{Package, Expr}
|
||||
import com.daml.lf.language.{LanguageVersion, PackageInterface}
|
||||
import com.daml.lf.speedy.Compiler.FullStackTrace
|
||||
import com.daml.lf.speedy.PartialTransaction.{CompleteTransaction, IncompleteTransaction}
|
||||
import com.daml.lf.speedy.SResult.SResultFinalValue
|
||||
import com.daml.lf.speedy.SExpr._
|
||||
import com.daml.lf.speedy.SValue._
|
||||
import com.daml.lf.testing.parser.Implicits._
|
||||
import com.daml.lf.testing.parser.ParserParameters
|
||||
import com.daml.lf.transaction.Node
|
||||
@ -47,7 +49,9 @@ class RollbackTest extends AnyWordSpec with Matchers with TableDrivenPropertyChe
|
||||
pkgs1: PureCompiledPackages
|
||||
)(e: Expr, party: Party): SubmittedTransaction = {
|
||||
def transactionSeed: crypto.Hash = crypto.Hash.hashPrivateKey("RollbackTest.scala")
|
||||
val machine = Speedy.Machine.fromUpdateExpr(pkgs1, transactionSeed, e, party)
|
||||
val se = pkgs1.compiler.unsafeCompile(e)
|
||||
val example = SEApp(se, Array(SEValue(SParty(party))))
|
||||
val machine = Speedy.Machine.fromUpdateSExpr(pkgs1, transactionSeed, example, party)
|
||||
val res = machine.run()
|
||||
res match {
|
||||
case _: SResultFinalValue =>
|
||||
@ -237,10 +241,7 @@ class RollbackTest extends AnyWordSpec with Matchers with TableDrivenPropertyChe
|
||||
forEvery(testCases) { (exp: String, expected: List[Tree]) =>
|
||||
s"""$exp, contracts expected: $expected """ in {
|
||||
val party = Party.assertFromString("Alice")
|
||||
val lit: PrimLit = PLParty(party)
|
||||
val arg: Expr = EPrimLit(lit)
|
||||
val example: Expr = EApp(e"M:$exp", arg)
|
||||
val tx: SubmittedTransaction = runUpdateExprGetTx(pkgs)(example, party)
|
||||
val tx: SubmittedTransaction = runUpdateExprGetTx(pkgs)(e"M:$exp", party)
|
||||
val ids: List[Tree] = shapeOfTransaction(tx)
|
||||
ids shouldBe expected
|
||||
}
|
||||
|
@ -731,8 +731,10 @@ class SBuiltinTest extends AnyFreeSpec with Matchers with TableDrivenPropertyChe
|
||||
|
||||
"EQUAL @ContractId" - {
|
||||
"works as expected" in {
|
||||
eval(e"EQUAL @(ContractId Mod:T) 'contract1' 'contract1'") shouldBe Right(SBool(true))
|
||||
eval(e"EQUAL @(ContractId Mod:T) 'contract1' 'contract2'") shouldBe Right(SBool(false))
|
||||
val cid1 = SContractId(Value.ContractId.assertFromString("#contract1"))
|
||||
val cid2 = SContractId(Value.ContractId.assertFromString("#contract2"))
|
||||
evalApp(e"EQUAL @(ContractId Mod:T)", Array(cid1, cid1)) shouldBe Right(SBool(true))
|
||||
evalApp(e"EQUAL @(ContractId Mod:T)", Array(cid1, cid2)) shouldBe Right(SBool(false))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1213,11 +1215,17 @@ class SBuiltinTest extends AnyFreeSpec with Matchers with TableDrivenPropertyChe
|
||||
|
||||
"Text Operations" - {
|
||||
"PARTY_TO_QUOTED_TEXT single quotes" in {
|
||||
eval(e"PARTY_TO_QUOTED_TEXT 'alice'") shouldBe Right(SText("'alice'"))
|
||||
evalApp(
|
||||
e"PARTY_TO_QUOTED_TEXT",
|
||||
Array(SParty(Ref.Party.assertFromString("alice"))),
|
||||
) shouldBe Right(SText("'alice'"))
|
||||
}
|
||||
|
||||
"PARTY_TO_TEXT does not single quote" in {
|
||||
eval(e"PARTY_TO_TEXT 'alice'") shouldBe Right(SText("alice"))
|
||||
evalApp(
|
||||
e"PARTY_TO_TEXT",
|
||||
Array(SParty(Ref.Party.assertFromString("alice"))),
|
||||
) shouldBe Right(SText("alice"))
|
||||
}
|
||||
|
||||
"TEXT_TO_PARTY" - {
|
||||
@ -1615,7 +1623,11 @@ object SBuiltinTest {
|
||||
evalSExpr(compiledPackages.compiler.unsafeCompile(e), onLedger)
|
||||
}
|
||||
|
||||
private def evalApp(e: Expr, args: Array[SValue], onLedger: Boolean): Either[SError, SValue] = {
|
||||
private def evalApp(
|
||||
e: Expr,
|
||||
args: Array[SValue],
|
||||
onLedger: Boolean = true,
|
||||
): Either[SError, SValue] = {
|
||||
evalSExpr(SEApp(compiledPackages.compiler.unsafeCompile(e), args.map(SEValue(_))), onLedger)
|
||||
}
|
||||
|
||||
|
@ -172,13 +172,19 @@ class SpeedyTest extends AnyWordSpec with Matchers {
|
||||
|
||||
val anyPkgs = typeAndCompile(anyPkg)
|
||||
|
||||
private val alice = SParty(Party.assertFromString("Alice"))
|
||||
|
||||
"to_any" should {
|
||||
|
||||
"succeed on Int64" in {
|
||||
eval(e"""to_any @Int64 1""", anyPkgs) shouldEqual Right(SAny(TBuiltin(BTInt64), SInt64(1)))
|
||||
}
|
||||
"succeed on record type without parameters" in {
|
||||
eval(e"""to_any @Test:T1 (Test:T1 {party = 'Alice'})""", anyPkgs) shouldEqual
|
||||
evalApp(
|
||||
e"""\ (p: Party) -> to_any @Test:T1 (Test:T1 {party = p})""",
|
||||
Array(alice),
|
||||
anyPkgs,
|
||||
) shouldEqual
|
||||
Right(
|
||||
SAny(
|
||||
TTyCon(Identifier(pkgId, QualifiedName.assertFromString("Test:T1"))),
|
||||
@ -191,7 +197,11 @@ class SpeedyTest extends AnyWordSpec with Matchers {
|
||||
)
|
||||
}
|
||||
"succeed on record type with parameters" in {
|
||||
eval(e"""to_any @(Test:T3 Int64) (Test:T3 @Int64 {party = 'Alice'})""", anyPkgs) shouldEqual
|
||||
evalApp(
|
||||
e"""\ (p : Party) -> to_any @(Test:T3 Int64) (Test:T3 @Int64 {party = p})""",
|
||||
Array(alice),
|
||||
anyPkgs,
|
||||
) shouldEqual
|
||||
Right(
|
||||
SAny(
|
||||
TApp(
|
||||
@ -205,7 +215,11 @@ class SpeedyTest extends AnyWordSpec with Matchers {
|
||||
),
|
||||
)
|
||||
)
|
||||
eval(e"""to_any @(Test:T3 Text) (Test:T3 @Text {party = 'Alice'})""", anyPkgs) shouldEqual
|
||||
evalApp(
|
||||
e"""\ (p : Party) -> to_any @(Test:T3 Text) (Test:T3 @Text {party = p})""",
|
||||
Array(alice),
|
||||
anyPkgs,
|
||||
) shouldEqual
|
||||
Right(
|
||||
SAny(
|
||||
TApp(
|
||||
@ -229,8 +243,9 @@ class SpeedyTest extends AnyWordSpec with Matchers {
|
||||
}
|
||||
|
||||
"return Some(tpl) if template type matches" in {
|
||||
eval(
|
||||
e"""from_any @Test:T1 (to_any @Test:T1 (Test:T1 {party = 'Alice'}))""",
|
||||
evalApp(
|
||||
e"""\(p : Party) -> from_any @Test:T1 (to_any @Test:T1 (Test:T1 {party = p}))""",
|
||||
Array(alice),
|
||||
anyPkgs,
|
||||
) shouldEqual
|
||||
Right(
|
||||
@ -247,16 +262,18 @@ class SpeedyTest extends AnyWordSpec with Matchers {
|
||||
}
|
||||
|
||||
"return None if template type does not match" in {
|
||||
eval(
|
||||
e"""from_any @Test:T2 (to_any @Test:T1 (Test:T1 {party = 'Alice'}))""",
|
||||
evalApp(
|
||||
e"""\(p : Party) -> from_any @Test:T2 (to_any @Test:T1 (Test:T1 {party = p}))""",
|
||||
Array(alice),
|
||||
anyPkgs,
|
||||
) shouldEqual Right(
|
||||
SOptional(None)
|
||||
)
|
||||
}
|
||||
"return Some(v) if type parameter is the same" in {
|
||||
eval(
|
||||
e"""from_any @(Test:T3 Int64) (to_any @(Test:T3 Int64) (Test:T3 @Int64 {party = 'Alice'}))""",
|
||||
evalApp(
|
||||
e"""\(p : Alice) -> from_any @(Test:T3 Int64) (to_any @(Test:T3 Int64) (Test:T3 @Int64 {party = p}))""",
|
||||
Array(alice),
|
||||
anyPkgs,
|
||||
) shouldEqual Right(
|
||||
SOptional(
|
||||
@ -271,8 +288,9 @@ class SpeedyTest extends AnyWordSpec with Matchers {
|
||||
)
|
||||
}
|
||||
"return None if type parameter is different" in {
|
||||
eval(
|
||||
e"""from_any @(Test:T3 Int64) (to_any @(Test:T3 Text) (Test:T3 @Int64 {party = 'Alice'}))""",
|
||||
evalApp(
|
||||
e"""\ (p : Party) -> from_any @(Test:T3 Int64) (to_any @(Test:T3 Text) (Test:T3 @Int64 {party = p}))""",
|
||||
Array(alice),
|
||||
anyPkgs,
|
||||
) shouldEqual Right(SOptional(None))
|
||||
}
|
||||
@ -489,8 +507,11 @@ class SpeedyTest extends AnyWordSpec with Matchers {
|
||||
|
||||
object SpeedyTest {
|
||||
|
||||
private def eval(e: Expr, packages: PureCompiledPackages): Either[SError, SValue] = {
|
||||
val machine = Speedy.Machine.fromPureExpr(packages, e)
|
||||
private def eval(e: Expr, packages: PureCompiledPackages): Either[SError, SValue] =
|
||||
evalSExpr(packages.compiler.unsafeCompile(e), packages)
|
||||
|
||||
private def evalSExpr(e: SExpr, packages: PureCompiledPackages): Either[SError, SValue] = {
|
||||
val machine = Speedy.Machine.fromPureSExpr(packages, e)
|
||||
final case class Goodbye(e: SError) extends RuntimeException("", null, false, false)
|
||||
try {
|
||||
val value = machine.run() match {
|
||||
@ -504,6 +525,15 @@ object SpeedyTest {
|
||||
}
|
||||
}
|
||||
|
||||
private def evalApp(
|
||||
e: Expr,
|
||||
args: Array[SValue],
|
||||
packages: PureCompiledPackages,
|
||||
): Either[SError, SValue] = {
|
||||
val se = packages.compiler.unsafeCompile(e)
|
||||
evalSExpr(SEApp(se, args.map(SEValue(_))), packages)
|
||||
}
|
||||
|
||||
@SuppressWarnings(Array("org.wartremover.warts.Any"))
|
||||
private implicit def resultEq: Equality[Either[SError, SValue]] = {
|
||||
case (Right(v1: SValue), Right(v2: SValue)) => svalue.Equality.areEqual(v1, v2)
|
||||
|
@ -330,7 +330,6 @@ object Ast {
|
||||
// Text should be treated as Utf8, data.Utf8 provide emulation functions for that
|
||||
final case class PLText(override val value: String) extends PrimLit
|
||||
final case class PLTimestamp(override val value: Time.Timestamp) extends PrimLit
|
||||
final case class PLParty(override val value: Party) extends PrimLit
|
||||
final case class PLDate(override val value: Time.Date) extends PrimLit
|
||||
final case class PLRoundingMode(override val value: java.math.RoundingMode) extends PrimLit
|
||||
|
||||
@ -591,17 +590,16 @@ object Ast {
|
||||
|
||||
final case class GenDValue[E](
|
||||
typ: Type,
|
||||
noPartyLiterals: Boolean,
|
||||
body: E,
|
||||
isTest: Boolean,
|
||||
) extends GenDefinition[E]
|
||||
|
||||
final class GenDValueCompanion[E] private[Ast] {
|
||||
def apply(typ: Type, noPartyLiterals: Boolean, body: E, isTest: Boolean): GenDValue[E] =
|
||||
GenDValue(typ = typ, noPartyLiterals = noPartyLiterals, body = body, isTest = isTest)
|
||||
def apply(typ: Type, body: E, isTest: Boolean): GenDValue[E] =
|
||||
GenDValue(typ = typ, body = body, isTest = isTest)
|
||||
|
||||
def unapply(arg: GenDValue[E]): Some[(Type, Boolean, E, Boolean)] =
|
||||
Some((arg.typ, arg.noPartyLiterals, arg.body, arg.isTest))
|
||||
def unapply(arg: GenDValue[E]): Some[(Type, E, Boolean)] =
|
||||
Some((arg.typ, arg.body, arg.isTest))
|
||||
}
|
||||
|
||||
type DValue = GenDValue[Expr]
|
||||
@ -947,25 +945,10 @@ object Ast {
|
||||
type DefExceptionSignature = GenDefException[Unit]
|
||||
val DefExceptionSignature = GenDefException(())
|
||||
|
||||
final case class FeatureFlags(
|
||||
forbidPartyLiterals: Boolean // If set to true, party literals are not allowed to appear in daml-lf packages.
|
||||
/*
|
||||
These flags are present in Daml-LF, but our ecosystem does not support them anymore:
|
||||
dontDivulgeContractIdsInCreateArguments: Boolean, // If set to true, arguments to creates are not divulged.
|
||||
// Instead target contract id's of exercises are divulged
|
||||
// and fetches are authorized.
|
||||
dontDiscloseNonConsumingChoicesToObservers: Boolean // If set to true, exercise nodes of
|
||||
// non-consuming choices are only
|
||||
// disclosed to the signatories and
|
||||
// controllers of the target contract/choice
|
||||
// and not to the observers of the target contract.
|
||||
*/
|
||||
)
|
||||
final case class FeatureFlags()
|
||||
|
||||
object FeatureFlags {
|
||||
val default = FeatureFlags(
|
||||
forbidPartyLiterals = false
|
||||
)
|
||||
val default = FeatureFlags()
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -64,7 +64,7 @@ class AstSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
|
||||
)
|
||||
val recordDef = DDataType(true, ImmArray.Empty, DataRecord(ImmArray.Empty))
|
||||
val variantDef = DDataType(true, ImmArray.Empty, DataVariant(ImmArray.Empty))
|
||||
val valDef = DValue(TUnit, false, EUnit, false)
|
||||
val valDef = DValue(TUnit, EUnit, false)
|
||||
|
||||
def defName(s: String) = DottedName.assertFromSegments(Iterable(s))
|
||||
|
||||
|
@ -227,8 +227,8 @@ private[daml] class AstRewriter(
|
||||
x
|
||||
case DDataType(serializable @ _, params @ _, DataInterface) =>
|
||||
x
|
||||
case DValue(typ, noPartyLiterals, body, isTest) =>
|
||||
DValue(apply(typ), noPartyLiterals, apply(body), isTest)
|
||||
case DValue(typ, body, isTest) =>
|
||||
DValue(apply(typ), apply(body), isTest)
|
||||
|
||||
case DTypeSyn(params @ _, typ @ _) =>
|
||||
throw new RuntimeException("TODO #3616,AstRewriter,DTypeSyn")
|
||||
|
@ -4,7 +4,7 @@
|
||||
package com.daml.lf.testing.parser
|
||||
|
||||
import com.daml.lf.data.Ref.{Location, Name}
|
||||
import com.daml.lf.data.{ImmArray, Ref}
|
||||
import com.daml.lf.data.ImmArray
|
||||
import com.daml.lf.language.Ast._
|
||||
import com.daml.lf.testing.parser.Parsers._
|
||||
import com.daml.lf.testing.parser.Token._
|
||||
@ -73,13 +73,6 @@ private[parser] class ExprParser[P](parserParameters: ParserParameters[P]) {
|
||||
acceptMatch("Text", { case Text(s) => PLText(s) }) |
|
||||
acceptMatch("Timestamp", { case Timestamp(l) => PLTimestamp(l) }) |
|
||||
acceptMatch("Date", { case Date(l) => PLDate(l) }) |
|
||||
acceptMatch(
|
||||
"Party",
|
||||
{
|
||||
case SimpleString(s) if Ref.Party.fromString(s).isRight =>
|
||||
PLParty(Ref.Party.assertFromString(s))
|
||||
},
|
||||
) |
|
||||
(id ^? roundingModes) ^^ PLRoundingMode
|
||||
|
||||
private lazy val primCon =
|
||||
|
@ -48,11 +48,10 @@ private[parser] class ModParser[P](parameters: ParserParameters[P]) {
|
||||
}
|
||||
|
||||
lazy val mod: Parser[Module] =
|
||||
Id("module") ~! tags(modTags) ~ dottedName ~ `{` ~ rep(definition <~ `;`) <~ `}` ^^ {
|
||||
case _ ~ modTag ~ modName ~ _ ~ defs =>
|
||||
Id("module") ~! dottedName ~ `{` ~ rep(definition <~ `;`) <~ `}` ^^ {
|
||||
case _ ~ modName ~ _ ~ defs =>
|
||||
val (definitions, templates, exceptions, interfaces) = split(defs)
|
||||
val flags = FeatureFlags(forbidPartyLiterals = modTag(noPartyLitsTag))
|
||||
Module.build(modName, definitions, templates, exceptions, interfaces, flags)
|
||||
Module.build(modName, definitions, templates, exceptions, interfaces, FeatureFlags.default)
|
||||
}
|
||||
|
||||
private lazy val definition: Parser[Def] =
|
||||
@ -115,7 +114,7 @@ private[parser] class ModParser[P](parameters: ParserParameters[P]) {
|
||||
private lazy val valDefinition: Parser[DataDef] =
|
||||
Id("val") ~>! tags(valDefTags) ~ dottedName ~ `:` ~ typ ~ `=` ~ expr ^^ {
|
||||
case defTags ~ id ~ _ ~ typ ~ _ ~ expr =>
|
||||
DataDef(id, DValue(typ, defTags(noPartyLitsTag), expr, defTags(isTestTag)))
|
||||
DataDef(id, DValue(typ, expr, defTags(isTestTag)))
|
||||
}
|
||||
|
||||
private lazy val templateKey: Parser[TemplateKey] =
|
||||
@ -223,14 +222,12 @@ private[parser] class ModParser[P](parameters: ParserParameters[P]) {
|
||||
}
|
||||
|
||||
private val serializableTag = Ref.Name.assertFromString("serializable")
|
||||
private val noPartyLitsTag = Ref.Name.assertFromString("noPartyLiterals")
|
||||
private val isTestTag = Ref.Name.assertFromString("isTest")
|
||||
private val nonConsumingTag = Ref.Name.assertFromString("nonConsuming")
|
||||
|
||||
private val dataDefTags = Set(serializableTag)
|
||||
private val templateChoiceTags = Set(nonConsumingTag)
|
||||
private val valDefTags = Set(noPartyLitsTag, isTestTag)
|
||||
private val modTags = Set(noPartyLitsTag)
|
||||
private val valDefTags = Set(isTestTag)
|
||||
|
||||
}
|
||||
|
||||
|
@ -152,8 +152,6 @@ class ParsersSpec extends AnyWordSpec with ScalaCheckPropertyChecks with Matcher
|
||||
"1970-01-02" -> PLDate(Time.Date.assertFromDaysSinceEpoch(1)),
|
||||
"1970-01-01T00:00:00.000001Z" -> PLTimestamp(Time.Timestamp.assertFromLong(1)),
|
||||
"1970-01-01T00:00:01Z" -> PLTimestamp(Time.Timestamp.assertFromLong(1000000)),
|
||||
"'party'" -> PLParty(Party.assertFromString("party")),
|
||||
""" ' aB0-_ ' """ -> PLParty(Party.assertFromString(" aB0-_ ")),
|
||||
"ROUNDING_UP" -> PLRoundingMode(java.math.RoundingMode.UP),
|
||||
)
|
||||
|
||||
@ -517,13 +515,13 @@ class ParsersSpec extends AnyWordSpec with ScalaCheckPropertyChecks with Matcher
|
||||
"""
|
||||
module Mod {
|
||||
|
||||
val @noPartyLiterals fact : Int64 -> Int64 = \(x: Int64) -> ERROR @INT64 "not implemented";
|
||||
val fact : Int64 -> Int64 = \(x: Int64) -> ERROR @INT64 "not implemented";
|
||||
|
||||
}
|
||||
"""
|
||||
|
||||
val valDef =
|
||||
DValue(t"Int64 -> Int64", true, e"""\(x: Int64) -> ERROR @INT64 "not implemented"""", false)
|
||||
DValue(t"Int64 -> Int64", e"""\(x: Int64) -> ERROR @INT64 "not implemented"""", false)
|
||||
|
||||
parseModules(p) shouldBe Right(
|
||||
List(
|
||||
@ -551,7 +549,7 @@ class ParsersSpec extends AnyWordSpec with ScalaCheckPropertyChecks with Matcher
|
||||
template (this : Person) = {
|
||||
precondition True;
|
||||
signatories Cons @Party [person] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
observers Cons @Party [Mod:Person {person} this] (Nil @Party);
|
||||
agreement "Agreement";
|
||||
choice Sleep (self) (u:Unit) : ContractId Mod:Person
|
||||
, controllers Cons @Party [person] (Nil @Party)
|
||||
@ -622,7 +620,7 @@ class ParsersSpec extends AnyWordSpec with ScalaCheckPropertyChecks with Matcher
|
||||
update = e"upure @Int64 i",
|
||||
),
|
||||
),
|
||||
observers = e"Cons @Party ['Alice'] (Nil @Party)",
|
||||
observers = e"Cons @Party [Mod:Person {person} this] (Nil @Party)",
|
||||
key = Some(TemplateKey(t"Party", e"(Mod:Person {name} this)", e"""\ (p: Party) -> p""")),
|
||||
implements = Map(
|
||||
human ->
|
||||
|
@ -326,7 +326,7 @@ object Repl {
|
||||
defn match {
|
||||
case DTypeSyn(_, _) => "<type synonym>" // FIXME: pp this
|
||||
case DDataType(_, _, _) => "<data type>" // FIXME(JM): pp this
|
||||
case DValue(typ, _, _, _) => prettyType(typ, pkgId, modId)
|
||||
case DValue(typ, _, _) => prettyType(typ, pkgId, modId)
|
||||
}
|
||||
|
||||
def prettyQualified(pkgId: PackageId, modId: ModuleName, m: Identifier): String = {
|
||||
@ -464,7 +464,7 @@ object Repl {
|
||||
case None =>
|
||||
println("Error: definition '" + id + "' not found. Try :list.")
|
||||
usage()
|
||||
case Some(DValue(_, _, body, _)) =>
|
||||
case Some(DValue(_, body, _)) =>
|
||||
val expr = argExprs.foldLeft(body)((e, arg) => EApp(e, arg))
|
||||
|
||||
val compiledPackages = PureCompiledPackages.assertBuild(state.packages)
|
||||
@ -503,7 +503,7 @@ object Repl {
|
||||
case None =>
|
||||
println("Error: " + id + " not found.")
|
||||
None
|
||||
case Some(DValue(_, _, body, true)) =>
|
||||
case Some(DValue(_, body, true)) =>
|
||||
val argExprs = args.map(s => assertRight(parser.parseExpr(s)))
|
||||
Some(argExprs.foldLeft(body)((e, arg) => EApp(e, arg)))
|
||||
case Some(_) =>
|
||||
@ -542,7 +542,7 @@ object Repl {
|
||||
(modName, mod) = module
|
||||
definition <- mod.definitions
|
||||
(dfnName, dfn) = definition
|
||||
bodyTest <- List(dfn).collect { case DValue(TScenario(_), _, body, true) => body }
|
||||
bodyTest <- List(dfn).collect { case DValue(TScenario(_), body, true) => body }
|
||||
} yield QualifiedName(modName, dfnName).toString -> bodyTest
|
||||
var failures = 0
|
||||
var successes = 0
|
||||
|
@ -174,7 +174,7 @@ object ScenarioRunner {
|
||||
scenarioDef: Ast.Definition,
|
||||
): Ast.Expr = {
|
||||
scenarioDef match {
|
||||
case Ast.DValue(_, _, body, _) => body
|
||||
case Ast.DValue(_, body, _) => body
|
||||
case _: Ast.DTypeSyn =>
|
||||
throw new RuntimeException(
|
||||
s"Requested scenario $scenarioRef is a type synonym, not a definition"
|
||||
|
@ -1,42 +0,0 @@
|
||||
// Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.lf.validation
|
||||
|
||||
import com.daml.lf.data.Ref.PackageId
|
||||
import com.daml.lf.language.Ast._
|
||||
import com.daml.lf.language.PackageInterface
|
||||
import com.daml.lf.validation.iterable.ExprIterable
|
||||
|
||||
private[validation] object PartyLiterals {
|
||||
|
||||
import Util.handleLookup
|
||||
|
||||
@throws[EForbiddenPartyLiterals]
|
||||
def checkModule(interface: PackageInterface, pkgId: PackageId, module: Module): Unit = {
|
||||
module.definitions.foreach {
|
||||
case (defName, DValue(typ @ _, noPartyLiterals, body, isTest @ _)) =>
|
||||
def context = ContextDefValue(pkgId, module.name, defName)
|
||||
if (noPartyLiterals)
|
||||
checkExpr(interface, context, body)
|
||||
else if (module.featureFlags.forbidPartyLiterals)
|
||||
throw EForbiddenPartyLiterals(context, ValRefWithPartyLiterals(context.ref))
|
||||
case _ =>
|
||||
}
|
||||
module.templates.foreach { case (defName, template) =>
|
||||
def context = ContextDefValue(pkgId, module.name, defName)
|
||||
ExprIterable(template).foreach(checkExpr(interface, context, _))
|
||||
}
|
||||
}
|
||||
|
||||
private def checkExpr(interface: PackageInterface, context: => Context, expr: Expr): Unit =
|
||||
expr match {
|
||||
case EPrimLit(party: PLParty) =>
|
||||
throw EForbiddenPartyLiterals(context, PartyLiteral(party.value))
|
||||
case EVal(valRef) if !handleLookup(context, interface.lookupValue(valRef)).noPartyLiterals =>
|
||||
throw EForbiddenPartyLiterals(context, ValRefWithPartyLiterals(valRef))
|
||||
case otherwise =>
|
||||
ExprIterable(otherwise).foreach(checkExpr(interface, context, _))
|
||||
}
|
||||
|
||||
}
|
@ -39,7 +39,6 @@ private[validation] object Typing {
|
||||
case PLNumeric(s) => TNumeric(TNat(Numeric.scale(s)))
|
||||
case PLText(_) => TText
|
||||
case PLTimestamp(_) => TTimestamp
|
||||
case PLParty(_) => TParty
|
||||
case PLDate(_) => TDate
|
||||
case PLRoundingMode(_) => TRoundingMode
|
||||
}
|
||||
@ -383,7 +382,7 @@ private[validation] object Typing {
|
||||
}
|
||||
|
||||
def checkDValue(dfn: DValue): Unit = dfn match {
|
||||
case DValue(typ, _, body, isTest) =>
|
||||
case DValue(typ, body, isTest) =>
|
||||
checkType(typ, KStar)
|
||||
checkExpr(body, typ)
|
||||
if (isTest) {
|
||||
|
@ -67,6 +67,5 @@ object Validation {
|
||||
): Unit = {
|
||||
Typing.checkModule(interface, pkgId, mod)
|
||||
Serializability.checkModule(interface, pkgId, mod)
|
||||
PartyLiterals.checkModule(interface, pkgId, mod)
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ private[validation] object ExprIterable {
|
||||
x match {
|
||||
case DTypeSyn(params @ _, typ @ _) => Iterator.empty
|
||||
case DDataType(serializable @ _, params @ _, dataCons @ _) => Iterator.empty
|
||||
case DValue(typ @ _, noPartyLiterals @ _, body, isTest @ _) =>
|
||||
case DValue(typ @ _, body, isTest @ _) =>
|
||||
Iterator(body)
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,7 @@ private[validation] object TypeIterable {
|
||||
Iterator.empty
|
||||
case DDataType(serializable @ _, params @ _, DataInterface) =>
|
||||
Iterator.empty
|
||||
case DValue(typ, noPartyLiterals @ _, body, isTest @ _) =>
|
||||
case DValue(typ, body, isTest @ _) =>
|
||||
Iterator(typ) ++ iterator(body)
|
||||
|
||||
}
|
||||
|
@ -33,11 +33,10 @@ class DependencyVersionSpec extends AnyWordSpec with TableDrivenPropertyChecks w
|
||||
|
||||
val mod = Module.build(
|
||||
name = modName,
|
||||
definitions = (u -> DValue(TUnit, true, EUnit, false)) +:
|
||||
definitions = (u -> DValue(TUnit, EUnit, false)) +:
|
||||
depRefs.map { case (depPkgId, depModName) =>
|
||||
depModName -> DValue(
|
||||
TUnit,
|
||||
true,
|
||||
EVal(Identifier(depPkgId, QualifiedName(depModName, u))),
|
||||
false,
|
||||
)
|
||||
|
@ -1,155 +0,0 @@
|
||||
// Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.lf
|
||||
package validation
|
||||
|
||||
import com.daml.lf.data.Ref.DottedName
|
||||
import com.daml.lf.testing.parser.Implicits._
|
||||
import com.daml.lf.testing.parser.defaultPackageId
|
||||
import org.scalatest.prop.TableDrivenPropertyChecks
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import org.scalatest.wordspec.AnyWordSpec
|
||||
|
||||
class PartyLiteralsSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
|
||||
|
||||
import PartyLiterals._
|
||||
|
||||
"Party Literals validation" should {
|
||||
|
||||
"disallows bad party literals" in {
|
||||
|
||||
val pkg =
|
||||
p"""
|
||||
module Mod {
|
||||
record R = {};
|
||||
val isAlice: Party -> Bool = EQUAL_PARTY 'Alice';
|
||||
val @noPartyLiterals v: Unit = ();
|
||||
}
|
||||
|
||||
// a well-formed module
|
||||
module NegativeTestCase {
|
||||
val @noPartyLiterals v: Unit = Mod:v;
|
||||
|
||||
val @noPartyLiterals isAlice: Party -> Bool =
|
||||
\ (party: Party) -> EQUAL_TEXT (PARTY_TO_TEXT party) "'Alice'";
|
||||
|
||||
record R = { party: Party };
|
||||
template (this : R) = {
|
||||
precondition True;
|
||||
signatories Cons @Party [party] (Nil @Party);
|
||||
observers Cons @Party [party] (Nil @Party);
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Unit) : Unit, controllers party to
|
||||
upure @Unit ();
|
||||
};
|
||||
}
|
||||
|
||||
module PositiveTestCase1 {
|
||||
val @noPartyLiterals bob : Party = 'Bob'; // disallowed party literal 'Bob'
|
||||
}
|
||||
|
||||
module PositiveTestCase2 {
|
||||
val @noPartyLiterals isAlice : Party -> Bool =
|
||||
Mod:isAlice; // disallowed value ref `Mod:isAllice`
|
||||
}
|
||||
|
||||
|
||||
module PositiveTestCase3 {
|
||||
record R = { party: Party };
|
||||
template (this : R) = {
|
||||
precondition EQUAL_PARTY party 'Alice'; // disallowed party literal 'Alice'
|
||||
signatories Cons @Party [party] (Nil @Party);
|
||||
observers Cons @Party [party] (Nil @Party);
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Mod:R): Unit, controllers party to
|
||||
upure @Unit ();
|
||||
} ;
|
||||
}
|
||||
|
||||
module PositiveTestCase4 {
|
||||
record R = { party: Party };
|
||||
template (this : R) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Alice'] (Nil @Party); // disallowed party literal 'Alice'
|
||||
observers Cons @Party [party] (Nil @Party);
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Mod:R): Unit, controllers party to
|
||||
upure @Unit ();
|
||||
} ;
|
||||
}
|
||||
|
||||
module PositiveTestCase5 {
|
||||
record R = { party: Party };
|
||||
template (this : R) = {
|
||||
precondition True;
|
||||
signatories Cons @Party [party] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party); // disallowed party literal 'Alice'
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Mod:R): Unit, controllers 'Alice' to
|
||||
upure @Unit ();
|
||||
} ;
|
||||
}
|
||||
|
||||
module PositiveTestCase6 {
|
||||
record R = { party: Party };
|
||||
template (this : R) = {
|
||||
precondition True;
|
||||
signatories Cons @Party [party] (Nil @Party);
|
||||
observers Cons @Party [party] (Nil @Party);
|
||||
agreement PARTY_TO_TEXT 'Alice'; // disallowed party literal 'Alice'
|
||||
choice Ch (self) (i : Mod:R): Unit, controllers 'Alice' to
|
||||
upure @Unit ();
|
||||
} ;
|
||||
}
|
||||
|
||||
module PositiveTestCase7 {
|
||||
record R = { party: Party };
|
||||
template (this : R) = {
|
||||
precondition True;
|
||||
signatories Cons @Party [party] (Nil @Party);
|
||||
observers Cons @Party [party] (Nil @Party);
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Mod:R): Party, controllers party to
|
||||
upure @Party 'Alice'; // disallowed party literal 'Alice'
|
||||
} ;
|
||||
}
|
||||
|
||||
module @noPartyLiterals PositiveTestCase8 {
|
||||
val bob : Party = Error "not implememted"; // disallowed value ref
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
val positiveTestCases = Table(
|
||||
"module",
|
||||
"PositiveTestCase1",
|
||||
"PositiveTestCase2",
|
||||
"PositiveTestCase3",
|
||||
"PositiveTestCase4",
|
||||
"PositiveTestCase5",
|
||||
"PositiveTestCase6",
|
||||
"PositiveTestCase7",
|
||||
"PositiveTestCase8",
|
||||
)
|
||||
|
||||
val interface = language.PackageInterface(Map(defaultPackageId -> pkg))
|
||||
|
||||
checkModule(
|
||||
interface,
|
||||
defaultPackageId,
|
||||
pkg.modules(DottedName.assertFromString("NegativeTestCase")),
|
||||
)
|
||||
forEvery(positiveTestCases) { modName =>
|
||||
an[EForbiddenPartyLiterals] should be thrownBy
|
||||
checkModule(
|
||||
interface,
|
||||
defaultPackageId,
|
||||
pkg.modules(DottedName.assertFromString(modName)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -149,19 +149,21 @@ class SerializabilitySpec extends AnyWordSpec with TableDrivenPropertyChecks wit
|
||||
|
||||
// well-formed module
|
||||
module NegativeTestCase {
|
||||
record @serializable SerializableRecord = {};
|
||||
record @serializable SerializableRecord = { alice: Party };
|
||||
|
||||
template (this : SerializableRecord) = {
|
||||
precondition True;
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Mod:SerializableType) : Mod:SerializableType, controllers $partiesAlice to upure @Mod:SerializableType (Mod:SerializableType {});
|
||||
choice Ch (self) (i : Mod:SerializableType) : Mod:SerializableType, controllers ${partiesAlice(
|
||||
"NegativeTestCase:SerializableRecord"
|
||||
)} to upure @Mod:SerializableType (Mod:SerializableType {});
|
||||
} ;
|
||||
}
|
||||
|
||||
module PositiveTestCase1 {
|
||||
record UnserializableRecord = {};
|
||||
record UnserializableRecord = { alice: Party };
|
||||
|
||||
template (this : UnserializableRecord) = { // disallowed unserializable type
|
||||
precondition True;
|
||||
@ -169,13 +171,15 @@ class SerializabilitySpec extends AnyWordSpec with TableDrivenPropertyChecks wit
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Mod:SerializableType) :
|
||||
Mod:SerializableType, controllers $partiesAlice
|
||||
Mod:SerializableType, controllers ${partiesAlice(
|
||||
"PositiveTestCase1:UnserializableRecord"
|
||||
)}
|
||||
to upure @Mod:SerializableType (Mod:SerializableType {});
|
||||
} ;
|
||||
}
|
||||
|
||||
module PositiveTestCase2 {
|
||||
record @serializable SerializableRecord = {};
|
||||
record @serializable SerializableRecord = { alice: Party };
|
||||
|
||||
template (this : SerializableRecord) = {
|
||||
precondition True;
|
||||
@ -183,13 +187,13 @@ class SerializabilitySpec extends AnyWordSpec with TableDrivenPropertyChecks wit
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Mod:UnserializableType) : // disallowed unserializable type
|
||||
Unit, controllers $partiesAlice to
|
||||
Unit, controllers ${partiesAlice("PositiveTestCase2:SerializableRecord")} to
|
||||
upure @Unit ();
|
||||
} ;
|
||||
}
|
||||
|
||||
module PositiveTestCase3 {
|
||||
record @serializable SerializableRecord = {};
|
||||
record @serializable SerializableRecord = { alice: Party };
|
||||
|
||||
template (this : SerializableRecord) = {
|
||||
precondition True;
|
||||
@ -197,7 +201,9 @@ class SerializabilitySpec extends AnyWordSpec with TableDrivenPropertyChecks wit
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Mod:SerializableType) :
|
||||
Mod:UnserializableType, controllers $partiesAlice to // disallowed unserializable type
|
||||
Mod:UnserializableType, controllers ${partiesAlice(
|
||||
"PositiveTestCase3:SerializableRecord"
|
||||
)} to // disallowed unserializable type
|
||||
upure @Mod:UnserializableType (Mod:UnserializableType {});
|
||||
} ;
|
||||
}
|
||||
@ -321,13 +327,13 @@ class SerializabilitySpec extends AnyWordSpec with TableDrivenPropertyChecks wit
|
||||
|
||||
record R (a: *) (b: *) = {f: a -> b };
|
||||
|
||||
record @serializable T = {};
|
||||
record @serializable T = {alice: Party, bob: Party};
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Cons @Party [bob] (Nil @Party);
|
||||
observers Cons @Party [alice] (Nil @Party);
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (x: Int64) : Decimal, controllers 'Bob' to upure @Int64 (DECIMAL_TO_INT64 x);
|
||||
choice Ch (self) (x: Int64) : Decimal, controllers bob to upure @Int64 (DECIMAL_TO_INT64 x);
|
||||
} ;
|
||||
|
||||
val f : Int64 -> Int64 = ERROR @(Int64 -> Int64) "not implemented";
|
||||
@ -346,6 +352,6 @@ class SerializabilitySpec extends AnyWordSpec with TableDrivenPropertyChecks wit
|
||||
Serializability.checkModule(w, defaultPackageId, mod)
|
||||
}
|
||||
|
||||
private val partiesAlice = "(Cons @Party ['Alice'] (Nil @Party))"
|
||||
private def partiesAlice(r: String) = s"(Cons @Party [$r {alice} this] (Nil @Party))"
|
||||
|
||||
}
|
||||
|
@ -158,8 +158,6 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
E"(( 1879-03-14 ))" -> T"(( Date ))",
|
||||
//ExpLitTimestamp
|
||||
E"(( 1969-07-20T20:17:00.000000Z ))" -> T"(( Timestamp ))",
|
||||
//ExpLitParty
|
||||
E"(( 'party' ))" -> T"(( Party ))",
|
||||
//TextMap
|
||||
E"Λ (τ : ⋆) . (( TEXTMAP_EMPTY @τ ))" -> T"∀ (τ : ⋆) . (( TextMap τ ))",
|
||||
//GenMap
|
||||
@ -364,7 +362,7 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
T"ContractId Mod:I → (( Update Mod:I ))",
|
||||
E"λ (e: Party) → (( fetch_by_key @Mod:T e ))" ->
|
||||
T"Party → (( Update (⟨ contract: Mod:T, contractId: ContractId Mod:T ⟩) ))",
|
||||
E"λ (e: Party) → (( lookup_by_key @Mod:T 'Bob' ))" ->
|
||||
E"λ (e: Party) → (( lookup_by_key @Mod:T e ))" ->
|
||||
T"Party → (( Update (Option (ContractId Mod:T)) ))",
|
||||
E"(( uget_time ))" ->
|
||||
T"(( Update Timestamp ))",
|
||||
@ -955,26 +953,26 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch1 (self) (i : Unit) : Unit
|
||||
, controllers Cons @Party ['Alice'] (Nil @Party)
|
||||
, controllers Nil @Party
|
||||
to upure @Unit ();
|
||||
choice Ch2 (self) (i : Unit) : Unit
|
||||
, controllers Cons @Party ['Alice'] (Nil @Party)
|
||||
, controllers Nil @Party
|
||||
, observers Nil @Party
|
||||
to upure @Unit ();
|
||||
choice Ch3 (self) (i : Unit) : Unit
|
||||
, controllers Cons @Party ['Alice'] (Nil @Party)
|
||||
, observers Cons @Party ['Alice'] (Nil @Party)
|
||||
, controllers Nil @Party
|
||||
, observers Nil @Party
|
||||
to upure @Unit ();
|
||||
implements Mod:I {
|
||||
method getParties = \(self: NegativeTestCase:T) -> Cons @Party [NegativeTestCase:T {person} self] (Nil @Party);
|
||||
};
|
||||
key @Mod:Key
|
||||
(Mod:Key { person = (NegativeTestCase:T {name} this), party = (NegativeTestCase:T {person} this) })
|
||||
(\ (key: Mod:Key) -> Cons @Party [(Mod:Key {party} key), 'Alice'] (Nil @Party) );
|
||||
(\ (key: Mod:Key) -> Cons @Party [(Mod:Key {party} key)] (Nil @Party) );
|
||||
} ;
|
||||
}
|
||||
|
||||
@ -985,8 +983,8 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
// in the next line, T should be of type *.
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
};
|
||||
}
|
||||
@ -997,8 +995,8 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
// in the next line, V should be of record.
|
||||
template (this : V) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
};
|
||||
}
|
||||
@ -1007,8 +1005,8 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
// template without data type
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
} ;
|
||||
}
|
||||
@ -1018,8 +1016,8 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
|
||||
template (this : T) = {
|
||||
precondition (); // precondition should be a boolean
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
} ;
|
||||
}
|
||||
@ -1030,9 +1028,9 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories (); // should be of (type List Party)
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Unit) : Unit, controllers Cons @Party ['Alice'] (Nil @Party) to upure @Unit ();
|
||||
choice Ch (self) (i : Unit) : Unit, controllers Nil @Party to upure @Unit ();
|
||||
} ;
|
||||
}
|
||||
|
||||
@ -1041,10 +1039,10 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers (); // should be of type (List Party)
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Unit) : Unit, controllers Cons @Party ['Alice'] (Nil @Party) to upure @Unit ();
|
||||
choice Ch (self) (i : Unit) : Unit, controllers Nil @Party to upure @Unit ();
|
||||
} ;
|
||||
}
|
||||
|
||||
@ -1053,8 +1051,8 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Bob'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Unit) : Unit
|
||||
, controllers () // should be of type (List Party)
|
||||
@ -1067,11 +1065,11 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Bob'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Unit) : Unit
|
||||
, controllers Cons @Party ['Alice'] (Nil @Party)
|
||||
, controllers Nil @Party
|
||||
, observers () // should be of type (List Party)
|
||||
to upure @Unit ();
|
||||
} ;
|
||||
@ -1082,10 +1080,10 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement (); // should be of type Text
|
||||
choice Ch (self) (i : Unit) : Unit, controllers Cons @Party ['Alice'] (Nil @Party) to upure @Unit ();
|
||||
choice Ch (self) (i : Unit) : Unit, controllers Nil @Party to upure @Unit ();
|
||||
} ;
|
||||
}
|
||||
|
||||
@ -1094,11 +1092,11 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : List) : Unit // the type of i (here List) should be of kind * (here it is * -> *)
|
||||
, controllers Cons @Party ['Alice'] (Nil @Party) to upure @Unit ();
|
||||
, controllers Nil @Party to upure @Unit ();
|
||||
} ;
|
||||
}
|
||||
|
||||
@ -1107,11 +1105,11 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Unit) : List // the return type (here List) should be of kind * (here it is * -> *)
|
||||
, controllers Cons @Party ['Alice'] (Nil @Party) to upure @(List) (/\ (tau : *). Nil @tau);
|
||||
, controllers Nil @Party to upure @(List) (/\ (tau : *). Nil @tau);
|
||||
} ;
|
||||
}
|
||||
|
||||
@ -1121,17 +1119,17 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Unit) : Unit, controllers Cons @Party ['Alice'] (Nil @Party) to upure @Unit ();
|
||||
choice Ch (self) (i : Unit) : Unit, controllers Nil @Party to upure @Unit ();
|
||||
key @Mod:Key
|
||||
// In the next line, the declared type do not match body
|
||||
(PositiveTestCase_KeyBodyShouldBeProperType:Key {
|
||||
person = (PositiveTestCase_KeyBodyShouldBeProperType:T {name} this),
|
||||
party = (PositiveTestCase_KeyBodyShouldBeProperType:T {person} this)
|
||||
})
|
||||
(\ (key: Mod:Key) -> Cons @Party [(Mod:Key {party} key), 'Alice'] (Nil @Party) );
|
||||
(\ (key: Mod:Key) -> Cons @Party [(Mod:Key {party} key)] (Nil @Party) );
|
||||
} ;
|
||||
}
|
||||
|
||||
@ -1142,10 +1140,10 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Unit) : Unit, controllers Cons @Party ['Alice'] (Nil @Party) to upure @Unit ();
|
||||
choice Ch (self) (i : Unit) : Unit, controllers Nil @Party to upure @Unit ();
|
||||
key @Mod:Key
|
||||
// In the next line, the declared type do not match body
|
||||
(Mod:Key {
|
||||
@ -1153,7 +1151,7 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
party = (PositiveTestCase_MaintainersShouldBeProperType:T {person} this)
|
||||
})
|
||||
(\ (key: PositiveTestCase_MaintainersShouldBeProperType:Key) ->
|
||||
Cons @Party [(PositiveTestCase_MaintainersShouldBeProperType:Key {party} key), 'Alice'] (Nil @Party) );
|
||||
Cons @Party [(PositiveTestCase_MaintainersShouldBeProperType:Key {party} key)] (Nil @Party) );
|
||||
} ;
|
||||
}
|
||||
|
||||
@ -1163,10 +1161,10 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Unit) : Unit, controllers Cons @Party ['Alice'] (Nil @Party) to upure @Unit ();
|
||||
choice Ch (self) (i : Unit) : Unit, controllers Nil @Party to upure @Unit ();
|
||||
key @Mod:Key
|
||||
// In the next line, the declared type do not match body
|
||||
(Mod:Key {
|
||||
@ -1183,10 +1181,10 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Unit) : Unit, controllers Cons @Party ['Alice'] (Nil @Party) to upure @Unit ();
|
||||
choice Ch (self) (i : Unit) : Unit, controllers Nil @Party to upure @Unit ();
|
||||
key @PositiveTestCase_MaintainersShouldNotUseThis:TBis
|
||||
(PositiveTestCase_MaintainersShouldNotUseThis:TBis {
|
||||
person = (PositiveTestCase_MaintainersShouldNotUseThis:T {name} this),
|
||||
@ -1194,7 +1192,7 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
})
|
||||
// In the next line, cannot use `this`
|
||||
(\ (key: PositiveTestCase_MaintainersShouldNotUseThis:TBis) ->
|
||||
Cons @Party [(PositiveTestCase_MaintainersShouldNotUseThis:T {person} this), 'Alice'] (Nil @Party) );
|
||||
Cons @Party [(PositiveTestCase_MaintainersShouldNotUseThis:T {person} this)] (Nil @Party) );
|
||||
};
|
||||
}
|
||||
|
||||
@ -1203,11 +1201,11 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Unit) : Unit
|
||||
, controllers Cons @Party ['Alice'] (Nil @Party)
|
||||
, controllers Nil @Party
|
||||
to upure @Unit ();
|
||||
implements Mod:I {
|
||||
method getParties = \(self: PositiveCase_InterfaceMethodShouldBeProperType:T) -> (); // should Be of type
|
||||
@ -1220,11 +1218,11 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Unit) : Unit
|
||||
, controllers Cons @Party ['Alice'] (Nil @Party)
|
||||
, controllers Nil @Party
|
||||
to upure @Unit ();
|
||||
implements Mod:I {
|
||||
};
|
||||
@ -1236,15 +1234,15 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] (Nil @Party);
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (i : Unit) : Unit
|
||||
, controllers Cons @Party ['Alice'] (Nil @Party)
|
||||
, controllers Nil @Party
|
||||
to upure @Unit ();
|
||||
implements Mod:I {
|
||||
method getParties = \(self: PositiveCase_ImplementsShouldOverrideOnlyMethods:T) ->
|
||||
Cons @Party [(PositiveCase_ImplementsShouldOverrideOnlyMethods:T {person} this), 'Alice'] (Nil @Party);
|
||||
Cons @Party [(PositiveCase_ImplementsShouldOverrideOnlyMethods:T {person} this)] (Nil @Party);
|
||||
method getName = \(self: PositiveCase_ImplementsShouldOverrideOnlyMethods:T) ->
|
||||
PositiveCase_ImplementsShouldOverrideOnlyMethods:T {name} this;
|
||||
};
|
||||
@ -1317,7 +1315,7 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
precondition True;
|
||||
method getParties: List Party;
|
||||
choice Ch1 (self) (i : Unit) : Unit,
|
||||
controllers Cons @Party ['Alice'] (Nil @Party)
|
||||
controllers Nil @Party
|
||||
to upure @Unit ();
|
||||
choice Ch2 (self) (i : Unit) : Unit,
|
||||
controllers call_method @NegativeTestCase:I getParties this,
|
||||
@ -1662,18 +1660,18 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
record @serializable T = { person: Party, name: Text };
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] Nil @Party;
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch (self) (x: Int64) : Decimal, controllers 'Bob' to upure @INT64 (DECIMAL_TO_INT64 x);
|
||||
key @Party (Mod:Person {person} this) (\ (p: Party) -> Cons @Party ['Alice', p] (Nil @Party));
|
||||
choice Ch (self) (x: Int64) : Decimal, controllers Nil @Party to upure @INT64 (DECIMAL_TO_INT64 x);
|
||||
key @Party (Mod:Person {person} this) (\ (p: Party) -> Cons @Party [p] (Nil @Party));
|
||||
};
|
||||
|
||||
interface (this : I) = {
|
||||
precondition True;
|
||||
method getParties: List Party;
|
||||
choice ChIface (self) (x: Int64) : Decimal,
|
||||
controllers 'Bob'
|
||||
controllers Nil @Party
|
||||
to upure @INT64 (DECIMAL_TO_INT64 x);
|
||||
};
|
||||
|
||||
@ -1684,10 +1682,10 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
|
||||
record @serializable Ti = { person: Party, name: Text };
|
||||
template (this: Ti) = {
|
||||
precondition True;
|
||||
signatories Cons @Party ['Bob'] Nil @Party;
|
||||
observers Cons @Party ['Alice'] (Nil @Party);
|
||||
signatories Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice ChTmpl (self) (x: Int64) : Decimal, controllers 'Bob' to upure @INT64 (DECIMAL_TO_INT64 x);
|
||||
choice ChTmpl (self) (x: Int64) : Decimal, controllers Nil @Party to upure @INT64 (DECIMAL_TO_INT64 x);
|
||||
implements Mod:I {
|
||||
method getParties = Cons @Party [(Mod:Ti {person} this)] (Nil @Party);
|
||||
};
|
||||
|
@ -190,11 +190,11 @@ object Script {
|
||||
def getScriptIds(ty: Type): Either[String, ScriptIds] =
|
||||
ScriptIds.fromType(ty).toRight(s"Expected type 'Daml.Script.Script a' but got $ty")
|
||||
script.flatMap {
|
||||
case GenDValue(TApp(TApp(TBuiltin(BTArrow), param), result), _, _, _) =>
|
||||
case GenDValue(TApp(TApp(TBuiltin(BTArrow), param), result), _, _) =>
|
||||
for {
|
||||
scriptIds <- getScriptIds(result)
|
||||
} yield Script.Function(scriptExpr, param, scriptIds)
|
||||
case GenDValue(ty, _, _, _) =>
|
||||
case GenDValue(ty, _, _) =>
|
||||
for {
|
||||
scriptIds <- getScriptIds(ty)
|
||||
} yield Script.Action(scriptExpr, scriptIds)
|
||||
|
@ -29,7 +29,7 @@
|
||||
- ensure correct privacy for rollback subtree: [BlindingSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/BlindingSpec.scala#L201)
|
||||
|
||||
## Semantics:
|
||||
- Exceptions, throw/catch.: [ExceptionTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/ExceptionTest.scala#L24)
|
||||
- Exceptions, throw/catch.: [ExceptionTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/ExceptionTest.scala#L25)
|
||||
- contract key behaviour (non-unique mode): [ContractKeySpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ContractKeySpec.scala#L383)
|
||||
- contract key behaviour (unique mode): [ContractKeySpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ContractKeySpec.scala#L389)
|
||||
- contract keys must have a non-empty set of maintainers: [ContractKeySpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ContractKeySpec.scala#L218)
|
||||
@ -44,21 +44,21 @@
|
||||
- ensure expression forms have the correct type: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L107)
|
||||
- ill-formed create command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L133)
|
||||
- ill-formed create-and-exercise command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L154)
|
||||
- ill-formed exception definitions are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1417)
|
||||
- ill-formed exception definitions are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1415)
|
||||
- ill-formed exercise command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L138)
|
||||
- ill-formed exercise-by-key command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L145)
|
||||
- ill-formed expressions are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L422)
|
||||
- ill-formed expressions are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L420)
|
||||
- ill-formed fetch command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L167)
|
||||
- ill-formed fetch-by-key command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L170)
|
||||
- ill-formed interfaces are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1310)
|
||||
- ill-formed interfaces are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1308)
|
||||
- ill-formed kinds are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L19)
|
||||
- ill-formed lookup command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L175)
|
||||
- ill-formed records are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1559)
|
||||
- ill-formed templates are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L938)
|
||||
- ill-formed type synonyms applications are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1538)
|
||||
- ill-formed type synonyms definitions are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1605)
|
||||
- ill-formed records are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1557)
|
||||
- ill-formed templates are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L936)
|
||||
- ill-formed type synonyms applications are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1536)
|
||||
- ill-formed type synonyms definitions are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1603)
|
||||
- ill-formed types are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L99)
|
||||
- ill-formed variants are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1582)
|
||||
- ill-formed variants are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1580)
|
||||
- well formed create command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L79)
|
||||
- well formed create-and-exercise command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L98)
|
||||
- well formed exercise command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L84)
|
||||
|
@ -173,9 +173,9 @@ object Trigger extends StrictLogging {
|
||||
for {
|
||||
definition <- compiledPackages.interface.lookupDefinition(triggerId).left.map(_.pretty)
|
||||
expr <- definition match {
|
||||
case GenDValue(TApp(TTyCon(tcon), stateTy), _, _, _) =>
|
||||
case GenDValue(TApp(TTyCon(tcon), stateTy), _, _) =>
|
||||
detectTriggerType(tcon, stateTy)
|
||||
case GenDValue(ty, _, _, _) => Left(s"$ty is not a valid type for a trigger")
|
||||
case GenDValue(ty, _, _) => Left(s"$ty is not a valid type for a trigger")
|
||||
case _ => Left(s"Trigger must points to a value but points to $definition")
|
||||
}
|
||||
triggerIds = TriggerIds(expr.ty.tycon.packageId)
|
||||
|
@ -30,7 +30,7 @@ object RunnerMain {
|
||||
for ((modName, mod) <- dar.main._2.modules) {
|
||||
for ((defName, defVal) <- mod.definitions) {
|
||||
defVal match {
|
||||
case DValue(TApp(TTyCon(tcon), _), _, _, _) => {
|
||||
case DValue(TApp(TTyCon(tcon), _), _, _) => {
|
||||
val triggerIds = TriggerIds(tcon.packageId)
|
||||
if (
|
||||
tcon == triggerIds.damlTrigger("Trigger")
|
||||
|
Loading…
Reference in New Issue
Block a user