LF: Clean up Ast (#11786)

- rename non-default builders `apply` to `build`
  * avoid confusing both
  * make explicit the build can crash

- make interfaceId and templateId fields consitent

- use when possible named arguments

- check for non-repetition of inherited choices

CHANGELOG_BEGIN
CHANGELOG_END
This commit is contained in:
Remy 2021-11-19 15:40:28 +01:00 committed by GitHub
parent 25e5bbb753
commit cbe9c922ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 311 additions and 269 deletions

View File

@ -241,7 +241,7 @@ class ReplService(
): Unit = { ): Unit = {
val lfVer = LanguageVersion(LanguageVersion.Major.V1, LanguageVersion.Minor(req.getMinor)) val lfVer = LanguageVersion(LanguageVersion.Major.V1, LanguageVersion.Minor(req.getMinor))
val mod = archive.moduleDecoder(lfVer, homePackageId).assertFromByteString(req.getDamlLf1) val mod = archive.moduleDecoder(lfVer, homePackageId).assertFromByteString(req.getDamlLf1)
val pkg = Package((mainModules + (mod.name -> mod)).values, Seq(), lfVer, None) val pkg = Package(mainModules.updated(mod.name, mod), Set.empty, lfVer, None)
// TODO[AH] Provide daml-script package id from REPL client. // TODO[AH] Provide daml-script package id from REPL client.
val Some(scriptPackageId) = this.signatures.collectFirst { val Some(scriptPackageId) = this.signatures.collectFirst {
case (pkgId, pkg) if pkg.modules.contains(DottedName.assertFromString("Daml.Script")) => pkgId case (pkgId, pkg) if pkg.modules.contains(DottedName.assertFromString("Daml.Script")) => pkgId

View File

@ -64,7 +64,7 @@ private[archive] class DecodeV1(minor: LV.Minor) {
val internedTypes = decodeInternedTypes(env0, lfPackage) val internedTypes = decodeInternedTypes(env0, lfPackage)
val env = env0.copy(internedTypes = internedTypes) val env = env0.copy(internedTypes = internedTypes)
Package( Package.build(
modules = lfPackage.getModulesList.asScala.map(env.decodeModule(_)), modules = lfPackage.getModulesList.asScala.map(env.decodeModule(_)),
directDeps = dependencyTracker.getDependencies, directDeps = dependencyTracker.getDependencies,
languageVersion = languageVersion, languageVersion = languageVersion,
@ -289,7 +289,7 @@ private[archive] class DecodeV1(minor: LV.Minor) {
} }
} }
Module( Module.build(
moduleName, moduleName,
defs, defs,
templates, templates,
@ -583,16 +583,14 @@ private[archive] class DecodeV1(minor: LV.Minor) {
lfTempl.getParamInternedStr, lfTempl.getParamInternedStr,
"DefTemplate.param.param", "DefTemplate.param.param",
) )
Template( Template.build(
param = paramName, param = paramName,
precond = if (lfTempl.hasPrecond) decodeExpr(lfTempl.getPrecond, s"$tpl:ensure") else ETrue, precond = if (lfTempl.hasPrecond) decodeExpr(lfTempl.getPrecond, s"$tpl:ensure") else ETrue,
signatories = decodeExpr(lfTempl.getSignatories, s"$tpl.signatory"), signatories = decodeExpr(lfTempl.getSignatories, s"$tpl.signatory"),
agreementText = decodeExpr(lfTempl.getAgreement, s"$tpl:agreement"), agreementText = decodeExpr(lfTempl.getAgreement, s"$tpl:agreement"),
choices = lfTempl.getChoicesList.asScala choices = lfTempl.getChoicesList.asScala.view.map(decodeChoice(tpl, _)),
.map(decodeChoice(tpl, _))
.map(ch => (ch.name, ch)),
observers = decodeExpr(lfTempl.getObservers, s"$tpl:observer"), observers = decodeExpr(lfTempl.getObservers, s"$tpl:observer"),
implements = lfImplements.map(decodeTemplateImplements).map(impl => (impl.interface, impl)), implements = lfImplements.view.map(decodeTemplateImplements),
key = key =
if (lfTempl.hasKey) Some(decodeTemplateKey(tpl, lfTempl.getKey, paramName)) if (lfTempl.hasKey) Some(decodeTemplateKey(tpl, lfTempl.getKey, paramName))
else None, else None,
@ -602,21 +600,19 @@ private[archive] class DecodeV1(minor: LV.Minor) {
private[this] def decodeTemplateImplements( private[this] def decodeTemplateImplements(
lfImpl: PLF.DefTemplate.Implements lfImpl: PLF.DefTemplate.Implements
): TemplateImplements = ): TemplateImplements =
TemplateImplements( TemplateImplements.build(
interface = decodeTypeConName(lfImpl.getInterface), interfaceId = decodeTypeConName(lfImpl.getInterface),
methods = lfImpl.getMethodsList.asScala methods = lfImpl.getMethodsList.asScala.view.map(decodeTemplateImplementsMethod),
.map(decodeTemplateImplementsMethod) inheritedChoices = lfImpl.getInheritedChoiceInternedNamesList.asScala.view
.map(method => (method.name, method)), .map(getInternedName(_, "TemplateImplements.inheritedChoices")),
inheritedChoices = lfImpl.getInheritedChoiceInternedNamesList.asScala
.map(getInternedName(_, "TemplateImplements.inheritedChoices"))
.toSet,
) )
private[this] def decodeTemplateImplementsMethod( private[this] def decodeTemplateImplementsMethod(
lfMethod: PLF.DefTemplate.ImplementsMethod lfMethod: PLF.DefTemplate.ImplementsMethod
): TemplateImplementsMethod = ): TemplateImplementsMethod =
TemplateImplementsMethod( TemplateImplementsMethod(
name = getInternedName(lfMethod.getMethodInternedName, "TemplateImplementsMethod.name"), methodName =
getInternedName(lfMethod.getMethodInternedName, "TemplateImplementsMethod.name"),
value = decodeExpr(lfMethod.getValue, "TemplateImplementsMethod.value"), value = decodeExpr(lfMethod.getValue, "TemplateImplementsMethod.value"),
) )
@ -669,14 +665,10 @@ private[archive] class DecodeV1(minor: LV.Minor) {
id: DottedName, id: DottedName,
lfInterface: PLF.DefInterface, lfInterface: PLF.DefInterface,
): DefInterface = ): DefInterface =
DefInterface( DefInterface.build(
param = getInternedName(lfInterface.getParamInternedStr, "DefInterface.param"), param = getInternedName(lfInterface.getParamInternedStr, "DefInterface.param"),
fixedChoices = lfInterface.getFixedChoicesList.asScala.view fixedChoices = lfInterface.getFixedChoicesList.asScala.view.map(decodeChoice(id, _)),
.map(decodeChoice(id, _)) methods = lfInterface.getMethodsList.asScala.view.map(decodeInterfaceMethod),
.map(choice => choice.name -> choice),
methods = lfInterface.getMethodsList.asScala.view
.map(decodeInterfaceMethod)
.map(method => method.name -> method),
precond = decodeExpr(lfInterface.getPrecond, s"$id:ensure"), precond = decodeExpr(lfInterface.getPrecond, s"$id:ensure"),
) )
@ -1126,8 +1118,8 @@ private[archive] class DecodeV1(minor: LV.Minor) {
assertSince(LV.Features.interfaces, "Expr.to_interface") assertSince(LV.Features.interfaces, "Expr.to_interface")
val toInterface = lfExpr.getToInterface val toInterface = lfExpr.getToInterface
EToInterface( EToInterface(
iface = decodeTypeConName(toInterface.getInterfaceType), interfaceId = decodeTypeConName(toInterface.getInterfaceType),
tpl = decodeTypeConName(toInterface.getTemplateType), templateId = decodeTypeConName(toInterface.getTemplateType),
value = decodeExpr(toInterface.getTemplateExpr, definition), value = decodeExpr(toInterface.getTemplateExpr, definition),
) )
@ -1135,8 +1127,8 @@ private[archive] class DecodeV1(minor: LV.Minor) {
assertSince(LV.Features.interfaces, "Expr.from_interface") assertSince(LV.Features.interfaces, "Expr.from_interface")
val fromInterface = lfExpr.getFromInterface val fromInterface = lfExpr.getFromInterface
EFromInterface( EFromInterface(
iface = decodeTypeConName(fromInterface.getInterfaceType), interfaceId = decodeTypeConName(fromInterface.getInterfaceType),
tpl = decodeTypeConName(fromInterface.getTemplateType), templateId = decodeTypeConName(fromInterface.getTemplateType),
value = decodeExpr(fromInterface.getInterfaceExpr, definition), value = decodeExpr(fromInterface.getInterfaceExpr, definition),
) )
@ -1144,8 +1136,9 @@ private[archive] class DecodeV1(minor: LV.Minor) {
assertSince(LV.Features.interfaces, "Expr.call_interface") assertSince(LV.Features.interfaces, "Expr.call_interface")
val callInterface = lfExpr.getCallInterface val callInterface = lfExpr.getCallInterface
ECallInterface( ECallInterface(
iface = decodeTypeConName(callInterface.getInterfaceType), interfaceId = decodeTypeConName(callInterface.getInterfaceType),
method = getInternedName(callInterface.getMethodInternedName, "ECallInterface.method"), methodName =
getInternedName(callInterface.getMethodInternedName, "ECallInterface.method"),
value = decodeExpr(callInterface.getInterfaceExpr, definition), value = decodeExpr(callInterface.getInterfaceExpr, definition),
) )
@ -1283,7 +1276,7 @@ private[archive] class DecodeV1(minor: LV.Minor) {
case PLF.Update.SumCase.CREATE_INTERFACE => case PLF.Update.SumCase.CREATE_INTERFACE =>
val create = lfUpdate.getCreateInterface val create = lfUpdate.getCreateInterface
UpdateCreateInterface( UpdateCreateInterface(
interface = decodeTypeConName(create.getInterface), interfaceId = decodeTypeConName(create.getInterface),
arg = decodeExpr(create.getExpr, definition), arg = decodeExpr(create.getExpr, definition),
) )
@ -1307,7 +1300,7 @@ private[archive] class DecodeV1(minor: LV.Minor) {
assertSince(LV.Features.interfaces, "exerciseInterface") assertSince(LV.Features.interfaces, "exerciseInterface")
val exercise = lfUpdate.getExerciseInterface val exercise = lfUpdate.getExerciseInterface
UpdateExerciseInterface( UpdateExerciseInterface(
interface = decodeTypeConName(exercise.getInterface), interfaceId = decodeTypeConName(exercise.getInterface),
choice = handleInternedName(exercise.getChoiceInternedStr), choice = handleInternedName(exercise.getChoiceInternedStr),
cidE = decodeExpr(exercise.getCid, definition), cidE = decodeExpr(exercise.getCid, definition),
argE = decodeExpr(exercise.getArg, definition), argE = decodeExpr(exercise.getArg, definition),
@ -1340,7 +1333,7 @@ private[archive] class DecodeV1(minor: LV.Minor) {
assertSince(LV.Features.interfaces, "fetchInterface") assertSince(LV.Features.interfaces, "fetchInterface")
val fetch = lfUpdate.getFetchInterface val fetch = lfUpdate.getFetchInterface
UpdateFetchInterface( UpdateFetchInterface(
interface = decodeTypeConName(fetch.getInterface), interfaceId = decodeTypeConName(fetch.getInterface),
contractId = decodeExpr(fetch.getCid, definition), contractId = decodeExpr(fetch.getCid, definition),
) )

View File

@ -70,7 +70,7 @@ private[daml] object DamlLfEncoder extends App {
} else None } else None
val pkg = val pkg =
Ast.Package(modules, Set.empty[PackageId], parserParameters.languageVersion, metadata) Ast.Package.build(modules, Set.empty[PackageId], parserParameters.languageVersion, metadata)
val pkgs = PackageInterface(Map(pkgId -> pkg)) val pkgs = PackageInterface(Map(pkgId -> pkg))
Validation.checkPackage(pkgs, pkgId, pkg).left.foreach(e => error(e.pretty)) Validation.checkPackage(pkgs, pkgId, pkg).left.foreach(e => error(e.pretty))

View File

@ -2106,12 +2106,7 @@ class EngineTest
val pkgId = Ref.PackageId.assertFromString("-pkg-") val pkgId = Ref.PackageId.assertFromString("-pkg-")
def pkg(version: LV) = def pkg(version: LV) =
language.Ast.Package( language.Ast.Package(Map.empty, Set.empty, version, None)
Iterable.empty,
Iterable.empty,
version,
None,
)
"reject disallow packages" in { "reject disallow packages" in {
val negativeTestCases = Table( val negativeTestCases = Table(

View File

@ -170,7 +170,7 @@ class InterfaceReaderSpec extends AnyWordSpec with Matchers with Inside {
"Package metadata should be extracted if present" in { "Package metadata should be extracted if present" in {
def pkg(metadata: Option[Ast.PackageMetadata]) = def pkg(metadata: Option[Ast.PackageMetadata]) =
Ast.Package( Ast.Package(
modules = Seq.empty, modules = Map.empty,
directDeps = Set.empty, directDeps = Set.empty,
languageVersion = LanguageVersion.default, languageVersion = LanguageVersion.default,
metadata = metadata, metadata = metadata,

View File

@ -377,10 +377,10 @@ private[lf] final class Compiler(
addDef(compileSignatories(identifier, tmpl)) addDef(compileSignatories(identifier, tmpl))
addDef(compileObservers(identifier, tmpl)) addDef(compileObservers(identifier, tmpl))
tmpl.implements.values.foreach { impl => tmpl.implements.values.foreach { impl =>
addDef(compileCreateByInterface(identifier, tmpl, impl.interface)) addDef(compileCreateByInterface(identifier, tmpl, impl.interfaceId))
addDef(compileImplements(identifier, impl.interface)) addDef(compileImplements(identifier, impl.interfaceId))
impl.methods.values.foreach(method => impl.methods.values.foreach(method =>
addDef(compileImplementsMethod(identifier, impl.interface, method)) addDef(compileImplementsMethod(identifier, impl.interfaceId, method))
) )
} }

View File

@ -188,9 +188,9 @@ class InterpreterTest extends AnyWordSpec with Matchers with TableDrivenProperty
PureCompiledPackages.assertBuild( PureCompiledPackages.assertBuild(
Map( Map(
dummyPkg -> dummyPkg ->
Package( Package.build(
List( List(
Module( Module.build(
name = modName, name = modName,
definitions = Map( definitions = Map(
DottedName.assertFromString("bar") -> DottedName.assertFromString("bar") ->
@ -211,14 +211,14 @@ class InterpreterTest extends AnyWordSpec with Matchers with TableDrivenProperty
val pkgs3 = PureCompiledPackages.assertBuild( val pkgs3 = PureCompiledPackages.assertBuild(
Map( Map(
dummyPkg -> dummyPkg ->
Package( Package.build(
List( List(
Module( Module(
name = modName, name = modName,
definitions = Map.empty, definitions = Map.empty,
templates = Map.empty, templates = Map.empty,
exceptions = Map.empty, exceptions = Map.empty,
interfaces = List.empty, interfaces = Map.empty,
featureFlags = FeatureFlags.default, featureFlags = FeatureFlags.default,
) )
), ),

View File

@ -156,13 +156,16 @@ object Ast {
final case class EFromAnyException(typ: Type, value: Expr) extends Expr final case class EFromAnyException(typ: Type, value: Expr) extends Expr
/** Convert template payload to interface it implements */ /** Convert template payload to interface it implements */
final case class EToInterface(iface: TypeConName, tpl: TypeConName, value: Expr) extends Expr final case class EToInterface(interfaceId: TypeConName, templateId: TypeConName, value: Expr)
extends Expr
/** Convert interface back to template payload if possible */ /** Convert interface back to template payload if possible */
final case class EFromInterface(iface: TypeConName, tpl: TypeConName, value: Expr) extends Expr final case class EFromInterface(interfaceId: TypeConName, templateId: TypeConName, value: Expr)
extends Expr
/** Invoke an interface method */ /** Invoke an interface method */
final case class ECallInterface(iface: TypeConName, method: MethodName, value: Expr) extends Expr final case class ECallInterface(interfaceId: TypeConName, methodName: MethodName, value: Expr)
extends Expr
// //
// Kinds // Kinds
@ -487,9 +490,9 @@ object Ast {
final case class UpdatePure(t: Type, expr: Expr) extends Update final case class UpdatePure(t: Type, expr: Expr) extends Update
final case class UpdateBlock(bindings: ImmArray[Binding], body: Expr) extends Update final case class UpdateBlock(bindings: ImmArray[Binding], body: Expr) extends Update
final case class UpdateCreate(templateId: TypeConName, arg: Expr) extends Update final case class UpdateCreate(templateId: TypeConName, arg: Expr) extends Update
final case class UpdateCreateInterface(interface: TypeConName, arg: Expr) extends Update final case class UpdateCreateInterface(interfaceId: TypeConName, arg: Expr) extends Update
final case class UpdateFetch(templateId: TypeConName, contractId: Expr) extends Update final case class UpdateFetch(templateId: TypeConName, contractId: Expr) extends Update
final case class UpdateFetchInterface(interface: TypeConName, contractId: Expr) extends Update final case class UpdateFetchInterface(interfaceId: TypeConName, contractId: Expr) extends Update
final case class UpdateExercise( final case class UpdateExercise(
templateId: TypeConName, templateId: TypeConName,
choice: ChoiceName, choice: ChoiceName,
@ -497,7 +500,7 @@ object Ast {
argE: Expr, argE: Expr,
) extends Update ) extends Update
final case class UpdateExerciseInterface( final case class UpdateExerciseInterface(
interface: TypeConName, interfaceId: TypeConName,
choice: ChoiceName, choice: ChoiceName,
cidE: Expr, cidE: Expr,
argE: Expr, argE: Expr,
@ -587,7 +590,7 @@ object Ast {
final class GenDValueCompanion[E] private[Ast] { final class GenDValueCompanion[E] private[Ast] {
def apply(typ: Type, noPartyLiterals: Boolean, body: E, isTest: Boolean): GenDValue[E] = def apply(typ: Type, noPartyLiterals: Boolean, body: E, isTest: Boolean): GenDValue[E] =
GenDValue(typ, noPartyLiterals, body, isTest) GenDValue(typ = typ, noPartyLiterals = noPartyLiterals, body = body, isTest = isTest)
def unapply(arg: GenDValue[E]): Some[(Type, Boolean, E, Boolean)] = def unapply(arg: GenDValue[E]): Some[(Type, Boolean, E, Boolean)] =
Some((arg.typ, arg.noPartyLiterals, arg.body, arg.isTest)) Some((arg.typ, arg.noPartyLiterals, arg.body, arg.isTest))
@ -626,7 +629,7 @@ object Ast {
final class GenTemplateKeyCompanion[E] private[Ast] { final class GenTemplateKeyCompanion[E] private[Ast] {
def apply(typ: Type, body: E, maintainers: E): GenTemplateKey[E] = def apply(typ: Type, body: E, maintainers: E): GenTemplateKey[E] =
GenTemplateKey(typ, body, maintainers) GenTemplateKey(typ = typ, body = body, maintainers = maintainers)
def unapply(arg: GenTemplateKey[E]): Some[(Type, E, E)] = def unapply(arg: GenTemplateKey[E]): Some[(Type, E, E)] =
Some((arg.typ, arg.body, arg.maintainers)) Some((arg.typ, arg.body, arg.maintainers))
@ -646,22 +649,32 @@ object Ast {
) )
final class GenDefInterfaceCompanion[E] { final class GenDefInterfaceCompanion[E] {
def apply( @throws[PackageError]
def build(
param: ExprVarName, // Binder for template argument. param: ExprVarName, // Binder for template argument.
fixedChoices: Iterable[(ChoiceName, GenTemplateChoice[E])], fixedChoices: Iterable[GenTemplateChoice[E]],
methods: Iterable[(MethodName, InterfaceMethod)], methods: Iterable[InterfaceMethod],
precond: E, precond: E,
): GenDefInterface[E] = { ): GenDefInterface[E] = {
val fixedChoiceMap = toMapWithoutDuplicate( val fixedChoiceMap = toMapWithoutDuplicate(
fixedChoices, fixedChoices.view.map(c => c.name -> c),
(name: ChoiceName) => throw PackageError(s"collision on interface choice name $name"), (name: ChoiceName) => PackageError(s"collision on interface choice name $name"),
) )
val methodMap = toMapWithoutDuplicate( val methodMap = toMapWithoutDuplicate(
methods, methods.view.map(c => c.name -> c),
(name: MethodName) => throw PackageError(s"collision on interface method name $name"), (name: MethodName) => PackageError(s"collision on interface method name $name"),
) )
GenDefInterface(param, fixedChoiceMap, methodMap, precond) GenDefInterface(param, fixedChoiceMap, methodMap, precond)
} }
def apply(
param: ExprVarName,
fixedChoices: Map[ChoiceName, GenTemplateChoice[E]],
methods: Map[MethodName, InterfaceMethod],
precond: E,
): GenDefInterface[E] =
GenDefInterface(param, fixedChoices, methods, precond)
def unapply(arg: GenDefInterface[E]): Some[ def unapply(arg: GenDefInterface[E]): Some[
( (
ExprVarName, ExprVarName,
@ -709,53 +722,54 @@ object Ast {
} }
final class GenTemplateCompanion[E] private[Ast] { final class GenTemplateCompanion[E] private[Ast] {
@throws[PackageError]
def build(
param: ExprVarName,
precond: E,
signatories: E,
agreementText: E,
choices: Iterable[GenTemplateChoice[E]],
observers: E,
key: Option[GenTemplateKey[E]],
implements: Iterable[GenTemplateImplements[E]],
): GenTemplate[E] =
GenTemplate[E](
param = param,
precond = precond,
signatories = signatories,
agreementText = agreementText,
choices = toMapWithoutDuplicate(
choices.view.map(c => c.name -> c),
(choiceName: ChoiceName) => PackageError(s"collision on choice name $choiceName"),
),
observers = observers,
key = key,
implements = toMapWithoutDuplicate(
implements.map(i => i.interfaceId -> i),
(ifaceId: TypeConName) =>
PackageError(s"repeated interface implementation ${ifaceId.toString}"),
),
)
def apply( def apply(
param: ExprVarName, param: ExprVarName,
precond: E, precond: E,
signatories: E, signatories: E,
agreementText: E, agreementText: E,
choices: Iterable[(ChoiceName, GenTemplateChoice[E])], choices: Map[ChoiceName, GenTemplateChoice[E]],
observers: E, observers: E,
key: Option[GenTemplateKey[E]], key: Option[GenTemplateKey[E]],
implements: Iterable[(TypeConName, GenTemplateImplements[E])], implements: Map[TypeConName, GenTemplateImplements[E]],
): GenTemplate[E] = { ) = GenTemplate(
param = param,
val choiceMap = toMapWithoutDuplicate( precond = precond,
choices, signatories = signatories,
(choiceName: ChoiceName) => throw PackageError(s"collision on choice name $choiceName"), agreementText = agreementText,
) choices = choices,
observers = observers,
val implementsMap = toMapWithoutDuplicate( key = key,
implements, implements = implements,
(ifaceName: TypeConName) => )
throw PackageError(s"repeated interface implementation ${ifaceName.toString}"),
)
GenTemplate[E](
param,
precond,
signatories,
agreementText,
choiceMap,
observers,
key,
implementsMap,
)
}
def apply(arg: GenTemplate[E]): Option[
(
ExprVarName,
E,
E,
E,
Map[ChoiceName, GenTemplateChoice[E]],
E,
Option[GenTemplateKey[E]],
Map[TypeConName, GenTemplateImplements[E]],
)
] = GenTemplate.unapply(arg)
def unapply(arg: GenTemplate[E]): Some[ def unapply(arg: GenTemplate[E]): Some[
( (
@ -811,14 +825,14 @@ object Ast {
update: E, update: E,
): GenTemplateChoice[E] = ): GenTemplateChoice[E] =
GenTemplateChoice( GenTemplateChoice(
name, name = name,
consuming, consuming = consuming,
controllers, controllers = controllers,
choiceObservers, choiceObservers = choiceObservers,
selfBinder, selfBinder = selfBinder,
argBinder, argBinder = argBinder,
returnType, returnType = returnType,
update, update = update,
) )
def unapply( def unapply(
@ -845,36 +859,41 @@ object Ast {
val TemplateChoiceSignature = new GenTemplateChoiceCompanion[Unit] val TemplateChoiceSignature = new GenTemplateChoiceCompanion[Unit]
final case class GenTemplateImplements[E]( final case class GenTemplateImplements[E](
interface: TypeConName, interfaceId: TypeConName,
methods: Map[MethodName, GenTemplateImplementsMethod[E]], methods: Map[MethodName, GenTemplateImplementsMethod[E]],
inheritedChoices: Set[ChoiceName], inheritedChoices: Set[ChoiceName],
) )
final class GenTemplateImplementsCompanion[E] private[Ast] { final class GenTemplateImplementsCompanion[E] private[Ast] {
def apply( @throws[PackageError]
interface: TypeConName, def build(
methods: Iterable[(MethodName, GenTemplateImplementsMethod[E])], interfaceId: TypeConName,
methods: Iterable[GenTemplateImplementsMethod[E]],
inheritedChoices: Iterable[ChoiceName], inheritedChoices: Iterable[ChoiceName],
): GenTemplateImplements[E] = { ): GenTemplateImplements[E] =
val methodMap = toMapWithoutDuplicate( new GenTemplateImplements[E](
methods, interfaceId = interfaceId,
(methodName: MethodName) => methods = toMapWithoutDuplicate(
throw PackageError(s"repeated method implementation $methodName"), methods.map(m => m.name -> m),
(name: MethodName) => PackageError(s"repeated method implementation $name"),
),
inheritedChoices = toSetWithoutDuplicate(
inheritedChoices,
(name: ChoiceName) => PackageError(s"repeated inherited Choices $name"),
),
) )
new GenTemplateImplements[E](interface, methodMap, inheritedChoices.toSet)
}
def apply( def apply(
interface: TypeConName, interfaceId: TypeConName,
methods: Map[MethodName, GenTemplateImplementsMethod[E]], methods: Map[MethodName, GenTemplateImplementsMethod[E]],
inheritedChoices: Set[ChoiceName], inheritedChoices: Set[ChoiceName],
): GenTemplateImplements[E] = ): GenTemplateImplements[E] =
GenTemplateImplements[E](interface, methods, inheritedChoices) GenTemplateImplements[E](interfaceId, methods, inheritedChoices)
def unapply( def unapply(
arg: GenTemplateImplements[E] arg: GenTemplateImplements[E]
): Some[(TypeConName, Map[MethodName, GenTemplateImplementsMethod[E]], Set[ChoiceName])] = ): Some[(TypeConName, Map[MethodName, GenTemplateImplementsMethod[E]], Set[ChoiceName])] =
Some((arg.interface, arg.methods, arg.inheritedChoices)) Some((arg.interfaceId, arg.methods, arg.inheritedChoices))
} }
type TemplateImplements = GenTemplateImplements[Expr] type TemplateImplements = GenTemplateImplements[Expr]
@ -889,11 +908,8 @@ object Ast {
) )
final class GenTemplateImplementsMethodCompanion[E] { final class GenTemplateImplementsMethodCompanion[E] {
def apply( def apply(methodName: MethodName, value: E): GenTemplateImplementsMethod[E] =
name: MethodName, GenTemplateImplementsMethod[E](methodName, value)
value: E,
): GenTemplateImplementsMethod[E] =
GenTemplateImplementsMethod[E](name, value)
def unapply( def unapply(
arg: GenTemplateImplementsMethod[E] arg: GenTemplateImplementsMethod[E]
@ -911,10 +927,10 @@ object Ast {
final class GenDefExceptionCompanion[E] private[Ast] { final class GenDefExceptionCompanion[E] private[Ast] {
def apply(message: E): GenDefException[E] = def apply(message: E): GenDefException[E] =
GenDefException(message) GenDefException(message = message)
def unapply(arg: GenDefException[E]): Some[E] = def unapply(arg: GenDefException[E]): Some[E] =
Some((arg.message)) Some(arg.message)
} }
type DefException = GenDefException[Expr] type DefException = GenDefException[Expr]
@ -964,53 +980,73 @@ object Ast {
private[this] def toMapWithoutDuplicate[Key, Value]( private[this] def toMapWithoutDuplicate[Key, Value](
xs: Iterable[(Key, Value)], xs: Iterable[(Key, Value)],
error: Key => Nothing, error: Key => PackageError,
): Map[Key, Value] = ): Map[Key, Value] =
xs.foldLeft[Map[Key, Value]](Map.empty[Key, Value]) { case (acc, (key, value)) => xs.foldLeft(Map.empty[Key, Value]) { case (acc, (key, value)) =>
if (acc.contains(key)) { if (acc.contains(key))
error(key) throw error(key)
} else { else
acc.updated(key, value) acc.updated(key, value)
}
} }
final class GenModuleCompanion[E] private[Ast] { private[this] def toSetWithoutDuplicate[X](
xs: Iterable[X],
error: X => PackageError,
): Set[X] =
xs.foldLeft(Set.empty[X])((acc, x) =>
if (acc.contains(x))
throw error(x)
else
acc + x
)
def apply( final class GenModuleCompanion[E] private[Ast] {
@throws[PackageError]
def build(
name: ModuleName, name: ModuleName,
definitions: Iterable[(DottedName, GenDefinition[E])], definitions: Iterable[(DottedName, GenDefinition[E])],
templates: Iterable[(DottedName, GenTemplate[E])], templates: Iterable[(DottedName, GenTemplate[E])],
exceptions: Iterable[(DottedName, GenDefException[E])], exceptions: Iterable[(DottedName, GenDefException[E])],
interfaces: Iterable[(DottedName, GenDefInterface[E])], interfaces: Iterable[(DottedName, GenDefInterface[E])],
featureFlags: FeatureFlags, featureFlags: FeatureFlags,
): GenModule[E] = { ): GenModule[E] =
GenModule(
val definitionMap = name = name,
toMapWithoutDuplicate( definitions = toMapWithoutDuplicate(
definitions, definitions,
(name: DottedName) => throw PackageError(s"Collision on definition name ${name.toString}"), (name: DottedName) => PackageError(s"Collision on definition name ${name.toString}"),
) ),
templates = toMapWithoutDuplicate(
val templateMap =
toMapWithoutDuplicate(
templates, templates,
(name: DottedName) => throw PackageError(s"Collision on template name ${name.toString}"), (name: DottedName) => PackageError(s"Collision on template name ${name.toString}"),
) ),
exceptions = toMapWithoutDuplicate(
val exceptionMap =
toMapWithoutDuplicate(
exceptions, exceptions,
(name: DottedName) => throw PackageError(s"Collision on exception name ${name.toString}"), (name: DottedName) => PackageError(s"Collision on exception name ${name.toString}"),
) ),
interfaces = toMapWithoutDuplicate(
val interfaceMap =
toMapWithoutDuplicate(
interfaces, interfaces,
(name: DottedName) => throw PackageError(s"Collision on interface name ${name.toString}"), (name: DottedName) => PackageError(s"Collision on interface name ${name.toString}"),
) ),
featureFlags = featureFlags,
)
GenModule(name, definitionMap, templateMap, exceptionMap, interfaceMap, featureFlags) def apply(
} name: ModuleName,
definitions: Map[DottedName, GenDefinition[E]],
templates: Map[DottedName, GenTemplate[E]],
exceptions: Map[DottedName, GenDefException[E]],
interfaces: Map[DottedName, GenDefInterface[E]],
featureFlags: FeatureFlags,
) =
GenModule(
name = name,
definitions = definitions,
templates = templates,
exceptions = exceptions,
interfaces = interfaces,
featureFlags = featureFlags,
)
def unapply(arg: GenModule[E]): Some[ def unapply(arg: GenModule[E]): Some[
( (
@ -1042,34 +1078,33 @@ object Ast {
) )
final class GenPackageCompanion[E] private[Ast] { final class GenPackageCompanion[E] private[Ast] {
@throws[PackageError]
def apply( def build(
modules: Iterable[GenModule[E]], modules: Iterable[GenModule[E]],
directDeps: Iterable[PackageId], directDeps: Iterable[PackageId],
languageVersion: LanguageVersion, languageVersion: LanguageVersion,
metadata: Option[PackageMetadata], metadata: Option[PackageMetadata],
): GenPackage[E] = { ): GenPackage[E] =
val modulesWithNames = modules.map(m => m.name -> m) GenPackage(
val moduleMap = modules = toMapWithoutDuplicate(
toMapWithoutDuplicate( modules.view.map(m => m.name -> m),
modulesWithNames, (modName: ModuleName) => PackageError(s"Collision on module name ${modName.toString}"),
(modName: ModuleName) => ),
throw PackageError(s"Collision on module name ${modName.toString}"), directDeps = directDeps.toSet,
) languageVersion = languageVersion,
this(moduleMap, directDeps.toSet, languageVersion, metadata) metadata = metadata,
} )
def apply( def apply(
modules: Map[ModuleName, GenModule[E]], modules: Map[ModuleName, GenModule[E]],
directDeps: Set[PackageId], directDeps: Set[PackageId],
languageVersion: LanguageVersion, languageVersion: LanguageVersion,
metadata: Option[PackageMetadata], metadata: Option[PackageMetadata],
) = ): GenPackage[E] =
GenPackage( GenPackage(
modules: Map[ModuleName, GenModule[E]], modules = modules,
directDeps: Set[PackageId], directDeps = directDeps,
languageVersion: LanguageVersion, languageVersion = languageVersion,
metadata: Option[PackageMetadata], metadata = metadata,
) )
def unapply(arg: GenPackage[E]): Some[ def unapply(arg: GenPackage[E]): Some[
@ -1079,7 +1114,17 @@ object Ast {
LanguageVersion, LanguageVersion,
Option[PackageMetadata], Option[PackageMetadata],
) )
] = Some((arg.modules, arg.directDeps, arg.languageVersion, arg.metadata)) ] = {
Some(
(
arg.modules,
arg.directDeps,
arg.languageVersion,
arg.metadata,
)
)
}
} }
type Package = GenPackage[Expr] type Package = GenPackage[Expr]

View File

@ -18,24 +18,24 @@ class AstSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
private def defaultVersion = LanguageVersion.defaultV1 private def defaultVersion = LanguageVersion.defaultV1
"Package.apply" should { "Package.build" should {
"catch module name collisions" in { "catch module name collisions" in {
Package( Package.build(
List( List(
Module(modName1, List.empty, List.empty, List.empty, List.empty, FeatureFlags.default), Module(modName1, Map.empty, Map.empty, Map.empty, Map.empty, FeatureFlags.default),
Module(modName2, List.empty, List.empty, List.empty, List.empty, FeatureFlags.default), Module(modName2, Map.empty, Map.empty, Map.empty, Map.empty, FeatureFlags.default),
), ),
Set.empty, Set.empty,
defaultVersion, defaultVersion,
None, None,
) )
a[PackageError] shouldBe thrownBy( a[PackageError] shouldBe thrownBy(
Package( Package.build(
List( List(
Module(modName1, List.empty, List.empty, List.empty, List.empty, FeatureFlags.default), Module(modName1, Map.empty, Map.empty, Map.empty, Map.empty, FeatureFlags.default),
Module(modName1, List.empty, List.empty, List.empty, List.empty, FeatureFlags.default), Module(modName1, Map.empty, Map.empty, Map.empty, Map.empty, FeatureFlags.default),
), ),
Set.empty, Set.empty,
defaultVersion, defaultVersion,
@ -47,7 +47,7 @@ class AstSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
} }
"Module.apply" should { "Module.build" should {
val template = Template( val template = Template(
param = Name.assertFromString("x"), param = Name.assertFromString("x"),
@ -57,7 +57,7 @@ class AstSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
choices = Map.empty, choices = Map.empty,
observers = eParties, observers = eParties,
key = None, key = None,
implements = List.empty, implements = Map.empty,
) )
def exception = DefException( def exception = DefException(
message = eText message = eText
@ -70,7 +70,7 @@ class AstSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
"catch definition name collisions" in { "catch definition name collisions" in {
Module.apply( Module.build(
name = modName1, name = modName1,
definitions = List( definitions = List(
defName("def1") -> recordDef, defName("def1") -> recordDef,
@ -85,7 +85,7 @@ class AstSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
) )
a[PackageError] shouldBe thrownBy( a[PackageError] shouldBe thrownBy(
Module.apply( Module.build(
name = modName1, name = modName1,
definitions = List( definitions = List(
defName("def1") -> recordDef, defName("def1") -> recordDef,
@ -104,7 +104,7 @@ class AstSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
"catch template collisions" in { "catch template collisions" in {
Module.apply( Module.build(
name = modName1, name = modName1,
definitions = List( definitions = List(
defName("defName1") -> recordDef, defName("defName1") -> recordDef,
@ -119,7 +119,7 @@ class AstSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
) )
a[PackageError] shouldBe thrownBy( a[PackageError] shouldBe thrownBy(
Module.apply( Module.build(
name = modName1, name = modName1,
definitions = List( definitions = List(
defName("defName1") -> recordDef, defName("defName1") -> recordDef,
@ -137,7 +137,7 @@ class AstSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
} }
"catch exception collisions" in { "catch exception collisions" in {
Module.apply( Module.build(
name = modName1, name = modName1,
definitions = List( definitions = List(
defName("defName1") -> recordDef, defName("defName1") -> recordDef,
@ -152,7 +152,7 @@ class AstSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
) )
a[PackageError] shouldBe thrownBy( a[PackageError] shouldBe thrownBy(
Module.apply( Module.build(
name = modName1, name = modName1,
definitions = List( definitions = List(
defName("defName1") -> recordDef, defName("defName1") -> recordDef,
@ -170,7 +170,7 @@ class AstSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
} }
"catch collisions between exception and template" in { "catch collisions between exception and template" in {
Module.apply( Module.build(
name = modName1, name = modName1,
definitions = List( definitions = List(
defName("defName1") -> recordDef, defName("defName1") -> recordDef,
@ -187,7 +187,7 @@ class AstSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
) )
a[PackageError] shouldBe thrownBy( a[PackageError] shouldBe thrownBy(
Module.apply( Module.build(
name = modName1, name = modName1,
definitions = List( definitions = List(
defName("defName1") -> recordDef, defName("defName1") -> recordDef,
@ -207,14 +207,12 @@ class AstSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
} }
"Template.apply" should { "Template.build" should {
def builder(name: ChoiceName, typ: Type, expr: Expr) = TemplateChoice( def builder(name: ChoiceName, typ: Type, expr: Expr) = TemplateChoice(
name = name, name = name,
consuming = true, consuming = true,
controllers = eParties, controllers = eParties,
// TODO https://github.com/digital-asset/daml/issues/7709
// need test for the Some case
choiceObservers = None, choiceObservers = None,
selfBinder = Name.assertFromString("self"), selfBinder = Name.assertFromString("self"),
argBinder = Name.assertFromString("arg") -> TUnit, argBinder = Name.assertFromString("arg") -> TUnit,
@ -225,17 +223,22 @@ class AstSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
val List(choice1, choice2, choice3) = val List(choice1, choice2, choice3) =
List("choice1", "choice2", "choice3").map(Name.assertFromString) List("choice1", "choice2", "choice3").map(Name.assertFromString)
"catch implements interface repetition " ignore {
// TODO https://github.com/digital-asset/daml/issues/10917
// implement
}
"catch choice name collisions" in { "catch choice name collisions" in {
Template( Template.build(
param = Name.assertFromString("x"), param = Name.assertFromString("x"),
precond = ETrue, precond = ETrue,
signatories = eParties, signatories = eParties,
agreementText = eText, agreementText = eText,
choices = List( choices = List(
choice1 -> builder(choice1, TUnit, EUnit), builder(choice1, TUnit, EUnit),
choice2 -> builder(choice2, TBool, ETrue), builder(choice2, TBool, ETrue),
choice3 -> builder(choice3, TText, eText), builder(choice3, TText, eText),
), ),
observers = eParties, observers = eParties,
key = None, key = None,
@ -243,15 +246,15 @@ class AstSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
) )
a[PackageError] shouldBe thrownBy( a[PackageError] shouldBe thrownBy(
Template( Template.build(
param = Name.assertFromString("x"), param = Name.assertFromString("x"),
precond = ETrue, precond = ETrue,
signatories = eParties, signatories = eParties,
agreementText = eText, agreementText = eText,
choices = List( choices = List(
choice1 -> builder(choice1, TUnit, EUnit), builder(choice1, TUnit, EUnit),
choice2 -> builder(choice2, TBool, ETrue), builder(choice2, TBool, ETrue),
choice1 -> builder(choice1, TText, eText), builder(choice1, TText, eText),
), ),
observers = eParties, observers = eParties,
key = None, key = None,
@ -261,6 +264,17 @@ class AstSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matchers {
} }
} }
"GenDefInterface.build " should {
"catch duplicate choices" ignore {
// TODO https://github.com/digital-asset/daml/issues/10917
// implement
}
"catch duplicate method" ignore {
// TODO https://github.com/digital-asset/daml/issues/10917
// implement
}
}
private val modName1 = DottedName.assertFromString("Mod1") private val modName1 = DottedName.assertFromString("Mod1")
private val modName2 = DottedName.assertFromString("Mod2") private val modName2 = DottedName.assertFromString("Mod2")

View File

@ -4,8 +4,7 @@
package com.daml.lf package com.daml.lf
package testing.parser package testing.parser
import com.daml.lf.data.ImmArray import com.daml.lf.data.{ImmArray, Ref}
import com.daml.lf.data.Ref.{ChoiceName, DottedName, Name}
import com.daml.lf.language.Ast._ import com.daml.lf.language.Ast._
import com.daml.lf.testing.parser.Parsers._ import com.daml.lf.testing.parser.Parsers._
import com.daml.lf.testing.parser.Token._ import com.daml.lf.testing.parser.Token._
@ -19,9 +18,9 @@ private[parser] class ModParser[P](parameters: ParserParameters[P]) {
import exprParser.{expr, expr0} import exprParser.{expr, expr0}
private def split(defs: Seq[Def]) = { private def split(defs: Seq[Def]) = {
val definitions = Seq.newBuilder[(DottedName, Definition)] val definitions = Seq.newBuilder[(Ref.DottedName, Definition)]
val templates = Seq.newBuilder[(DottedName, Template)] val templates = Seq.newBuilder[(Ref.DottedName, Template)]
val exceptions = Seq.newBuilder[(DottedName, DefException)] val exceptions = Seq.newBuilder[(Ref.DottedName, DefException)]
defs.foreach { defs.foreach {
case DataDef(name, defn) => case DataDef(name, defn) =>
definitions += name -> defn definitions += name -> defn
@ -36,7 +35,7 @@ private[parser] class ModParser[P](parameters: ParserParameters[P]) {
lazy val pkg: Parser[Package] = lazy val pkg: Parser[Package] =
opt(metadata) ~ rep(mod) ^^ { case metadata ~ modules => opt(metadata) ~ rep(mod) ^^ { case metadata ~ modules =>
Package(modules, Set.empty, parameters.languageVersion, metadata) Package.build(modules, List.empty, parameters.languageVersion, metadata)
} }
private lazy val metadata: Parser[PackageMetadata] = private lazy val metadata: Parser[PackageMetadata] =
@ -49,13 +48,13 @@ private[parser] class ModParser[P](parameters: ParserParameters[P]) {
case _ ~ modTag ~ modName ~ _ ~ defs => case _ ~ modTag ~ modName ~ _ ~ defs =>
val (definitions, templates, exceptions) = split(defs) val (definitions, templates, exceptions) = split(defs)
val flags = FeatureFlags(forbidPartyLiterals = modTag(noPartyLitsTag)) val flags = FeatureFlags(forbidPartyLiterals = modTag(noPartyLitsTag))
Module(modName, definitions, templates, exceptions, List.empty, flags) Module.build(modName, definitions, templates, exceptions, List.empty, flags)
} }
private lazy val definition: Parser[Def] = private lazy val definition: Parser[Def] =
synDefinition | recDefinition | variantDefinition | enumDefinition | valDefinition | templateDefinition | exceptionDefinition synDefinition | recDefinition | variantDefinition | enumDefinition | valDefinition | templateDefinition | exceptionDefinition
private def tags(allowed: Set[Name]): Parser[Set[Name]] = Parser { in => private def tags(allowed: Set[Ref.Name]): Parser[Set[Ref.Name]] = Parser { in =>
val parser = rep(`@` ~> id) ^^ { tags => val parser = rep(`@` ~> id) ^^ { tags =>
tags.foreach { t => tags.foreach { t =>
if (!allowed(t)) if (!allowed(t))
@ -69,7 +68,7 @@ private[parser] class ModParser[P](parameters: ParserParameters[P]) {
parser(in) parser(in)
} }
private lazy val binder: Parser[(Name, Type)] = private lazy val binder: Parser[(Ref.Name, Type)] =
id ~ `:` ~ typ ^^ { case id ~ _ ~ typ => id -> typ } id ~ `:` ~ typ ^^ { case id ~ _ ~ typ => id -> typ }
private lazy val synDefinition: Parser[DataDef] = private lazy val synDefinition: Parser[DataDef] =
@ -138,7 +137,7 @@ private[parser] class ModParser[P](parameters: ParserParameters[P]) {
key => key =>
TemplDef( TemplDef(
tycon, tycon,
Template(x, precon, signatories, agreement, choices, observers, key, List.empty), Template.build(x, precon, signatories, agreement, choices, observers, key, List.empty),
) )
} }
@ -147,20 +146,20 @@ private[parser] class ModParser[P](parameters: ParserParameters[P]) {
case tycon ~ _ ~ _ ~ message => ExcepDef(tycon, DefException(message)) case tycon ~ _ ~ _ ~ message => ExcepDef(tycon, DefException(message))
} }
private lazy val choiceParam: Parser[(Name, Type)] = private lazy val choiceParam: Parser[(Ref.Name, Type)] =
`(` ~> id ~ `:` ~ typ <~ `)` ^^ { case name ~ _ ~ typ => name -> typ } `(` ~> id ~ `:` ~ typ <~ `)` ^^ { case name ~ _ ~ typ => name -> typ }
private lazy val selfBinder: Parser[Name] = private lazy val selfBinder: Parser[Ref.Name] =
`(` ~> id <~ `)` `(` ~> id <~ `)`
private lazy val templateChoice: Parser[(ChoiceName, TemplateChoice)] = private lazy val templateChoice: Parser[TemplateChoice] =
Id("choice") ~> tags(templateChoiceTags) ~ id ~ selfBinder ~ choiceParam ~ Id("choice") ~> tags(templateChoiceTags) ~ id ~ selfBinder ~ choiceParam ~
(`:` ~> typ) ~ (`:` ~> typ) ~
(`,` ~> Id("controllers") ~> expr) ~ (`,` ~> Id("controllers") ~> expr) ~
opt(`,` ~> Id("observers") ~> expr) ~ opt(`,` ~> Id("observers") ~> expr) ~
(`to` ~> expr) ^^ { (`to` ~> expr) ^^ {
case choiceTags ~ name ~ self ~ param ~ retTyp ~ controllers ~ choiceObservers ~ update => case choiceTags ~ name ~ self ~ param ~ retTyp ~ controllers ~ choiceObservers ~ update =>
name -> TemplateChoice( TemplateChoice(
name, name,
!choiceTags(nonConsumingTag), !choiceTags(nonConsumingTag),
controllers, controllers,
@ -172,10 +171,10 @@ private[parser] class ModParser[P](parameters: ParserParameters[P]) {
) )
} }
private val serializableTag = Name.assertFromString("serializable") private val serializableTag = Ref.Name.assertFromString("serializable")
private val noPartyLitsTag = Name.assertFromString("noPartyLiterals") private val noPartyLitsTag = Ref.Name.assertFromString("noPartyLiterals")
private val isTestTag = Name.assertFromString("isTest") private val isTestTag = Ref.Name.assertFromString("isTest")
private val nonConsumingTag = Name.assertFromString("nonConsuming") private val nonConsumingTag = Ref.Name.assertFromString("nonConsuming")
private val dataDefTags = Set(serializableTag) private val dataDefTags = Set(serializableTag)
private val templateChoiceTags = Set(nonConsumingTag) private val templateChoiceTags = Set(nonConsumingTag)
@ -188,8 +187,8 @@ object ModParser {
private sealed trait Def extends Product with Serializable private sealed trait Def extends Product with Serializable
private final case class DataDef(name: DottedName, defn: Definition) extends Def private final case class DataDef(name: Ref.DottedName, defn: Definition) extends Def
private final case class TemplDef(name: DottedName, defn: Template) extends Def private final case class TemplDef(name: Ref.DottedName, defn: Template) extends Def
private final case class ExcepDef(name: DottedName, defn: DefException) extends Def private final case class ExcepDef(name: Ref.DottedName, defn: DefException) extends Def
} }

View File

@ -475,7 +475,7 @@ class ParsersSpec extends AnyWordSpec with ScalaCheckPropertyChecks with Matcher
parseModules(p) shouldBe Right( parseModules(p) shouldBe Right(
List( List(
Module( Module.build(
name = modName, name = modName,
definitions = List( definitions = List(
DottedName.assertFromSegments(ImmArray("Tree", "Node").toSeq) -> recDef, DottedName.assertFromSegments(ImmArray("Tree", "Node").toSeq) -> recDef,
@ -510,10 +510,10 @@ class ParsersSpec extends AnyWordSpec with ScalaCheckPropertyChecks with Matcher
List( List(
Module( Module(
name = modName, name = modName,
definitions = List(DottedName.assertFromString("fact") -> valDef), definitions = Map(DottedName.assertFromString("fact") -> valDef),
templates = List.empty, templates = Map.empty,
exceptions = List.empty, exceptions = Map.empty,
interfaces = List.empty, interfaces = Map.empty,
featureFlags = FeatureFlags.default, featureFlags = FeatureFlags.default,
) )
) )
@ -553,13 +553,13 @@ class ParsersSpec extends AnyWordSpec with ScalaCheckPropertyChecks with Matcher
""" """
val template = val template =
Template( Template.build(
param = n"this", param = n"this",
precond = e"True", precond = e"True",
signatories = e"Cons @Party [person] (Nil @Party)", signatories = e"Cons @Party [person] (Nil @Party)",
agreementText = e""" "Agreement" """, agreementText = e""" "Agreement" """,
choices = Map( choices = List(
n"Sleep" -> TemplateChoice( TemplateChoice(
name = n"Sleep", name = n"Sleep",
consuming = true, consuming = true,
controllers = e"Cons @Party [person] (Nil @Party)", controllers = e"Cons @Party [person] (Nil @Party)",
@ -569,7 +569,7 @@ class ParsersSpec extends AnyWordSpec with ScalaCheckPropertyChecks with Matcher
returnType = t"ContractId Mod:Person", returnType = t"ContractId Mod:Person",
update = e"upure @(ContractId Mod:Person) self", update = e"upure @(ContractId Mod:Person) self",
), ),
n"Nap" -> TemplateChoice( TemplateChoice(
name = n"Nap", name = n"Nap",
consuming = false, consuming = false,
controllers = e"Cons @Party [person] (Nil @Party)", controllers = e"Cons @Party [person] (Nil @Party)",
@ -579,7 +579,7 @@ class ParsersSpec extends AnyWordSpec with ScalaCheckPropertyChecks with Matcher
returnType = t"Int64", returnType = t"Int64",
update = e"upure @Int64 i", update = e"upure @Int64 i",
), ),
n"PowerNap" -> TemplateChoice( TemplateChoice(
name = n"PowerNap", name = n"PowerNap",
consuming = false, consuming = false,
controllers = e"Cons @Party [person] (Nil @Party)", controllers = e"Cons @Party [person] (Nil @Party)",
@ -605,10 +605,10 @@ class ParsersSpec extends AnyWordSpec with ScalaCheckPropertyChecks with Matcher
List( List(
Module( Module(
name = modName, name = modName,
definitions = List(name -> recDef), definitions = Map(name -> recDef),
templates = List(name -> template), templates = Map(name -> template),
exceptions = List.empty, exceptions = Map.empty,
interfaces = List.empty, interfaces = Map.empty,
featureFlags = FeatureFlags.default, featureFlags = FeatureFlags.default,
) )
) )
@ -635,12 +635,12 @@ class ParsersSpec extends AnyWordSpec with ScalaCheckPropertyChecks with Matcher
""" """
val template = val template =
Template( Template.build(
param = n"this", param = n"this",
precond = e"True", precond = e"True",
signatories = e"Nil @Unit", signatories = e"Nil @Unit",
agreementText = e""" "Agreement" """, agreementText = e""" "Agreement" """,
choices = Map.empty, choices = List.empty,
observers = e"Nil @Unit", observers = e"Nil @Unit",
key = None, key = None,
implements = List.empty, implements = List.empty,
@ -656,10 +656,10 @@ class ParsersSpec extends AnyWordSpec with ScalaCheckPropertyChecks with Matcher
List( List(
Module( Module(
name = modName, name = modName,
definitions = List(name -> recDef), definitions = Map(name -> recDef),
templates = List(name -> template), templates = Map(name -> template),
exceptions = List.empty, exceptions = Map.empty,
interfaces = List.empty, interfaces = Map.empty,
featureFlags = FeatureFlags.default, featureFlags = FeatureFlags.default,
) )
) )
@ -693,10 +693,10 @@ class ParsersSpec extends AnyWordSpec with ScalaCheckPropertyChecks with Matcher
List( List(
Module( Module(
name = modName, name = modName,
definitions = List(name -> recDef), definitions = Map(name -> recDef),
templates = List.empty, templates = Map.empty,
exceptions = List(name -> exception), exceptions = Map(name -> exception),
interfaces = List.empty, interfaces = Map.empty,
featureFlags = FeatureFlags.default, featureFlags = FeatureFlags.default,
) )
) )

View File

@ -474,13 +474,13 @@ private[validation] object Typing {
def checkIfaceImplementation(tplTcon: TypeConName, impl: TemplateImplements): Unit = { def checkIfaceImplementation(tplTcon: TypeConName, impl: TemplateImplements): Unit = {
val DefInterfaceSignature(_, fixedChoices, methods, _) = val DefInterfaceSignature(_, fixedChoices, methods, _) =
handleLookup(ctx, interface.lookupInterface(impl.interface)) handleLookup(ctx, interface.lookupInterface(impl.interfaceId))
val fixedChoiceSet = fixedChoices.keys.toSet val fixedChoiceSet = fixedChoices.keySet
if (impl.inheritedChoices != fixedChoiceSet) { if (impl.inheritedChoices != fixedChoiceSet) {
throw EBadInheritedChoices( throw EBadInheritedChoices(
ctx, ctx,
impl.interface, impl.interfaceId,
tplTcon, tplTcon,
fixedChoiceSet, fixedChoiceSet,
impl.inheritedChoices, impl.inheritedChoices,
@ -489,12 +489,12 @@ private[validation] object Typing {
methods.values.foreach { (method: InterfaceMethod) => methods.values.foreach { (method: InterfaceMethod) =>
if (!impl.methods.contains(method.name)) if (!impl.methods.contains(method.name))
throw EMissingInterfaceMethod(ctx, tplTcon, impl.interface, method.name) throw EMissingInterfaceMethod(ctx, tplTcon, impl.interfaceId, method.name)
} }
impl.methods.values.foreach { (tplMethod: TemplateImplementsMethod) => impl.methods.values.foreach { (tplMethod: TemplateImplementsMethod) =>
methods.get(tplMethod.name) match { methods.get(tplMethod.name) match {
case None => case None =>
throw EUnknownInterfaceMethod(ctx, tplTcon, impl.interface, tplMethod.name) throw EUnknownInterfaceMethod(ctx, tplTcon, impl.interfaceId, tplMethod.name)
case Some(method) => case Some(method) =>
checkExpr(tplMethod.value, TFun(TTyCon(tplTcon), method.returnType)) checkExpr(tplMethod.value, TFun(TTyCon(tplTcon), method.returnType))
} }
@ -502,8 +502,7 @@ private[validation] object Typing {
} }
def checkDefException(excepName: TypeConName, defException: DefException): Unit = { def checkDefException(excepName: TypeConName, defException: DefException): Unit = {
val DefException(message) = defException checkExpr(defException.message, TTyCon(excepName) ->: TText)
checkExpr(message, TTyCon(excepName) ->: TText)
() ()
} }

View File

@ -187,10 +187,7 @@ private[validation] object ExprIterable {
private[iterable] def iterator(x: TemplateImplementsMethod): Iterator[Expr] = private[iterable] def iterator(x: TemplateImplementsMethod): Iterator[Expr] =
x match { x match {
case TemplateImplementsMethod( case TemplateImplementsMethod(name @ _, value) =>
name @ _,
value,
) =>
Iterator(value) Iterator(value)
} }

View File

@ -31,7 +31,7 @@ class DependencyVersionSpec extends AnyWordSpec with TableDrivenPropertyChecks w
) = { ) = {
val (pkgId, modName) = ref val (pkgId, modName) = ref
val mod = Module( val mod = Module.build(
name = modName, name = modName,
definitions = (u -> DValue(TUnit, true, EUnit, false)) +: definitions = (u -> DValue(TUnit, true, EUnit, false)) +:
depRefs.map { case (depPkgId, depModName) => depRefs.map { case (depPkgId, depModName) =>

View File

@ -1221,7 +1221,7 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
"reject ill formed type record definitions" in { "reject ill formed type record definitions" in {
def checkModule(mod: Module) = { def checkModule(mod: Module) = {
val pkg = Package.apply(List(mod), List.empty, defaultLanguageVersion, None) val pkg = Package.build(List(mod), List.empty, defaultLanguageVersion, None)
Typing.checkModule(PackageInterface(Map(defaultPackageId -> pkg)), defaultPackageId, mod) Typing.checkModule(PackageInterface(Map(defaultPackageId -> pkg)), defaultPackageId, mod)
} }
@ -1244,7 +1244,7 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
"reject ill formed type variant definitions" in { "reject ill formed type variant definitions" in {
def checkModule(mod: Module) = { def checkModule(mod: Module) = {
val pkg = Package.apply(List(mod), List.empty, defaultLanguageVersion, None) val pkg = Package.build(List(mod), List.empty, defaultLanguageVersion, None)
Typing.checkModule(PackageInterface(Map(defaultPackageId -> pkg)), defaultPackageId, mod) Typing.checkModule(PackageInterface(Map(defaultPackageId -> pkg)), defaultPackageId, mod)
} }
@ -1267,7 +1267,7 @@ class TypingSpec extends AnyWordSpec with TableDrivenPropertyChecks with Matcher
"reject ill formed type synonym definitions" in { "reject ill formed type synonym definitions" in {
def checkModule(mod: Module) = { def checkModule(mod: Module) = {
val pkg = Package.apply(List(mod), List.empty, defaultLanguageVersion, None) val pkg = Package.build(List(mod), List.empty, defaultLanguageVersion, None)
Typing.checkModule(PackageInterface(Map(defaultPackageId -> pkg)), defaultPackageId, mod) Typing.checkModule(PackageInterface(Map(defaultPackageId -> pkg)), defaultPackageId, mod)
} }