2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[Module]{The @Module@ module.}
6 Representing modules and their flavours.
11 When compiling module A, which imports module B, we need to
12 know whether B will be in the same DLL as A.
13 If it's in the same DLL, we refer to B_f_closure
14 If it isn't, we refer to _imp__B_f_closure
15 When compiling A, we record in B's Module value whether it's
16 in a different DLL, by setting the DLL flag.
25 -- abstract, instance of Eq, Ord, Outputable
27 , isModuleInThisPackage, mkModuleInThisPackage,
30 , moduleNameString -- :: ModuleName -> EncodedString
31 , moduleNameUserString -- :: ModuleName -> UserString
32 , moduleNameFS -- :: ModuleName -> EncodedFS
34 , moduleString -- :: Module -> EncodedString
35 , moduleUserString -- :: Module -> UserString
36 , moduleName -- :: Module -> ModuleName
38 , mkVanillaModule -- :: ModuleName -> Module
39 , mkPrelModule -- :: UserString -> Module
40 , mkModule -- :: ModuleName -> PackageName -> Module
41 , mkHomeModule -- :: ModuleName -> Module
45 , mkModuleName -- :: UserString -> ModuleName
46 , mkModuleNameFS -- :: UserFS -> ModuleName
47 , mkSysModuleNameFS -- :: EncodedFS -> ModuleName
53 -- Where to find a .hi file
57 , elemModuleEnv, extendModuleEnv, extendModuleEnvList, plusModuleEnv_C
58 , delModuleEnvList, delModuleEnv, plusModuleEnv, lookupModuleEnv
59 , lookupWithDefaultModuleEnv, mapModuleEnv, mkModuleEnv, emptyModuleEnv
60 , moduleEnvElts, unitModuleEnv, isEmptyModuleEnv, foldModuleEnv
61 , lookupModuleEnvByName, extendModuleEnv_C
63 , ModuleSet, emptyModuleSet, mkModuleSet, moduleSetElts, extendModuleSet, elemModuleSet
67 #include "HsVersions.h"
70 import CmdLineOpts ( opt_InPackage )
71 import FastString ( FastString, uniqueOfFS )
72 import Unique ( Uniquable(..), mkUniqueGrimily )
78 %************************************************************************
80 \subsection{Interface file flavour}
82 %************************************************************************
84 A further twist to the tale is the support for dynamically linked
85 libraries under Win32. Here, dealing with the use of global variables
86 that's residing in a DLL requires special handling at the point of use
87 (there's an extra level of indirection, i.e., (**v) to get at v's
88 value, rather than just (*v) .) When slurping in an interface file we
89 then record whether it's coming from a .hi corresponding to a module
90 that's packaged up in a DLL or not, so that we later can emit the
93 The logic for how an interface file is marked as corresponding to a
94 module that's hiding in a DLL is explained elsewhere (ToDo: give
98 data Module = Module ModuleName PackageInfo
101 = ThisPackage -- A module from the same package
102 -- as the one being compiled
103 | AnotherPackage PackageName -- A module from a different package
105 | DunnoYet -- This is used when we don't yet know
106 -- Main case: we've come across Foo.x in an interface file
107 -- but we havn't yet opened Foo.hi. We need a Name for Foo.x
108 -- Later on (in RnEnv.newTopBinder) we'll update the cache
109 -- to have the right PackageInfo
111 type PackageName = FastString -- No encoding at all
113 preludePackage :: PackageName
114 preludePackage = SLIT("std")
116 instance Outputable PackageInfo where
117 -- Just used in debug prints of lex tokens and in debug modde
118 ppr ThisPackage = ptext SLIT("<THIS>")
119 ppr DunnoYet = ptext SLIT("<?>")
120 ppr (AnotherPackage p) = ptext p
124 %************************************************************************
126 \subsection{Where from}
128 %************************************************************************
130 The @WhereFrom@ type controls where the renamer looks for an interface file
133 data WhereFrom = ImportByUser -- Ordinary user import: look for M.hi
134 | ImportByUserSource -- User {- SOURCE -}: look for M.hi-boot
135 | ImportBySystem -- Non user import. Look for M.hi if M is in
136 -- the module this module depends on, or is a system-ish module;
137 -- M.hi-boot otherwise
139 instance Outputable WhereFrom where
140 ppr ImportByUser = empty
141 ppr ImportByUserSource = ptext SLIT("{- SOURCE -}")
142 ppr ImportBySystem = ptext SLIT("{- SYSTEM IMPORT -}")
146 %************************************************************************
148 \subsection{The name of a module}
150 %************************************************************************
153 newtype ModuleName = ModuleName EncodedFS
154 -- Haskell module names can include the quote character ',
155 -- so the module names have the z-encoding applied to them
157 instance Uniquable ModuleName where
158 getUnique (ModuleName nm) = mkUniqueGrimily (uniqueOfFS nm)
160 instance Eq ModuleName where
161 nm1 == nm2 = getUnique nm1 == getUnique nm2
163 -- Warning: gives an ordering relation based on the uniques of the
164 -- FastStrings which are the (encoded) module names. This is _not_
165 -- a lexicographical ordering.
166 instance Ord ModuleName where
167 nm1 `compare` nm2 = getUnique nm1 `compare` getUnique nm2
169 instance Outputable ModuleName where
173 pprModuleName :: ModuleName -> SDoc
174 pprModuleName (ModuleName nm) = pprEncodedFS nm
176 moduleNameFS :: ModuleName -> EncodedFS
177 moduleNameFS (ModuleName mod) = mod
179 moduleNameString :: ModuleName -> EncodedString
180 moduleNameString (ModuleName mod) = _UNPK_ mod
182 moduleNameUserString :: ModuleName -> UserString
183 moduleNameUserString (ModuleName mod) = decode (_UNPK_ mod)
185 -- used to be called mkSrcModule
186 mkModuleName :: UserString -> ModuleName
187 mkModuleName s = ModuleName (_PK_ (encode s))
189 -- used to be called mkSrcModuleFS
190 mkModuleNameFS :: UserFS -> ModuleName
191 mkModuleNameFS s = ModuleName (encodeFS s)
193 -- used to be called mkSysModuleFS
194 mkSysModuleNameFS :: EncodedFS -> ModuleName
195 mkSysModuleNameFS s = ModuleName s
197 -- Make a module in this package
198 mkModuleInThisPackage :: ModuleName -> Module
199 mkModuleInThisPackage nm = Module nm ThisPackage
203 instance Outputable Module where
206 instance Uniquable Module where
207 getUnique (Module nm _) = getUnique nm
209 -- Same if they have the same name.
210 instance Eq Module where
211 m1 == m2 = getUnique m1 == getUnique m2
213 -- Warning: gives an ordering relation based on the uniques of the
214 -- FastStrings which are the (encoded) module names. This is _not_
215 -- a lexicographical ordering.
216 instance Ord Module where
217 m1 `compare` m2 = getUnique m1 `compare` getUnique m2
222 pprModule :: Module -> SDoc
223 pprModule (Module mod p) = getPprStyle $ \ sty ->
224 if debugStyle sty then
225 -- Print the package too
226 ppr p <> dot <> pprModuleName mod
233 mkModule :: ModuleName -- Name of the module
236 mkModule mod_nm pack_name
237 = Module mod_nm pack_info
239 pack_info | pack_name == opt_InPackage = ThisPackage
240 | otherwise = AnotherPackage pack_name
242 mkHomeModule :: ModuleName -> Module
243 mkHomeModule mod_nm = Module mod_nm ThisPackage
245 -- Used temporarily when we first come across Foo.x in an interface
246 -- file, but before we've opened Foo.hi.
247 -- (Until we've opened Foo.hi we don't know what the PackageInfo is.)
248 mkVanillaModule :: ModuleName -> Module
249 mkVanillaModule name = Module name DunnoYet
251 mkPrelModule :: ModuleName -> Module
252 mkPrelModule name = mkModule name preludePackage
254 moduleString :: Module -> EncodedString
255 moduleString (Module (ModuleName fs) _) = _UNPK_ fs
257 moduleName :: Module -> ModuleName
258 moduleName (Module mod _) = mod
260 moduleUserString :: Module -> UserString
261 moduleUserString (Module mod _) = moduleNameUserString mod
263 isModuleInThisPackage :: Module -> Bool
264 isModuleInThisPackage (Module nm ThisPackage) = True
265 isModuleInThisPackage _ = False
267 printModulePrefix :: Module -> Bool
268 -- When printing, say M.x
269 printModulePrefix (Module nm ThisPackage) = False
270 printModulePrefix _ = True
274 %************************************************************************
276 \subsection{@ModuleEnv@s}
278 %************************************************************************
281 type ModuleEnv elt = UniqFM elt
283 emptyModuleEnv :: ModuleEnv a
284 mkModuleEnv :: [(Module, a)] -> ModuleEnv a
285 unitModuleEnv :: Module -> a -> ModuleEnv a
286 extendModuleEnv :: ModuleEnv a -> Module -> a -> ModuleEnv a
287 extendModuleEnv_C :: (a->a->a) -> ModuleEnv a -> Module -> a -> ModuleEnv a
288 plusModuleEnv :: ModuleEnv a -> ModuleEnv a -> ModuleEnv a
289 extendModuleEnvList :: ModuleEnv a -> [(Module, a)] -> ModuleEnv a
291 delModuleEnvList :: ModuleEnv a -> [Module] -> ModuleEnv a
292 delModuleEnv :: ModuleEnv a -> Module -> ModuleEnv a
293 plusModuleEnv_C :: (a -> a -> a) -> ModuleEnv a -> ModuleEnv a -> ModuleEnv a
294 mapModuleEnv :: (a -> b) -> ModuleEnv a -> ModuleEnv b
295 moduleEnvElts :: ModuleEnv a -> [a]
297 isEmptyModuleEnv :: ModuleEnv a -> Bool
298 lookupModuleEnv :: ModuleEnv a -> Module -> Maybe a
299 lookupModuleEnvByName:: ModuleEnv a -> ModuleName -> Maybe a
300 lookupWithDefaultModuleEnv :: ModuleEnv a -> a -> Module -> a
301 elemModuleEnv :: Module -> ModuleEnv a -> Bool
302 foldModuleEnv :: (a -> b -> b) -> b -> ModuleEnv a -> b
304 elemModuleEnv = elemUFM
305 extendModuleEnv = addToUFM
306 extendModuleEnv_C = addToUFM_C
307 extendModuleEnvList = addListToUFM
308 plusModuleEnv_C = plusUFM_C
309 delModuleEnvList = delListFromUFM
310 delModuleEnv = delFromUFM
311 plusModuleEnv = plusUFM
312 lookupModuleEnv = lookupUFM
313 lookupModuleEnvByName = lookupUFM
314 lookupWithDefaultModuleEnv = lookupWithDefaultUFM
315 mapModuleEnv = mapUFM
316 mkModuleEnv = listToUFM
317 emptyModuleEnv = emptyUFM
318 moduleEnvElts = eltsUFM
319 unitModuleEnv = unitUFM
320 isEmptyModuleEnv = isNullUFM
321 foldModuleEnv = foldUFM
326 type ModuleSet = UniqSet Module
327 mkModuleSet :: [Module] -> ModuleSet
328 extendModuleSet :: ModuleSet -> Module -> ModuleSet
329 emptyModuleSet :: ModuleSet
330 moduleSetElts :: ModuleSet -> [Module]
331 elemModuleSet :: Module -> ModuleSet -> Bool
333 emptyModuleSet = emptyUniqSet
334 mkModuleSet = mkUniqSet
335 extendModuleSet = addOneToUniqSet
336 moduleSetElts = uniqSetToList
337 elemModuleSet = elementOfUniqSet