on master help sign in
Simplify Docs.AST to simplify API diffing
commit774aebd7c583bcf3985946fc22846d787510ab03 authorEvan Czaplicki <evancz@users.noreply.github.com> dateFri 14 Apr 2017, 21:46 (10 years ago) parent56f76ac
8 files changed+308−289
src/AST/Declaration.hs+27−14 src/Canonicalize/Binops.hs+10−5 src/Docs/AST.hs+35−47 src/Docs/Centralize.hs+64−44 src/Docs/Check.hs+47−41 src/Elm/Compiler.hs+3−3 src/Elm/Docs.hs+119−132 src/Parse/Declaration.hs+3−3
src/AST/Declaration.hs+27−14
@@ -2,6 +2,8 @@
22{-# LANGUAGE OverloadedStrings #-}
33module AST.Declaration where
44
5+import Prelude hiding (Either(..))
6+import Control.Monad (liftM3)
57import Data.Binary
68import Data.Text (Text)
79
@@ -105,30 +107,40 @@ data Infix =
105107 }
106108
107109
108−data Assoc = L | N | R
110+data Assoc = Left | Non | Right
109111 deriving (Eq)
110112
111113
114+defaultAssociativity :: Assoc
115+defaultAssociativity =
116+ Left
117+
118+
119+defaultPrecedence :: Int
120+defaultPrecedence =
121+ 9
122+
123+
112124assocToText :: Assoc -> Text
113125assocToText assoc =
114126 case assoc of
115− L ->
127+ Left ->
116128 "left"
117129
118− N ->
130+ Non ->
119131 "non"
120132
121− R ->
133+ Right ->
122134 "right"
123135
124136
125137
126−-- BINARY CONVERSION
138+-- BINARY
127139
128140
129141instance Binary Infix where
130142 get =
131− Infix <$> get <*> get <*> get
143+ liftM3 Infix get get get
132144
133145 put (Infix op assoc prec) =
134146 do put op
@@ -139,15 +151,16 @@ instance Binary Infix where
139151instance Binary Assoc where
140152 get =
141153 do n <- getWord8
142− return $ case n of
143− 0 -> L
144− 1 -> N
145− 2 -> R
146− _ -> error "Error reading valid associativity from serialized string"
154+ return $
155+ case n of
156+ 0 -> Left
157+ 1 -> Non
158+ 2 -> Right
159+ _ -> error "Error reading valid associativity from serialized string"
147160
148161 put assoc =
149162 putWord8 $
150163 case assoc of
151− L -> 0
152− N -> 1
153− R -> 2
164+ Left -> 0
165+ Non -> 1
166+ Right -> 2
src/Canonicalize/Binops.hs+10−5
@@ -5,7 +5,7 @@ import Prelude hiding (last)
55import qualified Data.Map as Map
66import Data.Text (Text)
77
8−import AST.Declaration (Assoc(..))
8+import qualified AST.Declaration as Decl
99import qualified AST.Expression.Canonical as C
1010import qualified AST.Variable as Var
1111import qualified Canonicalize.Environment as Env
@@ -23,7 +23,7 @@ import qualified Reporting.Result as R
2323data Op =
2424 Op
2525 { _name :: Var.Canonical
26− , _assoc :: Assoc
26+ , _assoc :: Decl.Assoc
2727 , _prec :: Int
2828 , _region :: Region.Region
2929 }
@@ -32,10 +32,15 @@ data Op =
3232canonicalize :: Env.Env -> A.Located Text -> Var.Result Op
3333canonicalize env (A.A region op) =
3434 do name <- Var.variable region env op
35− let (assoc, prec) = Map.findWithDefault (L, 9) name (Env._infixes env)
35+ let (assoc, prec) = Map.findWithDefault defaults name (Env._infixes env)
3636 return $ Op name assoc prec region
3737
3838
39+defaults :: ( Decl.Assoc, Int )
40+defaults =
41+ ( Decl.defaultAssociativity, Decl.defaultPrecedence )
42+
43+
3944
4045-- FLATTEN
4146
@@ -94,10 +99,10 @@ flattenHelp makeBinop rootOp@(Op _ rootAssoc rootPrec _) middle last =
9499 else
95100
96101 case (rootAssoc, assoc) of
97− (L, L) ->
102+ (Decl.Left, Decl.Left) ->
98103 flattenHelp (\right -> binop name (makeBinop expr) right) op rest last
99104
100− (R, R) ->
105+ (Decl.Right, Decl.Right) ->
101106 flattenHelp (\right -> makeBinop (binop name expr right)) op rest last
102107
103108 (_, _) ->
src/Docs/AST.hs+35−47
@@ -1,9 +1,10 @@
11{-# OPTIONS_GHC -Wall #-}
22module Docs.AST
3− ( Centralized(..), Checked(..)
3+ ( Docs(..), Centralized, Checked
4+ , Entry(..), Raw, Good
5+ , Union(..)
6+ , Alias(..)
47 , Value(..), RawValue, GoodValue
5− , Alias(..), RawAlias, GoodAlias
6− , Union(..), RawUnion, GoodUnion
78 )
89 where
910
@@ -11,6 +12,7 @@ module Docs.AST
1112import qualified Data.Map as Map
1213import Data.Text (Text)
1314
15+import qualified AST.Declaration as Decl
1416import qualified Elm.Compiler.Type as Type
1517import qualified Reporting.Annotation as A
1618
@@ -19,73 +21,59 @@ import qualified Reporting.Annotation as A
1921-- DOCS
2022
2123
22−data Centralized =
23− Centralized
24− { comment :: Text
25− , values :: Map.Map Text (A.Located RawValue)
26− , aliases :: Map.Map Text (A.Located RawAlias)
27− , unions :: Map.Map Text (A.Located RawUnion)
28− }
29−
30−
31−data Checked =
32− Checked
33− { _comment :: Text
34− , _values :: Map.Map Text GoodValue
35− , _aliases :: Map.Map Text GoodAlias
36− , _unions :: Map.Map Text GoodUnion
24+data Docs unions aliases values =
25+ Docs
26+ { _overview :: Text
27+ , _unions :: Map.Map Text unions
28+ , _aliases :: Map.Map Text aliases
29+ , _values :: Map.Map Text values
3730 }
3831
3932
33+type Centralized =
34+ Docs (Raw Union) (Raw Alias) (Raw RawValue)
4035
41−-- VALUES
4236
43−
44−data Value comment tipe =
45− Value
46− { valueComment :: comment
47− , valueType :: tipe
48− , valueAssocPrec :: Maybe (Text,Int)
49− }
37+type Checked =
38+ Docs (Good Union) (Good Alias) (Good GoodValue)
5039
5140
52−type RawValue = Value (Maybe Text) (Maybe Type.Type)
5341
54−
55−type GoodValue = Value Text Type.Type
42+-- ENTRY
5643
5744
45+data Entry comment details =
46+ Entry
47+ { _comment :: !comment
48+ , _details :: !details
49+ }
5850
59−-- ALIAS
6051
52+type Raw a =
53+ A.Located (Entry (Maybe Text) a)
6154
62−data Alias comment =
63− Alias
64− { aliasComment :: comment
65− , aliasArgs :: [Text]
66− , aliasType :: Type.Type
67− }
6855
56+type Good a =
57+ Entry Text a
6958
70−type RawAlias = Alias (Maybe Text)
7159
7260
73−type GoodAlias = Alias Text
61+-- INFO
7462
7563
64+data Alias =
65+ Alias [Text] Type.Type
7666
77−-- UNION
7867
68+data Union =
69+ Union [Text] [(Text, [Type.Type])]
7970
80−data Union comment =
81− Union
82− { unionComment :: comment
83− , unionArgs :: [Text]
84− , unionCases :: [(Text, [Type.Type])]
85− }
8671
72+data Value tipe
73+ = Value tipe
74+ | Infix tipe Decl.Assoc Int
8775
88−type RawUnion = Union (Maybe Text)
8976
77+type RawValue = Value (Maybe Type.Type)
9078
91−type GoodUnion = Union Text
79+type GoodValue = Value Type.Type
src/Docs/Centralize.hs+64−44
@@ -5,76 +5,96 @@ import qualified Data.Map as Map
55import qualified Data.Maybe as Maybe
66import Data.Text (Text)
77
8−import qualified AST.Declaration as D
8+import qualified AST.Declaration as Decl
99import qualified AST.Expression.Canonical as Canonical
10+import qualified AST.Helpers as Help
1011import qualified AST.Pattern as Pattern
1112import qualified AST.Type as Type
1213import qualified Docs.AST as Docs
1314import qualified Elm.Compiler.Type.Extract as Extract
1415import qualified Reporting.Annotation as A
16+import qualified Reporting.Region as R
1517
1618
1719
18−-- CENTRALIZE DOCUMENTATION
20+-- CENTRALIZE
1921
2022
21−centralize :: D.Canonical -> Text -> Docs.Centralized
22−centralize (D.Decls defs unions aliases infixes) comment =
23+centralize :: Decl.Canonical -> Text -> Docs.Centralized
24+centralize (Decl.Decls defs unions aliases infixes) overview =
2325 let
2426 infixDict =
25− Map.fromList (map infixToEntry infixes)
27+ Map.fromList (map toInfixPair infixes)
2628 in
27− Docs.Centralized
28− comment
29− (Map.fromList (Maybe.mapMaybe (defToEntry infixDict) defs))
30− (Map.fromList (map aliasToEntry aliases))
29+ Docs.Docs
30+ overview
3131 (Map.fromList (map unionToEntry unions))
32+ (Map.fromList (map aliasToEntry aliases))
33+ (Map.fromList (Maybe.mapMaybe (defToEntry infixDict) defs))
3234
3335
3436
35−-- CONVERSION TO DOC ENTRIES
37+-- ENTRY
3638
3739
38−defToEntry
39− :: Map.Map Text (Text, Int)
40− -> A.Commented Canonical.Def
41− -> Maybe (Text, A.Located Docs.RawValue)
42−defToEntry infixDict (A.A (_, maybeComment) (Canonical.Def _ pattern _ maybeType)) =
43− case pattern of
44− A.A subregion (Pattern.Var name) ->
45− let
46− value =
47− Docs.Value
48− maybeComment
49− (fmap (Extract.extract . A.drop) maybeType)
50− (Map.lookup name infixDict)
51− in
52− Just (name, A.A subregion value)
40+type Entry a =
41+ (Text, Docs.Raw a)
5342
54− _ ->
55− Nothing
5643
44+makeEntry :: Text -> (R.Region, Maybe Text) -> details -> Entry details
45+makeEntry name (region, maybeComment) details =
46+ ( name, A.A region (Docs.Entry maybeComment details) )
47+
48+
49+
50+-- UNIONS
5751
58−unionToEntry :: A.Commented (D.Union Type.Canonical) -> (Text, A.Located Docs.RawUnion)
59−unionToEntry (A.A (region, maybeComment) (D.Type name args ctors)) =
60− let
61− ctors' =
62− map (second (map Extract.extract)) ctors
63− in
64− (name, A.A region (Docs.Union maybeComment args ctors'))
6552
53+unionToEntry :: A.Commented (Decl.Union Type.Canonical) -> Entry Docs.Union
54+unionToEntry (A.A ann (Decl.Type name args ctors)) =
55+ makeEntry name ann $ Docs.Union args $
56+ map (second (map Extract.extract)) ctors
6657
67−aliasToEntry :: A.Commented (D.Alias Type.Canonical) -> (Text, A.Located Docs.RawAlias)
68−aliasToEntry (A.A (region, maybeComment) (D.Type name args tipe)) =
69− ( name
70− , A.A region (Docs.Alias maybeComment args (Extract.extract tipe))
71− )
7258
7359
74−infixToEntry :: D.Infix -> (Text, (Text, Int))
75−infixToEntry (D.Infix name assoc precedence) =
60+-- ALIASES
61+
62+
63+aliasToEntry :: A.Commented (Decl.Alias Type.Canonical) -> Entry Docs.Alias
64+aliasToEntry (A.A ann (Decl.Type name args tipe)) =
65+ makeEntry name ann $ Docs.Alias args $ Extract.extract tipe
66+
67+
68+
69+-- VALUES
70+
71+
72+defToEntry :: Map.Map Text (Decl.Assoc, Int) -> A.Commented Canonical.Def -> Maybe (Entry Docs.RawValue)
73+defToEntry infixDict (A.A (_, maybeComment) definition) =
7674 let
77− fixity =
78− (D.assocToText assoc, precedence)
75+ (Canonical.Def _ (A.A region pattern) _ maybeType) =
76+ definition
77+
78+ tipe =
79+ fmap (Extract.extract . A.drop) maybeType
7980 in
80− ( name, fixity )
81+ case pattern of
82+ Pattern.Var name ->
83+ Just $ makeEntry name (region, maybeComment) $
84+ case Map.lookup name infixDict of
85+ Just (assoc, prec) ->
86+ Docs.Infix tipe assoc prec
87+
88+ Nothing ->
89+ if Help.isOp name then
90+ Docs.Infix tipe Decl.defaultAssociativity Decl.defaultPrecedence
91+ else
92+ Docs.Value tipe
93+
94+ _ ->
95+ Nothing
96+
97+
98+toInfixPair :: Decl.Infix -> ( Text, (Decl.Assoc, Int) )
99+toInfixPair (Decl.Infix name assoc precedence) =
100+ ( name, (assoc, precedence) )
src/Docs/Check.hs+47−41
@@ -42,18 +42,18 @@ check exports (A.A region maybeDocs) =
4242
4343
4444checkHelp :: R.Region -> Exposing.Canonical -> Docs.Centralized -> R.Result () w Error.Error Docs.Checked
45−checkHelp region exposing (Docs.Centralized comment values aliases unions) =
46− do docNames <- parseNames region comment
45+checkHelp region exposing (Docs.Docs overview unions aliases values) =
46+ do docNames <- parseNames region overview
4747
4848 let docSet = Set.fromList (map A.drop docNames)
4949 let restrict checker dict =
50− Map.traverseWithKey checker (Map.restrictKeys dict docSet)
50+ Map.traverseWithKey (checkEntry checker) (Map.restrictKeys dict docSet)
5151
5252 R.mapError Error.Docs $
53− Docs.Checked comment
54− <$> restrict checkValue values
53+ Docs.Docs overview
54+ <$> restrict (checkUnion exposing) unions
5555 <*> restrict checkAlias aliases
56− <*> restrict (checkUnion exposing) unions
56+ <*> restrict checkValue values
5757 <* checkCommentNames region exposing docNames
5858
5959
@@ -121,61 +121,67 @@ checkComment region name maybeComment =
121121
122122
123123
124−-- CHECK VALUE
124+-- CHECK ENTRY
125125
126126
127−checkValue :: Text -> A.Located Docs.RawValue -> Result w Docs.GoodValue
128−checkValue name (A.A region (Docs.Value comment tipe assocPrec)) =
129− Docs.Value
127+checkEntry :: (R.Region -> Text -> a -> Result w b) -> Text -> Docs.Raw a -> Result w (Docs.Good b)
128+checkEntry checkDetails name (A.A region (Docs.Entry comment details)) =
129+ Docs.Entry
130130 <$> checkComment region name comment
131− <*> checkValueType region name tipe
132− <*> pure assocPrec
131+ <*> checkDetails region name details
133132
134133
135−checkValueType :: R.Region -> Text -> Maybe Type.Type -> Result w Type.Type
136−checkValueType region name maybeType =
137− case maybeType of
138− Just tipe ->
139− R.ok tipe
140134
141− Nothing ->
142− R.throw region (E.NoType name)
135+-- CHECK UNION
136+
137+
138+checkUnion :: Exposing.Canonical -> R.Region -> Text -> Docs.Union -> Result w Docs.Union
139+checkUnion (Exposing.Canonical _ _ unions) _region name (Docs.Union args ctors) =
140+ let
141+ publicCtors =
142+ maybe [] id (lookup name unions)
143+
144+ isPublic (ctor, _) =
145+ ctor `elem` publicCtors
146+ in
147+ pure $ Docs.Union args (filter isPublic ctors)
143148
144149
145150
146151-- CHECK ALIAS
147152
148153
149−checkAlias :: Text -> A.Located Docs.RawAlias -> Result w Docs.GoodAlias
150−checkAlias name (A.A region (Docs.Alias comment args tipe)) =
151− Docs.Alias
152− <$> checkComment region name comment
153− <*> pure args
154− <*> pure tipe
154+checkAlias :: R.Region -> Text -> Docs.Alias -> Result w Docs.Alias
155+checkAlias _ _ alias =
156+ pure alias
155157
156158
157159
158−-- CHECK UNION
160+-- CHECK VALUE
159161
160162
161−checkUnion :: Exposing.Canonical -> Text -> A.Located Docs.RawUnion -> Result w Docs.GoodUnion
162−checkUnion (Exposing.Canonical _ _ unions) name (A.A region (Docs.Union comment args ctors)) =
163− Docs.Union
164− <$> checkComment region name comment
165− <*> pure args
166− <*> checkUnionCtors (Map.fromList unions) name ctors
163+checkValue :: R.Region -> Text -> Docs.RawValue -> Result w Docs.GoodValue
164+checkValue region name value =
165+ case value of
166+ Docs.Value tipe ->
167+ Docs.Value
168+ <$> checkValueType region name tipe
167169
170+ Docs.Infix tipe assoc prec ->
171+ Docs.Infix
172+ <$> checkValueType region name tipe
173+ <*> pure assoc
174+ <*> pure prec
168175
169−checkUnionCtors :: Map.Map Text [Text] -> Text -> [(Text, [Type.Type])] -> Result w [(Text, [Type.Type])]
170−checkUnionCtors unions name ctors =
171− let
172− publicCtors =
173− maybe [] id (Map.lookup name unions)
174176
175− isPublic (ctor, _) =
176− ctor `elem` publicCtors
177− in
178− R.ok $ filter isPublic ctors
177+checkValueType :: R.Region -> Text -> Maybe Type.Type -> Result w Type.Type
178+checkValueType region name maybeType =
179+ case maybeType of
180+ Just tipe ->
181+ R.ok tipe
182+
183+ Nothing ->
184+ R.throw region (E.NoType name)
179185
180186
181187
src/Elm/Compiler.hs+3−3
@@ -125,7 +125,7 @@ data Context =
125125
126126data Result =
127127 Result
128− { _docs :: Maybe Docs.Documentation
128+ { _docs :: Maybe Docs.Module
129129 , _iface :: M.Interface
130130 , _objs :: Obj.Graph
131131 }
@@ -135,7 +135,7 @@ data Result =
135135-- DOCUMENTATION
136136
137137
138−docsGen :: Bool -> Module.Optimized -> Result.Result () w Error.Error (Maybe Docs.Documentation)
138+docsGen :: Bool -> Module.Optimized -> Result.Result () w Error.Error (Maybe Docs.Module)
139139docsGen isExposed (Module.Module name info) =
140140 if not isExposed then
141141 Result.ok Nothing
@@ -143,7 +143,7 @@ docsGen isExposed (Module.Module name info) =
143143 else
144144 let
145145 toDocs checked =
146− Just (Docs.fromCheckedDocs (ModuleName._module name) checked)
146+ Just (Docs.Module (ModuleName._module name) checked)
147147 in
148148 toDocs <$> Docs.check (Module.exports info) (Module.docs info)
149149
src/Elm/Docs.hs+119−132
@@ -1,218 +1,205 @@
11{-# OPTIONS_GHC -Wall #-}
22{-# LANGUAGE OverloadedStrings #-}
33module Elm.Docs
4− ( Documentation(..)
5− , Alias(..)
6− , Union(..)
7− , Value(..)
8− , fromCheckedDocs
4+ ( Documentation
5+ , Module(..)
6+ , toDict
97 , decoder
108 , encode
9+ , Docs.Docs(..)
10+ , Docs.Checked
11+ , Docs.Entry(..)
12+ , Docs.Union(..)
13+ , Docs.Alias(..)
14+ , Docs.Value(..)
1115 )
1216 where
1317
18+
1419import qualified Data.Map as Map
1520import Data.Text (Text)
1621
22+import qualified AST.Declaration as Decl
1723import qualified Docs.AST as Docs
1824import qualified Elm.Compiler.Module as Module
1925import qualified Elm.Compiler.Type as Type
20−import qualified Elm.Compiler.Version as Version
21−import qualified Elm.Package as Pkg
2226import qualified Json.Decode as Decode
2327import qualified Json.Encode as Encode
2428import Json.Encode ((==>))
2529
2630
2731
28−-- DATA STRUCTURES
32+-- DOCUMENTATION
2933
3034
31−data Documentation =
32− Documentation
33− { _name :: Module.Raw
34− , _comment :: Text
35− , _aliases :: [Alias]
36− , _types :: [Union]
37− , _values :: [Value]
38− , _version :: Maybe Pkg.Version
39− }
35+type Documentation =
36+ Map.Map Module.Raw Docs.Checked
4037
4138
42−data Alias =
43− Alias
44− { _a_name :: Text
45− , _a_comment :: Text
46− , _a_args :: [Text]
47− , _a_type :: Type.Type
39+data Module =
40+ Module
41+ { _name :: !Module.Raw
42+ , _docs :: !Docs.Checked
4843 }
4944
5045
51−data Union =
52− Union
53− { _u_name :: Text
54− , _u_comment :: Text
55− , _u_args :: [Text]
56− , _u_cases :: [(Text, [Type.Type])]
57− }
58−
46+toDict :: [Module] -> Documentation
47+toDict modules =
48+ Map.fromList $ map (\(Module name docs) -> (name, docs)) modules
5949
60−data Value =
61− Value
62− { _v_name :: Text
63− , _v_comment :: Text
64− , _v_type :: Type.Type
65− , _v_fix :: Maybe (Text,Int)
66− }
6750
6851
52+-- ENCODE
6953
70−-- FROM CHECKED DOCS
7154
55+encode :: Module -> Encode.Value
56+encode (Module name (Docs.Docs overview unions aliases values)) =
57+ Encode.object $
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)
63+ ]
7264
73−fromCheckedDocs :: Module.Raw -> Docs.Checked -> Documentation
74−fromCheckedDocs name (Docs.Checked comment values aliases unions) =
75− let
76− toValue (vName, Docs.Value vComment tipe fix) =
77− Value vName vComment tipe fix
7865
79− toAlias (aName, Docs.Alias aComment args tipe) =
80− Alias aName aComment args tipe
8166
82− toUnion (uName, Docs.Union uComment args cases) =
83− Union uName uComment args cases
84− in
85− Documentation
86− name
87− comment
88− (map toAlias (Map.toList aliases))
89− (map toUnion (Map.toList unions))
90− (map toValue (Map.toList values))
91− (Just Version.version)
67+-- DECODE
9268
9369
70+decoder :: Decode.Decoder Module
71+decoder =
72+ Module
73+ <$> Decode.field "name" Module.decoder
74+ <*> decodeDocs
9475
95−-- JSON
9676
77+decodeDocs :: Decode.Decoder Docs.Checked
78+decodeDocs =
79+ Docs.Docs
80+ <$> Decode.field "comment" Decode.text
81+ <*> Decode.field "types" (entryDictDecoder unionDecoder)
82+ <*> Decode.field "aliases" (entryDictDecoder aliasDecoder)
83+ <*> Decode.field "values" (entryDictDecoder valueDecoder)
9784
98−encode :: Documentation -> Encode.Value
99−encode (Documentation name comment aliases types values elmVersion) =
100− Encode.object $
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
106− ]
107− ++
108− case elmVersion of
109− Nothing ->
110− []
11185
112− Just version ->
113− [ "generated-with-elm-version" ==> Pkg.encodeVersion version
114− ]
86+entryDictDecoder :: Decode.Decoder a -> Decode.Decoder (Map.Map Text (Docs.Good a))
87+entryDictDecoder subDecoder =
88+ Map.fromList <$> Decode.list (entryDecoder subDecoder)
11589
11690
117−decoder :: Decode.Decoder Documentation
118−decoder =
119− Documentation
120− <$> Decode.field "name" Module.decoder
121− <*> Decode.field "comment" Decode.text
122− <*> Decode.field "aliases" (Decode.list aliasDecoder)
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)
91+entryDecoder :: Decode.Decoder a -> Decode.Decoder ( Text, Docs.Good a )
92+entryDecoder subDecoder =
93+ Decode.map2 (,) (Decode.field "name" Decode.text) $
94+ Decode.map2 Docs.Entry (Decode.field "comment" Decode.text) $
95+ subDecoder
12696
12797
12898
129−-- JSON for ALIAS
99+-- ENCODE UNION
130100
131101
132−encodeAlias :: Alias -> Encode.Value
133−encodeAlias (Alias name comment args tipe) =
102+encodeUnion :: ( Text, Docs.Good Docs.Union ) -> Encode.Value
103+encodeUnion ( name, Docs.Entry comment (Docs.Union args cases) ) =
134104 Encode.object
135105 [ "name" ==> Encode.text name
136106 , "comment" ==> Encode.text comment
137107 , "args" ==> Encode.list Encode.text args
138− , "type" ==> Type.encode tipe
108+ , "cases" ==> Encode.list encodeCase cases
139109 ]
140110
141111
142−aliasDecoder :: Decode.Decoder Alias
143−aliasDecoder =
144− Alias
145− <$> Decode.field "name" Decode.text
146− <*> Decode.field "comment" Decode.text
147− <*> Decode.field "args" (Decode.list Decode.text)
148− <*> Decode.field "type" Type.decoder
112+encodeCase :: ( Text, [Type.Type] ) -> Encode.Value
113+encodeCase ( tag, args ) =
114+ Encode.list id [ Encode.text tag, Encode.list Type.encode args ]
115+
116+
117+
118+-- DECODE UNION
119+
120+
121+unionDecoder :: Decode.Decoder Docs.Union
122+unionDecoder =
123+ Docs.Union
124+ <$> Decode.field "args" (Decode.list Decode.text)
125+ <*> Decode.field "cases" (Decode.list caseDecoder)
149126
150127
128+caseDecoder :: Decode.Decoder ( Text, [Type.Type] )
129+caseDecoder =
130+ (,)
131+ <$> Decode.index 0 Decode.text
132+ <*> Decode.index 1 (Decode.list Type.decoder)
133+
151134
152−-- JSON for UNION
153135
136+-- ENCODE ALIAS
154137
155−encodeUnion :: Union -> Encode.Value
156−encodeUnion (Union name comment args cases) =
138+
139+encodeAlias :: ( Text, Docs.Good Docs.Alias ) -> Encode.Value
140+encodeAlias ( name, Docs.Entry comment (Docs.Alias args tipe) ) =
157141 Encode.object
158142 [ "name" ==> Encode.text name
159143 , "comment" ==> Encode.text comment
160144 , "args" ==> Encode.list Encode.text args
161− , "cases" ==> Encode.list encodeCase cases
145+ , "type" ==> Type.encode tipe
162146 ]
163147
164148
165−unionDecoder :: Decode.Decoder Union
166−unionDecoder =
167− 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)
172−
173149
174−encodeCase :: ( Text, [Type.Type] ) -> Encode.Value
175−encodeCase ( tag, args ) =
176− Encode.list id [ Encode.text tag, Encode.list Type.encode args ]
150+-- DECODE ALIAS
177151
178152
179−caseDecoder :: Decode.Decoder ( Text, [Type.Type] )
180−caseDecoder =
181− (,)
182− <$> Decode.index 0 Decode.text
183− <*> Decode.index 1 (Decode.list Type.decoder)
153+aliasDecoder :: Decode.Decoder Docs.Alias
154+aliasDecoder =
155+ Docs.Alias
156+ <$> Decode.field "args" (Decode.list Decode.text)
157+ <*> Decode.field "type" Type.decoder
184158
185159
186160
187−-- JSON for VALUE
161+-- ENCODE VALUE
188162
189163
190−encodeValue :: Value -> Encode.Value
191−encodeValue (Value name comment tipe assocPrec) =
164+encodeValue :: ( Text, Docs.Good Docs.GoodValue ) -> Encode.Value
165+encodeValue ( name, Docs.Entry comment value ) =
192166 Encode.object $
193167 [ "name" ==> Encode.text name
194168 , "comment" ==> Encode.text comment
195− , "type" ==> Type.encode tipe
196169 ]
197170 ++
198− case assocPrec of
199− Nothing ->
200− []
171+ case value of
172+ Docs.Value tipe ->
173+ [ "type" ==> Type.encode tipe
174+ ]
201175
202− Just (assoc, prec) ->
203− [ "associativity" ==> Encode.text assoc
176+ Docs.Infix tipe assoc prec ->
177+ [ "type" ==> Type.encode tipe
178+ , "associativity" ==> Encode.text (Decl.assocToText assoc)
204179 , "precedence" ==> Encode.int prec
205180 ]
206181
207182
208−valueDecoder :: Decode.Decoder Value
183+
184+-- DECODE VALUE
185+
186+
187+valueDecoder :: Decode.Decoder Docs.GoodValue
209188valueDecoder =
210− Value
211− <$> Decode.field "name" Decode.text
212− <*> Decode.field "comment" Decode.text
213− <*> Decode.field "type" Type.decoder
214− <*> Decode.maybe (
215− (,)
216− <$> Decode.field "associativity" Decode.text
217− <*> Decode.field "precedence" Decode.int
218− )
189+ do tipe <- Decode.field "type" Type.decoder
190+ Decode.oneOf
191+ [ Docs.Infix tipe
192+ <$> Decode.field "associativity" assocDecoder
193+ <*> Decode.field "precedence" Decode.int
194+ , Decode.succeed (Docs.Value tipe)
195+ ]
196+
197+
198+assocDecoder :: Decode.Decoder Decl.Assoc
199+assocDecoder =
200+ do txt <- Decode.text
201+ case txt of
202+ "left" -> Decode.succeed Decl.Left
203+ "non" -> Decode.succeed Decl.Non
204+ "right" -> Decode.succeed Decl.Right
205+ _ -> Decode.fail "an associativity"
src/Parse/Declaration.hs+3−3
@@ -117,11 +117,11 @@ infixDecl :: R.Position -> SParser Decl.Source
117117infixDecl start =
118118 oneOf
119119 [ do keyword "infixl"
120− inContext start E.Infix $ infixDeclHelp start Decl.L
120+ inContext start E.Infix $ infixDeclHelp start Decl.Left
121121 , do keyword "infixr"
122− inContext start E.Infix $ infixDeclHelp start Decl.R
122+ inContext start E.Infix $ infixDeclHelp start Decl.Right
123123 , do keyword "infix"
124− inContext start E.Infix $ infixDeclHelp start Decl.N
124+ inContext start E.Infix $ infixDeclHelp start Decl.Non
125125 ]
126126
127127