2
2
{-# LANGUAGE GADTs #-}
3
3
module Haskell.Ide.ApplyRefactPlugin where
4
4
5
+ import Control.Arrow
5
6
import Control.Monad.IO.Class
7
+ import Control.Monad.Trans.Either
8
+ import Data.Aeson
6
9
import qualified Data.Text as T
7
10
import qualified Data.Text.IO as T
8
11
import Data.Vinyl
9
12
import Haskell.Ide.Engine.MonadFunctions
10
13
import Haskell.Ide.Engine.PluginDescriptor
11
14
import Haskell.Ide.Engine.PluginUtils
12
15
import Haskell.Ide.Engine.SemanticTypes
13
- import Language.Haskell.HLint
14
- import Language.Haskell.HLint3
16
+ import Language.Haskell.HLint3 as Hlint
15
17
import Refact.Apply
16
18
import qualified Refact.Types as R
17
19
import Refact.Types hiding (SrcSpan )
@@ -49,10 +51,10 @@ applyOneCmd = CmdSync $ \_ctxs req -> do
49
51
logm $ " applyOneCmd:res=" ++ show res
50
52
case res of
51
53
Left err -> return $ IdeResponseFail (IdeError PluginError
52
- (T. pack $ " applyOne: " ++ show err) Nothing )
54
+ (T. pack $ " applyOne: " ++ show err) Null )
53
55
Right fs -> return (IdeResponseOk fs)
54
56
Right _ -> return $ IdeResponseError (IdeError InternalError
55
- " ApplyRefactPlugin.applyOneCmd: ghc’s exhaustiveness checker is broken" Nothing )
57
+ " ApplyRefactPlugin.applyOneCmd: ghc’s exhaustiveness checker is broken" Null )
56
58
57
59
58
60
-- ---------------------------------------------------------------------
@@ -66,49 +68,40 @@ applyAllCmd = CmdSync $ \_ctxs req -> do
66
68
logm $ " applyAllCmd:res=" ++ show res
67
69
case res of
68
70
Left err -> return $ IdeResponseFail (IdeError PluginError
69
- (T. pack $ " applyOne: " ++ show err) Nothing )
71
+ (T. pack $ " applyOne: " ++ show err) Null )
70
72
Right fs -> return (IdeResponseOk fs)
71
73
Right _ -> return $ IdeResponseError (IdeError InternalError
72
- " ApplyRefactPlugin.applyOneCmd: ghc’s exhaustiveness checker is broken" Nothing )
74
+ " ApplyRefactPlugin.applyOneCmd: ghc’s exhaustiveness checker is broken" Null )
73
75
74
76
75
77
-- ---------------------------------------------------------------------
76
78
77
79
applyHint :: FilePath -> Maybe Pos -> IO (Either String HieDiff )
78
80
applyHint file mpos = do
79
81
withTempFile $ \ f -> do
80
- -- absFile <- makeAbsolute file
81
- -- hlint /tmp/Foo.hs --refactor --refactor-options="-o /tmp/Bar.hs --pos 2,8"
82
-
83
- let
84
- optsf = " -o " ++ f
85
- opts = case mpos of
86
- Nothing -> optsf
87
- Just (r,c) -> optsf ++ " --pos " ++ show r ++ " ," ++ show c
88
- -- let hlintOpts = [file, "--quiet", "--refactor", "--refactor-options=" ++ opts ]
89
- let hlintOpts = [file, " --quiet" ]
90
- logm $ " applyHint=" ++ show hlintOpts
91
- res <- catchException $ hlint hlintOpts
92
- logm $ " applyHint:res=" ++ show res
93
- -- res <- hlint hlintOpts
94
- case res of
95
- Left x -> return $ Left (show x)
96
- Right x -> do
97
- let commands = makeApplyRefact x
98
- logm $ " applyHint:commands=" ++ show commands
99
- appliedFile <- applyRefactorings mpos commands file
100
- diff <- makeDiffResult file (T. pack appliedFile)
101
- logm $ " applyHint:diff=" ++ show diff
102
- return $ Right diff
103
-
104
- -- ---------------------------------------------------------------------
105
-
106
- makeApplyRefact :: [Suggestion ] -> [(String , [Refactoring R. SrcSpan ])]
107
- makeApplyRefact suggestions =
108
- map (\ (Suggestion i) -> (show i, ideaRefactoring i)) suggestions
109
-
110
- -- ---------------------------------------------------------------------
111
-
82
+ let optsf = " -o " ++ f
83
+ opts = case mpos of
84
+ Nothing -> optsf
85
+ Just (r,c) -> optsf ++ " --pos " ++ show r ++ " ," ++ show c
86
+ hlintOpts = [file, " --quiet" , " --refactor" , " --refactor-options=" ++ opts ]
87
+ runEitherT $ do
88
+ ideas <- runHlint file hlintOpts
89
+ liftIO $ logm $ " applyHint:ideas=" ++ show ideas
90
+ let commands = map (show &&& ideaRefactoring) ideas
91
+ appliedFile <- liftIO $ applyRefactorings mpos commands file
92
+ diff <- liftIO $ makeDiffResult file (T. pack appliedFile)
93
+ liftIO $ logm $ " applyHint:diff=" ++ show diff
94
+ return diff
95
+
96
+
97
+ runHlint :: FilePath -> [String ] -> EitherT String IO [Idea ]
98
+ runHlint file args =
99
+ do (flags,classify,hint) <- liftIO $ argsSettings args
100
+ res <- bimapEitherT showParseError id $ EitherT $ parseModuleEx flags file Nothing
101
+ pure $ applyHints classify hint [res]
102
+
103
+ showParseError :: Hlint. ParseError -> String
104
+ showParseError (Hlint. ParseError loc message content) = unlines [show loc, message, content]
112
105
113
106
makeDiffResult :: FilePath -> T. Text -> IO HieDiff
114
107
makeDiffResult orig new = do
0 commit comments