@@ -483,6 +483,7 @@ codeActionTests = testGroup "code actions"
483
483
, deleteUnusedDefinitionTests
484
484
, addInstanceConstraintTests
485
485
, addFunctionConstraintTests
486
+ , addTypeAnnotationsToLiteralsTest
486
487
]
487
488
488
489
codeLensesTests :: TestTree
@@ -1209,9 +1210,104 @@ deleteUnusedDefinitionTests = testGroup "delete unused definition action"
1209
1210
liftIO $ contentAfterAction @?= expectedResult
1210
1211
1211
1212
extractCodeAction docId actionPrefix = do
1212
- Just (CACodeAction action@ CodeAction { _title = actionTitle })
1213
- <- find (\ (CACodeAction CodeAction {_title= x}) -> actionPrefix `T.isPrefixOf` x)
1214
- <$> getCodeActions docId (R 0 0 0 0 )
1213
+ [action@ CodeAction { _title = actionTitle }] <- findCodeActionsByPrefix docId (R 0 0 0 0 ) [actionPrefix]
1214
+ return (action, actionTitle)
1215
+
1216
+ addTypeAnnotationsToLiteralsTest :: TestTree
1217
+ addTypeAnnotationsToLiteralsTest = testGroup " add type annotations to literals to satisfy contraints"
1218
+ [
1219
+ testSession " add default type to satisfy one contraint" $
1220
+ testFor
1221
+ (T. unlines [ " {-# OPTIONS_GHC -Wtype-defaults #-}"
1222
+ , " module A () where"
1223
+ , " "
1224
+ , " f = 1"
1225
+ ])
1226
+ [ (DsWarning , (3 , 4 ), " Defaulting the following constraint" ) ]
1227
+ " Add type annotation ‘Integer’ to ‘1’"
1228
+ (T. unlines [ " {-# OPTIONS_GHC -Wtype-defaults #-}"
1229
+ , " module A () where"
1230
+ , " "
1231
+ , " f = (1 :: Integer)"
1232
+ ])
1233
+
1234
+ , testSession " add default type to satisfy one contraint with duplicate literals" $
1235
+ testFor
1236
+ (T. unlines [ " {-# OPTIONS_GHC -Wtype-defaults #-}"
1237
+ , " {-# LANGUAGE OverloadedStrings #-}"
1238
+ , " module A () where"
1239
+ , " "
1240
+ , " import Debug.Trace"
1241
+ , " "
1242
+ , " f = seq \" debug\" traceShow \" debug\" "
1243
+ ])
1244
+ [ (DsWarning , (6 , 8 ), " Defaulting the following constraint" )
1245
+ , (DsWarning , (6 , 16 ), " Defaulting the following constraint" )
1246
+ ]
1247
+ " Add type annotation ‘[Char]’ to ‘\" debug\" ’"
1248
+ (T. unlines [ " {-# OPTIONS_GHC -Wtype-defaults #-}"
1249
+ , " {-# LANGUAGE OverloadedStrings #-}"
1250
+ , " module A () where"
1251
+ , " "
1252
+ , " import Debug.Trace"
1253
+ , " "
1254
+ , " f = seq (\" debug\" :: [Char]) traceShow \" debug\" "
1255
+ ])
1256
+ , testSession " add default type to satisfy two contraints" $
1257
+ testFor
1258
+ (T. unlines [ " {-# OPTIONS_GHC -Wtype-defaults #-}"
1259
+ , " {-# LANGUAGE OverloadedStrings #-}"
1260
+ , " module A () where"
1261
+ , " "
1262
+ , " import Debug.Trace"
1263
+ , " "
1264
+ , " f a = traceShow \" debug\" a"
1265
+ ])
1266
+ [ (DsWarning , (6 , 6 ), " Defaulting the following constraint" ) ]
1267
+ " Add type annotation ‘[Char]’ to ‘\" debug\" ’"
1268
+ (T. unlines [ " {-# OPTIONS_GHC -Wtype-defaults #-}"
1269
+ , " {-# LANGUAGE OverloadedStrings #-}"
1270
+ , " module A () where"
1271
+ , " "
1272
+ , " import Debug.Trace"
1273
+ , " "
1274
+ , " f a = traceShow (\" debug\" :: [Char]) a"
1275
+ ])
1276
+ , testSession " add default type to satisfy two contraints with duplicate literals" $
1277
+ testFor
1278
+ (T. unlines [ " {-# OPTIONS_GHC -Wtype-defaults #-}"
1279
+ , " {-# LANGUAGE OverloadedStrings #-}"
1280
+ , " module A () where"
1281
+ , " "
1282
+ , " import Debug.Trace"
1283
+ , " "
1284
+ , " f = seq (\" debug\" :: [Char]) (seq (\" debug\" :: [Char]) (traceShow \" debug\" ))"
1285
+ ])
1286
+ [ (DsWarning , (6 , 54 ), " Defaulting the following constraint" ) ]
1287
+ " Add type annotation ‘[Char]’ to ‘\" debug\" ’"
1288
+ (T. unlines [ " {-# OPTIONS_GHC -Wtype-defaults #-}"
1289
+ , " {-# LANGUAGE OverloadedStrings #-}"
1290
+ , " module A () where"
1291
+ , " "
1292
+ , " import Debug.Trace"
1293
+ , " "
1294
+ , " f = seq (\" debug\" :: [Char]) (seq (\" debug\" :: [Char]) (traceShow (\" debug\" :: [Char])))"
1295
+ ])
1296
+ ]
1297
+ where
1298
+ testFor source diag expectedTitle expectedResult = do
1299
+ docId <- createDoc " A.hs" " haskell" source
1300
+ expectDiagnostics [ (" A.hs" , diag) ]
1301
+
1302
+ (action, title) <- extractCodeAction docId " Add type annotation"
1303
+
1304
+ liftIO $ title @?= expectedTitle
1305
+ executeCodeAction action
1306
+ contentAfterAction <- documentContents docId
1307
+ liftIO $ contentAfterAction @?= expectedResult
1308
+
1309
+ extractCodeAction docId actionPrefix = do
1310
+ [action@ CodeAction { _title = actionTitle }] <- findCodeActionsByPrefix docId (R 0 0 0 0 ) [actionPrefix]
1215
1311
return (action, actionTitle)
1216
1312
1217
1313
@@ -2684,19 +2780,25 @@ openTestDataDoc path = do
2684
2780
createDoc path " haskell" source
2685
2781
2686
2782
findCodeActions :: TextDocumentIdentifier -> Range -> [T. Text ] -> Session [CodeAction ]
2687
- findCodeActions doc range expectedTitles = do
2783
+ findCodeActions = findCodeActions' (==) " is not a superset of"
2784
+
2785
+ findCodeActionsByPrefix :: TextDocumentIdentifier -> Range -> [T. Text ] -> Session [CodeAction ]
2786
+ findCodeActionsByPrefix = findCodeActions' T. isPrefixOf " is not prefix of"
2787
+
2788
+ findCodeActions' :: (T. Text -> T. Text -> Bool ) -> String -> TextDocumentIdentifier -> Range -> [T. Text ] -> Session [CodeAction ]
2789
+ findCodeActions' op errMsg doc range expectedTitles = do
2688
2790
actions <- getCodeActions doc range
2689
2791
let matches = sequence
2690
2792
[ listToMaybe
2691
2793
[ action
2692
2794
| CACodeAction action@ CodeAction { _title = actionTitle } <- actions
2693
- , actionTitle == expectedTitle ]
2795
+ , expectedTitle `op` actionTitle ]
2694
2796
| expectedTitle <- expectedTitles]
2695
2797
let msg = show
2696
2798
[ actionTitle
2697
2799
| CACodeAction CodeAction { _title = actionTitle } <- actions
2698
2800
]
2699
- ++ " is not a superset of "
2801
+ ++ " " <> errMsg <> " "
2700
2802
++ show expectedTitles
2701
2803
liftIO $ case matches of
2702
2804
Nothing -> assertFailure msg
0 commit comments