ghc-dump-core (empty) → 0.1.0.0
raw patch · 6 files changed
+583/−0 lines, 6 filesdep +basedep +bytestringdep +filepathsetup-changed
Dependencies added: base, bytestring, filepath, ghc, serialise, text
Files
- GhcDump/Ast.hs +236/−0
- GhcDump/Convert.hs +232/−0
- GhcDump/Plugin.hs +40/−0
- LICENSE +30/−0
- Setup.hs +2/−0
- ghc-dump-core.cabal +43/−0
+ GhcDump/Ast.hs view
@@ -0,0 +1,236 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE DeriveGeneric #-}+module GhcDump.Ast where++import GHC.Generics++import Data.Monoid+import qualified Data.ByteString as BS+import Codec.Serialise+import qualified Data.Text as T++import Unique (mkUnique)++data Unique = Unique !Char !Int+ deriving (Eq, Ord, Generic)+instance Serialise Unique++-- | This is dependent upon GHC+instance Show Unique where+ show (Unique c n) = show $ mkUnique c n++data ExternalName = ExternalName { externalModuleName :: !ModuleName+ , externalName :: !T.Text+ , externalUnique :: !Unique+ }+ | ForeignCall+ deriving (Eq, Ord, Generic, Show)+instance Serialise ExternalName++newtype BinderId = BinderId Unique+ deriving (Eq, Ord, Serialise, Show)++newtype SBinder = SBndr { unSBndr :: Binder' SBinder BinderId }+ deriving (Eq, Ord, Generic, Show)+instance Serialise SBinder++newtype Binder = Bndr { unBndr :: Binder' Binder Binder }+ deriving (Eq, Ord, Generic, Show)+instance Serialise Binder++binderUniqueName :: Binder -> T.Text+binderUniqueName (Bndr b) =+ binderName b <> T.pack "_" <> T.pack (show u)+ where BinderId u = binderId b++data Binder' bndr var = Binder { binderName :: !T.Text+ , binderId :: !BinderId+ , binderIdInfo :: IdInfo bndr var+ , binderIdDetails :: IdDetails+ , binderType :: Type' bndr var+ }+ | TyBinder { binderName :: !T.Text+ , binderId :: !BinderId+ , binderKind :: Type' bndr var+ }+ deriving (Eq, Ord, Generic, Show)+instance (Serialise bndr, Serialise var) => Serialise (Binder' bndr var)++data IdInfo bndr var+ = IdInfo { idiArity :: !Int+ , idiIsOneShot :: Bool+ , idiUnfolding :: Unfolding bndr var+ , idiInlinePragma :: !T.Text+ , idiOccInfo :: OccInfo+ , idiStrictnessSig :: !T.Text+ , idiDemandSig :: !T.Text+ , idiCallArity :: !Int+ }+ deriving (Eq, Ord, Generic, Show)+instance (Serialise bndr, Serialise var) => Serialise (IdInfo bndr var)++data Unfolding bndr var+ = NoUnfolding+ | BootUnfolding+ | OtherCon [AltCon]+ | DFunUnfolding+ | CoreUnfolding { unfTemplate :: Expr' bndr var+ , unfIsValue :: Bool+ , unfIsConLike :: Bool+ , unfIsWorkFree :: Bool+ , unfGuidance :: T.Text+ }+ deriving (Eq, Ord, Generic, Show)+instance (Serialise bndr, Serialise var) => Serialise (Unfolding bndr var)++data OccInfo = OccManyOccs -- | introduced in GHC 8.2+ | OccDead+ | OccOneOcc+ | OccLoopBreaker { occStrongLoopBreaker :: Bool }+ deriving (Eq, Ord, Generic, Show)+instance Serialise OccInfo++data IdDetails = VanillaId+ | RecSelId+ | DataConWorkId+ | DataConWrapId+ | ClassOpId+ | PrimOpId+ -- | FCallId (these are treated as ExternalNames since they have no binding site)+ | TickBoxOpId+ | DFunId+ | CoVarId -- | introduced in GHC 8.0+ | JoinId { joinIdArity :: !Int }+ deriving (Eq, Ord, Generic, Show)+instance Serialise IdDetails++data Lit = MachChar Char+ | MachStr BS.ByteString+ | MachNullAddr+ | MachInt Integer+ | MachInt64 Integer+ | MachWord Integer+ | MachWord64 Integer+ | MachFloat Rational+ | MachDouble Rational+ | MachLabel T.Text+ | LitInteger Integer+ deriving (Eq, Ord, Generic, Show)+instance Serialise Lit++data TyCon = TyCon !T.Text !Unique+ deriving (Eq, Ord, Generic, Show)+instance Serialise TyCon++type SType = Type' SBinder BinderId+type Type = Type' Binder Binder++data Type' bndr var+ = VarTy var+ | FunTy (Type' bndr var) (Type' bndr var)+ | TyConApp TyCon [Type' bndr var]+ | AppTy (Type' bndr var) (Type' bndr var)+ | ForAllTy bndr (Type' bndr var)+ | LitTy+ | CoercionTy+ deriving (Eq, Ord, Generic, Show)+instance (Serialise bndr, Serialise var) => Serialise (Type' bndr var)++newtype ModuleName = ModuleName {getModuleName :: T.Text}+ deriving (Eq, Ord, Serialise, Show)++type Module = Module' Binder Binder+type SModule = Module' SBinder BinderId++data Module' bndr var+ = Module { moduleName :: ModuleName+ , modulePhase :: T.Text+ , moduleTopBindings :: [TopBinding' bndr var]+ }+ deriving (Generic, Show)+instance (Serialise bndr, Serialise var) => Serialise (Module' bndr var)++moduleBindings :: Module' bndr var -> [(bndr, CoreStats, Expr' bndr var)]+moduleBindings = concatMap topBindings . moduleTopBindings++-- $binders+--+-- The binder story:+--+-- Things which might contain bound variables (e.g. expressions and types) have+-- a type variable which is instantiated at 'BinderId' in the serialised form or+-- 'Binder' after post-processing.+--+-- Note that bindings sites themselves are always 'Binder's.++type SExpr = Expr' SBinder BinderId+type Expr = Expr' Binder Binder++data Expr' bndr var+ = EVar var+ | EVarGlobal ExternalName+ | ELit Lit+ | EApp (Expr' bndr var) (Expr' bndr var)+ | ETyLam bndr (Expr' bndr var)+ | ELam bndr (Expr' bndr var)+ | ELet [(bndr, Expr' bndr var)] (Expr' bndr var)+ | ECase (Expr' bndr var) bndr [Alt' bndr var]+ | EType (Type' bndr var)+ | ECoercion+ deriving (Eq, Ord, Generic, Show)+instance (Serialise bndr, Serialise var) => Serialise (Expr' bndr var)++type SAlt = Alt' SBinder BinderId+type Alt = Alt' Binder Binder++data Alt' bndr var = Alt { altCon :: !AltCon+ , altBinders :: [bndr]+ , altRHS :: Expr' bndr var+ }+ deriving (Eq, Ord, Generic, Show)+instance (Serialise bndr, Serialise var) => Serialise (Alt' bndr var)++data AltCon = AltDataCon !T.Text+ | AltLit Lit+ | AltDefault+ deriving (Eq, Ord, Generic, Show)+instance Serialise AltCon++type STopBinding = TopBinding' SBinder BinderId+type TopBinding = TopBinding' Binder Binder++data TopBinding' bndr var+ = NonRecTopBinding bndr CoreStats (Expr' bndr var)+ | RecTopBinding [(bndr, CoreStats, Expr' bndr var)]+ deriving (Generic, Show)+instance (Serialise bndr, Serialise var) => Serialise (TopBinding' bndr var)++topBindings :: TopBinding' bndr var -> [(bndr, CoreStats, Expr' bndr var)]+topBindings (NonRecTopBinding a b c) = [(a,b,c)]+topBindings (RecTopBinding bs) = bs++data CoreStats+ = CoreStats { csTerms :: !Int+ , csTypes :: !Int+ , csCoercions :: !Int+ , csValBinds :: !Int+ , csJoinBinds :: !Int+ }+ deriving (Generic, Show)+instance Serialise CoreStats++instance Monoid CoreStats where+ mempty = CoreStats 0 0 0 0 0+ CoreStats a b c d e `mappend` CoreStats a' b' c' d' e' =+ CoreStats (a+a') (b+b') (c+c') (d+d') (e+e')++{-+data Rule' bndr var+ = Rule { ruleName :: T.Text+ , ruleActivation :: Activation+ , ruleFn :: Name+ , ruleBinders :: [bndr]+ , ruleRHS :: Expr' bndr var+ , ruleAuto :: Bool+ }+-}
+ GhcDump/Convert.hs view
@@ -0,0 +1,232 @@+{-# LANGUAGE CPP #-}+module GhcDump.Convert where++import Data.Bifunctor+import qualified Data.Text as T+import qualified Data.Text.Encoding as TE++import Literal (Literal(..))+import Var (Var)+import qualified Var+import Id (isFCallId)+import Module (ModuleName, moduleNameFS, moduleName)+import Unique (Unique, getUnique, unpkUnique)+import Name (getOccName, occNameFS, OccName, getName, nameModule_maybe)+import qualified IdInfo+import qualified BasicTypes as OccInfo (OccInfo(..), isStrongLoopBreaker)+#if MIN_VERSION_ghc(8,0,0)+import qualified CoreStats+#else+import qualified CoreUtils as CoreStats+#endif+import qualified CoreSyn+import CoreSyn (Expr(..), CoreExpr, Bind(..), CoreAlt, CoreBind, AltCon(..))+import HscTypes (ModGuts(..))+import FastString (FastString, fastStringToByteString)+#if MIN_VERSION_ghc(8,0,0)+import TyCoRep as Type (Type(..), TyBinder(..))+#else+import TypeRep as Type (Type(..))+#endif+import Type (splitFunTy_maybe)+import TyCon (TyCon, tyConUnique)++import Outputable (ppr, showSDoc, SDoc)+import DynFlags (unsafeGlobalDynFlags)++import GhcDump.Ast as Ast++cvtSDoc :: SDoc -> T.Text+cvtSDoc = T.pack . showSDoc unsafeGlobalDynFlags++fastStringToText :: FastString -> T.Text+fastStringToText = TE.decodeUtf8 . fastStringToByteString++occNameToText :: OccName -> T.Text+occNameToText = fastStringToText . occNameFS++cvtUnique :: Unique.Unique -> Ast.Unique+cvtUnique u =+ let (a,b) = unpkUnique u+ in Ast.Unique a b++cvtVar :: Var -> BinderId+cvtVar = BinderId . cvtUnique . Var.varUnique++cvtBinder :: Var -> SBinder+cvtBinder v+ | Var.isId v =+ SBndr $ Binder { binderName = occNameToText $ getOccName v+ , binderId = cvtVar v+ , binderIdInfo = cvtIdInfo $ Var.idInfo v+ , binderIdDetails = cvtIdDetails $ Var.idDetails v+ , binderType = cvtType $ Var.varType v+ }+ | otherwise =+ SBndr $ TyBinder { binderName = occNameToText $ getOccName v+ , binderId = cvtVar v+ , binderKind = cvtType $ Var.varType v+ }++cvtIdInfo :: IdInfo.IdInfo -> Ast.IdInfo SBinder BinderId+cvtIdInfo i =+ IdInfo { idiArity = IdInfo.arityInfo i+ , idiIsOneShot = IdInfo.oneShotInfo i == IdInfo.OneShotLam+ , idiUnfolding = cvtUnfolding $ IdInfo.unfoldingInfo i+ , idiInlinePragma = cvtSDoc $ ppr $ IdInfo.inlinePragInfo i+ , idiOccInfo = case IdInfo.occInfo i of+#if MIN_VERSION_ghc(8,1,0)+ OccInfo.ManyOccs{} -> OccManyOccs+#else+ OccInfo.NoOccInfo -> OccManyOccs+#endif+ OccInfo.IAmDead -> OccDead+ OccInfo.OneOcc{} -> OccOneOcc+ oi@OccInfo.IAmALoopBreaker{} -> OccLoopBreaker (OccInfo.isStrongLoopBreaker oi)+ , idiStrictnessSig = cvtSDoc $ ppr $ IdInfo.strictnessInfo i+ , idiDemandSig = cvtSDoc $ ppr $ IdInfo.demandInfo i+ , idiCallArity = IdInfo.callArityInfo i+ }++cvtUnfolding :: CoreSyn.Unfolding -> Ast.Unfolding SBinder BinderId+cvtUnfolding CoreSyn.NoUnfolding = Ast.NoUnfolding+#if MIN_VERSION_ghc(8,2,0)+cvtUnfolding CoreSyn.BootUnfolding = Ast.BootUnfolding+#endif+cvtUnfolding (CoreSyn.OtherCon cons) = Ast.OtherCon (map cvtAltCon cons)+cvtUnfolding (CoreSyn.DFunUnfolding{}) = Ast.DFunUnfolding+cvtUnfolding u@(CoreSyn.CoreUnfolding{}) =+ Ast.CoreUnfolding { unfTemplate = cvtExpr $ CoreSyn.uf_tmpl u+ , unfIsValue = CoreSyn.uf_is_value u+ , unfIsConLike = CoreSyn.uf_is_conlike u+ , unfIsWorkFree = CoreSyn.uf_is_work_free u+ , unfGuidance = cvtSDoc $ ppr $ CoreSyn.uf_guidance u+ }++cvtIdDetails :: IdInfo.IdDetails -> Ast.IdDetails+cvtIdDetails d =+ case d of+ IdInfo.VanillaId -> Ast.VanillaId+ IdInfo.RecSelId{} -> Ast.RecSelId+ IdInfo.DataConWorkId{} -> Ast.DataConWorkId+ IdInfo.DataConWrapId{} -> Ast.DataConWrapId+ IdInfo.ClassOpId{} -> Ast.ClassOpId+ IdInfo.PrimOpId{} -> Ast.PrimOpId+ IdInfo.FCallId{} -> error "This shouldn't happen"+ IdInfo.TickBoxOpId{} -> Ast.TickBoxOpId+ IdInfo.DFunId{} -> Ast.DFunId+#if MIN_VERSION_ghc(8,0,0)+ IdInfo.CoVarId{} -> Ast.CoVarId+#endif+#if MIN_VERSION_ghc(8,2,0)+ IdInfo.JoinId n -> Ast.JoinId n+#endif++cvtCoreStats :: CoreStats.CoreStats -> Ast.CoreStats+cvtCoreStats stats =+ Ast.CoreStats+ { csTerms = CoreStats.cs_tm stats+ , csTypes = CoreStats.cs_ty stats+ , csCoercions = CoreStats.cs_co stats+#if MIN_VERSION_ghc(8,2,0)+ , csValBinds = CoreStats.cs_vb stats+ , csJoinBinds = CoreStats.cs_jb stats+#else+ , csValBinds = 0+ , csJoinBinds = 0+#endif+ }++exprStats :: CoreExpr -> CoreStats.CoreStats+#if MIN_VERSION_ghc(8,0,0)+exprStats = CoreStats.exprStats+#else+-- exprStats wasn't exported in 7.10+exprStats _ = CoreStats.CS 0 0 0+#endif++cvtTopBind :: CoreBind -> STopBinding+cvtTopBind (NonRec b e) =+ NonRecTopBinding (cvtBinder b) (cvtCoreStats $ exprStats e) (cvtExpr e)+cvtTopBind (Rec bs) =+ RecTopBinding $ map to bs+ where to (b, e) = (cvtBinder b, cvtCoreStats $ exprStats e, cvtExpr e)++cvtExpr :: CoreExpr -> Ast.SExpr+cvtExpr expr =+ case expr of+ Var x+ -- foreign calls are local but have no binding site.+ -- TODO: use hasNoBinding here.+ | isFCallId x -> EVarGlobal ForeignCall+ | Just m <- nameModule_maybe $ getName x+ -> EVarGlobal $ ExternalName (cvtModuleName $ Module.moduleName m)+ (occNameToText $ getOccName x)+ (cvtUnique $ getUnique x)+ | otherwise -> EVar (cvtVar x)+ Lit l -> ELit (cvtLit l)+ App x y -> EApp (cvtExpr x) (cvtExpr y)+ Lam x e+ | Var.isTyVar x -> ETyLam (cvtBinder x) (cvtExpr e)+ | otherwise -> ELam (cvtBinder x) (cvtExpr e)+ Let (NonRec b e) body -> ELet [(cvtBinder b, cvtExpr e)] (cvtExpr body)+ Let (Rec bs) body -> ELet (map (bimap cvtBinder cvtExpr) bs) (cvtExpr body)+ Case e x _ as -> ECase (cvtExpr e) (cvtBinder x) (map cvtAlt as)+ Cast x _ -> cvtExpr x+ Tick _ e -> cvtExpr e+ Type t -> EType $ cvtType t+ Coercion _ -> ECoercion++cvtAlt :: CoreAlt -> Ast.SAlt+cvtAlt (con, bs, e) = Alt (cvtAltCon con) (map cvtBinder bs) (cvtExpr e)++cvtAltCon :: CoreSyn.AltCon -> Ast.AltCon+cvtAltCon (DataAlt altcon) = Ast.AltDataCon $ occNameToText $ getOccName altcon+cvtAltCon (LitAlt l) = Ast.AltLit $ cvtLit l+cvtAltCon DEFAULT = Ast.AltDefault++cvtLit :: Literal -> Ast.Lit+cvtLit l =+ case l of+ Literal.MachChar x -> Ast.MachChar x+ Literal.MachStr x -> Ast.MachStr x+ Literal.MachNullAddr -> Ast.MachNullAddr+ Literal.MachInt x -> Ast.MachInt x+ Literal.MachInt64 x -> Ast.MachInt64 x+ Literal.MachWord x -> Ast.MachWord x+ Literal.MachWord64 x -> Ast.MachWord64 x+ Literal.MachFloat x -> Ast.MachFloat x+ Literal.MachDouble x -> Ast.MachDouble x+ Literal.MachLabel x _ _ -> Ast.MachLabel $ fastStringToText x+ Literal.LitInteger x _ -> Ast.LitInteger x++cvtModule :: String -> ModGuts -> Ast.SModule+cvtModule phase guts =+ Ast.Module name (T.pack phase) (map cvtTopBind $ mg_binds guts)+ where name = cvtModuleName $ Module.moduleName $ mg_module guts++cvtModuleName :: Module.ModuleName -> Ast.ModuleName+cvtModuleName = Ast.ModuleName . fastStringToText . moduleNameFS++cvtType :: Type.Type -> Ast.SType+cvtType t+ | Just (a,b) <- splitFunTy_maybe t = Ast.FunTy (cvtType a) (cvtType b)+cvtType (Type.TyVarTy v) = Ast.VarTy (cvtVar v)+cvtType (Type.AppTy a b) = Ast.AppTy (cvtType a) (cvtType b)+cvtType (Type.TyConApp tc tys) = Ast.TyConApp (cvtTyCon tc) (map cvtType tys)+#if MIN_VERSION_ghc(8,2,0)+cvtType (Type.ForAllTy (Var.TvBndr b _) t) = Ast.ForAllTy (cvtBinder b) (cvtType t)+#elif MIN_VERSION_ghc(8,0,0)+cvtType (Type.ForAllTy (Named b _) t) = Ast.ForAllTy (cvtBinder b) (cvtType t)+cvtType (Type.ForAllTy (Anon _) t) = cvtType t+#else+cvtType (Type.ForAllTy b t) = Ast.ForAllTy (cvtBinder b) (cvtType t)+#endif+cvtType (Type.LitTy _) = Ast.LitTy+#if MIN_VERSION_ghc(8,0,0)+cvtType (Type.CastTy t _) = cvtType t+cvtType (Type.CoercionTy _) = Ast.CoercionTy+#endif++cvtTyCon :: TyCon.TyCon -> Ast.TyCon+cvtTyCon tc = TyCon (occNameToText $ getOccName tc) (cvtUnique $ tyConUnique tc)
+ GhcDump/Plugin.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE CPP #-}++module GhcDump.Plugin where++import Data.Maybe+import qualified Data.ByteString.Lazy as BSL+import qualified Codec.Serialise as Ser+import GhcPlugins hiding (TB)+import CoreMonad (pprPassDetails)+import ErrUtils (showPass)+import Text.Printf+import System.FilePath++import GhcDump.Convert++plugin :: Plugin+plugin = defaultPlugin { installCoreToDos = install }++install :: [CommandLineOption] -> [CoreToDo] -> CoreM [CoreToDo]+install _opts todo = do+ dflags <- getDynFlags+ return (intersperseDumps dflags todo)++intersperseDumps :: DynFlags -> [CoreToDo] -> [CoreToDo]+intersperseDumps dflags = go 0 "desugar"+ where+ go n phase (todo : rest) = pass n phase : todo : go (n+1) phase' rest+ where phase' = showSDocDump dflags (ppr todo <> text ":" <+> pprPassDetails todo)+ go n phase [] = [pass n phase]++ pass n phase = CoreDoPluginPass "DumpCore" (liftIO . dumpIn dflags n phase)++dumpIn :: DynFlags -> Int -> String -> ModGuts -> IO ModGuts+dumpIn dflags n phase guts = do+ let prefix = fromMaybe "dump" $ dumpPrefix dflags+ fname = printf "%spass-%04u.cbor" prefix n+ showPass dflags $ "GhcDump: Dumping core to "++fname+ let in_dump_dir = maybe id (</>) (dumpDir dflags)+ BSL.writeFile (in_dump_dir fname) $ Ser.serialise (cvtModule phase guts)+ return guts
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2017, Ben Gamari++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Ben Gamari nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ ghc-dump-core.cabal view
@@ -0,0 +1,43 @@+name: ghc-dump-core+version: 0.1.0.0+synopsis: An AST and compiler plugin for dumping GHC's Core representation.+description:+ @ghc-dump@ is a library, GHC plugin, and set of tools for recording and+ analysing GHC's Core representation. The plugin is compatible with GHC 7.10+ through 8.3, exporting a consistent (albeit somewhat lossy) representation+ across these versions. The AST is encoded as CBOR, which is small and easy to+ deserialise.+ .+ This package provides the AST and compiler plugin. See the @ghc-dump-util@+ package for a useful command-line tool for working with dumps produced by this+ plugin.+ .+ = Usage+ .+ "GhcDump.Plugin" provides a Core-to-Core plugin which dumps a representation+ of the Core AST to a file after every Core-to-Core pass. To use it, simply+ install this package and add @-fplugin GhcDump.Plugin@ to your GHC+ command-line. See the [README](https://github.com/bgamari/ghc-dump)+ for further analysis tips.++license: BSD3+license-file: LICENSE+author: Ben Gamari+maintainer: ben@well-typed.com+copyright: (c) 2017 Ben Gamari+category: Development+build-type: Simple+tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.2.2+cabal-version: >=1.10++library+ exposed-modules: GhcDump.Convert, GhcDump.Ast, GhcDump.Plugin+ ghc-options: -Wall+ other-extensions: GeneralizedNewtypeDeriving+ build-depends: base >=4.8 && <4.11,+ bytestring >= 0.10,+ text >=1.2 && <1.3,+ filepath >= 1.4,+ serialise >= 0.2 && <0.3,+ ghc >= 7.10 && < 8.4+ default-language: Haskell2010