@@ -146,10 +146,13 @@ data Log
146
146
| LogNewComponentCache ! (([FileDiagnostic ], Maybe HscEnvEq ), DependencyInfo )
147
147
| LogHieBios HieBios. Log
148
148
| LogSessionLoadingChanged
149
+ | LogSessionNewLoadedFiles ! [FilePath ]
149
150
deriving instance Show Log
150
151
151
152
instance Pretty Log where
152
153
pretty = \ case
154
+ LogSessionNewLoadedFiles files ->
155
+ " New loaded files:" <+> pretty files
153
156
LogNoneCradleFound path ->
154
157
" None cradle found for" <+> pretty path <+> " , ignoring the file"
155
158
LogSettingInitialDynFlags ->
@@ -425,7 +428,7 @@ loadSessionWithOptions :: Recorder (WithPriority Log) -> SessionLoadingOptions -
425
428
loadSessionWithOptions recorder SessionLoadingOptions {.. } rootDir que = do
426
429
let toAbsolutePath = toAbsolute rootDir -- see Note [Root Directory]
427
430
cradle_files <- newIORef (Set. fromList [] )
428
- -- error_loading_files <- newIORef (Set.fromList [])
431
+ error_loading_files <- newIORef (Set. fromList [] )
429
432
-- Mapping from hie.yaml file to HscEnv, one per hie.yaml file
430
433
hscEnvs <- newVar Map. empty :: IO (Var HieMap )
431
434
-- Mapping from a Filepath to HscEnv
@@ -603,19 +606,8 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
603
606
let ! exportsMap' = createExportsMap $ mapMaybe (fmap hirModIface) modIfaces
604
607
liftIO $ atomically $ modifyTVar' (exportsMap shakeExtras) (exportsMap' <> )
605
608
return [keys1, keys2]
606
-
607
-
608
609
return $ (second Map. keys this_options, Set. fromList $ fromNormalizedFilePath <$> newLoaded)
609
610
610
- let makeError hieYaml cradle err cfp = do
611
- dep_info <- getDependencyInfo (maybeToList hieYaml)
612
- let ncfp = toNormalizedFilePath' cfp
613
- let res = (map (\ err' -> renderCradleError err' cradle ncfp) err, Nothing )
614
- void $ modifyVar' fileToFlags $
615
- Map. insertWith HM. union hieYaml (HM. singleton ncfp (res, dep_info))
616
- void $ modifyVar' filesMap $ HM. insert ncfp hieYaml
617
- return (fst res)
618
-
619
611
let consultCradle :: Maybe FilePath -> FilePath -> IO (IdeResult HscEnvEq , [FilePath ])
620
612
consultCradle hieYaml cfp = do
621
613
let lfpLog = makeRelative rootDir cfp
@@ -630,12 +622,19 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
630
622
let progMsg = " Setting up " <> T. pack (takeBaseName (cradleRootDir cradle))
631
623
<> " (for " <> T. pack lfpLog <> " )"
632
624
633
- pendingFiles <- Set. fromList <$> (atomically $ flushTQueue pendingFilesTQueue)
625
+ pendingFiles' <- Set. fromList <$> (atomically $ flushTQueue pendingFilesTQueue)
626
+ -- remove the file from error loading files
627
+ errorFiles <- readIORef error_loading_files
628
+ -- remove error files from pending files since error loading need to load one by one
629
+ let pendingFiles = pendingFiles' `Set.difference` errorFiles
630
+ -- if the file is in error loading files, we fall back to single loading mode
631
+ let toLoads = if cfp `Set.member` errorFiles then Set. empty else pendingFiles
632
+
634
633
eopts <- mRunLspTCallback lspEnv (\ act -> withIndefiniteProgress progMsg Nothing NotCancellable (const act)) $
635
634
withTrace " Load cradle" $ \ addTag -> do
636
635
addTag " file" lfpLog
637
636
old_files <- readIORef cradle_files
638
- res <- cradleToOptsAndLibDir recorder (sessionLoading clientConfig) cradle cfp (Set. toList $ pendingFiles <> old_files)
637
+ res <- cradleToOptsAndLibDir recorder (sessionLoading clientConfig) cradle cfp (Set. toList $ Set. delete cfp $ toLoads <> old_files)
639
638
addTag " result" (show res)
640
639
return res
641
640
@@ -649,20 +648,37 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
649
648
[] -> error $ " GHC version could not be parsed: " <> version
650
649
((runTime, _): _)
651
650
| compileTime == runTime -> do
652
- (results, newLoaded ) <- session (hieYaml, toNormalizedFilePath' cfp, opts, libDir)
651
+ (results, allNewLoaded ) <- session (hieYaml, toNormalizedFilePath' cfp, opts, libDir)
653
652
-- put back to pending que if not listed in the results
654
- let remainPendingFiles = Set. delete cfp $ pendingFiles `Set.difference` newLoaded
653
+ -- delete cfp even if ew report No cradle target found for cfp
654
+ let remainPendingFiles = Set. delete cfp $ pendingFiles `Set.difference` allNewLoaded
655
+ let newLoadedT = pendingFiles `Set.intersection` allNewLoaded
655
656
atomically $ forM_ remainPendingFiles (writeTQueue pendingFilesTQueue)
656
- atomicModifyIORef' cradle_files (\ xs -> (pendingFiles `Set.intersection` newLoaded <> xs,() ))
657
+ -- log new loaded files
658
+ logWith recorder Info $ LogSessionNewLoadedFiles $ Set. toList newLoadedT
659
+ atomicModifyIORef' cradle_files (\ xs -> (newLoadedT <> xs,() ))
660
+ atomicModifyIORef' error_loading_files (\ old -> (old `Set.difference` newLoadedT, () ))
657
661
return results
658
662
| otherwise -> return (([renderPackageSetupException cfp GhcVersionMismatch {.. }], Nothing ),[] )
659
663
-- Failure case, either a cradle error or the none cradle
660
664
Left err -> do
661
- let failedLoadingFiles = nub $ cfp: concatMap cradleErrorLoadingFiles err
662
- let remainPendingFiles = Set. delete cfp $ pendingFiles `Set.difference` Set. fromList failedLoadingFiles
663
- atomically $ forM_ remainPendingFiles (writeTQueue pendingFilesTQueue)
664
- errors <- mapM (makeError hieYaml cradle err) $ failedLoadingFiles
665
- return ((concat errors, Nothing ), maybe [] pure hieYaml ++ concatMap cradleErrorDependencies err)
665
+ if (length toLoads > 1 )
666
+ then do
667
+ succLoaded_files <- readIORef cradle_files
668
+ -- mark as less loaded files as failedLoadingFiles possible
669
+ let failedLoadingFiles = (Set. insert cfp toLoads) `Set.difference` succLoaded_files
670
+ atomicModifyIORef' error_loading_files (\ xs -> (failedLoadingFiles <> xs,() ))
671
+ -- retry without other files
672
+ atomically $ forM_ pendingFiles (writeTQueue pendingFilesTQueue)
673
+ consultCradle hieYaml cfp
674
+ else do
675
+ dep_info <- getDependencyInfo (maybeToList hieYaml)
676
+ let ncfp = toNormalizedFilePath' cfp
677
+ let res = (map (\ err' -> renderCradleError err' cradle ncfp) err, Nothing )
678
+ void $ modifyVar' fileToFlags $
679
+ Map. insertWith HM. union hieYaml (HM. singleton ncfp (res, dep_info))
680
+ void $ modifyVar' filesMap $ HM. insert ncfp hieYaml
681
+ return (res, maybe [] pure hieYaml ++ concatMap cradleErrorDependencies err)
666
682
667
683
let
668
684
-- | We allow users to specify a loading strategy.
@@ -703,6 +719,10 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
703
719
deps_ok <- checkDependencyInfo old_di
704
720
if not deps_ok
705
721
then do
722
+ -- todo invoke the action to recompile the file
723
+ -- if deps are old, we can try to load the error files again
724
+ atomicModifyIORef' error_loading_files (\ xs -> (Set. delete file xs,() ))
725
+ atomicModifyIORef' cradle_files (\ xs -> (Set. delete file xs,() ))
706
726
-- If the dependencies are out of date then clear both caches and start
707
727
-- again.
708
728
modifyVar_ fileToFlags (const (return Map. empty))
0 commit comments