@@ -13,8 +13,10 @@ import Control.Monad.Trans.Class (lift)
13
13
import Control.Monad.Trans.Except (ExceptT , throwE )
14
14
import Control.Monad.Trans.Maybe
15
15
import Data.Aeson
16
+ import Data.Bifunctor (second )
16
17
import Data.Either.Extra (rights )
17
18
import Data.List
19
+ import Data.List.Extra (nubOrdOn )
18
20
import qualified Data.Map.Strict as Map
19
21
import Data.Maybe (isNothing , listToMaybe ,
20
22
mapMaybe )
@@ -113,30 +115,31 @@ codeAction recorder state plId (CodeActionParams _ _ docId _ context) = pluginRe
113
115
logWith recorder Info (LogImplementedMethods cls implemented)
114
116
pure
115
117
$ concatMap mkAction
116
- $ fmap (filter (\ (bind, _) -> bind `notElem` implemented))
117
- $ minDefToMethodGroups range sigs
118
- $ classMinimalDef cls
118
+ $ nubOrdOn snd
119
+ $ filter ((/=) mempty . snd )
120
+ $ fmap (second (filter (\ (bind, _) -> bind `notElem` implemented)))
121
+ $ mkMethodGroups range sigs cls
119
122
where
120
123
range = diag ^. J. range
121
124
122
- mkAction :: [(T. Text , T. Text )] -> [Command |? CodeAction ]
123
- mkAction methodGroup
125
+ mkMethodGroups :: Range -> [InstanceBindTypeSig ] -> Class -> [MethodGroup ]
126
+ mkMethodGroups range sigs cls = minimalDef <> [allClassMethods]
127
+ where
128
+ minimalDef = minDefToMethodGroups range sigs $ classMinimalDef cls
129
+ allClassMethods = (" all missing methods" , makeMethodDefinitions range sigs)
130
+
131
+ mkAction :: MethodGroup -> [Command |? CodeAction ]
132
+ mkAction (name, methods)
124
133
= [ mkCodeAction title
125
134
$ mkLspCommand plId codeActionCommandId title
126
- (Just $ mkCmdParams methodGroup False )
135
+ (Just $ mkCmdParams methods False )
127
136
, mkCodeAction titleWithSig
128
137
$ mkLspCommand plId codeActionCommandId titleWithSig
129
- (Just $ mkCmdParams methodGroup True )
138
+ (Just $ mkCmdParams methods True )
130
139
]
131
140
where
132
- title = mkTitle $ fst <$> methodGroup
133
- titleWithSig = mkTitleWithSig $ fst <$> methodGroup
134
-
135
- mkTitle methodGroup
136
- = " Add placeholders for "
137
- <> mconcat (intersperse " , " (fmap (\ m -> " '" <> m <> " '" ) methodGroup))
138
-
139
- mkTitleWithSig methodGroup = mkTitle methodGroup <> " with signature(s)"
141
+ title = " Add placeholders for " <> name
142
+ titleWithSig = title <> " with signature(s)"
140
143
141
144
mkCmdParams methodGroup withSig =
142
145
[toJSON (AddMinimalMethodsParams uri range (List methodGroup) withSig)]
@@ -211,15 +214,37 @@ isInstanceValBind :: ContextInfo -> Bool
211
214
isInstanceValBind (ValBind InstanceBind _ _) = True
212
215
isInstanceValBind _ = False
213
216
214
- -- Return (name text, signature text)
215
- minDefToMethodGroups :: Range -> [InstanceBindTypeSig ] -> BooleanFormula Name -> [[(T. Text , T. Text )]]
216
- minDefToMethodGroups range sigs = go
217
+ type MethodSignature = T. Text
218
+ type MethodName = T. Text
219
+ type MethodDefinition = (MethodName , MethodSignature )
220
+ type MethodGroup = (T. Text , [MethodDefinition ])
221
+
222
+ makeMethodDefinition :: InstanceBindTypeSig -> MethodDefinition
223
+ makeMethodDefinition sig = (name, signature)
224
+ where
225
+ name = T. drop (T. length bindingPrefix) (printOutputable (bindName sig))
226
+ signature = bindRendered sig
227
+
228
+ makeMethodDefinitions :: Range -> [InstanceBindTypeSig ] -> [MethodDefinition ]
229
+ makeMethodDefinitions range sigs =
230
+ [ makeMethodDefinition sig
231
+ | sig <- sigs
232
+ , inRange range (getSrcSpan $ bindName sig)
233
+ ]
234
+
235
+ signatureToName :: InstanceBindTypeSig -> T. Text
236
+ signatureToName sig = T. drop (T. length bindingPrefix) (printOutputable (bindName sig))
237
+
238
+ -- Return [groupName text, [(methodName text, signature text)]]
239
+ minDefToMethodGroups :: Range -> [InstanceBindTypeSig ] -> BooleanFormula Name -> [MethodGroup ]
240
+ minDefToMethodGroups range sigs minDef = makeMethodGroup <$> go minDef
217
241
where
218
- go ( Var mn) = [[ ( T. pack . occNameString . occName $ mn, bindRendered sig)
219
- | sig <- sigs
220
- , inRange range (getSrcSpan $ bindName sig )
221
- , printOutputable mn == T. drop ( T. length bindingPrefix) (printOutputable (bindName sig))
222
- ]]
242
+ makeMethodGroup methodDefinitions =
243
+ let name = mconcat $ intersperse " , " $ ( \ x -> " ' " <> x <> " ' " ) . fst <$> methodDefinitions
244
+ in (name, methodDefinitions )
245
+
246
+ go ( Var mn) = pure $ makeMethodDefinitions range $ filter ( (==) (printOutputable mn) . signatureToName) sigs
223
247
go (Or ms) = concatMap (go . unLoc) ms
224
248
go (And ms) = foldr (liftA2 (<>) ) [[] ] (fmap (go . unLoc) ms)
225
249
go (Parens m) = go (unLoc m)
250
+
0 commit comments