2 % (c) The University of Glasgow, 2000
4 \section[Finder]{Module Finder}
8 Finder, -- = ModuleName -> IO (Maybe (Module, ModuleLocation))
9 newFinder, -- :: PackageConfigInfo -> IO Finder,
14 #include "HsVersions.h"
16 import HscTypes ( Finder, ModuleLocation(..) )
32 The Finder provides a thin filesystem abstraction to the rest of the
33 compiler. For a given module, it knows (a) which package the module
34 lives in, so it can make a Module from a ModuleName, and (b) where the
35 source, interface, and object files for a module live.
39 -- caches contents of package directories, never expunged
40 GLOBAL_VAR(pkgDirCache, Nothing, Maybe (FiniteMap String (PackageName, FilePath)))
42 -- caches contents of home directories, expunged whenever we
43 -- create a new finder.
44 GLOBAL_VAR(homeDirCache, emptyFM, FiniteMap String FilePath)
46 -- caches finder mapping, expunged whenever we create a new finder.
47 GLOBAL_VAR(finderMapCache, emptyFM, FiniteMap ModuleName Module)
50 newFinder :: PackageConfigInfo -> IO Finder
51 newFinder (PackageConfigInfo pkgs) = do
53 writeIORef homeDirCache emptyFM
54 writeIORef finderMapCache emptyFM
56 -- populate the home dir cache, using the import path (the import path
57 -- is changed by -i flags on the command line, and defaults to ["."]).
58 home_imports <- readIORef import_paths
59 let extendFM fm path = do
60 contents <- getDirectoryContents' path
61 return (addListToFM fm (zip contents (repeat path)))
62 home_map <- foldM extendFM emptyFM home_imports
63 writeIORef homeDirCache home_map
65 -- populate the package cache, if necessary
66 pkg_cache <- readIORef pkgDirCache
70 let extendFM fm pkg = do
71 let dirs = import_dirs pkg
72 pkg_name = _PK_ (name pkg)
73 let addDir fm dir = do
74 contents <- getDirectoryContents' dir
75 return (addListToFM fm (zip contents
76 (repeat (pkg_name,dir))))
79 pkg_map <- foldM extendFM emptyFM pkgs
80 writeIORef pkgDirCache (Just pkg_map)
85 -- and return the finder
89 finder :: ModuleName -> IO (Maybe (Module, ModuleLocation))
91 j <- maybeHomeModule name
93 Just home_module -> return (Just home_module)
94 Nothing -> maybePackageModule name
96 maybeHomeModule :: ModuleName -> IO (Maybe (Module, ModuleLocation))
97 maybeHomeModule mod_name = do
98 home_cache <- readIORef homeDirCache
100 let basename = moduleNameString mod_name
101 hs = basename ++ ".hs"
102 lhs = basename ++ ".lhs"
104 case lookupFM home_cache hs of {
105 Just path -> mkHomeModuleLocn mod_name (path ++ '/':basename) hs;
108 case lookupFM home_cache lhs of {
109 Just path -> mkHomeModuleLocn mod_name (path ++ '/':basename) lhs;
110 Nothing -> return Nothing
114 mkHomeModuleLocn mod_name basename source_fn = do
116 -- figure out the .hi file name: it lives in the same dir as the
117 -- source, unless there's a -ohi flag on the command line.
118 ohi <- readIORef output_hi
119 hisuf <- readIORef hi_suf
120 let hifile = case ohi of
121 Nothing -> basename ++ hisuf
124 -- figure out the .o file name. It also lives in the same dir
125 -- as the source, but can be overriden by a -odir flag.
126 o_file <- odir_ify (basename ++ '.':phaseInputExt Ln)
128 return (Just (mkHomeModule mod_name,
136 maybePackageModule :: ModuleName -> IO (Maybe (Module, ModuleLocation))
137 maybePackageModule mod_name = do
138 maybe_pkg_cache <- readIORef pkgDirCache
139 case maybe_pkg_cache of {
140 Nothing -> panic "maybePackageModule: no pkg_cache";
143 -- hi-suffix for packages depends on the build tag.
145 do tag <- readIORef build_tag
148 else return (tag ++ "_hi")
150 let basename = moduleNameString mod_name
151 hi = basename ++ '.':package_hisuf
153 case lookupFM pkg_cache hi of
154 Nothing -> return Nothing
155 Just (pkg_name,path) ->
156 return (Just (mkModule mod_name pkg_name,
158 hs_file = error "package module; no source",
160 obj_file = error "package module; no object"
166 getDirectoryContents' d
167 = IO.catch (getDirectoryContents d)
168 (\_ -> do hPutStr stderr
169 ("WARNING: error while reading directory " ++ d)