haskell / haddock

Haskell Documentation Tool
www.haskell.org/haddock/
BSD 2-Clause "Simplified" License
361 stars 241 forks source link

Haddock loses section markers with named-chunks #797

Open LeventErkok opened 6 years ago

LeventErkok commented 6 years ago

For this input:

module A (
 -- * Section 1
 -- * Section 2
 foo
 ) where

-- | foo is True
foo = True

haddock nicely produces a document with two section names (Section 1 and 2) as expected. (Invoked as haddock --html a.hs)

However, if one inserts a "named-chunk" in between section headers, like this:

module A (
 -- * Section 1
 -- $doc
 -- * Section 2
 foo
 ) where

-- | foo is True
foo = True

{- $doc
   This is a named doc
-}

Then the generated html no longer has Section 2 in it. (Same invocation: haddock --html a.hs)

alexbiehl commented 6 years ago

Interesting, which haddock version do you use?

Levent Erkök notifications@github.com schrieb am Sa., 7. Apr. 2018, 22:05:

For this input:

module A ( -- Section 1 -- Section 2 foo ) where

-- | foo is True foo = True

haddock nicely produces a document with two section names (Section 1 and 2) as expected. (Invoked as haddock --html a.hs)

However, if one inserts a "named-chunk" in between section headers, like this:

module A ( -- Section 1 -- $doc -- Section 2 foo ) where

-- | foo is True foo = True

{- $doc This is a named doc -}

Then the generated html no longer has Section 2 in it. (Same invocation: haddock --html a.hs

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/haskell/haddock/issues/797, or mute the thread https://github.com/notifications/unsubscribe-auth/AByiiUbNGTDJ6lnnlRjywHqHT79_aYHOks5tmRwQgaJpZM4TLOzb .

LeventErkok commented 6 years ago
$ haddock --version
Haddock version 2.19.0, (c) Simon Marlow 2006
Ported to use the GHC API by David Waern 2006-2008
alexbiehl commented 6 years ago

This seems to be a GHC bug. For your example

module A (
 -- * Section 1
 -- $doc
 -- * Section 2
 foo
 ) where

-- | foo is True
foo = True

{- $doc
   This is a named doc
-}

with

$ ghc -ddump-parsed-ast -haddock Bug797.hs

gives this syntax tree for the export list:

 (HsModule
  (Just
   ({ html-test/src/Bug797.hs:1:8-13 }
    {ModuleName: Bug797}))
  (Just
   ({ html-test/src/Bug797.hs:(1,15)-(7,2) }
    [({ html-test/src/Bug797.hs:2:2-15 }
      (IEGroup
       (1)
       (HsDocString
        {FastString: " Section 1"})))
    ,({ html-test/src/Bug797.hs:(4,2)-(5,15) }
      (IEDocNamed
       "doc"))
    ,({ html-test/src/Bug797.hs:6:2-4 }
      (IEVar
       ({ html-test/src/Bug797.hs:6:2-4 }
        (IEName
         ({ html-test/src/Bug797.hs:6:2-4 }
          (Unqual
           {OccName: foo}))))))]))

Note that "Section 2" is missing.

Changing the input to:

module Bug797 (
 -- * Section 1
 -- $doc

 -- * Section 2
 foo
 ) where
...

results in

 (HsModule
  (Just
   ({ html-test/src/Bug797.hs:1:8-13 }
    {ModuleName: Bug797}))
  (Just
   ({ html-test/src/Bug797.hs:(1,15)-(7,2) }
    [({ html-test/src/Bug797.hs:2:2-15 }
      (IEGroup
       (1)
       (HsDocString
        {FastString: " Section 1"})))
    ,({ html-test/src/Bug797.hs:3:2-8 }
      (IEDocNamed
       "doc"))
    ,({ html-test/src/Bug797.hs:5:2-15 }
      (IEGroup
       (1)
       (HsDocString
        {FastString: " Section 2"})))
    ,({ html-test/src/Bug797.hs:6:2-4 }
      (IEVar
       ({ html-test/src/Bug797.hs:6:2-4 }
        (IEName
         ({ html-test/src/Bug797.hs:6:2-4 }
          (Unqual
           {OccName: foo}))))))]))
...

Now both sections and the named doc is present in the AST.

alexbiehl commented 6 years ago

See here:

https://github.com/ghc/ghc/blob/8b823f270e53627ddca1a993c05f1ab556742d96/compiler/parser/Parser.y#L834-L837

GHC tries to parse a full named doc section. All we want it to parse is just the reference to the named doc section here.

alexbiehl commented 6 years ago

Levent, are you interested in taking the lead here and fix the issue upstream?

LeventErkok commented 6 years ago

@alexbiehl Thanks for the analysis!

Filed here as a GHC issue: https://ghc.haskell.org/trac/ghc/ticket/15015#ticket

alexbiehl commented 6 years ago

@sjakobi IIRC you are in that area currently, would you like to take the lead here?

sjakobi commented 6 years ago

I'm quite busy until April 20, but I'll take a look then.

sjakobi commented 6 years ago

I'm afraid I still haven't looked into this. Admittedly I haven't had any contact with ghc's happy logic so far.

@harpocrates: You have more experience in this area. Is this something you would like to take a stab at?

harpocrates commented 6 years ago

Yeah, eventually... 😄

I know what the issue is though, so perhaps that's worth elaborating a bit more. The problem is actually at the token level. There is no lexical distinction drawn between a reference to a named chunk in an export list and an actual named chunk - both use ITdocCommentNamed. We should probably have a ITdocCommentReference which expects only a name (compared to ITdocCommentNamed which expects a name followed by a paragraph of comments).

sgraf812 commented 6 years ago

Can the former happen in a haddock comment? I.e. is it valid to define a named chunk within a haddock comment, like this:

-- | Stuff
-- $doc
-- Is this within the definition of the named chunk \$doc?

It sounds like this should not be the case, otherwise the syntax would be ambiguous.