diff --git a/ghcide/src/Development/IDE/Plugin/CodeAction.hs b/ghcide/src/Development/IDE/Plugin/CodeAction.hs index 75a9aa1024..9aa016813e 100644 --- a/ghcide/src/Development/IDE/Plugin/CodeAction.hs +++ b/ghcide/src/Development/IDE/Plugin/CodeAction.hs @@ -768,7 +768,7 @@ suggestExtendImport exportsMap (L _ HsModule {hsmodImports}) Diagnostic{_range=_ | otherwise = [] where suggestions decls binding mod srcspan - | range <- case [ x | (x,"") <- readSrcSpan (T.unpack srcspan)] of + | range <- case [ x | (x,"") <- readSrcSpan (T.unpack srcspan)] of [s] -> let x = realSrcSpanToRange s in x{_end = (_end x){_character = succ (_character (_end x))}} _ -> error "bug in srcspan parser", @@ -783,8 +783,13 @@ suggestExtendImport exportsMap (L _ HsModule {hsmodImports}) Diagnostic{_range=_ | otherwise = [] lookupExportMap binding mod | Just match <- Map.lookup binding (getExportsMap exportsMap) - , [ident] <- filter (\ident -> moduleNameText ident == mod) (Set.toList match) - = Just ident + -- Only for the situation that data constructor name is same as type constructor name, + -- let ident with parent be in front of the one without. + , sortedMatch <- sortBy (\ident1 ident2 -> parent ident2 `compare` parent ident1) (Set.toList match) + , idents <- filter (\ident -> moduleNameText ident == mod) sortedMatch + , (not . null) idents -- Ensure fallback while `idents` is empty + , ident <- head idents + = Just ident -- fallback to using GHC suggestion even though it is not always correct | otherwise diff --git a/ghcide/test/exe/Main.hs b/ghcide/test/exe/Main.hs index d7dda5dbba..94529222ed 100644 --- a/ghcide/test/exe/Main.hs +++ b/ghcide/test/exe/Main.hs @@ -1408,6 +1408,25 @@ extendImportTests = testGroup "extend import actions" , "import A (pattern Some)" , "k (Some x) = x" ]) + , testSession "type constructor name same as data constructor name" $ template + [("ModuleA.hs", T.unlines + [ "module ModuleA where" + , "newtype Foo = Foo Int" + ])] + ("ModuleB.hs", T.unlines + [ "module ModuleB where" + , "import ModuleA(Foo)" + , "f :: Foo" + , "f = Foo 1" + ]) + (Range (Position 3 4) (Position 3 6)) + ["Add Foo(Foo) to the import list of ModuleA"] + (T.unlines + [ "module ModuleB where" + , "import ModuleA(Foo (Foo))" + , "f :: Foo" + , "f = Foo 1" + ]) ] where codeActionTitle CodeAction{_title=x} = x