Skip to content

Commit

Permalink
LF: Scala serializability checker handle exceptions
Browse files Browse the repository at this point in the history
This is part of #8020.

CHANGELOG_BEGIN
CHANGELOG_END
  • Loading branch information
remyhaemmerle-da committed Jan 4, 2021
1 parent b45e379 commit 5a4dd45
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ private[validation] object Serializability {
checkType(targ)
case TBuiltin(builtinType) =>
builtinType match {
case BTInt64 | BTText | BTTimestamp | BTDate | BTParty | BTBool | BTUnit =>
case BTInt64 | BTText | BTTimestamp | BTDate | BTParty | BTBool | BTUnit |
BTAnyException | BTGeneralError | BTArithmeticError | BTContractError =>
()
case BTNumeric =>
unserializable(URNumeric)
case BTList =>
Expand All @@ -85,9 +87,6 @@ private[validation] object Serializability {
unserializable(URAny)
case BTTypeRep =>
unserializable(URTypeRep)
case BTAnyException | BTArithmeticError | BTContractError | BTGeneralError =>
// TODO https://github.com/digital-asset/daml/issues/8020
sys.error("exceptions not supported")
}
case TForall(_, _) =>
unserializable(URForall)
Expand Down Expand Up @@ -135,6 +134,15 @@ private[validation] object Serializability {
template.key.foreach(k => Env(version, world, context, SRKey, k.typ).checkType())
}

def checkException(
version: LanguageVersion,
world: World,
tyCon: TTyCon,
): Unit = {
val context = ContextTemplate(tyCon.tycon)
Env(version, world, context, SRTemplateArg, tyCon).checkType()
}

def checkModule(world: World, pkgId: PackageId, module: Module): Unit = {
val version = world.lookupPackage(NoContext, pkgId).languageVersion
module.definitions.foreach {
Expand All @@ -148,5 +156,9 @@ private[validation] object Serializability {
val tyCon = TTyCon(Identifier(pkgId, QualifiedName(module.name, defName)))
checkTemplate(version, world, tyCon, template)
}
module.exceptions.keys.foreach { defName =>
val tyCon = TTyCon(Identifier(pkgId, QualifiedName(module.name, defName)))
checkException(version, world, tyCon)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -164,53 +164,52 @@ class SerializabilitySpec extends AnyWordSpec with TableDrivenPropertyChecks wit
}

module PositiveTestCase1 {
record UnserializableRecord = {};

template (this : UnserializableRecord) = { // disallowed unserializable type
precondition True,
signatories Nil @Party,
observers Nil @Party,
agreement "Agreement",
choices {
choice Ch (self) (i : Mod:SerializableType) :
Mod:SerializableType, controllers $partiesAlice
to upure @Mod:SerializableType (Mod:SerializableType {})
}
} ;
}
record UnserializableRecord = {};

template (this : UnserializableRecord) = { // disallowed unserializable type
precondition True,
signatories Nil @Party,
observers Nil @Party,
agreement "Agreement",
choices {
choice Ch (self) (i : Mod:SerializableType) :
Mod:SerializableType, controllers $partiesAlice
to upure @Mod:SerializableType (Mod:SerializableType {})
}
} ;
}

module PositiveTestCase2 {
record @serializable SerializableRecord = {};

template (this : SerializableRecord) = {
precondition True,
signatories Nil @Party,
observers Nil @Party,
agreement "Agreement",
choices {
choice Ch (self) (i : Mod:UnserializableType) : // disallowed unserializable type
Unit, controllers $partiesAlice to
upure @Unit ()
}
} ;
}
record @serializable SerializableRecord = {};

template (this : SerializableRecord) = {
precondition True,
signatories Nil @Party,
observers Nil @Party,
agreement "Agreement",
choices {
choice Ch (self) (i : Mod:UnserializableType) : // disallowed unserializable type
Unit, controllers $partiesAlice to
upure @Unit ()
}
} ;
}

module PositiveTestCase3 {
record @serializable SerializableRecord = {};

template (this : SerializableRecord) = {
precondition True,
signatories Nil @Party,
observers Nil @Party,
agreement "Agreement",
choices {
choice Ch (self) (i : Mod:SerializableType) :
Mod:UnserializableType, controllers $partiesAlice to // disallowed unserializable type
upure @Mod:UnserializableType (Mod:UnserializableType {})
}
} ;
}
record @serializable SerializableRecord = {};

template (this : SerializableRecord) = {
precondition True,
signatories Nil @Party,
observers Nil @Party,
agreement "Agreement",
choices {
choice Ch (self) (i : Mod:SerializableType) :
Mod:UnserializableType, controllers $partiesAlice to // disallowed unserializable type
upure @Mod:UnserializableType (Mod:UnserializableType {})
}
} ;
}
"""

val positiveTestCases = Table(
Expand All @@ -227,6 +226,33 @@ class SerializabilitySpec extends AnyWordSpec with TableDrivenPropertyChecks wit

}

"reject unserializable exception definitions" in {

val pkg =
p"""
// well-formed module
module NegativeTestCase {
record @serializable SerializableRecord = { message: Text } ;

exception SerializableRecord = {
message \(e: Mod:SerializableRecord) -> Mod:SerializableRecord {message} e
} ;
}

module PositiveTestCase {
record UnserializableRecord = { message: Text } ;

exception UnserializableRecord = {
message \(e: Mod:UnserializableRecord) -> Mod:UnserializableRecord {message} e
} ;
}
"""

check(pkg, "NegativeTestCase")
an[EExpectedSerializableType] shouldBe thrownBy(check(pkg, "PositiveTestCase"))

}

"reject unserializable contract id" in {

val pkg =
Expand Down

0 comments on commit 5a4dd45

Please sign in to comment.