From 02d8e8fe95aac1c9ac1430180643ec57cb54a89d Mon Sep 17 00:00:00 2001 From: Moritz Kiefer Date: Tue, 5 Jan 2021 13:11:27 +0100 Subject: [PATCH] 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 --- ci/build.yml | 4 +- daml-lf/parser/BUILD.bazel | 18 +- .../daml/lf/testing/parser/ExprParser.scala | 12 +- .../daml/lf/testing/parser/KindParser.scala | 2 +- .../daml/lf/testing/parser/Lexer.scala | 12 +- .../daml/lf/testing/parser/ModParser.scala | 4 +- daml-lf/validation/BUILD.bazel | 17 +- .../daml/lf/validation/Collision.scala | 4 +- .../daml/lf/validation/PartyLiterals.scala | 6 +- .../daml/lf/validation/Recursion.scala | 18 +- .../daml/lf/validation/TypeSubst.scala | 7 +- .../daml/lf/validation/Typing.scala | 4 +- .../ExprIterable.scala} | 175 ++++++------- .../lf/validation/iterable/TypeIterable.scala | 215 ++++++++++++++++ .../traversable/TypeTraversable.scala | 235 ------------------ .../daml/lf/validation/SpecUtil.scala | 2 +- 16 files changed, 356 insertions(+), 379 deletions(-) rename daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/{traversable/ExprTraversable.scala => iterable/ExprIterable.scala} (50%) create mode 100644 daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/iterable/TypeIterable.scala delete mode 100644 daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/traversable/TypeTraversable.scala diff --git a/ci/build.yml b/ci/build.yml index b53bd82687..d3d1a1fcec 100644 --- a/ci/build.yml +++ b/ci/build.yml @@ -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: diff --git a/daml-lf/parser/BUILD.bazel b/daml-lf/parser/BUILD.bazel index d97c8fd150..41bdc0432d 100644 --- a/daml-lf/parser/BUILD.bazel +++ b/daml-lf/parser/BUILD.bazel @@ -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", ], ) diff --git a/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/ExprParser.scala b/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/ExprParser.scala index bab3288d73..4ce626129c 100644 --- a/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/ExprParser.scala +++ b/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/ExprParser.scala @@ -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) diff --git a/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/KindParser.scala b/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/KindParser.scala index 23aedbe126..a6be860263 100644 --- a/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/KindParser.scala +++ b/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/KindParser.scala @@ -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)) diff --git a/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/Lexer.scala b/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/Lexer.scala index 5782e80162..eab0d2d0cb 100644 --- a/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/Lexer.scala +++ b/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/Lexer.scala @@ -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)) } diff --git a/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/ModParser.scala b/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/ModParser.scala index bd331628d5..de6c70d678 100644 --- a/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/ModParser.scala +++ b/daml-lf/parser/src/main/scala/com/digitalasset/daml/lf/testing/parser/ModParser.scala @@ -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 ~ diff --git a/daml-lf/validation/BUILD.bazel b/daml-lf/validation/BUILD.bazel index 3bf289e88e..adb1f8eeaa 100644 --- a/daml-lf/validation/BUILD.bazel +++ b/daml-lf/validation/BUILD.bazel @@ -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", ], ) diff --git a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/Collision.scala b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/Collision.scala index 3d655c51a0..5d08cb0ce3 100644 --- a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/Collision.scala +++ b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/Collision.scala @@ -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) diff --git a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/PartyLiterals.scala b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/PartyLiterals.scala index afa436c0cf..8e4cc11e20 100644 --- a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/PartyLiterals.scala +++ b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/PartyLiterals.scala @@ -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, _)) } } diff --git a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/Recursion.scala b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/Recursion.scala index becb34ef67..b12119b4ff 100644 --- a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/Recursion.scala +++ b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/Recursion.scala @@ -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) } } diff --git a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/TypeSubst.scala b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/TypeSubst.scala index 311c80b588..b347f2b9c0 100644 --- a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/TypeSubst.scala +++ b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/TypeSubst.scala @@ -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] = diff --git a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/Typing.scala b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/Typing.scala index f4ba1a867e..337a6faafb 100644 --- a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/Typing.scala +++ b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/Typing.scala @@ -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_) } } diff --git a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/traversable/ExprTraversable.scala b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/iterable/ExprIterable.scala similarity index 50% rename from daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/traversable/ExprTraversable.scala rename to daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/iterable/ExprIterable.scala index 90e3242447..21a27cd923 100644 --- a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/traversable/ExprTraversable.scala +++ b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/iterable/ExprIterable.scala @@ -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(_)) } - } diff --git a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/iterable/TypeIterable.scala b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/iterable/TypeIterable.scala new file mode 100644 index 0000000000..b35b98031a --- /dev/null +++ b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/iterable/TypeIterable.scala @@ -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(_)) + } +} diff --git a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/traversable/TypeTraversable.scala b/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/traversable/TypeTraversable.scala deleted file mode 100644 index 11ba5c3189..0000000000 --- a/daml-lf/validation/src/main/scala/com/digitalasset/daml/lf/validation/traversable/TypeTraversable.scala +++ /dev/null @@ -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)) - } - } - -} diff --git a/daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/SpecUtil.scala b/daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/SpecUtil.scala index 4953958d50..b748af2781 100644 --- a/daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/SpecUtil.scala +++ b/daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/SpecUtil.scala @@ -26,7 +26,7 @@ private[validation] object SpecUtil { '∀' -> "forall", '→' -> "->", '←' -> "<-", - '₁' → "_1", + '₁' -> "_1", '₂' -> "_2", '₃' -> "_3", 'ᵢ' -> "_i",