Skip to content

Commit 6c9d44f

Browse files
authored
Makes local record field completion respects the fields sharing one single type signature (#2439)
* Correct the logic of retrieving field info from ParsedModule. * No concatMap required * Adds test case
1 parent 6c69e9d commit 6c9d44f

File tree

4 files changed

+25
-7
lines changed

4 files changed

+25
-7
lines changed

ghcide/src/Development/IDE/Plugin/Completions/Logic.hs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import Data.List.Extra as List hiding
2020
import qualified Data.Map as Map
2121

2222
import Data.Maybe (fromMaybe, isJust,
23-
listToMaybe,
2423
mapMaybe)
2524
import qualified Data.Text as T
2625
import qualified Text.Fuzzy.Parallel as Fuzzy
@@ -480,7 +479,7 @@ findRecordCompl uri pmod mn DataDecl {tcdLName, tcdDataDefn} = result
480479
(showGhc . unLoc $ con_name) field_labels mn doc Nothing
481480
| ConDeclH98{..} <- unLoc <$> dd_cons tcdDataDefn
482481
, Just con_details <- [getFlds con_args]
483-
, let field_names = mapMaybe extract con_details
482+
, let field_names = concatMap extract con_details
484483
, let field_labels = showGhc . unLoc <$> field_names
485484
, (not . List.null) field_labels
486485
]
@@ -493,11 +492,18 @@ findRecordCompl uri pmod mn DataDecl {tcdLName, tcdDataDefn} = result
493492
_ -> Nothing
494493

495494
extract ConDeclField{..}
496-
-- TODO: Why is cd_fld_names a list?
497-
| Just fld_name <- rdrNameFieldOcc . unLoc <$> listToMaybe cd_fld_names = Just fld_name
498-
| otherwise = Nothing
495+
-- NOTE: 'cd_fld_names' is grouped so that the fields
496+
-- sharing the same type declaration to fit in the same group; e.g.
497+
--
498+
-- @
499+
-- data Foo = Foo {arg1, arg2 :: Int, arg3 :: Int, arg4 :: Bool}
500+
-- @
501+
--
502+
-- is encoded as @[[arg1, arg2], [arg3], [arg4]]@
503+
-- Hence, we must concat nested arguments into one to get all the fields.
504+
= map (rdrNameFieldOcc . unLoc) cd_fld_names
499505
-- XConDeclField
500-
extract _ = Nothing
506+
extract _ = []
501507
findRecordCompl _ _ _ _ = []
502508

503509
ppr :: Outputable a => a -> T.Text

test/functional/Completion.hs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ tests = testGroup "completions" [
9494
liftIO $ do
9595
item ^. label @?= "accessor"
9696
item ^. kind @?= Just CiFunction
97-
9897
, testCase "have implicit foralls on basic polymorphic types" $ runSession hlsCommand fullCaps "test/testdata/completion" $ do
9998
doc <- openDoc "Completion.hs" "haskell"
10099

@@ -261,6 +260,17 @@ snippetTests = testGroup "snippets" [
261260
doc <- openDoc "Completion.hs" "haskell"
262261

263262
checkNoSnippets doc
263+
, testCase "works for record fields sharing the single signature" $ runSession hlsCommand fullCaps "test/testdata/completion" $ do
264+
doc <- openDoc "FieldsSharingSignature.hs" "haskell"
265+
266+
let te = TextEdit (Range (Position 1 0) (Position 1 2)) "MkF"
267+
_ <- applyEdit doc te
268+
269+
compls <- getCompletions doc (Position 1 6)
270+
let item = head $ filter (\c -> (c ^. label == "MkFoo") && maybe False ("MkFoo {" `T.isPrefixOf`) (c ^. insertText)) compls
271+
liftIO $ do
272+
item ^. insertTextFormat @?= Just Snippet
273+
item ^. insertText @?= Just "MkFoo {arg1=${1:_arg1}, arg2=${2:_arg2}, arg3=${3:_arg3}, arg4=${4:_arg4}, arg5=${5:_arg5}}"
264274
]
265275
where
266276
checkNoSnippets doc = do
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
data Foo = MkFoo { arg1, arg2, arg3 :: Int, arg4 :: Int, arg5 :: Double }

test/testdata/completion/hie.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ cradle:
44
- "Completion"
55
- "Context"
66
- "DupRecFields"
7+
- "FieldsSharingSignature"

0 commit comments

Comments
 (0)