Skip to content

Commit a186796

Browse files
authored
Merge pull request #689 from shayne-fletcher-da/issue-681
langexts explcitily enabled/disabled
2 parents 9f5776e + 22aa4f8 commit a186796

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

src/GHC/Util.hs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module GHC.Util (
1111
, getMessages
1212
, SDoc
1313
, Located
14+
, hseToGhcExtension
1415
-- Temporary : Export these so GHC doesn't consider them unused and
1516
-- tell weeder to ignore them.
1617
, isAtom, addParen, paren, isApp, isOpApp, isAnyApp, isDot, isSection, isDotApp
@@ -38,6 +39,8 @@ import "ghc-lib-parser" HeaderInfo
3839
import Data.List
3940
import System.FilePath
4041
import Language.Preprocessor.Unlit
42+
import qualified Language.Haskell.Exts.Extension as HSE
43+
import qualified Data.Map.Strict as Map
4144

4245
fakeSettings :: Settings
4346
fakeSettings = Settings
@@ -83,13 +86,21 @@ baseDynFlags :: DynFlags
8386
baseDynFlags = foldl' xopt_set
8487
(defaultDynFlags fakeSettings fakeLlvmConfig) enabledExtensions
8588

86-
parsePragmasIntoDynFlags ::
87-
DynFlags -> FilePath -> String -> IO (Either String DynFlags)
88-
parsePragmasIntoDynFlags flags filepath str =
89+
-- | Adjust the input 'DynFlags' to take into account language
90+
-- extensions to explicitly enable/disable as well as language
91+
-- extensions enabled by pragma in the source.
92+
parsePragmasIntoDynFlags :: DynFlags
93+
-> ([Extension], [Extension])
94+
-> FilePath
95+
-> String
96+
-> IO (Either String DynFlags)
97+
parsePragmasIntoDynFlags flags (enable, disable) filepath str =
8998
catchErrors $ do
9099
let opts = getOptions flags (stringToStringBuffer str) filepath
91100
(flags, _, _) <- parseDynamicFilePragma flags opts
92-
return $ Right flags
101+
let flags' = foldl' xopt_set flags enable
102+
let flags'' = foldl' xopt_unset flags' disable
103+
return $ Right flags''
93104
where
94105
catchErrors :: IO (Either String DynFlags) -> IO (Either String DynFlags)
95106
catchErrors act = handleGhcException reportErr
@@ -195,3 +206,12 @@ isSection x = case x of
195206
isDotApp :: HsExpr GhcPs -> Bool
196207
isDotApp (OpApp _ _ (L _ op) _) = isDot op
197208
isDotApp _ = False
209+
210+
-- | A mapping from 'HSE.KnownExtension' values to their
211+
-- 'GHC.LanguageExtensions.Type.Extension' equivalents.
212+
hseToGhcExtension :: Map.Map HSE.KnownExtension Extension
213+
hseToGhcExtension =
214+
let ghcExts = Map.fromList [(show x, x) | x <- [Cpp .. StarIsType]]
215+
in
216+
Map.fromList [ (x, ext) | x <- [minBound .. maxBound]
217+
, Just ext <- [Map.lookup (show x) ghcExts] ]

src/HSE/All.hs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import Data.List.Extra
2424
import Data.Maybe
2525
import Timing
2626
import Language.Preprocessor.Cpphs
27+
import Data.Either
2728
import Data.Set (Set)
2829
import qualified Data.Map as Map
2930
import qualified Data.Set as Set
@@ -37,6 +38,7 @@ import qualified "ghc-lib-parser" FastString
3738
import qualified "ghc-lib-parser" SrcLoc as GHC
3839
import qualified "ghc-lib-parser" ErrUtils
3940
import qualified "ghc-lib-parser" Outputable
41+
import qualified "ghc-lib-parser" GHC.LanguageExtensions.Type as GHC
4042

4143
vars :: FreeVars a => a -> [String]
4244
freeVars :: FreeVars a => a -> Set String
@@ -229,6 +231,17 @@ ghcFailOpParseModuleEx ppstr file str (loc, err) = do
229231
ErrUtils.pprLocErrMsg (ErrUtils.mkPlainErrMsg baseDynFlags loc err)
230232
return $ Left $ ParseError sl msg pe
231233

234+
-- | Produce a pair of lists from a 'ParseFlags' value representing
235+
-- language extensions to explicitly enable/disable.
236+
ghcExtensionsFromParseFlags :: ParseFlags
237+
-> ([GHC.Extension], [GHC.Extension])
238+
ghcExtensionsFromParseFlags ParseFlags {hseFlags=ParseMode {extensions=exts}}=
239+
partitionEithers $ mapMaybe toEither exts
240+
where
241+
toEither ke = case ke of
242+
EnableExtension e -> Left <$> Map.lookup e hseToGhcExtension
243+
DisableExtension e -> Right <$> Map.lookup e hseToGhcExtension
244+
232245
-- | Parse a Haskell module. Applies the C pre processor, and uses
233246
-- best-guess fixity resolution if there are ambiguities. The
234247
-- filename @-@ is treated as @stdin@. Requires some flags (often
@@ -242,7 +255,8 @@ parseModuleEx flags file str = timedIO "Parse" file $ do
242255
| otherwise -> readFileUTF8' file
243256
str <- return $ fromMaybe str $ stripPrefix "\65279" str -- remove the BOM if it exists, see #130
244257
ppstr <- runCpp (cppFlags flags) file str
245-
dynFlags <- parsePragmasIntoDynFlags baseDynFlags file ppstr
258+
let enableDisableExts = ghcExtensionsFromParseFlags flags
259+
dynFlags <- parsePragmasIntoDynFlags baseDynFlags enableDisableExts file ppstr
246260
case dynFlags of
247261
Right ghcFlags ->
248262
case (parseFileContentsWithComments (mkMode flags file) ppstr, parseFileGhcLib file ppstr ghcFlags) of

0 commit comments

Comments
 (0)