From d2995df9188c92076e52ac0eefb14267537ad065 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Thu, 11 Nov 2021 23:01:07 +0200 Subject: [PATCH 01/37] ghcide: Spans.AtPoint: pointCommand: explain --- ghcide/src/Development/IDE/Spans/AtPoint.hs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ghcide/src/Development/IDE/Spans/AtPoint.hs b/ghcide/src/Development/IDE/Spans/AtPoint.hs index 36bdd58303..25d7c7854e 100644 --- a/ghcide/src/Development/IDE/Spans/AtPoint.hs +++ b/ghcide/src/Development/IDE/Spans/AtPoint.hs @@ -387,7 +387,7 @@ defRowToSymbolInfo (DefRow{..}:.(modInfoSrcFile -> Just srcFile)) defRowToSymbolInfo _ = Nothing pointCommand :: HieASTs t -> Position -> (HieAST t -> a) -> [a] -pointCommand hf pos k = +pointCommand hf pos getter = catMaybes $ M.elems $ flip M.mapWithKey (getAsts hf) $ \fs ast -> -- Since GHC 9.2: -- getAsts :: Map HiePath (HieAst a) @@ -399,9 +399,8 @@ pointCommand hf pos k = -- -- 'coerce' here to avoid an additional function for maintaining -- backwards compatibility. - case selectSmallestContaining (sp $ coerce fs) ast of - Nothing -> Nothing - Just ast' -> Just $ k ast' + let smallestRange = selectSmallestContaining (sp $ coerce fs) ast in + fmap getter smallestRange where sloc fs = mkRealSrcLoc fs (line+1) (cha+1) sp fs = mkRealSrcSpan (sloc fs) (sloc fs) From 6cda03af35b7f832879bb9972f59c6b0efcae058 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Thu, 11 Nov 2021 23:40:10 +0200 Subject: [PATCH 02/37] ghcide: Spans.AtPoint: documentHighligh: m upd --- ghcide/src/Development/IDE/Spans/AtPoint.hs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ghcide/src/Development/IDE/Spans/AtPoint.hs b/ghcide/src/Development/IDE/Spans/AtPoint.hs index 25d7c7854e..fc4c82cb0c 100644 --- a/ghcide/src/Development/IDE/Spans/AtPoint.hs +++ b/ghcide/src/Development/IDE/Spans/AtPoint.hs @@ -40,6 +40,7 @@ import Control.Monad.IO.Class import Control.Monad.Trans.Class import Control.Monad.Trans.Maybe import Data.Coerce (coerce) +import Data.Set (Set) import qualified Data.HashMap.Strict as HM import qualified Data.Map.Strict as M import Data.Maybe @@ -163,8 +164,12 @@ documentHighlight hf rf pos = pure highlights n <- ns ref <- fromMaybe [] (M.lookup (Right n) rf) pure $ makeHighlight ref + + makeHighlight :: (RealSrcSpan, IdentifierDetails a) -> DocumentHighlight makeHighlight (sp,dets) = DocumentHighlight (realSrcSpanToRange sp) (Just $ highlightType $ identInfo dets) + + highlightType :: Set ContextInfo -> DocumentHighlightKind highlightType s = if any (isJust . getScopeFromContext) s then HkWrite From 2185fd48ad0ff110b5b15e63780052dc16b27664 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Thu, 11 Nov 2021 23:42:40 +0200 Subject: [PATCH 03/37] ghcide: LSP.HoverDefinition: align If these function are plased such - they need to be aligned. --- ghcide/src/Development/IDE/LSP/HoverDefinition.hs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ghcide/src/Development/IDE/LSP/HoverDefinition.hs b/ghcide/src/Development/IDE/LSP/HoverDefinition.hs index 97a5a3e065..ecd2e9a8c2 100644 --- a/ghcide/src/Development/IDE/LSP/HoverDefinition.hs +++ b/ghcide/src/Development/IDE/LSP/HoverDefinition.hs @@ -24,14 +24,14 @@ import Language.LSP.Types import qualified Data.Text as T -gotoDefinition :: IdeState -> TextDocumentPositionParams -> LSP.LspM c (Either ResponseError (ResponseResult TextDocumentDefinition)) -hover :: IdeState -> TextDocumentPositionParams -> LSP.LspM c (Either ResponseError (Maybe Hover)) +gotoDefinition :: IdeState -> TextDocumentPositionParams -> LSP.LspM c (Either ResponseError (ResponseResult TextDocumentDefinition)) +hover :: IdeState -> TextDocumentPositionParams -> LSP.LspM c (Either ResponseError (Maybe Hover)) gotoTypeDefinition :: IdeState -> TextDocumentPositionParams -> LSP.LspM c (Either ResponseError (ResponseResult TextDocumentTypeDefinition)) -documentHighlight :: IdeState -> TextDocumentPositionParams -> LSP.LspM c (Either ResponseError (List DocumentHighlight)) -gotoDefinition = request "Definition" getDefinition (InR $ InL $ List []) (InR . InL . List) -gotoTypeDefinition = request "TypeDefinition" getTypeDefinition (InR $ InL $ List []) (InR . InL . List) -hover = request "Hover" getAtPoint Nothing foundHover -documentHighlight = request "DocumentHighlight" highlightAtPoint (List []) List +documentHighlight :: IdeState -> TextDocumentPositionParams -> LSP.LspM c (Either ResponseError (List DocumentHighlight)) +gotoDefinition = request "Definition" getDefinition (InR $ InL $ List []) (InR . InL . List) +gotoTypeDefinition = request "TypeDefinition" getTypeDefinition (InR $ InL $ List []) (InR . InL . List) +hover = request "Hover" getAtPoint Nothing foundHover +documentHighlight = request "DocumentHighlight" highlightAtPoint (List []) List references :: IdeState -> ReferenceParams -> LSP.LspM c (Either ResponseError (List Location)) references ide (ReferenceParams (TextDocumentIdentifier uri) pos _ _ _) = liftIO $ From cf56091d1f352eb4b9a499062f220e9704b25500 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Fri, 12 Nov 2021 19:59:52 +0200 Subject: [PATCH 04/37] ghcide: Spans.AtPoint: atPoint: clarify local fun --- ghcide/src/Development/IDE/Spans/AtPoint.hs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ghcide/src/Development/IDE/Spans/AtPoint.hs b/ghcide/src/Development/IDE/Spans/AtPoint.hs index fc4c82cb0c..29edb0c6fd 100644 --- a/ghcide/src/Development/IDE/Spans/AtPoint.hs +++ b/ghcide/src/Development/IDE/Spans/AtPoint.hs @@ -209,12 +209,12 @@ atPoint -> Maybe (Maybe Range, [T.Text]) atPoint IdeOptions{} (HAR _ hf _ _ kind) (DKMap dm km) env pos = listToMaybe $ pointCommand hf pos hoverInfo where - -- Hover info for values/data + -- | Get hover info for values/data hoverInfo ast = (Just range, prettyNames ++ pTypes) where pTypes - | Prelude.length names == 1 = dropEnd1 $ map wrapHaskell prettyTypes - | otherwise = map wrapHaskell prettyTypes + | Prelude.length names == 1 = dropEnd1 $ map wrapHaskell prettyConcreteTypes + | otherwise = map wrapHaskell prettyConcreteTypes range = realSrcSpanToRange $ nodeSpan ast @@ -242,11 +242,13 @@ atPoint IdeOptions{} (HAR _ hf _ _ kind) (DKMap dm km) env pos = listToMaybe $ p version = T.pack $ showVersion (unitPackageVersion conf) pure $ " *(" <> pkgName <> "-" <> version <> ")*" - prettyTypes = map (("_ :: "<>) . prettyType) types prettyType t = case kind of HieFresh -> showGhc t HieFromDisk full_file -> showGhc $ hieTypeToIface $ recoverFullType t (hie_types full_file) + -- | Local inferred most concrete type signature. + prettyConcreteTypes = map (("_ :: "<>) . prettyType) types + definedAt name = -- do not show "at " and similar messages -- see the code of 'pprNameDefnLoc' for more information From 460a997f738ba48b282a7e8bf5b0ff78f0d20277 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Sat, 13 Nov 2021 21:21:37 +0200 Subject: [PATCH 05/37] Compat.HieAs (810): use fromMaybe --- hie-compat/src-ghc810/Compat/HieAst.hs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/hie-compat/src-ghc810/Compat/HieAst.hs b/hie-compat/src-ghc810/Compat/HieAst.hs index 3d2eba2feb..c4567953c3 100644 --- a/hie-compat/src-ghc810/Compat/HieAst.hs +++ b/hie-compat/src-ghc810/Compat/HieAst.hs @@ -50,7 +50,7 @@ import qualified Data.Map as M import qualified Data.Set as S import Data.Data ( Data, Typeable ) import Data.List ( foldl1' ) -import Data.Maybe ( listToMaybe ) +import Data.Maybe ( listToMaybe, fromMaybe ) import Control.Monad.Trans.Reader import Control.Monad.Trans.Class ( lift ) @@ -506,9 +506,7 @@ instance ToHie (Context (Located Var)) where C context (L (RealSrcSpan span) name') -> do m <- asks name_remapping - let name = case lookupNameEnv m (varName name') of - Just var -> var - Nothing-> name' + let name = fromMaybe name' (lookupNameEnv m (varName name')) pure [Node (NodeInfo S.empty [] $ @@ -523,9 +521,7 @@ instance ToHie (Context (Located Name)) where toHie c = case c of C context (L (RealSrcSpan span) name') -> do m <- asks name_remapping - let name = case lookupNameEnv m name' of - Just var -> varName var - Nothing -> name' + let name = maybe name' varName (lookupNameEnv m name') pure [Node (NodeInfo S.empty [] $ From 434d90fb3e680f0023400f2f7f4bfd7fc211861a Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 01:45:44 +0200 Subject: [PATCH 06/37] ghcide: Core.Compile: getDocsBatch: form local fun --- ghcide/src/Development/IDE/Core/Compile.hs | 24 ++++++++++++---------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 7b002f08fa..f1fe6a843d 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -658,7 +658,7 @@ setupFinderCache mss session = do -- Make modules available for others that import them, -- by putting them in the finder cache. let ims = map (installedModule (homeUnitId_ $ hsc_dflags session) . moduleName . ms_mod) mss - ifrs = zipWith (\ms -> InstalledFound (ms_location ms)) mss ims + ifrs = zipWith (InstalledFound . ms_location) mss ims -- set the target and module graph in the session graph = mkModuleGraph mss @@ -1000,7 +1000,15 @@ getDocsBatch -> [Name] -> IO [Either String (Maybe HsDocString, Map.Map Int HsDocString)] getDocsBatch hsc_env _mod _names = do - ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ forM _names $ \name -> + ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ traverse findNameInfo _names + case res of + Just x -> return $ map (first $ T.unpack . showGhc) x + Nothing -> throwErrors errs + where + throwErrors = liftIO . throwIO . mkSrcErr + + findNameInfo :: Name -> IOEnv (Env TcGblEnv TcLclEnv) (Either GetDocsFailure (Maybe HsDocString, Map.Map Int HsDocString)) + findNameInfo name = case nameModule_maybe name of Nothing -> return (Left $ NameHasNoModule name) Just mod -> do @@ -1008,15 +1016,9 @@ getDocsBatch hsc_env _mod _names = do , mi_decl_docs = DeclDocMap dmap , mi_arg_docs = ArgDocMap amap } <- loadModuleInterface "getModuleInterface" mod - if isNothing mb_doc_hdr && Map.null dmap && Map.null amap - then pure (Left (NoDocsInIface mod $ compiled name)) - else pure (Right ( Map.lookup name dmap - , Map.findWithDefault Map.empty name amap)) - case res of - Just x -> return $ map (first $ T.unpack . showGhc) x - Nothing -> throwErrors errs - where - throwErrors = liftIO . throwIO . mkSrcErr + pure $ if isNothing mb_doc_hdr && Map.null dmap && Map.null amap + then Left (NoDocsInIface mod $ compiled name) + else Right (Map.lookup name dmap, Map.findWithDefault mempty name amap) compiled n = -- TODO: Find a more direct indicator. case nameSrcLoc n of From 6c8371c8f7dff1ff56089be77bf59c3182cf707e Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 12:38:04 +0200 Subject: [PATCH 07/37] ghcide: Core.Compile: getDocsBatch: return (Name,) The types show it needs be such. The semantics of code in funciton show it needs be such. The use of the function shows it needs to be such. `zipWithM .. names` would not be needed. --- ghcide/src/Development/IDE/Core/Compile.hs | 32 ++++++++++++------- .../Development/IDE/Spans/Documentation.hs | 2 +- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index f1fe6a843d..c359a31757 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -998,27 +998,37 @@ getDocsBatch :: HscEnv -> Module -- ^ a moudle where the names are in scope -> [Name] - -> IO [Either String (Maybe HsDocString, Map.Map Int HsDocString)] + -> IO [(Name, Either String (Maybe HsDocString, Map.Map Int HsDocString))] getDocsBatch hsc_env _mod _names = do ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ traverse findNameInfo _names case res of - Just x -> return $ map (first $ T.unpack . showGhc) x + Just x -> return $ fun x Nothing -> throwErrors errs where + fun :: [(Name, Either GetDocsFailure c)] -> [(Name, Either String c)] + fun = + map fun1 + where + fun1 :: ((Name, Either GetDocsFailure c) -> (Name, Either String c)) + fun1 = fmap (first $ T.unpack . showGhc) + throwErrors = liftIO . throwIO . mkSrcErr - findNameInfo :: Name -> IOEnv (Env TcGblEnv TcLclEnv) (Either GetDocsFailure (Maybe HsDocString, Map.Map Int HsDocString)) + findNameInfo :: Name -> IOEnv (Env TcGblEnv TcLclEnv) (Name, Either GetDocsFailure (Maybe HsDocString, Map.Map Int HsDocString)) findNameInfo name = case nameModule_maybe name of - Nothing -> return (Left $ NameHasNoModule name) + Nothing -> return (name, Left $ NameHasNoModule name) Just mod -> do - ModIface { mi_doc_hdr = mb_doc_hdr - , mi_decl_docs = DeclDocMap dmap - , mi_arg_docs = ArgDocMap amap - } <- loadModuleInterface "getModuleInterface" mod - pure $ if isNothing mb_doc_hdr && Map.null dmap && Map.null amap - then Left (NoDocsInIface mod $ compiled name) - else Right (Map.lookup name dmap, Map.findWithDefault mempty name amap) + ModIface + { mi_doc_hdr = mb_doc_hdr + , mi_decl_docs = DeclDocMap dmap + , mi_arg_docs = ArgDocMap amap + } + <- loadModuleInterface "getModuleInterface" mod + pure . (name,) $ + if isNothing mb_doc_hdr && Map.null dmap && Map.null amap + then Left $ NoDocsInIface mod $ compiled name + else Right (Map.lookup name dmap, Map.findWithDefault mempty name amap) compiled n = -- TODO: Find a more direct indicator. case nameSrcLoc n of diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index 8afe4f72fe..e396b9340b 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -67,7 +67,7 @@ getDocumentationTryGhc env mod n = head <$> getDocumentationsTryGhc env mod [n] getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO [SpanDoc] getDocumentationsTryGhc env mod names = do - res <- catchSrcErrors (hsc_dflags env) "docs" $ getDocsBatch env mod names + res <- catchSrcErrors (hsc_dflags env) "docs" $ (fmap . fmap) snd $ getDocsBatch env mod names case res of Left _ -> return [] Right res -> zipWithM unwrap res names From 3a3814f914652bcc94742217fa251879c35dda95 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 12:49:43 +0200 Subject: [PATCH 08/37] ghcide: Core.Compile: getDocsBatch: ([(,)]->Map) --- ghcide/src/Development/IDE/Core/Compile.hs | 4 ++-- ghcide/src/Development/IDE/Spans/Documentation.hs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index c359a31757..bde51c873b 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -998,11 +998,11 @@ getDocsBatch :: HscEnv -> Module -- ^ a moudle where the names are in scope -> [Name] - -> IO [(Name, Either String (Maybe HsDocString, Map.Map Int HsDocString))] + -> IO (Map.Map Name (Either String (Maybe HsDocString, Map.Map Int HsDocString))) getDocsBatch hsc_env _mod _names = do ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ traverse findNameInfo _names case res of - Just x -> return $ fun x + Just x -> return $ Map.fromList $ fun x Nothing -> throwErrors errs where fun :: [(Name, Either GetDocsFailure c)] -> [(Name, Either String c)] diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index e396b9340b..b43a794283 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -32,6 +32,7 @@ import System.Directory import System.FilePath import Language.LSP.Types (filePathToUri, getUri) +import qualified Data.Map as Map mkDocMap :: HscEnv @@ -67,7 +68,7 @@ getDocumentationTryGhc env mod n = head <$> getDocumentationsTryGhc env mod [n] getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO [SpanDoc] getDocumentationsTryGhc env mod names = do - res <- catchSrcErrors (hsc_dflags env) "docs" $ (fmap . fmap) snd $ getDocsBatch env mod names + res <- catchSrcErrors (hsc_dflags env) "docs" $ (fmap . fmap) snd $ fmap Map.toList $ getDocsBatch env mod names case res of Left _ -> return [] Right res -> zipWithM unwrap res names From 7d6be6541238be1da7947ced0a31bbf3908c2830 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 13:04:14 +0200 Subject: [PATCH 09/37] ghcide: Spans.Documentation: getDocumentationsTryGhc: mv map --- ghcide/src/Development/IDE/Spans/Documentation.hs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index b43a794283..2a632e45bf 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -33,6 +33,7 @@ import System.FilePath import Language.LSP.Types (filePathToUri, getUri) import qualified Data.Map as Map +import Development.IDE.Types.Diagnostics (FileDiagnostic) mkDocMap :: HscEnv @@ -68,11 +69,14 @@ getDocumentationTryGhc env mod n = head <$> getDocumentationsTryGhc env mod [n] getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO [SpanDoc] getDocumentationsTryGhc env mod names = do - res <- catchSrcErrors (hsc_dflags env) "docs" $ (fmap . fmap) snd $ fmap Map.toList $ getDocsBatch env mod names + res <- fun case res of Left _ -> return [] - Right res -> zipWithM unwrap res names + Right res -> zipWithM unwrap (fmap snd res) names where + fun :: IO (Either [FileDiagnostic] [(Name, Either String (Maybe HsDocString, Map.Map Int HsDocString))]) + fun = catchSrcErrors (hsc_dflags env) "docs" $ Map.toList <$> getDocsBatch env mod names + unwrap (Right (Just docs, _)) n = SpanDocString docs <$> getUris n unwrap _ n = mkSpanDocText n From 0b0e2b703100038ef3c0899b5ffb1def5307b39e Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 13:10:46 +0200 Subject: [PATCH 10/37] ghcide: Spans.Documentation: getDocumentationsTryGhc: mv Map --- ghcide/src/Development/IDE/Spans/Documentation.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index 2a632e45bf..0f4b919b05 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -72,10 +72,10 @@ getDocumentationsTryGhc env mod names = do res <- fun case res of Left _ -> return [] - Right res -> zipWithM unwrap (fmap snd res) names + Right res -> zipWithM unwrap (fmap snd $ Map.toList res) names where - fun :: IO (Either [FileDiagnostic] [(Name, Either String (Maybe HsDocString, Map.Map Int HsDocString))]) - fun = catchSrcErrors (hsc_dflags env) "docs" $ Map.toList <$> getDocsBatch env mod names + fun :: IO (Either [FileDiagnostic] (Map.Map Name (Either String (Maybe HsDocString, Map.Map Int HsDocString)))) + fun = catchSrcErrors (hsc_dflags env) "docs" $ getDocsBatch env mod names unwrap (Right (Just docs, _)) n = SpanDocString docs <$> getUris n unwrap _ n = mkSpanDocText n From 08f4594f29ed1b9f9cce40cf99cd80feec41068b Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 13:21:46 +0200 Subject: [PATCH 11/37] ghcide: Spans.Documentation: getDocumentationsTryGhc: mv Map --- ghcide/src/Development/IDE/Spans/Documentation.hs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index 0f4b919b05..77a7f2ef1d 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -72,16 +72,14 @@ getDocumentationsTryGhc env mod names = do res <- fun case res of Left _ -> return [] - Right res -> zipWithM unwrap (fmap snd $ Map.toList res) names + Right res -> sequenceA $ unwrap <$> Map.toList res where fun :: IO (Either [FileDiagnostic] (Map.Map Name (Either String (Maybe HsDocString, Map.Map Int HsDocString)))) fun = catchSrcErrors (hsc_dflags env) "docs" $ getDocsBatch env mod names - unwrap (Right (Just docs, _)) n = SpanDocString docs <$> getUris n - unwrap _ n = mkSpanDocText n - - mkSpanDocText name = - SpanDocText [] <$> getUris name + unwrap :: (Name, Either a (Maybe HsDocString, b)) -> IO SpanDoc + unwrap (name, Right (Just docs, _)) = SpanDocString docs <$> getUris name + unwrap (name, _) = SpanDocText [] <$> getUris name -- Get the uris to the documentation and source html pages if they exist getUris name = do From b75de49ed3d12df3f73151cdcd6103101e2c7caa Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 13:27:36 +0200 Subject: [PATCH 12/37] ghcide: Spans.Documentation: getDocumentationsTryGhc: mv Map --- ghcide/src/Development/IDE/Spans/Documentation.hs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index 77a7f2ef1d..cc90e9049f 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -65,9 +65,9 @@ lookupKind env mod = fmap (fromRight Nothing) . catchSrcErrors (hsc_dflags env) "span" . lookupName env mod getDocumentationTryGhc :: HscEnv -> Module -> Name -> IO SpanDoc -getDocumentationTryGhc env mod n = head <$> getDocumentationsTryGhc env mod [n] +getDocumentationTryGhc env mod n = fmap head ((fmap . fmap) snd $ getDocumentationsTryGhc env mod [n]) -getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO [SpanDoc] +getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO [(Name, SpanDoc)] getDocumentationsTryGhc env mod names = do res <- fun case res of @@ -77,9 +77,9 @@ getDocumentationsTryGhc env mod names = do fun :: IO (Either [FileDiagnostic] (Map.Map Name (Either String (Maybe HsDocString, Map.Map Int HsDocString)))) fun = catchSrcErrors (hsc_dflags env) "docs" $ getDocsBatch env mod names - unwrap :: (Name, Either a (Maybe HsDocString, b)) -> IO SpanDoc - unwrap (name, Right (Just docs, _)) = SpanDocString docs <$> getUris name - unwrap (name, _) = SpanDocText [] <$> getUris name + unwrap :: (Name, Either a (Maybe HsDocString, b)) -> IO (Name, SpanDoc) + unwrap (name, Right (Just docs, _)) = (name,) . SpanDocString docs <$> getUris name + unwrap (name, _) = (name,) . SpanDocText [] <$> getUris name -- Get the uris to the documentation and source html pages if they exist getUris name = do From 99d45d5cfc6db04872958a3e8d3c2353f1080dfd Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 13:31:45 +0200 Subject: [PATCH 13/37] ghcide: Spans.Documentation: getDocumentationsTryGhc: use Map --- ghcide/src/Development/IDE/Spans/Documentation.hs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index cc90e9049f..9b4ea6bf94 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -65,21 +65,21 @@ lookupKind env mod = fmap (fromRight Nothing) . catchSrcErrors (hsc_dflags env) "span" . lookupName env mod getDocumentationTryGhc :: HscEnv -> Module -> Name -> IO SpanDoc -getDocumentationTryGhc env mod n = fmap head ((fmap . fmap) snd $ getDocumentationsTryGhc env mod [n]) +getDocumentationTryGhc env mod n = fmap head ((fmap . fmap) snd $ fmap Map.toList $ getDocumentationsTryGhc env mod [n]) -getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO [(Name, SpanDoc)] +getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO (Map.Map Name SpanDoc) getDocumentationsTryGhc env mod names = do res <- fun case res of - Left _ -> return [] - Right res -> sequenceA $ unwrap <$> Map.toList res + Left _ -> return mempty + Right res -> fmap Map.fromList $ sequenceA $ unwrap <$> Map.toList res where fun :: IO (Either [FileDiagnostic] (Map.Map Name (Either String (Maybe HsDocString, Map.Map Int HsDocString)))) fun = catchSrcErrors (hsc_dflags env) "docs" $ getDocsBatch env mod names unwrap :: (Name, Either a (Maybe HsDocString, b)) -> IO (Name, SpanDoc) unwrap (name, Right (Just docs, _)) = (name,) . SpanDocString docs <$> getUris name - unwrap (name, _) = (name,) . SpanDocText [] <$> getUris name + unwrap (name, _) = (name,) . SpanDocText mempty <$> getUris name -- Get the uris to the documentation and source html pages if they exist getUris name = do From 2e60be32c1d2264beadff00fbdb3b78e5931db67 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 15:54:40 +0200 Subject: [PATCH 14/37] ghcide: Spans.Documentation: getDocumentationTryGhc: idiom --- ghcide/src/Development/IDE/Spans/Documentation.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index 9b4ea6bf94..7d2cbabd1b 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -65,7 +65,8 @@ lookupKind env mod = fmap (fromRight Nothing) . catchSrcErrors (hsc_dflags env) "span" . lookupName env mod getDocumentationTryGhc :: HscEnv -> Module -> Name -> IO SpanDoc -getDocumentationTryGhc env mod n = fmap head ((fmap . fmap) snd $ fmap Map.toList $ getDocumentationsTryGhc env mod [n]) +-- 2021-11-17: FIXME: Code uses batch search for singleton & assumes that search always succeeds. +getDocumentationTryGhc env mod n = fromJust . Map.lookup n <$> getDocumentationsTryGhc env mod [n] getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO (Map.Map Name SpanDoc) getDocumentationsTryGhc env mod names = do From 3499bbb0cb374ada0dcc16260c297b095bc4d489 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 16:29:00 +0200 Subject: [PATCH 15/37] ghcide: Spans.Documentation: getDocumentationsTryGhc: structure Make code easier to reason about & functionally enhancable. --- .../Development/IDE/Spans/Documentation.hs | 52 +++++++++++-------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index 7d2cbabd1b..03cadf368e 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -73,32 +73,38 @@ getDocumentationsTryGhc env mod names = do res <- fun case res of Left _ -> return mempty - Right res -> fmap Map.fromList $ sequenceA $ unwrap <$> Map.toList res + Right res -> fmap Map.fromList $ sequenceA $ uncurry unwrap <$> Map.toList res where fun :: IO (Either [FileDiagnostic] (Map.Map Name (Either String (Maybe HsDocString, Map.Map Int HsDocString)))) fun = catchSrcErrors (hsc_dflags env) "docs" $ getDocsBatch env mod names - unwrap :: (Name, Either a (Maybe HsDocString, b)) -> IO (Name, SpanDoc) - unwrap (name, Right (Just docs, _)) = (name,) . SpanDocString docs <$> getUris name - unwrap (name, _) = (name,) . SpanDocText mempty <$> getUris name - - -- Get the uris to the documentation and source html pages if they exist - getUris name = do - (docFu, srcFu) <- - case nameModule_maybe name of - Just mod -> liftIO $ do - doc <- toFileUriText $ lookupDocHtmlForModule env mod - src <- toFileUriText $ lookupSrcHtmlForModule env mod - return (doc, src) - Nothing -> pure (Nothing, Nothing) - let docUri = (<> "#" <> selector <> showNameWithoutUniques name) <$> docFu - srcUri = (<> "#" <> showNameWithoutUniques name) <$> srcFu - selector - | isValName name = "v:" - | otherwise = "t:" - return $ SpanDocUris docUri srcUri - - toFileUriText = (fmap . fmap) (getUri . filePathToUri) + unwrap :: Name -> Either a (Maybe HsDocString, b) -> IO (Name, SpanDoc) + unwrap name a = (name,) . extractDocString a <$> getSpanDocUris name + where + extractDocString :: Either b1 (Maybe HsDocString, b2) -> SpanDocUris -> SpanDoc + -- 2021-11-17: FIXME: ArgDocs get dropped here - instead propagate them. + extractDocString (Right (Just docs, _)) = SpanDocString docs + extractDocString _ = SpanDocText mempty + + -- | Get the uris to the documentation and source html pages if they exist + getSpanDocUris :: Name -> IO SpanDocUris + getSpanDocUris name = do + (docFu, srcFu) <- + case nameModule_maybe name of + Just mod -> liftIO $ do + doc <- toFileUriText $ lookupDocHtmlForModule env mod + src <- toFileUriText $ lookupSrcHtmlForModule env mod + return (doc, src) + Nothing -> pure mempty + let docUri = (<> "#" <> selector <> showNameWithoutUniques name) <$> docFu + srcUri = (<> "#" <> showNameWithoutUniques name) <$> srcFu + selector + | isValName name = "v:" + | otherwise = "t:" + return $ SpanDocUris docUri srcUri + where + toFileUriText :: IO (Maybe FilePath) -> IO (Maybe T.Text) + toFileUriText = (fmap . fmap) (getUri . filePathToUri) getDocumentation :: HasSrcSpan name @@ -165,7 +171,7 @@ getDocumentation sources targetName = fromMaybe [] $ do docHeaders :: [RealLocated AnnotationComment] -> [T.Text] docHeaders = mapMaybe (\(L _ x) -> wrk x) - where + where wrk = \case -- When `Opt_Haddock` is enabled. AnnDocCommentNext s -> Just $ T.pack s From cbb3aba94f3272e6361228919656c3c6a637913c Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 17:17:58 +0200 Subject: [PATCH 16/37] ghcide: Core.Compile: getDocsBatch: use Map Turn `[]` into idiomatic Map. --- ghcide/src/Development/IDE/Core/Compile.hs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index bde51c873b..114b8c9e23 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -1000,17 +1000,17 @@ getDocsBatch -> [Name] -> IO (Map.Map Name (Either String (Maybe HsDocString, Map.Map Int HsDocString))) getDocsBatch hsc_env _mod _names = do - ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ traverse findNameInfo _names + ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ Map.fromList <$> traverse findNameInfo _names case res of - Just x -> return $ Map.fromList $ fun x + Just x -> return $ fun x Nothing -> throwErrors errs where - fun :: [(Name, Either GetDocsFailure c)] -> [(Name, Either String c)] + fun :: Map.Map Name (Either GetDocsFailure c) -> Map.Map Name (Either String c) fun = - map fun1 + Map.map fun1 where - fun1 :: ((Name, Either GetDocsFailure c) -> (Name, Either String c)) - fun1 = fmap (first $ T.unpack . showGhc) + fun1 :: Either GetDocsFailure c -> Either String c + fun1 = first $ T.unpack . showGhc throwErrors = liftIO . throwIO . mkSrcErr From eec22c6de7daeef6e1a43d0a21c496d39b053e2f Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 17:26:55 +0200 Subject: [PATCH 17/37] ghcide: Core.Compile: getDocsBatch: use T.Text --- ghcide/src/Development/IDE/Core/Compile.hs | 8 ++++---- ghcide/src/Development/IDE/Spans/Documentation.hs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 114b8c9e23..667e96c361 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -998,19 +998,19 @@ getDocsBatch :: HscEnv -> Module -- ^ a moudle where the names are in scope -> [Name] - -> IO (Map.Map Name (Either String (Maybe HsDocString, Map.Map Int HsDocString))) + -> IO (Map.Map Name (Either T.Text (Maybe HsDocString, Map.Map Int HsDocString))) getDocsBatch hsc_env _mod _names = do ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ Map.fromList <$> traverse findNameInfo _names case res of Just x -> return $ fun x Nothing -> throwErrors errs where - fun :: Map.Map Name (Either GetDocsFailure c) -> Map.Map Name (Either String c) + fun :: Map.Map Name (Either GetDocsFailure c) -> Map.Map Name (Either T.Text c) fun = Map.map fun1 where - fun1 :: Either GetDocsFailure c -> Either String c - fun1 = first $ T.unpack . showGhc + fun1 :: Either GetDocsFailure c -> Either T.Text c + fun1 = first showGhc throwErrors = liftIO . throwIO . mkSrcErr diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index 03cadf368e..664280aaed 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -75,7 +75,7 @@ getDocumentationsTryGhc env mod names = do Left _ -> return mempty Right res -> fmap Map.fromList $ sequenceA $ uncurry unwrap <$> Map.toList res where - fun :: IO (Either [FileDiagnostic] (Map.Map Name (Either String (Maybe HsDocString, Map.Map Int HsDocString)))) + fun :: IO (Either [FileDiagnostic] (Map.Map Name (Either T.Text (Maybe HsDocString, Map.Map Int HsDocString)))) fun = catchSrcErrors (hsc_dflags env) "docs" $ getDocsBatch env mod names unwrap :: Name -> Either a (Maybe HsDocString, b) -> IO (Name, SpanDoc) From 153a63b7ca62456a3d28431d20177b41101cb498 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 17:46:53 +0200 Subject: [PATCH 18/37] ghcide: Core.Compile: getDocsBatch: instead of IO throw use Either Throw was vacuous - it was thrown & catched & ignored. At least it shows explicit type to process further. --- ghcide/src/Development/IDE/Core/Compile.hs | 8 +++----- ghcide/src/Development/IDE/Spans/Documentation.hs | 9 ++++----- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 667e96c361..6c10a64042 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -998,12 +998,12 @@ getDocsBatch :: HscEnv -> Module -- ^ a moudle where the names are in scope -> [Name] - -> IO (Map.Map Name (Either T.Text (Maybe HsDocString, Map.Map Int HsDocString))) + -> IO (Either ErrorMessages (Map.Map Name (Either T.Text (Maybe HsDocString, Map.Map Int HsDocString)))) getDocsBatch hsc_env _mod _names = do ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ Map.fromList <$> traverse findNameInfo _names case res of - Just x -> return $ fun x - Nothing -> throwErrors errs + Just x -> pure $ pure $ fun x + Nothing -> pure $ Left errs where fun :: Map.Map Name (Either GetDocsFailure c) -> Map.Map Name (Either T.Text c) fun = @@ -1012,8 +1012,6 @@ getDocsBatch hsc_env _mod _names = do fun1 :: Either GetDocsFailure c -> Either T.Text c fun1 = first showGhc - throwErrors = liftIO . throwIO . mkSrcErr - findNameInfo :: Name -> IOEnv (Env TcGblEnv TcLclEnv) (Name, Either GetDocsFailure (Maybe HsDocString, Map.Map Int HsDocString)) findNameInfo name = case nameModule_maybe name of diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index 664280aaed..36d6b55af2 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -33,7 +33,6 @@ import System.FilePath import Language.LSP.Types (filePathToUri, getUri) import qualified Data.Map as Map -import Development.IDE.Types.Diagnostics (FileDiagnostic) mkDocMap :: HscEnv @@ -72,11 +71,11 @@ getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO (Map.Map Name SpanDo getDocumentationsTryGhc env mod names = do res <- fun case res of - Left _ -> return mempty - Right res -> fmap Map.fromList $ sequenceA $ uncurry unwrap <$> Map.toList res + Left _ -> return mempty -- catchSrcErrors (hsc_dflags env) "docs" + Right res -> fmap Map.fromList $ sequenceA $ uncurry unwrap <$> Map.toList res where - fun :: IO (Either [FileDiagnostic] (Map.Map Name (Either T.Text (Maybe HsDocString, Map.Map Int HsDocString)))) - fun = catchSrcErrors (hsc_dflags env) "docs" $ getDocsBatch env mod names + fun :: IO (Either ErrorMessages (Map.Map Name (Either T.Text (Maybe HsDocString, Map.Map Int HsDocString)))) + fun = getDocsBatch env mod names unwrap :: Name -> Either a (Maybe HsDocString, b) -> IO (Name, SpanDoc) unwrap name a = (name,) . extractDocString a <$> getSpanDocUris name From 48d95dce4855ffece487b5080b19e2ea235f1821 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 18:06:58 +0200 Subject: [PATCH 19/37] ghcide: Core.Compile: getDocsBatch: no faking ArgMap, say Maybe We can not process/reason on the ArgDoc logic - if we pretend no docs are docs. It is also aligns with main doc blocks processing. --- ghcide/src/Development/IDE/Core/Compile.hs | 12 ++++++------ ghcide/src/Development/IDE/Spans/Documentation.hs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 6c10a64042..c5d17427b3 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -998,12 +998,12 @@ getDocsBatch :: HscEnv -> Module -- ^ a moudle where the names are in scope -> [Name] - -> IO (Either ErrorMessages (Map.Map Name (Either T.Text (Maybe HsDocString, Map.Map Int HsDocString)))) + -> IO (Either ErrorMessages (Map.Map Name (Either T.Text (Maybe HsDocString, Maybe (Map.Map Int HsDocString))))) getDocsBatch hsc_env _mod _names = do ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ Map.fromList <$> traverse findNameInfo _names - case res of - Just x -> pure $ pure $ fun x - Nothing -> pure $ Left errs + pure $ case res of + Just x -> pure $ fun x + Nothing -> Left errs where fun :: Map.Map Name (Either GetDocsFailure c) -> Map.Map Name (Either T.Text c) fun = @@ -1012,7 +1012,7 @@ getDocsBatch hsc_env _mod _names = do fun1 :: Either GetDocsFailure c -> Either T.Text c fun1 = first showGhc - findNameInfo :: Name -> IOEnv (Env TcGblEnv TcLclEnv) (Name, Either GetDocsFailure (Maybe HsDocString, Map.Map Int HsDocString)) + findNameInfo :: Name -> IOEnv (Env TcGblEnv TcLclEnv) (Name, Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString))) findNameInfo name = case nameModule_maybe name of Nothing -> return (name, Left $ NameHasNoModule name) @@ -1026,7 +1026,7 @@ getDocsBatch hsc_env _mod _names = do pure . (name,) $ if isNothing mb_doc_hdr && Map.null dmap && Map.null amap then Left $ NoDocsInIface mod $ compiled name - else Right (Map.lookup name dmap, Map.findWithDefault mempty name amap) + else Right (Map.lookup name dmap, Map.lookup name amap) compiled n = -- TODO: Find a more direct indicator. case nameSrcLoc n of diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index 36d6b55af2..e0c49fa1f5 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -74,7 +74,7 @@ getDocumentationsTryGhc env mod names = do Left _ -> return mempty -- catchSrcErrors (hsc_dflags env) "docs" Right res -> fmap Map.fromList $ sequenceA $ uncurry unwrap <$> Map.toList res where - fun :: IO (Either ErrorMessages (Map.Map Name (Either T.Text (Maybe HsDocString, Map.Map Int HsDocString)))) + fun :: IO (Either ErrorMessages (Map.Map Name (Either T.Text (Maybe HsDocString, Maybe (Map.Map Int HsDocString))))) fun = getDocsBatch env mod names unwrap :: Name -> Either a (Maybe HsDocString, b) -> IO (Name, SpanDoc) From bbc918aecf8735ac42f94fa05d34b893fe4c83f0 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 18:21:19 +0200 Subject: [PATCH 20/37] ghcide: Core.Compile: getDocsBatch: use idiomatic Map.mapWithKey --- ghcide/src/Development/IDE/Spans/Documentation.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index e0c49fa1f5..eeb002c6fd 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -72,13 +72,13 @@ getDocumentationsTryGhc env mod names = do res <- fun case res of Left _ -> return mempty -- catchSrcErrors (hsc_dflags env) "docs" - Right res -> fmap Map.fromList $ sequenceA $ uncurry unwrap <$> Map.toList res + Right res -> sequenceA $ Map.mapWithKey unwrap res where fun :: IO (Either ErrorMessages (Map.Map Name (Either T.Text (Maybe HsDocString, Maybe (Map.Map Int HsDocString))))) fun = getDocsBatch env mod names - unwrap :: Name -> Either a (Maybe HsDocString, b) -> IO (Name, SpanDoc) - unwrap name a = (name,) . extractDocString a <$> getSpanDocUris name + unwrap :: Name -> Either a (Maybe HsDocString, b) -> IO SpanDoc + unwrap name a = extractDocString a <$> getSpanDocUris name where extractDocString :: Either b1 (Maybe HsDocString, b2) -> SpanDocUris -> SpanDoc -- 2021-11-17: FIXME: ArgDocs get dropped here - instead propagate them. From e638fcb230f450de44fdbf6bcd78cdf894054b8f Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 19:03:26 +0200 Subject: [PATCH 21/37] ghcide: Core.Compile: getDocsBatch: give explicit GetDocsFailure Showing error should be explicit, & conversion of error type should be a separate handling. This would also allow to establish proper processing for all these exception types. --- ghcide/src/Development/IDE/Core/Compile.hs | 19 +++++-------------- .../Development/IDE/Spans/Documentation.hs | 5 +---- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index c5d17427b3..156dc02d2c 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -39,7 +39,6 @@ import Development.IDE.GHC.Error import Development.IDE.GHC.Orphans () import Development.IDE.GHC.Util import Development.IDE.GHC.Warnings -import Development.IDE.Spans.Common import Development.IDE.Types.Diagnostics import Development.IDE.Types.Location import Development.IDE.Types.Options @@ -75,7 +74,7 @@ import Control.Lens hiding (List) import Control.Monad.Except import Control.Monad.Extra import Control.Monad.Trans.Except -import Data.Bifunctor (first, second) +import Data.Bifunctor (second) import qualified Data.ByteString as BS import qualified Data.DList as DL import Data.IORef @@ -104,6 +103,7 @@ import Data.Functor import qualified Data.HashMap.Strict as HashMap import Data.Map (Map) import Data.Tuple.Extra (dupe) +import Data.Either.Extra (maybeToEither) import Data.Unique as Unique import Development.IDE.Core.Tracing (withTrace) import Development.IDE.GHC.Compat.Util (emptyUDFM, plusUDFM_C) @@ -998,20 +998,11 @@ getDocsBatch :: HscEnv -> Module -- ^ a moudle where the names are in scope -> [Name] - -> IO (Either ErrorMessages (Map.Map Name (Either T.Text (Maybe HsDocString, Maybe (Map.Map Int HsDocString))))) + -> IO (Either ErrorMessages (Map.Map Name (Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString))))) getDocsBatch hsc_env _mod _names = do ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ Map.fromList <$> traverse findNameInfo _names - pure $ case res of - Just x -> pure $ fun x - Nothing -> Left errs - where - fun :: Map.Map Name (Either GetDocsFailure c) -> Map.Map Name (Either T.Text c) - fun = - Map.map fun1 - where - fun1 :: Either GetDocsFailure c -> Either T.Text c - fun1 = first showGhc - + pure $ maybeToEither errs res + where findNameInfo :: Name -> IOEnv (Env TcGblEnv TcLclEnv) (Name, Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString))) findNameInfo name = case nameModule_maybe name of diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index eeb002c6fd..ab347a056c 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -69,14 +69,11 @@ getDocumentationTryGhc env mod n = fromJust . Map.lookup n <$> getDocumentations getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO (Map.Map Name SpanDoc) getDocumentationsTryGhc env mod names = do - res <- fun + res <- getDocsBatch env mod names case res of Left _ -> return mempty -- catchSrcErrors (hsc_dflags env) "docs" Right res -> sequenceA $ Map.mapWithKey unwrap res where - fun :: IO (Either ErrorMessages (Map.Map Name (Either T.Text (Maybe HsDocString, Maybe (Map.Map Int HsDocString))))) - fun = getDocsBatch env mod names - unwrap :: Name -> Either a (Maybe HsDocString, b) -> IO SpanDoc unwrap name a = extractDocString a <$> getSpanDocUris name where From 177ca95f8efe89a7a612fee62d2edb191fb4f74c Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 21:03:21 +0200 Subject: [PATCH 22/37] ghcide: Core.Compile: getDocsBatch: add doc --- ghcide/src/Development/IDE/Core/Compile.hs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 156dc02d2c..ff5246035a 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -213,9 +213,7 @@ tcRnModule hsc_env keep_lbls pmod = do HsParsedModule { hpm_module = parsedSource pmod, hpm_src_files = pm_extra_src_files pmod, hpm_annotations = pm_annotations pmod } - let rn_info = case mrn_info of - Just x -> x - Nothing -> error "no renamed info tcRnModule" + let rn_info = fromMaybe (error "no renamed info tcRnModule") mrn_info pure (TcModuleResult pmod rn_info tc_gbl_env splices False) mkHiFileResultNoCompile :: HscEnv -> TcModuleResult -> IO HiFileResult @@ -999,6 +997,7 @@ getDocsBatch -> Module -- ^ a moudle where the names are in scope -> [Name] -> IO (Either ErrorMessages (Map.Map Name (Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString))))) + -- ^ Return a 'Map' of 'Name's to 'Either' (no docs messages) (general doc body & arg docs) getDocsBatch hsc_env _mod _names = do ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ Map.fromList <$> traverse findNameInfo _names pure $ maybeToEither errs res @@ -1016,9 +1015,9 @@ getDocsBatch hsc_env _mod _names = do <- loadModuleInterface "getModuleInterface" mod pure . (name,) $ if isNothing mb_doc_hdr && Map.null dmap && Map.null amap - then Left $ NoDocsInIface mod $ compiled name + then Left $ NoDocsInIface mod $ isCompiled name else Right (Map.lookup name dmap, Map.lookup name amap) - compiled n = + isCompiled n = -- TODO: Find a more direct indicator. case nameSrcLoc n of RealSrcLoc {} -> False @@ -1039,7 +1038,7 @@ lookupName hsc_env mod name = do tcthing <- tcLookup name case tcthing of AGlobal thing -> return thing - ATcId{tct_id=id} -> return (AnId id) + ATcId{tct_id=id} -> return $ AnId id _ -> panic "tcRnLookupName'" return res From 9de21af41cc62d52dd8f2461a9f3bb310e4ea30b Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 23:00:27 +0200 Subject: [PATCH 23/37] ghcide: Spans.Documentation: getDocumentationsTryGhc: clean-up --- ghcide/src/Development/IDE/Core/Compile.hs | 1 + ghcide/src/Development/IDE/Spans/Common.hs | 1 + .../Development/IDE/Spans/Documentation.hs | 30 ++++++++++--------- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index ff5246035a..7858bb3c7d 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -1014,6 +1014,7 @@ getDocsBatch hsc_env _mod _names = do } <- loadModuleInterface "getModuleInterface" mod pure . (name,) $ + -- 2021-11-17: NOTE: one does not simply check into Mordor (not 1 mode) if isNothing mb_doc_hdr && Map.null dmap && Map.null amap then Left $ NoDocsInIface mod $ isCompiled name else Right (Map.lookup name dmap, Map.lookup name amap) diff --git a/ghcide/src/Development/IDE/Spans/Common.hs b/ghcide/src/Development/IDE/Spans/Common.hs index 0a60120138..0717ff3147 100644 --- a/ghcide/src/Development/IDE/Spans/Common.hs +++ b/ghcide/src/Development/IDE/Spans/Common.hs @@ -40,6 +40,7 @@ showGhc = showSD . ppr showSD :: SDoc -> T.Text showSD = T.pack . unsafePrintSDoc +-- | Print name dropping unique tagging. showNameWithoutUniques :: Outputable a => a -> T.Text showNameWithoutUniques = T.pack . printNameWithoutUniques diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index ab347a056c..3df2dea035 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -15,6 +15,7 @@ module Development.IDE.Spans.Documentation ( import Control.Monad import Control.Monad.IO.Class import Control.Monad.Extra (findM) +import Data.Bool (bool) import Data.Either import Data.Foldable import Data.List.Extra @@ -32,7 +33,6 @@ import System.Directory import System.FilePath import Language.LSP.Types (filePathToUri, getUri) -import qualified Data.Map as Map mkDocMap :: HscEnv @@ -65,14 +65,14 @@ lookupKind env mod = getDocumentationTryGhc :: HscEnv -> Module -> Name -> IO SpanDoc -- 2021-11-17: FIXME: Code uses batch search for singleton & assumes that search always succeeds. -getDocumentationTryGhc env mod n = fromJust . Map.lookup n <$> getDocumentationsTryGhc env mod [n] +getDocumentationTryGhc env mod n = fromJust . M.lookup n <$> getDocumentationsTryGhc env mod [n] -getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO (Map.Map Name SpanDoc) +getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO (M.Map Name SpanDoc) getDocumentationsTryGhc env mod names = do res <- getDocsBatch env mod names case res of Left _ -> return mempty -- catchSrcErrors (hsc_dflags env) "docs" - Right res -> sequenceA $ Map.mapWithKey unwrap res + Right res -> sequenceA $ M.mapWithKey unwrap res where unwrap :: Name -> Either a (Maybe HsDocString, b) -> IO SpanDoc unwrap name a = extractDocString a <$> getSpanDocUris name @@ -88,19 +88,21 @@ getDocumentationsTryGhc env mod names = do (docFu, srcFu) <- case nameModule_maybe name of Just mod -> liftIO $ do - doc <- toFileUriText $ lookupDocHtmlForModule env mod - src <- toFileUriText $ lookupSrcHtmlForModule env mod + let + toUriFileText :: (HscEnv -> Module -> IO (Maybe FilePath)) -> IO (Maybe T.Text) + toUriFileText f = (fmap . fmap) (getUri . filePathToUri) $ f env mod + doc <- toUriFileText lookupDocHtmlForModule + src <- toUriFileText lookupSrcHtmlForModule return (doc, src) Nothing -> pure mempty - let docUri = (<> "#" <> selector <> showNameWithoutUniques name) <$> docFu - srcUri = (<> "#" <> showNameWithoutUniques name) <$> srcFu - selector - | isValName name = "v:" - | otherwise = "t:" + let + embelishUri :: Functor f => T.Text -> f T.Text -> f T.Text + embelishUri f = fmap (<> "#" <> f <> showNameWithoutUniques name) + + docUri = embelishUri (bool "t:" "v:" $ isValName name) docFu + srcUri = embelishUri mempty srcFu + return $ SpanDocUris docUri srcUri - where - toFileUriText :: IO (Maybe FilePath) -> IO (Maybe T.Text) - toFileUriText = (fmap . fmap) (getUri . filePathToUri) getDocumentation :: HasSrcSpan name From 2bc03597542083fbea098c160d261e2b036f3927 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Thu, 18 Nov 2021 20:20:46 +0200 Subject: [PATCH 24/37] ghcide: m refactors --- ghcide/src/Development/IDE/Core/Compile.hs | 3 ++- ghcide/src/Development/IDE/Core/Rules.hs | 11 +++++------ ghcide/src/Development/IDE/Spans/AtPoint.hs | 11 ++++++----- ghcide/src/Development/IDE/Spans/Common.hs | 4 +--- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 7858bb3c7d..477280a42d 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -694,7 +694,7 @@ mergeEnvs :: HscEnv -> [ModSummary] -> [HomeModInfo] -> [HscEnv] -> IO HscEnv mergeEnvs env extraModSummaries extraMods envs = do prevFinderCache <- concatFC <$> mapM (readIORef . hsc_FC) envs let ims = map (Compat.installedModule (homeUnitId_ $ hsc_dflags env) . moduleName . ms_mod) extraModSummaries - ifrs = zipWith (\ms -> InstalledFound (ms_location ms)) extraModSummaries ims + ifrs = zipWith (InstalledFound . ms_location) extraModSummaries ims newFinderCache <- newIORef $ foldl' (\fc (im, ifr) -> Compat.extendInstalledModuleEnv fc im ifr) prevFinderCache @@ -996,6 +996,7 @@ getDocsBatch :: HscEnv -> Module -- ^ a moudle where the names are in scope -> [Name] + -- 2021-11-18: NOTE: Map Int would become IntMap if next GHCs. -> IO (Either ErrorMessages (Map.Map Name (Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString))))) -- ^ Return a 'Map' of 'Name's to 'Either' (no docs messages) (general doc body & arg docs) getDocsBatch hsc_env _mod _names = do diff --git a/ghcide/src/Development/IDE/Core/Rules.hs b/ghcide/src/Development/IDE/Core/Rules.hs index 14ff4a29fa..449a58c0e2 100644 --- a/ghcide/src/Development/IDE/Core/Rules.hs +++ b/ghcide/src/Development/IDE/Core/Rules.hs @@ -574,9 +574,9 @@ getBindingsRule :: Rules () getBindingsRule = define $ \GetBindings f -> do HAR{hieKind=kind, refMap=rm} <- use_ GetHieAst f - case kind of - HieFresh -> pure ([], Just $ bindings rm) - HieFromDisk _ -> pure ([], Nothing) + pure . (mempty,) $ case kind of + HieFresh -> Just $ bindings rm + HieFromDisk _ -> Nothing getDocMapRule :: Rules () getDocMapRule = @@ -688,8 +688,7 @@ loadGhcSession ghcSessionDepsConfig = do afp <- liftIO $ makeAbsolute fp let nfp = toNormalizedFilePath' afp itExists <- getFileExists nfp - when itExists $ void $ do - use_ GetModificationTime nfp + when itExists $ void $ use_ GetModificationTime nfp mapM_ addDependency deps opts <- getIdeOptions @@ -722,7 +721,7 @@ ghcSessionDepsDefinition ghcSessionDepsDefinition fullModSummary GhcSessionDepsConfig{..} env file = do let hsc = hscEnv env - mbdeps <- mapM(fmap artifactFilePath . snd) <$> use_ GetLocatedImports file + mbdeps <- traverse (fmap artifactFilePath . snd) <$> use_ GetLocatedImports file case mbdeps of Nothing -> return Nothing Just deps -> do diff --git a/ghcide/src/Development/IDE/Spans/AtPoint.hs b/ghcide/src/Development/IDE/Spans/AtPoint.hs index 29edb0c6fd..9f2024b9ea 100644 --- a/ghcide/src/Development/IDE/Spans/AtPoint.hs +++ b/ghcide/src/Development/IDE/Spans/AtPoint.hs @@ -54,6 +54,7 @@ import Data.List.Extra (dropEnd1, nubOrd) import Data.Version (showVersion) import HieDb hiding (pointCommand) import System.Directory (doesFileExist) +import Data.Bool (bool) -- | Gives a Uri for the module, given the .hie file location and the the module info -- The Bool denotes if it is a boot module @@ -63,13 +64,13 @@ type LookupModule m = FilePath -> ModuleName -> Unit -> Bool -> MaybeT m Uri newtype FOIReferences = FOIReferences (HM.HashMap NormalizedFilePath (HieAstResult, PositionMapping)) computeTypeReferences :: Foldable f => f (HieAST Type) -> M.Map Name [Span] -computeTypeReferences = foldr (\ast m -> M.unionWith (++) (go ast) m) M.empty +computeTypeReferences = foldr (\ast m -> M.unionWith (<>) (go ast) m) M.empty where go ast = M.unionsWith (++) (this : map go (nodeChildren ast)) where this = M.fromListWith (++) $ map (, [nodeSpan ast]) - $ concatMap namesInType + $ foldMap namesInType $ mapMaybe (\x -> guard (not $ all isOccurrence $ identInfo x) *> identType x) $ M.elems $ nodeIdentifiers $ nodeInfo ast @@ -212,9 +213,9 @@ atPoint IdeOptions{} (HAR _ hf _ _ kind) (DKMap dm km) env pos = listToMaybe $ p -- | Get hover info for values/data hoverInfo ast = (Just range, prettyNames ++ pTypes) where - pTypes - | Prelude.length names == 1 = dropEnd1 $ map wrapHaskell prettyConcreteTypes - | otherwise = map wrapHaskell prettyConcreteTypes + pTypes = + bool id dropEnd1 (Prelude.length names == 1) + $ map wrapHaskell prettyConcreteTypes range = realSrcSpanToRange $ nodeSpan ast diff --git a/ghcide/src/Development/IDE/Spans/Common.hs b/ghcide/src/Development/IDE/Spans/Common.hs index 0717ff3147..9cf1d7faf9 100644 --- a/ghcide/src/Development/IDE/Spans/Common.hs +++ b/ghcide/src/Development/IDE/Spans/Common.hs @@ -97,9 +97,7 @@ spanDocToMarkdownForTest = haddockToMarkdown . H.toRegular . H._doc . H.parseParas Nothing -- Simple (and a bit hacky) conversion from Haddock markup to Markdown -haddockToMarkdown - :: H.DocH String String -> String - +haddockToMarkdown :: H.DocH String String -> String haddockToMarkdown H.DocEmpty = "" haddockToMarkdown (H.DocAppend d1 d2) From bc2978b64ee5e95231e0be78a31135dc77895c62 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Fri, 19 Nov 2021 21:05:49 +0200 Subject: [PATCH 25/37] ghcide: Core.Compile: add getDocsNonInteractive This function was "inspired" from GHC code of `getDocs`. Since `getDocsBatch` is not really used for batch - only for singleton elements, lets make 1 element processing function & use it. --- ghcide/src/Development/IDE/Core/Compile.hs | 52 +++++++++++----------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 477280a42d..b4e3e334e6 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -989,9 +989,33 @@ mkDetailsFromIface session iface linkable = do initIfaceLoad hsc' (typecheckIface iface) return (HomeModInfo iface details linkable) --- | Non-interactive, batch version of 'InteractiveEval.getDocs'. + +-- | Non-interactive modification of 'GHC.Runtime.Eval.getDocs'. -- The interactive paths create problems in ghc-lib builds ---- and leads to fun errors like "Cannot continue after interface file error". +--- and lead to fun errors like "Cannot continue after interface file error". +getDocsNonInteractive :: Name -> IOEnv (Env TcGblEnv TcLclEnv) (Name, Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString))) +getDocsNonInteractive name = do + case nameModule_maybe name of + Nothing -> return (name, Left $ NameHasNoModule name) + Just mod -> do + ModIface + { mi_doc_hdr = mb_doc_hdr + , mi_decl_docs = DeclDocMap dmap + , mi_arg_docs = ArgDocMap amap + } + <- loadModuleInterface "getModuleInterface" mod + let + isNameCompiled = + -- TODO: Find a more direct indicator. + case nameSrcLoc name of + RealSrcLoc {} -> False + UnhelpfulLoc {} -> True + pure . (name,) $ + if isNothing mb_doc_hdr && Map.null dmap && Map.null amap + then Left $ NoDocsInIface mod isNameCompiled + else Right (Map.lookup name dmap, Map.lookup name amap) + +-- | Non-interactive, batch version of 'GHC.Runtime.Eval.getDocs'. getDocsBatch :: HscEnv -> Module -- ^ a moudle where the names are in scope @@ -1000,30 +1024,8 @@ getDocsBatch -> IO (Either ErrorMessages (Map.Map Name (Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString))))) -- ^ Return a 'Map' of 'Name's to 'Either' (no docs messages) (general doc body & arg docs) getDocsBatch hsc_env _mod _names = do - ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ Map.fromList <$> traverse findNameInfo _names + ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ Map.fromList <$> traverse getDocsNonInteractive _names pure $ maybeToEither errs res - where - findNameInfo :: Name -> IOEnv (Env TcGblEnv TcLclEnv) (Name, Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString))) - findNameInfo name = - case nameModule_maybe name of - Nothing -> return (name, Left $ NameHasNoModule name) - Just mod -> do - ModIface - { mi_doc_hdr = mb_doc_hdr - , mi_decl_docs = DeclDocMap dmap - , mi_arg_docs = ArgDocMap amap - } - <- loadModuleInterface "getModuleInterface" mod - pure . (name,) $ - -- 2021-11-17: NOTE: one does not simply check into Mordor (not 1 mode) - if isNothing mb_doc_hdr && Map.null dmap && Map.null amap - then Left $ NoDocsInIface mod $ isCompiled name - else Right (Map.lookup name dmap, Map.lookup name amap) - isCompiled n = - -- TODO: Find a more direct indicator. - case nameSrcLoc n of - RealSrcLoc {} -> False - UnhelpfulLoc {} -> True fakeSpan :: RealSrcSpan fakeSpan = realSrcLocSpan $ mkRealSrcLoc (Util.fsLit "") 1 1 From 641d785b5ea038316bc89b38e5359723ae5edccf Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Fri, 26 Nov 2021 16:37:36 +0200 Subject: [PATCH 26/37] ghcide: Core.Compile: add diagMsgs --- ghcide/src/Development/IDE/Core/Compile.hs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index b4e3e334e6..2fe2ea2184 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -88,7 +88,6 @@ import System.Directory import System.FilePath import System.IO.Extra (fixIO, newTempFileWithin) --- GHC API imports -- GHC API imports import GHC (GetDocsFailure (..), mgModSummaries, @@ -807,6 +806,8 @@ getModSummaryFromImports env fp modTime contents = do , fingerPrintImports ] ++ map Util.fingerprintString opts +diagMsgs :: DynFlags -> Util.Bag (MsgEnvelope DecoratedSDoc) -> [FileDiagnostic] +diagMsgs = diagFromErrMsgs "parser" -- | Parse only the module header parseHeader @@ -824,7 +825,7 @@ parseHeader dflags filename contents = do case unP Compat.parseHeader (initParserState (initParserOpts dflags) contents loc) of #if MIN_VERSION_ghc(8,10,0) PFailed pst -> - throwE $ diagFromErrMsgs "parser" dflags $ getErrorMessages pst dflags + throwE $ diagMsgs dflags $ getErrorMessages pst dflags #else PFailed _ locErr msgErr -> throwE $ diagFromErrMsg "parser" dflags $ mkPlainErrMsg dflags locErr msgErr @@ -841,9 +842,9 @@ parseHeader dflags filename contents = do -- errors are those from which a parse tree just can't -- be produced. unless (null errs) $ - throwE $ diagFromErrMsgs "parser" dflags (fmap pprError errs) + throwE $ diagMsgs dflags (fmap pprError errs) - let warnings = diagFromErrMsgs "parser" dflags (fmap pprWarning warns) + let warnings = diagMsgs dflags (fmap pprWarning warns) return (warnings, rdr_module) -- | Given a buffer, flags, and file path, produce a @@ -861,7 +862,7 @@ parseFileContents env customPreprocessor filename ms = do contents = fromJust $ ms_hspp_buf ms case unP Compat.parseModule (initParserState (initParserOpts dflags) contents loc) of #if MIN_VERSION_ghc(8,10,0) - PFailed pst -> throwE $ diagFromErrMsgs "parser" dflags $ getErrorMessages pst dflags + PFailed pst -> throwE $ diagMsgs dflags $ getErrorMessages pst dflags #else PFailed _ locErr msgErr -> throwE $ diagFromErrMsg "parser" dflags $ mkPlainErrMsg dflags locErr msgErr @@ -882,7 +883,7 @@ parseFileContents env customPreprocessor filename ms = do -- errors are those from which a parse tree just can't -- be produced. unless (null errs) $ - throwE $ diagFromErrMsgs "parser" dflags errs + throwE $ diagMsgs dflags errs -- Ok, we got here. It's safe to continue. let IdePreprocessedSource preproc_warns errs parsed = customPreprocessor rdr_module @@ -920,7 +921,7 @@ parseFileContents env customPreprocessor filename ms = do srcs2 <- liftIO $ filterM doesFileExist srcs1 let pm = mkParsedModule ms parsed' srcs2 hpm_annotations - warnings = diagFromErrMsgs "parser" dflags warns + warnings = diagMsgs dflags warns pure (warnings ++ preproc_warnings, pm) loadHieFile :: Compat.NameCacheUpdater -> FilePath -> IO GHC.HieFile From d1fabad89ee9f37d5dc515921f31b93158c7b956 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Fri, 26 Nov 2021 21:26:20 +0200 Subject: [PATCH 27/37] ghcide: Core.Compile: add getDocsNonInteractive{',} `getDocsBatch` cuurently (& before) used only for single name retrieval function. Use of it is in `Documentation` module `getDocumentationTryGhc` where it wraps arg into singleton & gives to `getDocsBatch` & then recieves a Map with 1 entry & unsafely "lookups" doc in it. This work is to supply the proper single name retrieval-optimized version to stop that `getDocsBatch` there. & further ideally `getDocumentationTryGhc` uses single-retrieval & `getDocumentationsTryGhc` uses a batch mode & batch mode gets optimized along the lines of: https://github.com/haskell/haskell-language-server/pull/2371 --- ghcide/src/Development/IDE/Core/Compile.hs | 39 +++++++++++++++------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 2fe2ea2184..c5c3658d22 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -28,6 +28,7 @@ module Development.IDE.Core.Compile , loadInterface , loadModulesHome , setupFinderCache + , getDocsNonInteractive , getDocsBatch , lookupName ,mergeEnvs) where @@ -990,12 +991,20 @@ mkDetailsFromIface session iface linkable = do initIfaceLoad hsc' (typecheckIface iface) return (HomeModInfo iface details linkable) +fakeSpan :: RealSrcSpan +fakeSpan = realSrcLocSpan $ mkRealSrcLoc (Util.fsLit "") 1 1 --- | Non-interactive modification of 'GHC.Runtime.Eval.getDocs'. --- The interactive paths create problems in ghc-lib builds ---- and lead to fun errors like "Cannot continue after interface file error". -getDocsNonInteractive :: Name -> IOEnv (Env TcGblEnv TcLclEnv) (Name, Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString))) -getDocsNonInteractive name = do +initTypecheckEnv :: HscEnv -> Module -> TcRn r -> IO (Messages, Maybe r) +initTypecheckEnv hsc_env mod = initTc hsc_env HsSrcFile False mod fakeSpan + +getDocsNonInteractive' + :: Name + -> IOEnv + (Env TcGblEnv TcLclEnv) + (Name, + Either + GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString))) +getDocsNonInteractive' name = case nameModule_maybe name of Nothing -> return (name, Left $ NameHasNoModule name) Just mod -> do @@ -1007,7 +1016,7 @@ getDocsNonInteractive name = do <- loadModuleInterface "getModuleInterface" mod let isNameCompiled = - -- TODO: Find a more direct indicator. + -- comment from GHC: Find a more direct indicator. case nameSrcLoc name of RealSrcLoc {} -> False UnhelpfulLoc {} -> True @@ -1016,6 +1025,15 @@ getDocsNonInteractive name = do then Left $ NoDocsInIface mod isNameCompiled else Right (Map.lookup name dmap, Map.lookup name amap) +-- | Non-interactive modification of 'GHC.Runtime.Eval.getDocs'. +-- The interactive paths create problems in ghc-lib builds +--- and lead to fun errors like "Cannot continue after interface file error". +getDocsNonInteractive :: HscEnv -> Module -> Name -> IO (Either ErrorMessages (Name, Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString)))) +getDocsNonInteractive hsc_env mod name = do + ((_warns,errs), res) <- initTypecheckEnv hsc_env mod $ getDocsNonInteractive' name + pure $ maybeToEither errs res + + -- | Non-interactive, batch version of 'GHC.Runtime.Eval.getDocs'. getDocsBatch :: HscEnv @@ -1024,13 +1042,10 @@ getDocsBatch -- 2021-11-18: NOTE: Map Int would become IntMap if next GHCs. -> IO (Either ErrorMessages (Map.Map Name (Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString))))) -- ^ Return a 'Map' of 'Name's to 'Either' (no docs messages) (general doc body & arg docs) -getDocsBatch hsc_env _mod _names = do - ((_warns,errs), res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ Map.fromList <$> traverse getDocsNonInteractive _names +getDocsBatch hsc_env mod names = do + ((_warns,errs), res) <- initTypecheckEnv hsc_env mod $ Map.fromList <$> traverse getDocsNonInteractive' names pure $ maybeToEither errs res -fakeSpan :: RealSrcSpan -fakeSpan = realSrcLocSpan $ mkRealSrcLoc (Util.fsLit "") 1 1 - -- | Non-interactive, batch version of 'InteractiveEval.lookupNames'. -- The interactive paths create problems in ghc-lib builds --- and leads to fun errors like "Cannot continue after interface file error". @@ -1039,7 +1054,7 @@ lookupName :: HscEnv -> Name -> IO (Maybe TyThing) lookupName hsc_env mod name = do - (_messages, res) <- initTc hsc_env HsSrcFile False mod fakeSpan $ do + (_messages, res) <- initTypecheckEnv hsc_env mod $ do tcthing <- tcLookup name case tcthing of AGlobal thing -> return thing From 926689c42f4e3716ee225df01bf1f81f471e7bd3 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Fri, 26 Nov 2021 21:51:15 +0200 Subject: [PATCH 28/37] ghcide: Documentation: getDocumentationTryGhc: implement for 1 elem --- .../Development/IDE/Spans/Documentation.hs | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index 3df2dea035..4a01e1bd6e 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -12,7 +12,6 @@ module Development.IDE.Spans.Documentation ( , mkDocMap ) where -import Control.Monad import Control.Monad.IO.Class import Control.Monad.Extra (findM) import Data.Bool (bool) @@ -65,7 +64,44 @@ lookupKind env mod = getDocumentationTryGhc :: HscEnv -> Module -> Name -> IO SpanDoc -- 2021-11-17: FIXME: Code uses batch search for singleton & assumes that search always succeeds. -getDocumentationTryGhc env mod n = fromJust . M.lookup n <$> getDocumentationsTryGhc env mod [n] +getDocumentationTryGhc env mod = fun + where + fun :: Name -> IO SpanDoc + fun name = do + res <- getDocsNonInteractive env mod name + case res of + Left _ -> pure emptySpanDoc -- catchSrcErrors (hsc_dflags env) "docs" + Right res -> uncurry unwrap res + where + unwrap :: Name -> Either a (Maybe HsDocString, b) -> IO SpanDoc + unwrap name a = extractDocString a <$> getSpanDocUris name + where + extractDocString :: Either b1 (Maybe HsDocString, b2) -> SpanDocUris -> SpanDoc + -- 2021-11-17: FIXME: ArgDocs get dropped here - instead propagate them. + extractDocString (Right (Just docs, _)) = SpanDocString docs + extractDocString _ = SpanDocText mempty + + -- | Get the uris to the documentation and source html pages if they exist + getSpanDocUris :: Name -> IO SpanDocUris + getSpanDocUris name = do + (docFu, srcFu) <- + case nameModule_maybe name of + Just mod -> liftIO $ do + let + toUriFileText :: (HscEnv -> Module -> IO (Maybe FilePath)) -> IO (Maybe T.Text) + toUriFileText f = (fmap . fmap) (getUri . filePathToUri) $ f env mod + doc <- toUriFileText lookupDocHtmlForModule + src <- toUriFileText lookupSrcHtmlForModule + return (doc, src) + Nothing -> pure mempty + let + embelishUri :: Functor f => T.Text -> f T.Text -> f T.Text + embelishUri f = fmap (<> "#" <> f <> showNameWithoutUniques name) + + docUri = embelishUri (bool "t:" "v:" $ isValName name) docFu + srcUri = embelishUri mempty srcFu + + return $ SpanDocUris docUri srcUri getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO (M.Map Name SpanDoc) getDocumentationsTryGhc env mod names = do From af17a8df6b3b0a243aa5bd74deb2ab273a172d67 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Fri, 26 Nov 2021 22:02:59 +0200 Subject: [PATCH 29/37] ghcide: Documentation: form intoSpanDoc --- .../Development/IDE/Spans/Documentation.hs | 86 ++++++------------- 1 file changed, 26 insertions(+), 60 deletions(-) diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index 4a01e1bd6e..0f4e921d20 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -62,71 +62,23 @@ lookupKind :: HscEnv -> Module -> Name -> IO (Maybe TyThing) lookupKind env mod = fmap (fromRight Nothing) . catchSrcErrors (hsc_dflags env) "span" . lookupName env mod -getDocumentationTryGhc :: HscEnv -> Module -> Name -> IO SpanDoc --- 2021-11-17: FIXME: Code uses batch search for singleton & assumes that search always succeeds. -getDocumentationTryGhc env mod = fun - where - fun :: Name -> IO SpanDoc - fun name = do - res <- getDocsNonInteractive env mod name - case res of - Left _ -> pure emptySpanDoc -- catchSrcErrors (hsc_dflags env) "docs" - Right res -> uncurry unwrap res - where - unwrap :: Name -> Either a (Maybe HsDocString, b) -> IO SpanDoc - unwrap name a = extractDocString a <$> getSpanDocUris name - where - extractDocString :: Either b1 (Maybe HsDocString, b2) -> SpanDocUris -> SpanDoc - -- 2021-11-17: FIXME: ArgDocs get dropped here - instead propagate them. - extractDocString (Right (Just docs, _)) = SpanDocString docs - extractDocString _ = SpanDocText mempty - - -- | Get the uris to the documentation and source html pages if they exist - getSpanDocUris :: Name -> IO SpanDocUris - getSpanDocUris name = do - (docFu, srcFu) <- - case nameModule_maybe name of - Just mod -> liftIO $ do - let - toUriFileText :: (HscEnv -> Module -> IO (Maybe FilePath)) -> IO (Maybe T.Text) - toUriFileText f = (fmap . fmap) (getUri . filePathToUri) $ f env mod - doc <- toUriFileText lookupDocHtmlForModule - src <- toUriFileText lookupSrcHtmlForModule - return (doc, src) - Nothing -> pure mempty - let - embelishUri :: Functor f => T.Text -> f T.Text -> f T.Text - embelishUri f = fmap (<> "#" <> f <> showNameWithoutUniques name) - - docUri = embelishUri (bool "t:" "v:" $ isValName name) docFu - srcUri = embelishUri mempty srcFu - - return $ SpanDocUris docUri srcUri - -getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO (M.Map Name SpanDoc) -getDocumentationsTryGhc env mod names = do - res <- getDocsBatch env mod names - case res of - Left _ -> return mempty -- catchSrcErrors (hsc_dflags env) "docs" - Right res -> sequenceA $ M.mapWithKey unwrap res +intoSpanDoc :: HscEnv -> Name -> Either a (Maybe HsDocString, b) -> IO SpanDoc +intoSpanDoc env name a = extractDocString a <$> getSpanDocUris name where - unwrap :: Name -> Either a (Maybe HsDocString, b) -> IO SpanDoc - unwrap name a = extractDocString a <$> getSpanDocUris name - where - extractDocString :: Either b1 (Maybe HsDocString, b2) -> SpanDocUris -> SpanDoc - -- 2021-11-17: FIXME: ArgDocs get dropped here - instead propagate them. - extractDocString (Right (Just docs, _)) = SpanDocString docs - extractDocString _ = SpanDocText mempty - - -- | Get the uris to the documentation and source html pages if they exist - getSpanDocUris :: Name -> IO SpanDocUris - getSpanDocUris name = do + extractDocString :: Either b1 (Maybe HsDocString, b2) -> SpanDocUris -> SpanDoc + -- 2021-11-17: FIXME: ArgDocs get dropped here - instead propagate them. + extractDocString (Right (Just docs, _)) = SpanDocString docs + extractDocString _ = SpanDocText mempty + + -- | Get the uris to the documentation and source html pages if they exist + getSpanDocUris :: Name -> IO SpanDocUris + getSpanDocUris name = do (docFu, srcFu) <- case nameModule_maybe name of Just mod -> liftIO $ do let - toUriFileText :: (HscEnv -> Module -> IO (Maybe FilePath)) -> IO (Maybe T.Text) - toUriFileText f = (fmap . fmap) (getUri . filePathToUri) $ f env mod + toUriFileText :: (HscEnv -> Module -> IO (Maybe FilePath)) -> IO (Maybe T.Text) + toUriFileText f = (fmap . fmap) (getUri . filePathToUri) $ f env mod doc <- toUriFileText lookupDocHtmlForModule src <- toUriFileText lookupSrcHtmlForModule return (doc, src) @@ -140,6 +92,20 @@ getDocumentationsTryGhc env mod names = do return $ SpanDocUris docUri srcUri +getDocumentationTryGhc :: HscEnv -> Module -> Name -> IO SpanDoc +getDocumentationTryGhc env mod name = do + res <- getDocsNonInteractive env mod name + case res of + Left _ -> pure emptySpanDoc + Right res -> uncurry (intoSpanDoc env) res + +getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO (M.Map Name SpanDoc) +getDocumentationsTryGhc env mod names = do + res <- getDocsBatch env mod names + case res of + Left _ -> return mempty + Right res -> sequenceA $ M.mapWithKey (intoSpanDoc env) res + getDocumentation :: HasSrcSpan name => [ParsedModule] -- ^ All of the possible modules it could be defined in. From 5dee794d0fab04b729cc98b6e867fba1a9d6e33f Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Fri, 26 Nov 2021 23:03:06 +0200 Subject: [PATCH 30/37] ghcide: Documentation: mkDocsMap: m clean-up --- ghcide/src/Development/IDE/Core/Compile.hs | 7 ++++--- ghcide/src/Development/IDE/Spans/Documentation.hs | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index c5c3658d22..8473129ad2 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -991,11 +991,12 @@ mkDetailsFromIface session iface linkable = do initIfaceLoad hsc' (typecheckIface iface) return (HomeModInfo iface details linkable) -fakeSpan :: RealSrcSpan -fakeSpan = realSrcLocSpan $ mkRealSrcLoc (Util.fsLit "") 1 1 - initTypecheckEnv :: HscEnv -> Module -> TcRn r -> IO (Messages, Maybe r) initTypecheckEnv hsc_env mod = initTc hsc_env HsSrcFile False mod fakeSpan + where + fakeSpan :: RealSrcSpan + fakeSpan = realSrcLocSpan $ mkRealSrcLoc (Util.fsLit "") 1 1 + getDocsNonInteractive' :: Name diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index 0f4e921d20..18dd381ddf 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -44,16 +44,16 @@ mkDocMap env rm this_mod = k <- foldrM getType (tcg_type_env this_mod) names pure $ DKMap d k where - getDocs n map - | maybe True (mod ==) $ nameModule_maybe n = pure map -- we already have the docs in this_docs, or they do not exist + getDocs n mapToSpanDoc + | maybe True (mod ==) $ nameModule_maybe n = pure mapToSpanDoc -- we already have the docs in this_docs, or they do not exist | otherwise = do doc <- getDocumentationTryGhc env mod n - pure $ extendNameEnv map n doc - getType n map + pure $ extendNameEnv mapToSpanDoc n doc + getType n mapToTyThing | isTcOcc $ occName n = do kind <- lookupKind env mod n - pure $ maybe map (extendNameEnv map n) kind - | otherwise = pure map + pure $ maybe mapToTyThing (extendNameEnv mapToTyThing n) kind + | otherwise = pure mapToTyThing names = rights $ S.toList idents idents = M.keysSet rm mod = tcg_mod this_mod From 8ea3a6cf15c9ac51ced040efe76273dfe8bd3f6e Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 30 Nov 2021 15:13:37 +0200 Subject: [PATCH 31/37] ghcide: Core.Compile: add GHC compatibility --- ghcide/src/Development/IDE/Core/Compile.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 8473129ad2..6b90800f1e 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -1029,7 +1029,7 @@ getDocsNonInteractive' name = -- | Non-interactive modification of 'GHC.Runtime.Eval.getDocs'. -- The interactive paths create problems in ghc-lib builds --- and lead to fun errors like "Cannot continue after interface file error". -getDocsNonInteractive :: HscEnv -> Module -> Name -> IO (Either ErrorMessages (Name, Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString)))) +getDocsNonInteractive :: HscEnv -> Module -> Name -> IO (Either GHC.ErrorMessages (Name, Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString)))) getDocsNonInteractive hsc_env mod name = do ((_warns,errs), res) <- initTypecheckEnv hsc_env mod $ getDocsNonInteractive' name pure $ maybeToEither errs res @@ -1041,7 +1041,7 @@ getDocsBatch -> Module -- ^ a moudle where the names are in scope -> [Name] -- 2021-11-18: NOTE: Map Int would become IntMap if next GHCs. - -> IO (Either ErrorMessages (Map.Map Name (Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString))))) + -> IO (Either GHC.ErrorMessages (Map.Map Name (Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString))))) -- ^ Return a 'Map' of 'Name's to 'Either' (no docs messages) (general doc body & arg docs) getDocsBatch hsc_env mod names = do ((_warns,errs), res) <- initTypecheckEnv hsc_env mod $ Map.fromList <$> traverse getDocsNonInteractive' names From b6cdbb0c59273579e37f993c169ac165c866940f Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 15 Dec 2021 14:33:48 +0200 Subject: [PATCH 32/37] ghcide: Compat: Outputable: fx 9.0.1 Utils.Error reexport --- ghcide/src/Development/IDE/GHC/Compat/Outputable.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ghcide/src/Development/IDE/GHC/Compat/Outputable.hs b/ghcide/src/Development/IDE/GHC/Compat/Outputable.hs index e3b6d2a453..70a31e62fc 100644 --- a/ghcide/src/Development/IDE/GHC/Compat/Outputable.hs +++ b/ghcide/src/Development/IDE/GHC/Compat/Outputable.hs @@ -49,7 +49,7 @@ import GHC.Driver.Session import GHC.Driver.Types as HscTypes import GHC.Types.Name.Reader (GlobalRdrEnv) import GHC.Types.SrcLoc -import GHC.Utils.Error as Err hiding (mkWarnMsg) +import GHC.Utils.Error hiding (mkWarnMsg) import qualified GHC.Utils.Error as Err import GHC.Utils.Outputable as Out #else From addd66d21223507ed69cbb452e152a9a933f1dc1 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 15 Dec 2021 14:45:30 +0200 Subject: [PATCH 33/37] ghcide: Compat: Outputable: export Messages --- ghcide/src/Development/IDE/GHC/Compat/Outputable.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/ghcide/src/Development/IDE/GHC/Compat/Outputable.hs b/ghcide/src/Development/IDE/GHC/Compat/Outputable.hs index 70a31e62fc..74e05625e2 100644 --- a/ghcide/src/Development/IDE/GHC/Compat/Outputable.hs +++ b/ghcide/src/Development/IDE/GHC/Compat/Outputable.hs @@ -27,6 +27,7 @@ module Development.IDE.GHC.Compat.Outputable ( mkWarnMsg, mkSrcErr, srcErrorMessages, + Messages ) where From 1dcba356345fc686203f49b2d3bf8d49745f3956 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 15 Dec 2021 14:52:50 +0200 Subject: [PATCH 34/37] ghcide: Compat: Outputable: export ErrorMessages --- ghcide/src/Development/IDE/GHC/Compat/Outputable.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ghcide/src/Development/IDE/GHC/Compat/Outputable.hs b/ghcide/src/Development/IDE/GHC/Compat/Outputable.hs index 74e05625e2..69f8607629 100644 --- a/ghcide/src/Development/IDE/GHC/Compat/Outputable.hs +++ b/ghcide/src/Development/IDE/GHC/Compat/Outputable.hs @@ -27,7 +27,8 @@ module Development.IDE.GHC.Compat.Outputable ( mkWarnMsg, mkSrcErr, srcErrorMessages, - Messages + Messages, + ErrorMessages ) where From faefef3a2bac89d6edd3bff1dde9227d5648457e Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 15 Dec 2021 18:11:20 +0200 Subject: [PATCH 35/37] ghcide: Spans: AtPoint: pointCommand: form local function --- ghcide/src/Development/IDE/Spans/AtPoint.hs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ghcide/src/Development/IDE/Spans/AtPoint.hs b/ghcide/src/Development/IDE/Spans/AtPoint.hs index 9f2024b9ea..23fcdf4d35 100644 --- a/ghcide/src/Development/IDE/Spans/AtPoint.hs +++ b/ghcide/src/Development/IDE/Spans/AtPoint.hs @@ -396,7 +396,9 @@ defRowToSymbolInfo _ = Nothing pointCommand :: HieASTs t -> Position -> (HieAST t -> a) -> [a] pointCommand hf pos getter = - catMaybes $ M.elems $ flip M.mapWithKey (getAsts hf) $ \fs ast -> + catMaybes $ M.elems $ M.mapWithKey findInfo (getAsts hf) + where + findInfo fs ast = -- Since GHC 9.2: -- getAsts :: Map HiePath (HieAst a) -- type HiePath = LexialFastString @@ -409,7 +411,6 @@ pointCommand hf pos getter = -- backwards compatibility. let smallestRange = selectSmallestContaining (sp $ coerce fs) ast in fmap getter smallestRange - where sloc fs = mkRealSrcLoc fs (line+1) (cha+1) sp fs = mkRealSrcSpan (sloc fs) (sloc fs) line = _line pos From 62ede27ebfae84e3389b825e2897fbe3381688be Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Thu, 16 Dec 2021 15:58:50 +0200 Subject: [PATCH 36/37] ghcide: Core: Compile: getDocsNonInteractive': docs & comment --- ghcide/src/Development/IDE/Core/Compile.hs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 6b90800f1e..dc2f29fb2a 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -997,7 +997,10 @@ initTypecheckEnv hsc_env mod = initTc hsc_env HsSrcFile False mod fakeSpan fakeSpan :: RealSrcSpan fakeSpan = realSrcLocSpan $ mkRealSrcLoc (Util.fsLit "") 1 1 - +-- | Non-interactive handling of the module interface. +-- A non-interactive modification of code from the 'GHC.Runtime.Eval.getDocs'. +-- The interactive paths create problems in ghc-lib builds +--- and lead to fun errors like "Cannot continue after interface file error". getDocsNonInteractive' :: Name -> IOEnv @@ -1008,7 +1011,7 @@ getDocsNonInteractive' getDocsNonInteractive' name = case nameModule_maybe name of Nothing -> return (name, Left $ NameHasNoModule name) - Just mod -> do + Just mod -> do -- in GHC here was an interactive check & handling. ModIface { mi_doc_hdr = mb_doc_hdr , mi_decl_docs = DeclDocMap dmap @@ -1027,8 +1030,6 @@ getDocsNonInteractive' name = else Right (Map.lookup name dmap, Map.lookup name amap) -- | Non-interactive modification of 'GHC.Runtime.Eval.getDocs'. --- The interactive paths create problems in ghc-lib builds ---- and lead to fun errors like "Cannot continue after interface file error". getDocsNonInteractive :: HscEnv -> Module -> Name -> IO (Either GHC.ErrorMessages (Name, Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString)))) getDocsNonInteractive hsc_env mod name = do ((_warns,errs), res) <- initTypecheckEnv hsc_env mod $ getDocsNonInteractive' name From 334188af3113eb37d195d874bd2ae4a722c9aad3 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Sat, 25 Dec 2021 17:22:14 +0200 Subject: [PATCH 37/37] ghcide: Spans: {AtPoint,Common,LocalBindings}: m reverts --- ghcide/src/Development/IDE/Spans/Common.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ghcide/src/Development/IDE/Spans/Common.hs b/ghcide/src/Development/IDE/Spans/Common.hs index 9cf1d7faf9..59b7029484 100644 --- a/ghcide/src/Development/IDE/Spans/Common.hs +++ b/ghcide/src/Development/IDE/Spans/Common.hs @@ -40,7 +40,7 @@ showGhc = showSD . ppr showSD :: SDoc -> T.Text showSD = T.pack . unsafePrintSDoc --- | Print name dropping unique tagging. +-- | Print the name, dropping the unique tagging from it. showNameWithoutUniques :: Outputable a => a -> T.Text showNameWithoutUniques = T.pack . printNameWithoutUniques