[project @ 2001-11-27 10:03:36 by simonpj]
[ghc-hetmet.git] / ghc / compiler / basicTypes / Module.lhs
index 92d3cee..9b43ed7 100644 (file)
@@ -21,45 +21,60 @@ in a different DLL, by setting the DLL flag.
 \begin{code}
 module Module 
     (
-      Module               -- abstract, instance of Eq, Ord, Outputable
+      Module,                  -- Abstract, instance of Eq, Ord, Outputable
+
+    , PackageName              -- = FastString; instance of Outputable, Uniquable
+    , modulePackage            -- :: Module -> PackageName
+    , preludePackage           -- :: PackageName       name of Standard Prelude package
+
     , ModuleName
-    , ModuleKind(..)
-    , isPackageKind
+    , pprModuleName            -- :: ModuleName -> SDoc
+    , printModulePrefix
 
+    , moduleName               -- :: Module -> ModuleName 
     , moduleNameString         -- :: ModuleName -> EncodedString
     , moduleNameUserString     -- :: ModuleName -> UserString
+    , moduleNameFS             -- :: ModuleName -> EncodedFS
 
-    , moduleString          -- :: Module -> EncodedString
-    , moduleUserString      -- :: Module -> UserString
-    , moduleName           -- :: Module -> ModuleName
+    , moduleString             -- :: Module -> EncodedString
+    , moduleUserString         -- :: Module -> UserString
 
---    , mkVanillaModule            -- :: ModuleName -> Module
---    , mkThisModule       -- :: ModuleName -> Module
---    , mkPrelModule          -- :: UserString -> Module
-    , mkModule             -- :: ModuleName -> ModuleKind -> Module
-    
---    , isLocalModule       -- :: Module -> Bool
+    , mkVanillaModule          -- :: ModuleName -> Module
+    , isVanillaModule          -- :: Module -> Bool
+    , mkPrelModule             -- :: UserString -> Module
+    , isPrelModule             -- :: Module -> Bool
+    , mkModule                 -- :: ModuleName -> PackageName -> Module
+    , mkHomeModule             -- :: ModuleName -> Module
+    , isHomeModule             -- :: Module -> Bool
 
-    , mkSrcModule
+    , mkModuleName             -- :: UserString -> ModuleName
+    , mkModuleNameFS           -- :: UserFS    -> ModuleName
+    , mkSysModuleNameFS                -- :: EncodedFS -> ModuleName
 
-    , mkSrcModuleFS         -- :: UserFS    -> ModuleName
-    , mkSysModuleFS         -- :: EncodedFS -> ModuleName
-
-    , pprModule, pprModuleName
+    , pprModule,
  
-    , PackageName
-
        -- Where to find a .hi file
     , WhereFrom(..)
 
+    , ModuleEnv,
+    , elemModuleEnv, extendModuleEnv, extendModuleEnvList, plusModuleEnv_C
+    , delModuleEnvList, delModuleEnv, plusModuleEnv, lookupModuleEnv
+    , lookupWithDefaultModuleEnv, mapModuleEnv, mkModuleEnv, emptyModuleEnv
+    , moduleEnvElts, unitModuleEnv, isEmptyModuleEnv, foldModuleEnv
+    , lookupModuleEnvByName, extendModuleEnv_C
+
+    , ModuleSet, emptyModuleSet, mkModuleSet, moduleSetElts, extendModuleSet, elemModuleSet
+
     ) where
 
 #include "HsVersions.h"
 import OccName
 import Outputable
 import CmdLineOpts     ( opt_InPackage )
-import FastString      ( FastString, uniqueOfFS )
-import Unique          ( Uniquable(..), mkUniqueGrimily )
+import FastString      ( FastString )
+import Unique          ( Uniquable(..) )
+import UniqFM
+import UniqSet
 \end{code}
 
 
@@ -69,42 +84,46 @@ import Unique               ( Uniquable(..), mkUniqueGrimily )
 %*                                                                     *
 %************************************************************************
 
-A further twist to the tale is the support for dynamically linked libraries under
-Win32. Here, dealing with the use of global variables that's residing in a DLL
-requires special handling at the point of use (there's an extra level of indirection,
-i.e., (**v) to get at v's value, rather than just (*v) .) When slurping in an
-interface file we then record whether it's coming from a .hi corresponding to a
-module that's packaged up in a DLL or not, so that we later can emit the
+A further twist to the tale is the support for dynamically linked
+libraries under Win32. Here, dealing with the use of global variables
+that's residing in a DLL requires special handling at the point of use
+(there's an extra level of indirection, i.e., (**v) to get at v's
+value, rather than just (*v) .) When slurping in an interface file we
+then record whether it's coming from a .hi corresponding to a module
+that's packaged up in a DLL or not, so that we later can emit the
 appropriate code.
 
-The logic for how an interface file is marked as corresponding to a module that's
-hiding in a DLL is explained elsewhere (ToDo: give renamer href here.)
-
-@SourceOnly@ and @ObjectCode@ indicate a module from the same package
-as the one being compiled, i.e. a home module.  @InPackage@ means one
-from a different package.
+The logic for how an interface file is marked as corresponding to a
+module that's hiding in a DLL is explained elsewhere (ToDo: give
+renamer href here.)
 
 \begin{code}
-data ModuleKind
-   = SourceOnly FilePath            -- .hs
-   | ObjectCode FilePath FilePath   -- .o, .hi
-   | InPackage  PackageName
+data Module = Module ModuleName PackageInfo
+
+data PackageInfo
+  = ThisPackage                                -- A module from the same package 
+                                       -- as the one being compiled
+  | AnotherPackage PackageName         -- A module from a different package
 
-isPackageKind (InPackage _) = True
-isPackageKind _             = False
+  | DunnoYet   -- This is used when we don't yet know
+               -- Main case: we've come across Foo.x in an interface file
+               -- but we havn't yet opened Foo.hi.  We need a Name for Foo.x
+               -- Later on (in RnEnv.newTopBinder) we'll update the cache
+               -- to have the right PackageName
 
 type PackageName = FastString          -- No encoding at all
 
 preludePackage :: PackageName
 preludePackage = SLIT("std")
 
-instance Outputable ModuleKind where
-   ppr (SourceOnly path_hs) 
-      = text "SourceOnly" <+> text (show path_hs)
-   ppr (ObjectCode path_o path_hi)
-      = text "ObjectCode" <+> text (show path_o) <+> text (show path_hi)
-   ppr (InPackage pkgname)
-      = text "InPackage" <+> text (show pkgname)
+packageInfoPackage :: PackageInfo -> PackageName
+packageInfoPackage ThisPackage        = opt_InPackage
+packageInfoPackage DunnoYet          = SLIT("<?>")
+packageInfoPackage (AnotherPackage p) = p
+
+instance Outputable PackageInfo where
+       -- Just used in debug prints of lex tokens and in debug modde
+   ppr pkg_info = ppr (packageInfoPackage pkg_info)
 \end{code}
 
 
@@ -122,6 +141,9 @@ data WhereFrom = ImportByUser               -- Ordinary user import: look for M.hi
               | ImportBySystem         -- Non user import.  Look for M.hi if M is in
                                        -- the module this module depends on, or is a system-ish module; 
                                        -- M.hi-boot otherwise
+              | ImportByCmdLine        -- The user typed a qualified name at
+                                       -- the GHCi prompt, try to demand-load
+                                       -- the interface.
 
 instance Outputable WhereFrom where
   ppr ImportByUser       = empty
@@ -137,35 +159,49 @@ instance Outputable WhereFrom where
 %************************************************************************
 
 \begin{code}
-type ModuleName = EncodedFS
+newtype ModuleName = ModuleName EncodedFS
        -- Haskell module names can include the quote character ',
        -- so the module names have the z-encoding applied to them
 
+instance Uniquable ModuleName where
+  getUnique (ModuleName nm) = getUnique nm
+
+instance Eq ModuleName where
+  nm1 == nm2 = getUnique nm1 == getUnique nm2
+
+-- Warning: gives an ordering relation based on the uniques of the
+-- FastStrings which are the (encoded) module names.  This is _not_
+-- a lexicographical ordering.
+instance Ord ModuleName where
+  nm1 `compare` nm2 = getUnique nm1 `compare` getUnique nm2
+
+instance Outputable ModuleName where
+  ppr = pprModuleName
+
+
 pprModuleName :: ModuleName -> SDoc
-pprModuleName nm = pprEncodedFS nm
+pprModuleName (ModuleName nm) = pprEncodedFS nm
+
+moduleNameFS :: ModuleName -> EncodedFS
+moduleNameFS (ModuleName mod) = mod
 
 moduleNameString :: ModuleName -> EncodedString
-moduleNameString mod = _UNPK_ mod
+moduleNameString (ModuleName mod) = _UNPK_ mod
 
 moduleNameUserString :: ModuleName -> UserString
-moduleNameUserString mod = decode (_UNPK_ mod)
+moduleNameUserString (ModuleName mod) = decode (_UNPK_ mod)
 
-mkSrcModule :: UserString -> ModuleName
-mkSrcModule s = _PK_ (encode s)
+-- used to be called mkSrcModule
+mkModuleName :: UserString -> ModuleName
+mkModuleName s = ModuleName (_PK_ (encode s))
 
-mkSrcModuleFS :: UserFS -> ModuleName
-mkSrcModuleFS s = encodeFS s
-
-mkSysModuleFS :: EncodedFS -> ModuleName
-mkSysModuleFS s = s 
-\end{code}
+-- used to be called mkSrcModuleFS
+mkModuleNameFS :: UserFS -> ModuleName
+mkModuleNameFS s = ModuleName (encodeFS s)
 
-\begin{code}
-data Module 
-   = Module {
-        mod_name :: ModuleName,
-        mod_kind :: ModuleKind
-     }
+-- used to be called mkSysModuleFS
+mkSysModuleNameFS :: EncodedFS -> ModuleName
+mkSysModuleNameFS s = ModuleName s 
 \end{code}
 
 \begin{code}
@@ -173,7 +209,7 @@ instance Outputable Module where
   ppr = pprModule
 
 instance Uniquable Module where
-  getUnique (Module nm _) = mkUniqueGrimily (uniqueOfFS nm)
+  getUnique (Module nm _) = getUnique nm
 
 -- Same if they have the same name.
 instance Eq Module where
@@ -199,44 +235,120 @@ pprModule (Module mod p) = getPprStyle $ \ sty ->
 
 
 \begin{code}
-mkModule :: ModuleName -> ModuleKind -> Module
-mkModule = Module
--- I don't think anybody except the Finder should ever try to create a
--- Module now, so this lot commented out pro tem (JRS)
---mkModule :: ModuleName       -- Name of the module
---      -> PackageName
---      -> Module
---mkModule mod_nm pack_name
---  = Module mod_nm pack_info
---  where
---    pack_info | pack_name == opt_InPackage = ThisPackage
---           | otherwise                  = AnotherPackage pack_name
-
-
---mkVanillaModule :: ModuleName -> Module
---mkVanillaModule name = Module name ThisPackage
-       -- Used temporarily when we first come across Foo.x in an interface
-       -- file, but before we've opened Foo.hi.
-       -- (Until we've opened Foo.hi we don't know what the PackageInfo is.)
-
---mkThisModule :: ModuleName -> Module -- The module being compiled
---mkThisModule name = Module name ThisPackage
-
---mkPrelModule :: ModuleName -> Module
---mkPrelModule name = mkModule name preludePackage
+mkModule :: ModuleName -- Name of the module
+        -> PackageName
+        -> Module
+mkModule mod_nm pack_name
+  = Module mod_nm pack_info
+  where
+    pack_info | pack_name == opt_InPackage = ThisPackage
+             | otherwise                  = AnotherPackage pack_name
+
+mkHomeModule :: ModuleName -> Module
+mkHomeModule mod_nm = Module mod_nm ThisPackage
+
+isHomeModule :: Module -> Bool
+isHomeModule (Module nm ThisPackage) = True
+isHomeModule _                       = False
+
+-- Used temporarily when we first come across Foo.x in an interface
+-- file, but before we've opened Foo.hi.
+-- (Until we've opened Foo.hi we don't know what the Package is.)
+mkVanillaModule :: ModuleName -> Module
+mkVanillaModule name = Module name DunnoYet
+
+isVanillaModule :: Module -> Bool
+isVanillaModule (Module nm DunnoYet) = True
+isVanillaModule _                       = False
+
+mkPrelModule :: ModuleName -> Module
+mkPrelModule name = mkModule name preludePackage
+
+isPrelModule :: Module -> Bool
+isPrelModule (Module nm (AnotherPackage p)) | p == preludePackage = True
+isPrelModule _                       = False
 
 moduleString :: Module -> EncodedString
-moduleString (Module mod _) = _UNPK_ mod
+moduleString (Module (ModuleName fs) _) = _UNPK_ fs
 
 moduleName :: Module -> ModuleName
-moduleName (Module mod _) = mod
+moduleName (Module mod pkg_info) = mod
+
+modulePackage :: Module -> PackageName
+modulePackage (Module mod pkg_info) = packageInfoPackage pkg_info
 
 moduleUserString :: Module -> UserString
 moduleUserString (Module mod _) = moduleNameUserString mod
+
+printModulePrefix :: Module -> Bool
+  -- When printing, say M.x
+printModulePrefix (Module nm ThisPackage) = False
+printModulePrefix _                       = True
 \end{code}
 
+
+%************************************************************************
+%*                                                                      *
+\subsection{@ModuleEnv@s}
+%*                                                                      *
+%************************************************************************
+
 \begin{code}
---isLocalModule :: Module -> Bool
---isLocalModule (Module _ ThisPackage) = True
---isLocalModule _                           = False
+type ModuleEnv elt = UniqFM elt
+
+emptyModuleEnv       :: ModuleEnv a
+mkModuleEnv          :: [(Module, a)] -> ModuleEnv a
+unitModuleEnv        :: Module -> a -> ModuleEnv a
+extendModuleEnv      :: ModuleEnv a -> Module -> a -> ModuleEnv a
+extendModuleEnv_C    :: (a->a->a) -> ModuleEnv a -> Module -> a -> ModuleEnv a
+plusModuleEnv        :: ModuleEnv a -> ModuleEnv a -> ModuleEnv a
+extendModuleEnvList  :: ModuleEnv a -> [(Module, a)] -> ModuleEnv a
+                  
+delModuleEnvList     :: ModuleEnv a -> [Module] -> ModuleEnv a
+delModuleEnv         :: ModuleEnv a -> Module -> ModuleEnv a
+plusModuleEnv_C      :: (a -> a -> a) -> ModuleEnv a -> ModuleEnv a -> ModuleEnv a
+mapModuleEnv         :: (a -> b) -> ModuleEnv a -> ModuleEnv b
+moduleEnvElts        :: ModuleEnv a -> [a]
+                  
+isEmptyModuleEnv     :: ModuleEnv a -> Bool
+lookupModuleEnv      :: ModuleEnv a -> Module     -> Maybe a
+lookupModuleEnvByName:: ModuleEnv a -> ModuleName -> Maybe a
+lookupWithDefaultModuleEnv :: ModuleEnv a -> a -> Module -> a
+elemModuleEnv        :: Module -> ModuleEnv a -> Bool
+foldModuleEnv        :: (a -> b -> b) -> b -> ModuleEnv a -> b
+
+elemModuleEnv       = elemUFM
+extendModuleEnv     = addToUFM
+extendModuleEnv_C   = addToUFM_C
+extendModuleEnvList = addListToUFM
+plusModuleEnv_C     = plusUFM_C
+delModuleEnvList    = delListFromUFM
+delModuleEnv        = delFromUFM
+plusModuleEnv       = plusUFM
+lookupModuleEnv     = lookupUFM
+lookupModuleEnvByName = lookupUFM
+lookupWithDefaultModuleEnv = lookupWithDefaultUFM
+mapModuleEnv        = mapUFM
+mkModuleEnv         = listToUFM
+emptyModuleEnv      = emptyUFM
+moduleEnvElts       = eltsUFM
+unitModuleEnv       = unitUFM
+isEmptyModuleEnv    = isNullUFM
+foldModuleEnv       = foldUFM
+\end{code}
+
+\begin{code}
+
+type ModuleSet = UniqSet Module
+mkModuleSet    :: [Module] -> ModuleSet
+extendModuleSet :: ModuleSet -> Module -> ModuleSet
+emptyModuleSet  :: ModuleSet
+moduleSetElts   :: ModuleSet -> [Module]
+elemModuleSet   :: Module -> ModuleSet -> Bool
+
+emptyModuleSet  = emptyUniqSet
+mkModuleSet     = mkUniqSet
+extendModuleSet = addOneToUniqSet
+moduleSetElts   = uniqSetToList
+elemModuleSet   = elementOfUniqSet
 \end{code}