{-# LANGUAGE CPP #-}

-- | Compat module for the main Driver types, such as 'HscEnv',
-- 'UnitEnv' and some DynFlags compat functions.
module Development.IDE.GHC.Compat.Env (
    Env.HscEnv(hsc_FC, hsc_NC, hsc_IC, hsc_mod_graph
#if MIN_VERSION_ghc(9,3,0)
              , hsc_type_env_vars
#else
              , hsc_type_env_var
#endif
              ),
    Env.hsc_HPT,
    InteractiveContext(..),
    setInteractivePrintName,
    setInteractiveDynFlags,
    Env.hsc_dflags,
    hsc_EPS,
    Env.hsc_logger,
    Env.hsc_tmpfs,
    Env.hsc_unit_env,
    Env.hsc_hooks,
    hscSetHooks,
    TmpFs,
    -- * HomeUnit
    hscHomeUnit,
    HomeUnit,
    setHomeUnitId_,
    Home.mkHomeModule,
    -- * Provide backwards Compatible
    -- types and helper functions.
    Logger(..),
    UnitEnv,
    hscSetUnitEnv,
    hscSetFlags,
    initTempFs,
    -- * Home Unit
    Session.homeUnitId_,
    -- * DynFlags Helper
    setBytecodeLinkerOptions,
    setInterpreterLinkerOptions,
    Session.safeImportsOn,
    -- * Ways
    Ways,
    Way,
    hostFullWays,
    setWays,
    wayGeneralFlags,
    wayUnsetGeneralFlags,
    -- * Backend, backwards compatible
    Backend,
    setBackend,
    ghciBackend,
    Development.IDE.GHC.Compat.Env.platformDefaultBackend,
    ) where

import           GHC                 (setInteractiveDynFlags)

-- See Note [Guidelines For Using CPP In GHCIDE Import Statements]

import           GHC.Driver.Backend  as Backend
import qualified GHC.Driver.Env      as Env
import           GHC.Driver.Hooks    (Hooks)
import           GHC.Driver.Session
import qualified GHC.Driver.Session  as Session
import           GHC.Platform.Ways
import           GHC.Runtime.Context
import           GHC.Unit.Env        (UnitEnv)
import           GHC.Unit.Home       as Home
import           GHC.Unit.Types      (UnitId)
import           GHC.Utils.Logger
import           GHC.Utils.TmpFs

#if !MIN_VERSION_ghc(9,3,0)
import           GHC.Driver.Env      (HscEnv, hsc_EPS)
#endif

#if MIN_VERSION_ghc(9,3,0)
import           GHC.Driver.Env      (HscEnv)
#endif

#if MIN_VERSION_ghc(9,3,0)
hsc_EPS :: HscEnv -> UnitEnv
hsc_EPS = Env.hsc_unit_env
#endif


setHomeUnitId_ :: UnitId -> DynFlags -> DynFlags
setHomeUnitId_ :: UnitId -> DynFlags -> DynFlags
setHomeUnitId_ UnitId
uid DynFlags
df = DynFlags
df { homeUnitId_ :: UnitId
Session.homeUnitId_ = UnitId
uid }

hscSetFlags :: DynFlags -> HscEnv -> HscEnv
hscSetFlags :: DynFlags -> HscEnv -> HscEnv
hscSetFlags DynFlags
df HscEnv
env = HscEnv
env { hsc_dflags :: DynFlags
Env.hsc_dflags = DynFlags
df }

initTempFs :: HscEnv -> IO HscEnv
initTempFs :: HscEnv -> IO HscEnv
initTempFs HscEnv
env = do
  TmpFs
tmpFs <- IO TmpFs
initTmpFs
  forall (f :: * -> *) a. Applicative f => a -> f a
pure HscEnv
env { hsc_tmpfs :: TmpFs
Env.hsc_tmpfs = TmpFs
tmpFs }

hscSetUnitEnv :: UnitEnv -> HscEnv -> HscEnv
hscSetUnitEnv :: UnitEnv -> HscEnv -> HscEnv
hscSetUnitEnv UnitEnv
ue HscEnv
env = HscEnv
env { hsc_unit_env :: UnitEnv
Env.hsc_unit_env = UnitEnv
ue }

hscSetHooks :: Hooks -> HscEnv -> HscEnv
hscSetHooks :: Hooks -> HscEnv -> HscEnv
hscSetHooks Hooks
hooks HscEnv
env =
  HscEnv
env { hsc_hooks :: Hooks
Env.hsc_hooks = Hooks
hooks }

hscHomeUnit :: HscEnv -> HomeUnit
hscHomeUnit :: HscEnv -> HomeUnit
hscHomeUnit =
  HscEnv -> HomeUnit
Env.hsc_home_unit

-- | We don't want to generate object code so we compile to bytecode
-- (HscInterpreted) which implies LinkInMemory
-- HscInterpreted
setBytecodeLinkerOptions :: DynFlags -> DynFlags
setBytecodeLinkerOptions :: DynFlags -> DynFlags
setBytecodeLinkerOptions DynFlags
df = DynFlags
df {
    ghcLink :: GhcLink
ghcLink   = GhcLink
LinkInMemory
#if MIN_VERSION_ghc(9,5,0)
  , backend = noBackend
#else
  , backend :: Backend
backend = Backend
NoBackend
#endif
  , ghcMode :: GhcMode
ghcMode = GhcMode
CompManager
    }

setInterpreterLinkerOptions :: DynFlags -> DynFlags
setInterpreterLinkerOptions :: DynFlags -> DynFlags
setInterpreterLinkerOptions DynFlags
df = DynFlags
df {
    ghcLink :: GhcLink
ghcLink   = GhcLink
LinkInMemory
#if MIN_VERSION_ghc(9,5,0)
   , backend = interpreterBackend
#else
  , backend :: Backend
backend = Backend
Interpreter
#endif
  , ghcMode :: GhcMode
ghcMode = GhcMode
CompManager
    }

-- -------------------------------------------------------
-- Ways helpers
-- -------------------------------------------------------


setWays :: Ways -> DynFlags -> DynFlags
setWays :: Ways -> DynFlags -> DynFlags
setWays Ways
newWays DynFlags
flags =
  DynFlags
flags { targetWays_ :: Ways
Session.targetWays_ = Ways
newWays}

-- -------------------------------------------------------
-- Backend helpers
-- -------------------------------------------------------


ghciBackend  :: Backend
#if MIN_VERSION_ghc(9,6,0)
ghciBackend = interpreterBackend
#else
ghciBackend :: Backend
ghciBackend = Backend
Interpreter
#endif

platformDefaultBackend :: DynFlags -> Backend
platformDefaultBackend :: DynFlags -> Backend
platformDefaultBackend =
  Platform -> Backend
Backend.platformDefaultBackend forall b c a. (b -> c) -> (a -> b) -> a -> c
. DynFlags -> Platform
targetPlatform

setBackend :: Backend -> DynFlags -> DynFlags
setBackend :: Backend -> DynFlags -> DynFlags
setBackend Backend
backend DynFlags
flags =
  DynFlags
flags { backend :: Backend
backend = Backend
backend }