Pass retroImplements from Ast.DefInterface to DefInterface (#14843)

* pass retroImplements from Ast.DefInterface to DefInterface and addted test case

CHANGELOG_BEGIN
CHANGELOG_END

* added todo

CHANGELOG_BEGIN
CHANGELOG_END

* fixed findTemplate , added test cases

CHANGELOG_BEGIN
CHANGELOG_END

* add test data

CHANGELOG_BEGIN
CHANGELOG_END

* add copyright

CHANGELOG_BEGIN
CHANGELOG_END
This commit is contained in:
Chun Lok Ling 2022-08-25 23:53:01 +01:00 committed by GitHub
parent e0ca74bdd6
commit 47216d1f1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 86 additions and 13 deletions

View File

@ -6,11 +6,11 @@ package com.daml.lf.typesig
import java.{util => j}
import com.daml.lf.data.ImmArray.ImmArraySeq
import com.daml.lf.data.Ref, Ref.{Identifier, PackageId, PackageName, PackageVersion, QualifiedName}
import com.daml.lf.data.Ref
import Ref.{Identifier, PackageId, PackageName, PackageVersion, QualifiedName}
import reader.Errors
import com.daml.daml_lf_dev.DamlLf
import com.daml.lf.archive.ArchivePayload
import scalaz.std.either._
import scalaz.std.tuple._
import scalaz.syntax.bifunctor._
@ -123,7 +123,8 @@ final case class PackageSignature(
import PackageSignature.findTemplate
val (s, tplsM) = sm
if (tcn.packageId == packageId)
findTemplate(tplsM, tcn.qualifiedName).map { case itt @ TypeDecl.Template(_, dt) =>
findTemplate(tplsM orElse typeDecls, tcn.qualifiedName).map {
case itt @ TypeDecl.Template(_, dt) =>
f => (s, tplsM.updated(tcn.qualifiedName, itt.copy(template = f(dt))))
}
else setTemplate(s, tcn) map (_ andThen ((_, tplsM)))
@ -192,10 +193,10 @@ object PackageSignature {
readPackageSignature(lf)
private[typesig] def findTemplate[K](
m: Map[K, TypeDecl],
m: PartialFunction[K, TypeDecl],
k: K,
): Option[TypeDecl.Template] =
m get k collect { case itt: TypeDecl.Template => itt }
m.lift(k) collect { case itt: TypeDecl.Template => itt }
// Given a lookup function for package state setters, produce a lookup function
// for setters on specific templates in that set of packages.

View File

@ -286,8 +286,8 @@ object SignatureReader {
s"interface view type ${astIf.view.pretty} must be either a no-argument type reference or unit",
)
}
// TODO #14081 pass actual retroactive implements instead of empty
} yield name -> typesig.DefInterface(choices, Set.empty, viewType)
retroImplements = astIf.coImplements.keySet
} yield name -> typesig.DefInterface(choices, retroImplements, viewType)
private[lf] def toIfaceType(
ctx: QualifiedName,

View File

@ -0,0 +1,23 @@
-- Copyright (c) 2022 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
-- SPDX-License-Identifier: Apache-2.0
module RetroInterface where
import qualified InterfaceTestPackage as P
data EmptyInterfaceView = EmptyInterfaceView {}
interface RetroIf where
viewtype EmptyInterfaceView
getOwner: Party
dup: Update (ContractId P.TIf)
choice Useless2: ContractId P.TIf with
interfacely: ContractId P.TIf
controller getOwner this
do
dup this
interface instance RetroIf for P.Foo where
view = EmptyInterfaceView
getOwner = party
dup = toInterfaceContractId <$> create this

View File

@ -193,6 +193,8 @@ class SignatureReaderSpec extends AnyWordSpec with Matchers with Inside {
"a real dar" should {
import archive.DarReader.readArchiveFromFile
import QualifiedName.{assertFromString => qn}
import Ref.ChoiceName.{assertFromString => cn}
lazy val itp = {
val file = requiredResource("daml-lf/api-type-signature/InterfaceTestPackage.dar")
@ -206,17 +208,24 @@ class SignatureReaderSpec extends AnyWordSpec with Matchers with Inside {
}
lazy val itpES = EnvironmentSignature.fromPackageSignatures(itp).resolveChoices
lazy val itpWithoutRetroImplements = itp.copy(
main = itp.main.copy(
interfaces = itp.main.interfaces - qn("RetroInterface:RetroIf")
)
)
lazy val itpESWithoutRetroImplements =
EnvironmentSignature.fromPackageSignatures(itpWithoutRetroImplements).resolveChoices
"load without errors" in {
itp shouldBe itp
}
import QualifiedName.{assertFromString => qn}
import Ref.ChoiceName.{assertFromString => cn}
val Foo = qn("InterfaceTestPackage:Foo")
val Bar = cn("Bar")
val Archive = cn("Archive")
val TIf = qn("InterfaceTestPackage:TIf")
val LibTIf = qn("InterfaceTestLib:TIf")
val RetroIf = qn("RetroInterface:RetroIf")
val LibTIfView = qn("InterfaceTestLib:TIfView")
val Useless = cn("Useless")
val UselessTy = qn("InterfaceTestPackage:Useless")
@ -256,12 +265,19 @@ class SignatureReaderSpec extends AnyWordSpec with Matchers with Inside {
}
"have interfaces with choices" in {
itp.main.interfaces.keySet should ===(Set(LibTIf, TIf))
itp.main.interfaces.keySet should ===(Set(LibTIf, TIf, RetroIf))
inside(itp.main.interfaces(TIf).choices get Useless) {
case Some(TheUselessChoice(UselessTy, TIf)) =>
}
}
"have interfaces with retroImplements" in {
itp.main.interfaces.keySet should ===(Set(LibTIf, TIf, RetroIf))
itp.main.interfaces(RetroIf).retroImplements should ===(
Set(Ref.TypeConName(itp.main.packageId, Foo))
)
}
// TODO SC #14067 depends on #14112
"identify a record interface view" ignore {
inside(itp.main.interfaces(LibTIf).viewType) { case Some(Ref.TypeConName(_, LibTIfView)) =>
@ -325,8 +341,41 @@ class SignatureReaderSpec extends AnyWordSpec with Matchers with Inside {
}
"resolve retro implements harmlessly when there are none" in {
PackageSignature.resolveRetroImplements((), itp.all)((_, _) => None) should ===((), itp.all)
itpES.resolveRetroImplements should ===(itpES)
PackageSignature.resolveRetroImplements((), itpWithoutRetroImplements.all)((_, _) =>
None
) should ===((), itpWithoutRetroImplements.all)
itpESWithoutRetroImplements.resolveRetroImplements should ===(itpESWithoutRetroImplements)
}
"resolve retro implements" in {
val (_, itpResolvedRetro) =
PackageSignature.resolveRetroImplements((), itp.all)((_, _) => None)
itpResolvedRetro should !==(itp.all)
inside(
itpResolvedRetro.find(_.packageId == itp.main.packageId)
) { case Some(packageSignature) =>
inside(packageSignature.interfaces.get(RetroIf)) {
case Some(DefInterface(_, retroImplements, _)) =>
retroImplements shouldBe empty
}
inside(packageSignature.typeDecls.get(Foo)) {
case Some(TypeDecl.Template(_, DefTemplate(_, _, implementedInterfaces))) =>
implementedInterfaces should contain(Ref.TypeConName(itp.main.packageId, RetroIf))
}
}
val itsESResolvedRetro = itpES.resolveRetroImplements
itsESResolvedRetro should !==(itpES)
inside(
itsESResolvedRetro.interfaces.get(Ref.TypeConName(itp.main.packageId, RetroIf))
) { case Some(DefInterface(_, retroImplements, _)) =>
retroImplements shouldBe empty
}
inside(itsESResolvedRetro.typeDecls.get(Ref.TypeConName(itp.main.packageId, Foo))) {
case Some(TypeDecl.Template(_, DefTemplate(_, _, implementedInterfaces))) =>
implementedInterfaces should contain(Ref.TypeConName(itp.main.packageId, RetroIf))
}
}
}