1
1
{-# LANGUAGE ExistentialQuantification #-}
2
2
{-# LANGUAGE RankNTypes #-}
3
3
{-# LANGUAGE TypeFamilies #-}
4
+ {-# LANGUAGE CPP #-}
4
5
5
6
{-|
6
7
The logic for setting up a ghcide session by tapping into hie-bios.
@@ -100,6 +101,10 @@ import HieDb.Types
100
101
import HieDb.Utils
101
102
import qualified System.Random as Random
102
103
import System.Random (RandomGen )
104
+ import Control.Monad.IO.Unlift (MonadUnliftIO )
105
+ import Debug.Trace
106
+ import Control.Exception (evaluate )
107
+ import Control.DeepSeq
103
108
104
109
data Log
105
110
= LogSettingInitialDynFlags
@@ -208,11 +213,13 @@ data SessionLoadingOptions = SessionLoadingOptions
208
213
, getCacheDirs :: String -> [String ] -> IO CacheDirs
209
214
-- | Return the GHC lib dir to use for the 'unsafeGlobalDynFlags'
210
215
, getInitialGhcLibDir :: Recorder (WithPriority Log ) -> FilePath -> IO (Maybe LibDir )
216
+ # if ! MIN_VERSION_ghc (9 ,3 ,0 )
211
217
, fakeUid :: UnitId
212
218
-- ^ unit id used to tag the internal component built by ghcide
213
219
-- To reuse external interface files the unit ids must match,
214
220
-- thus make sure to build them with `--this-unit-id` set to the
215
221
-- same value as the ghcide fake uid
222
+ # endif
216
223
}
217
224
218
225
instance Default SessionLoadingOptions where
@@ -221,7 +228,9 @@ instance Default SessionLoadingOptions where
221
228
,loadCradle = loadWithImplicitCradle
222
229
,getCacheDirs = getCacheDirsDefault
223
230
,getInitialGhcLibDir = getInitialGhcLibDirDefault
231
+ #if !MIN_VERSION_ghc(9,3,0)
224
232
,fakeUid = Compat. toUnitId (Compat. stringToUnit " main" )
233
+ #endif
225
234
}
226
235
227
236
-- | Find the cradle for a given 'hie.yaml' configuration.
@@ -494,7 +503,11 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
494
503
new_deps' <- forM new_deps $ \ RawComponentInfo {.. } -> do
495
504
-- Remove all inplace dependencies from package flags for
496
505
-- components in this HscEnv
506
+ #if MIN_VERSION_ghc(9,3,0)
507
+ let (df2, uids) = (rawComponentDynFlags, [] )
508
+ #else
497
509
let (df2, uids) = removeInplacePackages fakeUid inplace rawComponentDynFlags
510
+ #endif
498
511
let prefix = show rawComponentUnitId
499
512
-- See Note [Avoiding bad interface files]
500
513
let hscComponents = sort $ map show uids
@@ -517,10 +530,14 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
517
530
-- that I do not fully understand
518
531
log Info $ LogMakingNewHscEnv inplace
519
532
hscEnv <- emptyHscEnv ideNc libDir
520
- newHscEnv <-
533
+ ! newHscEnv <-
521
534
-- Add the options for the current component to the HscEnv
522
535
evalGhcEnv hscEnv $ do
523
- _ <- setSessionDynFlags $ setHomeUnitId_ fakeUid df
536
+ _ <- setSessionDynFlags
537
+ #if !MIN_VERSION_ghc(9,3,0)
538
+ $ setHomeUnitId_ fakeUid
539
+ #endif
540
+ df
524
541
getSession
525
542
526
543
-- Modify the map so the hieYaml now maps to the newly created
@@ -718,7 +735,11 @@ cradleToOptsAndLibDir recorder cradle file = do
718
735
logWith recorder Info $ LogNoneCradleFound file
719
736
return (Left [] )
720
737
738
+ #if MIN_VERSION_ghc(9,3,0)
739
+ emptyHscEnv :: NameCache -> FilePath -> IO HscEnv
740
+ #else
721
741
emptyHscEnv :: IORef NameCache -> FilePath -> IO HscEnv
742
+ #endif
722
743
emptyHscEnv nc libDir = do
723
744
env <- runGhc (Just libDir) getSession
724
745
initDynLinker env
@@ -757,7 +778,11 @@ toFlagsMap TargetDetails{..} =
757
778
[ (l, (targetEnv, targetDepends)) | l <- targetLocations]
758
779
759
780
781
+ #if MIN_VERSION_ghc(9,3,0)
782
+ setNameCache :: NameCache -> HscEnv -> HscEnv
783
+ #else
760
784
setNameCache :: IORef NameCache -> HscEnv -> HscEnv
785
+ #endif
761
786
setNameCache nc hsc = hsc { hsc_NC = nc }
762
787
763
788
-- | Create a mapping from FilePaths to HscEnvEqs
@@ -773,6 +798,11 @@ newComponentCache
773
798
newComponentCache recorder exts cradlePath cfp hsc_env uids ci = do
774
799
let df = componentDynFlags ci
775
800
hscEnv' <-
801
+ #if MIN_VERSION_ghc(9,3,0)
802
+ -- Set up a multi component session with the other units on GHC 9.4
803
+ Compat. initUnits (map snd uids) (hscSetFlags df hsc_env)
804
+ #elif MIN_VERSION_ghc(9,3,0)
805
+ -- This initializes the units for GHC 9.2
776
806
-- Add the options for the current component to the HscEnv
777
807
-- We want to call `setSessionDynFlags` instead of `hscSetFlags`
778
808
-- because `setSessionDynFlags` also initializes the package database,
@@ -782,14 +812,20 @@ newComponentCache recorder exts cradlePath cfp hsc_env uids ci = do
782
812
evalGhcEnv hsc_env $ do
783
813
_ <- setSessionDynFlags $ df
784
814
getSession
815
+ #else
816
+ -- getOptions is enough to initialize units on GHC <9.2
817
+ pure $ hscSetFlags df hsc_env { hsc_IC = (hsc_IC hsc_env) { ic_dflags = df } }
818
+ #endif
785
819
820
+ traceM " got new hsc env"
786
821
787
822
let newFunc = maybe newHscEnvEqPreserveImportPaths newHscEnvEq cradlePath
788
823
henv <- newFunc hscEnv' uids
789
824
let targetEnv = ([] , Just henv)
790
825
targetDepends = componentDependencyInfo ci
791
826
res = (targetEnv, targetDepends)
792
827
logWith recorder Debug $ LogNewComponentCache res
828
+ evaluate $ liftRnf rwhnf $ componentTargets ci
793
829
794
830
let mk t = fromTargetId (importPaths df) exts (targetId t) targetEnv targetDepends
795
831
ctargets <- concatMapM mk (componentTargets ci)
@@ -998,9 +1034,11 @@ setOptions (ComponentOptions theOpts compRoot _) dflags = do
998
1034
-- initPackages parses the -package flags and
999
1035
-- sets up the visibility for each component.
1000
1036
-- Throws if a -package flag cannot be satisfied.
1001
- env <- hscSetFlags dflags'' <$> getSession
1002
- final_env' <- liftIO $ wrapPackageSetupException $ Compat. initUnits env
1003
- return (hsc_dflags final_env', targets)
1037
+ -- This only works for GHC <9.2
1038
+ -- For GHC >= 9.2, we need to modify the unit env in the hsc_dflags, which
1039
+ -- is done later in newComponentCache
1040
+ final_flags <- liftIO $ wrapPackageSetupException $ Compat. oldInitUnits dflags''
1041
+ return (final_flags, targets)
1004
1042
1005
1043
setIgnoreInterfacePragmas :: DynFlags -> DynFlags
1006
1044
setIgnoreInterfacePragmas df =
0 commit comments