- let mod_str = moduleNameUserString mod_name
- basename = map (\c -> if c == '.' then '/' else c) mod_str
- hs = basename ++ ".hs"
- lhs = basename ++ ".lhs"
-
- found <- findOnPath home_path hs
- case found of {
- -- special case to avoid getting "./foo.hs" all the time
- Just "." -> mkHomeModuleLocn mod_name basename (Just hs);
- Just path -> mkHomeModuleLocn mod_name
- (path ++ '/':basename) (Just (path ++ '/':hs));
- Nothing -> do
-
- found <- findOnPath home_path lhs
- case found of {
- -- special case to avoid getting "./foo.hs" all the time
- Just "." -> mkHomeModuleLocn mod_name basename (Just lhs);
- Just path -> mkHomeModuleLocn mod_name
- (path ++ '/':basename) (Just (path ++ '/':lhs));
- Nothing -> do
-
- -- can't find a source file anywhere, check for a lone .hi file.
- hisuf <- readIORef v_Hi_suf
- let hi = basename ++ '.':hisuf
- found <- findOnPath home_path hi
- case found of {
- Just path -> mkHiOnlyModuleLocn mod_name hi;
- Nothing -> do
-
- -- last chance: .hi-boot-<ver> and .hi-boot
- let hi_boot = basename ++ ".hi-boot"
- let hi_boot_ver = basename ++ ".hi-boot-" ++ cHscIfaceFileVersion
- found <- findOnPath home_path hi_boot_ver
- case found of {
- Just path -> mkHiOnlyModuleLocn mod_name hi;
- Nothing -> do
- found <- findOnPath home_path hi_boot
- case found of {
- Just path -> mkHiOnlyModuleLocn mod_name hi;
- Nothing -> return Nothing
- }}}}}
-
-
-mkHiOnlyModuleLocn mod_name hi_file = do
- return (Just (mkHomeModule mod_name,
- ModuleLocation{
- ml_hspp_file = Nothing,
- ml_hs_file = Nothing,
- ml_hi_file = hi_file,
- ml_obj_file = Nothing
- }
- ))
+ searchPathExts home_path mod_name exts
+
+-- -----------------------------------------------------------------------------
+-- Looking for a package module
+
+findPackageMod :: ModuleName -> IO (Either [FilePath] (Module, ModLocation))
+findPackageMod mod_name = do
+ mode <- readIORef v_GhcMode
+ imp_dirs <- getPackageImportPath -- including the 'auto' ones
+
+ -- hi-suffix for packages depends on the build tag.
+ package_hisuf <-
+ do tag <- readIORef v_Build_tag
+ if null tag
+ then return "hi"
+ else return (tag ++ "_hi")
+
+ let
+ hi_exts =
+ [ (package_hisuf, mkPackageModLocation package_hisuf mod_name) ]
+
+ source_exts =
+ [ ("hs", mkPackageModLocation package_hisuf mod_name)
+ , ("lhs", mkPackageModLocation package_hisuf mod_name)
+ ]
+
+ -- mkdependHS needs to look for source files in packages too, so
+ -- that we can make dependencies between package before they have
+ -- been built.
+ exts
+ | mode == DoMkDependHS = hi_exts ++ source_exts
+ | otherwise = hi_exts
+
+ -- we never look for a .hi-boot file in an external package;
+ -- .hi-boot files only make sense for the home package.
+ searchPathExts imp_dirs mod_name exts
+
+-- -----------------------------------------------------------------------------
+-- General path searching
+
+searchPathExts
+ :: [FilePath] -- paths to search
+ -> ModuleName -- module name
+ -> [ (
+ String, -- suffix
+ String -> String -> String -> IO (Module, ModLocation) -- action
+ )
+ ]
+ -> IO (Either [FilePath] (Module, ModLocation))
+
+searchPathExts path mod_name exts = search to_search
+ where
+ mod_str = moduleNameUserString mod_name
+ basename = map (\c -> if c == '.' then '/' else c) mod_str
+
+ to_search :: [(FilePath, IO (Module,ModLocation))]
+ to_search = [ (file, fn p basename ext)
+ | p <- path,
+ (ext,fn) <- exts,
+ let base | p == "." = basename
+ | otherwise = p ++ '/':basename
+ file = base ++ '.':ext
+ ]
+
+ search [] = return (Left (map fst to_search))
+ search ((file, result) : rest) = do
+ b <- doesFileExist file
+ if b
+ then Right `liftM` result
+ else search rest
+
+-- -----------------------------------------------------------------------------
+-- Building ModLocations
+
+mkHiOnlyModLocation hisuf mod_name path basename extension = do
+ loc <- hiOnlyModLocation path basename hisuf
+ let result = (mkHomeModule mod_name, loc)
+ addToFinderCache mod_name result
+ return result
+
+mkPackageModLocation hisuf mod_name path basename _extension = do
+ loc <- hiOnlyModLocation path basename hisuf
+ let result = (mkPackageModule mod_name, loc)
+ addToFinderCache mod_name result
+ return result
+
+hiOnlyModLocation path basename hisuf
+ = do { obj_fn <- mkObjPath path basename ;
+ return (ModLocation{ ml_hspp_file = Nothing,
+ ml_hs_file = Nothing,
+ ml_hi_file = path ++ '/':basename ++ '.':hisuf,
+ -- Remove the .hi-boot suffix from
+ -- hi_file, if it had one. We always
+ -- want the name of the real .hi file
+ -- in the ml_hi_file field.
+ ml_obj_file = obj_fn
+ })}
+
+-- -----------------------------------------------------------------------------
+-- Constructing a home module location