@@ -146,10 +146,13 @@ data Log
146146 | LogNewComponentCache ! (([FileDiagnostic ], Maybe HscEnvEq ), DependencyInfo )
147147 | LogHieBios HieBios. Log
148148 | LogSessionLoadingChanged
149+ | LogSessionNewLoadedFiles ! [FilePath ]
149150deriving instance Show Log
150151
151152instance Pretty Log where
152153 pretty = \ case
154+ LogSessionNewLoadedFiles files ->
155+ " New loaded files:" <+> pretty files
153156 LogNoneCradleFound path ->
154157 " None cradle found for" <+> pretty path <+> " , ignoring the file"
155158 LogSettingInitialDynFlags ->
@@ -425,7 +428,7 @@ loadSessionWithOptions :: Recorder (WithPriority Log) -> SessionLoadingOptions -
425428loadSessionWithOptions recorder SessionLoadingOptions {.. } rootDir que = do
426429 let toAbsolutePath = toAbsolute rootDir -- see Note [Root Directory]
427430 cradle_files <- newIORef (Set. fromList [] )
428- -- error_loading_files <- newIORef (Set.fromList [])
431+ error_loading_files <- newIORef (Set. fromList [] )
429432 -- Mapping from hie.yaml file to HscEnv, one per hie.yaml file
430433 hscEnvs <- newVar Map. empty :: IO (Var HieMap )
431434 -- Mapping from a Filepath to HscEnv
@@ -603,19 +606,8 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
603606 let ! exportsMap' = createExportsMap $ mapMaybe (fmap hirModIface) modIfaces
604607 liftIO $ atomically $ modifyTVar' (exportsMap shakeExtras) (exportsMap' <> )
605608 return [keys1, keys2]
606-
607-
608609 return $ (second Map. keys this_options, Set. fromList $ fromNormalizedFilePath <$> newLoaded)
609610
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-
619611 let consultCradle :: Maybe FilePath -> FilePath -> IO (IdeResult HscEnvEq , [FilePath ])
620612 consultCradle hieYaml cfp = do
621613 let lfpLog = makeRelative rootDir cfp
@@ -630,12 +622,19 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
630622 let progMsg = " Setting up " <> T. pack (takeBaseName (cradleRootDir cradle))
631623 <> " (for " <> T. pack lfpLog <> " )"
632624
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+
634633 eopts <- mRunLspTCallback lspEnv (\ act -> withIndefiniteProgress progMsg Nothing NotCancellable (const act)) $
635634 withTrace " Load cradle" $ \ addTag -> do
636635 addTag " file" lfpLog
637636 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)
639638 addTag " result" (show res)
640639 return res
641640
@@ -649,20 +648,37 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
649648 [] -> error $ " GHC version could not be parsed: " <> version
650649 ((runTime, _): _)
651650 | compileTime == runTime -> do
652- (results, newLoaded ) <- session (hieYaml, toNormalizedFilePath' cfp, opts, libDir)
651+ (results, allNewLoaded ) <- session (hieYaml, toNormalizedFilePath' cfp, opts, libDir)
653652 -- 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
655656 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, () ))
657661 return results
658662 | otherwise -> return (([renderPackageSetupException cfp GhcVersionMismatch {.. }], Nothing ),[] )
659663 -- Failure case, either a cradle error or the none cradle
660664 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)
666682
667683 let
668684 -- | We allow users to specify a loading strategy.
@@ -703,6 +719,10 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
703719 deps_ok <- checkDependencyInfo old_di
704720 if not deps_ok
705721 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,() ))
706726 -- If the dependencies are out of date then clear both caches and start
707727 -- again.
708728 modifyVar_ fileToFlags (const (return Map. empty))
0 commit comments