diff --git a/app/MainHie.hs b/app/MainHie.hs index 3335fa29e..9976bd89d 100644 --- a/app/MainHie.hs +++ b/app/MainHie.hs @@ -5,7 +5,6 @@ module Main where import Control.Monad import Data.Monoid ((<>)) import Data.Version (showVersion) -import qualified GhcMod.Types as GM import Haskell.Ide.Engine.MonadFunctions import Haskell.Ide.Engine.MonadTypes import Haskell.Ide.Engine.Options @@ -121,13 +120,12 @@ run opts = do d <- getCurrentDirectory logm $ "Current directory:" ++ d - let vomitOptions = GM.defaultOptions { GM.optOutput = oo { GM.ooptLogLevel = GM.GmVomit}} - oo = GM.optOutput GM.defaultOptions - let defaultOpts = if optGhcModVomit opts then vomitOptions else GM.defaultOptions + let vomitOptions = defaultOptions { boLogging = BlVomit} + let defaultOpts = if optGhcModVomit opts then vomitOptions else defaultOptions -- Running HIE on projects with -Werror breaks most of the features since all warnings -- will be treated with the same severity of type errors. In order to offer a more useful -- experience, we make sure warnings are always reported as warnings by setting -Wwarn - ghcModOptions = defaultOpts { GM.optGhcUserOptions = ["-Wwarn"] } + biosOptions = defaultOpts { boGhcUserOptions = ["-Wwarn"] } when (optGhcModVomit opts) $ logm "Enabling --vomit for ghc-mod. Output will be on stderr" @@ -139,8 +137,8 @@ run opts = do -- launch the dispatcher. if optJson opts then do - scheduler <- newScheduler plugins' ghcModOptions + scheduler <- newScheduler plugins' biosOptions jsonStdioTransport scheduler else do - scheduler <- newScheduler plugins' ghcModOptions + scheduler <- newScheduler plugins' biosOptions lspStdioTransport scheduler origDir plugins' (optCaptureFile opts) diff --git a/cabal.project b/cabal.project index 0c2906b77..958a340bb 100644 --- a/cabal.project +++ b/cabal.project @@ -8,5 +8,6 @@ packages: ./submodules/floskell ./submodules/ghc-mod/ ./submodules/ghc-mod/core/ + ./submodules/ghc-mod/ghc-project-types tests: true diff --git a/hie-plugin-api/Haskell/Ide/Engine/Ghc.hs b/hie-plugin-api/Haskell/Ide/Engine/Ghc.hs new file mode 100644 index 000000000..569613f41 --- /dev/null +++ b/hie-plugin-api/Haskell/Ide/Engine/Ghc.hs @@ -0,0 +1,238 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TupleSections #-} +{-# LANGUAGE TypeFamilies #-} +-- | This module provides the interface to GHC, mainly for loading +-- modules while updating the module cache. + +module Haskell.Ide.Engine.Ghc + ( + setTypecheckedModule + , Diagnostics + , AdditionalErrs + , cabalModuleGraphs + , makeRevRedirMapFunc + ) where + +import Bag +import Control.Monad.IO.Class +import Data.IORef +import qualified Data.Map.Strict as Map +import qualified Data.Set as Set +import qualified Data.Text as T +import ErrUtils +import qualified GhcMod.DynFlags as GM +import qualified GhcMod.Error as GM +import qualified GhcMod.Gap as GM +import qualified GhcMod.ModuleLoader as GM +import qualified GhcMod.Monad as GM +import Data.Monoid ((<>)) +import qualified GhcMod.Target as GM +import qualified GhcMod.Types as GM +import qualified GhcMod.Utils as GM +import Haskell.Ide.Engine.MonadFunctions +import Haskell.Ide.Engine.MonadTypes +import Haskell.Ide.Engine.PluginUtils +import System.FilePath + +import DynFlags +import GHC +import IOEnv as G +import HscTypes +import Outputable (renderWithStyle) + +-- --------------------------------------------------------------------- + +type Diagnostics = Map.Map Uri (Set.Set Diagnostic) +type AdditionalErrs = [T.Text] + +-- --------------------------------------------------------------------- + +lspSev :: Severity -> DiagnosticSeverity +lspSev SevWarning = DsWarning +lspSev SevError = DsError +lspSev SevFatal = DsError +lspSev SevInfo = DsInfo +lspSev _ = DsInfo + +-- --------------------------------------------------------------------- +-- type LogAction = DynFlags -> WarnReason -> Severity -> SrcSpan -> PprStyle -> MsgDoc -> IO () +logDiag :: (FilePath -> FilePath) -> IORef AdditionalErrs -> IORef Diagnostics -> LogAction +logDiag rfm eref dref df _reason sev spn style msg = do + eloc <- srcSpan2Loc rfm spn + let msgTxt = T.pack $ renderWithStyle df msg style + case eloc of + Right (Location uri range) -> do + let update = Map.insertWith Set.union uri l + where l = Set.singleton diag + diag = Diagnostic range (Just $ lspSev sev) Nothing (Just "ghcmod") msgTxt Nothing + modifyIORef' dref update + Left _ -> do + modifyIORef' eref (msgTxt:) + return () + +-- --------------------------------------------------------------------- + +-- unhelpfulSrcSpanErr :: T.Text -> IdeError +-- unhelpfulSrcSpanErr err = +-- IdeError PluginError +-- ("Unhelpful SrcSpan" <> ": \"" <> err <> "\"") +-- Null + +-- --------------------------------------------------------------------- + +srcErrToDiag :: MonadIO m + => DynFlags + -> (FilePath -> FilePath) + -> SourceError -> m (Diagnostics, AdditionalErrs) +srcErrToDiag df rfm se = do + debugm "in srcErrToDiag" + let errMsgs = bagToList $ srcErrorMessages se + processMsg err = do + let sev = Just DsError + unqual = errMsgContext err + st = GM.mkErrStyle' df unqual + msgTxt = T.pack $ renderWithStyle df (pprLocErrMsg err) st + eloc <- srcSpan2Loc rfm $ errMsgSpan err + case eloc of + Right (Location uri range) -> + return $ Right (uri, Diagnostic range sev Nothing (Just "ghcmod") msgTxt Nothing) + Left _ -> return $ Left msgTxt + processMsgs [] = return (Map.empty,[]) + processMsgs (x:xs) = do + res <- processMsg x + (m,es) <- processMsgs xs + case res of + Right (uri, diag) -> + return (Map.insertWith Set.union uri (Set.singleton diag) m, es) + Left e -> return (m, e:es) + processMsgs errMsgs + +-- --------------------------------------------------------------------- + +myWrapper :: GM.IOish m + => (FilePath -> FilePath) + -> GM.GmlT m () + -> GM.GmlT m (Diagnostics, AdditionalErrs) +myWrapper rfm action = do + env <- getSession + diagRef <- liftIO $ newIORef Map.empty + errRef <- liftIO $ newIORef [] + let setLogger df = df { log_action = logDiag rfm errRef diagRef } + setDeferTypedHoles = setGeneralFlag' Opt_DeferTypedHoles + ghcErrRes msg = (Map.empty, [T.pack msg]) + handlers = errorHandlers ghcErrRes (srcErrToDiag (hsc_dflags env) rfm ) + action' = do + GM.withDynFlags (setLogger . setDeferTypedHoles) action + diags <- liftIO $ readIORef diagRef + errs <- liftIO $ readIORef errRef + return (diags,errs) + GM.gcatches action' handlers + +-- --------------------------------------------------------------------- + +errorHandlers :: (Monad m) => (String -> a) -> (SourceError -> m a) -> [GM.GHandler m a] +errorHandlers ghcErrRes renderSourceError = handlers + where + -- ghc throws GhcException, SourceError, GhcApiError and + -- IOEnvFailure. ghc-mod-core throws GhcModError. + handlers = + [ GM.GHandler $ \(ex :: GM.GhcModError) -> + return $ ghcErrRes (show ex) + , GM.GHandler $ \(ex :: IOEnvFailure) -> + return $ ghcErrRes (show ex) + , GM.GHandler $ \(ex :: GhcApiError) -> + return $ ghcErrRes (show ex) + , GM.GHandler $ \(ex :: SourceError) -> + renderSourceError ex + , GM.GHandler $ \(ex :: GhcException) -> + return $ ghcErrRes $ GM.renderGm $ GM.ghcExceptionDoc ex + , GM.GHandler $ \(ex :: IOError) -> + return $ ghcErrRes (show ex) + -- , GM.GHandler $ \(ex :: GM.SomeException) -> + -- return $ ghcErrRes (show ex) + ] + +-- --------------------------------------------------------------------- + +setTypecheckedModule :: Uri -> IdeGhcM (IdeResult (Diagnostics, AdditionalErrs)) +setTypecheckedModule uri = + pluginGetFile "setTypecheckedModule: " uri $ \fp -> do + fileMap <- GM.getMMappedFiles + debugm $ "setTypecheckedModule: file mapping state is: " ++ show fileMap + rfm <- GM.mkRevRedirMapFunc + let + ghcErrRes msg = ((Map.empty, [T.pack msg]),Nothing,Nothing) + progTitle = "Typechecking " <> T.pack (takeFileName fp) + debugm "setTypecheckedModule: before ghc-mod" + -- TODO:AZ: loading this one module may/should trigger loads of any + -- other modules which currently have a VFS entry. Need to make + -- sure that their diagnostics are reported, and their module + -- cache entries are updated. + -- TODO: Are there any hooks we can use to report back on the progress? + ((diags', errs), mtm, mpm) <- withIndefiniteProgress progTitle NotCancellable $ GM.gcatches + (GM.getModulesGhc' (myWrapper rfm) fp) + (errorHandlers ghcErrRes (return . ghcErrRes . show)) + debugm "setTypecheckedModule: after ghc-mod" + + canonUri <- canonicalizeUri uri + let diags = Map.insertWith Set.union canonUri Set.empty diags' + diags2 <- case (mpm,mtm) of + (Just pm, Nothing) -> do + debugm $ "setTypecheckedModule: Did get parsed module for: " ++ show fp + cacheModule fp (Left pm) + debugm "setTypecheckedModule: done" + return diags + + (_, Just tm) -> do + debugm $ "setTypecheckedModule: Did get typechecked module for: " ++ show fp + sess <- fmap GM.gmgsSession . GM.gmGhcSession <$> GM.gmsGet + + -- set the session before we cache the module, so that deferred + -- responses triggered by cacheModule can access it + modifyMTS (\s -> s {ghcSession = sess}) + cacheModule fp (Right tm) + debugm "setTypecheckedModule: done" + return diags + + _ -> do + debugm $ "setTypecheckedModule: Didn't get typechecked or parsed module for: " ++ show fp + debugm $ "setTypecheckedModule: errs: " ++ show errs + + failModule fp + + let sev = Just DsError + range = Range (Position 0 0) (Position 1 0) + msgTxt = T.unlines errs + let d = Diagnostic range sev Nothing (Just "ghcmod") msgTxt Nothing + return $ Map.insertWith Set.union canonUri (Set.singleton d) diags + + return $ IdeResultOk (diags2,errs) + +-- --------------------------------------------------------------------- + +cabalModuleGraphs :: IdeGhcM [GM.GmModuleGraph] +cabalModuleGraphs = doCabalModuleGraphs + where + doCabalModuleGraphs :: (GM.IOish m) => GM.GhcModT m [GM.GmModuleGraph] + doCabalModuleGraphs = do + crdl <- GM.cradle + case GM.cradleCabalFile crdl of + Just _ -> do + mcs <- GM.cabalResolvedComponents + let graph = map GM.gmcHomeModuleGraph $ Map.elems mcs + return graph + Nothing -> return [] + +-- --------------------------------------------------------------------- + +makeRevRedirMapFunc :: IdeGhcM (FilePath -> FilePath) +makeRevRedirMapFunc = make + where + make :: (GM.IOish m) => GM.GhcModT m (FilePath -> FilePath) + make = GM.mkRevRedirMapFunc + +-- --------------------------------------------------------------------- diff --git a/hie-plugin-api/Haskell/Ide/Engine/ModuleCache.hs b/hie-plugin-api/Haskell/Ide/Engine/ModuleCache.hs index 0fcfa27d9..9c984a247 100644 --- a/hie-plugin-api/Haskell/Ide/Engine/ModuleCache.hs +++ b/hie-plugin-api/Haskell/Ide/Engine/ModuleCache.hs @@ -114,7 +114,8 @@ withCachedInfo fp def callback = deferIfNotCached fp go -- If you need custom data, see also 'ifCachedModuleAndData'. -- If you are in IdeDeferM and would like to wait until a cached module is available, -- see also 'withCachedModule'. -ifCachedModule :: (HasGhcModuleCache m, GM.MonadIO m, CacheableModule b) => FilePath -> a -> (b -> CachedInfo -> m a) -> m a +ifCachedModule :: (HasGhcModuleCache m, MonadIO m, CacheableModule b) + => FilePath -> a -> (b -> CachedInfo -> m a) -> m a ifCachedModule fp def callback = do muc <- getUriCache fp let x = do @@ -177,7 +178,7 @@ withCachedModuleAndData fp def callback = deferIfNotCached fp go go (UriCacheSuccess (UriCache _ _ Nothing _)) = wrap (Defer fp go) go UriCacheFailed = return def -getUriCache :: (HasGhcModuleCache m, GM.MonadIO m) => FilePath -> m (Maybe UriCacheResult) +getUriCache :: (HasGhcModuleCache m, MonadIO m) => FilePath -> m (Maybe UriCacheResult) getUriCache fp = do uri' <- liftIO $ canonicalizePath fp fmap (Map.lookup uri' . uriCaches) getModuleCache @@ -211,7 +212,7 @@ lookupCachedData fp tm info dat = do -- | Saves a module to the cache and executes any deferred -- responses waiting on that module. -cacheModule :: FilePath -> (Either GHC.ParsedModule GHC.TypecheckedModule) -> IdeGhcM () +cacheModule :: FilePath -> Either GHC.ParsedModule GHC.TypecheckedModule -> IdeGhcM () cacheModule uri modul = do uri' <- liftIO $ canonicalizePath uri rfm <- GM.mkRevRedirMapFunc diff --git a/hie-plugin-api/Haskell/Ide/Engine/PluginApi.hs b/hie-plugin-api/Haskell/Ide/Engine/PluginApi.hs new file mode 100644 index 000000000..55bf6b61b --- /dev/null +++ b/hie-plugin-api/Haskell/Ide/Engine/PluginApi.hs @@ -0,0 +1,71 @@ +-- | This module provides an API that software intented to be +-- integrated into HIE can use, so that they can make use of the +-- shared BIOS features. + +{- +-- Stuff used in HaRe currently +Options(..) +defaultOptions +GmModuleGraph(..) +ModulePath(..) +GmComponent(..) +GmComponentType(..) + +CachedInfo(..) +HasGhcModuleCache(..) +IdeGhcM + +cabalModuleGraphs +filePathToUri +makeRevRedirMapFunc + +MonadIO(..) +ifCachedModule +runIdeGhcMBare +setTypecheckedModule +-} + + +module Haskell.Ide.Engine.PluginApi + ( + -- ** Re-exported from ghc-mod via ghc-project-types + GP.GmModuleGraph(..) + , GP.ModulePath(..) + , GP.GmComponent(..) + , GP.GmComponentType(..) + + -- * IDE monads + , HIE.IdeState(..) + , HIE.IdeGhcM + , HIE.runIdeGhcM + , HIE.runIdeGhcMBare + , HIE.IdeM + , HIE.runIdeM + , HIE.IdeDeferM + , HIE.MonadIde + , HIE.iterT + , HIE.LiftsToGhc(..) + , HIE.HasGhcModuleCache(..) + , HIE.cabalModuleGraphs + , HIE.makeRevRedirMapFunc + + -- * Using the HIE module cache etc + , HIE.setTypecheckedModule + , HIE.Diagnostics + , HIE.AdditionalErrs + , LSP.filePathToUri + , HIE.ifCachedModule + , HIE.CachedInfo(..) + + -- * used for tests in HaRe + , HIE.BiosLogLevel(..) + , HIE.BiosOptions(..) + , HIE.defaultOptions + ) where + +import qualified GhcProject.Types as GP +import qualified Haskell.Ide.Engine.Ghc as HIE +import qualified Haskell.Ide.Engine.GhcModuleCache as HIE (CachedInfo(..),HasGhcModuleCache(..)) +import qualified Haskell.Ide.Engine.ModuleCache as HIE (ifCachedModule) +import qualified Haskell.Ide.Engine.PluginsIdeMonads as HIE +import qualified Language.Haskell.LSP.Types as LSP ( filePathToUri ) diff --git a/hie-plugin-api/Haskell/Ide/Engine/PluginUtils.hs b/hie-plugin-api/Haskell/Ide/Engine/PluginUtils.hs index 7bd8e5105..6648294ef 100644 --- a/hie-plugin-api/Haskell/Ide/Engine/PluginUtils.hs +++ b/hie-plugin-api/Haskell/Ide/Engine/PluginUtils.hs @@ -92,6 +92,8 @@ srcSpan2Range :: SrcSpan -> Either T.Text Range srcSpan2Range spn = realSrcSpan2Range <$> getRealSrcSpan spn + + reverseMapFile :: MonadIO m => (FilePath -> FilePath) -> FilePath -> m FilePath reverseMapFile rfm fp = do fp' <- liftIO $ canonicalizePath fp @@ -288,4 +290,4 @@ rangeLinesFromVfs (VirtualFile _ yitext) (Range (Position lf _cf) (Position lt _ where (_ ,s1) = Yi.splitAtLine lf yitext (s2, _) = Yi.splitAtLine (lt - lf) s1 - r = Yi.toText s2 \ No newline at end of file + r = Yi.toText s2 diff --git a/hie-plugin-api/Haskell/Ide/Engine/PluginsIdeMonads.hs b/hie-plugin-api/Haskell/Ide/Engine/PluginsIdeMonads.hs index 673dde609..53e873b5f 100644 --- a/hie-plugin-api/Haskell/Ide/Engine/PluginsIdeMonads.hs +++ b/hie-plugin-api/Haskell/Ide/Engine/PluginsIdeMonads.hs @@ -47,6 +47,7 @@ module Haskell.Ide.Engine.PluginsIdeMonads , IdeState(..) , IdeGhcM , runIdeGhcM + , runIdeGhcMBare , IdeM , runIdeM , IdeDeferM @@ -86,6 +87,11 @@ module Haskell.Ide.Engine.PluginsIdeMonads , PublishDiagnosticsParams(..) , List(..) , FormattingOptions(..) + -- * Options + , BiosLogLevel(..) + , BiosOptions(..) + , defaultOptions + , mkGhcModOptions ) where @@ -96,7 +102,7 @@ import Control.Monad.Reader import Control.Monad.Trans.Free import Control.Monad.Trans.Control -import Data.Aeson +import Data.Aeson hiding (defaultOptions) import qualified Data.ConstrainedDynamic as CD import Data.Default import qualified Data.List as List @@ -115,11 +121,14 @@ import qualified GhcMod.Monad as GM import qualified GhcMod.Types as GM import GHC.Generics import GHC ( HscEnv ) +import qualified DynFlags as GHC +import qualified GHC as GHC +import qualified HscTypes as GHC import Haskell.Ide.Engine.Compat import Haskell.Ide.Engine.Config -import Haskell.Ide.Engine.MultiThreadState import Haskell.Ide.Engine.GhcModuleCache +import Haskell.Ide.Engine.MultiThreadState import qualified Language.Haskell.LSP.Core as Core import Language.Haskell.LSP.Types.Capabilities @@ -335,14 +344,25 @@ getDiagnosticProvidersConfig c = Map.fromList [("applyrefact",hlintOn c) type IdeGhcM = GM.GhcModT IdeM -- | Run an IdeGhcM with Cradle found from the current directory -runIdeGhcM :: GM.Options -> IdePlugins -> Maybe (Core.LspFuncs Config) -> TVar IdeState -> IdeGhcM a -> IO a -runIdeGhcM ghcModOptions plugins mlf stateVar f = do +runIdeGhcM :: BiosOptions -> IdePlugins -> Maybe (Core.LspFuncs Config) -> TVar IdeState -> IdeGhcM a -> IO a +runIdeGhcM biosOptions plugins mlf stateVar f = do env <- IdeEnv <$> pure mlf <*> getProcessID <*> pure plugins + let ghcModOptions = mkGhcModOptions biosOptions (eres, _) <- flip runReaderT stateVar $ flip runReaderT env $ GM.runGhcModT ghcModOptions f case eres of Left err -> liftIO $ throwIO err Right res -> return res +-- | Run an IdeGhcM in an external context (e.g. HaRe), with no plugins or LSP functions +runIdeGhcMBare :: BiosOptions -> IdeGhcM a -> IO a +runIdeGhcMBare biosOptions f = do + let + plugins = IdePlugins Map.empty + mlf = Nothing + initialState = IdeState emptyModuleCache Map.empty Map.empty Nothing + stateVar <- newTVarIO initialState + runIdeGhcM biosOptions plugins mlf stateVar f + -- | A computation that is deferred until the module is cached. -- Note that the module may not typecheck, in which case 'UriCacheFailed' is passed data Defer a = Defer FilePath (UriCacheResult -> a) deriving Functor @@ -482,6 +502,15 @@ instance HasGhcModuleCache IdeM where tvar <- lift ask liftIO $ atomically $ modifyTVar' tvar (\st -> st { moduleCache = mc }) +-- --------------------------------------------------------------------- + +instance GHC.HasDynFlags IdeGhcM where + getDynFlags = GHC.hsc_dflags <$> GHC.getSession + +instance GHC.GhcMonad IdeGhcM where + getSession = GM.unGmlT GM.gmlGetSession + setSession env = GM.unGmlT (GM.gmlSetSession env) + -- --------------------------------------------------------------------- -- Results -- --------------------------------------------------------------------- @@ -553,3 +582,45 @@ data IdeError = IdeError instance ToJSON IdeError instance FromJSON IdeError + +-- --------------------------------------------------------------------- +-- Probably need to move this some time, but hitting import cycle issues + +data BiosLogLevel = + BlError + | BlWarning + | BlInfo + | BlDebug + | BlVomit + deriving (Eq, Ord, Enum, Bounded, Show, Read) + +data BiosOptions = BiosOptions { + boGhcUserOptions :: [String] + , boLogging :: BiosLogLevel + } deriving Show + +defaultOptions :: BiosOptions +defaultOptions = BiosOptions { + boGhcUserOptions = [] + , boLogging = BlWarning + } + +fmBiosLog :: BiosLogLevel -> GM.GmLogLevel +fmBiosLog bl = case bl of + BlError -> GM.GmError + BlWarning -> GM.GmWarning + BlInfo -> GM.GmInfo + BlDebug -> GM.GmDebug + BlVomit -> GM.GmVomit + +-- --------------------------------------------------------------------- + +-- | Apply BiosOptions to default ghc-mod Options +mkGhcModOptions :: BiosOptions -> GM.Options +mkGhcModOptions bo = GM.defaultOptions + { + GM.optGhcUserOptions = boGhcUserOptions bo + , GM.optOutput = (GM.optOutput GM.defaultOptions) { GM.ooptLogLevel = fmBiosLog (boLogging bo) } + } + +-- --------------------------------------------------------------------- diff --git a/hie-plugin-api/hie-plugin-api.cabal b/hie-plugin-api/hie-plugin-api.cabal index c4d81af5c..99e670ef2 100644 --- a/hie-plugin-api/hie-plugin-api.cabal +++ b/hie-plugin-api/hie-plugin-api.cabal @@ -22,13 +22,15 @@ library Haskell.Ide.Engine.Compat Haskell.Ide.Engine.Config Haskell.Ide.Engine.Context + Haskell.Ide.Engine.Ghc Haskell.Ide.Engine.GhcModuleCache Haskell.Ide.Engine.ModuleCache Haskell.Ide.Engine.MonadFunctions Haskell.Ide.Engine.MonadTypes Haskell.Ide.Engine.MultiThreadState - Haskell.Ide.Engine.PluginsIdeMonads + Haskell.Ide.Engine.PluginApi Haskell.Ide.Engine.PluginUtils + Haskell.Ide.Engine.PluginsIdeMonads Haskell.Ide.Engine.TypeMap build-depends: base >= 4.9 && < 5 , Diff @@ -42,6 +44,7 @@ library , free , ghc , ghc-mod-core >= 5.9.0.0 + , ghc-project-types >= 5.9.0.0 , haskell-lsp == 0.11.* , hslogger , monad-control diff --git a/src/Haskell/Ide/Engine/Plugin/GhcMod.hs b/src/Haskell/Ide/Engine/Plugin/GhcMod.hs index 5665bc24b..8eb1efff1 100644 --- a/src/Haskell/Ide/Engine/Plugin/GhcMod.hs +++ b/src/Haskell/Ide/Engine/Plugin/GhcMod.hs @@ -5,36 +5,44 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} -module Haskell.Ide.Engine.Plugin.GhcMod where +module Haskell.Ide.Engine.Plugin.GhcMod + ( + ghcmodDescriptor + + -- * For tests + , Bindings(..) + , FunctionSig(..) + , InfoParams(..) + , TypeDef(..) + , TypeParams(..) + , TypedHoles(..) -- only to keep the GHC 8.4 and below unused field warning happy + , ValidSubstitutions(..) + , extractHoleSubstitutions + , extractMissingSignature + , extractRenamableTerms + , extractUnusedTerm + , infoCmd' + , lintCmd' + , newTypeCmd + , symbolProvider + ) where -import Bag -import Control.Monad.IO.Class import Control.Lens hiding (cons, children) import Data.Aeson import Data.Function import qualified Data.HashMap.Strict as HM -import Data.IORef import Data.List -import qualified Data.Map.Strict as Map import Data.Maybe import Data.Monoid ((<>)) -import qualified Data.Set as Set import qualified Data.Text as T -import System.FilePath -import ErrUtils import Name import GHC.Generics import qualified GhcMod as GM -import qualified GhcMod.DynFlags as GM -import qualified GhcMod.Error as GM import qualified GhcMod.Gap as GM -import qualified GhcMod.ModuleLoader as GM -import qualified GhcMod.Monad as GM import qualified GhcMod.SrcUtils as GM import qualified GhcMod.Types as GM -import qualified GhcMod.Utils as GM -import Haskell.Ide.Engine.MonadFunctions -import Haskell.Ide.Engine.MonadTypes +import Haskell.Ide.Engine.Ghc +import Haskell.Ide.Engine.MonadTypes hiding (defaultOptions) import Haskell.Ide.Engine.PluginUtils import qualified Haskell.Ide.Engine.Support.HieExtras as Hie import Haskell.Ide.Engine.ArtifactMap @@ -42,13 +50,11 @@ import qualified Language.Haskell.LSP.Types as LSP import qualified Language.Haskell.LSP.Types.Lens as LSP import Language.Haskell.Refact.API (hsNamessRdr) -import DynFlags import GHC -import IOEnv as G import HscTypes import DataCon import TcRnTypes -import Outputable (renderWithStyle, mkUserStyle, Depth(..)) +import Outputable (mkUserStyle, Depth(..)) -- --------------------------------------------------------------------- @@ -75,162 +81,11 @@ ghcmodDescriptor plId = PluginDescriptor -- --------------------------------------------------------------------- -type Diagnostics = Map.Map Uri (Set.Set Diagnostic) -type AdditionalErrs = [T.Text] - checkCmd :: CommandFunc Uri (Diagnostics, AdditionalErrs) checkCmd = CmdSync setTypecheckedModule -- --------------------------------------------------------------------- -lspSev :: Severity -> DiagnosticSeverity -lspSev SevWarning = DsWarning -lspSev SevError = DsError -lspSev SevFatal = DsError -lspSev SevInfo = DsInfo -lspSev _ = DsInfo - --- type LogAction = DynFlags -> WarnReason -> Severity -> SrcSpan -> PprStyle -> MsgDoc -> IO () -logDiag :: (FilePath -> FilePath) -> IORef AdditionalErrs -> IORef Diagnostics -> LogAction -logDiag rfm eref dref df _reason sev spn style msg = do - eloc <- srcSpan2Loc rfm spn - let msgTxt = T.pack $ renderWithStyle df msg style - case eloc of - Right (Location uri range) -> do - let update = Map.insertWith Set.union uri l - where l = Set.singleton diag - diag = Diagnostic range (Just $ lspSev sev) Nothing (Just "ghcmod") msgTxt Nothing - modifyIORef' dref update - Left _ -> do - modifyIORef' eref (msgTxt:) - return () - -unhelpfulSrcSpanErr :: T.Text -> IdeError -unhelpfulSrcSpanErr err = - IdeError PluginError - ("Unhelpful SrcSpan" <> ": \"" <> err <> "\"") - Null - -srcErrToDiag :: MonadIO m - => DynFlags - -> (FilePath -> FilePath) - -> SourceError -> m (Diagnostics, AdditionalErrs) -srcErrToDiag df rfm se = do - debugm "in srcErrToDiag" - let errMsgs = bagToList $ srcErrorMessages se - processMsg err = do - let sev = Just DsError - unqual = errMsgContext err - st = GM.mkErrStyle' df unqual - msgTxt = T.pack $ renderWithStyle df (pprLocErrMsg err) st - eloc <- srcSpan2Loc rfm $ errMsgSpan err - case eloc of - Right (Location uri range) -> - return $ Right (uri, Diagnostic range sev Nothing (Just "ghcmod") msgTxt Nothing) - Left _ -> return $ Left msgTxt - processMsgs [] = return (Map.empty,[]) - processMsgs (x:xs) = do - res <- processMsg x - (m,es) <- processMsgs xs - case res of - Right (uri, diag) -> - return (Map.insertWith Set.union uri (Set.singleton diag) m, es) - Left e -> return (m, e:es) - processMsgs errMsgs - -myWrapper :: GM.IOish m - => (FilePath -> FilePath) - -> GM.GmlT m () - -> GM.GmlT m (Diagnostics, AdditionalErrs) -myWrapper rfm action = do - env <- getSession - diagRef <- liftIO $ newIORef Map.empty - errRef <- liftIO $ newIORef [] - let setLogger df = df { log_action = logDiag rfm errRef diagRef } - setDeferTypedHoles = setGeneralFlag' Opt_DeferTypedHoles - ghcErrRes msg = (Map.empty, [T.pack msg]) - handlers = errorHandlers ghcErrRes (srcErrToDiag (hsc_dflags env) rfm ) - action' = do - GM.withDynFlags (setLogger . setDeferTypedHoles) action - diags <- liftIO $ readIORef diagRef - errs <- liftIO $ readIORef errRef - return (diags,errs) - GM.gcatches action' handlers - -errorHandlers :: (Monad m) => (String -> a) -> (SourceError -> m a) -> [GM.GHandler m a] -errorHandlers ghcErrRes renderSourceError = handlers - where - -- ghc throws GhcException, SourceError, GhcApiError and - -- IOEnvFailure. ghc-mod-core throws GhcModError. - handlers = - [ GM.GHandler $ \(ex :: GM.GhcModError) -> - return $ ghcErrRes (show ex) - , GM.GHandler $ \(ex :: IOEnvFailure) -> - return $ ghcErrRes (show ex) - , GM.GHandler $ \(ex :: GhcApiError) -> - return $ ghcErrRes (show ex) - , GM.GHandler $ \(ex :: SourceError) -> - renderSourceError ex - , GM.GHandler $ \(ex :: GhcException) -> - return $ ghcErrRes $ GM.renderGm $ GM.ghcExceptionDoc ex - , GM.GHandler $ \(ex :: IOError) -> - return $ ghcErrRes (show ex) - -- , GM.GHandler $ \(ex :: GM.SomeException) -> - -- return $ ghcErrRes (show ex) - ] - -setTypecheckedModule :: Uri -> IdeGhcM (IdeResult (Diagnostics, AdditionalErrs)) -setTypecheckedModule uri = - pluginGetFile "setTypecheckedModule: " uri $ \fp -> do - fileMap <- GM.getMMappedFiles - debugm $ "setTypecheckedModule: file mapping state is: " ++ show fileMap - rfm <- GM.mkRevRedirMapFunc - let - ghcErrRes msg = ((Map.empty, [T.pack msg]),Nothing,Nothing) - progTitle = "Typechecking " <> T.pack (takeFileName fp) - debugm "setTypecheckedModule: before ghc-mod" - -- TODO: Are there any hooks we can use to report back on the progress? - ((diags', errs), mtm, mpm) <- withIndefiniteProgress progTitle NotCancellable $ GM.gcatches - (GM.getModulesGhc' (myWrapper rfm) fp) - (errorHandlers ghcErrRes (return . ghcErrRes . show)) - debugm "setTypecheckedModule: after ghc-mod" - - canonUri <- canonicalizeUri uri - let diags = Map.insertWith Set.union canonUri Set.empty diags' - diags2 <- case (mpm,mtm) of - (Just pm, Nothing) -> do - debugm $ "setTypecheckedModule: Did get parsed module for: " ++ show fp - cacheModule fp (Left pm) - debugm "setTypecheckedModule: done" - return diags - - (_, Just tm) -> do - debugm $ "setTypecheckedModule: Did get typechecked module for: " ++ show fp - sess <- fmap GM.gmgsSession . GM.gmGhcSession <$> GM.gmsGet - - -- set the session before we cache the module, so that deferred - -- responses triggered by cacheModule can access it - modifyMTS (\s -> s {ghcSession = sess}) - cacheModule fp (Right tm) - debugm "setTypecheckedModule: done" - return diags - - _ -> do - debugm $ "setTypecheckedModule: Didn't get typechecked or parsed module for: " ++ show fp - debugm $ "setTypecheckedModule: errs: " ++ show errs - - failModule fp - - let sev = Just DsError - range = Range (Position 0 0) (Position 1 0) - msgTxt = T.unlines errs - let d = Diagnostic range sev Nothing (Just "ghcmod") msgTxt Nothing - return $ Map.insertWith Set.union canonUri (Set.singleton d) diags - - return $ IdeResultOk (diags2,errs) - --- --------------------------------------------------------------------- - lintCmd :: CommandFunc Uri T.Text lintCmd = CmdSync lintCmd' diff --git a/src/Haskell/Ide/Engine/Plugin/HaRe.hs b/src/Haskell/Ide/Engine/Plugin/HaRe.hs index 55202ea52..0c9988382 100644 --- a/src/Haskell/Ide/Engine/Plugin/HaRe.hs +++ b/src/Haskell/Ide/Engine/Plugin/HaRe.hs @@ -22,7 +22,6 @@ import qualified Data.Text.IO as T import Exception import GHC.Generics (Generic) import qualified GhcMod.Error as GM -import qualified GhcMod.Monad as GM import qualified GhcMod.Utils as GM import Haskell.Ide.Engine.ArtifactMap import Haskell.Ide.Engine.MonadFunctions @@ -241,7 +240,11 @@ runHareCommand name cmd = do -- --------------------------------------------------------------------- -runHareCommand' :: RefactGhc a +-- newtype RefactGhc a = RefactGhc +-- { unRefactGhc :: StateT RefactState HIE.IdeGhcM a +-- } + +runHareCommand' :: forall a. RefactGhc a -> IdeGhcM (Either String a) runHareCommand' cmd = do let initialState = @@ -254,11 +257,11 @@ runHareCommand' cmd = ,rsStorage = StorageNone ,rsCurrentTarget = Nothing ,rsModule = Nothing} - let cmd' = unRefactGhc cmd + let + cmd' :: StateT RefactState IdeGhcM a + cmd' = unRefactGhc cmd embeddedCmd = - GM.unGmlT $ - hoist (liftIO . flip evalStateT initialState) - (GM.GmlT cmd') + evalStateT cmd' initialState handlers :: Applicative m => [GM.GHandler m (Either String a)] @@ -267,6 +270,7 @@ runHareCommand' cmd = ,GM.GHandler (\(err :: GM.GhcModError) -> pure (Left (show err)))] fmap Right embeddedCmd `GM.gcatches` handlers + -- --------------------------------------------------------------------- -- | This is like hoist from the mmorph package, but build on -- `MonadTransControl` since we don’t have an `MFunctor` instance. diff --git a/src/Haskell/Ide/Engine/Scheduler.hs b/src/Haskell/Ide/Engine/Scheduler.hs index b30b9dad4..d3de638ea 100644 --- a/src/Haskell/Ide/Engine/Scheduler.hs +++ b/src/Haskell/Ide/Engine/Scheduler.hs @@ -60,8 +60,8 @@ data Scheduler m = Scheduler { plugins :: IdePlugins -- ^ The list of plugins that will be used for responding to requests - , ghcModOptions :: GM.Options - -- ^ Options for the ghc-mod session. Since we only keep a single ghc-mod session + , biosOptions :: BiosOptions + -- ^ Options for the bios session. Since we only keep a single bios session -- at a time, this cannot be changed a runtime. , requestsToCancel :: STM.TVar (Set.Set J.LspId) @@ -99,10 +99,10 @@ class HasScheduler a m where newScheduler :: IdePlugins -- ^ The list of plugins that will be used for responding to requests - -> GM.Options - -- ^ Options for the ghc-mod session. Since we only keep a single ghc-mod session + -> BiosOptions + -- ^ Options for the bios session. Since we only keep a single bios session -> IO (Scheduler m) -newScheduler plugins ghcModOptions = do +newScheduler plugins biosOpts = do cancelTVar <- STM.atomically $ STM.newTVar Set.empty wipTVar <- STM.atomically $ STM.newTVar Set.empty versionTVar <- STM.atomically $ STM.newTVar Map.empty @@ -110,7 +110,7 @@ newScheduler plugins ghcModOptions = do ghcChan <- Channel.newChan return $ Scheduler { plugins = plugins - , ghcModOptions = ghcModOptions + , biosOptions = biosOpts , requestsToCancel = cancelTVar , requestsInProgress = wipTVar , documentVersions = versionTVar @@ -152,7 +152,7 @@ runScheduler Scheduler {..} errorHandler callbackHandler mlf = do stateVar <- STM.newTVarIO initialState - let runGhcDisp = runIdeGhcM ghcModOptions plugins mlf stateVar $ + let runGhcDisp = runIdeGhcM biosOptions plugins mlf stateVar $ ghcDispatcher dEnv errorHandler callbackHandler ghcChanOut runIdeDisp = runIdeM plugins mlf stateVar $ ideDispatcher dEnv errorHandler callbackHandler ideChanOut diff --git a/src/Haskell/Ide/Engine/Support/HieExtras.hs b/src/Haskell/Ide/Engine/Support/HieExtras.hs index f890ba905..68f689749 100644 --- a/src/Haskell/Ide/Engine/Support/HieExtras.hs +++ b/src/Haskell/Ide/Engine/Support/HieExtras.hs @@ -482,7 +482,7 @@ getSymbolsAtPoint :: Position -> CachedInfo -> [(Range,Name)] getSymbolsAtPoint pos info = maybe [] (`getArtifactsAtPos` locMap info) $ newPosToOld info pos -- |Get a symbol from the given location map at the given location. --- Retrieves the name and range of the symbol at the given location +-- Retrieves the name and range of the symbol at the given location -- from the cached location map. symbolFromTypecheckedModule :: LocMap @@ -563,8 +563,8 @@ findTypeDef uri pos = pluginGetFile "findTypeDef: " uri $ \file -> -- | Get SrcSpan of the name at the given position. -- If the old position is Nothing, e.g. there is no cached info about it, -- Nothing is returned. - -- - -- Otherwise, searches for the Type of the given position + -- + -- Otherwise, searches for the Type of the given position -- and retrieves its SrcSpan. getTypeSrcSpanFromPosition :: Maybe Position -> ExceptT () IdeDeferM SrcSpan @@ -647,7 +647,7 @@ gotoModule rfm mn = do case fr of Found (ModLocation (Just src) _ _) _ -> do fp <- reverseMapFile rfm src - + let r = Range (Position 0 0) (Position 0 0) loc = Location (filePathToUri fp) r return (IdeResultOk [loc]) @@ -805,7 +805,7 @@ prefixes = -- --------------------------------------------------------------------- getFormattingPlugin :: Config -> IdePlugins -> Maybe (PluginDescriptor, FormattingProvider) -getFormattingPlugin config plugins = do +getFormattingPlugin config plugins = do let providerName = formattingProvider config fmtPlugin <- Map.lookup providerName (ipMap plugins) fmtProvider <- pluginFormattingProvider fmtPlugin diff --git a/src/Haskell/Ide/Engine/Transport/LspStdio.hs b/src/Haskell/Ide/Engine/Transport/LspStdio.hs index a0b167afc..93e22e7b3 100644 --- a/src/Haskell/Ide/Engine/Transport/LspStdio.hs +++ b/src/Haskell/Ide/Engine/Transport/LspStdio.hs @@ -42,13 +42,13 @@ import Data.Text.Encoding import qualified GhcMod.Monad.Types as GM import qualified GhcModCore as GM import Haskell.Ide.Engine.Config +import qualified Haskell.Ide.Engine.Ghc as HIE import Haskell.Ide.Engine.LSP.CodeActions import Haskell.Ide.Engine.LSP.Reactor import Haskell.Ide.Engine.MonadFunctions import Haskell.Ide.Engine.MonadTypes import qualified Haskell.Ide.Engine.Plugin.ApplyRefact as ApplyRefact import Haskell.Ide.Engine.Plugin.Base -import qualified Haskell.Ide.Engine.Plugin.GhcMod as GhcMod import qualified Haskell.Ide.Engine.Plugin.HaRe as HaRe import qualified Haskell.Ide.Engine.Plugin.Hoogle as Hoogle import Haskell.Ide.Engine.PluginUtils @@ -955,7 +955,7 @@ requestDiagnosticsNormal tn file mVer = do -- get GHC diagnostics and loads the typechecked module into the cache let reqg = GReq tn (Just file) (Just (file,ver)) Nothing callbackg - $ GhcMod.setTypecheckedModule file + $ HIE.setTypecheckedModule file callbackg (pd, errs) = do forM_ errs $ \e -> do reactorSend $ NotShowMessage $ diff --git a/stack-8.2.1.yaml b/stack-8.2.1.yaml index da9efb9b1..8d3486c0b 100644 --- a/stack-8.2.1.yaml +++ b/stack-8.2.1.yaml @@ -10,6 +10,7 @@ extra-deps: - ./submodules/floskell - ./submodules/ghc-mod - ./submodules/ghc-mod/core +- ./submodules/ghc-mod/ghc-project-types # - brittany-0.11.0.0 - butcher-1.3.1.1 diff --git a/stack-8.2.2.yaml b/stack-8.2.2.yaml index e4816a72b..ee4c992b0 100644 --- a/stack-8.2.2.yaml +++ b/stack-8.2.2.yaml @@ -10,6 +10,7 @@ extra-deps: - ./submodules/floskell - ./submodules/ghc-mod - ./submodules/ghc-mod/core +- ./submodules/ghc-mod/ghc-project-types # - brittany-0.11.0.0 - butcher-1.3.1.1 diff --git a/stack-8.4.2.yaml b/stack-8.4.2.yaml index b6f221167..d41413e32 100644 --- a/stack-8.4.2.yaml +++ b/stack-8.4.2.yaml @@ -10,6 +10,7 @@ extra-deps: - ./submodules/floskell - ./submodules/ghc-mod - ./submodules/ghc-mod/core +- ./submodules/ghc-mod/ghc-project-types # - brittany-0.11.0.0 - base-compat-0.9.3 diff --git a/stack-8.4.3.yaml b/stack-8.4.3.yaml index c7a13b24a..bf273d163 100644 --- a/stack-8.4.3.yaml +++ b/stack-8.4.3.yaml @@ -10,6 +10,7 @@ extra-deps: - ./submodules/floskell - ./submodules/ghc-mod - ./submodules/ghc-mod/core +- ./submodules/ghc-mod/ghc-project-types - base-compat-0.9.3 - cabal-plan-0.3.0.0 diff --git a/stack-8.4.4.yaml b/stack-8.4.4.yaml index 0f49dc09a..8d61f560d 100644 --- a/stack-8.4.4.yaml +++ b/stack-8.4.4.yaml @@ -10,6 +10,7 @@ extra-deps: - ./submodules/floskell - ./submodules/ghc-mod - ./submodules/ghc-mod/core +- ./submodules/ghc-mod/ghc-project-types # - brittany-0.11.0.0 - cabal-plan-0.4.0.0 diff --git a/stack-8.6.1.yaml b/stack-8.6.1.yaml index 7c2fab2d3..2f10c127d 100644 --- a/stack-8.6.1.yaml +++ b/stack-8.6.1.yaml @@ -10,6 +10,7 @@ extra-deps: - ./submodules/floskell - ./submodules/ghc-mod - ./submodules/ghc-mod/core +- ./submodules/ghc-mod/ghc-project-types - apply-refact-0.6.0.0 - butcher-1.3.2.1 diff --git a/stack-8.6.2.yaml b/stack-8.6.2.yaml index c5f3f20a2..974acfc24 100644 --- a/stack-8.6.2.yaml +++ b/stack-8.6.2.yaml @@ -10,6 +10,7 @@ extra-deps: - ./submodules/floskell - ./submodules/ghc-mod - ./submodules/ghc-mod/core +- ./submodules/ghc-mod/ghc-project-types - butcher-1.3.2.1 - cabal-plan-0.4.0.0 diff --git a/stack-8.6.3.yaml b/stack-8.6.3.yaml index 78e7ca848..a47419c8c 100644 --- a/stack-8.6.3.yaml +++ b/stack-8.6.3.yaml @@ -10,6 +10,7 @@ extra-deps: - ./submodules/floskell - ./submodules/ghc-mod - ./submodules/ghc-mod/core +- ./submodules/ghc-mod/ghc-project-types - butcher-1.3.2.1 - cabal-plan-0.4.0.0 diff --git a/stack-8.6.4.yaml b/stack-8.6.4.yaml index b5a43add9..6e8c74ec1 100644 --- a/stack-8.6.4.yaml +++ b/stack-8.6.4.yaml @@ -10,6 +10,7 @@ extra-deps: - ./submodules/floskell - ./submodules/ghc-mod - ./submodules/ghc-mod/core +- ./submodules/ghc-mod/ghc-project-types - butcher-1.3.2.1 - cabal-plan-0.4.0.0 diff --git a/stack-8.6.5.yaml b/stack-8.6.5.yaml index 25601fa42..e06acd30e 100644 --- a/stack-8.6.5.yaml +++ b/stack-8.6.5.yaml @@ -10,6 +10,7 @@ extra-deps: - ./submodules/floskell - ./submodules/ghc-mod - ./submodules/ghc-mod/core +- ./submodules/ghc-mod/ghc-project-types - ansi-terminal-0.8.2 - butcher-1.3.2.1 diff --git a/stack.yaml b/stack.yaml index 25601fa42..e06acd30e 100644 --- a/stack.yaml +++ b/stack.yaml @@ -10,6 +10,7 @@ extra-deps: - ./submodules/floskell - ./submodules/ghc-mod - ./submodules/ghc-mod/core +- ./submodules/ghc-mod/ghc-project-types - ansi-terminal-0.8.2 - butcher-1.3.2.1 diff --git a/submodules/HaRe b/submodules/HaRe index 53979f062..dfab00043 160000 --- a/submodules/HaRe +++ b/submodules/HaRe @@ -1 +1 @@ -Subproject commit 53979f062bebcaa132390d1fd0cec74a51662952 +Subproject commit dfab0004320c28e1aa0331a507a9428952f2c938 diff --git a/submodules/ghc-mod b/submodules/ghc-mod index b20536757..17403cede 160000 --- a/submodules/ghc-mod +++ b/submodules/ghc-mod @@ -1 +1 @@ -Subproject commit b20536757f34769c6fe4478f13b71a55c9ae582e +Subproject commit 17403cedeaa85e5d78d548afc95e1467cc3f5720 diff --git a/test/unit/GhcModPluginSpec.hs b/test/unit/GhcModPluginSpec.hs index cca539ff3..22877d0a4 100644 --- a/test/unit/GhcModPluginSpec.hs +++ b/test/unit/GhcModPluginSpec.hs @@ -10,6 +10,7 @@ import Data.Monoid #endif import qualified Data.Set as S import qualified Data.Text as T +import Haskell.Ide.Engine.Ghc import Haskell.Ide.Engine.MonadTypes import Haskell.Ide.Engine.Plugin.GhcMod import Haskell.Ide.Engine.PluginUtils diff --git a/test/unit/HaRePluginSpec.hs b/test/unit/HaRePluginSpec.hs index 6a4824355..ec797ce70 100644 --- a/test/unit/HaRePluginSpec.hs +++ b/test/unit/HaRePluginSpec.hs @@ -10,9 +10,9 @@ import Control.Monad.IO.Class import Data.Aeson import qualified Data.Map as M import qualified Data.HashMap.Strict as H +import Haskell.Ide.Engine.Ghc import Haskell.Ide.Engine.MonadTypes import Haskell.Ide.Engine.PluginUtils -import Haskell.Ide.Engine.Plugin.GhcMod import Haskell.Ide.Engine.Plugin.HaRe import Haskell.Ide.Engine.Support.HieExtras import Language.Haskell.LSP.Types ( Location(..) diff --git a/test/utils/TestUtils.hs b/test/utils/TestUtils.hs index 56a70c468..526608352 100644 --- a/test/utils/TestUtils.hs +++ b/test/utils/TestUtils.hs @@ -25,8 +25,8 @@ import Data.Typeable import Data.Yaml import qualified Data.Map as Map import Data.Maybe -import qualified GhcMod.Monad as GM -import qualified GhcMod.Types as GM +-- import qualified GhcMod.Monad as GM +-- import qualified GhcMod.Types as GM import qualified Language.Haskell.LSP.Core as Core import Haskell.Ide.Engine.MonadTypes import System.Directory @@ -41,16 +41,12 @@ import Text.Blaze.Internal -- --------------------------------------------------------------------- -testOptions :: GM.Options -testOptions = GM.defaultOptions { - GM.optOutput = GM.OutputOpts { - GM.ooptLogLevel = GM.GmError - -- GM.ooptLogLevel = GM.GmVomit - , GM.ooptStyle = GM.PlainStyle - , GM.ooptLineSeparator = GM.LineSeparator "\0" - , GM.ooptLinePrefix = Nothing - } - +testOptions :: BiosOptions +testOptions = defaultOptions { + boLogging = BlError + -- boLoggingg = BlDebug + -- boLoggingg = BlVomit + -- , boGhcUserOptions = ["-v4", "-DDEBUG"] }