2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[RnIfaces]{Cacheing and Renaming of Interfaces}
7 #include "HsVersions.h"
22 import PreludeGlaST ( returnPrimIO, thenPrimIO, seqPrimIO,
23 readVar, writeVar, MutableVar(..)
31 import RnUtils ( RnEnv(..) )
32 import ParseIface ( parseIface, ParsedIface )
34 import Bag ( emptyBag )
35 import CmdLineOpts ( opt_HiSuffix, opt_SysHiSuffix )
36 import ErrUtils ( Error(..), Warning(..) )
37 import FiniteMap ( emptyFM, lookupFM, addToFM )
39 import Maybes ( MaybeErr(..) )
40 import Util ( startsWith, panic )
44 type ModuleToIfaceContents = FiniteMap Module ParsedIface
45 type ModuleToIfaceFilePath = FiniteMap Module FilePath
48 = MutableVar _RealWorld (ModuleToIfaceContents,
49 ModuleToIfaceFilePath)
52 *********************************************************
54 \subsection{Looking for interface files}
56 *********************************************************
58 Return a mapping from module-name to
59 absolute-filename-for-that-interface.
61 findHiFiles :: [FilePath] -> [FilePath] -> IO (FiniteMap Module FilePath)
63 findHiFiles dirs sysdirs
64 = do_dirs emptyFM (dirs ++ sysdirs)
66 do_dirs env [] = return env
67 do_dirs env (dir:dirs)
68 = do_dir env dir >>= \ new_env ->
72 = --trace ("Having a go on..."++dir) $
73 getDirectoryContents dir >>= \ entries ->
74 do_entries env entries
76 do_entries env [] = return env
78 = do_entry env e >>= \ new_env ->
82 = case (acceptable_hi (reverse e)) of
83 Nothing -> --trace ("Deemed uncool:"++e) $
88 case (lookupFM env pmod) of
89 Nothing -> --trace ("Adding "++mod++" -> "++e) $
90 return (addToFM env pmod e)
91 Just xx -> trace ("Already mapped: "++mod++" -> "++xx) $
94 acceptable_hi rev_e -- looking at pathname *backwards*
95 = case (startsWith (reverse opt_HiSuffix) rev_e) of
97 Just xs -> plausible_modname xs{-reversed-}
100 plausible_modname rev_e
102 cand = reverse (takeWhile is_modname_char rev_e)
104 if null cand || not (isUpper (head cand))
108 is_modname_char c = isAlphanum c || c == '_'
111 *********************************************************
113 \subsection{Reading interface files}
115 *********************************************************
117 Return cached info about a Module's interface; otherwise,
118 read the interface (using our @ModuleToIfaceFilePath@ map
119 to decide where to look).
122 cachedIface :: IfaceCache
124 -> IO (MaybeErr ParsedIface Error)
126 cachedIface iface_var mod
127 = readVar iface_var `thenPrimIO` \ (iface_fm, file_fm) ->
129 case (lookupFM iface_fm mod) of
130 Just iface -> return (Succeeded iface)
132 case (lookupFM file_fm mod) of
133 Nothing -> return (Failed (noIfaceErr mod))
135 readIface file mod >>= \ read_iface ->
137 Failed err -> return (Failed err)
140 iface_fm' = addToFM iface_fm mod iface
142 writeVar iface_var (iface_fm', file_fm) `seqPrimIO`
143 return (Succeeded iface)
147 readIface :: FilePath -> Module
148 -> IO (MaybeErr ParsedIface Error)
151 = readFile file `thenPrimIO` \ read_result ->
153 Left err -> return (Failed (cannaeReadErr file))
154 Right contents -> return (Succeeded (parseIface contents))
159 rnIfaces :: IfaceCache -- iface cache
160 -> RnEnv -- original name env
162 -> RenamedHsModule -- module to extend with iface decls
163 -> [RnName] -- imported names required
164 -> PrimIO (RenamedHsModule, -- extended module
165 ImplicitEnv, -- implicit names required
169 rnIfaces iface_var occ_env us rn_module todo
170 = returnPrimIO (rn_module, (emptyFM, emptyFM), emptyBag, emptyBag)
176 IfaceCache -- iface cache
177 -> [RnName] -- all imported names required
178 -> [Module] -- directly imported modules
179 -> PrimIO (VersionInfo, -- info about version numbers
180 [Module]) -- special instance modules
182 type VersionInfo = [(Module, Version, [(FAST_STRING, Version)])]
184 finalIfaceInfo iface_var imps_reqd imp_mods
185 = returnPrimIO ([], [])
191 = ppCat [ppPStr SLIT("Could not find interface for:"), ppPStr mod]
193 cannaeReadErr file sty
194 = ppCat [ppPStr SLIT("Failed in reading file:"), ppStr file]