aboutsummaryrefslogtreecommitdiff
path: root/haddock-api/src/Haddock/Parser.hs
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2021-01-05 19:30:24 -0500
committerBen Gamari <ben@smart-cactus.org>2021-01-13 18:39:25 -0500
commite1230ede3d1c77a6916e318aefcd47829e56035c (patch)
tree36b89a8d6fae359a5c5de4887c020a6101bd5cf8 /haddock-api/src/Haddock/Parser.hs
parent9a7e3d6fa3faad2ccb75f7f3e9d9f4bc203a77ca (diff)
parent99f61534a470b84c424fde0835215de6a3b6d721 (diff)
Merge remote-tracking branch 'origin/ghc-9.0' into ghc-head
Diffstat (limited to 'haddock-api/src/Haddock/Parser.hs')
-rw-r--r--haddock-api/src/Haddock/Parser.hs42
1 files changed, 29 insertions, 13 deletions
diff --git a/haddock-api/src/Haddock/Parser.hs b/haddock-api/src/Haddock/Parser.hs
index 366bcd55..ab2fa549 100644
--- a/haddock-api/src/Haddock/Parser.hs
+++ b/haddock-api/src/Haddock/Parser.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE ViewPatterns #-}
-- |
-- Module : Haddock.Parser
-- Copyright : (c) Mateusz Kowalczyk 2013,
@@ -15,27 +16,42 @@ module Haddock.Parser ( parseParas
import qualified Documentation.Haddock.Parser as P
import Documentation.Haddock.Types
+import Haddock.Types
import GHC.Driver.Session ( DynFlags )
import GHC.Driver.Config
import GHC.Data.FastString ( fsLit )
-import GHC.Parser.Lexer ( initParserState, unP, ParseResult(POk) )
+import GHC.Parser.Lexer ( initParserState, unP, ParseResult(POk, PFailed) )
import GHC.Parser ( parseIdentifier )
-import GHC.Types.Name.Reader ( RdrName )
-import GHC.Types.SrcLoc ( mkRealSrcLoc, unLoc )
+import GHC.Types.Name.Occurrence ( occNameString )
+import GHC.Types.Name.Reader ( RdrName(..) )
+import GHC.Types.SrcLoc ( mkRealSrcLoc, GenLocated(..) )
import GHC.Data.StringBuffer ( stringToStringBuffer )
-parseParas :: DynFlags -> Maybe Package -> String -> MetaDoc mod RdrName
+
+parseParas :: DynFlags -> Maybe Package -> String -> MetaDoc mod (Wrap NsRdrName)
parseParas d p = overDoc (P.overIdentifier (parseIdent d)) . P.parseParas p
-parseString :: DynFlags -> String -> DocH mod RdrName
+parseString :: DynFlags -> String -> DocH mod (Wrap NsRdrName)
parseString d = P.overIdentifier (parseIdent d) . P.parseString
-parseIdent :: DynFlags -> String -> Maybe RdrName
-parseIdent dflags str0 =
- let buffer = stringToStringBuffer str0
- realSrcLc = mkRealSrcLoc (fsLit "<unknown file>") 0 0
- pstate = initParserState (initParserOpts dflags) buffer realSrcLc
- in case unP parseIdentifier pstate of
- POk _ name -> Just (unLoc name)
- _ -> Nothing
+parseIdent :: DynFlags -> Namespace -> String -> Maybe (Wrap NsRdrName)
+parseIdent dflags ns str0 =
+ case unP parseIdentifier (pstate str1) of
+ POk _ (L _ name)
+ -- Guards against things like 'Q.--', 'Q.case', etc.
+ -- See https://github.com/haskell/haddock/issues/952 and Trac #14109
+ | Qual _ occ <- name
+ , PFailed{} <- unP parseIdentifier (pstate (occNameString occ))
+ -> Nothing
+ | otherwise
+ -> Just (wrap (NsRdrName ns name))
+ PFailed{} -> Nothing
+ where
+ realSrcLc = mkRealSrcLoc (fsLit "<unknown file>") 0 0
+ pstate str = initParserState (initParserOpts dflags) (stringToStringBuffer str) realSrcLc
+ (wrap,str1) = case str0 of
+ '(' : s@(c : _) | c /= ',', c /= ')' -- rule out tuple names
+ -> (Parenthesized, init s)
+ '`' : s@(_ : _) -> (Backticked, init s)
+ _ -> (Unadorned, str0)