Skip to content

Fix completion for record dot syntax when record isn't known #4619

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions ghcide-test/exe/CompletionTests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import Test.Hls.Util
import Test.Tasty
import Test.Tasty.HUnit


tests :: TestTree
tests
= testGroup "completion"
Expand Down Expand Up @@ -61,6 +60,7 @@ completionTest :: HasCallStack => String -> [T.Text] -> Position -> [(T.Text, Co
completionTest name src pos expected = testSessionSingleFile name "A.hs" (T.unlines src) $ do
docId <- openDoc "A.hs" "haskell"
_ <- waitForDiagnostics

compls <- getAndResolveCompletions docId pos
let compls' = [ (_label, _kind, _insertText, _additionalTextEdits) | CompletionItem{..} <- compls]
let emptyToMaybe x = if T.null x then Nothing else Just x
Expand Down Expand Up @@ -211,7 +211,38 @@ localCompletionTests = [

compls <- getCompletions doc (Position 0 15)
liftIO $ filter ("AAA" `T.isPrefixOf`) (mapMaybe _insertText compls) @?= ["AAAAA"]
pure ()
pure (),
completionTest
"polymorphic record dot completion"
[ "{-# LANGUAGE OverloadedRecordDot #-}"
, "module A () where"
, "data Record = Record"
, " { field1 :: Int"
, " , field2 :: Int"
, " }"
, -- Without the following, this file doesn't trigger any diagnostics, so completionTest waits forever
"triggerDiag :: UnknownType"
, "foo record = record.f"
]
(Position 7 21)
[("field1", CompletionItemKind_Function, "field1", True, False, Nothing)
,("field2", CompletionItemKind_Function, "field2", True, False, Nothing)
],
completionTest
"qualified polymorphic record dot completion"
[ "{-# LANGUAGE OverloadedRecordDot #-}"
, "module A () where"
, "data Record = Record"
, " { field1 :: Int"
, " , field2 :: Int"
, " }"
, "someValue = undefined"
, "foo = A.someValue.f"
]
(Position 7 19)
[("field1", CompletionItemKind_Function, "field1", True, False, Nothing)
,("field2", CompletionItemKind_Function, "field2", True, False, Nothing)
]
]

nonLocalCompletionTests :: [TestTree]
Expand Down
4 changes: 3 additions & 1 deletion ghcide/src/Development/IDE/Plugin/Completions/Logic.hs
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,9 @@ getCompletionPrefixFromRope pos@(Position l c) ropetext =
[] -> Nothing
(x:xs) -> do
let modParts = reverse $ filter (not .T.null) xs
modName = T.intercalate "." modParts
-- Must check the prefix is a valid module name, else record dot accesses treat
-- the record name as a qualName for search and generated imports
modName = if all (isUpper . T.head) modParts then T.intercalate "." modParts else ""
return $ PosPrefixInfo { fullLine = curLine, prefixScope = modName, prefixText = x, cursorPos = pos }

completionPrefixPos :: PosPrefixInfo -> Position
Expand Down
Loading