Skip to content

Commit a05e2bf

Browse files
committed
Fix parsing of NoXyz extensions
fixes #401
1 parent 7ce1279 commit a05e2bf

File tree

2 files changed

+29
-13
lines changed
  • lib/Language/Haskell/Stylish
  • tests/Language/Haskell/Stylish/Parse

2 files changed

+29
-13
lines changed

lib/Language/Haskell/Stylish/Parse.hs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@ module Language.Haskell.Stylish.Parse
55

66

77
--------------------------------------------------------------------------------
8-
import Control.Monad ((>=>))
98
import Data.List (foldl',
109
stripPrefix)
1110
import Data.Maybe (fromMaybe,
1211
listToMaybe,
1312
mapMaybe)
14-
import Data.Traversable (for)
1513
import qualified GHC.Data.StringBuffer as GHC
1614
import GHC.Driver.Ppr as GHC
1715
import qualified GHC.Driver.Session as GHC
@@ -35,6 +33,15 @@ import Language.Haskell.Stylish.Module
3533
type Extensions = [String]
3634

3735

36+
--------------------------------------------------------------------------------
37+
parseExtension :: String -> Either String (LangExt.Extension, Bool)
38+
parseExtension str = case GHCEx.readExtension str of
39+
Just e -> Right (e, True)
40+
Nothing -> case str of
41+
'N' : 'o' : str' -> fmap not <$> parseExtension str'
42+
_ -> Left $ "Unknown extension: " ++ show str
43+
44+
3845
--------------------------------------------------------------------------------
3946
-- | Filter out lines which use CPP macros
4047
unCpp :: String -> String
@@ -60,23 +67,24 @@ dropBom str = str
6067
parseModule :: Extensions -> Maybe FilePath -> String -> Either String Module
6168
parseModule externalExts0 fp string = do
6269
-- Parse extensions.
63-
externalExts1 <- for externalExts0 $ \s -> case GHCEx.readExtension s of
64-
Nothing -> Left $ "Unknown extension: " ++ show s
65-
Just e -> Right e
70+
externalExts1 <- traverse parseExtension externalExts0
6671

6772
-- Build first dynflags.
68-
let dynFlags0 = foldl' turnOn baseDynFlags externalExts1
73+
let dynFlags0 = foldl' toggleExt baseDynFlags externalExts1
6974

7075
-- Parse options from file
7176
let fileOptions = fmap GHC.unLoc $ GHC.getOptions dynFlags0
7277
(GHC.stringToStringBuffer string)
7378
(fromMaybe "-" fp)
74-
fileExtensions = mapMaybe
75-
(stripPrefix "-X" >=> GHCEx.readExtension)
79+
fileExtensions = mapMaybe (\str -> do
80+
str' <- stripPrefix "-X" str
81+
case parseExtension str' of
82+
Left _ -> Nothing
83+
Right x -> pure x)
7684
fileOptions
7785

7886
-- Set further dynflags.
79-
let dynFlags1 = foldl' turnOn dynFlags0 fileExtensions
87+
let dynFlags1 = foldl' toggleExt dynFlags0 fileExtensions
8088
`GHC.gopt_set` GHC.Opt_KeepRawTokenStream
8189

8290
-- Possibly strip CPP.
@@ -92,7 +100,7 @@ parseModule externalExts0 fp string = do
92100
where
93101
withFileName x = maybe "" (<> ": ") fp <> x
94102

95-
turnOn dynFlags ext = foldl'
96-
turnOn
97-
(GHC.xopt_set dynFlags ext)
98-
[rhs | (lhs, True, rhs) <- GHC.impliedXFlags, lhs == ext]
103+
toggleExt dynFlags (ext, onOff) = foldl'
104+
toggleExt
105+
((if onOff then GHC.xopt_set else GHC.xopt_unset) dynFlags ext)
106+
[(rhs, onOff') | (lhs, onOff', rhs) <- GHC.impliedXFlags, lhs == ext]

tests/Language/Haskell/Stylish/Parse/Tests.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ tests = testGroup "Language.Haskell.Stylish.Parse"
3030
, testCase "UnicodeSyntax extension" testUnicodeSyntax
3131
, testCase "XmlSyntax regression" testXmlSyntaxRegression
3232
, testCase "MagicHash regression" testMagicHashRegression
33+
, testCase "Disabling extensions" testDisableExtensions
3334
]
3435

3536
--------------------------------------------------------------------------------
@@ -138,6 +139,13 @@ testMagicHashRegression = returnsRight $ parseModule [] Nothing $ unlines
138139
[ "xs = \"foo\"#|1#|'a'#|bar#|Nil"
139140
]
140141

142+
testDisableExtensions :: Assertion
143+
testDisableExtensions = returnsRight $
144+
parseModule ["NoImplicitPrelude"] Nothing $ unlines
145+
[ "{-# NoStarIsType #-}"
146+
, "main = return ()"
147+
]
148+
141149
--------------------------------------------------------------------------------
142150
returnsRight :: HasCallStack => Show a => Either a b -> Assertion
143151
returnsRight action = withFrozenCallStack $ either (assertFailure . show) mempty action

0 commit comments

Comments
 (0)