Skip to content

Commit a717bc8

Browse files
committed
Leverage apply-refact improvements
* applyRefactoring accepts ghc extensions to parse the file * new applyRefactoring' function accepts the parsed module Thanks @zliu41!
1 parent 78d7b45 commit a717bc8

File tree

1 file changed

+51
-24
lines changed
  • plugins/hls-hlint-plugin/src/Ide/Plugin

1 file changed

+51
-24
lines changed

plugins/hls-hlint-plugin/src/Ide/Plugin/Hlint.hs

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE ScopedTypeVariables #-}
12
{-# LANGUAGE CPP #-}
23
{-# LANGUAGE DeriveAnyClass #-}
34
{-# LANGUAGE DeriveGeneric #-}
@@ -39,12 +40,16 @@ import Development.IDE.Core.Shake (getDiagnostics)
3940
#ifdef GHC_LIB
4041
import Data.List (nub)
4142
import "ghc-lib" GHC hiding (DynFlags(..))
43+
import "ghc-lib" GHC.LanguageExtension (Extension)
4244
import "ghc" GHC as RealGHC (DynFlags(..))
4345
import "ghc" HscTypes as RealGHC.HscTypes (hsc_dflags)
4446
import qualified "ghc" EnumSet as EnumSet
4547
import Language.Haskell.GhclibParserEx.GHC.Driver.Session as GhclibParserEx (readExtension)
4648
#else
4749
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)
4853
#endif
4954

5055
import Ide.Logger
@@ -176,7 +181,14 @@ getIdeas nfp = do
176181
fmap applyHints' (moduleEx flags)
177182

178183
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
180192
moduleEx flags = do
181193
mbpm <- getParsedModule nfp
182194
-- If ghc was not able to parse the module, we disable hlint diagnostics
@@ -190,20 +202,18 @@ getIdeas nfp = do
190202
Just <$> (liftIO $ parseModuleEx flags' fp contents')
191203

192204
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
198206
logm $ "hlint:getIdeas:setExtensions:" ++ show hlintExts
199207
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
207217
#endif
208218

209219
-- ---------------------------------------------------------------------
@@ -334,10 +344,15 @@ applyOneCmd lf ide (AOP uri pos title) = do
334344
applyHint :: IdeState -> NormalizedFilePath -> Maybe OneHint -> IO (Either String WorkspaceEdit)
335345
applyHint ide nfp mhint =
336346
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
338350
let ideas' = maybe ideas (`filterIdeas` ideas) mhint
339-
let commands = map (show &&& ideaRefactoring) ideas'
351+
let commands = map ideaRefactoring ideas'
340352
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
341356
-- set Nothing as "position" for "applyRefactorings" because
342357
-- applyRefactorings expects the provided position to be _within_ the scope
343358
-- of each refactoring it will apply.
@@ -353,27 +368,39 @@ applyHint ide nfp mhint =
353368
-- If we provide "applyRefactorings" with "Just (1,13)" then
354369
-- the "Redundant bracket" hint will never be executed
355370
-- 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
363374
hClose h
364375
writeFileUTF8NoNewLineTranslation temp oldContent
365-
(Right <$> applyRefactorings Nothing commands temp) `catches`
376+
let exts = runAction' getExtensions
377+
(Right <$> applyRefactorings Nothing commands temp exts)
378+
`catches`
366379
[ Handler $ \e -> return (Left (show (e :: IOException)))
367380
, Handler $ \e -> return (Left (show (e :: ErrorCall)))
368381
]
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
369396
case res of
370397
Right appliedFile -> do
371398
let uri = fromNormalizedUri (filePathToUri' nfp)
372399
let wsEdit = diffText' True (uri, oldContent) (T.pack appliedFile) IncludeDeletions
373400
liftIO $ logm $ "hlint:applyHint:diff=" ++ show wsEdit
374401
ExceptT $ return (Right wsEdit)
375402
Left err ->
376-
throwE (show err)
403+
throwE err
377404
where
378405
-- | If we are only interested in applying a particular hint then
379406
-- let's filter out all the irrelevant ideas

0 commit comments

Comments
 (0)