1
+ {-# LANGUAGE ScopedTypeVariables #-}
1
2
{-# LANGUAGE CPP #-}
2
3
{-# LANGUAGE DeriveAnyClass #-}
3
4
{-# LANGUAGE DeriveGeneric #-}
@@ -39,12 +40,16 @@ import Development.IDE.Core.Shake (getDiagnostics)
39
40
#ifdef GHC_LIB
40
41
import Data.List (nub )
41
42
import "ghc-lib" GHC hiding (DynFlags (.. ))
43
+ import "ghc-lib" GHC.LanguageExtension (Extension )
42
44
import "ghc" GHC as RealGHC (DynFlags (.. ))
43
45
import "ghc" HscTypes as RealGHC.HscTypes (hsc_dflags )
44
46
import qualified "ghc" EnumSet as EnumSet
45
47
import Language.Haskell.GhclibParserEx.GHC.Driver.Session as GhclibParserEx (readExtension )
46
48
#else
47
49
import Development.IDE.GHC.Compat hiding (DynFlags (.. ))
50
+ import HscTypes (hsc_dflags )
51
+ import Language.Haskell.GHC.ExactPrint.Parsers (postParseTransform )
52
+ import Language.Haskell.GHC.ExactPrint.Delta (normalLayout )
48
53
#endif
49
54
50
55
import Ide.Logger
@@ -176,7 +181,14 @@ getIdeas nfp = do
176
181
fmap applyHints' (moduleEx flags)
177
182
178
183
where moduleEx :: ParseFlags -> Action (Maybe (Either ParseError ModuleEx ))
179
- #ifdef GHC_LIB
184
+ #ifndef GHC_LIB
185
+ moduleEx _flags = do
186
+ mbpm <- getParsedModule nfp
187
+ return $ createModule <$> mbpm
188
+ where createModule pm = Right (createModuleEx anns modu)
189
+ where anns = pm_annotations pm
190
+ modu = pm_parsed_source pm
191
+ #else
180
192
moduleEx flags = do
181
193
mbpm <- getParsedModule nfp
182
194
-- If ghc was not able to parse the module, we disable hlint diagnostics
@@ -190,20 +202,18 @@ getIdeas nfp = do
190
202
Just <$> (liftIO $ parseModuleEx flags' fp contents')
191
203
192
204
setExtensions flags = do
193
- hsc <- hscEnv <$> use_ GhcSession nfp
194
- let dflags = hsc_dflags hsc
195
- let hscExts = EnumSet. toList (extensionFlags dflags)
196
- let hscExts' = mapMaybe (GhclibParserEx. readExtension . show ) hscExts
197
- let hlintExts = nub $ enabledExtensions flags ++ hscExts'
205
+ hlintExts <- getExtensions
198
206
logm $ " hlint:getIdeas:setExtensions:" ++ show hlintExts
199
207
return $ flags { enabledExtensions = hlintExts }
200
- #else
201
- moduleEx _flags = do
202
- mbpm <- getParsedModule nfp
203
- return $ createModule <$> mbpm
204
- where createModule pm = Right (createModuleEx anns modu)
205
- where anns = pm_annotations pm
206
- modu = pm_parsed_source pm
208
+
209
+ getExtensions :: Action [Extension ]
210
+ getExtensions = do
211
+ hsc <- hscEnv <$> use_ GhcSession nfp
212
+ let dflags = hsc_dflags hsc
213
+ let hscExts = EnumSet. toList (extensionFlags dflags)
214
+ let hscExts' = mapMaybe (GhclibParserEx. readExtension . show ) hscExts
215
+ let hlintExts = nub $ enabledExtensions flags ++ hscExts'
216
+ return hlintExts
207
217
#endif
208
218
209
219
-- ---------------------------------------------------------------------
@@ -334,10 +344,15 @@ applyOneCmd lf ide (AOP uri pos title) = do
334
344
applyHint :: IdeState -> NormalizedFilePath -> Maybe OneHint -> IO (Either String WorkspaceEdit )
335
345
applyHint ide nfp mhint =
336
346
runExceptT $ do
337
- ideas <- bimapExceptT showParseError id $ ExceptT $ liftIO $ runAction " applyHint" ide $ getIdeas nfp
347
+ let runAction' :: Action a -> IO a
348
+ runAction' = runAction " applyHint" ide
349
+ ideas <- bimapExceptT showParseError id $ ExceptT $ runAction' $ getIdeas nfp
338
350
let ideas' = maybe ideas (`filterIdeas` ideas) mhint
339
- let commands = map ( show &&& ideaRefactoring) ideas'
351
+ let commands = map ideaRefactoring ideas'
340
352
liftIO $ logm $ " applyHint:apply=" ++ show commands
353
+ let fp = fromNormalizedFilePath nfp
354
+ (_, mbOldContent) <- liftIO $ runAction' $ getFileContents nfp
355
+ oldContent <- maybe (liftIO $ T. readFile fp) return mbOldContent
341
356
-- set Nothing as "position" for "applyRefactorings" because
342
357
-- applyRefactorings expects the provided position to be _within_ the scope
343
358
-- of each refactoring it will apply.
@@ -353,27 +368,39 @@ applyHint ide nfp mhint =
353
368
-- If we provide "applyRefactorings" with "Just (1,13)" then
354
369
-- the "Redundant bracket" hint will never be executed
355
370
-- because SrcSpan (1,20,??,??) doesn't contain position (1,13).
356
- let fp = fromNormalizedFilePath nfp
357
- (_, mbOldContent) <- liftIO $ runAction " hlint" ide $ getFileContents nfp
358
- oldContent <- maybe (liftIO $ T. readFile fp) return mbOldContent
359
- -- We need to save a file with last edited contents cause `apply-refact`
360
- -- doesn't expose a function taking directly contents instead a file path.
361
- -- Ideally we should try to expose that function upstream and remove this.
362
- res <- liftIO $ withSystemTempFile (takeFileName fp) $ \ temp h -> do
371
+ #ifdef GHC_LIB
372
+ res <-
373
+ liftIO $ withSystemTempFile (takeFileName fp) $ \ temp h -> do
363
374
hClose h
364
375
writeFileUTF8NoNewLineTranslation temp oldContent
365
- (Right <$> applyRefactorings Nothing commands temp) `catches`
376
+ let exts = runAction' getExtensions
377
+ (Right <$> applyRefactorings Nothing commands temp exts)
378
+ `catches`
366
379
[ Handler $ \ e -> return (Left (show (e :: IOException )))
367
380
, Handler $ \ e -> return (Left (show (e :: ErrorCall )))
368
381
]
382
+ #else
383
+ mbParsedModule <- liftIO $ runAction' $ getParsedModule nfp
384
+ res <-
385
+ case mbParsedModule of
386
+ Nothing -> throwE " Apply hint: error parsing the module"
387
+ Just pm -> do
388
+ let anns = pm_annotations pm
389
+ let modu = pm_parsed_source pm
390
+ hsc <- liftIO $ runAction' $ hscEnv <$> use_ GhcSession nfp
391
+ let dflags = hsc_dflags hsc
392
+ (anns', modu') <-
393
+ ExceptT $ return $ postParseTransform (Right (anns, [] , dflags, modu)) normalLayout
394
+ liftIO (Right <$> applyRefactorings' Nothing commands anns' modu')
395
+ #endif
369
396
case res of
370
397
Right appliedFile -> do
371
398
let uri = fromNormalizedUri (filePathToUri' nfp)
372
399
let wsEdit = diffText' True (uri, oldContent) (T. pack appliedFile) IncludeDeletions
373
400
liftIO $ logm $ " hlint:applyHint:diff=" ++ show wsEdit
374
401
ExceptT $ return (Right wsEdit)
375
402
Left err ->
376
- throwE ( show err)
403
+ throwE err
377
404
where
378
405
-- | If we are only interested in applying a particular hint then
379
406
-- let's filter out all the irrelevant ideas
0 commit comments