Skip to content

Commit e2bf01b

Browse files
authored
Fix completion snippets on DuplicateRecordFields (#1360)
* Use par_lbl rather than gre_name for field selectors * Add test
1 parent 32e1fad commit e2bf01b

File tree

2 files changed

+31
-15
lines changed

2 files changed

+31
-15
lines changed

Diff for: ghcide/src/Development/IDE/Plugin/Completions/Logic.hs

+10-15
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,13 @@ mkAdditionalEditsCommand :: PluginId -> ExtendImport -> IO Command
206206
mkAdditionalEditsCommand pId edits =
207207
mkLspCommand pId (CommandId extendImportCommandId) "extend import" (Just [toJSON edits])
208208

209-
mkNameCompItem :: Uri -> Maybe T.Text -> Name -> ModuleName -> Maybe Type -> Maybe Backtick -> SpanDoc -> Maybe (LImportDecl GhcPs) -> CompItem
209+
mkNameCompItem :: Uri -> Maybe T.Text -> OccName -> ModuleName -> Maybe Type -> Maybe Backtick -> SpanDoc -> Maybe (LImportDecl GhcPs) -> CompItem
210210
mkNameCompItem doc thingParent origName origMod thingType isInfix docs !imp = CI {..}
211211
where
212-
compKind = occNameToComKind typeText $ occName origName
212+
compKind = occNameToComKind typeText origName
213213
importedFrom = Right $ showModName origMod
214-
isTypeCompl = isTcOcc $ occName origName
215-
label = showGhc origName
214+
isTypeCompl = isTcOcc origName
215+
label = stripPrefix $ showGhc origName
216216
insertText = case isInfix of
217217
Nothing -> case getArgText <$> thingType of
218218
Nothing -> label
@@ -345,10 +345,10 @@ cacheDataProducer uri packageState curMod globalEnv inScopeEnv limports deps = d
345345
toCompItem :: Parent -> Module -> ModuleName -> Name -> Maybe (LImportDecl GhcPs) -> IO [CompItem]
346346
toCompItem par m mn n imp' = do
347347
docs <- getDocumentationTryGhc packageState curMod deps n
348-
let mbParent = case par of
349-
NoParent -> Nothing
350-
ParentIs n -> Just (showNameWithoutUniques n)
351-
FldParent n _ -> Just (showNameWithoutUniques n)
348+
let (mbParent, originName) = case par of
349+
NoParent -> (Nothing, nameOccName n)
350+
ParentIs n' -> (Just $ showNameWithoutUniques n', nameOccName n)
351+
FldParent n' lbl -> (Just $ showNameWithoutUniques n', maybe (nameOccName n) mkVarOccFS lbl)
352352
tys <- catchSrcErrors (hsc_dflags packageState) "completion" $ do
353353
name' <- lookupName packageState m n
354354
return ( name' >>= safeTyThingType
@@ -361,7 +361,7 @@ cacheDataProducer uri packageState curMod globalEnv inScopeEnv limports deps = d
361361
[mkRecordSnippetCompItem uri mbParent ctxStr flds (ppr mn) docs imp']
362362
_ -> []
363363

364-
return $ mkNameCompItem uri mbParent n mn ty Nothing docs imp'
364+
return $ mkNameCompItem uri mbParent originName mn ty Nothing docs imp'
365365
: recordCompls
366366

367367
(unquals,quals) <- getCompls rdrElts
@@ -588,7 +588,7 @@ getCompletions plId ideOpts CC {allModNamesAsNS, unqualCompls, qualCompls, impor
588588
-> return $ filtPragmaCompls (pragmaSuffix fullLine)
589589
| otherwise -> do
590590
let uniqueFiltCompls = nubOrdOn insertText filtCompls
591-
compls <- mapM (mkCompl plId ideOpts . stripAutoGenerated) uniqueFiltCompls
591+
compls <- mapM (mkCompl plId ideOpts) uniqueFiltCompls
592592
return $ filtModNameCompls
593593
++ filtKeywordCompls
594594
++ map ( toggleSnippets caps withSnippets) compls
@@ -657,16 +657,11 @@ openingBacktick line prefixModule prefixText Position { _character }
657657

658658
-- | Under certain circumstance GHC generates some extra stuff that we
659659
-- don't want in the autocompleted symbols
660-
stripAutoGenerated :: CompItem -> CompItem
661-
stripAutoGenerated ci =
662-
ci {label = stripPrefix (label ci)}
663660
{- When e.g. DuplicateRecordFields is enabled, compiler generates
664661
names like "$sel:accessor:One" and "$sel:accessor:Two" to disambiguate record selectors
665662
https://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields/DuplicateRecordFields#Implementation
666663
-}
667-
668664
-- TODO: Turn this into an alex lexer that discards prefixes as if they were whitespace.
669-
670665
stripPrefix :: T.Text -> T.Text
671666
stripPrefix name = T.takeWhile (/=':') $ go prefixes
672667
where

Diff for: ghcide/test/exe/Main.hs

+21
Original file line numberDiff line numberDiff line change
@@ -3948,6 +3948,27 @@ otherCompletionTests = [
39483948
(Position 3 11)
39493949
[("Integer", CiStruct, "Integer ", True, True, Nothing)],
39503950

3951+
testSession "duplicate record fields" $ do
3952+
void $
3953+
createDoc "B.hs" "haskell" $
3954+
T.unlines
3955+
[ "{-# LANGUAGE DuplicateRecordFields #-}",
3956+
"module B where",
3957+
"newtype Foo = Foo { member :: () }",
3958+
"newtype Bar = Bar { member :: () }"
3959+
]
3960+
docA <-
3961+
createDoc "A.hs" "haskell" $
3962+
T.unlines
3963+
[ "module A where",
3964+
"import B",
3965+
"memb"
3966+
]
3967+
_ <- waitForDiagnostics
3968+
compls <- getCompletions docA $ Position 2 4
3969+
let compls' = [txt | CompletionItem {_insertText = Just txt, ..} <- compls, _label == "member"]
3970+
liftIO $ compls' @?= ["member ${1:Foo}", "member ${1:Bar}"],
3971+
39513972
testSessionWait "maxCompletions" $ do
39523973
doc <- createDoc "A.hs" "haskell" $ T.unlines
39533974
[ "{-# OPTIONS_GHC -Wunused-binds #-}",

0 commit comments

Comments
 (0)