\begin{code}
module MkIface (
- mkFinalIface,
- pprModDetails, pprIface, pprUsage,
+ showIface, mkFinalIface,
+ pprModDetails, pprIface, pprUsage, pprUsages, pprExports,
ifaceTyThing,
) where
import HsCore ( HsIdInfo(..), UfExpr(..), toUfExpr, toUfBndr )
import HsTypes ( toHsTyVars )
import TysPrim ( alphaTyVars )
-import BasicTypes ( Fixity(..), NewOrData(..), Activation(..),
+import BasicTypes ( NewOrData(..), Activation(..),
Version, initialVersion, bumpVersion
)
import NewDemand ( isTopSig )
import RnMonad
import RnHsSyn ( RenamedInstDecl, RenamedTyClDecl )
import HscTypes ( VersionInfo(..), ModIface(..), ModDetails(..),
- ModuleLocation(..), GhciMode(..),
+ ModuleLocation(..), GhciMode(..),
+ FixityEnv, lookupFixity, collectFixities,
IfaceDecls, mkIfaceDecls, dcl_tycl, dcl_rules, dcl_insts,
- TyThing(..), DFunId, Avails, TypeEnv,
+ TyThing(..), DFunId, TypeEnv,
+ GenAvailInfo,
WhatsImported(..), GenAvailInfo(..),
- ImportVersion, AvailInfo, Deprecations(..),
+ ImportVersion, Deprecations(..),
lookupVersion, typeEnvIds
)
import CoreSyn ( CoreRule(..), IdCoreRule )
import CoreFVs ( ruleLhsFreeNames )
import CoreUnfold ( neverUnfold, unfoldingTemplate )
-import PprCore ( pprIdCoreRule )
-import Name ( getName, nameModule, toRdrName, isGlobalName,
+import PprCore ( pprIdRules )
+import Name ( getName, toRdrName, isExternalName,
nameIsLocalOrFrom, Name, NamedThing(..) )
import NameEnv
import NameSet
import OccName ( pprOccName )
-import TyCon ( TyCon, getSynTyConDefn, isSynTyCon, isNewTyCon,
- isAlgTyCon, tyConGenIds, tyConTheta, tyConTyVars,
- tyConDataCons, tyConFamilySize, isPrimTyCon,
- isClassTyCon, isForeignTyCon, tyConArity
- )
+import TyCon
import Class ( classExtraBigSig, classTyCon, DefMeth(..) )
import FieldLabel ( fieldLabelType )
import TcType ( tcSplitSigmaTy, tidyTopType, deNoteType, namesOfDFunHead )
import Outputable
import Module ( ModuleName )
import Util ( sortLt, dropList )
+import Binary ( getBinFileWithDict )
+import BinIface ( writeBinIface )
import ErrUtils ( dumpIfSet_dyn )
import Monad ( when )
import Maybe ( catMaybes )
-import IO ( IOMode(..), openFile, hClose )
+import IO ( putStrLn )
\end{code}
%************************************************************************
%* *
+\subsection{Print out the contents of a binary interface}
+%* *
+%************************************************************************
+
+\begin{code}
+showIface :: FilePath -> IO ()
+showIface filename = do
+ parsed_iface <- Binary.getBinFileWithDict filename
+ let ParsedIface{
+ pi_mod=pi_mod, pi_pkg=pi_pkg, pi_vers=pi_vers,
+ pi_orphan=pi_orphan, pi_usages=pi_usages,
+ pi_exports=pi_exports, pi_decls=pi_decls,
+ pi_fixity=pi_fixity, pi_insts=pi_insts,
+ pi_rules=pi_rules, pi_deprecs=pi_deprecs } = parsed_iface
+ putStrLn (showSDoc (vcat [
+ text "__interface" <+> doubleQuotes (ppr pi_pkg)
+ <+> ppr pi_mod <+> ppr pi_vers
+ <+> (if pi_orphan then char '!' else empty)
+ <+> ptext SLIT("where"),
+ -- no instance Outputable (WhatsImported):
+ pprExports id (snd pi_exports),
+ pprUsages id pi_usages,
+ hsep (map ppr_fix pi_fixity) <> semi,
+ vcat (map ppr_inst pi_insts),
+ vcat (map ppr_decl pi_decls),
+ ppr pi_rules
+ -- no instance Outputable (Either):
+ -- ppr pi_deprecs
+ ]))
+ where
+ ppr_fix (n,f) = ppr f <+> ppr n
+ ppr_inst i = ppr i <+> semi
+ ppr_decl (v,d) = int v <+> ppr d <> semi
+\end{code}
+
+%************************************************************************
+%* *
\subsection{Completing an interface}
%* *
%************************************************************************
-- Write the interface file, if necessary
; when (must_write_hi_file maybe_diffs)
- (writeIface hi_file_path final_iface)
+ (writeBinIface hi_file_path final_iface)
+-- (writeIface hi_file_path final_iface)
-- Debug printing
; write_diffs dflags final_iface maybe_diffs
isOrphanModule this_mod (ModDetails {md_insts = insts, md_rules = rules})
= any orphan_inst insts || any orphan_rule rules
where
+ -- A rule is an orphan if the LHS mentions nothing defined locally
orphan_inst dfun_id = no_locals (namesOfDFunHead (idType dfun_id))
+ -- A instance is an orphan if its head mentions nothing defined locally
orphan_rule rule = no_locals (ruleLhsFreeNames rule)
+
no_locals names = isEmptyNameSet (filterNameSet (nameIsLocalOrFrom this_mod) names)
\end{code}
tcdCtxt = toHsContext (tyConTheta tycon),
tcdName = getName tycon,
tcdTyVars = toHsTyVars tyvars,
- tcdCons = map ifaceConDecl (tyConDataCons tycon),
- tcdNCons = tyConFamilySize tycon,
+ tcdCons = ifaceConDecls (tyConDataConDetails tycon),
tcdDerivs = Nothing,
tcdSysNames = map getName (tyConGenIds tycon),
tcdLoc = noSrcLoc }
tcdFoType = DNType, -- The only case at present
tcdLoc = noSrcLoc }
- | isPrimTyCon tycon
+ | isPrimTyCon tycon || isFunTyCon tycon
-- needed in GHCi for ':info Int#', for example
= TyData { tcdND = DataType,
tcdCtxt = [],
tcdName = getName tycon,
tcdTyVars = toHsTyVars (take (tyConArity tycon) alphaTyVars),
- tcdCons = [],
- tcdNCons = 0,
+ tcdCons = Unknown,
tcdDerivs = Nothing,
tcdSysNames = [],
tcdLoc = noSrcLoc }
new_or_data | isNewTyCon tycon = NewType
| otherwise = DataType
+ ifaceConDecls Unknown = Unknown
+ ifaceConDecls (HasCons n) = HasCons n
+ ifaceConDecls (DataCons cs) = DataCons (map ifaceConDecl cs)
+
ifaceConDecl data_con
= ConDecl (getName data_con) (getName (dataConId data_con))
(toHsTyVars ex_tyvars)
pp_change False what = text what <+> ptext SLIT("changed")
diffDecls :: VersionInfo -- Old version
- -> NameEnv Fixity -> NameEnv Fixity -- Old and new fixities
+ -> FixityEnv -> FixityEnv -- Old and new fixities
-> [RenamedTyClDecl] -> [RenamedTyClDecl] -- Old and new decls
-> (Bool, -- True <=> no change
SDoc, -- Record of differences
-- When seeing if two decls are the same,
-- remember to check whether any relevant fixity has changed
eq_tc d1 d2 = d1 == d2 && all (same_fixity . fst) (tyClDeclNames d1)
- same_fixity n = lookupNameEnv old_fixities n == lookupNameEnv new_fixities n
+ same_fixity n = lookupFixity old_fixities n == lookupFixity new_fixities n
diff ok_so_far pp new_vers [] [] = (ok_so_far, pp, new_vers)
diff ok_so_far pp new_vers (od:ods) [] = diff False (pp $$ only_old od) new_vers ods []
ids = [id | id <- typeEnvIds type_env, want_sig id]
want_sig id | opt_PprStyle_Debug = True
| otherwise = isLocalId id &&
- isGlobalName (idName id) &&
+ isExternalName (idName id) &&
not (id `elem` dfun_ids)
-- isLocalId ignores data constructors, records selectors etc
- -- The isGlobalName ignores local dictionary and method bindings
+ -- The isExternalName ignores local dictionary and method bindings
-- that the type checker has invented. User-defined things have
-- Global names.
dump_rules :: [IdCoreRule] -> SDoc
dump_rules [] = empty
dump_rules rs = vcat [ptext SLIT("{-# RULES"),
- nest 4 (vcat (map pprIdCoreRule rs)),
+ nest 4 (pprIdRules rs),
ptext SLIT("#-}")]
\end{code}
%************************************************************************
\begin{code}
-writeIface :: FilePath -> ModIface -> IO ()
-writeIface hi_path mod_iface
- = do { if_hdl <- openFile hi_path WriteMode
- ; printForIface if_hdl from_this_mod (pprIface mod_iface)
- ; hClose if_hdl
- }
- where
- -- Print names unqualified if they are from this module
- from_this_mod n = nameModule n == this_mod
- this_mod = mi_module mod_iface
-
pprIface :: ModIface -> SDoc
pprIface iface
= vcat [ ptext SLIT("__interface")
- <+> doubleQuotes (ptext opt_InPackage)
+ <+> doubleQuotes (ptext (mi_package iface))
<+> ppr (mi_module iface) <+> ppr (vers_module version_info)
<+> pp_sub_vers
<+> (if mi_orphan iface then char '!' else empty)
<+> int opt_HiVersion
<+> ptext SLIT("where")
- , vcat (map pprExport (mi_exports iface))
- , vcat (map pprUsage (mi_usages iface))
+ , pprExports nameOccName (mi_exports iface)
+ , pprUsages nameOccName (mi_usages iface)
, pprFixities (mi_fixities iface) (dcl_tycl decls)
, pprIfaceDecls (vers_decls version_info) decls
version_info = mi_version iface
decls = mi_decls iface
exp_vers = vers_exports version_info
+
rule_vers = vers_rules version_info
pp_sub_vers | exp_vers == initialVersion && rule_vers == initialVersion = empty
AvailTC C [x, y] C!(x,y) -- Exporting x, y but not C
\begin{code}
-pprExport :: (ModuleName, Avails) -> SDoc
-pprExport (mod, items)
+pprExports :: Eq a => (a -> OccName) -> [(ModuleName, [GenAvailInfo a])] -> SDoc
+pprExports getOcc exports = vcat (map (pprExport getOcc) exports)
+
+pprExport :: Eq a => (a -> OccName) -> (ModuleName, [GenAvailInfo a]) -> SDoc
+pprExport getOcc (mod, items)
= hsep [ ptext SLIT("__export "), ppr mod, hsep (map pp_avail items) ] <> semi
where
- pp_avail :: AvailInfo -> SDoc
- pp_avail (Avail name) = pprOcc name
+ --pp_avail :: GenAvailInfo a -> SDoc
+ pp_avail (Avail name) = ppr (getOcc name)
pp_avail (AvailTC _ []) = empty
- pp_avail (AvailTC n (n':ns)) | n==n' = pprOcc n <> pp_export ns
- | otherwise = pprOcc n <> char '|' <> pp_export (n':ns)
+ pp_avail (AvailTC n (n':ns))
+ | n==n' = ppr (getOcc n) <> pp_export ns
+ | otherwise = ppr (getOcc n) <> char '|' <> pp_export (n':ns)
pp_export [] = empty
- pp_export names = braces (hsep (map pprOcc names))
+ pp_export names = braces (hsep (map (ppr.getOcc) names))
pprOcc :: Name -> SDoc -- Print the occurrence name only
pprOcc n = pprOccName (nameOccName n)
\begin{code}
-pprUsage :: ImportVersion Name -> SDoc
-pprUsage (m, has_orphans, is_boot, whats_imported)
+pprUsages :: (a -> OccName) -> [ImportVersion a] -> SDoc
+pprUsages getOcc usages = vcat (map (pprUsage getOcc) usages)
+
+pprUsage :: (a -> OccName) -> ImportVersion a -> SDoc
+pprUsage getOcc (m, has_orphans, is_boot, whats_imported)
= hsep [ptext SLIT("import"), ppr m,
pp_orphan, pp_boot,
pp_versions whats_imported
-- Importing the whole module is indicated by an empty list
pp_versions NothingAtAll = empty
pp_versions (Everything v) = dcolon <+> int v
- pp_versions (Specifically vm ve nvs vr) = dcolon <+> int vm <+> pp_export_version ve <+> int vr
- <+> hsep [ pprOcc n <+> int v | (n,v) <- nvs ]
+ pp_versions (Specifically vm ve nvs vr) =
+ dcolon <+> int vm <+> pp_export_version ve <+> int vr
+ <+> hsep [ ppr (getOcc n) <+> int v | (n,v) <- nvs ]
pp_export_version Nothing = empty
pp_export_version (Just v) = int v
\end{code}
\begin{code}
-pprFixities :: (Outputable a)
- => NameEnv a
+pprFixities :: NameEnv Fixity
-> [TyClDecl Name pat]
-> SDoc
pprFixities fixity_map decls
= hsep [ ppr fix <+> ppr n
- | d <- decls,
- (n,_) <- tyClDeclNames d,
- Just fix <- [lookupNameEnv fixity_map n]] <> semi
+ | (n,fix) <- collectFixities fixity_map decls ] <> semi
-- Disgusting to print these two together, but that's
-- the way the interface parser currently expects them.