remove support of retroactie interface instance in api-type-signature (#18382)

This commit is contained in:
Remy 2024-02-06 11:11:15 +01:00 committed by GitHub
parent 6112752c19
commit 0b1ceafe6c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 10 additions and 206 deletions

View File

@ -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 () {

View File

@ -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] {

View File

@ -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)
}

View File

@ -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`.
*/

View File

@ -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,

View File

@ -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) =

View File

@ -52,7 +52,6 @@ final class DependencyGraphSpec extends AnyWordSpec with Matchers {
returnType = TypeCon(TypeConName(baz), ImmArraySeq.empty),
)
),
retroImplements = Set.empty,
viewType = Some(vt),
)
),

View File

@ -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.
*/