[project @ 2000-10-11 14:08:23 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                -- abstract, instance of Eq, Ord, Outputable
25     , ModuleName
26
27     , moduleNameString          -- :: ModuleName -> EncodedString
28     , moduleNameUserString      -- :: ModuleName -> UserString
29
30     , moduleString          -- :: Module -> EncodedString
31     , moduleUserString      -- :: Module -> UserString
32     , moduleName            -- :: Module -> ModuleName
33
34     , mkVanillaModule       -- :: ModuleName -> Module
35     , mkThisModule          -- :: ModuleName -> Module
36     , mkPrelModule          -- :: UserString -> Module
37     , mkModule              -- :: ModuleName -> PackageName -> Module
38     
39     , isLocalModule       -- :: Module -> Bool
40
41     , mkSrcModule
42
43     , mkSrcModuleFS         -- :: UserFS    -> ModuleName
44     , mkSysModuleFS         -- :: EncodedFS -> ModuleName
45
46     , pprModule, pprModuleName
47  
48     , PackageName
49
50         -- Where to find a .hi file
51     , WhereFrom(..)
52
53     ) where
54
55 #include "HsVersions.h"
56 import OccName
57 import Outputable
58 import CmdLineOpts      ( opt_InPackage )
59 import FastString       ( FastString )
60 \end{code}
61
62
63 %************************************************************************
64 %*                                                                      *
65 \subsection{Interface file flavour}
66 %*                                                                      *
67 %************************************************************************
68
69 A further twist to the tale is the support for dynamically linked libraries under
70 Win32. Here, dealing with the use of global variables that's residing in a DLL
71 requires special handling at the point of use (there's an extra level of indirection,
72 i.e., (**v) to get at v's value, rather than just (*v) .) When slurping in an
73 interface file we then record whether it's coming from a .hi corresponding to a
74 module that's packaged up in a DLL or not, so that we later can emit the
75 appropriate code.
76
77 The logic for how an interface file is marked as corresponding to a module that's
78 hiding in a DLL is explained elsewhere (ToDo: give renamer href here.)
79
80 \begin{code}
81 data PackageInfo = ThisPackage                  -- A module from the same package 
82                                                 -- as the one being compiled
83                  | AnotherPackage PackageName   -- A module from a different package
84
85 type PackageName = FastString           -- No encoding at all
86
87 preludePackage :: PackageName
88 preludePackage = SLIT("std")
89
90 instance Show PackageInfo where -- Just used in debug prints of lex tokens
91                                 -- and in debug modde
92   showsPrec n ThisPackage        s = "<THIS>"   ++ s
93   showsPrec n (AnotherPackage p) s = (_UNPK_ p) ++ s
94 \end{code}
95
96
97 %************************************************************************
98 %*                                                                      *
99 \subsection{Where from}
100 %*                                                                      *
101 %************************************************************************
102
103 The @WhereFrom@ type controls where the renamer looks for an interface file
104
105 \begin{code}
106 data WhereFrom = ImportByUser           -- Ordinary user import: look for M.hi
107                | ImportByUserSource     -- User {- SOURCE -}: look for M.hi-boot
108                | ImportBySystem         -- Non user import.  Look for M.hi if M is in
109                                         -- the module this module depends on, or is a system-ish module; 
110                                         -- M.hi-boot otherwise
111
112 instance Outputable WhereFrom where
113   ppr ImportByUser       = empty
114   ppr ImportByUserSource = ptext SLIT("{- SOURCE -}")
115   ppr ImportBySystem     = ptext SLIT("{- SYSTEM IMPORT -}")
116 \end{code}
117
118
119 %************************************************************************
120 %*                                                                      *
121 \subsection{The name of a module}
122 %*                                                                      *
123 %************************************************************************
124
125 \begin{code}
126 type ModuleName = EncodedFS
127         -- Haskell module names can include the quote character ',
128         -- so the module names have the z-encoding applied to them
129
130 pprModuleName :: ModuleName -> SDoc
131 pprModuleName nm = pprEncodedFS nm
132
133 moduleNameString :: ModuleName -> EncodedString
134 moduleNameString mod = _UNPK_ mod
135
136 moduleNameUserString :: ModuleName -> UserString
137 moduleNameUserString mod = decode (_UNPK_ mod)
138
139 mkSrcModule :: UserString -> ModuleName
140 mkSrcModule s = _PK_ (encode s)
141
142 mkSrcModuleFS :: UserFS -> ModuleName
143 mkSrcModuleFS s = encodeFS s
144
145 mkSysModuleFS :: EncodedFS -> ModuleName
146 mkSysModuleFS s = s 
147 \end{code}
148
149 \begin{code}
150 data Module = Module ModuleName PackageInfo
151 \end{code}
152
153 \begin{code}
154 instance Outputable Module where
155   ppr = pprModule
156
157 instance Eq Module where
158   (Module m1 _) == (Module m2 _) = m1 == m2
159
160 instance Ord Module where
161   (Module m1 _) `compare` (Module m2 _) = m1 `compare` m2
162 \end{code}
163
164
165 \begin{code}
166 pprModule :: Module -> SDoc
167 pprModule (Module mod p) = getPprStyle $ \ sty ->
168                            if debugStyle sty then
169                                 -- Print the package too
170                                 text (show p) <> dot <> pprModuleName mod
171                            else
172                                 pprModuleName mod
173 \end{code}
174
175
176 \begin{code}
177 mkModule :: ModuleName  -- Name of the module
178          -> PackageName
179          -> Module
180 mkModule mod_nm pack_name
181   = Module mod_nm pack_info
182   where
183     pack_info | pack_name == opt_InPackage = ThisPackage
184               | otherwise                  = AnotherPackage pack_name
185
186
187 mkVanillaModule :: ModuleName -> Module
188 mkVanillaModule name = Module name ThisPackage
189         -- Used temporarily when we first come across Foo.x in an interface
190         -- file, but before we've opened Foo.hi.
191         -- (Until we've opened Foo.hi we don't know what the PackageInfo is.)
192
193 mkThisModule :: ModuleName -> Module    -- The module being compiled
194 mkThisModule name = Module name ThisPackage
195
196 mkPrelModule :: ModuleName -> Module
197 mkPrelModule name = mkModule name preludePackage
198
199 moduleString :: Module -> EncodedString
200 moduleString (Module mod _) = _UNPK_ mod
201
202 moduleName :: Module -> ModuleName
203 moduleName (Module mod _) = mod
204
205 moduleUserString :: Module -> UserString
206 moduleUserString (Module mod _) = moduleNameUserString mod
207 \end{code}
208
209 \begin{code}
210 isLocalModule :: Module -> Bool
211 isLocalModule (Module _ ThisPackage) = True
212 isLocalModule _                      = False
213 \end{code}