1
- {-# LANGUAGE CPP #-}
2
1
{-# LANGUAGE TupleSections #-}
3
2
4
3
module Refact.Apply
@@ -7,18 +6,12 @@ module Refact.Apply
7
6
, parseExtensions
8
7
) where
9
8
10
- import Data.List
11
- import GHC.LanguageExtensions.Type ( Extension ( .. ) )
9
+ import Control.Monad ( unless )
10
+ import Data.List ( intercalate )
12
11
import Refact.Fixity
13
12
import Refact.Internal
14
13
import Refact.Types
15
14
16
- #if __GLASGOW_HASKELL__ <= 806
17
- import DynFlags (FlagSpec (flagSpecFlag , flagSpecName ), xFlags )
18
- #else
19
- import Language.Haskell.GhclibParserEx.GHC.Driver.Session (impliedXFlags , readExtension )
20
- #endif
21
-
22
15
-- | Apply a set of refactorings as supplied by hlint
23
16
applyRefactorings
24
17
:: Maybe (Int , Int )
@@ -34,106 +27,16 @@ applyRefactorings
34
27
-- prior to it which has an overlapping source span and is not filtered out.
35
28
-> FilePath
36
29
-- ^ Target file
37
- -> ([Extension ], [Extension ])
38
- -- ^ Enabled and disabled extensions. These are in addition to the @LANGUAGE@ pragmas
39
- -- in the target file. When they conflict with the @LANGUAGE@ pragmas, pragmas win.
30
+ -> [String ]
31
+ -- ^ GHC extensions, e.g., @LambdaCase@, @NoStarIsType@. The list is processed from left
32
+ -- to right. An extension (e.g., @StarIsType@) may be overridden later (e.g., by @NoStarIsType@).
33
+ --
34
+ -- These are in addition to the @LANGUAGE@ pragmas in the target file. When they conflict
35
+ -- with the @LANGUAGE@ pragmas, pragmas win.
40
36
-> IO String
41
37
applyRefactorings optionsPos inp file exts = do
38
+ let (enabled, disabled, invalid) = parseExtensions exts
39
+ unless (null invalid) . fail $ " Unsupported extensions: " ++ intercalate " , " invalid
42
40
(as, m) <- either (onError " apply" ) (uncurry applyFixities)
43
- =<< parseModuleWithArgs exts file
41
+ =<< parseModuleWithArgs (enabled, disabled) file
44
42
apply optionsPos False ((mempty ,) <$> inp) file Silent as m
45
-
46
- -- | Parse the input into (enabled extensions, disabled extensions, invalid input).
47
- -- Implied extensions are automatically added. For example, @FunctionalDependencies@
48
- -- implies @MultiParamTypeClasses@, and @RebindableSyntax@ implies @NoImplicitPrelude@.
49
- --
50
- -- The input is processed from left to right. An extension (e.g., @StarIsType@)
51
- -- may be overridden later (e.g., by @NoStarIsType@).
52
- --
53
- -- Extensions that appear earlier in the input will appear later in the output.
54
- -- Implied extensions appear in the end. If an extension occurs multiple times in the input,
55
- -- the last one is used.
56
- --
57
- -- >>> parseExtensions ["GADTs", "RebindableSyntax", "StarIsType", "GADTs", "InvalidExtension", "NoStarIsType"]
58
- -- ([GADTs, RebindableSyntax, GADTSyntax, MonoLocalBinds], [StarIsType, ImplicitPrelude], ["InvalidExtension"])
59
- parseExtensions :: [String ] -> ([Extension ], [Extension ], [String ])
60
- parseExtensions = addImplied . foldl' f mempty
61
- where
62
- f :: ([Extension ], [Extension ], [String ]) -> String -> ([Extension ], [Extension ], [String ])
63
- f (ys, ns, is) (' N' : ' o' : s) | Just ext <- readExtension s =
64
- (delete ext ys, ext : delete ext ns, is)
65
- f (ys, ns, is) s | Just ext <- readExtension s =
66
- (ext : delete ext ys, delete ext ns, is)
67
- f (ys, ns, is) s = (ys, ns, s : is)
68
-
69
- addImplied :: ([Extension ], [Extension ], [String ]) -> ([Extension ], [Extension ], [String ])
70
- addImplied (ys, ns, is) = (ys ++ impliedOn, ns ++ impliedOff, is)
71
- where
72
- impliedOn = [b | ext <- ys, (a, True , b) <- impliedXFlags, a == ext]
73
- impliedOff = [b | ext <- ys, (a, False , b) <- impliedXFlags, a == ext]
74
-
75
- #if __GLASGOW_HASKELL__ <= 806
76
- readExtension :: String -> Maybe Extension
77
- readExtension s = flagSpecFlag <$> find ((== s) . flagSpecName) xFlags
78
-
79
- -- | Copied from "Language.Haskell.GhclibParserEx.GHC.Driver.Session", in order to
80
- -- support GHC 8.6
81
- impliedXFlags :: [(Extension , Bool , Extension )]
82
- impliedXFlags
83
- -- See Note [Updating flag description in the User's Guide]
84
- = [ (RankNTypes , True , ExplicitForAll )
85
- , (QuantifiedConstraints , True , ExplicitForAll )
86
- , (ScopedTypeVariables , True , ExplicitForAll )
87
- , (LiberalTypeSynonyms , True , ExplicitForAll )
88
- , (ExistentialQuantification , True , ExplicitForAll )
89
- , (FlexibleInstances , True , TypeSynonymInstances )
90
- , (FunctionalDependencies , True , MultiParamTypeClasses )
91
- , (MultiParamTypeClasses , True , ConstrainedClassMethods ) -- c.f. #7854
92
- , (TypeFamilyDependencies , True , TypeFamilies )
93
-
94
- , (RebindableSyntax , False , ImplicitPrelude ) -- NB: turn off!
95
-
96
- , (DerivingVia , True , DerivingStrategies )
97
-
98
- , (GADTs , True , GADTSyntax )
99
- , (GADTs , True , MonoLocalBinds )
100
- , (TypeFamilies , True , MonoLocalBinds )
101
-
102
- , (TypeFamilies , True , KindSignatures ) -- Type families use kind signatures
103
- , (PolyKinds , True , KindSignatures ) -- Ditto polymorphic kinds
104
-
105
- -- TypeInType is now just a synonym for a couple of other extensions.
106
- , (TypeInType , True , DataKinds )
107
- , (TypeInType , True , PolyKinds )
108
- , (TypeInType , True , KindSignatures )
109
-
110
- -- AutoDeriveTypeable is not very useful without DeriveDataTypeable
111
- , (AutoDeriveTypeable , True , DeriveDataTypeable )
112
-
113
- -- We turn this on so that we can export associated type
114
- -- type synonyms in subordinates (e.g. MyClass(type AssocType))
115
- , (TypeFamilies , True , ExplicitNamespaces )
116
- , (TypeOperators , True , ExplicitNamespaces )
117
-
118
- , (ImpredicativeTypes , True , RankNTypes )
119
-
120
- -- Record wild-cards implies field disambiguation
121
- -- Otherwise if you write (C {..}) you may well get
122
- -- stuff like " 'a' not in scope ", which is a bit silly
123
- -- if the compiler has just filled in field 'a' of constructor 'C'
124
- , (RecordWildCards , True , DisambiguateRecordFields )
125
-
126
- , (ParallelArrays , True , ParallelListComp )
127
-
128
- , (JavaScriptFFI , True , InterruptibleFFI )
129
-
130
- , (DeriveTraversable , True , DeriveFunctor )
131
- , (DeriveTraversable , True , DeriveFoldable )
132
-
133
- -- Duplicate record fields require field disambiguation
134
- , (DuplicateRecordFields , True , DisambiguateRecordFields )
135
-
136
- , (TemplateHaskell , True , TemplateHaskellQuotes )
137
- , (Strict , True , StrictData )
138
- ]
139
- #endif
0 commit comments