summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/GHC/Parser/Annotation.hs1028
1 files changed, 964 insertions, 64 deletions
diff --git a/compiler/GHC/Parser/Annotation.hs b/compiler/GHC/Parser/Annotation.hs
index 33e48a1a50..9d158c95b7 100644
--- a/compiler/GHC/Parser/Annotation.hs
+++ b/compiler/GHC/Parser/Annotation.hs
@@ -1,27 +1,106 @@
+{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE FlexibleInstances #-}
module GHC.Parser.Annotation (
+ -- * Out-of-tree API Annotations. Exist for the duration of !5158,
+ -- * will be removed by !2418
getAnnotation, getAndRemoveAnnotation,
getAnnotationComments,getAndRemoveAnnotationComments,
ApiAnns(..),
ApiAnnKey,
+ AddAnn(..), mkParensApiAnn,
+
+ -- * Core API Annotation types
AnnKeywordId(..),
- AddAnn(..),mkParensApiAnn,
AnnotationComment(..),
IsUnicodeSyntax(..),
unicodeAnn,
HasE(..),
- LRdrName -- Exists for haddocks only
+
+ -- * In-tree Api Annotations
+ AddApiAnn(..),
+ AnnAnchor(..), annAnchorRealSrcSpan,
+ DeltaPos(..),
+
+ ApiAnn, ApiAnn'(..), Anchor(..), AnchorOperation(..),
+ spanAsAnchor, realSpanAsAnchor,
+ noAnn,
+
+ -- ** Comments in Annotations
+
+ ApiAnnComments(..), LAnnotationComment, com, noCom,
+ getFollowingComments, setFollowingComments, setPriorComments,
+ ApiAnnCO,
+
+ -- ** Annotations in 'GenLocated'
+ LocatedA, LocatedL, LocatedC, LocatedN, LocatedAn, LocatedP,
+ SrcSpanAnnA, SrcSpanAnnL, SrcSpanAnnP, SrcSpanAnnC, SrcSpanAnnN, SrcSpanAnn'(..),
+
+ -- ** Annotation data types used in 'GenLocated'
+
+ AnnListItem(..), AnnList(..),
+ AnnParen(..), ParenType(..), parenTypeKws,
+ AnnPragma(..),
+ AnnContext(..),
+ NameAnn(..), NameAdornment(..),
+ NoApiAnns(..),
+ AnnSortKey(..),
+
+ -- ** Trailing annotations in lists
+ TrailingAnn(..), addTrailingAnnToA, addTrailingAnnToL, addTrailingCommaToN,
+
+ -- ** Utilities for converting between different 'GenLocated' when
+ -- ** we do not care about the annotations.
+ la2na, na2la, n2l, l2n, l2l, la2la,
+ reLoc, reLocA, reLocL, reLocC, reLocN,
+
+ la2r, realSrcSpan,
+
+ -- ** Building up annotations
+ extraToAnnList, reAnn,
+ reAnnL, reAnnC,
+ addAnns, addAnnsA, widenSpan, widenAnchor, widenAnchorR, widenLocatedAn,
+
+ -- ** Querying annotations
+ getLocAnn,
+ apiAnnAnns, apiAnnAnnsL,
+ annParen2AddApiAnn,
+
+ -- ** Working with locations of annotations
+ sortLocatedA,
+ mapLocA,
+ combineLocsA,
+ combineSrcSpansA,
+ addCLocA, addCLocAA,
+
+ -- ** Constructing 'GenLocated' annotation types when we do not care about annotations.
+ noLocA, getLocA,
+ noSrcSpanA,
+ noAnnSrcSpan,
+
+ -- ** Working with comments in annotations
+ noComments, comment, addCommentsToSrcAnn, setCommentsSrcAnn,
+ addCommentsToApiAnn, setCommentsApiAnn,
+ transferComments,
+
+ placeholderRealSpan,
) where
import GHC.Prelude
-import GHC.Types.Name.Reader
-import GHC.Utils.Outputable
-import GHC.Types.SrcLoc
-import qualified Data.Map as Map
import Data.Data
-
+import Data.Function (on)
+import Data.List (sortBy)
+import qualified Data.Map as Map
+import Data.Semigroup
+import GHC.Data.FastString
+import GHC.Types.Name
+import GHC.Types.SrcLoc
+import GHC.Utils.Binary
+import GHC.Utils.Outputable hiding ( (<>) )
+import GHC.Utils.Panic
{-
Note [Api annotations]
@@ -34,22 +113,6 @@ elements from the original source: this includes keywords such as
braces, and also comments. We collectively refer to this
metadata as the "API annotations".
-Rather than annotate the resulting parse tree with these locations
-directly (this would be a major change to some fairly core data
-structures in GHC), we instead capture locations for these elements in a
-structure separate from the parse tree, and returned in the
-pm_annotations field of the ParsedModule type.
-
-The full ApiAnns type is
-
-> data ApiAnns =
-> ApiAnns
-> { apiAnnItems :: Map.Map ApiAnnKey [RealSrcSpan],
-> apiAnnEofPos :: Maybe RealSrcSpan,
-> apiAnnComments :: Map.Map RealSrcSpan [RealLocated AnnotationComment],
-> apiAnnRogueComments :: [RealLocated AnnotationComment]
-> }
-
NON-COMMENT ELEMENTS
Intuitively, every AST element directly contains a bag of keywords
@@ -57,62 +120,31 @@ Intuitively, every AST element directly contains a bag of keywords
can show up multiple times before the next AST element), each of which
needs to be associated with its location in the original source code.
-Consequently, the structure that records non-comment elements is logically
-a two level map, from the RealSrcSpan of the AST element containing it, to
-a map from keywords ('AnnKeyWord') to all locations of the keyword directly
-in the AST element:
-
-> type ApiAnnKey = (RealSrcSpan,AnnKeywordId)
->
-> Map.Map ApiAnnKey [RealSrcSpan]
-
-So
-
-> let x = 1 in 2 *x
-
-would result in the AST element
-
- L span (HsLet (binds for x = 1) (2 * x))
-
-and the annotations
-
- (span,AnnLet) having the location of the 'let' keyword
- (span,AnnEqual) having the location of the '=' sign
- (span,AnnIn) having the location of the 'in' keyword
+These keywords are recorded directly in the AST element in which they
+occur, for the GhcPs phase.
For any given element in the AST, there is only a set number of
keywords that are applicable for it (e.g., you'll never see an
'import' keyword associated with a let-binding.) The set of allowed
keywords is documented in a comment associated with the constructor
of a given AST element, although the ground truth is in GHC.Parser
-and GHC.Parser.PostProcess (which actually add the annotations; see #13012).
+and GHC.Parser.PostProcess (which actually add the annotations).
COMMENT ELEMENTS
-Every comment is associated with a *located* AnnotationComment.
We associate comments with the lowest (most specific) AST element
enclosing them:
-> Map.Map RealSrcSpan [RealLocated AnnotationComment]
-
PARSER STATE
-There are three fields in PState (the parser state) which play a role
+There is one field in PState (the parser state) which play a role
with annotations.
-> annotations :: [(ApiAnnKey,[RealSrcSpan])],
-> comment_q :: [RealLocated AnnotationComment],
-> annotations_comments :: [(RealSrcSpan,[RealLocated AnnotationComment])]
-
-The 'annotations' and 'annotations_comments' fields are simple: they simply
-accumulate annotations that will end up in 'ApiAnns' at the end
-(after they are passed to Map.fromList).
+> comment_q :: [LAnnotationComment],
The 'comment_q' field captures comments as they are seen in the token stream,
so that when they are ready to be allocated via the parser they are
-available (at the time we lex a comment, we don't know what the enclosing
-AST node of it is, so we can't associate it with a RealSrcSpan in
-annotations_comments).
+available.
PARSER EMISSION OF ANNOTATIONS
@@ -136,7 +168,9 @@ https://gitlab.haskell.org/ghc/ghc/wikis/api-annotations
-}
-- ---------------------------------------------------------------------
--- If you update this, update the Note [Api annotations] above
+-- This section should be removed when we move to the new APi Annotations
+
+
data ApiAnns =
ApiAnns
{ apiAnnItems :: Map.Map ApiAnnKey [RealSrcSpan],
@@ -229,6 +263,7 @@ getAndRemoveAnnotationComments anns span =
Nothing -> ([], anns)
where ann_comments = apiAnnComments anns
+-- End of section to be removed with new API Annotations
-- --------------------------------------------------------------------
-- | API Annotations exist so that tools can perform source to source
@@ -262,6 +297,7 @@ data AnnKeywordId
| AnnCloseQ -- ^ '|]'
| AnnCloseQU -- ^ '|]', unicode variant
| AnnCloseP -- ^ ')'
+ | AnnClosePH -- ^ '\#)'
| AnnCloseS -- ^ ']'
| AnnColon
| AnnComma -- ^ as a list separator
@@ -304,7 +340,7 @@ data AnnKeywordId
| AnnNewtype
| AnnName -- ^ where a name loses its location in the AST, this carries it
| AnnOf
- | AnnOpen -- ^ '(\#' or '{-\# LANGUAGE' etc
+ | AnnOpen -- ^ '{-\# LANGUAGE' etc
| AnnOpenB -- ^ '(|'
| AnnOpenBU -- ^ '(|', unicode variant
| AnnOpenC -- ^ '{'
@@ -313,6 +349,7 @@ data AnnKeywordId
| AnnOpenEQU -- ^ '[|', unicode variant
| AnnOpenP -- ^ '('
| AnnOpenS -- ^ '['
+ | AnnOpenPH -- ^ '(\#'
| AnnDollar -- ^ prefix '$' -- TemplateHaskell
| AnnDollarDollar -- ^ prefix '$$' -- TemplateHaskell
| AnnPackageName
@@ -378,8 +415,6 @@ instance Outputable AnnotationComment where
-- 'GHC.Parser.Annotation.AnnRarrow'
-- 'GHC.Parser.Annotation.AnnTilde'
-- - May have 'GHC.Parser.Annotation.AnnComma' when in a list
-type LRdrName = Located RdrName
-
-- | Certain tokens can have alternate representations when unicode syntax is
-- enabled. This flag is attached to those tokens in the lexer so that the
@@ -415,3 +450,868 @@ unicodeAnn ann = ann
-- This type indicates whether the 'e' is present or not.
data HasE = HasE | NoE
deriving (Eq, Ord, Data, Show)
+
+-- ---------------------------------------------------------------------
+
+-- | Captures an annotation, storing the @'AnnKeywordId'@ and its
+-- location. The parser only ever inserts @'AnnAnchor'@ fields with a
+-- RealSrcSpan being the original location of the annotation in the
+-- source file.
+-- The @'AnnAnchor'@ can also store a delta position if the AST has been
+-- modified and needs to be pretty printed again.
+-- The usual way an 'AddApiAnn' is created is using the 'mj' ("make
+-- jump") function, and then it can be inserted into the appropriate
+-- annotation.
+data AddApiAnn = AddApiAnn AnnKeywordId AnnAnchor deriving (Data,Show,Eq,Ord)
+
+-- | The anchor for an @'AnnKeywordId'@. The Parser inserts the @'AR'@
+-- variant, giving the exact location of the original item in the
+-- parsed source. This can be replace by the @'AD'@ version, to
+-- provide a position for the item relative to the end of the previous
+-- item in the source. This is useful when editing an AST prior to
+-- exact printing the changed one.
+data AnnAnchor = AR RealSrcSpan
+ | AD DeltaPos
+ deriving (Data,Show,Eq,Ord)
+
+-- | Relative position, line then column. If 'deltaLine' is zero then
+-- 'deltaColumn' gives the number of spaces between the end of the
+-- preceding output element and the start of the one this is attached
+-- to, on the same line. If 'deltaLine' is > 0, then it is the number
+-- of lines to advance, and 'deltaColumn' is the start column on the
+-- new line.
+data DeltaPos =
+ DP
+ { deltaLine :: !Int,
+ deltaColumn :: !Int
+ } deriving (Show,Eq,Ord,Data)
+
+
+annAnchorRealSrcSpan :: AnnAnchor -> RealSrcSpan
+annAnchorRealSrcSpan (AR r) = r
+annAnchorRealSrcSpan (AD _) = placeholderRealSpan
+
+instance Outputable AnnAnchor where
+ ppr (AR r) = text "AR" <+> ppr r
+ ppr (AD d) = text "AD" <+> ppr d
+
+instance Outputable AddApiAnn where
+ ppr (AddApiAnn kw ss) = text "AddApiAnn" <+> ppr kw <+> ppr ss
+
+-- ---------------------------------------------------------------------
+
+{-
+Note [In-tree Api annotations]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+GHC 7.10 brought in the concept of API Annotations,
+https://gitlab.haskell.org/ghc/ghc/-/wikis/api-annotations:
+
+ The hsSyn AST does not directly capture the locations of certain
+ keywords and punctuation, such as 'let', 'in', 'do', etc.
+
+ These locations are required by any tools wanting to parse a haskell
+ file, transform the AST in some way, and then regenerate the
+ original layout for the unchaged parts."
+
+These were returned in a separate data structure, linked to the main
+AST via a combination of SrcSpan and constructor name.
+
+This indirect linkage kept the AST uncluttered, but made working with
+the annotations complex, as two separate data structures had to be
+changed at the same time in a coherent way.
+
+From GHC 9.2.1, these annotations are captured directly in the AST,
+using the types in this file, and the Trees That Grow (TTG) extension
+points for GhcPs.
+
+See Note [XRec and Anno in the AST] for details of how this is done.
+-}
+
+-- | The API Annotations are now kept in the HsSyn AST for the GhcPs
+-- phase. We do not always have API Annotations though, only for
+-- parsed code. This type captures that, and allows the
+-- representation decision to be easily revisited as it evolves.
+--
+-- A goal of the annotations is that an AST can be edited, including
+-- moving subtrees from one place to another, duplicating them, and so
+-- on. This means that each fragment must be self-contained. To this
+-- end, each annotated fragment keeps track of the anchor position it
+-- was originally captured at, being simply the start span of the
+-- topmost element of the ast fragment. This gives us a way to later
+-- re-calculate all Located items in this layer of the AST, as well as
+-- any annotations captured. The comments associated with the AST
+-- fragment are also captured here.
+--
+-- The 'ann' type parameter allows this general structure to be
+-- specialised to the specific set of locations of original API
+-- Annotation elements. So for 'HsLet' we have
+--
+-- type instance XLet GhcPs = ApiAnn' AnnsLet
+-- data AnnsLet
+-- = AnnsLet {
+-- alLet :: AnnAnchor,
+-- alIn :: AnnAnchor
+-- } deriving Data
+--
+-- The spacing between the items under the scope of a given ApiAnn' is
+-- derived from the original 'Anchor'. But there is no requirement
+-- that the items included in the sub-element have a "matching"
+-- location in their relative anchors. This allows us to freely move
+-- elements around, and stitch together new AST fragments out of old
+-- ones, and have them still printed out in a reasonable way.
+data ApiAnn' ann
+ = ApiAnn { entry :: Anchor
+ -- ^ Base location for the start of the syntactic element
+ -- holding the annotations.
+ , anns :: ann -- ^ Annotations added by the Parser
+ , comments :: ApiAnnComments
+ -- ^ Comments enclosed in the SrcSpan of the element
+ -- this `ApiAnn'` is attached to
+ }
+ | ApiAnnNotUsed -- ^ No Annotation for generated code,
+ -- e.g. from TH, deriving, etc.
+ deriving (Data, Eq, Functor)
+
+-- | An 'Anchor' records the base location for the start of the
+-- syntactic element holding the annotations, and is used as the point
+-- of reference for calculating delta positions for contained
+-- annotations. If an AST element is moved or deleted, the original
+-- location is also tracked, for printing the source without gaps.
+data Anchor = Anchor { anchor :: RealSrcSpan
+ -- ^ Base location for the start of
+ -- the syntactic element holding
+ -- the annotations.
+ , anchor_op :: AnchorOperation }
+ deriving (Data, Eq, Show)
+
+-- | If tools modify the parsed source, the 'MovedAnchor' variant can
+-- directly provide the spacing for this item relative to the previous
+-- one when printing. This allows AST fragments with a particular
+-- anchor to be freely moved, without worrying about recalculating the
+-- appropriate anchor span.
+data AnchorOperation = UnchangedAnchor
+ | MovedAnchor DeltaPos
+ deriving (Data, Eq, Show)
+
+
+spanAsAnchor :: SrcSpan -> Anchor
+spanAsAnchor s = Anchor (realSrcSpan s) UnchangedAnchor
+
+realSpanAsAnchor :: RealSrcSpan -> Anchor
+realSpanAsAnchor s = Anchor s UnchangedAnchor
+
+-- ---------------------------------------------------------------------
+
+-- | When we are parsing we add comments that belong a particular AST
+-- element, and print them together with the element, interleaving
+-- them into the output stream. But when editin the AST, to move
+-- fragments around, it is useful to be able to first separate the
+-- comments into those occuring before the AST element and those
+-- following it. The 'AnnCommentsBalanced' constructor is used to do
+-- this. The GHC parser will only insert the 'AnnComments' form.
+data ApiAnnComments = AnnComments
+ { priorComments :: ![LAnnotationComment] }
+ | AnnCommentsBalanced
+ { priorComments :: ![LAnnotationComment]
+ , followingComments :: ![LAnnotationComment] }
+ deriving (Data, Eq)
+
+type LAnnotationComment = GenLocated Anchor AnnotationComment
+
+noCom :: ApiAnnComments
+noCom = AnnComments []
+
+com :: [LAnnotationComment] -> ApiAnnComments
+com cs = AnnComments cs
+
+-- ---------------------------------------------------------------------
+
+-- | This type is the most direct mapping of the previous API
+-- Annotations model. It captures the containing `SrcSpan' in its
+-- `entry` `Anchor`, has a list of `AddApiAnn` as before, and keeps
+-- track of the comments associated with the anchor.
+type ApiAnn = ApiAnn' [AddApiAnn]
+
+-- ---------------------------------------------------------------------
+-- Annotations attached to a 'SrcSpan'.
+-- ---------------------------------------------------------------------
+
+-- | The 'SrcSpanAnn\'' type wraps a normal 'SrcSpan', together with
+-- an extra annotation type. This is mapped to a specific `GenLocated`
+-- usage in the AST through the `XRec` and `Anno` type families.
+data SrcSpanAnn' a = SrcSpanAnn { ann :: a, locA :: SrcSpan }
+ deriving (Data, Eq)
+-- See Note [XRec and Anno in the AST]
+
+-- | We mostly use 'SrcSpanAnn\'' with an 'ApiAnn\''
+type SrcAnn ann = SrcSpanAnn' (ApiAnn' ann)
+-- AZ: is SrcAnn the right abbreviation here? Any better suggestions?
+
+-- AZ: should we rename LocatedA to LocatedL? The name comes from
+-- this being the most common usage, and hence being the default
+-- annotation. It also has a matching set if utility functions such as
+-- locA, noLocA, etc. LocatedL would then need a new name, but it is
+-- relatively rare, and captures a list having an openinc and closing
+-- adorment, such as parens, braces, etc.
+type LocatedA = GenLocated SrcSpanAnnA
+type LocatedN = GenLocated SrcSpanAnnN
+
+type LocatedL = GenLocated SrcSpanAnnL
+type LocatedP = GenLocated SrcSpanAnnP
+type LocatedC = GenLocated SrcSpanAnnC
+
+type SrcSpanAnnA = SrcAnn AnnListItem
+type SrcSpanAnnN = SrcAnn NameAnn
+
+type SrcSpanAnnL = SrcAnn AnnList
+type SrcSpanAnnP = SrcAnn AnnPragma
+type SrcSpanAnnC = SrcAnn AnnContext
+
+-- | General representation of a 'GenLocated' type carrying a
+-- parameterised annotation type.
+type LocatedAn an = GenLocated (SrcAnn an)
+
+{-
+Note [XRec and Anno in the AST]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The API annotations are now captured directly inside the AST, using
+TTG extension points. However certain annotations need to be captured
+on the Located versions too. While there is a general form for these,
+captured in the type SrcSpanAnn', there are also specific usages in
+different contexts.
+
+Some of the particular use cases are
+
+1) RdrNames, which can have additional items such as backticks or parens
+
+2) Items which occur in lists, and the annotation relates purely
+to its usage inside a list.
+
+See the section above this note for the rest.
+
+The Anno type family maps the specific SrcSpanAnn' variant for a given
+item.
+
+So
+
+ type instance XRec (GhcPass p) a = GenLocated (Anno a) a
+ type instance Anno RdrName = SrcSpanAnnN
+ type LocatedN = GenLocated SrcSpanAnnN
+
+meaning we can have type LocatedN RdrName
+
+-}
+
+-- ---------------------------------------------------------------------
+-- Annotations for items in a list
+-- ---------------------------------------------------------------------
+
+-- | Captures the location of punctuation occuring between items,
+-- normally in a list. It is captured as a trailing annotation.
+data TrailingAnn
+ = AddSemiAnn AnnAnchor -- ^ Trailing ';'
+ | AddCommaAnn AnnAnchor -- ^ Trailing ','
+ | AddVbarAnn AnnAnchor -- ^ Trailing '|'
+ | AddRarrowAnn AnnAnchor -- ^ Trailing '->'
+ | AddRarrowAnnU AnnAnchor -- ^ Trailing '->', unicode variant
+ deriving (Data,Show,Eq, Ord)
+
+instance Outputable TrailingAnn where
+ ppr (AddSemiAnn ss) = text "AddSemiAnn" <+> ppr ss
+ ppr (AddCommaAnn ss) = text "AddCommaAnn" <+> ppr ss
+ ppr (AddVbarAnn ss) = text "AddVbarAnn" <+> ppr ss
+ ppr (AddRarrowAnn ss) = text "AddRarrowAnn" <+> ppr ss
+ ppr (AddRarrowAnnU ss) = text "AddRarrowAnnU" <+> ppr ss
+
+-- | Annotation for items appearing in a list. They can have one or
+-- more trailing punctuations items, such as commas or semicolons.
+data AnnListItem
+ = AnnListItem {
+ lann_trailing :: [TrailingAnn]
+ }
+ deriving (Data, Eq)
+
+-- ---------------------------------------------------------------------
+-- Annotations for the context of a list of items
+-- ---------------------------------------------------------------------
+
+-- | Annotation for the "container" of a list. This captures
+-- surrounding items such as braces if present, and introductory
+-- keywords such as 'where'.
+data AnnList
+ = AnnList {
+ -- TODO:AZ: should we distinguish AnnList variants for lists
+ -- with layout and without?
+ al_anchor :: Maybe Anchor, -- ^ start point of a list having layout
+ al_open :: Maybe AddApiAnn,
+ al_close :: Maybe AddApiAnn,
+ al_rest :: [AddApiAnn], -- ^ context, such as 'where' keyword
+ al_trailing :: [TrailingAnn]
+ } deriving (Data,Eq)
+
+-- ---------------------------------------------------------------------
+-- Annotations for parenthesised elements, such as tuples, lists
+-- ---------------------------------------------------------------------
+
+-- | API Annotation for an item having surrounding "brackets", such as
+-- tuples or lists
+data AnnParen
+ = AnnParen {
+ ap_adornment :: ParenType,
+ ap_open :: AnnAnchor,
+ ap_close :: AnnAnchor
+ } deriving (Data)
+
+-- | Detail of the "brackets" used in an 'AnnParen' API Annotation.
+data ParenType
+ = AnnParens -- ^ '(', ')'
+ | AnnParensHash -- ^ '(#', '#)'
+ | AnnParensSquare -- ^ '[', ']'
+ deriving (Eq, Ord, Data)
+
+-- | Maps the 'ParenType' to the related opening and closing
+-- AnnKeywordId. Used when actually printing the item.
+parenTypeKws :: ParenType -> (AnnKeywordId, AnnKeywordId)
+parenTypeKws AnnParens = (AnnOpenP, AnnCloseP)
+parenTypeKws AnnParensHash = (AnnOpenPH, AnnClosePH)
+parenTypeKws AnnParensSquare = (AnnOpenS, AnnCloseS)
+
+-- ---------------------------------------------------------------------
+
+-- | API Annotation for the 'Context' data type.
+data AnnContext
+ = AnnContext {
+ ac_darrow :: Maybe (IsUnicodeSyntax, AnnAnchor),
+ -- ^ location and encoding of the '=>', if present.
+ ac_open :: [AnnAnchor], -- ^ zero or more opening parentheses.
+ ac_close :: [AnnAnchor] -- ^ zero or more closing parentheses.
+ } deriving (Data)
+
+
+-- ---------------------------------------------------------------------
+-- Annotations for names
+-- ---------------------------------------------------------------------
+
+-- | API Annotations for a 'RdrName'. There are many kinds of
+-- adornment that can be attached to a given 'RdrName'. This type
+-- captures them, as detailed on the individual constructors.
+data NameAnn
+ -- | Used for a name with an adornment, so '`foo`', '(bar)'
+ = NameAnn {
+ nann_adornment :: NameAdornment,
+ nann_open :: AnnAnchor,
+ nann_name :: AnnAnchor,
+ nann_close :: AnnAnchor,
+ nann_trailing :: [TrailingAnn]
+ }
+ -- | Used for @(,,,)@, or @(#,,,#)#
+ | NameAnnCommas {
+ nann_adornment :: NameAdornment,
+ nann_open :: AnnAnchor,
+ nann_commas :: [AnnAnchor],
+ nann_close :: AnnAnchor,
+ nann_trailing :: [TrailingAnn]
+ }
+ -- | Used for @()@, @(##)@, @[]@
+ | NameAnnOnly {
+ nann_adornment :: NameAdornment,
+ nann_open :: AnnAnchor,
+ nann_close :: AnnAnchor,
+ nann_trailing :: [TrailingAnn]
+ }
+ -- | Used for @->@, as an identifier
+ | NameAnnRArrow {
+ nann_name :: AnnAnchor,
+ nann_trailing :: [TrailingAnn]
+ }
+ -- | Used for an item with a leading @'@. The annotation for
+ -- unquoted item is stored in 'nann_quoted'.
+ | NameAnnQuote {
+ nann_quote :: AnnAnchor,
+ nann_quoted :: SrcSpanAnnN,
+ nann_trailing :: [TrailingAnn]
+ }
+ -- | Used when adding a 'TrailingAnn' to an existing 'LocatedN'
+ -- which has no Api Annotation (via the 'ApiAnnNotUsed' constructor.
+ | NameAnnTrailing {
+ nann_trailing :: [TrailingAnn]
+ }
+ deriving (Data, Eq)
+
+-- | A 'NameAnn' can capture the locations of surrounding adornments,
+-- such as parens or backquotes. This data type identifies what
+-- particular pair are being used.
+data NameAdornment
+ = NameParens -- ^ '(' ')'
+ | NameParensHash -- ^ '(#' '#)'
+ | NameBackquotes -- ^ '`'
+ | NameSquare -- ^ '[' ']'
+ deriving (Eq, Ord, Data)
+
+-- ---------------------------------------------------------------------
+
+-- | API Annotation used for capturing the locations of annotations in
+-- pragmas.
+data AnnPragma
+ = AnnPragma {
+ apr_open :: AddApiAnn,
+ apr_close :: AddApiAnn,
+ apr_rest :: [AddApiAnn]
+ } deriving (Data,Eq)
+
+-- ---------------------------------------------------------------------
+-- | Captures the sort order of sub elements. This is needed when the
+-- sub-elements have been split (as in a HsLocalBind which holds separate
+-- binds and sigs) or for infix patterns where the order has been
+-- re-arranged. It is captured explicitly so that after the Delta phase a
+-- SrcSpan is used purely as an index into the annotations, allowing
+-- transformations of the AST including the introduction of new Located
+-- items or re-arranging existing ones.
+data AnnSortKey
+ = NoAnnSortKey
+ | AnnSortKey [RealSrcSpan]
+ deriving (Data, Eq)
+
+-- ---------------------------------------------------------------------
+
+
+-- | Helper function used in the parser to add a 'TrailingAnn' items
+-- to an existing annotation.
+addTrailingAnnToL :: SrcSpan -> TrailingAnn -> ApiAnnComments
+ -> ApiAnn' AnnList -> ApiAnn' AnnList
+addTrailingAnnToL s t cs ApiAnnNotUsed
+ = ApiAnn (spanAsAnchor s) (AnnList (Just $ spanAsAnchor s) Nothing Nothing [] [t]) cs
+addTrailingAnnToL _ t cs n = n { anns = addTrailing (anns n)
+ , comments = comments n <> cs }
+ where
+ addTrailing n = n { al_trailing = t : al_trailing n }
+
+-- | Helper function used in the parser to add a 'TrailingAnn' items
+-- to an existing annotation.
+addTrailingAnnToA :: SrcSpan -> TrailingAnn -> ApiAnnComments
+ -> ApiAnn' AnnListItem -> ApiAnn' AnnListItem
+addTrailingAnnToA s t cs ApiAnnNotUsed
+ = ApiAnn (spanAsAnchor s) (AnnListItem [t]) cs
+addTrailingAnnToA _ t cs n = n { anns = addTrailing (anns n)
+ , comments = comments n <> cs }
+ where
+ addTrailing n = n { lann_trailing = t : lann_trailing n }
+
+-- | Helper function used in the parser to add a comma location to an
+-- existing annotation.
+addTrailingCommaToN :: SrcSpan -> ApiAnn' NameAnn -> AnnAnchor -> ApiAnn' NameAnn
+addTrailingCommaToN s ApiAnnNotUsed l
+ = ApiAnn (spanAsAnchor s) (NameAnnTrailing [AddCommaAnn l]) noCom
+addTrailingCommaToN _ n l = n { anns = addTrailing (anns n) l }
+ where
+ addTrailing :: NameAnn -> AnnAnchor -> NameAnn
+ addTrailing n l = n { nann_trailing = AddCommaAnn l : nann_trailing n }
+
+-- ---------------------------------------------------------------------
+
+-- |Helper function (temporary) during transition of names
+-- Discards any annotations
+l2n :: LocatedAn a1 a2 -> LocatedN a2
+l2n (L la a) = L (noAnnSrcSpan (locA la)) a
+
+n2l :: LocatedN a -> LocatedA a
+n2l (L la a) = L (na2la la) a
+
+-- |Helper function (temporary) during transition of names
+-- Discards any annotations
+la2na :: SrcSpanAnn' a -> SrcSpanAnnN
+la2na l = noAnnSrcSpan (locA l)
+
+-- |Helper function (temporary) during transition of names
+-- Discards any annotations
+la2la :: LocatedAn ann1 a2 -> LocatedAn ann2 a2
+la2la (L la a) = L (noAnnSrcSpan (locA la)) a
+
+l2l :: SrcSpanAnn' a -> SrcAnn ann
+l2l l = noAnnSrcSpan (locA l)
+
+-- |Helper function (temporary) during transition of names
+-- Discards any annotations
+na2la :: SrcSpanAnn' a -> SrcAnn ann
+na2la l = noAnnSrcSpan (locA l)
+
+reLoc :: LocatedAn a e -> Located e
+reLoc (L (SrcSpanAnn _ l) a) = L l a
+
+reLocA :: Located e -> LocatedAn ann e
+reLocA (L l a) = (L (SrcSpanAnn ApiAnnNotUsed l) a)
+
+reLocL :: LocatedN e -> LocatedA e
+reLocL (L l a) = (L (na2la l) a)
+
+reLocC :: LocatedN e -> LocatedC e
+reLocC (L l a) = (L (na2la l) a)
+
+reLocN :: LocatedN a -> Located a
+reLocN (L (SrcSpanAnn _ l) a) = L l a
+
+-- ---------------------------------------------------------------------
+
+realSrcSpan :: SrcSpan -> RealSrcSpan
+realSrcSpan (RealSrcSpan s _) = s
+realSrcSpan _ = mkRealSrcSpan l l -- AZ temporary
+ where
+ l = mkRealSrcLoc (fsLit "foo") (-1) (-1)
+
+la2r :: SrcSpanAnn' a -> RealSrcSpan
+la2r l = realSrcSpan (locA l)
+
+extraToAnnList :: AnnList -> [AddApiAnn] -> AnnList
+extraToAnnList (AnnList a o c e t) as = AnnList a o c (e++as) t
+
+reAnn :: [TrailingAnn] -> ApiAnnComments -> Located a -> LocatedA a
+reAnn anns cs (L l a) = L (SrcSpanAnn (ApiAnn (spanAsAnchor l) (AnnListItem anns) cs) l) a
+
+reAnnC :: AnnContext -> ApiAnnComments -> Located a -> LocatedC a
+reAnnC anns cs (L l a) = L (SrcSpanAnn (ApiAnn (spanAsAnchor l) anns cs) l) a
+
+reAnnL :: ann -> ApiAnnComments -> Located e -> GenLocated (SrcAnn ann) e
+reAnnL anns cs (L l a) = L (SrcSpanAnn (ApiAnn (spanAsAnchor l) anns cs) l) a
+
+getLocAnn :: Located a -> SrcSpanAnnA
+getLocAnn (L l _) = SrcSpanAnn ApiAnnNotUsed l
+
+
+getLocA :: GenLocated (SrcSpanAnn' a) e -> SrcSpan
+getLocA (L (SrcSpanAnn _ l) _) = l
+
+noLocA :: a -> LocatedAn an a
+noLocA = L (SrcSpanAnn ApiAnnNotUsed noSrcSpan)
+
+noAnnSrcSpan :: SrcSpan -> SrcAnn ann
+noAnnSrcSpan l = SrcSpanAnn ApiAnnNotUsed l
+
+noSrcSpanA :: SrcAnn ann
+noSrcSpanA = noAnnSrcSpan noSrcSpan
+
+-- | Short form for 'ApiAnnNotUsed'
+noAnn :: ApiAnn' a
+noAnn = ApiAnnNotUsed
+
+
+addAnns :: ApiAnn -> [AddApiAnn] -> ApiAnnComments -> ApiAnn
+addAnns (ApiAnn l as1 cs) as2 cs2
+ = ApiAnn (widenAnchor l (as1 ++ as2)) (as1 ++ as2) (cs <> cs2)
+addAnns ApiAnnNotUsed [] (AnnComments []) = ApiAnnNotUsed
+addAnns ApiAnnNotUsed [] (AnnCommentsBalanced [] []) = ApiAnnNotUsed
+addAnns ApiAnnNotUsed as cs = ApiAnn (Anchor placeholderRealSpan UnchangedAnchor) as cs
+
+-- AZ:TODO use widenSpan here too
+addAnnsA :: SrcSpanAnnA -> [TrailingAnn] -> ApiAnnComments -> SrcSpanAnnA
+addAnnsA (SrcSpanAnn (ApiAnn l as1 cs) loc) as2 cs2
+ = SrcSpanAnn (ApiAnn l (AnnListItem (lann_trailing as1 ++ as2)) (cs <> cs2)) loc
+addAnnsA (SrcSpanAnn ApiAnnNotUsed loc) [] (AnnComments [])
+ = SrcSpanAnn ApiAnnNotUsed loc
+addAnnsA (SrcSpanAnn ApiAnnNotUsed loc) [] (AnnCommentsBalanced [] [])
+ = SrcSpanAnn ApiAnnNotUsed loc
+addAnnsA (SrcSpanAnn ApiAnnNotUsed loc) as cs
+ = SrcSpanAnn (ApiAnn (spanAsAnchor loc) (AnnListItem as) cs) loc
+
+-- | The annotations need to all come after the anchor. Make sure
+-- this is the case.
+widenSpan :: SrcSpan -> [AddApiAnn] -> SrcSpan
+widenSpan s as = foldl combineSrcSpans s (go as)
+ where
+ go [] = []
+ go (AddApiAnn _ (AR s):rest) = RealSrcSpan s Nothing : go rest
+ go (AddApiAnn _ (AD _):rest) = go rest
+
+-- | The annotations need to all come after the anchor. Make sure
+-- this is the case.
+widenRealSpan :: RealSrcSpan -> [AddApiAnn] -> RealSrcSpan
+widenRealSpan s as = foldl combineRealSrcSpans s (go as)
+ where
+ go [] = []
+ go (AddApiAnn _ (AR s):rest) = s : go rest
+ go (AddApiAnn _ (AD _):rest) = go rest
+
+widenAnchor :: Anchor -> [AddApiAnn] -> Anchor
+widenAnchor (Anchor s op) as = Anchor (widenRealSpan s as) op
+
+widenAnchorR :: Anchor -> RealSrcSpan -> Anchor
+widenAnchorR (Anchor s op) r = Anchor (combineRealSrcSpans s r) op
+
+widenLocatedAn :: SrcSpanAnn' an -> [AddApiAnn] -> SrcSpanAnn' an
+widenLocatedAn (SrcSpanAnn a l) as = SrcSpanAnn a (widenSpan l as)
+
+apiAnnAnnsL :: ApiAnn' a -> [a]
+apiAnnAnnsL ApiAnnNotUsed = []
+apiAnnAnnsL (ApiAnn _ anns _) = [anns]
+
+apiAnnAnns :: ApiAnn -> [AddApiAnn]
+apiAnnAnns ApiAnnNotUsed = []
+apiAnnAnns (ApiAnn _ anns _) = anns
+
+annParen2AddApiAnn :: ApiAnn' AnnParen -> [AddApiAnn]
+annParen2AddApiAnn ApiAnnNotUsed = []
+annParen2AddApiAnn (ApiAnn _ (AnnParen pt o c) _)
+ = [AddApiAnn ai o, AddApiAnn ac c]
+ where
+ (ai,ac) = parenTypeKws pt
+
+-- TODO: enable when we migrate
+-- apiAnnComments :: ApiAnn' an -> ApiAnnComments
+-- apiAnnComments ApiAnnNotUsed = AnnComments []
+-- apiAnnComments (ApiAnn _ _ cs) = cs
+
+-- ---------------------------------------------------------------------
+-- sortLocatedA :: [LocatedA a] -> [LocatedA a]
+sortLocatedA :: [GenLocated (SrcSpanAnn' a) e] -> [GenLocated (SrcSpanAnn' a) e]
+sortLocatedA = sortBy (leftmost_smallest `on` getLocA)
+
+mapLocA :: (a -> b) -> GenLocated SrcSpan a -> GenLocated (SrcAnn ann) b
+mapLocA f (L l a) = L (noAnnSrcSpan l) (f a)
+
+-- AZ:TODO: move this somewhere sane
+
+combineLocsA :: Semigroup a => GenLocated (SrcSpanAnn' a) e1 -> GenLocated (SrcSpanAnn' a) e2 -> SrcSpanAnn' a
+combineLocsA (L a _) (L b _) = combineSrcSpansA a b
+
+combineSrcSpansA :: Semigroup a => SrcSpanAnn' a -> SrcSpanAnn' a -> SrcSpanAnn' a
+combineSrcSpansA (SrcSpanAnn aa la) (SrcSpanAnn ab lb)
+ = SrcSpanAnn (aa <> ab) (combineSrcSpans la lb)
+
+-- | Combine locations from two 'Located' things and add them to a third thing
+addCLocA :: GenLocated (SrcSpanAnn' a) e1 -> GenLocated SrcSpan e2 -> e3 -> GenLocated (SrcAnn ann) e3
+addCLocA a b c = L (noAnnSrcSpan $ combineSrcSpans (locA $ getLoc a) (getLoc b)) c
+
+addCLocAA :: GenLocated (SrcSpanAnn' a1) e1 -> GenLocated (SrcSpanAnn' a2) e2 -> e3 -> GenLocated (SrcAnn ann) e3
+addCLocAA a b c = L (noAnnSrcSpan $ combineSrcSpans (locA $ getLoc a) (locA $ getLoc b)) c
+
+-- ---------------------------------------------------------------------
+-- Utilities for manipulating ApiAnnComments
+-- ---------------------------------------------------------------------
+
+getFollowingComments :: ApiAnnComments -> [LAnnotationComment]
+getFollowingComments (AnnComments _) = []
+getFollowingComments (AnnCommentsBalanced _ cs) = cs
+
+setFollowingComments :: ApiAnnComments -> [LAnnotationComment] -> ApiAnnComments
+setFollowingComments (AnnComments ls) cs = AnnCommentsBalanced ls cs
+setFollowingComments (AnnCommentsBalanced ls _) cs = AnnCommentsBalanced ls cs
+
+setPriorComments :: ApiAnnComments -> [LAnnotationComment] -> ApiAnnComments
+setPriorComments (AnnComments _) cs = AnnComments cs
+setPriorComments (AnnCommentsBalanced _ ts) cs = AnnCommentsBalanced cs ts
+
+-- ---------------------------------------------------------------------
+-- Comment-only annotations
+-- ---------------------------------------------------------------------
+
+-- TODO:AZ I think ApiAnnCO is not needed
+type ApiAnnCO = ApiAnn' NoApiAnns -- ^ Api Annotations for comments only
+
+data NoApiAnns = NoApiAnns
+ deriving (Data,Eq,Ord)
+
+noComments ::ApiAnnCO
+noComments = ApiAnn (Anchor placeholderRealSpan UnchangedAnchor) NoApiAnns noCom
+
+-- TODO:AZ get rid of this
+placeholderRealSpan :: RealSrcSpan
+placeholderRealSpan = realSrcLocSpan (mkRealSrcLoc (mkFastString "placeholder") (-1) (-1))
+
+comment :: RealSrcSpan -> ApiAnnComments -> ApiAnnCO
+comment loc cs = ApiAnn (Anchor loc UnchangedAnchor) NoApiAnns cs
+
+-- ---------------------------------------------------------------------
+-- Utilities for managing comments in an `ApiAnn' a` structure.
+-- ---------------------------------------------------------------------
+
+-- | Add additional comments to a 'SrcAnn', used for manipulating the
+-- AST prior to exact printing the changed one.
+addCommentsToSrcAnn :: (Monoid ann) => SrcAnn ann -> ApiAnnComments -> SrcAnn ann
+addCommentsToSrcAnn (SrcSpanAnn ApiAnnNotUsed loc) cs
+ = SrcSpanAnn (ApiAnn (Anchor (realSrcSpan loc) UnchangedAnchor) mempty cs) loc
+addCommentsToSrcAnn (SrcSpanAnn (ApiAnn a an cs) loc) cs'
+ = SrcSpanAnn (ApiAnn a an (cs <> cs')) loc
+
+-- | Replace any existing comments on a 'SrcAnn', used for manipulating the
+-- AST prior to exact printing the changed one.
+setCommentsSrcAnn :: (Monoid ann) => SrcAnn ann -> ApiAnnComments -> SrcAnn ann
+setCommentsSrcAnn (SrcSpanAnn ApiAnnNotUsed loc) cs
+ = SrcSpanAnn (ApiAnn (Anchor (realSrcSpan loc) UnchangedAnchor) mempty cs) loc
+setCommentsSrcAnn (SrcSpanAnn (ApiAnn a an _) loc) cs
+ = SrcSpanAnn (ApiAnn a an cs) loc
+
+-- | Add additional comments, used for manipulating the
+-- AST prior to exact printing the changed one.
+addCommentsToApiAnn :: (Monoid a)
+ => SrcSpan -> ApiAnn' a -> ApiAnnComments -> ApiAnn' a
+addCommentsToApiAnn loc ApiAnnNotUsed cs
+ = ApiAnn (Anchor (realSrcSpan loc) UnchangedAnchor) mempty cs
+addCommentsToApiAnn _ (ApiAnn a an ocs) ncs = ApiAnn a an (ocs <> ncs)
+
+-- | Replace any existing comments, used for manipulating the
+-- AST prior to exact printing the changed one.
+setCommentsApiAnn :: (Monoid a)
+ => SrcSpan -> ApiAnn' a -> ApiAnnComments -> ApiAnn' a
+setCommentsApiAnn loc ApiAnnNotUsed cs
+ = ApiAnn (Anchor (realSrcSpan loc) UnchangedAnchor) mempty cs
+setCommentsApiAnn _ (ApiAnn a an _) cs = ApiAnn a an cs
+
+-- | Transfer comments from the annotations in one 'SrcAnn' to those
+-- in another. The originals are not changed. This is used when
+-- manipulating an AST prior to exact printing,
+transferComments :: (Monoid ann)
+ => SrcAnn ann -> SrcAnn ann -> (SrcAnn ann, SrcAnn ann)
+transferComments from@(SrcSpanAnn ApiAnnNotUsed _) to = (from, to)
+transferComments (SrcSpanAnn (ApiAnn a an cs) l) to
+ = ((SrcSpanAnn (ApiAnn a an noCom) l), addCommentsToSrcAnn to cs)
+
+-- ---------------------------------------------------------------------
+-- Semigroup instances, to allow easy combination of annotaion elements
+-- ---------------------------------------------------------------------
+
+instance (Semigroup an) => Semigroup (SrcSpanAnn' an) where
+ (SrcSpanAnn a1 l1) <> (SrcSpanAnn a2 l2) = SrcSpanAnn (a1 <> a2) (combineSrcSpans l1 l2)
+ -- The critical part about the location is its left edge, and all
+ -- annotations must follow it. So we combine them which yields the
+ -- largest span
+
+instance (Semigroup a) => Semigroup (ApiAnn' a) where
+ ApiAnnNotUsed <> x = x
+ x <> ApiAnnNotUsed = x
+ (ApiAnn l1 a1 b1) <> (ApiAnn l2 a2 b2) = ApiAnn (l1 <> l2) (a1 <> a2) (b1 <> b2)
+ -- The critical part about the anchor is its left edge, and all
+ -- annotations must follow it. So we combine them which yields the
+ -- largest span
+
+instance Ord Anchor where
+ compare (Anchor s1 _) (Anchor s2 _) = compare s1 s2
+
+instance Semigroup Anchor where
+ Anchor r1 o1 <> Anchor r2 _ = Anchor (combineRealSrcSpans r1 r2) o1
+
+instance Semigroup ApiAnnComments where
+ AnnComments cs1 <> AnnComments cs2 = AnnComments (cs1 ++ cs2)
+ AnnComments cs1 <> AnnCommentsBalanced cs2 as2 = AnnCommentsBalanced (cs1 ++ cs2) as2
+ AnnCommentsBalanced cs1 as1 <> AnnComments cs2 = AnnCommentsBalanced (cs1 ++ cs2) as1
+ AnnCommentsBalanced cs1 as1 <> AnnCommentsBalanced cs2 as2 = AnnCommentsBalanced (cs1 ++ cs2) (as1++as2)
+
+
+instance (Monoid a) => Monoid (ApiAnn' a) where
+ mempty = ApiAnnNotUsed
+
+instance Semigroup AnnListItem where
+ (AnnListItem l1) <> (AnnListItem l2) = AnnListItem (l1 <> l2)
+
+instance Monoid AnnListItem where
+ mempty = AnnListItem []
+
+
+instance Semigroup AnnList where
+ (AnnList a1 o1 c1 r1 t1) <> (AnnList a2 o2 c2 r2 t2)
+ = AnnList (a1 <> a2) (c o1 o2) (c c1 c2) (r1 <> r2) (t1 <> t2)
+ where
+ -- Left biased combination for the open and close annotations
+ c Nothing x = x
+ c x Nothing = x
+ c f _ = f
+
+instance Monoid AnnList where
+ mempty = AnnList Nothing Nothing Nothing [] []
+
+instance Semigroup NameAnn where
+ _ <> _ = panic "semigroup nameann"
+
+instance Monoid NameAnn where
+ mempty = NameAnnTrailing []
+
+
+instance Semigroup AnnSortKey where
+ NoAnnSortKey <> x = x
+ x <> NoAnnSortKey = x
+ AnnSortKey ls1 <> AnnSortKey ls2 = AnnSortKey (ls1 <> ls2)
+
+instance Monoid AnnSortKey where
+ mempty = NoAnnSortKey
+
+instance (Outputable a) => Outputable (ApiAnn' a) where
+ ppr (ApiAnn l a c) = text "ApiAnn" <+> ppr l <+> ppr a <+> ppr c
+ ppr ApiAnnNotUsed = text "ApiAnnNotUsed"
+
+instance Outputable Anchor where
+ ppr (Anchor a o) = text "Anchor" <+> ppr a <+> ppr o
+
+instance Outputable AnchorOperation where
+ ppr UnchangedAnchor = text "UnchangedAnchor"
+ ppr (MovedAnchor d) = text "MovedAnchor" <+> ppr d
+
+instance Outputable DeltaPos where
+ ppr (DP l c) = text "DP" <+> ppr l <+> ppr c
+
+instance Outputable (GenLocated Anchor AnnotationComment) where
+ ppr (L l c) = text "L" <+> ppr l <+> ppr c
+
+instance Outputable ApiAnnComments where
+ ppr (AnnComments cs) = text "AnnComments" <+> ppr cs
+ ppr (AnnCommentsBalanced cs ts) = text "AnnCommentsBalanced" <+> ppr cs <+> ppr ts
+
+instance (NamedThing (Located a)) => NamedThing (LocatedAn an a) where
+ getName (L l a) = getName (L (locA l) a)
+
+instance Outputable AnnContext where
+ ppr (AnnContext a o c) = text "AnnContext" <+> ppr a <+> ppr o <+> ppr c
+
+instance Outputable AnnSortKey where
+ ppr NoAnnSortKey = text "NoAnnSortKey"
+ ppr (AnnSortKey ls) = text "AnnSortKey" <+> ppr ls
+
+instance Outputable IsUnicodeSyntax where
+ ppr = text . show
+
+instance Binary a => Binary (LocatedL a) where
+ -- We do not serialise the annotations
+ put_ bh (L l x) = do
+ put_ bh (locA l)
+ put_ bh x
+
+ get bh = do
+ l <- get bh
+ x <- get bh
+ return (L (noAnnSrcSpan l) x)
+
+instance (Outputable a) => Outputable (SrcSpanAnn' a) where
+ ppr (SrcSpanAnn a l) = text "SrcSpanAnn" <+> ppr a <+> ppr l
+
+instance (Outputable a, Outputable e)
+ => Outputable (GenLocated (SrcSpanAnn' a) e) where
+ ppr = pprLocated
+
+instance Outputable AnnListItem where
+ ppr (AnnListItem ts) = text "AnnListItem" <+> ppr ts
+
+instance Outputable NameAdornment where
+ ppr NameParens = text "NameParens"
+ ppr NameParensHash = text "NameParensHash"
+ ppr NameBackquotes = text "NameBackquotes"
+ ppr NameSquare = text "NameSquare"
+
+instance Outputable NameAnn where
+ ppr (NameAnn a o n c t)
+ = text "NameAnn" <+> ppr a <+> ppr o <+> ppr n <+> ppr c <+> ppr t
+ ppr (NameAnnCommas a o n c t)
+ = text "NameAnnCommas" <+> ppr a <+> ppr o <+> ppr n <+> ppr c <+> ppr t
+ ppr (NameAnnOnly a o c t)
+ = text "NameAnnOnly" <+> ppr a <+> ppr o <+> ppr c <+> ppr t
+ ppr (NameAnnRArrow n t)
+ = text "NameAnnRArrow" <+> ppr n <+> ppr t
+ ppr (NameAnnQuote q n t)
+ = text "NameAnnQuote" <+> ppr q <+> ppr n <+> ppr t
+ ppr (NameAnnTrailing t)
+ = text "NameAnnTrailing" <+> ppr t
+
+instance Outputable AnnList where
+ ppr (AnnList a o c r t)
+ = text "AnnList" <+> ppr a <+> ppr o <+> ppr c <+> ppr r <+> ppr t
+
+instance Outputable AnnPragma where
+ ppr (AnnPragma o c r) = text "AnnPragma" <+> ppr o <+> ppr c <+> ppr r