Skip to content

Commit b7a74c6

Browse files
harpocratesalexbiehl
authored andcommitted
Show where instances are defined (haskell#748)
* Indicate source module of instances Above instance, we now also display a link to the module where the instance was defined. This is sometimes helpful in figuring out what to import. * Source module for type/data families too * Remove parens * Accept tests
1 parent e787b57 commit b7a74c6

24 files changed

+530
-112
lines changed

haddock-api/src/Haddock/Backends/LaTeX.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -530,14 +530,14 @@ ppDocInstances unicode (i : rest)
530530
(is, rest') = spanWith isUndocdInstance rest
531531

532532
isUndocdInstance :: DocInstance a -> Maybe (InstHead a)
533-
isUndocdInstance (i,Nothing,_) = Just i
533+
isUndocdInstance (i,Nothing,_,_) = Just i
534534
isUndocdInstance _ = Nothing
535535

536536
-- | Print a possibly commented instance. The instance header is printed inside
537537
-- an 'argBox'. The comment is printed to the right of the box in normal comment
538538
-- style.
539539
ppDocInstance :: Bool -> DocInstance DocNameI -> LaTeX
540-
ppDocInstance unicode (instHead, doc, _) =
540+
ppDocInstance unicode (instHead, doc, _, _) =
541541
declWithDoc (ppInstDecl unicode instHead) (fmap docToLaTeX $ fmap _doc doc)
542542

543543

haddock-api/src/Haddock/Backends/Xhtml/Decl.hs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -566,8 +566,8 @@ ppInstances links origin instances splice unicode qual
566566
where
567567
instName = getOccString origin
568568
instDecl :: Int -> DocInstance DocNameI -> (SubDecl,Located DocName)
569-
instDecl no (inst, mdoc, loc) =
570-
((ppInstHead links splice unicode qual mdoc origin False no inst), loc)
569+
instDecl no (inst, mdoc, loc, mdl) =
570+
((ppInstHead links splice unicode qual mdoc origin False no inst mdl), loc)
571571

572572

573573
ppOrphanInstances :: LinksInfo
@@ -581,8 +581,8 @@ ppOrphanInstances links instances splice unicode qual
581581
instOrigin inst = OriginClass (ihdClsName inst)
582582

583583
instDecl :: Int -> DocInstance DocNameI -> (SubDecl,Located DocName)
584-
instDecl no (inst, mdoc, loc) =
585-
((ppInstHead links splice unicode qual mdoc (instOrigin inst) True no inst), loc)
584+
instDecl no (inst, mdoc, loc, mdl) =
585+
((ppInstHead links splice unicode qual mdoc (instOrigin inst) True no inst mdl), loc)
586586

587587

588588
ppInstHead :: LinksInfo -> Splice -> Unicode -> Qualification
@@ -591,21 +591,22 @@ ppInstHead :: LinksInfo -> Splice -> Unicode -> Qualification
591591
-> Bool -- ^ Is instance orphan
592592
-> Int -- ^ Normal
593593
-> InstHead DocNameI
594+
-> Maybe Module
594595
-> SubDecl
595-
ppInstHead links splice unicode qual mdoc origin orphan no ihd@(InstHead {..}) =
596+
ppInstHead links splice unicode qual mdoc origin orphan no ihd@(InstHead {..}) mdl =
596597
case ihdInstType of
597598
ClassInst { .. } ->
598599
( subInstHead iid $ ppContextNoLocs clsiCtx unicode qual HideEmptyContexts <+> typ
599600
, mdoc
600-
, [subInstDetails iid ats sigs]
601+
, [subInstDetails iid ats sigs mname]
601602
)
602603
where
603604
sigs = ppInstanceSigs links splice unicode qual clsiSigs
604605
ats = ppInstanceAssocTys links splice unicode qual clsiAssocTys
605606
TypeInst rhs ->
606607
( subInstHead iid ptype
607608
, mdoc
608-
, [subFamInstDetails iid prhs]
609+
, [subFamInstDetails iid prhs mname]
609610
)
610611
where
611612
ptype = keyword "type" <+> typ
@@ -614,11 +615,12 @@ ppInstHead links splice unicode qual mdoc origin orphan no ihd@(InstHead {..}) =
614615
DataInst dd ->
615616
( subInstHead iid pdata
616617
, mdoc
617-
, [subFamInstDetails iid pdecl])
618+
, [subFamInstDetails iid pdecl mname])
618619
where
619620
pdata = keyword "data" <+> typ
620621
pdecl = pdata <+> ppShortDataDecl False True dd [] unicode qual
621622
where
623+
mname = maybe noHtml (\m -> toHtml "Defined in" <+> ppModule m) mdl
622624
iid = instanceId origin no orphan ihd
623625
typ = ppAppNameTypes ihdClsName ihdTypes unicode qual
624626

haddock-api/src/Haddock/Backends/Xhtml/Layout.hs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import Haddock.Backends.Xhtml.Utils
4747
import Haddock.Types
4848
import Haddock.Utils (makeAnchorId, nameAnchorId)
4949
import qualified Data.Map as Map
50-
import Text.XHtml hiding ( name, title, p, quote )
50+
import Text.XHtml hiding ( name, title, quote )
5151

5252
import FastString ( unpackFS )
5353
import GHC
@@ -228,15 +228,17 @@ subInstHead iid hdr =
228228
subInstDetails :: String -- ^ Instance unique id (for anchor generation)
229229
-> [Html] -- ^ Associated type contents
230230
-> [Html] -- ^ Method contents (pretty-printed signatures)
231+
-> Html -- ^ Source module
231232
-> Html
232-
subInstDetails iid ats mets =
233-
subInstSection iid << (subAssociatedTypes ats <+> subMethods mets)
233+
subInstDetails iid ats mets mdl =
234+
subInstSection iid << (p mdl <+> subAssociatedTypes ats <+> subMethods mets)
234235

235236
subFamInstDetails :: String -- ^ Instance unique id (for anchor generation)
236237
-> Html -- ^ Type or data family instance
238+
-> Html -- ^ Source module TODO: use this
237239
-> Html
238-
subFamInstDetails iid fi =
239-
subInstSection iid << thediv ! [theclass "src"] << fi
240+
subFamInstDetails iid fi mdl =
241+
subInstSection iid << (p mdl <+> (thediv ! [theclass "src"] << fi))
240242

241243
subInstSection :: String -- ^ Instance unique id (for anchor generation)
242244
-> Html

haddock-api/src/Haddock/Interface/AttachInstances.hs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ attachInstances expInfo ifaces instIfaceMap = do
6969

7070
attachOrphanInstances :: ExportInfo -> Interface -> IfaceMap -> InstIfaceMap -> [ClsInst] -> [DocInstance GhcRn]
7171
attachOrphanInstances expInfo iface ifaceMap instIfaceMap cls_instances =
72-
[ (synifyInstHead i, instLookup instDocMap n iface ifaceMap instIfaceMap, (L (getSrcSpan n) n))
72+
[ (synifyInstHead i, instLookup instDocMap n iface ifaceMap instIfaceMap, (L (getSrcSpan n) n), Nothing)
7373
| let is = [ (instanceSig i, getName i) | i <- cls_instances, isOrphan (is_orphan i) ]
7474
, (i@(_,_,cls,tys), n) <- sortBy (comparing $ first instHead) is
7575
, not $ isInstanceHidden expInfo cls tys
@@ -91,22 +91,30 @@ attachToExportItem index expInfo iface ifaceMap instIfaceMap export =
9191
let mb_instances = lookupNameEnv index (tcdName d)
9292
cls_instances = maybeToList mb_instances >>= fst
9393
fam_instances = maybeToList mb_instances >>= snd
94-
fam_insts = [ (synifyFamInst i opaque, doc,spanNameE n (synifyFamInst i opaque) (L eSpan (tcdName d)) )
94+
fam_insts = [ ( synifyFamInst i opaque
95+
, doc
96+
, spanNameE n (synifyFamInst i opaque) (L eSpan (tcdName d))
97+
, nameModule_maybe n
98+
)
9599
| i <- sortBy (comparing instFam) fam_instances
96100
, let n = getName i
97101
, let doc = instLookup instDocMap n iface ifaceMap instIfaceMap
98102
, not $ isNameHidden expInfo (fi_fam i)
99103
, not $ any (isTypeHidden expInfo) (fi_tys i)
100104
, let opaque = isTypeHidden expInfo (fi_rhs i)
101105
]
102-
cls_insts = [ (synifyInstHead i, instLookup instDocMap n iface ifaceMap instIfaceMap, spanName n (synifyInstHead i) (L eSpan (tcdName d)))
106+
cls_insts = [ ( synifyInstHead i
107+
, instLookup instDocMap n iface ifaceMap instIfaceMap
108+
, spanName n (synifyInstHead i) (L eSpan (tcdName d))
109+
, nameModule_maybe n
110+
)
103111
| let is = [ (instanceSig i, getName i) | i <- cls_instances ]
104112
, (i@(_,_,cls,tys), n) <- sortBy (comparing $ first instHead) is
105113
, not $ isInstanceHidden expInfo cls tys
106114
]
107115
-- fam_insts but with failing type fams filtered out
108-
cleanFamInsts = [ (fi, n, L l r) | (Right fi, n, L l (Right r)) <- fam_insts ]
109-
famInstErrs = [ errm | (Left errm, _, _) <- fam_insts ]
116+
cleanFamInsts = [ (fi, n, L l r, m) | (Right fi, n, L l (Right r), m) <- fam_insts ]
117+
famInstErrs = [ errm | (Left errm, _, _, _) <- fam_insts ]
110118
in do
111119
dfs <- getDynFlags
112120
let mkBug = (text "haddock-bug:" <+>) . text

haddock-api/src/Haddock/Interface/Rename.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -627,11 +627,11 @@ renameWc rn_thing (HsWC { hswc_body = thing })
627627
, hswc_wcs = PlaceHolder }) }
628628

629629
renameDocInstance :: DocInstance GhcRn -> RnM (DocInstance DocNameI)
630-
renameDocInstance (inst, idoc, L l n) = do
630+
renameDocInstance (inst, idoc, L l n, m) = do
631631
inst' <- renameInstHead inst
632632
n' <- rename n
633633
idoc' <- mapM renameDoc idoc
634-
return (inst', idoc',L l n')
634+
return (inst', idoc', L l n', m)
635635

636636
renameExportItem :: ExportItem GhcRn -> RnM (ExportItem DocNameI)
637637
renameExportItem item = case item of

haddock-api/src/Haddock/Types.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ mkPseudoFamilyDecl (FamilyDecl { .. }) = PseudoFamilyDecl
388388

389389

390390
-- | An instance head that may have documentation and a source location.
391-
type DocInstance name = (InstHead name, Maybe (MDoc (IdP name)), Located (IdP name))
391+
type DocInstance name = (InstHead name, Maybe (MDoc (IdP name)), Located (IdP name), Maybe Module)
392392

393393
-- | The head of an instance. Consists of a class name, a list of type
394394
-- parameters (which may be annotated with kinds), and an instance type

html-test/ref/Bug26.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,11 @@
180180
><details id="i:ic:C:C:1"
181181
><summary class="hide-when-js-enabled"
182182
>Instance details</summary
183-
><div class="subs methods"
183+
><p
184+
>Defined in <a href="#"
185+
>Bug26</a
186+
></p
187+
> <div class="subs methods"
184188
><p class="caption"
185189
>Methods</p
186190
><p class="src"

html-test/ref/Bug294.html

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,11 @@
7878
><details id="i:id:A:DP:1"
7979
><summary class="hide-when-js-enabled"
8080
>Instance details</summary
81-
><div class="src"
81+
><p
82+
>Defined in <a href="#"
83+
>Bug294</a
84+
></p
85+
> <div class="src"
8286
><span class="keyword"
8387
>data</span
8488
> <a href="#" title="Bug294"
@@ -116,7 +120,11 @@
116120
><details id="i:id:A:TP:2"
117121
><summary class="hide-when-js-enabled"
118122
>Instance details</summary
119-
><div class="src"
123+
><p
124+
>Defined in <a href="#"
125+
>Bug294</a
126+
></p
127+
> <div class="src"
120128
><span class="keyword"
121129
>data</span
122130
> <a href="#" title="Bug294"
@@ -210,7 +218,11 @@
210218
><details id="i:if:TP:TP:1"
211219
><summary class="hide-when-js-enabled"
212220
>Instance details</summary
213-
><div class="src"
221+
><p
222+
>Defined in <a href="#"
223+
>Bug294</a
224+
></p
225+
> <div class="src"
214226
><span class="keyword"
215227
>data</span
216228
> <a href="#" title="Bug294"
@@ -268,7 +280,11 @@
268280
><details id="i:if:DP:DP:1"
269281
><summary class="hide-when-js-enabled"
270282
>Instance details</summary
271-
><div class="src"
283+
><p
284+
>Defined in <a href="#"
285+
>Bug294</a
286+
></p
287+
> <div class="src"
272288
><span class="keyword"
273289
>data</span
274290
> <a href="#" title="Bug294"
@@ -324,7 +340,11 @@
324340
><details id="i:if:TO-39-:TO-39-:1"
325341
><summary class="hide-when-js-enabled"
326342
>Instance details</summary
327-
><div class="src"
343+
><p
344+
>Defined in <a href="#"
345+
>Bug294</a
346+
></p
347+
> <div class="src"
328348
><span class="keyword"
329349
>data</span
330350
> <a href="#" title="Bug294"

html-test/ref/Bug548.html

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,11 @@
116116
><details id="i:id:WrappedArrow:Generic1:1"
117117
><summary class="hide-when-js-enabled"
118118
>Instance details</summary
119-
><div class="subs associated-types"
119+
><p
120+
>Defined in <a href="#"
121+
>Control.Applicative</a
122+
></p
123+
> <div class="subs associated-types"
120124
><p class="caption"
121125
>Associated Types</p
122126
><p class="src"
@@ -188,7 +192,11 @@
188192
><details id="i:id:WrappedArrow:Functor:2"
189193
><summary class="hide-when-js-enabled"
190194
>Instance details</summary
191-
><div class="subs methods"
195+
><p
196+
>Defined in <a href="#"
197+
>Control.Applicative</a
198+
></p
199+
> <div class="subs methods"
192200
><p class="caption"
193201
>Methods</p
194202
><p class="src"
@@ -240,7 +248,11 @@
240248
><details id="i:id:WrappedArrow:Applicative:3"
241249
><summary class="hide-when-js-enabled"
242250
>Instance details</summary
243-
><div class="subs methods"
251+
><p
252+
>Defined in <a href="#"
253+
>Control.Applicative</a
254+
></p
255+
> <div class="subs methods"
244256
><p class="caption"
245257
>Methods</p
246258
><p class="src"
@@ -330,7 +342,11 @@
330342
><details id="i:id:WrappedArrow:Alternative:4"
331343
><summary class="hide-when-js-enabled"
332344
>Instance details</summary
333-
><div class="subs methods"
345+
><p
346+
>Defined in <a href="#"
347+
>Control.Applicative</a
348+
></p
349+
> <div class="subs methods"
334350
><p class="caption"
335351
>Methods</p
336352
><p class="src"
@@ -396,7 +412,11 @@
396412
><details id="i:id:WrappedArrow:Generic:5"
397413
><summary class="hide-when-js-enabled"
398414
>Instance details</summary
399-
><div class="subs associated-types"
415+
><p
416+
>Defined in <a href="#"
417+
>Control.Applicative</a
418+
></p
419+
> <div class="subs associated-types"
400420
><p class="caption"
401421
>Associated Types</p
402422
><p class="src"
@@ -470,7 +490,11 @@
470490
><details id="i:id:WrappedArrow:Rep1:6"
471491
><summary class="hide-when-js-enabled"
472492
>Instance details</summary
473-
><div class="src"
493+
><p
494+
>Defined in <a href="#"
495+
>Control.Applicative</a
496+
></p
497+
> <div class="src"
474498
><span class="keyword"
475499
>type</span
476500
> <a href="#" title="GHC.Generics"
@@ -534,7 +558,11 @@
534558
><details id="i:id:WrappedArrow:Rep:7"
535559
><summary class="hide-when-js-enabled"
536560
>Instance details</summary
537-
><div class="src"
561+
><p
562+
>Defined in <a href="#"
563+
>Control.Applicative</a
564+
></p
565+
> <div class="src"
538566
><span class="keyword"
539567
>type</span
540568
> <a href="#" title="GHC.Generics"

html-test/ref/Bug613.html

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,11 @@
122122
><details id="i:ic:Functor:Functor:1"
123123
><summary class="hide-when-js-enabled"
124124
>Instance details</summary
125-
><div class="subs methods"
125+
><p
126+
>Defined in <a href="#"
127+
>Bug613</a
128+
></p
129+
> <div class="subs methods"
126130
><p class="caption"
127131
>Methods</p
128132
><p class="src"
@@ -160,7 +164,11 @@
160164
><details id="i:ic:Functor:Functor:2"
161165
><summary class="hide-when-js-enabled"
162166
>Instance details</summary
163-
><div class="subs methods"
167+
><p
168+
>Defined in <a href="#"
169+
>Bug613</a
170+
></p
171+
> <div class="subs methods"
164172
><p class="caption"
165173
>Methods</p
166174
><p class="src"
@@ -234,7 +242,11 @@
234242
><details id="i:id:ThreeVars:Functor:1"
235243
><summary class="hide-when-js-enabled"
236244
>Instance details</summary
237-
><div class="subs methods"
245+
><p
246+
>Defined in <a href="#"
247+
>Bug613</a
248+
></p
249+
> <div class="subs methods"
238250
><p class="caption"
239251
>Methods</p
240252
><p class="src"

0 commit comments

Comments
 (0)