@@ -0,0 +1,81 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+module StackTrace.Plugin (plugin) where
3+
4+import GhcPlugins
5+import TcRnTypes (IfM, TcM, TcGblEnv, tcg_binds, tcg_rn_decls)
6+import HsExtension (GhcTc, GhcRn)
7+import HsDecls (HsGroup)
8+import HsExpr (LHsExpr)
9+import HsSyn
10+
11+import Data.Maybe
12+
13+plugin :: Plugin
14+plugin = defaultPlugin
15+ { parsedResultAction = parsedPlugin
16+ }
17+
18+parsedPlugin :: [CommandLineOption] -> ModSummary -> HsParsedModule -> Hsc HsParsedModule
19+parsedPlugin _ _ pm = do
20+ dflags <- getDynFlags
21+
22+ let extract = hsmodImports . unLoc
23+ addGHCStackMod = noLoc $ simpleImportDecl $ mkModuleName "GHC.Stack"
24+
25+ m = updateHsModule addGHCStackMod updateHsmodDecl <$> hpm_module pm
26+ pm' = pm { hpm_module = m }
27+
28+ return pm'
29+
30+updateHsModule :: LImportDecl GhcPs -> (LHsDecl GhcPs -> LHsDecl GhcPs) -> HsModule GhcPs -> HsModule GhcPs
31+updateHsModule importDecl update hsm = hsm
32+ { hsmodImports = importDecl:decls
33+ , hsmodDecls = map update lhss
34+ }
35+ where
36+ decls = hsmodImports hsm
37+ lhss = hsmodDecls hsm
38+
39+--------------
40+
41+updateHsmodDecl :: LHsDecl GhcPs -> LHsDecl GhcPs
42+updateHsmodDecl = fmap updateHsDecl
43+
44+updateHsDecl :: HsDecl GhcPs -> HsDecl GhcPs
45+updateHsDecl (SigD xSig s) = SigD xSig (updateSig s)
46+updateHsDecl decl = decl
47+
48+updateSig :: Sig GhcPs -> Sig GhcPs
49+updateSig (TypeSig xSig ls t) = TypeSig xSig ls (updateLHsSigWcType t)
50+updateSig sig = sig
51+
52+updateLHsSigWcType :: LHsSigWcType GhcPs -> LHsSigWcType GhcPs
53+updateLHsSigWcType lhs@HsWC{} = lhs { hswc_body = updateLHsSigType (hswc_body lhs) }
54+updateLHsSigWcType lhs@XHsWildCardBndrs{} = lhs
55+
56+updateLHsSigType :: LHsSigType GhcPs -> LHsSigType GhcPs
57+updateLHsSigType lhs@HsIB{} = lhs { hsib_body = updateLHsType (hsib_body lhs )}
58+updateLHsSigType lhs@XHsImplicitBndrs{} = lhs
59+
60+updateLHsType :: LHsType GhcPs -> LHsType GhcPs
61+updateLHsType = fmap updateHsType
62+
63+-- Main process
64+updateHsType :: HsType GhcPs -> HsType GhcPs
65+updateHsType ty@(HsQualTy xty ctxt body) = HsQualTy xty (fmap appendHSC ctxt) body
66+updateHsType ty@HsTyVar{} = HsQualTy noExt (noLoc $ appendHSC []) (noLoc ty)
67+updateHsType ty@HsAppTy{} = HsQualTy noExt (noLoc $ appendHSC []) (noLoc ty)
68+updateHsType ty@HsFunTy{} = HsQualTy noExt (noLoc $ appendHSC []) (noLoc ty)
69+updateHsType ty@HsListTy{} = HsQualTy noExt (noLoc $ appendHSC []) (noLoc ty)
70+updateHsType ty@HsTupleTy{} = HsQualTy noExt (noLoc $ appendHSC []) (noLoc ty)
71+updateHsType ty = ty
72+
73+appendHSC :: HsContext GhcPs -> HsContext GhcPs
74+appendHSC cs = mkHSC : cs
75+
76+-- make HasCallStack => constraint
77+mkHSC :: LHsType GhcPs
78+mkHSC = noLoc $ HsTyVar noExt NotPromoted lId
79+
80+lId :: Located (IdP GhcPs)
81+lId = noLoc $ mkRdrUnqual $ mkClsOcc "HasCallStack"