From 108514298e4a3bab36f5409d5a2cb395cee58e41 Mon Sep 17 00:00:00 2001 From: Pepe Iborra Date: Sun, 31 Jan 2021 13:26:50 +0000 Subject: [PATCH] Handle qualified imports --- .../src/Development/IDE/Plugin/Completions.hs | 11 +++--- .../IDE/Plugin/Completions/Logic.hs | 7 ++++ .../IDE/Plugin/Completions/Types.hs | 3 +- ghcide/test/exe/Main.hs | 34 ++++++++++++++++--- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/ghcide/src/Development/IDE/Plugin/Completions.hs b/ghcide/src/Development/IDE/Plugin/Completions.hs index 327a2c42b00..052bb58c117 100644 --- a/ghcide/src/Development/IDE/Plugin/Completions.hs +++ b/ghcide/src/Development/IDE/Plugin/Completions.hs @@ -175,7 +175,8 @@ extendImportHandler' ideState ExtendImport {..} return (ms, ps, imps) let df = ms_hspp_opts ms wantedModule = mkModuleName (T.unpack importName) - imp <- liftMaybe $ find (isWantedModule wantedModule) imps + wantedQual = mkModuleName . T.unpack <$> importQual + imp <- liftMaybe $ find (isWantedModule wantedModule wantedQual) imps wedit <- liftEither $ rewriteToWEdit df doc (annsA ps) $ @@ -184,10 +185,12 @@ extendImportHandler' ideState ExtendImport {..} | otherwise = mzero -isWantedModule :: ModuleName -> GenLocated l (ImportDecl pass) -> Bool -isWantedModule wantedModule (L _ it@ImportDecl{ideclName, ideclHiding = Just (False, _)}) = +isWantedModule :: ModuleName -> Maybe ModuleName -> GenLocated l (ImportDecl pass) -> Bool +isWantedModule wantedModule Nothing (L _ it@ImportDecl{ideclName, ideclHiding = Just (False, _)}) = not (isQualifiedImport it) && unLoc ideclName == wantedModule -isWantedModule _ _ = False +isWantedModule wantedModule (Just qual) (L _ ImportDecl{ideclAs, ideclName, ideclHiding = Just (False, _)}) = + unLoc ideclName == wantedModule && (wantedModule == qual || (unLoc <$> ideclAs) == Just qual) +isWantedModule _ _ _ = False liftMaybe :: Monad m => Maybe a -> MaybeT m a liftMaybe a = MaybeT $ pure a diff --git a/ghcide/src/Development/IDE/Plugin/Completions/Logic.hs b/ghcide/src/Development/IDE/Plugin/Completions/Logic.hs index b925d78e8e4..18380058a10 100644 --- a/ghcide/src/Development/IDE/Plugin/Completions/Logic.hs +++ b/ghcide/src/Development/IDE/Plugin/Completions/Logic.hs @@ -229,6 +229,7 @@ mkNameCompItem doc thingParent origName origMod thingType isInfix docs !imp = CI { doc, thingParent, importName = showModName $ unLoc $ ideclName $ unLoc x, + importQual = getImportQual x, newThing = showNameWithoutUniques origName } @@ -742,6 +743,7 @@ mkRecordSnippetCompItem uri parent ctxStr compl mn docs imp = r { doc = uri, thingParent = parent, importName = showModName $ unLoc $ ideclName $ unLoc x, + importQual = getImportQual x, newThing = ctxStr } } @@ -751,3 +753,8 @@ mkRecordSnippetCompItem uri parent ctxStr compl mn docs imp = r snippet = T.intercalate (T.pack ", ") snippet_parts buildSnippet = ctxStr <> " {" <> snippet <> "}" importedFrom = Right mn + +getImportQual :: LImportDecl GhcPs -> Maybe T.Text +getImportQual (L _ imp) + | isQualifiedImport imp = Just $ T.pack $ moduleNameString $ fromMaybe (unLoc $ ideclName imp) (unLoc <$> ideclAs imp) + | otherwise = Nothing diff --git a/ghcide/src/Development/IDE/Plugin/Completions/Types.hs b/ghcide/src/Development/IDE/Plugin/Completions/Types.hs index a1375bcf4b4..528ab1baf22 100644 --- a/ghcide/src/Development/IDE/Plugin/Completions/Types.hs +++ b/ghcide/src/Development/IDE/Plugin/Completions/Types.hs @@ -25,7 +25,8 @@ data ExtendImport = ExtendImport { doc :: !Uri, newThing :: !T.Text, thingParent :: !(Maybe T.Text), - importName :: !T.Text + importName :: !T.Text, + importQual :: !(Maybe T.Text) } deriving (Eq, Show, Generic) deriving anyclass (FromJSON, ToJSON) diff --git a/ghcide/test/exe/Main.hs b/ghcide/test/exe/Main.hs index 1822a3a745e..aaf2d16ccf3 100644 --- a/ghcide/test/exe/Main.hs +++ b/ghcide/test/exe/Main.hs @@ -3501,19 +3501,45 @@ nonLocalCompletionTests = , completionCommandTest "show imports not in list - names with _" ["{-# LANGUAGE NoImplicitPrelude #-}", - "module A where", "import qualified Control.Monad as M (msum)", "f = M.mapM_"] + "module A where", "import Control.Monad as M (msum)", "f = M.mapM_"] (Position 3 11) "mapM_" ["{-# LANGUAGE NoImplicitPrelude #-}", - "module A where", "import qualified Control.Monad as M (msum, mapM_)", "f = M.mapM_"] + "module A where", "import Control.Monad as M (msum, mapM_)", "f = M.mapM_"] , completionCommandTest "show imports not in list - initial empty list" ["{-# LANGUAGE NoImplicitPrelude #-}", - "module A where", "import qualified Control.Monad as M ()", "f = M.joi"] + "module A where", "import Control.Monad as M ()", "f = M.joi"] (Position 3 10) "join" ["{-# LANGUAGE NoImplicitPrelude #-}", - "module A where", "import qualified Control.Monad as M (join)", "f = M.joi"] + "module A where", "import Control.Monad as M (join)", "f = M.joi"] + , testGroup "qualified imports" + [ completionCommandTest + "single" + ["{-# LANGUAGE NoImplicitPrelude #-}", + "module A where", "import Control.Monad ()", "f = Control.Monad.joi"] + (Position 3 22) + "join" + ["{-# LANGUAGE NoImplicitPrelude #-}", + "module A where", "import Control.Monad (join)", "f = Control.Monad.joi"] + , completionCommandTest + "as" + ["{-# LANGUAGE NoImplicitPrelude #-}", + "module A where", "import Control.Monad as M ()", "f = M.joi"] + (Position 3 10) + "join" + ["{-# LANGUAGE NoImplicitPrelude #-}", + "module A where", "import Control.Monad as M (join)", "f = M.joi"] + , completionCommandTest + "multiple" + ["{-# LANGUAGE NoImplicitPrelude #-}", + "module A where", "import Control.Monad as M ()", "import Control.Monad as N ()", "f = N.joi"] + (Position 4 10) + "join" + ["{-# LANGUAGE NoImplicitPrelude #-}", + "module A where", "import Control.Monad as M ()", "import Control.Monad as N (join)", "f = N.joi"] + ] , testGroup "Data constructor" [ completionCommandTest "not imported"