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