@@ -24,6 +24,7 @@ module Stack.ComponentFile
2424
2525import Control.Exception ( throw )
2626import Data.List ( find , isPrefixOf )
27+ import Data.Foldable (foldrM )
2728import qualified Data.Map.Strict as M
2829import qualified Data.Set as S
2930import qualified Data.Text as T
@@ -160,34 +161,38 @@ resolveFilesAndDeps
160161 GetPackageFileContext
161162 (Map ModuleName (Path Abs File ),[DotCabalPath ],[PackageWarning ])
162163resolveFilesAndDeps component dirs names0 = do
163- (dotCabalPaths, foundModules, missingModules) <- loop names0 S. empty
164+ (dotCabalPaths, foundModules, missingModules, _ ) <- loop names0 S. empty M . empty
164165 warnings <-
165166 liftM2 (++) (warnUnlisted foundModules) (warnMissing missingModules)
166167 pure (foundModules, dotCabalPaths, warnings)
167168 where
168- loop [] _ = pure ([] , M. empty, [] )
169- loop names doneModules0 = do
169+ loop [] _ _ = pure ([] , M. empty, [] , M. empty )
170+ loop names doneModules0 knownUsages = do
170171 resolved <- resolveFiles dirs names
171172 let foundFiles = mapMaybe snd resolved
172173 foundModules = mapMaybe toResolvedModule resolved
173174 missingModules = mapMaybe toMissingModule resolved
174- pairs <- mapM (getDependencies component dirs) foundFiles
175+ getDependenciesFold c (ps, ku) = do
176+ p <- getDependencies ku component dirs c
177+ pure (p : ps, ku <> snd p)
178+ (pairs, foundUsages) <- foldrM getDependenciesFold ([] , knownUsages) foundFiles
175179 let doneModules = S. union
176180 doneModules0
177181 (S. fromList (mapMaybe dotCabalModule names))
178182 moduleDeps = S. unions (map fst pairs)
179- thDepFiles = concatMap snd pairs
183+ thDepFiles = concatMap ( M. elems . snd ) pairs
180184 modulesRemaining = S. difference moduleDeps doneModules
181185 -- Ignore missing modules discovered as dependencies - they may
182186 -- have been deleted.
183- (resolvedFiles, resolvedModules, _) <-
184- loop (map DotCabalModule (S. toList modulesRemaining)) doneModules
187+ (resolvedFiles, resolvedModules, _, foundUsages' ) <-
188+ loop (map DotCabalModule (S. toList modulesRemaining)) doneModules foundUsages
185189 pure
186190 ( nubOrd $ foundFiles <> map DotCabalFilePath thDepFiles <> resolvedFiles
187191 , M. union
188192 (M. fromList foundModules)
189193 resolvedModules
190194 , missingModules
195+ , foundUsages'
191196 )
192197 warnUnlisted foundModules = do
193198 let unlistedModules =
@@ -233,37 +238,40 @@ resolveFilesAndDeps component dirs names0 = do
233238
234239-- | Get the dependencies of a Haskell module file.
235240getDependencies
236- :: NamedComponent
241+ :: Map FilePath (Path Abs File )
242+ -> NamedComponent
237243 -> [Path Abs Dir ]
238244 -> DotCabalPath
239- -> RIO GetPackageFileContext (Set ModuleName , [ Path Abs File ] )
240- getDependencies component dirs dotCabalPath =
245+ -> RIO GetPackageFileContext (Set ModuleName , Map FilePath ( Path Abs File ) )
246+ getDependencies knownUsages component dirs dotCabalPath =
241247 case dotCabalPath of
242248 DotCabalModulePath resolvedFile -> readResolvedHi resolvedFile
243249 DotCabalMainPath resolvedFile -> readResolvedHi resolvedFile
244- DotCabalFilePath {} -> pure (S. empty, [] )
245- DotCabalCFilePath {} -> pure (S. empty, [] )
250+ DotCabalFilePath {} -> pure (S. empty, M. empty )
251+ DotCabalCFilePath {} -> pure (S. empty, M. empty )
246252 where
247253 readResolvedHi resolvedFile = do
248254 dumpHIDir <- componentOutputDir component <$> asks ctxDistDir
249255 dir <- asks (parent . ctxFile)
250256 let sourceDir = fromMaybe dir $ find (`isProperPrefixOf` resolvedFile) dirs
251257 stripSourceDir d = stripProperPrefix d resolvedFile
252258 case stripSourceDir sourceDir of
253- Nothing -> pure (S. empty, [] )
259+ Nothing -> pure (S. empty, M. empty )
254260 Just fileRel -> do
255261 let hiPath = FilePath. replaceExtension
256262 (toFilePath (dumpHIDir </> fileRel))
257263 " .hi"
258264 dumpHIExists <- liftIO $ D. doesFileExist hiPath
259265 if dumpHIExists
260- then parseHI hiPath
261- else pure (S. empty, [] )
266+ then parseHI knownUsages hiPath
267+ else pure (S. empty, M. empty )
262268
263269-- | Parse a .hi file into a set of modules and files.
264270parseHI
265- :: FilePath -> RIO GetPackageFileContext (Set ModuleName , [Path Abs File ])
266- parseHI hiPath = do
271+ :: Map FilePath (Path Abs File )
272+ -> FilePath
273+ -> RIO GetPackageFileContext (Set ModuleName , Map FilePath (Path Abs File ))
274+ parseHI knownUsages hiPath = do
267275 dir <- asks (parent . ctxFile)
268276 result <-
269277 liftIO $ catchAnyDeep
@@ -277,26 +285,28 @@ parseHI hiPath = do
277285 , flow " Decoding failure:"
278286 , style Error $ fromString msg
279287 ]
280- pure (S. empty, [] )
288+ pure (S. empty, M. empty )
281289 Right iface -> do
282290 let moduleNames = fmap (fromString . T. unpack . decodeUtf8Lenient . fst ) .
283291 Iface. unList . Iface. dmods . Iface. deps
284- resolveFileDependency file = do
285- resolved <-
286- liftIO (forgivingResolveFile dir file) >>=
287- rejectMissingFile
288- when (isNothing resolved) $
289- prettyWarnL
290- [ flow " Dependent file listed in:"
291- , style File $ fromString hiPath
292- , flow " does not exist:"
293- , style File $ fromString file
294- ]
295- pure resolved
292+ resolveFileDependency file =
293+ case M. lookup file knownUsages of
294+ Just p ->
295+ pure $ Just (file, p)
296+ Nothing -> do
297+ resolved <- forgivingResolveFile dir file >>= rejectMissingFile
298+ when (isNothing resolved) $
299+ prettyWarnL
300+ [ flow " Dependent file listed in:"
301+ , style File $ fromString hiPath
302+ , flow " does not exist:"
303+ , style File $ fromString file
304+ ]
305+ pure $ (file,) <$> resolved
296306 resolveUsages = traverse
297307 (resolveFileDependency . Iface. unUsage) . Iface. unList . Iface. usage
298308 resolvedUsages <- catMaybes <$> resolveUsages iface
299- pure (S. fromList $ moduleNames iface, resolvedUsages)
309+ pure (S. fromList $ moduleNames iface, M. fromList resolvedUsages)
300310
301311-- | The directory where generated files are put like .o or .hs (from .x files).
302312componentOutputDir :: NamedComponent -> Path Abs Dir -> Path Abs Dir
0 commit comments