@@ -1,218 +1,205 @@
1{-# OPTIONS_GHC -Wall #-}
1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Elm.Docs
3module Elm.Docs
4− ( Documentation(..)
4+ ( Documentation
5− , Alias(..)
5+ , Module(..)
6− , Union(..)
6+ , toDict
14import qualified Data.Map as Map
19import qualified Data.Map as Map
15import Data.Text (Text)
20import Data.Text (Text)
22+import qualified AST.Declaration as Decl
17import qualified Docs.AST as Docs
23import qualified Docs.AST as Docs
18import qualified Elm.Compiler.Module as Module
24import qualified Elm.Compiler.Module as Module
19import qualified Elm.Compiler.Type as Type
25import qualified Elm.Compiler.Type as Type
20−import qualified Elm.Compiler.Version as Version
21−import qualified Elm.Package as Pkg
22import qualified Json.Decode as Decode
26import qualified Json.Decode as Decode
23import qualified Json.Encode as Encode
27import qualified Json.Encode as Encode
24import Json.Encode ((==>))
28import Json.Encode ((==>))
28−-- DATA STRUCTURES
32+-- DOCUMENTATION
31−data Documentation =
35+type Documentation =
33− { _name :: Module.Raw
36+ Map.Map Module.Raw Docs.Checked
35− , _aliases :: [Alias]
38− , _version :: Maybe Pkg.Version
42−data Alias =
39+data Module =
44− { _a_name :: Text
41+ { _name :: !Module.Raw
45− , _a_comment :: Text
42+ , _docs :: !Docs.Checked
47− , _a_type :: Type.Type
51−data Union =
46+toDict :: [Module] -> Documentation
52− Union
47+toDict modules =
53− { _u_name :: Text
48+ Map.fromList $ map (\(Module name docs) -> (name, docs)) modules
56− , _u_cases :: [(Text, [Type.Type])]
64− , _v_type :: Type.Type
65− , _v_fix :: Maybe (Text,Int)
55+encode :: Module -> Encode.Value
56+encode (Module name (Docs.Docs overview unions aliases values)) =
58+ [ "name" ==> Module.encode name
59+ , "comment" ==> Encode.text overview
60+ , "types" ==> Encode.list encodeUnion (Map.toList unions)
61+ , "aliases" ==> Encode.list encodeAlias (Map.toList aliases)
62+ , "values" ==> Encode.list encodeValue (Map.toList values)
73−fromCheckedDocs :: Module.Raw -> Docs.Checked -> Documentation
74−fromCheckedDocs name (Docs.Checked comment values aliases unions) =
76− toValue (vName, Docs.Value vComment tipe fix) =
77− Value vName vComment tipe fix
79− toAlias (aName, Docs.Alias aComment args tipe) =
80− Alias aName aComment args tipe
82− toUnion (uName, Docs.Union uComment args cases) =
67+-- DECODE
83− Union uName uComment args cases
88− (map toAlias (Map.toList aliases))
89− (map toUnion (Map.toList unions))
90− (map toValue (Map.toList values))
91− (Just Version.version)
70+decoder :: Decode.Decoder Module
73+ <$> Decode.field "name" Module.decoder
77+decodeDocs :: Decode.Decoder Docs.Checked
80+ <$> Decode.field "comment" Decode.text
81+ <*> Decode.field "types" (entryDictDecoder unionDecoder)
82+ <*> Decode.field "aliases" (entryDictDecoder aliasDecoder)
83+ <*> Decode.field "values" (entryDictDecoder valueDecoder)
98−encode :: Documentation -> Encode.Value
99−encode (Documentation name comment aliases types values elmVersion) =
101− [ "name" ==> Module.encode name
102− , "comment" ==> Encode.text comment
103− , "aliases" ==> Encode.list encodeAlias aliases
104− , "types" ==> Encode.list encodeUnion types
105− , "values" ==> Encode.list encodeValue values
112− Just version ->
86+entryDictDecoder :: Decode.Decoder a -> Decode.Decoder (Map.Map Text (Docs.Good a))
113− [ "generated-with-elm-version" ==> Pkg.encodeVersion version
87+entryDictDecoder subDecoder =
114− ]
88+ Map.fromList <$> Decode.list (entryDecoder subDecoder)
117−decoder :: Decode.Decoder Documentation
91+entryDecoder :: Decode.Decoder a -> Decode.Decoder ( Text, Docs.Good a )
118−decoder =
92+entryDecoder subDecoder =
120− <$> Decode.field "name" Module.decoder
93+ Decode.map2 (,) (Decode.field "name" Decode.text) $
121− <*> Decode.field "comment" Decode.text
94+ Decode.map2 Docs.Entry (Decode.field "comment" Decode.text) $
122− <*> Decode.field "aliases" (Decode.list aliasDecoder)
95+ subDecoder
123− <*> Decode.field "types" (Decode.list unionDecoder)
124− <*> Decode.field "values" (Decode.list valueDecoder)
125− <*> Decode.maybe (Decode.field "generated-with-elm-version" Pkg.versionDecoder)
129−-- JSON for ALIAS
99+-- ENCODE UNION
132−encodeAlias :: Alias -> Encode.Value
102+encodeUnion :: ( Text, Docs.Good Docs.Union ) -> Encode.Value
133−encodeAlias (Alias name comment args tipe) =
103+encodeUnion ( name, Docs.Entry comment (Docs.Union args cases) ) =
134 Encode.object
104 Encode.object
135 [ "name" ==> Encode.text name
105 [ "name" ==> Encode.text name
136 , "comment" ==> Encode.text comment
106 , "comment" ==> Encode.text comment
137 , "args" ==> Encode.list Encode.text args
107 , "args" ==> Encode.list Encode.text args
138− , "type" ==> Type.encode tipe
108+ , "cases" ==> Encode.list encodeCase cases
112+encodeCase :: ( Text, [Type.Type] ) -> Encode.Value
113+encodeCase ( tag, args ) =
114+ Encode.list id [ Encode.text tag, Encode.list Type.encode args ]
142−aliasDecoder :: Decode.Decoder Alias
121+unionDecoder :: Decode.Decoder Docs.Union
143−aliasDecoder =
122+unionDecoder =
144− Alias
123+ Docs.Union
145− <$> Decode.field "name" Decode.text
124+ <$> Decode.field "args" (Decode.list Decode.text)
146− <*> Decode.field "comment" Decode.text
147− <*> Decode.field "args" (Decode.list Decode.text)
125+ <*> Decode.field "cases" (Decode.list caseDecoder)
148− <*> Decode.field "type" Type.decoder
128+caseDecoder :: Decode.Decoder ( Text, [Type.Type] )
131+ <$> Decode.index 0 Decode.text
132+ <*> Decode.index 1 (Decode.list Type.decoder)
155−encodeUnion :: Union -> Encode.Value
138+
156−encodeUnion (Union name comment args cases) =
139+encodeAlias :: ( Text, Docs.Good Docs.Alias ) -> Encode.Value
140+encodeAlias ( name, Docs.Entry comment (Docs.Alias args tipe) ) =
157 Encode.object
141 Encode.object
158 [ "name" ==> Encode.text name
142 [ "name" ==> Encode.text name
159 , "comment" ==> Encode.text comment
143 , "comment" ==> Encode.text comment
160 , "args" ==> Encode.list Encode.text args
144 , "args" ==> Encode.list Encode.text args
161− , "cases" ==> Encode.list encodeCase cases
145+ , "type" ==> Type.encode tipe
165−unionDecoder :: Decode.Decoder Union
168− <$> Decode.field "name" Decode.text
169− <*> Decode.field "comment" Decode.text
170− <*> Decode.field "args" (Decode.list Decode.text)
171− <*> Decode.field "cases" (Decode.list caseDecoder)
174−encodeCase :: ( Text, [Type.Type] ) -> Encode.Value
150+-- DECODE ALIAS
175−encodeCase ( tag, args ) =
176− Encode.list id [ Encode.text tag, Encode.list Type.encode args ]
179−caseDecoder :: Decode.Decoder ( Text, [Type.Type] )
153+aliasDecoder :: Decode.Decoder Docs.Alias
180−caseDecoder =
154+aliasDecoder =
182− <$> Decode.index 0 Decode.text
156+ <$> Decode.field "args" (Decode.list Decode.text)
183− <*> Decode.index 1 (Decode.list Type.decoder)
157+ <*> Decode.field "type" Type.decoder
187−-- JSON for VALUE
161+-- ENCODE VALUE
190−encodeValue :: Value -> Encode.Value
164+encodeValue :: ( Text, Docs.Good Docs.GoodValue ) -> Encode.Value
191−encodeValue (Value name comment tipe assocPrec) =
165+encodeValue ( name, Docs.Entry comment value ) =
192 Encode.object $
166 Encode.object $
193 [ "name" ==> Encode.text name
167 [ "name" ==> Encode.text name
194 , "comment" ==> Encode.text comment
168 , "comment" ==> Encode.text comment
195− , "type" ==> Type.encode tipe
198− case assocPrec of
171+ case value of
199− Nothing ->
172+ Docs.Value tipe ->
173+ [ "type" ==> Type.encode tipe
202− Just (assoc, prec) ->
176+ Docs.Infix tipe assoc prec ->
177+ [ "type" ==> Type.encode tipe
203− [ "associativity" ==> Encode.text assoc
178+ , "associativity" ==> Encode.text (Decl.assocToText assoc)
204 , "precedence" ==> Encode.int prec
179 , "precedence" ==> Encode.int prec
208−valueDecoder :: Decode.Decoder Value
187+valueDecoder :: Decode.Decoder Docs.GoodValue
209valueDecoder =
188valueDecoder =
211− <$> Decode.field "name" Decode.text
212− <*> Decode.field "comment" Decode.text
213− <*> Decode.field "type" Type.decoder
189+ do tipe <- Decode.field "type" Type.decoder
214− <*> Decode.maybe (
190+ Decode.oneOf
215− (,)
191+ [ Docs.Infix tipe
216− <$> Decode.field "associativity" Decode.text
192+ <$> Decode.field "associativity" assocDecoder
217− <*> Decode.field "precedence" Decode.int
193+ <*> Decode.field "precedence" Decode.int
218− )
194+ , Decode.succeed (Docs.Value tipe)
198+assocDecoder :: Decode.Decoder Decl.Assoc
200+ do txt <- Decode.text
202+ "left" -> Decode.succeed Decl.Left
203+ "non" -> Decode.succeed Decl.Non
204+ "right" -> Decode.succeed Decl.Right
205+ _ -> Decode.fail "an associativity"