-- -- Copyright (C) 2004 Don Stewart - http://www.cse.unsw.edu.au/~dons -- -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public -- License as published by the Free Software Foundation; either -- version 2.1 of the License, or (at your option) any later version. -- -- This library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public -- License along with this library; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -- USA -- -- Based on code from $fptools/ghc/compiler/main/HscTypes.lhs -- (c) The University of Glasgow 2002 -- module Language.Hi.Syntax where import Language.Hi.FastString import Data.List ( intersperse ) -- --------------------------------------------------------------------- -- An Iface, the representation of an .hi file. -- -- The abstract syntax that we don't need is blanked with a default -- type, however we must be careful in BinIface to still parse the -- correct number of bytes for each data type. This involves leaving the -- code alone, other than to add the types of the sub-constructors of -- the types we have blanked out (because they can't be inferred -- anymore). -- data Iface = Iface { mi_package :: String, -- what package is this? mi_module :: String, -- what module is this? mi_deps :: Dependencies, mi_usages :: [Usage], mi_exports :: [IfaceExport] {-,-} -- mi_decls :: [(Version,IfaceDecl)] {-,-} -- mi_mod_vers :: !Version, -- mi_orphan :: !Bool, -- mi_boot :: !Bool, -- mi_exp_vers :: !Version, -- mi_fixities :: [(OccName,Fixity)], -- mi_deprecs :: [IfaceDeprec], -- mi_insts :: [IfaceInst], -- mi_rules :: [IfaceRule], -- mi_rule_vers :: !Version, } emptyIface = Iface { mi_package = undefined, mi_module = undefined, mi_deps = noDependencies, mi_usages = undefined, mi_exports = undefined } -- --------------------------------------------------------------------- -- pretty-print an interface -- showIface :: Iface -> String showIface (Iface { mi_package = p, mi_module = m, mi_deps = deps, mi_usages = us }) = "interface \"" ++ p ++ "\" " ++ m ++ "\n" ++ pprDeps deps ++ "\n" ++ (concat $ intersperse "\n" (map pprUsage us)) -- "\n" ++ (concat $ intersperse "\n" (map pprExport es)) pprDeps :: Dependencies -> String pprDeps (Deps { dep_mods = mods, dep_pkgs = pkgs }) = "module dependencies: " ++ (concat $ intersperse ", " mods) ++ "\npackage dependencies: " ++ (concat $ intersperse ", " pkgs) pprUsage :: Usage -> String pprUsage usage = hsep ["import", usg_name usage] pprExport :: IfaceExport -> String pprExport (fsmod, items) = hsep [ "export", unpackFS fsmod, hsep (map pp_avail items) ] where pp_avail :: GenAvailInfo OccName -> String pp_avail (Avail nm) = ppr_occ nm pp_avail (AvailTC _ []) = empty pp_avail (AvailTC n (n':ns)) | n==n' = (ppr_occ n) ++ pp_export ns | otherwise = (ppr_occ n) ++ "|" ++ pp_export (n':ns) pp_export [] = empty pp_export names = "{" ++ (hsep (map ppr_occ names)) ++ "}" ppr_occ (OccName _ s) = s -- -- TODO bring in the Pretty library -- hsep = \ss -> concat (intersperse " " ss) empty = "" -- --------------------------------------------------------------------- -- -- Dependency info about modules and packages below this one -- in the import hierarchy. See TcRnTypes.ImportAvails for details. -- -- Invariant: the dependencies of a module M never includes M -- Invariant: the lists are unordered, with no duplicates -- -- The fields are: -- Home-package module dependencies -- External package dependencies -- Orphan modules (whether home or external pkg) data Dependencies = Deps { dep_mods :: [ModuleName], dep_pkgs :: [PackageName] {-,-} } deriving (Show) noDependencies :: Dependencies noDependencies = Deps [] [] -- -- Type aliases need to have a real type so the parser can work out how -- to parse them. You have to find what these are by reading GHC. -- type ModuleName = String {- was FastString -} -- Module type PackageName = String {- was FastString -} -- Packages type Version = Int -- BasicTypes type EncodedFS = FastString -- FastString type IfaceExport = (EncodedFS, [GenAvailInfo OccName]) -- HscTypes data GenAvailInfo name = Avail name -- An ordinary identifier | AvailTC name -- The name of the type or class [name] -- The available pieces of type/class. -- NB: If the type or class is itself -- to be in scope, it must be in this list. -- Thus, typically: AvailTC Eq [Eq, ==, /=] deriving Show data OccName = OccName NameSpace String {- was EncodedFS -} deriving Show instance Eq OccName where (OccName sp1 s1) == (OccName sp2 s2) = s1 == s2 && sp1 == sp2 data NameSpace = VarName -- variables, and "source" data constructors | DataName -- "real" data constructors | TvName -- tyvars | TcClsName -- type constructors and classes deriving (Eq, Show) data Usage = Usage { usg_name :: ModuleName, -- Name of the module usg_mod :: Version, -- Module version usg_exports :: Maybe Version, -- Export-list version, if we depend on it usg_entities :: [(OccName,Version)],-- Sorted by occurrence name usg_rules :: Version -- Orphan-rules version (for non-orphan -- modules this will always be initialVersion) } deriving Show ------------------------------------------------------------------------ -- TODO parsing type and decl information out of the .hi file -- complex data structure... -- {- data IfaceExtName = ExtPkg ModuleName OccName -- From an external package; no version # -- Also used for wired-in things regardless -- of whether they are home-pkg or not | HomePkg ModuleName OccName Version -- From another module in home package; -- has version # | LocalTop OccName -- Top-level from the same module as -- the enclosing IfaceDecl | LocalTopSub -- Same as LocalTop, but for a class method or constr OccName -- Class-meth/constr name OccName -- Parent class/datatype name -- LocalTopSub is written into iface files as LocalTop; the parent -- info is only used when computing version information in MkIface data IfaceTyCon -- Abbreviations for common tycons with known names = IfaceTc IfaceExtName -- The common case | IfaceIntTc | IfaceBoolTc | IfaceCharTc | IfaceListTc | IfacePArrTc | IfaceTupTc Boxity Arity type Arity = Int -- BasicTypes data Boxity = Boxed | Unboxed type IfaceContext = [IfacePredType] data IfacePredType -- NewTypes are handled as ordinary TyConApps = IfaceClassP IfaceExtName [IfaceType] | IfaceIParam (IPName OccName) IfaceType data IPName name = Dupable name -- ?x: you can freely duplicate this implicit parameter | Linear name -- %x: you must use the splitting function to duplicate it deriving( Eq, Ord ) -- Ord is used in the IP name cache finite map -- (used in HscTypes.OrigIParamCache) data IfaceType = IfaceTyVar OccName -- Type variable only, not tycon | IfaceAppTy IfaceType IfaceType | IfaceForAllTy IfaceTvBndr IfaceType | IfacePredTy IfacePredType | IfaceTyConApp IfaceTyCon [IfaceType] -- Not necessarily saturated -- Includes newtypes, synonyms, tuples | IfaceFunTy IfaceType IfaceType data IfaceBndr -- Local (non-top-level) binders = IfaceIdBndr IfaceIdBndr | IfaceTvBndr IfaceTvBndr type IfaceIdBndr = (OccName, IfaceType) -- OccName, because always local type IfaceTvBndr = (OccName, IfaceKind) type IfaceKind = Kind -- Re-use the Kind type, but no KindVars in it data IfaceIdInfo = NoInfo -- When writing interface file without -O | HasInfo [IfaceInfoItem] -- Has info, and here it is data IfaceInfoItem = HsArity Arity | HsStrictness StrictSig | HsUnfold Activation IfaceExpr | HsNoCafRefs | HsWorker IfaceExtName Arity -- Worker, if any see IdInfo.WorkerInfo -- for why we want arity here. -- NB: we need IfaceExtName (not just OccName) because the worker -- can simplify to a function in another module. -- NB: Specialisations and rules come in separately and are -- only later attached to the Id. Partial reason: some are orphans. newtype StrictSig = StrictSig DmdType data IfaceDecl = IfaceId { ifName :: OccName, ifType :: IfaceType, ifIdInfo :: IfaceIdInfo } | IfaceData { ifCtxt :: IfaceContext, -- Context ifName :: OccName, -- Type constructor ifTyVars :: [IfaceTvBndr], -- Type variables ifCons :: IfaceConDecls, -- Includes new/data info ifRec :: RecFlag, -- Recursive or not? ifVrcs :: ArgVrcs, ifGeneric :: Bool -- True <=> generic converter functions available } -- We need this for imported data decls, since the -- imported modules may have been compiled with -- different flags to the current compilation unit | IfaceSyn { ifName :: OccName, -- Type constructor ifTyVars :: [IfaceTvBndr], -- Type variables ifVrcs :: ArgVrcs, ifSynRhs :: IfaceType -- synonym expansion } | IfaceClass { ifCtxt :: IfaceContext, -- Context... ifName :: OccName, -- Name of the class ifTyVars :: [IfaceTvBndr], -- Type variables ifFDs :: [FunDep OccName], -- Functional dependencies ifSigs :: [IfaceClassOp], -- Method signatures ifRec :: RecFlag, -- Is newtype/datatype associated with the class recursive? ifVrcs :: ArgVrcs -- ... and what are its argument variances ... } | IfaceForeign { ifName :: OccName, -- Needs expanding when we move beyond .NET ifExtName :: Maybe FastString } -} ------------------------------------------------------------------------ -- -- all this stuff may be enabled if we ever want other information out -- {- type ArgVrcs = [(Bool,Bool)] -- TyCon type CLabelString = FastString -- CStrings type CcName = EncodedFS -- CostCentre type DeprecTxt = FastString -- BasicTypes type FunDep a = ([a],[a]) -- Class type IfaceAlt = (IfaceConAlt,[OccName],IfaceExpr) -- IfaceSyn type IfaceContext = [IfacePredType] -- IfaceType type IfaceDeprec = Deprecs [(OccName,DeprecTxt)] -- HscTypes type IfaceIdBndr = (OccName, IfaceType) -- IfaceType type IfaceKind = Kind -- IfaceType type IfaceTvBndr = (OccName, IfaceKind) -- IfaceType type RuleName = FastString -- CoreSyn -- -- Empty definitions for the various types we need, but whose results we -- don't care about. -- -- 'data' types that have a parsing method associated with them -- This list corresponds to each instance in BinIface -- -- Try to keep this list ordered by the order they appear in BinIface -- data Deprecs a = Deprecs data Activation = Activation data StrictnessMark = StrictnessMark data Boxity = Boxity data TupCon = TupCon data RecFlag = RecFlag data DefMeth = DefMeth data FixityDirection = FixityDirection data Fixity = Fixity data DmdType = DmdType data Demand = Demand data Demands = Demands data DmdResult = DmdResult data StrictSig = StrictSig data IsCafCC = IsCafCC data IsDupdCC = IsDupdCC data CostCentre = CostCentre data IfaceExtName = IfaceExtName data IfaceBndr = IfaceBndr data Kind = Kind data IfaceTyCon = IfaceTyCon data IfacePredType = IfacePredType data IfaceExpr = IfaceExpr data IfaceConAlt = IfaceConAlt data IfaceBinding = IfaceBinding data IfaceIdInfo = IfaceIdInfo data IfaceNoteItem = IfaceNoteItem data IfaceInfoItem = IfaceInfoItem data IfaceNote = IfaceNote data IfaceInst = IfaceInst data IfaceConDecls = IfaceConDecls data IfaceConDecl = IfaceConDecl data IfaceClassOp = IfaceClassOp data IfaceRule = IfaceRule data Literal = Literal data ForeignCall = ForeignCall data Safety = Safety data CExportSpec = CExportSpec data CCallSpec = CCallSpec data CCallTarget = CCallTarget data CCallConv = CCallConv data DNCallSpec = DNCallSpec data DNKind = DNKind data DNType = DNType -}