[project @ 2000-10-13 16:36:21 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, 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     , moduleNameFS              -- :: ModuleName -> EncodedFS
33
34     , moduleString              -- :: Module -> EncodedString
35     , moduleUserString          -- :: Module -> UserString
36     , moduleName                -- :: Module -> ModuleName
37
38     , mkVanillaModule       -- :: ModuleName -> Module
39 --    , mkThisModule        -- :: ModuleName -> Module
40     , mkPrelModule              -- :: UserString -> Module
41     , mkModule                  -- :: ModuleName -> ModuleKind -> Module
42     , isLocalModule             -- :: Module -> Bool
43
44 --    , mkSrcModule
45
46     , mkModuleName              -- :: UserString -> ModuleName
47     , mkModuleNameFS            -- :: UserFS    -> ModuleName
48     , mkSysModuleNameFS         -- :: EncodedFS -> ModuleName
49
50     , pprModule,
51  
52     , PackageName
53
54         -- Where to find a .hi file
55     , WhereFrom(..)
56
57     , ModuleEnv,
58     , elemModuleEnv, extendModuleEnv, extendModuleEnvList, plusModuleEnv_C
59     , delModuleEnvList, delModuleEnv, plusModuleEnv, lookupModuleEnv
60     , lookupWithDefaultModuleEnv, mapModuleEnv, mkModuleEnv, emptyModuleEnv
61     , rngModuleEnv, unitModuleEnv, isEmptyModuleEnv, foldModuleEnv
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 libraries under
82 Win32. Here, dealing with the use of global variables that's residing in a DLL
83 requires special handling at the point of use (there's an extra level of indirection,
84 i.e., (**v) to get at v's value, rather than just (*v) .) When slurping in an
85 interface file we then record whether it's coming from a .hi corresponding to a
86 module that's packaged up in a DLL or not, so that we later can emit the
87 appropriate code.
88
89 The logic for how an interface file is marked as corresponding to a module that's
90 hiding in a DLL is explained elsewhere (ToDo: give renamer href here.)
91
92 @SourceOnly@ and @ObjectCode@ indicate a module from the same package
93 as the one being compiled, i.e. a home module.  @InPackage@ means one
94 from a different package.
95
96 \begin{code}
97 data Module = Module ModuleName ModuleKind
98
99 data ModuleKind
100    = SourceOnly FilePath            -- .hs
101    | ObjectCode FilePath FilePath   -- .o, .hi
102    | InPackage  PackageName
103
104 moduleName (Module m _) = m
105 moduleKind (Module _ k) = k
106
107 isLocalModuleKind (InPackage _) = False
108 isLocalModuleKind _             = True
109
110 type PackageName = FastString           -- No encoding at all
111
112 preludePackage :: ModuleKind
113 preludePackage = InPackage SLIT("std")
114
115 instance Outputable ModuleKind where
116    ppr (SourceOnly path_hs) 
117       = text "SourceOnly" <+> text (show path_hs)
118    ppr (ObjectCode path_o path_hi)
119       = text "ObjectCode" <+> text (show path_o) <+> text (show path_hi)
120    ppr (InPackage pkgname)
121       = text "InPackage" <+> text (show pkgname)
122 \end{code}
123
124
125 %************************************************************************
126 %*                                                                      *
127 \subsection{Where from}
128 %*                                                                      *
129 %************************************************************************
130
131 The @WhereFrom@ type controls where the renamer looks for an interface file
132
133 \begin{code}
134 data WhereFrom = ImportByUser           -- Ordinary user import: look for M.hi
135                | ImportByUserSource     -- User {- SOURCE -}: look for M.hi-boot
136                | ImportBySystem         -- Non user import.  Look for M.hi if M is in
137                                         -- the module this module depends on, or is a system-ish module; 
138                                         -- M.hi-boot otherwise
139
140 instance Outputable WhereFrom where
141   ppr ImportByUser       = empty
142   ppr ImportByUserSource = ptext SLIT("{- SOURCE -}")
143   ppr ImportBySystem     = ptext SLIT("{- SYSTEM IMPORT -}")
144 \end{code}
145
146
147 %************************************************************************
148 %*                                                                      *
149 \subsection{The name of a module}
150 %*                                                                      *
151 %************************************************************************
152
153 \begin{code}
154 newtype ModuleName = ModuleName EncodedFS
155         -- Haskell module names can include the quote character ',
156         -- so the module names have the z-encoding applied to them
157
158 instance Uniquable ModuleName where
159   getUnique (ModuleName nm) = mkUniqueGrimily (uniqueOfFS nm)
160
161 instance Eq ModuleName where
162   nm1 == nm2 = getUnique nm1 == getUnique nm2
163
164 -- Warning: gives an ordering relation based on the uniques of the
165 -- FastStrings which are the (encoded) module names.  This is _not_
166 -- a lexicographical ordering.
167 instance Ord ModuleName where
168   nm1 `compare` nm2 = getUnique nm1 `compare` getUnique nm2
169
170 instance Outputable ModuleName where
171   ppr = pprModuleName
172
173
174 pprModuleName :: ModuleName -> SDoc
175 pprModuleName (ModuleName nm) = pprEncodedFS nm
176
177 moduleNameFS :: ModuleName -> EncodedFS
178 moduleNameFS (ModuleName mod) = mod
179
180 moduleNameString :: ModuleName -> EncodedString
181 moduleNameString (ModuleName mod) = _UNPK_ mod
182
183 moduleNameUserString :: ModuleName -> UserString
184 moduleNameUserString (ModuleName mod) = decode (_UNPK_ mod)
185
186 -- used to be called mkSrcModule
187 mkModuleName :: UserString -> ModuleName
188 mkModuleName s = ModuleName (_PK_ (encode s))
189
190 -- used to be called mkSrcModuleFS
191 mkModuleNameFS :: UserFS -> ModuleName
192 mkModuleNameFS s = ModuleName (encodeFS s)
193
194 -- used to be called mkSysModuleFS
195 mkSysModuleNameFS :: EncodedFS -> ModuleName
196 mkSysModuleNameFS s = ModuleName s 
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 -> ModuleKind -> Module
231 mkModule = Module
232 -- I don't think anybody except the Finder should ever try to create a
233 -- Module now, so this lot commented out pro tem (JRS)
234 --mkModule :: ModuleName        -- Name of the module
235 --       -> PackageName
236 --       -> Module
237 --mkModule mod_nm pack_name
238 --  = Module mod_nm pack_info
239 --  where
240 --    pack_info | pack_name == opt_InPackage = ThisPackage
241 --            | otherwise                  = AnotherPackage pack_name
242
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 (panic "mkVanillaModule:unknown mod_kind field")
249
250 --mkThisModule :: ModuleName -> Module  -- The module being compiled
251 --mkThisModule name = Module name ThisPackage
252
253 mkPrelModule :: ModuleName -> Module
254 mkPrelModule name = Module name preludePackage
255
256 moduleString :: Module -> EncodedString
257 moduleString (Module (ModuleName fs) _) = _UNPK_ fs
258
259 moduleName :: Module -> ModuleName
260 moduleName (Module mod _) = mod
261
262 moduleUserString :: Module -> UserString
263 moduleUserString (Module mod _) = moduleNameUserString mod
264
265 isLocalModule :: Module -> Bool
266 isLocalModule (Module nm kind) = isLocalModuleKind kind
267 \end{code}
268
269 %************************************************************************
270 %*                                                                      *
271 \subsection{@ModuleEnv@s}
272 %*                                                                      *
273 %************************************************************************
274
275 \begin{code}
276 type ModuleEnv elt = UniqFM elt
277
278 emptyModuleEnv       :: ModuleEnv a
279 mkModuleEnv          :: [(Module, a)] -> ModuleEnv a
280 unitModuleEnv        :: Module -> a -> ModuleEnv a
281 extendModuleEnv      :: ModuleEnv a -> Module -> a -> ModuleEnv a
282 plusModuleEnv        :: ModuleEnv a -> ModuleEnv a -> ModuleEnv a
283 extendModuleEnvList  :: ModuleEnv a -> [(Module, a)] -> ModuleEnv a
284                   
285 delModuleEnvList     :: ModuleEnv a -> [Module] -> ModuleEnv a
286 delModuleEnv         :: ModuleEnv a -> Module -> ModuleEnv a
287 plusModuleEnv_C      :: (a -> a -> a) -> ModuleEnv a -> ModuleEnv a -> ModuleEnv a
288 mapModuleEnv         :: (a -> b) -> ModuleEnv a -> ModuleEnv b
289 rngModuleEnv         :: ModuleEnv a -> [a]
290                   
291 isEmptyModuleEnv     :: ModuleEnv a -> Bool
292 lookupModuleEnv      :: ModuleEnv a -> Module -> Maybe a
293 lookupWithDefaultModuleEnv :: ModuleEnv a -> a -> Module -> a
294 elemModuleEnv        :: Module -> ModuleEnv a -> Bool
295 foldModuleEnv        :: (a -> b -> b) -> b -> ModuleEnv a -> b
296
297 elemModuleEnv       = elemUFM
298 extendModuleEnv     = addToUFM
299 extendModuleEnvList = addListToUFM
300 plusModuleEnv_C     = plusUFM_C
301 delModuleEnvList    = delListFromUFM
302 delModuleEnv        = delFromUFM
303 plusModuleEnv       = plusUFM
304 lookupModuleEnv     = lookupUFM
305 lookupWithDefaultModuleEnv = lookupWithDefaultUFM
306 mapModuleEnv        = mapUFM
307 mkModuleEnv         = listToUFM
308 emptyModuleEnv      = emptyUFM
309 rngModuleEnv        = eltsUFM
310 unitModuleEnv       = unitUFM
311 isEmptyModuleEnv    = isNullUFM
312 foldModuleEnv       = foldUFM
313 \end{code}