git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge pull request #1116 from hdgarrood/infix-docs
13ad776Phil Freeman
psc-publish/tests/Test.hs+11−8
@@ -1,5 +1,6 @@
1{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
1{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
2{-# OPTIONS_GHC -fno-warn-unused-imports #-}
2{-# OPTIONS_GHC -fno-warn-unused-imports #-}
3+{-# LANGUAGE ScopedTypeVariables #-}
3
4
4-- | To run these tests:
5-- | To run these tests:
5--
6--
@@ -11,6 +12,7 @@ module Test where
11
12
12import Control.Monad
13import Control.Monad
13import Control.Applicative
14import Control.Applicative
15+import Control.Exception
14import System.Process
16import System.Process
15import System.Directory
17import System.Directory
16import qualified Data.ByteString.Lazy as BL
18import qualified Data.ByteString.Lazy as BL
@@ -21,17 +23,17 @@ import Data.Aeson.BetterErrors
21import Main
23import Main
22import Language.PureScript.Docs
24import Language.PureScript.Docs
23
25
24−packageName = "purescript-integers"
26+pkgName = "purescript-prelude"
25−packageUrl = "https://github.com/purescript/" ++ packageName
27+packageUrl = "https://github.com/purescript/" ++ pkgName
26−packageDir = "tmp/" ++ packageName
28+packageDir = "tmp/" ++ pkgName
27
29
28−pushd :: FilePath -> IO a -> IO a
30+pushd :: forall a. FilePath -> IO a -> IO a
29pushd dir act = do
31pushd dir act = do
30 original <- getCurrentDirectory
32 original <- getCurrentDirectory
31 setCurrentDirectory dir
33 setCurrentDirectory dir
32− result <- act
34+ result <- try act :: IO (Either IOException a)
33 setCurrentDirectory original
35 setCurrentDirectory original
34− return result
36+ either throwIO return result
35
37
36clonePackage :: IO ()
38clonePackage :: IO ()
37clonePackage = do
39clonePackage = do
@@ -39,8 +41,9 @@ clonePackage = do
39 pushd packageDir $ do
41 pushd packageDir $ do
40 exists <- doesDirectoryExist ".git"
42 exists <- doesDirectoryExist ".git"
41 unless exists $ do
43 unless exists $ do
42− putStrLn ("Cloning " ++ packageName ++ " into " ++ packageDir ++ "...")
44+ putStrLn ("Cloning " ++ pkgName ++ " into " ++ packageDir ++ "...")
43 readProcess "git" ["clone", packageUrl, "."] "" >>= putStr
45 readProcess "git" ["clone", packageUrl, "."] "" >>= putStr
46+ readProcess "git" ["tag", "v999.0.0"] "" >>= putStr
44
47
45bowerInstall :: IO ()
48bowerInstall :: IO ()
46bowerInstall = do
49bowerInstall = do
@@ -54,7 +57,7 @@ getPackage = do
54 pushd packageDir preparePackage
57 pushd packageDir preparePackage
55
58
56data TestResult
59data TestResult
57− = ParseFailed (ParseError UploadedPackageError)
60+ = ParseFailed (ParseError PackageError)
58 | Mismatch ByteString ByteString -- ^ encoding before, encoding after
61 | Mismatch ByteString ByteString -- ^ encoding before, encoding after
59 | Pass ByteString
62 | Pass ByteString
60 deriving (Show)
63 deriving (Show)
src/Language/PureScript/AST/Exported.hs+12−8
@@ -98,8 +98,10 @@ typeInstanceConstituents _ = []
98
98
99
99
100-- |
100-- |
101−-- Test if a declaration is exported, given a module's export list. Prefer
101+-- Test if a declaration is exported, given a module's export list. Note that
102+-- this function does not account for type instance declarations of
103+-- non-exported types, or non-exported data constructors. Therefore, you should
102−-- 'exportedDeclarations' to this function, where possible.
104+-- prefer 'exportedDeclarations' to this function, where possible.
103--
105--
104isExported :: Maybe [DeclarationRef] -> Declaration -> Bool
106isExported :: Maybe [DeclarationRef] -> Declaration -> Bool
105isExported Nothing _ = True
107isExported Nothing _ = True
@@ -107,13 +109,15 @@ isExported _ TypeInstanceDeclaration{} = True
107isExported exps (PositionedDeclaration _ _ d) = isExported exps d
109isExported exps (PositionedDeclaration _ _ d) = isExported exps d
108isExported (Just exps) decl = any (matches decl) exps
110isExported (Just exps) decl = any (matches decl) exps
109 where
111 where
110− matches (TypeDeclaration ident _) (ValueRef ident') = ident == ident'
112+ matches (TypeDeclaration ident _) (ValueRef ident') = ident == ident'
111− matches (ValueDeclaration ident _ _ _) (ValueRef ident') = ident == ident'
113+ matches (ValueDeclaration ident _ _ _) (ValueRef ident') = ident == ident'
112− matches (ExternDeclaration ident _) (ValueRef ident') = ident == ident'
114+ matches (ExternDeclaration ident _) (ValueRef ident') = ident == ident'
115+ matches (FixityDeclaration _ name) (ValueRef ident') = name == runIdent ident'
113− matches (DataDeclaration _ ident _ _) (TypeRef ident' _) = ident == ident'
116+ matches (DataDeclaration _ ident _ _) (TypeRef ident' _) = ident == ident'
114− matches (ExternDataDeclaration ident _) (TypeRef ident' _) = ident == ident'
117+ matches (ExternDataDeclaration ident _) (TypeRef ident' _) = ident == ident'
115− matches (TypeSynonymDeclaration ident _ _) (TypeRef ident' _) = ident == ident'
118+ matches (TypeSynonymDeclaration ident _ _) (TypeRef ident' _) = ident == ident'
116 matches (TypeClassDeclaration ident _ _ _) (TypeClassRef ident') = ident == ident'
119 matches (TypeClassDeclaration ident _ _ _) (TypeClassRef ident') = ident == ident'
120+
117 matches (PositionedDeclaration _ _ d) r = d `matches` r
121 matches (PositionedDeclaration _ _ d) r = d `matches` r
118 matches d (PositionedDeclarationRef _ _ r) = d `matches` r
122 matches d (PositionedDeclarationRef _ _ r) = d `matches` r
119 matches _ _ = False
123 matches _ _ = False
src/Language/PureScript/AST/Operators.hs+14−2
@@ -12,11 +12,14 @@
12--
12--
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15+{-# LANGUAGE OverloadedStrings #-}
15{-# LANGUAGE DeriveDataTypeable #-}
16{-# LANGUAGE DeriveDataTypeable #-}
16
17
17module Language.PureScript.AST.Operators where
18module Language.PureScript.AST.Operators where
18
19
19import qualified Data.Data as D
20import qualified Data.Data as D
21+import Data.Aeson ((.=))
22+import qualified Data.Aeson as A
20
23
21-- |
24-- |
22-- A precedence level for an infix operator
25-- A precedence level for an infix operator
@@ -26,14 +29,23 @@ type Precedence = Integer
26-- |
29-- |
27-- Associativity for infix operators
30-- Associativity for infix operators
28--
31--
29−data Associativity = Infixl | Infixr | Infix deriving (D.Data, D.Typeable)
32+data Associativity = Infixl | Infixr | Infix deriving (Eq, Ord, D.Data, D.Typeable)
30
33
31instance Show Associativity where
34instance Show Associativity where
32 show Infixl = "infixl"
35 show Infixl = "infixl"
33 show Infixr = "infixr"
36 show Infixr = "infixr"
34 show Infix = "infix"
37 show Infix = "infix"
35
38
39+instance A.ToJSON Associativity where
40+ toJSON = A.toJSON . show
41+
36-- |
42-- |
37-- Fixity data for infix operators
43-- Fixity data for infix operators
38--
44--
39−data Fixity = Fixity Associativity Precedence deriving (Show, D.Data, D.Typeable)
45+data Fixity = Fixity Associativity Precedence deriving (Show, Eq, Ord, D.Data, D.Typeable)
46+
47+instance A.ToJSON Fixity where
48+ toJSON (Fixity associativity precedence) =
49+ A.object [ "associativity" .= associativity
50+ , "precedence" .= precedence
51+ ]
src/Language/PureScript/Docs/AsMarkdown.hs+16
@@ -44,6 +44,8 @@ declAsMarkdown RenderedDeclaration{..} = do
44 zipWithM_ (\f c -> tell' (childToString f c)) (First : repeat NotFirst) children
44 zipWithM_ (\f c -> tell' (childToString f c)) (First : repeat NotFirst) children
45 spacer
45 spacer
46
46
47+ for_ rdFixity (\fixity -> fixityAsMarkdown fixity >> spacer)
48+
47 for_ rdComments tell'
49 for_ rdComments tell'
48
50
49 unless (null instances) $ do
51 unless (null instances) $ do
@@ -61,6 +63,20 @@ codeToString = outputWith elemAsMarkdown
61 elemAsMarkdown (Keyword x) = x
63 elemAsMarkdown (Keyword x) = x
62 elemAsMarkdown Space = " "
64 elemAsMarkdown Space = " "
63
65
66+fixityAsMarkdown :: P.Fixity -> Docs
67+fixityAsMarkdown (P.Fixity associativity precedence) =
68+ tell' $ concat [ "_"
69+ , associativityStr
70+ , " / precedence "
71+ , show precedence
72+ , "_"
73+ ]
74+ where
75+ associativityStr = case associativity of
76+ P.Infixl -> "left-associative"
77+ P.Infixr -> "right-associative"
78+ P.Infix -> "non-associative"
79+
64childToString :: First -> RenderedChildDeclaration -> String
80childToString :: First -> RenderedChildDeclaration -> String
65childToString f RenderedChildDeclaration{..} =
81childToString f RenderedChildDeclaration{..} =
66 case rcdType of
82 case rcdType of
src/Language/PureScript/Docs/Render.hs+104−47
@@ -5,16 +5,17 @@
5
5
6-- | Functions for rendering documentation generated from PureScript code.
6-- | Functions for rendering documentation generated from PureScript code.
7
7
8−module Language.PureScript.Docs.Render (
8+module Language.PureScript.Docs.Render
9− renderModule,
9+ ( renderModule
10− collectBookmarks
10+ , collectBookmarks
11−) where
11+ ) where
12
12
13import Control.Monad
13import Control.Monad
14+import Control.Category ((>>>))
14import Data.Either
15import Data.Either
15import Data.Monoid ((<>))
16import Data.Monoid ((<>))
16−import Data.Maybe (mapMaybe)
17+import Data.Maybe (mapMaybe, isNothing)
17−import Data.List (nub)
18+import Data.List (nub, isPrefixOf, isSuffixOf)
18
19
19import qualified Language.PureScript as P
20import qualified Language.PureScript as P
20
21
@@ -27,51 +28,82 @@ import Language.PureScript.Docs.Utils.MonoidExtras
27--
28--
28renderModule :: P.Module -> RenderedModule
29renderModule :: P.Module -> RenderedModule
29renderModule m@(P.Module coms moduleName _ _) =
30renderModule m@(P.Module coms moduleName _ _) =
30− RenderedModule (show moduleName) comments declarations
31+ RenderedModule (show moduleName) comments (declarations m)
31 where
32 where
32 comments = renderComments coms
33 comments = renderComments coms
33− declarations = groupChildren declarationsWithChildren
34+ declarations =
34− declarationsWithChildren = mapMaybe go (P.exportedDeclarations m)
35+ P.exportedDeclarations
35− go decl = getDeclarationTitle decl
36+ >>> mapMaybe (\d -> getDeclarationTitle d >>= renderDeclaration d)
36− >>= renderDeclaration decl
37+ >>> augmentDeclarations
37−
38+ >>> map addDefaultFixity
39+
38−-- | An intermediate stage which we go through during rendering.
40+-- | The data type for an intermediate stage which we go through during
41+-- rendering.
39--
42--
40-- In the first pass, we take all top level declarations in the module, and
43-- In the first pass, we take all top level declarations in the module, and
41−-- render those which should appear at the top level in the output, as well as
44+-- collect other information which will later be used to augment the top level
42−-- those which should appear as children of other declarations in the output.
45+-- declarations. These two situation correspond to the Right and Left
46+-- constructors, respectively.
43--
47--
44−-- In the second pass, we move all children under their respective parents,
48+-- In the second pass, we go over all of the Left values and augment the
45−-- or discard them if none are found.
49+-- relevant declarations, leaving only the augmented Right values.
46--
50--
47−-- This two-pass system is only necessary for type instance declarations, since
51+-- Note that in the Left case, we provide a [String] as well as augment
48−-- they appear at the top level in the AST, and since they might need to appear
52+-- information. The [String] value should be a list of titles of declarations
49−-- as children in two places (for example, if a data type defined in a module
53+-- that the augmentation should apply to. For example, for a type instance
50−-- is an instance of a type class also defined in that module).
54+-- declaration, that would be any types or type classes mentioned in the
55+-- instance. For a fixity declaration, it would be just the relevant operator's
56+-- name.
57+type IntermediateDeclaration
58+ = Either ([String], DeclarationAugment) RenderedDeclaration
59+
60+-- | Some data which will be used to augment a RenderedDeclaration in the
61+-- output.
51--
62--
52−-- This data type is used as an intermediate type between the two stages. The
63+-- The AugmentChild constructor allows us to move all children under their
53−-- Left case is a child declaration, together with a list of parent declaration
64+-- respective parents. It is only necessary for type instance declarations,
54−-- titles which this may appear as a child of.
65+-- since they appear at the top level in the AST, and since they might need to
66+-- appear as children in two places (for example, if a data type defined in a
67+-- module is an instance of a type class also defined in that module).
55--
68--
56−-- The Right case is a top level declaration which should pass straight through
69+-- The AugmentFixity constructor allows us to augment operator definitions
57−-- the second stage; the only way it might change is if child declarations are
70+-- with their associativity and precedence.
58−-- added to it.
71+data DeclarationAugment
59−type IntermediateDeclaration
72+ = AugmentChild RenderedChildDeclaration
60− = Either ([String], RenderedChildDeclaration) RenderedDeclaration
73+ | AugmentFixity P.Fixity
61−
74+
62−-- | Move child declarations into their respective parents; the second pass.
75+-- | Augment top-level declarations; the second pass. See the comments under
63−-- See the comments under the type synonym IntermediateDeclaration for more
76+-- the type synonym IntermediateDeclaration for more information.
64−-- information.
65−groupChildren :: [IntermediateDeclaration] -> [RenderedDeclaration]
77+augmentDeclarations :: [IntermediateDeclaration] -> [RenderedDeclaration]
66−groupChildren (partitionEithers -> (children, toplevels)) =
78+augmentDeclarations (partitionEithers -> (augments, toplevels)) =
67− foldl go toplevels children
79+ foldl go toplevels augments
68 where
80 where
69− go ds (parentTitles, child) =
81+ go ds (parentTitles, a) =
70 map (\d ->
82 map (\d ->
71 if rdTitle d `elem` parentTitles
83 if rdTitle d `elem` parentTitles
72− then d { rdChildren = rdChildren d ++ [child] }
84+ then augmentWith a d
73 else d) ds
85 else d) ds
74
86
87+ augmentWith a d =
88+ case a of
89+ AugmentChild child ->
90+ d { rdChildren = rdChildren d ++ [child] }
91+ AugmentFixity fixity ->
92+ d { rdFixity = Just fixity }
93+
94+-- | Add the default operator fixity for operators which do not have associated
95+-- fixity declarations.
96+--
97+-- TODO: This may no longer be necessary after issue 806 is resolved, hopefully
98+-- in 0.8.
99+addDefaultFixity :: RenderedDeclaration -> RenderedDeclaration
100+addDefaultFixity rd@RenderedDeclaration{..}
101+ | isOp rdTitle && isNothing rdFixity = rd { rdFixity = Just defaultFixity }
102+ | otherwise = rd
103+ where
104+ isOp str = "(" `isPrefixOf` str && ")" `isSuffixOf` str
105+ defaultFixity = P.Fixity P.Infixl (-1)
106+
75getDeclarationTitle :: P.Declaration -> Maybe String
107getDeclarationTitle :: P.Declaration -> Maybe String
76getDeclarationTitle (P.TypeDeclaration name _) = Just (show name)
108getDeclarationTitle (P.TypeDeclaration name _) = Just (show name)
77getDeclarationTitle (P.ExternDeclaration name _) = Just (show name)
109getDeclarationTitle (P.ExternDeclaration name _) = Just (show name)
@@ -80,11 +112,23 @@ getDeclarationTitle (P.ExternDataDeclaration name _) = Just (show name)
80getDeclarationTitle (P.TypeSynonymDeclaration name _ _) = Just (show name)
112getDeclarationTitle (P.TypeSynonymDeclaration name _ _) = Just (show name)
81getDeclarationTitle (P.TypeClassDeclaration name _ _ _) = Just (show name)
113getDeclarationTitle (P.TypeClassDeclaration name _ _ _) = Just (show name)
82getDeclarationTitle (P.TypeInstanceDeclaration name _ _ _ _) = Just (show name)
114getDeclarationTitle (P.TypeInstanceDeclaration name _ _ _ _) = Just (show name)
115+getDeclarationTitle (P.FixityDeclaration _ name) = Just ("(" ++ name ++ ")")
83getDeclarationTitle (P.PositionedDeclaration _ _ d) = getDeclarationTitle d
116getDeclarationTitle (P.PositionedDeclaration _ _ d) = getDeclarationTitle d
84getDeclarationTitle _ = Nothing
117getDeclarationTitle _ = Nothing
85
118
119+-- | Create a basic RenderedDeclaration value.
120+mkDeclaration :: String -> RenderedCode -> RenderedDeclaration
121+mkDeclaration title code =
122+ RenderedDeclaration { rdTitle = title
123+ , rdComments = Nothing
124+ , rdCode = code
125+ , rdSourceSpan = Nothing
126+ , rdChildren = []
127+ , rdFixity = Nothing
128+ }
129+
86basicDeclaration :: String -> RenderedCode -> Maybe IntermediateDeclaration
130basicDeclaration :: String -> RenderedCode -> Maybe IntermediateDeclaration
87−basicDeclaration title code = Just (Right (RenderedDeclaration title Nothing code Nothing []))
131+basicDeclaration title code = Just $ Right $ mkDeclaration title code
88
132
89renderDeclaration :: P.Declaration -> String -> Maybe IntermediateDeclaration
133renderDeclaration :: P.Declaration -> String -> Maybe IntermediateDeclaration
90renderDeclaration (P.TypeDeclaration ident' ty) title =
134renderDeclaration (P.TypeDeclaration ident' ty) title =
@@ -100,7 +144,7 @@ renderDeclaration (P.ExternDeclaration ident' ty) title =
100 <> sp <> syntax "::" <> sp
144 <> sp <> syntax "::" <> sp
101 <> renderType ty
145 <> renderType ty
102renderDeclaration (P.DataDeclaration dtype name args ctors) title =
146renderDeclaration (P.DataDeclaration dtype name args ctors) title =
103− Just (Right (RenderedDeclaration title Nothing code Nothing children))
147+ Just (Right (mkDeclaration title code) { rdChildren = children })
104 where
148 where
105 typeApp = foldl P.TypeApp (P.TypeConstructor (P.Qualified Nothing name)) (map toTypeVar args)
149 typeApp = foldl P.TypeApp (P.TypeConstructor (P.Qualified Nothing name)) (map toTypeVar args)
106 code = keyword (show dtype) <> sp <> renderType typeApp
150 code = keyword (show dtype) <> sp <> renderType typeApp
@@ -128,7 +172,7 @@ renderDeclaration (P.TypeSynonymDeclaration name args ty) title =
128 , renderType ty
172 , renderType ty
129 ]
173 ]
130renderDeclaration (P.TypeClassDeclaration name args implies ds) title = do
174renderDeclaration (P.TypeClassDeclaration name args implies ds) title = do
131− Just (Right (RenderedDeclaration title Nothing code Nothing children))
175+ Just (Right (mkDeclaration title code) { rdChildren = children })
132 where
176 where
133 code = mintersperse sp $
177 code = mintersperse sp $
134 [keywordClass]
178 [keywordClass]
@@ -163,7 +207,7 @@ renderDeclaration (P.TypeClassDeclaration name args implies ds) title = do
163 in RenderedChildDeclaration (show ident') Nothing childCode Nothing ChildTypeClassMember
207 in RenderedChildDeclaration (show ident') Nothing childCode Nothing ChildTypeClassMember
164 renderClassMember _ = error "Invalid argument to renderClassMember."
208 renderClassMember _ = error "Invalid argument to renderClassMember."
165renderDeclaration (P.TypeInstanceDeclaration name constraints className tys _) title = do
209renderDeclaration (P.TypeInstanceDeclaration name constraints className tys _) title = do
166− Just (Left (classNameString : typeNameStrings, childDecl))
210+ Just (Left (classNameString : typeNameStrings, AugmentChild childDecl))
167 where
211 where
168 classNameString = unQual className
212 classNameString = unQual className
169 typeNameStrings = nub (concatMap (P.everythingOnTypes (++) extractProperNames) tys)
213 typeNameStrings = nub (concatMap (P.everythingOnTypes (++) extractProperNames) tys)
@@ -194,14 +238,27 @@ renderDeclaration (P.TypeInstanceDeclaration name constraints className tys _) t
194 in renderType supApp
238 in renderType supApp
195
239
196 classApp = foldl P.TypeApp (P.TypeConstructor className) tys
240 classApp = foldl P.TypeApp (P.TypeConstructor className) tys
241+renderDeclaration (P.FixityDeclaration fixity _) title =
242+ Just (Left ([title], AugmentFixity fixity))
197renderDeclaration (P.PositionedDeclaration srcSpan com d') title =
243renderDeclaration (P.PositionedDeclaration srcSpan com d') title =
198 fmap (addComments . addSourceSpan) (renderDeclaration d' title)
244 fmap (addComments . addSourceSpan) (renderDeclaration d' title)
199 where
245 where
246+ addComments (Right d) =
247+ Right (d { rdComments = renderComments com })
248+ addComments (Left augment) =
200− addComments (Left (t, d)) = Left (t, d { rcdComments = renderComments com })
249+ Left (withAugmentChild (\d -> d { rcdComments = renderComments com })
201− addComments (Right d) = Right (d { rdComments = renderComments com })
250+ augment)
202−
251+
252+ addSourceSpan (Right d) =
253+ Right (d { rdSourceSpan = Just srcSpan })
254+ addSourceSpan (Left augment) =
203− addSourceSpan (Left (t, d)) = Left (t, d { rcdSourceSpan = Just srcSpan })
255+ Left (withAugmentChild (\d -> d { rcdSourceSpan = Just srcSpan })
204− addSourceSpan (Right d) = Right (d { rdSourceSpan = Just srcSpan })
256+ augment)
257+
258+ withAugmentChild f (t, a) =
259+ case a of
260+ AugmentChild d -> (t, AugmentChild (f d))
261+ _ -> (t, a)
205renderDeclaration _ _ = Nothing
262renderDeclaration _ _ = Nothing
206
263
207renderComments :: [P.Comment] -> Maybe String
264renderComments :: [P.Comment] -> Maybe String
src/Language/PureScript/Docs/Types.hs+18
@@ -80,6 +80,7 @@ data RenderedDeclaration = RenderedDeclaration
80 , rdCode :: RenderedCode
80 , rdCode :: RenderedCode
81 , rdSourceSpan :: Maybe P.SourceSpan
81 , rdSourceSpan :: Maybe P.SourceSpan
82 , rdChildren :: [RenderedChildDeclaration]
82 , rdChildren :: [RenderedChildDeclaration]
83+ , rdFixity :: Maybe P.Fixity
83 }
84 }
84 deriving (Show, Eq, Ord)
85 deriving (Show, Eq, Ord)
85
86
@@ -121,6 +122,7 @@ data PackageError
121 | InvalidVersion
122 | InvalidVersion
122 | InvalidDeclarationType
123 | InvalidDeclarationType
123 | InvalidRenderedCode String
124 | InvalidRenderedCode String
125+ | InvalidFixity
124 deriving (Show, Eq, Ord)
126 deriving (Show, Eq, Ord)
125
127
126type Bookmark = InPackage (P.ModuleName, String)
128type Bookmark = InPackage (P.ModuleName, String)
@@ -210,6 +212,21 @@ asDeclaration =
210 <*> key "code" asRenderedCode .! InvalidRenderedCode
212 <*> key "code" asRenderedCode .! InvalidRenderedCode
211 <*> key "sourceSpan" (perhaps asSourceSpan)
213 <*> key "sourceSpan" (perhaps asSourceSpan)
212 <*> key "children" (eachInArray asRenderedChildDeclaration)
214 <*> key "children" (eachInArray asRenderedChildDeclaration)
215+ <*> key "fixity" (perhaps asFixity)
216+
217+asFixity :: Parse PackageError P.Fixity
218+asFixity = P.Fixity <$> key "associativity" asAssociativity
219+ <*> key "precedence" asIntegral
220+
221+parseAssociativity :: String -> Maybe P.Associativity
222+parseAssociativity str = case str of
223+ "infix" -> Just P.Infix
224+ "infixl" -> Just P.Infixl
225+ "infixr" -> Just P.Infixr
226+ _ -> Nothing
227+
228+asAssociativity :: Parse PackageError P.Associativity
229+asAssociativity = withString (maybe (Left InvalidFixity) Right . parseAssociativity)
213
230
214asRenderedChildDeclaration :: Parse PackageError RenderedChildDeclaration
231asRenderedChildDeclaration :: Parse PackageError RenderedChildDeclaration
215asRenderedChildDeclaration =
232asRenderedChildDeclaration =
@@ -293,6 +310,7 @@ instance A.ToJSON RenderedDeclaration where
293 , "code" .= rdCode
310 , "code" .= rdCode
294 , "sourceSpan" .= rdSourceSpan
311 , "sourceSpan" .= rdSourceSpan
295 , "children" .= rdChildren
312 , "children" .= rdChildren
313+ , "fixity" .= rdFixity
296 ]
314 ]
297
315
298instance A.ToJSON RenderedChildDeclaration where
316instance A.ToJSON RenderedChildDeclaration where