mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 01:07:18 +03:00
remove support of retroactie interface instance in api-type-signature (#18382)
This commit is contained in:
parent
6112752c19
commit
0b1ceafe6c
@ -49,7 +49,7 @@ class PackageService(
|
||||
) {
|
||||
|
||||
def append(diff: PackageStore): State = {
|
||||
val newPackageStore = appendAndResolveRetroactiveInterfaces(resolveChoicesIn(diff))
|
||||
val newPackageStore = this.packageStore ++ resolveChoicesIn(diff)
|
||||
val (tpIdMap, ifaceIdMap) = getTemplateIdInterfaceMaps(newPackageStore)
|
||||
State(
|
||||
packageIds = newPackageStore.keySet,
|
||||
@ -67,17 +67,6 @@ class PackageService(
|
||||
val findIface = typesig.PackageSignature.findInterface(Function unlift lookupIf)
|
||||
diff.transform((_, iface) => iface resolveChoicesAndIgnoreUnresolvedChoices findIface)
|
||||
}
|
||||
|
||||
private[this] def appendAndResolveRetroactiveInterfaces(diff: PackageStore): PackageStore = {
|
||||
def lookupIf(packageStore: PackageStore, pkId: Ref.PackageId) =
|
||||
packageStore
|
||||
.get(pkId)
|
||||
.map((_, { (newSig: typesig.PackageSignature) => packageStore.updated(pkId, newSig) }))
|
||||
|
||||
val (packageStore2, diffElems) =
|
||||
typesig.PackageSignature.resolveRetroImplements(packageStore, diff.values.toSeq)(lookupIf)
|
||||
packageStore2 ++ diffElems.view.map(p => (p.packageId, p))
|
||||
}
|
||||
}
|
||||
|
||||
private class StateCache private () {
|
||||
|
@ -12,17 +12,7 @@ import scalaz.syntax.semigroup._
|
||||
import scalaz.syntax.traverse._
|
||||
import scalaz.syntax.std.map._
|
||||
import scalaz.syntax.std.option._
|
||||
import scalaz.{
|
||||
Applicative,
|
||||
Bifunctor,
|
||||
Bitraverse,
|
||||
Bifoldable,
|
||||
Foldable,
|
||||
Functor,
|
||||
Monoid,
|
||||
Semigroup,
|
||||
Traverse,
|
||||
}
|
||||
import scalaz.{Applicative, Bifunctor, Bitraverse, Bifoldable, Foldable, Functor, Monoid, Traverse}
|
||||
import scalaz.Tags.FirstVal
|
||||
import java.{util => j}
|
||||
|
||||
@ -213,29 +203,6 @@ final case class DefTemplate[+Ty](
|
||||
}
|
||||
|
||||
def getKey: j.Optional[_ <: Ty] = key.toJava
|
||||
|
||||
private[typesig] def extendWithInterface[OTy >: Ty](
|
||||
ifaceName: Ref.TypeConName,
|
||||
ifc: DefInterface[OTy],
|
||||
): DefTemplate[OTy] = {
|
||||
import TemplateChoices.{Resolved, Unresolved}
|
||||
copy(
|
||||
implementedInterfaces = implementedInterfaces :+ ifaceName,
|
||||
tChoices = tChoices match {
|
||||
case unr @ Unresolved(_, sources) =>
|
||||
unr.copy(unresolvedChoiceSources = sources incl ifaceName)
|
||||
// If unresolved, we need only add ifc as a future interface to resolve;
|
||||
// otherwise, we must self-resolve and add to preexisting resolutions
|
||||
case r @ Resolved(rc) =>
|
||||
type K[C] = Semigroup[Resolved.Choices[C]]
|
||||
r.copy(resolvedChoices =
|
||||
FirstVal
|
||||
.unsubst[K, TemplateChoice[OTy]](Semigroup.apply)
|
||||
.append(rc, ifc choicesAsResolved ifaceName)
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object DefTemplate {
|
||||
@ -315,14 +282,16 @@ sealed abstract class TemplateChoices[+Ty] extends Product with Serializable {
|
||||
): Either[ResolveError[Resolved[O]], Resolved[O]] = this match {
|
||||
case Unresolved(direct, unresolved) =>
|
||||
val getAstInterface = astInterfaces.lift
|
||||
type ResolutionResult[C] = (Set[Ref.TypeConName], Resolved.Choices[C])
|
||||
type ResolutionResult[C] =
|
||||
(Set[Ref.TypeConName], Map[Ref.ChoiceName, NonEmpty[Map[Option[Ref.TypeConName], C]]])
|
||||
val (missing, resolved): ResolutionResult[TemplateChoice[O]] =
|
||||
FirstVal.unsubst[ResolutionResult, TemplateChoice[O]](
|
||||
unresolved.forgetNE
|
||||
.foldMap { tcn =>
|
||||
getAstInterface(tcn).cata(
|
||||
{ astIf =>
|
||||
val tcnResolved = astIf choicesAsResolved tcn
|
||||
val tcnResolved =
|
||||
astIf.choices.transform((_, tc) => NonEmpty(Map, some(tcn) -> tc))
|
||||
FirstVal.subst[ResolutionResult, TemplateChoice[O]](
|
||||
Set.empty[Ref.TypeConName],
|
||||
tcnResolved,
|
||||
@ -381,11 +350,6 @@ object TemplateChoices {
|
||||
object Resolved {
|
||||
private[daml] def fromDirect[Ty](directChoices: Map[Ref.ChoiceName, TemplateChoice[Ty]]) =
|
||||
Resolved(directAsResolved(directChoices))
|
||||
|
||||
// choice type abstracted over the TemplateChoice, for specifying
|
||||
// aggregation of choices (typically with tags, foldMap, semigroup)
|
||||
private[typesig] type Choices[C] =
|
||||
Map[Ref.ChoiceName, NonEmpty[Map[Option[Ref.TypeConName], C]]]
|
||||
}
|
||||
|
||||
implicit val `TemplateChoices traverse`: Traverse[TemplateChoices] = new Traverse[TemplateChoices]
|
||||
@ -424,37 +388,13 @@ object TemplateChoice {
|
||||
}
|
||||
|
||||
/** @param choices Choices of this interface, indexed by name
|
||||
* @param retroImplements IDs of templates that implement this interface, upon
|
||||
* introduction of this interface into the environment
|
||||
*/
|
||||
final case class DefInterface[+Ty](
|
||||
choices: Map[Ref.ChoiceName, TemplateChoice[Ty]],
|
||||
retroImplements: Set[Ref.TypeConName],
|
||||
viewType: Option[Ref.TypeConName],
|
||||
) {
|
||||
def getChoices: j.Map[Ref.ChoiceName, _ <: TemplateChoice[Ty]] =
|
||||
choices.asJava
|
||||
|
||||
// Restructure `choices` in the resolved-choices data structure format,
|
||||
// for aggregation with [[TemplateChoices.Resolved]].
|
||||
private[typesig] def choicesAsResolved[Name](
|
||||
selfName: Name
|
||||
): Map[Ref.ChoiceName, NonEmpty[Map[Option[Name], TemplateChoice[Ty]]]] =
|
||||
choices transform ((_, tc) => NonEmpty(Map, some(selfName) -> tc))
|
||||
|
||||
private[typesig] def resolveRetroImplements[S, OTy >: Ty](selfName: Ref.TypeConName, s: S)(
|
||||
setTemplate: SetterAt[Ref.TypeConName, S, DefTemplate[OTy]]
|
||||
): (S, DefInterface[OTy]) = {
|
||||
def addMySelf(dt: DefTemplate[OTy]) =
|
||||
dt.extendWithInterface(selfName, this)
|
||||
|
||||
retroImplements
|
||||
.foldLeft((s, retroImplements)) { (sr, tplName) =>
|
||||
val (s, remaining) = sr
|
||||
setTemplate(s, tplName).cata(setter => (setter(addMySelf), remaining - tplName), sr)
|
||||
}
|
||||
.map(remaining => copy(retroImplements = remaining))
|
||||
}
|
||||
}
|
||||
|
||||
object DefInterface extends FWTLike[DefInterface] {
|
||||
|
@ -8,8 +8,6 @@ import com.daml.lf.archive.Dar
|
||||
import data.Ref, Ref.{Identifier, PackageId}
|
||||
|
||||
import scala.collection.immutable.Map
|
||||
import scalaz.std.tuple._
|
||||
import scalaz.syntax.functor._
|
||||
import scalaz.syntax.std.map._
|
||||
import scalaz.Semigroup
|
||||
|
||||
@ -47,21 +45,6 @@ final case class EnvironmentSignature(
|
||||
}
|
||||
})
|
||||
|
||||
def resolveRetroImplements: EnvironmentSignature = {
|
||||
import PackageSignature.findTemplate
|
||||
val (newTypeDecls, newInterfaces) = interfaces.foldLeft((typeDecls, interfaces)) {
|
||||
case ((typeDecls, interfaces), (ifTc, defIf)) =>
|
||||
defIf
|
||||
.resolveRetroImplements(ifTc, typeDecls) { case (typeDecls, tplName) =>
|
||||
findTemplate(typeDecls, tplName) map { itt => f =>
|
||||
typeDecls.updated(tplName, itt.copy(template = f(itt.template)))
|
||||
}
|
||||
}
|
||||
.map(defIf => interfaces.updated(ifTc, defIf))
|
||||
}
|
||||
copy(typeDecls = newTypeDecls, interfaces = newInterfaces)
|
||||
}
|
||||
|
||||
def resolveInterfaceViewType(tcn: Ref.TypeConName): Option[DefInterface.ViewTypeFWT] =
|
||||
typeDecls get tcn flatMap (_.asInterfaceViewType)
|
||||
}
|
||||
|
@ -11,11 +11,9 @@ 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._
|
||||
import scalaz.syntax.std.boolean._
|
||||
|
||||
import scala.collection.immutable.{Map, SeqOps}
|
||||
import scala.collection.immutable.Map
|
||||
import scala.jdk.CollectionConverters._
|
||||
|
||||
// Duplicate of the one in com.daml.lf.language to separate Ast and Iface
|
||||
@ -100,40 +98,6 @@ final case class PackageSignature(
|
||||
findInterface: PartialFunction[Ref.TypeConName, DefInterface.FWT]
|
||||
): PackageSignature = resolveChoices(findInterface, failIfUnresolvedChoicesLeft = false)
|
||||
|
||||
/** Update internal templates, as well as external templates via `setTemplates`,
|
||||
* with retroactive interface implementations.
|
||||
*
|
||||
* @param setTemplate Used to look up templates that can't be found in this
|
||||
* interface
|
||||
*/
|
||||
private def resolveRetroImplements[S](
|
||||
s: S
|
||||
)(setTemplate: SetterAt[Ref.TypeConName, S, DefTemplate.FWT]): (S, PackageSignature) = {
|
||||
type SandTpls = (S, Map[QualifiedName, TypeDecl.Template])
|
||||
def setTpl(
|
||||
sm: SandTpls,
|
||||
tcn: Ref.TypeConName,
|
||||
): Option[(DefTemplate.FWT => DefTemplate.FWT) => SandTpls] = {
|
||||
import PackageSignature.findTemplate
|
||||
val (s, tplsM) = sm
|
||||
if (tcn.packageId == packageId)
|
||||
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)))
|
||||
}
|
||||
|
||||
val ((sEnd, newTpls), newIfcs) = interfaces.foldLeft(
|
||||
((s, Map.empty): SandTpls, Map.empty[QualifiedName, DefInterface.FWT])
|
||||
) { case ((s, astIfs), (ifcName, astIf)) =>
|
||||
astIf
|
||||
.resolveRetroImplements(Ref.TypeConName(packageId, ifcName), s)(setTpl)
|
||||
.rightMap(newIf => astIfs.updated(ifcName, newIf))
|
||||
}
|
||||
(sEnd, copy(typeDecls = typeDecls ++ newTpls, interfaces = newIfcs))
|
||||
}
|
||||
|
||||
private def resolveInterfaceViewType(n: Ref.QualifiedName): Option[Record.FWT] =
|
||||
typeDecls get n flatMap (_.asInterfaceViewType)
|
||||
}
|
||||
@ -192,55 +156,6 @@ object PackageSignature {
|
||||
): Option[TypeDecl.Template] =
|
||||
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.
|
||||
private[this] def setPackageTemplates[S](
|
||||
findPackage: GetterSetterAt[PackageId, S, PackageSignature]
|
||||
): SetterAt[Ref.TypeConName, S, DefTemplate.FWT] = {
|
||||
def go(s: S, tcn: Ref.TypeConName): Option[(DefTemplate.FWT => DefTemplate.FWT) => S] = for {
|
||||
foundPkg <- findPackage(s, tcn.packageId)
|
||||
(ifc, sIfc) = foundPkg
|
||||
itt <- findTemplate(ifc.typeDecls, tcn.qualifiedName)
|
||||
} yield f =>
|
||||
sIfc(
|
||||
ifc.copy(typeDecls =
|
||||
ifc.typeDecls.updated(tcn.qualifiedName, itt.copy(template = f(itt.template)))
|
||||
)
|
||||
)
|
||||
go
|
||||
}
|
||||
|
||||
/** Extend the set of interfaces represented by `s` and `findPackage` with
|
||||
* `newSignatures`. Produce the resulting `S` and a replacement copy of
|
||||
* `newSignatures` with templates and interfaces therein resolved.
|
||||
*
|
||||
* Does not search members of `s` for fresh interfaces.
|
||||
*/
|
||||
def resolveRetroImplements[S, CC[B] <: Seq[B] with SeqOps[B, CC, CC[B]]](
|
||||
s: S,
|
||||
newSignatures: CC[PackageSignature],
|
||||
)(
|
||||
findPackage: GetterSetterAt[PackageId, S, PackageSignature]
|
||||
): (S, CC[PackageSignature]) = {
|
||||
type St = (S, CC[PackageSignature])
|
||||
val findTpl = setPackageTemplates[St] { case ((s, newSignatures), pkgId) =>
|
||||
findPackage(s, pkgId).map(_.rightMap(_ andThen ((_, newSignatures)))).orElse {
|
||||
val ix = newSignatures indexWhere (_.packageId == pkgId)
|
||||
(ix >= 0) option ((newSignatures(ix), newSig => (s, newSignatures.updated(ix, newSig))))
|
||||
}
|
||||
}
|
||||
|
||||
(0 until newSignatures.size).foldLeft((s, newSignatures)) {
|
||||
case (st @ (_, newSignatures), ifcK) =>
|
||||
val ((s2, newSignatures2), newAtIfcK) =
|
||||
newSignatures(ifcK).resolveRetroImplements(st)(findTpl)
|
||||
// the tricky part here: newSignatures2 is guaranteed not to have altered
|
||||
// the value at ifcK, and to have made all "self" changes in newAtIfcK.
|
||||
// So there is no conflict, we can discard the value in the seq
|
||||
(s2, newSignatures2.updated(ifcK, newAtIfcK))
|
||||
}
|
||||
}
|
||||
|
||||
/** An argument for [[PackageSignature#resolveChoices]] given a package database,
|
||||
* such as json-api's `LedgerReader.PackageStore`.
|
||||
*/
|
||||
|
@ -260,7 +260,7 @@ object SignatureReader {
|
||||
s"interface view type ${astIf.view.pretty} must be either a no-argument type reference or unit",
|
||||
)
|
||||
}
|
||||
} yield name -> typesig.DefInterface(choices, Set.empty, viewType)
|
||||
} yield name -> typesig.DefInterface(choices, viewType)
|
||||
|
||||
private[lf] def toIfaceType(
|
||||
ctx: QualifiedName,
|
||||
|
@ -201,14 +201,6 @@ 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
|
||||
}
|
||||
@ -329,13 +321,6 @@ class SignatureReaderSpec extends AnyWordSpec with Matchers with Inside {
|
||||
Bar -> Set(None),
|
||||
)
|
||||
}
|
||||
|
||||
"resolve retro implements harmlessly when there are none" in {
|
||||
PackageSignature.resolveRetroImplements((), itpWithoutRetroImplements.all)((_, _) =>
|
||||
None
|
||||
) should ===((), itpWithoutRetroImplements.all)
|
||||
itpESWithoutRetroImplements.resolveRetroImplements should ===(itpESWithoutRetroImplements)
|
||||
}
|
||||
}
|
||||
|
||||
private def wrappInModule(dataName: DottedName, dfn: Ast.DDataType) =
|
||||
|
@ -52,7 +52,6 @@ final class DependencyGraphSpec extends AnyWordSpec with Matchers {
|
||||
returnType = TypeCon(TypeConName(baz), ImmArraySeq.empty),
|
||||
)
|
||||
),
|
||||
retroImplements = Set.empty,
|
||||
viewType = Some(vt),
|
||||
)
|
||||
),
|
||||
|
@ -167,20 +167,18 @@ object CodeGenRunner extends StrictLogging {
|
||||
Reference.Module(id.packageId, id.qualifiedName.module)
|
||||
}
|
||||
|
||||
val resolvedSignatures = resolveRetroInterfaces(signatures)
|
||||
|
||||
implicit val resolvedPrefixes: PackagePrefixes =
|
||||
PackagePrefixes(
|
||||
resolvePackagePrefixes(
|
||||
packagePrefixes,
|
||||
modulePrefixes,
|
||||
resolvedSignatures,
|
||||
signatures,
|
||||
generatedModuleIds,
|
||||
)
|
||||
)
|
||||
|
||||
new CodeGenRunner.Scope(
|
||||
resolvedSignatures,
|
||||
signatures,
|
||||
transitiveClosure.serializableTypes,
|
||||
)
|
||||
}
|
||||
@ -271,11 +269,6 @@ object CodeGenRunner extends StrictLogging {
|
||||
interface
|
||||
}
|
||||
|
||||
private[this] def resolveRetroInterfaces(
|
||||
signatures: Seq[PackageSignature]
|
||||
): Seq[PackageSignature] =
|
||||
PackageSignature.resolveRetroImplements((), signatures)((_, _) => None)._2
|
||||
|
||||
/** Given the package prefixes specified per DAR and the module-prefixes specified in
|
||||
* daml.yaml, produce the combined prefixes per package id.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user