Skip to content

Commit e9e8e71

Browse files
yoshitsugujneira
andauthored
Suggest hiding imports when local definition exists (#2320)
Co-authored-by: Javier Neira <atreyu.bbb@gmail.com>
1 parent 6e297c5 commit e9e8e71

File tree

6 files changed

+69
-11
lines changed

6 files changed

+69
-11
lines changed

ghcide/src/Development/IDE/Plugin/CodeAction.hs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -882,8 +882,9 @@ suggestImportDisambiguation df (Just txt) ps@(L _ HsModule {hsmodImports}) fileC
882882
"Ambiguous occurrence ‘([^’]+)’"
883883
, Just modules <-
884884
map last
885-
<$> allMatchRegexUnifySpaces _message "imported from ‘([^’]+)’" =
886-
suggestions ambiguous modules
885+
<$> allMatchRegexUnifySpaces _message "imported from ‘([^’]+)’"
886+
, local <- matchRegexUnifySpaces _message "defined at .+:[0-9]+:[0-9]+" =
887+
suggestions ambiguous modules (isJust local)
887888
| otherwise = []
888889
where
889890
locDic =
@@ -906,16 +907,16 @@ suggestImportDisambiguation df (Just txt) ps@(L _ HsModule {hsmodImports}) fileC
906907
-- > removeAllDuplicates [1, 1, 2, 3, 2] = [3]
907908
removeAllDuplicates = map head . filter ((==1) <$> length) . group . sort
908909
hasDuplicate xs = length xs /= length (S.fromList xs)
909-
suggestions symbol mods
910+
suggestions symbol mods local
910911
| hasDuplicate mods = case mapM toModuleTarget (removeAllDuplicates mods) of
911-
Just targets -> suggestionsImpl symbol (map (, []) targets)
912+
Just targets -> suggestionsImpl symbol (map (, []) targets) local
912913
Nothing -> []
913914
| otherwise = case mapM toModuleTarget mods of
914-
Just targets -> suggestionsImpl symbol (oneAndOthers targets)
915+
Just targets -> suggestionsImpl symbol (oneAndOthers targets) local
915916
Nothing -> []
916-
suggestionsImpl symbol targetsWithRestImports =
917+
suggestionsImpl symbol targetsWithRestImports local =
917918
sortOn fst
918-
[ ( renderUniquify mode modNameText symbol
919+
[ ( renderUniquify mode modNameText symbol False
919920
, disambiguateSymbol ps fileContents diag symbol mode
920921
)
921922
| (modTarget, restImports) <- targetsWithRestImports
@@ -942,10 +943,14 @@ suggestImportDisambiguation df (Just txt) ps@(L _ HsModule {hsmodImports}) fileC
942943
_ -> False
943944
]
944945
++ [HideOthers restImports | not (null restImports)]
946+
] ++ [ ( renderUniquify mode T.empty symbol True
947+
, disambiguateSymbol ps fileContents diag symbol mode
948+
) | local, not (null targetsWithRestImports)
949+
, let mode = HideOthers (uncurry (:) (head targetsWithRestImports))
945950
]
946-
renderUniquify HideOthers {} modName symbol =
947-
"Use " <> modName <> " for " <> symbol <> ", hiding other imports"
948-
renderUniquify (ToQualified _ qual) _ symbol =
951+
renderUniquify HideOthers {} modName symbol local =
952+
"Use " <> (if local then "local definition" else modName) <> " for " <> symbol <> ", hiding other imports"
953+
renderUniquify (ToQualified _ qual) _ symbol _ =
949954
"Replace with qualified: "
950955
<> T.pack (moduleNameString qual)
951956
<> "."
@@ -1005,7 +1010,6 @@ disambiguateSymbol pm fileContents Diagnostic {..} (T.unpack -> symbol) = \case
10051010
liftParseAST @RdrName df $
10061011
prettyPrint $ L (mkGeneralSrcSpan "") rdr
10071012
]
1008-
10091013
findImportDeclByRange :: [LImportDecl GhcPs] -> Range -> Maybe (LImportDecl GhcPs)
10101014
findImportDeclByRange xs range = find (\(L l _)-> srcSpanToRange l == Just range) xs
10111015

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module HideFunctionWithoutLocal where
2+
3+
import AVec (fromList)
4+
import BVec (fromList)
5+
import CVec hiding ((++), cons)
6+
import DVec hiding ((++), cons, snoc)
7+
import EVec as E hiding ((++))
8+
import Prelude hiding ((++))
9+
10+
theOp = (++)
11+
12+
data Vec a
13+
14+
(++) = undefined
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module HideFunctionWithoutLocal where
2+
3+
import AVec (fromList)
4+
import BVec (fromList, (++))
5+
import CVec hiding (cons)
6+
import DVec hiding (cons, snoc)
7+
import EVec as E
8+
9+
theOp = (++)
10+
11+
data Vec a
12+
13+
(++) = undefined
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module HidePreludeLocalInfix where
2+
import Prelude hiding ((++))
3+
4+
infixed xs ys = xs ++ ys
5+
6+
data Vec a
7+
8+
(++) :: Vec a -> Vec a -> Vec a
9+
(++) = undefined
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module HidePreludeLocalInfix where
2+
3+
infixed xs ys = xs ++ ys
4+
5+
data Vec a
6+
7+
(++) :: Vec a -> Vec a -> Vec a
8+
(++) = undefined

ghcide/test/exe/Main.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,10 +1798,20 @@ suggestImportDisambiguationTests = testGroup "suggest import disambiguation acti
17981798
compareHideFunctionTo [(8,9),(10,8)]
17991799
"Use EVec for ++, hiding other imports"
18001800
"HideFunction.expected.append.E.hs"
1801+
, testCase "Hide functions without local" $
1802+
compareTwo
1803+
"HideFunctionWithoutLocal.hs" [(8,8)]
1804+
"Use local definition for ++, hiding other imports"
1805+
"HideFunctionWithoutLocal.expected.hs"
18011806
, testCase "Prelude" $
18021807
compareHideFunctionTo [(8,9),(10,8)]
18031808
"Use Prelude for ++, hiding other imports"
18041809
"HideFunction.expected.append.Prelude.hs"
1810+
, testCase "Prelude and local definition, infix" $
1811+
compareTwo
1812+
"HidePreludeLocalInfix.hs" [(2,19)]
1813+
"Use local definition for ++, hiding other imports"
1814+
"HidePreludeLocalInfix.expected.hs"
18051815
, testCase "AVec, indented" $
18061816
compareTwo "HidePreludeIndented.hs" [(3,8)]
18071817
"Use AVec for ++, hiding other imports"

0 commit comments

Comments
 (0)