@@ -1,4 +1,5 @@
1−{-# LANGUAGE DeriveFunctor, PatternGuards #-}
1+{-# LANGUAGE DeriveFunctor, PatternGuards, MultiWayIf #-}
2+{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
2module Idris.Docs (pprintDocs, getDocs, pprintConstDocs, FunDoc, FunDoc'(..), Docs, Docs'(..)) where
3module Idris.Docs (pprintDocs, getDocs, pprintConstDocs, FunDoc, FunDoc'(..), Docs, Docs'(..)) where
4import Idris.AbsSyntax
5import Idris.AbsSyntax
@@ -10,6 +11,8 @@ import Idris.Docstrings (Docstring, emptyDocstring, noDocs, nullDocstring, rende
11import Util.Pretty
12import Util.Pretty
14+import Control.Arrow (first)
13import Data.Maybe
16import Data.Maybe
14import Data.List
17import Data.List
15import qualified Data.Text as T
18import qualified Data.Text as T
@@ -32,9 +35,10 @@ data Docs' d = FunDoc (FunDoc' d)
32 | ClassDoc Name d -- class docs
35 | ClassDoc Name d -- class docs
33 [FunDoc' d] -- method docs
36 [FunDoc' d] -- method docs
34 [(Name, Maybe d)] -- parameters and their docstrings
37 [(Name, Maybe d)] -- parameters and their docstrings
35− [(PTerm, (d, [(Name, d)]))] -- instances
38+ [(Maybe Name, PTerm, (d, [(Name, d)]))] -- instances: name for named instances, the constraint term, the docs
36 [PTerm] -- subclasses
39 [PTerm] -- subclasses
37 [PTerm] -- superclasses
40 [PTerm] -- superclasses
41+ | NamedInstanceDoc Name (FunDoc' d) -- name is class
38 | ModDoc [String] -- Module name
42 | ModDoc [String] -- Module name
40 deriving Functor
44 deriving Functor
@@ -102,7 +106,11 @@ pprintDocs ist (ClassDoc n doc meths params instances subclasses superclasses)
103 nest 4 (text "Instances:" <$>
107 nest 4 (text "Instances:" <$>
104 vsep (if null instances then [text "<no instances>"]
108 vsep (if null instances then [text "<no instances>"]
105− else map pprintInstance instances))
109+ else map pprintInstance normalInstances))
111+ (if null namedInstances then empty
112+ else line <$> nest 4 (text "Named instances:" <$>
113+ vsep (map pprintInstance namedInstances)))
107 (if null subclasses then empty
115 (if null subclasses then empty
108 else line <$> nest 4 (text "Subclasses:" <$>
116 else line <$> nest 4 (text "Subclasses:" <$>
@@ -113,14 +121,17 @@ pprintDocs ist (ClassDoc n doc meths params instances subclasses superclasses)
113 vsep (map dumpInstance superclasses)))
121 vsep (map dumpInstance superclasses)))
115 params' = zip pNames (repeat False)
123 params' = zip pNames (repeat False)
125+ (normalInstances, namedInstances) = partition (\(n, _, _) -> not $ isJust n)
117 pNames = map fst params
128 pNames = map fst params
119 ppo = ppOptionIst ist
130 ppo = ppOptionIst ist
120 infixes = idris_infixes ist
131 infixes = idris_infixes ist
122− pprintInstance (term, (doc, argDocs)) =
133+ pprintInstance (mname, term, (doc, argDocs)) =
123− nest 4 (dumpInstance term <>
134+ nest 4 (iname mname <> dumpInstance term <>
124 (if nullDocstring doc
135 (if nullDocstring doc
125 then empty
136 then empty
126 else line <>
137 else line <>
@@ -133,6 +144,10 @@ pprintDocs ist (ClassDoc n doc meths params instances subclasses superclasses)
133 then empty
144 then empty
134 else line <> vsep (map (prettyInstanceParam (map fst argDocs)) argDocs))
145 else line <> vsep (map (prettyInstanceParam (map fst argDocs)) argDocs))
148+ iname Nothing = empty
149+ iname (Just n) = annName n <+> colon <> space
136 prettyInstanceParam params (name, doc) =
151 prettyInstanceParam params (name, doc) =
137 if nullDocstring doc
152 if nullDocstring doc
138 then empty
153 then empty
@@ -170,6 +185,9 @@ pprintDocs ist (ClassDoc n doc meths params instances subclasses superclasses)
170 then vsep (map (\(nm,md) -> prettyName True False params' nm <+> maybe empty (showDoc ist) md) params)
185 then vsep (map (\(nm,md) -> prettyName True False params' nm <+> maybe empty (showDoc ist) md) params)
171 else hsep (punctuate comma (map (prettyName True False params' . fst) params))
186 else hsep (punctuate comma (map (prettyName True False params' . fst) params))
188+pprintDocs ist (NamedInstanceDoc _cls doc)
189+ = nest 4 (text "Named instance:" <$> pprintFD ist doc)
173pprintDocs ist (ModDoc mod docs)
191pprintDocs ist (ModDoc mod docs)
174 = nest 4 $ text "Module" <+> text (concat (intersperse "." mod)) <> colon <$>
192 = nest 4 $ text "Module" <+> text (concat (intersperse "." mod)) <> colon <$>
175 renderDocstring (renderDocTerm (pprintDelab ist) (normaliseAll (tt_ctxt ist) [])) docs
193 renderDocstring (renderDocTerm (pprintDelab ist) (normaliseAll (tt_ctxt ist) [])) docs
@@ -190,13 +208,23 @@ getDocs n@(NS n' ns) w | n' == modDocName
190 " do not exist! This shouldn't have happened and is a bug."
208 " do not exist! This shouldn't have happened and is a bug."
191getDocs n w
209getDocs n w
192 = do i <- getIState
210 = do i <- getIState
193− docs <- case lookupCtxt n (idris_classes i) of
211+ docs <- if | Just ci <- lookupCtxtExact n (idris_classes i)
194− [ci] -> docClass n ci
212+ -> docClass n ci
195− _ -> case lookupCtxt n (idris_datatypes i) of
213+ | Just ti <- lookupCtxtExact n (idris_datatypes i)
196− [ti] -> docData n ti
214+ -> docData n ti
215+ | Just class_ <- classNameForInst i n
216+ -> do fd <- docFun n
217+ return $ NamedInstanceDoc class_ fd
197− _ -> do fd <- docFun n
219+ -> do fd <- docFun n
198− return (FunDoc fd)
220+ return (FunDoc fd)
199 return $ fmap (howMuch w) docs
221 return $ fmap (howMuch w) docs
222+ where classNameForInst :: IState -> Name -> Maybe Name
223+ classNameForInst ist n =
225+ | (cn, ci) <- toAlist (idris_classes ist)
226+ , n `elem` class_instances ci
201docData :: Name -> TypeInfo -> Idris Docs
229docData :: Name -> TypeInfo -> Idris Docs
202docData n ti
230docData n ti
@@ -209,19 +237,26 @@ docClass n ci
209 = do i <- getIState
237 = do i <- getIState
210 let docStrings = listToMaybe $ lookupCtxt n $ idris_docstrings i
238 let docStrings = listToMaybe $ lookupCtxt n $ idris_docstrings i
211 docstr = maybe emptyDocstring fst docStrings
239 docstr = maybe emptyDocstring fst docStrings
212− params = map (\pn -> (pn, docStrings >>= (lookup pn . snd))) (class_params ci)
240+ params = map (\pn -> (pn, docStrings >>= (lookup pn . snd)))
213− instanceDocs = map (fromMaybe (emptyDocstring, []) .
242+ docsForInstance inst = fromMaybe (emptyDocstring, []) .
215− flip lookupCtxt (idris_docstrings i))
243+ flip lookupCtxtExact (idris_docstrings i) $
216− (class_instances ci)
244+ inst
245+ instances = map (\inst -> (namedInst inst,
247+ docsForInstance inst))
217− instances = zip (map (delabTy i) (class_instances ci)) instanceDocs
248+ (nub (class_instances ci))
218− (subclasses, instances') = partition (isSubclass . fst) instances
249+ (subclasses, instances') = partition (isSubclass . (\(_,tm,_) -> tm)) instances
219 superclasses = catMaybes $ map getDInst (class_default_superclasses ci)
250 superclasses = catMaybes $ map getDInst (class_default_superclasses ci)
220 mdocs <- mapM (docFun . fst) (class_methods ci)
251 mdocs <- mapM (docFun . fst) (class_methods ci)
221 return $ ClassDoc
252 return $ ClassDoc
222 n docstr mdocs params
253 n docstr mdocs params
223− instances' (map fst subclasses) superclasses
254+ instances' (map (\(_,tm,_) -> tm) subclasses) superclasses
256+ namedInst (NS n ns) = fmap (flip NS ns) (namedInst n)
257+ namedInst n@(UN _) = Just n
258+ namedInst _ = Nothing
225 getDInst (PInstance _ _ _ _ _ _ _ t _ _) = Just t
260 getDInst (PInstance _ _ _ _ _ _ _ t _ _) = Just t
226 getDInst _ = Nothing
261 getDInst _ = Nothing
@@ -250,6 +285,7 @@ docFun n
250 where funName :: Name -> String
285 where funName :: Name -> String
251 funName (UN n) = str n
286 funName (UN n) = str n
252 funName (NS n _) = funName n
287 funName (NS n _) = funName n
254getPArgNames :: PTerm -> [(Name, Docstring DocTerm)] -> [(Name, PTerm, Plicity, Maybe (Docstring DocTerm))]
290getPArgNames :: PTerm -> [(Name, Docstring DocTerm)] -> [(Name, PTerm, Plicity, Maybe (Docstring DocTerm))]
255getPArgNames (PPi plicity name ty body) ds =
291getPArgNames (PPi plicity name ty body) ds =