@@ -479,7 +479,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
479
479
-- files in the project so that `knownFiles` can learn about them and
480
480
-- we can generate a complete module graph
481
481
let extendKnownTargets newTargets = do
482
- knownTargets <- concatForM newTargets $ \ TargetDetails {.. } ->
482
+ knownTargets <- concatForM newTargets $ \ TargetDetails {.. } ->
483
483
case targetTarget of
484
484
TargetFile f -> do
485
485
-- If a target file has multiple possible locations, then we
@@ -563,9 +563,27 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
563
563
let (new,old) = NE. splitAt (NE. length new_deps) all_deps'
564
564
pure (Map. insert hieYaml (NE. toList all_deps) m, (new,old))
565
565
566
+ let restartSession all_targets new_deps = do
567
+ restartShakeSession VFSUnmodified " new component" [] $ do
568
+ keys2 <- invalidateShakeCache
569
+ keys1 <- extendKnownTargets all_targets
570
+ return [keys1, keys2]
571
+
572
+ -- Typecheck all files in the project on startup
573
+ checkProject <- getCheckProject
574
+ unless (null new_deps || not checkProject) $ do
575
+ cfps' <- liftIO $ filterM (IO. doesFileExist . fromNormalizedFilePath) (concatMap targetLocations all_targets)
576
+ void $ shakeEnqueue extras $ mkDelayedAction " InitialLoad" Debug $ void $ do
577
+ mmt <- uses GetModificationTime cfps'
578
+ let cs_exist = catMaybes (zipWith (<$) cfps' mmt)
579
+ modIfaces <- uses GetModIface cs_exist
580
+ -- update exports map
581
+ shakeExtras <- getShakeExtras
582
+ let ! exportsMap' = createExportsMap $ mapMaybe (fmap hirModIface) modIfaces
583
+ liftIO $ atomically $ modifyTVar' (exportsMap shakeExtras) (exportsMap' <> )
566
584
567
585
let session :: (Maybe FilePath , NormalizedFilePath , ComponentOptions , FilePath )
568
- -> IO (IdeResult HscEnvEq ,[FilePath ])
586
+ -> IO (( IdeResult HscEnvEq ,[FilePath ]), ([ TargetDetails ], [ ComponentInfo ]) )
569
587
session args@ (hieYaml, _cfp, _opts, _libDir) = do
570
588
(new_deps, old_deps) <- packageSetup args
571
589
@@ -576,14 +594,15 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
576
594
hscEnv <- emptyHscEnv ideNc _libDir
577
595
let new_cache = newComponentCache recorder optExtensions _cfp hscEnv
578
596
all_target_details <- new_cache old_deps new_deps
579
-
597
+ let all_targets' = concat all_target_details
598
+ flags_map' = HM. fromList (concatMap toFlagsMap all_targets')
580
599
this_dep_info <- getDependencyInfo $ maybeToList hieYaml
600
+
581
601
let (all_targets, this_flags_map, this_options)
582
602
= case HM. lookup _cfp flags_map' of
583
603
Just this -> (all_targets', flags_map', this)
584
604
Nothing -> (this_target_details : all_targets', HM. insert _cfp this_flags flags_map', this_flags)
585
- where all_targets' = concat all_target_details
586
- flags_map' = HM. fromList (concatMap toFlagsMap all_targets')
605
+ where
587
606
this_target_details = TargetDetails (TargetFile _cfp) this_error_env this_dep_info [_cfp]
588
607
this_flags = (this_error_env, this_dep_info)
589
608
this_error_env = ([this_error], Nothing )
@@ -598,25 +617,8 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
598
617
-- The VFS doesn't change on cradle edits, re-use the old one.
599
618
-- Invalidate all the existing GhcSession build nodes by restarting the Shake session
600
619
-- todo result only when batch cradle loading is done
601
- keys2 <- invalidateShakeCache
602
- restartShakeSession VFSUnmodified " new component" [] $ do
603
- keys1 <- extendKnownTargets all_targets
604
- return [keys1, keys2]
605
-
606
- -- Typecheck all files in the project on startup
607
- checkProject <- getCheckProject
608
- unless (null new_deps || not checkProject) $ do
609
- cfps' <- liftIO $ filterM (IO. doesFileExist . fromNormalizedFilePath) (concatMap targetLocations all_targets)
610
- void $ shakeEnqueue extras $ mkDelayedAction " InitialLoad" Debug $ void $ do
611
- mmt <- uses GetModificationTime cfps'
612
- let cs_exist = catMaybes (zipWith (<$) cfps' mmt)
613
- modIfaces <- uses GetModIface cs_exist
614
- -- update exports map
615
- shakeExtras <- getShakeExtras
616
- let ! exportsMap' = createExportsMap $ mapMaybe (fmap hirModIface) modIfaces
617
- liftIO $ atomically $ modifyTVar' (exportsMap shakeExtras) (exportsMap' <> )
618
-
619
- return $ second Map. keys this_options
620
+ -- restartSession all_targets new_deps
621
+ return $ (second Map. keys this_options, (all_targets, new_deps))
620
622
621
623
let eoptsHscEnv (hieYaml, cfp, cradle, eopts) =
622
624
case eopts of
@@ -629,8 +631,8 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
629
631
((runTime, _): _)
630
632
| compileTime == runTime -> do
631
633
atomicModifyIORef' cradle_files (\ xs -> (cfp: xs,() ))
632
- session (hieYaml, toNormalizedFilePath' cfp, opts, libDir)
633
- | otherwise -> return (([renderPackageSetupException cfp GhcVersionMismatch {.. }], Nothing ),[] )
634
+ fmap ( fmap Just ) $ session (hieYaml, toNormalizedFilePath' cfp, opts, libDir)
635
+ | otherwise -> return ((( [renderPackageSetupException cfp GhcVersionMismatch {.. }], Nothing ),[] ), Nothing )
634
636
-- Failure case, either a cradle error or the none cradle
635
637
Left err -> do
636
638
dep_info <- getDependencyInfo (maybeToList hieYaml)
@@ -639,10 +641,11 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
639
641
void $ modifyVar' fileToFlags $
640
642
Map. insertWith HM. union hieYaml (HM. singleton ncfp (res, dep_info))
641
643
void $ modifyVar' filesMap $ HM. insert ncfp hieYaml
642
- return (res, maybe [] pure hieYaml ++ concatMap cradleErrorDependencies err)
644
+ return (( res, maybe [] pure hieYaml ++ concatMap cradleErrorDependencies err), Nothing )
643
645
644
- let consultCradles :: [(Maybe FilePath , FilePath )] -> IO [(IdeResult HscEnvEq , [FilePath ])]
645
- consultCradles hyCfpList = do
646
+ let
647
+ consultCradles [] = return []
648
+ consultCradles hyCfpList = do
646
649
let cfps = map snd hyCfpList
647
650
let lfpLogs = map (makeRelative rootDir . snd ) hyCfpList
648
651
logWith recorder Info $ LogCradlePaths lfpLogs
@@ -656,7 +659,8 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
656
659
return res
657
660
mapM eoptsHscEnv (zipWith (\ ((hieYaml, fp), cr) eopts -> (hieYaml, fp, cr, eopts) ) (zip hyCfpList cradles) eoptsList)
658
661
659
- let consultCradle :: Maybe FilePath -> FilePath -> IO (IdeResult HscEnvEq , [FilePath ])
662
+ let
663
+ -- consultCradle :: Maybe FilePath -> FilePath -> IO (IdeResult HscEnvEq, [FilePath])
660
664
consultCradle hieYaml cfp = do
661
665
let lfpLog = makeRelative rootDir cfp
662
666
logWith recorder Info $ LogCradlePath lfpLog
@@ -697,7 +701,8 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
697
701
698
702
-- This caches the mapping from hie.yaml + Mod.hs -> [String]
699
703
-- Returns the Ghc session and the cradle dependencies
700
- let sessionOpts :: (Maybe FilePath , FilePath ) -> IO (IdeResult HscEnvEq , [FilePath ])
704
+ let
705
+ -- sessionOpts :: (Maybe FilePath, FilePath) -> IO (IdeResult HscEnvEq, [FilePath])
701
706
sessionOpts (hieYaml, file) = do
702
707
Extra. whenM didSessionLoadingPreferenceConfigChange $ do
703
708
logWith recorder Info LogSessionLoadingChanged
@@ -722,7 +727,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
722
727
-- Keep the same name cache
723
728
modifyVar_ hscEnvs (return . Map. adjust (const [] ) hieYaml )
724
729
consultCradle hieYaml cfp
725
- else return (opts, Map. keys old_di)
730
+ else return (( opts, Map. keys old_di), Nothing )
726
731
Nothing -> consultCradle hieYaml cfp
727
732
728
733
let readSessionOptsFromCache (hieYaml, file) = do
@@ -748,7 +753,11 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
748
753
cached <- mapM readSessionOptsFromCache yamlFiles
749
754
let (toConsults, cachedResults) = partitionEithers cached
750
755
results <- consultCradles toConsults
751
- let consultMap = Map. fromList $ zip (map snd toConsults) results
756
+ let envs = map fst results
757
+ let mergeDeps (x, y) (a, b) = (x <> a, y <> b)
758
+ let (tgs, deps) = foldr mergeDeps ([] , [] ) $ mapMaybe snd results
759
+ Extra. whenM (return $ notNull toConsults) (restartSession tgs deps)
760
+ let consultMap = Map. fromList $ zip (map snd toConsults) envs
752
761
let cachedMap = Map. fromList cachedResults
753
762
return $ consultMap <> cachedMap
754
763
@@ -767,13 +776,13 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
767
776
-- at a time. Therefore the IORef contains the currently running cradle, if we try
768
777
-- to get some more options then we wait for the currently running action to finish
769
778
-- before attempting to do so.
770
- let getOptions :: FilePath -> IO (IdeResult HscEnvEq , [FilePath ])
771
- getOptions file = do
772
- let ncfp = toNormalizedFilePath' (toAbsolutePath file)
773
- cachedHieYamlLocation <- HM. lookup ncfp <$> readVar filesMap
774
- hieYaml <- cradleLoc file
775
- sessionOpts (join cachedHieYamlLocation <|> hieYaml, file) `Safe.catch` \ e ->
776
- return (([renderPackageSetupException file e], Nothing ), maybe [] pure hieYaml)
779
+ -- let getOptions :: FilePath -> IO (IdeResult HscEnvEq, [FilePath])
780
+ -- getOptions file = do
781
+ -- let ncfp = toNormalizedFilePath' (toAbsolutePath file)
782
+ -- cachedHieYamlLocation <- HM.lookup ncfp <$> readVar filesMap
783
+ -- hieYaml <- cradleLoc file
784
+ -- sessionOpts (join cachedHieYamlLocation <|> hieYaml, file) `Safe.catch` \e ->
785
+ -- return (([renderPackageSetupException file e], Nothing), maybe [] pure hieYaml)
777
786
778
787
let getOptionsBatch :: FilePath -> IO (IdeResult HscEnvEq , [FilePath ])
779
788
getOptionsBatch file' = do
@@ -799,9 +808,10 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
799
808
-- how we do batch loading of cradles depends on the the type of cradle we are using
800
809
cradleToOptsAndLibDirs :: Recorder (WithPriority Log ) -> SessionLoadingPreferenceConfig -> [(Cradle Void , FilePath )] -> [FilePath ]
801
810
-> IO [Either [CradleError ] (ComponentOptions , FilePath , String )]
802
- cradleToOptsAndLibDirs recorder loadConfig cradleFiles old_fps = do
811
+ cradleToOptsAndLibDirs recorder loadConfig [] old_fps = error " cradleToOptsAndLibDirs: empty list of cradles"
812
+ cradleToOptsAndLibDirs recorder loadConfig cradleFiles@ (cr: crs) old_fps = do
803
813
-- let result :: [([FilePath], CradleLoadResult ComponentOptions)]
804
- results <- HieBios. getCompilerOptionsInBatch (LoadWithContext old_fps) cradleFiles
814
+ results <- HieBios. getCompilerOptionsInBatch (LoadWithContext old_fps) (cr :| crs)
805
815
let resultMap :: Map. Map FilePath (CradleLoadResult ComponentOptions )
806
816
resultMap = Map. fromList $ [ (fp, r) | (fps, r) <- results, fp <- fps ]
807
817
mapM (\ (cr, fp) -> collectBiosResult recorder cr fp (resultMap Map. ! fp)) cradleFiles
0 commit comments