@@ -14,6 +14,7 @@ module Development.IDE.LSP.CodeAction
14
14
import Language.Haskell.LSP.Types
15
15
import Development.IDE.GHC.Compat
16
16
import Development.IDE.Core.Rules
17
+ import Development.IDE.Core.RuleTypes
17
18
import Development.IDE.Core.Shake
18
19
import Development.IDE.LSP.Server
19
20
import Development.IDE.Types.Location
@@ -24,6 +25,7 @@ import Language.Haskell.LSP.VFS
24
25
import Language.Haskell.LSP.Messages
25
26
import qualified Data.Rope.UTF16 as Rope
26
27
import Data.Aeson.Types (toJSON , fromJSON , Value (.. ), Result (.. ))
28
+ import Control.Monad.Trans.Maybe
27
29
import Data.Char
28
30
import Data.Maybe
29
31
import Data.List.Extra
@@ -53,19 +55,20 @@ codeLens
53
55
-> CodeLensParams
54
56
-> IO (List CodeLens )
55
57
codeLens _lsp ideState CodeLensParams {_textDocument= TextDocumentIdentifier uri} = do
56
- diag <- getDiagnostics ideState
57
58
case uriToFilePath' uri of
58
59
Just (toNormalizedFilePath -> filePath) -> do
60
+ _ <- runAction ideState $ runMaybeT $ useE TypeCheck filePath
61
+ diag <- getDiagnostics ideState
59
62
pure $ List
60
63
[ CodeLens _range (Just (Command title " typesignature.add" (Just $ List [toJSON edit]))) Nothing
61
64
| (dFile, dDiag@ Diagnostic {_range= _range@ Range {.. },.. }) <- diag
62
65
, dFile == filePath
63
- , (title, tedit) <- suggestTopLevelBinding False dDiag
66
+ , (title, tedit) <- suggestSignature False dDiag
64
67
, let edit = WorkspaceEdit (Just $ Map. singleton uri $ List tedit) Nothing
65
68
]
66
69
Nothing -> pure $ List []
67
70
68
- -- | Generate code lenses .
71
+ -- | Execute the "typesignature.add" command .
69
72
executeAddSignatureCommand
70
73
:: LSP. LspFuncs ()
71
74
-> IdeState
@@ -177,12 +180,12 @@ suggestAction contents diag@Diagnostic{_range=_range@Range{..},..}
177
180
extractFitNames = map (T. strip . head . T. splitOn " :: " )
178
181
in map proposeHoleFit $ nubOrd $ findSuggestedHoleFits _message
179
182
180
- | tlb@ [_] <- suggestTopLevelBinding True diag = tlb
183
+ | tlb@ [_] <- suggestSignature True diag = tlb
181
184
182
185
suggestAction _ _ = []
183
186
184
- suggestTopLevelBinding :: Bool -> Diagnostic -> [(T. Text , [TextEdit ])]
185
- suggestTopLevelBinding isQuickFix Diagnostic {_range= _range@ Range {.. },.. }
187
+ suggestSignature :: Bool -> Diagnostic -> [(T. Text , [TextEdit ])]
188
+ suggestSignature isQuickFix Diagnostic {_range= _range@ Range {.. },.. }
186
189
| " Top-level binding with no type signature" `T.isInfixOf` _message = let
187
190
filterNewlines = T. concat . T. lines
188
191
unifySpaces = T. unwords . T. words
@@ -192,7 +195,23 @@ suggestTopLevelBinding isQuickFix Diagnostic{_range=_range@Range{..},..}
192
195
title = if isQuickFix then " add signature: " <> signature else signature
193
196
action = TextEdit beforeLine $ signature <> " \n "
194
197
in [(title, [action])]
195
- suggestTopLevelBinding _ _ = []
198
+ suggestSignature isQuickFix Diagnostic {_range= _range@ Range {.. },.. }
199
+ | " Polymorphic local binding with no type signature" `T.isInfixOf` _message = let
200
+ filterNewlines = T. concat . T. lines
201
+ unifySpaces = T. unwords . T. words
202
+ signature = removeInitialForAll
203
+ $ T. takeWhile (\ x -> x/= ' *' && x/= ' •' )
204
+ $ T. strip $ unifySpaces $ last $ T. splitOn " type signature: " $ filterNewlines _message
205
+ startOfLine = Position (_line _start) (_character _start)
206
+ beforeLine = Range startOfLine startOfLine
207
+ title = if isQuickFix then " add signature: " <> signature else signature
208
+ action = TextEdit beforeLine $ signature <> " \n " <> T. replicate (_character _start) " "
209
+ in [(title, [action])]
210
+ where removeInitialForAll :: T. Text -> T. Text
211
+ removeInitialForAll (T. breakOnEnd " :: " -> (nm, ty))
212
+ | " forall" `T.isPrefixOf` ty = nm <> T. drop 2 (snd (T. breakOn " ." ty))
213
+ | otherwise = nm <> ty
214
+ suggestSignature _ _ = []
196
215
197
216
topOfHoleFitsMarker :: T. Text
198
217
topOfHoleFitsMarker =
0 commit comments