Skip to content
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

Import disambiguation: Corrects handling of fully-applied and one-sided sectioned operators in qualifying strategy #1294

Merged
merged 5 commits into from
Feb 3, 2021
Merged
Show file tree
Hide file tree
Changes from 2 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
34 changes: 23 additions & 11 deletions ghcide/src/Development/IDE/Plugin/CodeAction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ suggestAction packageExports ideOptions parsedModule text df annSource diag =
[ suggestSignature True diag
, rewrite df annSource $ \_ ps -> suggestExtendImport packageExports ps diag
, rewrite df annSource $ \df ps ->
suggestImportDisambiguation df ps diag
suggestImportDisambiguation df text ps diag
, suggestFillTypeWildcard diag
, suggestFixConstructorImport text diag
, suggestModuleTypo diag
Expand Down Expand Up @@ -705,8 +705,12 @@ suggestExtendImport exportsMap (L _ HsModule {hsmodImports}) Diagnostic{_range=_
, parent = Nothing
, isDatacon = False}

data HidingMode = HideOthers [ModuleTarget]
| ToQualified ModuleName
data HidingMode
= HideOthers [ModuleTarget]
| ToQualified
Bool
-- ^ Parenthesised?
ModuleName
deriving (Show)

data ModuleTarget
Expand All @@ -730,10 +734,11 @@ isPreludeImplicit = xopt Lang.ImplicitPrelude
-- | Suggests disambiguation for ambiguous symbols.
suggestImportDisambiguation ::
DynFlags ->
Maybe T.Text ->
ParsedSource ->
Diagnostic ->
[(T.Text, [Rewrite])]
suggestImportDisambiguation df ps@(L _ HsModule {hsmodImports}) diag@Diagnostic {..}
suggestImportDisambiguation df (Just txt) ps@(L _ HsModule {hsmodImports}) diag@Diagnostic {..}
| Just [ambiguous] <-
matchRegexUnifySpaces
_message
Expand All @@ -759,7 +764,8 @@ suggestImportDisambiguation df ps@(L _ HsModule {hsmodImports}) diag@Diagnostic
= Just $ ImplicitPrelude $
maybe [] NE.toList (Map.lookup "Prelude" locDic)
toModuleTarget mName = ExistingImp <$> Map.lookup mName locDic

parensed =
"(" `T.isPrefixOf` T.strip (textInRange _range txt)
suggestions symbol mods
| Just targets <- mapM toModuleTarget mods =
sortOn fst
Expand All @@ -771,12 +777,12 @@ suggestImportDisambiguation df ps@(L _ HsModule {hsmodImports}) diag@Diagnostic
modNameText = T.pack $ moduleNameString modName
, mode <-
HideOthers restImports :
[ ToQualified qual
[ ToQualified parensed qual
| ExistingImp imps <- [modTarget]
, L _ qual <- nubOrd $ mapMaybe (ideclAs . unLoc)
$ NE.toList imps
]
++ [ToQualified modName
++ [ToQualified parensed modName
| any (occursUnqualified symbol . unLoc)
(targetImports modTarget)
|| case modTarget of
Expand All @@ -787,11 +793,12 @@ suggestImportDisambiguation df ps@(L _ HsModule {hsmodImports}) diag@Diagnostic
| otherwise = []
renderUniquify HideOthers {} modName symbol =
"Use " <> modName <> " for " <> symbol <> ", hiding other imports"
renderUniquify (ToQualified qual) _ symbol =
renderUniquify (ToQualified _ qual) _ symbol =
"Replace with qualified: "
<> T.pack (moduleNameString qual)
<> "."
<> symbol
suggestImportDisambiguation _ _ _ _ = []

occursUnqualified :: T.Text -> ImportDecl GhcPs -> Bool
occursUnqualified symbol ImportDecl{..}
Expand Down Expand Up @@ -832,14 +839,19 @@ disambiguateSymbol pm Diagnostic {..} (T.unpack -> symbol) = \case
else hideSymbol symbol <$> imps
| ImplicitPrelude imps <- hiddens0
]
(ToQualified qualMod) ->
(ToQualified parensed qualMod) ->
let occSym = mkVarOcc symbol
rdr = Qual qualMod occSym
in [ Rewrite (rangeToSrcSpan "<dummy>" _range) $ \df -> do
liftParseAST @(HsExpr GhcPs) df $
asExpr = parensed && isSymOcc occSym
konn marked this conversation as resolved.
Show resolved Hide resolved
in [ if asExpr
then Rewrite (rangeToSrcSpan "<dummy>" _range) $ \df ->
liftParseAST @(HsExpr GhcPs) df $
prettyPrint $
HsVar @GhcPs noExtField $
L (UnhelpfulSpan "") rdr
else Rewrite (rangeToSrcSpan "<dummy>" _range) $ \df ->
liftParseAST @RdrName df $
prettyPrint $ L (UnhelpfulSpan "") rdr
]

findImportDeclByRange :: [LImportDecl GhcPs] -> Range -> Maybe (LImportDecl GhcPs)
Expand Down
5 changes: 5 additions & 0 deletions ghcide/test/data/hiding/HideQualifyInfix.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module HideQualifyInfix where

import AVec

infixed xs ys = xs ++ ys
5 changes: 5 additions & 0 deletions ghcide/test/data/hiding/HideQualifyInfix.hs.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module HideQualifyInfix where

import AVec

infixed xs ys = xs Prelude.++ ys
5 changes: 5 additions & 0 deletions ghcide/test/data/hiding/HideQualifySectionLeft.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module HideQualifySectionLeft where

import AVec

sectLeft xs = (++ xs)
5 changes: 5 additions & 0 deletions ghcide/test/data/hiding/HideQualifySectionLeft.hs.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module HideQualifySectionLeft where

import AVec

sectLeft xs = (Prelude.++ xs)
5 changes: 5 additions & 0 deletions ghcide/test/data/hiding/HideQualifySectionRight.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module HideQualifySectionRight where

import AVec

sectLeft xs = (xs ++)
5 changes: 5 additions & 0 deletions ghcide/test/data/hiding/HideQualifySectionRight.hs.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module HideQualifySectionRight where

import AVec

sectLeft xs = (xs Prelude.++)
17 changes: 16 additions & 1 deletion ghcide/test/exe/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1539,10 +1539,25 @@ suggestImportDisambiguationTests = testGroup "suggest import disambiguation acti
"HideFunction.hs.expected.qualified.fromList.E"
]
, testGroup "(++)"
[ testCase "Prelude" $
[ testCase "Prelude, parensed" $
compareHideFunctionTo [(8,9),(10,8)]
"Replace with qualified: Prelude.++"
"HideFunction.hs.expected.qualified.append.Prelude"
, testCase "Prelude, infix" $
compareTwo
"HideQualifyInfix.hs" [(4,19)]
"Replace with qualified: Prelude.++"
"HideQualifyInfix.hs.expected"
, testCase "Prelude, left section" $
compareTwo
"HideQualifySectionLeft.hs" [(4,15)]
"Replace with qualified: Prelude.++"
"HideQualifySectionLeft.hs.expected"
, testCase "Prelude, right section" $
compareTwo
"HideQualifySectionRight.hs" [(4,18)]
"Replace with qualified: Prelude.++"
"HideQualifySectionRight.hs.expected"
]
]
]
Expand Down