From 052a3414d541134412c076f366fe3ebfd661a1f3 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 2 Feb 2022 00:34:55 +0200 Subject: [PATCH 01/35] ghcide: Core.Compile: getDocsBatch: form local fun --- ghcide/src/Development/IDE/Core/Compile.hs | 50 +++++++++++++++------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 9279abd288..9e02fa342c 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -672,6 +672,30 @@ handleGenerationErrors' dflags source action = . (("Error during " ++ T.unpack source) ++) . show @SomeException ] +-- | Initialise the finder cache, dependencies should be topologically +-- sorted. +setupFinderCache :: [ModSummary] -> HscEnv -> IO HscEnv +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 (InstalledFound . ms_location) mss ims + -- set the target and module graph in the session + graph = mkModuleGraph mss + + -- We have to create a new IORef here instead of modifying the existing IORef as + -- it is shared between concurrent compilations. + prevFinderCache <- readIORef $ hsc_FC session + let newFinderCache = + foldl' + (\fc (im, ifr) -> GHC.extendInstalledModuleEnv fc im ifr) prevFinderCache + $ zip ims ifrs + newFinderCacheVar <- newIORef $! newFinderCache + + pure $ session { hsc_FC = newFinderCacheVar, hsc_mod_graph = graph } + + -- | Load modules, quickly. Input doesn't need to be desugared. -- A module must be loaded before dependent modules can be typechecked. -- This variant of loadModuleHome will *never* cause recompilation, it just @@ -1003,21 +1027,7 @@ getDocsBatch -> [Name] -> IO [Either String (Maybe HsDocString, IntMap HsDocString)] getDocsBatch hsc_env _mod _names = do - (msgs, res) <- initTc hsc_env HsSrcFile False _mod fakeSpan $ forM _names $ \name -> - case nameModule_maybe name of - Nothing -> return (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 - if isNothing mb_doc_hdr && Map.null dmap && null amap - then pure (Left (NoDocsInIface mod $ compiled name)) - else pure (Right ( Map.lookup name dmap , -#if !MIN_VERSION_ghc(9,2,0) - IntMap.fromAscList $ Map.toAscList $ -#endif - Map.findWithDefault mempty name amap)) + ((_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 @@ -1028,6 +1038,16 @@ getDocsBatch hsc_env _mod _names = do #endif 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 + ModIface { mi_doc_hdr = mb_doc_hdr + , mi_decl_docs = DeclDocMap dmap + , mi_arg_docs = ArgDocMap amap + } <- loadModuleInterface "getModuleInterface" mod compiled n = -- TODO: Find a more direct indicator. case nameSrcLoc n of From aee5550df661c67ed165197e5a6dd39feb940c2a Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Fri, 4 Feb 2022 21:42:29 +0200 Subject: [PATCH 02/35] 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 | 31 +++++++++++++------ .../Development/IDE/Spans/Documentation.hs | 2 +- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 9e02fa342c..748bc2cd39 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -1025,29 +1025,42 @@ getDocsBatch :: HscEnv -> Module -- ^ a moudle where the names are in scope -> [Name] - -> IO [Either String (Maybe HsDocString, IntMap 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 - Nothing -> throwErrors + Just x -> return $ fun x + Nothing -> throwErrors errs #if MIN_VERSION_ghc(9,2,0) $ Error.getErrorMessages msgs #else $ snd msgs #endif 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 + 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 ffa2a25c6e..ce3a8d58be 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -72,7 +72,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 34e16cf66afe451f13ffda3e74ebe5eef3611448 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Fri, 4 Feb 2022 21:42:55 +0200 Subject: [PATCH 03/35] ghcide: Core.Compile: getDocsBatch: ([(,)]->Map) --- ghcide/src/Development/IDE/Core/Compile.hs | 4 ++-- ghcide/src/Development/IDE/Spans/Documentation.hs | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 748bc2cd39..03ced3f63a 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -1025,11 +1025,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 #if MIN_VERSION_ghc(9,2,0) $ Error.getErrorMessages msgs diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index ce3a8d58be..c4bae8ada4 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -31,7 +31,8 @@ import Development.IDE.Spans.Common import System.Directory import System.FilePath -import Language.LSP.Types (filePathToUri, getUri) +import Language.LSP.Types (filePathToUri, getUri) +import qualified Data.Map as Map mkDocMap :: HscEnv @@ -72,7 +73,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 749e844a3a863461759240136b0c02f7e8a2a69f Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 13:04:14 +0200 Subject: [PATCH 04/35] 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 c4bae8ada4..01b93363d7 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 @@ -73,11 +74,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 b3cc9436679e0969ba0c99ca6bdb36213cf86fdb Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 13:10:46 +0200 Subject: [PATCH 05/35] 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 01b93363d7..924648145a 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -77,10 +77,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 bd6fbb4941c760d8237095951238236d64c1bcd1 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 13:21:46 +0200 Subject: [PATCH 06/35] 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 924648145a..78b73d4c5b 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -77,16 +77,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 ec9f99d5c29fcf7f8546e826c5fe7913f90b976e Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 13:27:36 +0200 Subject: [PATCH 07/35] 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 78b73d4c5b..f86248418e 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -70,9 +70,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 @@ -82,9 +82,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 ff060166deb667c2f070603bfcd0909129bfef38 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 13:31:45 +0200 Subject: [PATCH 08/35] 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 f86248418e..9488779c97 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -70,21 +70,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 85d14fdd97df9a8c777ba09bff3d30f0c53de115 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 15:54:40 +0200 Subject: [PATCH 09/35] 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 9488779c97..ed42008dc9 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -70,7 +70,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 94550147586b7d6a7acab71db393e1c524c145e2 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 16:29:00 +0200 Subject: [PATCH 10/35] 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 ed42008dc9..7154936774 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -78,32 +78,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 @@ -175,7 +181,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 770332eda0b9812a164d86c5267263acb31f0cef Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 17:17:58 +0200 Subject: [PATCH 11/35] 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 03ced3f63a..26608c2e2f 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -1027,9 +1027,9 @@ 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 #if MIN_VERSION_ghc(9,2,0) $ Error.getErrorMessages msgs @@ -1037,12 +1037,12 @@ getDocsBatch hsc_env _mod _names = do $ snd msgs #endif 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 87432000fa95f9bc7d0f90c5d5dd0c7d726d2324 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 17:26:55 +0200 Subject: [PATCH 12/35] 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 26608c2e2f..6c2d68671d 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -1025,7 +1025,7 @@ 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 @@ -1037,12 +1037,12 @@ getDocsBatch hsc_env _mod _names = do $ snd msgs #endif 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 7154936774..37262ff311 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -80,7 +80,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 c0437ebc989f1575823d717d35613b99db7275ed Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 2 Feb 2022 00:38:50 +0200 Subject: [PATCH 13/35] 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 | 13 +++---------- ghcide/src/Development/IDE/Spans/Documentation.hs | 9 ++++----- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 6c2d68671d..60d78226bc 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -1025,17 +1025,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 -#if MIN_VERSION_ghc(9,2,0) - $ Error.getErrorMessages msgs -#else - $ snd msgs -#endif + 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 = @@ -1044,8 +1039,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 37262ff311..5ae4eaf0a3 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 @@ -77,11 +76,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 cf5dc825e641d8e27de847fd995d98e1e9ae13c6 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 18:06:58 +0200 Subject: [PATCH 14/35] 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 60d78226bc..de2ab76417 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -1025,12 +1025,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 = @@ -1039,7 +1039,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) @@ -1053,7 +1053,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 5ae4eaf0a3..0f483c6125 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -79,7 +79,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 03e91bff1a72837e3e91d23fbf7469c3a0356e01 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 18:21:19 +0200 Subject: [PATCH 15/35] 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 0f483c6125..20f50b5a14 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -77,13 +77,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 2e306c9a0a294301ddf1e8a6dc33da5037eeeeb2 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 19:03:26 +0200 Subject: [PATCH 16/35] 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 de2ab76417..bafc673846 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -38,7 +38,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 @@ -78,7 +77,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 @@ -109,6 +108,7 @@ import qualified Data.HashMap.Strict as HashMap import Data.IntMap (IntMap) 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) @@ -1025,20 +1025,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 20f50b5a14..ba3f373963 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -74,14 +74,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 8aaf5ca78276dbb12c86310eddfd7e9bb10db614 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 17 Nov 2021 21:03:21 +0200 Subject: [PATCH 17/35] 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 bafc673846..30ecc3f1fd 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -221,9 +221,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 @@ -1026,6 +1024,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 @@ -1043,9 +1042,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 @@ -1066,7 +1065,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 5192cfb3a907c9ccadf0754843c32e7be5252b25 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Fri, 4 Feb 2022 21:43:21 +0200 Subject: [PATCH 18/35] ghcide: Spans.Documentation: getDocumentationsTryGhc: clean-up --- .../Development/IDE/Spans/Documentation.hs | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index ba3f373963..18988ce627 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -13,8 +13,9 @@ module Development.IDE.Spans.Documentation ( ) where import Control.Monad -import Control.Monad.Extra (findM) 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 @@ -70,14 +70,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 @@ -93,19 +93,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 0a5900dee53eeb6bb6bd9df92d300f80d03be3e6 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Sat, 25 Dec 2021 20:13:27 +0200 Subject: [PATCH 19/35] 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 | 51 ++++++++++++---------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 30ecc3f1fd..8d6ae276a8 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -1016,9 +1016,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 @@ -1026,29 +1050,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,) $ - 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 b75167462c26bce57634676b3034be5dc3163301 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 2 Feb 2022 00:39:56 +0200 Subject: [PATCH 20/35] 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 8d6ae276a8..874b52b7d3 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -27,6 +27,7 @@ module Development.IDE.Core.Compile , loadHieFile , loadInterface , loadModulesHome + , getDocsNonInteractive , getDocsBatch , lookupName ,mergeEnvs) where @@ -1016,12 +1017,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 @@ -1033,7 +1042,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 @@ -1042,6 +1051,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 @@ -1049,13 +1067,10 @@ getDocsBatch -> [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 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". @@ -1064,7 +1079,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 ffbe9a8c28a5db49ebeb20bbcd1b45b5692ee517 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Fri, 26 Nov 2021 21:51:15 +0200 Subject: [PATCH 21/35] 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 18988ce627..c3fe9bd7e4 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) @@ -70,7 +69,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 39ad13333e09ebbeeefc8582db7a7a363914c657 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Fri, 26 Nov 2021 22:02:59 +0200 Subject: [PATCH 22/35] 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 c3fe9bd7e4..c23ba655d9 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -67,71 +67,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) @@ -145,6 +97,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 7d9d5ea689f3c9289a34222139d8183845a0e8f9 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Fri, 26 Nov 2021 23:03:06 +0200 Subject: [PATCH 23/35] 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 874b52b7d3..cfc5ba1e27 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -1017,11 +1017,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 c23ba655d9..4c79afb91b 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -49,16 +49,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 a2a6c2ddb3375f089d10b086a87968d39eb90e77 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 30 Nov 2021 15:13:37 +0200 Subject: [PATCH 24/35] ghcide: Core.Compile: add GHC compatibility --- ghcide/src/Development/IDE/Core/Compile.hs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index cfc5ba1e27..f25da02120 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -1055,7 +1055,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 @@ -1066,7 +1066,8 @@ getDocsBatch :: HscEnv -> 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))))) + -- 2021-11-18: NOTE: Map Int would become IntMap if next GHCs. + -> 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 3191e45fad369b3c5c7bbb3715ff2ad47f4fd3be Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 15 Dec 2021 14:33:48 +0200 Subject: [PATCH 25/35] 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 e3a4ecabe2..8a5cde3821 100644 --- a/ghcide/src/Development/IDE/GHC/Compat/Outputable.hs +++ b/ghcide/src/Development/IDE/GHC/Compat/Outputable.hs @@ -50,7 +50,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 4f841734deeb839415293fc1663d88391bccce7e Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 15 Dec 2021 14:45:30 +0200 Subject: [PATCH 26/35] 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 8a5cde3821..4b1d3655e0 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 109f2cb696453de39b39f12290348b91c20fcede Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Wed, 15 Dec 2021 14:52:50 +0200 Subject: [PATCH 27/35] 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 4b1d3655e0..6db404afdf 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 2928b02caabdfde1d9d72aaa2e376d1347c4e8c0 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Thu, 16 Dec 2021 15:58:50 +0200 Subject: [PATCH 28/35] 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 f25da02120..b917471fe4 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -1023,7 +1023,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 @@ -1034,7 +1037,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 @@ -1053,8 +1056,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 c68f9beb38af3ca18eca438fbb5d4968a3c731e7 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Fri, 4 Feb 2022 21:44:07 +0200 Subject: [PATCH 29/35] ghcide: {Core.Compile,Spans.Documentation}: mark Lazy & Strict Maps --- ghcide/src/Development/IDE/Core/Compile.hs | 18 +++++++++--------- .../src/Development/IDE/Spans/Documentation.hs | 9 +++++---- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index b917471fe4..d965ae0692 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -84,7 +84,7 @@ import qualified Data.DList as DL import Data.IORef import qualified Data.IntMap.Strict as IntMap import Data.List.Extra -import qualified Data.Map.Strict as Map +import qualified Data.Map.Strict as MS import Data.Maybe import qualified Data.Text as T import Data.Time (UTCTime, getCurrentTime) @@ -93,7 +93,6 @@ import System.Directory import System.FilePath import System.IO.Extra (fixIO, newTempFileWithin) --- GHC API imports -- GHC API imports import GHC (GetDocsFailure (..), mgModSummaries, @@ -108,6 +107,7 @@ import Data.Functor import qualified Data.HashMap.Strict as HashMap import Data.IntMap (IntMap) import Data.Map (Map) +import qualified Data.Map as ML import Data.Tuple.Extra (dupe) import Data.Either.Extra (maybeToEither) import Data.Unique as Unique @@ -751,7 +751,7 @@ mergeEnvs env extraModSummaries extraMods envs = do -- To work around this, we coerce to the underlying type -- To remove this, I plan to upstream the missing Monoid instance concatFC :: [FinderCache] -> FinderCache - concatFC = unsafeCoerce (mconcat @(Map InstalledModule InstalledFindResult)) + concatFC = unsafeCoerce (mconcat @(ML.Map InstalledModule InstalledFindResult)) withBootSuffix :: HscSource -> ModLocation -> ModLocation withBootSuffix HsBootFile = addBootSuffixLocnOut @@ -1033,7 +1033,7 @@ getDocsNonInteractive' (Env TcGblEnv TcLclEnv) (Name, Either - GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString))) + GetDocsFailure (Maybe HsDocString, Maybe (MS.Map Int HsDocString))) getDocsNonInteractive' name = case nameModule_maybe name of Nothing -> return (name, Left $ NameHasNoModule name) @@ -1051,12 +1051,12 @@ getDocsNonInteractive' name = RealSrcLoc {} -> False UnhelpfulLoc {} -> True pure . (name,) $ - if isNothing mb_doc_hdr && Map.null dmap && Map.null amap + if isNothing mb_doc_hdr && MS.null dmap && MS.null amap then Left $ NoDocsInIface mod isNameCompiled - else Right (Map.lookup name dmap, Map.lookup name amap) + else Right (MS.lookup name dmap, MS.lookup name amap) -- | Non-interactive modification of 'GHC.Runtime.Eval.getDocs'. -getDocsNonInteractive :: HscEnv -> Module -> Name -> IO (Either GHC.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 (MS.Map Int HsDocString)))) getDocsNonInteractive hsc_env mod name = do ((_warns,errs), res) <- initTypecheckEnv hsc_env mod $ getDocsNonInteractive' name pure $ maybeToEither errs res @@ -1068,10 +1068,10 @@ 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 GHC.ErrorMessages (Map.Map Name (Either GetDocsFailure (Maybe HsDocString, Maybe (Map.Map Int HsDocString))))) + -> IO (Either GHC.ErrorMessages (MS.Map Name (Either GetDocsFailure (Maybe HsDocString, Maybe (MS.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 + ((_warns,errs), res) <- initTypecheckEnv hsc_env mod $ MS.fromList <$> traverse getDocsNonInteractive' names pure $ maybeToEither errs res -- | Non-interactive, batch version of 'InteractiveEval.lookupNames'. diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index 4c79afb91b..c871d14240 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -18,7 +18,8 @@ import Data.Bool (bool) import Data.Either import Data.Foldable import Data.List.Extra -import qualified Data.Map as M +import qualified Data.Map as ML +import qualified Data.Map.Strict as MS import Data.Maybe import qualified Data.Set as S import qualified Data.Text as T @@ -60,7 +61,7 @@ mkDocMap env rm this_mod = pure $ maybe mapToTyThing (extendNameEnv mapToTyThing n) kind | otherwise = pure mapToTyThing names = rights $ S.toList idents - idents = M.keysSet rm + idents = ML.keysSet rm mod = tcg_mod this_mod lookupKind :: HscEnv -> Module -> Name -> IO (Maybe TyThing) @@ -104,12 +105,12 @@ getDocumentationTryGhc env mod name = do Left _ -> pure emptySpanDoc Right res -> uncurry (intoSpanDoc env) res -getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO (M.Map Name SpanDoc) +getDocumentationsTryGhc :: HscEnv -> Module -> [Name] -> IO (MS.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 + Right res -> sequenceA $ MS.mapWithKey (intoSpanDoc env) res getDocumentation :: HasSrcSpan name From 60b6a84f48667917d080757912f55404bd29ca74 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Sat, 5 Feb 2022 17:25:18 +0200 Subject: [PATCH 30/35] ghcide: Documentation: mkDocsMap: fx --- ghcide/src/Development/IDE/Spans/Documentation.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index c871d14240..f5d73ffda1 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -46,7 +46,7 @@ mkDocMap env rm this_mod = #else let (_ , DeclDocMap this_docs, _) = extractDocs this_mod #endif - d <- foldrM getDocs (mkNameEnv $ M.toList $ fmap (`SpanDocString` SpanDocUris Nothing Nothing) this_docs) names + d <- foldrM getDocs (mkNameEnv $ MS.toList $ fmap (`SpanDocString` SpanDocUris Nothing Nothing) this_docs) names k <- foldrM getType (tcg_type_env this_mod) names pure $ DKMap d k where From bec8e39fc1a487ffa75a9e7a6f246e3a0dedc92f Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Sat, 5 Feb 2022 23:25:25 +0200 Subject: [PATCH 31/35] ghcide: Compile: rm setupFinderCache --- ghcide/src/Development/IDE/Core/Compile.hs | 24 ---------------------- 1 file changed, 24 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index d965ae0692..8e3081f5d9 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -671,30 +671,6 @@ handleGenerationErrors' dflags source action = . (("Error during " ++ T.unpack source) ++) . show @SomeException ] --- | Initialise the finder cache, dependencies should be topologically --- sorted. -setupFinderCache :: [ModSummary] -> HscEnv -> IO HscEnv -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 (InstalledFound . ms_location) mss ims - -- set the target and module graph in the session - graph = mkModuleGraph mss - - -- We have to create a new IORef here instead of modifying the existing IORef as - -- it is shared between concurrent compilations. - prevFinderCache <- readIORef $ hsc_FC session - let newFinderCache = - foldl' - (\fc (im, ifr) -> GHC.extendInstalledModuleEnv fc im ifr) prevFinderCache - $ zip ims ifrs - newFinderCacheVar <- newIORef $! newFinderCache - - pure $ session { hsc_FC = newFinderCacheVar, hsc_mod_graph = graph } - - -- | Load modules, quickly. Input doesn't need to be desugared. -- A module must be loaded before dependent modules can be typechecked. -- This variant of loadModuleHome will *never* cause recompilation, it just From 8ee6a9f7aa22c8bbab4e5531bc725f9d4862b0e4 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Sat, 5 Feb 2022 23:48:43 +0200 Subject: [PATCH 32/35] ghcide: Compile: (Map Int -> IntMap) --- ghcide/src/Development/IDE/Core/Compile.hs | 24 ++++++++++++++-------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 8e3081f5d9..30322a311e 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -83,6 +83,7 @@ import qualified Data.ByteString as BS import qualified Data.DList as DL import Data.IORef import qualified Data.IntMap.Strict as IntMap +import Data.IntMap.Strict (IntMap) import Data.List.Extra import qualified Data.Map.Strict as MS import Data.Maybe @@ -105,7 +106,6 @@ import Data.Binary import Data.Coerce import Data.Functor import qualified Data.HashMap.Strict as HashMap -import Data.IntMap (IntMap) import Data.Map (Map) import qualified Data.Map as ML import Data.Tuple.Extra (dupe) @@ -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 (\ms -> Compat.installedModule (toUnitId $ moduleUnit $ ms_mod ms) (moduleName (ms_mod ms))) extraModSummaries - ifrs = zipWith (\ms -> InstalledFound (ms_location ms)) extraModSummaries ims + ifrs = zipWith (InstalledFound . ms_location) extraModSummaries ims -- Very important to force this as otherwise the hsc_mod_graph field is not -- forced and ends up retaining a reference to all the old hsc_envs we have merged to get -- this new one, which in turn leads to the EPS referencing the HPT. @@ -711,7 +711,7 @@ mergeEnvs env extraModSummaries extraMods envs = do foldl' (\fc (im, ifr) -> Compat.extendInstalledModuleEnv fc im ifr) prevFinderCache $ zip ims ifrs - liftRnf rwhnf module_graph_nodes `seq` (return $ loadModulesHome extraMods $ env{ + liftRnf rwhnf module_graph_nodes `seq` return (loadModulesHome extraMods $ env{ hsc_HPT = foldMapBy mergeUDFM emptyUDFM hsc_HPT envs, hsc_FC = newFinderCache, hsc_mod_graph = mkModuleGraph module_graph_nodes @@ -828,7 +828,7 @@ parseHeader -> FilePath -- ^ the filename (for source locations) -> Util.StringBuffer -- ^ Haskell module source text (full Unicode is supported) #if MIN_VERSION_ghc(9,0,1) - -> ExceptT [FileDiagnostic] m ([FileDiagnostic], Located(HsModule)) + -> ExceptT [FileDiagnostic] m ([FileDiagnostic], Located HsModule) #else -> ExceptT [FileDiagnostic] m ([FileDiagnostic], Located(HsModule GhcPs)) #endif @@ -1009,7 +1009,7 @@ getDocsNonInteractive' (Env TcGblEnv TcLclEnv) (Name, Either - GetDocsFailure (Maybe HsDocString, Maybe (MS.Map Int HsDocString))) + GetDocsFailure (Maybe HsDocString, Maybe (IntMap HsDocString))) getDocsNonInteractive' name = case nameModule_maybe name of Nothing -> return (name, Left $ NameHasNoModule name) @@ -1026,13 +1026,19 @@ getDocsNonInteractive' name = case nameSrcLoc name of RealSrcLoc {} -> False UnhelpfulLoc {} -> True +#if MIN_VERSION_ghc(9,2,1) + amap' = amap +#else + amap' = MS.map (IntMap.fromAscList . MS.toAscList) amap +#endif + pure . (name,) $ - if isNothing mb_doc_hdr && MS.null dmap && MS.null amap + if isNothing mb_doc_hdr && MS.null dmap && MS.null amap' then Left $ NoDocsInIface mod isNameCompiled - else Right (MS.lookup name dmap, MS.lookup name amap) + else Right (MS.lookup name dmap, MS.lookup name amap') -- | Non-interactive modification of 'GHC.Runtime.Eval.getDocs'. -getDocsNonInteractive :: HscEnv -> Module -> Name -> IO (Either GHC.ErrorMessages (Name, Either GetDocsFailure (Maybe HsDocString, Maybe (MS.Map Int HsDocString)))) +getDocsNonInteractive :: HscEnv -> Module -> Name -> IO (Either GHC.ErrorMessages (Name, Either GetDocsFailure (Maybe HsDocString, Maybe (IntMap HsDocString)))) getDocsNonInteractive hsc_env mod name = do ((_warns,errs), res) <- initTypecheckEnv hsc_env mod $ getDocsNonInteractive' name pure $ maybeToEither errs res @@ -1044,7 +1050,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 GHC.ErrorMessages (MS.Map Name (Either GetDocsFailure (Maybe HsDocString, Maybe (MS.Map Int HsDocString))))) + -> IO (Either GHC.ErrorMessages (MS.Map Name (Either GetDocsFailure (Maybe HsDocString, Maybe (IntMap 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 $ MS.fromList <$> traverse getDocsNonInteractive' names From 567ab4e32551bff652a2316d34b6b7dee85548c6 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Sun, 6 Feb 2022 15:04:45 +0200 Subject: [PATCH 33/35] ghcide: Compile: {initTypecheckEnv, getDocs{NonInteractive,Batch}} upd to GHC 9.2 types --- ghcide/src/Development/IDE/Core/Compile.hs | 58 ++++++++++++++++++---- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 30322a311e..56104b7790 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -106,7 +106,6 @@ import Data.Binary import Data.Coerce import Data.Functor import qualified Data.HashMap.Strict as HashMap -import Data.Map (Map) import qualified Data.Map as ML import Data.Tuple.Extra (dupe) import Data.Either.Extra (maybeToEither) @@ -993,7 +992,17 @@ mkDetailsFromIface session iface linkable = do initIfaceLoad hsc' (typecheckIface iface) return (HomeModInfo iface details linkable) -initTypecheckEnv :: HscEnv -> Module -> TcRn r -> IO (Messages, Maybe r) +initTypecheckEnv + :: HscEnv + -> Module + -> TcRn r + -> IO + ( Messages +#if MIN_VERSION_ghc(9,2,1) + DecoratedSDoc +#endif + , Maybe r + ) initTypecheckEnv hsc_env mod = initTc hsc_env HsSrcFile False mod fakeSpan where fakeSpan :: RealSrcSpan @@ -1038,10 +1047,31 @@ getDocsNonInteractive' name = else Right (MS.lookup name dmap, MS.lookup name amap') -- | Non-interactive modification of 'GHC.Runtime.Eval.getDocs'. -getDocsNonInteractive :: HscEnv -> Module -> Name -> IO (Either GHC.ErrorMessages (Name, Either GetDocsFailure (Maybe HsDocString, Maybe (IntMap HsDocString)))) -getDocsNonInteractive hsc_env mod name = do - ((_warns,errs), res) <- initTypecheckEnv hsc_env mod $ getDocsNonInteractive' name - pure $ maybeToEither errs res +getDocsNonInteractive + :: HscEnv + -> Module + -> Name + -> IO + ( Either + GHC.ErrorMessages + ( Name + , Either + GetDocsFailure + ( Maybe HsDocString + , Maybe (IntMap HsDocString) + ) + ) + ) +getDocsNonInteractive hsc_env mod name = + do + let + init = initTypecheckEnv hsc_env mod $ getDocsNonInteractive' name +#if MIN_VERSION_ghc (9,2,1) + (Error.getErrorMessages -> errs, res) <- init +#else + ((_warns,errs), res) <- init +#endif + pure $ maybeToEither errs res -- | Non-interactive, batch version of 'GHC.Runtime.Eval.getDocs'. @@ -1049,12 +1079,18 @@ 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 GHC.ErrorMessages (MS.Map Name (Either GetDocsFailure (Maybe HsDocString, Maybe (IntMap HsDocString))))) + -> IO(Either GHC.ErrorMessages (MS.Map Name (Either GetDocsFailure (Maybe HsDocString, Maybe (IntMap 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 $ MS.fromList <$> traverse getDocsNonInteractive' names - pure $ maybeToEither errs res +getDocsBatch hsc_env mod names = + do + let + init = initTypecheckEnv hsc_env mod $ MS.fromList <$> traverse getDocsNonInteractive' names +#if MIN_VERSION_ghc (9,2,1) + (Error.getErrorMessages -> errs, res) <- init +#else + ((_warns,errs), res) <- init +#endif + pure $ maybeToEither errs res -- | Non-interactive, batch version of 'InteractiveEval.lookupNames'. -- The interactive paths create problems in ghc-lib builds From 68ebfdf102dc9c7edeeff1754b52497797cc3e78 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Sun, 6 Feb 2022 18:54:09 +0200 Subject: [PATCH 34/35] ghcide: {Compile, Documentation}: m mark Map's Strict --- ghcide/src/Development/IDE/Core/Compile.hs | 7 ++++--- ghcide/src/Development/IDE/Spans/Documentation.hs | 3 +-- 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 56104b7790..01ff2c139f 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -82,9 +82,11 @@ import Data.Bifunctor (second) import qualified Data.ByteString as BS import qualified Data.DList as DL import Data.IORef +#if !MIN_VERSION_ghc(9,2,1) import qualified Data.IntMap.Strict as IntMap +#endif import Data.IntMap.Strict (IntMap) -import Data.List.Extra +import Data.List.Extra import qualified Data.Map.Strict as MS import Data.Maybe import qualified Data.Text as T @@ -106,7 +108,6 @@ import Data.Binary import Data.Coerce import Data.Functor import qualified Data.HashMap.Strict as HashMap -import qualified Data.Map as ML import Data.Tuple.Extra (dupe) import Data.Either.Extra (maybeToEither) import Data.Unique as Unique @@ -726,7 +727,7 @@ mergeEnvs env extraModSummaries extraMods envs = do -- To work around this, we coerce to the underlying type -- To remove this, I plan to upstream the missing Monoid instance concatFC :: [FinderCache] -> FinderCache - concatFC = unsafeCoerce (mconcat @(ML.Map InstalledModule InstalledFindResult)) + concatFC = unsafeCoerce (mconcat @(MS.Map InstalledModule InstalledFindResult)) withBootSuffix :: HscSource -> ModLocation -> ModLocation withBootSuffix HsBootFile = addBootSuffixLocnOut diff --git a/ghcide/src/Development/IDE/Spans/Documentation.hs b/ghcide/src/Development/IDE/Spans/Documentation.hs index f5d73ffda1..a075da3244 100644 --- a/ghcide/src/Development/IDE/Spans/Documentation.hs +++ b/ghcide/src/Development/IDE/Spans/Documentation.hs @@ -18,7 +18,6 @@ import Data.Bool (bool) import Data.Either import Data.Foldable import Data.List.Extra -import qualified Data.Map as ML import qualified Data.Map.Strict as MS import Data.Maybe import qualified Data.Set as S @@ -61,7 +60,7 @@ mkDocMap env rm this_mod = pure $ maybe mapToTyThing (extendNameEnv mapToTyThing n) kind | otherwise = pure mapToTyThing names = rights $ S.toList idents - idents = ML.keysSet rm + idents = MS.keysSet rm mod = tcg_mod this_mod lookupKind :: HscEnv -> Module -> Name -> IO (Maybe TyThing) From 0a8701703356c46c2ee78377156d0cc6e7c82874 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Sun, 6 Feb 2022 19:22:15 +0200 Subject: [PATCH 35/35] ghcide: Compile: m: upd --- ghcide/src/Development/IDE/Core/Compile.hs | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 01ff2c139f..1dead73a6a 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -1052,17 +1052,7 @@ getDocsNonInteractive :: HscEnv -> Module -> Name - -> IO - ( Either - GHC.ErrorMessages - ( Name - , Either - GetDocsFailure - ( Maybe HsDocString - , Maybe (IntMap HsDocString) - ) - ) - ) + -> IO (Either GHC.ErrorMessages (Name, Either GetDocsFailure (Maybe HsDocString, Maybe (IntMap HsDocString)))) getDocsNonInteractive hsc_env mod name = do let @@ -1077,10 +1067,10 @@ getDocsNonInteractive hsc_env mod name = -- | Non-interactive, batch version of 'GHC.Runtime.Eval.getDocs'. getDocsBatch - :: HscEnv - -> Module -- ^ a moudle where the names are in scope - -> [Name] - -> IO(Either GHC.ErrorMessages (MS.Map Name (Either GetDocsFailure (Maybe HsDocString, Maybe (IntMap HsDocString))))) + :: HscEnv + -> Module -- ^ a moudle where the names are in scope + -> [Name] + -> IO (Either GHC.ErrorMessages (MS.Map Name (Either GetDocsFailure (Maybe HsDocString, Maybe (IntMap HsDocString))))) -- ^ Return a 'Map' of 'Name's to 'Either' (no docs messages) (general doc body & arg docs) getDocsBatch hsc_env mod names = do