1-- Copyright (c) 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2-- SPDX-License-Identifier: Apache-2.0
4module Development.IDE.Functions.Documentation (
11import qualified Data.Map as M
13import qualified Data.Text as T
14import Development.IDE.Functions.GHCError
15import Development.IDE.Functions.SpanInfo
16import Development.IDE.UtilGHC
21 :: Name -- ^ The name you want documentation for.
22 -> [TypecheckedModule] -- ^ All of the possible modules it could be defined in.
23 -> [RealLocated AnnotationComment]
24-- This finds any documentation between the name you want
25-- documentation for and the one before it. This is only an
26-- approximately correct algorithm and there are easily constructed
27-- cases where it will be wrong (if so then usually slightly but there
28-- may be edge cases where it is very wrong).
29-- TODO : Build a version of GHC exactprint to extract this information
31getDocumentation targetName tcs = fromMaybe [] $ do
32 -- Find the module the target is defined in.
33 targetNameSpan <- realSpan $ nameSrcSpan targetName
36 $ filter ((==) (Just $ srcSpanFile targetNameSpan) . annotationFileName)
37 $ reverse tcs -- TODO : Is reversing the list here really neccessary?
38 -- Names bound by the module (we want to exclude non-"top-level"
39 -- bindings but unfortunately we get all here).
40 let bs = mapMaybe name_of_bind
41 (listifyAllSpans (tm_typechecked_source tc) :: [LHsBind GhcTc])
42 -- Sort the names' source spans.
43 let sortedSpans = sortedNameSpans bs
44 -- Now go ahead and extract the docs.
46 nameInd <- elemIndex targetNameSpan sortedSpans
49 then sortedSpans !! (nameInd - 1)
50 else zeroSpan $ srcSpanFile targetNameSpan
51 -- Annoyingly "-- |" documentation isn't annotated with a location,
52 -- so you have to pull it out from the elements.
54 $ filter (\(L target _) -> isBetween target prevNameSpan targetNameSpan)
55 $ mapMaybe (\(L l v) -> L <$> realSpan l <*> pure v)
60 -- Get the name bound by a binding. We only concern ourselves with
61 -- @FunBind@ (which covers functions and variables).
62 name_of_bind :: LHsBind GhcTc -> Maybe Name
63 name_of_bind (L _ FunBind {fun_id}) = Just (getName (unLoc fun_id))
64 name_of_bind _ = Nothing
65 -- Get source spans from names, discard unhelpful spans, remove
66 -- duplicates and sort.
67 sortedNameSpans :: [Name] -> [RealSrcSpan]
68 sortedNameSpans ls = nubSort (mapMaybe (realSpan . nameSrcSpan) ls)
69 isBetween target before after = before <= target && target <= after
70 ann = snd . pm_annotations . tm_parsed_module
71 annotationFileName :: TypecheckedModule -> Maybe FastString
72 annotationFileName = fmap srcSpanFile . listToMaybe . realSpans . ann
73 realSpans :: M.Map SrcSpan [Located a] -> [RealSrcSpan]
75 mapMaybe (realSpan . getLoc)
79-- | Shows this part of the documentation
80docHeaders :: [RealLocated AnnotationComment]
82docHeaders = mapMaybe (wrk . unRealSrcSpan)
85 AnnDocCommentNext s -> Just $ T.pack s
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