hls-qualify-imported-names-plugin 2.0.0.1 → 2.1.0.0
raw patch · 2 files changed
+97/−109 lines, 2 filesdep +lensdep ~ghcidedep ~hls-plugin-apidep ~hls-test-utilsPVP ok
version bump matches the API change (PVP)
Dependencies added: lens
Dependency ranges changed: ghcide, hls-plugin-api, hls-test-utils
API changes (from Hackage documentation)
Files
hls-qualify-imported-names-plugin.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: hls-qualify-imported-names-plugin-version: 2.0.0.1+version: 2.1.0.0 synopsis: A Haskell Language Server plugin that qualifies imported names description: Please see the README on GitHub at <https://github.com/haskell/haskell-language-server#readme>@@ -30,9 +30,10 @@ , containers , deepseq , ghc- , ghcide == 2.0.0.1+ , ghcide == 2.1.0.0 , hls-graph- , hls-plugin-api == 2.0.0.1+ , hls-plugin-api == 2.1.0.0+ , lens , lsp , text , unordered-containers@@ -55,4 +56,4 @@ , text , filepath , hls-qualify-imported-names-plugin- , hls-test-utils == 2.0.0.1+ , hls-test-utils == 2.1.0.0
src/Ide/Plugin/QualifyImportedNames.hs view
@@ -7,74 +7,79 @@ module Ide.Plugin.QualifyImportedNames (descriptor) where -import Control.Monad (foldM)-import Control.Monad.IO.Class (MonadIO (liftIO))-import Control.Monad.Trans.State.Strict (State)-import qualified Control.Monad.Trans.State.Strict as State-import Data.DList (DList)-import qualified Data.DList as DList-import Data.Foldable (Foldable (foldl'), find)-import qualified Data.HashMap.Strict as HashMap-import Data.List (sortOn)-import qualified Data.List as List-import qualified Data.Map.Strict as Map-import Data.Maybe (fromMaybe, mapMaybe)-import Data.Text (Text)-import qualified Data.Text as Text-import Development.IDE (spanContainsRange)-import Development.IDE.Core.RuleTypes (GetFileContents (GetFileContents),- GetHieAst (GetHieAst),- HieAstResult (HAR, refMap),- TcModuleResult (TcModuleResult, tmrParsed, tmrTypechecked),- TypeCheck (TypeCheck))-import Development.IDE.Core.Service (runAction)-import Development.IDE.Core.Shake (IdeState, use)-import Development.IDE.GHC.Compat (ContextInfo (Use),- GenLocated (..), GhcPs,- GlobalRdrElt, GlobalRdrEnv,- HsModule (hsmodImports),- Identifier,- IdentifierDetails (IdentifierDetails, identInfo),- ImpDeclSpec (ImpDeclSpec, is_as, is_dloc, is_qual),- ImportSpec (ImpSpec),- LImportDecl, ModuleName,- Name, NameEnv, OccName,- ParsedModule, RefMap, Span,- SrcSpan,- TcGblEnv (tcg_rdr_env),- emptyUFM, globalRdrEnvElts,- gre_imp, gre_name, locA,- lookupNameEnv,- moduleNameString,- nameOccName, occNameString,- pattern GRE,- pattern ParsedModule,- plusUFM_C, pm_parsed_source,- srcSpanEndCol,- srcSpanEndLine,- srcSpanStartCol,- srcSpanStartLine, unitUFM)-import Development.IDE.GHC.Error (isInsideSrcSpan)-import Development.IDE.Types.Diagnostics (List (List))-import Development.IDE.Types.Location (NormalizedFilePath,- Position (Position),- Range (Range), Uri,- toNormalizedUri)-import Ide.Types (PluginDescriptor (pluginHandlers),- PluginId,- PluginMethodHandler,- defaultPluginDescriptor,- mkPluginHandler)-import Language.LSP.Types (CodeAction (CodeAction, _command, _diagnostics, _disabled, _edit, _isPreferred, _kind, _title, _xdata),- CodeActionKind (CodeActionQuickFix),- CodeActionParams (CodeActionParams),- Method (TextDocumentCodeAction),- SMethod (STextDocumentCodeAction),- TextDocumentIdentifier (TextDocumentIdentifier),- TextEdit (TextEdit),- WorkspaceEdit (WorkspaceEdit, _changeAnnotations, _changes, _documentChanges),- type (|?) (InR),- uriToNormalizedFilePath)+import Control.Lens ((^.))+import Control.Monad (foldM)+import Control.Monad.IO.Class (MonadIO (liftIO))+import Control.Monad.Trans.State.Strict (State)+import qualified Control.Monad.Trans.State.Strict as State+import Data.DList (DList)+import qualified Data.DList as DList+import Data.Foldable (Foldable (foldl'), find)+import qualified Data.HashMap.Strict as HashMap+import Data.List (sortOn)+import qualified Data.List as List+import qualified Data.Map.Strict as Map+import Data.Maybe (fromMaybe, isJust, mapMaybe)+import Data.Text (Text)+import qualified Data.Text as Text+import Development.IDE (spanContainsRange)+import Development.IDE.Core.PluginUtils+import Development.IDE.Core.RuleTypes (GetFileContents (GetFileContents),+ GetHieAst (GetHieAst),+ HieAstResult (HAR, refMap),+ TcModuleResult (TcModuleResult, tmrParsed, tmrTypechecked),+ TypeCheck (TypeCheck))+import Development.IDE.Core.Service (runAction)+import Development.IDE.Core.Shake (IdeState, use)+import Development.IDE.GHC.Compat (ContextInfo (Use),+ GenLocated (..), GhcPs,+ GlobalRdrElt, GlobalRdrEnv,+ HsModule (hsmodImports),+ Identifier,+ IdentifierDetails (IdentifierDetails, identInfo),+ ImpDeclSpec (ImpDeclSpec, is_as, is_dloc, is_qual),+ ImportSpec (ImpSpec),+ LImportDecl, ModuleName,+ Name, NameEnv, OccName,+ ParsedModule, RefMap, Span,+ SrcSpan,+ TcGblEnv (tcg_rdr_env),+ emptyUFM, globalRdrEnvElts,+ gre_imp, gre_name, locA,+ lookupNameEnv,+ moduleNameString,+ nameOccName, occNameString,+ pattern GRE,+ pattern ParsedModule,+ plusUFM_C, pm_parsed_source,+ srcSpanEndCol,+ srcSpanEndLine,+ srcSpanStartCol,+ srcSpanStartLine, unitUFM)+import Development.IDE.GHC.Error (isInsideSrcSpan)+import Development.IDE.Types.Location (NormalizedFilePath,+ Position (Position),+ Range (Range), Uri,+ toNormalizedUri)+import Ide.Plugin.Error (PluginError (PluginRuleFailed),+ getNormalizedFilePathE,+ handleMaybe, handleMaybeM)+import Ide.Types (PluginDescriptor (pluginHandlers),+ PluginId,+ PluginMethodHandler,+ defaultPluginDescriptor,+ mkPluginHandler)+import qualified Language.LSP.Protocol.Lens as L+import Language.LSP.Protocol.Message (Method (Method_TextDocumentCodeAction),+ SMethod (SMethod_TextDocumentCodeAction))+import Language.LSP.Protocol.Types (CodeAction (CodeAction, _command, _data_, _diagnostics, _disabled, _edit, _isPreferred, _kind, _title),+ CodeActionKind (CodeActionKind_QuickFix),+ CodeActionParams (CodeActionParams),+ TextDocumentIdentifier (TextDocumentIdentifier),+ TextEdit (TextEdit),+ WorkspaceEdit (WorkspaceEdit, _changeAnnotations, _changes, _documentChanges),+ type (|?) (InL, InR),+ uriToNormalizedFilePath) thenCmp :: Ordering -> Ordering -> Ordering {-# INLINE thenCmp #-}@@ -84,7 +89,7 @@ descriptor :: PluginId -> PluginDescriptor IdeState descriptor pluginId = (defaultPluginDescriptor pluginId) { pluginHandlers = mconcat- [ mkPluginHandler STextDocumentCodeAction codeActionProvider+ [ mkPluginHandler SMethod_TextDocumentCodeAction codeActionProvider ] } @@ -98,31 +103,17 @@ makeCodeActions :: Uri -> [TextEdit] -> [a |? CodeAction] makeCodeActions uri textEdits = [InR CodeAction {..} | not (null textEdits)] where _title = "Qualify imported names"- _kind = Just CodeActionQuickFix+ _kind = Just CodeActionKind_QuickFix _command = Nothing _edit = Just WorkspaceEdit {..}- _changes = Just $ HashMap.singleton uri $ List textEdits+ _changes = Just $ Map.singleton uri textEdits _documentChanges = Nothing _diagnostics = Nothing _isPreferred = Nothing _disabled = Nothing- _xdata = Nothing+ _data_ = Nothing _changeAnnotations = Nothing -getTypeCheckedModule :: IdeState -> NormalizedFilePath -> IO (Maybe TcModuleResult)-getTypeCheckedModule ideState normalizedFilePath =- runAction "QualifyImportedNames.TypeCheck" ideState (use TypeCheck normalizedFilePath)--getHieAst :: IdeState -> NormalizedFilePath -> IO (Maybe HieAstResult)-getHieAst ideState normalizedFilePath =- runAction "QualifyImportedNames.GetHieAst" ideState (use GetHieAst normalizedFilePath)--getSourceText :: IdeState -> NormalizedFilePath -> IO (Maybe Text)-getSourceText ideState normalizedFilePath = do- fileContents <- runAction "QualifyImportedNames.GetFileContents" ideState (use GetFileContents normalizedFilePath)- if | Just (_, sourceText) <- fileContents -> pure sourceText- | otherwise -> pure Nothing- data ImportedBy = ImportedBy { importedByAlias :: !ModuleName, importedBySrcSpan :: !SrcSpan@@ -236,23 +227,19 @@ -- 2. refMap from GetHieAst contains location of names and how they are used. -- 3. For each used name in refMap check whether the name comes from an import -- at the origin of the code action.-codeActionProvider :: PluginMethodHandler IdeState TextDocumentCodeAction-codeActionProvider ideState pluginId (CodeActionParams _ _ documentId range context)- | TextDocumentIdentifier uri <- documentId- , Just normalizedFilePath <- uriToNormalizedFilePath (toNormalizedUri uri) = liftIO $ do- tcModuleResult <- getTypeCheckedModule ideState normalizedFilePath- if | Just TcModuleResult { tmrParsed, tmrTypechecked } <- tcModuleResult- , Just _ <- findLImportDeclAt range tmrParsed -> do- hieAstResult <- getHieAst ideState normalizedFilePath- sourceText <- getSourceText ideState normalizedFilePath- if | Just HAR {..} <- hieAstResult- , Just sourceText <- sourceText- , let globalRdrEnv = tcg_rdr_env tmrTypechecked- , let nameToImportedByMap = globalRdrEnvToNameToImportedByMap globalRdrEnv- , let usedIdentifiers = refMapToUsedIdentifiers refMap- , let textEdits = usedIdentifiersToTextEdits range nameToImportedByMap sourceText usedIdentifiers ->- pure $ Right $ List (makeCodeActions uri textEdits)- | otherwise -> pure $ Right $ List []- | otherwise -> pure $ Right $ List []- | otherwise = pure $ Right $ List []+codeActionProvider :: PluginMethodHandler IdeState Method_TextDocumentCodeAction+codeActionProvider ideState pluginId (CodeActionParams _ _ documentId range context) = do+ normalizedFilePath <- getNormalizedFilePathE (documentId ^. L.uri)+ TcModuleResult { tmrParsed, tmrTypechecked } <- runActionE "QualifyImportedNames.TypeCheck" ideState $ useE TypeCheck normalizedFilePath+ if isJust (findLImportDeclAt range tmrParsed)+ then do+ HAR {..} <- runActionE "QualifyImportedNames.GetHieAst" ideState (useE GetHieAst normalizedFilePath)+ (_, sourceTextM) <- runActionE "QualifyImportedNames.GetFileContents" ideState (useE GetFileContents normalizedFilePath)+ sourceText <- handleMaybe (PluginRuleFailed "GetFileContents") sourceTextM+ let globalRdrEnv = tcg_rdr_env tmrTypechecked+ nameToImportedByMap = globalRdrEnvToNameToImportedByMap globalRdrEnv+ usedIdentifiers = refMapToUsedIdentifiers refMap+ textEdits = usedIdentifiersToTextEdits range nameToImportedByMap sourceText usedIdentifiers+ pure $ InL (makeCodeActions (documentId ^. L.uri) textEdits)+ else pure $ InL []