-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathabortChg.hs
108 lines (96 loc) · 3.57 KB
/
abortChg.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
{-#LANGUAGE DeriveGeneric, StandaloneDeriving#-}
module AbortPlugin (plugin) where
import Control.Monad
import Control.Monad.IO.Class
import qualified EnumSet as S
import GhcPlugins hiding (errorMsg,(<>))
import ErrUtils
import Data.Traversable
import GHC.LanguageExtensions
import GHC.Generics
import Data.List (foldl',(\\))
import Data.Monoid
import Data.Data
import Control.Exception (throw)
import qualified Bag
import qualified HscTypes
import HsSyn
import ApiAnnotation
import HeaderInfo
import qualified Dhall
plugin :: Plugin
plugin = defaultPlugin
{ parsedResultAction = \commandLineOptions modSummary parsedModule -> do
checkExts commandLineOptions modSummary parsedModule
checkImports commandLineOptions modSummary parsedModule
pure parsedModule
}
deriving instance Typeable DynFlags
checkExts :: (HasDynFlags m, MonadIO m) => [CommandLineOption] -> ModSummary -> HsParsedModule -> m ()
checkExts commandLineOptions modSummary (HsParsedModule { hpm_module = L pos parsedModule, hpm_src_files = src_files, hpm_annotations = (annKeys, annotations) })
= do
flags <- getDynFlags
let allowed :: [Extension]
allowed =
[ MonomorphismRestriction
, RelaxedPolyRec
, ForeignFunctionInterface
, ImplicitPrelude
, DoAndIfThenElse
, EmptyDataDecls
, PatternGuards
, NondecreasingIndentation
, TraditionalRecordSyntax
, MonadFailDesugaring
, StarIsType
]
HsModule { hsmodName = name, hsmodExports = exports, hsmodImports = imports, hsmodDecls = decls }
= parsedModule
extensions = extensionFlags flags
badExtensions = S.toList (foldl' (flip S.delete) extensions allowed)
extensionErrors =
[ ErrUtils.mkPlainErrMsg
flags
pos
(ErrUtils.formatErrDoc
flags
(ErrUtils.errDoc
[ text ("Forbidden extension used: " ++ show extensionName) ]
[]
[]
)
)
| extensionName <- badExtensions
]
liftIO (throw (HscTypes.mkSrcErr (Bag.listToBag extensionErrors)))
unless (null badExtensions) $ liftIO (ghcExit flags 1)
checkImports :: (HasDynFlags m, MonadIO m) => [CommandLineOption] -> ModSummary -> HsParsedModule -> m ()
checkImports commandLineOptions modSummary (HsParsedModule { hpm_module = L pos parsedModule, hpm_src_files = src_files, hpm_annotations = (annKeys, annotations) })
= do
flags <- getDynFlags
let allowedImports :: [String]
allowedImports = "Prelude" : ["Data.List"]
HsModule { hsmodName = name, hsmodExports = exports, hsmodImports = imports, hsmodDecls = decls }
= parsedModule
importsUsed = map snd (ms_textual_imps modSummary <> ms_srcimps modSummary)
badImports =
[ rval
| rval@(L _ n) <- importsUsed
, moduleNameString n `notElem` allowedImports
]
let
importErrors =
[ ErrUtils.mkPlainErrMsg
flags
importPosition
(ErrUtils.formatErrDoc
flags
(ErrUtils.errDoc
[ text ("Forbidden import used: " ++ moduleNameString importName) ]
[]
[]
)
)
| L importPosition importName <- badImports
]
liftIO (throw (HscTypes.mkSrcErr (Bag.listToBag importErrors)))