@@ -22,6 +22,7 @@ import Idris.Unlit
2222
2323import Control.Monad.State
2424import Data.List
25+import qualified Data.Set as S
2526import Data.Time.Clock
2627import System.Directory
2728import Util.System (readSource)
@@ -48,10 +49,17 @@ modName (IBC fp src) = modName src
4849-- any module has a descendent which needs reloading, return its
4950-- source, otherwise return the IBC
5051getModuleFiles :: [ModuleTree] -> [IFileType]
51−getModuleFiles ts = nub $ execState (modList ts) [] where
52− modList :: [ModuleTree] -> State [IFileType] ()
52+getModuleFiles ts
53+ = let (files, rebuild) = execState (modList ts) ([], S.empty) in
54+ updateToSrc rebuild (nub files)
55+ where
56+ -- Get the order of building modules. As we go we'll find things that
57+ -- need rebuilding, which we keep track of in the Set.
58+ -- The order of the list matters - things which get build first appear
59+ -- in the list first. We'll remove any repetition later.
60+ modList :: [ModuleTree] -> State ([IFileType], S.Set IFileType) ()
5361 modList [] = return ()
54− modList (m : ms) = do modTree [] m; modList ms
62+ modList (m : ms) = do modTree S.empty m; modList ms
5563
5664 modTree path (MTree p rechk tm deps)
5765 = do let file = chkReload rechk p
@@ -60,11 +68,11 @@ getModuleFiles ts = nub $ execState (modList ts) [] where
6068 let depMod = latest tm [] deps
6169 let needsRechk = rechk || depMod > tm
6270
63− st <- get
64− if needsRechk then put $ nub (getSrc file : updateToSrc path st)
65− else put $ nub (file : st)
66− st <- get
67− mapM_ (modTree (getSrc p : path)) deps
71+ (st, rebuild) <- get
72+ if needsRechk then put $ (getSrc file : st, S.union path rebuild)
73+ else put $ (file : st, rebuild)
74+ (st, rebuild) <- get
75+ mapM_ (modTree (S.insert (getSrc p) path)) deps
6876
6977 chkReload False p = p
7078 chkReload True (IBC fn src) = chkReload True src
@@ -73,10 +81,11 @@ getModuleFiles ts = nub $ execState (modList ts) [] where
7381 getSrc (IBC fn src) = getSrc src
7482 getSrc f = f
7583
76− updateToSrc path [] = []
77− updateToSrc path (x : xs) = if getSrc x `elem` path
78− then getSrc x : updateToSrc path xs
79− else x : updateToSrc path xs
84+ updateToSrc rebuilds [] = []
85+ updateToSrc rebuilds (x : xs)
86+ = if getSrc x `S.member` rebuilds
87+ then getSrc x : updateToSrc rebuilds xs
88+ else x : updateToSrc rebuilds xs
8089
8190-- | Strip quotes and the backslash escapes that Haskeline adds
8291extractFileName :: String -> String