1module Docs.Check (check) where
3import qualified Data.List as List
4import qualified Data.Map as Map
5import qualified Data.Set as Set
8import qualified AST.Variable as Var
9import qualified Docs.AST as Docs
10import qualified Elm.Compiler.Type as Type
11import Elm.Utils ((|>))
12import qualified Reporting.Annotation as A
13import qualified Reporting.Error as Error
14import qualified Reporting.Error.Docs as E
15import qualified Reporting.Helpers as Help (nearbyNames)
16import qualified Reporting.Region as R
17import qualified Reporting.Result as R
19 ( Parser, addLocation, getPosition
20 , spaces, checkSpace, whitespace, SPos(..)
21 , capVar, lowVar, leftParen, rightParen, infixOp, runAt
22 , chompUntilDocs, comma, oneOf
30check :: [Var.Value] -> A.Located (Maybe Docs.Centralized) -> R.Result () w Error.Error Docs.Checked
31check exports (A.A region maybeDocs) =
34 R.throw region (Error.Docs E.NoDocs)
37 checkHelp region exports docs
40checkHelp :: R.Region -> [Var.Value] -> Docs.Centralized -> R.Result () w Error.Error Docs.Checked
41checkHelp region exports (Docs.Docs comment aliases types values) =
44 map (\(tipe, Var.Listing tags _) -> (tipe, tags)) (Var.getUnions exports)
46 do docNames <- parseNames region comment
47 let docSet = Set.fromList (map A.drop docNames)
48 R.mapError Error.Docs $
49 (\() -> Docs.Docs comment)
50 <$> checkModuleComment region exports docNames
51 <*> checkCategory docSet (checkComment Docs.aliasComment) aliases
52 <*> checkCategory docSet (checkUnion exportedUnions) types
53 <*> checkCategory docSet checkValue values
56type Result w a = R.Result () w E.Error a
61 -> (Text -> a -> Result w b)
63 -> Result w (Map.Map Text b)
64checkCategory docSet check dict =
66 |> Map.filterWithKey (\key _ -> Set.member key docSet)
67 |> Map.mapWithKey check
71checkComment :: (a -> Maybe Text) -> Text -> A.Located a -> Result w (A.Located a)
72checkComment getComment name (A.A region value) =
73 case getComment value of
75 R.throw region (E.NoComment name)
78 R.ok (A.A region value)
81checkUnion :: [(Text, [Text])] -> Text -> A.Located Docs.Union -> Result w (A.Located Docs.Union)
82checkUnion exportedUnions name value =
84 <$> filterUnionTags exportedUnions name value
85 <*> checkComment Docs.unionComment name value
88filterUnionTags :: [(Text, [Text])] -> Text -> A.Located Docs.Union -> Result w (A.Located Docs.Union)
89filterUnionTags exportedUnions name (A.A region union@(Docs.Union _ _ ctors)) =
92 maybe [] id (List.lookup name exportedUnions)
94 R.ok $ A.A region $ union
96 filter (\(tag, _) -> elem tag exportedTags) ctors
101checkValue :: Text -> A.Located (Docs.Value (Maybe Type.Type)) -> Result w (A.Located (Docs.Value Type.Type))
102checkValue name value =
104 <$> hasType name value
105 <*> checkComment Docs.valueComment name value
108hasType :: Text -> A.Located (Docs.Value (Maybe Type.Type)) -> Result w (A.Located (Docs.Value Type.Type))
109hasType name (A.A region value) =
110 case Docs.valueType value of
112 R.ok (A.A region (value { Docs.valueType = tipe }))
115 R.throw region (E.NoType name)
119-- CHECK MODULE COMMENT
122checkModuleComment :: R.Region -> [Var.Value] -> [A.Located Text] -> Result w ()
123checkModuleComment docRegion exports locatedDocNames =
126 map valueName exports
129 Map.fromList (map (\name -> (name, ())) exportNames)
132 Map.fromList (map (\(A.A region name) -> (name, region)) locatedDocNames)
134 extraNameError (name, region) =
135 R.throw region (E.OnlyInDocs name (Help.nearbyNames id name exportNames))
138 Map.difference docDict exportDict
140 |> traverse extraNameError
143 Map.difference exportDict docDict
148 if null namesOnlyInExports then
151 R.throw docRegion (E.OnlyInExports namesOnlyInExports)
162parseNames :: R.Region -> Text -> R.Result () w Error.Error [A.Located Text]
163parseNames (R.Region (R.Position row col) _) comment =
164 case runAt row (col + 3) (namesParser []) comment of
165 Left (A.A region parseError) ->
166 R.throw region (Error.Syntax parseError)
173namesParser :: [A.Located Text] -> Parser [A.Located Text]
175 do isDocs <- chompUntilDocs
176 if isDocs then namesParserHelp names else return names
179namesParserHelp :: [A.Located Text] -> Parser [A.Located Text]
180namesParserHelp names =
181 do pos <- getPosition
182 (SPos spos) <- whitespace
184 then namesParser names
185 else namesParser =<< chompNames names
188chompNames :: [A.Located Text] -> Parser [A.Located Text]
190 do name <- addLocation (oneOf [ lowVar, capVar, operator ])
196 chompNames (name:names)
201operator :: Parser Text
209valueName :: Var.Value -> Text
212 Var.Value name -> name
213 Var.Alias name -> name
214 Var.Union name _ -> name
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list