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