2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[Module]{The @Module@ module.}
6 Representing modules and their flavours.
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.
24 Module -- abstract, instance of Eq, Ord, Outputable
27 , moduleNameString -- :: ModuleName -> EncodedString
28 , moduleNameUserString -- :: ModuleName -> UserString
30 , moduleString -- :: Module -> EncodedString
31 , moduleUserString -- :: Module -> UserString
32 , moduleName -- :: Module -> ModuleName
34 , mkVanillaModule -- :: ModuleName -> Module
35 , mkThisModule -- :: ModuleName -> Module
36 , mkPrelModule -- :: UserString -> Module
37 , mkModule -- :: ModuleName -> PackageName -> Module
39 , isLocalModule -- :: Module -> Bool
43 , mkSrcModuleFS -- :: UserFS -> ModuleName
44 , mkSysModuleFS -- :: EncodedFS -> ModuleName
46 , pprModule, pprModuleName
50 -- Where to find a .hi file
51 , WhereFrom(..), SearchPath, mkSearchPath
52 , ModuleHiMap, mkModuleHiMaps
56 #include "HsVersions.h"
60 import CmdLineOpts ( opt_Static, opt_InPackage, opt_WarnHiShadows, opt_HiMapSep )
61 import Constants ( interfaceFileFormatVersion )
62 import Maybes ( seqMaybe )
63 import Maybe ( fromMaybe )
64 import Directory ( doesFileExist )
65 import DirUtils ( getDirectoryContents )
66 import List ( intersperse )
67 import Monad ( foldM )
68 import IO ( hPutStrLn, stderr, isDoesNotExistError )
69 import FastString ( FastString )
73 %************************************************************************
75 \subsection{Interface file flavour}
77 %************************************************************************
79 A further twist to the tale is the support for dynamically linked libraries under
80 Win32. Here, dealing with the use of global variables that's residing in a DLL
81 requires special handling at the point of use (there's an extra level of indirection,
82 i.e., (**v) to get at v's value, rather than just (*v) .) When slurping in an
83 interface file we then record whether it's coming from a .hi corresponding to a
84 module that's packaged up in a DLL or not, so that we later can emit the
87 The logic for how an interface file is marked as corresponding to a module that's
88 hiding in a DLL is explained elsewhere (ToDo: give renamer href here.)
91 data PackageInfo = ThisPackage -- A module from the same package
92 -- as the one being compiled
93 | AnotherPackage PackageName -- A module from a different package
95 type PackageName = FastString -- No encoding at all
97 preludePackage :: PackageName
98 preludePackage = SLIT("std")
100 instance Show PackageInfo where -- Just used in debug prints of lex tokens
101 -- and in debug modde
102 showsPrec n ThisPackage s = "<THIS>" ++ s
103 showsPrec n (AnotherPackage p) s = (_UNPK_ p) ++ s
107 %************************************************************************
109 \subsection{Where from}
111 %************************************************************************
113 The @WhereFrom@ type controls where the renamer looks for an interface file
116 data WhereFrom = ImportByUser -- Ordinary user import: look for M.hi
117 | ImportByUserSource -- User {- SOURCE -}: look for M.hi-boot
118 | ImportBySystem -- Non user import. Look for M.hi if M is in
119 -- the module this module depends on, or is a system-ish module;
120 -- M.hi-boot otherwise
122 instance Outputable WhereFrom where
123 ppr ImportByUser = empty
124 ppr ImportByUserSource = ptext SLIT("{- SOURCE -}")
125 ppr ImportBySystem = ptext SLIT("{- SYSTEM IMPORT -}")
129 %************************************************************************
131 \subsection{The name of a module}
133 %************************************************************************
136 type ModuleName = EncodedFS
137 -- Haskell module names can include the quote character ',
138 -- so the module names have the z-encoding applied to them
140 pprModuleName :: ModuleName -> SDoc
141 pprModuleName nm = pprEncodedFS nm
143 moduleNameString :: ModuleName -> EncodedString
144 moduleNameString mod = _UNPK_ mod
146 moduleNameUserString :: ModuleName -> UserString
147 moduleNameUserString mod = decode (_UNPK_ mod)
149 mkSrcModule :: UserString -> ModuleName
150 mkSrcModule s = _PK_ (encode s)
152 mkSrcModuleFS :: UserFS -> ModuleName
153 mkSrcModuleFS s = encodeFS s
155 mkSysModuleFS :: EncodedFS -> ModuleName
160 data Module = Module ModuleName PackageInfo
164 instance Outputable Module where
167 instance Eq Module where
168 (Module m1 _) == (Module m2 _) = m1 == m2
170 instance Ord Module where
171 (Module m1 _) `compare` (Module m2 _) = m1 `compare` m2
176 pprModule :: Module -> SDoc
177 pprModule (Module mod p) = getPprStyle $ \ sty ->
178 if debugStyle sty then
179 -- Print the package too
180 text (show p) <> dot <> pprModuleName mod
187 mkModule :: ModuleName -- Name of the module
190 mkModule mod_nm pack_name
191 = Module mod_nm pack_info
193 pack_info | pack_name == opt_InPackage = ThisPackage
194 | otherwise = AnotherPackage pack_name
197 mkVanillaModule :: ModuleName -> Module
198 mkVanillaModule name = Module name ThisPackage
199 -- Used temporarily when we first come across Foo.x in an interface
200 -- file, but before we've opened Foo.hi.
201 -- (Until we've opened Foo.hi we don't know what the PackageInfo is.)
203 mkThisModule :: ModuleName -> Module -- The module being compiled
204 mkThisModule name = Module name ThisPackage
206 mkPrelModule :: ModuleName -> Module
207 mkPrelModule name = mkModule name preludePackage
209 moduleString :: Module -> EncodedString
210 moduleString (Module mod _) = _UNPK_ mod
212 moduleName :: Module -> ModuleName
213 moduleName (Module mod _) = mod
215 moduleUserString :: Module -> UserString
216 moduleUserString (Module mod _) = moduleNameUserString mod
220 isLocalModule :: Module -> Bool
221 isLocalModule (Module _ ThisPackage) = True
222 isLocalModule _ = False
226 %************************************************************************
228 \subsection{Finding modules in the file system
230 %************************************************************************
233 type ModuleHiMap = FiniteMap ModuleName String
234 -- Mapping from module name to
235 -- * the file path of its corresponding interface file,
239 (We allege that) it is quicker to build up a mapping from module names
240 to the paths to their corresponding interface files once, than to search
241 along the import part every time we slurp in a new module (which we
245 type SearchPath = [(String,String)] -- List of (directory,suffix) pairs to search
246 -- for interface files.
248 mkModuleHiMaps :: SearchPath -> IO (SearchPath, ModuleHiMap, ModuleHiMap)
249 mkModuleHiMaps dirs = do (hi,hi_boot) <- foldM (getAllFilesMatching dirs) (env,env) dirs
250 return (dirs, hi, hi_boot)
254 getAllFilesMatching :: SearchPath
255 -> (ModuleHiMap, ModuleHiMap)
256 -> (FilePath, String)
257 -> IO (ModuleHiMap, ModuleHiMap)
258 getAllFilesMatching dirs hims (dir_path, suffix) = ( do
259 -- fpaths entries do not have dir_path prepended
260 fpaths <- getDirectoryContents dir_path
261 return (foldl addModules hims fpaths))
266 ("Import path element `" ++ dir_path ++
267 if (isDoesNotExistError err) then
268 "' does not exist, ignoring."
270 "' couldn't read, ignoring.")
275 xiffus = reverse dotted_suffix
276 dotted_suffix = case suffix of
281 hi_boot_version_xiffus =
282 reverse (show interfaceFileFormatVersion) ++ '-':hi_boot_xiffus
283 hi_boot_xiffus = "toob-ih." -- .hi-boot reversed!
285 addModules his@(hi_env, hib_env) filename = fromMaybe his $
286 FMAP add_hi (go xiffus rev_fname) `seqMaybe`
288 FMAP add_vhib (go hi_boot_version_xiffus rev_fname) `seqMaybe`
289 -- If there's a Foo.hi-boot-N file then override any Foo.hi-boot
291 FMAP add_hib (go hi_boot_xiffus rev_fname)
293 rev_fname = reverse filename
294 path = dir_path ++ '/':filename
296 -- In these functions file_nm is the base of the filename,
297 -- with the path and suffix both stripped off. The filename
298 -- is the *unencoded* module name (else 'make' gets confused).
299 -- But the domain of the HiMaps is ModuleName which is encoded.
300 add_hi file_nm = (add_to_map addNewOne hi_env file_nm, hib_env)
301 add_vhib file_nm = (hi_env, add_to_map overrideNew hib_env file_nm)
302 add_hib file_nm = (hi_env, add_to_map addNewOne hib_env file_nm)
304 add_to_map combiner env file_nm
305 = addToFM_C combiner env mod_nm path
307 mod_nm = mkSrcModuleFS file_nm
309 -- go prefix (prefix ++ stuff) == Just (reverse stuff)
310 go [] xs = Just (_PK_ (reverse xs))
312 go (x:xs) (y:ys) | x == y = go xs ys
313 | otherwise = Nothing
315 addNewOne | opt_WarnHiShadows = conflict
316 | otherwise = stickWithOld
318 stickWithOld old new = old
319 overrideNew old new = new
321 conflict old_path new_path
322 | old_path /= new_path =
323 pprTrace "Warning: " (text "Identically named interface files present on the import path, " $$
324 text (show old_path) <+> text "shadows" $$
325 text (show new_path) $$
326 text "on the import path: " <+>
327 text (concat (intersperse ":" (map fst dirs))))
329 | otherwise = old_path -- don't warn about innocous shadowings.
333 %*********************************************************
335 \subsection{Making a search path}
337 %*********************************************************
339 @mkSearchPath@ takes a string consisting of a colon-separated list
340 of directories and corresponding suffixes, and turns it into a list
341 of (directory, suffix) pairs. For example:
344 mkSearchPath "foo%.hi:.%.p_hi:baz%.mc_hi"
345 = [("foo",".hi"),( ".", ".p_hi"), ("baz",".mc_hi")]
349 mkSearchPath :: Maybe String -> SearchPath
350 mkSearchPath Nothing = [(".",".hi")] -- ToDo: default should be to look in
351 -- the directory the module we're compiling
353 mkSearchPath (Just s) = go s
357 case span (/= '%') s of
359 case span (/= opt_HiMapSep) rs of
360 (hisuf,_:rest) -> (dir,hisuf):go rest
361 (hisuf,[]) -> [(dir,hisuf)]