Skip to content

Commit a330f60

Browse files
authored
Merge pull request #5876 from unisonweb/cp/ucm-dependents-api
2 parents 68a68d2 + e16ced0 commit a330f60

File tree

18 files changed

+1423
-284
lines changed

18 files changed

+1423
-284
lines changed

codebase2/codebase-sqlite/U/Codebase/Sqlite/Queries.hs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1878,6 +1878,9 @@ getDirectDependenciesOfScope isBuiltinType scope = do
18781878
SELECT object_id, component_index
18791879
FROM $tempTableName
18801880
)
1881+
AND
1882+
-- Filter out self-dependencies
1883+
((d.dependency_object_id, d.dependency_component_index) IS DISTINCT FROM (d.dependent_object_id, d.dependent_component_index))
18811884
|]
18821885

18831886
-- Drop the temporary table
@@ -1930,6 +1933,9 @@ getDirectDependentsWithinScope scope query = do
19301933
ON d.dependent_object_id = s.object_id
19311934
AND d.dependent_component_index = s.component_index
19321935
JOIN object o ON s.object_id = o.id
1936+
WHERE
1937+
-- Filter out self-dependents
1938+
((d.dependency_object_id, d.dependency_component_index) IS DISTINCT FROM (d.dependent_object_id, d.dependent_component_index))
19331939
|]
19341940

19351941
-- Drop the temporary tables
@@ -1990,11 +1996,13 @@ getTransitiveDependentsWithinScope scope query = do
19901996
WITH RECURSIVE
19911997
dependents_index_in_scope AS (
19921998
SELECT *
1993-
FROM dependents_index
1994-
WHERE (dependent_object_id, dependent_component_index) IN (
1999+
FROM dependents_index d
2000+
WHERE (d.dependent_object_id, d.dependent_component_index) IN (
19952001
SELECT object_id, component_index
19962002
FROM $scopeTableName
19972003
)
2004+
-- Ignore self-dependents
2005+
AND ((d.dependency_object_id, d.dependency_component_index) IS DISTINCT FROM (d.dependent_object_id, d.dependent_component_index))
19982006
),
19992007
transitive_dependents (object_id, component_index, type_id) AS (
20002008
SELECT d.dependent_object_id, d.dependent_component_index, o.type_id

parser-typechecker/src/Unison/Codebase.hs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,11 @@ module Unison.Codebase
9696
SqliteCodebase.Operations.hashLength,
9797
SqliteCodebase.Operations.branchHashLength,
9898

99-
-- * Dependents
99+
-- * Dependents/Dependencies
100100
dependents,
101101
dependentsOfComponent,
102+
dependentsWithinBranchScope,
103+
directDependencies,
102104

103105
-- * Sync
104106

@@ -124,6 +126,7 @@ module Unison.Codebase
124126
where
125127

126128
import Control.Monad.Except (ExceptT)
129+
import Data.Bifoldable (Bifoldable (..))
127130
import Data.Map qualified as Map
128131
import Data.Set qualified as Set
129132
import Data.Text qualified as Text
@@ -173,8 +176,10 @@ import Unison.Typechecker.TypeLookup (TypeLookup (TypeLookup))
173176
import Unison.Typechecker.TypeLookup qualified as TL
174177
import Unison.UnisonFile qualified as UF
175178
import Unison.Util.Defns (Defns (..), DefnsF)
179+
import Unison.Util.Defns qualified as Defns
176180
import Unison.Util.Recursion (XNor (Both, Neither), cata)
177181
import Unison.Util.Relation qualified as Rel
182+
import Unison.Util.Set qualified as Set
178183
import Unison.Var (Var)
179184
import Unison.WatchKind qualified as WK
180185

@@ -521,6 +526,36 @@ dependentsOfComponent h =
521526
. Set.map Reference.DerivedId
522527
<$> SqliteCodebase.Operations.dependentsOfComponentImpl h
523528

529+
-- | Find direct dependents of any provided definitions which are within the provided branch.
530+
--
531+
-- Note: You may wish to delete lib deps beforehand.
532+
dependentsWithinBranchScope :: Branch.Branch0 m -> (DefnsF Set Referent.Referent Reference.TypeReference) -> Sqlite.Transaction (DefnsF Set TermReferenceId Reference.TypeReferenceId)
533+
dependentsWithinBranchScope branch0 refs = do
534+
Operations.directDependentsWithinScope
535+
( Set.union
536+
(Set.mapMaybe Reference.toId (Branch.deepTypeReferences branch0))
537+
(Set.mapMaybe Referent.toTermReferenceId (Branch.deepReferents branch0))
538+
)
539+
(bifoldMap (Set.map Referent.toReference) id refs)
540+
541+
directDependencies ::
542+
(DefnsF Set Referent.Referent Reference.TypeReference) ->
543+
Sqlite.Transaction (DefnsF Set TermReference TypeReference)
544+
directDependencies refs = do
545+
Operations.directDependenciesOfScope
546+
Builtin.isBuiltinType
547+
( let refToIds :: Reference -> Set Reference.Id
548+
refToIds =
549+
maybe Set.empty Set.singleton . Reference.toId
550+
in bifoldMap
551+
( foldMap \case
552+
Referent.Con ref _ -> Defns.fromTypes (refToIds (ref ^. ConstructorReference.reference_))
553+
Referent.Ref ref -> Defns.fromTerms (refToIds ref)
554+
)
555+
(foldMap (refToIds >>> Defns.fromTypes))
556+
refs
557+
)
558+
524559
-- | Get the set of terms-or-constructors that have the given type.
525560
termsOfType :: (Var v) => Codebase m v a -> Type v a -> Sqlite.Transaction (Set Referent.Referent)
526561
termsOfType c ty = termsOfTypeByReference c $ Hashing.typeToReference ty

unison-cli/src/Unison/Codebase/Editor/HandleInput/Dependencies.hs

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,14 @@ where
66
import Control.Arrow ((***))
77
import Data.Bifoldable (bifoldMap, binull)
88
import Data.Set qualified as Set
9-
import U.Codebase.Sqlite.Operations qualified as Operations
10-
import Unison.Builtin qualified as Builtin
119
import Unison.Cli.Monad (Cli)
1210
import Unison.Cli.Monad qualified as Cli
1311
import Unison.Cli.MonadUtils qualified as Cli
1412
import Unison.Cli.NameResolutionUtils (resolveHQName)
13+
import Unison.Codebase qualified as Codebase
1514
import Unison.Codebase.Branch.Names qualified as Branch
1615
import Unison.Codebase.Editor.Output
1716
import Unison.Codebase.Editor.StructuredArgument qualified as SA
18-
import Unison.ConstructorReference qualified as ConstructorReference
1917
import Unison.HashQualified qualified as HQ
2018
import Unison.HashQualifiedPrime qualified as HQ'
2119
import Unison.LabeledDependency qualified as LD
@@ -25,11 +23,9 @@ import Unison.Prelude
2523
import Unison.PrettyPrintEnv qualified as PPE
2624
import Unison.PrettyPrintEnv.Names qualified as PPE
2725
import Unison.Reference (Reference)
28-
import Unison.Reference qualified as Reference
2926
import Unison.Referent qualified as Referent
3027
import Unison.Syntax.HashQualifiedPrime qualified as HQ'
3128
import Unison.Util.Defns (Defns (..), DefnsF)
32-
import Unison.Util.Defns qualified as Defns
3329

3430
handleDependencies :: HQ.HashQualified Name -> Cli ()
3531
handleDependencies hq = do
@@ -44,20 +40,7 @@ handleDependencies hq = do
4440
in PPE.makePPE (PPE.hqNamer 10 names) (PPE.suffixifyByHash names)
4541

4642
dependencies <- do
47-
Cli.runTransaction do
48-
Operations.directDependenciesOfScope
49-
Builtin.isBuiltinType
50-
( let refToIds :: Reference -> Set Reference.Id
51-
refToIds =
52-
maybe Set.empty Set.singleton . Reference.toId
53-
in bifoldMap
54-
( foldMap \case
55-
Referent.Con ref _ -> Defns.fromTypes (refToIds (ref ^. ConstructorReference.reference_))
56-
Referent.Ref ref -> Defns.fromTerms (refToIds ref)
57-
)
58-
(foldMap (refToIds >>> Defns.fromTypes))
59-
refs
60-
)
43+
Cli.runTransaction $ Codebase.directDependencies refs
6144

6245
let dependencyNames ::
6346
DefnsF

unison-cli/src/Unison/Codebase/Editor/HandleInput/Dependents.hs

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ where
55

66
import Data.Bifoldable (bifoldMap, binull)
77
import Data.Set qualified as Set
8-
import U.Codebase.Sqlite.Operations qualified as Operations
98
import Unison.Cli.Monad (Cli)
109
import Unison.Cli.Monad qualified as Cli
1110
import Unison.Cli.MonadUtils qualified as Cli
1211
import Unison.Cli.NameResolutionUtils (resolveHQName)
12+
import Unison.Codebase qualified as Codebase
1313
import Unison.Codebase.Branch qualified as Branch
1414
import Unison.Codebase.Branch.Names qualified as Branch
1515
import Unison.Codebase.Editor.Output
@@ -24,9 +24,8 @@ import Unison.PrettyPrintEnv qualified as PPE
2424
import Unison.PrettyPrintEnv.Names qualified as PPE
2525
import Unison.Reference qualified as Reference
2626
import Unison.Referent qualified as Referent
27-
import Unison.Syntax.HashQualifiedPrime qualified as HQ' (toText)
27+
import Unison.Syntax.HashQualifiedPrime qualified as HQ'
2828
import Unison.Util.Defns (Defns (..), DefnsF)
29-
import Unison.Util.Set qualified as Set
3029

3130
handleDependents :: HQ.HashQualified Name -> Cli ()
3231
handleDependents hq = do
@@ -36,23 +35,11 @@ handleDependents hq = do
3635
Cli.returnEarly (LabeledReferenceNotFound hq)
3736

3837
namespace <- Cli.getCurrentProjectRoot0
39-
let ppe =
40-
let names = Branch.toNames namespace
41-
in PPE.makePPE (PPE.hqNamer 10 names) (PPE.suffixifyByHash names)
42-
4338
let namespaceWithoutLibdeps = Branch.deleteLibdeps namespace
4439
let ppeWithoutLibdeps =
4540
let names = Branch.toNames namespaceWithoutLibdeps
4641
in PPE.makePPE (PPE.hqNamer 10 names) (PPE.suffixifyByHash names)
47-
48-
dependents <- do
49-
Cli.runTransaction do
50-
Operations.directDependentsWithinScope
51-
( Set.union
52-
(Set.mapMaybe Reference.toId (Branch.deepTypeReferences namespaceWithoutLibdeps))
53-
(Set.mapMaybe Referent.toTermReferenceId (Branch.deepReferents namespaceWithoutLibdeps))
54-
)
55-
(bifoldMap (Set.map Referent.toReference) id refs)
42+
dependents <- Cli.runTransaction $ Codebase.dependentsWithinBranchScope namespaceWithoutLibdeps refs
5643

5744
let dependentNames ::
5845
DefnsF
@@ -69,11 +56,15 @@ handleDependents hq = do
6956
Set.toList
7057
>>> mapMaybe (g >>> listToMaybe)
7158
>>> Name.sortByText (fst >>> HQ'.toText)
72-
7359
-- Set numbered args
7460
(dependentNames.types ++ dependentNames.terms)
7561
& map (SA.HashQualified . HQ'.toHQ . fst)
7662
& Cli.setNumberedArgs
7763

7864
let lds = bifoldMap (Set.map LD.referent) (Set.map LD.typeRef) refs
65+
66+
let ppe =
67+
let names = Branch.toNames namespace
68+
in PPE.makePPE (PPE.hqNamer 10 names) (PPE.suffixifyByHash names)
69+
7970
Cli.respond (ListDependents ppe lds dependentNames)

unison-share-api/src/Unison/Server/Backend.hs

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ module Unison.Server.Backend
4747
termEntryLabeledDependencies,
4848
termListEntry,
4949
Codebase.termReferentsByShortHash,
50+
termSummaryForReferent,
51+
typeSummaryForReference,
5052
typeDeclHeader,
5153
typeEntryDisplayName,
5254
typeEntryHQName,
@@ -58,6 +60,8 @@ module Unison.Server.Backend
5860
renderDocRefs,
5961
docsForDefinitionName,
6062
normaliseRootCausalHash,
63+
resolveProjectRootHash,
64+
resolveProjectRoot,
6165

6266
-- * Unused, could remove?
6367
resolveRootBranchHash,
@@ -97,6 +101,7 @@ import System.Directory
97101
import System.FilePath
98102
import Text.FuzzyFind qualified as FZF
99103
import U.Codebase.Branch (NamespaceStats (..))
104+
import U.Codebase.Branch qualified as V2
100105
import U.Codebase.Branch qualified as V2Branch
101106
import U.Codebase.Causal qualified as V2Causal
102107
import U.Codebase.HashTags (BranchHash, CausalHash (..))
@@ -144,7 +149,7 @@ import Unison.PrettyPrintEnv qualified as PPE
144149
import Unison.PrettyPrintEnv.Names qualified as PPE
145150
import Unison.PrettyPrintEnv.Util qualified as PPE
146151
import Unison.PrettyPrintEnvDecl qualified as PPED
147-
import Unison.Project (ProjectBranchName, ProjectName)
152+
import Unison.Project (ProjectAndBranch (..), ProjectBranchName, ProjectName)
148153
import Unison.Reference (Reference, TermReference, TypeReference)
149154
import Unison.Reference qualified as Reference
150155
import Unison.Referent (Referent)
@@ -1236,3 +1241,73 @@ loadTypeDisplayObject c = \case
12361241
Reference.DerivedId id ->
12371242
maybe (MissingObject $ Reference.idToShortHash id) UserObject
12381243
<$> Codebase.getTypeDeclaration c id
1244+
1245+
resolveProjectRoot :: Codebase IO v a -> ProjectAndBranch ProjectName ProjectBranchName -> Backend IO (V2.CausalBranch Sqlite.Transaction)
1246+
resolveProjectRoot codebase projectAndBranchName@(ProjectAndBranch projectName branchName) = do
1247+
mayCB <- liftIO . Codebase.runTransaction codebase $ Codebase.getShallowProjectRootByNames projectAndBranchName
1248+
case mayCB of
1249+
Nothing -> throwError (ProjectBranchNameNotFound projectName branchName)
1250+
Just cb -> pure cb
1251+
1252+
resolveProjectRootHash :: Codebase IO v a -> ProjectAndBranch ProjectName ProjectBranchName -> Backend IO CausalHash
1253+
resolveProjectRootHash codebase projectAndBranchName = do
1254+
resolveProjectRoot codebase projectAndBranchName <&> V2Causal.causalHash
1255+
1256+
termSummaryForReferent ::
1257+
Codebase IO Symbol Ann ->
1258+
Referent ->
1259+
Maybe Name ->
1260+
(Set LD.LabeledDependency -> Sqlite.Transaction PPED.PrettyPrintEnvDecl) ->
1261+
Maybe Width ->
1262+
Backend IO TermSummary
1263+
termSummaryForReferent codebase referent mayName mkPPE mayWidth = do
1264+
let shortHash = Referent.toShortHash referent
1265+
let termReference = Referent.toReference referent
1266+
let v2Referent = Cv.referent1to2 referent
1267+
1268+
sig <- hoistBackend (Codebase.runTransaction codebase) do
1269+
sig <- lift (loadReferentType codebase referent)
1270+
pure sig
1271+
case sig of
1272+
Nothing ->
1273+
throwError (MissingSignatureForTerm termReference)
1274+
Just typeSig -> do
1275+
let deps = Type.labeledDependencies typeSig
1276+
pped <- lift . Codebase.runTransaction codebase $ mkPPE deps
1277+
let formattedTermSig = formatSuffixedType pped width typeSig
1278+
let summary = mkSummary termReference formattedTermSig
1279+
tag <- lift $ getTermTag codebase v2Referent sig
1280+
let displayName = PPE.termName (PPED.unsuffixifiedPPE pped) referent
1281+
pure $ TermSummary (maybe displayName HQ.NameOnly mayName) shortHash summary tag
1282+
where
1283+
width = mayDefaultWidth mayWidth
1284+
mkSummary reference termSig =
1285+
if Reference.isBuiltin reference
1286+
then BuiltinObject termSig
1287+
else UserObject termSig
1288+
1289+
typeSummaryForReference ::
1290+
Codebase IO Symbol Ann ->
1291+
Reference ->
1292+
Maybe Name ->
1293+
(Set LD.LabeledDependency -> Sqlite.Transaction PPED.PrettyPrintEnvDecl) ->
1294+
Maybe Width ->
1295+
Backend IO TypeSummary
1296+
typeSummaryForReference codebase reference mayName mkPPED mayWidth = do
1297+
let shortHash = Reference.toShortHash reference
1298+
lift do
1299+
Codebase.runTransaction codebase do
1300+
pped <- mkPPED $ Set.singleton (LD.TypeReference reference)
1301+
let displayName = PPE.typeName (PPED.unsuffixifiedPPE pped) reference
1302+
tag <- getTypeTag codebase reference
1303+
displayDecl <- displayType codebase reference
1304+
let syntaxHeader = typeToSyntaxHeader width displayName displayDecl
1305+
pure $
1306+
TypeSummary
1307+
{ displayName = (maybe displayName HQ.NameOnly mayName),
1308+
hash = shortHash,
1309+
summary = bimap mungeSyntaxText mungeSyntaxText syntaxHeader,
1310+
tag = tag
1311+
}
1312+
where
1313+
width = mayDefaultWidth mayWidth

0 commit comments

Comments
 (0)