- where
- cache = hsc_FC hsc_env
- dflags = hsc_dflags hsc_env
-
- -- We've found the module, so the remaining question is
- -- whether it's visible or not
- found :: FinderCacheEntry -> FindResult
- found (loc, Nothing)
- | home_allowed = Found loc HomePackage
- | otherwise = NotFound []
- found (loc, Just (pkg, exposed_mod))
- | explicit && not exposed_mod = ModuleHidden pkg_name
- | explicit && not (exposed pkg) = PackageHidden pkg_name
- | otherwise =
- Found loc (ExtPackage (mkPackageId (package pkg)))
- where
- pkg_name = packageConfigId pkg
-
- found_new entry = do
- addToFinderCache cache name entry
- return $! found entry
-
- not_cached
- | not home_allowed = do
- j <- findPackageModule' dflags name
- case j of
- Ok entry -> found_new entry
- MultiplePackages pkgs -> return (FoundMultiple pkgs)
- CantFindAmongst paths -> return (NotFound paths)
-
- | otherwise = do
- j <- findHomeModule' dflags name
- case j of
- Ok entry -> found_new entry
- MultiplePackages pkgs -> return (FoundMultiple pkgs)
- CantFindAmongst home_files -> do
- r <- findPackageModule' dflags name
- case r of
- CantFindAmongst pkg_files ->
- return (NotFound (home_files ++ pkg_files))
- MultiplePackages pkgs ->
- return (FoundMultiple pkgs)
- Ok entry ->
- found_new entry
-
-addHomeModuleToFinder :: HscEnv -> Module -> ModLocation -> IO ()
-addHomeModuleToFinder hsc_env mod loc
- = addToFinderCache (hsc_FC hsc_env) mod (loc, Nothing)
-
-uncacheModule :: HscEnv -> Module -> IO ()
-uncacheModule hsc_env mod = removeFromFinderCache (hsc_FC hsc_env) mod
+ pkg_import = findExposedPackageModule hsc_env mod_name mb_pkg
+
+ unqual_import = home_import
+ `orIfNotFound`
+ findExposedPackageModule hsc_env mod_name Nothing
+
+-- | Locate a specific 'Module'. The purpose of this function is to
+-- create a 'ModLocation' for a given 'Module', that is to find out
+-- where the files associated with this module live. It is used when
+-- reading the interface for a module mentioned by another interface,
+-- for example (a "system import").
+
+findExactModule :: HscEnv -> Module -> IO FindResult
+findExactModule hsc_env mod =
+ let dflags = hsc_dflags hsc_env in
+ if modulePackageId mod == thisPackage dflags
+ then findHomeModule hsc_env (moduleName mod)
+ else findPackageModule hsc_env mod
+
+-- -----------------------------------------------------------------------------
+-- Helpers
+
+orIfNotFound :: IO FindResult -> IO FindResult -> IO FindResult
+orIfNotFound this or_this = do
+ res <- this
+ case res of
+ NotFound { fr_paths = paths1, fr_mods_hidden = mh1
+ , fr_pkgs_hidden = ph1, fr_suggestions = s1 }
+ -> do res2 <- or_this
+ case res2 of
+ NotFound { fr_paths = paths2, fr_pkg = mb_pkg2, fr_mods_hidden = mh2
+ , fr_pkgs_hidden = ph2, fr_suggestions = s2 }
+ -> return (NotFound { fr_paths = paths1 ++ paths2
+ , fr_pkg = mb_pkg2 -- snd arg is the package search
+ , fr_mods_hidden = mh1 ++ mh2
+ , fr_pkgs_hidden = ph1 ++ ph2
+ , fr_suggestions = s1 ++ s2 })
+ _other -> return res2
+ _other -> return res
+
+
+homeSearchCache :: HscEnv -> ModuleName -> IO FindResult -> IO FindResult
+homeSearchCache hsc_env mod_name do_this = do
+ m <- lookupFinderCache (hsc_FC hsc_env) mod_name
+ case m of
+ Just result -> return result
+ Nothing -> do
+ result <- do_this
+ addToFinderCache (hsc_FC hsc_env) mod_name result
+ case result of
+ Found loc mod -> addToModLocationCache (hsc_MLC hsc_env) mod loc
+ _other -> return ()
+ return result
+
+findExposedPackageModule :: HscEnv -> ModuleName -> Maybe FastString
+ -> IO FindResult
+findExposedPackageModule hsc_env mod_name mb_pkg
+ -- not found in any package:
+ = case lookupModuleWithSuggestions (hsc_dflags hsc_env) mod_name of
+ Left suggest -> return (NotFound { fr_paths = [], fr_pkg = Nothing
+ , fr_pkgs_hidden = [], fr_mods_hidden = []
+ , fr_suggestions = suggest })
+ Right found
+ | null found_exposed -- Found, but with no exposed copies
+ -> return (NotFound { fr_paths = [], fr_pkg = Nothing
+ , fr_pkgs_hidden = mod_hiddens, fr_mods_hidden = pkg_hiddens
+ , fr_suggestions = [] })
+
+ | [(pkg_conf,_)] <- found_exposed -- Found uniquely
+ -> let pkgid = packageConfigId pkg_conf in
+ findPackageModule_ hsc_env (mkModule pkgid mod_name) pkg_conf
+
+ | otherwise -- Found in more than one place
+ -> return (FoundMultiple (map (packageConfigId.fst) found_exposed))
+ where
+ for_this_pkg = case mb_pkg of
+ Nothing -> found
+ Just p -> filter ((`matches` p) . fst) found
+ found_exposed = filter is_exposed for_this_pkg
+ is_exposed (pkg_conf,exposed_mod) = exposed pkg_conf && exposed_mod
+
+ mod_hiddens = [ packageConfigId pkg_conf
+ | (pkg_conf,False) <- found ]
+
+ pkg_hiddens = [ packageConfigId pkg_conf
+ | (pkg_conf,_) <- found, not (exposed pkg_conf) ]
+
+ pkg_conf `matches` pkg
+ = case packageName pkg_conf of
+ PackageName n -> pkg == mkFastString n
+
+modLocationCache :: HscEnv -> Module -> IO FindResult -> IO FindResult
+modLocationCache hsc_env mod do_this = do
+ mb_loc <- lookupModLocationCache mlc mod
+ case mb_loc of
+ Just loc -> return (Found loc mod)
+ Nothing -> do
+ result <- do_this
+ case result of
+ Found loc mod -> addToModLocationCache (hsc_MLC hsc_env) mod loc
+ _other -> return ()
+ return result
+ where
+ mlc = hsc_MLC hsc_env
+
+addHomeModuleToFinder :: HscEnv -> ModuleName -> ModLocation -> IO Module
+addHomeModuleToFinder hsc_env mod_name loc = do
+ let mod = mkModule (thisPackage (hsc_dflags hsc_env)) mod_name
+ addToFinderCache (hsc_FC hsc_env) mod_name (Found loc mod)
+ addToModLocationCache (hsc_MLC hsc_env) mod loc
+ return mod
+
+uncacheModule :: HscEnv -> ModuleName -> IO ()
+uncacheModule hsc_env mod = do
+ let this_pkg = thisPackage (hsc_dflags hsc_env)
+ removeFromFinderCache (hsc_FC hsc_env) mod
+ removeFromModLocationCache (hsc_MLC hsc_env) (mkModule this_pkg mod)