2 % (c) The University of Glasgow, 2000
4 \section[Finder]{Module Finder}
8 initFinder, -- :: [PackageConfig] -> IO (),
9 findModule, -- :: ModuleName -> IO (Maybe (Module, ModuleLocation))
10 findModuleDep, -- :: ModuleName -> Bool -> IO (Maybe (Module, ModuleLocation))
11 findPackageModule, -- :: ModuleName -> IO (Maybe (Module, ModuleLocation))
12 mkHomeModuleLocn, -- :: ModuleName -> String -> FilePath
13 -- -> IO ModuleLocation
14 emptyHomeDirCache, -- :: IO ()
15 flushPackageCache -- :: [PackageConfig] -> IO ()
18 #include "HsVersions.h"
20 import HscTypes ( ModuleLocation(..) )
21 import Packages ( PackageConfig(..) )
36 The Finder provides a thin filesystem abstraction to the rest of the
37 compiler. For a given module, it knows (a) whether the module lives
38 in the home package or in another package, so it can make a Module
39 from a ModuleName, and (b) where the source, interface, and object
40 files for a module live.
42 It does *not* know which particular package a module lives in, because
43 that information is only contained in the interface file.
46 initFinder :: [PackageConfig] -> IO ()
47 initFinder pkgs = return ()
49 -- empty, and lazilly fill in the package cache
50 flushPackageCache :: [PackageConfig] -> IO ()
51 flushPackageCache pkgs = return ()
53 emptyHomeDirCache :: IO ()
54 emptyHomeDirCache = return ()
56 findModule :: ModuleName -> IO (Maybe (Module, ModuleLocation))
57 findModule name = findModuleDep name False
59 findModuleDep :: ModuleName -> Bool -> IO (Maybe (Module, ModuleLocation))
60 findModuleDep name is_source
61 = do { j <- maybeHomeModule name is_source
63 Just home_module -> return (Just home_module)
64 Nothing -> findPackageMod name False
67 maybeHomeModule :: ModuleName -> Bool -> IO (Maybe (Module, ModuleLocation))
68 maybeHomeModule mod_name is_source = do
69 home_path <- readIORef v_Import_paths
70 hisuf <- readIORef v_Hi_suf
71 mode <- readIORef v_GhcMode
73 let mod_str = moduleNameUserString mod_name
74 basename = map (\c -> if c == '.' then '/' else c) mod_str
76 -- In compilation manager modes, we look for source files in the home
77 -- package because we can compile these automatically. In one-shot
78 -- compilation mode we look for .hi files only.
80 -- When generating dependencies, we're interested in either category.
83 [ ("hs", \ fName path -> mkHomeModuleLocn mod_name path fName)
84 , ("lhs", \ fName path -> mkHomeModuleLocn mod_name path fName)
86 hi_exts = [ (hisuf, \ fName path -> mkHiOnlyModuleLocn mod_name fName) ]
89 | mode == DoMkDependHS = hi_exts ++ source_exts
90 | isCompManagerMode mode = source_exts
93 -- last chance: .hi-boot-<ver> and .hi-boot
94 hi_boot_ver = "hi-boot-" ++ cHscIfaceFileVersion
97 [ (hi_boot_ver, \ fName path -> mkHiOnlyModuleLocn mod_name fName)
98 , ("hi-boot", \ fName path -> mkHiOnlyModuleLocn mod_name fName)
101 searchPathExts home_path basename
102 (if is_source then (boot_exts++std_exts) else std_exts ++ boot_exts)
103 -- for SOURCE imports, check the hi-boot extensions
104 -- before the source/iface ones, to avoid
105 -- creating circ Makefile deps.
107 mkHiOnlyModuleLocn mod_name hi_file =
109 ( mkHomeModule mod_name
110 , ModuleLocation{ ml_hspp_file = Nothing
111 , ml_hs_file = Nothing
112 , ml_hi_file = hi_file
113 , ml_obj_file = Nothing
117 -- The .hi file always follows the module name, whereas the object
118 -- file may follow the name of the source file in the case where the
119 -- two differ (see summariseFile in compMan/CompManager.lhs).
121 mkHomeModuleLocn mod_name
122 basename -- everything but the extension
123 source_fn -- full path to the source (required)
126 hisuf <- readIORef v_Hi_suf
127 hidir <- readIORef v_Hi_dir
129 -- take the *last* component of the module name (if a hierarchical name),
130 -- and append it to the directory to get the .hi file name.
131 let (_,mod_str) = split_longest_prefix (moduleNameUserString mod_name) (=='.')
132 hi_filename = mod_str ++ '.':hisuf
133 hi_path | Just d <- hidir = d
134 | otherwise = getdir basename
135 hi = hi_path ++ '/':hi_filename
137 -- figure out the .o file name. It also lives in the same dir
138 -- as the source, but can be overriden by a -odir flag.
139 o_file <- odir_ify (basename ++ '.':phaseInputExt Ln) >>= osuf_ify
141 return (mkHomeModule mod_name,
142 ModuleLocation{ ml_hspp_file = Nothing
143 , ml_hs_file = Just source_fn
145 , ml_obj_file = Just o_file
148 findPackageMod :: ModuleName
150 -> IO (Maybe (Module, ModuleLocation))
151 findPackageMod mod_name hiOnly = do
152 pkgs <- getPackageInfo
154 -- hi-suffix for packages depends on the build tag.
156 do tag <- readIORef v_Build_tag
159 else return (tag ++ "_hi")
160 let imp_dirs = concatMap import_dirs pkgs
161 mod_str = moduleNameUserString mod_name
162 basename = map (\c -> if c == '.' then '/' else c) mod_str
164 retPackageModule mod_name mbFName path =
165 return ( mkPackageModule mod_name
166 , ModuleLocation{ ml_hspp_file = Nothing
167 , ml_hs_file = mbFName
168 , ml_hi_file = path ++ '.':package_hisuf
169 , ml_obj_file = Nothing
174 ((package_hisuf,\ fName path -> retPackageModule mod_name Nothing path) :
175 -- can packages contain hi-boots?
176 (if hiOnly then [] else
177 [ ("hs", \ fName path -> retPackageModule mod_name (Just fName) path)
178 , ("lhs", \ fName path -> retPackageModule mod_name (Just fName) path)
182 findPackageModule :: ModuleName -> IO (Maybe (Module, ModuleLocation))
183 findPackageModule mod_name = findPackageMod mod_name True
185 searchPathExts :: [FilePath]
187 -> [(String, FilePath -> String -> IO (Module, ModuleLocation))]
188 -> IO (Maybe (Module, ModuleLocation))
189 searchPathExts path basename exts = search path
191 search [] = return Nothing
192 search (p:ps) = loop exts
194 base | p == "." = basename
195 | otherwise = p ++ '/':basename
198 loop ((ext,fn):exts) = do
199 let file = base ++ '.':ext
200 b <- doesFileExist file
201 if b then Just `liftM` fn file base