@@ -1,5 +1,6 @@
11module Idris.Chaser(buildTree, getImports, getModuleFiles, ModuleTree(..)) where
22
3+import Idris.Core.TT
34import Idris.Parser
45import Idris.AbsSyntax
56import Idris.Imports
@@ -79,22 +80,31 @@ getIModTime (IBC i _) = getModificationTime i
7980getIModTime (IDR i) = getModificationTime i
8081getIModTime (LIDR i) = getModificationTime i
8182
82−getImports :: FilePath -> Idris (FilePath, [ImportInfo])
83−getImports f = do
84− i <- getIState
85− let file = extractFileName f
86− ibcsd <- valIBCSubDir i
87− ids <- allImportDirs
88− fp <- findImport ids ibcsd file
83+getImports :: [(FilePath, [ImportInfo])] -> [FilePath] ->
84+ Idris [(FilePath, [ImportInfo])]
85+getImports acc [] = return acc
86+getImports acc (f : fs) = do
87+ i <- getIState
88+ let file = extractFileName f
89+ ibcsd <- valIBCSubDir i
90+ ids <- allImportDirs
91+ idrisCatch (do
92+ fp <- findImport ["."] ibcsd file
8993 let parsef = fname fp
90− exist <- runIO $ doesFileExist parsef
91− if exist then do
92− src_in <- runIO $ readSource parsef
93− src <- if lit fp then tclift $ unlit parsef src_in else return src_in
94− (_, _, modules, _) <- parseImports parsef src
95− clearParserWarnings
96− return (parsef, modules)
97− else return (parsef, [])
94+ case lookup parsef acc of
95+ Just _ -> getImports acc fs
96+ _ -> do
97+ exist <- runIO $ doesFileExist parsef
98+ if exist then do
99+ src_in <- runIO $ readSource parsef
100+ src <- if lit fp then tclift $ unlit parsef src_in
101+ else return src_in
102+ (_, _, modules, _) <- parseImports parsef src
103+ clearParserWarnings
104+ getImports ((parsef, modules) : acc)
105+ (fs ++ map import_path modules)
106+ else getImports ((parsef, []) : acc) fs)
107+ (\_ -> getImports acc fs) -- not in current soure tree, ignore
98108 where
99109 lit (LIDR _) = True
100110 lit _ = False
@@ -127,7 +137,10 @@ buildTree built importlists fp = evalStateT (btree [] fp) []
127137 mt <- lift $ runIO $ getIModTime fp
128138 if (file `elem` built)
129139 then return [MTree fp False mt []]
130− else if file `elem` stk then return []
140+ else if file `elem` stk then
141+ do lift $ tclift $ tfail
142+ (Msg $ "Cycle detected in imports: "
143+ ++ showSep " -> " (reverse (file : stk)))
131144 else do donetree <- get
132145 case lookup file donetree of
133146 Just t -> return t