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