X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2FhsSyn%2FHsDecls.lhs;h=a6dc19e88cc3805349223bd07e27c09825d597e8;hp=d8e1a348b88ac3767e0dc8abaab22516b859ed4d;hb=6084fb5517da34f65034370a3695e2af3b85ce2b;hpb=3afa01b9ff2006864e3ce4b4d960f0289a266ea2 diff --git a/compiler/hsSyn/HsDecls.lhs b/compiler/hsSyn/HsDecls.lhs index d8e1a34..a6dc19e 100644 --- a/compiler/hsSyn/HsDecls.lhs +++ b/compiler/hsSyn/HsDecls.lhs @@ -1,58 +1,64 @@ % +% (c) The University of Glasgow 2006 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 % -\section[HsDecls]{Abstract syntax: global declarations} + +HsDecls: Abstract syntax: global declarations Definitions for: @TyDecl@ and @oCnDecl@, @ClassDecl@, @InstDecl@, @DefaultDecl@ and @ForeignDecl@. \begin{code} +{-# OPTIONS -fno-warn-incomplete-patterns #-} +-- The above warning supression flag is a temporary kludge. +-- While working on this module you are encouraged to remove it and fix +-- any warnings in the module. See +-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings +-- for details + module HsDecls ( HsDecl(..), LHsDecl, TyClDecl(..), LTyClDecl, - InstDecl(..), LInstDecl, NewOrData(..), + InstDecl(..), LInstDecl, DerivDecl(..), LDerivDecl, NewOrData(..), + FamilyFlavour(..), RuleDecl(..), LRuleDecl, RuleBndr(..), DefaultDecl(..), LDefaultDecl, SpliceDecl(..), ForeignDecl(..), LForeignDecl, ForeignImport(..), ForeignExport(..), CImportSpec(..), FoType(..), - ConDecl(..), ResType(..), LConDecl, - DeprecDecl(..), LDeprecDecl, + ConDecl(..), ResType(..), ConDeclField(..), LConDecl, + HsConDeclDetails, hsConDeclArgTys, + DocDecl(..), LDocDecl, docDeclDoc, + WarnDecl(..), LWarnDecl, HsGroup(..), emptyRdrGroup, emptyRnGroup, appendGroups, tcdName, tyClDeclNames, tyClDeclTyVars, - isClassDecl, isSynDecl, isDataDecl, + isClassDecl, isSynDecl, isDataDecl, isTypeDecl, isFamilyDecl, + isFamInstDecl, countTyClDecls, - conDetailsTys, + instDeclATs, collectRuleBndrSigTys, ) where -#include "HsVersions.h" - -- friends: import {-# SOURCE #-} HsExpr( HsExpr, pprExpr ) -- Because Expr imports Decls via HsBracket -import HsBinds ( HsValBinds(..), HsBind, LHsBinds, plusHsValBinds, - Sig(..), LSig, LFixitySig, pprLHsBinds, - emptyValBindsIn, emptyValBindsOut ) -import HsPat ( HsConDetails(..), hsConArgs ) -import HsImpExp ( pprHsVar ) +import HsBinds +import HsPat import HsTypes -import NameSet ( NameSet ) -import HscTypes ( DeprecTxt ) -import CoreSyn ( RuleName ) -import Kind ( Kind, pprKind ) -import BasicTypes ( Activation(..) ) -import ForeignCall ( CCallTarget(..), DNCallSpec, CCallConv, Safety, - CExportSpec(..), CLabelString ) +import HsDoc +import NameSet +import {- Kind parts of -} Type +import BasicTypes +import ForeignCall -- others: -import FunDeps ( pprFundeps ) -import Class ( FunDep ) +import Class import Outputable -import Util ( count ) -import SrcLoc ( Located(..), unLoc, noLoc ) +import Util +import SrcLoc import FastString -\end{code} +import Data.Maybe ( isJust ) +\end{code} %************************************************************************ %* * @@ -66,13 +72,16 @@ type LHsDecl id = Located (HsDecl id) data HsDecl id = TyClD (TyClDecl id) | InstD (InstDecl id) + | DerivD (DerivDecl id) | ValD (HsBind id) | SigD (Sig id) | DefD (DefaultDecl id) | ForD (ForeignDecl id) - | DeprecD (DeprecDecl id) + | WarningD (WarnDecl id) | RuleD (RuleDecl id) | SpliceD (SpliceDecl id) + | DocD (DocDecl id) + -- NB: all top-level fixity decls are contained EITHER -- EITHER SigDs @@ -94,6 +103,7 @@ data HsGroup id hs_valds :: HsValBinds id, hs_tyclds :: [LTyClDecl id], hs_instds :: [LInstDecl id], + hs_derivds :: [LDerivDecl id], hs_fixds :: [LFixitySig id], -- Snaffled out of both top-level fixity signatures, @@ -101,18 +111,21 @@ data HsGroup id hs_defds :: [LDefaultDecl id], hs_fords :: [LForeignDecl id], - hs_depds :: [LDeprecDecl id], - hs_ruleds :: [LRuleDecl id] + hs_warnds :: [LWarnDecl id], + hs_ruleds :: [LRuleDecl id], + + hs_docs :: [LDocDecl id] } emptyGroup, emptyRdrGroup, emptyRnGroup :: HsGroup a emptyRdrGroup = emptyGroup { hs_valds = emptyValBindsIn } emptyRnGroup = emptyGroup { hs_valds = emptyValBindsOut } -emptyGroup = HsGroup { hs_tyclds = [], hs_instds = [], +emptyGroup = HsGroup { hs_tyclds = [], hs_instds = [], hs_derivds = [], hs_fixds = [], hs_defds = [], hs_fords = [], - hs_depds = [], hs_ruleds = [], - hs_valds = error "emptyGroup hs_valds: Can't happen" } + hs_warnds = [], hs_ruleds = [], + hs_valds = error "emptyGroup hs_valds: Can't happen", + hs_docs = [] } appendGroups :: HsGroup a -> HsGroup a -> HsGroup a appendGroups @@ -120,50 +133,59 @@ appendGroups hs_valds = val_groups1, hs_tyclds = tyclds1, hs_instds = instds1, + hs_derivds = derivds1, hs_fixds = fixds1, hs_defds = defds1, hs_fords = fords1, - hs_depds = depds1, - hs_ruleds = rulds1 } + hs_warnds = warnds1, + hs_ruleds = rulds1, + hs_docs = docs1 } HsGroup { hs_valds = val_groups2, hs_tyclds = tyclds2, hs_instds = instds2, + hs_derivds = derivds2, hs_fixds = fixds2, hs_defds = defds2, hs_fords = fords2, - hs_depds = depds2, - hs_ruleds = rulds2 } + hs_warnds = warnds2, + hs_ruleds = rulds2, + hs_docs = docs2 } = HsGroup { hs_valds = val_groups1 `plusHsValBinds` val_groups2, hs_tyclds = tyclds1 ++ tyclds2, hs_instds = instds1 ++ instds2, + hs_derivds = derivds1 ++ derivds2, hs_fixds = fixds1 ++ fixds2, hs_defds = defds1 ++ defds2, hs_fords = fords1 ++ fords2, - hs_depds = depds1 ++ depds2, - hs_ruleds = rulds1 ++ rulds2 } + hs_warnds = warnds1 ++ warnds2, + hs_ruleds = rulds1 ++ rulds2, + hs_docs = docs1 ++ docs2 } \end{code} \begin{code} instance OutputableBndr name => Outputable (HsDecl name) where - ppr (TyClD dcl) = ppr dcl - ppr (ValD binds) = ppr binds - ppr (DefD def) = ppr def - ppr (InstD inst) = ppr inst - ppr (ForD fd) = ppr fd - ppr (SigD sd) = ppr sd - ppr (RuleD rd) = ppr rd - ppr (DeprecD dd) = ppr dd - ppr (SpliceD dd) = ppr dd + ppr (TyClD dcl) = ppr dcl + ppr (ValD binds) = ppr binds + ppr (DefD def) = ppr def + ppr (InstD inst) = ppr inst + ppr (DerivD deriv) = ppr deriv + ppr (ForD fd) = ppr fd + ppr (SigD sd) = ppr sd + ppr (RuleD rd) = ppr rd + ppr (WarningD wd) = ppr wd + ppr (SpliceD dd) = ppr dd + ppr (DocD doc) = ppr doc instance OutputableBndr name => Outputable (HsGroup name) where ppr (HsGroup { hs_valds = val_decls, hs_tyclds = tycl_decls, hs_instds = inst_decls, + hs_derivds = deriv_decls, hs_fixds = fix_decls, - hs_depds = deprec_decls, + hs_warnds = deprec_decls, hs_fords = foreign_decls, hs_defds = default_decls, hs_ruleds = rule_decls }) @@ -171,6 +193,7 @@ instance OutputableBndr name => Outputable (HsGroup name) where ppr_ds deprec_decls, ppr_ds rule_decls, ppr val_decls, ppr_ds tycl_decls, ppr_ds inst_decls, + ppr_ds deriv_decls, ppr_ds foreign_decls] where ppr_ds [] = empty @@ -179,7 +202,7 @@ instance OutputableBndr name => Outputable (HsGroup name) where data SpliceDecl id = SpliceDecl (Located (HsExpr id)) -- Top level splice instance OutputableBndr name => Outputable (SpliceDecl name) where - ppr (SpliceDecl e) = ptext SLIT("$") <> parens (pprExpr (unLoc e)) + ppr (SpliceDecl e) = ptext (sLit "$") <> parens (pprExpr (unLoc e)) \end{code} @@ -323,10 +346,26 @@ Interface file code: \begin{code} --- TyClDecls are precisely the kind of declarations that can --- appear in interface files; or (internally) in GHC's interface --- for a module. That's why (despite the misnomer) IfaceSig and ForeignType --- are both in TyClDecl +-- Representation of indexed types +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Family kind signatures are represented by the variant `TyFamily'. It +-- covers "type family", "newtype family", and "data family" declarations, +-- distinguished by the value of the field `tcdFlavour'. +-- +-- Indexed types are represented by 'TyData' and 'TySynonym' using the field +-- 'tcdTyPats::Maybe [LHsType name]', with the following meaning: +-- +-- * If it is 'Nothing', we have a *vanilla* data type declaration or type +-- synonym declaration and 'tcdVars' contains the type parameters of the +-- type constructor. +-- +-- * If it is 'Just pats', we have the definition of an indexed type. Then, +-- 'pats' are type patterns for the type-indexes of the type constructor +-- and 'tcdTyVars' are the variables in those patterns. Hence, the arity of +-- the indexed type (ie, the number of indexes) is 'length tcdTyPats' and +-- *not* 'length tcdVars'. +-- +-- In both cases, 'tcdVars' collects all variables we need to quantify over. type LTyClDecl name = Located (TyClDecl name) @@ -335,18 +374,38 @@ data TyClDecl name tcdLName :: Located name, tcdExtName :: Maybe FastString, tcdFoType :: FoType - } + } + + -- type/data/newtype family T :: *->* + | TyFamily { tcdFlavour:: FamilyFlavour, -- type, new, or data + tcdLName :: Located name, -- type constructor + tcdTyVars :: [LHsTyVarBndr name], -- type variables + tcdKind :: Maybe Kind -- result kind + } + -- Declares a data type or newtype, giving its construcors + -- data/newtype T a = + -- data/newtype instance T [a] = | TyData { tcdND :: NewOrData, tcdCtxt :: LHsContext name, -- Context tcdLName :: Located name, -- Type constructor + tcdTyVars :: [LHsTyVarBndr name], -- Type variables - tcdKindSig :: Maybe Kind, -- Optional kind sig; - -- (only for the 'where' form) + + tcdTyPats :: Maybe [LHsType name], -- Type patterns + -- Just [t1..tn] for data instance T t1..tn = ... + -- in this case tcdTyVars = fv( tcdTyPats ) + -- Nothing for everything else + + tcdKindSig:: Maybe Kind, -- Optional kind sig + -- (Just k) for a GADT-style 'data', or 'data + -- instance' decl with explicit kind sig tcdCons :: [LConDecl name], -- Data constructors - -- For data T a = T1 | T2 a the LConDecls all have ResTyH98 - -- For data T a where { T1 :: T a } the LConDecls all have ResTyGADT + -- For data T a = T1 | T2 a + -- the LConDecls all have ResTyH98 + -- For data T a where { T1 :: T a } + -- the LConDecls all have ResTyGADT tcdDerivs :: Maybe [LHsType name] -- Derivings; Nothing => not specified @@ -359,6 +418,10 @@ data TyClDecl name | TySynonym { tcdLName :: Located name, -- type constructor tcdTyVars :: [LHsTyVarBndr name], -- type variables + tcdTyPats :: Maybe [LHsType name], -- Type patterns + -- See comments for tcdTyPats in TyData + -- 'Nothing' => vanilla type synonym + tcdSynRhs :: LHsType name -- synonym expansion } @@ -367,28 +430,55 @@ data TyClDecl name tcdTyVars :: [LHsTyVarBndr name], -- Class type variables tcdFDs :: [Located (FunDep name)], -- Functional deps tcdSigs :: [LSig name], -- Methods' signatures - tcdMeths :: LHsBinds name -- Default methods + tcdMeths :: LHsBinds name, -- Default methods + tcdATs :: [LTyClDecl name], -- Associated types; ie + -- only 'TyFamily' and + -- 'TySynonym'; the + -- latter for defaults + tcdDocs :: [LDocDecl name] -- Haddock docs } data NewOrData - = NewType -- "newtype Blah ..." - | DataType -- "data Blah ..." - deriving( Eq ) -- Needed because Demand derives Eq + = NewType -- "newtype Blah ..." + | DataType -- "data Blah ..." + deriving( Eq ) -- Needed because Demand derives Eq + +data FamilyFlavour + = TypeFamily -- "type family ..." + | DataFamily -- "data family ..." \end{code} Simple classifiers \begin{code} -isDataDecl, isSynDecl, isClassDecl :: TyClDecl name -> Bool - -isSynDecl (TySynonym {}) = True -isSynDecl other = False +isDataDecl, isTypeDecl, isSynDecl, isClassDecl, isFamilyDecl, isFamInstDecl :: + TyClDecl name -> Bool +-- data/newtype or data/newtype instance declaration isDataDecl (TyData {}) = True -isDataDecl other = False +isDataDecl _other = False + +-- type or type instance declaration +isTypeDecl (TySynonym {}) = True +isTypeDecl _other = False + +-- vanilla Haskell type synonym (ie, not a type instance) +isSynDecl (TySynonym {tcdTyPats = Nothing}) = True +isSynDecl _other = False +-- type class isClassDecl (ClassDecl {}) = True -isClassDecl other = False +isClassDecl _ = False + +-- type family declaration +isFamilyDecl (TyFamily {}) = True +isFamilyDecl _other = False + +-- family instance (types, newtypes, and data types) +isFamInstDecl tydecl + | isTypeDecl tydecl + || isDataDecl tydecl = isJust (tcdTyPats tydecl) + | otherwise = False \end{code} Dealing with names @@ -403,35 +493,41 @@ tyClDeclNames :: Eq name => TyClDecl name -> [Located name] -- For record fields, the first one counts as the SrcLoc -- We use the equality to filter out duplicate field names -tyClDeclNames (TySynonym {tcdLName = name}) = [name] -tyClDeclNames (ForeignType {tcdLName = name}) = [name] +tyClDeclNames (TyFamily {tcdLName = name}) = [name] +tyClDeclNames (TySynonym {tcdLName = name}) = [name] +tyClDeclNames (ForeignType {tcdLName = name}) = [name] -tyClDeclNames (ClassDecl {tcdLName = cls_name, tcdSigs = sigs}) - = cls_name : [n | L _ (TypeSig n _) <- sigs] +tyClDeclNames (ClassDecl {tcdLName = cls_name, tcdSigs = sigs, tcdATs = ats}) + = cls_name : + concatMap (tyClDeclNames . unLoc) ats ++ [n | L _ (TypeSig n _) <- sigs] tyClDeclNames (TyData {tcdLName = tc_name, tcdCons = cons}) = tc_name : conDeclsNames (map unLoc cons) -tyClDeclTyVars (TySynonym {tcdTyVars = tvs}) = tvs -tyClDeclTyVars (TyData {tcdTyVars = tvs}) = tvs -tyClDeclTyVars (ClassDecl {tcdTyVars = tvs}) = tvs -tyClDeclTyVars (ForeignType {}) = [] +tyClDeclTyVars :: TyClDecl name -> [LHsTyVarBndr name] +tyClDeclTyVars (TyFamily {tcdTyVars = tvs}) = tvs +tyClDeclTyVars (TySynonym {tcdTyVars = tvs}) = tvs +tyClDeclTyVars (TyData {tcdTyVars = tvs}) = tvs +tyClDeclTyVars (ClassDecl {tcdTyVars = tvs}) = tvs +tyClDeclTyVars (ForeignType {}) = [] \end{code} \begin{code} -countTyClDecls :: [TyClDecl name] -> (Int, Int, Int, Int) - -- class, data, newtype, synonym decls +countTyClDecls :: [TyClDecl name] -> (Int, Int, Int, Int, Int, Int) + -- class, synonym decls, data, newtype, family decls, family instances countTyClDecls decls - = (count isClassDecl decls, - count isSynDecl decls, - count isDataTy decls, - count isNewTy decls) + = (count isClassDecl decls, + count isSynDecl decls, -- excluding... + count isDataTy decls, -- ...family... + count isNewTy decls, -- ...instances + count isFamilyDecl decls, + count isFamInstDecl decls) where - isDataTy TyData{tcdND=DataType} = True - isDataTy _ = False + isDataTy TyData{tcdND = DataType, tcdTyPats = Nothing} = True + isDataTy _ = False - isNewTy TyData{tcdND=NewType} = True - isNewTy _ = False + isNewTy TyData{tcdND = NewType, tcdTyPats = Nothing} = True + isNewTy _ = False \end{code} \begin{code} @@ -439,57 +535,92 @@ instance OutputableBndr name => Outputable (TyClDecl name) where ppr (ForeignType {tcdLName = ltycon}) - = hsep [ptext SLIT("foreign import type dotnet"), ppr ltycon] - - ppr (TySynonym {tcdLName = ltycon, tcdTyVars = tyvars, tcdSynRhs = mono_ty}) - = hang (ptext SLIT("type") <+> pp_decl_head [] ltycon tyvars <+> equals) + = hsep [ptext (sLit "foreign import type dotnet"), ppr ltycon] + + ppr (TyFamily {tcdFlavour = flavour, tcdLName = ltycon, + tcdTyVars = tyvars, tcdKind = mb_kind}) + = pp_flavour <+> pp_decl_head [] ltycon tyvars Nothing <+> pp_kind + where + pp_flavour = case flavour of + TypeFamily -> ptext (sLit "type family") + DataFamily -> ptext (sLit "data family") + + pp_kind = case mb_kind of + Nothing -> empty + Just kind -> dcolon <+> pprKind kind + + ppr (TySynonym {tcdLName = ltycon, tcdTyVars = tyvars, tcdTyPats = typats, + tcdSynRhs = mono_ty}) + = hang (ptext (sLit "type") <+> + (if isJust typats then ptext (sLit "instance") else empty) <+> + pp_decl_head [] ltycon tyvars typats <+> + equals) 4 (ppr mono_ty) ppr (TyData {tcdND = new_or_data, tcdCtxt = context, tcdLName = ltycon, - tcdTyVars = tyvars, tcdKindSig = mb_sig, tcdCons = condecls, - tcdDerivs = derivings}) - = pp_tydecl (ppr new_or_data <+> pp_decl_head (unLoc context) ltycon tyvars <+> ppr_sig mb_sig) + tcdTyVars = tyvars, tcdTyPats = typats, tcdKindSig = mb_sig, + tcdCons = condecls, tcdDerivs = derivings}) + = pp_tydecl (null condecls && isJust mb_sig) + (ppr new_or_data <+> + (if isJust typats then ptext (sLit "instance") else empty) <+> + pp_decl_head (unLoc context) ltycon tyvars typats <+> + ppr_sig mb_sig) (pp_condecls condecls) derivings where ppr_sig Nothing = empty ppr_sig (Just kind) = dcolon <+> pprKind kind - ppr (ClassDecl {tcdCtxt = context, tcdLName = lclas, tcdTyVars = tyvars, tcdFDs = fds, - tcdSigs = sigs, tcdMeths = methods}) - | null sigs -- No "where" part + ppr (ClassDecl {tcdCtxt = context, tcdLName = lclas, tcdTyVars = tyvars, + tcdFDs = fds, + tcdSigs = sigs, tcdMeths = methods, tcdATs = ats}) + | null sigs && null ats -- No "where" part = top_matter | otherwise -- Laid out - = sep [hsep [top_matter, ptext SLIT("where {")], - nest 4 (sep [sep (map ppr_sig sigs), pprLHsBinds methods, char '}'])] + = sep [hsep [top_matter, ptext (sLit "where {")], + nest 4 (sep [ sep (map ppr_semi ats) + , sep (map ppr_semi sigs) + , pprLHsBinds methods + , char '}'])] where - top_matter = ptext SLIT("class") <+> pp_decl_head (unLoc context) lclas tyvars <+> pprFundeps (map unLoc fds) - ppr_sig sig = ppr sig <> semi + top_matter = ptext (sLit "class") + <+> pp_decl_head (unLoc context) lclas tyvars Nothing + <+> pprFundeps (map unLoc fds) + ppr_semi decl = ppr decl <> semi pp_decl_head :: OutputableBndr name => HsContext name -> Located name -> [LHsTyVarBndr name] + -> Maybe [LHsType name] -> SDoc -pp_decl_head context thing tyvars +pp_decl_head context thing tyvars Nothing -- no explicit type patterns = hsep [pprHsContext context, ppr thing, interppSP tyvars] +pp_decl_head context thing _ (Just typats) -- explicit type patterns + = hsep [ pprHsContext context, ppr thing + , hsep (map (pprParendHsType.unLoc) typats)] + +pp_condecls :: OutputableBndr name => [LConDecl name] -> SDoc pp_condecls cs@(L _ ConDecl{ con_res = ResTyGADT _ } : _) -- In GADT syntax - = hang (ptext SLIT("where")) 2 (vcat (map ppr cs)) + = hang (ptext (sLit "where")) 2 (vcat (map ppr cs)) pp_condecls cs -- In H98 syntax - = equals <+> sep (punctuate (ptext SLIT(" |")) (map ppr cs)) + = equals <+> sep (punctuate (ptext (sLit " |")) (map ppr cs)) -pp_tydecl pp_head pp_decl_rhs derivings +pp_tydecl :: OutputableBndr name => Bool -> SDoc -> SDoc -> Maybe [LHsType name] -> SDoc +pp_tydecl True pp_head _ _ + = pp_head +pp_tydecl False pp_head pp_decl_rhs derivings = hang pp_head 4 (sep [ - pp_decl_rhs, - case derivings of - Nothing -> empty - Just ds -> hsep [ptext SLIT("deriving"), parens (interpp'SP ds)] + pp_decl_rhs, + case derivings of + Nothing -> empty + Just ds -> hsep [ptext (sLit "deriving"), parens (interpp'SP ds)] ]) instance Outputable NewOrData where - ppr NewType = ptext SLIT("newtype") - ppr DataType = ptext SLIT("data") + ppr NewType = ptext (sLit "newtype") + ppr DataType = ptext (sLit "data") \end{code} @@ -527,11 +658,25 @@ data ConDecl name , con_cxt :: LHsContext name -- The context. This *does not* include the -- "stupid theta" which lives only in the TyData decl - , con_details :: HsConDetails name (LBangType name) -- The main payload + , con_details :: HsConDeclDetails name -- The main payload , con_res :: ResType name -- Result type of the constructor + + , con_doc :: Maybe (LHsDoc name) -- A possible Haddock comment } +type HsConDeclDetails name = HsConDetails (LBangType name) [ConDeclField name] + +hsConDeclArgTys :: HsConDeclDetails name -> [LBangType name] +hsConDeclArgTys (PrefixCon tys) = tys +hsConDeclArgTys (InfixCon ty1 ty2) = [ty1,ty2] +hsConDeclArgTys (RecCon flds) = map cd_fld_type flds + +data ConDeclField name -- Record fields have Haddoc docs on them + = ConDeclField { cd_fld_name :: Located name, + cd_fld_type :: LBangType name, + cd_fld_doc :: Maybe (LHsDoc name) } + data ResType name = ResTyH98 -- Constructor was declared using Haskell 98 syntax | ResTyGADT (LHsType name) -- Constructor was declared using GADT-style syntax, @@ -539,7 +684,7 @@ data ResType name \end{code} \begin{code} -conDeclsNames :: Eq name => [ConDecl name] -> [Located name] +conDeclsNames :: (Eq name) => [ConDecl name] -> [Located name] -- See tyClDeclNames for what this does -- The function is boringly complicated because of the records -- And since we only have equality, we have to be a little careful @@ -547,14 +692,13 @@ conDeclsNames cons = snd (foldl do_one ([], []) cons) where do_one (flds_seen, acc) (ConDecl { con_name = lname, con_details = RecCon flds }) - = (map unLoc new_flds ++ flds_seen, lname : [f | f <- new_flds] ++ acc) + = (map unLoc new_flds ++ flds_seen, lname : new_flds ++ acc) where - new_flds = [ f | (f,_) <- flds, not (unLoc f `elem` flds_seen) ] + new_flds = filterOut (\f -> unLoc f `elem` flds_seen) + (map cd_fld_name flds) do_one (flds_seen, acc) c = (flds_seen, (con_name c):acc) - -conDetailsTys details = map getBangType (hsConArgs details) \end{code} @@ -562,23 +706,34 @@ conDetailsTys details = map getBangType (hsConArgs details) instance (OutputableBndr name) => Outputable (ConDecl name) where ppr = pprConDecl -pprConDecl (ConDecl con expl tvs cxt details ResTyH98) - = sep [pprHsForAll expl tvs cxt, ppr_details con details] +pprConDecl :: OutputableBndr name => ConDecl name -> SDoc +pprConDecl (ConDecl con expl tvs cxt details ResTyH98 doc) + = sep [ppr_mbDoc doc, pprHsForAll expl tvs cxt, ppr_details con details] where - ppr_details con (InfixCon t1 t2) = hsep [ppr t1, pprHsVar con, ppr t2] + ppr_details con (InfixCon t1 t2) = hsep [ppr t1, pprHsInfix con, ppr t2] ppr_details con (PrefixCon tys) = hsep (pprHsVar con : map ppr tys) ppr_details con (RecCon fields) = ppr con <+> ppr_fields fields -pprConDecl (ConDecl con expl tvs cxt (PrefixCon arg_tys) (ResTyGADT res_ty)) +pprConDecl (ConDecl con expl tvs cxt (PrefixCon arg_tys) (ResTyGADT res_ty) _) = ppr con <+> dcolon <+> sep [pprHsForAll expl tvs cxt, ppr (foldr mk_fun_ty res_ty arg_tys)] where mk_fun_ty a b = noLoc (HsFunTy a b) -pprConDecl (ConDecl con expl tvs cxt (RecCon fields) (ResTyGADT res_ty)) - = sep [pprHsForAll expl tvs cxt, ppr con <+> ppr fields <+> dcolon <+> ppr res_ty] -ppr_fields fields = braces (sep (punctuate comma (map ppr_field fields))) -ppr_field (n, ty) = ppr n <+> dcolon <+> ppr ty +pprConDecl (ConDecl con expl tvs cxt (RecCon fields) (ResTyGADT res_ty) _) + = sep [pprHsForAll expl tvs cxt, ppr con <+> ppr_fields fields <+> dcolon <+> ppr res_ty] + +pprConDecl (ConDecl con _expl _tvs _cxt (InfixCon _ _) (ResTyGADT _res_ty) _) + = pprPanic "pprConDecl" (ppr con) + -- In GADT syntax we don't allow infix constructors + + +ppr_fields :: OutputableBndr name => [ConDeclField name] -> SDoc +ppr_fields fields = braces (sep (punctuate comma (map ppr_fld fields))) + where + ppr_fld (ConDeclField { cd_fld_name = n, cd_fld_type = ty, + cd_fld_doc = doc }) + = ppr n <+> dcolon <+> ppr ty <+> ppr_mbDoc doc \end{code} %************************************************************************ @@ -595,14 +750,38 @@ data InstDecl name -- Using a polytype means that the renamer conveniently -- figures out the quantified type variables for us. (LHsBinds name) - [LSig name] -- User-supplied pragmatic info + [LSig name] -- User-supplied pragmatic info + [LTyClDecl name]-- Associated types (ie, 'TyData' and + -- 'TySynonym' only) instance (OutputableBndr name) => Outputable (InstDecl name) where - ppr (InstDecl inst_ty binds uprags) - = vcat [hsep [ptext SLIT("instance"), ppr inst_ty, ptext SLIT("where")], - nest 4 (ppr uprags), - nest 4 (pprLHsBinds binds) ] + ppr (InstDecl inst_ty binds uprags ats) + = vcat [hsep [ptext (sLit "instance"), ppr inst_ty, ptext (sLit "where")] + , nest 4 $ vcat (map ppr ats) + , nest 4 $ vcat (map ppr uprags) + , nest 4 $ pprLHsBinds binds ] + +-- Extract the declarations of associated types from an instance +-- +instDeclATs :: InstDecl name -> [LTyClDecl name] +instDeclATs (InstDecl _ _ _ ats) = ats +\end{code} + +%************************************************************************ +%* * +\subsection[DerivDecl]{A stand-alone instance deriving declaration +%* * +%************************************************************************ + +\begin{code} +type LDerivDecl name = Located (DerivDecl name) + +data DerivDecl name = DerivDecl (LHsType name) + +instance (OutputableBndr name) => Outputable (DerivDecl name) where + ppr (DerivDecl ty) + = hsep [ptext (sLit "derived instance"), ppr ty] \end{code} %************************************************************************ @@ -625,7 +804,7 @@ instance (OutputableBndr name) => Outputable (DefaultDecl name) where ppr (DefaultDecl tys) - = ptext SLIT("default") <+> parens (interpp'SP tys) + = ptext (sLit "default") <+> parens (interpp'SP tys) \end{code} %************************************************************************ @@ -645,10 +824,10 @@ instance (OutputableBndr name) type LForeignDecl name = Located (ForeignDecl name) data ForeignDecl name - = ForeignImport (Located name) (LHsType name) ForeignImport Bool -- defines name - | ForeignExport (Located name) (LHsType name) ForeignExport Bool -- uses name + = ForeignImport (Located name) (LHsType name) ForeignImport -- defines name + | ForeignExport (Located name) (LHsType name) ForeignExport -- uses name --- specification of an imported external entity in dependence on the calling +-- Specification Of an imported external entity in dependence on the calling -- convention -- data ForeignImport = -- import of a C entity @@ -698,29 +877,29 @@ data FoType = DNType -- In due course we'll add subtype stuff -- instance OutputableBndr name => Outputable (ForeignDecl name) where - ppr (ForeignImport n ty fimport _) = - ptext SLIT("foreign import") <+> ppr fimport <+> - ppr n <+> dcolon <+> ppr ty - ppr (ForeignExport n ty fexport _) = - ptext SLIT("foreign export") <+> ppr fexport <+> - ppr n <+> dcolon <+> ppr ty + ppr (ForeignImport n ty fimport) = + hang (ptext (sLit "foreign import") <+> ppr fimport <+> ppr n) + 2 (dcolon <+> ppr ty) + ppr (ForeignExport n ty fexport) = + hang (ptext (sLit "foreign export") <+> ppr fexport <+> ppr n) + 2 (dcolon <+> ppr ty) instance Outputable ForeignImport where ppr (DNImport spec) = - ptext SLIT("dotnet") <+> ppr spec + ptext (sLit "dotnet") <+> ppr spec ppr (CImport cconv safety header lib spec) = ppr cconv <+> ppr safety <+> char '"' <> pprCEntity header lib spec <> char '"' where pprCEntity header lib (CLabel lbl) = - ptext SLIT("static") <+> ftext header <+> char '&' <> + ptext (sLit "static") <+> ftext header <+> char '&' <> pprLib lib <> ppr lbl pprCEntity header lib (CFunction (StaticTarget lbl)) = - ptext SLIT("static") <+> ftext header <+> char '&' <> + ptext (sLit "static") <+> ftext header <+> char '&' <> pprLib lib <> ppr lbl - pprCEntity header lib (CFunction (DynamicTarget)) = - ptext SLIT("dynamic") - pprCEntity _ _ (CWrapper) = ptext SLIT("wrapper") + pprCEntity _ _ (CFunction (DynamicTarget)) = + ptext (sLit "dynamic") + pprCEntity _ _ (CWrapper) = ptext (sLit "wrapper") -- pprLib lib | nullFS lib = empty | otherwise = char '[' <> ppr lib <> char ']' @@ -729,10 +908,10 @@ instance Outputable ForeignExport where ppr (CExport (CExportStatic lbl cconv)) = ppr cconv <+> char '"' <> ppr lbl <> char '"' ppr (DNExport ) = - ptext SLIT("dotnet") <+> ptext SLIT("\"\"") + ptext (sLit "dotnet") <+> ptext (sLit "\"\"") instance Outputable FoType where - ppr DNType = ptext SLIT("type dotnet") + ppr DNType = ptext (sLit "type dotnet") \end{code} @@ -763,7 +942,7 @@ collectRuleBndrSigTys :: [RuleBndr name] -> [LHsType name] collectRuleBndrSigTys bndrs = [ty | RuleBndrSig _ ty <- bndrs] instance OutputableBndr name => Outputable (RuleDecl name) where - ppr (HsRule name act ns lhs fv_lhs rhs fv_rhs) + ppr (HsRule name act ns lhs _fv_lhs rhs _fv_rhs) = sep [text "{-# RULES" <+> doubleQuotes (ftext name) <+> ppr act, nest 4 (pp_forall <+> pprExpr (unLoc lhs)), nest 4 (equals <+> pprExpr (unLoc rhs) <+> text "#-}") ] @@ -776,6 +955,33 @@ instance OutputableBndr name => Outputable (RuleBndr name) where ppr (RuleBndrSig name ty) = ppr name <> dcolon <> ppr ty \end{code} +%************************************************************************ +%* * +\subsection[DocDecl]{Document comments} +%* * +%************************************************************************ + +\begin{code} + +type LDocDecl name = Located (DocDecl name) + +data DocDecl name + = DocCommentNext (HsDoc name) + | DocCommentPrev (HsDoc name) + | DocCommentNamed String (HsDoc name) + | DocGroup Int (HsDoc name) + +-- Okay, I need to reconstruct the document comments, but for now: +instance Outputable (DocDecl name) where + ppr _ = text "" + +docDeclDoc :: DocDecl name -> HsDoc name +docDeclDoc (DocCommentNext d) = d +docDeclDoc (DocCommentPrev d) = d +docDeclDoc (DocCommentNamed _ d) = d +docDeclDoc (DocGroup _ d) = d + +\end{code} %************************************************************************ %* * @@ -786,11 +992,11 @@ instance OutputableBndr name => Outputable (RuleBndr name) where We use exported entities for things to deprecate. \begin{code} -type LDeprecDecl name = Located (DeprecDecl name) +type LWarnDecl name = Located (WarnDecl name) -data DeprecDecl name = Deprecation name DeprecTxt +data WarnDecl name = Warning name WarningTxt -instance OutputableBndr name => Outputable (DeprecDecl name) where - ppr (Deprecation thing txt) +instance OutputableBndr name => Outputable (WarnDecl name) where + ppr (Warning thing txt) = hsep [text "{-# DEPRECATED", ppr thing, doubleQuotes (ppr txt), text "#-}"] \end{code}