From 720debbe1fef7213e62bc27dff7281c33d1b8183 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Fri, 10 Jan 2020 11:50:22 +0100 Subject: [PATCH 01/18] Show kinds in hover --- ghcide.cabal | 1 + src/Development/IDE/Core/Completions.hs | 16 +-------- src/Development/IDE/Spans/Calculate.hs | 32 ++++++++---------- src/Development/IDE/Spans/Common.hs | 39 ++++++++++++++++++++++ src/Development/IDE/Spans/Documentation.hs | 15 +++++++-- 5 files changed, 66 insertions(+), 37 deletions(-) create mode 100644 src/Development/IDE/Spans/Common.hs diff --git a/ghcide.cabal b/ghcide.cabal index f59ba49ae..9c3028472 100644 --- a/ghcide.cabal +++ b/ghcide.cabal @@ -134,6 +134,7 @@ library Development.IDE.LSP.Outline Development.IDE.Spans.AtPoint Development.IDE.Spans.Calculate + Development.IDE.Spans.Common Development.IDE.Spans.Documentation Development.IDE.Spans.Type ghc-options: -Wall -Wno-name-shadowing diff --git a/src/Development/IDE/Core/Completions.hs b/src/Development/IDE/Core/Completions.hs index 8c72f853f..c73fc7e20 100644 --- a/src/Development/IDE/Core/Completions.hs +++ b/src/Development/IDE/Core/Completions.hs @@ -24,8 +24,6 @@ import Type import Var import Packages import DynFlags -import ConLike -import DataCon import SrcLoc as GHC import Language.Haskell.LSP.Types @@ -36,19 +34,7 @@ import Development.IDE.Spans.Documentation import Development.IDE.GHC.Util import Development.IDE.GHC.Error import Development.IDE.Types.Options - --- From haskell-ide-engine/src/Haskell/Ide/Engine/Support/HieExtras.hs - -safeTyThingId :: TyThing -> Maybe Id -safeTyThingId (AnId i) = Just i -safeTyThingId (AConLike (RealDataCon dc)) = Just $ dataConWrapId dc -safeTyThingId _ = Nothing - -safeTyThingType :: TyThing -> Maybe Type -safeTyThingType thing - | Just i <- safeTyThingId thing = Just (varType i) -safeTyThingType (ATyCon tycon) = Just (tyConKind tycon) -safeTyThingType _ = Nothing +import Development.IDE.Spans.Common -- From haskell-ide-engine/hie-plugin-api/Haskell/Ide/Engine/Context.hs diff --git a/src/Development/IDE/Spans/Calculate.hs b/src/Development/IDE/Spans/Calculate.hs index 8a235a344..555a2e88d 100644 --- a/src/Development/IDE/Spans/Calculate.hs +++ b/src/Development/IDE/Spans/Calculate.hs @@ -9,13 +9,11 @@ -- | Get information on modules, identifiers, etc. -module Development.IDE.Spans.Calculate(getSrcSpanInfos,listifyAllSpans) where +module Development.IDE.Spans.Calculate(getSrcSpanInfos) where import ConLike import Control.Monad import qualified CoreUtils -import Data.Data -import qualified Data.Generics import Data.List import Data.Maybe import DataCon @@ -25,13 +23,13 @@ import GhcMonad import FastString (mkFastString) import Development.IDE.Types.Location import Development.IDE.Spans.Type -import Development.IDE.GHC.Error (zeroSpan) +import Development.IDE.GHC.Error (zeroSpan, catchSrcErrors) import Prelude hiding (mod) import TcHsSyn import Var import Development.IDE.Core.Compile import Development.IDE.GHC.Util - +import Development.IDE.Spans.Common -- A lot of things gained an extra X argument in GHC 8.6, which we mostly ignore -- this U ignores that arg in 8.6, but is hidden in 8.4 @@ -145,7 +143,16 @@ getLHsType => TypecheckedModule -> LHsType GhcRn -> m [(SpanSource, SrcSpan, Maybe Type)] -getLHsType _ (L spn (HsTyVar U _ v)) = pure [(Named $ unLoc v, spn, Nothing)] +getLHsType _ (L spn (HsTyVar U _ v)) = do + let n = unLoc v + -- docs <- getDocumentationTryGhc' [tm] n + ty <- catchSrcErrors "completion" $ do + name' <- lookupName n + return $ name' >>= safeTyThingType + let ty' = case ty of + Right (Just x) -> Just x + _ -> Nothing + pure [(Named n, spn, ty')] getLHsType _ _ = pure [] importInfo :: [(Located ModuleName, Maybe NormalizedFilePath)] @@ -160,19 +167,6 @@ importInfo = mapMaybe (uncurry wrk) where fpToSpanSource :: FilePath -> SpanSource fpToSpanSource fp = SpanS $ RealSrcSpan $ zeroSpan $ mkFastString fp --- | Get ALL source spans in the source. -listifyAllSpans :: (Typeable a, Data m) => m -> [Located a] -listifyAllSpans tcs = - Data.Generics.listify p tcs - where p (L spn _) = isGoodSrcSpan spn --- This is a version of `listifyAllSpans` specialized on picking out --- patterns. It comes about since GHC now defines `type LPat p = Pat --- p` (no top-level locations). -listifyAllSpans' :: Typeable a - => TypecheckedSource -> [Pat a] -listifyAllSpans' tcs = Data.Generics.listify (const True) tcs - - -- | Pretty print the types into a 'SpanInfo'. toSpanInfo :: (SpanSource, SrcSpan, Maybe Type) -> Maybe SpanInfo toSpanInfo (name,mspan,typ) = diff --git a/src/Development/IDE/Spans/Common.hs b/src/Development/IDE/Spans/Common.hs new file mode 100644 index 000000000..bfea85e0f --- /dev/null +++ b/src/Development/IDE/Spans/Common.hs @@ -0,0 +1,39 @@ +module Development.IDE.Spans.Common ( + listifyAllSpans +, listifyAllSpans' +, safeTyThingId +, safeTyThingType +) where + +import Data.Data +import qualified Data.Generics + +import GHC +import ConLike +import Var +import DataCon + +-- | Get ALL source spans in the source. +listifyAllSpans :: (Typeable a, Data m) => m -> [Located a] +listifyAllSpans tcs = + Data.Generics.listify p tcs + where p (L spn _) = isGoodSrcSpan spn +-- This is a version of `listifyAllSpans` specialized on picking out +-- patterns. It comes about since GHC now defines `type LPat p = Pat +-- p` (no top-level locations). +listifyAllSpans' :: Typeable a + => TypecheckedSource -> [Pat a] +listifyAllSpans' tcs = Data.Generics.listify (const True) tcs + +-- From haskell-ide-engine/src/Haskell/Ide/Engine/Support/HieExtras.hs + +safeTyThingId :: TyThing -> Maybe Id +safeTyThingId (AnId i) = Just i +safeTyThingId (AConLike (RealDataCon dc)) = Just $ dataConWrapId dc +safeTyThingId _ = Nothing + +safeTyThingType :: TyThing -> Maybe Type +safeTyThingType thing + | Just i <- safeTyThingId thing = Just (varType i) +safeTyThingType (ATyCon tycon) = Just (tyConKind tycon) +safeTyThingType _ = Nothing \ No newline at end of file diff --git a/src/Development/IDE/Spans/Documentation.hs b/src/Development/IDE/Spans/Documentation.hs index 31f319b75..750274fd1 100644 --- a/src/Development/IDE/Spans/Documentation.hs +++ b/src/Development/IDE/Spans/Documentation.hs @@ -7,6 +7,7 @@ module Development.IDE.Spans.Documentation ( getDocumentation , getDocumentationTryGhc + , getDocumentationTryGhc' ) where import Control.Monad @@ -15,7 +16,7 @@ import qualified Data.Map as M import Data.Maybe import qualified Data.Text as T import Development.IDE.GHC.Error -import Development.IDE.Spans.Calculate +import Development.IDE.Spans.Common import FastString import GHC import SrcLoc @@ -32,9 +33,17 @@ getDocumentationTryGhc -> [TypecheckedModule] -> Name -> IO [T.Text] +getDocumentationTryGhc packageState tcs name = + runGhcEnv packageState $ getDocumentationTryGhc' tcs name + +getDocumentationTryGhc' + :: GhcMonad m + => [TypecheckedModule] + -> Name + -> m [T.Text] #if MIN_GHC_API_VERSION(8,6,0) -getDocumentationTryGhc packageState tcs name = do - res <- runGhcEnv packageState $ catchSrcErrors "docs" $ getDocs name +getDocumentationTryGhc' tcs name = do + res <- catchSrcErrors "docs" $ getDocs name case res of Right (Right (Just docs, _)) -> return [T.pack $ haddockToMarkdown $ H.toRegular $ H._doc $ H.parseParas Nothing $ unpackHDS docs] _ -> return $ getDocumentation tcs name From 0859cf04b04a4feb03ee3a43440b6b56179a1e92 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Fri, 10 Jan 2020 12:25:47 +0100 Subject: [PATCH 02/18] Documentation on hover --- src/Development/IDE/Core/Rules.hs | 4 +- src/Development/IDE/Spans/AtPoint.hs | 21 +++--- src/Development/IDE/Spans/Calculate.hs | 95 +++++++++++++++----------- src/Development/IDE/Spans/Type.hs | 5 +- 4 files changed, 69 insertions(+), 56 deletions(-) diff --git a/src/Development/IDE/Core/Rules.hs b/src/Development/IDE/Core/Rules.hs index b0b5c5c12..859e21431 100644 --- a/src/Development/IDE/Core/Rules.hs +++ b/src/Development/IDE/Core/Rules.hs @@ -262,9 +262,11 @@ getSpanInfoRule :: Rules () getSpanInfoRule = define $ \GetSpanInfo file -> do tc <- use_ TypeCheck file + deps <- maybe (TransitiveDependencies [] []) fst <$> useWithStale GetDependencies file + tms <- mapMaybe (fmap fst) <$> usesWithStale TypeCheck (transitiveModuleDeps deps) (fileImports, _) <- use_ GetLocatedImports file packageState <- hscEnv <$> use_ GhcSession file - x <- liftIO $ getSrcSpanInfos packageState fileImports tc + x <- liftIO $ getSrcSpanInfos packageState fileImports tc tms return ([], Just x) -- Typechecks a module. diff --git a/src/Development/IDE/Spans/AtPoint.hs b/src/Development/IDE/Spans/AtPoint.hs index ea5600635..09c3b7107 100644 --- a/src/Development/IDE/Spans/AtPoint.hs +++ b/src/Development/IDE/Spans/AtPoint.hs @@ -8,7 +8,6 @@ module Development.IDE.Spans.AtPoint ( , gotoDefinition ) where -import Development.IDE.Spans.Documentation import Development.IDE.GHC.Error import Development.IDE.GHC.Orphans() import Development.IDE.Types.Location @@ -54,36 +53,32 @@ atPoint -> [SpanInfo] -> Position -> Maybe (Maybe Range, [T.Text]) -atPoint IdeOptions{..} tcs srcSpans pos = do +atPoint IdeOptions{..} _ srcSpans pos = do firstSpan <- listToMaybe $ deEmpasizeGeneratedEqShow $ spansAtPoint pos srcSpans return (Just (range firstSpan), hoverInfo firstSpan) where -- Hover info for types, classes, type variables - hoverInfo SpanInfo{spaninfoType = Nothing , ..} = - documentation <> (wrapLanguageSyntax <$> name <> kind) <> location + hoverInfo SpanInfo{spaninfoType = Nothing , spaninfoDocs = docs , ..} = + (wrapLanguageSyntax <$> name) <> location <> docs where - documentation = findDocumentation mbName name = [maybe shouldNotHappen showName mbName] location = [maybe shouldNotHappen definedAt mbName] - kind = [] -- TODO shouldNotHappen = "ghcide: did not expect a type level component without a name" mbName = getNameM spaninfoSource -- Hover info for values/data - hoverInfo SpanInfo{spaninfoType = (Just typ), ..} = - documentation <> (wrapLanguageSyntax <$> nameOrSource <> typeAnnotation) <> location + hoverInfo SpanInfo{spaninfoType = (Just typ), spaninfoDocs = docs , ..} = + (wrapLanguageSyntax <$> nameOrSource) <> location <> docs where mbName = getNameM spaninfoSource - documentation = findDocumentation mbName - typeAnnotation = [colon <> showName typ] - nameOrSource = [maybe literalSource qualifyNameIfPossible mbName] + typeAnnotation = colon <> showName typ + nameOrSource = [maybe literalSource qualifyNameIfPossible mbName <> "\n" <> typeAnnotation] literalSource = "" -- TODO: literals: display (length-limited) source qualifyNameIfPossible name' = modulePrefix <> showName name' where modulePrefix = maybe "" (<> ".") (getModuleNameAsText name') location = [maybe "" definedAt mbName] - findDocumentation = maybe [] (getDocumentation tcs) - definedAt name = "**Defined " <> T.pack (showSDocUnsafe $ pprNameDefnLoc name) <> "**\n" + definedAt name = "*Defined " <> T.pack (showSDocUnsafe $ pprNameDefnLoc name) <> "*\n" range SpanInfo{..} = Range (Position spaninfoStartLine spaninfoStartCol) diff --git a/src/Development/IDE/Spans/Calculate.hs b/src/Development/IDE/Spans/Calculate.hs index 555a2e88d..d7a4fc70d 100644 --- a/src/Development/IDE/Spans/Calculate.hs +++ b/src/Development/IDE/Spans/Calculate.hs @@ -16,6 +16,7 @@ import Control.Monad import qualified CoreUtils import Data.List import Data.Maybe +import qualified Data.Text as T import DataCon import Desugar import GHC @@ -30,6 +31,7 @@ import Var import Development.IDE.Core.Compile import Development.IDE.GHC.Util import Development.IDE.Spans.Common +import Development.IDE.Spans.Documentation -- A lot of things gained an extra X argument in GHC 8.6, which we mostly ignore -- this U ignores that arg in 8.6, but is hidden in 8.4 @@ -44,40 +46,42 @@ getSrcSpanInfos :: HscEnv -> [(Located ModuleName, Maybe NormalizedFilePath)] -> TcModuleResult + -> [TcModuleResult] -> IO [SpanInfo] -getSrcSpanInfos env imports tc = - runGhcEnv env - . getSpanInfo imports - $ tmrModule tc +getSrcSpanInfos env imports tc tms = + runGhcEnv env $ + getSpanInfo imports (tmrModule tc) (map tmrModule tms) -- | Get ALL source spans in the module. getSpanInfo :: GhcMonad m => [(Located ModuleName, Maybe NormalizedFilePath)] -- ^ imports -> TypecheckedModule + -> [TypecheckedModule] -> m [SpanInfo] -getSpanInfo mods tcm = +getSpanInfo mods tcm tcms = do let tcs = tm_typechecked_source tcm bs = listifyAllSpans tcs :: [LHsBind GhcTc] es = listifyAllSpans tcs :: [LHsExpr GhcTc] ps = listifyAllSpans' tcs :: [Pat GhcTc] ts = listifyAllSpans $ tm_renamed_source tcm :: [LHsType GhcRn] - bts <- mapM (getTypeLHsBind tcm) bs -- binds - ets <- mapM (getTypeLHsExpr tcm) es -- expressions - pts <- mapM (getTypeLPat tcm) ps -- patterns - tts <- mapM (getLHsType tcm) ts -- types + allModules = tcm:tcms + bts <- mapM (getTypeLHsBind allModules) bs -- binds + ets <- mapM (getTypeLHsExpr allModules) es -- expressions + pts <- mapM (getTypeLPat allModules) ps -- patterns + tts <- mapM (getLHsType allModules) ts -- types let imports = importInfo mods let exports = getExports tcm let exprs = exports ++ imports ++ concat bts ++ concat tts ++ catMaybes (ets ++ pts) return (mapMaybe toSpanInfo (sortBy cmp exprs)) - where cmp (_,a,_) (_,b,_) + where cmp (_,a,_,_) (_,b,_,_) | a `isSubspanOf` b = LT | b `isSubspanOf` a = GT | otherwise = compare (srcSpanStart a) (srcSpanStart b) -getExports :: TypecheckedModule -> [(SpanSource, SrcSpan, Maybe Type)] +getExports :: TypecheckedModule -> [(SpanSource, SrcSpan, Maybe Type, [T.Text])] getExports m | Just (_, _, Just exports, _) <- renamedSource m = - [ (Named $ unLoc n, getLoc n, Nothing) + [ (Named $ unLoc n, getLoc n, Nothing, []) | (e, _) <- exports , n <- ieLNames $ unLoc e ] @@ -93,27 +97,32 @@ ieLNames _ = [] -- | Get the name and type of a binding. getTypeLHsBind :: (GhcMonad m) - => TypecheckedModule + => [TypecheckedModule] -> LHsBind GhcTc - -> m [(SpanSource, SrcSpan, Maybe Type)] -getTypeLHsBind _ (L _spn FunBind{ fun_id = pid - , fun_matches = MG{mg_alts=(L _ matches)}}) = - return [(Named (getName (unLoc pid)), getLoc match, Just (varType (unLoc pid))) | match <- matches ] + -> m [(SpanSource, SrcSpan, Maybe Type, [T.Text])] +getTypeLHsBind tms (L _spn FunBind{ fun_id = pid + , fun_matches = MG{mg_alts=(L _ matches)}}) = do + let name = getName (unLoc pid) + docs <- getDocumentationTryGhc' tms name + return [(Named name, getLoc match, Just (varType (unLoc pid)), docs) | match <- matches ] getTypeLHsBind _ _ = return [] -- | Get the name and type of an expression. getTypeLHsExpr :: (GhcMonad m) - => TypecheckedModule + => [TypecheckedModule] -> LHsExpr GhcTc - -> m (Maybe (SpanSource, SrcSpan, Maybe Type)) -getTypeLHsExpr _ e = do + -> m (Maybe (SpanSource, SrcSpan, Maybe Type, [T.Text])) +getTypeLHsExpr tms e = do hs_env <- getSession (_, mbe) <- liftIO (deSugarExpr hs_env e) - return $ - case mbe of - Just expr -> - Just (getSpanSource (unLoc e), getLoc e, Just (CoreUtils.exprType expr)) - Nothing -> Nothing + case mbe of + Just expr -> do + let ss = getSpanSource (unLoc e) + docs <- case ss of + Named n -> getDocumentationTryGhc' tms n + _ -> return [] + return $ Just (ss, getLoc e, Just (CoreUtils.exprType expr), docs) + Nothing -> return Nothing where getSpanSource :: HsExpr GhcTc -> SpanSource getSpanSource (HsVar U (L _ i)) = Named (getName i) @@ -125,12 +134,15 @@ getTypeLHsExpr _ e = do -- | Get the name and type of a pattern. getTypeLPat :: (GhcMonad m) - => TypecheckedModule + => [TypecheckedModule] -> Pat GhcTc - -> m (Maybe (SpanSource, SrcSpan, Maybe Type)) -getTypeLPat _ pat = - let (src, spn) = getSpanSource pat in - return $ Just (src, spn, Just (hsPatType pat)) + -> m (Maybe (SpanSource, SrcSpan, Maybe Type, [T.Text])) +getTypeLPat tms pat = do + let (src, spn) = getSpanSource pat + docs <- case src of + Named n -> getDocumentationTryGhc' tms n + _ -> return [] + return $ Just (src, spn, Just (hsPatType pat), docs) where getSpanSource :: Pat GhcTc -> (SpanSource, SrcSpan) getSpanSource (VarPat U (L spn vid)) = (Named (getName vid), spn) @@ -140,36 +152,36 @@ getTypeLPat _ pat = getLHsType :: GhcMonad m - => TypecheckedModule + => [TypecheckedModule] -> LHsType GhcRn - -> m [(SpanSource, SrcSpan, Maybe Type)] -getLHsType _ (L spn (HsTyVar U _ v)) = do + -> m [(SpanSource, SrcSpan, Maybe Type, [T.Text])] +getLHsType tms (L spn (HsTyVar U _ v)) = do let n = unLoc v - -- docs <- getDocumentationTryGhc' [tm] n + docs <- getDocumentationTryGhc' tms n ty <- catchSrcErrors "completion" $ do name' <- lookupName n return $ name' >>= safeTyThingType let ty' = case ty of Right (Just x) -> Just x _ -> Nothing - pure [(Named n, spn, ty')] + pure [(Named n, spn, ty', docs)] getLHsType _ _ = pure [] importInfo :: [(Located ModuleName, Maybe NormalizedFilePath)] - -> [(SpanSource, SrcSpan, Maybe Type)] + -> [(SpanSource, SrcSpan, Maybe Type, [T.Text])] importInfo = mapMaybe (uncurry wrk) where - wrk :: Located ModuleName -> Maybe NormalizedFilePath -> Maybe (SpanSource, SrcSpan, Maybe Type) + wrk :: Located ModuleName -> Maybe NormalizedFilePath -> Maybe (SpanSource, SrcSpan, Maybe Type, [T.Text]) wrk modName = \case Nothing -> Nothing - Just fp -> Just (fpToSpanSource $ fromNormalizedFilePath fp, getLoc modName, Nothing) + Just fp -> Just (fpToSpanSource $ fromNormalizedFilePath fp, getLoc modName, Nothing, []) -- TODO make this point to the module name fpToSpanSource :: FilePath -> SpanSource fpToSpanSource fp = SpanS $ RealSrcSpan $ zeroSpan $ mkFastString fp -- | Pretty print the types into a 'SpanInfo'. -toSpanInfo :: (SpanSource, SrcSpan, Maybe Type) -> Maybe SpanInfo -toSpanInfo (name,mspan,typ) = +toSpanInfo :: (SpanSource, SrcSpan, Maybe Type, [T.Text]) -> Maybe SpanInfo +toSpanInfo (name,mspan,typ,docs) = case mspan of RealSrcSpan spn -> -- GHC’s line and column numbers are 1-based while LSP’s line and column @@ -179,5 +191,6 @@ toSpanInfo (name,mspan,typ) = (srcSpanEndLine spn - 1) (srcSpanEndCol spn - 1) typ - name) + name + docs) _ -> Nothing diff --git a/src/Development/IDE/Spans/Type.hs b/src/Development/IDE/Spans/Type.hs index 437132292..3c1c851a4 100644 --- a/src/Development/IDE/Spans/Type.hs +++ b/src/Development/IDE/Spans/Type.hs @@ -14,6 +14,7 @@ module Development.IDE.Spans.Type( import GHC import Control.DeepSeq import OccName +import qualified Data.Text as T import Development.IDE.GHC.Util -- | Type of some span of source code. Most of these fields are @@ -34,9 +35,11 @@ data SpanInfo = -- any. This can be useful for accessing a variety of -- information about the identifier such as module, -- locality, definition location, etc. + ,spaninfoDocs :: ![T.Text] + -- ^ Documentation for the element } instance Show SpanInfo where - show (SpanInfo sl sc el ec t n) = + show (SpanInfo sl sc el ec t n _docs) = unwords ["(SpanInfo", show sl, show sc, show el, show ec , show $ maybe "NoType" prettyPrint t, "(" <> show n <> "))"] From 0373c024042e4c973d6e8fe2c572c336248ab6d9 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Fri, 10 Jan 2020 12:32:47 +0100 Subject: [PATCH 03/18] Enable kind tests --- test/exe/Main.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/exe/Main.hs b/test/exe/Main.hs index ff26345c5..4f499e4ce 100644 --- a/test/exe/Main.hs +++ b/test/exe/Main.hs @@ -1127,8 +1127,8 @@ findDefinitionAndHoverTests = let , test yes yes mclL36 mcl "top-level fn 1st clause" , test yes yes mclL37 mcl "top-level fn 2nd clause #246" , test no broken docL41 doc "documentation #7" - , test no broken eitL40 kindE "kind of Either #273" - , test no broken intL40 kindI "kind of Int #273" + , test no yes eitL40 kindE "kind of Either #273" + , test no yes intL40 kindI "kind of Int #273" , test no broken tvrL40 kindV "kind of (* -> *) type variable #273" , test no broken intL41 litI "literal Int in hover info #274" , test no broken chrL36 litC "literal Char in hover info #274" From 7535b24924c1d2944323e5b2c8a33bdc24512447 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Fri, 10 Jan 2020 14:55:38 +0100 Subject: [PATCH 04/18] Fix tests --- test/exe/Main.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/exe/Main.hs b/test/exe/Main.hs index 4f499e4ce..710c067d1 100644 --- a/test/exe/Main.hs +++ b/test/exe/Main.hs @@ -1029,7 +1029,7 @@ findDefinitionAndHoverTests = let _ -> liftIO $ assertFailure $ "test not expecting this kind of hover info" <> show hover extractLineColFromHoverMsg :: T.Text -> [T.Text] - extractLineColFromHoverMsg = T.splitOn ":" . head . T.splitOn "**" . last . T.splitOn (sourceFileName <> ":") + extractLineColFromHoverMsg = T.splitOn ":" . head . T.splitOn "*" . last . T.splitOn (sourceFileName <> ":") checkHoverRange :: Range -> Maybe Range -> T.Text -> Session () checkHoverRange expectedRange rangeInHover msg = From 44808882447b217f4a7c1b99b4bb452b2db7396d Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Fri, 10 Jan 2020 15:14:48 +0100 Subject: [PATCH 05/18] Print literals --- src/Development/IDE/Core/CompletionsTypes.hs | 8 ++------ src/Development/IDE/Spans/AtPoint.hs | 11 ++++++++--- src/Development/IDE/Spans/Calculate.hs | 6 +++++- src/Development/IDE/Spans/Common.hs | 9 ++++++++- src/Development/IDE/Spans/Type.hs | 3 +++ 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/Development/IDE/Core/CompletionsTypes.hs b/src/Development/IDE/Core/CompletionsTypes.hs index c7f5b33c3..12f169c6a 100644 --- a/src/Development/IDE/Core/CompletionsTypes.hs +++ b/src/Development/IDE/Core/CompletionsTypes.hs @@ -5,15 +5,11 @@ module Development.IDE.Core.CompletionsTypes ( import Control.DeepSeq import qualified Data.Map as Map import qualified Data.Text as T - import GHC -import Outputable -import DynFlags --- From haskell-ide-engine/src/Haskell/Ide/Engine/LSP/Completions.hs +import Development.IDE.Spans.Common -showGhc :: Outputable a => a -> String -showGhc = showPpr unsafeGlobalDynFlags +-- From haskell-ide-engine/src/Haskell/Ide/Engine/LSP/Completions.hs data Backtick = Surrounded | LeftSide deriving Show data CompItem = CI diff --git a/src/Development/IDE/Spans/AtPoint.hs b/src/Development/IDE/Spans/AtPoint.hs index 09c3b7107..17b77e926 100644 --- a/src/Development/IDE/Spans/AtPoint.hs +++ b/src/Development/IDE/Spans/AtPoint.hs @@ -17,7 +17,8 @@ import Development.Shake import Development.IDE.GHC.Util import Development.IDE.GHC.Compat import Development.IDE.Types.Options -import Development.IDE.Spans.Type as SpanInfo +import Development.IDE.Spans.Type as SpanInfo +import Development.IDE.Spans.Common -- GHC API imports import Avail @@ -72,8 +73,11 @@ atPoint IdeOptions{..} _ srcSpans pos = do where mbName = getNameM spaninfoSource typeAnnotation = colon <> showName typ - nameOrSource = [maybe literalSource qualifyNameIfPossible mbName <> "\n" <> typeAnnotation] - literalSource = "" -- TODO: literals: display (length-limited) source + expr = case spaninfoSource of + Named n -> qualifyNameIfPossible n + Lit _ l -> T.pack (showGhc l) + _ -> "" + nameOrSource = [expr <> "\n" <> typeAnnotation] qualifyNameIfPossible name' = modulePrefix <> showName name' where modulePrefix = maybe "" (<> ".") (getModuleNameAsText name') location = [maybe "" definedAt mbName] @@ -107,6 +111,7 @@ locationsAtPoint getHieFile IdeOptions{..} pkgState pos = where getSpan :: SpanSource -> m (Maybe SrcSpan) getSpan NoSource = pure Nothing getSpan (SpanS sp) = pure $ Just sp + getSpan (Lit sp _) = pure $ Just sp getSpan (Named name) = case nameSrcSpan name of sp@(RealSrcSpan _) -> pure $ Just sp sp@(UnhelpfulSpan _) -> runMaybeT $ do diff --git a/src/Development/IDE/Spans/Calculate.hs b/src/Development/IDE/Spans/Calculate.hs index d7a4fc70d..93babd84d 100644 --- a/src/Development/IDE/Spans/Calculate.hs +++ b/src/Development/IDE/Spans/Calculate.hs @@ -117,13 +117,17 @@ getTypeLHsExpr tms e = do (_, mbe) <- liftIO (deSugarExpr hs_env e) case mbe of Just expr -> do - let ss = getSpanSource (unLoc e) + let ss = getSpanSource' e docs <- case ss of Named n -> getDocumentationTryGhc' tms n _ -> return [] return $ Just (ss, getLoc e, Just (CoreUtils.exprType expr), docs) Nothing -> return Nothing where + getSpanSource' :: LHsExpr GhcTc -> SpanSource + getSpanSource' (L s xpr) + | HsLit U lit <- xpr = Lit s lit + getSpanSource' xpr = getSpanSource (unLoc xpr) getSpanSource :: HsExpr GhcTc -> SpanSource getSpanSource (HsVar U (L _ i)) = Named (getName i) getSpanSource (HsConLikeOut U (RealDataCon dc)) = Named (dataConName dc) diff --git a/src/Development/IDE/Spans/Common.hs b/src/Development/IDE/Spans/Common.hs index bfea85e0f..71cd49902 100644 --- a/src/Development/IDE/Spans/Common.hs +++ b/src/Development/IDE/Spans/Common.hs @@ -1,5 +1,6 @@ module Development.IDE.Spans.Common ( - listifyAllSpans + showGhc +, listifyAllSpans , listifyAllSpans' , safeTyThingId , safeTyThingType @@ -12,6 +13,12 @@ import GHC import ConLike import Var import DataCon +import Outputable +import DynFlags + + +showGhc :: Outputable a => a -> String +showGhc = showPpr unsafeGlobalDynFlags -- | Get ALL source spans in the source. listifyAllSpans :: (Typeable a, Data m) => m -> [Located a] diff --git a/src/Development/IDE/Spans/Type.hs b/src/Development/IDE/Spans/Type.hs index 3c1c851a4..3d385ade1 100644 --- a/src/Development/IDE/Spans/Type.hs +++ b/src/Development/IDE/Spans/Type.hs @@ -16,6 +16,7 @@ import Control.DeepSeq import OccName import qualified Data.Text as T import Development.IDE.GHC.Util +import Development.IDE.Spans.Common -- | Type of some span of source code. Most of these fields are -- unboxed but Haddock doesn't show that. @@ -50,6 +51,7 @@ instance NFData SpanInfo where -- we don't always get a name out so sometimes manually annotating source is more appropriate data SpanSource = Named Name | SpanS SrcSpan + | Lit SrcSpan (HsLit GhcTc) | NoSource deriving (Eq) @@ -57,6 +59,7 @@ instance Show SpanSource where show = \case Named n -> "Named " ++ occNameString (occName n) SpanS sp -> "Span " ++ show sp + Lit sp lit -> "Lit " ++ show sp ++ " " ++ showGhc lit NoSource -> "NoSource" getNameM :: SpanSource -> Maybe Name From cd34d0d3ba54b047e4a0fc4a1a95a052f8058703 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Fri, 10 Jan 2020 15:27:15 +0100 Subject: [PATCH 06/18] Show (some) overloaded literals --- src/Development/IDE/Spans/AtPoint.hs | 7 +++++-- src/Development/IDE/Spans/Calculate.hs | 3 ++- src/Development/IDE/Spans/Documentation.hs | 2 +- src/Development/IDE/Spans/Type.hs | 5 ++--- test/exe/Main.hs | 4 ++-- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Development/IDE/Spans/AtPoint.hs b/src/Development/IDE/Spans/AtPoint.hs index 17b77e926..5880702ac 100644 --- a/src/Development/IDE/Spans/AtPoint.hs +++ b/src/Development/IDE/Spans/AtPoint.hs @@ -18,7 +18,6 @@ import Development.IDE.GHC.Util import Development.IDE.GHC.Compat import Development.IDE.Types.Options import Development.IDE.Spans.Type as SpanInfo -import Development.IDE.Spans.Common -- GHC API imports import Avail @@ -75,7 +74,7 @@ atPoint IdeOptions{..} _ srcSpans pos = do typeAnnotation = colon <> showName typ expr = case spaninfoSource of Named n -> qualifyNameIfPossible n - Lit _ l -> T.pack (showGhc l) + Lit _ l -> crop $ T.pack l _ -> "" nameOrSource = [expr <> "\n" <> typeAnnotation] qualifyNameIfPossible name' = modulePrefix <> showName name' @@ -84,6 +83,10 @@ atPoint IdeOptions{..} _ srcSpans pos = do definedAt name = "*Defined " <> T.pack (showSDocUnsafe $ pprNameDefnLoc name) <> "*\n" + crop txt + | T.length txt > 50 = T.take 46 txt <> " ..." + | otherwise = txt + range SpanInfo{..} = Range (Position spaninfoStartLine spaninfoStartCol) (Position spaninfoEndLine spaninfoEndCol) diff --git a/src/Development/IDE/Spans/Calculate.hs b/src/Development/IDE/Spans/Calculate.hs index 93babd84d..ea22721e8 100644 --- a/src/Development/IDE/Spans/Calculate.hs +++ b/src/Development/IDE/Spans/Calculate.hs @@ -126,7 +126,8 @@ getTypeLHsExpr tms e = do where getSpanSource' :: LHsExpr GhcTc -> SpanSource getSpanSource' (L s xpr) - | HsLit U lit <- xpr = Lit s lit + | HsLit U lit <- xpr = Lit s (showGhc lit) + | HsOverLit U lit <- xpr = Lit s (showGhc lit) getSpanSource' xpr = getSpanSource (unLoc xpr) getSpanSource :: HsExpr GhcTc -> SpanSource getSpanSource (HsVar U (L _ i)) = Named (getName i) diff --git a/src/Development/IDE/Spans/Documentation.hs b/src/Development/IDE/Spans/Documentation.hs index 1ff2f50a9..d2bf5add6 100644 --- a/src/Development/IDE/Spans/Documentation.hs +++ b/src/Development/IDE/Spans/Documentation.hs @@ -48,7 +48,7 @@ getDocumentationTryGhc' tcs name = do Right (Right (Just docs, _)) -> return [T.pack $ haddockToMarkdown $ H.toRegular $ H._doc $ H.parseParas Nothing $ unpackHDS docs] _ -> return $ getDocumentation tcs name #else -getDocumentationTryGhc _packageState tcs name = do +getDocumentationTryGhc' _packageState tcs name = do return $ getDocumentation tcs name #endif diff --git a/src/Development/IDE/Spans/Type.hs b/src/Development/IDE/Spans/Type.hs index 3d385ade1..bbcc0fd35 100644 --- a/src/Development/IDE/Spans/Type.hs +++ b/src/Development/IDE/Spans/Type.hs @@ -16,7 +16,6 @@ import Control.DeepSeq import OccName import qualified Data.Text as T import Development.IDE.GHC.Util -import Development.IDE.Spans.Common -- | Type of some span of source code. Most of these fields are -- unboxed but Haddock doesn't show that. @@ -51,7 +50,7 @@ instance NFData SpanInfo where -- we don't always get a name out so sometimes manually annotating source is more appropriate data SpanSource = Named Name | SpanS SrcSpan - | Lit SrcSpan (HsLit GhcTc) + | Lit SrcSpan String | NoSource deriving (Eq) @@ -59,7 +58,7 @@ instance Show SpanSource where show = \case Named n -> "Named " ++ occNameString (occName n) SpanS sp -> "Span " ++ show sp - Lit sp lit -> "Lit " ++ show sp ++ " " ++ showGhc lit + Lit sp lit -> "Lit " ++ show sp ++ " " ++ lit NoSource -> "NoSource" getNameM :: SpanSource -> Maybe Name diff --git a/test/exe/Main.hs b/test/exe/Main.hs index 710c067d1..977c68ff2 100644 --- a/test/exe/Main.hs +++ b/test/exe/Main.hs @@ -1130,8 +1130,8 @@ findDefinitionAndHoverTests = let , test no yes eitL40 kindE "kind of Either #273" , test no yes intL40 kindI "kind of Int #273" , test no broken tvrL40 kindV "kind of (* -> *) type variable #273" - , test no broken intL41 litI "literal Int in hover info #274" - , test no broken chrL36 litC "literal Char in hover info #274" + , test no yes intL41 litI "literal Int in hover info #274" + , test no yes chrL36 litC "literal Char in hover info #274" , test no broken txtL8 litT "literal Text in hover info #274" , test no broken lstL43 litL "literal List in hover info #274" , test no broken docL41 constr "type constraint in hover info #283" From ccbbfeaddcb7e0e358a6389fde2829b8fa1c29b4 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Fri, 10 Jan 2020 16:25:19 +0100 Subject: [PATCH 07/18] Fix for 8.4 --- src/Development/IDE/Spans/Documentation.hs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Development/IDE/Spans/Documentation.hs b/src/Development/IDE/Spans/Documentation.hs index d2bf5add6..76d6145c3 100644 --- a/src/Development/IDE/Spans/Documentation.hs +++ b/src/Development/IDE/Spans/Documentation.hs @@ -33,8 +33,13 @@ getDocumentationTryGhc -> [TypecheckedModule] -> Name -> IO [T.Text] +#if MIN_GHC_API_VERSION(8,6,0) getDocumentationTryGhc packageState tcs name = runGhcEnv packageState $ getDocumentationTryGhc' tcs name +#else +getDocumentationTryGhc _packageState tcs name = + return $ getDocumentation tcs name +#endif getDocumentationTryGhc' :: GhcMonad m @@ -48,7 +53,7 @@ getDocumentationTryGhc' tcs name = do Right (Right (Just docs, _)) -> return [T.pack $ haddockToMarkdown $ H.toRegular $ H._doc $ H.parseParas Nothing $ unpackHDS docs] _ -> return $ getDocumentation tcs name #else -getDocumentationTryGhc' _packageState tcs name = do +getDocumentationTryGhc' tcs name = do return $ getDocumentation tcs name #endif From 8330ca34ae098ede1edbe8d4e1917fca7fedf003 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Fri, 10 Jan 2020 16:59:00 +0100 Subject: [PATCH 08/18] Fix tests --- test/exe/Main.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/exe/Main.hs b/test/exe/Main.hs index 3bfbfca4e..0059b0a5e 100644 --- a/test/exe/Main.hs +++ b/test/exe/Main.hs @@ -1092,14 +1092,14 @@ findDefinitionAndHoverTests = let lclL33 = Position 33 22 mclL36 = Position 36 1 ; mcl = [mkR 36 0 36 14] mclL37 = Position 37 1 - spaceL37 = Position 37 24 ; space = [ExpectNoDefinitions, ExpectHoverText [":: Char"]] + spaceL37 = Position 37 24 ; space = [ExpectHoverText [":: Char"]] docL41 = Position 41 1 ; doc = [ExpectHoverText ["Recognizable docs: kpqz"]] ; constr = [ExpectHoverText ["Monad m =>"]] eitL40 = Position 40 28 ; kindE = [ExpectHoverText [":: * -> * -> *\n"]] intL40 = Position 40 34 ; kindI = [ExpectHoverText [":: *\n"]] tvrL40 = Position 40 37 ; kindV = [ExpectHoverText [":: * -> *\n"]] intL41 = Position 41 20 ; litI = [ExpectHoverText ["7518"]] - chrL36 = Position 36 25 ; litC = [ExpectHoverText ["'t'"]] + chrL36 = Position 37 24 ; litC = [ExpectHoverText ["'f'"]] txtL8 = Position 8 14 ; litT = [ExpectHoverText ["\"dfgv\""]] lstL43 = Position 43 12 ; litL = [ExpectHoverText ["[ 8391 :: Int, 6268 ]"]] outL45 = Position 45 3 ; outSig = [ExpectHoverText ["outer", "Bool"], mkR 46 0 46 5] From 6f72be74033396783580b1bf64211b61d4252890 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Fri, 10 Jan 2020 17:04:10 +0100 Subject: [PATCH 09/18] Do not consider literals for definitions --- src/Development/IDE/Spans/AtPoint.hs | 2 +- test/exe/Main.hs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Development/IDE/Spans/AtPoint.hs b/src/Development/IDE/Spans/AtPoint.hs index 5880702ac..74651e7a1 100644 --- a/src/Development/IDE/Spans/AtPoint.hs +++ b/src/Development/IDE/Spans/AtPoint.hs @@ -114,7 +114,7 @@ locationsAtPoint getHieFile IdeOptions{..} pkgState pos = where getSpan :: SpanSource -> m (Maybe SrcSpan) getSpan NoSource = pure Nothing getSpan (SpanS sp) = pure $ Just sp - getSpan (Lit sp _) = pure $ Just sp + getSpan (Lit _ _) = pure Nothing getSpan (Named name) = case nameSrcSpan name of sp@(RealSrcSpan _) -> pure $ Just sp sp@(UnhelpfulSpan _) -> runMaybeT $ do diff --git a/test/exe/Main.hs b/test/exe/Main.hs index 0059b0a5e..a5eaa1adc 100644 --- a/test/exe/Main.hs +++ b/test/exe/Main.hs @@ -1092,7 +1092,7 @@ findDefinitionAndHoverTests = let lclL33 = Position 33 22 mclL36 = Position 36 1 ; mcl = [mkR 36 0 36 14] mclL37 = Position 37 1 - spaceL37 = Position 37 24 ; space = [ExpectHoverText [":: Char"]] + spaceL37 = Position 37 24 ; space = [ExpectNoDefinitions, ExpectHoverText [":: Char"]] docL41 = Position 41 1 ; doc = [ExpectHoverText ["Recognizable docs: kpqz"]] ; constr = [ExpectHoverText ["Monad m =>"]] eitL40 = Position 40 28 ; kindE = [ExpectHoverText [":: * -> * -> *\n"]] From c459abf8c3cf2dcf9595832072c3892988924d6c Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Thu, 16 Jan 2020 15:11:25 +0100 Subject: [PATCH 10/18] Suggestions by @cocreature --- .hlint.yaml | 1 + src/Development/IDE/Core/Completions.hs | 6 +- src/Development/IDE/Core/CompletionsTypes.hs | 2 +- src/Development/IDE/Core/Rules.hs | 4 +- src/Development/IDE/Spans/AtPoint.hs | 12 +- src/Development/IDE/Spans/Calculate.hs | 50 ++++----- src/Development/IDE/Spans/Common.hs | 100 ++++++++++++++++- src/Development/IDE/Spans/Documentation.hs | 112 ++----------------- src/Development/IDE/Spans/Type.hs | 15 +-- 9 files changed, 150 insertions(+), 152 deletions(-) diff --git a/.hlint.yaml b/.hlint.yaml index f98cd88df..99331c036 100644 --- a/.hlint.yaml +++ b/.hlint.yaml @@ -84,6 +84,7 @@ - Development.IDE.LSP.CodeAction - Development.IDE.Spans.Calculate - Development.IDE.Spans.Documentation + - Development.IDE.Spans.Common - Main - flags: diff --git a/src/Development/IDE/Core/Completions.hs b/src/Development/IDE/Core/Completions.hs index 1f7398b0d..09c2fe84c 100644 --- a/src/Development/IDE/Core/Completions.hs +++ b/src/Development/IDE/Core/Completions.hs @@ -139,7 +139,7 @@ mkCompl IdeOptions{..} CI{origName,importedFrom,thingType,label,isInfix,docs} = typeText | Just t <- thingType = Just . stripForall $ T.pack (showGhc t) | otherwise = Nothing - docs' = ("*Defined in '" <> importedFrom <> "'*\n") : docs + docs' = ("*Defined in '" <> importedFrom <> "'*\n") : spanDocToMarkdown docs colon = if optNewColonConvention then ": " else ":: " stripForall :: T.Text -> T.Text @@ -256,12 +256,12 @@ cacheDataProducer packageState dflags tm tcs = do let typ = Just $ varType var name = Var.varName var label = T.pack $ showGhc name - docs <- getDocumentationTryGhc packageState (tm:tcs) name + docs <- runGhcEnv packageState $ getDocumentationTryGhc (tm:tcs) name return $ CI name (showModName curMod) typ label Nothing docs toCompItem :: ModuleName -> Name -> IO CompItem toCompItem mn n = do - docs <- getDocumentationTryGhc packageState (tm:tcs) n + docs <- runGhcEnv packageState $ getDocumentationTryGhc (tm:tcs) n ty <- runGhcEnv packageState $ catchSrcErrors "completion" $ do name' <- lookupName n return $ name' >>= safeTyThingType diff --git a/src/Development/IDE/Core/CompletionsTypes.hs b/src/Development/IDE/Core/CompletionsTypes.hs index 12f169c6a..cce485750 100644 --- a/src/Development/IDE/Core/CompletionsTypes.hs +++ b/src/Development/IDE/Core/CompletionsTypes.hs @@ -19,7 +19,7 @@ data CompItem = CI , label :: T.Text -- ^ Label to display to the user. , isInfix :: Maybe Backtick -- ^ Did the completion happen -- in the context of an infix notation. - , docs :: [T.Text] -- ^ Available documentation. + , docs :: SpanDoc -- ^ Available documentation. } instance Show CompItem where show CI { .. } = "CompItem { origName = \"" ++ showGhc origName ++ "\"" diff --git a/src/Development/IDE/Core/Rules.hs b/src/Development/IDE/Core/Rules.hs index 859e21431..d0d14a3ce 100644 --- a/src/Development/IDE/Core/Rules.hs +++ b/src/Development/IDE/Core/Rules.hs @@ -104,9 +104,7 @@ getAtPoint :: NormalizedFilePath -> Position -> Action (Maybe (Maybe Range, [T.T getAtPoint file pos = fmap join $ runMaybeT $ do opts <- lift getIdeOptions spans <- useE GetSpanInfo file - files <- transitiveModuleDeps <$> useE GetDependencies file - tms <- usesE TypeCheck (file : files) - return $ AtPoint.atPoint opts (map tmrModule tms) spans pos + return $ AtPoint.atPoint opts spans pos -- | Goto Definition. getDefinition :: NormalizedFilePath -> Position -> Action (Maybe Location) diff --git a/src/Development/IDE/Spans/AtPoint.hs b/src/Development/IDE/Spans/AtPoint.hs index 74651e7a1..e8faadb95 100644 --- a/src/Development/IDE/Spans/AtPoint.hs +++ b/src/Development/IDE/Spans/AtPoint.hs @@ -18,6 +18,7 @@ import Development.IDE.GHC.Util import Development.IDE.GHC.Compat import Development.IDE.Types.Options import Development.IDE.Spans.Type as SpanInfo +import Development.IDE.Spans.Common (spanDocToMarkdown) -- GHC API imports import Avail @@ -49,17 +50,16 @@ gotoDefinition getHieFile ideOpts pkgState srcSpans pos = -- | Synopsis for the name at a given position. atPoint :: IdeOptions - -> [TypecheckedModule] -> [SpanInfo] -> Position -> Maybe (Maybe Range, [T.Text]) -atPoint IdeOptions{..} _ srcSpans pos = do +atPoint IdeOptions{..} srcSpans pos = do firstSpan <- listToMaybe $ deEmpasizeGeneratedEqShow $ spansAtPoint pos srcSpans return (Just (range firstSpan), hoverInfo firstSpan) where -- Hover info for types, classes, type variables hoverInfo SpanInfo{spaninfoType = Nothing , spaninfoDocs = docs , ..} = - (wrapLanguageSyntax <$> name) <> location <> docs + (wrapLanguageSyntax <$> name) <> location <> spanDocToMarkdown docs where name = [maybe shouldNotHappen showName mbName] location = [maybe shouldNotHappen definedAt mbName] @@ -68,13 +68,13 @@ atPoint IdeOptions{..} _ srcSpans pos = do -- Hover info for values/data hoverInfo SpanInfo{spaninfoType = (Just typ), spaninfoDocs = docs , ..} = - (wrapLanguageSyntax <$> nameOrSource) <> location <> docs + (wrapLanguageSyntax <$> nameOrSource) <> location <> spanDocToMarkdown docs where mbName = getNameM spaninfoSource typeAnnotation = colon <> showName typ expr = case spaninfoSource of Named n -> qualifyNameIfPossible n - Lit _ l -> crop $ T.pack l + Lit l -> crop $ T.pack l _ -> "" nameOrSource = [expr <> "\n" <> typeAnnotation] qualifyNameIfPossible name' = modulePrefix <> showName name' @@ -114,7 +114,7 @@ locationsAtPoint getHieFile IdeOptions{..} pkgState pos = where getSpan :: SpanSource -> m (Maybe SrcSpan) getSpan NoSource = pure Nothing getSpan (SpanS sp) = pure $ Just sp - getSpan (Lit _ _) = pure Nothing + getSpan (Lit _) = pure Nothing getSpan (Named name) = case nameSrcSpan name of sp@(RealSrcSpan _) -> pure $ Just sp sp@(UnhelpfulSpan _) -> runMaybeT $ do diff --git a/src/Development/IDE/Spans/Calculate.hs b/src/Development/IDE/Spans/Calculate.hs index bde444d94..a89f86427 100644 --- a/src/Development/IDE/Spans/Calculate.hs +++ b/src/Development/IDE/Spans/Calculate.hs @@ -16,7 +16,6 @@ import Control.Monad import qualified CoreUtils import Data.List import Data.Maybe -import qualified Data.Text as T import DataCon import Desugar import GHC @@ -74,13 +73,15 @@ getSpanInfo mods tcm tcms = tts <- mapM (getLHsType allModules) ts -- types let imports = importInfo mods let exports = getExports tcm - let exprs = exports ++ imports ++ concat bts ++ concat tts ++ catMaybes (ets ++ pts) + let exprs = addEmptyInfo exports ++ addEmptyInfo imports ++ concat bts ++ concat tts ++ catMaybes (ets ++ pts) return (mapMaybe toSpanInfo (sortBy cmp exprs)) where cmp (_,a,_,_) (_,b,_,_) | a `isSubspanOf` b = LT | b `isSubspanOf` a = GT | otherwise = compare (srcSpanStart a) (srcSpanStart b) + addEmptyInfo = map (\(a,b) -> (a,b,Nothing,emptySpanDoc)) + -- | The locations in the typechecked module are slightly messed up in some cases (e.g. HsMatchContext always -- points to the first match) whereas the parsed module has the correct locations. -- Therefore we build up a map from OccName to the corresponding definition in the parsed module @@ -90,10 +91,10 @@ getSpanInfo mods tcm tcms = funBindMap :: ParsedModule -> OccEnv (HsBind GhcPs) funBindMap pm = mkOccEnv $ [ (occName $ unLoc f, bnd) | L _ (Compat.ValD bnd@FunBind{fun_id = f}) <- hsmodDecls $ unLoc $ pm_parsed_source pm ] -getExports :: TypecheckedModule -> [(SpanSource, SrcSpan, Maybe Type, [T.Text])] +getExports :: TypecheckedModule -> [(SpanSource, SrcSpan)] getExports m | Just (_, _, Just exports, _) <- renamedSource m = - [ (Named $ unLoc n, getLoc n, Nothing, []) + [ (Named $ unLoc n, getLoc n) | (e, _) <- exports , n <- ieLNames $ unLoc e ] @@ -112,16 +113,16 @@ getTypeLHsBind :: (GhcMonad m) => [TypecheckedModule] -> OccEnv (HsBind GhcPs) -> LHsBind GhcTc - -> m [(SpanSource, SrcSpan, Maybe Type, [T.Text])] + -> m [(SpanSource, SrcSpan, Maybe Type, SpanDoc)] getTypeLHsBind tms funBinds (L _spn FunBind{fun_id = pid}) | Just FunBind {fun_matches = MG{mg_alts=L _ matches}} <- lookupOccEnv funBinds (occName $ unLoc pid) = do let name = getName (unLoc pid) - docs <- getDocumentationTryGhc' tms name + docs <- getDocumentationTryGhc tms name return [(Named name, getLoc mc_fun, Just (varType (unLoc pid)), docs) | match <- matches, FunRhs{mc_fun = mc_fun} <- [m_ctxt $ unLoc match] ] -- In theory this shouldn’t ever fail but if it does, we can at least show the first clause. getTypeLHsBind tms _ (L _spn FunBind{fun_id = pid,fun_matches = MG{}}) = do let name = getName (unLoc pid) - docs <- getDocumentationTryGhc' tms name + docs <- getDocumentationTryGhc tms name return [(Named name, getLoc pid, Just (varType (unLoc pid)), docs)] getTypeLHsBind _ _ _ = return [] @@ -129,42 +130,39 @@ getTypeLHsBind _ _ _ = return [] getTypeLHsExpr :: (GhcMonad m) => [TypecheckedModule] -> LHsExpr GhcTc - -> m (Maybe (SpanSource, SrcSpan, Maybe Type, [T.Text])) + -> m (Maybe (SpanSource, SrcSpan, Maybe Type, SpanDoc)) getTypeLHsExpr tms e = do hs_env <- getSession (_, mbe) <- liftIO (deSugarExpr hs_env e) case mbe of Just expr -> do - let ss = getSpanSource' e + let ss = getSpanSource (unLoc e) docs <- case ss of - Named n -> getDocumentationTryGhc' tms n - _ -> return [] + Named n -> getDocumentationTryGhc tms n + _ -> return emptySpanDoc return $ Just (ss, getLoc e, Just (CoreUtils.exprType expr), docs) Nothing -> return Nothing where - getSpanSource' :: LHsExpr GhcTc -> SpanSource - getSpanSource' (L s xpr) - | HsLit U lit <- xpr = Lit s (showGhc lit) - | HsOverLit U lit <- xpr = Lit s (showGhc lit) - getSpanSource' xpr = getSpanSource (unLoc xpr) getSpanSource :: HsExpr GhcTc -> SpanSource + getSpanSource (HsLit U lit) = Lit (showGhc lit) + getSpanSource (HsOverLit U lit) = Lit (showGhc lit) getSpanSource (HsVar U (L _ i)) = Named (getName i) getSpanSource (HsConLikeOut U (RealDataCon dc)) = Named (dataConName dc) getSpanSource RecordCon {rcon_con_name} = Named (getName rcon_con_name) getSpanSource (HsWrap U _ xpr) = getSpanSource xpr getSpanSource (HsPar U xpr) = getSpanSource (unLoc xpr) - getSpanSource _ = NoSource + getSpanSource _ = NoSource -- | Get the name and type of a pattern. getTypeLPat :: (GhcMonad m) => [TypecheckedModule] -> Pat GhcTc - -> m (Maybe (SpanSource, SrcSpan, Maybe Type, [T.Text])) + -> m (Maybe (SpanSource, SrcSpan, Maybe Type, SpanDoc)) getTypeLPat tms pat = do let (src, spn) = getSpanSource pat docs <- case src of - Named n -> getDocumentationTryGhc' tms n - _ -> return [] + Named n -> getDocumentationTryGhc tms n + _ -> return emptySpanDoc return $ Just (src, spn, Just (hsPatType pat), docs) where getSpanSource :: Pat GhcTc -> (SpanSource, SrcSpan) @@ -177,10 +175,10 @@ getLHsType :: GhcMonad m => [TypecheckedModule] -> LHsType GhcRn - -> m [(SpanSource, SrcSpan, Maybe Type, [T.Text])] + -> m [(SpanSource, SrcSpan, Maybe Type, SpanDoc)] getLHsType tms (L spn (HsTyVar U _ v)) = do let n = unLoc v - docs <- getDocumentationTryGhc' tms n + docs <- getDocumentationTryGhc tms n ty <- catchSrcErrors "completion" $ do name' <- lookupName n return $ name' >>= safeTyThingType @@ -191,19 +189,19 @@ getLHsType tms (L spn (HsTyVar U _ v)) = do getLHsType _ _ = pure [] importInfo :: [(Located ModuleName, Maybe NormalizedFilePath)] - -> [(SpanSource, SrcSpan, Maybe Type, [T.Text])] + -> [(SpanSource, SrcSpan)] importInfo = mapMaybe (uncurry wrk) where - wrk :: Located ModuleName -> Maybe NormalizedFilePath -> Maybe (SpanSource, SrcSpan, Maybe Type, [T.Text]) + wrk :: Located ModuleName -> Maybe NormalizedFilePath -> Maybe (SpanSource, SrcSpan) wrk modName = \case Nothing -> Nothing - Just fp -> Just (fpToSpanSource $ fromNormalizedFilePath fp, getLoc modName, Nothing, []) + Just fp -> Just (fpToSpanSource $ fromNormalizedFilePath fp, getLoc modName) -- TODO make this point to the module name fpToSpanSource :: FilePath -> SpanSource fpToSpanSource fp = SpanS $ RealSrcSpan $ zeroSpan $ mkFastString fp -- | Pretty print the types into a 'SpanInfo'. -toSpanInfo :: (SpanSource, SrcSpan, Maybe Type, [T.Text]) -> Maybe SpanInfo +toSpanInfo :: (SpanSource, SrcSpan, Maybe Type, SpanDoc) -> Maybe SpanInfo toSpanInfo (name,mspan,typ,docs) = case mspan of RealSrcSpan spn -> diff --git a/src/Development/IDE/Spans/Common.hs b/src/Development/IDE/Spans/Common.hs index 71cd49902..f51da818f 100644 --- a/src/Development/IDE/Spans/Common.hs +++ b/src/Development/IDE/Spans/Common.hs @@ -1,13 +1,18 @@ +{-# LANGUAGE CPP #-} module Development.IDE.Spans.Common ( showGhc , listifyAllSpans , listifyAllSpans' , safeTyThingId , safeTyThingType +, SpanDoc(..) +, emptySpanDoc +, spanDocToMarkdown ) where import Data.Data import qualified Data.Generics +import qualified Data.Text as T import GHC import ConLike @@ -16,6 +21,9 @@ import DataCon import Outputable import DynFlags +import Data.Char (isSpace) +import qualified Documentation.Haddock.Parser as H +import qualified Documentation.Haddock.Types as H showGhc :: Outputable a => a -> String showGhc = showPpr unsafeGlobalDynFlags @@ -43,4 +51,94 @@ safeTyThingType :: TyThing -> Maybe Type safeTyThingType thing | Just i <- safeTyThingId thing = Just (varType i) safeTyThingType (ATyCon tycon) = Just (tyConKind tycon) -safeTyThingType _ = Nothing \ No newline at end of file +safeTyThingType _ = Nothing + +-- Possible documentation for an element in the code +data SpanDoc + = SpanDocString HsDocString + | SpanDocText [T.Text] + deriving Show + +emptySpanDoc :: SpanDoc +emptySpanDoc = SpanDocText [] + +spanDocToMarkdown :: SpanDoc -> [T.Text] +spanDocToMarkdown (SpanDocString docs) + = [T.pack $ haddockToMarkdown $ H.toRegular $ H._doc $ H.parseParas Nothing $ unpackHDS docs] +spanDocToMarkdown (SpanDocText txt) = txt + +-- Simple (and a bit hacky) conversion from Haddock markup to Markdown +haddockToMarkdown + :: H.DocH String String -> String + +haddockToMarkdown H.DocEmpty + = "" +haddockToMarkdown (H.DocAppend d1 d2) + = haddockToMarkdown d1 Prelude.<> haddockToMarkdown d2 +haddockToMarkdown (H.DocString s) + = s +haddockToMarkdown (H.DocParagraph p) + = "\n\n" ++ haddockToMarkdown p +haddockToMarkdown (H.DocIdentifier i) + = "`" ++ i ++ "`" +haddockToMarkdown (H.DocIdentifierUnchecked i) + = "`" ++ i ++ "`" +haddockToMarkdown (H.DocModule i) + = "`" ++ i ++ "`" +haddockToMarkdown (H.DocWarning w) + = haddockToMarkdown w +haddockToMarkdown (H.DocEmphasis d) + = "*" ++ haddockToMarkdown d ++ "*" +haddockToMarkdown (H.DocBold d) + = "**" ++ haddockToMarkdown d ++ "**" +haddockToMarkdown (H.DocMonospaced d) + = "`" ++ escapeBackticks (haddockToMarkdown d) ++ "`" + where + escapeBackticks "" = "" + escapeBackticks ('`':ss) = '\\':'`':escapeBackticks ss + escapeBackticks (s :ss) = s:escapeBackticks ss +haddockToMarkdown (H.DocCodeBlock d) + = "\n```haskell\n" ++ haddockToMarkdown d ++ "\n```\n" +haddockToMarkdown (H.DocExamples es) + = "\n```haskell\n" ++ unlines (map exampleToMarkdown es) ++ "\n```\n" + where + exampleToMarkdown (H.Example expr result) + = ">>> " ++ expr ++ "\n" ++ unlines result +haddockToMarkdown (H.DocHyperlink (H.Hyperlink url Nothing)) + = "<" ++ url ++ ">" +#if MIN_VERSION_haddock_library(1,8,0) +haddockToMarkdown (H.DocHyperlink (H.Hyperlink url (Just label))) + = "[" ++ haddockToMarkdown label ++ "](" ++ url ++ ")" +#else +haddockToMarkdown (H.DocHyperlink (H.Hyperlink url (Just label))) + = "[" ++ label ++ "](" ++ url ++ ")" +#endif +haddockToMarkdown (H.DocPic (H.Picture url Nothing)) + = "![](" ++ url ++ ")" +haddockToMarkdown (H.DocPic (H.Picture url (Just label))) + = "![" ++ label ++ "](" ++ url ++ ")" +haddockToMarkdown (H.DocAName aname) + = "[" ++ aname ++ "]:" +haddockToMarkdown (H.DocHeader (H.Header level title)) + = replicate level '#' ++ " " ++ haddockToMarkdown title + +haddockToMarkdown (H.DocUnorderedList things) + = '\n' : (unlines $ map (\thing -> "+ " ++ dropWhile isSpace (haddockToMarkdown thing)) things) +haddockToMarkdown (H.DocOrderedList things) + = '\n' : (unlines $ map (\thing -> "1. " ++ dropWhile isSpace (haddockToMarkdown thing)) things) +haddockToMarkdown (H.DocDefList things) + = '\n' : (unlines $ map (\(term, defn) -> "+ **" ++ haddockToMarkdown term ++ "**: " ++ haddockToMarkdown defn) things) + +-- we cannot render math by default +haddockToMarkdown (H.DocMathInline _) + = "*cannot render inline math formula*" +haddockToMarkdown (H.DocMathDisplay _) + = "\n\n*cannot render display math formula*\n\n" + +-- TODO: render tables +haddockToMarkdown (H.DocTable _t) + = "\n\n*tables are not yet supported*\n\n" + +-- things I don't really know how to handle +haddockToMarkdown (H.DocProperty _) + = "" -- don't really know what to do diff --git a/src/Development/IDE/Spans/Documentation.hs b/src/Development/IDE/Spans/Documentation.hs index 76d6145c3..e3fed96d4 100644 --- a/src/Development/IDE/Spans/Documentation.hs +++ b/src/Development/IDE/Spans/Documentation.hs @@ -7,7 +7,6 @@ module Development.IDE.Spans.Documentation ( getDocumentation , getDocumentationTryGhc - , getDocumentationTryGhc' ) where import Control.Monad @@ -21,40 +20,21 @@ import FastString import GHC import SrcLoc -#if MIN_GHC_API_VERSION(8,6,0) -import Data.Char (isSpace) -import Development.IDE.GHC.Util -import qualified Documentation.Haddock.Parser as H -import qualified Documentation.Haddock.Types as H -#endif getDocumentationTryGhc - :: HscEnv - -> [TypecheckedModule] - -> Name - -> IO [T.Text] -#if MIN_GHC_API_VERSION(8,6,0) -getDocumentationTryGhc packageState tcs name = - runGhcEnv packageState $ getDocumentationTryGhc' tcs name -#else -getDocumentationTryGhc _packageState tcs name = - return $ getDocumentation tcs name -#endif - -getDocumentationTryGhc' :: GhcMonad m => [TypecheckedModule] -> Name - -> m [T.Text] + -> m SpanDoc #if MIN_GHC_API_VERSION(8,6,0) -getDocumentationTryGhc' tcs name = do +getDocumentationTryGhc tcs name = do res <- catchSrcErrors "docs" $ getDocs name case res of - Right (Right (Just docs, _)) -> return [T.pack $ haddockToMarkdown $ H.toRegular $ H._doc $ H.parseParas Nothing $ unpackHDS docs] - _ -> return $ getDocumentation tcs name + Right (Right (Just docs, _)) -> return $ SpanDocString docs + _ -> return $ SpanDocText $ getDocumentation tcs name #else -getDocumentationTryGhc' tcs name = do - return $ getDocumentation tcs name +getDocumentationTryGhc tcs name = do + return $ SpanDocText $ getDocumentation tcs name #endif getDocumentation @@ -128,82 +108,4 @@ docHeaders = mapMaybe (\(L _ x) -> wrk x) AnnLineComment s -> if "-- |" `isPrefixOf` s then Just $ T.pack s else Nothing - _ -> Nothing - -#if MIN_GHC_API_VERSION(8,6,0) --- Simple (and a bit hacky) conversion from Haddock markup to Markdown -haddockToMarkdown - :: H.DocH String String -> String - -haddockToMarkdown H.DocEmpty - = "" -haddockToMarkdown (H.DocAppend d1 d2) - = haddockToMarkdown d1 <> haddockToMarkdown d2 -haddockToMarkdown (H.DocString s) - = s -haddockToMarkdown (H.DocParagraph p) - = "\n\n" ++ haddockToMarkdown p -haddockToMarkdown (H.DocIdentifier i) - = "`" ++ i ++ "`" -haddockToMarkdown (H.DocIdentifierUnchecked i) - = "`" ++ i ++ "`" -haddockToMarkdown (H.DocModule i) - = "`" ++ i ++ "`" -haddockToMarkdown (H.DocWarning w) - = haddockToMarkdown w -haddockToMarkdown (H.DocEmphasis d) - = "*" ++ haddockToMarkdown d ++ "*" -haddockToMarkdown (H.DocBold d) - = "**" ++ haddockToMarkdown d ++ "**" -haddockToMarkdown (H.DocMonospaced d) - = "`" ++ escapeBackticks (haddockToMarkdown d) ++ "`" - where - escapeBackticks "" = "" - escapeBackticks ('`':ss) = '\\':'`':escapeBackticks ss - escapeBackticks (s :ss) = s:escapeBackticks ss -haddockToMarkdown (H.DocCodeBlock d) - = "\n```haskell\n" ++ haddockToMarkdown d ++ "\n```\n" -haddockToMarkdown (H.DocExamples es) - = "\n```haskell\n" ++ unlines (map exampleToMarkdown es) ++ "\n```\n" - where - exampleToMarkdown (H.Example expr result) - = ">>> " ++ expr ++ "\n" ++ unlines result -haddockToMarkdown (H.DocHyperlink (H.Hyperlink url Nothing)) - = "<" ++ url ++ ">" -#if MIN_VERSION_haddock_library(1,8,0) -haddockToMarkdown (H.DocHyperlink (H.Hyperlink url (Just label))) - = "[" ++ haddockToMarkdown label ++ "](" ++ url ++ ")" -#else -haddockToMarkdown (H.DocHyperlink (H.Hyperlink url (Just label))) - = "[" ++ label ++ "](" ++ url ++ ")" -#endif -haddockToMarkdown (H.DocPic (H.Picture url Nothing)) - = "![](" ++ url ++ ")" -haddockToMarkdown (H.DocPic (H.Picture url (Just label))) - = "![" ++ label ++ "](" ++ url ++ ")" -haddockToMarkdown (H.DocAName aname) - = "[" ++ aname ++ "]:" -haddockToMarkdown (H.DocHeader (H.Header level title)) - = replicate level '#' ++ " " ++ haddockToMarkdown title - -haddockToMarkdown (H.DocUnorderedList things) - = '\n' : (unlines $ map (\thing -> "+ " ++ dropWhile isSpace (haddockToMarkdown thing)) things) -haddockToMarkdown (H.DocOrderedList things) - = '\n' : (unlines $ map (\thing -> "1. " ++ dropWhile isSpace (haddockToMarkdown thing)) things) -haddockToMarkdown (H.DocDefList things) - = '\n' : (unlines $ map (\(term, defn) -> "+ **" ++ haddockToMarkdown term ++ "**: " ++ haddockToMarkdown defn) things) - --- we cannot render math by default -haddockToMarkdown (H.DocMathInline _) - = "*cannot render inline math formula*" -haddockToMarkdown (H.DocMathDisplay _) - = "\n\n*cannot render display math formula*\n\n" - --- TODO: render tables -haddockToMarkdown (H.DocTable _t) - = "\n\n*tables are not yet supported*\n\n" - --- things I don't really know how to handle -haddockToMarkdown (H.DocProperty _) - = "" -- don't really know what to do -#endif + _ -> Nothing \ No newline at end of file diff --git a/src/Development/IDE/Spans/Type.hs b/src/Development/IDE/Spans/Type.hs index bbcc0fd35..1823666bc 100644 --- a/src/Development/IDE/Spans/Type.hs +++ b/src/Development/IDE/Spans/Type.hs @@ -14,8 +14,8 @@ module Development.IDE.Spans.Type( import GHC import Control.DeepSeq import OccName -import qualified Data.Text as T import Development.IDE.GHC.Util +import Development.IDE.Spans.Common -- | Type of some span of source code. Most of these fields are -- unboxed but Haddock doesn't show that. @@ -35,13 +35,14 @@ data SpanInfo = -- any. This can be useful for accessing a variety of -- information about the identifier such as module, -- locality, definition location, etc. - ,spaninfoDocs :: ![T.Text] + ,spaninfoDocs :: !SpanDoc -- ^ Documentation for the element } instance Show SpanInfo where - show (SpanInfo sl sc el ec t n _docs) = + show (SpanInfo sl sc el ec t n docs) = unwords ["(SpanInfo", show sl, show sc, show el, show ec - , show $ maybe "NoType" prettyPrint t, "(" <> show n <> "))"] + , show $ maybe "NoType" prettyPrint t, "(" <> show n <> "))" + , "docs(" <> show docs <> ")"] instance NFData SpanInfo where rnf = rwhnf @@ -50,7 +51,7 @@ instance NFData SpanInfo where -- we don't always get a name out so sometimes manually annotating source is more appropriate data SpanSource = Named Name | SpanS SrcSpan - | Lit SrcSpan String + | Lit String | NoSource deriving (Eq) @@ -58,10 +59,10 @@ instance Show SpanSource where show = \case Named n -> "Named " ++ occNameString (occName n) SpanS sp -> "Span " ++ show sp - Lit sp lit -> "Lit " ++ show sp ++ " " ++ lit + Lit lit -> "Lit " ++ lit NoSource -> "NoSource" getNameM :: SpanSource -> Maybe Name getNameM = \case Named name -> Just name - _ -> Nothing + _ -> Nothing \ No newline at end of file From fc7978c61b032b11e2f534810e6237cdd2a2eb7d Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Thu, 16 Jan 2020 15:28:21 +0100 Subject: [PATCH 11/18] No warning for 8.4 --- src/Development/IDE/Spans/Common.hs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Development/IDE/Spans/Common.hs b/src/Development/IDE/Spans/Common.hs index f51da818f..c95449d3d 100644 --- a/src/Development/IDE/Spans/Common.hs +++ b/src/Development/IDE/Spans/Common.hs @@ -1,4 +1,6 @@ {-# LANGUAGE CPP #-} +#include "ghc-api-version.h" + module Development.IDE.Spans.Common ( showGhc , listifyAllSpans @@ -64,9 +66,14 @@ emptySpanDoc = SpanDocText [] spanDocToMarkdown :: SpanDoc -> [T.Text] spanDocToMarkdown (SpanDocString docs) +#if MIN_GHC_API_VERSION(8,6,0) = [T.pack $ haddockToMarkdown $ H.toRegular $ H._doc $ H.parseParas Nothing $ unpackHDS docs] +#else + = [] +#endif spanDocToMarkdown (SpanDocText txt) = txt +#if MIN_GHC_API_VERSION(8,6,0) -- Simple (and a bit hacky) conversion from Haddock markup to Markdown haddockToMarkdown :: H.DocH String String -> String @@ -142,3 +149,4 @@ haddockToMarkdown (H.DocTable _t) -- things I don't really know how to handle haddockToMarkdown (H.DocProperty _) = "" -- don't really know what to do +#endif \ No newline at end of file From e34200c797b28d26588b23bb4f829e8716e08692 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Thu, 16 Jan 2020 15:35:10 +0100 Subject: [PATCH 12/18] More fixes for 8.4 --- src/Development/IDE/Spans/Common.hs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Development/IDE/Spans/Common.hs b/src/Development/IDE/Spans/Common.hs index c95449d3d..3d712f9ec 100644 --- a/src/Development/IDE/Spans/Common.hs +++ b/src/Development/IDE/Spans/Common.hs @@ -23,9 +23,11 @@ import DataCon import Outputable import DynFlags +#if MIN_GHC_API_VERSION(8,6,0) import Data.Char (isSpace) import qualified Documentation.Haddock.Parser as H import qualified Documentation.Haddock.Types as H +#endif showGhc :: Outputable a => a -> String showGhc = showPpr unsafeGlobalDynFlags @@ -65,10 +67,11 @@ emptySpanDoc :: SpanDoc emptySpanDoc = SpanDocText [] spanDocToMarkdown :: SpanDoc -> [T.Text] -spanDocToMarkdown (SpanDocString docs) #if MIN_GHC_API_VERSION(8,6,0) +spanDocToMarkdown (SpanDocString docs) = [T.pack $ haddockToMarkdown $ H.toRegular $ H._doc $ H.parseParas Nothing $ unpackHDS docs] #else +spanDocToMarkdown (SpanDocString _) = [] #endif spanDocToMarkdown (SpanDocText txt) = txt From b9e504f782997d41d09b9a5dae1bab61cbcca804 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Mon, 20 Jan 2020 09:07:52 +0100 Subject: [PATCH 13/18] Make it work with ghc-lib --- src/Development/IDE/Spans/Common.hs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Development/IDE/Spans/Common.hs b/src/Development/IDE/Spans/Common.hs index f0c00d6ad..18244bbc9 100644 --- a/src/Development/IDE/Spans/Common.hs +++ b/src/Development/IDE/Spans/Common.hs @@ -5,8 +5,10 @@ module Development.IDE.Spans.Common ( showGhc , listifyAllSpans , listifyAllSpans' +#ifndef GHC_LIB , safeTyThingId , safeTyThingType +#endif , SpanDoc(..) , emptySpanDoc , spanDocToMarkdown From 0522913b147e7130cd466fd8165e4c4df08596f9 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Mon, 20 Jan 2020 09:32:26 +0100 Subject: [PATCH 14/18] More fixes for warnings when compiled with ghc-lib --- src/Development/IDE/Spans/Common.hs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Development/IDE/Spans/Common.hs b/src/Development/IDE/Spans/Common.hs index 18244bbc9..2d54c60d7 100644 --- a/src/Development/IDE/Spans/Common.hs +++ b/src/Development/IDE/Spans/Common.hs @@ -19,11 +19,13 @@ import qualified Data.Generics import qualified Data.Text as T import GHC +import Outputable +import DynFlags +#ifndef GHC_LIB import ConLike import Var import DataCon -import Outputable -import DynFlags +#endif #if MIN_GHC_API_VERSION(8,6,0) import Data.Char (isSpace) From f9a9929293cf5056542803da2f5e6ea24a2993b0 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Mon, 20 Jan 2020 10:10:45 +0100 Subject: [PATCH 15/18] More fixes to build in ghc-lib --- src/Development/IDE/Core/Completions.hs | 3 --- src/Development/IDE/Spans/Common.hs | 13 ++++++------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/Development/IDE/Core/Completions.hs b/src/Development/IDE/Core/Completions.hs index ea0c38ed6..6d9a384be 100644 --- a/src/Development/IDE/Core/Completions.hs +++ b/src/Development/IDE/Core/Completions.hs @@ -34,10 +34,7 @@ import Development.IDE.Spans.Documentation import Development.IDE.GHC.Error import Development.IDE.Types.Options import Development.IDE.Spans.Common - -#ifndef GHC_LIB import Development.IDE.GHC.Util -#endif -- From haskell-ide-engine/hie-plugin-api/Haskell/Ide/Engine/Context.hs diff --git a/src/Development/IDE/Spans/Common.hs b/src/Development/IDE/Spans/Common.hs index 2d54c60d7..139724d0e 100644 --- a/src/Development/IDE/Spans/Common.hs +++ b/src/Development/IDE/Spans/Common.hs @@ -5,8 +5,8 @@ module Development.IDE.Spans.Common ( showGhc , listifyAllSpans , listifyAllSpans' -#ifndef GHC_LIB , safeTyThingId +#ifndef GHC_LIB , safeTyThingType #endif , SpanDoc(..) @@ -50,12 +50,6 @@ listifyAllSpans' tcs = Data.Generics.listify (const True) tcs #ifndef GHC_LIB -- From haskell-ide-engine/src/Haskell/Ide/Engine/Support/HieExtras.hs - -safeTyThingId :: TyThing -> Maybe Id -safeTyThingId (AnId i) = Just i -safeTyThingId (AConLike (RealDataCon dc)) = Just $ dataConWrapId dc -safeTyThingId _ = Nothing - safeTyThingType :: TyThing -> Maybe Type safeTyThingType thing | Just i <- safeTyThingId thing = Just (varType i) @@ -63,6 +57,11 @@ safeTyThingType (ATyCon tycon) = Just (tyConKind tycon) safeTyThingType _ = Nothing #endif +safeTyThingId :: TyThing -> Maybe Id +safeTyThingId (AnId i) = Just i +safeTyThingId (AConLike (RealDataCon dc)) = Just $ dataConWrapId dc +safeTyThingId _ = Nothing + -- Possible documentation for an element in the code data SpanDoc = SpanDocString HsDocString From 078a089422330f50f3b7ff3f47043dda98ee6992 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Mon, 20 Jan 2020 14:05:49 +0100 Subject: [PATCH 16/18] Try once again to build with ghc-lib --- src/Development/IDE/Spans/Common.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Development/IDE/Spans/Common.hs b/src/Development/IDE/Spans/Common.hs index 139724d0e..2def298d3 100644 --- a/src/Development/IDE/Spans/Common.hs +++ b/src/Development/IDE/Spans/Common.hs @@ -21,8 +21,8 @@ import qualified Data.Text as T import GHC import Outputable import DynFlags -#ifndef GHC_LIB import ConLike +#ifndef GHC_LIB import Var import DataCon #endif From 1a479fdf29d22db814a0949c8326a92cbe8cb72c Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Mon, 20 Jan 2020 14:45:21 +0100 Subject: [PATCH 17/18] More fixes for ghc-lib --- src/Development/IDE/Spans/Calculate.hs | 4 ++++ src/Development/IDE/Spans/Common.hs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Development/IDE/Spans/Calculate.hs b/src/Development/IDE/Spans/Calculate.hs index a89f86427..d4c0e36d9 100644 --- a/src/Development/IDE/Spans/Calculate.hs +++ b/src/Development/IDE/Spans/Calculate.hs @@ -179,9 +179,13 @@ getLHsType getLHsType tms (L spn (HsTyVar U _ v)) = do let n = unLoc v docs <- getDocumentationTryGhc tms n +#ifdef GHC_LIB + let ty = Right Nothing +#else ty <- catchSrcErrors "completion" $ do name' <- lookupName n return $ name' >>= safeTyThingType +#endif let ty' = case ty of Right (Just x) -> Just x _ -> Nothing diff --git a/src/Development/IDE/Spans/Common.hs b/src/Development/IDE/Spans/Common.hs index 2def298d3..7505e9d49 100644 --- a/src/Development/IDE/Spans/Common.hs +++ b/src/Development/IDE/Spans/Common.hs @@ -22,9 +22,9 @@ import GHC import Outputable import DynFlags import ConLike +import DataCon #ifndef GHC_LIB import Var -import DataCon #endif #if MIN_GHC_API_VERSION(8,6,0) From 9b487e9ca24a1faf5ef9df023dec499ada60324c Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Mon, 20 Jan 2020 20:44:42 +0100 Subject: [PATCH 18/18] Fix warning with ghc-lib --- src/Development/IDE/Spans/Calculate.hs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Development/IDE/Spans/Calculate.hs b/src/Development/IDE/Spans/Calculate.hs index d4c0e36d9..ed83923e5 100644 --- a/src/Development/IDE/Spans/Calculate.hs +++ b/src/Development/IDE/Spans/Calculate.hs @@ -24,7 +24,11 @@ import FastString (mkFastString) import OccName import Development.IDE.Types.Location import Development.IDE.Spans.Type +#ifdef GHC_LIB +import Development.IDE.GHC.Error (zeroSpan) +#else import Development.IDE.GHC.Error (zeroSpan, catchSrcErrors) +#endif import Prelude hiding (mod) import TcHsSyn import Var