Commit 803fc5db authored by Alan Zimmerman's avatar Alan Zimmerman Committed by Austin Seipp

Add API Annotations

Summary:
The final design and discussion is captured at
https://ghc.haskell.org/trac/ghc/wiki/GhcAstAnnotations

This is a proof of concept implementation of a completely
separate annotation structure, populated in the parser,and tied to the
AST by means of a virtual "node-key" comprising the surrounding
SrcSpan and a value derived from the specific constructor used for the
node.

The key parts of the design are the following.

== The Annotations ==

In `hsSyn/ApiAnnotation.hs`

```lang=haskell
type ApiAnns = (Map.Map ApiAnnKey SrcSpan, Map.Map SrcSpan [Located Token])

type ApiAnnKey = (SrcSpan,AnnKeywordId)

-- ---------------------------------------------------------------------

-- | Retrieve an annotation based on the @SrcSpan@ of the annotated AST
-- element, and the known type of the annotation.
getAnnotation :: ApiAnns -> SrcSpan -> AnnKeywordId -> Maybe SrcSpan
getAnnotation (anns,_) span ann = Map.lookup (span,ann) anns

-- |Retrieve the comments allocated to the current @SrcSpan@
getAnnotationComments :: ApiAnns -> SrcSpan -> [Located Token]
getAnnotationComments (_,anns) span =
  case Map.lookup span anns of
    Just cs -> cs
    Nothing -> []

-- | Note: in general the names of these are taken from the
-- corresponding token, unless otherwise noted
data AnnKeywordId
         = AnnAs
         | AnnBang
         | AnnClass
         | AnnClose -- ^ } or ] or ) or #) etc
         | AnnComma
         | AnnDarrow
         | AnnData
         | AnnDcolon
         ....
```

== Capturing in the lexer/parser ==

The annotations are captured in the lexer / parser by extending PState to include a field

In `parser/Lexer.x`

```lang=haskell
data PState = PState {
        ....
        annotations :: [(ApiAnnKey,SrcSpan)]
        -- Annotations giving the locations of 'noise' tokens in the
        -- source, so that users of the GHC API can do source to
        -- source conversions.
     }
```

The lexer exposes a helper function to add an annotation

```lang=haskell
addAnnotation :: SrcSpan -> Ann -> SrcSpan -> P ()
addAnnotation l a v = P $ \s -> POk s {
  annotations = ((AK l a), v) : annotations s
  } ()

```

The parser also has some helper functions of the form

```lang=haskell
type MaybeAnn = Maybe (SrcSpan -> P ())

gl = getLoc
gj x = Just (gl x)

ams :: Located a -> [MaybeAnn] -> P (Located a)
ams a@(L l _) bs = (mapM_ (\a -> a l) $ catMaybes bs) >> return a
```

This allows annotations to be captured in the parser by means of

```
ctypedoc :: { LHsType RdrName }
        : 'forall' tv_bndrs '.' ctypedoc {% hintExplicitForall (getLoc $1) >>
                                            ams (LL $ mkExplicitHsForAllTy $2 (noLoc []) $4)
                                                [mj AnnForall $1,mj AnnDot $3] }
        | context '=>' ctypedoc         {% ams (LL $ mkQualifiedHsForAllTy   $1 $3)
                                               [mj AnnDarrow $2] }
        | ipvar '::' type               {% ams (LL (HsIParamTy (unLoc $1) $3))
                                               [mj AnnDcolon $2] }
        | typedoc                       { $1 }
```

== Parse result ==

```lang-haskell
data HsParsedModule = HsParsedModule {
    hpm_module    :: Located (HsModule RdrName),
    hpm_src_files :: [FilePath],
       -- ^ extra source files (e.g. from #includes).  The lexer collects
       -- these from '# <file> <line>' pragmas, which the C preprocessor
       -- leaves behind.  These files and their timestamps are stored in
       -- the .hi file, so that we can force recompilation if any of
       -- them change (#3589)
    hpm_annotations :: ApiAnns
  }

-- | The result of successful parsing.
data ParsedModule =
  ParsedModule { pm_mod_summary   :: ModSummary
               , pm_parsed_source :: ParsedSource
               , pm_extra_src_files :: [FilePath]
               , pm_annotations :: ApiAnns }
```

This diff depends on D426

Test Plan: sh ./validate

Reviewers: austin, simonpj, Mikolaj

Reviewed By: simonpj, Mikolaj

Subscribers: Mikolaj, goldfire, thomie, carter

Differential Revision: https://phabricator.haskell.org/D438

GHC Trac Issues: #9628
parent 7927658e
......@@ -246,6 +246,9 @@ Note that (Foo a) might not be an instance of Ord.
\begin{code}
-- | A data constructor
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClose','ApiAnnotation.AnnComma'
data DataCon
= MkData {
dcName :: Name, -- This is the name of the *source data con*
......
......@@ -331,6 +331,7 @@ Library
OptCoercion
Parser
RdrHsSyn
ApiAnnotation
ForeignCall
PrelInfo
PrelNames
......
......@@ -537,6 +537,7 @@ compiler_stage2_dll0_MODULES = \
InstEnv \
Kind \
Lexeme \
ApiAnnotation \
ListSetOps \
Literal \
LoadIface \
......@@ -599,6 +600,7 @@ ifeq "$(GhcWithInterpreter)" "YES"
# These files are reacheable from DynFlags
# only by GHCi-enabled code (see #9552)
compiler_stage2_dll0_MODULES += \
ApiAnnotation \
Bitmap \
BlockId \
ByteCodeAsm \
......
......@@ -119,6 +119,13 @@ data HsBindLR idL idR
-- But note that the form @f :: a->a = ...@
-- parses as a pattern binding, just like
-- @(f :: a -> a) = ... @
--
-- 'ApiAnnotation.AnnKeywordId's
--
-- - 'ApiAnnotation.AnnFunId', attached to each element of fun_matches
--
-- - 'ApiAnnotation.AnnEqual','ApiAnnotation.AnnWhere',
-- 'ApiAnnotation.AnnOpen','ApiAnnotation.AnnClose',
FunBind {
fun_id :: Located idL,
......@@ -129,10 +136,12 @@ data HsBindLR idL idR
fun_co_fn :: HsWrapper, -- ^ Coercion from the type of the MatchGroup to the type of
-- the Id. Example:
--
-- @
-- f :: Int -> forall a. a -> a
-- f x y = y
-- @
--
-- Then the MatchGroup will have type (Int -> a' -> a')
-- (with a free type variable a'). The coercion will take
-- a CoreExpr of this type and convert it to a CoreExpr of
......@@ -150,6 +159,10 @@ data HsBindLR idL idR
-- | The pattern is never a simple variable;
-- That case is done by FunBind
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnBang',
-- 'ApiAnnotation.AnnEqual','ApiAnnotation.AnnWhere',
-- 'ApiAnnotation.AnnOpen','ApiAnnotation.AnnClose',
| PatBind {
pat_lhs :: LPat idL,
pat_rhs :: GRHSs idR (LHsExpr idR),
......@@ -183,6 +196,9 @@ data HsBindLR idL idR
}
| PatSynBind (PatSynBind idL idR)
-- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnPattern',
-- 'ApiAnnotation.AnnLarrow','ApiAnnotation.AnnWhere'
-- 'ApiAnnotation.AnnOpen','ApiAnnotation.AnnClose'
deriving (Typeable)
deriving instance (DataId idL, DataId idR)
......@@ -525,12 +541,16 @@ isEmptyIPBinds :: HsIPBinds id -> Bool
isEmptyIPBinds (IPBinds is ds) = null is && isEmptyTcEvBinds ds
type LIPBind id = Located (IPBind id)
-- ^ May have 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnSemi' when in a
-- list
-- | Implicit parameter bindings.
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnEqual'
{- These bindings start off as (Left "x") in the parser and stay
that way until after type-checking when they are replaced with
(Right d), where "d" is the name of the dictionary holding the
evidene for the implicit parameter. -}
evidence for the implicit parameter. -}
data IPBind id
= IPBind (Either HsIPName id) (LHsExpr id)
deriving (Typeable)
......@@ -566,6 +586,9 @@ type LSig name = Located (Sig name)
data Sig name
= -- | An ordinary type signature
-- @f :: Num a => a -> a@
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnDcolon',
-- 'ApiAnnotation.AnnComma'
TypeSig [Located name] (LHsType name)
-- | A pattern synonym type signature
......@@ -587,11 +610,15 @@ data Sig name
-- the desired Id itself, replete with its name, type
-- and IdDetails. Otherwise it's just like a type
-- signature: there should be an accompanying binding
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnDefault',
-- 'ApiAnnotation.AnnDcolon','ApiAnnotation.AnnDotdot'
| IdSig Id
-- | An ordinary fixity declaration
--
-- > infixl *** 8
-- > infixl 8 ***
--
| FixSig (FixitySig name)
......@@ -599,6 +626,10 @@ data Sig name
--
-- > {#- INLINE f #-}
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClose','ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnVal','ApiAnnotation.AnnTilde',
-- 'ApiAnnotation.AnnClose'
| InlineSig (Located name) -- Function name
InlinePragma -- Never defaultInlinePragma
......@@ -606,6 +637,10 @@ data Sig name
--
-- > {-# SPECIALISE f :: Int -> Int #-}
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnOpen','ApiAnnotation.AnnTilde',
-- 'ApiAnnotation.AnnVal','ApiAnnotation.AnnClose',
-- 'ApiAnnotation.AnnDcolon','ApiAnnotation.AnnClose',
| SpecSig (Located name) -- Specialise a function or datatype ...
[LHsType name] -- ... to these types
InlinePragma -- The pragma on SPECIALISE_INLINE form.
......@@ -618,11 +653,18 @@ data Sig name
--
-- (Class tys); should be a specialisation of the
-- current instance declaration
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnInstance','ApiAnnotation.AnnClose'
| SpecInstSig (LHsType name)
-- | A minimal complete definition pragma
--
-- > {-# MINIMAL a | (b, c | (d | e)) #-}
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnVbar','ApiAnnotation.AnnComma',
-- 'ApiAnnotation.AnnClose'
| MinimalSig (BooleanFormula (Located name))
deriving (Typeable)
......
......@@ -117,6 +117,10 @@ import Data.Maybe
\begin{code}
type LHsDecl id = Located (HsDecl id)
-- ^ When in a list this may have
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnSemi'
--
-- | A Haskell Declaration
data HsDecl id
......@@ -459,9 +463,19 @@ type LTyClDecl name = Located (TyClDecl name)
-- | A type or class declaration.
data TyClDecl name
= -- | @type/data family T :: *->*@
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnType',
-- 'ApiAnnotation.AnnData',
-- 'ApiAnnotation.AnnFamily','ApiAnnotation.AnnWhere',
-- 'ApiAnnotation.AnnOpen','ApiAnnotation.AnnDcolon',
-- 'ApiAnnotation.AnnClose'
FamDecl { tcdFam :: FamilyDecl name }
| -- | @type@ declaration
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnType',
-- 'ApiAnnotation.AnnEqual',
SynDecl { tcdLName :: Located name -- ^ Type constructor
, tcdTyVars :: LHsTyVarBndrs name -- ^ Type variables; for an associated type
-- these include outer binders
......@@ -469,6 +483,11 @@ data TyClDecl name
, tcdFVs :: PostRn name NameSet }
| -- | @data@ declaration
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnData',
-- 'ApiAnnotation.AnnFamily',
-- 'ApiAnnotation.AnnNewType',
-- 'ApiAnnotation.AnnNewType','ApiAnnotation.AnnWhere'
DataDecl { tcdLName :: Located name -- ^ Type constructor
, tcdTyVars :: LHsTyVarBndrs name -- ^ Type variables; for an assoicated type
-- these include outer binders
......@@ -491,6 +510,12 @@ data TyClDecl name
tcdDocs :: [LDocDecl], -- ^ Haddock docs
tcdFVs :: PostRn name NameSet
}
-- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnClass',
-- 'ApiAnnotation.AnnWhere','ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClose'
-- - The tcdFDs will have 'ApiAnnotation.AnnVbar',
-- 'ApiAnnotation.AnnComma'
-- 'ApiAnnotation.AnnRarrow'
deriving (Typeable)
deriving instance (DataId id) => Data (TyClDecl id)
......@@ -799,7 +824,11 @@ data HsDataDefn name -- The payload of a data type defn
-- @
-- Typically the foralls and ty args are empty, but they
-- are non-empty for the newtype-deriving case
}
--
-- - 'ApiAnnotation.AnnKeywordId' :
-- 'ApiAnnotation.AnnDeriving',
-- 'ApiAnnotation.AnnOpen','ApiAnnotation.AnnClose'
}
deriving( Typeable )
deriving instance (DataId id) => Data (HsDataDefn id)
......@@ -809,19 +838,30 @@ data NewOrData
deriving( Eq, Data, Typeable ) -- Needed because Demand derives Eq
type LConDecl name = Located (ConDecl name)
-- ^ May have 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnSemi' when
-- in a GADT constructor list
-- |
--
-- @
-- data T b = forall a. Eq a => MkT a b
-- MkT :: forall b a. Eq a => MkT a b
--
-- data T b where
-- MkT1 :: Int -> T Int
--
-- data T = Int `MkT` Int
-- | MkT2
--
-- data T a where
-- Int `MkT` Int :: T Int
-- @
--
-- - 'ApiAnnotation.AnnKeywordId's : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnDotdot','ApiAnnotation.AnnCLose',
-- 'ApiAnnotation.AnnEqual','ApiAnnotation.AnnVbar',
-- 'ApiAnnotation.AnnDarrow','ApiAnnotation.AnnDarrow',
-- 'ApiAnnotation.AnnForall','ApiAnnotation.AnnDot'
data ConDecl name
= ConDecl
{ con_names :: [Located name]
......@@ -992,6 +1032,8 @@ It is parameterised over its tfe_pats field:
\begin{code}
----------------- Type synonym family instances -------------
type LTyFamInstEqn name = Located (TyFamInstEqn name)
-- ^ May have 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnSemi'
-- when in a list
type LTyFamDefltEqn name = Located (TyFamDefltEqn name)
type HsTyPats name = HsWithBndrs name [LHsType name]
......@@ -1009,6 +1051,8 @@ data TyFamEqn name pats
{ tfe_tycon :: Located name
, tfe_pats :: pats
, tfe_rhs :: LHsType name }
-- ^
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnEqual'
deriving( Typeable )
deriving instance (DataId name, Data pats) => Data (TyFamEqn name pats)
......@@ -1017,6 +1061,9 @@ data TyFamInstDecl name
= TyFamInstDecl
{ tfid_eqn :: LTyFamInstEqn name
, tfid_fvs :: PostRn name NameSet }
-- ^
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnType',
-- 'ApiAnnotation.AnnInstance',
deriving( Typeable )
deriving instance (DataId name) => Data (TyFamInstDecl name)
......@@ -1028,8 +1075,13 @@ data DataFamInstDecl name
{ dfid_tycon :: Located name
, dfid_pats :: HsTyPats name -- LHS
, dfid_defn :: HsDataDefn name -- RHS
, dfid_fvs :: PostRn name NameSet } -- Rree vars for
-- dependency analysis
, dfid_fvs :: PostRn name NameSet } -- Free vars for
-- dependency analysis
-- ^
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnData',
-- 'ApiAnnotation.AnnNewType','ApiAnnotation.AnnInstance',
-- 'ApiAnnotation.AnnWhere','ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClose'
deriving( Typeable )
deriving instance (DataId name) => Data (DataFamInstDecl name)
......@@ -1047,7 +1099,15 @@ data ClsInstDecl name
, cid_tyfam_insts :: [LTyFamInstDecl name] -- Type family instances
, cid_datafam_insts :: [LDataFamInstDecl name] -- Data family instances
, cid_overlap_mode :: Maybe (Located OverlapMode)
-- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClose',
}
-- ^
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnInstance',
-- 'ApiAnnotation.AnnWhere',
-- 'ApiAnnotation.AnnOpen','ApiAnnotation.AnnClose',
--
deriving (Typeable)
deriving instance (DataId id) => Data (ClsInstDecl id)
......@@ -1184,6 +1244,10 @@ type LDerivDecl name = Located (DerivDecl name)
data DerivDecl name = DerivDecl
{ deriv_type :: LHsType name
, deriv_overlap_mode :: Maybe (Located OverlapMode)
-- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClose',
-- 'ApiAnnotation.AnnDeriving',
-- 'ApiAnnotation.AnnInstance',
}
deriving (Typeable)
deriving instance (DataId name) => Data (DerivDecl name)
......@@ -1208,6 +1272,9 @@ type LDefaultDecl name = Located (DefaultDecl name)
data DefaultDecl name
= DefaultDecl [LHsType name]
-- ^ - 'ApiAnnotation.AnnKeywordId's : 'ApiAnnotation.AnnDefault',
-- 'ApiAnnotation.AnnOpen','ApiAnnotation.AnnClose'
deriving (Typeable)
deriving instance (DataId name) => Data (DefaultDecl name)
......@@ -1243,6 +1310,10 @@ data ForeignDecl name
(LHsType name) -- sig_ty
(PostTc name Coercion) -- sig_ty ~ rep_ty
ForeignExport
-- ^
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnForeign',
-- 'ApiAnnotation.AnnImport','ApiAnnotation.AnnExport',
-- 'ApiAnnotation.AnnDcolon'
deriving (Typeable)
deriving instance (DataId name) => Data (ForeignDecl name)
{-
......@@ -1358,6 +1429,11 @@ data RuleDecl name
(PostRn name NameSet) -- Free-vars from the LHS
(Located (HsExpr name)) -- RHS
(PostRn name NameSet) -- Free-vars from the RHS
-- ^
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnEqual',
-- 'ApiAnnotation.AnnOpen','ApiAnnotation.AnnVal',
-- 'ApiAnnotation.AnnClose','ApiAnnotation.AnnTilde',
-- 'ApiAnnotation.AnnForall','ApiAnnotation.AnnDot',
deriving (Typeable)
deriving instance (DataId name) => Data (RuleDecl name)
......@@ -1365,6 +1441,9 @@ type LRuleBndr name = Located (RuleBndr name)
data RuleBndr name
= RuleBndr (Located name)
| RuleBndrSig (Located name) (HsWithBndrs name (LHsType name))
-- ^
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnDcolon','ApiAnnotation.AnnClose'
deriving (Typeable)
deriving instance (DataId name) => Data (RuleBndr name)
......@@ -1409,18 +1488,27 @@ data VectDecl name
= HsVect
(Located name)
(LHsExpr name)
-- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnEqual','ApiAnnotation.AnnClose'
| HsNoVect
(Located name)
-- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClose'
| HsVectTypeIn -- pre type-checking
Bool -- 'TRUE' => SCALAR declaration
(Located name)
(Maybe (Located name)) -- 'Nothing' => no right-hand side
-- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnType','ApiAnnotation.AnnClose',
-- 'ApiAnnotation.AnnEqual'
| HsVectTypeOut -- post type-checking
Bool -- 'TRUE' => SCALAR declaration
TyCon
(Maybe TyCon) -- 'Nothing' => no right-hand side
| HsVectClassIn -- pre type-checking
(Located name)
-- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClass','ApiAnnotation.AnnClose',
| HsVectClassOut -- post type-checking
Class
| HsVectInstIn -- pre type-checking (always SCALAR) !!!FIXME: should be superfluous now
......@@ -1536,6 +1624,10 @@ instance OutputableBndr name => Outputable (WarnDecl name) where
type LAnnDecl name = Located (AnnDecl name)
data AnnDecl name = HsAnnotation (AnnProvenance name) (Located (HsExpr name))
-- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnType'
-- 'ApiAnnotation.AnnModule'
-- 'ApiAnnotation.AnnClose'
deriving (Typeable)
deriving instance (DataId name) => Data (AnnDecl name)
......@@ -1574,6 +1666,8 @@ type LRoleAnnotDecl name = Located (RoleAnnotDecl name)
data RoleAnnotDecl name
= RoleAnnotDecl (Located name) -- type constructor
[Located (Maybe Role)] -- optional annotations
-- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnType',
-- 'ApiAnnotation.AnnRole'
deriving (Data, Typeable)
instance OutputableBndr name => Outputable (RoleAnnotDecl name) where
......
......@@ -52,6 +52,8 @@ import Data.Data hiding (Fixity)
-- * Expressions proper
type LHsExpr id = Located (HsExpr id)
-- ^ May have 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnComma' when
-- in a list
-------------------------
-- | PostTcExpr is an evidence expression attached to the syntax tree by the
......@@ -132,9 +134,15 @@ data HsExpr id
| HsLit HsLit -- ^ Simple (non-overloaded) literals
| HsLam (MatchGroup id (LHsExpr id)) -- ^ Lambda abstraction. Currently always a single match
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnLam',
-- 'ApiAnnotation.AnnRarrow',
| HsLamCase (PostTc id Type) (MatchGroup id (LHsExpr id)) -- ^ Lambda-case
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnLam',
-- 'ApiAnnotation.AnnCase','ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClose'
| HsApp (LHsExpr id) (LHsExpr id) -- ^ Application
-- | Operator applications:
......@@ -149,10 +157,18 @@ data HsExpr id
(LHsExpr id) -- right operand
-- | Negation operator. Contains the negated expression and the name
-- of 'negate'
| NegApp (LHsExpr id)
(SyntaxExpr id)
-- of 'negate'
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnMinus'
| NegApp (LHsExpr id)
(SyntaxExpr id)
-- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClose'
-- - Note: if 'ApiAnnotation.AnnVal' is present this is actually an
-- inactive 'HsSCC'
-- - Note: if multiple 'ApiAnnotation.AnnVal' are
-- present this is actually an inactive 'HsTickPragma'
| HsPar (LHsExpr id) -- ^ Parenthesised expr; see Note [Parens in HsSyn]
| SectionL (LHsExpr id) -- operand; see Note [Sections in HsSyn]
......@@ -161,13 +177,23 @@ data HsExpr id
(LHsExpr id) -- operand
-- | Used for explicit tuples and sections thereof
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClose'
| ExplicitTuple
[LHsTupArg id]
Boxity
-- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnCase',
-- 'ApiAnnotation.AnnOf','ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClose'
| HsCase (LHsExpr id)
(MatchGroup id (LHsExpr id))
-- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnIf',
-- 'ApiAnnotation.AnnSemi',
-- 'ApiAnnotation.AnnThen','ApiAnnotation.AnnSemi2',
-- 'ApiAnnotation.AnnElse',
| HsIf (Maybe (SyntaxExpr id)) -- cond function
-- Nothing => use the built-in 'if'
-- See Note [Rebindable if]
......@@ -176,12 +202,23 @@ data HsExpr id
(LHsExpr id) -- else part
-- | Multi-way if
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnIf'
-- 'ApiAnnotation.AnnOpen','ApiAnnotation.AnnClose',
| HsMultiIf (PostTc id Type) [LGRHS id (LHsExpr id)]
-- | let(rec)
| HsLet (HsLocalBinds id)
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnLet',
-- 'ApiAnnotation.AnnIn','ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClose'
| HsLet (HsLocalBinds id)
(LHsExpr id)
-- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnDo',
-- 'ApiAnnotation.AnnOpen', 'ApiAnnotation.AnnSemi',
-- 'ApiAnnotation.AnnVbar',
-- 'ApiAnnotation.AnnClose'
| HsDo (HsStmtContext Name) -- The parameterisation is unimportant
-- because in this context we never use
-- the PatGuard or ParStmt variant
......@@ -189,23 +226,37 @@ data HsExpr id
(PostTc id Type) -- Type of the whole expression
-- | Syntactic list: [a,b,c,...]
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClose'
| ExplicitList
(PostTc id Type) -- Gives type of components of list
(Maybe (SyntaxExpr id)) -- For OverloadedLists, the fromListN witness
[LHsExpr id]
-- | Syntactic parallel array: [:e1, ..., en:]
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnDotdot','ApiAnnotation.AnnComma',
-- 'ApiAnnotation.AnnVbar'
-- 'ApiAnnotation.AnnClose'
| ExplicitPArr
(PostTc id Type) -- type of elements of the parallel array
[LHsExpr id]
-- | Record construction
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnDotdot','ApiAnnotation.AnnClose'
| RecordCon (Located id) -- The constructor. After type checking
-- it's the dataConWrapId of the constructor
PostTcExpr -- Data con Id applied to type args
(HsRecordBinds id)
-- | Record update
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnDotdot','ApiAnnotation.AnnClose'
| RecordUpd (LHsExpr id)
(HsRecordBinds id)
-- (HsMatchGroup Id) -- Filled in by the type checker to be
......@@ -218,8 +269,10 @@ data HsExpr id
-- For a type family, the arg types are of the *instance* tycon,
-- not the family tycon
-- | Expression with an explicit type signature. @e :: type@
| ExprWithTySig
-- | Expression with an explicit type signature. @e :: type@
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnDcolon'
| ExprWithTySig
(LHsExpr id)
(LHsType id)
......@@ -229,7 +282,11 @@ data HsExpr id
-- round-tripping purposes
-- | Arithmetic sequence
| ArithSeq
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnDotdot','ApiAnnotation.AnnComma',
-- 'ApiAnnotation.AnnClose'
| ArithSeq
PostTcExpr
(Maybe (SyntaxExpr id)) -- For OverloadedLists, the fromList witness
(ArithSeqInfo id)
......@@ -239,15 +296,22 @@ data HsExpr id
PostTcExpr -- [:e1..e2:] or [:e1, e2..e3:]
(ArithSeqInfo id)
-- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnVal', 'ApiAnnotation.AnnClose'
| HsSCC FastString -- "set cost centre" SCC pragma
(LHsExpr id) -- expr whose cost is to be measured
-- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnVal', 'ApiAnnotation.AnnClose'
| HsCoreAnn FastString -- hdaume: core annotation
(LHsExpr id)
-----------------------------------------------------------
-- MetaHaskell Extensions
-- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnOpen','ApiAnnotation.AnnClose',
-- 'ApiAnnotation.AnnClose'
| HsBracket (HsBracket id)
-- See Note [Pending Splices]
......@@ -262,6 +326,8 @@ data HsExpr id
[PendingTcSplice] -- _typechecked_ splices to be
-- pasted back in by the desugarer
-- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClose'
| HsSpliceE Bool -- True <=> typed splice
(HsSplice id) -- False <=> untyped
......@@ -272,6 +338,9 @@ data HsExpr id
-- Arrow notation extension
-- | @proc@ notation for Arrows
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnProc',
-- 'ApiAnnotation.AnnRarrow'
| HsProc (LPat id) -- arrow abstraction, proc
(LHsCmdTop id) -- body of the abstraction
-- always has an empty stack
......@@ -280,6 +349,10 @@ data HsExpr id
-- The following are commands, not expressions proper
-- They are only used in the parsing stage and are removed
-- immediately in parser.RdrHsSyn.checkCommand
-- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.Annlarrowtail',
-- 'ApiAnnotation.Annrarrowtail','ApiAnnotation.AnnLarrowtail',
-- 'ApiAnnotation.AnnRarrowtail'
| HsArrApp -- Arrow tail, or arrow application (f -< arg)
(LHsExpr id) -- arrow expression, f
(LHsExpr id) -- input expression, arg
......@@ -289,6 +362,8 @@ data HsExpr id
Bool -- True => right-to-left (f -< arg)
-- False => left-to-right (arg >- f)
-- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnClose'
| HsArrForm -- Command formation, (| e cmd1 .. cmdn |)
(LHsExpr id) -- the operator
-- after type-checking, a type abstraction to be
......@@ -309,6 +384,14 @@ data HsExpr id
Int -- module-local tick number for False
(LHsExpr id) -- sub-expression
-- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnOpen',
-- 'ApiAnnotation.AnnVal','ApiAnnotation.AnnVal2',
-- 'ApiAnnotation.AnnColon','ApiAnnotation.AnnVal3',
-- 'ApiAnnotation.AnnMinus',
-- 'ApiAnnotation.AnnVal4','ApiAnnotation.AnnColon2',
-- 'ApiAnnotation.AnnVal5',
-- 'ApiAnnotation.AnnClose'
| HsTickPragma -- A pragma introduced tick
(FastString,(Int,Int),(Int,Int)) -- external span for this tick
(LHsExpr id)
......@@ -319,12 +402,15 @@ data HsExpr id
| EWildPat -- wildcard
-- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnAt'
| EAsPat (Located id) -- as pattern
(LHsExpr id)
-- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnRarrow'
| EViewPat (LHsExpr id) -- view pattern
(LHsExpr id)
-- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnTilde'
| ELazyPat (LHsExpr id) -- ~ pattern
| HsType (LHsType id) -- Explicit type argument; e.g f {| Int |} x y
......@@ -342,6 +428,7 @@ deriving instance (DataId id) => Data (HsExpr id)