Port //daml-lf/(parser|validation) to Scala 2.13 (#8391)

* Port //daml-lf/(parser|validation) to Scala 2.13

changelog_begin
changelog_end

* Rename (Expr|Type)Traversable to (Expr|Type)Iterable

changelog_begin
changelog_end
This commit is contained in:
Moritz Kiefer 2021-01-05 13:11:27 +01:00 committed by GitHub
parent c1ff0d5d0d
commit 02d8e8fe95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 356 additions and 379 deletions

View File

@ -164,9 +164,9 @@ jobs:
- bash: |
set -euo pipefail
eval "$(./dev-env/bin/dade-assist)"
bazel build --config scala_2_13 //libs-scala/... //daml-lf/data/... //daml-lf/language/... //daml-lf/transaction/...
bazel build --config scala_2_13 //libs-scala/... //daml-lf/data/... //daml-lf/language/... //daml-lf/transaction/... //daml-lf/validation/... //daml-lf/parser/...
# gatling-utils tests fail with a ClassNotFoundException for scala.collection.SeqLike
bazel test --config scala_2_13 -- //libs-scala/... //daml-lf/data/... //daml-lf/language/... //daml-lf/transaction/... -//libs-scala/gatling-utils/...
bazel test --config scala_2_13 -- //libs-scala/... //daml-lf/data/... //daml-lf/language/... //daml-lf/transaction/... //daml-lf/validation/... //daml-lf/parser/... -//libs-scala/gatling-utils/...
displayName: 'Build'
- template: tell-slack-failed.yml
parameters:

View File

@ -6,12 +6,20 @@ load(
"da_scala_library",
"da_scala_test",
"lf_scalacopts",
"silencer_plugin",
)
da_scala_library(
name = "parser",
srcs = glob(["src/main/**/*.scala"]),
scalacopts = lf_scalacopts,
plugins = [silencer_plugin],
scala_deps = [
"@maven//:org_scala_lang_modules_scala_parser_combinators",
"@maven//:org_scalaz_scalaz_core",
],
scalacopts = lf_scalacopts + [
"-P:silencer:lineContentFilters=standardInterpolator",
],
visibility = [
"//daml-lf:__subpackages__",
"//ledger:__subpackages__",
@ -19,8 +27,6 @@ da_scala_library(
deps = [
"//daml-lf/data",
"//daml-lf/language",
"@maven//:org_scala_lang_modules_scala_parser_combinators_2_12",
"@maven//:org_scalaz_scalaz_core_2_12",
],
)
@ -28,6 +34,10 @@ da_scala_test(
name = "parser-test",
size = "small",
srcs = glob(["src/test/**/*.scala"]),
scala_deps = [
"@maven//:org_scalacheck_scalacheck",
"@maven//:org_scalatestplus_scalacheck_1_14",
],
scalacopts = lf_scalacopts,
visibility = [
"//daml-lf:__subpackages__",
@ -36,7 +46,5 @@ da_scala_test(
":parser",
"//daml-lf/data",
"//daml-lf/language",
"@maven//:org_scalacheck_scalacheck_2_12",
"@maven//:org_scalatestplus_scalacheck_1_14_2_12",
],
)

View File

@ -44,7 +44,7 @@ private[parser] class ExprParser[P](parserParameters: ParserParameters[P]) {
(id ^? builtinFunctions) ^^ EBuiltin |
caseOf |
id ^^ EVar |
`(` ~> expr <~ `)`
(`(` ~> expr <~ `)`)
lazy val exprs: Parser[List[Expr]] = rep(expr0)
@ -62,7 +62,7 @@ private[parser] class ExprParser[P](parserParameters: ParserParameters[P]) {
private lazy val primCon =
Id("True") ^^^ PCTrue |
Id("False") ^^^ PCFalse |
`(` ~ `)` ^^^ PCUnit
(`(` ~ `)` ^^^ PCUnit)
private lazy val eAppAgr: Parser[EAppAgr] =
argTyp ^^ EAppTypArg |
@ -204,10 +204,10 @@ private[parser] class ExprParser[P](parserParameters: ParserParameters[P]) {
private lazy val pattern: Parser[CasePat] =
primCon ^^ CPPrimCon |
`nil` ^^^ CPNil |
`cons` ~>! id ~ id ^^ { case x1 ~ x2 => CPCons(x1, x2) } |
`none` ^^^ CPNone |
`some` ~>! id ^^ CPSome |
(`nil` ^^^ CPNil) |
(`cons` ~>! id ~ id ^^ { case x1 ~ x2 => CPCons(x1, x2) }) |
(`none` ^^^ CPNone) |
(`some` ~>! id ^^ CPSome) |
(fullIdentifier <~ `:`) ~ id ~ opt(id) ^^ {
case tyCon ~ vName ~ Some(x) =>
CPVariant(tyCon, vName, x)

View File

@ -12,7 +12,7 @@ private[daml] object KindParser {
lazy val kind0: Parser[Kind] =
`*` ^^ (_ => KStar) |
Id("nat") ^^ (_ => KNat) |
`(` ~> kind <~ `)`
(`(` ~> kind <~ `)`)
lazy val kind: Parser[Kind] = rep1sep(kind0, `->`) ^^ (_.reduceRight(KArrow))

View File

@ -67,7 +67,7 @@ private[parser] object Lexer extends RegexParsers {
"=" ^^^ `=` |
"_" ^^^ Token.`_` |
"|" ^^^ `|` |
"""[a-zA-Z\$_][\w\$]*""".r ^^ (s => keywords.getOrElse(s, Id(s))) |
"""[a-zA-Z_\$][\w\$]*""".r ^^ (s => keywords.getOrElse(s, Id(s))) |
"""#\w+""".r ^^ ContractId |
"""\'([^\\\']|\\\'|\\\\)+\'""".r >> toSimpleString |
"""\"([^\\\"]|\\n|\\r|\\\"|\\\'|\\\\)*\"""".r >> toText |
@ -107,18 +107,18 @@ private[parser] object Lexer extends RegexParsers {
private def toNumber(s: String): Parser[Number] =
(in: Input) =>
Try(Success(Number(s.toLong), in))
.getOrElse(Error(s"cannot interpret $s as a Number", in))
.getOrElse[ParseResult[Number]](Error(s"cannot interpret $s as a Number", in))
@SuppressWarnings(Array("org.wartremover.warts.Product", "org.wartremover.warts.Serializable"))
private def toText(s: String): Parser[Text] =
(in: Input) =>
Try(Success(Text(StringContext.treatEscapes(s.drop(1).dropRight(1))), in))
.getOrElse(Error(s"cannot interpret $s as a Text", in))
Try(Success(Text(StringContext.processEscapes(s.drop(1).dropRight(1))), in))
.getOrElse[ParseResult[Text]](Error(s"cannot interpret $s as a Text", in))
@SuppressWarnings(Array("org.wartremover.warts.Product", "org.wartremover.warts.Serializable"))
private def toSimpleString(s: String): Parser[SimpleString] =
(in: Input) =>
Try(Success(SimpleString(StringContext.treatEscapes(s.drop(1).dropRight(1))), in))
.getOrElse(Error(s"cannot interpret $s as a SimpleText", in))
Try(Success(SimpleString(StringContext.processEscapes(s.drop(1).dropRight(1))), in))
.getOrElse[ParseResult[SimpleString]](Error(s"cannot interpret $s as a SimpleText", in))
}

View File

@ -119,14 +119,14 @@ private[parser] class ModParser[P](parameters: ParserParameters[P]) {
}
private lazy val templateDefinition: Parser[TemplDef] =
Id("template") ~ `(` ~> id ~ `:` ~ dottedName ~ `)` ~ `=` ~ `{` ~
(Id("template") ~ `(` ~> id ~ `:` ~ dottedName ~ `)` ~ `=` ~ `{` ~
(Id("precondition") ~> expr) ~
(`,` ~> Id("signatories") ~> expr) ~
(`,` ~> Id("observers") ~> expr) ~
(`,` ~> Id("agreement") ~> expr) ~
(`,` ~> Id("choices") ~ `{` ~> repsep(templateChoice, `,`) <~ `}`) ~
opt(`,` ~> Id("key") ~> templateKey) <~
`}` ^^ {
`}`) ^^ {
case x ~ _ ~ tycon ~ _ ~ _ ~ _ ~
precon ~
signatories ~

View File

@ -6,11 +6,16 @@ load(
"da_scala_library",
"da_scala_test",
"lf_scalacopts",
"silencer_plugin",
)
da_scala_library(
name = "validation",
srcs = glob(["src/main/**/*.scala"]),
scala_deps = [
"@maven//:org_scalaz_scalaz_core",
"@maven//:org_scala_lang_modules_scala_collection_compat",
],
scalacopts = lf_scalacopts,
tags = ["maven_coordinates=com.daml:daml-lf-validation:__VERSION__"],
visibility = [
@ -20,7 +25,6 @@ da_scala_library(
deps = [
"//daml-lf/data",
"//daml-lf/language",
"@maven//:org_scalaz_scalaz_core_2_12",
],
)
@ -28,12 +32,19 @@ da_scala_test(
name = "validation-test",
size = "small",
srcs = glob(["src/test/**/*.scala"]),
scalacopts = lf_scalacopts,
plugins = [silencer_plugin],
scalacopts = lf_scalacopts + [
"-P:silencer:lineContentFilters=standardInterpolator",
],
versioned_scala_deps = {
"2.12": [
"@maven//:org_scalaz_scalaz_core",
],
},
deps = [
":validation",
"//daml-lf/data",
"//daml-lf/language",
"//daml-lf/parser",
"@maven//:org_scalaz_scalaz_core_2_12",
],
)

View File

@ -35,8 +35,8 @@ private[validation] object Collision {
} throw ECollision(pkgId, entity1, entity2)
private def namedEntitiesFromPkg(
modules: Traversable[(ModuleName, Ast.Module)]
): Traversable[NamedEntity] =
modules: Iterable[(ModuleName, Ast.Module)]
): Iterable[NamedEntity] =
modules.flatMap {
case (modName, module) =>
val namedModule = NModDef(modName, module.definitions.toList)

View File

@ -5,7 +5,7 @@ package com.daml.lf.validation
import com.daml.lf.data.Ref.PackageId
import com.daml.lf.language.Ast._
import com.daml.lf.validation.traversable.ExprTraversable
import com.daml.lf.validation.iterable.ExprIterable
private[validation] object PartyLiterals {
@ -23,7 +23,7 @@ private[validation] object PartyLiterals {
module.templates.foreach {
case (defName, template) =>
def context = ContextDefValue(pkgId, module.name, defName)
ExprTraversable(template).foreach(checkExpr(world, context, _))
ExprIterable(template).foreach(checkExpr(world, context, _))
}
}
@ -34,7 +34,7 @@ private[validation] object PartyLiterals {
case EVal(valRef) if !world.lookupValue(context, valRef).noPartyLiterals =>
throw EForbiddenPartyLiterals(context, ValRefWithPartyLiterals(valRef))
case otherwise =>
ExprTraversable(otherwise).foreach(checkExpr(world, context, _))
ExprIterable(otherwise).foreach(checkExpr(world, context, _))
}
}

View File

@ -6,7 +6,7 @@ package com.daml.lf.validation
import com.daml.lf.data.Ref._
import com.daml.lf.language.Ast._
import com.daml.lf.language.Graphs
import com.daml.lf.validation.traversable.{ExprTraversable, TypeTraversable}
import com.daml.lf.validation.iterable.{ExprIterable, TypeIterable}
private[validation] object Recursion {
@ -29,14 +29,14 @@ private[validation] object Recursion {
def modRefsInType(acc: Set[ModuleName], typ0: Type): Set[ModuleName] = typ0 match {
case TSynApp(typeSynName, _) if typeSynName.packageId == pkgId =>
(TypeTraversable(typ0) foldLeft (acc + typeSynName.qualifiedName.module))(modRefsInType)
(TypeIterable(typ0) foldLeft (acc + typeSynName.qualifiedName.module))(modRefsInType)
case TTyCon(typeConName) if typeConName.packageId == pkgId =>
acc + typeConName.qualifiedName.module
case otherwise =>
(TypeTraversable(otherwise) foldLeft acc)(modRefsInType)
(TypeIterable(otherwise) foldLeft acc)(modRefsInType)
}
(TypeTraversable(module) foldLeft Set.empty[ModuleName])(modRefsInType)
(TypeIterable(module) foldLeft Set.empty[ModuleName])(modRefsInType)
}
val modRefsInExprs: Set[ModuleName] = {
@ -46,12 +46,12 @@ private[validation] object Recursion {
acc + valRef.qualifiedName.module
case EAbs(binder @ _, body, ref) =>
ref.iterator.toSet.filter(_.packageId == pkgId).map(_.qualifiedName.module) |
(ExprTraversable(body) foldLeft acc)(modRefsInVal)
(ExprIterable(body) foldLeft acc)(modRefsInVal)
case otherwise =>
(ExprTraversable(otherwise) foldLeft acc)(modRefsInVal)
(ExprIterable(otherwise) foldLeft acc)(modRefsInVal)
}
(ExprTraversable(module) foldLeft Set.empty[ModuleName])(modRefsInVal)
(ExprIterable(module) foldLeft Set.empty[ModuleName])(modRefsInVal)
}
@ -73,9 +73,9 @@ private[validation] object Recursion {
private def synRefsOfType(acc: Set[TypeSynName], typ: Type): Set[TypeSynName] = typ match {
case TSynApp(typeSynName, _) =>
(TypeTraversable(typ) foldLeft (acc + typeSynName))(synRefsOfType)
(TypeIterable(typ) foldLeft (acc + typeSynName))(synRefsOfType)
case otherwise =>
(TypeTraversable(otherwise) foldLeft acc)(synRefsOfType)
(TypeIterable(otherwise) foldLeft acc)(synRefsOfType)
}
}

View File

@ -6,7 +6,8 @@ package com.daml.lf.validation
import com.daml.lf.data.Ref.Name
import com.daml.lf.language.Ast._
import com.daml.lf.validation.Util._
import com.daml.lf.validation.traversable.TypeTraversable
import com.daml.lf.validation.iterable.TypeIterable
import scala.collection.compat.immutable.LazyList
private[validation] object TypeSubst {
@ -32,7 +33,7 @@ private[validation] object TypeSubst {
}
private def freshTypeVarName(fv: Set[TypeVarName]): TypeVarName =
Stream
LazyList
.from(0)
.map(i => Name.assertFromString("$freshVar" + i.toString))
.filterNot(fv.contains)(0)
@ -58,7 +59,7 @@ private[validation] object TypeSubst {
case TVar(name) =>
acc + name
case otherwise @ _ =>
(TypeTraversable(typ) foldLeft acc)(freeVars)
(TypeIterable(typ) foldLeft acc)(freeVars)
}
private def freeVars(subst: Map[TypeVarName, Type]): Set[TypeVarName] =

View File

@ -10,7 +10,7 @@ import com.daml.lf.language.Util._
import com.daml.lf.language.LanguageVersion
import com.daml.lf.validation.AlphaEquiv._
import com.daml.lf.validation.Util._
import com.daml.lf.validation.traversable.TypeTraversable
import com.daml.lf.validation.iterable.TypeIterable
import scala.annotation.tailrec
@ -930,7 +930,7 @@ private[validation] object Typing {
case TVar(_) | TForall(_, _) | TSynApp(_, _) =>
throw EExpectedAnyType(ctx, typ)
case _ =>
TypeTraversable(typ).foreach(checkAnyType_)
TypeIterable(typ).foreach(checkAnyType_)
}
}

View File

@ -2,152 +2,134 @@
// SPDX-License-Identifier: Apache-2.0
package com.daml.lf.validation
package traversable
package iterable
import com.daml.lf.language.Ast._
import com.daml.lf.validation.Util._
private[validation] object ExprTraversable {
private[validation] object ExprIterable {
that =>
private[traversable] def foreach[U](x: Expr, f: Expr => U): Unit = {
private[iterable] def iterator(x: Expr): Iterator[Expr] = {
x match {
case EVar(_) | EBuiltin(_) | EPrimCon(_) | EPrimLit(_) | EVal(_) | EEnumCon(_, _) | ETypeRep(
_) =>
Iterator.empty
case ELocation(_, expr) =>
f(expr)
Iterator(expr)
case ERecCon(tycon @ _, fields) =>
fields.values.foreach(f)
fields.values
case ERecProj(tycon @ _, field @ _, record) =>
f(record)
Iterator(record)
case ERecUpd(tycon @ _, field @ _, record, update) =>
f(record)
f(update)
Iterator(record, update)
case EVariantCon(tycon @ _, variant @ _, arg) =>
f(arg)
Iterator(arg)
case EStructCon(fields) =>
fields.values.foreach(f)
fields.values
case EStructProj(field @ _, struct) =>
f(struct)
Iterator(struct)
case EStructUpd(field @ _, struct, update) =>
f(struct)
f(update)
Iterator(struct, update)
case EApp(fun, arg) =>
f(fun)
f(arg)
Iterator(fun, arg)
case ETyApp(expr, typ @ _) =>
f(expr)
Iterator(expr)
case EAbs(binder @ _, body, ref @ _) =>
f(body)
Iterator(body)
case ETyAbs(binder @ _, body) =>
f(body)
Iterator(body)
case ECase(scrut, alts) =>
f(scrut)
alts.iterator.foreach(a => f(a.expr))
Iterator(scrut) ++ alts.iterator.map(_.expr)
case ELet(binding, body) =>
f(binding.bound)
f(body)
case ENil(_) =>
Iterator(binding.bound, body)
case ENil(_) => Iterator.empty
case ECons(typ @ _, front, tail) =>
front.iterator.foreach(f)
f(tail)
front.iterator ++ Iterator(tail)
case EUpdate(update) =>
foreach(update, f)
iterator(update)
case EScenario(scenario) =>
foreach(scenario, f)
case ENone(typ @ _) =>
iterator(scenario)
case ENone(typ @ _) => Iterator.empty
case ESome(typ @ _, body) =>
f(body)
Iterator(body)
case EToAny(ty @ _, body) =>
f(body)
Iterator(body)
case EFromAny(ty @ _, body) =>
f(body)
Iterator(body)
case EThrow(returnType @ _, exceptionType @ _, exception) =>
f(exception)
Iterator(exception)
case EToAnyException(typ @ _, value) =>
f(value)
Iterator(value)
case EFromAnyException(typ @ _, value) =>
f(value)
Iterator(value)
}
()
}
private[traversable] def foreach[U](x: Update, f: Expr => U): Unit = {
private[iterable] def iterator(x: Update): Iterator[Expr] = {
x match {
case UpdatePure(typ @ _, expr) =>
f(expr)
Iterator(expr)
case UpdateBlock(bindings, body) =>
bindings.iterator.foreach(b => f(b.bound))
f(body)
bindings.iterator.map(_.bound) ++ Iterator(body)
case UpdateCreate(templateId @ _, arg) =>
f(arg)
Iterator(arg)
case UpdateFetch(templateId @ _, contractId) =>
f(contractId)
Iterator(contractId)
case UpdateExercise(templateId @ _, choice @ _, cid, arg) =>
f(cid)
f(arg)
Iterator(cid, arg)
case UpdateExerciseByKey(templateId @ _, choice @ _, key, arg) =>
f(key)
f(arg)
case UpdateGetTime =>
Iterator(key, arg)
case UpdateGetTime => Iterator.empty
case UpdateFetchByKey(rbk) =>
f(rbk.key)
Iterator(rbk.key)
case UpdateLookupByKey(rbk) =>
f(rbk.key)
Iterator(rbk.key)
case UpdateEmbedExpr(typ @ _, body) =>
f(body)
Iterator(body)
case UpdateTryCatch(typ @ _, body, binder @ _, handler) =>
f(body)
f(handler)
Iterator(body, handler)
}
()
}
private[traversable] def foreach[U](x: Scenario, f: Expr => U): Unit = {
private[iterable] def iterator(x: Scenario): Iterator[Expr] = {
x match {
case ScenarioPure(typ @ _, expr) =>
f(expr)
Iterator(expr)
case ScenarioBlock(bindings, body) =>
bindings.iterator.foreach(b => f(b.bound))
f(body)
bindings.iterator.map(_.bound) ++ Iterator(body)
case ScenarioCommit(party, update, retType @ _) =>
f(party)
f(update)
Iterator(party, update)
case ScenarioMustFailAt(party, update, retType @ _) =>
f(party)
f(update)
Iterator(party, update)
case ScenarioPass(relTime) =>
f(relTime)
case ScenarioGetTime =>
Iterator(relTime)
case ScenarioGetTime => Iterator.empty
case ScenarioGetParty(name) =>
f(name)
Iterator(name)
case ScenarioEmbedExpr(typ @ _, body) =>
f(body)
Iterator(body)
}
()
}
private[traversable] def foreach[U](x: Definition, f: Expr => U): Unit =
private[iterable] def iterator(x: Definition): Iterator[Expr] =
x match {
case DTypeSyn(params @ _, typ @ _) =>
case DDataType(serializable @ _, params @ _, dataCons @ _) =>
case DTypeSyn(params @ _, typ @ _) => Iterator.empty
case DDataType(serializable @ _, params @ _, dataCons @ _) => Iterator.empty
case DValue(typ @ _, noPartyLiterals @ _, body, isTest @ _) =>
f(body)
()
Iterator(body)
}
private[traversable] def foreach[U](x: Template, f: Expr => U): Unit =
private[iterable] def iterator(x: Template): Iterator[Expr] =
x match {
case Template(param @ _, precond, signatories, agreementText, choices, observers, key) =>
f(precond)
f(signatories)
f(agreementText)
choices.values.foreach(foreach(_, f))
f(observers)
key.foreach(foreach(_, f))
Iterator(precond, signatories, agreementText) ++
choices.values.iterator.flatMap(iterator(_)) ++
Iterator(observers) ++
key.iterator.flatMap(iterator(_))
}
private[traversable] def foreach[U](x: TemplateChoice, f: Expr => U): Unit =
private[iterable] def iterator(x: TemplateChoice): Iterator[Expr] =
x match {
case TemplateChoice(
name @ _,
@ -158,36 +140,31 @@ private[validation] object ExprTraversable {
binder @ _,
returnType @ _,
update) =>
f(controllers)
observers.map(f)
f(update)
()
Iterator(controllers) ++
observers.iterator ++
Iterator(update)
}
private[traversable] def foreach[U](x: TemplateKey, f: Expr => U): Unit =
private[iterable] def iterator(x: TemplateKey): Iterator[Expr] =
x match {
case TemplateKey(typ @ _, body, maintainers) =>
f(body)
f(maintainers)
()
Iterator(body, maintainers)
}
def apply(expr: Expr): Traversable[Expr] =
new Traversable[Expr] {
def foreach[U](f: Expr => U): Unit = that.foreach(expr, f)
def apply(expr: Expr): Iterable[Expr] =
new Iterable[Expr] {
override def iterator: Iterator[Expr] = ExprIterable.iterator(expr)
}
def apply(template: Template): Traversable[Expr] =
new Traversable[Expr] {
def foreach[U](f: Expr => U): Unit = that.foreach(template, f)
def apply(template: Template): Iterable[Expr] =
new Iterable[Expr] {
override def iterator: Iterator[Expr] = ExprIterable.iterator(template)
}
def apply(module: Module): Traversable[Expr] =
new Traversable[Expr] {
def foreach[U](f: Expr => U): Unit = {
module.definitions.values.foreach(that.foreach(_, f))
module.templates.values.foreach(that.foreach(_, f))
}
def apply(module: Module): Iterable[Expr] =
new Iterable[Expr] {
override def iterator: Iterator[Expr] =
module.definitions.values.iterator.flatMap(ExprIterable.iterator(_)) ++
module.templates.values.iterator.flatMap(ExprIterable.iterator(_))
}
}

View File

@ -0,0 +1,215 @@
// 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
package iterable
import com.daml.lf.language.Ast._
import com.daml.lf.validation.Util._
private[validation] object TypeIterable {
that =>
private def toType(tyCon: TypeConApp): Type =
(tyCon.args.iterator foldLeft (TTyCon(tyCon.tycon): Type))(TApp)
private[validation] def iterator(typ: Type): Iterator[Type] =
typ match {
case TSynApp(_, args) =>
args.iterator
case TVar(_) | TTyCon(_) | TBuiltin(_) | TNat(_) =>
Iterator.empty
case TApp(tyfun, arg) =>
Iterator(tyfun, arg)
case TForall(binder @ _, body) =>
Iterator(body)
case TStruct(fields) =>
fields.values
}
private[validation] def iterator(expr0: Expr): Iterator[Type] = {
expr0 match {
case ERecCon(tycon, fields @ _) =>
Iterator(toType(tycon)) ++
fields.values.flatMap(iterator(_))
case ERecProj(tycon, field @ _, record) =>
Iterator(toType(tycon)) ++
iterator(record)
case ERecUpd(tycon, field @ _, record, update) =>
Iterator(toType(tycon)) ++
iterator(record) ++ iterator(update)
case EVariantCon(tycon, variant @ _, arg) =>
Iterator(toType(tycon)) ++
iterator(arg)
case ETyApp(expr, typ) =>
iterator(expr) ++ Iterator(typ)
case EAbs((boundVarName @ _, boundVarType), body, ref @ _) =>
Iterator(boundVarType) ++ iterator(body)
case ELet(binding, body) =>
iterator(binding) ++ iterator(body)
case EEnumCon(tyConName, _) =>
Iterator(TTyCon(tyConName))
case EToAny(typ, expr) =>
Iterator(typ) ++ iterator(expr)
case EFromAny(typ, expr) =>
Iterator(typ) ++ iterator(expr)
case ETypeRep(tyCon) =>
Iterator(tyCon)
case ENil(typ) =>
Iterator(typ)
case ECons(typ, front, tail) =>
Iterator(typ) ++
front.iterator.flatMap(iterator(_)) ++
iterator(tail)
case ENone(typ) =>
Iterator(typ)
case ESome(typ, body) =>
Iterator(typ) ++ iterator(body)
case EUpdate(u) =>
iterator(u)
case EScenario(s) =>
iterator(s)
case EThrow(returnType, exceptionType, exception) =>
Iterator(returnType, exceptionType) ++
iterator(exception)
case EToAnyException(typ, value) =>
Iterator(typ) ++
iterator(value)
case EFromAnyException(typ, value) =>
Iterator(typ) ++
iterator(value)
case EVar(_) | EVal(_) | EBuiltin(_) | EPrimCon(_) | EPrimLit(_) | EApp(_, _) | ECase(_, _) |
ELocation(_, _) | EStructCon(_) | EStructProj(_, _) | EStructUpd(_, _, _) |
ETyAbs(_, _) =>
ExprIterable.iterator(expr0).flatMap(iterator(_))
}
}
private[validation] def iterator(update: Update): Iterator[Type] =
update match {
case UpdatePure(typ, expr) =>
Iterator(typ) ++ iterator(expr)
case UpdateBlock(bindings, body) =>
bindings.iterator.flatMap(iterator(_)) ++
iterator(body)
case UpdateCreate(templateId, arg) =>
Iterator(TTyCon(templateId)) ++
iterator(arg)
case UpdateFetch(templateId, contractId) =>
Iterator(TTyCon(templateId)) ++
iterator(contractId)
case UpdateExercise(templateId, choice @ _, cid, arg) =>
Iterator(TTyCon(templateId)) ++
iterator(cid) ++
iterator(arg)
case UpdateExerciseByKey(templateId, choice @ _, key, arg) =>
Iterator(TTyCon(templateId)) ++
iterator(key) ++
iterator(arg)
case UpdateEmbedExpr(typ, body) =>
Iterator(typ) ++
iterator(body)
case UpdateGetTime | UpdateFetchByKey(_) | UpdateLookupByKey(_) =>
ExprIterable.iterator(update).flatMap(iterator(_))
case UpdateTryCatch(typ, body, binder @ _, handler) =>
Iterator(typ) ++
iterator(body) ++
iterator(handler)
}
private[validation] def iterator(binding: Binding): Iterator[Type] =
binding match {
case Binding(binder @ _, typ, bound) =>
Iterator(typ) ++ iterator(bound)
}
private[validation] def iterator(scenario: Scenario): Iterator[Type] =
scenario match {
case ScenarioPure(typ, expr) =>
Iterator(typ) ++ iterator(expr)
case ScenarioBlock(bindings, body) =>
bindings.iterator.flatMap(iterator(_)) ++
iterator(body)
case ScenarioCommit(party, update, retType) =>
iterator(party) ++
iterator(update) ++
Iterator(retType)
case ScenarioMustFailAt(party, update, retType) =>
iterator(party) ++
iterator(update) ++
Iterator(retType)
case ScenarioEmbedExpr(typ, body) =>
Iterator(typ) ++
iterator(body)
case ScenarioGetTime | ScenarioPass(_) | ScenarioGetParty(_) =>
ExprIterable.iterator(scenario).flatMap(iterator(_))
}
private[validation] def iterator(defn: Definition): Iterator[Type] =
defn match {
case DTypeSyn(params @ _, typ) =>
Iterator(typ)
case DDataType(serializable @ _, params @ _, DataRecord(fields)) =>
fields.values
case DDataType(serializable @ _, params @ _, DataVariant(variants)) =>
variants.values
case DDataType(serializable @ _, params @ _, DataEnum(values @ _)) =>
Iterator.empty
case DValue(typ, noPartyLiterals @ _, body, isTest @ _) =>
Iterator(typ) ++ iterator(body)
}
private[validation] def iterator(x: Template): Iterator[Type] =
x match {
case Template(param @ _, precond, signatories, agreementText, choices, observers, key) =>
iterator(precond) ++
iterator(signatories) ++
iterator(agreementText) ++
choices.values.flatMap(iterator(_)) ++
iterator(observers) ++
key.iterator.flatMap(iterator(_))
}
private[validation] def iterator(choice: TemplateChoice): Iterator[Type] =
choice match {
case TemplateChoice(
name @ _,
consuming @ _,
controllers,
observers,
selfBinder @ _,
(boundedVarName @ _, boundedVarType),
retType,
update) =>
iterator(controllers) ++
observers.iterator.flatMap(iterator(_)) ++
iterator(update) ++
Iterator(boundedVarType) ++
Iterator(retType)
}
private[validation] def iterator(key: TemplateKey): Iterator[Type] =
key match {
case TemplateKey(typ, body, maintainers) =>
Iterator(typ) ++
iterator(body) ++
iterator(maintainers)
}
def apply(typ: Type): Iterable[Type] =
new Iterable[Type] {
override def iterator = that.iterator(typ)
}
def apply(expr: Expr): Iterable[Type] =
new Iterable[Type] {
override def iterator = that.iterator(expr)
}
def apply(module: Module): Iterable[Type] =
new Iterable[Type] {
override def iterator: Iterator[Type] =
module.definitions.values.iterator.flatMap(that.iterator(_)) ++
module.templates.values.iterator.flatMap(that.iterator(_))
}
}

View File

@ -1,235 +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
package traversable
import com.daml.lf.language.Ast._
import com.daml.lf.validation.Util._
private[validation] object TypeTraversable {
that =>
private def toType(tyCon: TypeConApp): Type =
(tyCon.args.iterator foldLeft (TTyCon(tyCon.tycon): Type))(TApp)
private[validation] def foreach[U](typ: Type, f: Type => U): Unit =
typ match {
case TSynApp(_, args) =>
args.iterator.foreach(f)
case TVar(_) | TTyCon(_) | TBuiltin(_) | TNat(_) =>
case TApp(tyfun, arg) =>
f(tyfun)
f(arg)
()
case TForall(binder @ _, body) =>
f(body)
()
case TStruct(fields) =>
fields.values.foreach(f)
}
private[validation] def foreach[U](expr0: Expr, f: Type => U): Unit = {
expr0 match {
case ERecCon(tycon, fields @ _) =>
f(toType(tycon))
fields.values.foreach(foreach(_, f))
case ERecProj(tycon, field @ _, record) =>
f(toType(tycon))
foreach(record, f)
case ERecUpd(tycon, field @ _, record, update) =>
f(toType(tycon))
foreach(record, f)
foreach(update, f)
case EVariantCon(tycon, variant @ _, arg) =>
f(toType(tycon))
foreach(arg, f)
case ETyApp(expr, typ) =>
foreach(expr, f)
f(typ)
case EAbs((boundVarName @ _, boundVarType), body, ref @ _) =>
f(boundVarType)
foreach(body, f)
case ELet(binding, body) =>
foreach(binding, f)
foreach(body, f)
case EEnumCon(tyConName, _) =>
f(TTyCon(tyConName))
case EToAny(typ, expr) =>
f(typ)
foreach(expr, f)
case EFromAny(typ, expr) =>
f(typ)
foreach(expr, f)
case ETypeRep(tyCon) =>
f(tyCon)
case ENil(typ) =>
f(typ)
case ECons(typ, front, tail) =>
f(typ)
front.iterator.foreach(foreach(_, f))
foreach(tail, f)
case ENone(typ) =>
f(typ)
case ESome(typ, body) =>
f(typ)
foreach(body, f)
case EUpdate(u) =>
foreach(u, f)
case EScenario(s) =>
foreach(s, f)
case EThrow(returnType, exceptionType, exception) =>
f(returnType)
f(exceptionType)
foreach(exception, f)
case EToAnyException(typ, value) =>
f(typ)
foreach(value, f)
case EFromAnyException(typ, value) =>
f(typ)
foreach(value, f)
case EVar(_) | EVal(_) | EBuiltin(_) | EPrimCon(_) | EPrimLit(_) | EApp(_, _) | ECase(_, _) |
ELocation(_, _) | EStructCon(_) | EStructProj(_, _) | EStructUpd(_, _, _) |
ETyAbs(_, _) =>
ExprTraversable.foreach(expr0, foreach(_, f))
}
()
}
private[validation] def foreach[U](update: Update, f: Type => U): Unit =
update match {
case UpdatePure(typ, expr) =>
f(typ)
foreach(expr, f)
case UpdateBlock(bindings, body) =>
bindings.iterator.foreach(foreach(_, f))
foreach(body, f)
case UpdateCreate(templateId, arg) =>
f(TTyCon(templateId))
foreach(arg, f)
case UpdateFetch(templateId, contractId) =>
f(TTyCon(templateId))
foreach(contractId, f)
case UpdateExercise(templateId, choice @ _, cid, arg) =>
f(TTyCon(templateId))
foreach(cid, f)
foreach(arg, f)
case UpdateExerciseByKey(templateId, choice @ _, key, arg) =>
f(TTyCon(templateId))
foreach(key, f)
foreach(arg, f)
case UpdateEmbedExpr(typ, body) =>
f(typ)
foreach(body, f)
case UpdateGetTime | UpdateFetchByKey(_) | UpdateLookupByKey(_) =>
ExprTraversable.foreach(update, foreach(_, f))
case UpdateTryCatch(typ, body, binder @ _, handler) =>
f(typ)
foreach(body, f)
foreach(handler, f)
}
private[validation] def foreach[U](binding: Binding, f: Type => U): Unit =
binding match {
case Binding(binder @ _, typ, bound) =>
f(typ)
foreach(bound, f)
}
private[validation] def foreach[U](scenario: Scenario, f: Type => U): Unit =
scenario match {
case ScenarioPure(typ, expr) =>
f(typ)
foreach(expr, f)
case ScenarioBlock(bindings, body) =>
bindings.foreach(foreach(_, f))
foreach(body, f)
case ScenarioCommit(party, update, retType) =>
foreach(party, f)
foreach(update, f)
f(retType)
()
case ScenarioMustFailAt(party, update, retType) =>
foreach(party, f)
foreach(update, f)
f(retType)
()
case ScenarioEmbedExpr(typ, body) =>
f(typ)
foreach(body, f)
case ScenarioGetTime | ScenarioPass(_) | ScenarioGetParty(_) =>
ExprTraversable.foreach(scenario, foreach(_, f))
}
private[validation] def foreach[U](defn: Definition, f: Type => U): Unit =
defn match {
case DTypeSyn(params @ _, typ) =>
f(typ)
()
case DDataType(serializable @ _, params @ _, DataRecord(fields)) =>
fields.values.foreach(f)
case DDataType(serializable @ _, params @ _, DataVariant(variants)) =>
variants.values.foreach(f)
case DDataType(serializable @ _, params @ _, DataEnum(values @ _)) =>
case DValue(typ, noPartyLiterals @ _, body, isTest @ _) =>
f(typ)
foreach(body, f)
}
private[validation] def foreach[U](x: Template, f: Type => U): Unit =
x match {
case Template(param @ _, precond, signatories, agreementText, choices, observers, key) =>
foreach(precond, f)
foreach(signatories, f)
foreach(agreementText, f)
choices.values.foreach(foreach(_, f))
foreach(observers, f)
key.foreach(foreach(_, f))
}
private[validation] def foreach[U](choice: TemplateChoice, f: Type => U): Unit =
choice match {
case TemplateChoice(
name @ _,
consuming @ _,
controllers,
observers,
selfBinder @ _,
(boundedVarName @ _, boundedVarType),
retType,
update) =>
foreach(controllers, f)
observers.foreach(foreach(_, f))
foreach(update, f)
f(boundedVarType)
f(retType)
()
}
private[validation] def foreach[U](key: TemplateKey, f: Type => U): Unit =
key match {
case TemplateKey(typ, body, maintainers) =>
f(typ)
foreach(body, f)
foreach(maintainers, f)
}
def apply(typ: Type): Traversable[Type] =
new Traversable[Type] {
def foreach[U](f: Type => U): Unit = that.foreach(typ, f)
}
def apply(expr: Expr): Traversable[Type] =
new Traversable[Type] {
def foreach[U](f: Type => U): Unit = that.foreach(expr, f)
}
def apply(module: Module): Traversable[Type] =
new Traversable[Type] {
def foreach[U](f: Type => U): Unit = {
module.definitions.values.foreach(that.foreach(_, f))
module.templates.values.foreach(that.foreach(_, f))
}
}
}

View File

@ -26,7 +26,7 @@ private[validation] object SpecUtil {
'∀' -> "forall",
'→' -> "->",
'←' -> "<-",
'₁' "_1",
'₁' -> "_1",
'₂' -> "_2",
'₃' -> "_3",
'ᵢ' -> "_i",