module Unison.Merge.Diffblob
  ( Diffblob (..),
    makeDiffblob,
    DiffblobLog (..),
  )
where

import Control.Lens.Fold (folded)
import Data.List qualified as List
import Data.Map.Strict qualified as Map
import Data.Set qualified as Set
import Data.Set.Lens (setOf)
import Unison.DataDeclaration (Decl)
import Unison.DataDeclaration.Dependencies qualified as Decl
import Unison.DeclNameLookup (DeclNameLookup)
import Unison.LabeledDependency (LabeledDependency)
import Unison.LabeledDependency qualified as LabeledDependency
import Unison.Merge.CombineDiffs (CombinedDiffOp, combineDiffs)
import Unison.Merge.Diff (diffSynhashedDefns)
import Unison.Merge.DiffOp (DiffOp)
import Unison.Merge.Libdeps (applyLibdepsDiff, diffLibdeps, getTwoFreshLibdepNames, mergeLibdepsDiffs)
import Unison.Merge.Narrow (narrowDefns)
import Unison.Merge.PartitionCombinedDiffs (partitionCombinedDiffs)
import Unison.Merge.Rename (SimpleRenames, makeRenames, makeSimpleRenames)
import Unison.Merge.Synhash (synhashDefns, synhashLcaDefns)
import Unison.Merge.Synhashed (Synhashed)
import Unison.Merge.ThreeWay (GThreeWay (..), ThreeWay (..))
import Unison.Merge.ThreeWay qualified as ThreeWay
import Unison.Merge.TwoWay (TwoWay (..))
import Unison.Merge.TwoWay qualified as TwoWay
import Unison.Merge.Unconflicts (Unconflicts)
import Unison.Merge.Updated (GUpdated (..), Updated)
import Unison.Merge.Updated qualified as Updated
import Unison.Name (Name)
import Unison.NameSegment (NameSegment)
import Unison.Names (Names)
import Unison.Parser.Ann (Ann)
import Unison.PartialDeclNameLookup (PartialDeclNameLookup)
import Unison.Prelude
import Unison.PrettyPrintEnv (PrettyPrintEnv)
import Unison.PrettyPrintEnv qualified as PPE
import Unison.PrettyPrintEnv.Names qualified as PPE
import Unison.PrettyPrintEnvDecl (PrettyPrintEnvDecl)
import Unison.PrettyPrintEnvDecl qualified as PPED
import Unison.Reference (TermReference, TermReferenceId, TypeReference, TypeReferenceId)
import Unison.Reference qualified as Reference
import Unison.Referent (Referent)
import Unison.Referent qualified as Referent
import Unison.Symbol (Symbol)
import Unison.Term (Term)
import Unison.Term qualified as Term
import Unison.Type (Type)
import Unison.Type qualified as Type
import Unison.UnconflictedLocalDefnsView (UnconflictedLocalDefnsView (..))
import Unison.Util.BiMultimap qualified as BiMultimap
import Unison.Util.Defns (Defns (..), DefnsF, DefnsF2, DefnsF3, zipDefnsWith)

data Diffblob libdep = Diffblob
  { forall libdep.
Diffblob libdep
-> TwoWay (DefnsF (Map Name) TermReference TermReference)
conflicts :: TwoWay (DefnsF (Map Name) TermReference TypeReference),
    forall libdep.
Diffblob libdep -> GThreeWay PartialDeclNameLookup DeclNameLookup
declNameLookups :: GThreeWay PartialDeclNameLookup DeclNameLookup,
    forall libdep.
Diffblob libdep -> ThreeWay UnconflictedLocalDefnsView
defns :: ThreeWay UnconflictedLocalDefnsView,
    forall libdep.
Diffblob libdep
-> ThreeWay (DefnsF Set TermReferenceId TermReferenceId)
defnsIds :: ThreeWay (DefnsF Set TermReferenceId TypeReferenceId),
    forall libdep.
Diffblob libdep
-> DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
diff :: DefnsF2 (Map Name) CombinedDiffOp Referent TypeReference,
    forall libdep.
Diffblob libdep
-> TwoWay
     (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
diffsFromLCA :: TwoWay (DefnsF3 (Map Name) DiffOp Synhashed Referent TypeReference),
    -- Hydrated narrowed definitions. These are not necessarily all of the definitions needed for actually rendering
    -- a file, e.g. it doesn't contain dependents. It's included here because we did some work to hydrate these, and if
    -- we need to hydrate more *later*, we ought to look in this map first (to save duplicate work).
    forall libdep.
Diffblob libdep
-> Defns
     (Map TermReferenceId (Term Symbol Ann, Type Symbol Ann))
     (Map TermReferenceId (Decl Symbol Ann))
hydratedNarrowedDefns ::
      Defns
        (Map TermReferenceId (Term Symbol Ann, Type Symbol Ann))
        (Map TypeReferenceId (Decl Symbol Ann)),
    forall libdep. Diffblob libdep -> Updated (Map NameSegment libdep)
libdeps :: Updated (Map NameSegment libdep),
    forall libdep.
Diffblob libdep -> TwoWay (Map NameSegment (DiffOp libdep))
libdepsDiffs :: TwoWay (Map NameSegment (DiffOp libdep)),
    forall libdep.
Diffblob libdep
-> TwoWay
     (DefnsF (Map Name) (Updated Referent) (Updated TermReference))
propagatedUpdates :: TwoWay (DefnsF (Map Name) (Updated Referent) (Updated TypeReference)),
    forall libdep.
Diffblob libdep -> TwoWay (Defns SimpleRenames SimpleRenames)
simpleRenames :: TwoWay (Defns SimpleRenames SimpleRenames),
    forall libdep.
Diffblob libdep -> DefnsF Unconflicts Referent TermReference
unconflicts :: DefnsF Unconflicts Referent TypeReference
  }

data DiffblobLog m = DiffblobLog
  { forall (m :: * -> *).
DiffblobLog m
-> ThreeWay (DefnsF (Map Name) Referent TermReference) -> m ()
logDefns :: ThreeWay (DefnsF (Map Name) Referent TypeReference) -> m (),
    forall (m :: * -> *).
DiffblobLog m
-> TwoWay (Updated (DefnsF (Map Name) Referent TermReference))
-> m ()
logNarrowedDefns :: TwoWay (Updated (DefnsF (Map Name) Referent TypeReference)) -> m (),
    forall (m :: * -> *).
DiffblobLog m
-> TwoWay
     (GUpdated
        (DefnsF2 (Map Name) Synhashed Referent TermReference)
        (DefnsF2 (Map Name) Synhashed Referent TermReference))
-> m ()
logSynhashedNarrowedDefns ::
      TwoWay
        ( GUpdated
            (DefnsF2 (Map Name) Synhashed Referent TypeReference)
            (DefnsF2 (Map Name) Synhashed Referent TypeReference)
        ) ->
      m (),
    forall (m :: * -> *).
DiffblobLog m
-> TwoWay
     (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
-> m ()
logDiffsFromLCA :: TwoWay (DefnsF3 (Map Name) DiffOp Synhashed Referent TypeReference) -> m (),
    forall (m :: * -> *).
DiffblobLog m
-> DefnsF2 (Map Name) CombinedDiffOp Referent TermReference -> m ()
logDiff :: DefnsF2 (Map Name) CombinedDiffOp Referent TypeReference -> m ()
  }

makeDiffblob ::
  forall libdep m.
  (Eq libdep, Monad m) =>
  DiffblobLog m ->
  ( ThreeWay (DefnsF Set TermReferenceId TypeReferenceId) ->
    m
      ( Defns
          (Map TermReferenceId (Term Symbol Ann, Type Symbol Ann))
          (Map TypeReferenceId (Decl Symbol Ann))
      )
  ) ->
  (ThreeWay (Set LabeledDependency) -> m (ThreeWay Names)) ->
  ThreeWay UnconflictedLocalDefnsView ->
  ThreeWay (Map NameSegment libdep) ->
  GThreeWay PartialDeclNameLookup DeclNameLookup ->
  m (Diffblob libdep)
makeDiffblob :: forall libdep (m :: * -> *).
(Eq libdep, Monad m) =>
DiffblobLog m
-> (ThreeWay (DefnsF Set TermReferenceId TermReferenceId)
    -> m (Defns
            (Map TermReferenceId (Term Symbol Ann, Type Symbol Ann))
            (Map TermReferenceId (Decl Symbol Ann))))
-> (ThreeWay (Set LabeledDependency) -> m (ThreeWay Names))
-> ThreeWay UnconflictedLocalDefnsView
-> ThreeWay (Map NameSegment libdep)
-> GThreeWay PartialDeclNameLookup DeclNameLookup
-> m (Diffblob libdep)
makeDiffblob DiffblobLog m
logger ThreeWay (DefnsF Set TermReferenceId TermReferenceId)
-> m (Defns
        (Map TermReferenceId (Term Symbol Ann, Type Symbol Ann))
        (Map TermReferenceId (Decl Symbol Ann)))
hydrate ThreeWay (Set LabeledDependency) -> m (ThreeWay Names)
loadNames ThreeWay UnconflictedLocalDefnsView
defns ThreeWay (Map NameSegment libdep)
libdeps GThreeWay PartialDeclNameLookup DeclNameLookup
declNameLookups = do
  let defnsByName :: ThreeWay (DefnsF (Map Name) Referent TermReference)
defnsByName = (BiMultimap Referent Name -> Map Name Referent)
-> (BiMultimap TermReference Name -> Map Name TermReference)
-> Defns (BiMultimap Referent Name) (BiMultimap TermReference Name)
-> DefnsF (Map Name) Referent TermReference
forall a b c d. (a -> b) -> (c -> d) -> Defns a c -> Defns b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap BiMultimap Referent Name -> Map Name Referent
forall a b. BiMultimap a b -> Map b a
BiMultimap.range BiMultimap TermReference Name -> Map Name TermReference
forall a b. BiMultimap a b -> Map b a
BiMultimap.range (Defns (BiMultimap Referent Name) (BiMultimap TermReference Name)
 -> DefnsF (Map Name) Referent TermReference)
-> (UnconflictedLocalDefnsView
    -> Defns
         (BiMultimap Referent Name) (BiMultimap TermReference Name))
-> UnconflictedLocalDefnsView
-> DefnsF (Map Name) Referent TermReference
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.defns) (UnconflictedLocalDefnsView
 -> DefnsF (Map Name) Referent TermReference)
-> ThreeWay UnconflictedLocalDefnsView
-> ThreeWay (DefnsF (Map Name) Referent TermReference)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ThreeWay UnconflictedLocalDefnsView
defns

  DiffblobLog m
logger.logDefns ThreeWay (DefnsF (Map Name) Referent TermReference)
defnsByName

  let defnsIds :: ThreeWay (DefnsF Set TermReferenceId TypeReferenceId)
      defnsIds :: ThreeWay (DefnsF Set TermReferenceId TermReferenceId)
defnsIds =
        DefnsF (Map Name) Referent TermReference
-> DefnsF Set TermReferenceId TermReferenceId
toIds (DefnsF (Map Name) Referent TermReference
 -> DefnsF Set TermReferenceId TermReferenceId)
-> ThreeWay (DefnsF (Map Name) Referent TermReference)
-> ThreeWay (DefnsF Set TermReferenceId TermReferenceId)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ThreeWay (DefnsF (Map Name) Referent TermReference)
defnsByName

  -- Narrow definitions to those that could have different syntactic hashes
  let narrowedDefns :: TwoWay (Updated (DefnsF (Map Name) Referent TermReference))
narrowedDefns =
        HasCallStack =>
GThreeWay PartialDeclNameLookup DeclNameLookup
-> ThreeWay (DefnsF (Map Name) Referent TermReference)
-> TwoWay (Updated (DefnsF (Map Name) Referent TermReference))
GThreeWay PartialDeclNameLookup DeclNameLookup
-> ThreeWay (DefnsF (Map Name) Referent TermReference)
-> TwoWay (Updated (DefnsF (Map Name) Referent TermReference))
narrowDefns GThreeWay PartialDeclNameLookup DeclNameLookup
declNameLookups ThreeWay (DefnsF (Map Name) Referent TermReference)
defnsByName

  let narrowedDefns3 :: ThreeWay (DefnsF (Map Name) Referent TermReference)
narrowedDefns3 =
        TwoWay (Updated (DefnsF (Map Name) Referent TermReference))
-> ThreeWay (DefnsF (Map Name) Referent TermReference)
forall a. Semigroup a => TwoWay (Updated a) -> ThreeWay a
TwoWay.updatedToThreeWay TwoWay (Updated (DefnsF (Map Name) Referent TermReference))
narrowedDefns

  let narrowedDefnsIds3 :: ThreeWay (DefnsF Set TermReferenceId TermReferenceId)
narrowedDefnsIds3 =
        DefnsF (Map Name) Referent TermReference
-> DefnsF Set TermReferenceId TermReferenceId
toIds (DefnsF (Map Name) Referent TermReference
 -> DefnsF Set TermReferenceId TermReferenceId)
-> ThreeWay (DefnsF (Map Name) Referent TermReference)
-> ThreeWay (DefnsF Set TermReferenceId TermReferenceId)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ThreeWay (DefnsF (Map Name) Referent TermReference)
narrowedDefns3

  DiffblobLog m
logger.logNarrowedDefns TwoWay (Updated (DefnsF (Map Name) Referent TermReference))
narrowedDefns

  -- Hydrate only the narrowed definitions
  Defns
  (Map TermReferenceId (Term Symbol Ann, Type Symbol Ann))
  (Map TermReferenceId (Decl Symbol Ann))
hydratedNarrowedDefns <-
    ThreeWay (DefnsF Set TermReferenceId TermReferenceId)
-> m (Defns
        (Map TermReferenceId (Term Symbol Ann, Type Symbol Ann))
        (Map TermReferenceId (Decl Symbol Ann)))
hydrate ThreeWay (DefnsF Set TermReferenceId TermReferenceId)
narrowedDefnsIds3

  -- Load the names of all dependencies hydrated definitions
  ThreeWay Names
dependencyNames <-
    let hydratedNarrowedDefnsList :: Defns
  [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))]
  [(TermReferenceId, Decl Symbol Ann)]
hydratedNarrowedDefnsList = (Map TermReferenceId (Term Symbol Ann, Type Symbol Ann)
 -> [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))])
-> (Map TermReferenceId (Decl Symbol Ann)
    -> [(TermReferenceId, Decl Symbol Ann)])
-> Defns
     (Map TermReferenceId (Term Symbol Ann, Type Symbol Ann))
     (Map TermReferenceId (Decl Symbol Ann))
-> Defns
     [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))]
     [(TermReferenceId, Decl Symbol Ann)]
forall a b c d. (a -> b) -> (c -> d) -> Defns a c -> Defns b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap Map TermReferenceId (Term Symbol Ann, Type Symbol Ann)
-> [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))]
forall k a. Map k a -> [(k, a)]
Map.toList Map TermReferenceId (Decl Symbol Ann)
-> [(TermReferenceId, Decl Symbol Ann)]
forall k a. Map k a -> [(k, a)]
Map.toList Defns
  (Map TermReferenceId (Term Symbol Ann, Type Symbol Ann))
  (Map TermReferenceId (Decl Symbol Ann))
hydratedNarrowedDefns
        f :: Set a -> [(a, b)] -> [(a, b)]
f Set a
refs = ((a, b) -> Bool) -> [(a, b)] -> [(a, b)]
forall a. (a -> Bool) -> [a] -> [a]
List.filter (\(a
ref, b
_) -> a -> Set a -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member a
ref Set a
refs)
     in ThreeWay (Set LabeledDependency) -> m (ThreeWay Names)
loadNames (ThreeWay (Set LabeledDependency) -> m (ThreeWay Names))
-> ThreeWay (Set LabeledDependency) -> m (ThreeWay Names)
forall a b. (a -> b) -> a -> b
$
          (\DefnsF Set TermReferenceId TermReferenceId
defns -> Defns
  [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))]
  [(TermReferenceId, Decl Symbol Ann)]
-> Set LabeledDependency
forall (f :: * -> *).
Foldable f =>
DefnsF
  f
  (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
  (TermReferenceId, Decl Symbol Ann)
-> Set LabeledDependency
toLabeledDependencies ((Set TermReferenceId
 -> [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))]
 -> [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))])
-> (Set TermReferenceId
    -> [(TermReferenceId, Decl Symbol Ann)]
    -> [(TermReferenceId, Decl Symbol Ann)])
-> DefnsF Set TermReferenceId TermReferenceId
-> Defns
     [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))]
     [(TermReferenceId, Decl Symbol Ann)]
-> Defns
     [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))]
     [(TermReferenceId, Decl Symbol Ann)]
forall tm1 tm2 tm3 ty1 ty2 ty3.
(tm1 -> tm2 -> tm3)
-> (ty1 -> ty2 -> ty3)
-> Defns tm1 ty1
-> Defns tm2 ty2
-> Defns tm3 ty3
zipDefnsWith Set TermReferenceId
-> [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))]
-> [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))]
forall {a} {b}. Ord a => Set a -> [(a, b)] -> [(a, b)]
f Set TermReferenceId
-> [(TermReferenceId, Decl Symbol Ann)]
-> [(TermReferenceId, Decl Symbol Ann)]
forall {a} {b}. Ord a => Set a -> [(a, b)] -> [(a, b)]
f DefnsF Set TermReferenceId TermReferenceId
defns Defns
  [(TermReferenceId, (Term Symbol Ann, Type Symbol Ann))]
  [(TermReferenceId, Decl Symbol Ann)]
hydratedNarrowedDefnsList))
            (DefnsF Set TermReferenceId TermReferenceId
 -> Set LabeledDependency)
-> ThreeWay (DefnsF Set TermReferenceId TermReferenceId)
-> ThreeWay (Set LabeledDependency)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ThreeWay (DefnsF Set TermReferenceId TermReferenceId)
narrowedDefnsIds3

  -- Compute the syntactic hashes of the narrowed+hydrated definitions
  let synhashedNarrowedDefns :: TwoWay (Updated (DefnsF2 (Map Name) Synhashed Referent TypeReference))
      synhashedNarrowedDefns :: TwoWay
  (GUpdated
     (DefnsF2 (Map Name) Synhashed Referent TermReference)
     (DefnsF2 (Map Name) Synhashed Referent TermReference))
synhashedNarrowedDefns =
        ((Term Symbol Ann, Type Symbol Ann) -> Term Symbol Ann)
-> ThreeWay Names
-> GThreeWay PartialDeclNameLookup DeclNameLookup
-> TwoWay (Updated (DefnsF (Map Name) Referent TermReference))
-> Defns
     (Map TermReferenceId (Term Symbol Ann, Type Symbol Ann))
     (Map TermReferenceId (Decl Symbol Ann))
-> TwoWay
     (GUpdated
        (DefnsF2 (Map Name) Synhashed Referent TermReference)
        (DefnsF2 (Map Name) Synhashed Referent TermReference))
forall term.
(term -> Term Symbol Ann)
-> ThreeWay Names
-> GThreeWay PartialDeclNameLookup DeclNameLookup
-> TwoWay (Updated (DefnsF (Map Name) Referent TermReference))
-> Defns
     (Map TermReferenceId term) (Map TermReferenceId (Decl Symbol Ann))
-> TwoWay
     (GUpdated
        (DefnsF2 (Map Name) Synhashed Referent TermReference)
        (DefnsF2 (Map Name) Synhashed Referent TermReference))
makeSynhashedNarrowedDefns
          (Term Symbol Ann, Type Symbol Ann) -> Term Symbol Ann
forall a b. (a, b) -> a
fst
          ThreeWay Names
dependencyNames
          GThreeWay PartialDeclNameLookup DeclNameLookup
declNameLookups
          TwoWay (Updated (DefnsF (Map Name) Referent TermReference))
narrowedDefns
          Defns
  (Map TermReferenceId (Term Symbol Ann, Type Symbol Ann))
  (Map TermReferenceId (Decl Symbol Ann))
hydratedNarrowedDefns

  DiffblobLog m
logger.logSynhashedNarrowedDefns TwoWay
  (GUpdated
     (DefnsF2 (Map Name) Synhashed Referent TermReference)
     (DefnsF2 (Map Name) Synhashed Referent TermReference))
synhashedNarrowedDefns

  -- Identify all renames
  let renames :: TwoWay (DefnsF [] Rename Rename)
renames =
        Updated
  (Defns
     (BiMultimap (Synhashed Referent) Name)
     (BiMultimap (Synhashed TermReference) Name))
-> DefnsF [] Rename Rename
makeRenames (Updated
   (Defns
      (BiMultimap (Synhashed Referent) Name)
      (BiMultimap (Synhashed TermReference) Name))
 -> DefnsF [] Rename Rename)
-> (GUpdated
      (DefnsF2 (Map Name) Synhashed Referent TermReference)
      (DefnsF2 (Map Name) Synhashed Referent TermReference)
    -> Updated
         (Defns
            (BiMultimap (Synhashed Referent) Name)
            (BiMultimap (Synhashed TermReference) Name)))
-> GUpdated
     (DefnsF2 (Map Name) Synhashed Referent TermReference)
     (DefnsF2 (Map Name) Synhashed Referent TermReference)
-> DefnsF [] Rename Rename
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DefnsF2 (Map Name) Synhashed Referent TermReference
 -> Defns
      (BiMultimap (Synhashed Referent) Name)
      (BiMultimap (Synhashed TermReference) Name))
-> GUpdated
     (DefnsF2 (Map Name) Synhashed Referent TermReference)
     (DefnsF2 (Map Name) Synhashed Referent TermReference)
-> Updated
     (Defns
        (BiMultimap (Synhashed Referent) Name)
        (BiMultimap (Synhashed TermReference) Name))
forall a b. (a -> b) -> Updated a -> Updated b
Updated.map ((Map Name (Synhashed Referent)
 -> BiMultimap (Synhashed Referent) Name)
-> (Map Name (Synhashed TermReference)
    -> BiMultimap (Synhashed TermReference) Name)
-> DefnsF2 (Map Name) Synhashed Referent TermReference
-> Defns
     (BiMultimap (Synhashed Referent) Name)
     (BiMultimap (Synhashed TermReference) Name)
forall a b c d. (a -> b) -> (c -> d) -> Defns a c -> Defns b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap Map Name (Synhashed Referent)
-> BiMultimap (Synhashed Referent) Name
forall a b. (Ord a, Ord b) => Map b a -> BiMultimap a b
BiMultimap.fromRange Map Name (Synhashed TermReference)
-> BiMultimap (Synhashed TermReference) Name
forall a b. (Ord a, Ord b) => Map b a -> BiMultimap a b
BiMultimap.fromRange) (GUpdated
   (DefnsF2 (Map Name) Synhashed Referent TermReference)
   (DefnsF2 (Map Name) Synhashed Referent TermReference)
 -> DefnsF [] Rename Rename)
-> TwoWay
     (GUpdated
        (DefnsF2 (Map Name) Synhashed Referent TermReference)
        (DefnsF2 (Map Name) Synhashed Referent TermReference))
-> TwoWay (DefnsF [] Rename Rename)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TwoWay
  (GUpdated
     (DefnsF2 (Map Name) Synhashed Referent TermReference)
     (DefnsF2 (Map Name) Synhashed Referent TermReference))
synhashedNarrowedDefns

  -- Filter all renames down to just "simple" renames
  let simpleRenames :: TwoWay (Defns SimpleRenames SimpleRenames)
simpleRenames =
        DefnsF [] Rename Rename -> Defns SimpleRenames SimpleRenames
makeSimpleRenames (DefnsF [] Rename Rename -> Defns SimpleRenames SimpleRenames)
-> TwoWay (DefnsF [] Rename Rename)
-> TwoWay (Defns SimpleRenames SimpleRenames)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TwoWay (DefnsF [] Rename Rename)
renames

  -- Diff LCA->Alice and LCA->Bob
  let (TwoWay (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
diffsFromLCA, TwoWay
  (DefnsF (Map Name) (Updated Referent) (Updated TermReference))
propagatedUpdates) =
        TwoWay
  (GUpdated
     (DefnsF2 (Map Name) Synhashed Referent TermReference)
     (DefnsF2 (Map Name) Synhashed Referent TermReference))
-> (TwoWay
      (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference),
    TwoWay
      (DefnsF (Map Name) (Updated Referent) (Updated TermReference)))
diffSynhashedDefns TwoWay
  (GUpdated
     (DefnsF2 (Map Name) Synhashed Referent TermReference)
     (DefnsF2 (Map Name) Synhashed Referent TermReference))
synhashedNarrowedDefns

  DiffblobLog m
logger.logDiffsFromLCA TwoWay (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
diffsFromLCA

  -- Combine the LCA->Alice and LCA->Bob diffs together
  let diff :: DefnsF2 (Map Name) CombinedDiffOp Referent TypeReference
      diff :: DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
diff =
        TwoWay (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
-> DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
combineDiffs TwoWay (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
diffsFromLCA

  DiffblobLog m
logger.logDiff DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
diff

  -- Partition the combined diff into the conflicted things and the unconflicted things
  let (TwoWay (DefnsF (Map Name) TermReference TermReference)
conflicts, DefnsF Unconflicts Referent TermReference
unconflicts) =
        TwoWay
  (Defns (BiMultimap Referent Name) (BiMultimap TermReference Name))
-> TwoWay DeclNameLookup
-> DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
-> (TwoWay (DefnsF (Map Name) TermReference TermReference),
    DefnsF Unconflicts Referent TermReference)
partitionCombinedDiffs ((.defns) (UnconflictedLocalDefnsView
 -> Defns
      (BiMultimap Referent Name) (BiMultimap TermReference Name))
-> TwoWay UnconflictedLocalDefnsView
-> TwoWay
     (Defns (BiMultimap Referent Name) (BiMultimap TermReference Name))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ThreeWay UnconflictedLocalDefnsView
-> TwoWay UnconflictedLocalDefnsView
forall a. ThreeWay a -> TwoWay a
ThreeWay.forgetLca ThreeWay UnconflictedLocalDefnsView
defns) (GThreeWay PartialDeclNameLookup DeclNameLookup
-> TwoWay DeclNameLookup
forall a b. GThreeWay a b -> TwoWay b
ThreeWay.gforgetLca GThreeWay PartialDeclNameLookup DeclNameLookup
declNameLookups) DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
diff

  -- Diff and merge libdeps
  let libdepsDiffs :: TwoWay (Map NameSegment (DiffOp libdep))
      libdepsDiffs :: TwoWay (Map NameSegment (DiffOp libdep))
libdepsDiffs =
        ThreeWay (Map NameSegment libdep)
-> TwoWay (Map NameSegment (DiffOp libdep))
forall k v.
(Ord k, Eq v) =>
ThreeWay (Map k v) -> TwoWay (Map k (DiffOp v))
diffLibdeps ThreeWay (Map NameSegment libdep)
libdeps

  let mergedLibdeps :: Map NameSegment libdep
      mergedLibdeps :: Map NameSegment libdep
mergedLibdeps =
        (Set NameSegment -> NameSegment -> (NameSegment, NameSegment))
-> ThreeWay (Map NameSegment libdep)
-> Map NameSegment (LibdepDiffOp libdep)
-> Map NameSegment libdep
forall k v.
Ord k =>
(Set k -> k -> (k, k))
-> ThreeWay (Map k v) -> Map k (LibdepDiffOp v) -> Map k v
applyLibdepsDiff
          Set NameSegment -> NameSegment -> (NameSegment, NameSegment)
getTwoFreshLibdepNames
          ThreeWay (Map NameSegment libdep)
libdeps
          (TwoWay (Map NameSegment (DiffOp libdep))
-> Map NameSegment (LibdepDiffOp libdep)
forall k v.
(Ord k, Eq v) =>
TwoWay (Map k (DiffOp v)) -> Map k (LibdepDiffOp v)
mergeLibdepsDiffs TwoWay (Map NameSegment (DiffOp libdep))
libdepsDiffs)

  pure
    Diffblob
      { TwoWay (DefnsF (Map Name) TermReference TermReference)
$sel:conflicts:Diffblob :: TwoWay (DefnsF (Map Name) TermReference TermReference)
conflicts :: TwoWay (DefnsF (Map Name) TermReference TermReference)
conflicts,
        GThreeWay PartialDeclNameLookup DeclNameLookup
$sel:declNameLookups:Diffblob :: GThreeWay PartialDeclNameLookup DeclNameLookup
declNameLookups :: GThreeWay PartialDeclNameLookup DeclNameLookup
declNameLookups,
        ThreeWay UnconflictedLocalDefnsView
$sel:defns:Diffblob :: ThreeWay UnconflictedLocalDefnsView
defns :: ThreeWay UnconflictedLocalDefnsView
defns,
        ThreeWay (DefnsF Set TermReferenceId TermReferenceId)
$sel:defnsIds:Diffblob :: ThreeWay (DefnsF Set TermReferenceId TermReferenceId)
defnsIds :: ThreeWay (DefnsF Set TermReferenceId TermReferenceId)
defnsIds,
        DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
$sel:diff:Diffblob :: DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
diff :: DefnsF2 (Map Name) CombinedDiffOp Referent TermReference
diff,
        TwoWay (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
$sel:diffsFromLCA:Diffblob :: TwoWay (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
diffsFromLCA :: TwoWay (DefnsF3 (Map Name) DiffOp Synhashed Referent TermReference)
diffsFromLCA,
        $sel:libdeps:Diffblob :: Updated (Map NameSegment libdep)
libdeps = Updated {$sel:old:Updated :: Map NameSegment libdep
old = ThreeWay (Map NameSegment libdep)
libdeps.lca, $sel:new:Updated :: Map NameSegment libdep
new = Map NameSegment libdep
mergedLibdeps},
        TwoWay (Map NameSegment (DiffOp libdep))
$sel:libdepsDiffs:Diffblob :: TwoWay (Map NameSegment (DiffOp libdep))
libdepsDiffs :: TwoWay (Map NameSegment (DiffOp libdep))
libdepsDiffs,
        Defns
  (Map TermReferenceId (Term Symbol Ann, Type Symbol Ann))
  (Map TermReferenceId (Decl Symbol Ann))
$sel:hydratedNarrowedDefns:Diffblob :: Defns
  (Map TermReferenceId (Term Symbol Ann, Type Symbol Ann))
  (Map TermReferenceId (Decl Symbol Ann))
hydratedNarrowedDefns :: Defns
  (Map TermReferenceId (Term Symbol Ann, Type Symbol Ann))
  (Map TermReferenceId (Decl Symbol Ann))
hydratedNarrowedDefns,
        TwoWay
  (DefnsF (Map Name) (Updated Referent) (Updated TermReference))
$sel:propagatedUpdates:Diffblob :: TwoWay
  (DefnsF (Map Name) (Updated Referent) (Updated TermReference))
propagatedUpdates :: TwoWay
  (DefnsF (Map Name) (Updated Referent) (Updated TermReference))
propagatedUpdates,
        TwoWay (Defns SimpleRenames SimpleRenames)
$sel:simpleRenames:Diffblob :: TwoWay (Defns SimpleRenames SimpleRenames)
simpleRenames :: TwoWay (Defns SimpleRenames SimpleRenames)
simpleRenames,
        DefnsF Unconflicts Referent TermReference
$sel:unconflicts:Diffblob :: DefnsF Unconflicts Referent TermReference
unconflicts :: DefnsF Unconflicts Referent TermReference
unconflicts
      }

toIds :: DefnsF (Map Name) Referent TypeReference -> DefnsF Set TermReferenceId TypeReferenceId
toIds :: DefnsF (Map Name) Referent TermReference
-> DefnsF Set TermReferenceId TermReferenceId
toIds =
  (Map Name Referent -> Set TermReferenceId)
-> (Map Name TermReference -> Set TermReferenceId)
-> DefnsF (Map Name) Referent TermReference
-> DefnsF Set TermReferenceId TermReferenceId
forall a b c d. (a -> b) -> (c -> d) -> Defns a c -> Defns b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap
    (Getting (Set TermReferenceId) (Map Name Referent) TermReferenceId
-> Map Name Referent -> Set TermReferenceId
forall a s. Getting (Set a) s a -> s -> Set a
setOf (forall (f :: * -> *) a. Foldable f => IndexedFold Int (f a) a
folded @(Map Name) ((Referent -> Const (Set TermReferenceId) Referent)
 -> Map Name Referent
 -> Const (Set TermReferenceId) (Map Name Referent))
-> ((TermReferenceId
     -> Const (Set TermReferenceId) TermReferenceId)
    -> Referent -> Const (Set TermReferenceId) Referent)
-> Getting
     (Set TermReferenceId) (Map Name Referent) TermReferenceId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TermReference -> Const (Set TermReferenceId) TermReference)
-> Referent -> Const (Set TermReferenceId) Referent
forall r (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p r (f r) -> p (Referent' r) (f (Referent' r))
Referent.termReference_ ((TermReference -> Const (Set TermReferenceId) TermReference)
 -> Referent -> Const (Set TermReferenceId) Referent)
-> ((TermReferenceId
     -> Const (Set TermReferenceId) TermReferenceId)
    -> TermReference -> Const (Set TermReferenceId) TermReference)
-> (TermReferenceId -> Const (Set TermReferenceId) TermReferenceId)
-> Referent
-> Const (Set TermReferenceId) Referent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TermReferenceId -> Const (Set TermReferenceId) TermReferenceId)
-> TermReference -> Const (Set TermReferenceId) TermReference
Prism' TermReference TermReferenceId
Reference._DerivedId))
    (Getting
  (Set TermReferenceId) (Map Name TermReference) TermReferenceId
-> Map Name TermReference -> Set TermReferenceId
forall a s. Getting (Set a) s a -> s -> Set a
setOf (forall (f :: * -> *) a. Foldable f => IndexedFold Int (f a) a
folded @(Map Name) ((TermReference -> Const (Set TermReferenceId) TermReference)
 -> Map Name TermReference
 -> Const (Set TermReferenceId) (Map Name TermReference))
-> ((TermReferenceId
     -> Const (Set TermReferenceId) TermReferenceId)
    -> TermReference -> Const (Set TermReferenceId) TermReference)
-> Getting
     (Set TermReferenceId) (Map Name TermReference) TermReferenceId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TermReferenceId -> Const (Set TermReferenceId) TermReferenceId)
-> TermReference -> Const (Set TermReferenceId) TermReference
Prism' TermReference TermReferenceId
Reference._DerivedId))

makeSynhashedNarrowedDefns ::
  (term -> Term Symbol Ann) ->
  ThreeWay Names ->
  GThreeWay PartialDeclNameLookup DeclNameLookup ->
  TwoWay (Updated (DefnsF (Map Name) Referent TypeReference)) ->
  Defns (Map TermReferenceId term) (Map TypeReferenceId (Decl Symbol Ann)) ->
  TwoWay (GUpdated (DefnsF2 (Map Name) Synhashed Referent TypeReference) (DefnsF2 (Map Name) Synhashed Referent TypeReference))
makeSynhashedNarrowedDefns :: forall term.
(term -> Term Symbol Ann)
-> ThreeWay Names
-> GThreeWay PartialDeclNameLookup DeclNameLookup
-> TwoWay (Updated (DefnsF (Map Name) Referent TermReference))
-> Defns
     (Map TermReferenceId term) (Map TermReferenceId (Decl Symbol Ann))
-> TwoWay
     (GUpdated
        (DefnsF2 (Map Name) Synhashed Referent TermReference)
        (DefnsF2 (Map Name) Synhashed Referent TermReference))
makeSynhashedNarrowedDefns term -> Term Symbol Ann
toTerm ThreeWay Names
allNames GThreeWay PartialDeclNameLookup DeclNameLookup
declNameLookups TwoWay (Updated (DefnsF (Map Name) Referent TermReference))
defns Defns
  (Map TermReferenceId term) (Map TermReferenceId (Decl Symbol Ann))
hydratedDefns =
  DefnsF2 (Map Name) Synhashed Referent TermReference
-> DefnsF2 (Map Name) Synhashed Referent TermReference
-> GUpdated
     (DefnsF2 (Map Name) Synhashed Referent TermReference)
     (DefnsF2 (Map Name) Synhashed Referent TermReference)
forall a b. a -> b -> GUpdated a b
Updated
    (DefnsF2 (Map Name) Synhashed Referent TermReference
 -> DefnsF2 (Map Name) Synhashed Referent TermReference
 -> GUpdated
      (DefnsF2 (Map Name) Synhashed Referent TermReference)
      (DefnsF2 (Map Name) Synhashed Referent TermReference))
-> TwoWay (DefnsF2 (Map Name) Synhashed Referent TermReference)
-> TwoWay
     (DefnsF2 (Map Name) Synhashed Referent TermReference
      -> GUpdated
           (DefnsF2 (Map Name) Synhashed Referent TermReference)
           (DefnsF2 (Map Name) Synhashed Referent TermReference))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ( (Map Name (Synhashed Referent)
 -> Map Name Referent -> Map Name (Synhashed Referent))
-> (Map Name (Synhashed TermReference)
    -> Map Name TermReference -> Map Name (Synhashed TermReference))
-> DefnsF2 (Map Name) Synhashed Referent TermReference
-> DefnsF (Map Name) Referent TermReference
-> DefnsF2 (Map Name) Synhashed Referent TermReference
forall tm1 tm2 tm3 ty1 ty2 ty3.
(tm1 -> tm2 -> tm3)
-> (ty1 -> ty2 -> ty3)
-> Defns tm1 ty1
-> Defns tm2 ty2
-> Defns tm3 ty3
zipDefnsWith
            Map Name (Synhashed Referent)
-> Map Name Referent -> Map Name (Synhashed Referent)
forall k a b. Ord k => Map k a -> Map k b -> Map k a
Map.intersection
            Map Name (Synhashed TermReference)
-> Map Name TermReference -> Map Name (Synhashed TermReference)
forall k a b. Ord k => Map k a -> Map k b -> Map k a
Map.intersection
            ( (term -> Term Symbol Ann)
-> PrettyPrintEnv
-> PartialDeclNameLookup
-> DefnsF (Map Name) Referent TermReference
-> Defns
     (Map TermReferenceId term) (Map TermReferenceId (Decl Symbol Ann))
-> DefnsF2 (Map Name) Synhashed Referent TermReference
forall term.
HasCallStack =>
(term -> Term Symbol Ann)
-> PrettyPrintEnv
-> PartialDeclNameLookup
-> DefnsF (Map Name) Referent TermReference
-> Defns
     (Map TermReferenceId term) (Map TermReferenceId (Decl Symbol Ann))
-> DefnsF2 (Map Name) Synhashed Referent TermReference
synhashLcaDefns
                term -> Term Symbol Ann
toTerm
                PrettyPrintEnv
ppe
                GThreeWay PartialDeclNameLookup DeclNameLookup
declNameLookups.lca
                (TwoWay (DefnsF (Map Name) Referent TermReference)
-> DefnsF (Map Name) Referent TermReference
forall m. Monoid m => TwoWay m -> m
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold TwoWay (DefnsF (Map Name) Referent TermReference)
oldDefns) -- left-biased map union is fine, the maps have equal values at equal keys
                Defns
  (Map TermReferenceId term) (Map TermReferenceId (Decl Symbol Ann))
hydratedDefns
            )
            (DefnsF (Map Name) Referent TermReference
 -> DefnsF2 (Map Name) Synhashed Referent TermReference)
-> TwoWay (DefnsF (Map Name) Referent TermReference)
-> TwoWay (DefnsF2 (Map Name) Synhashed Referent TermReference)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TwoWay (DefnsF (Map Name) Referent TermReference)
oldDefns
        )
    TwoWay
  (DefnsF2 (Map Name) Synhashed Referent TermReference
   -> GUpdated
        (DefnsF2 (Map Name) Synhashed Referent TermReference)
        (DefnsF2 (Map Name) Synhashed Referent TermReference))
-> TwoWay (DefnsF2 (Map Name) Synhashed Referent TermReference)
-> TwoWay
     (GUpdated
        (DefnsF2 (Map Name) Synhashed Referent TermReference)
        (DefnsF2 (Map Name) Synhashed Referent TermReference))
forall a b. TwoWay (a -> b) -> TwoWay a -> TwoWay b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ( (term -> Term Symbol Ann)
-> PrettyPrintEnv
-> Defns
     (Map TermReferenceId term) (Map TermReferenceId (Decl Symbol Ann))
-> DeclNameLookup
-> DefnsF (Map Name) Referent TermReference
-> DefnsF2 (Map Name) Synhashed Referent TermReference
forall term.
HasCallStack =>
(term -> Term Symbol Ann)
-> PrettyPrintEnv
-> Defns
     (Map TermReferenceId term) (Map TermReferenceId (Decl Symbol Ann))
-> DeclNameLookup
-> DefnsF (Map Name) Referent TermReference
-> DefnsF2 (Map Name) Synhashed Referent TermReference
synhashDefns term -> Term Symbol Ann
toTerm PrettyPrintEnv
ppe Defns
  (Map TermReferenceId term) (Map TermReferenceId (Decl Symbol Ann))
hydratedDefns
            (DeclNameLookup
 -> DefnsF (Map Name) Referent TermReference
 -> DefnsF2 (Map Name) Synhashed Referent TermReference)
-> TwoWay DeclNameLookup
-> TwoWay
     (DefnsF (Map Name) Referent TermReference
      -> DefnsF2 (Map Name) Synhashed Referent TermReference)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GThreeWay PartialDeclNameLookup DeclNameLookup
-> TwoWay DeclNameLookup
forall a b. GThreeWay a b -> TwoWay b
ThreeWay.gforgetLca GThreeWay PartialDeclNameLookup DeclNameLookup
declNameLookups
            TwoWay
  (DefnsF (Map Name) Referent TermReference
   -> DefnsF2 (Map Name) Synhashed Referent TermReference)
-> TwoWay (DefnsF (Map Name) Referent TermReference)
-> TwoWay (DefnsF2 (Map Name) Synhashed Referent TermReference)
forall a b. TwoWay (a -> b) -> TwoWay a -> TwoWay b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> TwoWay (DefnsF (Map Name) Referent TermReference)
newDefns
        )
  where
    oldDefns :: TwoWay (DefnsF (Map Name) Referent TermReference)
oldDefns = (.old) (Updated (DefnsF (Map Name) Referent TermReference)
 -> DefnsF (Map Name) Referent TermReference)
-> TwoWay (Updated (DefnsF (Map Name) Referent TermReference))
-> TwoWay (DefnsF (Map Name) Referent TermReference)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TwoWay (Updated (DefnsF (Map Name) Referent TermReference))
defns
    newDefns :: TwoWay (DefnsF (Map Name) Referent TermReference)
newDefns = (.new) (Updated (DefnsF (Map Name) Referent TermReference)
 -> DefnsF (Map Name) Referent TermReference)
-> TwoWay (Updated (DefnsF (Map Name) Referent TermReference))
-> TwoWay (DefnsF (Map Name) Referent TermReference)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TwoWay (Updated (DefnsF (Map Name) Referent TermReference))
defns

    ppeds :: ThreeWay PrettyPrintEnvDecl
    ppeds :: ThreeWay PrettyPrintEnvDecl
ppeds =
      ThreeWay Names
allNames ThreeWay Names
-> (Names -> PrettyPrintEnvDecl) -> ThreeWay PrettyPrintEnvDecl
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \Names
names -> Namer -> Suffixifier -> PrettyPrintEnvDecl
PPED.makePPED (Names -> Namer
PPE.namer Names
names) (Names -> Suffixifier
PPE.suffixifyByHash Names
names)

    ppe :: PrettyPrintEnv
    ppe :: PrettyPrintEnv
ppe =
      ThreeWay PrettyPrintEnvDecl
ppeds.alice.unsuffixifiedPPE
        PrettyPrintEnv -> PrettyPrintEnv -> PrettyPrintEnv
`PPE.addFallback` ThreeWay PrettyPrintEnvDecl
ppeds.bob.unsuffixifiedPPE
        PrettyPrintEnv -> PrettyPrintEnv -> PrettyPrintEnv
`PPE.addFallback` ThreeWay PrettyPrintEnvDecl
ppeds.lca.unsuffixifiedPPE

toLabeledDependencies ::
  (Foldable f) =>
  DefnsF f (TermReferenceId, (Term Symbol Ann, Type Symbol Ann)) (TypeReferenceId, Decl Symbol Ann) ->
  Set LabeledDependency
toLabeledDependencies :: forall (f :: * -> *).
Foldable f =>
DefnsF
  f
  (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
  (TermReferenceId, Decl Symbol Ann)
-> Set LabeledDependency
toLabeledDependencies DefnsF
  f
  (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
  (TermReferenceId, Decl Symbol Ann)
defns =
  Set LabeledDependency
-> Set LabeledDependency -> Set LabeledDependency
forall a. Ord a => Set a -> Set a -> Set a
Set.union
    ( DefnsF
  f
  (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
  (TermReferenceId, Decl Symbol Ann)
defns.terms f (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
-> (f (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
    -> Set LabeledDependency)
-> Set LabeledDependency
forall a b. a -> (a -> b) -> b
& ((TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
 -> Set LabeledDependency)
-> f (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
-> Set LabeledDependency
forall m a. Monoid m => (a -> m) -> f a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap \(TermReferenceId
ref, (Term Symbol Ann
term, Type Symbol Ann
typ)) ->
        LabeledDependency -> Set LabeledDependency -> Set LabeledDependency
forall a. Ord a => a -> Set a -> Set a
Set.insert
          (TermReferenceId -> LabeledDependency
LabeledDependency.derivedTerm TermReferenceId
ref)
          (Term Symbol Ann -> Set LabeledDependency
forall v vt at ap a.
(Ord v, Ord vt) =>
Term2 vt at ap v a -> Set LabeledDependency
Term.labeledDependencies Term Symbol Ann
term Set LabeledDependency
-> Set LabeledDependency -> Set LabeledDependency
forall a. Semigroup a => a -> a -> a
<> Type Symbol Ann -> Set LabeledDependency
forall v a. Ord v => Type v a -> Set LabeledDependency
Type.labeledDependencies Type Symbol Ann
typ)
    )
    ( DefnsF
  f
  (TermReferenceId, (Term Symbol Ann, Type Symbol Ann))
  (TermReferenceId, Decl Symbol Ann)
defns.types f (TermReferenceId, Decl Symbol Ann)
-> (f (TermReferenceId, Decl Symbol Ann) -> Set LabeledDependency)
-> Set LabeledDependency
forall a b. a -> (a -> b) -> b
& ((TermReferenceId, Decl Symbol Ann) -> Set LabeledDependency)
-> f (TermReferenceId, Decl Symbol Ann) -> Set LabeledDependency
forall m a. Monoid m => (a -> m) -> f a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap \(TermReferenceId
ref, Decl Symbol Ann
decl) ->
        TermReference -> Decl Symbol Ann -> Set LabeledDependency
forall v a.
Var v =>
TermReference -> Decl v a -> Set LabeledDependency
Decl.labeledDeclDependenciesIncludingSelfAndFieldAccessors (TermReferenceId -> TermReference
forall h t. Id' h -> Reference' t h
Reference.DerivedId TermReferenceId
ref) Decl Symbol Ann
decl
    )