module Unison.Codebase.Editor.HandleInput.EditDependents
( handleEditDependents,
)
where
import Control.Monad.Reader (ask)
import Data.Set qualified as Set
import U.Codebase.Sqlite.Operations qualified as Operations
import Unison.Cli.Monad (Cli)
import Unison.Cli.Monad qualified as Cli
import Unison.Cli.MonadUtils qualified as Cli
import Unison.Cli.NameResolutionUtils (resolveHQName)
import Unison.Codebase.Branch qualified as Branch
import Unison.Codebase.Branch.Names qualified as Branch
import Unison.Codebase.Editor.HandleInput.EditNamespace (getNamesForEdit)
import Unison.Codebase.Editor.HandleInput.ShowDefinition (showDefinitions)
import Unison.Codebase.Editor.Input (OutputLocation (..), RelativeToFold (..))
import Unison.Codebase.Editor.Output qualified as Output
import Unison.ConstructorReference qualified as ConstructorReference
import Unison.HashQualified qualified as HQ
import Unison.Name (Name)
import Unison.Names (Names (..))
import Unison.Prelude
import Unison.PrettyPrintEnv.Names qualified as PPE
import Unison.PrettyPrintEnvDecl qualified as PPED
import Unison.Reference (TermReference, TypeReference)
import Unison.Reference qualified as Reference
import Unison.Referent qualified as Referent
import Unison.Util.Defns (Defns (..), DefnsF)
import Unison.Util.Defns qualified as Defns
import Unison.Util.Relation qualified as Relation
handleEditDependents :: HQ.HashQualified Name -> Cli ()
handleEditDependents :: HashQualified Name -> Cli ()
handleEditDependents HashQualified Name
name = do
refs0 <- HashQualified Name -> Cli (DefnsF Set Referent TermReference)
resolveHQName HashQualified Name
name
let refs :: DefnsF Set TermReference TypeReference
refs =
let f :: Referent -> DefnsF Set TermReference TermReference
f = \case
Referent.Con ConstructorReference
ref ConstructorType
_ -> Set TermReference -> DefnsF Set TermReference TermReference
forall terms types. Monoid terms => types -> Defns terms types
Defns.fromTypes (TermReference -> Set TermReference
forall a. a -> Set a
Set.singleton (ConstructorReference
ref ConstructorReference
-> Getting TermReference ConstructorReference TermReference
-> TermReference
forall s a. s -> Getting a s a -> a
^. Getting TermReference ConstructorReference TermReference
forall r s (f :: * -> *).
Functor f =>
(r -> f s)
-> GConstructorReference r -> f (GConstructorReference s)
ConstructorReference.reference_))
Referent.Ref TermReference
ref -> Set TermReference -> DefnsF Set TermReference TermReference
forall types terms. Monoid types => terms -> Defns terms types
Defns.fromTerms (TermReference -> Set TermReference
forall a. a -> Set a
Set.singleton TermReference
ref)
in Set TermReference
-> Set TermReference -> DefnsF Set TermReference TermReference
forall terms types. terms -> types -> Defns terms types
Defns Set TermReference
forall a. Set a
Set.empty DefnsF Set Referent TermReference
refs0.types DefnsF Set TermReference TermReference
-> DefnsF Set TermReference TermReference
-> DefnsF Set TermReference TermReference
forall a. Semigroup a => a -> a -> a
<> (Referent -> DefnsF Set TermReference TermReference)
-> Set Referent -> DefnsF Set TermReference TermReference
forall m a. Monoid m => (a -> m) -> Set a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Referent -> DefnsF Set TermReference TermReference
f DefnsF Set Referent TermReference
refs0.terms
(ppe, types, terms) <-
Cli.withRespondRegion \Output -> Cli ()
respondRegion -> do
Output -> Cli ()
respondRegion (Pretty ColorText -> Output
Output.Literal Pretty ColorText
"Loading branch...")
branch <- Cli (Branch0 IO)
Cli.getCurrentBranch0
let ppe =
let names :: Names
names = Branch0 IO -> Names
forall (m :: * -> *). Branch0 m -> Names
Branch.toNames Branch0 IO
branch
in Namer -> Suffixifier -> PrettyPrintEnvDecl
PPED.makePPED (Int -> Names -> Namer
PPE.hqNamer Int
10 Names
names) (Names -> Suffixifier
PPE.suffixifyByHashName Names
names)
let branchWithoutLibdeps = Branch0 IO -> Branch0 IO
forall (m :: * -> *). Branch0 m -> Branch0 m
Branch.deleteLibdeps Branch0 IO
branch
respondRegion (Output.Literal "Identifying dependents...")
dependents <-
Cli.runTransaction do
Operations.transitiveDependentsWithinScope
(Branch.deepDefnsIds branchWithoutLibdeps)
refs
let refsAndDependents =
Defns
{ terms :: Set Referent
terms =
[Set Referent] -> Set Referent
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions
[ (TermReference -> Referent) -> Set TermReference -> Set Referent
forall a b. (a -> b) -> Set a -> Set b
Set.mapMonotonic TermReference -> Referent
Referent.fromTermReference DefnsF Set TermReference TermReference
refs.terms,
(TermReferenceId -> Referent)
-> Set TermReferenceId -> Set Referent
forall a b. (a -> b) -> Set a -> Set b
Set.mapMonotonic TermReferenceId -> Referent
Referent.fromTermReferenceId DefnsF Set TermReferenceId TermReferenceId
dependents.terms
],
types :: Set TermReference
types =
[Set TermReference] -> Set TermReference
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions
[ DefnsF Set TermReference TermReference
refs.types,
(TermReferenceId -> TermReference)
-> Set TermReferenceId -> Set TermReference
forall a b. (a -> b) -> Set a -> Set b
Set.mapMonotonic TermReferenceId -> TermReference
Reference.fromId DefnsF Set TermReferenceId TermReferenceId
dependents.types
]
}
respondRegion (Output.Literal "Loading dependents...")
env <- ask
(types, terms) <-
Cli.runTransaction
( getNamesForEdit
env.codebase
ppe
Names
{ terms =
branchWithoutLibdeps
& Branch.deepTerms
& Relation.restrictDom refsAndDependents.terms
& Relation.swap,
types =
branchWithoutLibdeps
& Branch.deepTypes
& Relation.restrictDom refsAndDependents.types
& Relation.swap
}
)
pure (ppe, types, terms)
let misses = []
showDefinitions (LatestFileLocation WithinFold) (const True) ppe terms types misses