@@ -1,5 +1,6 @@
1module Idris.Chaser(buildTree, getImports, getModuleFiles, ModuleTree(..)) where
1module Idris.Chaser(buildTree, getImports, getModuleFiles, ModuleTree(..)) where
3import Idris.Parser
4import Idris.Parser
4import Idris.AbsSyntax
5import Idris.AbsSyntax
5import Idris.Imports
6import Idris.Imports
@@ -79,22 +80,31 @@ getIModTime (IBC i _) = getModificationTime i
79getIModTime (IDR i) = getModificationTime i
80getIModTime (IDR i) = getModificationTime i
80getIModTime (LIDR i) = getModificationTime i
81getIModTime (LIDR i) = getModificationTime i
83+getImports :: [(FilePath, [ImportInfo])] -> [FilePath] ->
82−getImports :: FilePath -> Idris (FilePath, [ImportInfo])
84+ Idris [(FilePath, [ImportInfo])]
83−getImports f = do
85+getImports acc [] = return acc
86+getImports acc (f : fs) = do
84− i <- getIState
87+ i <- getIState
85− let file = extractFileName f
88+ let file = extractFileName f
86− ibcsd <- valIBCSubDir i
89+ ibcsd <- valIBCSubDir i
87− ids <- allImportDirs
90+ ids <- allImportDirs
88− fp <- findImport ids ibcsd file
92+ fp <- findImport ["."] ibcsd file
89 let parsef = fname fp
93 let parsef = fname fp
94+ case lookup parsef acc of
95+ Just _ -> getImports acc fs
90− exist <- runIO $ doesFileExist parsef
97+ exist <- runIO $ doesFileExist parsef
91− if exist then do
98+ if exist then do
92− src_in <- runIO $ readSource parsef
99+ src_in <- runIO $ readSource parsef
93− src <- if lit fp then tclift $ unlit parsef src_in else return src_in
100+ src <- if lit fp then tclift $ unlit parsef src_in
94− (_, _, modules, _) <- parseImports parsef src
102+ (_, _, modules, _) <- parseImports parsef src
95− clearParserWarnings
103+ clearParserWarnings
96− return (parsef, modules)
104+ getImports ((parsef, modules) : acc)
105+ (fs ++ map import_path modules)
97− else return (parsef, [])
106+ else getImports ((parsef, []) : acc) fs)
107+ (\_ -> getImports acc fs) -- not in current soure tree, ignore
99 lit (LIDR _) = True
109 lit (LIDR _) = True
100 lit _ = False
110 lit _ = False
@@ -127,7 +137,10 @@ buildTree built importlists fp = evalStateT (btree [] fp) []
127 mt <- lift $ runIO $ getIModTime fp
137 mt <- lift $ runIO $ getIModTime fp
128 if (file `elem` built)
138 if (file `elem` built)
129 then return [MTree fp False mt []]
139 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)))
131 else do donetree <- get
144 else do donetree <- get
132 case lookup file donetree of
145 case lookup file donetree of
133 Just t -> return t
146 Just t -> return t