@@ -1,23 +1,11 @@
1{-# LANGUAGE RankNTypes #-}
1{-# LANGUAGE RankNTypes #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
4module StackTrace.Plugin (plugin) where
3module StackTrace.Plugin (plugin) where
6import Control.Arrow (first)
5import Control.Arrow (first)
7import Data.Monoid (Any(Any, getAny))
6import Data.Monoid (Any(Any, getAny))
8−import GHC.Types.SrcLoc
9−#if __GLASGOW_HASKELL__ >= 900
13import GhcPlugins
7import GhcPlugins
15−#if __GLASGOW_HASKELL__ >= 810
18−#if __GLASGOW_HASKELL__ < 810
19import HsSyn
8import HsSyn
22type Traversal s t a b
10type Traversal s t a b
23 = forall f. Applicative f =>
11 = forall f. Applicative f =>
@@ -40,30 +28,13 @@ parsedPlugin _ _ pm = do
40ghcStackModuleName :: ModuleName
28ghcStackModuleName :: ModuleName
41ghcStackModuleName = mkModuleName "AutoImported.GHC.Stack"
29ghcStackModuleName = mkModuleName "AutoImported.GHC.Stack"
43−#if __GLASGOW_HASKELL__ < 810
44−importDeclQualified :: Bool
45−importDeclQualified = True
47−importDeclQualified :: ImportDeclQualifiedStyle
48−importDeclQualified = QualifiedPre
51ghcStackImport :: Located (ImportDecl (GhcPass p))
31ghcStackImport :: Located (ImportDecl (GhcPass p))
52ghcStackImport =
32ghcStackImport =
53− L srcSpan $
33+ noLoc $
54 (simpleImportDecl $ mkModuleName "GHC.Stack")
34 (simpleImportDecl $ mkModuleName "GHC.Stack")
55− { ideclQualified = importDeclQualified, ideclAs = Just $ noLoc ghcStackModuleName }
35+ {ideclQualified = True, ideclAs = Just $ noLoc ghcStackModuleName}
57− -- This is for GHC-9 related problems. @noLoc@ causes GHC to throw warnings
58− -- about unused imports. Even if the import is used
59− -- See: https://github.com/waddlaw/haskell-stack-trace-plugin/issues/16
60− srcSpan = RealSrcSpan (realSrcLocSpan $ mkRealSrcLoc "haskell-stack-trace-plugin:very-unique-file-name-to-avoid-collision" 1 1) Nothing
62−#if __GLASGOW_HASKELL__ >= 900
63−updateHsModule :: HsModule -> HsModule
65updateHsModule :: HsModule GhcPs -> HsModule GhcPs
37updateHsModule :: HsModule GhcPs -> HsModule GhcPs
67updateHsModule hsm =
38updateHsModule hsm =
68 hsm {hsmodImports = hsmodImports', hsmodDecls = hsmodDecls'}
39 hsm {hsmodImports = hsmodImports', hsmodDecls = hsmodDecls'}
@@ -85,6 +56,7 @@ updateHsModule hsm =
85 astTraversal :: Traversal' (LHsDecl GhcPs) (HsType GhcPs)
56 astTraversal :: Traversal' (LHsDecl GhcPs) (HsType GhcPs)
86 astTraversal = updateHsmodDecl
57 astTraversal = updateHsmodDecl
87 . updateHsDecl
58 . updateHsDecl
88 . updateLHsSigWsType
60 . updateLHsSigWsType
89 . updateLHsSigType
61 . updateLHsSigType
90 . updateLHsType
62 . updateLHsType
@@ -93,56 +65,10 @@ updateHsModule hsm =
93updateHsmodDecl :: Traversal' (LHsDecl GhcPs) (HsDecl GhcPs)
65updateHsmodDecl :: Traversal' (LHsDecl GhcPs) (HsDecl GhcPs)
94updateHsmodDecl = traverse
66updateHsmodDecl = traverse
96−updateHsDecl :: Traversal' (HsDecl GhcPs) (LHsSigWcType GhcPs)
68+updateHsDecl :: Traversal' (HsDecl GhcPs) (Sig GhcPs)
97−updateHsDecl f (SigD xSig s) = SigD xSig <$> updateSig f s
69+updateHsDecl f (SigD xSig s) = SigD xSig <$> f s
98−updateHsDecl f (ValD xVal hsBind) = ValD xVal <$> updateHsBind f hsBind
99updateHsDecl _ sig = pure sig
70updateHsDecl _ sig = pure sig
101−updateHsBind :: Traversal' (HsBind GhcPs) (LHsSigWcType GhcPs)
102−updateHsBind f bind@FunBind {} = (\x -> bind {fun_matches = x}) <$> updateMatchGroup f (fun_matches bind)
103−updateHsBind _ bind = pure bind
105−updateMatchGroup :: Traversal' (MatchGroup GhcPs (LHsExpr GhcPs)) (LHsSigWcType GhcPs)
106−updateMatchGroup f mg@MG {} = (\x -> mg {mg_alts = x}) <$> updateLLMatch f (mg_alts mg)
107−#if __GLASGOW_HASKELL__ < 900
108−updateMatchGroup _ mg = pure mg
111−updateLocated :: Functor f => (a -> b -> f c) -> a -> Located b -> f (Located c)
112−updateLocated f g (L l e) = L l <$> f g e
114−updateLLMatch :: Traversal' (Located [LMatch GhcPs (LHsExpr GhcPs)]) (LHsSigWcType GhcPs)
115−updateLLMatch = updateLocated updateLMatches
117−updateLMatches :: Traversal' [LMatch GhcPs (LHsExpr GhcPs)] (LHsSigWcType GhcPs)
118−updateLMatches f = traverse (updateLocated updateMatch f)
120−updateMatch :: Traversal' (Match GhcPs (LHsExpr GhcPs)) (LHsSigWcType GhcPs)
121−updateMatch f m@Match {} = (\x -> m {m_grhss = x}) <$> updateGrhss f (m_grhss m)
122−#if __GLASGOW_HASKELL__ < 900
123−updateMatch _ m = pure m
126−updateGrhss :: Traversal' (GRHSs GhcPs (LHsExpr GhcPs)) (LHsSigWcType GhcPs)
127−updateGrhss f grhss@GRHSs {} = (\x -> grhss {grhssLocalBinds = x}) <$> updateLHsLocalBinds f (grhssLocalBinds grhss)
128−#if __GLASGOW_HASKELL__ < 900
129−updateGrhss _ grhss = pure grhss
132−updateLHsLocalBinds :: Traversal' (LHsLocalBinds GhcPs) (LHsSigWcType GhcPs)
133−updateLHsLocalBinds = updateLocated updateLocalBinds
135−updateLocalBinds :: Traversal' (HsLocalBinds GhcPs) (LHsSigWcType GhcPs)
136−updateLocalBinds f (HsValBinds xHsValBinds hsValBindsLR) = HsValBinds xHsValBinds <$> updateHsValBindsLR f hsValBindsLR
137−updateLocalBinds _ hsValBinds = pure hsValBinds
139−updateHsValBindsLR :: Traversal' (HsValBindsLR GhcPs GhcPs) (LHsSigWcType GhcPs)
140−updateHsValBindsLR f (ValBinds xValBinds lHsBindsLR lSigs) = ValBinds xValBinds lHsBindsLR <$> updateLSigs f lSigs
141−updateHsValBindsLR _ valBinds = pure valBinds
143−updateLSigs :: Traversal' [LSig GhcPs] (LHsSigWcType GhcPs)
144−updateLSigs f = traverse (updateLocated updateSig f)
146updateSig :: Traversal' (Sig GhcPs) (LHsSigWcType GhcPs)
72updateSig :: Traversal' (Sig GhcPs) (LHsSigWcType GhcPs)
147updateSig f (TypeSig xSig ls t) = TypeSig xSig ls <$> f t
73updateSig f (TypeSig xSig ls t) = TypeSig xSig ls <$> f t
148updateSig _ sig = pure sig
74updateSig _ sig = pure sig
@@ -150,62 +76,41 @@ updateSig _ sig = pure sig
150updateLHsSigWsType :: Traversal' (LHsSigWcType GhcPs) (LHsSigType GhcPs)
76updateLHsSigWsType :: Traversal' (LHsSigWcType GhcPs) (LHsSigType GhcPs)
151updateLHsSigWsType f lhs@HsWC {} =
77updateLHsSigWsType f lhs@HsWC {} =
152 (\x -> lhs {hswc_body = x}) <$> f (hswc_body lhs)
78 (\x -> lhs {hswc_body = x}) <$> f (hswc_body lhs)
153−#if __GLASGOW_HASKELL__ < 900
154updateLHsSigWsType _ lhs = pure lhs
79updateLHsSigWsType _ lhs = pure lhs
157updateLHsSigType :: Traversal' (LHsSigType GhcPs) (LHsType GhcPs)
81updateLHsSigType :: Traversal' (LHsSigType GhcPs) (LHsType GhcPs)
158updateLHsSigType f lhs@HsIB {} =
82updateLHsSigType f lhs@HsIB {} =
159 (\x -> lhs {hsib_body = x}) <$> f (hsib_body lhs)
83 (\x -> lhs {hsib_body = x}) <$> f (hsib_body lhs)
160−#if __GLASGOW_HASKELL__ < 900
161updateLHsSigType _ lhs = pure lhs
84updateLHsSigType _ lhs = pure lhs
164updateLHsType :: Traversal' (LHsType GhcPs) (HsType GhcPs)
86updateLHsType :: Traversal' (LHsType GhcPs) (HsType GhcPs)
165updateLHsType = traverse
87updateLHsType = traverse
167-- Main process
89-- Main process
168updateHsType :: HsType GhcPs -> (Any, HsType GhcPs)
90updateHsType :: HsType GhcPs -> (Any, HsType GhcPs)
169−updateHsType ty@(HsQualTy xty ctxt body) =
91+updateHsType (HsQualTy xty ctxt body) =
170− if hasHasCallStack (unLoc ctxt)
172− else flagASTModified $ HsQualTy xty (fmap appendHSC ctxt) body
92+ flagASTModified $ HsQualTy xty (fmap appendHSC ctxt) body
173updateHsType ty@HsTyVar {} =
93updateHsType ty@HsTyVar {} =
174− flagASTModified $ HsQualTy xQualTy (noLoc $ appendHSC []) (noLoc ty)
94+ flagASTModified $ HsQualTy noExt (noLoc $ appendHSC []) (noLoc ty)
175updateHsType ty@HsAppTy {} =
95updateHsType ty@HsAppTy {} =
176− flagASTModified $ HsQualTy xQualTy (noLoc $ appendHSC []) (noLoc ty)
96+ flagASTModified $ HsQualTy noExt (noLoc $ appendHSC []) (noLoc ty)
177updateHsType ty@HsFunTy {} =
97updateHsType ty@HsFunTy {} =
178− flagASTModified $ HsQualTy xQualTy (noLoc $ appendHSC []) (noLoc ty)
98+ flagASTModified $ HsQualTy noExt (noLoc $ appendHSC []) (noLoc ty)
179updateHsType ty@HsListTy {} =
99updateHsType ty@HsListTy {} =
180− flagASTModified $ HsQualTy xQualTy (noLoc $ appendHSC []) (noLoc ty)
100+ flagASTModified $ HsQualTy noExt (noLoc $ appendHSC []) (noLoc ty)
181updateHsType ty@HsTupleTy {} =
101updateHsType ty@HsTupleTy {} =
182− flagASTModified $ HsQualTy xQualTy (noLoc $ appendHSC []) (noLoc ty)
102+ flagASTModified $ HsQualTy noExt (noLoc $ appendHSC []) (noLoc ty)
183updateHsType ty = pure ty
103updateHsType ty = pure ty
185−#if __GLASGOW_HASKELL__ < 810
189−xQualTy :: NoExtField
193flagASTModified :: a -> (Any, a)
105flagASTModified :: a -> (Any, a)
194flagASTModified a = (Any True, a)
106flagASTModified a = (Any True, a)
196appendHSC :: HsContext GhcPs -> HsContext GhcPs
108appendHSC :: HsContext GhcPs -> HsContext GhcPs
197appendHSC cs = mkHSC : cs
109appendHSC cs = mkHSC : cs
199−hasHasCallStack :: HsContext GhcPs -> Bool
200−hasHasCallStack = any (checkHsType . unLoc)
202− checkHsType :: HsType GhcPs -> Bool
203− checkHsType (HsTyVar _ _ lid) = unLoc lid == (mkRdrUnqual $ mkClsOcc "HasCallStack")
204− checkHsType _ = False
206-- make HasCallStack => constraint
111-- make HasCallStack => constraint
207mkHSC :: LHsType GhcPs
112mkHSC :: LHsType GhcPs
208−mkHSC = noLoc $ HsTyVar xQualTy NotPromoted lId
113+mkHSC = noLoc $ HsTyVar noExt NotPromoted lId
210lId :: Located (IdP GhcPs)
115lId :: Located (IdP GhcPs)
211lId = noLoc $ mkRdrQual ghcStackModuleName $ mkClsOcc "HasCallStack"
116lId = noLoc $ mkRdrQual ghcStackModuleName $ mkClsOcc "HasCallStack"