[project @ 2000-11-16 11:39:36 by simonmar]
[ghc-hetmet.git] / ghc / compiler / basicTypes / Module.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section[Module]{The @Module@ module.}
5
6 Representing modules and their flavours.
7
8
9 Notes on DLLs
10 ~~~~~~~~~~~~~
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.
17
18
19
20
21 \begin{code}
22 module Module 
23     (
24       Module, moduleName, packageOfModule,
25                             -- abstract, instance of Eq, Ord, Outputable
26     , ModuleName
27     , isModuleInThisPackage, mkModuleInThisPackage,
28     , printModulePrefix
29
30     , moduleNameString          -- :: ModuleName -> EncodedString
31     , moduleNameUserString      -- :: ModuleName -> UserString
32     , moduleNameFS              -- :: ModuleName -> EncodedFS
33
34     , moduleString              -- :: Module -> EncodedString
35     , moduleUserString          -- :: Module -> UserString
36
37     , mkVanillaModule           -- :: ModuleName -> Module
38     , mkPrelModule              -- :: UserString -> Module
39     , mkModule                  -- :: ModuleName -> PackageName -> Module
40     , mkHomeModule              -- :: ModuleName -> Module
41
42 --    , mkSrcModule
43
44     , mkModuleName              -- :: UserString -> ModuleName
45     , mkModuleNameFS            -- :: UserFS    -> ModuleName
46     , mkSysModuleNameFS         -- :: EncodedFS -> ModuleName
47
48     , pprModule,
49  
50     , PackageName
51
52         -- Where to find a .hi file
53     , WhereFrom(..)
54
55     , ModuleEnv,
56     , elemModuleEnv, extendModuleEnv, extendModuleEnvList, plusModuleEnv_C
57     , delModuleEnvList, delModuleEnv, plusModuleEnv, lookupModuleEnv
58     , lookupWithDefaultModuleEnv, mapModuleEnv, mkModuleEnv, emptyModuleEnv
59     , moduleEnvElts, unitModuleEnv, isEmptyModuleEnv, foldModuleEnv
60     , lookupModuleEnvByName, extendModuleEnv_C
61
62     , ModuleSet, emptyModuleSet, mkModuleSet, moduleSetElts, extendModuleSet, elemModuleSet
63
64     ) where
65
66 #include "HsVersions.h"
67 import OccName
68 import Outputable
69 import CmdLineOpts      ( opt_InPackage )
70 import FastString       ( FastString, uniqueOfFS )
71 import Unique           ( Uniquable(..), mkUniqueGrimily )
72 import UniqFM
73 import UniqSet
74 \end{code}
75
76
77 %************************************************************************
78 %*                                                                      *
79 \subsection{Interface file flavour}
80 %*                                                                      *
81 %************************************************************************
82
83 A further twist to the tale is the support for dynamically linked
84 libraries under Win32. Here, dealing with the use of global variables
85 that's residing in a DLL requires special handling at the point of use
86 (there's an extra level of indirection, i.e., (**v) to get at v's
87 value, rather than just (*v) .) When slurping in an interface file we
88 then record whether it's coming from a .hi corresponding to a module
89 that's packaged up in a DLL or not, so that we later can emit the
90 appropriate code.
91
92 The logic for how an interface file is marked as corresponding to a
93 module that's hiding in a DLL is explained elsewhere (ToDo: give
94 renamer href here.)
95
96 \begin{code}
97 data Module = Module ModuleName PackageInfo
98
99 data PackageInfo 
100   = ThisPackage                         -- A module from the same package 
101                                         -- as the one being compiled
102   | AnotherPackage PackageName          -- A module from a different package
103
104   | DunnoYet    -- This is used when we don't yet know
105                 -- Main case: we've come across Foo.x in an interface file
106                 -- but we havn't yet opened Foo.hi.  We need a Name for Foo.x
107                 -- Later on (in RnEnv.newTopBinder) we'll update the cache
108                 -- to have the right PackageInfo
109
110 type PackageName = FastString           -- No encoding at all
111
112 preludePackage :: PackageName
113 preludePackage = SLIT("std")
114
115 instance Outputable PackageInfo where
116         -- Just used in debug prints of lex tokens and in debug modde
117    ppr ThisPackage        = ptext SLIT("<THIS>")
118    ppr DunnoYet           = ptext SLIT("<?>")
119    ppr (AnotherPackage p) = ptext p
120 \end{code}
121
122
123 %************************************************************************
124 %*                                                                      *
125 \subsection{Where from}
126 %*                                                                      *
127 %************************************************************************
128
129 The @WhereFrom@ type controls where the renamer looks for an interface file
130
131 \begin{code}
132 data WhereFrom = ImportByUser           -- Ordinary user import: look for M.hi
133                | ImportByUserSource     -- User {- SOURCE -}: look for M.hi-boot
134                | ImportBySystem         -- Non user import.  Look for M.hi if M is in
135                                         -- the module this module depends on, or is a system-ish module; 
136                                         -- M.hi-boot otherwise
137
138 instance Outputable WhereFrom where
139   ppr ImportByUser       = empty
140   ppr ImportByUserSource = ptext SLIT("{- SOURCE -}")
141   ppr ImportBySystem     = ptext SLIT("{- SYSTEM IMPORT -}")
142 \end{code}
143
144
145 %************************************************************************
146 %*                                                                      *
147 \subsection{The name of a module}
148 %*                                                                      *
149 %************************************************************************
150
151 \begin{code}
152 newtype ModuleName = ModuleName EncodedFS
153         -- Haskell module names can include the quote character ',
154         -- so the module names have the z-encoding applied to them
155
156 instance Uniquable ModuleName where
157   getUnique (ModuleName nm) = mkUniqueGrimily (uniqueOfFS nm)
158
159 instance Eq ModuleName where
160   nm1 == nm2 = getUnique nm1 == getUnique nm2
161
162 -- Warning: gives an ordering relation based on the uniques of the
163 -- FastStrings which are the (encoded) module names.  This is _not_
164 -- a lexicographical ordering.
165 instance Ord ModuleName where
166   nm1 `compare` nm2 = getUnique nm1 `compare` getUnique nm2
167
168 instance Outputable ModuleName where
169   ppr = pprModuleName
170
171
172 pprModuleName :: ModuleName -> SDoc
173 pprModuleName (ModuleName nm) = pprEncodedFS nm
174
175 moduleNameFS :: ModuleName -> EncodedFS
176 moduleNameFS (ModuleName mod) = mod
177
178 moduleNameString :: ModuleName -> EncodedString
179 moduleNameString (ModuleName mod) = _UNPK_ mod
180
181 moduleNameUserString :: ModuleName -> UserString
182 moduleNameUserString (ModuleName mod) = decode (_UNPK_ mod)
183
184 -- used to be called mkSrcModule
185 mkModuleName :: UserString -> ModuleName
186 mkModuleName s = ModuleName (_PK_ (encode s))
187
188 -- used to be called mkSrcModuleFS
189 mkModuleNameFS :: UserFS -> ModuleName
190 mkModuleNameFS s = ModuleName (encodeFS s)
191
192 -- used to be called mkSysModuleFS
193 mkSysModuleNameFS :: EncodedFS -> ModuleName
194 mkSysModuleNameFS s = ModuleName s 
195
196 -- Make a module in this package
197 mkModuleInThisPackage :: ModuleName -> Module
198 mkModuleInThisPackage nm = Module nm ThisPackage
199 \end{code}
200
201 \begin{code}
202 instance Outputable Module where
203   ppr = pprModule
204
205 instance Uniquable Module where
206   getUnique (Module nm _) = getUnique nm
207
208 -- Same if they have the same name.
209 instance Eq Module where
210   m1 == m2 = getUnique m1 == getUnique m2
211
212 -- Warning: gives an ordering relation based on the uniques of the
213 -- FastStrings which are the (encoded) module names.  This is _not_
214 -- a lexicographical ordering.
215 instance Ord Module where
216   m1 `compare` m2 = getUnique m1 `compare` getUnique m2
217 \end{code}
218
219
220 \begin{code}
221 pprModule :: Module -> SDoc
222 pprModule (Module mod p) = getPprStyle $ \ sty ->
223                            if debugStyle sty then
224                                 -- Print the package too
225                                 ppr p <> dot <> pprModuleName mod
226                            else
227                                 pprModuleName mod
228 \end{code}
229
230
231 \begin{code}
232 mkModule :: ModuleName  -- Name of the module
233          -> PackageName
234          -> Module
235 mkModule mod_nm pack_name
236   = Module mod_nm pack_info
237   where
238     pack_info | pack_name == opt_InPackage = ThisPackage
239               | otherwise                  = AnotherPackage pack_name
240
241 mkHomeModule :: ModuleName -> Module
242 mkHomeModule mod_nm = Module mod_nm ThisPackage
243
244 -- Used temporarily when we first come across Foo.x in an interface
245 -- file, but before we've opened Foo.hi.
246 -- (Until we've opened Foo.hi we don't know what the PackageInfo is.)
247 mkVanillaModule :: ModuleName -> Module
248 mkVanillaModule name = Module name DunnoYet
249
250 mkPrelModule :: ModuleName -> Module
251 mkPrelModule name = mkModule name preludePackage
252
253 moduleString :: Module -> EncodedString
254 moduleString (Module (ModuleName fs) _) = _UNPK_ fs
255
256 moduleName :: Module -> ModuleName
257 moduleName (Module mod pkg_info) = mod
258
259 moduleUserString :: Module -> UserString
260 moduleUserString (Module mod _) = moduleNameUserString mod
261
262 isModuleInThisPackage :: Module -> Bool
263 isModuleInThisPackage (Module nm ThisPackage) = True
264 isModuleInThisPackage _                       = False
265
266 packageOfModule :: Module -> Maybe PackageName
267 packageOfModule (Module nm (AnotherPackage pn)) = Just pn
268 packageOfModule _                               = Nothing
269
270 printModulePrefix :: Module -> Bool
271   -- When printing, say M.x
272 printModulePrefix (Module nm ThisPackage) = False
273 printModulePrefix _                       = True
274 \end{code}
275
276
277 %************************************************************************
278 %*                                                                      *
279 \subsection{@ModuleEnv@s}
280 %*                                                                      *
281 %************************************************************************
282
283 \begin{code}
284 type ModuleEnv elt = UniqFM elt
285
286 emptyModuleEnv       :: ModuleEnv a
287 mkModuleEnv          :: [(Module, a)] -> ModuleEnv a
288 unitModuleEnv        :: Module -> a -> ModuleEnv a
289 extendModuleEnv      :: ModuleEnv a -> Module -> a -> ModuleEnv a
290 extendModuleEnv_C    :: (a->a->a) -> ModuleEnv a -> Module -> a -> ModuleEnv a
291 plusModuleEnv        :: ModuleEnv a -> ModuleEnv a -> ModuleEnv a
292 extendModuleEnvList  :: ModuleEnv a -> [(Module, a)] -> ModuleEnv a
293                   
294 delModuleEnvList     :: ModuleEnv a -> [Module] -> ModuleEnv a
295 delModuleEnv         :: ModuleEnv a -> Module -> ModuleEnv a
296 plusModuleEnv_C      :: (a -> a -> a) -> ModuleEnv a -> ModuleEnv a -> ModuleEnv a
297 mapModuleEnv         :: (a -> b) -> ModuleEnv a -> ModuleEnv b
298 moduleEnvElts        :: ModuleEnv a -> [a]
299                   
300 isEmptyModuleEnv     :: ModuleEnv a -> Bool
301 lookupModuleEnv      :: ModuleEnv a -> Module     -> Maybe a
302 lookupModuleEnvByName:: ModuleEnv a -> ModuleName -> Maybe a
303 lookupWithDefaultModuleEnv :: ModuleEnv a -> a -> Module -> a
304 elemModuleEnv        :: Module -> ModuleEnv a -> Bool
305 foldModuleEnv        :: (a -> b -> b) -> b -> ModuleEnv a -> b
306
307 elemModuleEnv       = elemUFM
308 extendModuleEnv     = addToUFM
309 extendModuleEnv_C   = addToUFM_C
310 extendModuleEnvList = addListToUFM
311 plusModuleEnv_C     = plusUFM_C
312 delModuleEnvList    = delListFromUFM
313 delModuleEnv        = delFromUFM
314 plusModuleEnv       = plusUFM
315 lookupModuleEnv     = lookupUFM
316 lookupModuleEnvByName = lookupUFM
317 lookupWithDefaultModuleEnv = lookupWithDefaultUFM
318 mapModuleEnv        = mapUFM
319 mkModuleEnv         = listToUFM
320 emptyModuleEnv      = emptyUFM
321 moduleEnvElts       = eltsUFM
322 unitModuleEnv       = unitUFM
323 isEmptyModuleEnv    = isNullUFM
324 foldModuleEnv       = foldUFM
325 \end{code}
326
327 \begin{code}
328
329 type ModuleSet = UniqSet Module
330 mkModuleSet     :: [Module] -> ModuleSet
331 extendModuleSet :: ModuleSet -> Module -> ModuleSet
332 emptyModuleSet  :: ModuleSet
333 moduleSetElts   :: ModuleSet -> [Module]
334 elemModuleSet   :: Module -> ModuleSet -> Bool
335
336 emptyModuleSet  = emptyUniqSet
337 mkModuleSet     = mkUniqSet
338 extendModuleSet = addOneToUniqSet
339 moduleSetElts   = uniqSetToList
340 elemModuleSet   = elementOfUniqSet
341 \end{code}