ConDecl(..), ConDetails(..),
BangType(..), getBangType,
DeprecDecl(..), DeprecTxt,
- hsDeclName, instDeclName, tyClDeclName, tyClDeclNames,
- isClassDecl, isSynDecl, isDataDecl, countTyClDecls, toHsRule,
- mkClassDeclSysNames,
- getClassDeclSysNames
+ hsDeclName, instDeclName, tyClDeclName, tyClDeclNames, tyClDeclSysNames,
+ isClassDecl, isSynDecl, isDataDecl, isIfaceSigDecl, countTyClDecls,
+ mkClassDeclSysNames, isIfaceRuleDecl, ifaceRuleDeclName,
+ getClassDeclSysNames, conDetailsTys
) where
#include "HsVersions.h"
import HsExpr ( HsExpr )
import HsTypes
import PprCore ( pprCoreRule )
-import HsCore ( UfExpr(UfVar), UfBinder, HsIdInfo, pprHsIdInfo,
- eq_ufBinders, eq_ufExpr, pprUfExpr, toUfExpr, toUfBndr
+import HsCore ( UfExpr, UfBinder, HsIdInfo, pprHsIdInfo,
+ eq_ufBinders, eq_ufExpr, pprUfExpr
)
import CoreSyn ( CoreRule(..) )
import BasicTypes ( NewOrData(..) )
import CallConv ( CallConv, pprCallConv )
-import Name ( getName )
-- others:
+import Name ( NamedThing )
import FunDeps ( pprFundeps )
-import Class ( FunDep )
+import Class ( FunDep, DefMeth(..) )
import CStrings ( CLabelString, pprCLabelString )
import Outputable
-import SrcLoc ( SrcLoc, noSrcLoc )
+import SrcLoc ( SrcLoc )
\end{code}
\begin{code}
#ifdef DEBUG
-hsDeclName :: (Outputable name, Outputable pat)
+hsDeclName :: (NamedThing name, Outputable name, Outputable pat)
=> HsDecl name pat -> name
#endif
hsDeclName (TyClD decl) = tyClDeclName decl
\end{code}
\begin{code}
-instance (Outputable name, Outputable pat)
+instance (NamedThing name, Outputable name, Outputable pat)
=> Outputable (HsDecl name pat) where
ppr (TyClD dcl) = ppr dcl
ppr (DeprecD dd) = ppr dd
\end{code}
-\begin{code}
-instance Ord name => Eq (HsDecl name pat) where
- -- Used only when comparing interfaces,
- -- at which time only signature and type/class decls
- (TyClD d1) == (TyClD d2) = d1 == d2
- _ == _ = False
-\end{code}
-
%************************************************************************
%* *
(MonoBinds name pat) -- default methods
(ClassDeclSysNames name)
SrcLoc
+\end{code}
+
+Simple classifiers
+
+\begin{code}
+isIfaceSigDecl, isDataDecl, isSynDecl, isClassDecl :: TyClDecl name pat -> Bool
+
+isIfaceSigDecl (IfaceSig _ _ _ _) = True
+isIfaceSigDecl other = False
+
+isSynDecl (TySynonym _ _ _ _) = True
+isSynDecl other = False
+isDataDecl (TyData _ _ _ _ _ _ _ _ _ _) = True
+isDataDecl other = False
+
+isClassDecl (ClassDecl _ _ _ _ _ _ _ _ ) = True
+isClassDecl other = False
+\end{code}
+
+Dealing with names
+
+\begin{code}
+--------------------------------
tyClDeclName :: TyClDecl name pat -> name
tyClDeclName (IfaceSig name _ _ _) = name
tyClDeclName (TyData _ _ name _ _ _ _ _ _ _) = name
tyClDeclName (ClassDecl _ name _ _ _ _ _ _) = name
+--------------------------------
tyClDeclNames :: Eq name => TyClDecl name pat -> [(name, SrcLoc)]
-- Returns all the binding names of the decl, along with their SrcLocs
-- The first one is guaranteed to be the name of the decl
tyClDeclNames (TySynonym name _ _ loc)
= [(name,loc)]
-tyClDeclNames (ClassDecl _ name _ _ sigs _ _ loc)
- = (name,loc) : [(name,loc) | ClassOpSig n _ _ loc <- sigs]
+tyClDeclNames (ClassDecl _ cls_name _ _ sigs _ _ loc)
+ = (cls_name,loc) : [(n,loc) | ClassOpSig n _ _ loc <- sigs]
+
+tyClDeclNames (TyData _ _ tc_name _ cons _ _ loc _ _)
+ = (tc_name,loc) : conDeclsNames cons
+
+tyClDeclNames (IfaceSig name _ _ loc) = [(name,loc)]
+
+--------------------------------
+tyClDeclSysNames :: TyClDecl name pat -> [(name, SrcLoc)]
+-- Similar to tyClDeclNames, but returns the "implicit"
+-- or "system" names of the declaration
-tyClDeclNames (TyData _ _ name _ cons _ _ loc _ _)
- = (name,loc) : conDeclsNames cons
+tyClDeclSysNames (ClassDecl _ _ _ _ _ _ names loc) = [(n,loc) | n <- names]
+tyClDeclSysNames (TyData _ _ _ _ cons _ _ _ _ _) = [(wkr_name,loc) | ConDecl _ wkr_name _ _ _ loc <- cons]
+tyClDeclSysNames decl = []
-tyClDeclNames (IfaceSig _ _ _ _) = []
+--------------------------------
type ClassDeclSysNames name = [name]
-- [tycon, datacon wrapper, datacon worker,
-- superclass selector 1, ..., superclass selector n]
getClassDeclSysNames (a:b:c:ds) = (a,b,c,ds)
\end{code}
-
\begin{code}
-isDataDecl, isSynDecl, isClassDecl :: TyClDecl name pat -> Bool
-
-isSynDecl (TySynonym _ _ _ _) = True
-isSynDecl other = False
-
-isDataDecl (TyData _ _ _ _ _ _ _ _ _ _) = True
-isDataDecl other = False
-
-isClassDecl (ClassDecl _ _ _ _ _ _ _ _ ) = True
-isClassDecl other = False
-\end{code}
-
-\begin{code}
-instance Ord name => Eq (TyClDecl name pat) where
+instance (NamedThing name, Ord name) => Eq (TyClDecl name pat) where
-- Used only when building interface files
(==) (IfaceSig n1 t1 i1 _)
(IfaceSig n2 t2 i2 _) = n1==n2 && t1==t2 && i1==i2
(==) _ _ = False -- default case
-
eq_hsFD env (ns1,ms1) (ns2,ms2)
= eqListBy (eq_hsVar env) ns1 ns2 && eqListBy (eq_hsVar env) ms1 ms2
eq_cls_sig env (ClassOpSig n1 dm1 ty1 _) (ClassOpSig n2 dm2 ty2 _)
= n1==n2 && dm1 `eq_dm` dm2 && eq_hsType env ty1 ty2
where
- -- Ignore the name of the default method.
+ -- Ignore the name of the default method for (DefMeth id)
-- This is used for comparing declarations before putting
-- them into interface files, and the name of the default
-- method isn't relevant
- (Just (explicit_dm1)) `eq_dm` (Just (explicit_dm2)) = explicit_dm1 == explicit_dm2
- Nothing `eq_dm` Nothing = True
- dm1 `eq_dm` dm2 = False
+ Nothing `eq_dm` Nothing = True
+ (Just NoDefMeth) `eq_dm` (Just NoDefMeth) = True
+ (Just GenDefMeth) `eq_dm` (Just GenDefMeth) = True
+ (Just (DefMeth _)) `eq_dm` (Just (DefMeth _)) = True
+ dm1 `eq_dm` dm2 = False
+
+
\end{code}
\begin{code}
\end{code}
\begin{code}
-instance (Outputable name, Outputable pat)
+instance (NamedThing name, Outputable name, Outputable pat)
=> Outputable (TyClDecl name pat) where
ppr (IfaceSig var ty info _) = hsep [ppr var, dcolon, ppr ty, pprHsIdInfo info]
name -- Name of the constructor's 'worker Id'
-- Filled in as the ConDecl is built
- [HsTyVarBndr name] -- Existentially quantified type variables
+ [HsTyVarBndr name] -- Existentially quantified type variables
(HsContext name) -- ...and context
-- If both are empty then there are no existentials
\end{code}
\begin{code}
+conDetailsTys :: ConDetails name -> [HsType name]
+conDetailsTys (VanillaCon btys) = map getBangType btys
+conDetailsTys (InfixCon bty1 bty2) = [getBangType bty1, getBangType bty2]
+conDetailsTys (RecCon fields) = [getBangType bty | (_, bty) <- fields]
+
+
eq_ConDecl env (ConDecl n1 _ tvs1 cxt1 cds1 _)
(ConDecl n2 _ tvs2 cxt2 cds2 _)
= n1 == n2 &&
- (eqWithHsTyVars tvs1 tvs2 $ \ env ->
+ (eq_hsTyVars env tvs1 tvs2 $ \ env ->
eq_hsContext env cxt1 cxt2 &&
eq_ConDetails env cds1 cds2)
name -- Head of LHS
CoreRule
+isIfaceRuleDecl (HsRule _ _ _ _ _ _) = False
+isIfaceRuleDecl other = True
+
+ifaceRuleDeclName :: RuleDecl name pat -> name
+ifaceRuleDeclName (IfaceRule _ _ n _ _ _) = n
+ifaceRuleDeclName (IfaceRuleOut n r) = n
+ifaceRuleDeclName (HsRule fs _ _ _ _ _) = pprPanic "ifaceRuleDeclName" (ppr fs)
data RuleBndr name
= RuleBndr name
| RuleBndrSig name (HsType name)
-instance Ord name => Eq (RuleDecl name pat) where
+instance (NamedThing name, Ord name) => Eq (RuleDecl name pat) where
-- Works for IfaceRules only; used when comparing interface file versions
(IfaceRule n1 bs1 f1 es1 rhs1 _) == (IfaceRule n2 bs2 f2 es2 rhs2 _)
= n1==n2 && f1 == f2 &&
eq_ufBinders emptyEqHsEnv bs1 bs2 (\env ->
eqListBy (eq_ufExpr env) (rhs1:es1) (rhs2:es2))
-instance (Outputable name, Outputable pat)
+instance (NamedThing name, Outputable name, Outputable pat)
=> Outputable (RuleDecl name pat) where
ppr (HsRule name tvs ns lhs rhs loc)
= sep [text "{-# RULES" <+> doubleQuotes (ptext name),
instance Outputable name => Outputable (RuleBndr name) where
ppr (RuleBndr name) = ppr name
ppr (RuleBndrSig name ty) = ppr name <> dcolon <> ppr ty
-
-toHsRule id (BuiltinRule _)
- = pprTrace "toHsRule: builtin" (ppr id) (bogusIfaceRule id)
-
-toHsRule id (Rule name bndrs args rhs)
- = IfaceRule name (map toUfBndr bndrs) (getName id)
- (map toUfExpr args) (toUfExpr rhs) noSrcLoc
-
-bogusIfaceRule id
- = IfaceRule SLIT("bogus") [] (getName id) [] (UfVar (getName id)) noSrcLoc
\end{code}