Skip to content

Commit

Permalink
include contract keys in the Scala codegen output plan when using --r…
Browse files Browse the repository at this point in the history
…oot (#6696)

* include DefTemplate's key types under the Ty type variable

* note that contract key types are included by folding over DefTemplates' Tys

- the topo sort from --root now correctly includes contract keys

* test that contract key dependencies get included in the Scala codegen plan

* no changelog

CHANGELOG_BEGIN
CHANGELOG_END
  • Loading branch information
S11001001 committed Jul 10, 2020
1 parent 1edc02a commit dba6ac7
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
package com.daml.lf.iface

import scalaz.std.map._
import scalaz.std.option._
import scalaz.std.tuple._
import scalaz.syntax.applicative.^
import scalaz.syntax.semigroup._
import scalaz.syntax.traverse._
import scalaz.{Applicative, Bifunctor, Bitraverse, Bifoldable, Foldable, Functor, Monoid, Traverse}
import java.{util => j}
Expand Down Expand Up @@ -166,14 +168,14 @@ final case class Enum(constructors: ImmArraySeq[Ref.Name]) extends DataType[Noth
def asDataType[RT, PVT]: DataType[RT, PVT] = this
}

final case class DefTemplate[+Ty](choices: Map[Ref.Name, TemplateChoice[Ty]], key: Option[Type]) {
final case class DefTemplate[+Ty](choices: Map[Ref.Name, TemplateChoice[Ty]], key: Option[Ty]) {
def map[B](f: Ty => B): DefTemplate[B] = Functor[DefTemplate].map(this)(f)

def getChoices: j.Map[Ref.ChoiceName, _ <: TemplateChoice[Ty]] =
choices.asJava

def getKey: j.Optional[Type] =
key.fold(j.Optional.empty[Type])(k => j.Optional.of(k))
def getKey: j.Optional[_ <: Ty] =
key.fold(j.Optional.empty[Ty])(k => j.Optional.of(k))
}

object DefTemplate {
Expand All @@ -182,13 +184,13 @@ object DefTemplate {
implicit val `TemplateDecl traverse`: Traverse[DefTemplate] =
new Traverse[DefTemplate] with Foldable.FromFoldMap[DefTemplate] {
override def foldMap[A, B: Monoid](fa: DefTemplate[A])(f: A => B): B =
fa.choices foldMap (_ foldMap f)
fa.choices.foldMap(_ foldMap f) |+| (fa.key foldMap f)

override def traverseImpl[G[_]: Applicative, A, B](fab: DefTemplate[A])(
f: A => G[B]): G[DefTemplate[B]] = {
Applicative[G].map(fab.choices traverse (_ traverse f))(choices =>
fab.copy(choices = choices))
}
f: A => G[B]): G[DefTemplate[B]] =
^(fab.choices traverse (_ traverse f), fab.key traverse f) { (choices, key) =>
fab.copy(choices = choices, key = key)
}
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ private final case class LFDependencyGraph(private val util: lf.LFUtil)
val templateNodes = decls.to[ImmArraySeq].collect {
case (qualName, InterfaceType.Template(typ, tpl)) =>
val recDeps = typ.foldMap(Util.genTypeTopLevelDeclNames)
val choiceDeps = tpl.foldMap(Util.genTypeTopLevelDeclNames)
val choiceAndKeyDeps = tpl.foldMap(Util.genTypeTopLevelDeclNames)
(
qualName,
Node(
TemplateWrapper(DefTemplateWithRecord(typ, tpl)),
recDeps ++ choiceDeps,
recDeps ++ choiceAndKeyDeps,
collectDepError = true))
}
Graph.cyclicDependencies(internalNodes = typeDeclNodes, roots = templateNodes)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.codegen.lf
package com.daml.codegen
package lf

import com.daml.lf.data.Ref
import org.scalatest.{Inside, Matchers, WordSpec}
Expand All @@ -12,6 +13,7 @@ import scalaz._
import scalaz.std.anyVal._
import scalaz.syntax.foldable1._
import scalaz.syntax.monad._
import scalaz.syntax.std.map._

class LFUtilSpec extends WordSpec with Matchers with Inside with PropertyChecks {
import LFUtilSpec._
Expand Down Expand Up @@ -110,6 +112,16 @@ class LFUtilSpec extends WordSpec with Matchers with Inside with PropertyChecks
}
}
}

"orderedDependencies" should {
"include contract keys" in {
val ei = CodeGen.filterTemplatesBy(Seq("HasKey".r))(envInterfaceWithKey)
LFUtil("a", ei, new java.io.File("."))
.orderedDependencies(ei)
.deps map (_._1) should ===(
Vector("a:b:It", "a:b:HasKey") map Ref.Identifier.assertFromString)
}
}
}

object LFUtilSpec {
Expand All @@ -126,4 +138,19 @@ object LFUtilSpec {
Shrink { nela =>
Shrink.shrink((nela.head, nela.tail.toVector)) map { case (h, t) => NonEmptyList(h, t: _*) }
}

import com.daml.lf.iface._
import com.daml.lf.data.ImmArray.ImmArraySeq

private[this] val fooRec = Record(ImmArraySeq.empty)
val envInterfaceWithKey = EnvironmentInterface(
Map(
"a:b:HasKey" -> InterfaceType.Template(
fooRec,
DefTemplate(
Map.empty,
Some(TypeCon(TypeConName(Ref.Identifier assertFromString "a:b:It"), ImmArraySeq.empty)))),
"a:b:NoKey" -> InterfaceType.Template(fooRec, DefTemplate(Map.empty, None)),
"a:b:It" -> InterfaceType.Normal(DefDataType(ImmArraySeq.empty, fooRec)),
) mapKeys Ref.Identifier.assertFromString)
}

0 comments on commit dba6ac7

Please sign in to comment.