-
-
Notifications
You must be signed in to change notification settings - Fork 369
/
Copy pathStaticPlugin.hs
113 lines (90 loc) · 3.21 KB
/
StaticPlugin.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
{-# LANGUAGE CPP #-}
module Wingman.StaticPlugin
( staticPlugin
, metaprogramHoleName
, pattern WingmanMetaprogram
, pattern MetaprogramSyntax
) where
import Data.Data
import Development.IDE.GHC.Compat
import Development.IDE.GHC.Compat.Util
import GHC.LanguageExtensions.Type (Extension(EmptyCase, QuasiQuotes))
import Generics.SYB
import Ide.Types
staticPlugin :: DynFlagsModifications
staticPlugin = mempty
{ dynFlagsModifyGlobal =
\df -> allowEmptyCaseButWithWarning
$ flip gopt_unset Opt_SortBySubsumHoleFits
$ flip gopt_unset Opt_ShowValidHoleFits
$ df
{ refLevelHoleFits = Just 0
, maxRefHoleFits = Just 0
, maxValidHoleFits = Just 0
#if __GLASGOW_HASKELL__ >= 808
, staticPlugins = staticPlugins df <> [metaprogrammingPlugin]
#endif
}
#if __GLASGOW_HASKELL__ >= 808
, dynFlagsModifyParser = enableQuasiQuotes
#endif
}
pattern MetaprogramSourceText :: SourceText
pattern MetaprogramSourceText = SourceText "wingman-meta-program"
pattern WingmanMetaprogram :: FastString -> HsExpr p
pattern WingmanMetaprogram mp <-
#if __GLASGOW_HASKELL__ >= 900
HsPragE _ (HsPragSCC _ MetaprogramSourceText (StringLiteral NoSourceText mp))
(L _ ( HsVar _ _))
#else
HsSCC _ MetaprogramSourceText (StringLiteral NoSourceText mp)
(L _ ( HsVar _ _))
#endif
enableQuasiQuotes :: DynFlags -> DynFlags
enableQuasiQuotes = flip xopt_set QuasiQuotes
-- | Wingman wants to support destructing of empty cases, but these are a parse
-- error by default. So we want to enable 'EmptyCase', but then that leads to
-- silent errors without 'Opt_WarnIncompletePatterns'.
allowEmptyCaseButWithWarning :: DynFlags -> DynFlags
allowEmptyCaseButWithWarning =
flip xopt_set EmptyCase . flip wopt_set Opt_WarnIncompletePatterns
#if __GLASGOW_HASKELL__ >= 808
metaprogrammingPlugin :: StaticPlugin
metaprogrammingPlugin =
StaticPlugin $ PluginWithArgs (defaultPlugin { parsedResultAction = worker }) []
where
worker :: Monad m => [CommandLineOption] -> ModSummary -> HsParsedModule -> m HsParsedModule
worker _ _ pm = pure $ pm { hpm_module = addMetaprogrammingSyntax $ hpm_module pm }
#endif
metaprogramHoleName :: OccName
metaprogramHoleName = mkVarOcc "_$metaprogram"
mkMetaprogram :: SrcSpan -> FastString -> HsExpr GhcPs
mkMetaprogram ss mp =
#if __GLASGOW_HASKELL__ >= 900
HsPragE noExtField (HsPragSCC noExtField MetaprogramSourceText (StringLiteral NoSourceText mp))
#else
HsSCC noExtField MetaprogramSourceText (StringLiteral NoSourceText mp)
#endif
$ L ss
$ HsVar noExtField
$ L ss
$ mkRdrUnqual
$ metaprogramHoleName
addMetaprogrammingSyntax :: Data a => a -> a
addMetaprogrammingSyntax =
everywhere $ mkT $ \case
L ss (MetaprogramSyntax mp) ->
L ss $ mkMetaprogram ss mp
(x :: LHsExpr GhcPs) -> x
pattern MetaprogramSyntax :: FastString -> HsExpr GhcPs
pattern MetaprogramSyntax mp <-
HsSpliceE _ (HsQuasiQuote _ _ (occNameString . rdrNameOcc -> "wingman") _ mp)
where
MetaprogramSyntax mp =
HsSpliceE noExtField $
HsQuasiQuote
noExtField
(mkRdrUnqual $ mkVarOcc "splice")
(mkRdrUnqual $ mkVarOcc "wingman")
noSrcSpan
mp