1
1
module Unison.Server.NameSearch.Postgres
2
2
( NameSearch (.. ),
3
3
nameSearchForPerspective ,
4
+
5
+ -- * Searches are also exported A'la carte.
6
+ termRefsByHQNamesOf ,
7
+ typeRefsByHQNamesOf ,
4
8
)
5
9
where
6
10
7
11
import Control.Lens
8
12
import Data.Set qualified as Set
9
- import Share.Codebase qualified as Codebase
13
+ import Share.Postgres ( QueryM )
10
14
import Share.Postgres qualified as PG
11
15
import Share.Postgres.NameLookups.Conversions qualified as CV
12
16
import Share.Postgres.NameLookups.Ops as NLOps
13
17
import Share.Postgres.NameLookups.Queries (ShouldSuffixify (NoSuffixify ))
14
18
import Share.Postgres.NameLookups.Types
15
19
import Share.Postgres.NamesPerspective.Types (NamesPerspective , perspectiveCurrentMountPathPrefix )
16
20
import Share.Prelude
17
- import Unison.Codebase.Path qualified as Path
18
21
import Unison.HashQualifiedPrime qualified as HQ'
19
22
import Unison.Name (Name )
20
23
import Unison.Name qualified as Name
@@ -25,6 +28,7 @@ import Unison.Reference qualified as V1Reference
25
28
import Unison.Referent qualified as V1Referent
26
29
import Unison.Server.NameSearch (NameSearch (.. ), Search (.. ))
27
30
import Unison.Server.SearchResult qualified as SR
31
+ import Unison.ShortHash qualified as V1ShortHash
28
32
29
33
nameSearchForPerspective :: forall m . (PG. QueryM m ) => NamesPerspective m -> NameSearch m
30
34
nameSearchForPerspective namesPerspective =
@@ -39,7 +43,7 @@ nameSearchForPerspective namesPerspective =
39
43
{ lookupNames = lookupNamesForTypes,
40
44
lookupRelativeHQRefs' = \ searchType hqname ->
41
45
case searchType of
42
- ExactName -> hqTypeSearch . fmap stripMountPathPrefix $ hqname
46
+ ExactName -> typeRefsByHQNamesOf namesPerspective id . fmap stripMountPathPrefix $ hqname
43
47
-- We can implement this, but it's not currently used anywhere on share.
44
48
IncludeSuffixes -> error " Suffix search not yet implemented on Share" ,
45
49
makeResult = \ hqname r names -> pure $ SR. typeResult hqname r names,
@@ -50,7 +54,7 @@ nameSearchForPerspective namesPerspective =
50
54
{ lookupNames = lookupNamesForTerms,
51
55
lookupRelativeHQRefs' = \ searchType hqname ->
52
56
case searchType of
53
- ExactName -> hqTermSearch . fmap stripMountPathPrefix $ hqname
57
+ ExactName -> termRefsByHQNamesOf namesPerspective id . fmap stripMountPathPrefix $ hqname
54
58
-- We can implement this, but it's not currently used anywhere on share.
55
59
IncludeSuffixes -> error " Suffix search not yet implemented on Share" ,
56
60
makeResult = \ hqname r names -> pure $ SR. termResult hqname r names,
@@ -73,68 +77,58 @@ nameSearchForPerspective namesPerspective =
73
77
& fmap (\ (fqnSegments, _suffixSegments) -> HQ'. HashQualified (reversedSegmentsToName fqnSegments) (V1Referent. toShortHash ref))
74
78
& Set. fromList
75
79
& pure
76
- -- Search the codebase for matches to the given hq name.
77
- hqTermSearch :: HQ'. HashQualified Name -> m (Set V1Referent. Referent )
78
- hqTermSearch hqName = do
79
- case hqName of
80
- HQ'. NameOnly name -> do
81
- namedRefs <- NLOps. termRefsForExactNamesOf namesPerspective id (coerce $ Name. reverseSegments name)
82
- namedRefs
83
- & fmap (\ (NamedRef {ref}) -> ref)
84
- & Set. fromList
85
- & pure
86
- HQ'. HashQualified name sh -> do
87
- let fqn = fullyQualifyName name
88
- termRefsV1 <-
89
- Set. toList <$> Codebase. termReferentsByShortHash sh
90
- termRefsPG <- catMaybes <$> CV. referents1ToPGOf traversed termRefsV1
91
- names <-
92
- NLOps. termNamesForRefsWithinNamespaceOf namesPerspective (Just . coerce $ Name. reverseSegments name) NoSuffixify traversed termRefsPG
93
- <&> (fmap . fmap ) fst -- Only need the fqn
94
- zip termRefsV1 names
95
- & mapMaybe
96
- ( \ (termRef, matches) ->
97
- -- Return a valid ref if at least one match was found.
98
- if any (\ n -> ReversedName (coerce @ (NonEmpty NameSegment ) @ (NonEmpty Text ) $ Name. reverseSegments fqn) == n) matches
99
- then (Just termRef)
100
- else Nothing
101
- )
102
- & Set. fromList
103
- & pure
104
-
105
- -- Search the codebase for matches to the given hq name.
106
- hqTypeSearch :: HQ'. HashQualified Name -> m (Set V1. Reference )
107
- hqTypeSearch hqName = do
108
- case hqName of
109
- HQ'. NameOnly name -> do
110
- namedRefs <- NLOps. typeRefsForExactNamesOf namesPerspective id (coerce $ Name. reverseSegments name)
111
- namedRefs
112
- & fmap (\ NamedRef {ref} -> ref)
113
- & Set. fromList
114
- & pure
115
- HQ'. HashQualified name sh -> do
116
- let fqn = fullyQualifyName name
117
- typeRefs <- Set. toList <$> Codebase. typeReferencesByShortHash sh
118
- typeRefsPG <- catMaybes <$> CV. references1ToPGOf traversed typeRefs
119
- names <-
120
- NLOps. typeNamesForRefsWithinNamespaceOf namesPerspective (Just . coerce $ Name. reverseSegments name) NoSuffixify traversed typeRefsPG
121
- <&> (fmap . fmap ) fst -- Only need the fqn
122
- zip typeRefs names
123
- & mapMaybe
124
- ( \ (typeRef, matches) ->
125
- -- Return a valid ref if at least one match was found.
126
- if any (\ n -> ReversedName (coerce @ (NonEmpty NameSegment ) @ (NonEmpty Text ) $ Name. reverseSegments fqn) == n) matches
127
- then Just typeRef
128
- else Nothing
129
- )
130
- & Set. fromList
131
- & pure
132
80
133
81
reversedSegmentsToName :: ReversedName -> Name
134
82
reversedSegmentsToName = Name. fromReverseSegments . coerce
135
83
136
- -- Fully qualify a name by prepending the current namespace perspective's path
137
- fullyQualifyName :: Name -> Name
138
- fullyQualifyName name =
139
- -- TODO: Is it actually correct to do this?
140
- fromMaybe name $ Path. maybePrefixName (Path. AbsolutePath' $ Path. Absolute (Path. fromList . (fmap NameSegment ) . into @ [Text ] $ perspectiveCurrentMountPathPrefix namesPerspective)) name
84
+ -- | Search the codebase for terms which exactly match the hq name.
85
+ termRefsByHQNamesOf ::
86
+ (QueryM m ) =>
87
+ NamesPerspective m ->
88
+ Traversal s t (HQ'. HashQualified Name ) (Set V1Referent. Referent ) ->
89
+ s ->
90
+ m t
91
+ termRefsByHQNamesOf namesPerspective trav s = do
92
+ s
93
+ & asListOf trav %%~ \ hqNames -> do
94
+ let tupled =
95
+ hqNames <&> \ case
96
+ HQ'. NameOnly name -> (coerce @ (NonEmpty NameSegment ) @ ReversedName $ Name. reverseSegments name, Nothing )
97
+ HQ'. HashQualified name sh -> (coerce @ (NonEmpty NameSegment ) @ ReversedName $ Name. reverseSegments name, Just sh)
98
+ foundTermRefs <- NLOps. termRefsForExactNamesOf namesPerspective (traversed . _1) tupled
99
+ foundTermRefs
100
+ & over (traversed . _1 . traversed) (\ NamedRef {ref} -> ref)
101
+ <&> ( \ case
102
+ (results, Nothing ) -> results
103
+ (results, Just sh) ->
104
+ results
105
+ & filter (\ ref -> sh `V1ShortHash.isPrefixOf` V1Referent. toShortHash ref)
106
+ )
107
+ <&> Set. fromList
108
+ & pure
109
+
110
+ -- | Search the codebase for types which exactly match the hq name.
111
+ typeRefsByHQNamesOf ::
112
+ (QueryM m ) =>
113
+ NamesPerspective m ->
114
+ Traversal s t (HQ'. HashQualified Name ) (Set V1Reference. Reference ) ->
115
+ s ->
116
+ m t
117
+ typeRefsByHQNamesOf namesPerspective trav s = do
118
+ s
119
+ & asListOf trav %%~ \ hqNames -> do
120
+ let tupled =
121
+ hqNames <&> \ case
122
+ HQ'. NameOnly name -> (coerce @ (NonEmpty NameSegment ) @ ReversedName $ Name. reverseSegments name, Nothing )
123
+ HQ'. HashQualified name sh -> (coerce @ (NonEmpty NameSegment ) @ ReversedName $ Name. reverseSegments name, Just sh)
124
+ foundTypeRefs <- NLOps. typeRefsForExactNamesOf namesPerspective (traversed . _1) tupled
125
+ foundTypeRefs
126
+ & over (traversed . _1 . traversed) (\ NamedRef {ref} -> ref)
127
+ <&> ( \ case
128
+ (results, Nothing ) -> results
129
+ (results, Just sh) ->
130
+ results
131
+ & filter (\ ref -> sh `V1ShortHash.isPrefixOf` V1Reference. toShortHash ref)
132
+ )
133
+ <&> Set. fromList
134
+ & pure
0 commit comments