Skip to content

Commit 550bcd6

Browse files
committed
Migrate parsing from haskell-src-exts to ghc-lib-parser
Hoogle uses haskell-src-exts both for parsing declarations and as an internal representation of them (see EDecl constructor of data Entry). The problem is that haskell-src-exts was not updated since 2020 and fell behind modern Haskell syntax, uncapable to parse a significant portion of Hackage. ghc-lib-parser is a modern and supported alternative. Complete migration to ghc-lib-parser would be a mammoth task, so this commit implements only half of it: use ghc-lib-parser for parsing, but convert received HsDecl back to Decl from haskell-src-exts, so that the rest of Hoogle can carry on unchanged.
1 parent 80fa8f9 commit 550bcd6

File tree

4 files changed

+647
-8
lines changed

4 files changed

+647
-8
lines changed

hoogle.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ library
6060
extra >= 1.6.6,
6161
filepath,
6262
foundation >= 0.0.13,
63+
ghc-lib-parser >= 9.6,
6364
old-locale,
6465
hashable,
6566
haskell-src-exts >= 1.22 && < 1.24,
@@ -110,6 +111,7 @@ library
110111
Input.Download
111112
Input.Haddock
112113
Input.Item
114+
Input.ParseDecl
113115
Input.Reorder
114116
Input.Set
115117
Input.Settings

src/Input/Haddock.hs

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Data.List.Extra
88
import Data.Maybe
99
import Data.Data
1010
import Input.Item
11+
import Input.ParseDecl
1112
import General.Util
1213
import Control.DeepSeq
1314
import Control.Monad.Trans.Class
@@ -169,8 +170,6 @@ readItem (stripPrefix "data (" -> Just xs) -- tuple data type
169170
op s x = x
170171
readItem _ = Nothing
171172

172-
myParseDecl = fmap (fmap $ const ()) . parseDeclWithMode parseMode -- partial application, to share the initialisation cost
173-
174173
unGADT (GDataDecl a b c d _ [] e) = DataDecl a b c d [] e
175174
unGADT x = x
176175

@@ -192,16 +191,79 @@ input_haddock_test = testing "Input.Haddock.parseLine" $ do
192191
test "newtype Identity a"
193192
test "foo :: Int# -> b"
194193
test "(,,) :: a -> b -> c -> (a, b, c)"
195-
test "data (,,) a b"
194+
"data (,,) a b" === "data Tuple3 a b" -- when ghc-lib-parser >= 9.8
196195
test "reverse :: [a] -> [a]"
197-
test "reverse :: [:a:] -> [:a:]"
196+
-- Parallel Haskell has never been implemented
197+
-- test "reverse :: [:a:] -> [:a:]"
198198
test "module Foo.Bar"
199199
test "data Char"
200200
"data Char :: *" === "data Char"
201201
"newtype ModuleName :: *" === "newtype ModuleName"
202202
"Progress :: !(Maybe String) -> {-# UNPACK #-} !Int -> !(Int -> Bool) -> Progress" ===
203203
"Progress :: Maybe String -> Int -> (Int -> Bool) -> Progress"
204-
-- Broken in the last HSE release, fixed in HSE HEAD
205-
-- test "quotRemInt# :: Int# -> Int# -> (# Int#, Int# #)"
204+
test "quotRemInt# :: Int# -> Int# -> (# Int#, Int# #)"
206205
test "( # ) :: Int"
207206
test "pattern MyPattern :: ()"
207+
test "degrees :: Floating x => Radians x -> Degrees x"
208+
test "class Angle a"
209+
test "instance Eq x => Eq (Degrees x)"
210+
test "instance Angle Degrees"
211+
test "type Queue a = Deque Nonthreadsafe Nonthreadsafe SingleEnd SingleEnd Grow Safe a"
212+
test "class DequeClass d => PopL d"
213+
test "tests_fifo :: DequeClass d => (forall elt . IO (d elt)) -> Test"
214+
test "class ParUnsafe iv p | p -> iv"
215+
"(##) :: Diagram -> Diagram -> Diagram" === "( ## ) :: Diagram -> Diagram -> Diagram"
216+
test "instance LayoutClass Positioned []"
217+
test "data Ord a => Range a"
218+
test "aPair :: Proxy (,)"
219+
test "aTriple :: Proxy (,,)"
220+
test "qop :: (Ord a, Show qtyp, Show (QFlipTyp qtyp), QFlipTyp (QFlipTyp qtyp) ~ qtyp) => Set (QueryRep QAtomTyp a) -> Set (QueryRep (QFlipTyp qtyp) a) -> QueryRep qtyp a"
221+
test "reorient :: (Unbox a) => Bernsteinp Int a -> Bernsteinp Int a"
222+
"type family PrimM a :: * -> *;" === "type family PrimM a :: * -> *"
223+
test "HSNil :: HSet '[]"
224+
"HSCons :: !elem -> HSet elems -> HSet (elem : elems)" === "HSCons :: elem -> HSet elems -> HSet (elem : elems)"
225+
test "instance Data.HSet.Reverse.HReverse '[e] els1 els2 => Data.HSet.Reverse.HReverse '[] (e : els1) els2"
226+
test "instance Data.HSet.Remove.HRemove (e : els) els 'TypeFun.Data.Peano.Z"
227+
test "Free :: (forall m . Monad m => Effects effects m -> m a) -> Free effects a"
228+
test "infixl 3 <||"
229+
test "instance Data.String.IsString t => Data.String.IsString (t Yi.MiniBuffer.::: doc)"
230+
test "runValueExpression :: (Functor f) => Expression a ((->) b) f r -> f ((a -> b) -> r)"
231+
test "HCons :: (x :: *) -> HList xs -> HList (x : xs)"
232+
test "instance forall k (key :: k) . Data.Traversable.Traversable (Data.ComposableAssociation.Association key)"
233+
test "ReflH :: forall (k :: *) (t :: k) . HetEq t t"
234+
test "egcd :: (PID d, (Euclidean d)) => d -> d -> (d, d, d)"
235+
test "proc :: FilePath -> [String] -> CreateProcess"
236+
test "unitTests :: Proxy '()"
237+
test "type OneToFour = '[1, 2, 3, 4]"
238+
test "data family Prio pol item :: *"
239+
test "set :: (Monad m, ToByteString a) => Key -> a -> Opts \"SET\" -> Redis m Bool"
240+
test "by :: ByteString -> Opts \"SORT\""
241+
test "infixr 9 :+:"
242+
test "instance forall k1 k2 (expectation1 :: k2) (expectation2 :: k1) . (Test.TypeSpec.Core.PrettyTypeSpec expectation1, Test.TypeSpec.Core.PrettyTypeSpec expectation2) => Test.TypeSpec.Core.PrettyTypeSpec '(expectation1, expectation2)"
243+
test "SomeFoo :: Foo a => m a -> SomeFoo m"
244+
test "(@~?) :: (HasCallStack, Ord a, Num a, Show a, ?epsilon :: a) => a -> a -> Assertion"
245+
test "data Data where { Idx :: {idxChildren :: Index key (Node height key val)} -> Node ('S height) key val}"
246+
test "UnexpectedResponse :: forall k a b . () => Host -> Response k a b -> ProtocolError"
247+
test "(.) :: Category k cat => forall (b :: k) (c :: k) (a :: k) . cat b c -> cat a b -> cat a c"
248+
test "infixl 3 `And`"
249+
test "infix 1 `shouldBe`"
250+
test "pattern The :: The d a => a -> d"
251+
test "Html :: Element \"html\" '[] (Elements [\"head\", \"body\"]) (ManifestA & '[])"
252+
test "instance forall k1 v1 (pk :: k1 -> GHC.Types.Constraint) (k2 :: k1) (pv :: v1 -> GHC.Types.Constraint) (v2 :: v1) . (pk k2, pv v2) => Type.Membership.KeyTargetAre pk pv (k2 'Type.Membership.Internal.:> v2)"
253+
test "crDoubleBuffer :: CompactorReturn s -> {-# UNPACK #-} !DoubleBuffer s"
254+
test "expectationFailure :: (?callStack :: CallStack) => String -> Expectation"
255+
test "type family MapTyCon t xs = r | r -> xs"
256+
test "pattern Id :: CRCategory k => (β ~ α, Object k α) => k α β"
257+
test "pattern Stream :: () => () => Repetition"
258+
test "In# :: (# #) -> In (a :: Effects) (b :: Effects)"
259+
test "anyAsciiDecimalWord# :: Addr# -> Addr# -> (# (# #) | (# Word#, Addr# #) #)"
260+
test "class SymbolToField (sym :: Symbol) rec typ | sym rec -> typ"
261+
test "closestPairDist_spec :: _ => ([r] -> r) -> (r -> t) -> [b] -> Property"
262+
-- Cannot faithfully represent ConstraintKind with ImplicitParams in HSE
263+
-- test "type HasCallStack = ?callStack :: CallStack"
264+
-- Cannot faithfully represent @r in HSE
265+
-- test "Maybe# :: forall (r :: RuntimeRep) (a :: TYPE r). (# (# #) | a #) -> Maybe# @r a"
266+
-- Cannot faithfully represent visible binders in HSE
267+
-- test "data NDFamily_ :: forall (name :: Name) -> forall (ks :: Params name). ParamsProxy name ks -> Res name ks Any :~: r -> Args name ks -> Exp r"
268+
-- Cannot faithfully represent standalone kind signatures in HSE
269+
-- test "type MinBound :: a;"

0 commit comments

Comments
 (0)