git.iko.soy/rowtype-yoga/purescript-docs-search
on master help sign in
Wrap ModuleName and PackageName strings into newtypes
fd2b46eklntsky
src/Docs/Search/App/SearchResults.purs+25−25
@@ -14,6 +14,7 @@ import Docs.Search.PackageIndex (PackageResult)
14import Docs.Search.SearchResult (ResultInfo(..), SearchResult(..))
14import Docs.Search.SearchResult (ResultInfo(..), SearchResult(..))
15import Docs.Search.TypeDecoder (Constraint(..), FunDep(..), FunDeps(..), Kind(..), QualifiedName(..), Type(..), TypeArgument(..), joinForAlls, joinRows)
15import Docs.Search.TypeDecoder (Constraint(..), FunDep(..), FunDeps(..), Kind(..), QualifiedName(..), Type(..), TypeArgument(..), joinForAlls, joinRows)
16import Docs.Search.TypeIndex (TypeIndex)
16import Docs.Search.TypeIndex (TypeIndex)
17+import Docs.Search.Types (ModuleName(..), packageInfoToString)
17
18
18import Prelude
19import Prelude
19
20
@@ -21,7 +22,7 @@ import Data.Array ((!!))
21import Data.Array as Array
22import Data.Array as Array
22import Data.List as List
23import Data.List as List
23import Data.Maybe (Maybe(..), isJust, fromMaybe)
24import Data.Maybe (Maybe(..), isJust, fromMaybe)
24−import Data.Newtype (wrap)
25+import Data.Newtype (wrap, unwrap)
25import Data.String.CodeUnits (stripSuffix) as String
26import Data.String.CodeUnits (stripSuffix) as String
26import Data.String.Common (null, trim) as String
27import Data.String.Common (null, trim) as String
27import Data.String.Pattern (Pattern(..)) as String
28import Data.String.Pattern (Pattern(..)) as String
@@ -63,7 +64,7 @@ data Query a
63
64
64
65
65data Action
66data Action
66− = SearchResultClicked String
67+ = SearchResultClicked ModuleName
67 | MoreResultsRequested
68 | MoreResultsRequested
68
69
69
70
@@ -145,7 +146,7 @@ handleAction = case _ of
145 location <- Window.location window
146 location <- Window.location window
146 pathname <- Location.pathname location
147 pathname <- Location.pathname location
147 pure $ isJust $
148 pure $ isJust $
148− String.stripSuffix (String.Pattern $ moduleName <> ".html") pathname
149+ String.stripSuffix (String.Pattern $ unwrap moduleName <> ".html") pathname
149
150
150 when onThisPage do
151 when onThisPage do
151 showPageContents
152 showPageContents
@@ -254,7 +255,7 @@ renderPackageResult { name, description, repository } =
254 , HH.a [ HP.class_ (wrap "result__link")
255 , HH.a [ HP.class_ (wrap "result__link")
255 , HP.href $ fromMaybe "" repository # homePageFromRepository
256 , HP.href $ fromMaybe "" repository # homePageFromRepository
256 ]
257 ]
257− [ HH.text name ]
258+ [ HH.text $ unwrap name ]
258 ]
259 ]
259 ]
260 ]
260 ] <>
261 ] <>
@@ -280,9 +281,9 @@ renderModuleResult { name, package } =
280 [ HH.text "M" ]
281 [ HH.text "M" ]
281
282
282 , HH.a [ HP.class_ (wrap "result__link")
283 , HH.a [ HP.class_ (wrap "result__link")
283− , HP.href $ name <> ".html"
284+ , HP.href $ unwrap name <> ".html"
284 ]
285 ]
285− [ HH.text name ]
286+ [ HH.text $ unwrap name ]
286 ]
287 ]
287 ]
288 ]
288 ]
289 ]
@@ -300,7 +301,7 @@ renderSearchResult markdownIt (SearchResult result) =
300 [ HH.a [ HP.class_ (wrap "result__link")
301 [ HH.a [ HP.class_ (wrap "result__link")
301 , HE.onClick $ const $ Just $ SearchResultClicked result.moduleName
302 , HE.onClick $ const $ Just $ SearchResultClicked result.moduleName
302 , HP.href $
303 , HP.href $
303− result.moduleName <> ".html#" <>
304+ unwrap result.moduleName <> ".html#" <>
304 result.hashAnchor <> ":" <> result.name
305 result.hashAnchor <> ":" <> result.name
305 ]
306 ]
306 [ HH.text result.name ]
307 [ HH.text result.name ]
@@ -321,7 +322,7 @@ renderSearchResult markdownIt (SearchResult result) =
321 , HP.title "Package"
322 , HP.title "Package"
322 ]
323 ]
323 [ HH.text "P" ]
324 [ HH.text "P" ]
324− , HH.text result.packageName
325+ , HH.text $ packageInfoToString result.packageInfo
325 ]
326 ]
326
327
327 , HH.span [ HP.class_ (wrap "result__actions__item") ]
328 , HH.span [ HP.class_ (wrap "result__actions__item") ]
@@ -331,7 +332,7 @@ renderSearchResult markdownIt (SearchResult result) =
331 , HP.title "Module"
332 , HP.title "Module"
332 ]
333 ]
333 [ HH.text "M" ]
334 [ HH.text "M" ]
334− , HH.text result.moduleName
335+ , HH.text $ unwrap result.moduleName
335 ]
336 ]
336 ]
337 ]
337 ]
338 ]
@@ -341,7 +342,7 @@ renderResultType
341 :: forall a rest
342 :: forall a rest
342 . { info :: ResultInfo
343 . { info :: ResultInfo
343 , name :: String
344 , name :: String
344− , moduleName :: String
345+ , moduleName :: ModuleName
345 | rest
346 | rest
346 }
347 }
347 -> Array (HH.HTML a Action)
348 -> Array (HH.HTML a Action)
@@ -371,7 +372,7 @@ renderResultType result =
371
372
372renderValueSignature
373renderValueSignature
373 :: forall a rest
374 :: forall a rest
374− . { moduleName :: String
375+ . { moduleName :: ModuleName
375 , name :: String
376 , name :: String
376 | rest
377 | rest
377 }
378 }
@@ -391,7 +392,7 @@ renderTypeClassSignature
391 , arguments :: Array TypeArgument
392 , arguments :: Array TypeArgument
392 , superclasses :: Array Constraint
393 , superclasses :: Array Constraint
393 }
394 }
394− -> { name :: String, moduleName :: String | rest }
395+ -> { name :: String, moduleName :: ModuleName | rest }
395 -> Array (HH.HTML a Action)
396 -> Array (HH.HTML a Action)
396renderTypeClassSignature { fundeps, arguments, superclasses } { name, moduleName } =
397renderTypeClassSignature { fundeps, arguments, superclasses } { name, moduleName } =
397 [ keyword "class"
398 [ keyword "class"
@@ -520,14 +521,14 @@ renderType = case _ of
520 TypeOp qname -> renderQualifiedName true TypeLevel qname
521 TypeOp qname -> renderQualifiedName true TypeLevel qname
521
522
522 TypeApp (TypeApp (TypeConstructor
523 TypeApp (TypeApp (TypeConstructor
523− (QualifiedName { moduleName: [ "Prim" ]
524+ (QualifiedName { moduleNameParts: [ "Prim" ]
524 , name: "Function" })) t1) t2 ->
525 , name: "Function" })) t1) t2 ->
525 HH.span_ [ renderType t1
526 HH.span_ [ renderType t1
526 , syntax " -> "
527 , syntax " -> "
527 , renderType t2
528 , renderType t2
528 ]
529 ]
529
530
530− TypeApp (TypeConstructor (QualifiedName { moduleName: [ "Prim" ]
531+ TypeApp (TypeConstructor (QualifiedName { moduleNameParts: [ "Prim" ]
531 , name: "Record" }))
532 , name: "Record" }))
532 row ->
533 row ->
533 renderRow false row
534 renderRow false row
@@ -635,6 +636,9 @@ renderRow asRow =
635 opening = if asRow then "( " else "{ "
636 opening = if asRow then "( " else "{ "
636 closing = if asRow then " )" else " }"
637 closing = if asRow then " )" else " }"
637
638
639+ primRecord :: QualifiedName
640+ primRecord = QualifiedName { moduleNameParts: [ "Prim" ], name: "Record" }
641+
638
642
639renderConstraint
643renderConstraint
640 :: forall a
644 :: forall a
@@ -652,18 +656,18 @@ renderQualifiedName
652 -> DeclLevel
656 -> DeclLevel
653 -> QualifiedName
657 -> QualifiedName
654 -> HH.HTML a Action
658 -> HH.HTML a Action
655−renderQualifiedName isInfix level (QualifiedName { moduleName, name })
659+renderQualifiedName isInfix level (QualifiedName { moduleNameParts, name })
656 = if isBuiltIn then
660 = if isBuiltIn then
657 HH.text name
661 HH.text name
658 else
662 else
659 HH.a [ HE.onClick $ const $ Just $
663 HH.a [ HE.onClick $ const $ Just $
660− SearchResultClicked moduleNameString
664+ SearchResultClicked $ moduleName
661− , makeHref level isInfix moduleNameString name
665+ , makeHref level isInfix moduleName name
662 ]
666 ]
663 [ HH.text name ]
667 [ HH.text name ]
664 where
668 where
665− moduleNameString = Array.intercalate "." moduleName
669+ moduleName = ModuleName $ Array.intercalate "." $ moduleNameParts
666− isBuiltIn = moduleName !! 0 == Just "Prim"
670+ isBuiltIn = moduleNameParts !! 0 == Just "Prim"
667
671
668
672
669renderKind
673renderKind
@@ -681,20 +685,16 @@ makeHref
681 :: forall t rest
685 :: forall t rest
682 . DeclLevel
686 . DeclLevel
683 -> Boolean
687 -> Boolean
684− -> String
688+ -> ModuleName
685 -> String
689 -> String
686 -> HH.IProp ( href :: String | rest ) t
690 -> HH.IProp ( href :: String | rest ) t
687makeHref level isInfix moduleName name =
691makeHref level isInfix moduleName name =
688 HP.href $
692 HP.href $
689− moduleName <> ".html#" <>
693+ unwrap moduleName <> ".html#" <>
690 declLevelToHashAnchor level <> ":" <>
694 declLevelToHashAnchor level <> ":" <>
691 if isInfix then "type (" <> name <> ")" else name
695 if isInfix then "type (" <> name <> ")" else name
692
696
693
697
694−primRecord :: QualifiedName
695−primRecord = QualifiedName { moduleName: [ "Prim" ], name: "Record" }
696−
697−
698keyword
698keyword
699 :: forall a
699 :: forall a
700 . String
700 . String
src/Docs/Search/App/Sidebar.purs+7−6
@@ -2,9 +2,10 @@ module Docs.Search.App.Sidebar where
2
2
3import Docs.Search.Config (config)
3import Docs.Search.Config (config)
4import Docs.Search.ModuleIndex (PackedModuleIndex)
4import Docs.Search.ModuleIndex (PackedModuleIndex)
5−import Docs.Search.Types (ModuleName, PackageName)
5+import Docs.Search.Types (ModuleName, PackageName(..))
6
6
7import Prelude
7import Prelude
8+
8import Data.Array as Array
9import Data.Array as Array
9import Data.Lens ((.~))
10import Data.Lens ((.~))
10import Data.Lens.Record (prop)
11import Data.Lens.Record (prop)
@@ -12,7 +13,7 @@ import Data.List (foldr)
12import Data.Map (Map)
13import Data.Map (Map)
13import Data.Map as Map
14import Data.Map as Map
14import Data.Maybe (Maybe(..), isJust)
15import Data.Maybe (Maybe(..), isJust)
15−import Data.Newtype (wrap)
16+import Data.Newtype (wrap, unwrap)
16import Data.Set (Set)
17import Data.Set (Set)
17import Data.Set as Set
18import Data.Set as Set
18import Data.Symbol (SProxy(..))
19import Data.Symbol (SProxy(..))
@@ -132,7 +133,7 @@ render { moduleIndex, groupingMode, moduleNames, isIndexHTML } =
132 ]
133 ]
133 where
134 where
134
135
135− renderPackageEntry (packageName /\ modules) =
136+ renderPackageEntry (PackageName packageName /\ modules) =
136 HH.li [ HP.classes [ wrap "li-package" ] ]
137 HH.li [ HP.classes [ wrap "li-package" ] ]
137 [ HH.details_
138 [ HH.details_
138 [ HH.summary_ [ HH.text packageName ]
139 [ HH.summary_ [ HH.text packageName ]
@@ -142,11 +143,11 @@ render { moduleIndex, groupingMode, moduleNames, isIndexHTML } =
142
143
143 renderModuleName moduleName =
144 renderModuleName moduleName =
144 HH.li_
145 HH.li_
145− [ HH.a [ HP.href (moduleName <> ".html") ]
146+ [ HH.a [ HP.href (unwrap moduleName <> ".html") ]
146− [ HH.text moduleName ]
147+ [ HH.text $ unwrap moduleName ]
147 ]
148 ]
148
149
149− packageList :: Array (String /\ Set ModuleName)
150+ packageList :: Array (PackageName /\ Set ModuleName)
150 packageList = Map.toUnfoldable moduleIndex
151 packageList = Map.toUnfoldable moduleIndex
151
152
152
153
src/Docs/Search/Declarations.purs+44−40
@@ -1,10 +1,10 @@
1module Docs.Search.Declarations where
1module Docs.Search.Declarations where
2
2
3import Docs.Search.DocsJson (ChildDeclType(..), ChildDeclaration(..), DeclType(..), Declaration(..), DocsJson(..), SourceSpan)
3import Docs.Search.DocsJson (ChildDeclType(..), ChildDeclaration(..), DeclType(..), Declaration(..), DocsJson(..), SourceSpan)
4−import Docs.Search.Score (Scores)
4+import Docs.Search.Score (Scores, getPackageScore, getPackageScoreForPackageName)
5import Docs.Search.SearchResult (ResultInfo(..), SearchResult(..))
5import Docs.Search.SearchResult (ResultInfo(..), SearchResult(..))
6import Docs.Search.TypeDecoder (Constraint(..), QualifiedName(..), Type(..), Kind, joinForAlls)
6import Docs.Search.TypeDecoder (Constraint(..), QualifiedName(..), Type(..), Kind, joinForAlls)
7−import Docs.Search.Types (ModuleName, PackageName)
7+import Docs.Search.Types (ModuleName(..), PackageName(..), PackageInfo(..))
8
8
9import Prelude
9import Prelude
10
10
@@ -14,7 +14,6 @@ import Data.Array as Array
14import Data.Foldable (foldr)
14import Data.Foldable (foldr)
15import Data.List (List, (:))
15import Data.List (List, (:))
16import Data.List as List
16import Data.List as List
17−import Data.Map as Map
18import Data.Maybe (Maybe(..), fromMaybe)
17import Data.Maybe (Maybe(..), fromMaybe)
19import Data.Newtype (class Newtype, unwrap, wrap)
18import Data.Newtype (class Newtype, unwrap, wrap)
20import Data.Search.Trie (Trie, alter)
19import Data.Search.Trie (Trie, alter)
@@ -24,8 +23,7 @@ import Data.String.Common (toLower)
24import Data.String.Pattern (Pattern(..))
23import Data.String.Pattern (Pattern(..))
25
24
26
25
27−newtype Declarations
28− = Declarations (Trie Char (List SearchResult))
26+newtype Declarations = Declarations (Trie Char (List SearchResult))
29
27
30derive instance newtypeDeclarations :: Newtype Declarations _
28derive instance newtypeDeclarations :: Newtype Declarations _
31derive newtype instance semigroupDeclarations :: Semigroup Declarations
29derive newtype instance semigroupDeclarations :: Semigroup Declarations
@@ -42,7 +40,7 @@ insertDocsJson
42 -> Trie Char (List SearchResult)
40 -> Trie Char (List SearchResult)
43 -> Trie Char (List SearchResult)
41 -> Trie Char (List SearchResult)
44insertDocsJson scores (DocsJson { name, declarations }) trie
42insertDocsJson scores (DocsJson { name, declarations }) trie
45− = foldr (insertDeclaration scores name) trie declarations
43+ = foldr (insertDeclaration scores $ ModuleName name) trie declarations
46
44
47
45
48insertDeclaration
46insertDeclaration
@@ -63,13 +61,13 @@ insertSearchResult
63 -> Trie Char (List SearchResult)
61 -> Trie Char (List SearchResult)
64insertSearchResult { path, result } trie =
62insertSearchResult { path, result } trie =
65 let path' = List.fromFoldable $ toCharArray $ toLower path in
63 let path' = List.fromFoldable $ toCharArray $ toLower path in
66− alter path' (Just <<< updateResults) trie
64+ alter path' (Just <<< updateResults) trie
67− where
65+ where
68− updateResults mbOldResults
66+ updateResults mbOldResults
69− | Just oldResults <- mbOldResults =
67+ | Just oldResults <- mbOldResults =
70− result : oldResults
68+ result : oldResults
71− | otherwise =
69+ | otherwise =
72− List.singleton result
70+ List.singleton result
73
71
74
72
75-- | For each declaration, extract its own `SearchResult` and `SearchResult`s
73-- | For each declaration, extract its own `SearchResult` and `SearchResult`s
@@ -82,19 +80,17 @@ resultsForDeclaration
82 , result :: SearchResult
80 , result :: SearchResult
83 }
81 }
84resultsForDeclaration scores moduleName indexEntry@(Declaration entry) =
82resultsForDeclaration scores moduleName indexEntry@(Declaration entry) =
85− let { info, title, sourceSpan, comments, children } = entry
86− { name, declLevel } = getLevelAndName info.declType title
87− packageName = extractPackageName moduleName sourceSpan
88− in case mkInfo declLevel indexEntry of
83+ case mkInfo declLevel indexEntry of
89− Nothing -> mempty
84+ Nothing -> mempty
90− Just info' ->
85+ Just info' ->
91 let result = SearchResult { name: title
86 let result = SearchResult { name: title
92 , comments
87 , comments
93 , hashAnchor: declLevelToHashAnchor declLevel
88 , hashAnchor: declLevelToHashAnchor declLevel
94 , moduleName
89 , moduleName
95 , sourceSpan
90 , sourceSpan
96− , packageName
91+ , packageInfo
97− , score: fromMaybe 0 $ Map.lookup packageName scores
92+ , score:
93+ fromMaybe 0 $ getPackageScoreForPackageName scores <$> mbPackageName
98 , info: info'
94 , info: info'
99 }
95 }
100 in
96 in
@@ -104,8 +100,16 @@ resultsForDeclaration scores moduleName indexEntry@(Declaration entry) =
104 }
100 }
105 ) <>
101 ) <>
106 ( List.fromFoldable children >>=
102 ( List.fromFoldable children >>=
107− resultsForChildDeclaration scores packageName moduleName result
103+ resultsForChildDeclaration scores packageInfo moduleName result
108 )
104 )
105+ where
106+ { info, title, sourceSpan, comments, children } = entry
107+ { name, declLevel } = getLevelAndName info.declType title
108+ packageInfo = extractPackageName moduleName sourceSpan
109+ mbPackageName =
110+ case packageInfo of
111+ Package packageName -> Just packageName
112+ _ -> Nothing
109
113
110
114
111mkInfo :: DeclLevel -> Declaration -> Maybe ResultInfo
115mkInfo :: DeclLevel -> Declaration -> Maybe ResultInfo
@@ -188,31 +192,30 @@ getLevelAndName DeclExternKind name = { name, declLevel: KindLevel }
188-- | Extract package name from `sourceSpan.name`, which contains path to
192-- | Extract package name from `sourceSpan.name`, which contains path to
189-- | the source file. If `ModuleName` string starts with `Prim.`, it's a
193-- | the source file. If `ModuleName` string starts with `Prim.`, it's a
190-- | built-in (guaranteed by the compiler).
194-- | built-in (guaranteed by the compiler).
191−extractPackageName :: ModuleName -> Maybe SourceSpan -> PackageName
195+extractPackageName :: ModuleName -> Maybe SourceSpan -> PackageInfo
192−extractPackageName moduleName _
196+extractPackageName (ModuleName moduleName) _
193− | String.split (Pattern ".") moduleName !! 0 == Just "Prim" = "<builtin>"
197+ | String.split (Pattern ".") moduleName !! 0 == Just "Prim" = Builtin
194−extractPackageName _ Nothing = "<unknown>"
198+extractPackageName _ Nothing = UnknownPackage
195extractPackageName _ (Just { name }) =
199extractPackageName _ (Just { name }) =
196− let dirs = String.split (Pattern "/") name
197− in
198− fromMaybe "<local package>" do
200+ fromMaybe LocalPackage do
199− topLevelDir <- dirs !! 0
201+ topLevelDir <- dirs !! 0
200− if topLevelDir == ".spago"
202+ if topLevelDir == ".spago"
201− then dirs !! 1
203+ then Package <<< PackageName <$> dirs !! 1
202− else do
204+ else do
203− bowerDirIx <- Array.findIndex (_ == "bower_components") dirs
205+ bowerDirIx <- Array.findIndex (_ == "bower_components") dirs
204− dirs !! (bowerDirIx + 1)
206+ Package <<< PackageName <$> dirs !! (bowerDirIx + 1)
207+ where dirs = String.split (Pattern "/") name
205
208
206
209
207-- | Extract `SearchResults` from a `ChildDeclaration`.
210-- | Extract `SearchResults` from a `ChildDeclaration`.
208resultsForChildDeclaration
211resultsForChildDeclaration
209 :: Scores
212 :: Scores
210− -> PackageName
213+ -> PackageInfo
211 -> ModuleName
214 -> ModuleName
212 -> SearchResult
215 -> SearchResult
213 -> ChildDeclaration
216 -> ChildDeclaration
214 -> List { path :: String, result :: SearchResult }
217 -> List { path :: String, result :: SearchResult }
215−resultsForChildDeclaration scores packageName moduleName parentResult
218+resultsForChildDeclaration scores packageInfo moduleName parentResult
216 child@(ChildDeclaration { title, info, comments, mbSourceSpan })
219 child@(ChildDeclaration { title, info, comments, mbSourceSpan })
217 | Just resultInfo <- mkChildInfo parentResult child =
220 | Just resultInfo <- mkChildInfo parentResult child =
218 { path: title
221 { path: title
@@ -225,8 +228,8 @@ resultsForChildDeclaration scores packageName moduleName parentResult
225 , hashAnchor: "v"
228 , hashAnchor: "v"
226 , moduleName
229 , moduleName
227 , sourceSpan: mbSourceSpan
230 , sourceSpan: mbSourceSpan
228− , packageName
231+ , packageInfo
229− , score: fromMaybe 0 $ Map.lookup packageName scores
232+ , score: getPackageScore scores packageInfo
230 , info: resultInfo
233 , info: resultInfo
231 }
234 }
232 } # List.singleton
235 } # List.singleton
@@ -261,7 +264,8 @@ mkChildInfo
261
264
262 -- Then we construct a qualified name of the type class.
265 -- Then we construct a qualified name of the type class.
263 constraintClass =
266 constraintClass =
267+ QualifiedName { moduleNameParts:
264− QualifiedName { moduleName: String.split (wrap ".") moduleName
268+ String.split (wrap ".") $ unwrap moduleName
265 , name: resultName }
269 , name: resultName }
266
270
267 -- We concatenate two lists:
271 -- We concatenate two lists:
src/Docs/Search/Engine.purs+10−10
@@ -5,7 +5,7 @@ import Docs.Search.PackageIndex (PackageIndex, PackageResult)
5import Docs.Search.Score (Scores)
5import Docs.Search.Score (Scores)
6import Docs.Search.SearchResult (SearchResult, typeOfResult)
6import Docs.Search.SearchResult (SearchResult, typeOfResult)
7import Docs.Search.TypeQuery (TypeQuery(..), parseTypeQuery, penalty)
7import Docs.Search.TypeQuery (TypeQuery(..), parseTypeQuery, penalty)
8−import Docs.Search.Types (PackageName, ModuleName)
8+import Docs.Search.Types (PackageInfo(..), PackageName(..), ModuleName(..))
9
9
10import Prelude
10import Prelude
11
11
@@ -73,25 +73,25 @@ getResultScore (PackResult r) = r.score
73getResultScore (MdlResult r) = r.score
73getResultScore (MdlResult r) = r.score
74
74
75
75
76−getResultPackageName :: Result -> PackageName
76+getResultPackageInfo :: Result -> PackageInfo
77−getResultPackageName (DeclResult r) = (unwrap r).packageName
77+getResultPackageInfo (DeclResult r) = (unwrap r).packageInfo
78−getResultPackageName (TypeResult r) = (unwrap r).packageName
78+getResultPackageInfo (TypeResult r) = (unwrap r).packageInfo
79−getResultPackageName (PackResult r) = r.name
79+getResultPackageInfo (PackResult r) = Package r.name
80−getResultPackageName (MdlResult r) = r.package
80+getResultPackageInfo (MdlResult r) = Package $ r.package
81
81
82
82
83getResultModuleName :: Result -> ModuleName
83getResultModuleName :: Result -> ModuleName
84getResultModuleName (DeclResult r) = (unwrap r).moduleName
84getResultModuleName (DeclResult r) = (unwrap r).moduleName
85getResultModuleName (TypeResult r) = (unwrap r).moduleName
85getResultModuleName (TypeResult r) = (unwrap r).moduleName
86−getResultModuleName (PackResult r) = ""
86+getResultModuleName (PackResult r) = ModuleName ""
87getResultModuleName (MdlResult r) = r.name
87getResultModuleName (MdlResult r) = r.name
88
88
89
89
90getResultName :: Result -> String
90getResultName :: Result -> String
91getResultName (DeclResult r) = (unwrap r).name
91getResultName (DeclResult r) = (unwrap r).name
92getResultName (TypeResult r) = (unwrap r).name
92getResultName (TypeResult r) = (unwrap r).name
93−getResultName (PackResult r) = r.name
93+getResultName (PackResult r) = unwrap r.name
94−getResultName (MdlResult r) = r.name
94+getResultName (MdlResult r) = unwrap r.name
95
95
96
96
97sortByPopularity
97sortByPopularity
@@ -102,7 +102,7 @@ sortByPopularity
102sortByPopularity { packageIndex } =
102sortByPopularity { packageIndex } =
103 Array.sortBy (
103 Array.sortBy (
104 compare `on` (getResultScore >>> negate) <>
104 compare `on` (getResultScore >>> negate) <>
105− compare `on` getResultPackageName <>
105+ compare `on` getResultPackageInfo <>
106 compare `on` getResultModuleName <>
106 compare `on` getResultModuleName <>
107 -- Identifier name comes last: we want to make sure no `Result`s are
107 -- Identifier name comes last: we want to make sure no `Result`s are
108 -- equal, to avoid having unstable ordering.
108 -- equal, to avoid having unstable ordering.
src/Docs/Search/Interactive.purs+23−17
@@ -1,16 +1,6 @@
1-- | Definitions for the "search REPL".
1-- | Definitions for the "search REPL".
2module Docs.Search.Interactive where
2module Docs.Search.Interactive where
3
3
4−import Prelude
5−
6−import Data.Array as Array
7−import Data.Identity (Identity(..))
8−import Data.Maybe (fromMaybe)
9−import Data.Newtype (un, unwrap, wrap)
10−import Data.Search.Trie as Trie
11−import Data.String (length) as String
12−import Data.String.Common (split, trim) as String
13−import Data.Tuple (fst)
14import Docs.Search.Declarations (Declarations, mkDeclarations)
4import Docs.Search.Declarations (Declarations, mkDeclarations)
15import Docs.Search.DocsJson (DataDeclType(..))
5import Docs.Search.DocsJson (DataDeclType(..))
16import Docs.Search.Engine (mkEngineState, Result(..))
6import Docs.Search.Engine (mkEngineState, Result(..))
@@ -26,6 +16,18 @@ import Docs.Search.Terminal (bold, cyan, green, yellow)
26import Docs.Search.TypeDecoder (Constraint, FunDeps, Kind, QualifiedName, Type, TypeArgument)
16import Docs.Search.TypeDecoder (Constraint, FunDeps, Kind, QualifiedName, Type, TypeArgument)
27import Docs.Search.TypeIndex (resultsWithTypes)
17import Docs.Search.TypeIndex (resultsWithTypes)
28import Docs.Search.TypePrinter (keyword, showConstraint, showFunDeps, showKind, showType, showTypeArgument, space, syntax)
18import Docs.Search.TypePrinter (keyword, showConstraint, showFunDeps, showKind, showType, showTypeArgument, space, syntax)
19+import Docs.Search.Types (PackageName, ModuleName, PackageInfo, packageInfoToString)
20+
21+import Prelude
22+
23+import Data.Array as Array
24+import Data.Identity (Identity(..))
25+import Data.Maybe (fromMaybe)
26+import Data.Newtype (un, unwrap, wrap)
27+import Data.Search.Trie as Trie
28+import Data.String (length) as String
29+import Data.String.Common (split, trim) as String
30+import Data.Tuple (fst)
29import Effect (Effect)
31import Effect (Effect)
30import Effect.Aff (launchAff_)
32import Effect.Aff (launchAff_)
31import Effect.Class (liftEffect)
33import Effect.Class (liftEffect)
@@ -122,33 +124,37 @@ showResult = case _ of
122
124
123
125
124showSearchResult :: SearchResult -> String
126showSearchResult :: SearchResult -> String
125−showSearchResult (SearchResult result@{ name, comments, moduleName, packageName }) =
127+showSearchResult (SearchResult result@{ name, comments, moduleName, packageInfo }) =
126 showSignature result <> "\n" <>
128 showSignature result <> "\n" <>
127
129
128 (fromMaybe "\n" $
130 (fromMaybe "\n" $
129 comments <#> \comment ->
131 comments <#> \comment ->
130 "\n" <> leftShift 3 (String.trim comment) <> "\n\n") <>
132 "\n" <> leftShift 3 (String.trim comment) <> "\n\n") <>
131
133
134+ bold (
135+ cyan (rightPad 40 $ packageInfoToString packageInfo)
136+ ) <>
137+ space <>
132− bold (cyan (rightPad 40 packageName)) <> space <> bold (green moduleName)
138+ bold (green $ unwrap moduleName)
133
139
134
140
135showPackageResult :: PackageResult -> String
141showPackageResult :: PackageResult -> String
136showPackageResult { name, description } =
142showPackageResult { name, description } =
137− bold (cyan "package") <> " " <> bold (yellow name) <>
143+ bold (cyan "package") <> " " <> bold (yellow $ unwrap name) <>
138
144
139 (description >#> \text -> "\n\n" <> leftShift 3 text <> "\n")
145 (description >#> \text -> "\n\n" <> leftShift 3 text <> "\n")
140
146
141
147
142showModuleResult :: ModuleResult -> String
148showModuleResult :: ModuleResult -> String
143showModuleResult { name, package } =
149showModuleResult { name, package } =
144− bold (cyan "module") <> " " <> bold (green name)
150+ bold (cyan "module") <> " " <> bold (green $ unwrap name)
145
151
146
152
147showSignature ::
153showSignature ::
148 forall rest.
154 forall rest.
149 { name :: String
155 { name :: String
150− , moduleName :: String
156+ , moduleName :: ModuleName
151− , packageName :: String
157+ , packageInfo :: PackageInfo
152 , info :: ResultInfo
158 , info :: ResultInfo
153 | rest
159 | rest
154 }
160 }
@@ -185,7 +191,7 @@ showTypeClassSignature
185 , arguments :: Array TypeArgument
191 , arguments :: Array TypeArgument
186 , superclasses :: Array Constraint
192 , superclasses :: Array Constraint
187 }
193 }
188− -> { name :: String, moduleName :: String | rest }
194+ -> { name :: String, moduleName :: ModuleName | rest }
189 -> String
195 -> String
190showTypeClassSignature { fundeps, arguments, superclasses } { name, moduleName } =
196showTypeClassSignature { fundeps, arguments, superclasses } { name, moduleName } =
191
197
src/Docs/Search/ModuleIndex.purs+9−6
@@ -3,9 +3,9 @@ module Docs.Search.ModuleIndex where
3import Docs.Search.Config (config)
3import Docs.Search.Config (config)
4import Docs.Search.Declarations (Declarations(..))
4import Docs.Search.Declarations (Declarations(..))
5import Docs.Search.SearchResult (SearchResult(..))
5import Docs.Search.SearchResult (SearchResult(..))
6−import Docs.Search.Types (ModuleName, PackageName)
6+import Docs.Search.Types (ModuleName, PackageName, PackageInfo(..))
7import Docs.Search.Extra (stringToList)
7import Docs.Search.Extra (stringToList)
8−import Docs.Search.Score (Scores, normalizePackageName)
8+import Docs.Search.Score (Scores)
9
9
10import Prelude
10import Prelude
11
11
@@ -22,6 +22,7 @@ import Data.List (List, (:))
22import Data.Map (Map)
22import Data.Map (Map)
23import Data.Map as Map
23import Data.Map as Map
24import Data.Maybe (fromMaybe)
24import Data.Maybe (fromMaybe)
25+import Data.Newtype (unwrap)
25import Data.Search.Trie (Trie)
26import Data.Search.Trie (Trie)
26import Data.Search.Trie as Trie
27import Data.Search.Trie as Trie
27import Data.Set (Set)
28import Data.Set (Set)
@@ -68,7 +69,9 @@ unpackModuleIndex packageModules =
68-- | E.g. `"Data.Array.ST" -> ["data.array.st", "array.st", "st"]`.
69-- | E.g. `"Data.Array.ST" -> ["data.array.st", "array.st", "st"]`.
69extractModuleNameParts :: ModuleName -> List String
70extractModuleNameParts :: ModuleName -> List String
70extractModuleNameParts =
71extractModuleNameParts =
72+ unwrap >>> String.toLower >>>
73+ String.split (Pattern ".") >>>
71− foldl (\acc el -> el : map (_ <> "." <> el) acc) mempty <<< String.split (Pattern ".") <<< String.toLower
74+ foldl (\acc el -> el : map (_ <> "." <> el) acc) mempty
72
75
73
76
74queryModuleIndex
77queryModuleIndex
@@ -83,7 +86,7 @@ queryModuleIndex scores { index, modulePackages } query =
83 Array.nub <#>
86 Array.nub <#>
84 (\name -> do
87 (\name -> do
85 package <- Map.lookup name modulePackages
88 package <- Map.lookup name modulePackages
86− pure { name, package, score: fromMaybe 0 $ Map.lookup (normalizePackageName package) scores }) #
89+ pure { name, package, score: fromMaybe 0 $ Map.lookup package scores }) #
87 Array.catMaybes
90 Array.catMaybes
88
91
89
92
@@ -97,9 +100,9 @@ mkPackedModuleIndex (Declarations trie) =
97 -> Map PackageName (Set ModuleName)
100 -> Map PackageName (Set ModuleName)
98 extract = foldr (Map.unionWith Set.union) mempty <<< map mkEntry
101 extract = foldr (Map.unionWith Set.union) mempty <<< map mkEntry
99 where
102 where
100− mkEntry (SearchResult { packageName, moduleName }) =
103+ mkEntry (SearchResult { packageInfo: Package packageName, moduleName }) =
101 Map.singleton packageName (Set.singleton moduleName)
104 Map.singleton packageName (Set.singleton moduleName)
102−
105+ mkEntry _ = mempty
103
106
104loadModuleIndex :: Aff PackedModuleIndex
107loadModuleIndex :: Aff PackedModuleIndex
105loadModuleIndex = do
108loadModuleIndex = do
src/Docs/Search/PackageIndex.purs+15−12
@@ -2,7 +2,8 @@ module Docs.Search.PackageIndex where
2
2
3import Docs.Search.Config (config)
3import Docs.Search.Config (config)
4import Docs.Search.Extra (stringToList)
4import Docs.Search.Extra (stringToList)
5−import Docs.Search.Score (Scores, getPackageScore, normalizePackageName)
5+import Docs.Search.Score (Scores, getPackageScoreForPackageName, normalizePackageName)
6+import Docs.Search.Types (PackageName, RawPackageName(..))
6
7
7import Prelude
8import Prelude
8
9
@@ -23,10 +24,10 @@ import Web.Bower.PackageMeta (PackageMeta(..))
23
24
24
25
25type PackageResult
26type PackageResult
26− = { name :: String
27+ = { name :: PackageName
27 , description :: Maybe String
28 , description :: Maybe String
28 , score :: Int
29 , score :: Int
29− , dependencies :: Array String
30+ , dependencies :: Array PackageName
30 , repository :: Maybe String
31 , repository :: Maybe String
31 }
32 }
32
33
@@ -44,24 +45,26 @@ mkPackageInfo packageScores pms =
44 where
45 where
45 insert
46 insert
46 :: PackageMeta
47 :: PackageMeta
47− -> Map String PackageResult
48+ -> Map PackageName PackageResult
48− -> Map String PackageResult
49+ -> Map PackageName PackageResult
49 insert
50 insert
50 (PackageMeta { name
51 (PackageMeta { name
51 , description
52 , description
52 , dependencies
53 , dependencies
53 , devDependencies
54 , devDependencies
54 , repository }) =
55 , repository }) =
55−
56− Map.insert
56+ Map.insert
57− name
57+ packageName
58− { name
58+ { name: packageName
59 , description: description
59 , description: description
60− , score: getPackageScore packageScores $ normalizePackageName name
60+ , score: getPackageScoreForPackageName packageScores packageName
61+ , dependencies:
61− , dependencies: unwrap dependencies <#> (_.packageName)
62+ unwrap dependencies <#>
63+ (_.packageName >>> RawPackageName >>> normalizePackageName)
62 , repository: repository <#> (_.url)
64 , repository: repository <#> (_.url)
63 }
65 }
64
66
67+ where packageName = normalizePackageName $ RawPackageName name
65
68
66mkScoresFromPackageIndex :: PackageIndex -> Scores
69mkScoresFromPackageIndex :: PackageIndex -> Scores
67mkScoresFromPackageIndex =
70mkScoresFromPackageIndex =
@@ -78,7 +81,7 @@ loadPackageIndex = do
78mkPackageIndex :: PackageInfo -> PackageIndex
81mkPackageIndex :: PackageInfo -> PackageIndex
79mkPackageIndex =
82mkPackageIndex =
80 Array.foldr
83 Array.foldr
81− (\package -> Trie.insert (stringToList $ normalizePackageName package.name) package)
84+ (\package -> Trie.insert (stringToList $ unwrap package.name) package)
82 mempty
85 mempty
83
86
84
87
src/Docs/Search/Score.purs+17−12
@@ -1,6 +1,6 @@
1module Docs.Search.Score where
1module Docs.Search.Score where
2
2
3−import Docs.Search.Types (PackageName)
3+import Docs.Search.Types (RawPackageName(..), PackageName(..), PackageInfo(..))
4
4
5import Prelude
5import Prelude
6
6
@@ -15,16 +15,9 @@ import Web.Bower.PackageMeta (Dependencies, PackageMeta)
15
15
16type Scores = Map PackageName Int
16type Scores = Map PackageName Int
17
17
18−
19−getPackageScore :: Scores -> PackageName -> Int
20−getPackageScore _ "<builtin>" = 1000000
21−getPackageScore _ "<local package>" = 2000000
22−getPackageScore scores name = fromMaybe 0 $ Map.lookup name scores
23−
24−
25−normalizePackageName :: PackageName -> PackageName
18+normalizePackageName :: RawPackageName -> PackageName
26−normalizePackageName packageName =
19+normalizePackageName (RawPackageName p) =
27− fromMaybe packageName $ String.stripPrefix (wrap "purescript-") packageName
20+ fromMaybe (PackageName p) $ map wrap $ String.stripPrefix (wrap "purescript-") p
28
21
29
22
30-- | Construct a mapping from package names to their scores, based on number
23-- | Construct a mapping from package names to their scores, based on number
@@ -44,4 +37,16 @@ mkScores =
44 Array.foldr
37 Array.foldr
45 (\dep -> Map.insertWith add dep 1)
38 (\dep -> Map.insertWith add dep 1)
46 scores
39 scores
47− (deps # unwrap >>> map (_.packageName >>> normalizePackageName))
40+ (deps # unwrap >>> map (_.packageName >>> RawPackageName >>> normalizePackageName))
41+
42+
43+getPackageScore :: Scores -> PackageInfo -> Int
44+getPackageScore scores = case _ of
45+ Package p -> getPackageScoreForPackageName scores p
46+ Builtin -> 100000
47+ LocalPackage -> 200000
48+ UnknownPackage -> 0
49+
50+
51+getPackageScoreForPackageName :: Scores -> PackageName -> Int
52+getPackageScoreForPackageName scores p = fromMaybe 0 $ Map.lookup p scores
src/Docs/Search/SearchResult.purs+3−2
@@ -2,6 +2,7 @@ module Docs.Search.SearchResult where
2
2
3import Docs.Search.DocsJson (DataDeclType)
3import Docs.Search.DocsJson (DataDeclType)
4import Docs.Search.TypeDecoder (Constraint, FunDeps, Kind, QualifiedName, Type, TypeArgument)
4import Docs.Search.TypeDecoder (Constraint, FunDeps, Kind, QualifiedName, Type, TypeArgument)
5+import Docs.Search.Types (PackageName, PackageInfo, ModuleName)
5
6
6import Prelude
7import Prelude
7
8
@@ -59,8 +60,8 @@ newtype SearchResult
59 { name :: String
60 { name :: String
60 , comments :: Maybe String
61 , comments :: Maybe String
61 , hashAnchor :: String
62 , hashAnchor :: String
62− , moduleName :: String
63+ , moduleName :: ModuleName
63− , packageName :: String
64+ , packageInfo :: PackageInfo
64 , score :: Int
65 , score :: Int
65 , sourceSpan :: Maybe { start :: Array Int
66 , sourceSpan :: Maybe { start :: Array Int
66 , end :: Array Int
67 , end :: Array Int
src/Docs/Search/TypeDecoder.purs+4−4
@@ -25,20 +25,20 @@ instance showQualifiedName :: Show QualifiedName where
25 show = genericShow
25 show = genericShow
26
26
27newtype QualifiedName
27newtype QualifiedName
28− = QualifiedName { moduleName :: Array String
28+ = QualifiedName { moduleNameParts :: Array String
29 , name :: String
29 , name :: String
30 }
30 }
31
31
32instance decodeJsonQualifiedName :: DecodeJson QualifiedName where
32instance decodeJsonQualifiedName :: DecodeJson QualifiedName where
33 decodeJson json = do
33 decodeJson json = do
34 decodeTuple
34 decodeTuple
35− (\moduleName name -> QualifiedName { moduleName, name })
35+ (\moduleNameParts name -> QualifiedName { moduleNameParts, name })
36 (mkJsonError "QualifiedName" json)
36 (mkJsonError "QualifiedName" json)
37 json
37 json
38
38
39instance encodeJsonQualifiedName :: EncodeJson QualifiedName where
39instance encodeJsonQualifiedName :: EncodeJson QualifiedName where
40− encodeJson (QualifiedName { moduleName, name }) =
40+ encodeJson (QualifiedName { moduleNameParts, name }) =
41− encodeTuple moduleName name
41+ encodeTuple moduleNameParts name
42
42
43mkJsonError :: String -> Json -> (forall i. i -> String)
43mkJsonError :: String -> Json -> (forall i. i -> String)
44mkJsonError name json _ =
44mkJsonError name json _ =
src/Docs/Search/TypeIndex.purs+3−1
@@ -8,6 +8,7 @@ import Docs.Search.Score (Scores)
8import Docs.Search.SearchResult (ResultInfo(..), SearchResult(..))
8import Docs.Search.SearchResult (ResultInfo(..), SearchResult(..))
9import Docs.Search.TypeDecoder (Type)
9import Docs.Search.TypeDecoder (Type)
10import Docs.Search.TypeQuery (TypeQuery)
10import Docs.Search.TypeQuery (TypeQuery)
11+import Docs.Search.Types (ModuleName(..))
11import Docs.Search.TypeShape (shapeOfType, shapeOfTypeQuery, stringifyShape)
12import Docs.Search.TypeShape (shapeOfType, shapeOfTypeQuery, stringifyShape)
12
13
13import Prelude
14import Prelude
@@ -48,7 +49,8 @@ mkTypeIndex scores docsJsons =
48
49
49allResults :: Scores -> DocsJson -> Array SearchResult
50allResults :: Scores -> DocsJson -> Array SearchResult
50allResults scores (DocsJson { name, declarations }) =
51allResults scores (DocsJson { name, declarations }) =
51− declarations >>= (resultsForDeclaration scores name >>> map (_.result) >>> Array.fromFoldable)
52+ declarations >>= (resultsForDeclaration scores (ModuleName name) >>>
53+ map (_.result) >>> Array.fromFoldable)
52
54
53
55
54resultsWithTypes :: Scores -> DocsJson -> Array SearchResult
56resultsWithTypes :: Scores -> DocsJson -> Array SearchResult
src/Docs/Search/TypePrinter.purs+2−2
@@ -21,13 +21,13 @@ showType = case _ of
21 TypeOp qname -> showQualifiedName qname
21 TypeOp qname -> showQualifiedName qname
22
22
23 TypeApp (TypeApp (TypeConstructor
23 TypeApp (TypeApp (TypeConstructor
24− (QualifiedName { moduleName: [ "Prim" ]
24+ (QualifiedName { moduleNameParts: [ "Prim" ]
25 , name: "Function" }))
25 , name: "Function" }))
26 t1)
26 t1)
27 t2 ->
27 t2 ->
28 showType t1 <> syntax " -> " <> showType t2
28 showType t1 <> syntax " -> " <> showType t2
29
29
30− TypeApp (TypeConstructor (QualifiedName { moduleName: [ "Prim" ]
30+ TypeApp (TypeConstructor (QualifiedName { moduleNameParts: [ "Prim" ]
31 , name: "Record" }))
31 , name: "Record" }))
32 row ->
32 row ->
33 showRow false row
33 showRow false row
src/Docs/Search/TypeQuery.purs+3−3
@@ -248,7 +248,7 @@ unify query type_ = go Nil (List.singleton { q: query, t: type_ })
248 -- * Functions
248 -- * Functions
249 go acc ({ q: QFun q1 q2
249 go acc ({ q: QFun q1 q2
250 , t: TypeApp (TypeApp (TypeConstructor
250 , t: TypeApp (TypeApp (TypeConstructor
251− (QualifiedName { moduleName: [ "Prim" ]
251+ (QualifiedName { moduleNameParts: [ "Prim" ]
252 , name: "Function" })) t1) t2 } : rest) =
252 , name: "Function" })) t1) t2 } : rest) =
253 go acc ({ q: q1, t: t1 } : { q: q2, t: t2 } : rest)
253 go acc ({ q: q1, t: t1 } : { q: q2, t: t2 } : rest)
254 go acc ({ q: q@(QFun q1 q2), t } : rest) =
254 go acc ({ q: q@(QFun q1 q2), t } : rest) =
@@ -257,7 +257,7 @@ unify query type_ = go Nil (List.singleton { q: query, t: type_ })
257 -- * Rows
257 -- * Rows
258 go acc ({ q: QApp (QConst "Record") (QRow qRows)
258 go acc ({ q: QApp (QConst "Record") (QRow qRows)
259 , t: TypeApp (TypeConstructor
259 , t: TypeApp (TypeConstructor
260− (QualifiedName { moduleName: [ "Prim" ]
260+ (QualifiedName { moduleNameParts: [ "Prim" ]
261 , name: "Record" })) row } : rest) =
261 , name: "Record" })) row } : rest) =
262 let { rows, ty } = joinRows row
262 let { rows, ty } = joinRows row
263 qRowsLength = List.length qRows
263 qRowsLength = List.length qRows
@@ -407,7 +407,7 @@ typeSize = go 0 <<< List.singleton
407 go n (TypeOp _ : rest) =
407 go n (TypeOp _ : rest) =
408 go (n + 1) rest
408 go (n + 1) rest
409 go n (TypeApp (TypeApp (TypeConstructor
409 go n (TypeApp (TypeApp (TypeConstructor
410− (QualifiedName { moduleName: [ "Prim" ]
410+ (QualifiedName { moduleNameParts: [ "Prim" ]
411 , name: "Function" })) t1) t2 : rest) =
411 , name: "Function" })) t1) t2 : rest) =
412 go (n + 1) (t1 : t2 : rest)
412 go (n + 1) (t1 : t2 : rest)
413 go n (TypeApp q1 q2 : rest) =
413 go n (TypeApp q1 q2 : rest) =
src/Docs/Search/TypeShape.purs+1−1
@@ -101,7 +101,7 @@ shapeOfType ty = List.reverse $ go (pure ty) Nil
101 TypeWildcard ->
101 TypeWildcard ->
102 go rest (PVar : acc)
102 go rest (PVar : acc)
103
103
104− TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleName: ["Prim"]
104+ TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"]
105 , name: "Function" })) t1) t2 ->
105 , name: "Function" })) t1) t2 ->
106 go (t1 : t2 : rest) (PFun : acc)
106 go (t1 : t2 : rest) (PFun : acc)
107
107
src/Docs/Search/Types.purs+56−2
@@ -1,5 +1,59 @@
1module Docs.Search.Types where
1module Docs.Search.Types where
2
2
3−type ModuleName = String
3+import Prelude
4
4
5+import Data.Argonaut.Decode (class DecodeJson)
6+import Data.Argonaut.Decode.Generic.Rep (genericDecodeJson)
7+import Data.Argonaut.Encode (class EncodeJson)
8+import Data.Argonaut.Encode.Generic.Rep (genericEncodeJson)
9+import Data.Generic.Rep (class Generic)
10+import Data.Generic.Rep.Show (genericShow)
11+import Data.Newtype (class Newtype)
12+
13+
14+newtype ModuleName = ModuleName String
15+
16+derive instance newtypeModuleName :: Newtype ModuleName _
17+derive instance genericModuleName :: Generic ModuleName _
18+derive newtype instance eqModuleName :: Eq ModuleName
19+derive newtype instance ordModuleName :: Ord ModuleName
20+derive newtype instance decodeJsonModuleName :: DecodeJson ModuleName
21+derive newtype instance encodeJsonModuleName :: EncodeJson ModuleName
22+
23+
24+-- | Non-normalized package name, e.g. `purescript-prelude` or just `prelude`.
25+newtype RawPackageName = RawPackageName String
26+
27+derive instance newtypeRawPackageName :: Newtype RawPackageName _
28+
29+
30+-- | Normalized package name without "purescript-" prefix.
5−type PackageName = String
31+newtype PackageName = PackageName String
32+
33+derive instance newtypePackageName :: Newtype PackageName _
34+derive newtype instance eqPackageName :: Eq PackageName
35+derive newtype instance ordPackageName :: Ord PackageName
36+derive newtype instance showPackageName :: Show PackageName
37+derive newtype instance decodeJsonPackageName :: DecodeJson PackageName
38+derive newtype instance encodeJsonPackageName :: EncodeJson PackageName
39+derive instance genericPackageName :: Generic PackageName _
40+
41+
42+data PackageInfo = Package PackageName | Builtin | LocalPackage | UnknownPackage
43+
44+derive instance eqPackageInfo :: Eq PackageInfo
45+derive instance ordPackageInfo :: Ord PackageInfo
46+derive instance genericPackageInfo :: Generic PackageInfo _
47+instance showPackageInfo :: Show PackageInfo where
48+ show = genericShow
49+
50+instance decodeJsonPackageInfo :: DecodeJson PackageInfo where
51+ decodeJson = genericDecodeJson
52+instance encodeJsonPackageInfo :: EncodeJson PackageInfo where
53+ encodeJson = genericEncodeJson
54+
55+packageInfoToString :: PackageInfo -> String
56+packageInfoToString (Package (PackageName p)) = p
57+packageInfoToString Builtin = "<builtin>"
58+packageInfoToString LocalPackage = "<local package>"
59+packageInfoToString UnknownPackage = "<unknown package>"
test/Main.purs+16−16
@@ -67,7 +67,7 @@ mainTest = do
67 """
67 """
68
68
69 assertRight (decodeJson qualifiedName)
69 assertRight (decodeJson qualifiedName)
70− (QualifiedName { moduleName: ["Prim"]
70+ (QualifiedName { moduleNameParts: ["Prim"]
71 , name: "Type"
71 , name: "Type"
72 }
72 }
73 )
73 )
@@ -87,7 +87,7 @@ mainTest = do
87 """
87 """
88
88
89 assertRight (decodeJson namedKind)
89 assertRight (decodeJson namedKind)
90− (NamedKind $ QualifiedName { moduleName: ["Prim"]
90+ (NamedKind $ QualifiedName { moduleNameParts: ["Prim"]
91 , name: "Type"
91 , name: "Type"
92 }
92 }
93 )
93 )
@@ -111,7 +111,7 @@ mainTest = do
111 """
111 """
112
112
113 assertRight (decodeJson row)
113 assertRight (decodeJson row)
114− (Row $ NamedKind $ QualifiedName { moduleName: ["Prim"]
114+ (Row $ NamedKind $ QualifiedName { moduleNameParts: ["Prim"]
115 , name: "Type"
115 , name: "Type"
116 }
116 }
117 )
117 )
@@ -154,11 +154,11 @@ mainTest = do
154 }
154 }
155 """
155 """
156 assertRight (decodeJson funKind)
156 assertRight (decodeJson funKind)
157− (FunKind (Row $ NamedKind $ QualifiedName { moduleName: ["Prim"]
157+ (FunKind (Row $ NamedKind $ QualifiedName { moduleNameParts: ["Prim"]
158 , name: "Type"
158 , name: "Type"
159 }
159 }
160 )
160 )
161− (Row $ NamedKind $ QualifiedName { moduleName: ["Prim"]
161+ (Row $ NamedKind $ QualifiedName { moduleNameParts: ["Prim"]
162 , name: "Type"
162 , name: "Type"
163 }
163 }
164 )
164 )
@@ -181,7 +181,7 @@ mainTest = do
181 }
181 }
182 """
182 """
183 assertRight (decodeJson constraint)
183 assertRight (decodeJson constraint)
184− (Constraint { constraintClass: QualifiedName { moduleName: ["Prim"]
184+ (Constraint { constraintClass: QualifiedName { moduleNameParts: ["Prim"]
185 , name: "Partial"
185 , name: "Partial"
186 }
186 }
187 , constraintArgs: []
187 , constraintArgs: []
@@ -230,7 +230,7 @@ mainTest = do
230
230
231 assertRight (decodeJson typeApp1) $
231 assertRight (decodeJson typeApp1) $
232 TypeApp
232 TypeApp
233− (TypeConstructor (QualifiedName { moduleName:
233+ (TypeConstructor (QualifiedName { moduleNameParts:
234 [ "Control"
234 [ "Control"
235 , "Monad"
235 , "Monad"
236 , "ST"
236 , "ST"
@@ -256,7 +256,7 @@ mainTest = do
256 }
256 }
257 """
257 """
258 assertRight (decodeJson typeOp) $
258 assertRight (decodeJson typeOp) $
259− TypeOp $ QualifiedName { moduleName: [ "Data", "NaturalTransformation" ]
259+ TypeOp $ QualifiedName { moduleNameParts: [ "Data", "NaturalTransformation" ]
260 , name: "~>"
260 , name: "~>"
261 }
261 }
262
262
@@ -293,7 +293,7 @@ mainTest = do
293
293
294 assertRight (decodeJson binaryNoParens) $
294 assertRight (decodeJson binaryNoParens) $
295 BinaryNoParensType
295 BinaryNoParensType
296− (TypeOp $ QualifiedName { moduleName: ["Data", "NaturalTransformation"], name: "~>" })
296+ (TypeOp $ QualifiedName { moduleNameParts: ["Data", "NaturalTransformation"], name: "~>" })
297 (TypeVar "m")
297 (TypeVar "m")
298 (TypeVar "n")
298 (TypeVar "n")
299
299
@@ -335,14 +335,14 @@ mainTest = do
335 assertRight (decodeJson parensInType) $
335 assertRight (decodeJson parensInType) $
336 ParensInType $
336 ParensInType $
337 TypeApp
337 TypeApp
338− (TypeConstructor (QualifiedName { moduleName:
338+ (TypeConstructor (QualifiedName { moduleNameParts:
339 [ "Data"
339 [ "Data"
340 , "Maybe"
340 , "Maybe"
341 ],
341 ],
342 name: "Maybe"
342 name: "Maybe"
343 }
343 }
344 ))
344 ))
345− (TypeConstructor (QualifiedName { moduleName:
345+ (TypeConstructor (QualifiedName { moduleNameParts:
346 [ "Prim"
346 [ "Prim"
347 ],
347 ],
348 name: "String"
348 name: "String"
@@ -389,7 +389,7 @@ mainTest = do
389 assertRight (decodeJson rcons) $
389 assertRight (decodeJson rcons) $
390 RCons
390 RCons
391 "tail"
391 "tail"
392− (TypeApp (TypeConstructor $ QualifiedName { moduleName: [ "Data", "Symbol" ], name: "SProxy" })
392+ (TypeApp (TypeConstructor $ QualifiedName { moduleNameParts: [ "Data", "Symbol" ], name: "SProxy" })
393 (TypeVar "t"))
393 (TypeVar "t"))
394 REmpty
394 REmpty
395
395
@@ -545,8 +545,8 @@ mainTest = do
545 """
545 """
546 assertRight (decodeJson forallJson) $
546 assertRight (decodeJson forallJson) $
547 ForAll "f"
547 ForAll "f"
548− (Just (FunKind (NamedKind (QualifiedName { moduleName: ["Prim","RowList"], name: "RowList" })) (NamedKind (QualifiedName { moduleName: ["Prim"], name: "Type" }))))
548+ (Just (FunKind (NamedKind (QualifiedName { moduleNameParts: ["Prim","RowList"], name: "RowList" })) (NamedKind (QualifiedName { moduleNameParts: ["Prim"], name: "Type" }))))
549− (TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleName: ["Prim"], name: "Function" })) (TypeApp (TypeVar "f") (TypeVar "l"))) (TypeApp (TypeConstructor (QualifiedName { moduleName: ["Data","List","Types"], name: "List" })) (ParensInType (TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleName: ["Data","Tuple"], name: "Tuple" })) (TypeConstructor (QualifiedName { moduleName: ["Prim"], name: "String" }))) (TypeConstructor (QualifiedName { moduleName: ["Prim"], name: "String" }))))))
549+ (TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"], name: "Function" })) (TypeApp (TypeVar "f") (TypeVar "l"))) (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Data","List","Types"], name: "List" })) (ParensInType (TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Data","Tuple"], name: "Tuple" })) (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"], name: "String" }))) (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"], name: "String" }))))))
550
550
551
551
552
552
@@ -558,7 +558,7 @@ mainTest = do
558{"annotation":[],"tag":"ForAll","contents":["o",{"annotation":[],"tag":"ForAll","contents":["r",{"annotation":[],"tag":"ForAll","contents":["l",{"annotation":[],"tag":"ConstrainedType","contents":[{"constraintAnn":[],"constraintClass":[["Type","Data","Boolean"],"And"],"constraintArgs":[{"annotation":[],"tag":"TypeVar","contents":"l"},{"annotation":[],"tag":"TypeVar","contents":"r"},{"annotation":[],"tag":"TypeVar","contents":"o"}],"constraintData":null},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Type","Data","Boolean"],"BProxy"]},{"annotation":[],"tag":"TypeVar","contents":"l"}]}]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Type","Data","Boolean"],"BProxy"]},{"annotation":[],"tag":"TypeVar","contents":"r"}]}]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Type","Data","Boolean"],"BProxy"]},{"annotation":[],"tag":"TypeVar","contents":"o"}]}]}]}]},null]},null]},null]}
558{"annotation":[],"tag":"ForAll","contents":["o",{"annotation":[],"tag":"ForAll","contents":["r",{"annotation":[],"tag":"ForAll","contents":["l",{"annotation":[],"tag":"ConstrainedType","contents":[{"constraintAnn":[],"constraintClass":[["Type","Data","Boolean"],"And"],"constraintArgs":[{"annotation":[],"tag":"TypeVar","contents":"l"},{"annotation":[],"tag":"TypeVar","contents":"r"},{"annotation":[],"tag":"TypeVar","contents":"o"}],"constraintData":null},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Type","Data","Boolean"],"BProxy"]},{"annotation":[],"tag":"TypeVar","contents":"l"}]}]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Type","Data","Boolean"],"BProxy"]},{"annotation":[],"tag":"TypeVar","contents":"r"}]}]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Type","Data","Boolean"],"BProxy"]},{"annotation":[],"tag":"TypeVar","contents":"o"}]}]}]}]},null]},null]},null]}
559 """
559 """
560
560
561− assertRight (decodeJson json) $ (ForAll "o" Nothing (ForAll "r" Nothing (ForAll "l" Nothing (ConstrainedType (Constraint { constraintArgs: [(TypeVar "l"),(TypeVar "r"),(TypeVar "o")], constraintClass: (QualifiedName { moduleName: ["Type","Data","Boolean"], name: "And" }) }) (TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleName: ["Prim"], name: "Function" })) (TypeApp (TypeConstructor (QualifiedName { moduleName: ["Type","Data","Boolean"], name: "BProxy" })) (TypeVar "l"))) (TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleName: ["Prim"], name: "Function" })) (TypeApp (TypeConstructor (QualifiedName { moduleName: ["Type","Data","Boolean"], name: "BProxy" })) (TypeVar "r"))) (TypeApp (TypeConstructor (QualifiedName { moduleName: ["Type","Data","Boolean"], name: "BProxy" })) (TypeVar "o"))))))))
561+ assertRight (decodeJson json) $ (ForAll "o" Nothing (ForAll "r" Nothing (ForAll "l" Nothing (ConstrainedType (Constraint { constraintArgs: [(TypeVar "l"),(TypeVar "r"),(TypeVar "o")], constraintClass: (QualifiedName { moduleNameParts: ["Type","Data","Boolean"], name: "And" }) }) (TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"], name: "Function" })) (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Type","Data","Boolean"], name: "BProxy" })) (TypeVar "l"))) (TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"], name: "Function" })) (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Type","Data","Boolean"], name: "BProxy" })) (TypeVar "r"))) (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Type","Data","Boolean"], name: "BProxy" })) (TypeVar "o"))))))))
562
562
563 suite "Kind encoder" do
563 suite "Kind encoder" do
564 test "FunKind" do
564 test "FunKind" do
@@ -570,4 +570,4 @@ mainTest = do
570
570
571
571
572qualified :: Array String -> String -> QualifiedName
572qualified :: Array String -> String -> QualifiedName
573−qualified moduleName name = QualifiedName { moduleName, name }
573+qualified moduleNameParts name = QualifiedName { moduleNameParts, name }
test/Test/Declarations.purs+14−11
@@ -2,8 +2,11 @@ module Test.Declarations where
2
2
3import Prelude
3import Prelude
4
4
5−import Data.Maybe (Maybe(..))
6import Docs.Search.Declarations (extractPackageName)
5import Docs.Search.Declarations (extractPackageName)
6+import Docs.Search.Types (PackageName(..), PackageInfo(..))
7+
8+import Data.Maybe (Maybe(..))
9+import Data.Newtype (wrap)
7
10
8import Test.Unit (TestSuite, suite, test)
11import Test.Unit (TestSuite, suite, test)
9import Test.Unit.Assert as Assert
12import Test.Unit.Assert as Assert
@@ -12,26 +15,26 @@ tests :: TestSuite
12tests = do
15tests = do
13 suite "Declarations" do
16 suite "Declarations" do
14 test "extractPackageName" do
17 test "extractPackageName" do
15− Assert.equal "<builtin>" (extractPackageName "Prim" Nothing)
18+ Assert.equal Builtin (extractPackageName (wrap "Prim") Nothing)
16− Assert.equal "<builtin>" (extractPackageName "Prim.Foo" Nothing)
19+ Assert.equal Builtin (extractPackageName (wrap "Prim.Foo") Nothing)
17− Assert.equal "<builtin>" (extractPackageName "Prim.Foo.Bar" Nothing)
20+ Assert.equal Builtin (extractPackageName (wrap "Prim.Foo.Bar") Nothing)
18− Assert.equal "<unknown>" (extractPackageName "Primitive" Nothing)
21+ Assert.equal UnknownPackage (extractPackageName (wrap "Primitive") Nothing)
19− Assert.equal "foo"
22+ Assert.equal (Package $ PackageName "foo")
20− (extractPackageName "Foo" $
23+ (extractPackageName (wrap "Foo") $
21 Just { start: []
24 Just { start: []
22 , end: []
25 , end: []
23 , name: ".spago/foo/src/Foo.purs"
26 , name: ".spago/foo/src/Foo.purs"
24 }
27 }
25 )
28 )
26− Assert.equal "bar"
29+ Assert.equal (Package $ PackageName "bar")
27− (extractPackageName "Bar" $
30+ (extractPackageName (wrap "Bar") $
28 Just { start: []
31 Just { start: []
29 , end: []
32 , end: []
30 , name: "/path/to/somewhere/bower_components/bar/src/Bar.purs"
33 , name: "/path/to/somewhere/bower_components/bar/src/Bar.purs"
31 }
34 }
32 )
35 )
33− Assert.equal "<local package>"
36+ Assert.equal LocalPackage
34− (extractPackageName "Bar" $
37+ (extractPackageName (wrap "Bar") $
35 Just { start: []
38 Just { start: []
36 , end: []
39 , end: []
37 , name: "/path/to/somewhere/src/Bar.purs"
40 , name: "/path/to/somewhere/src/Bar.purs"
test/Test/ModuleIndex.purs+3−2
@@ -5,6 +5,7 @@ import Docs.Search.ModuleIndex (extractModuleNameParts)
5import Prelude
5import Prelude
6
6
7import Data.List as List
7import Data.List as List
8+import Data.Newtype (wrap)
8import Test.Unit (TestSuite, suite, test)
9import Test.Unit (TestSuite, suite, test)
9import Test.Unit.Assert as Assert
10import Test.Unit.Assert as Assert
10
11
@@ -14,11 +15,11 @@ tests = do
14 suite "ModuleIndex" do
15 suite "ModuleIndex" do
15
16
16 test "test #0" do
17 test "test #0" do
17− Assert.equal (extractModuleNameParts "Data.Array.ST") (
18+ Assert.equal (extractModuleNameParts $ wrap "Data.Array.ST") (
18 List.fromFoldable [ "st", "array.st", "data.array.st" ]
19 List.fromFoldable [ "st", "array.st", "data.array.st" ]
19 )
20 )
20
21
21 test "test #1" do
22 test "test #1" do
22− Assert.equal (extractModuleNameParts "Foo") (
23+ Assert.equal (extractModuleNameParts $ wrap "Foo") (
23 List.fromFoldable [ "foo" ]
24 List.fromFoldable [ "foo" ]
24 )
25 )
test/Test/TypeQuery.purs+3−3
@@ -245,7 +245,7 @@ tests = do
245 c2 = constr (qname [""] "GenericEq") [TypeVar "rep"]
245 c2 = constr (qname [""] "GenericEq") [TypeVar "rep"]
246
246
247 fun t1 t2 =
247 fun t1 t2 =
248− TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleName: ["Prim"]
248+ TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"]
249 , name: "Function" })) t1) t2
249 , name: "Function" })) t1) t2
250 type_ =
250 type_ =
251 ForAll "a" Nothing $
251 ForAll "a" Nothing $
@@ -391,7 +391,7 @@ nl :: forall t5 t6. Foldable t6 => t5 -> t6 t5 -> NonEmptyList t5
391nl x rst = NonEmptyList.cons' x $ List.fromFoldable rst
391nl x rst = NonEmptyList.cons' x $ List.fromFoldable rst
392
392
393unitType :: Type
393unitType :: Type
394−unitType = TypeConstructor (QualifiedName { moduleName: []
394+unitType = TypeConstructor (QualifiedName { moduleNameParts: []
395 , name: "Unit"
395 , name: "Unit"
396 })
396 })
397
397
@@ -399,7 +399,7 @@ countFreeVars :: TypeQuery -> Int
399countFreeVars = getFreeVariables >>> Set.size
399countFreeVars = getFreeVariables >>> Set.size
400
400
401qname :: Array String -> String -> QualifiedName
401qname :: Array String -> String -> QualifiedName
402−qname m n = QualifiedName { moduleName: m, name: n }
402+qname m n = QualifiedName { moduleNameParts: m, name: n }
403
403
404constr :: QualifiedName -> Array Type -> Constraint
404constr :: QualifiedName -> Array Type -> Constraint
405constr c a = Constraint { constraintClass: c, constraintArgs: a }
405constr c a = Constraint { constraintClass: c, constraintArgs: a }