Serialize docstrings to ifaces, display them with new GHCi :doc command
ClosedPublic

Authored by sjakobi on May 31 2018, 8:24 AM.

Details

Summary

If -haddock is set, we now extract docstrings from the renamed ast
and serialize them in the .hi-files.

This includes some of the changes from D4749 with the notable
exceptions of the docstring lexing and renaming.

A currently limited and experimental GHCi :doc command can be used
to display docstrings for declarations.

The formatting of pretty-printed docstrings is changed slightly,
causing some changes in testsuite/tests/haddock.

Test Plan

./validate

Diff Detail

sjakobi created this revision.May 31 2018, 8:24 AM
sjakobi updated this revision to Diff 16611.May 31 2018, 8:34 AM
  • Remove outdated TODO

Here is a little demonstration of the :doc command:

$ cabal get optparse-generic
Downloading optparse-generic-1.3.0...
Unpacking to optparse-generic-1.3.0/
$ cd optparse-generic-1.3.0/
$ cabal new-build -w ~/src/ghc-hh-8.6/inplace/bin/ghc-stage2
$ ~/src/ghc-hh-8.6/inplace/bin/ghc-stage2 --interactive
GHCi, version 8.5.20180530: http://www.haskell.org/ghc/  :? for help
Loaded package environment from
/home/simon/tmp/tmp2/optparse-generic-1.3.0/.ghc.environment.x86_64-linux-8.5.20180530
Loaded GHCi configuration from /home/simon/.ghci
λ :load src/Options/Generic.hs
[1 of 1] Compiling Options.Generic  ( src/Options/Generic.hs, interpreted )
Ok, one module loaded.
λ :doc getRecord
ghc-stage2: Can't find any documentation for Options.Generic.
This is probably because the module was loaded without '-haddock',
but it's also possible that the module contains no documentation.

Try running ':set -haddock' and :load the file again.
λ :set -haddock
λ :load src/Options/Generic.hs
[1 of 1] Compiling Options.Generic  ( src/Options/Generic.hs, interpreted )
Ok, one module loaded.
λ :doc getRecord
 Marshal any value that implements `ParseRecord` from the command line

 If you need to modify the top-level 'ParserInfo' or 'ParserPrefs'
 use the 'getRecordWith' function.
λ :doc Only
ghc-stage2: Can't find any documentation for Data.Tuple.Only.
This is probably because the module was compiled without '-haddock',
but it's also possible that the module contains no documentation.

Try re-compiling with '-haddock'.
λ
Leaving GHCi.
$ cabal new-build -w ~/src/ghc-hh-8.6/inplace/bin/ghc-stage2
--ghc-options "-haddock"
$ ~/src/ghc-hh-8.6/inplace/bin/ghc-stage2 --interactive
GHCi, version 8.5.20180530: http://www.haskell.org/ghc/  :? for help
Loaded package environment from
/home/simon/tmp/tmp2/optparse-generic-1.3.0/.ghc.environment.x86_64-linux-8.5.20180530
Loaded GHCi configuration from /home/simon/.ghci
λ :load src/Options/Generic.hs
[1 of 1] Compiling Options.Generic  ( src/Options/Generic.hs, interpreted )
Ok, one module loaded.
λ :doc Only
<has no documentation>

 The 1-tuple type or single-value "collection".

 This type is structurally equivalent to the
 'Data.Functor.Identity.Identity' type, but its intent is more
 about serving as the anonymous 1-tuple type missing from Haskell for attaching
 typeclass instances.

 Parameter usage example:

 @encodeSomething ('Only' (42::Int))@

 Result usage example:

 @xs <- decodeSomething
forM_ xs $ \\('Only' id) -> {- ... -}@

λ :doc x

<interactive>:1:1: error: Not in scope: ‘x’
λ x = ()
λ :doc x
Docs are unavailable for interactive declarations.
λ :doc Monad
 The 'Monad' class defines the basic operations over a /monad/,
a concept from a branch of mathematics known as /category theory/.
From the perspective of a Haskell programmer, however, it is best to
think of a monad as an /abstract datatype/ of actions.
Haskell's @do@ expressions provide a convenient syntax for writing
monadic expressions.

Instances of 'Monad' should satisfy the following laws:

* @'return' a '>>=' k  =  k a@
* @m '>>=' 'return'  =  m@
* @m '>>=' (\\x -> k x '>>=' h)  =  (m '>>=' k) '>>=' h@

Furthermore, the 'Monad' and 'Applicative' operations should relate as follows:

* @'pure' = 'return'@
* @('<*>') = 'ap'@

The above laws imply:

* @'fmap' f xs  =  xs '>>=' 'return' . f@
* @('>>') = ('*>')@

and that 'pure' and ('<*>') satisfy the applicative functor laws.

The instances of 'Monad' for lists, 'Data.Maybe.Maybe' and 'System.IO.IO'
defined in the "Prelude" satisfy these laws.
sjakobi updated this revision to Diff 16616.May 31 2018, 10:34 AM
  • mk/config.mk.in: Add -haddock to GhcLibHcOpts
sjakobi updated this revision to Diff 16628.Jun 1 2018, 9:04 AM
  • Fix concatenation of docstrings
alexbiehl accepted this revision.Jun 3 2018, 7:43 AM

I think this is a good first iteration on the matter which nicely sidesteps the debate of the markup language used and can safely be included as technical preview.

Maybe we could output a note that :doc is a tech preview and that ANSI codes and highlighting might come in later iterations.

compiler/deSugar/ExtractDocs.hs
27

I know this is mostly copied from haddock. But I would like this whole bunch to go eventually – not in this PR of course.

I envision a world where docstrings are attached to the corresponding declarations at parsing time which hopefully makes these extra rounds unnecessary.

compiler/hsSyn/HsDoc.hs
106

This is quadric in the length of the doc strings. Not sure if it matters here.

compiler/main/InteractiveEval.hs
849

Ha, nice. Maybe there is a more direct indicator?

compiler/typecheck/TcRnMonad.hs
240

Can you explain in more detail what this means?

This revision is now accepted and ready to land.Jun 3 2018, 7:43 AM
sjakobi updated this revision to Diff 16681.Jun 3 2018, 10:19 AM
  • HsDoc: Fix complexity of concatDocs
  • getDocs: Add TODO
  • Expand comment on why we keep the renamed syntax with -haddock
sjakobi marked 2 inline comments as done.Jun 3 2018, 10:32 AM

Maybe we could output a note that :doc is a tech preview and that ANSI codes and highlighting might come in later iterations.

I used "experimental" when describing :doc in the docs.

Outputting such a note with each use of :doc seems kind of noisy to me.

compiler/deSugar/ExtractDocs.hs
27

I envision a world where docstrings are attached to the corresponding declarations at parsing time which hopefully makes these extra rounds unnecessary.

Sounds like an idea worth discussing further. Maybe create a Trac ticket.

compiler/main/InteractiveEval.hs
849

I had asked about that on IRC but got no response. I've added a TODO for now.

compiler/typecheck/TcRnMonad.hs
240

Does my expanded comment help? I wasn't quite sure what you wanted to know.

bgamari accepted this revision.Jun 4 2018, 4:56 PM

Looks good; I'll fix the issue noted inline when I merged.

compiler/main/InteractiveEval.hs
858

Good, I'm glad this is a TODO.

docs/users_guide/ghci.rst
2377

This should be a semicolon.

This revision was automatically updated to reflect the committed changes.