X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2FhsSyn%2FHsDecls.lhs;h=273cc98c540ee03f8243cc4f6050fb7771210c87;hp=f6beb23bc86ac8a8d4adabb8a00991527aa8a2a5;hb=f96194794bf099020706c3816d1a5678b40addbb;hpb=15486d73d84483243f40fa245e63e7e88d5ed0ad diff --git a/compiler/hsSyn/HsDecls.lhs b/compiler/hsSyn/HsDecls.lhs index f6beb23..273cc98 100644 --- a/compiler/hsSyn/HsDecls.lhs +++ b/compiler/hsSyn/HsDecls.lhs @@ -1,59 +1,83 @@ % +% (c) The University of Glasgow 2006 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 % -\section[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 + +-- | Abstract syntax of global declarations. +-- +-- Definitions for: @TyDecl@ and @ConDecl@, @ClassDecl@, +-- @InstDecl@, @DefaultDecl@ and @ForeignDecl@. module HsDecls ( - HsDecl(..), LHsDecl, TyClDecl(..), LTyClDecl, - InstDecl(..), LInstDecl, DerivDecl(..), LDerivDecl, NewOrData(..), - RuleDecl(..), LRuleDecl, RuleBndr(..), - DefaultDecl(..), LDefaultDecl, SpliceDecl(..), - ForeignDecl(..), LForeignDecl, ForeignImport(..), ForeignExport(..), - CImportSpec(..), FoType(..), - ConDecl(..), ResType(..), LConDecl, - DeprecDecl(..), LDeprecDecl, - HsGroup(..), emptyRdrGroup, emptyRnGroup, appendGroups, - tcdName, tyClDeclNames, tyClDeclTyVars, - isClassDecl, isTFunDecl, isSynDecl, isDataDecl, isKindSigDecl, - isIdxTyDecl, - countTyClDecls, - conDetailsTys, - instDeclATs, - collectRuleBndrSigTys, + -- * Toplevel declarations + HsDecl(..), LHsDecl, + -- ** Class or type declarations + TyClDecl(..), LTyClDecl, + isClassDecl, isSynDecl, isDataDecl, isTypeDecl, isFamilyDecl, + isFamInstDecl, tcdName, tyClDeclNames, tyClDeclTyVars, + countTyClDecls, + -- ** Instance declarations + InstDecl(..), LInstDecl, NewOrData(..), FamilyFlavour(..), + instDeclATs, + -- ** Standalone deriving declarations + DerivDecl(..), LDerivDecl, + -- ** @RULE@ declarations + RuleDecl(..), LRuleDecl, RuleBndr(..), + collectRuleBndrSigTys, + -- ** @default@ declarations + DefaultDecl(..), LDefaultDecl, + -- ** Top-level template haskell splice + SpliceDecl(..), + -- ** Foreign function interface declarations + ForeignDecl(..), LForeignDecl, ForeignImport(..), ForeignExport(..), + CImportSpec(..), + -- ** Data-constructor declarations + ConDecl(..), LConDecl, ResType(..), + HsConDeclDetails, hsConDeclArgTys, hsConDeclsNames, + -- ** Document comments + DocDecl(..), LDocDecl, docDeclDoc, + -- ** Deprecations + WarnDecl(..), LWarnDecl, + -- ** Annotations + AnnDecl(..), LAnnDecl, + AnnProvenance(..), annProvenanceName_maybe, modifyAnnProvenanceNameM, + + -- * Grouping + HsGroup(..), emptyRdrGroup, emptyRnGroup, appendGroups ) 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 CoreSyn ( RuleName ) -import {- Kind parts of -} Type ( Kind, pprKind ) -import BasicTypes ( Activation(..), DeprecTxt ) -import ForeignCall ( CCallTarget(..), DNCallSpec, CCallConv, Safety, - CExportSpec(..), CLabelString ) +import HsDoc +import NameSet +import {- Kind parts of -} Type +import BasicTypes +import ForeignCall -- others: -import Class ( FunDep, pprFundeps ) +import Class import Outputable -import Util ( count ) -import SrcLoc ( Located(..), unLoc, noLoc ) +import Util +import SrcLoc import FastString -import Maybe ( isJust ) -\end{code} +import Control.Monad ( liftM ) +import Data.Maybe ( isJust ) +\end{code} %************************************************************************ %* * @@ -64,17 +88,21 @@ import Maybe ( isJust ) \begin{code} type LHsDecl id = Located (HsDecl id) +-- | A Haskell Declaration data HsDecl id - = TyClD (TyClDecl id) - | InstD (InstDecl id) + = TyClD (TyClDecl id) -- ^ A type or class declaration. + | InstD (InstDecl id) -- ^ An instance declaration. | DerivD (DerivDecl id) | ValD (HsBind id) | SigD (Sig id) | DefD (DefaultDecl id) | ForD (ForeignDecl id) - | DeprecD (DeprecDecl id) + | WarningD (WarnDecl id) + | AnnD (AnnDecl id) | RuleD (RuleDecl id) | SpliceD (SpliceDecl id) + | DocD (DocDecl) + -- NB: all top-level fixity decls are contained EITHER -- EITHER SigDs @@ -89,7 +117,7 @@ data HsDecl id -- -- The latter is for class methods only --- A [HsDecl] is categorised into a HsGroup before being +-- | A 'HsDecl' is categorised into a 'HsGroup' before being -- fed to the renamer. data HsGroup id = HsGroup { @@ -104,8 +132,11 @@ data HsGroup id hs_defds :: [LDefaultDecl id], hs_fords :: [LForeignDecl id], - hs_depds :: [LDeprecDecl id], - hs_ruleds :: [LRuleDecl id] + hs_warnds :: [LWarnDecl id], + hs_annds :: [LAnnDecl id], + hs_ruleds :: [LRuleDecl id], + + hs_docs :: [LDocDecl] } emptyGroup, emptyRdrGroup, emptyRnGroup :: HsGroup a @@ -113,9 +144,10 @@ emptyRdrGroup = emptyGroup { hs_valds = emptyValBindsIn } emptyRnGroup = emptyGroup { hs_valds = emptyValBindsOut } 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_fixds = [], hs_defds = [], hs_annds = [], + hs_fords = [], hs_warnds = [], hs_ruleds = [], + hs_valds = error "emptyGroup hs_valds: Can't happen", + hs_docs = [] } appendGroups :: HsGroup a -> HsGroup a -> HsGroup a appendGroups @@ -126,9 +158,11 @@ appendGroups hs_derivds = derivds1, hs_fixds = fixds1, hs_defds = defds1, + hs_annds = annds1, 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, @@ -136,34 +170,40 @@ appendGroups hs_derivds = derivds2, hs_fixds = fixds2, hs_defds = defds2, + hs_annds = annds2, 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_fixds = fixds1 ++ fixds2, + hs_annds = annds1 ++ annds2, 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 (DerivD deriv) = ppr deriv - 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 (AnnD ad) = ppr ad + ppr (SpliceD dd) = ppr dd + ppr (DocD doc) = ppr doc instance OutputableBndr name => Outputable (HsGroup name) where ppr (HsGroup { hs_valds = val_decls, @@ -171,24 +211,26 @@ instance OutputableBndr name => Outputable (HsGroup name) where hs_instds = inst_decls, hs_derivds = deriv_decls, hs_fixds = fix_decls, - hs_depds = deprec_decls, + hs_warnds = deprec_decls, + hs_annds = ann_decls, hs_fords = foreign_decls, hs_defds = default_decls, hs_ruleds = rule_decls }) = vcat [ppr_ds fix_decls, ppr_ds default_decls, - ppr_ds deprec_decls, ppr_ds rule_decls, + ppr_ds deprec_decls, ppr_ds ann_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 - ppr_ds ds = text "" $$ vcat (map ppr ds) + ppr_ds ds = blankLine $$ vcat (map ppr ds) 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} @@ -332,20 +374,11 @@ 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 -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- Kind signatures of indexed types come in two flavours: --- --- * kind signatures for type functions: variant `TyFunction' and --- --- * kind signatures for indexed data types and newtypes : variant `TyData' --- iff a kind is present in `tcdKindSig' and there are no constructors in --- `tcdCons'. +-- 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: @@ -354,9 +387,9 @@ Interface file code: -- 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, +-- * 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 'tcdVars' are the variables in those patterns. Hence, the arity of +-- 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'. -- @@ -364,103 +397,133 @@ Interface file code: type LTyClDecl name = Located (TyClDecl name) +-- | A type or class declaration. data TyClDecl name = ForeignType { tcdLName :: Located name, - tcdExtName :: Maybe FastString, - tcdFoType :: FoType - } + tcdExtName :: Maybe FastString + } + - | TyData { tcdND :: NewOrData, - tcdCtxt :: LHsContext name, -- Context - tcdLName :: Located name, -- Type constructor - tcdTyVars :: [LHsTyVarBndr name], -- Type variables - tcdTyPats :: Maybe [LHsType name], -- Type patterns - tcdKindSig:: Maybe Kind, -- Optional kind sig; - -- (only for the - -- 'where' form and - -- indexed type sigs) + | -- | @type/data family T :: *->*@ + TyFamily { tcdFlavour:: FamilyFlavour, -- type or data + tcdLName :: Located name, -- type constructor + tcdTyVars :: [LHsTyVarBndr name], -- type variables + tcdKind :: Maybe Kind -- result kind + } - 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 + + | -- | 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 + + 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 signature. + -- + -- @(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 'LConDecl's all have 'ResTyH98'. + -- For @data T a where { T1 :: T a }@ + -- the 'LConDecls' all have 'ResTyGADT'. tcdDerivs :: Maybe [LHsType name] - -- Derivings; Nothing => not specified - -- Just [] => derive exactly what is asked + -- ^ Derivings; @Nothing@ => not specified, + -- @Just []@ => derive exactly what is asked + -- -- These "types" must be of form + -- @ -- forall ab. C ty1 ty2 + -- @ -- Typically the foralls and ty args are empty, but they -- are non-empty for the newtype-deriving case } - | TyFunction {tcdLName :: Located name, -- type constructor - tcdTyVars :: [LHsTyVarBndr name], -- type variables - tcdIso :: Bool, -- injective type? - tcdKind :: Kind -- result kind - } + | 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 - | TySynonym { tcdLName :: Located name, -- type constructor - tcdTyVars :: [LHsTyVarBndr name], -- type variables - tcdTyPats :: Maybe [LHsType name], -- Type patterns - -- 'Nothing' => vanilla - -- type synonym - tcdSynRhs :: LHsType name -- synonym expansion + tcdSynRhs :: LHsType name -- ^ synonym expansion } - | ClassDecl { tcdCtxt :: LHsContext name, -- Context... - tcdLName :: Located name, -- Name of the class - tcdTyVars :: [LHsTyVarBndr name], -- Class type variables - tcdFDs :: [Located (FunDep name)], -- Functional deps - tcdSigs :: [LSig name], -- Methods' signatures - tcdMeths :: LHsBinds name, -- Default methods - tcdATs :: [LTyClDecl name] -- Associated types; ie - -- only 'TyData', - -- 'TyFunction', - -- and 'TySynonym' + | ClassDecl { tcdCtxt :: LHsContext name, -- ^ Context... + tcdLName :: Located name, -- ^ Name of the class + tcdTyVars :: [LHsTyVarBndr name], -- ^ Class type variables + tcdFDs :: [Located (FunDep name)], -- ^ Functional deps + tcdSigs :: [LSig name], -- ^ Methods' signatures + tcdMeths :: LHsBinds name, -- ^ Default methods + tcdATs :: [LTyClDecl name], -- ^ Associated types; ie + -- only 'TyFamily' and + -- 'TySynonym'; the + -- latter for defaults + tcdDocs :: [LDocDecl] -- ^ 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} -isTFunDecl, isDataDecl, isSynDecl, isClassDecl, isKindSigDecl, isIdxTyDecl :: - TyClDecl name -> Bool +-- | @True@ <=> argument is a @data@\/@newtype@ or @data@\/@newtype instance@ +-- declaration. +isDataDecl :: TyClDecl name -> Bool +isDataDecl (TyData {}) = True +isDataDecl _other = False --- type function kind signature -isTFunDecl (TyFunction {}) = True -isTFunDecl other = False +-- | type or type instance declaration +isTypeDecl :: TyClDecl name -> Bool +isTypeDecl (TySynonym {}) = True +isTypeDecl _other = False --- vanilla Haskell type synonym +-- | vanilla Haskell type synonym (ie, not a type instance) +isSynDecl :: TyClDecl name -> Bool isSynDecl (TySynonym {tcdTyPats = Nothing}) = True -isSynDecl other = False - --- type equation (of a type function) -isTEqnDecl (TySynonym {tcdTyPats = Just _}) = True -isTEqnDecl other = False - -isDataDecl (TyData {}) = True -isDataDecl other = False +isSynDecl _other = False +-- | type class +isClassDecl :: TyClDecl name -> Bool isClassDecl (ClassDecl {}) = True -isClassDecl other = False - --- kind signature (for an indexed type) -isKindSigDecl (TyFunction {} ) = True -isKindSigDecl (TyData {tcdKindSig = Just _, - tcdCons = [] }) = True -isKindSigDecl other = False - --- definition of an instance of an indexed type -isIdxTyDecl tydecl - | isTEqnDecl tydecl = True - | isDataDecl tydecl = isJust (tcdTyPats tydecl) - | otherwise = False +isClassDecl _ = False + +-- | type family declaration +isFamilyDecl :: TyClDecl name -> Bool +isFamilyDecl (TyFamily {}) = True +isFamilyDecl _other = False + +-- | family instance (types, newtypes, and data types) +isFamInstDecl :: TyClDecl name -> Bool +isFamInstDecl tydecl + | isTypeDecl tydecl + || isDataDecl tydecl = isJust (tcdTyPats tydecl) + | otherwise = False \end{code} Dealing with names @@ -470,12 +533,12 @@ tcdName :: TyClDecl name -> name tcdName decl = unLoc (tcdLName decl) tyClDeclNames :: Eq name => TyClDecl name -> [Located name] --- Returns all the *binding* names of the decl, along with their SrcLocs --- The first one is guaranteed to be the name of the decl --- For record fields, the first one counts as the SrcLoc --- We use the equality to filter out duplicate field names +-- ^ Returns all the /binding/ names of the decl, along with their SrcLocs. +-- The first one is guaranteed to be the name of the decl. For record fields +-- mentioned in multiple constructors, the SrcLoc will be from the first +-- occurence. We use the equality to filter out duplicate field names -tyClDeclNames (TyFunction {tcdLName = name}) = [name] +tyClDeclNames (TyFamily {tcdLName = name}) = [name] tyClDeclNames (TySynonym {tcdLName = name}) = [name] tyClDeclNames (ForeignType {tcdLName = name}) = [name] @@ -484,9 +547,10 @@ tyClDeclNames (ClassDecl {tcdLName = cls_name, tcdSigs = sigs, tcdATs = ats}) concatMap (tyClDeclNames . unLoc) ats ++ [n | L _ (TypeSig n _) <- sigs] tyClDeclNames (TyData {tcdLName = tc_name, tcdCons = cons}) - = tc_name : conDeclsNames (map unLoc cons) + = tc_name : hsConDeclsNames cons -tyClDeclTyVars (TyFunction {tcdTyVars = tvs}) = tvs +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 @@ -495,21 +559,20 @@ tyClDeclTyVars (ForeignType {}) = [] \begin{code} countTyClDecls :: [TyClDecl name] -> (Int, Int, Int, Int, Int, Int) - -- class, synonym decls, type function signatures, - -- type function equations, data, newtype + -- class, synonym decls, data, newtype, family decls, family instances countTyClDecls decls - = (count isClassDecl decls, - count isSynDecl decls, - count isTFunDecl decls, - count isTEqnDecl 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} @@ -517,21 +580,24 @@ instance OutputableBndr name => Outputable (TyClDecl name) where ppr (ForeignType {tcdLName = ltycon}) - = hsep [ptext SLIT("foreign import type dotnet"), ppr ltycon] + = hsep [ptext (sLit "foreign import type dotnet"), ppr ltycon] - ppr (TyFunction {tcdLName = ltycon, tcdTyVars = tyvars, tcdIso = iso, - tcdKind = kind}) - = typeMaybeIso <+> pp_decl_head [] ltycon tyvars Nothing <+> - dcolon <+> pprKind kind + ppr (TyFamily {tcdFlavour = flavour, tcdLName = ltycon, + tcdTyVars = tyvars, tcdKind = mb_kind}) + = pp_flavour <+> pp_decl_head [] ltycon tyvars Nothing <+> pp_kind where - typeMaybeIso = if iso - then ptext SLIT("type family iso") - else ptext SLIT("type family") + 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) <+> + = hang (ptext (sLit "type") <+> + (if isJust typats then ptext (sLit "instance") else empty) <+> pp_decl_head [] ltycon tyvars typats <+> equals) 4 (ppr mono_ty) @@ -541,7 +607,7 @@ instance OutputableBndr name tcdCons = condecls, tcdDerivs = derivings}) = pp_tydecl (null condecls && isJust mb_sig) (ppr new_or_data <+> - (if isJust typats then ptext SLIT("instance") else empty) <+> + (if isJust typats then ptext (sLit "instance") else empty) <+> pp_decl_head (unLoc context) ltycon tyvars typats <+> ppr_sig mb_sig) (pp_condecls condecls) @@ -557,13 +623,13 @@ instance OutputableBndr name = top_matter | otherwise -- Laid out - = sep [hsep [top_matter, ptext SLIT("where {")], + = 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") + top_matter = ptext (sLit "class") <+> pp_decl_head (unLoc context) lclas tyvars Nothing <+> pprFundeps (map unLoc fds) ppr_semi decl = ppr decl <> semi @@ -580,24 +646,26 @@ 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 True 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)] + 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} @@ -624,45 +692,74 @@ type LConDecl name = Located (ConDecl name) data ConDecl name = ConDecl - { con_name :: Located name -- Constructor name; this is used for the - -- DataCon itself, and for the user-callable wrapper Id - - , con_explicit :: HsExplicitForAll -- Is there an user-written forall? (cf. HStypes.HsForAllTy) - - , con_qvars :: [LHsTyVarBndr name] -- ResTyH98: the constructor's existential type variables - -- ResTyGADT: all the constructor's quantified type variables - - , con_cxt :: LHsContext name -- The context. This *does not* include the - -- "stupid theta" which lives only in the TyData decl + { con_name :: Located name + -- ^ Constructor name. This is used for the DataCon itself, and for + -- the user-callable wrapper Id. + + , con_explicit :: HsExplicitForAll + -- ^ Is there an user-written forall? (cf. 'HsTypes.HsForAllTy') + + , con_qvars :: [LHsTyVarBndr name] + -- ^ Type variables. Depending on 'con_res' this describes the + -- follewing entities + -- + -- - ResTyH98: the constructor's *existential* type variables + -- - ResTyGADT: *all* the constructor's quantified type variables + + , con_cxt :: LHsContext name + -- ^ The context. This /does not/ include the \"stupid theta\" which + -- lives only in the 'TyData' decl. + + , con_details :: HsConDeclDetails name + -- ^ The main payload + + , con_res :: ResType name + -- ^ Result type of the constructor + + , con_doc :: Maybe LHsDocString + -- ^ A possible Haddock comment. + + , con_old_rec :: Bool + -- ^ TEMPORARY field; True <=> user has employed now-deprecated syntax for + -- GADT-style record decl C { blah } :: T a b + -- Remove this when we no longer parse this stuff, and hence do not + -- need to report decprecated use + } - , con_details :: HsConDetails name (LBangType name) -- The main payload +type HsConDeclDetails name = HsConDetails (LBangType name) [ConDeclField name] - , con_res :: ResType name -- Result type of the constructor - } +hsConDeclArgTys :: HsConDeclDetails name -> [LBangType name] +hsConDeclArgTys (PrefixCon tys) = tys +hsConDeclArgTys (InfixCon ty1 ty2) = [ty1,ty2] +hsConDeclArgTys (RecCon flds) = map cd_fld_type flds data ResType name = ResTyH98 -- Constructor was declared using Haskell 98 syntax | ResTyGADT (LHsType name) -- Constructor was declared using GADT-style syntax, -- and here is its result type + +instance OutputableBndr name => Outputable (ResType name) where + -- Debugging only + ppr ResTyH98 = ptext (sLit "ResTyH98") + ppr (ResTyGADT ty) = ptext (sLit "ResTyGADT") <+> pprParendHsType (unLoc ty) \end{code} \begin{code} -conDeclsNames :: Eq name => [ConDecl name] -> [Located name] +hsConDeclsNames :: (Eq name) => [LConDecl 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 -conDeclsNames cons +hsConDeclsNames 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) + do_one (flds_seen, acc) (L _ (ConDecl { con_name = lname, con_details = RecCon flds })) + = (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) + do_one (flds_seen, acc) (L _ (ConDecl { con_name = lname })) + = (flds_seen, lname:acc) \end{code} @@ -670,23 +767,32 @@ 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_name =con, con_explicit = expl, con_qvars = tvs + , con_cxt = cxt, con_details = details + , con_res = ResTyH98, con_doc = 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 + ppr_details con (RecCon fields) = ppr con <+> pprConDeclFields fields -pprConDecl (ConDecl con expl tvs cxt (PrefixCon arg_tys) (ResTyGADT res_ty)) +pprConDecl (ConDecl { con_name = con, con_explicit = expl, con_qvars = tvs + , con_cxt = cxt, con_details = PrefixCon arg_tys + , con_res = 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_name = con, con_explicit = expl, con_qvars = tvs + , con_cxt = cxt, con_details = RecCon fields, con_res = ResTyGADT res_ty }) + = sep [ppr con <+> dcolon <+> pprHsForAll expl tvs cxt, + pprConDeclFields fields <+> arrow <+> ppr res_ty] + +pprConDecl (ConDecl {con_name = con, con_details = InfixCon {}, con_res = ResTyGADT {} }) + = pprPanic "pprConDecl" (ppr con) + -- In GADT syntax we don't allow infix constructors \end{code} %************************************************************************ @@ -710,10 +816,10 @@ data InstDecl name instance (OutputableBndr name) => Outputable (InstDecl name) where ppr (InstDecl inst_ty binds uprags ats) - = vcat [hsep [ptext SLIT("instance"), ppr inst_ty, ptext SLIT("where")], - nest 4 (ppr ats), - nest 4 (ppr uprags), - nest 4 (pprLHsBinds binds) ] + = 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 -- @@ -730,12 +836,11 @@ instDeclATs (InstDecl _ _ _ ats) = ats \begin{code} type LDerivDecl name = Located (DerivDecl name) -data DerivDecl name - = DerivDecl (Located name) (LHsType name) +data DerivDecl name = DerivDecl (LHsType name) instance (OutputableBndr name) => Outputable (DerivDecl name) where - ppr (DerivDecl cls ty) - = hsep [ptext SLIT("deriving"), ppr cls, ppr ty] + ppr (DerivDecl ty) + = hsep [ptext (sLit "deriving instance"), ppr ty] \end{code} %************************************************************************ @@ -758,7 +863,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} %************************************************************************ @@ -801,13 +906,8 @@ data ForeignImport = -- import of a C entity CImport CCallConv -- ccall or stdcall Safety -- safe or unsafe FastString -- name of C header - FastString -- name of library object CImportSpec -- details of the C entity - -- import of a .NET function - -- - | DNImport DNCallSpec - -- details of an external C entity -- data CImportSpec = CLabel CLabelString -- import address of a C label @@ -819,53 +919,36 @@ data CImportSpec = CLabel CLabelString -- import address of a C label -- convention -- data ForeignExport = CExport CExportSpec -- contains the calling convention - | DNExport -- presently unused - --- abstract type imported from .NET --- -data FoType = DNType -- In due course we'll add subtype stuff - deriving (Eq) -- Used for equality instance for TyClDecl - -- pretty printing of foreign declarations -- instance OutputableBndr name => Outputable (ForeignDecl name) where ppr (ForeignImport n ty fimport) = - ptext SLIT("foreign import") <+> ppr fimport <+> - ppr n <+> dcolon <+> ppr ty + hang (ptext (sLit "foreign import") <+> ppr fimport <+> ppr n) + 2 (dcolon <+> ppr ty) ppr (ForeignExport n ty fexport) = - ptext SLIT("foreign export") <+> ppr fexport <+> - ppr n <+> dcolon <+> ppr ty + 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 - ppr (CImport cconv safety header lib spec) = + ppr (CImport cconv safety header spec) = ppr cconv <+> ppr safety <+> - char '"' <> pprCEntity header lib spec <> char '"' + char '"' <> pprCEntity spec <> char '"' where - pprCEntity header lib (CLabel lbl) = - ptext SLIT("static") <+> ftext header <+> char '&' <> - pprLib lib <> ppr lbl - pprCEntity header lib (CFunction (StaticTarget lbl)) = - ptext SLIT("static") <+> ftext header <+> char '&' <> - pprLib lib <> ppr lbl - pprCEntity header lib (CFunction (DynamicTarget)) = - ptext SLIT("dynamic") - pprCEntity _ _ (CWrapper) = ptext SLIT("wrapper") - -- - pprLib lib | nullFS lib = empty - | otherwise = char '[' <> ppr lib <> char ']' + pp_hdr = if nullFS header then empty else ftext header + + pprCEntity (CLabel lbl) = + ptext (sLit "static") <+> pp_hdr <+> char '&' <> ppr lbl + pprCEntity (CFunction (StaticTarget lbl)) = + ptext (sLit "static") <+> pp_hdr <+> ppr lbl + pprCEntity (CFunction (DynamicTarget)) = + ptext (sLit "dynamic") + pprCEntity (CWrapper) = ptext (sLit "wrapper") instance Outputable ForeignExport where ppr (CExport (CExportStatic lbl cconv)) = ppr cconv <+> char '"' <> ppr lbl <> char '"' - ppr (DNExport ) = - ptext SLIT("dotnet") <+> ptext SLIT("\"\"") - -instance Outputable FoType where - ppr DNType = ptext SLIT("type dotnet") \end{code} @@ -896,7 +979,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 "#-}") ] @@ -909,6 +992,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 = Located (DocDecl) + +data DocDecl + = DocCommentNext HsDocString + | DocCommentPrev HsDocString + | DocCommentNamed String HsDocString + | DocGroup Int HsDocString + +-- Okay, I need to reconstruct the document comments, but for now: +instance Outputable DocDecl where + ppr _ = text "" + +docDeclDoc :: DocDecl -> HsDocString +docDeclDoc (DocCommentNext d) = d +docDeclDoc (DocCommentPrev d) = d +docDeclDoc (DocCommentNamed _ d) = d +docDeclDoc (DocGroup _ d) = d + +\end{code} %************************************************************************ %* * @@ -919,11 +1029,50 @@ 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} + +%************************************************************************ +%* * +\subsection[AnnDecl]{Annotations} +%* * +%************************************************************************ + +\begin{code} +type LAnnDecl name = Located (AnnDecl name) + +data AnnDecl name = HsAnnotation (AnnProvenance name) (Located (HsExpr name)) + +instance (OutputableBndr name) => Outputable (AnnDecl name) where + ppr (HsAnnotation provenance expr) + = hsep [text "{-#", pprAnnProvenance provenance, pprExpr (unLoc expr), text "#-}"] + + +data AnnProvenance name = ValueAnnProvenance name + | TypeAnnProvenance name + | ModuleAnnProvenance + +annProvenanceName_maybe :: AnnProvenance name -> Maybe name +annProvenanceName_maybe (ValueAnnProvenance name) = Just name +annProvenanceName_maybe (TypeAnnProvenance name) = Just name +annProvenanceName_maybe ModuleAnnProvenance = Nothing + +-- TODO: Replace with Traversable instance when GHC bootstrap version rises high enough +modifyAnnProvenanceNameM :: Monad m => (before -> m after) -> AnnProvenance before -> m (AnnProvenance after) +modifyAnnProvenanceNameM fm prov = + case prov of + ValueAnnProvenance name -> liftM ValueAnnProvenance (fm name) + TypeAnnProvenance name -> liftM TypeAnnProvenance (fm name) + ModuleAnnProvenance -> return ModuleAnnProvenance + +pprAnnProvenance :: OutputableBndr name => AnnProvenance name -> SDoc +pprAnnProvenance ModuleAnnProvenance = ptext (sLit "ANN module") +pprAnnProvenance (ValueAnnProvenance name) = ptext (sLit "ANN") <+> ppr name +pprAnnProvenance (TypeAnnProvenance name) = ptext (sLit "ANN type") <+> ppr name +\end{code}