mirror of
https://github.com/haskell/ghcide.git
synced 2024-12-17 15:11:41 +03:00
Clean up the IDE (#961)
* Split the Options into a separate module * Make the Logger handle live in IO * Reduce the amount of IDE logging to just two * Rename CompileOpts to IdeOptions * Rename PackageState to PackageDynFlags * Clean up setting the PackageDynFlags * Stop hiding PackageState, we no longer clash on it * Introduce a helper for collecting the package flags * Move the StringBuffer conversion to its only use
This commit is contained in:
parent
c0e9c90429
commit
1c27ffe760
@ -8,9 +8,7 @@
|
||||
-- | Based on https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/API.
|
||||
-- Given a list of paths to find libraries, and a file to compile, produce a list of 'CoreModule' values.
|
||||
module Development.IDE.Functions.Compile
|
||||
( CompileOpts(..)
|
||||
, PackageState(..)
|
||||
, GhcModule(..)
|
||||
( GhcModule(..)
|
||||
, TcModuleResult(..)
|
||||
, LoadPackageResult(..)
|
||||
, getGhcDynFlags
|
||||
@ -29,6 +27,7 @@ import qualified Development.IDE.Functions.FindImports as FindImports
|
||||
import Development.IDE.Functions.GHCError
|
||||
import Development.IDE.Functions.SpanInfo
|
||||
import Development.IDE.UtilGHC
|
||||
import Development.IDE.Types.Options
|
||||
|
||||
import GHC hiding (parseModule, typecheckModule)
|
||||
import qualified Parser
|
||||
@ -38,7 +37,7 @@ import Bag
|
||||
import qualified GHC
|
||||
import Panic
|
||||
import GhcMonad
|
||||
import GhcPlugins as GHC hiding (PackageState, fst3, (<>))
|
||||
import GhcPlugins as GHC hiding (fst3, (<>))
|
||||
import qualified HeaderInfo as Hdr
|
||||
import MkIface
|
||||
import NameCache
|
||||
@ -61,24 +60,6 @@ import Development.IDE.Types.SpanInfo
|
||||
import GHC.Generics (Generic)
|
||||
import System.FilePath
|
||||
|
||||
-- TODO (MK) Move to a separate Options module
|
||||
data CompileOpts = CompileOpts
|
||||
{ optPreprocessor :: GHC.ParsedSource -> ([(GHC.SrcSpan, String)], GHC.ParsedSource)
|
||||
, optRunGhcSession :: forall a. Maybe ParsedModule -> PackageState -> Ghc a -> IO a
|
||||
-- ^ Setup a GHC session using a given package state. If a `ParsedModule` is supplied,
|
||||
-- the import path should be setup for that module.
|
||||
, optWriteIface :: Bool
|
||||
|
||||
, optMbPackageName :: Maybe String
|
||||
|
||||
, optPackageDbs :: [FilePath]
|
||||
, optHideAllPkgs :: Bool
|
||||
, optPackageImports :: [(String, ModRenaming)]
|
||||
|
||||
, optThreads :: Int
|
||||
, optShakeProfiling :: Maybe FilePath
|
||||
}
|
||||
|
||||
-- | 'CoreModule' together with some additional information required for the
|
||||
-- conversion to DAML-LF.
|
||||
data GhcModule = GhcModule
|
||||
@ -106,9 +87,9 @@ data LoadPackageResult = LoadPackageResult
|
||||
|
||||
-- | Get source span info, used for e.g. AtPoint and Goto Definition.
|
||||
getSrcSpanInfos
|
||||
:: CompileOpts
|
||||
:: IdeOptions
|
||||
-> ParsedModule
|
||||
-> PackageState
|
||||
-> PackageDynFlags
|
||||
-> [(Located ModuleName, Maybe FilePath)]
|
||||
-> TcModuleResult
|
||||
-> IO [SpanInfo]
|
||||
@ -120,18 +101,18 @@ getSrcSpanInfos opt mod packageState imports tc =
|
||||
|
||||
-- | Given a string buffer, return a pre-processed @ParsedModule@.
|
||||
parseModule
|
||||
:: CompileOpts
|
||||
-> PackageState
|
||||
:: IdeOptions
|
||||
-> PackageDynFlags
|
||||
-> FilePath
|
||||
-> (UTCTime, SB.StringBuffer)
|
||||
-> IO ([FileDiagnostic], Maybe ParsedModule)
|
||||
parseModule opt@CompileOpts{..} packageState file =
|
||||
parseModule opt@IdeOptions{..} packageState file =
|
||||
fmap (either (, Nothing) (second Just)) . Ex.runExceptT .
|
||||
-- We need packages since imports fail to resolve otherwise.
|
||||
runGhcSessionExcept opt Nothing packageState . parseFileContents optPreprocessor file
|
||||
|
||||
computePackageDeps ::
|
||||
CompileOpts -> PackageState -> InstalledUnitId -> IO (Either [FileDiagnostic] [InstalledUnitId])
|
||||
IdeOptions -> PackageDynFlags -> InstalledUnitId -> IO (Either [FileDiagnostic] [InstalledUnitId])
|
||||
computePackageDeps opts packageState iuid =
|
||||
Ex.runExceptT $
|
||||
runGhcSessionExcept opts Nothing packageState $
|
||||
@ -149,9 +130,9 @@ getPackage dflags p =
|
||||
|
||||
-- | Typecheck a single module using the supplied dependencies and packages.
|
||||
typecheckModule
|
||||
:: CompileOpts
|
||||
:: IdeOptions
|
||||
-> ParsedModule
|
||||
-> PackageState
|
||||
-> PackageDynFlags
|
||||
-> UniqSupply
|
||||
-> [TcModuleResult]
|
||||
-> [LoadPackageResult]
|
||||
@ -169,8 +150,8 @@ typecheckModule opt mod packageState uniqSupply deps pkgs pm =
|
||||
|
||||
-- | Load a pkg and populate the name cache and external package state.
|
||||
loadPackage ::
|
||||
CompileOpts
|
||||
-> PackageState
|
||||
IdeOptions
|
||||
-> PackageDynFlags
|
||||
-> UniqSupply
|
||||
-> [LoadPackageResult]
|
||||
-> InstalledUnitId
|
||||
@ -196,9 +177,9 @@ loadPackage opt packageState us lps p =
|
||||
-- | Compile a single type-checked module to a 'CoreModule' value, or
|
||||
-- provide errors.
|
||||
compileModule
|
||||
:: CompileOpts
|
||||
:: IdeOptions
|
||||
-> ParsedModule
|
||||
-> PackageState
|
||||
-> PackageDynFlags
|
||||
-> UniqSupply
|
||||
-> [TcModuleResult]
|
||||
-> [LoadPackageResult]
|
||||
@ -233,27 +214,27 @@ compileModule opt mod packageState uniqSupply deps pkgs tmr =
|
||||
-- | Evaluate a GHC session using a new environment constructed with
|
||||
-- the supplied options.
|
||||
runGhcSessionExcept
|
||||
:: CompileOpts
|
||||
:: IdeOptions
|
||||
-> Maybe ParsedModule
|
||||
-> PackageState
|
||||
-> PackageDynFlags
|
||||
-> Ex.ExceptT e Ghc a
|
||||
-> Ex.ExceptT e IO a
|
||||
runGhcSessionExcept opts mbMod pkg m =
|
||||
Ex.ExceptT $ runGhcSession opts mbMod pkg $ Ex.runExceptT m
|
||||
|
||||
|
||||
getGhcDynFlags :: CompileOpts -> ParsedModule -> PackageState -> IO DynFlags
|
||||
getGhcDynFlags :: IdeOptions -> ParsedModule -> PackageDynFlags -> IO DynFlags
|
||||
getGhcDynFlags opts mod pkg = runGhcSession opts (Just mod) pkg getSessionDynFlags
|
||||
|
||||
-- | Evaluate a GHC session using a new environment constructed with
|
||||
-- the supplied options.
|
||||
runGhcSession
|
||||
:: CompileOpts
|
||||
:: IdeOptions
|
||||
-> Maybe ParsedModule
|
||||
-> PackageState
|
||||
-> PackageDynFlags
|
||||
-> Ghc a
|
||||
-> IO a
|
||||
runGhcSession CompileOpts{..} = optRunGhcSession
|
||||
runGhcSession IdeOptions{..} = optRunGhcSession
|
||||
|
||||
-- When we make a fresh GHC environment, the OrigNameCache comes already partially
|
||||
-- populated. So to be safe, we simply extend this one.
|
||||
@ -496,11 +477,11 @@ parsePragmasIntoDynFlags fp contents = catchSrcErrors $ do
|
||||
(dflags, _, _) <- parseDynamicFilePragma dflags0 opts
|
||||
return dflags
|
||||
|
||||
generatePackageState :: [FilePath] -> Bool -> [(String, ModRenaming)] -> IO PackageState
|
||||
generatePackageState :: [FilePath] -> Bool -> [(String, ModRenaming)] -> IO PackageDynFlags
|
||||
generatePackageState paths hideAllPkgs pkgImports = do
|
||||
let dflags = setPackageImports hideAllPkgs pkgImports $ setPackageDbs paths (defaultDynFlags fakeSettings fakeLlvmConfig)
|
||||
(newDynFlags, _) <- initPackages dflags
|
||||
pure $ PackageState (pkgDatabase newDynFlags) (pkgState newDynFlags) (thisUnitIdInsts_ newDynFlags)
|
||||
pure $ getPackageDynFlags newDynFlags
|
||||
|
||||
-- | Run something in a Ghc monad and catch the errors (SourceErrors and
|
||||
-- compiler-internal exceptions like Panic or InstallationError).
|
||||
|
@ -13,13 +13,11 @@ module Development.IDE.Logger
|
||||
import qualified Data.Text as T
|
||||
import GHC.Stack
|
||||
|
||||
data Handle m = Handle {
|
||||
logError :: HasCallStack => T.Text -> m ()
|
||||
, logWarning :: HasCallStack => T.Text -> m ()
|
||||
, logInfo :: HasCallStack => T.Text -> m ()
|
||||
, logDebug :: HasCallStack => T.Text -> m ()
|
||||
data Handle = Handle {
|
||||
logSeriousError :: HasCallStack => T.Text -> IO ()
|
||||
, logDebug :: HasCallStack => T.Text -> IO ()
|
||||
}
|
||||
|
||||
makeNopHandle :: Monad m => Handle m
|
||||
makeNopHandle = Handle e e e e where
|
||||
makeNopHandle :: Handle
|
||||
makeNopHandle = Handle e e where
|
||||
e _ = pure ()
|
||||
|
@ -12,6 +12,7 @@ module Development.IDE.State.FileStore(
|
||||
|
||||
|
||||
import StringBuffer
|
||||
import Development.IDE.UtilGHC()
|
||||
|
||||
import qualified Data.Map.Strict as Map
|
||||
import qualified Data.Text as T
|
||||
@ -21,12 +22,12 @@ import qualified System.Directory as Dir
|
||||
import Development.Shake
|
||||
import Development.Shake.Classes
|
||||
import Development.IDE.State.Shake
|
||||
import Development.IDE.UtilGHC
|
||||
import Control.Concurrent.Extra
|
||||
import Control.Exception
|
||||
import GHC.Generics
|
||||
import System.IO.Error
|
||||
import qualified Data.ByteString.Char8 as BS
|
||||
import qualified StringBuffer as SB
|
||||
import Development.IDE.Types.Diagnostics
|
||||
import Data.Time
|
||||
|
||||
@ -141,7 +142,13 @@ setBufferModified state absFile (mcontents, !time) = do
|
||||
-- update vars synchronously
|
||||
modifyVar_ envDirtyFiles $ evaluate . case mcontents of
|
||||
Nothing -> Map.delete absFile
|
||||
Just contents -> Map.insert absFile $ strictPair time (textToStringBuffer contents)
|
||||
Just contents -> Map.insert absFile $ strictPair time $ textToStringBuffer contents
|
||||
|
||||
-- run shake to update results regarding the files of interest
|
||||
void $ shakeRun state []
|
||||
|
||||
|
||||
-- would be nice to do this more efficiently...
|
||||
textToStringBuffer :: T.Text -> SB.StringBuffer
|
||||
-- would be nice to do this more efficiently...
|
||||
textToStringBuffer = SB.stringToStringBuffer . T.unpack
|
||||
|
@ -15,6 +15,7 @@ module Development.IDE.State.RuleTypes(
|
||||
import Control.DeepSeq
|
||||
import Development.IDE.Functions.Compile (TcModuleResult, GhcModule, LoadPackageResult(..))
|
||||
import qualified Development.IDE.Functions.Compile as Compile
|
||||
import qualified Development.IDE.UtilGHC as Compile
|
||||
import Development.IDE.Functions.FindImports (Import(..))
|
||||
import Development.IDE.Functions.DependencyInformation
|
||||
import Data.Hashable
|
||||
@ -61,7 +62,7 @@ type instance RuleResult GenerateCore = GhcModule
|
||||
|
||||
-- | We capture the subset of `DynFlags` that is computed by package initialization in a rule to
|
||||
-- make session initialization cheaper by reusing it.
|
||||
type instance RuleResult LoadPackageState = Compile.PackageState
|
||||
type instance RuleResult LoadPackageState = Compile.PackageDynFlags
|
||||
|
||||
-- | Resolve the imports in a module to the list of either external packages or absolute file paths
|
||||
-- for modules in the same package.
|
||||
|
@ -28,6 +28,7 @@ import Control.Exception (evaluate)
|
||||
import Control.Monad.Except
|
||||
import Control.Monad.Extra (whenJust)
|
||||
import qualified Development.IDE.Functions.Compile as Compile
|
||||
import qualified Development.IDE.Types.Options as Compile
|
||||
import Development.IDE.Functions.DependencyInformation
|
||||
import Development.IDE.Functions.FindImports
|
||||
import Development.IDE.State.FileStore
|
||||
@ -152,7 +153,7 @@ getDefinitionForFile file pos = do
|
||||
spans <- useE GetSpanInfo file
|
||||
return $ AtPoint.gotoDefinition spans pos
|
||||
|
||||
getOpts :: Action Compile.CompileOpts
|
||||
getOpts :: Action Compile.IdeOptions
|
||||
getOpts = envOptions <$> getServiceEnv
|
||||
|
||||
------------------------------------------------------------
|
||||
|
@ -16,18 +16,17 @@ module Development.IDE.State.Service(
|
||||
setFilesOfInterest,
|
||||
writeProfile,
|
||||
getDiagnostics, unsafeClearDiagnostics,
|
||||
logDebug, logInfo, logWarning, logError
|
||||
logDebug, logSeriousError
|
||||
) where
|
||||
|
||||
import Control.Concurrent.Extra
|
||||
import Control.Monad.Except
|
||||
import Development.IDE.Functions.Compile (CompileOpts(..))
|
||||
import Development.IDE.Types.Options (IdeOptions(..))
|
||||
import Development.IDE.State.FileStore
|
||||
import qualified Development.IDE.Logger as Logger
|
||||
import Data.Maybe
|
||||
import Data.Set (Set)
|
||||
import qualified Data.Set as Set
|
||||
import qualified Data.Text as T
|
||||
import Development.IDE.Functions.GHCError
|
||||
import Development.Shake hiding (Diagnostic, Env, newCache)
|
||||
import Development.IDE.Types.LSP as Compiler
|
||||
@ -39,7 +38,7 @@ import Development.IDE.State.Shake
|
||||
|
||||
-- | Environment threaded through the Shake actions.
|
||||
data Env = Env
|
||||
{ envOptions :: CompileOpts
|
||||
{ envOptions :: IdeOptions
|
||||
-- ^ Compiler options.
|
||||
, envOfInterestVar :: Var (Set FilePath)
|
||||
-- ^ The files of interest.
|
||||
@ -49,7 +48,7 @@ data Env = Env
|
||||
instance IsIdeGlobal Env
|
||||
|
||||
|
||||
mkEnv :: CompileOpts -> IO Env
|
||||
mkEnv :: IdeOptions -> IO Env
|
||||
mkEnv options = do
|
||||
ofInterestVar <- newVar Set.empty
|
||||
uniqSupplyVar <- mkSplitUniqSupply 'a' >>= newVar
|
||||
@ -72,8 +71,8 @@ unsafeClearDiagnostics = unsafeClearAllDiagnostics
|
||||
-- | Initialise the Compiler Service.
|
||||
initialise :: Rules ()
|
||||
-> Maybe (Event -> IO ())
|
||||
-> Logger.Handle IO
|
||||
-> CompileOpts
|
||||
-> Logger.Handle
|
||||
-> IdeOptions
|
||||
-> IO IdeState
|
||||
initialise mainRule toDiags logger options =
|
||||
shakeOpen
|
||||
@ -90,7 +89,7 @@ initialise mainRule toDiags logger options =
|
||||
writeProfile :: IdeState -> FilePath -> IO ()
|
||||
writeProfile = shakeProfile
|
||||
|
||||
setProfiling :: CompileOpts -> ShakeOptions -> ShakeOptions
|
||||
setProfiling :: IdeOptions -> ShakeOptions -> ShakeOptions
|
||||
setProfiling opts shakeOpts =
|
||||
maybe shakeOpts (\p -> shakeOpts { shakeReport = [p], shakeTimings = True }) (optShakeProfiling opts)
|
||||
|
||||
@ -119,9 +118,3 @@ setFilesOfInterest state files = do
|
||||
|
||||
getServiceEnv :: Action Env
|
||||
getServiceEnv = getIdeGlobalAction
|
||||
|
||||
logDebug, logInfo, logWarning, logError :: IdeState -> T.Text -> IO ()
|
||||
logDebug = shakeLogDebug
|
||||
logInfo = shakeLogInfo
|
||||
logWarning = shakeLogWarning
|
||||
logError = shakeLogError
|
||||
|
@ -38,10 +38,8 @@ module Development.IDE.State.Shake(
|
||||
garbageCollect,
|
||||
setPriority,
|
||||
sendEvent,
|
||||
shakeLogDebug,
|
||||
shakeLogInfo,
|
||||
shakeLogWarning,
|
||||
shakeLogError,
|
||||
Development.IDE.State.Shake.logDebug,
|
||||
Development.IDE.State.Shake.logSeriousError,
|
||||
) where
|
||||
|
||||
import Development.Shake
|
||||
@ -78,7 +76,7 @@ import Numeric.Extra
|
||||
-- information we stash inside the shakeExtra field
|
||||
data ShakeExtras = ShakeExtras
|
||||
{eventer :: Event -> IO ()
|
||||
,logger :: Logger.Handle IO
|
||||
,logger :: Logger.Handle
|
||||
,globals :: Var (Map.HashMap TypeRep Dynamic)
|
||||
,state :: Var Values
|
||||
}
|
||||
@ -221,7 +219,7 @@ getValues state key file = do
|
||||
|
||||
-- | Open a 'IdeState', should be shut using 'shakeShut'.
|
||||
shakeOpen :: (Event -> IO ()) -- ^ diagnostic handler
|
||||
-> Logger.Handle IO
|
||||
-> Logger.Handle
|
||||
-> ShakeOptions
|
||||
-> Rules ()
|
||||
-> IO IdeState
|
||||
@ -245,13 +243,13 @@ shakeRun :: IdeState -> [Action a] -> IO (IO [a])
|
||||
-- not even start, which would make issues with async exceptions less problematic.
|
||||
shakeRun IdeState{shakeExtras=ShakeExtras{..}, ..} acts = modifyVar shakeAbort $ \stop -> do
|
||||
(stopTime,_) <- duration stop
|
||||
Logger.logInfo logger $ T.pack $ "Starting shakeRun (aborting the previous one took " ++ showDuration stopTime ++ ")"
|
||||
Logger.logDebug logger $ T.pack $ "Starting shakeRun (aborting the previous one took " ++ showDuration stopTime ++ ")"
|
||||
bar <- newBarrier
|
||||
start <- offsetTime
|
||||
thread <- forkFinally (shakeRunDatabaseProfile shakeDb acts) $ \res -> do
|
||||
signalBarrier bar res
|
||||
runTime <- start
|
||||
Logger.logInfo logger $ T.pack $
|
||||
Logger.logDebug logger $ T.pack $
|
||||
"Finishing shakeRun (took " ++ showDuration runTime ++ ", " ++ (if isLeft res then "exception" else "completed") ++ ")"
|
||||
-- important: we send an async exception to the thread, then wait for it to die, before continuing
|
||||
return (do killThread thread; void $ waitBarrier bar, either throwIO return =<< waitBarrier bar)
|
||||
@ -302,12 +300,12 @@ uses_ key files = do
|
||||
reportSeriousError :: String -> Action ()
|
||||
reportSeriousError t = do
|
||||
ShakeExtras{logger} <- getShakeExtras
|
||||
liftIO $ Logger.logError logger $ T.pack t
|
||||
liftIO $ Logger.logSeriousError logger $ T.pack t
|
||||
|
||||
reportSeriousErrorDie :: String -> Action a
|
||||
reportSeriousErrorDie t = do
|
||||
ShakeExtras{logger} <- getShakeExtras
|
||||
liftIO $ Logger.logError logger $ T.pack t
|
||||
liftIO $ Logger.logSeriousError logger $ T.pack t
|
||||
fail t
|
||||
|
||||
|
||||
@ -419,12 +417,10 @@ sendEvent e = do
|
||||
liftIO $ eventer e
|
||||
|
||||
-- | bit of an odd signature because we're trying to remove priority
|
||||
sl :: (Handle IO -> T.Text -> IO ()) -> IdeState -> T.Text -> IO ()
|
||||
sl :: (Handle -> T.Text -> IO ()) -> IdeState -> T.Text -> IO ()
|
||||
sl f IdeState{shakeExtras=ShakeExtras{logger}} p = f logger p
|
||||
|
||||
shakeLogDebug, shakeLogInfo, shakeLogWarning, shakeLogError
|
||||
logDebug, logSeriousError
|
||||
:: IdeState -> T.Text -> IO ()
|
||||
shakeLogDebug = sl logDebug
|
||||
shakeLogInfo = sl logInfo
|
||||
shakeLogWarning = sl logWarning
|
||||
shakeLogError = sl logError
|
||||
logDebug = sl Logger.logDebug
|
||||
logSeriousError = sl Logger.logSeriousError
|
||||
|
31
src/Development/IDE/Types/Options.hs
Normal file
31
src/Development/IDE/Types/Options.hs
Normal file
@ -0,0 +1,31 @@
|
||||
-- Copyright (c) 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
-- SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
{-# LANGUAGE RankNTypes #-}
|
||||
|
||||
-- | Options
|
||||
module Development.IDE.Types.Options
|
||||
( IdeOptions(..)
|
||||
) where
|
||||
|
||||
import Development.IDE.UtilGHC
|
||||
import GHC hiding (parseModule, typecheckModule)
|
||||
import GhcPlugins as GHC hiding (fst3, (<>))
|
||||
|
||||
|
||||
data IdeOptions = IdeOptions
|
||||
{ optPreprocessor :: GHC.ParsedSource -> ([(GHC.SrcSpan, String)], GHC.ParsedSource)
|
||||
, optRunGhcSession :: forall a. Maybe ParsedModule -> PackageDynFlags -> Ghc a -> IO a
|
||||
-- ^ Setup a GHC session using a given package state. If a `ParsedModule` is supplied,
|
||||
-- the import path should be setup for that module.
|
||||
, optWriteIface :: Bool
|
||||
|
||||
, optMbPackageName :: Maybe String
|
||||
|
||||
, optPackageDbs :: [FilePath]
|
||||
, optHideAllPkgs :: Bool
|
||||
, optPackageImports :: [(String, ModRenaming)]
|
||||
|
||||
, optThreads :: Int
|
||||
, optShakeProfiling :: Maybe FilePath
|
||||
}
|
@ -12,9 +12,8 @@
|
||||
--
|
||||
-- * Call setSessionDynFlags, use modifyDynFlags instead. It's faster and avoids loading packages.
|
||||
module Development.IDE.UtilGHC(
|
||||
PackageState(..),
|
||||
PackageDynFlags(..), setPackageDynFlags, getPackageDynFlags,
|
||||
modifyDynFlags,
|
||||
textToStringBuffer,
|
||||
removeTypeableInfo,
|
||||
setPackageImports,
|
||||
setPackageDbs,
|
||||
@ -25,7 +24,6 @@ module Development.IDE.UtilGHC(
|
||||
mkImport,
|
||||
runGhcFast,
|
||||
setImports,
|
||||
setPackageState,
|
||||
setThisInstalledUnitId,
|
||||
modIsInternal
|
||||
) where
|
||||
@ -34,18 +32,17 @@ import Config
|
||||
import Fingerprint
|
||||
import GHC hiding (convertLit)
|
||||
import GhcMonad
|
||||
import GhcPlugins as GHC hiding (PackageState, fst3, (<>))
|
||||
import GhcPlugins as GHC hiding (fst3, (<>))
|
||||
import HscMain
|
||||
import qualified Packages
|
||||
import Platform
|
||||
import qualified StringBuffer as SB
|
||||
import qualified EnumSet
|
||||
|
||||
import Control.DeepSeq
|
||||
import Data.IORef
|
||||
import Data.List
|
||||
import qualified Data.Text as T
|
||||
import GHC.Generics (Generic)
|
||||
import qualified StringBuffer as SB
|
||||
|
||||
----------------------------------------------------------------------
|
||||
-- GHC setup
|
||||
@ -82,15 +79,29 @@ modifyDynFlags f = do
|
||||
modifySession $ \h ->
|
||||
h { hsc_dflags = newFlags, hsc_IC = (hsc_IC h) {ic_dflags = newFlags} }
|
||||
|
||||
-- | This is the subset of `DynFlags` that is computed by package initialization.
|
||||
data PackageState = PackageState
|
||||
{ pkgStateDb :: !(Maybe [(FilePath, [Packages.PackageConfig])])
|
||||
, pkgStateState :: !Packages.PackageState
|
||||
, pkgThisUnitIdInsts :: !(Maybe [(ModuleName, Module)])
|
||||
} deriving (Generic, Show)
|
||||
-- | The subset of @DynFlags@ computed by package initialization.
|
||||
data PackageDynFlags = PackageDynFlags
|
||||
{ pdfPkgDatabase :: !(Maybe [(FilePath, [Packages.PackageConfig])])
|
||||
, pdfPkgState :: !Packages.PackageState
|
||||
, pdfThisUnitIdInsts :: !(Maybe [(ModuleName, Module)])
|
||||
} deriving (Generic, Show)
|
||||
|
||||
instance NFData PackageState where
|
||||
rnf (PackageState db state insts) = db `seq` state `seq` rnf insts
|
||||
instance NFData PackageDynFlags where
|
||||
rnf (PackageDynFlags db state insts) = db `seq` state `seq` rnf insts
|
||||
|
||||
setPackageDynFlags :: PackageDynFlags -> DynFlags -> DynFlags
|
||||
setPackageDynFlags PackageDynFlags{..} dflags = dflags
|
||||
{ pkgDatabase = pdfPkgDatabase
|
||||
, pkgState = pdfPkgState
|
||||
, thisUnitIdInsts_ = pdfThisUnitIdInsts
|
||||
}
|
||||
|
||||
getPackageDynFlags :: DynFlags -> PackageDynFlags
|
||||
getPackageDynFlags DynFlags{..} = PackageDynFlags
|
||||
{ pdfPkgDatabase = pkgDatabase
|
||||
, pdfPkgState = pkgState
|
||||
, pdfThisUnitIdInsts = thisUnitIdInsts_
|
||||
}
|
||||
|
||||
|
||||
-- | A version of `showSDoc` that uses default flags (to avoid uses of
|
||||
@ -102,10 +113,6 @@ showSDocDefault = showSDoc dynFlags
|
||||
prettyPrint :: Outputable a => a -> String
|
||||
prettyPrint = showSDocDefault . ppr
|
||||
|
||||
textToStringBuffer :: T.Text -> SB.StringBuffer
|
||||
-- would be nice to do this more efficiently...
|
||||
textToStringBuffer = SB.stringToStringBuffer . T.unpack
|
||||
|
||||
-- FIXME(#1203): This must move out of `haskell-ide-core` and into `damlc`.
|
||||
internalModules :: [String]
|
||||
internalModules =
|
||||
@ -177,14 +184,6 @@ setThisInstalledUnitId unitId dflags =
|
||||
setImports :: [FilePath] -> DynFlags -> DynFlags
|
||||
setImports paths dflags = dflags { importPaths = paths }
|
||||
|
||||
setPackageState :: PackageState -> DynFlags -> DynFlags
|
||||
setPackageState state dflags =
|
||||
dflags
|
||||
{ pkgDatabase = pkgStateDb state
|
||||
, pkgState = pkgStateState state
|
||||
, thisUnitIdInsts_ = pkgThisUnitIdInsts state
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- Orphan instances for types from the GHC API.
|
||||
|
Loading…
Reference in New Issue
Block a user