packages feed

ghc-exactprint 1.10.0.0 → 1.11.0.0

raw patch · 20 files changed

+5407/−6028 lines, 20 filesdep ~basedep ~ghcdep ~ghc-bootPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, ghc, ghc-boot

API changes (from Hackage documentation)

- Language.Haskell.GHC.ExactPrint.ExactPrint: instance (Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (GHC.Parser.Annotation.LocatedA (body GHC.Hs.Extension.GhcPs)), Language.Haskell.Syntax.Extension.Anno (Language.Haskell.Syntax.Expr.StmtLR GHC.Hs.Extension.GhcPs GHC.Hs.Extension.GhcPs (GHC.Parser.Annotation.LocatedA (body GHC.Hs.Extension.GhcPs))) GHC.Types.~ GHC.Parser.Annotation.SrcSpanAnnA, Language.Haskell.Syntax.Extension.Anno [GHC.Types.SrcLoc.GenLocated GHC.Parser.Annotation.SrcSpanAnnA (Language.Haskell.Syntax.Expr.StmtLR GHC.Hs.Extension.GhcPs GHC.Hs.Extension.GhcPs (GHC.Parser.Annotation.LocatedA (body GHC.Hs.Extension.GhcPs)))] GHC.Types.~ GHC.Parser.Annotation.SrcSpanAnnL, Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (GHC.Parser.Annotation.LocatedL [GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.StmtLR GHC.Hs.Extension.GhcPs GHC.Hs.Extension.GhcPs (GHC.Parser.Annotation.LocatedA (body GHC.Hs.Extension.GhcPs)))])) => Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (Language.Haskell.Syntax.Expr.StmtLR GHC.Hs.Extension.GhcPs GHC.Hs.Extension.GhcPs (GHC.Parser.Annotation.LocatedA (body GHC.Hs.Extension.GhcPs)))
- Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (GHC.Parser.Annotation.LocatedA body) => Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (Language.Haskell.Syntax.Pat.HsFieldBind (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Type.AmbiguousFieldOcc GHC.Hs.Extension.GhcPs)) (GHC.Parser.Annotation.LocatedA body))
- Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (GHC.Parser.Annotation.LocatedL [GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.StmtLR GHC.Hs.Extension.GhcPs GHC.Hs.Extension.GhcPs (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.HsCmd GHC.Hs.Extension.GhcPs)))])
- Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (GHC.Parser.Annotation.LocatedL [GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.StmtLR GHC.Hs.Extension.GhcPs GHC.Hs.Extension.GhcPs (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.HsExpr GHC.Hs.Extension.GhcPs)))])
- Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (GHC.Parser.Annotation.LocatedL [GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.ImpExp.IE GHC.Hs.Extension.GhcPs)])
- Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (Language.Haskell.Syntax.Expr.Match GHC.Hs.Extension.GhcPs (GHC.Parser.Annotation.LocatedA body)) => Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (GHC.Parser.Annotation.LocatedL [GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.Match GHC.Hs.Extension.GhcPs (GHC.Parser.Annotation.LocatedA body))])
- Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (Language.Haskell.Syntax.Type.AmbiguousFieldOcc GHC.Hs.Extension.GhcPs)
- Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint Language.Haskell.GHC.ExactPrint.ExactPrint.DataFamInstDeclWithContext
- Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrintTVFlag GHC.Types.Var.Specificity
- Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.HasTrailing (GHC.Parser.Annotation.AddEpAnn, GHC.Parser.Annotation.AddEpAnn)
- Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.HasTrailing GHC.Parser.Annotation.AddEpAnn
- Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.HasTrailing GHC.Parser.Annotation.AnnList
- Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.HasTrailing [GHC.Parser.Annotation.AddEpAnn]
- Language.Haskell.GHC.ExactPrint.Lookup: AnnAnyclass :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnAs :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnBackquote :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnBang :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnBy :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnCase :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnCases :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnClass :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnClose :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnCloseB :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnCloseBU :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnCloseC :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnCloseP :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnClosePH :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnCloseQ :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnCloseQU :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnCloseS :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnColon :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnComma :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnCommaTuple :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnDarrow :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnDarrowU :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnData :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnDcolon :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnDcolonU :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnDefault :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnDeriving :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnDo :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnDollar :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnDollarDollar :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnDot :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnDotdot :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnElse :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnEqual :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnExport :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnFamily :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnForall :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnForallU :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnForeign :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnFunId :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnGroup :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnHeader :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnHiding :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnIf :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnImport :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnIn :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnInfix :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnInstance :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnLam :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnLarrow :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnLarrowU :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnLarrowtail :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnLarrowtailU :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnLet :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnLollyU :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnMdo :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnMinus :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnModule :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnName :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnNewtype :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnOf :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnOpen :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnOpenB :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnOpenBU :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnOpenC :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnOpenE :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnOpenEQ :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnOpenEQU :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnOpenP :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnOpenPH :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnOpenS :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnPackageName :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnPattern :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnPercent :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnPercentOne :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnProc :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnQualified :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnRarrow :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnRarrowU :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnRarrowtail :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnRarrowtailU :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnRec :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnRole :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnSafe :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnSemi :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnSignature :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnSimpleQuote :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnStatic :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnStock :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnThTyQuote :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnThen :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnTilde :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnType :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnUnit :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnUsing :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnVal :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnValStr :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnVbar :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnVia :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnWhere :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: Annlarrowtail :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnlarrowtailU :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: Annrarrowtail :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnrarrowtailU :: AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: Comment :: !String -> !NoCommentsLocation -> !RealSrcSpan -> !Maybe AnnKeywordId -> Comment
- Language.Haskell.GHC.ExactPrint.Lookup: [commentContents] :: Comment -> !String
- Language.Haskell.GHC.ExactPrint.Lookup: [commentLoc] :: Comment -> !NoCommentsLocation
- Language.Haskell.GHC.ExactPrint.Lookup: [commentOrigin] :: Comment -> !Maybe AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: [commentPriorTok] :: Comment -> !RealSrcSpan
- Language.Haskell.GHC.ExactPrint.Lookup: data AnnKeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: data Comment
- Language.Haskell.GHC.ExactPrint.Lookup: keywordToString :: AnnKeywordId -> String
- Language.Haskell.GHC.ExactPrint.Utils: addEpAnnLoc :: AddEpAnn -> EpaLocation
- Language.Haskell.GHC.ExactPrint.Utils: setTrailingAnnLoc :: TrailingAnn -> EpaLocation -> TrailingAnn
- Language.Haskell.GHC.ExactPrint.Utils: trailingAnnLoc :: TrailingAnn -> EpaLocation
- Language.Haskell.GHC.ExactPrint.Utils: undeltaSpan :: RealSrcSpan -> AnnKeywordId -> DeltaPos -> AddEpAnn
+ Language.Haskell.GHC.ExactPrint.ExactPrint: instance (Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (GHC.Parser.Annotation.LocatedA (body GHC.Hs.Extension.GhcPs)), Language.Haskell.Syntax.Extension.Anno (Language.Haskell.Syntax.Expr.StmtLR GHC.Hs.Extension.GhcPs GHC.Hs.Extension.GhcPs (GHC.Parser.Annotation.LocatedA (body GHC.Hs.Extension.GhcPs))) GHC.Types.~ GHC.Parser.Annotation.SrcSpanAnnA, Language.Haskell.Syntax.Extension.Anno [GHC.Types.SrcLoc.GenLocated GHC.Parser.Annotation.SrcSpanAnnA (Language.Haskell.Syntax.Expr.StmtLR GHC.Hs.Extension.GhcPs GHC.Hs.Extension.GhcPs (GHC.Parser.Annotation.LocatedA (body GHC.Hs.Extension.GhcPs)))] GHC.Types.~ GHC.Parser.Annotation.SrcSpanAnnLW, Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (GHC.Parser.Annotation.LocatedLW [GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.StmtLR GHC.Hs.Extension.GhcPs GHC.Hs.Extension.GhcPs (GHC.Parser.Annotation.LocatedA (body GHC.Hs.Extension.GhcPs)))])) => Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (Language.Haskell.Syntax.Expr.StmtLR GHC.Hs.Extension.GhcPs GHC.Hs.Extension.GhcPs (GHC.Parser.Annotation.LocatedA (body GHC.Hs.Extension.GhcPs)))
+ Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (GHC.Parser.Annotation.LocatedLI [GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.ImpExp.IE GHC.Hs.Extension.GhcPs)])
+ Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (GHC.Parser.Annotation.LocatedLW [GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.StmtLR GHC.Hs.Extension.GhcPs GHC.Hs.Extension.GhcPs (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.HsCmd GHC.Hs.Extension.GhcPs)))])
+ Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (GHC.Parser.Annotation.LocatedLW [GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.StmtLR GHC.Hs.Extension.GhcPs GHC.Hs.Extension.GhcPs (GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.HsExpr GHC.Hs.Extension.GhcPs)))])
+ Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (Language.Haskell.Syntax.Decls.DataFamInstDecl GHC.Hs.Extension.GhcPs)
+ Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (Language.Haskell.Syntax.Expr.Match GHC.Hs.Extension.GhcPs (GHC.Parser.Annotation.LocatedA body)) => Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (GHC.Parser.Annotation.LocatedLW [GHC.Parser.Annotation.LocatedA (Language.Haskell.Syntax.Expr.Match GHC.Hs.Extension.GhcPs (GHC.Parser.Annotation.LocatedA body))])
+ Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (Language.Haskell.Syntax.Type.HsBndrVar GHC.Hs.Extension.GhcPs)
+ Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrintTVFlag Language.Haskell.Syntax.Specificity.Specificity
+ Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.HasTrailing (GHC.Parser.Annotation.AnnList a)
+ Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.HasTrailing (GHC.Parser.Annotation.TokForall, GHC.Parser.Annotation.EpToken ".")
+ Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.HasTrailing (GHC.Parser.Annotation.TokForall, GHC.Parser.Annotation.TokRarrow)
+ Language.Haskell.GHC.ExactPrint.ExactPrint: setAnchorAn :: HasTrailing an => LocatedAn an a -> EpaLocation -> [TrailingAnn] -> EpAnnComments -> LocatedAn an a
+ Language.Haskell.GHC.ExactPrint.Utils: annListBracketsLocs :: AnnListBrackets -> (EpaLocation, EpaLocation)
- Language.Haskell.GHC.ExactPrint: setAnnotationAnchor :: ExactPrint a => a -> Anchor -> [TrailingAnn] -> EpAnnComments -> a
+ Language.Haskell.GHC.ExactPrint: setAnnotationAnchor :: ExactPrint a => a -> EpaLocation -> [TrailingAnn] -> EpAnnComments -> a
- Language.Haskell.GHC.ExactPrint.ExactPrint: setAnnotationAnchor :: ExactPrint a => a -> Anchor -> [TrailingAnn] -> EpAnnComments -> a
+ Language.Haskell.GHC.ExactPrint.ExactPrint: setAnnotationAnchor :: ExactPrint a => a -> EpaLocation -> [TrailingAnn] -> EpAnnComments -> a
- Language.Haskell.GHC.ExactPrint.Types: Comment :: !String -> !NoCommentsLocation -> !RealSrcSpan -> !Maybe AnnKeywordId -> Comment
+ Language.Haskell.GHC.ExactPrint.Types: Comment :: !String -> !NoCommentsLocation -> !RealSrcSpan -> !Maybe String -> Comment
- Language.Haskell.GHC.ExactPrint.Types: [commentOrigin] :: Comment -> !Maybe AnnKeywordId
+ Language.Haskell.GHC.ExactPrint.Types: [commentOrigin] :: Comment -> !Maybe String
- Language.Haskell.GHC.ExactPrint.Utils: hsDocStringComments :: Anchor -> RealSrcSpan -> HsDocString -> [Comment]
+ Language.Haskell.GHC.ExactPrint.Utils: hsDocStringComments :: EpaLocation -> RealSrcSpan -> HsDocString -> [Comment]
- Language.Haskell.GHC.ExactPrint.Utils: mkKWComment :: AnnKeywordId -> NoCommentsLocation -> Comment
+ Language.Haskell.GHC.ExactPrint.Utils: mkKWComment :: String -> NoCommentsLocation -> Comment
- Language.Haskell.GHC.ExactPrint.Utils: sortAnchorLocated :: [GenLocated Anchor a] -> [GenLocated Anchor a]
+ Language.Haskell.GHC.ExactPrint.Utils: sortAnchorLocated :: [GenLocated EpaLocation a] -> [GenLocated EpaLocation a]
- Language.Haskell.GHC.ExactPrint.Utils: splitOnWhere :: SplitWhere -> [AddEpAnn] -> [LEpaComment] -> ([LEpaComment], [LEpaComment])
+ Language.Haskell.GHC.ExactPrint.Utils: splitOnWhere :: SplitWhere -> EpToken "where" -> [LEpaComment] -> ([LEpaComment], [LEpaComment])

Files

ChangeLog view
@@ -1,3 +1,5 @@+2024-12-06 v1.11.0.0+	* Support GHC 9.12.1 (rc1) 2024-05-21 v1.10.0.0 	* Make the Language.Haskell.GHC.ExactPrint.Transform API pure 	* Remove EPOoptions fields that had no effect
ghc-exactprint.cabal view
@@ -1,12 +1,12 @@ cabal-version:       2.4 name:                ghc-exactprint-version:             1.10.0.0+version:             1.11.0.0 synopsis:            ExactPrint for GHC description:         Using the API Annotations available from GHC 9.2.1, this                      library provides a means to round trip any code that can                      be compiled by GHC, currently excluding lhs files.                      .-                     Note: requires GHC 9.10.*. For earlier GHC+                     Note: requires GHC 9.12.*. For earlier GHC                      versions see lower version numbers.                      . @@ -16,11 +16,12 @@ maintainer:          alan.zimm@gmail.com category:            Development build-type:          Simple-tested-with:         GHC == 9.10.1+tested-with:         GHC == 9.12.1 extra-doc-files:     ChangeLog extra-source-files:  tests/examples/failing/*.hs                      tests/examples/failing/*.hs.bad                      tests/examples/ghc910/*.hs+                     tests/examples/ghc912/*.hs                      tests/examples/pre-ghc910/*.hs                      tests/examples/pre-ghc910/*.hs-boot                      tests/examples/transform/*.hs@@ -47,7 +48,6 @@   import: warnings   exposed-modules:     Language.Haskell.GHC.ExactPrint                      , Language.Haskell.GHC.ExactPrint.ExactPrint-                     , Language.Haskell.GHC.ExactPrint.Lookup                      , Language.Haskell.GHC.ExactPrint.Parsers                      , Language.Haskell.GHC.ExactPrint.Preprocess                      , Language.Haskell.GHC.ExactPrint.Transform@@ -55,15 +55,15 @@                      , Language.Haskell.GHC.ExactPrint.Utils    hs-source-dirs:      src-  build-depends:       base >=4.20 && <4.21+  build-depends:       base >=4.21 && <4.22                      , containers >= 0.5  && < 0.8-                     , ghc       >= 9.10 && < 9.11-                     , ghc-boot  >= 9.10 && < 9.11+                     , ghc       >= 9.12 && < 9.13+                     , ghc-boot  >= 9.12 && < 9.13                      , mtl       >= 2.2.1 && < 2.5                      , syb       >= 0.5 && < 0.8    default-language:    Haskell2010-  if impl (ghc < 9.10)+  if impl (ghc < 9.12)     buildable: False  Test-Suite test@@ -82,14 +82,14 @@                      , Test.Transform   GHC-Options:         -threaded   Default-language:    Haskell2010-  Build-depends:       base < 4.21+  Build-depends:       base < 4.22                      , HUnit >= 1.2                      , containers >= 0.5                      , Diff                      , directory >= 1.2                      , extra                      , filepath  >= 1.4-                     , ghc       >= 9.10+                     , ghc       >= 9.12                      , ghc-paths  >= 0.1                      , syb        >= 0.5                      , silently   >= 1.2@@ -100,7 +100,7 @@                      mtl        >= 2.2.1   else       build-depends: ghc-exactprint-  if impl (ghc < 9.10)+  if impl (ghc < 9.12)       buildable: False  executable roundtrip@@ -110,15 +110,15 @@   other-modules: Test.Common                  Test.CommonUtils   default-language:    Haskell2010-  if impl (ghc >= 9.10) && flag (roundtrip)+  if impl (ghc >= 9.12) && flag (roundtrip)     build-depends:                  HUnit      < 1.7-               , base       < 4.21+               , base       < 4.22                , containers < 0.8                , directory  < 1.4                , extra      < 1.8                , filepath   < 1.6-               , ghc        >= 9.10 && < 9.11+               , ghc        >= 9.12 && < 9.13                , ghc-exactprint                , ghc-paths  < 0.2                , time       < 1.13@@ -135,11 +135,11 @@   other-modules: Test.CommonUtils   default-language:    Haskell2010   if flag (roundtrip)-    build-depends: base < 4.21+    build-depends: base < 4.22                  , directory < 1.4                  , extra     < 1.8                  , filepath  < 1.6-                 , ghc       >= 9.10 && < 9.11+                 , ghc       >= 9.12 && < 9.13                  , Diff      < 0.6     buildable: True   else@@ -153,12 +153,12 @@ --   hs-source-dirs: tests --   default-language:    Haskell2010 --   if flag (roundtrip)---     build-depends: base < 4.21+--     build-depends: base < 4.22 --                  , containers --                  , directory --                  , extra --                  , filepath---                  , ghc       >= 9.10+--                  , ghc       >= 9.12 --                  , HUnit --                  , text   >= 1.2.2 --                  , turtle >= 1.3.0
src/Language/Haskell/GHC/ExactPrint/ExactPrint.hs view
@@ -1,5091 +1,4946 @@ {-# LANGUAGE BangPatterns         #-}-{-# LANGUAGE DeriveDataTypeable   #-}-{-# LANGUAGE FlexibleContexts     #-}-{-# LANGUAGE FlexibleInstances    #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE MultiWayIf           #-}-{-# LANGUAGE NamedFieldPuns       #-}-{-# LANGUAGE RankNTypes           #-}-{-# LANGUAGE StandaloneDeriving   #-}-{-# LANGUAGE TypeFamilies         #-}-{-# LANGUAGE TypeSynonymInstances #-}-{-# LANGUAGE ViewPatterns         #-}-{-# LANGUAGE ScopedTypeVariables  #-}-{-# LANGUAGE TupleSections        #-}-{-# LANGUAGE TypeApplications     #-}-{-# LANGUAGE TypeOperators        #-}-{-# LANGUAGE BlockArguments       #-}-{-# LANGUAGE UndecidableInstances  #-} -- For the (StmtLR GhcPs GhcPs (LocatedA (body GhcPs))) ExactPrint instance-{-# OPTIONS_GHC -Wno-incomplete-uni-patterns -Wno-incomplete-record-updates #-}--module Language.Haskell.GHC.ExactPrint.ExactPrint-  (-    ExactPrint(..)-  , exactPrint-  , exactPrintWithOptions-  , makeDeltaAst--  -- * Configuration-  , EPOptions(epTokenPrint, epWhitespacePrint)-  , stringOptions-  , epOptions-  , deltaOptions-  ) where--import GHC-import GHC.Base (NonEmpty(..))-import GHC.Core.Coercion.Axiom (Role(..))-import GHC.Data.Bag-import qualified GHC.Data.BooleanFormula as BF-import GHC.Data.FastString-import GHC.TypeLits-import GHC.Types.Basic hiding (EP)-import GHC.Types.Fixity-import GHC.Types.ForeignCall-import GHC.Types.Name.Reader-import GHC.Types.PkgQual-import GHC.Types.SourceText-import GHC.Types.SrcLoc-import GHC.Types.Var-import GHC.Unit.Module.Warnings-import GHC.Utils.Misc-import GHC.Utils.Outputable hiding ( (<>) )-import GHC.Utils.Panic--import Language.Haskell.Syntax.Basic (FieldLabelString(..))--import Control.Monad (forM, when, unless)-import Control.Monad.Identity (Identity(..))-import qualified Control.Monad.Reader as Reader-import Control.Monad.RWS (MonadReader, RWST, evalRWST, tell, modify, get, gets, ask)-import Control.Monad.Trans (lift)-import Data.Data ( Data )-import Data.Dynamic-import Data.Foldable-import Data.Functor.Const-import qualified Data.Set as Set-import Data.Typeable-import Data.List ( partition, sort, sortBy)-import qualified Data.Map.Strict as Map-import Data.Maybe ( isJust, mapMaybe )-import Data.Void--import Language.Haskell.GHC.ExactPrint.Lookup-import Language.Haskell.GHC.ExactPrint.Utils-import Language.Haskell.GHC.ExactPrint.Types---- -----------------------------------------------------------------------exactPrint :: ExactPrint ast => ast -> String-exactPrint ast = snd $ runIdentity (runEP stringOptions (markAnnotated ast))---- | The additional option to specify the printing configuration.-exactPrintWithOptions :: (ExactPrint ast, Monoid b, Monad m)-                      => EPOptions m b-                      -> ast-                      -> m (ast, b)-exactPrintWithOptions r ast =-    runEP r (markAnnotated ast)---- | Transform concrete annotations into relative annotations.--- This should be unnecessary from GHC 9.10-makeDeltaAst :: ExactPrint ast => ast -> ast-makeDeltaAst ast = fst $ runIdentity (runEP deltaOptions (markAnnotated ast))----------------------------------------------------------type EP w m a = RWST (EPOptions m w) (EPWriter w) EPState m a--runEP :: (Monad m)-      => EPOptions m w-      -> EP w m a -> m (a, w)-runEP epReader action = do-  (ast, w) <- evalRWST action epReader defaultEPState-  return (ast, output w)---- -----------------------------------------------------------------------defaultEPState :: EPState-defaultEPState = EPState-             { epPos      = (1,1)-             , dLHS       = 0-             , pMarkLayout = False-             , pLHS = 0-             , dMarkLayout = False-             , dPriorEndPosition = (1,1)-             , uAnchorSpan = badRealSrcSpan-             , uExtraDP = Nothing-             , uExtraDPReturn = Nothing-             , pAcceptSpan = False-             , epComments = []-             , epCommentsApplied = []-             , epEof = Nothing-             }----- ------------------------------------------------------------------------ The EP monad and basic combinators---- | The R part of RWS. The environment. Updated via 'local' as we--- enter a new AST element, having a different anchor point.-data EPOptions m a = EPOptions-            { epTokenPrint :: String -> m a-            , epWhitespacePrint :: String -> m a-            }---- | Helper to create a 'EPOptions'-epOptions :: (String -> m a)-          -> (String -> m a)-          -> EPOptions m a-epOptions tokenPrint wsPrint = EPOptions-             { epWhitespacePrint = wsPrint-             , epTokenPrint = tokenPrint-             }---- | Options which can be used to print as a normal String.-stringOptions :: EPOptions Identity String-stringOptions = epOptions return return---- | Options which can be used to simply update the AST to be in delta--- form, without generating output-deltaOptions :: EPOptions Identity ()-deltaOptions = epOptions (\_ -> return ()) (\_ -> return ())--data EPWriter a = EPWriter-              { output :: !a }--instance Monoid w => Semigroup (EPWriter w) where-  (EPWriter a) <> (EPWriter b) = EPWriter (a <> b)--instance Monoid w => Monoid (EPWriter w) where-  mempty = EPWriter mempty--data EPState = EPState-             { uAnchorSpan :: !RealSrcSpan -- ^ in pre-changed AST-                                          -- reference frame, from-                                          -- Annotation-             , uExtraDP :: !(Maybe Anchor) -- ^ Used to anchor a-                                             -- list-             , uExtraDPReturn :: !(Maybe DeltaPos)-                  -- ^ Used to return Delta version of uExtraDP-             , pAcceptSpan :: Bool -- ^ When we have processed an-                                   -- entry of EpaDelta, accept the-                                   -- next `EpaSpan` start as the-                                   -- current output position. i.e. do-                                   -- not advance epPos. Achieved by-                                   -- setting dPriorEndPosition to the-                                   -- end of the span.--             -- Print phase-             , epPos        :: !Pos -- ^ Current output position-             , pMarkLayout  :: !Bool-             , pLHS   :: !LayoutStartCol--             -- Delta phase-             , dPriorEndPosition :: !Pos -- ^ End of Position reached-                                         -- when processing the-                                         -- preceding element-             , dMarkLayout :: !Bool-             , dLHS        :: !LayoutStartCol--             -- Shared-             , epComments :: ![Comment]-             , epCommentsApplied :: ![[Comment]]-             , epEof :: !(Maybe (RealSrcSpan, RealSrcSpan))-             }---- ------------------------------------------------------------------------- AZ:TODO: this can just be a function :: (EpAnn a) -> Entry-class HasEntry ast where-  fromAnn :: ast -> Entry--class HasTrailing a where-  trailing :: a -> [TrailingAnn]-  setTrailing :: a -> [TrailingAnn] -> a--setAnchorEpa :: (HasTrailing an)-             => EpAnn an -> Anchor -> [TrailingAnn] -> EpAnnComments -> EpAnn an-setAnchorEpa (EpAnn _ an _) anc ts cs = EpAnn anc (setTrailing an ts)          cs--setAnchorHsModule :: HsModule GhcPs -> Anchor -> EpAnnComments -> HsModule GhcPs-setAnchorHsModule hsmod anc cs = hsmod { hsmodExt = (hsmodExt hsmod) {hsmodAnn = an'} }-  where-    anc' = anc-    an' = setAnchorEpa (hsmodAnn $ hsmodExt hsmod) anc' [] cs--setAnchorAn :: (HasTrailing an)-             => LocatedAn an a -> Anchor -> [TrailingAnn] -> EpAnnComments -> LocatedAn an a-setAnchorAn (L (EpAnn _ an _) a) anc ts cs = (L (EpAnn anc (setTrailing an ts) cs) a)-     -- `debug` ("setAnchorAn: anc=" ++ showAst anc)--setAnchorEpaL :: EpAnn AnnList -> Anchor -> [TrailingAnn] -> EpAnnComments -> EpAnn AnnList-setAnchorEpaL (EpAnn _ an _) anc ts cs = EpAnn anc (setTrailing (an {al_anchor = Nothing}) ts) cs---- ------------------------------------------------------------------------- | Key entry point.  Switches to an independent AST element with its--- own annotation, calculating new offsets, etc-markAnnotated :: (Monad m, Monoid w, ExactPrint a) => a -> EP w m a-markAnnotated a = enterAnn (getAnnotationEntry a) a---- | For HsModule, because we do not have a proper SrcSpan, we must--- indicate to flush trailing comments when done.-data FlushComments = FlushComments-                   | NoFlushComments-                   deriving (Eq, Show)---- | For GenLocated SrcSpan, we construct an entry location but cannot update it.-data CanUpdateAnchor = CanUpdateAnchor-                     | CanUpdateAnchorOnly-                     | NoCanUpdateAnchor-                   deriving (Eq, Show, Data)--data Entry = Entry Anchor [TrailingAnn] EpAnnComments FlushComments CanUpdateAnchor-           | NoEntryVal---- | For flagging whether to capture comments in an EpaDelta or not-data CaptureComments = CaptureComments-                     | NoCaptureComments--mkEntry :: Anchor -> [TrailingAnn] -> EpAnnComments -> Entry-mkEntry anc ts cs = Entry anc ts cs NoFlushComments CanUpdateAnchor--instance (HasTrailing a) => HasEntry (EpAnn a) where-  fromAnn (EpAnn anc a cs) = mkEntry anc (trailing a) cs---- -----------------------------------------------------------------------instance HasTrailing NoEpAnns where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing EpaLocation where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing AddEpAnn where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing [AddEpAnn] where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing (AddEpAnn, AddEpAnn) where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing EpAnnSumPat where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing AnnList where-  trailing a = al_trailing a-  setTrailing a ts = a { al_trailing = ts }--instance HasTrailing AnnListItem where-  trailing a = lann_trailing a-  setTrailing a ts = a { lann_trailing = ts }--instance HasTrailing AnnPragma where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing AnnContext where-  trailing (AnnContext ma _opens _closes)-    = case ma of-      Just (UnicodeSyntax, r) -> [AddDarrowUAnn r]-      Just (NormalSyntax,  r) -> [AddDarrowAnn r]-      Nothing -> []--  setTrailing a [AddDarrowUAnn r] = a {ac_darrow = Just (UnicodeSyntax, r)}-  setTrailing a [AddDarrowAnn r] = a{ac_darrow = Just (NormalSyntax, r)}-  setTrailing a [] = a{ac_darrow = Nothing}-  setTrailing a ts = error $ "Cannot setTrailing " ++ showAst ts ++ " for " ++ showAst a---instance HasTrailing AnnParen where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing AnnsIf where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing EpAnnHsCase where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing AnnFieldLabel where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing AnnProjection where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing AnnExplicitSum where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing (Maybe EpAnnUnboundVar) where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing GrhsAnn where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing AnnSig where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing HsRuleAnn where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing EpAnnImportDecl where-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing AnnsModule where-  -- Report none, as all are used internally-  trailing _ = []-  setTrailing a _ = a--instance HasTrailing NameAnn where-  trailing a = nann_trailing a-  setTrailing a ts = a { nann_trailing = ts }--instance HasTrailing Bool where-  trailing _ = []-  setTrailing a _ = a---- -----------------------------------------------------------------------fromAnn' :: (HasEntry a) => a -> Entry-fromAnn' an = case fromAnn an of-  NoEntryVal -> NoEntryVal-  Entry a ts c _ u -> Entry a ts c FlushComments u---- -----------------------------------------------------------------------astId :: (Typeable a) => a -> String-astId a = show (typeOf a)--cua :: (Monad m, Monoid w) => CanUpdateAnchor -> EP w m [a] -> EP w m [a]-cua CanUpdateAnchor f = f-cua CanUpdateAnchorOnly _ = return []-cua NoCanUpdateAnchor _ = return []---- | "Enter" an annotation, by using the associated 'anchor' field as--- the new reference point for calculating all DeltaPos positions.--- This is the heart of the exact printing process.------ This is combination of the ghc=exactprint Delta.withAST and--- Print.exactPC functions and effectively does the delta processing--- immediately followed by the print processing.  JIT ghc-exactprint.-enterAnn :: (Monad m, Monoid w, ExactPrint a) => Entry -> a -> EP w m a-enterAnn NoEntryVal a = do-  p <- getPosP-  debugM $ "enterAnn:starting:NO ANN:(p,a) =" ++ show (p, astId a)-  r <- exact a-  debugM $ "enterAnn:done:NO ANN:p =" ++ show (p, astId a)-  return r-enterAnn !(Entry anchor' trailing_anns cs flush canUpdateAnchor) a = do-  acceptSpan <- getAcceptSpan-  setAcceptSpan False-  case anchor' of-    EpaDelta _ _ -> setAcceptSpan True-    _            -> return ()-  p <- getPosP-  pe0 <- getPriorEndD-  debugM $ "enterAnn:starting:(anchor',p,pe,a) =" ++ show (showAst anchor', p, pe0, astId a)-  prevAnchor <- getAnchorU-  let curAnchor = case anchor' of-        EpaSpan (RealSrcSpan r _) -> r-        _ -> prevAnchor-  debugM $ "enterAnn:(curAnchor):=" ++ show (rs2range curAnchor)-  case canUpdateAnchor of-    CanUpdateAnchor -> pushAppliedComments-    _ -> return ()-  case anchor' of-    EpaDelta _ dcs -> do-      debugM $ "enterAnn:Delta:Flushing comments"-      flushComments []-      debugM $ "enterAnn:Delta:Printing prior comments:" ++ showGhc (priorComments cs)-      mapM_ printOneComment (concatMap tokComment $ priorComments cs)-      debugM $ "enterAnn:Delta:Printing EpaDelta comments:" ++ showGhc dcs-      mapM_ printOneComment (concatMap tokComment dcs)-    _ -> do-      debugM $ "enterAnn:Adding comments:" ++ showGhc (priorComments cs)-      addCommentsA (priorComments cs)-  debugM $ "enterAnn:Added comments"-  printCommentsBefore curAnchor-  priorCs <- cua canUpdateAnchor takeAppliedComments -- no pop-  -- --------------------------  case anchor' of-    EpaDelta dp _ -> do-      debugM $ "enterAnn: EpaDelta:" ++ show dp-      -- Set the original anchor as prior end, so the rest of this AST-      -- fragment has a reference-      setPriorEndNoLayoutD (ss2pos curAnchor)-    _ -> do-      if acceptSpan-        then setPriorEndNoLayoutD (ss2pos curAnchor)-        else return ()--  -- --------------------------  if ((fst $ fst $ rs2range curAnchor) >= 0)-    then-      setAnchorU curAnchor-    else-      debugM $ "enterAnn: not calling setAnchorU for : " ++ show (rs2range curAnchor)-  -- --------------------------------------------------------------------  -- Make sure the running dPriorEndPosition gets updated according to-  -- the change in the current anchor.--  -- Compute the distance from dPriorEndPosition to the start of the new span.--  -- While processing in the context of the prior anchor, we choose to-  -- enter a new Anchor, which has a defined position relative to the-  -- prior anchor, even if we do not actively output anything at that-  -- point.-  -- Is this edp?--  -- --------------------------------------------------------------------  -- The first part corresponds to the delta phase, so should only use-  -- delta phase variables ------------------------------------  -- Calculate offset required to get to the start of the SrcSPan-  !off <- getLayoutOffsetD-  let spanStart = ss2pos curAnchor-  priorEndAfterComments <- getPriorEndD-  let edp' = adjustDeltaForOffset-               -- Use the propagated offset if one is set-               -- Note that we need to use the new offset if it has-               -- changed.-               off (ss2delta priorEndAfterComments curAnchor)-  debugM $ "enterAnn: (edp',off,priorEndAfterComments,curAnchor):" ++ show (edp',off,priorEndAfterComments,rs2range curAnchor)-  let edp'' = case anchor' of-        EpaDelta dp _ -> dp-        _ -> edp'-  -- ----------------------------------------------  med <- getExtraDP-  setExtraDP Nothing-  let (edp, medr) = case med of-        Nothing -> (edp'', Nothing)-        Just (EpaDelta dp _) -> (dp, Nothing)-                   -- Replace original with desired one. Allows all-                   -- list entry values to be DP (1,0)-        Just (EpaSpan (RealSrcSpan r _)) -> (dp, Just dp)-          where-            dp = adjustDeltaForOffset-                   off (ss2delta priorEndAfterComments r)-        Just (EpaSpan (UnhelpfulSpan r)) -> panic $ "enterAnn: UnhelpfulSpan:" ++ show r-  when (isJust med) $ debugM $ "enterAnn:(med,edp)=" ++ showAst (med,edp)-  when (isJust medr) $ setExtraDPReturn medr-  -- ----------------------------------------------  -- Preparation complete, perform the action-  when (priorEndAfterComments < spanStart) (do-    debugM $ "enterAnn.dPriorEndPosition:spanStart=" ++ show spanStart-    modify (\s -> s { dPriorEndPosition    = spanStart } ))--  debugM $ "enterAnn: (anchor', curAnchor):" ++ show (anchor', rs2range curAnchor)-  -- debugM $ "enterAnn: (dLHS,spanStart,pec,edp)=" ++ show (off,spanStart,priorEndAfterComments,edp)-  p0 <- getPosP-  d <- getPriorEndD-  debugM $ "enterAnn: (posp, posd)=" ++ show (p0,d)--  -- end of delta phase processing-  -- --------------------------------------------------------------------  -- start of print phase processing--  advance edp-  debugM $ "enterAnn:exact a starting:" ++ show (showAst anchor')-  a' <- exact a-  debugM $ "enterAnn:exact a done:" ++ show (showAst anchor')--  -- Core recursive exactprint done, start end of Entry processing--  when (flush == FlushComments) $ do-    debugM $ "flushing comments in enterAnn:" ++ showAst (cs, getFollowingComments cs)-    flushComments (getFollowingComments cs)-    debugM $ "flushing comments in enterAnn done"--  !eof <- getEofPos-  case eof of-    Nothing -> return ()-    Just (pos, prior) -> do-       let dp = if pos == prior-             then (DifferentLine 1 0)-             else origDelta pos prior-       debugM $ "EOF:(pos,posEnd,prior,dp) =" ++ showGhc (ss2pos pos, ss2posEnd pos, ss2pos prior, dp)-       printStringAtLsDelta dp ""-       setEofPos Nothing -- Only do this once--  -- Deal with exit from the current anchor-  when (flush == NoFlushComments) $ do-    printCommentsIn curAnchor -- Make sure all comments in the span are printed--  p1 <- getPosP-  pe1 <- getPriorEndD-  debugM $ "enterAnn:done:(anchor,p,pe,a) =" ++ show (showAst anchor', p1, pe1, astId a')--  case anchor' of-    EpaDelta _ _ -> return ()-    EpaSpan (RealSrcSpan rss _) -> do-      setAcceptSpan False-      setPriorEndD (snd $ rs2range rss)-    EpaSpan _ -> return ()--  -- Outside the anchor, mark any trailing-  postCs <- cua canUpdateAnchor takeAppliedCommentsPop-  following <- if (flush == NoFlushComments)-          then do-              let (before, after) = splitAfterTrailingAnns trailing_anns-                                                           (getFollowingComments cs)-              addCommentsA before-              return after-           else return []-  !trailing' <- markTrailing trailing_anns-  -- mapM_ printOneComment (concatMap tokComment $ following)-  addCommentsA following--  -- Update original anchor, comments based on the printing process-  let newAnchor = EpaDelta edp []-  debugM $ "enterAnn:setAnnotationAnchor:(canUpdateAnchor,newAnchor,priorCs,postCs):" ++ showAst (canUpdateAnchor,newAnchor,priorCs,postCs)-  let r = case canUpdateAnchor of-            CanUpdateAnchor -> setAnnotationAnchor a' newAnchor trailing' (mkEpaComments priorCs postCs)-            CanUpdateAnchorOnly -> setAnnotationAnchor a' newAnchor [] emptyComments-            NoCanUpdateAnchor -> a'-  return r---- ------------------------------------------------------------------------- | Split the span following comments into ones that occur prior to--- the last trailing ann, and ones after.-splitAfterTrailingAnns :: [TrailingAnn] -> [LEpaComment] -> ([LEpaComment], [LEpaComment])-splitAfterTrailingAnns [] cs = ([], cs)-splitAfterTrailingAnns tas cs = (before, after)-  where-    trailing_loc ta = case ta_location ta of-        EpaSpan (RealSrcSpan s _) -> [s]-        _ -> []-    (before, after) = case reverse (concatMap trailing_loc tas) of-        [] -> ([],cs)-        (s:_) -> (b,a)-          where-            s_pos = ss2pos s-            (b,a) = break (\(L ll _) -> (ss2pos $ anchor ll) > s_pos)-                          cs----- -----------------------------------------------------------------------addCommentsA :: (Monad m, Monoid w) => [LEpaComment] -> EP w m ()-addCommentsA csNew = addComments False (concatMap tokComment csNew)--{--TODO: When we addComments, some may have an anchor that is no longer-valid, as it has been moved and has an anchor_op.--Does an Anchor even make sense for a comment, perhaps it should be an-EpaLocation?--How do we sort them? do we assign a location based on when we add them-to the list, based on the current output pos?  Except the offset is a-delta compared to a reference location.  Need to nail the concept of-the reference location.--By definition it is the current anchor, so work against that. And that-also means that the first entry comment that has moved should not have-a line offset.--}-addComments :: (Monad m, Monoid w) => Bool -> [Comment] -> EP w m ()-addComments sortNeeded csNew = do-  debugM $ "addComments:csNew" ++ show csNew-  cs <- getUnallocatedComments-  debugM $ "addComments:cs" ++ show cs-  -- We can only sort the comments if we are in the first phase,-  -- were all comments have locations. If any have EpaDelta the-  -- sort will fail, so we do not try.-  if sortNeeded && all noDelta (csNew ++ cs)-    then putUnallocatedComments (sort (cs ++ csNew))-    else putUnallocatedComments (cs ++ csNew)--noDelta :: Comment -> Bool-noDelta c = case commentLoc c of-    EpaSpan _ -> True-    _ -> False---- ------------------------------------------------------------------------- | Just before we print out the EOF comments, flush the remaining--- ones in the state.-flushComments :: (Monad m, Monoid w) => [LEpaComment] -> EP w m ()-flushComments !trailing_anns = do-  debugM $ "flushComments entered: " ++ showAst trailing_anns-  addCommentsA trailing_anns-  debugM $ "flushComments after addCommentsA"-  cs <- getUnallocatedComments-  debugM $ "flushComments: got cs"-  debugM $ "flushing comments starting: cs" ++ showAst cs-    -- AZ:TODO: is the sort still needed?-  -- mapM_ printOneComment (sortComments cs)-  mapM_ printOneComment cs-  putUnallocatedComments []-  debugM $ "flushing comments done"---- ------------------------------------------------------------------------- |In order to interleave annotations into the stream, we turn them into--- comments. They are removed from the annotation to avoid duplication.-annotationsToComments :: (Monad m, Monoid w)-  => a -> Lens a [AddEpAnn] -> [AnnKeywordId] -> EP w m a-annotationsToComments a l kws = do-  let (newComments, newAnns) = go ([],[]) (view l a)-  addComments True newComments-  return (set l (reverse newAnns) a)-  where-    keywords = Set.fromList kws--    go :: ([Comment], [AddEpAnn]) -> [AddEpAnn] -> ([Comment], [AddEpAnn])-    go acc [] = acc-    go (cs',ans) ((AddEpAnn k ss) : ls)-      | Set.member k keywords = go ((mkKWComment k (epaToNoCommentsLocation ss)):cs', ans) ls-      | otherwise             = go (cs', (AddEpAnn k ss):ans)    ls---- ------------------------------------------------------------------------- Temporary function to simply reproduce the "normal" pretty printer output-withPpr :: (Monad m, Monoid w, Outputable a) => a -> EP w m a-withPpr a = do-  ss <- getAnchorU-  debugM $ "withPpr: ss=" ++ show ss-  printStringAtRs' ss (showPprUnsafe a)-  return a---- ------------------------------------------------------------------------- | An AST fragment with an annotation must be able to return the--- requirements for nesting another one, captured in an 'Entry', and--- to be able to use the rest of the exactprint machinery to print the--- element.  In the analogy to Outputable, 'exact' plays the role of--- 'ppr'.-class (Typeable a) => ExactPrint a where-  getAnnotationEntry :: a -> Entry-  setAnnotationAnchor :: a -> Anchor -> [TrailingAnn] -> EpAnnComments -> a-  exact :: (Monad m, Monoid w) => a -> EP w m a---- ------------------------------------------------------------------------ Start of utility functions--- -----------------------------------------------------------------------printSourceText :: (Monad m, Monoid w) => SourceText -> String -> EP w m ()-printSourceText (NoSourceText) txt   =  printStringAdvance txt >> return ()-printSourceText (SourceText   txt) _ =  printStringAdvance (unpackFS txt) >> return ()--printSourceTextAA :: (Monad m, Monoid w) => SourceText -> String -> EP w m ()-printSourceTextAA (NoSourceText) txt   = printStringAdvanceA  txt >> return ()-printSourceTextAA (SourceText   txt) _ = printStringAdvanceA  (unpackFS txt) >> return ()---- -----------------------------------------------------------------------printStringAtRs :: (Monad m, Monoid w) => RealSrcSpan -> String -> EP w m EpaLocation-printStringAtRs pa str = printStringAtRsC CaptureComments pa str--printStringAtRsC :: (Monad m, Monoid w)-  => CaptureComments -> RealSrcSpan -> String -> EP w m EpaLocation-printStringAtRsC capture pa str = do-  debugM $ "printStringAtRsC: pa=" ++ showAst pa-  printCommentsBefore pa-  pe <- getPriorEndD-  debugM $ "printStringAtRsC:pe=" ++ show pe-  let p = ss2delta pe pa-  p' <- adjustDeltaForOffsetM p-  debugM $ "printStringAtRsC:(p,p')=" ++ show (p,p')-  printStringAtLsDelta p' str-  setPriorEndASTD pa-  cs' <- case capture of-    CaptureComments -> takeAppliedComments-    NoCaptureComments -> return []-  debugM $ "printStringAtRsC:cs'=" ++ show cs'-  debugM $ "printStringAtRsC:p'=" ++ showAst p'-  debugM $ "printStringAtRsC: (EpaDelta p' [])=" ++ showAst (EpaDelta p' NoComments)-  debugM $ "printStringAtRsC: (EpaDelta p' (map comment2LEpaComment cs'))=" ++ showAst (EpaDelta p' (map comment2LEpaComment cs'))-  return (EpaDelta p' (map comment2LEpaComment cs'))--printStringAtRs' :: (Monad m, Monoid w) => RealSrcSpan -> String -> EP w m ()-printStringAtRs' pa str = printStringAtRsC NoCaptureComments pa str >> return ()---- -----------------------------------------------------------------------printStringAtMLoc' :: (Monad m, Monoid w)-  => Maybe EpaLocation -> String -> EP w m (Maybe EpaLocation)-printStringAtMLoc' (Just aa) s = Just <$> printStringAtAA aa s-printStringAtMLoc' Nothing s = do-  printStringAtLsDelta (SameLine 1) s-  return (Just (EpaDelta (SameLine 1) []))--printStringAtMLocL :: (Monad m, Monoid w)-  => EpAnn a -> Lens a (Maybe EpaLocation) -> String -> EP w m (EpAnn a)-printStringAtMLocL (EpAnn anc an cs) l s = do-  r <- go (view l an) s-  return (EpAnn anc (set l r an) cs)-  where-    go (Just aa) str = Just <$> printStringAtAA aa str-    go Nothing str = do-      printStringAtLsDelta (SameLine 1) str-      return (Just (EpaDelta (SameLine 1) []))--printStringAdvanceA :: (Monad m, Monoid w) => String -> EP w m ()-printStringAdvanceA str = printStringAtAA (EpaDelta (SameLine 0) []) str >> return ()--printStringAtAA :: (Monad m, Monoid w) => EpaLocation -> String -> EP w m EpaLocation-printStringAtAA el str = printStringAtAAC CaptureComments el str--printStringAtNC :: (Monad m, Monoid w) => NoCommentsLocation -> String -> EP w m NoCommentsLocation-printStringAtNC el str = do-    el' <- printStringAtAAC NoCaptureComments (noCommentsToEpaLocation el) str-    return (epaToNoCommentsLocation el')--printStringAtAAL :: (Monad m, Monoid w)-  => a -> Lens a EpaLocation -> String -> EP w m a-printStringAtAAL an l str = do-  r <- printStringAtAAC CaptureComments (view l an) str-  return (set l r an)--printStringAtAAC :: (Monad m, Monoid w)-  => CaptureComments -> EpaLocation -> String -> EP w m EpaLocation-printStringAtAAC capture (EpaSpan (RealSrcSpan r _)) s = printStringAtRsC capture r s-printStringAtAAC _capture (EpaSpan ss@(UnhelpfulSpan _)) _s = error $ "printStringAtAAC:ss=" ++ show ss-printStringAtAAC capture (EpaDelta d cs) s = do-  mapM_ printOneComment $ concatMap tokComment cs-  pe1 <- getPriorEndD-  p1 <- getPosP-  printStringAtLsDelta d s-  p2 <- getPosP-  pe2 <- getPriorEndD-  debugM $ "printStringAtAA:(pe1,pe2,p1,p2)=" ++ show (pe1,pe2,p1,p2)-  setPriorEndASTPD (pe1,pe2)-  cs' <- case capture of-    CaptureComments -> takeAppliedComments-    NoCaptureComments -> return []-  debugM $ "printStringAtAA:(pe1,pe2,p1,p2,cs')=" ++ show (pe1,pe2,p1,p2,cs')-  return (EpaDelta d (map comment2LEpaComment cs'))---- -----------------------------------------------------------------------markExternalSourceTextE :: (Monad m, Monoid w) => EpaLocation -> SourceText -> String -> EP w m EpaLocation-markExternalSourceTextE l NoSourceText txt   = printStringAtAA l txt-markExternalSourceTextE l (SourceText txt) _ = printStringAtAA l (unpackFS txt)---- -----------------------------------------------------------------------markLensMAA :: (Monad m, Monoid w)-  => EpAnn a -> Lens a (Maybe AddEpAnn) -> EP w m (EpAnn a)-markLensMAA epann l = markLensMAA' epann (lepa . l)--markLensMAA' :: (Monad m, Monoid w)-  => a -> Lens a (Maybe AddEpAnn) -> EP w m a-markLensMAA' a l =-  case view l a of-    Nothing -> return a-    Just aa -> do-      aa' <- markAddEpAnn aa-      return (set l (Just aa') a)---- ---------------------------------------markLensAA :: (Monad m, Monoid w)-  => EpAnn a -> Lens a AddEpAnn -> EP w m (EpAnn a)-markLensAA epann l = markLensAA' epann (lepa . l)--markLensAA' :: (Monad m, Monoid w)-  => a -> Lens a AddEpAnn -> EP w m a-markLensAA' a l = do-  a' <- markKw (view l a)-  return (set l a' a)---- ---------------------------------------markEpAnnLMS :: (Monad m, Monoid w)-  => EpAnn a -> Lens a [AddEpAnn] -> AnnKeywordId -> Maybe String -> EP w m (EpAnn a)-markEpAnnLMS epann l kw ms = markEpAnnLMS'' epann (lepa . l) kw ms--markEpAnnLMS'' :: (Monad m, Monoid w)-  => a -> Lens a [AddEpAnn] -> AnnKeywordId -> Maybe String -> EP w m a-markEpAnnLMS'' an l kw Nothing = markEpAnnL an l kw-markEpAnnLMS'' a l kw (Just str) = do-  anns <- mapM go (view l a)-  return (set l anns a)-  where-    go :: (Monad m, Monoid w) => AddEpAnn -> EP w m AddEpAnn-    go (AddEpAnn kw' r)-      | kw' == kw = do-          r' <- printStringAtAA r str-          return (AddEpAnn kw' r')-      | otherwise = return (AddEpAnn kw' r)---- ---------------------------------------markEpAnnMS' :: (Monad m, Monoid w)-  => [AddEpAnn] -> AnnKeywordId -> Maybe String -> EP w m [AddEpAnn]-markEpAnnMS' anns kw Nothing = mark anns kw-markEpAnnMS' anns kw (Just str) = do-  mapM go anns-  where-    go :: (Monad m, Monoid w) => AddEpAnn -> EP w m AddEpAnn-    go (AddEpAnn kw' r)-      | kw' == kw = do-          r' <- printStringAtAA r str-          return (AddEpAnn kw' r')-      | otherwise = return (AddEpAnn kw' r)---- ---------------------------------------markEpAnnLMS' :: (Monad m, Monoid w)-  => EpAnn a -> Lens a AddEpAnn -> AnnKeywordId -> Maybe String -> EP w m (EpAnn a)-markEpAnnLMS' an l kw ms = markEpAnnLMS0 an (lepa . l) kw ms--markEpAnnLMS0 :: (Monad m, Monoid w)-  => a -> Lens a AddEpAnn -> AnnKeywordId -> Maybe String -> EP w m a-markEpAnnLMS0 an l _kw Nothing = markLensKwA an l-markEpAnnLMS0 a l kw (Just str) = do-  anns <- go (view l a)-  return (set l anns a)-  where-    go :: (Monad m, Monoid w) => AddEpAnn -> EP w m AddEpAnn-    go (AddEpAnn kw' r)-      | kw' == kw = do-          r' <- printStringAtAA r str-          return (AddEpAnn kw' r')-      | otherwise = return (AddEpAnn kw' r)---- -----------------------------------------------------------------------markEpToken :: forall m w tok . (Monad m, Monoid w, KnownSymbol tok)-  => EpToken tok -> EP w m (EpToken tok)-markEpToken NoEpTok = return NoEpTok-markEpToken (EpTok aa) = do-  aa' <- printStringAtAA aa (symbolVal (Proxy @tok))-  return (EpTok aa')--markEpUniToken :: forall m w tok utok . (Monad m, Monoid w, KnownSymbol tok, KnownSymbol utok)-  => EpUniToken tok utok -> EP w m (EpUniToken tok utok)-markEpUniToken NoEpUniTok = return NoEpUniTok-markEpUniToken (EpUniTok aa isUnicode)  = do-  aa' <- case isUnicode of-    NormalSyntax  -> printStringAtAA aa (symbolVal (Proxy @tok))-    UnicodeSyntax -> printStringAtAA aa (symbolVal (Proxy @utok))-  return (EpUniTok aa' isUnicode)---- -----------------------------------------------------------------------markArrow :: (Monad m, Monoid w) => HsArrow GhcPs -> EP w m (HsArrow GhcPs)-markArrow (HsUnrestrictedArrow arr) = do-  arr' <- markEpUniToken arr-  return (HsUnrestrictedArrow arr')-markArrow (HsLinearArrow (EpPct1 pct1 arr)) = do-  pct1' <- markEpToken pct1-  arr' <- markEpUniToken arr-  return (HsLinearArrow (EpPct1 pct1' arr'))-markArrow (HsLinearArrow (EpLolly arr)) = do-  arr' <- markEpToken arr-  return (HsLinearArrow (EpLolly arr'))-markArrow (HsExplicitMult (pct, arr) t) = do-  pct' <- markEpToken pct-  t' <- markAnnotated t-  arr' <- markEpUniToken arr-  return (HsExplicitMult (pct', arr') t')----- -----------------------------------------------------------------------markAnnCloseP :: (Monad m, Monoid w) => EpAnn AnnPragma -> EP w m (EpAnn AnnPragma)-markAnnCloseP an = markEpAnnLMS' an lapr_close AnnClose (Just "#-}")--markAnnCloseP' :: (Monad m, Monoid w) => AnnPragma -> EP w m AnnPragma-markAnnCloseP' an = markEpAnnLMS0 an lapr_close AnnClose (Just "#-}")--markAnnOpenP :: (Monad m, Monoid w) => EpAnn AnnPragma -> SourceText -> String -> EP w m (EpAnn AnnPragma)-markAnnOpenP an NoSourceText txt   = markEpAnnLMS' an lapr_open AnnOpen (Just txt)-markAnnOpenP an (SourceText txt) _ = markEpAnnLMS' an lapr_open AnnOpen (Just $ unpackFS txt)--markAnnOpenP' :: (Monad m, Monoid w) => AnnPragma -> SourceText -> String -> EP w m AnnPragma-markAnnOpenP' an NoSourceText txt   = markEpAnnLMS0 an lapr_open AnnOpen (Just txt)-markAnnOpenP' an (SourceText txt) _ = markEpAnnLMS0 an lapr_open AnnOpen (Just $ unpackFS txt)--markAnnOpen :: (Monad m, Monoid w) => [AddEpAnn] -> SourceText -> String -> EP w m [AddEpAnn]-markAnnOpen an NoSourceText txt   = markEpAnnLMS'' an lidl AnnOpen (Just txt)-markAnnOpen an (SourceText txt) _ = markEpAnnLMS'' an lidl AnnOpen (Just $ unpackFS txt)--markAnnOpen' :: (Monad m, Monoid w)-  => Maybe EpaLocation -> SourceText -> String -> EP w m (Maybe EpaLocation)-markAnnOpen' ms NoSourceText txt   = printStringAtMLoc' ms txt-markAnnOpen' ms (SourceText txt) _ = printStringAtMLoc' ms $ unpackFS txt--markAnnOpen'' :: (Monad m, Monoid w)-  => EpaLocation -> SourceText -> String -> EP w m EpaLocation-markAnnOpen'' el NoSourceText txt   = printStringAtAA el txt-markAnnOpen'' el (SourceText txt) _ = printStringAtAA el $ unpackFS txt---- ----------------------------------------------------------------------{--data AnnParen-  = AnnParen {-      ap_adornment :: ParenType,-      ap_open      :: EpaLocation,-      ap_close     :: EpaLocation-      } deriving (Data)--}-markOpeningParen, markClosingParen :: (Monad m, Monoid w) => AnnParen -> EP w m AnnParen-markOpeningParen an = markParen an lfst-markClosingParen an = markParen an lsnd--markParen :: (Monad m, Monoid w) => AnnParen -> (forall a. Lens (a,a) a) -> EP w m AnnParen-markParen (AnnParen pt o c) l = do-  loc' <- markKwA (view l $ kw pt) (view l (o, c))-  let (o',c') = set l loc' (o,c)-  return (AnnParen pt o' c')-  where-    kw AnnParens       = (AnnOpenP,  AnnCloseP)-    kw AnnParensHash   = (AnnOpenPH, AnnClosePH)-    kw AnnParensSquare = (AnnOpenS, AnnCloseS)---- ------------------------------------------------------------------------ Bare bones Optics--- Base on From https://hackage.haskell.org/package/lens-tutorial-1.0.3/docs/Control-Lens-Tutorial.html--type Lens    a b = forall f . Functor f => (b -> f        b) -> (a -> f        a)-type Getting a b =                         (b -> Const  b b) -> (a -> Const b  a)-type ASetter a b =                         (b -> Identity b) -> (a -> Identity a)--view :: MonadReader s m => Getting s a -> m a-view l = Reader.asks (getConst . l Const)-{-# INLINE view #-}--over :: ASetter a b -> (b -> b) -> (a -> a)-over l f = runIdentity . l (Identity . f)-{-# INLINE over #-}--set  :: Lens a b -> b -> a -> a-set lens b = over lens (\_ -> b)-{-# INLINE set #-}--{--Question: How do I combine lenses?--Answer: You compose them, using function composition (Yes, really!)--You can think of the function composition operator as having this type:--(.) :: Lens' a b -> Lens' b c -> Lens' a c--}---- ------------------------------------------------------------------------ Lenses---- data EpAnn ann---   = EpAnn { entry   :: !Anchor---            , anns     :: !ann---            , comments :: !EpAnnComments---            }--lepa :: Lens (EpAnn a) a-lepa k epAnn = fmap (\newAnns -> epAnn { anns = newAnns })-                    (k (anns epAnn))---- data AnnsModule---   = AnnsModule {---     am_main :: [AddEpAnn],---     am_decls :: AnnList---     } deriving (Data, Eq)--lam_main :: Lens AnnsModule [AddEpAnn]-lam_main k annsModule = fmap (\newAnns -> annsModule { am_main = newAnns })-                             (k (am_main annsModule))---- lam_decls :: Lens AnnsModule AnnList--- lam_decls k annsModule = fmap (\newAnns -> annsModule { am_decls = newAnns })---                               (k (am_decls annsModule))----- data EpAnnImportDecl = EpAnnImportDecl---   { importDeclAnnImport    :: EpaLocation---   , importDeclAnnPragma    :: Maybe (EpaLocation, EpaLocation)---   , importDeclAnnSafe      :: Maybe EpaLocation---   , importDeclAnnQualified :: Maybe EpaLocation---   , importDeclAnnPackage   :: Maybe EpaLocation---   , importDeclAnnAs        :: Maybe EpaLocation---   } deriving (Data)--limportDeclAnnImport :: Lens EpAnnImportDecl EpaLocation-limportDeclAnnImport k annImp = fmap (\new -> annImp { importDeclAnnImport = new })-                                     (k (importDeclAnnImport annImp))---- limportDeclAnnPragma :: Lens EpAnnImportDecl (Maybe (EpaLocation, EpaLocation))--- limportDeclAnnPragma k annImp = fmap (\new -> annImp { importDeclAnnPragma = new })---                                      (k (importDeclAnnPragma annImp))--limportDeclAnnSafe :: Lens EpAnnImportDecl (Maybe EpaLocation)-limportDeclAnnSafe k annImp = fmap (\new -> annImp { importDeclAnnSafe = new })-                                     (k (importDeclAnnSafe annImp))--limportDeclAnnQualified :: Lens EpAnnImportDecl (Maybe EpaLocation)-limportDeclAnnQualified k annImp = fmap (\new -> annImp { importDeclAnnQualified = new })-                                     (k (importDeclAnnQualified annImp))--limportDeclAnnPackage :: Lens EpAnnImportDecl (Maybe EpaLocation)-limportDeclAnnPackage k annImp = fmap (\new -> annImp { importDeclAnnPackage = new })-                                     (k (importDeclAnnPackage annImp))---- limportDeclAnnAs :: Lens EpAnnImportDecl (Maybe EpaLocation)--- limportDeclAnnAs k annImp = fmap (\new -> annImp { importDeclAnnAs = new })---                                      (k (importDeclAnnAs annImp))---- ----------------------------------------- data AnnList---   = AnnList {---       al_anchor    :: Maybe Anchor, -- ^ start point of a list having layout---       al_open      :: Maybe AddEpAnn,---       al_close     :: Maybe AddEpAnn,---       al_rest      :: [AddEpAnn], -- ^ context, such as 'where' keyword---       al_trailing  :: [TrailingAnn] -- ^ items appearing after the---                                     -- list, such as '=>' for a---                                     -- context---       } deriving (Data,Eq)--lal_open :: Lens AnnList (Maybe AddEpAnn)-lal_open k parent = fmap (\new -> parent { al_open = new })-                           (k (al_open parent))--lal_close :: Lens AnnList (Maybe AddEpAnn)-lal_close k parent = fmap (\new -> parent { al_close = new })-                           (k (al_close parent))--lal_rest :: Lens AnnList [AddEpAnn]-lal_rest k parent = fmap (\new -> parent { al_rest = new })-                           (k (al_rest parent))---- lal_trailing :: Lens AnnList [TrailingAnn]--- lal_trailing k parent = fmap (\new -> parent { al_trailing = new })---                            (k (al_trailing parent))---- ---------------------------------------lapr_rest :: Lens AnnPragma [AddEpAnn]-lapr_rest k parent = fmap (\newAnns -> parent { apr_rest = newAnns })-                          (k (apr_rest parent))--lapr_open :: Lens AnnPragma AddEpAnn-lapr_open k parent = fmap (\new -> parent { apr_open = new })-                          (k (apr_open parent))--lapr_close :: Lens AnnPragma AddEpAnn-lapr_close k parent = fmap (\new -> parent { apr_close = new })-                          (k (apr_close parent))--lidl :: Lens [AddEpAnn] [AddEpAnn]-lidl k parent = fmap (\new -> new)-                     (k parent)--lid :: Lens a a-lid k parent = fmap (\new -> new)-                    (k parent)--lfst :: Lens (a,a) a-lfst k parent = fmap (\new -> (new, snd parent))-                     (k (fst parent))--lsnd :: Lens (a,a) a-lsnd k parent = fmap (\new -> (fst parent, new))-                     (k (snd parent))---- ---------------------------------------- data AnnExplicitSum---   = AnnExplicitSum {---       aesOpen       :: EpaLocation,---       aesBarsBefore :: [EpaLocation],---       aesBarsAfter  :: [EpaLocation],---       aesClose      :: EpaLocation---       } deriving Data--laesOpen :: Lens AnnExplicitSum EpaLocation-laesOpen k parent = fmap (\new -> parent { aesOpen = new })-                         (k (aesOpen parent))--laesBarsBefore :: Lens AnnExplicitSum [EpaLocation]-laesBarsBefore k parent = fmap (\new -> parent { aesBarsBefore = new })-                               (k (aesBarsBefore parent))--laesBarsAfter :: Lens AnnExplicitSum [EpaLocation]-laesBarsAfter k parent = fmap (\new -> parent { aesBarsAfter = new })-                               (k (aesBarsAfter parent))--laesClose :: Lens AnnExplicitSum EpaLocation-laesClose k parent = fmap (\new -> parent { aesClose = new })-                               (k (aesClose parent))---- ---------------------------------------- data AnnFieldLabel---   = AnnFieldLabel {---       afDot :: Maybe EpaLocation---       } deriving Data--lafDot :: Lens AnnFieldLabel (Maybe EpaLocation)-lafDot k parent = fmap (\new -> parent { afDot = new })-                         (k (afDot parent))---- ---------------------------------------- data AnnProjection---   = AnnProjection {---       apOpen  :: EpaLocation, -- ^ '('---       apClose :: EpaLocation  -- ^ ')'---       } deriving Data--lapOpen :: Lens AnnProjection EpaLocation-lapOpen k parent = fmap (\new -> parent { apOpen = new })-                         (k (apOpen parent))--lapClose :: Lens AnnProjection EpaLocation-lapClose k parent = fmap (\new -> parent { apClose = new })-                         (k (apClose parent))---- ---------------------------------------- data AnnsIf---   = AnnsIf {---       aiIf       :: EpaLocation,---       aiThen     :: EpaLocation,---       aiElse     :: EpaLocation,---       aiThenSemi :: Maybe EpaLocation,---       aiElseSemi :: Maybe EpaLocation---       } deriving Data--laiIf :: Lens AnnsIf EpaLocation-laiIf k parent = fmap (\new -> parent { aiIf = new })-                      (k (aiIf parent))--laiThen :: Lens AnnsIf EpaLocation-laiThen k parent = fmap (\new -> parent { aiThen = new })-                        (k (aiThen parent))--laiElse :: Lens AnnsIf EpaLocation-laiElse k parent = fmap (\new -> parent { aiElse = new })-                        (k (aiElse parent))--laiThenSemi :: Lens AnnsIf (Maybe EpaLocation)-laiThenSemi k parent = fmap (\new -> parent { aiThenSemi = new })-                            (k (aiThenSemi parent))--laiElseSemi :: Lens AnnsIf (Maybe EpaLocation)-laiElseSemi k parent = fmap (\new -> parent { aiElseSemi = new })-                            (k (aiElseSemi parent))---- ----------------------------------------- data AnnParen---   = AnnParen {---       ap_adornment :: ParenType,---       ap_open      :: EpaLocation,---       ap_close     :: EpaLocation---       } deriving (Data)---- lap_open :: Lens AnnParen EpaLocation--- lap_open k parent = fmap (\new -> parent { ap_open = new })---                          (k (ap_open parent))---- lap_close :: Lens AnnParen EpaLocation--- lap_close k parent = fmap (\new -> parent { ap_close = new })---                           (k (ap_close parent))---- ---------------------------------------- data EpAnnHsCase = EpAnnHsCase---       { hsCaseAnnCase :: EpaLocation---       , hsCaseAnnOf   :: EpaLocation---       , hsCaseAnnsRest :: [AddEpAnn]---       } deriving Data--lhsCaseAnnCase :: Lens EpAnnHsCase EpaLocation-lhsCaseAnnCase k parent = fmap (\new -> parent { hsCaseAnnCase = new })-                               (k (hsCaseAnnCase parent))--lhsCaseAnnOf :: Lens EpAnnHsCase EpaLocation-lhsCaseAnnOf k parent = fmap (\new -> parent { hsCaseAnnOf = new })-                               (k (hsCaseAnnOf parent))--lhsCaseAnnsRest :: Lens EpAnnHsCase [AddEpAnn]-lhsCaseAnnsRest k parent = fmap (\new -> parent { hsCaseAnnsRest = new })-                                (k (hsCaseAnnsRest parent))---- ------------------------------------------------------------------------- data HsRuleAnn---   = HsRuleAnn---        { ra_tyanns :: Maybe (AddEpAnn, AddEpAnn)---                  -- ^ The locations of 'forall' and '.' for forall'd type vars---                  -- Using AddEpAnn to capture possible unicode variants---        , ra_tmanns :: Maybe (AddEpAnn, AddEpAnn)---                  -- ^ The locations of 'forall' and '.' for forall'd term vars---                  -- Using AddEpAnn to capture possible unicode variants---        , ra_rest :: [AddEpAnn]---        } deriving (Data, Eq)--lra_tyanns :: Lens HsRuleAnn (Maybe (AddEpAnn, AddEpAnn))-lra_tyanns k parent = fmap (\new -> parent { ra_tyanns = new })-                               (k (ra_tyanns parent))--ff :: Maybe (a,b) -> (Maybe a,Maybe b)-ff Nothing = (Nothing, Nothing)-ff (Just (a,b)) = (Just a, Just b)---gg :: (Maybe a,Maybe b) -> Maybe (a,b)-gg (Nothing, Nothing) = Nothing-gg (Just a, Just b) = Just (a,b)-gg _ = error "gg:expecting two Nothing or two Just"--lff :: Lens (Maybe (a,b)) (Maybe a,Maybe b)-lff k parent = fmap (\new -> gg new)-                    (k (ff parent))---- (.) :: Lens' a b -> Lens' b c -> Lens' a c-lra_tyanns_fst :: Lens HsRuleAnn (Maybe AddEpAnn)-lra_tyanns_fst = lra_tyanns . lff . lfst--lra_tyanns_snd :: Lens HsRuleAnn (Maybe AddEpAnn)-lra_tyanns_snd = lra_tyanns . lff . lsnd--lra_tmanns :: Lens HsRuleAnn (Maybe (AddEpAnn, AddEpAnn))-lra_tmanns k parent = fmap (\new -> parent { ra_tmanns = new })-                               (k (ra_tmanns parent))--lra_tmanns_fst :: Lens HsRuleAnn (Maybe AddEpAnn)-lra_tmanns_fst = lra_tmanns . lff . lfst--lra_tmanns_snd :: Lens HsRuleAnn (Maybe AddEpAnn)-lra_tmanns_snd = lra_tmanns . lff . lsnd--lra_rest :: Lens HsRuleAnn [AddEpAnn]-lra_rest k parent = fmap (\new -> parent { ra_rest = new })-                                (k (ra_rest parent))----- ------------------------------------------------------------------------ data GrhsAnn---   = GrhsAnn {---       ga_vbar :: Maybe EpaLocation, -- TODO:AZ do we need this?---       ga_sep  :: AddEpAnn -- ^ Match separator location---       } deriving (Data)--lga_vbar :: Lens GrhsAnn (Maybe EpaLocation)-lga_vbar k parent = fmap (\new -> parent { ga_vbar = new })-                                (k (ga_vbar parent))--lga_sep :: Lens GrhsAnn AddEpAnn-lga_sep k parent = fmap (\new -> parent { ga_sep = new })-                                (k (ga_sep parent))---- ------------------------------------------------------------------------ data AnnSig---   = AnnSig {---       asDcolon :: AddEpAnn, -- Not an EpaAnchor to capture unicode option---       asRest   :: [AddEpAnn]---       } deriving Data--lasDcolon :: Lens AnnSig AddEpAnn-lasDcolon k parent = fmap (\new -> parent { asDcolon = new })-                                (k (asDcolon parent))--lasRest :: Lens AnnSig [AddEpAnn]-lasRest k parent = fmap (\new -> parent { asRest = new })-                                (k (asRest parent))---- ------------------------------------------------------------------------ data EpAnnSumPat = EpAnnSumPat---       { sumPatParens      :: [AddEpAnn]---       , sumPatVbarsBefore :: [EpaLocation]---       , sumPatVbarsAfter  :: [EpaLocation]---       } deriving Data--lsumPatParens :: Lens EpAnnSumPat [AddEpAnn]-lsumPatParens k parent = fmap (\new -> parent { sumPatParens = new })-                              (k (sumPatParens parent))--lsumPatVbarsBefore :: Lens EpAnnSumPat [EpaLocation]-lsumPatVbarsBefore k parent = fmap (\new -> parent { sumPatVbarsBefore = new })-                              (k (sumPatVbarsBefore parent))--lsumPatVbarsAfter :: Lens EpAnnSumPat [EpaLocation]-lsumPatVbarsAfter k parent = fmap (\new -> parent { sumPatVbarsAfter = new })-                              (k (sumPatVbarsAfter parent))---- End of lenses--- -----------------------------------------------------------------------markLensKwA :: (Monad m, Monoid w)-  => a -> Lens a AddEpAnn -> EP w m a-markLensKwA a l = do-  loc <- markKw (view l a)-  return (set l loc a)--markLensKw' :: (Monad m, Monoid w)-  => EpAnn a -> Lens a EpaLocation -> AnnKeywordId -> EP w m (EpAnn a)-markLensKw' (EpAnn anc a cs) l kw = do-  loc <- markKwA kw (view l a)-  return (EpAnn anc (set l loc a) cs)--markLensKw :: (Monad m, Monoid w)-  => a -> Lens a EpaLocation -> AnnKeywordId -> EP w m a-markLensKw a l kw = do-  loc <- markKwA kw (view l a)-  return (set l loc a)--markAnnKwAllL :: (Monad m, Monoid w)-  => a -> Lens a [EpaLocation] -> AnnKeywordId -> EP w m a-markAnnKwAllL a l kw = do-  anns <- mapM (markKwA kw) (view l a)-  return (set l anns a)--markLensKwM :: (Monad m, Monoid w)-  => EpAnn a -> Lens a (Maybe EpaLocation) -> AnnKeywordId -> EP w m (EpAnn a)-markLensKwM (EpAnn anc a cs) l kw = do-  new <- go (view l a)-  return (EpAnn anc (set l new a) cs)-  where-    go Nothing = return Nothing-    go (Just s) = Just <$> markKwA kw s--markLensKwM' :: (Monad m, Monoid w)-  => a -> Lens a (Maybe EpaLocation) -> AnnKeywordId -> EP w m a-markLensKwM' a l kw = do-  new <- go (view l a)-  return (set l new a)-  where-    go Nothing = return Nothing-    go (Just s) = Just <$> markKwA kw s---- -----------------------------------------------------------------------markEpAnnL' :: (Monad m, Monoid w)-  => EpAnn ann -> Lens ann [AddEpAnn] -> AnnKeywordId -> EP w m (EpAnn ann)-markEpAnnL' epann l kw = markEpAnnL epann (lepa . l) kw--markEpAnnL :: (Monad m, Monoid w)-  => ann -> Lens ann [AddEpAnn] -> AnnKeywordId -> EP w m ann-markEpAnnL a l kw = do-  anns <- mark (view l a) kw-  return (set l anns a)---- ---------------------------------------markEpAnnAllL :: (Monad m, Monoid w)-  => EpAnn ann -> Lens ann [AddEpAnn] -> AnnKeywordId -> EP w m (EpAnn ann)-markEpAnnAllL (EpAnn anc a cs) l kw = do-  anns <- mapM doit (view l a)-  return (EpAnn anc (set l anns a) cs)-  where-    doit an@(AddEpAnn ka _)-      = if ka == kw-          then markKw an-          else return an--markEpAnnAllL' :: (Monad m, Monoid w)-  => ann -> Lens ann [AddEpAnn] -> AnnKeywordId -> EP w m ann-markEpAnnAllL' a l kw = do-  anns <- mapM doit (view l a)-  return (set l anns a)-  where-    doit an@(AddEpAnn ka _)-      = if ka == kw-          then markKw an-          else return an--markAddEpAnn :: (Monad m, Monoid w) => AddEpAnn -> EP w m AddEpAnn-markAddEpAnn a@(AddEpAnn kw _) = do-  r <- mark [a] kw-  case r of-    [a'] -> return a'-    _ -> error "Should not happen: markAddEpAnn"--mark :: (Monad m, Monoid w) => [AddEpAnn] -> AnnKeywordId -> EP w m [AddEpAnn]-mark anns kw = do-  case find' kw anns of-    (lead, Just aa, end) -> do-      aa' <- markKw aa-      return (lead ++ [aa'] ++ end)-    (_lead, Nothing, _end) -> case find' (unicodeAnn kw) anns of-      (leadu, Just aau, endu) -> do-        aau' <- markKw aau-        return (leadu ++ [aau'] ++ endu)-      (_,Nothing,_) -> return anns---- | Find for update, returning lead section of the list, item if--- found, and tail of the list-find' :: AnnKeywordId -> [AddEpAnn] -> ([AddEpAnn], Maybe AddEpAnn, [AddEpAnn])-find' kw anns = (lead, middle, end)-  where-    (lead, rest) = break (\(AddEpAnn k _) -> k == kw) anns-    (middle,end) = case rest of-      [] -> (Nothing, [])-      (x:xs) -> (Just x, xs)--markKw :: (Monad m, Monoid w) => AddEpAnn -> EP w m AddEpAnn-markKw an = markKwC CaptureComments an--markKwC :: (Monad m, Monoid w) => CaptureComments -> AddEpAnn -> EP w m AddEpAnn-markKwC capture (AddEpAnn kw ss) = do-  ss' <- markKwAC capture kw ss-  return (AddEpAnn kw ss')---- | This should be the main driver of the process, managing printing keywords.--- It returns the 'EpaDelta' variant of the passed in 'EpaLocation'-markKwA :: (Monad m, Monoid w) => AnnKeywordId -> EpaLocation -> EP w m EpaLocation-markKwA kw aa = markKwAC CaptureComments kw aa--markKwAC :: (Monad m, Monoid w)-  => CaptureComments -> AnnKeywordId -> EpaLocation -> EP w m EpaLocation-markKwAC capture kw aa = printStringAtAAC capture aa (keywordToString kw)---- | Print a keyword encoded in a 'TrailingAnn'-markKwT :: (Monad m, Monoid w) => TrailingAnn -> EP w m TrailingAnn-markKwT (AddSemiAnn ss)    = AddSemiAnn    <$> markKwA AnnSemi ss-markKwT (AddCommaAnn ss)   = AddCommaAnn   <$> markKwA AnnComma ss-markKwT (AddVbarAnn ss)    = AddVbarAnn    <$> markKwA AnnVbar ss-markKwT (AddDarrowAnn ss)  = AddDarrowAnn  <$> markKwA AnnDarrow ss-markKwT (AddDarrowUAnn ss) = AddDarrowUAnn <$> markKwA AnnDarrowU ss---- -----------------------------------------------------------------------markAnnList :: (Monad m, Monoid w)-  => EpAnn AnnList -> EP w m a -> EP w m (EpAnn AnnList, a)-markAnnList ann action = do-  markAnnListA ann $ \a -> do-    r <- action-    return (a,r)--markAnnList' :: (Monad m, Monoid w)-  => AnnList -> EP w m a -> EP w m (AnnList, a)-markAnnList' ann action = do-  markAnnListA' ann $ \a -> do-    r <- action-    return (a,r)--markAnnListA :: (Monad m, Monoid w)-  => EpAnn AnnList-  -> (EpAnn AnnList -> EP w m (EpAnn AnnList, a))-  -> EP w m (EpAnn AnnList, a)-markAnnListA an action = do-  an0 <- markLensMAA an lal_open-  an1 <- markEpAnnAllL an0 lal_rest AnnSemi-  (an2, r) <- action an1-  an3 <- markLensMAA an2 lal_close-  return (an3, r)--markAnnListA' :: (Monad m, Monoid w)-  => AnnList-  -> (AnnList -> EP w m (AnnList, a))-  -> EP w m (AnnList, a)-markAnnListA' an action = do-  an0 <- markLensMAA' an lal_open-  an1 <- markEpAnnAllL' an0 lal_rest AnnSemi-  (an2, r) <- action an1-  an3 <- markLensMAA' an2 lal_close-  return (an3, r)---- -----------------------------------------------------------------------printCommentsBefore :: (Monad m, Monoid w) => RealSrcSpan -> EP w m ()-printCommentsBefore ss = do-  cs <- commentAllocationBefore ss-  debugM $ "printCommentsBefore: (ss): " ++ showPprUnsafe (rs2range ss)-  -- debugM $ "printComments: (ss,comment locations): " ++ showPprUnsafe (rs2range ss,map commentLoc cs)-  mapM_ printOneComment cs--printCommentsIn :: (Monad m, Monoid w) => RealSrcSpan -> EP w m ()-printCommentsIn ss = do-  cs <- commentAllocationIn ss-  debugM $ "printCommentsIn: (ss): " ++ showPprUnsafe (rs2range ss)-  -- debugM $ "printComments: (ss,comment locations): " ++ showPprUnsafe (rs2range ss,map commentLoc cs)-  mapM_ printOneComment cs-  debugM $ "printCommentsIn:done"---- -----------------------------------------------------------------------printOneComment :: (Monad m, Monoid w) => Comment -> EP w m ()-printOneComment c@(Comment _str loc _r _mo) = do-  debugM $ "printOneComment:c=" ++ showGhc c-  dp <-case loc of-    EpaDelta dp _ -> return dp-    EpaSpan (RealSrcSpan r _) -> do-        pe <- getPriorEndD-        debugM $ "printOneComment:pe=" ++ showGhc pe-        let dp = ss2delta pe r-        debugM $ "printOneComment:(dp,pe,loc)=" ++ showGhc (dp,pe,loc)-        adjustDeltaForOffsetM dp-    EpaSpan (UnhelpfulSpan _) -> return (SameLine 0)-  mep <- getExtraDP-  dp' <- case mep of-    Just (EpaDelta edp _) -> do-      debugM $ "printOneComment:edp=" ++ show edp-      adjustDeltaForOffsetM edp-    _ -> return dp-  -- Start of debug printing-  LayoutStartCol dOff <- getLayoutOffsetD-  debugM $ "printOneComment:(dp,dp',dOff,loc)=" ++ showGhc (dp,dp',dOff,loc)-  -- End of debug printing-  updateAndApplyComment c dp'-  printQueuedComment c dp'--updateAndApplyComment :: (Monad m, Monoid w) => Comment -> DeltaPos -> EP w m ()-updateAndApplyComment (Comment str anc pp mo) dp = do-  applyComment (Comment str anc' pp mo)-  where-    (r,c) = ss2posEnd pp-    dp'' = case anc of-      EpaDelta dp1 _ -> dp1-      EpaSpan (RealSrcSpan la _) ->-           if r == 0-             then (ss2delta (r,c+0) la)-             else (ss2delta (r,c)   la)-      EpaSpan (UnhelpfulSpan _) -> SameLine 0-    dp' = case anc of-      EpaSpan (RealSrcSpan r1 _) ->-          if pp == r1-                 then dp-                 else dp''-      _ -> dp''-    op' = case dp' of-            SameLine n -> if n >= 0-                            then EpaDelta dp' NoComments-                            else EpaDelta dp NoComments-            _ -> EpaDelta dp' NoComments-    anc' = if str == "" && op' == EpaDelta (SameLine 0) NoComments -- EOF comment-           then EpaDelta dp NoComments-           else EpaDelta dp NoComments---- -----------------------------------------------------------------------commentAllocationBefore :: (Monad m, Monoid w) => RealSrcSpan -> EP w m [Comment]-commentAllocationBefore ss = do-  cs <- getUnallocatedComments-  -- Note: The CPP comment injection may change the file name in the-  -- RealSrcSpan, which affects comparison, as the Ord instance for-  -- RealSrcSpan compares the file first. So we sort via ss2pos-  -- TODO: this is inefficient, use Pos all the way through-  let (earlier,later) = partition (\(Comment _str loc _r _mo) ->-                                     case loc of-                                       EpaSpan (RealSrcSpan r _) -> (ss2pos r) <= (ss2pos ss)-                                       _ -> True -- Choose one-                                  ) cs-  putUnallocatedComments later-  -- debugM $ "commentAllocation:(ss,earlier,later)" ++ show (rs2range ss,earlier,later)-  return earlier--commentAllocationIn :: (Monad m, Monoid w) => RealSrcSpan -> EP w m [Comment]-commentAllocationIn ss = do-  cs <- getUnallocatedComments-  -- Note: The CPP comment injection may change the file name in the-  -- RealSrcSpan, which affects comparison, as the Ord instance for-  -- RealSrcSpan compares the file first. So we sort via ss2pos-  -- TODO: this is inefficient, use Pos all the way through-  let (earlier,later) = partition (\(Comment _str loc _r _mo) ->-                                     case loc of-                                       EpaSpan (RealSrcSpan r _) -> (ss2posEnd r) <= (ss2posEnd ss)-                                       _ -> True -- Choose one-                                  ) cs-  putUnallocatedComments later-  -- debugM $ "commentAllocation:(ss,earlier,later)" ++ show (rs2range ss,earlier,later)-  return earlier--- -----------------------------------------------------------------------markAnnotatedWithLayout :: (Monad m, Monoid w) => ExactPrint ast => ast -> EP w m ast-markAnnotatedWithLayout a = setLayoutBoth $ markAnnotated a---- -----------------------------------------------------------------------markTopLevelList :: (Monad m, Monoid w) => ExactPrint ast => [ast] -> EP w m [ast]-markTopLevelList ls = mapM (\a -> setLayoutTopLevelP $ markAnnotated a) ls---- ------------------------------------------------------------------------ End of utility functions--- ------------------------------------------------------------------------ Start of ExactPrint instances--- ------------------------------------------------------------------------- | Bare Located elements are simply stripped off without further--- processing.-instance (ExactPrint a) => ExactPrint (Located a) where-  getAnnotationEntry (L l _) = case l of-    UnhelpfulSpan _ -> NoEntryVal-    _ -> Entry (EpaSpan l) [] emptyComments NoFlushComments CanUpdateAnchorOnly--  setAnnotationAnchor (L l a) _anc _ts _cs = L l a--  exact (L l a) = L l <$> markAnnotated a--instance (ExactPrint a) => ExactPrint (LocatedE a) where-  getAnnotationEntry (L l _) = Entry l [] emptyComments NoFlushComments CanUpdateAnchorOnly-  setAnnotationAnchor (L _ a) anc _ts _cs = L anc a--  exact (L la a) = do-    debugM $ "LocatedE a:la loc=" ++ show (ss2range $ locA la)-    a' <- markAnnotated a-    return (L la a')--instance (ExactPrint a) => ExactPrint (LocatedA a) where-  getAnnotationEntry = entryFromLocatedA-  setAnnotationAnchor la anc ts cs = setAnchorAn la anc ts cs-  exact (L la a) = do-    debugM $ "LocatedA a:la loc=" ++ show (ss2range $ locA la)-    a' <- markAnnotated a-    return (L la a')--instance (ExactPrint a) => ExactPrint (LocatedAn NoEpAnns a) where-  getAnnotationEntry = entryFromLocatedA-  setAnnotationAnchor la anc ts cs = setAnchorAn la anc ts cs-  exact (L la a) = do-    a' <- markAnnotated a-    return (L la a')--instance (ExactPrint a) => ExactPrint [a] where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor ls _ _ _ = ls-  exact ls = mapM markAnnotated ls--instance (ExactPrint a) => ExactPrint (Maybe a) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor ma _ _ _ = ma-  exact ma = mapM markAnnotated ma---- ------------------------------------------------------------------------- | 'Located (HsModule GhcPs)' corresponds to 'ParsedSource'-instance ExactPrint (HsModule GhcPs) where-  getAnnotationEntry hsmod = fromAnn' (hsmodAnn $ hsmodExt hsmod)-  -- A bit pointless actually changing anything here-  setAnnotationAnchor hsmod anc _ts cs = setAnchorHsModule hsmod anc cs-                   `debug` ("setAnnotationAnchor hsmod called" ++ showAst (anc,cs))--  exact (HsModule (XModulePs an lo mdeprec mbDoc) mmn mexports imports decls) = do--    let mbDoc' = mbDoc--    (an0, mmn' , mdeprec', mexports') <--      case mmn of-        Nothing -> return (an, mmn, mdeprec, mexports)-        Just m -> do-          an0 <- markEpAnnL' an lam_main AnnModule-          m' <- markAnnotated m--          mdeprec' <- setLayoutTopLevelP $ markAnnotated mdeprec--          mexports' <- setLayoutTopLevelP $ markAnnotated mexports--          an1 <- setLayoutTopLevelP $ markEpAnnL' an0 lam_main AnnWhere--          return (an1, Just m', mdeprec', mexports')--    lo0 <- case lo of-        EpExplicitBraces open close -> do-          open' <- markEpToken open-          return (EpExplicitBraces open' close)-        _ -> return lo--    am_decls' <- markTrailing (am_decls $ anns an0)--    mid <- markAnnotated (HsModuleImpDecls (am_cs $ anns an0) imports decls)-    let imports' = id_imps mid-    let decls' = id_decls mid--    lo1 <- case lo0 of-        EpExplicitBraces open close -> do-          close' <- markEpToken close-          return (EpExplicitBraces open close')-        _ -> return lo--    -- Print EOF-    case am_eof $ anns an of-      Nothing -> return ()-      Just (pos, prior) -> do-        debugM $ "am_eof:" ++ showGhc (pos, prior)-        setEofPos (Just (pos, prior))--    let anf = an0 { anns = (anns an0) { am_decls = am_decls', am_cs = [] }}-    debugM $ "HsModule, anf=" ++ showAst anf--    return (HsModule (XModulePs anf lo1 mdeprec' mbDoc') mmn' mexports' imports' decls')---- ------------------------------------------------------------------------- | This is used to ensure the comments are updated into the right--- place for makeDeltaAst.-data HsModuleImpDecls-    = HsModuleImpDecls {-        id_cs     :: [LEpaComment],-        id_imps   :: [LImportDecl GhcPs],-        id_decls  :: [LHsDecl GhcPs]-    } deriving Data--instance ExactPrint HsModuleImpDecls where-  -- Use an UnHelpfulSpan for the anchor, we are only interested in the comments-  getAnnotationEntry mid = mkEntry (EpaSpan (UnhelpfulSpan UnhelpfulNoLocationInfo)) [] (EpaComments (id_cs mid))-  setAnnotationAnchor mid _anc _ cs = mid { id_cs = priorComments cs ++ getFollowingComments cs }-     `debug` ("HsModuleImpDecls.setAnnotationAnchor:cs=" ++ showAst cs)-  exact (HsModuleImpDecls cs imports decls) = do-    imports' <- markTopLevelList imports-    decls' <- markTopLevelList (filter notDocDecl decls)-    return (HsModuleImpDecls cs imports' decls')----- -----------------------------------------------------------------------instance ExactPrint ModuleName where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor n _anc _ cs = n-     `debug` ("ModuleName.setAnnotationAnchor:cs=" ++ showAst cs)-  exact n = do-    debugM $ "ModuleName: " ++ showPprUnsafe n-    withPpr n---- -----------------------------------------------------------------------instance ExactPrint (LocatedP (WarningTxt GhcPs)) where-  getAnnotationEntry = entryFromLocatedA-  setAnnotationAnchor = setAnchorAn--  exact (L an (WarningTxt mb_cat src ws)) = do-    an0 <- markAnnOpenP an src "{-# WARNING"-    mb_cat' <- markAnnotated mb_cat-    an1 <- markEpAnnL' an0 lapr_rest AnnOpenS-    ws' <- markAnnotated ws-    an2 <- markEpAnnL' an1 lapr_rest AnnCloseS-    an3 <- markAnnCloseP an2-    return (L an3 (WarningTxt mb_cat' src ws'))--  exact (L an (DeprecatedTxt src ws)) = do-    an0 <- markAnnOpenP an src "{-# DEPRECATED"-    an1 <- markEpAnnL' an0 lapr_rest AnnOpenS-    ws' <- markAnnotated ws-    an2 <- markEpAnnL' an1 lapr_rest AnnCloseS-    an3 <- markAnnCloseP an2-    return (L an3 (DeprecatedTxt src ws'))--instance ExactPrint InWarningCategory where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (InWarningCategory tkIn source (L l wc)) = do-      tkIn' <- markEpToken tkIn-      L l' (_,wc') <- markAnnotated (L l (source, wc))-      return (InWarningCategory tkIn' source (L l' wc'))--instance ExactPrint (SourceText, WarningCategory) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (st, WarningCategory wc) = do-      case st of-          NoSourceText -> printStringAdvance $ "\"" ++ (unpackFS wc) ++ "\""-          SourceText src -> printStringAdvance $ (unpackFS src)-      return (st, WarningCategory wc)---- -----------------------------------------------------------------------instance ExactPrint (ImportDecl GhcPs) where-  getAnnotationEntry idecl = fromAnn (ideclAnn $ ideclExt idecl)-  setAnnotationAnchor idecl anc ts cs = idecl { ideclExt-                    = (ideclExt idecl) { ideclAnn = setAnchorEpa (ideclAnn $ ideclExt idecl) anc ts cs} }--  exact (ImportDecl (XImportDeclPass ann msrc impl)-                     modname mpkg src safeflag qualFlag mAs hiding) = do--    ann0 <- markLensKw' ann limportDeclAnnImport AnnImport-    let (EpAnn _anc an _cs) = ann0--    -- "{-# SOURCE" and "#-}"-    importDeclAnnPragma' <--      case msrc of-        SourceText _txt -> do-          debugM $ "ImportDecl sourcetext"-          case importDeclAnnPragma an of-            Just (mo, mc) -> do-              mo' <- markAnnOpen'' mo msrc "{-# SOURCE"-              mc' <- printStringAtAA mc "#-}"-              return $ Just (mo', mc')-            Nothing ->  do-              _ <- markAnnOpen' Nothing msrc "{-# SOURCE"-              printStringAtLsDelta (SameLine 1) "#-}"-              return Nothing-        NoSourceText -> return (importDeclAnnPragma an)-    ann1 <- if safeflag-      then (markLensKwM ann0 limportDeclAnnSafe AnnSafe)-      else return ann0-    ann2 <--      case qualFlag of-        QualifiedPre  -- 'qualified' appears in prepositive position.-          -> printStringAtMLocL ann1 limportDeclAnnQualified "qualified"-        _ -> return ann1-    ann3 <--      case mpkg of-       RawPkgQual (StringLiteral src' v _) ->-         printStringAtMLocL ann2 limportDeclAnnPackage (sourceTextToString src' (show v))-       _ -> return ann2-    modname' <- markAnnotated modname--    ann4 <--      case qualFlag of-        QualifiedPost  -- 'qualified' appears in postpositive position.-          -> printStringAtMLocL ann3 limportDeclAnnQualified "qualified"-        _ -> return ann3--    (importDeclAnnAs', mAs') <--      case mAs of-        Nothing -> return (importDeclAnnAs an, Nothing)-        Just m0 -> do-          a <- printStringAtMLoc' (importDeclAnnAs an) "as"-          m'' <- markAnnotated m0-          return (a, Just m'')--    hiding' <--      case hiding of-        Nothing -> return hiding-        Just (isHiding,lie) -> do-          lie' <- markAnnotated lie-          return (Just (isHiding, lie'))--    let (EpAnn anc' an' cs') = ann4-    let an2 = an' { importDeclAnnAs = importDeclAnnAs'-                  , importDeclAnnPragma = importDeclAnnPragma'-                  }--    return (ImportDecl (XImportDeclPass (EpAnn anc' an2 cs') msrc impl)-                     modname' mpkg src safeflag qualFlag mAs' hiding')----- -----------------------------------------------------------------------instance ExactPrint HsDocString where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (MultiLineDocString decorator (x :| xs)) = do-    printStringAdvance ("-- " ++ printDecorator decorator)-    pe <- getPriorEndD-    debugM $ "MultiLineDocString: (pe,x)=" ++ showAst (pe,x)-    x' <- markAnnotated x-    xs' <- markAnnotated (map dedentDocChunk xs)-    return (MultiLineDocString decorator (x' :| xs'))-  exact x = do-    -- TODO: can this happen?-    debugM $ "Not exact printing:" ++ showAst x-    return x---instance ExactPrint HsDocStringChunk where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact chunk = do-    printStringAdvance ("--" ++ unpackHDSC chunk)-    return chunk---instance ExactPrint a => ExactPrint (WithHsDocIdentifiers a GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (WithHsDocIdentifiers ds ids) = do-    ds' <- exact ds-    return (WithHsDocIdentifiers ds' ids)---- -----------------------------------------------------------------------instance ExactPrint (HsDecl GhcPs) where-  getAnnotationEntry (TyClD      _ _) = NoEntryVal-  getAnnotationEntry (InstD      _ _) = NoEntryVal-  getAnnotationEntry (DerivD     _ _) = NoEntryVal-  getAnnotationEntry (ValD       _ _) = NoEntryVal-  getAnnotationEntry (SigD       _ _) = NoEntryVal-  getAnnotationEntry (KindSigD   _ _) = NoEntryVal-  getAnnotationEntry (DefD       _ _) = NoEntryVal-  getAnnotationEntry (ForD       _ _) = NoEntryVal-  getAnnotationEntry (WarningD   _ _) = NoEntryVal-  getAnnotationEntry (AnnD       _ _) = NoEntryVal-  getAnnotationEntry (RuleD      _ _) = NoEntryVal-  getAnnotationEntry (SpliceD    _ _) = NoEntryVal-  getAnnotationEntry (DocD       _ _) = NoEntryVal-  getAnnotationEntry (RoleAnnotD _ _) = NoEntryVal--  -- We do not recurse, the generic traversal using this feature-  -- should do that for us.-  setAnnotationAnchor d _ _ _ = d--  exact (TyClD       x d) = TyClD       x <$> markAnnotated d-  exact (InstD       x d) = InstD       x <$> markAnnotated d-  exact (DerivD      x d) = DerivD      x <$> markAnnotated d-  exact (ValD        x d) = ValD        x <$> markAnnotated d-  exact (SigD        x d) = SigD        x <$> markAnnotated d-  exact (KindSigD    x d) = KindSigD    x <$> markAnnotated d-  exact (DefD        x d) = DefD        x <$> markAnnotated d-  exact (ForD        x d) = ForD        x <$> markAnnotated d-  exact (WarningD    x d) = WarningD    x <$> markAnnotated d-  exact (AnnD        x d) = AnnD        x <$> markAnnotated d-  exact (RuleD       x d) = RuleD       x <$> markAnnotated d-  exact (SpliceD     x d) = SpliceD     x <$> markAnnotated d-  exact (DocD        x d) = DocD        x <$> markAnnotated d-  exact (RoleAnnotD  x d) = RoleAnnotD  x <$> markAnnotated d---- -----------------------------------------------------------------------instance ExactPrint (InstDecl GhcPs) where-  getAnnotationEntry (ClsInstD     _ _) = NoEntryVal-  getAnnotationEntry (DataFamInstD _ _) = NoEntryVal-  getAnnotationEntry (TyFamInstD   _ _) = NoEntryVal--  setAnnotationAnchor d _ _ _ = d---  exact (ClsInstD     a  cid) = do-    cid' <- markAnnotated cid-    return (ClsInstD     a  cid')-  exact (DataFamInstD a decl) = do-    d' <- markAnnotated (DataFamInstDeclWithContext noAnn TopLevel decl)-    return (DataFamInstD a (dc_d d'))-  exact (TyFamInstD a eqn) = do-    eqn' <- markAnnotated eqn-    return (TyFamInstD a eqn')---- -----------------------------------------------------------------------data DataFamInstDeclWithContext-  = DataFamInstDeclWithContext-    { _dc_a :: [AddEpAnn]-    , _dc_f :: TopLevelFlag-    , dc_d :: DataFamInstDecl GhcPs-    }--instance ExactPrint DataFamInstDeclWithContext where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (DataFamInstDeclWithContext an c d) = do-    debugM $ "starting DataFamInstDeclWithContext:an=" ++ showAst an-    (an', d') <- exactDataFamInstDecl an c d-    return (DataFamInstDeclWithContext an' c d')---- -----------------------------------------------------------------------exactDataFamInstDecl :: (Monad m, Monoid w)-                     => [AddEpAnn] -> TopLevelFlag -> DataFamInstDecl GhcPs-                     -> EP w m ([AddEpAnn], DataFamInstDecl GhcPs)-exactDataFamInstDecl an top_lvl-  (DataFamInstDecl (FamEqn { feqn_ext    = an2-                           , feqn_tycon  = tycon-                           , feqn_bndrs  = bndrs-                           , feqn_pats   = pats-                           , feqn_fixity = fixity-                           , feqn_rhs    = defn })) = do-    (an', an2', tycon', bndrs', pats',  defn') <- exactDataDefn an2 pp_hdr defn-                                          -- See Note [an and an2 in exactDataFamInstDecl]-    return-      (an',-       DataFamInstDecl ( FamEqn { feqn_ext    = an2'-                                , feqn_tycon  = tycon'-                                , feqn_bndrs  = bndrs'-                                , feqn_pats   = pats'-                                , feqn_fixity = fixity-                                , feqn_rhs    = defn' }))-                    `debug` ("exactDataFamInstDecl: defn' derivs:" ++ showAst (dd_derivs defn'))-  where-    pp_hdr :: (Monad m, Monoid w)-           => Maybe (LHsContext GhcPs)-           -> EP w m ( [AddEpAnn]-                     , LocatedN RdrName-                     , HsOuterTyVarBndrs () GhcPs-                     , HsFamEqnPats GhcPs-                     , Maybe (LHsContext GhcPs))-    pp_hdr mctxt = do-      an0 <- case top_lvl of-               TopLevel -> markEpAnnL an lidl AnnInstance -- TODO: maybe in toplevel-               NotTopLevel -> return an-      exactHsFamInstLHS an0 tycon bndrs pats fixity mctxt--{--Note [an and an2 in exactDataFamInstDecl]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-The exactDataFamInstDecl function is called to render a-DataFamInstDecl within its surrounding context. This context is-rendered via the 'pp_hdr' function, which uses the exact print-annotations from that context, named 'an'.  The EPAs used for-rendering the DataDefn are contained in the FamEqn, and are called-'an2'.---}---- -----------------------------------------------------------------------instance ExactPrint (DerivDecl GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (DerivDecl (mw, an) typ ms mov) = do-    an0 <- markEpAnnL an lidl AnnDeriving-    ms' <- mapM markAnnotated ms-    an1 <- markEpAnnL an0 lidl AnnInstance-    mw' <- mapM markAnnotated mw-    mov' <- mapM markAnnotated mov-    typ' <- markAnnotated typ-    return (DerivDecl (mw', an1) typ' ms' mov')---- -----------------------------------------------------------------------instance ExactPrint (ForeignDecl GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (ForeignImport an n ty fimport) = do-    an0 <- markEpAnnL an lidl AnnForeign-    an1 <- markEpAnnL an0 lidl AnnImport--    fimport' <- markAnnotated fimport--    n' <- markAnnotated n-    an2 <- markEpAnnL an1 lidl AnnDcolon-    ty' <- markAnnotated ty-    return (ForeignImport an2 n' ty' fimport')--  exact (ForeignExport an n ty fexport) = do-    an0 <- markEpAnnL an lidl AnnForeign-    an1 <- markEpAnnL an0 lidl AnnExport-    fexport' <- markAnnotated fexport-    n' <- markAnnotated n-    an2 <- markEpAnnL an1 lidl AnnDcolon-    ty' <- markAnnotated ty-    return (ForeignExport an2 n' ty' fexport')---- -----------------------------------------------------------------------instance ExactPrint (ForeignImport GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (CImport (L ls src) cconv safety@(L l _) mh imp) = do-    cconv' <- markAnnotated cconv-    safety' <- if notDodgyE l-        then markAnnotated safety-        else return safety-    ls' <- if notDodgyE ls-        then markExternalSourceTextE ls src ""-        else return ls-    return (CImport (L ls' src) cconv' safety' mh imp)---- -----------------------------------------------------------------------instance ExactPrint (ForeignExport GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (CExport (L ls src) spec) = do-    debugM $ "CExport starting"-    spec' <- markAnnotated spec-    ls' <- if notDodgyE ls-        then markExternalSourceTextE ls src ""-        else return ls-    return (CExport (L ls' src) spec')---- -----------------------------------------------------------------------instance ExactPrint CExportSpec where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (CExportStatic st lbl cconv) = do-    debugM $ "CExportStatic starting"-    cconv' <- markAnnotated cconv-    return (CExportStatic st lbl cconv')---- -----------------------------------------------------------------------instance ExactPrint Safety where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact = withPpr---- -----------------------------------------------------------------------instance ExactPrint CCallConv where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact = withPpr---- -----------------------------------------------------------------------instance ExactPrint (WarnDecls GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (Warnings (an,src) warns) = do-    an0 <- markAnnOpen an src "{-# WARNING" -- Note: might be {-# DEPRECATED-    warns' <- markAnnotated warns-    an1 <- markEpAnnLMS'' an0 lidl AnnClose (Just "#-}")-    return (Warnings (an1,src) warns')---- -----------------------------------------------------------------------instance ExactPrint (WarnDecl GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (Warning (ns_spec, an) lns  (WarningTxt mb_cat src ls )) = do-    mb_cat' <- markAnnotated mb_cat-    ns_spec' <- exactNsSpec ns_spec-    lns' <- markAnnotated lns-    an0 <- markEpAnnL an lidl AnnOpenS -- "["-    ls' <- markAnnotated ls-    an1 <- markEpAnnL an0 lidl AnnCloseS -- "]"-    return (Warning (ns_spec', an1) lns'  (WarningTxt mb_cat' src ls'))-    -- return (Warning an1 lns'  (WarningTxt mb_cat' src ls'))--  exact (Warning (ns_spec, an) lns (DeprecatedTxt src ls)) = do-    ns_spec' <- exactNsSpec ns_spec-    lns' <- markAnnotated lns-    an0 <- markEpAnnL an lidl AnnOpenS -- "["-    ls' <- markAnnotated ls-    an1 <- markEpAnnL an0 lidl AnnCloseS -- "]"-    return (Warning (ns_spec', an1) lns' (DeprecatedTxt src ls'))-    -- return (Warning an1 lns' (DeprecatedTxt src ls'))--exactNsSpec :: (Monad m, Monoid w) => NamespaceSpecifier -> EP w m NamespaceSpecifier-exactNsSpec NoNamespaceSpecifier = pure NoNamespaceSpecifier-exactNsSpec (TypeNamespaceSpecifier type_) = do-  type_' <- markEpToken type_-  pure (TypeNamespaceSpecifier type_')-exactNsSpec (DataNamespaceSpecifier data_) = do-  data_' <- markEpToken data_-  pure (DataNamespaceSpecifier data_')---- -----------------------------------------------------------------------instance ExactPrint StringLiteral where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (StringLiteral src fs mcomma) = do-    printSourceTextAA src (show (unpackFS fs))-    mcomma' <- mapM (\r -> printStringAtNC r ",") mcomma-    return (StringLiteral src fs mcomma')----- -----------------------------------------------------------------------instance ExactPrint FastString where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  -- TODO: https://ghc.haskell.org/trac/ghc/ticket/10313 applies.-  -- exact fs = printStringAdvance (show (unpackFS fs))-  exact fs = printStringAdvance (unpackFS fs) >> return fs---- -----------------------------------------------------------------------instance ExactPrint (RuleDecls GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (HsRules (an, src) rules) = do-    an0 <--      case src of-        NoSourceText      -> markEpAnnLMS'' an lidl AnnOpen  (Just "{-# RULES")-        SourceText srcTxt -> markEpAnnLMS'' an lidl AnnOpen  (Just $ unpackFS srcTxt)-    rules' <- markAnnotated rules-    an1 <- markEpAnnLMS'' an0 lidl AnnClose (Just "#-}")-    return (HsRules (an1,src) rules')---- -----------------------------------------------------------------------instance ExactPrint (RuleDecl GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (HsRule (an,nsrc) (L ln n) act mtybndrs termbndrs lhs rhs) = do-    (L ln' _) <- markAnnotated (L ln (nsrc, n))-    an0 <- markActivation an lra_rest act-    (an1, mtybndrs') <--      case mtybndrs of-        Nothing -> return (an0, Nothing)-        Just bndrs -> do-          an1 <-  markLensMAA' an0 lra_tyanns_fst  -- AnnForall-          bndrs' <- mapM markAnnotated bndrs-          an2 <- markLensMAA' an1 lra_tyanns_snd  -- AnnDot-          return (an2, Just bndrs')--    an2 <- markLensMAA' an1 lra_tmanns_fst  -- AnnForall-    termbndrs' <- mapM markAnnotated termbndrs-    an3 <- markLensMAA' an2 lra_tmanns_snd  -- AnnDot--    lhs' <- markAnnotated lhs-    an4 <- markEpAnnL an3 lra_rest AnnEqual-    rhs' <- markAnnotated rhs-    return (HsRule (an4,nsrc) (L ln' n) act mtybndrs' termbndrs' lhs' rhs')--markActivation :: (Monad m, Monoid w)-  => a -> Lens a [AddEpAnn] -> Activation -> EP w m a-markActivation an l act = do-  case act of-    ActiveBefore src phase -> do-      an0 <- markEpAnnL an l AnnOpenS --  '['-      an1 <- markEpAnnL an0 l AnnTilde -- ~-      an2 <- markEpAnnLMS'' an1 l AnnVal (Just (toSourceTextWithSuffix src (show phase) ""))-      an3 <- markEpAnnL an2 l AnnCloseS -- ']'-      return an3-    ActiveAfter src phase -> do-      an0 <- markEpAnnL an l AnnOpenS --  '['-      an1 <- markEpAnnLMS'' an0 l AnnVal (Just (toSourceTextWithSuffix src (show phase) ""))-      an2 <- markEpAnnL an1 l AnnCloseS -- ']'-      return an2-    NeverActive -> do-      an0 <- markEpAnnL an l AnnOpenS --  '['-      an1 <- markEpAnnL an0 l AnnTilde -- ~-      an2 <- markEpAnnL an1 l AnnCloseS -- ']'-      return an2-    _ -> return an---- -----------------------------------------------------------------------instance ExactPrint (SpliceDecl GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (SpliceDecl x splice flag) = do-    splice' <- markAnnotated splice-    return (SpliceDecl x splice' flag)---- -----------------------------------------------------------------------instance ExactPrint (DocDecl GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  -- We print these as plain comments instead, do a NOP here.-  exact v = return v---- -----------------------------------------------------------------------instance ExactPrint (RoleAnnotDecl GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (RoleAnnotDecl an ltycon roles) = do-    an0 <- markEpAnnL an lidl AnnType-    an1 <- markEpAnnL an0 lidl AnnRole-    ltycon' <- markAnnotated ltycon-    let markRole (L l (Just r)) = do-          (L l' r') <- markAnnotated (L l r)-          return (L l' (Just r'))-        markRole (L l Nothing) = do-          e' <- printStringAtAA  (entry l) "_"-          return (L (l { entry = e'}) Nothing)-    roles' <- mapM markRole roles-    return (RoleAnnotDecl an1 ltycon' roles')---- -----------------------------------------------------------------------instance ExactPrint Role where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact = withPpr---- -----------------------------------------------------------------------instance ExactPrint (RuleBndr GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (RuleBndr x ln) = do-    ln' <- markAnnotated ln-    return (RuleBndr x ln')-  exact (RuleBndrSig an ln (HsPS x ty)) = do-    an0 <- markEpAnnL an lidl AnnOpenP -- "("-    ln' <- markAnnotated ln-    an1 <- markEpAnnL an0 lidl AnnDcolon-    ty' <- markAnnotated ty-    an2 <- markEpAnnL an1 lidl AnnCloseP -- ")"-    return (RuleBndrSig an2 ln' (HsPS x ty'))---- -----------------------------------------------------------------------instance (ExactPrint body) => ExactPrint (FamEqn GhcPs body) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor fe _ _ _s = fe-  exact (FamEqn { feqn_ext = an-                , feqn_tycon  = tycon-                , feqn_bndrs  = bndrs-                , feqn_pats   = pats-                , feqn_fixity = fixity-                , feqn_rhs    = rhs }) = do-    (an0, tycon', bndrs', pats', _) <- exactHsFamInstLHS an tycon bndrs pats fixity Nothing-    an1 <- markEpAnnL an0 lidl AnnEqual-    rhs' <- markAnnotated rhs-    return (FamEqn { feqn_ext = an1-                   , feqn_tycon  = tycon'-                   , feqn_bndrs  = bndrs'-                   , feqn_pats   = pats'-                   , feqn_fixity = fixity-                   , feqn_rhs    = rhs' })---- -----------------------------------------------------------------------exactHsFamInstLHS ::-      (Monad m, Monoid w)-   => [AddEpAnn]-   -> LocatedN RdrName-   -> HsOuterTyVarBndrs () GhcPs-   -> HsFamEqnPats GhcPs-   -> LexicalFixity-   -> Maybe (LHsContext GhcPs)-   -> EP w m ( [AddEpAnn]-             , LocatedN RdrName-             , HsOuterTyVarBndrs () GhcPs-             , HsFamEqnPats GhcPs, Maybe (LHsContext GhcPs))-exactHsFamInstLHS an thing bndrs typats fixity mb_ctxt = do-  an0 <- markEpAnnL an lidl AnnForall-  bndrs' <- markAnnotated bndrs-  an1 <- markEpAnnL an0 lidl AnnDot-  mb_ctxt' <- mapM markAnnotated mb_ctxt-  (an2, thing', typats') <- exact_pats an1 typats-  return (an2, thing', bndrs', typats', mb_ctxt')-  where-    exact_pats :: (Monad m, Monoid w)-      => [AddEpAnn] -> HsFamEqnPats GhcPs -> EP w m ([AddEpAnn], LocatedN RdrName, HsFamEqnPats GhcPs)-    exact_pats an' (patl:patr:pats)-      | Infix <- fixity-      = let exact_op_app = do-              an0 <- markEpAnnAllL' an' lidl AnnOpenP-              patl' <- markAnnotated patl-              thing' <- markAnnotated thing-              patr' <- markAnnotated patr-              an1 <- markEpAnnAllL' an0 lidl AnnCloseP-              return (an1, thing', [patl',patr'])-        in case pats of-             [] -> exact_op_app-             _  -> do-               (an0, thing', p) <- exact_op_app-               pats' <- mapM markAnnotated pats-               return (an0, thing', p++pats')--    exact_pats an' pats = do-      an0 <- markEpAnnAllL' an' lidl AnnOpenP-      thing' <- markAnnotated thing-      pats' <- markAnnotated pats-      an1 <- markEpAnnAllL' an0 lidl AnnCloseP-      return (an1, thing', pats')---- -----------------------------------------------------------------------instance (ExactPrint tm, ExactPrint ty, Outputable tm, Outputable ty)-     =>  ExactPrint (HsArg GhcPs tm ty) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (HsValArg x tm) = do-      tm' <- markAnnotated tm-      return (HsValArg x tm')-  exact (HsTypeArg at ty) = do-      at' <- markEpToken at-      ty' <- markAnnotated ty-      return (HsTypeArg at' ty')-  exact x@(HsArgPar _sp)    = withPpr x -- Does not appear in original source---- -----------------------------------------------------------------------instance ExactPrint (ClsInstDecl GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (ClsInstDecl { cid_ext = (mbWarn, an, sortKey)-                     , cid_poly_ty = inst_ty, cid_binds = binds-                     , cid_sigs = sigs, cid_tyfam_insts = ats-                     , cid_overlap_mode = mbOverlap-                     , cid_datafam_insts = adts })-      = do-          (mbWarn', an0, mbOverlap', inst_ty') <- top_matter-          an1 <- markEpAnnL an0 lidl AnnOpenC-          an2 <- markEpAnnAllL' an1 lid AnnSemi-          (sortKey', ds) <- withSortKey sortKey-                               [(ClsAtTag, prepareListAnnotationA ats),-                                (ClsAtdTag, prepareListAnnotationF adts),-                                (ClsMethodTag, prepareListAnnotationA (bagToList binds)),-                                (ClsSigTag, prepareListAnnotationA sigs)-                               ]-          an3 <- markEpAnnL an2 lidl AnnCloseC -- '}'-          let-            ats'   = undynamic ds-            adts'  = undynamic ds-            binds' = listToBag $ undynamic ds-            sigs'  = undynamic ds-          return (ClsInstDecl { cid_ext = (mbWarn', an3, sortKey')-                              , cid_poly_ty = inst_ty', cid_binds = binds'-                              , cid_sigs = sigs', cid_tyfam_insts = ats'-                              , cid_overlap_mode = mbOverlap'-                              , cid_datafam_insts = adts' })--      where-        top_matter = do-          an0 <- markEpAnnL an lidl AnnInstance-          mw <- mapM markAnnotated mbWarn-          mo <- mapM markAnnotated mbOverlap-          it <- markAnnotated inst_ty-          an1 <- markEpAnnL an0 lidl AnnWhere -- Optional-          return (mw, an1, mo,it)---- -----------------------------------------------------------------------instance ExactPrint (TyFamInstDecl GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact d@(TyFamInstDecl { tfid_xtn = an, tfid_eqn = eqn }) = do-    an0 <- markEpAnnL an lidl AnnType-    an1 <- markEpAnnL an0 lidl AnnInstance-    eqn' <- markAnnotated eqn-    return (d { tfid_xtn = an1, tfid_eqn = eqn' })---- -----------------------------------------------------------------------instance ExactPrint (LocatedP OverlapMode) where-  getAnnotationEntry = entryFromLocatedA-  setAnnotationAnchor = setAnchorAn--  -- NOTE: NoOverlap is only used in the typechecker-  exact (L an (NoOverlap src)) = do-    an0 <- markAnnOpenP an src "{-# NO_OVERLAP"-    an1 <- markAnnCloseP an0-    return (L an1 (NoOverlap src))--  exact (L an (Overlappable src)) = do-    an0 <- markAnnOpenP an src "{-# OVERLAPPABLE"-    an1 <- markAnnCloseP an0-    return (L an1 (Overlappable src))--  exact (L an (Overlapping src)) = do-    an0 <- markAnnOpenP an src "{-# OVERLAPPING"-    an1 <- markAnnCloseP an0-    return (L an1 (Overlapping src))--  exact (L an (Overlaps src)) = do-    an0 <- markAnnOpenP an src "{-# OVERLAPS"-    an1 <- markAnnCloseP an0-    return (L an1 (Overlaps src))--  exact (L an (Incoherent src)) = do-    an0 <- markAnnOpenP an src "{-# INCOHERENT"-    an1 <- markAnnCloseP an0-    return (L an1 (Incoherent src))--  exact (L an (NonCanonical src)) = do-    an0 <- markAnnOpenP an src "{-# INCOHERENT"-    an1 <- markAnnCloseP an0-    return (L an1 (Incoherent src))---- -----------------------------------------------------------------------instance ExactPrint (HsBind GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (FunBind x fid matches) = do-    matches' <- markAnnotated matches-    let-      fun_id' = case unLoc (mg_alts matches') of-        [] -> fid-        (L _ m:_) -> case m_ctxt m of-          FunRhs f _ _ -> f-          _ -> fid-    return (FunBind x fun_id' matches')--  exact (PatBind x pat q grhss) = do-    q' <- markAnnotated q-    pat' <- markAnnotated pat-    grhss' <- markAnnotated grhss-    return (PatBind x pat' q' grhss')-  exact (PatSynBind x bind) = do-    bind' <- markAnnotated bind-    return (PatSynBind x bind')--  exact x = error $ "HsBind: exact for " ++ showAst x--instance ExactPrint (HsMultAnn GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (HsNoMultAnn x) = return (HsNoMultAnn x)-  exact (HsPct1Ann tok) = do-      tok' <- markEpToken tok-      return (HsPct1Ann tok')-  exact (HsMultAnn tok ty) = do-      tok' <- markEpToken tok-      ty' <- markAnnotated ty-      return (HsMultAnn tok' ty')---- -----------------------------------------------------------------------instance ExactPrint (PatSynBind GhcPs GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (PSB{ psb_ext = an-            , psb_id = psyn, psb_args = details-            , psb_def = pat-            , psb_dir = dir }) = do-    an0 <- markEpAnnL an lidl AnnPattern-    (an1, psyn', details') <--      case details of-        InfixCon v1 v2 -> do-          v1' <- markAnnotated v1-          psyn' <- markAnnotated psyn-          v2' <- markAnnotated v2-          return (an0, psyn',InfixCon v1' v2')-        PrefixCon tvs vs -> do-          psyn' <- markAnnotated psyn-          tvs' <- markAnnotated tvs-          vs' <- markAnnotated vs-          return (an0, psyn', PrefixCon tvs' vs')-        RecCon vs -> do-          psyn' <- markAnnotated psyn-          an1 <- markEpAnnL an0 lidl AnnOpenC  -- '{'-          vs' <- markAnnotated vs-          an2 <- markEpAnnL an1 lidl AnnCloseC -- '}'-          return (an2, psyn', RecCon vs')--    (an2, pat', dir') <--      case dir of-        Unidirectional           -> do-          an2 <- markEpAnnL an1 lidl AnnLarrow-          pat' <- markAnnotated pat-          return (an2, pat', dir)-        ImplicitBidirectional    -> do-          an2 <- markEpAnnL an1 lidl AnnEqual-          pat' <- markAnnotated pat-          return (an2, pat', dir)-        ExplicitBidirectional mg -> do-          an2 <- markEpAnnL an1 lidl AnnLarrow-          pat' <- markAnnotated pat-          an3 <- markEpAnnL an2 lidl  AnnWhere-          mg' <- markAnnotated mg-          return (an3, pat', ExplicitBidirectional mg')--    return (PSB{ psb_ext = an2-               , psb_id = psyn', psb_args = details'-               , psb_def = pat'-               , psb_dir = dir' })----- -----------------------------------------------------------------------instance ExactPrint (RecordPatSynField GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (RecordPatSynField f v) = do-      f' <- markAnnotated f-      return (RecordPatSynField f' v)---- -----------------------------------------------------------------------instance ExactPrint (Match GhcPs (LocatedA (HsCmd GhcPs))) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (Match an mctxt pats grhss) =-    exactMatch (Match an mctxt pats grhss)---- ---------------------------------------instance ExactPrint (Match GhcPs (LocatedA (HsExpr GhcPs))) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (Match an mctxt pats grhss) =-    exactMatch (Match an mctxt pats grhss)---- -----------------------------------------------------------------------exactMatch :: (Monad m, Monoid w, ExactPrint (GRHSs GhcPs body))-           => (Match GhcPs body) -> EP w m (Match GhcPs body)-exactMatch (Match an mctxt pats grhss) = do--  debugM $ "exact Match entered"--  (an0, mctxt', pats') <--    case mctxt of-      FunRhs fun fixity strictness -> do-        debugM $ "exact Match FunRhs:" ++ showPprUnsafe fun-        an0' <--          case strictness of-            SrcStrict -> markEpAnnL an lidl AnnBang-            _ -> pure an-        case fixity of-          Prefix -> do-            an' <- annotationsToComments an0' lidl [AnnOpenP,AnnCloseP]-            fun' <- markAnnotated fun-            pats' <- markAnnotated pats-            return (an', FunRhs fun' fixity strictness, pats')-          Infix ->-            case pats of-              (p1:p2:rest)-                | null rest -> do-                    p1'  <- markAnnotated p1-                    fun' <- markAnnotated fun-                    p2'  <- markAnnotated p2-                    return (an0', FunRhs fun' fixity strictness, [p1',p2'])-                | otherwise -> do-                    an0  <- markEpAnnL an0' lidl AnnOpenP-                    p1'  <- markAnnotated p1-                    fun' <- markAnnotated fun-                    p2'  <- markAnnotated p2-                    an1  <- markEpAnnL an0 lidl AnnCloseP-                    rest' <- mapM markAnnotated rest-                    return (an1, FunRhs fun' fixity strictness, p1':p2':rest')-              _ -> panic "FunRhs"--      -- ToDo: why is LamSingle treated differently?-      LamAlt LamSingle -> do-        an0' <- markEpAnnL an lidl AnnLam-        pats' <- markAnnotated pats-        return (an0', LamAlt LamSingle, pats')-      LamAlt v -> do-        pats' <- markAnnotated pats-        return (an, LamAlt v, pats')--      CaseAlt -> do-        pats' <- markAnnotated pats-        return (an, CaseAlt, pats')-      _ -> do-        mctxt' <- withPpr mctxt-        return (an, mctxt', pats)--  grhss' <- markAnnotated grhss--  return (Match an0 mctxt' pats' grhss')---- -----------------------------------------------------------------------instance ExactPrint (GRHSs GhcPs (LocatedA (HsExpr GhcPs))) where-  getAnnotationEntry (GRHSs _ _ _) = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (GRHSs cs grhss binds) = do-    addCommentsA $ priorComments cs-    addCommentsA $ getFollowingComments cs-    grhss' <- markAnnotated grhss-    binds' <- markAnnotated binds-    -- The comments will be added back as they are printed-    return (GRHSs emptyComments grhss' binds')---instance ExactPrint (GRHSs GhcPs (LocatedA (HsCmd GhcPs))) where-  getAnnotationEntry (GRHSs _ _ _) = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (GRHSs cs grhss binds) = do-    addCommentsA $ priorComments cs-    addCommentsA $ getFollowingComments cs-    grhss' <- markAnnotated grhss-    binds' <- markAnnotated binds-    -- The comments will be added back as they are printed-    return (GRHSs emptyComments grhss' binds')---- -----------------------------------------------------------------------instance ExactPrint (HsLocalBinds GhcPs) where-  getAnnotationEntry (HsValBinds an _) = fromAnn an-  getAnnotationEntry (HsIPBinds{}) = NoEntryVal-  getAnnotationEntry (EmptyLocalBinds{}) = NoEntryVal--  setAnnotationAnchor (HsValBinds an a) anc ts cs = HsValBinds (setAnchorEpaL an anc ts cs) a-  setAnnotationAnchor a _ _ _ = a--  exact (HsValBinds an valbinds) = do-    debugM $ "exact HsValBinds: an=" ++ showAst an-    an0 <- markEpAnnL' an lal_rest AnnWhere--    case al_anchor $ anns an of-      Just anc -> do-        when (not $ isEmptyValBinds valbinds) $ setExtraDP (Just anc)-      _ -> return ()--    (an1, valbinds') <- markAnnList an0 $ markAnnotatedWithLayout valbinds-    debugM $ "exact HsValBinds: an1=" ++ showAst an1-    medr <- getExtraDPReturn-    an2 <- case medr of-             Nothing -> return an1-             Just dp -> do-                 setExtraDPReturn Nothing-                 return $ an1 { anns = (anns an1) { al_anchor = Just (EpaDelta dp []) }}-    return (HsValBinds an2 valbinds')--  exact (HsIPBinds an bs) = do-    (an2,bs') <- markAnnListA an $ \an0 -> do-                           an1 <- markEpAnnL' an0 lal_rest AnnWhere-                           bs' <- markAnnotated bs-                           return (an1, bs')-    return (HsIPBinds an2 bs')-  exact b@(EmptyLocalBinds _) = return b----- ----------------------------------------------------------------------instance ExactPrint (HsValBindsLR GhcPs GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (ValBinds sortKey binds sigs) = do-    decls <- setLayoutBoth $ mapM markAnnotated $ hsDeclsValBinds (ValBinds sortKey binds sigs)-    let-      binds' = listToBag $ concatMap decl2Bind decls-      sigs'  =             concatMap decl2Sig decls-      sortKey' = captureOrderBinds decls-    return (ValBinds sortKey' binds' sigs')-  exact (XValBindsLR _) = panic "XValBindsLR"--undynamic :: Typeable a => [Dynamic] -> [a]-undynamic ds = mapMaybe fromDynamic ds---- -----------------------------------------------------------------------instance ExactPrint (HsIPBinds GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (IPBinds x binds) = setLayoutBoth $ do-      binds' <- markAnnotated binds-      return (IPBinds x binds')---- -----------------------------------------------------------------------instance ExactPrint (IPBind GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (IPBind an lr rhs) = do-    lr' <- markAnnotated lr-    an0 <- markEpAnnL an lidl AnnEqual-    rhs' <- markAnnotated rhs-    return (IPBind an0 lr' rhs')----- -----------------------------------------------------------------------instance ExactPrint HsIPName where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact i@(HsIPName fs) = printStringAdvanceA ("?" ++ (unpackFS fs)) >> return i---- ------------------------------------------------------------------------ Managing lists which have been separated, e.g. Sigs and Binds--prepareListAnnotationF :: (Monad m, Monoid w) =>-  [LDataFamInstDecl GhcPs] -> [(RealSrcSpan,EP w m Dynamic)]-prepareListAnnotationF ls = map (\b -> (realSrcSpan $ getLocA b, go b)) ls-  where-    go (L l a) = do-      (L l' d') <- markAnnotated (L l (DataFamInstDeclWithContext noAnn NotTopLevel a))-      return (toDyn (L l' (dc_d d')))--prepareListAnnotationA :: (Monad m, Monoid w, ExactPrint (LocatedAn an a))-  => [LocatedAn an a] -> [(RealSrcSpan,EP w m Dynamic)]-prepareListAnnotationA ls = map (\b -> (realSrcSpan $ getLocA b,go b)) ls-  where-    go b = do-      b' <- markAnnotated b-      return (toDyn b')--withSortKey :: (Monad m, Monoid w)-  => AnnSortKey DeclTag -> [(DeclTag, [(RealSrcSpan, EP w m Dynamic)])]-  -> EP w m (AnnSortKey DeclTag, [Dynamic])-withSortKey annSortKey xs = do-  debugM $ "withSortKey:annSortKey=" ++ showAst annSortKey-  let (sk, ordered) = case annSortKey of-                  NoAnnSortKey -> (annSortKey', map snd os)-                    where-                      doOne (tag, ds) = map (\d -> (tag, d)) ds-                      xsExpanded = concatMap doOne xs-                      os = sortBy orderByFst $ xsExpanded-                      annSortKey' = AnnSortKey (map fst os)-                  AnnSortKey _keys -> (annSortKey, orderedDecls annSortKey (Map.fromList xs))-  ordered' <- mapM snd ordered-  return (sk, ordered')--orderByFst :: Ord a => (t, (a,b1)) -> (t, (a, b2)) -> Ordering-orderByFst (_,(a,_)) (_,(b,_)) = compare a b---- -----------------------------------------------------------------------instance ExactPrint (Sig GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (TypeSig an vars ty)  = do-    (an', vars', ty') <- exactVarSig an vars ty-    return (TypeSig an' vars' ty')--  exact (PatSynSig an lns typ) = do-    an0 <- markEpAnnL an lasRest AnnPattern-    lns' <- markAnnotated lns-    an1 <- markLensAA' an0 lasDcolon-    typ' <- markAnnotated typ-    return (PatSynSig an1 lns' typ')--  exact (ClassOpSig an is_deflt vars ty)-    | is_deflt  = do-        an0 <- markEpAnnL an lasRest AnnDefault-        (an1, vars',ty') <- exactVarSig an0 vars ty-        return (ClassOpSig an1 is_deflt vars' ty')-    | otherwise = do-        (an0, vars',ty') <- exactVarSig an vars ty-        return (ClassOpSig an0 is_deflt vars' ty')--  exact (FixSig an (FixitySig ns names (Fixity src v fdir))) = do-    let fixstr = case fdir of-         InfixL -> "infixl"-         InfixR -> "infixr"-         InfixN -> "infix"-    an0 <- markEpAnnLMS'' an  lidl AnnInfix (Just fixstr)-    an1 <- markEpAnnLMS'' an0 lidl AnnVal (Just (sourceTextToString src (show v)))-    ns' <- markAnnotated ns-    names' <- markAnnotated names-    return (FixSig an1 (FixitySig ns' names' (Fixity src v fdir)))--  exact (InlineSig an ln inl) = do-    an0 <- markAnnOpen an (inl_src inl) "{-# INLINE"-    an1 <- markActivation an0 id (inl_act inl)-    ln' <- markAnnotated ln-    an2 <- markEpAnnLMS'' an1 lidl AnnClose (Just "#-}")-    return (InlineSig an2 ln' inl)--  exact (SpecSig an ln typs inl) = do-    an0 <- markAnnOpen an (inl_src inl) "{-# SPECIALISE" -- Note: may be {-# SPECIALISE_INLINE-    an1 <- markActivation an0 lidl (inl_act inl)-    ln' <- markAnnotated ln-    an2 <- markEpAnnL an1 lidl AnnDcolon-    typs' <- markAnnotated typs-    an3 <- markEpAnnLMS'' an2 lidl AnnClose (Just "#-}")-    return (SpecSig an3 ln' typs' inl)--  exact (SpecInstSig (an,src) typ) = do-    an0 <- markAnnOpen an src "{-# SPECIALISE"-    an1 <- markEpAnnL an0 lidl AnnInstance-    typ' <- markAnnotated typ-    an2 <- markEpAnnLMS'' an1 lidl AnnClose (Just "#-}")-    return (SpecInstSig (an2,src) typ')--  exact (MinimalSig (an,src) formula) = do-    an0 <- markAnnOpen an src "{-# MINIMAL"-    formula' <- markAnnotated formula-    an1 <- markEpAnnLMS'' an0 lidl AnnClose (Just "#-}")-    return (MinimalSig (an1,src) formula')--  exact (SCCFunSig (an,src) ln ml) = do-    an0 <- markAnnOpen an src "{-# SCC"-    ln' <- markAnnotated ln-    ml' <- markAnnotated ml-    an1 <- markEpAnnLMS'' an0 lidl AnnClose (Just "#-}")-    return (SCCFunSig (an1,src) ln' ml')--  exact (CompleteMatchSig (an,src) cs mty) = do-    an0 <- markAnnOpen an src "{-# COMPLETE"-    cs' <- mapM markAnnotated cs-    (an1, mty') <--      case mty of-        Nothing -> return (an0, mty)-        Just ty -> do-          an1 <- markEpAnnL an0 lidl AnnDcolon-          ty' <- markAnnotated ty-          return (an1, Just ty')-    an2 <- markEpAnnLMS'' an1 lidl AnnClose (Just "#-}")-    return (CompleteMatchSig (an2,src) cs' mty')---- -----------------------------------------------------------------------instance ExactPrint NamespaceSpecifier where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact NoNamespaceSpecifier = return NoNamespaceSpecifier-  exact (TypeNamespaceSpecifier typeTok) = do-      typeTok' <- markEpToken typeTok-      return (TypeNamespaceSpecifier typeTok')-  exact (DataNamespaceSpecifier dataTok) = do-      dataTok' <- markEpToken dataTok-      return (DataNamespaceSpecifier dataTok')---- -----------------------------------------------------------------------exactVarSig :: (Monad m, Monoid w, ExactPrint a)-  => AnnSig -> [LocatedN RdrName] -> a -> EP w m (AnnSig, [LocatedN RdrName], a)-exactVarSig an vars ty = do-  vars' <- mapM markAnnotated vars-  an0 <- markLensAA' an lasDcolon-  ty' <- markAnnotated ty-  return (an0, vars', ty')---- -----------------------------------------------------------------------instance ExactPrint (StandaloneKindSig GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (StandaloneKindSig an vars sig) = do-    an0 <- markEpAnnL an lidl AnnType-    vars' <- markAnnotated vars-    an1 <- markEpAnnL an0 lidl AnnDcolon-    sig' <- markAnnotated sig-    return (StandaloneKindSig an1 vars' sig')---- -----------------------------------------------------------------------instance ExactPrint (DefaultDecl GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (DefaultDecl an tys) = do-    an0 <- markEpAnnL an lidl AnnDefault-    an1 <- markEpAnnL an0 lidl AnnOpenP-    tys' <- markAnnotated tys-    an2 <- markEpAnnL an1 lidl AnnCloseP-    return (DefaultDecl an2 tys')---- -----------------------------------------------------------------------instance ExactPrint (AnnDecl GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (HsAnnotation (an, src) prov e) = do-    an0 <- markAnnOpenP' an src "{-# ANN"-    (an1, prov') <--      case prov of-        (ValueAnnProvenance n) -> do-          n' <- markAnnotated n-          return (an0, ValueAnnProvenance n')-        (TypeAnnProvenance n) -> do-          an1 <- markEpAnnL an0 lapr_rest AnnType-          n' <- markAnnotated n-          return (an1, TypeAnnProvenance n')-        ModuleAnnProvenance -> do-          an1 <- markEpAnnL an0 lapr_rest AnnModule-          return (an1, prov)--    e' <- markAnnotated e-    an2 <- markAnnCloseP' an1-    return (HsAnnotation (an2,src) prov' e')---- -----------------------------------------------------------------------instance ExactPrint (BF.BooleanFormula (LocatedN RdrName)) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (BF.Var x)  = do-    x' <- markAnnotated x-    return (BF.Var x')-  exact (BF.Or ls)  = do-    ls' <- markAnnotated ls-    return (BF.Or ls')-  exact (BF.And ls) = do-    ls' <- markAnnotated ls-    return (BF.And ls')-  exact (BF.Parens x)  = do-    x' <- markAnnotated x-    return (BF.Parens x')---- -----------------------------------------------------------------------instance (ExactPrint body) => ExactPrint (HsWildCardBndrs GhcPs body) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _= a-  exact (HsWC x ty) = do-    ty' <- markAnnotated ty-    return (HsWC x ty')---- -----------------------------------------------------------------------instance ExactPrint (GRHS GhcPs (LocatedA (HsExpr GhcPs))) where-  getAnnotationEntry (GRHS an _ _) = fromAnn an-  setAnnotationAnchor (GRHS an a b) anc ts cs = GRHS (setAnchorEpa an anc ts cs) a b--  exact (GRHS an guards expr) = do-    an0 <- if null guards-             then return an-             else markLensKwM an lga_vbar AnnVbar-    guards' <- markAnnotated guards-    an1 <- markLensAA an0 lga_sep -- Mark the matchSeparator for these GRHSs-    expr' <- markAnnotated expr-    return (GRHS an1 guards' expr')--instance ExactPrint (GRHS GhcPs (LocatedA (HsCmd GhcPs))) where-  getAnnotationEntry (GRHS ann _ _) = fromAnn ann-  setAnnotationAnchor (GRHS an a b) anc ts cs = GRHS (setAnchorEpa an anc ts cs) a b--  exact (GRHS an guards expr) = do-    an0 <- markLensKwM an lga_vbar AnnVbar-    guards' <- markAnnotated guards-    an1 <- markLensAA an0 lga_sep -- Mark the matchSeparator for these GRHSs-    expr' <- markAnnotated expr-    return (GRHS an1 guards' expr')---- -----------------------------------------------------------------------instance ExactPrint (HsExpr GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _s = a--  exact (HsVar x n) = do-    -- The parser inserts a placeholder value for a record pun rhs. This must be-    -- filtered.-    let pun_RDR = "pun-right-hand-side"-    n' <- if (showPprUnsafe n /= pun_RDR)-      then markAnnotated n-      else return n-    return (HsVar x n')-  exact (HsUnboundVar an n) = do-    case an of-      Just (EpAnnUnboundVar (ob,cb) l) -> do-        ob' <-  printStringAtAA ob "`"-        l' <- printStringAtAA l  "_"-        cb' <- printStringAtAA cb "`"-        return (HsUnboundVar (Just (EpAnnUnboundVar (ob',cb') l')) n)-      _ -> do-        printStringAdvanceA "_" >> return ()-        return (HsUnboundVar an n)-  exact x@(HsOverLabel _ src l) = do-    printStringAdvanceA "#" >> return ()-    case src of-      NoSourceText   -> printStringAdvanceA (unpackFS l)  >> return ()-      SourceText txt -> printStringAdvanceA (unpackFS txt) >> return ()-    return x--  exact x@(HsIPVar _ (HsIPName n))-    = printStringAdvance ("?" ++ unpackFS n) >> return x--  exact x@(HsOverLit _an ol) = do-    let str = case ol_val ol of-                HsIntegral   (IL src _ _) -> src-                HsFractional (FL { fl_text = src }) -> src-                HsIsString src _          -> src-    case str of-      SourceText s -> printStringAdvance (unpackFS s) >> return ()-      NoSourceText -> withPpr x >> return ()-    return x--  exact (HsLit an lit) = do-    lit' <- withPpr lit-    return (HsLit an lit')--  exact (HsLam an lam_variant mg) = do-    an0 <- mark an AnnLam-    an1 <- case lam_variant of-             LamSingle -> return an0-             LamCase -> mark an0 AnnCase-             LamCases -> mark an0 AnnCases-    mg' <- markAnnotated mg-    return (HsLam an1 lam_variant mg')--  exact (HsApp an e1 e2) = do-    p <- getPosP-    debugM $ "HsApp entered. p=" ++ show p-    e1' <- markAnnotated e1-    e2' <- markAnnotated e2-    return (HsApp an e1' e2')-  exact (HsAppType at fun arg) = do-    fun' <- markAnnotated fun-    at' <- markEpToken at-    arg' <- markAnnotated arg-    return (HsAppType at' fun' arg')-  exact (OpApp an e1 e2 e3) = do-    e1' <- markAnnotated e1-    e2' <- markAnnotated e2-    e3' <- markAnnotated e3-    return (OpApp an e1' e2' e3')--  exact (NegApp an e s) = do-    an0 <- markEpAnnL an lidl AnnMinus-    e' <- markAnnotated e-    return (NegApp an0 e' s)--  exact (HsPar (lpar, rpar) e) = do-    lpar' <- markEpToken lpar-    e' <- markAnnotated e-    debugM $ "HsPar closing paren"-    rpar' <- markEpToken rpar-    debugM $ "HsPar done"-    return (HsPar (lpar', rpar') e')--  exact (SectionL an expr op) = do-    expr' <- markAnnotated expr-    op' <- markAnnotated op-    return (SectionL an expr' op')--  exact (SectionR an op expr) = do-    op' <- markAnnotated op-    expr' <- markAnnotated expr-    return (SectionR an op' expr')--  exact (ExplicitTuple an args b) = do-    an0 <- if b == Boxed then markEpAnnL an lidl AnnOpenP-                         else markEpAnnL an lidl AnnOpenPH--    args' <- mapM markAnnotated args--    an1 <- if b == Boxed then markEpAnnL an0 lidl AnnCloseP-                         else markEpAnnL an0 lidl AnnClosePH-    debugM $ "ExplicitTuple done"-    return (ExplicitTuple an1 args' b)--  exact (ExplicitSum an alt arity expr) = do-    an0 <- markLensKw an laesOpen AnnOpenPH-    an1 <- markAnnKwAllL an0 laesBarsBefore AnnVbar-    expr' <- markAnnotated expr-    an2 <- markAnnKwAllL an1 laesBarsAfter AnnVbar-    an3 <- markLensKw an2 laesClose AnnClosePH-    return (ExplicitSum an3 alt arity expr')--  exact (HsCase an e alts) = do-    an0 <- markLensKw an lhsCaseAnnCase AnnCase-    e' <- markAnnotated e-    an1 <- markLensKw an0 lhsCaseAnnOf AnnOf-    an2 <- markEpAnnL an1 lhsCaseAnnsRest AnnOpenC-    an3 <- markEpAnnAllL' an2 lhsCaseAnnsRest AnnSemi-    alts' <- setLayoutBoth $ markAnnotated alts-    an4 <- markEpAnnL an3 lhsCaseAnnsRest AnnCloseC-    return (HsCase an4 e' alts')--  exact (HsIf an e1 e2 e3) = do-    an0 <- markLensKw an laiIf AnnIf-    e1' <- markAnnotated e1-    an1 <- markLensKwM' an0 laiThenSemi AnnSemi-    an2 <- markLensKw an1 laiThen AnnThen-    e2' <- markAnnotated e2-    an3 <- markLensKwM' an2 laiElseSemi AnnSemi-    an4 <- markLensKw an3 laiElse AnnElse-    e3' <- markAnnotated e3-    return (HsIf an4 e1' e2' e3')--  exact (HsMultiIf an mg) = do-    an0 <- markEpAnnL an lidl AnnIf-    an1 <- markEpAnnL an0 lidl AnnOpenC -- optional-    mg' <- markAnnotated mg-    an2 <- markEpAnnL an1 lidl AnnCloseC -- optional-    return (HsMultiIf an2 mg')--  exact (HsLet (tkLet, tkIn) binds e) = do-    setLayoutBoth $ do -- Make sure the 'in' gets indented too-      tkLet' <- markEpToken tkLet-      binds' <- setLayoutBoth $ markAnnotated binds-      tkIn' <- markEpToken tkIn-      e' <- markAnnotated e-      return (HsLet (tkLet',tkIn') binds' e')--  exact (HsDo an do_or_list_comp stmts) = do-    debugM $ "HsDo"-    (an',stmts') <- markAnnListA' an $ \a -> exactDo a do_or_list_comp stmts-    return (HsDo an' do_or_list_comp stmts')--  exact (ExplicitList an es) = do-    debugM $ "ExplicitList start"-    an0 <- markLensMAA' an lal_open-    es' <- markAnnotated es-    an1 <- markLensMAA' an0 lal_close-    debugM $ "ExplicitList end"-    return (ExplicitList an1 es')-  exact (RecordCon an con_id binds) = do-    con_id' <- markAnnotated con_id-    an0 <- markEpAnnL an lidl AnnOpenC-    binds' <- markAnnotated binds-    an1 <- markEpAnnL an0 lidl AnnCloseC-    return (RecordCon an1 con_id' binds')-  exact (RecordUpd an expr fields) = do-    expr' <- markAnnotated expr-    an0 <- markEpAnnL an lidl AnnOpenC-    fields' <- markAnnotated fields-    an1 <- markEpAnnL an0 lidl AnnCloseC-    return (RecordUpd an1 expr' fields')-  exact (HsGetField an expr field) = do-    expr' <- markAnnotated expr-    field' <- markAnnotated field-    return (HsGetField an expr' field')-  exact (HsProjection an flds) = do-    an0 <- markLensKw an lapOpen AnnOpenP-    flds' <- mapM markAnnotated flds-    an1 <- markLensKw an0 lapClose AnnCloseP-    return (HsProjection an1 flds')-  exact (ExprWithTySig an expr sig) = do-    expr' <- markAnnotated expr-    an0 <- markEpAnnL an lidl AnnDcolon-    sig' <- markAnnotated sig-    return (ExprWithTySig an0 expr' sig')-  exact (ArithSeq an s seqInfo) = do-    an0 <- markEpAnnL an lidl AnnOpenS -- '['-    (an1, seqInfo') <--      case seqInfo of-        From e -> do-          e' <- markAnnotated e-          an' <- markEpAnnL an0 lidl AnnDotdot-          return (an', From e')-        FromTo e1 e2 -> do-          e1' <- markAnnotated e1-          an' <- markEpAnnL an0 lidl AnnDotdot-          e2' <- markAnnotated e2-          return (an', FromTo e1' e2')-        FromThen e1 e2 -> do-          e1' <- markAnnotated e1-          an' <- markEpAnnL an0 lidl AnnComma-          e2' <- markAnnotated e2-          an'' <- markEpAnnL an' lidl AnnDotdot-          return (an'', FromThen e1' e2')-        FromThenTo e1 e2 e3 -> do-          e1' <- markAnnotated e1-          an' <- markEpAnnL an0 lidl AnnComma-          e2' <- markAnnotated e2-          an'' <- markEpAnnL an' lidl AnnDotdot-          e3' <- markAnnotated e3-          return (an'', FromThenTo e1' e2' e3')-    an2 <- markEpAnnL an1 lidl AnnCloseS -- ']'-    return (ArithSeq an2 s seqInfo')---  exact (HsTypedBracket an e) = do-    an0 <- markEpAnnLMS'' an lidl AnnOpen (Just "[||")-    an1 <- markEpAnnLMS'' an0 lidl AnnOpenE (Just "[e||")-    e' <- markAnnotated e-    an2 <- markEpAnnLMS'' an1 lidl AnnClose (Just "||]")-    return (HsTypedBracket an2 e')--  exact (HsUntypedBracket an (ExpBr a e)) = do-    an0 <- markEpAnnL an  lidl AnnOpenEQ -- "[|"-    an1 <- markEpAnnL an0 lidl AnnOpenE  -- "[e|" -- optional-    e' <- markAnnotated e-    an2 <- markEpAnnL an1 lidl AnnCloseQ -- "|]"-    return (HsUntypedBracket an2 (ExpBr a e'))--  exact (HsUntypedBracket an (PatBr a e)) = do-    an0 <- markEpAnnLMS'' an lidl AnnOpen (Just "[p|")-    e' <- markAnnotated e-    an1 <- markEpAnnL an0 lidl AnnCloseQ -- "|]"-    return (HsUntypedBracket an1 (PatBr a e'))--  exact (HsUntypedBracket an (DecBrL a e)) = do-    an0 <- markEpAnnLMS'' an lidl AnnOpen (Just "[d|")-    an1 <- markEpAnnL an0 lidl AnnOpenC-    e' <- markAnnotated e-    an2 <- markEpAnnL an1 lidl AnnCloseC-    an3 <- markEpAnnL an2 lidl AnnCloseQ -- "|]"-    return (HsUntypedBracket an3 (DecBrL a e'))--  exact (HsUntypedBracket an (TypBr a e)) = do-    an0 <- markEpAnnLMS'' an lidl AnnOpen (Just "[t|")-    e' <- markAnnotated e-    an1 <- markEpAnnL an0 lidl AnnCloseQ -- "|]"-    return (HsUntypedBracket an1 (TypBr a e'))--  exact (HsUntypedBracket an (VarBr a b e)) = do-    (an0, e') <- if b-      then do-        an' <- markEpAnnL an lidl AnnSimpleQuote-        e' <- markAnnotated e-        return (an', e')-      else do-        an' <- markEpAnnL an lidl AnnThTyQuote-        e' <- markAnnotated e-        return (an', e')-    return (HsUntypedBracket an0 (VarBr a b e'))--  exact (HsTypedSplice an s)   = do-    an0 <- markEpAnnL an lidl AnnDollarDollar-    s' <- markAnnotated s-    return (HsTypedSplice an0 s')--  exact (HsUntypedSplice an s) = do-    s' <- markAnnotated s-    return (HsUntypedSplice an s')--  exact (HsProc an p c) = do-    debugM $ "HsProc start"-    an0 <- markEpAnnL an lidl AnnProc-    p' <- markAnnotated p-    an1 <- markEpAnnL an0 lidl AnnRarrow-    debugM $ "HsProc after AnnRarrow"-    c' <- markAnnotated c-    return (HsProc an1 p' c')--  exact (HsStatic an e) = do-    an0 <- markEpAnnL an lidl AnnStatic-    e' <- markAnnotated e-    return (HsStatic an0 e')--  exact (HsPragE a prag e) = do-    prag' <- markAnnotated prag-    e' <- markAnnotated e-    return (HsPragE a prag' e')--  exact (HsEmbTy toktype t) = do-    toktype' <- markEpToken toktype-    t' <- markAnnotated t-    return (HsEmbTy toktype' t')--  exact x = error $ "exact HsExpr for:" ++ showAst x---- -----------------------------------------------------------------------exactDo :: (Monad m, Monoid w, ExactPrint (LocatedAn an a))-        => AnnList -> HsDoFlavour -> LocatedAn an a-        -> EP w m (AnnList, LocatedAn an a)-exactDo an (DoExpr m)    stmts = exactMdo an m AnnDo           >>= \an0 -> markMaybeDodgyStmts an0 stmts-exactDo an GhciStmtCtxt  stmts = markEpAnnL an lal_rest AnnDo >>= \an0 -> markMaybeDodgyStmts an0 stmts-exactDo an (MDoExpr m)   stmts = exactMdo an m AnnMdo          >>= \an0 -> markMaybeDodgyStmts an0 stmts-exactDo an ListComp      stmts = markMaybeDodgyStmts an stmts-exactDo an MonadComp     stmts = markMaybeDodgyStmts an stmts--exactMdo :: (Monad m, Monoid w)-  => AnnList -> Maybe ModuleName -> AnnKeywordId -> EP w m AnnList-exactMdo an Nothing            kw = markEpAnnL    an lal_rest kw-exactMdo an (Just module_name) kw = markEpAnnLMS'' an lal_rest kw (Just n)-    where-      n = (moduleNameString module_name) ++ "." ++ (keywordToString kw)--markMaybeDodgyStmts :: (Monad m, Monoid w, ExactPrint (LocatedAn an a))-  => AnnList -> LocatedAn an a -> EP w m (AnnList, LocatedAn an a)-markMaybeDodgyStmts an stmts =-  if notDodgy stmts-    then do-      r <- markAnnotatedWithLayout stmts-      return (an, r)-    else return (an, stmts)--notDodgy :: GenLocated (EpAnn ann) a -> Bool-notDodgy (L (EpAnn anc _ _) _) = notDodgyE anc--notDodgyE :: EpaLocation -> Bool-notDodgyE anc =-  case anc of-    EpaSpan s -> isGoodSrcSpan s-    EpaDelta{} -> True---- ----------------------------------------------------------------------instance ExactPrint (HsPragE GhcPs) where-  getAnnotationEntry HsPragSCC{}  = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (HsPragSCC (an,st) sl) = do-    an0 <- markAnnOpenP' an st "{-# SCC"-    let txt = sourceTextToString (sl_st sl) (unpackFS $ sl_fs sl)-    an1 <- markEpAnnLMS'' an0 lapr_rest AnnVal    (Just txt) -- optional-    an2 <- markEpAnnLMS'' an1 lapr_rest AnnValStr (Just txt) -- optional-    an3 <- markAnnCloseP' an2-    return (HsPragSCC (an3,st) sl)----- -----------------------------------------------------------------------instance ExactPrint (HsUntypedSplice GhcPs) where-  getAnnotationEntry _ = NoEntryVal--  setAnnotationAnchor a _ _  _= a--  exact (HsUntypedSpliceExpr an e) = do-    an0 <- markEpAnnL an lidl AnnDollar-    e' <- markAnnotated e-    return (HsUntypedSpliceExpr an0 e')--  exact (HsQuasiQuote an q (L l fs)) = do-    -- The quasiquote string does not honour layout offsets. Store-    -- the colOffset for now.-    -- TODO: use local?-    oldOffset <- getLayoutOffsetP-    EPState{pMarkLayout} <- get-    unless pMarkLayout $ setLayoutOffsetP 0-    printStringAdvance-            -- Note: Lexer.x does not provide unicode alternative. 2017-02-26-            ("[" ++ (showPprUnsafe q) ++ "|" ++ (unpackFS fs) ++ "|]")-    unless pMarkLayout $ setLayoutOffsetP oldOffset-    return (HsQuasiQuote an q (L l fs))---- ------------------------------------------------------------------------- TODO:AZ: combine these instances-instance ExactPrint (MatchGroup GhcPs (LocatedA (HsExpr GhcPs))) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (MG x matches) = do-    -- TODO:AZ use SortKey, in MG ann.-    matches' <- markAnnotated matches-    return (MG x matches')--instance ExactPrint (MatchGroup GhcPs (LocatedA (HsCmd GhcPs))) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (MG x matches) = do-    -- TODO:AZ use SortKey, in MG ann.-    matches' <- if notDodgy matches-      then markAnnotated matches-      else return matches-    return (MG x matches')---- -----------------------------------------------------------------------instance (ExactPrint body) => ExactPrint (HsRecFields GhcPs body) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (HsRecFields fields mdot) = do-    fields' <- markAnnotated fields-    mdot' <- case mdot of-      Nothing -> return Nothing-      Just (L ss d) -> do-        ss' <- printStringAtAA ss ".."-        return $ Just (L ss' d)-      -- Note: mdot contains the SrcSpan where the ".." appears, if present-    return (HsRecFields fields' mdot')---- -----------------------------------------------------------------------instance (ExactPrint body)-    => ExactPrint (HsFieldBind (LocatedA (FieldOcc GhcPs)) body) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (HsFieldBind an f arg isPun) = do-    debugM $ "HsFieldBind"-    f' <- markAnnotated f-    (an0, arg') <- if isPun then return (an, arg)-             else do-               an0 <- markEpAnnL an lidl AnnEqual-               arg' <- markAnnotated arg-               return (an0, arg')-    return (HsFieldBind an0 f' arg' isPun)---- -----------------------------------------------------------------------instance (ExactPrint body)-    => ExactPrint (HsFieldBind (LocatedAn NoEpAnns (FieldLabelStrings GhcPs)) body) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (HsFieldBind an f arg isPun) = do-    debugM $ "HsFieldBind FieldLabelStrings"-    f' <- markAnnotated f-    (an0, arg') <- if isPun then return (an, arg)-             else do-               an0 <- markEpAnnL an lidl AnnEqual-               arg' <- markAnnotated arg-               return (an0, arg')-    return (HsFieldBind an0 f' arg' isPun)---- -----------------------------------------------------------------------instance (ExactPrint (LocatedA body))-    => ExactPrint (HsFieldBind (LocatedA (AmbiguousFieldOcc GhcPs)) (LocatedA body)) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (HsFieldBind an f arg isPun) = do-    debugM $ "HsRecUpdField"-    f' <- markAnnotated f-    an0 <- if isPun then return an-             else markEpAnnL an lidl AnnEqual-    arg' <- if isPun-              then return arg-              else markAnnotated arg-    return (HsFieldBind an0 f' arg' isPun)---- ----------------------------------------------------------------------instance ExactPrint (LHsRecUpdFields GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact flds@(RegularRecUpdFields    { recUpdFields  = rbinds }) = do-    debugM $ "RegularRecUpdFields"-    rbinds' <- markAnnotated rbinds-    return $ flds { recUpdFields = rbinds' }-  exact flds@(OverloadedRecUpdFields { olRecUpdFields = pbinds }) = do-    debugM $ "OverloadedRecUpdFields"-    pbinds' <- markAnnotated pbinds-    return $ flds { olRecUpdFields = pbinds' }---- -----------------------------------------------------------------------instance ExactPrint (FieldLabelStrings GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (FieldLabelStrings fs) = FieldLabelStrings <$> markAnnotated fs---- -----------------------------------------------------------------------instance ExactPrint (DotFieldOcc GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (DotFieldOcc an (L loc (FieldLabelString fs))) = do-    an0 <- markLensKwM' an lafDot  AnnDot-    -- The field name has a SrcSpanAnnN, print it as a-    -- LocatedN RdrName-    L loc' _ <- markAnnotated (L loc (mkVarUnqual fs))-    return (DotFieldOcc an0 (L loc' (FieldLabelString fs)))---- -----------------------------------------------------------------------instance ExactPrint (HsTupArg GhcPs) where-  getAnnotationEntry (Present _ _) = NoEntryVal-  getAnnotationEntry (Missing (EpAnn _ False _)) = NoEntryVal-  getAnnotationEntry (Missing an)   = fromAnn an--  setAnnotationAnchor (Present a b) _ _ _ = Present a b-  setAnnotationAnchor (Missing an)   anc ts cs = Missing (setAnchorEpa an anc ts cs)--  exact (Present a e) = Present a <$> markAnnotated e--  exact a@(Missing (EpAnn _ False _)) = return a-  exact a@(Missing _) = printStringAdvance "," >> return a---- -----------------------------------------------------------------------instance ExactPrint (HsCmdTop GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (HsCmdTop a cmd) = HsCmdTop a <$> markAnnotated cmd---- -----------------------------------------------------------------------instance ExactPrint (HsCmd GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (HsCmdArrApp an arr arg o isRightToLeft) = do-    if isRightToLeft-      then do-        arr' <- markAnnotated arr-        an0 <- markKw an-        arg' <- markAnnotated arg-        return (HsCmdArrApp an0 arr' arg' o isRightToLeft)-      else do-        arg' <- markAnnotated arg-        an0 <- markKw an-        arr' <- markAnnotated arr-        return (HsCmdArrApp an0 arr' arg' o isRightToLeft)--  exact (HsCmdArrForm an e fixity mf cs) = do-    an0 <- markLensMAA' an lal_open-    (e',cs') <- case (fixity, cs) of-      (Infix, (arg1:argrest)) -> do-        arg1' <- markAnnotated arg1-        e' <- markAnnotated e-        argrest' <- markAnnotated argrest-        return (e', arg1':argrest')-      (Prefix, _) -> do-        e' <- markAnnotated e-        cs' <- markAnnotated cs-        return (e', cs')-      (Infix, []) -> error "Not possible"-    an1 <- markLensMAA' an0 lal_close-    return (HsCmdArrForm an1 e' fixity mf cs')--  exact (HsCmdApp an e1 e2) = do-    e1' <- markAnnotated e1-    e2' <- markAnnotated e2-    return (HsCmdApp an e1' e2')--  exact (HsCmdLam an lam_variant matches) = do-    an0 <- markEpAnnL an lidl AnnLam-    an1 <- case lam_variant of-             LamSingle -> return an0-             LamCase -> markEpAnnL an0 lidl AnnCase-             LamCases -> markEpAnnL an0 lidl AnnCases-    matches' <- markAnnotated matches-    return (HsCmdLam an1 lam_variant matches')--  exact (HsCmdPar (lpar, rpar) e) = do-    lpar' <- markEpToken lpar-    e' <- markAnnotated e-    rpar' <- markEpToken rpar-    return (HsCmdPar (lpar', rpar') e')--  exact (HsCmdCase an e alts) = do-    an0 <- markLensKw an lhsCaseAnnCase AnnCase-    e' <- markAnnotated e-    an1 <- markLensKw an0 lhsCaseAnnOf AnnOf-    an2 <- markEpAnnL an1 lhsCaseAnnsRest AnnOpenC-    an3 <- markEpAnnAllL' an2 lhsCaseAnnsRest AnnSemi-    alts' <- markAnnotated alts-    an4 <- markEpAnnL an3 lhsCaseAnnsRest AnnCloseC-    return (HsCmdCase an4 e' alts')--  exact (HsCmdIf an a e1 e2 e3) = do-    an0 <- markLensKw an laiIf AnnIf-    e1' <- markAnnotated e1-    an1 <- markLensKwM' an0 laiThenSemi AnnSemi-    an2 <- markLensKw an1 laiThen AnnThen-    e2' <- markAnnotated e2-    an3 <- markLensKwM' an2 laiElseSemi AnnSemi-    an4 <- markLensKw an3 laiElse AnnElse-    e3' <- markAnnotated e3-    return (HsCmdIf an4 a e1' e2' e3')--  exact (HsCmdLet (tkLet, tkIn) binds e) = do-    setLayoutBoth $ do -- Make sure the 'in' gets indented too-      tkLet' <- markEpToken tkLet-      binds' <- setLayoutBoth $ markAnnotated binds-      tkIn' <- markEpToken tkIn-      e' <- markAnnotated e-      return (HsCmdLet (tkLet', tkIn') binds' e')--  exact (HsCmdDo an es) = do-    debugM $ "HsCmdDo"-    an0 <- markEpAnnL an lal_rest AnnDo-    es' <- markAnnotated es-    return (HsCmdDo an0 es')---- -----------------------------------------------------------------------instance (-  ExactPrint (LocatedA (body GhcPs)),-                 Anno (StmtLR GhcPs GhcPs (LocatedA (body GhcPs))) ~ SrcSpanAnnA,-           Anno [GenLocated SrcSpanAnnA (StmtLR GhcPs GhcPs (LocatedA (body GhcPs)))] ~ SrcSpanAnnL,-           (ExactPrint (LocatedL [LocatedA (StmtLR GhcPs GhcPs (LocatedA (body GhcPs)))])))-   => ExactPrint (StmtLR GhcPs GhcPs (LocatedA (body GhcPs))) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _s = a--  exact (LastStmt a body b c) = do-    debugM $ "LastStmt"-    body' <- markAnnotated body-    return (LastStmt a body' b c)--  exact (BindStmt an pat body) = do-    debugM $ "BindStmt"-    pat' <- markAnnotated pat-    an0 <- markEpAnnL an lidl AnnLarrow-    body' <- markAnnotated body-    return (BindStmt an0 pat' body')--  exact (ApplicativeStmt _ _body _) = do-    error $ "ApplicativeStmt is introduced in the renamer"--  exact (BodyStmt a body b c) = do-    debugM $ "BodyStmt"-    body' <- markAnnotated body-    return (BodyStmt a body' b c)--  exact (LetStmt an binds) = do-    debugM $ "LetStmt"-    an0 <- markEpAnnL an lidl AnnLet-    binds' <- markAnnotated binds-    return (LetStmt an0 binds')--  exact (ParStmt a pbs b c) = do-    debugM $ "ParStmt"-    pbs' <- markAnnotated pbs-    return (ParStmt a pbs' b c)--  exact (TransStmt an form stmts b using by c d e) = do-    debugM $ "TransStmt"-    stmts' <- markAnnotated stmts-    (an', by', using') <- exactTransStmt an by using form-    return (TransStmt an' form stmts' b using' by' c d e)--  exact (RecStmt an stmts a b c d e) = do-    debugM $ "RecStmt"-    an0 <- markEpAnnL an lal_rest AnnRec-    (an1, stmts') <- markAnnList' an0 (markAnnotated stmts)-    return (RecStmt an1 stmts' a b c d e)---- -----------------------------------------------------------------------instance ExactPrint (ParStmtBlock GhcPs GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (ParStmtBlock a stmts b c) = do-    stmts' <- markAnnotated stmts-    return (ParStmtBlock a stmts' b c)--exactTransStmt :: (Monad m, Monoid w)-  => [AddEpAnn] -> Maybe (LHsExpr GhcPs) -> (LHsExpr GhcPs) -> TransForm-  -> EP w m ([AddEpAnn], Maybe (LHsExpr GhcPs), (LHsExpr GhcPs))-exactTransStmt an by using ThenForm = do-  debugM $ "exactTransStmt:ThenForm"-  an0 <- markEpAnnL an lidl AnnThen-  using' <- markAnnotated using-  case by of-    Nothing -> return (an0, by, using')-    Just b -> do-      an1 <- markEpAnnL an0 lidl AnnBy-      b' <- markAnnotated b-      return (an1, Just b', using')-exactTransStmt an by using GroupForm = do-  debugM $ "exactTransStmt:GroupForm"-  an0 <- markEpAnnL an lidl AnnThen-  an1 <- markEpAnnL an0 lidl AnnGroup-  (an2, by') <- case by of-    Nothing -> return (an1, by)-    Just b -> do-      an2 <- markEpAnnL an1 lidl AnnBy-      b' <- markAnnotated b-      return (an2, Just b')-  an3 <- markEpAnnL an2 lidl AnnUsing-  using' <- markAnnotated using-  return (an3, by', using')---- -----------------------------------------------------------------------instance ExactPrint (TyClDecl GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _s = a--  exact (FamDecl a decl) = do-    decl' <- markAnnotated decl-    return (FamDecl a decl')--  exact (SynDecl { tcdSExt = an-                 , tcdLName = ltycon, tcdTyVars = tyvars, tcdFixity = fixity-                 , tcdRhs = rhs }) = do-    -- There may be arbitrary parens around parts of the constructor-    -- that are infix.  Turn these into comments so that they feed-    -- into the right place automatically-    -- TODO: no longer sorting on insert. What now?-    an0 <- annotationsToComments an lidl [AnnOpenP,AnnCloseP]-    an1 <- markEpAnnL an0 lidl AnnType--    (_anx, ltycon', tyvars',_,_) <- exactVanillaDeclHead ltycon tyvars fixity Nothing-    an2 <- markEpAnnL an1 lidl AnnEqual-    rhs' <- markAnnotated rhs-    return (SynDecl { tcdSExt = an2-                    , tcdLName = ltycon', tcdTyVars = tyvars', tcdFixity = fixity-                    , tcdRhs = rhs' })--  -- TODO: add a workaround for https://gitlab.haskell.org/ghc/ghc/-/issues/20452-  exact (DataDecl { tcdDExt = an, tcdLName = ltycon, tcdTyVars = tyvars-                  , tcdFixity = fixity, tcdDataDefn = defn }) = do-    (_, an', ltycon', tyvars', _, defn') <--      exactDataDefn an (exactVanillaDeclHead ltycon tyvars fixity) defn-    return (DataDecl { tcdDExt = an', tcdLName = ltycon', tcdTyVars = tyvars'-                     , tcdFixity = fixity, tcdDataDefn = defn' })--  -- -------------------------------------  exact (ClassDecl {tcdCExt = (an, lo, sortKey),-                    tcdCtxt = context, tcdLName = lclas, tcdTyVars = tyvars,-                    tcdFixity = fixity,-                    tcdFDs  = fds,-                    tcdSigs = sigs, tcdMeths = methods,-                    tcdATs = ats, tcdATDefs = at_defs,-                    tcdDocs = _docs})-      -- TODO: add a test that demonstrates tcdDocs-      | null sigs && isEmptyBag methods && null ats && null at_defs -- No "where" part-      = do-          (an0, fds', lclas', tyvars',context') <- top_matter-          an1 <- markEpAnnL an0 lidl AnnOpenC-          an2 <- markEpAnnL an1 lidl AnnCloseC-          return (ClassDecl {tcdCExt = (an2, lo, sortKey),-                             tcdCtxt = context', tcdLName = lclas', tcdTyVars = tyvars',-                             tcdFixity = fixity,-                             tcdFDs  = fds',-                             tcdSigs = sigs, tcdMeths = methods,-                             tcdATs = ats, tcdATDefs = at_defs,-                             tcdDocs = _docs})--      | otherwise       -- Laid out-      = do-          (an0, fds', lclas', tyvars',context') <- top_matter-          an1 <- markEpAnnL    an0 lidl AnnOpenC-          an2 <- markEpAnnAllL' an1 lidl AnnSemi-          (sortKey', ds) <- withSortKey sortKey-                               [(ClsSigTag, prepareListAnnotationA sigs),-                                (ClsMethodTag, prepareListAnnotationA (bagToList methods)),-                                (ClsAtTag, prepareListAnnotationA ats),-                                (ClsAtdTag, prepareListAnnotationA at_defs)-                             -- ++ prepareListAnnotation docs-                               ]-          an3 <- markEpAnnL an2 lidl AnnCloseC-          let-            sigs'    = undynamic ds-            methods' = listToBag $ undynamic ds-            ats'     = undynamic ds-            at_defs' = undynamic ds-          return (ClassDecl {tcdCExt = (an3, lo, sortKey'),-                             tcdCtxt = context', tcdLName = lclas', tcdTyVars = tyvars',-                             tcdFixity = fixity,-                             tcdFDs  = fds',-                             tcdSigs = sigs', tcdMeths = methods',-                             tcdATs = ats', tcdATDefs = at_defs',-                             tcdDocs = _docs})-      where-        top_matter = do-          an' <- annotationsToComments an lidl  [AnnOpenP, AnnCloseP]-          an0 <- markEpAnnL an' lidl AnnClass-          (_, lclas', tyvars',_,context') <-  exactVanillaDeclHead lclas tyvars fixity context-          (an1, fds') <- if (null fds)-            then return (an0, fds)-            else do-              an1 <- markEpAnnL an0 lidl AnnVbar-              fds' <- markAnnotated fds-              return (an1, fds')-          an2 <- markEpAnnL an1 lidl AnnWhere-          return (an2, fds', lclas', tyvars',context')----- -----------------------------------------------------------------------instance ExactPrint (FunDep GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (FunDep an ls rs') = do-    ls' <- markAnnotated ls-    an0 <- markEpAnnL an lidl AnnRarrow-    rs'' <- markAnnotated rs'-    return (FunDep an0 ls' rs'')---- -----------------------------------------------------------------------instance ExactPrint (FamilyDecl GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (FamilyDecl { fdExt = an-                    , fdInfo = info-                    , fdTopLevel = top_level-                    , fdLName = ltycon-                    , fdTyVars = tyvars-                    , fdFixity = fixity-                    , fdResultSig = L lr result-                    , fdInjectivityAnn = mb_inj }) = do-    an0 <- exactFlavour an info-    an1 <- exact_top_level an0-    an2 <- annotationsToComments an1 lidl [AnnOpenP,AnnCloseP]-    (_, ltycon', tyvars',_,_) <- exactVanillaDeclHead ltycon tyvars fixity Nothing-    (an3, result') <- exact_kind an2-    (an4, mb_inj') <--      case mb_inj of-        Nothing -> return (an3, mb_inj)-        Just inj -> do-          an4 <- markEpAnnL an3 lidl AnnVbar-          inj' <- markAnnotated inj-          return (an4, Just inj')-    (an5, info') <--             case info of-               ClosedTypeFamily mb_eqns -> do-                 an5 <- markEpAnnL an4 lidl AnnWhere-                 an6 <- markEpAnnL an5 lidl AnnOpenC-                 (an7, mb_eqns') <--                   case mb_eqns of-                     Nothing -> do-                       an7 <- markEpAnnL an6 lidl AnnDotdot-                       return (an7, mb_eqns)-                     Just eqns -> do-                       eqns' <- markAnnotated eqns-                       return (an6, Just eqns')-                 an8 <- markEpAnnL an7 lidl AnnCloseC-                 return (an8, ClosedTypeFamily mb_eqns')-               _ -> return (an4, info)-    return (FamilyDecl { fdExt = an5-                       , fdInfo = info'-                       , fdTopLevel = top_level-                       , fdLName = ltycon'-                       , fdTyVars = tyvars'-                       , fdFixity = fixity-                       , fdResultSig = L lr result'-                       , fdInjectivityAnn = mb_inj' })-    where-      exact_top_level an' =-        case top_level of-          TopLevel    -> markEpAnnL an' lidl AnnFamily-          NotTopLevel -> do-            -- It seems that in some kind of legacy-            -- mode the 'family' keyword is still-            -- accepted.-            markEpAnnL an' lidl AnnFamily--      exact_kind an' =-        case result of-          NoSig    _         -> return (an', result)-          KindSig  x kind    -> do-            an0 <- markEpAnnL an' lidl AnnDcolon-            kind' <- markAnnotated kind-            return (an0, KindSig  x kind')-          TyVarSig x tv_bndr -> do-            an0 <- markEpAnnL an' lidl AnnEqual-            tv_bndr' <- markAnnotated tv_bndr-            return (an0, TyVarSig x tv_bndr')---exactFlavour :: (Monad m, Monoid w) => [AddEpAnn] -> FamilyInfo GhcPs -> EP w m [AddEpAnn]-exactFlavour an DataFamily            = markEpAnnL an lidl AnnData-exactFlavour an OpenTypeFamily        = markEpAnnL an lidl AnnType-exactFlavour an (ClosedTypeFamily {}) = markEpAnnL an lidl AnnType---- -----------------------------------------------------------------------exactDataDefn-  :: (Monad m, Monoid w)-  => [AddEpAnn]-  -> (Maybe (LHsContext GhcPs) -> EP w m ([AddEpAnn]-                                         , LocatedN RdrName-                                         , a-                                         , b-                                         , Maybe (LHsContext GhcPs))) -- Printing the header-  -> HsDataDefn GhcPs-  -> EP w m ( [AddEpAnn] -- ^ from exactHdr-            , [AddEpAnn] -- ^ updated one passed in-            , LocatedN RdrName, a, b, HsDataDefn GhcPs)-exactDataDefn an exactHdr-                 (HsDataDefn { dd_ext = x, dd_ctxt = context-                             , dd_cType = mb_ct-                             , dd_kindSig = mb_sig-                             , dd_cons = condecls, dd_derivs = derivings }) = do--  an' <- annotationsToComments an lidl [AnnOpenP, AnnCloseP]--  an0 <- case condecls of-    DataTypeCons is_type_data _ -> do-      an0' <- if is_type_data-                then markEpAnnL an' lidl AnnType-                else return an'-      markEpAnnL an0' lidl AnnData-    NewTypeCon   _ -> markEpAnnL an' lidl AnnNewtype--  an1 <- markEpAnnL an0 lidl AnnInstance -- optional-  mb_ct' <- mapM markAnnotated mb_ct-  (anx, ln', tvs', b, context') <- exactHdr context-  (an2, mb_sig') <- case mb_sig of-    Nothing -> return (an1, Nothing)-    Just kind -> do-      an2 <- markEpAnnL an1 lidl AnnDcolon-      kind' <- markAnnotated kind-      return (an2, Just kind')-  an3 <- if (needsWhere condecls)-    then markEpAnnL an2 lidl AnnWhere-    else return an2-  an4 <- markEpAnnL an3 lidl AnnOpenC-  (an5, condecls') <- exact_condecls an4 (toList condecls)-  let condecls'' = case condecls of-        DataTypeCons d _ -> DataTypeCons d condecls'-        NewTypeCon _     -> case condecls' of-          [decl] -> NewTypeCon decl-          _ -> panic "exacprint NewTypeCon"-  an6 <- markEpAnnL an5 lidl AnnCloseC-  derivings' <- mapM markAnnotated derivings-  return (anx, an6, ln', tvs', b,-                 (HsDataDefn { dd_ext = x, dd_ctxt = context'-                             , dd_cType = mb_ct'-                             , dd_kindSig = mb_sig'-                             , dd_cons = condecls'', dd_derivs = derivings' }))---exactVanillaDeclHead :: (Monad m, Monoid w)-                     => LocatedN RdrName-                     -> LHsQTyVars GhcPs-                     -> LexicalFixity-                     -> Maybe (LHsContext GhcPs)-                     -> EP w m ( [AddEpAnn]-                               , LocatedN RdrName-                               , LHsQTyVars GhcPs-                               , (), Maybe (LHsContext GhcPs))-exactVanillaDeclHead thing tvs@(HsQTvs { hsq_explicit = tyvars }) fixity context = do-  let-    exact_tyvars (varl:varsr)-      | hvarsr : tvarsr@(_ : _) <- varsr-      , fixity == Infix = do-          varl' <- markAnnotated varl-          thing' <- markAnnotated thing-          hvarsr' <- markAnnotated hvarsr-          tvarsr' <- markAnnotated tvarsr-          return (thing', varl':hvarsr':tvarsr')-      | fixity == Infix = do-          varl' <- markAnnotated varl-          thing' <- markAnnotated thing-          varsr' <- markAnnotated varsr-          return (thing', varl':varsr')-      | otherwise = do-          thing' <- markAnnotated thing-          vs <- mapM markAnnotated (varl:varsr)-          return (thing', vs)-    exact_tyvars [] = do-      thing' <- markAnnotated thing-      return (thing', [])-  context' <- mapM markAnnotated context-  (thing', tyvars') <- exact_tyvars tyvars-  return (noAnn, thing', tvs { hsq_explicit = tyvars' }, (), context')---- -----------------------------------------------------------------------instance ExactPrint (InjectivityAnn GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (InjectivityAnn an lhs rhs) = do-    an0 <- markEpAnnL an lidl AnnVbar-    lhs' <- markAnnotated lhs-    an1 <- markEpAnnL an0 lidl AnnRarrow-    rhs' <- mapM markAnnotated rhs-    return (InjectivityAnn an1 lhs' rhs')---- -----------------------------------------------------------------------class Typeable flag => ExactPrintTVFlag flag where-  exactTVDelimiters :: (Monad m, Monoid w)-    => [AddEpAnn] -> flag-    -> ([AddEpAnn] -> EP w m ([AddEpAnn], HsTyVarBndr flag GhcPs))-    -> EP w m ([AddEpAnn], flag, (HsTyVarBndr flag GhcPs))--instance ExactPrintTVFlag () where-  exactTVDelimiters an flag thing_inside = do-    an0 <- markEpAnnAllL' an lid AnnOpenP-    (an1, r) <- thing_inside an0-    an2 <- markEpAnnAllL' an1 lid AnnCloseP-    return (an2, flag, r)--instance ExactPrintTVFlag Specificity where-  exactTVDelimiters an s thing_inside = do-    an0 <- markEpAnnAllL' an lid open-    (an1, r) <- thing_inside an0-    an2 <- markEpAnnAllL' an1 lid close-    return (an2, s, r)-    where-      (open, close) = case s of-        SpecifiedSpec -> (AnnOpenP, AnnCloseP)-        InferredSpec  -> (AnnOpenC, AnnCloseC)--instance ExactPrintTVFlag (HsBndrVis GhcPs) where-  exactTVDelimiters an0 bvis thing_inside = do-    bvis' <- case bvis of-      HsBndrRequired _ -> return bvis-      HsBndrInvisible at -> HsBndrInvisible <$> markEpToken at-    an1 <- markEpAnnAllL' an0 lid AnnOpenP-    (an2, r) <- thing_inside an1-    an3 <- markEpAnnAllL' an2 lid AnnCloseP-    return (an3, bvis', r)--instance ExactPrintTVFlag flag => ExactPrint (HsTyVarBndr flag GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (UserTyVar an flag n) = do-    r <- exactTVDelimiters an flag $ \ani -> do-           n' <- markAnnotated n-           return (ani, UserTyVar an flag n')-    case r of-      (an', flag', UserTyVar _ _ n'') -> return (UserTyVar an' flag' n'')-      _ -> error "KindedTyVar should never happen here"-  exact (KindedTyVar an flag n k) = do-    r <- exactTVDelimiters an flag $ \ani -> do-          n' <- markAnnotated n-          an0 <- markEpAnnL ani lidl AnnDcolon-          k' <- markAnnotated k-          return (an0, KindedTyVar an0 flag n' k')-    case r of-      (an',flag', KindedTyVar _ _ n'' k'') -> return (KindedTyVar an' flag' n'' k'')-      _ -> error "UserTyVar should never happen here"---- -----------------------------------------------------------------------instance ExactPrint (HsType GhcPs) where-  getAnnotationEntry _         = NoEntryVal-  setAnnotationAnchor a _ _ _s = a--  exact (HsForAllTy { hst_xforall = an-                    , hst_tele = tele, hst_body = ty }) = do-    tele' <- markAnnotated tele-    ty' <- markAnnotated ty-    return (HsForAllTy { hst_xforall = an-                       , hst_tele = tele', hst_body = ty' })--  exact (HsQualTy an ctxt ty) = do-    ctxt' <- markAnnotated ctxt-    ty' <- markAnnotated ty-    return (HsQualTy an ctxt' ty')-  exact (HsTyVar an promoted name) = do-    an0 <- if (promoted == IsPromoted)-             then markEpAnnL an lidl AnnSimpleQuote-             else return an-    name' <- markAnnotated name-    return (HsTyVar an0 promoted name')-  exact (HsAppTy an t1 t2) = do-    t1' <- markAnnotated t1-    t2' <- markAnnotated t2-    return (HsAppTy an t1' t2')-  exact (HsAppKindTy at ty ki) = do-    ty' <- markAnnotated ty-    at' <- markEpToken at-    ki' <- markAnnotated ki-    return (HsAppKindTy at' ty' ki')-  exact (HsFunTy an mult ty1 ty2) = do-    ty1' <- markAnnotated ty1-    mult' <- markArrow mult-    ty2' <- markAnnotated ty2-    return (HsFunTy an mult' ty1' ty2')-  exact (HsListTy an tys) = do-    an0 <- markOpeningParen an-    tys' <- markAnnotated tys-    an1 <- markClosingParen an0-    return (HsListTy an1 tys')-  exact (HsTupleTy an con tys) = do-    an0 <- markOpeningParen an-    tys' <- markAnnotated tys-    an1 <- markClosingParen an0-    return (HsTupleTy an1 con tys')-  exact (HsSumTy an tys) = do-    an0 <- markOpeningParen an-    tys' <- markAnnotated tys-    an1 <- markClosingParen an0-    return (HsSumTy an1 tys')-  exact (HsOpTy an promoted t1 lo t2) = do-    an0 <- if (isPromoted promoted)-        then markEpAnnL an lidl AnnSimpleQuote-        else return an-    t1' <- markAnnotated t1-    lo' <- markAnnotated lo-    t2' <- markAnnotated t2-    return (HsOpTy an0 promoted t1' lo' t2')-  exact (HsParTy an ty) = do-    an0 <- markOpeningParen an-    ty' <- markAnnotated ty-    an1 <- markClosingParen an0-    return (HsParTy an1 ty')-  exact (HsIParamTy an n t) = do-    n' <- markAnnotated n-    an0 <- markEpAnnL an lidl AnnDcolon-    t' <- markAnnotated t-    return (HsIParamTy an0 n' t')-  exact (HsStarTy an isUnicode) = do-    if isUnicode-        then printStringAdvance "\x2605" -- Unicode star-        else printStringAdvance "*"-    return (HsStarTy an isUnicode)-  exact (HsKindSig an ty k) = do-    ty' <- markAnnotated ty-    an0 <- markEpAnnL an lidl AnnDcolon-    k' <- markAnnotated k-    return (HsKindSig an0 ty' k')-  exact (HsSpliceTy a splice) = do-    splice' <- markAnnotated splice-    return (HsSpliceTy a splice')-  exact (HsDocTy an ty doc) = do-    ty' <- markAnnotated ty-    return (HsDocTy an ty' doc)-  exact (HsBangTy an (HsSrcBang mt up str) ty) = do-    an0 <--      case mt of-        NoSourceText -> return an-        SourceText src -> do-          debugM $ "HsBangTy: src=" ++ showAst src-          an0 <- markEpAnnMS' an AnnOpen  (Just $ unpackFS src)-          an1 <- markEpAnnMS' an0 AnnClose (Just "#-}")-          debugM $ "HsBangTy: done unpackedness"-          return an1-    an1 <--      case str of-        SrcLazy     -> mark an0 AnnTilde-        SrcStrict   -> mark an0 AnnBang-        NoSrcStrict -> return an0-    ty' <- markAnnotated ty-    return (HsBangTy an1 (HsSrcBang mt up str) ty')-  exact (HsExplicitListTy an prom tys) = do-    an0 <- if (isPromoted prom)-             then mark an AnnSimpleQuote-             else return an-    an1 <- mark an0 AnnOpenS-    tys' <- markAnnotated tys-    an2 <- mark an1 AnnCloseS-    return (HsExplicitListTy an2 prom tys')-  exact (HsExplicitTupleTy an tys) = do-    an0 <- mark an AnnSimpleQuote-    an1 <- mark an0 AnnOpenP-    tys' <- markAnnotated tys-    an2 <- mark an1 AnnCloseP-    return (HsExplicitTupleTy an2 tys')-  exact (HsTyLit a lit) = do-    case lit of-      (HsNumTy src v) -> printSourceText src (show v)-      (HsStrTy src v) -> printSourceText src (show v)-      (HsCharTy src v) -> printSourceText src (show v)-    return (HsTyLit a lit)-  exact t@(HsWildCardTy _) = printStringAdvance "_" >> return t-  exact x = error $ "missing match for HsType:" ++ showAst x---- -----------------------------------------------------------------------instance ExactPrint (HsForAllTelescope GhcPs) where-  getAnnotationEntry (HsForAllVis an _)   = fromAnn an-  getAnnotationEntry (HsForAllInvis an _) = fromAnn an--  setAnnotationAnchor (HsForAllVis an a) anc ts cs = HsForAllVis (setAnchorEpa an anc ts cs) a-  setAnnotationAnchor (HsForAllInvis an a) anc ts cs = HsForAllInvis (setAnchorEpa an anc ts cs) a--  exact (HsForAllVis an bndrs)   = do-    an0 <- markLensAA an lfst -- AnnForall-    bndrs' <- markAnnotated bndrs-    an1 <- markLensAA an0 lsnd -- AnnRarrow-    return (HsForAllVis an1 bndrs')--  exact (HsForAllInvis an bndrs) = do-    an0 <- markLensAA an lfst -- AnnForall-    bndrs' <- markAnnotated bndrs-    an1 <- markLensAA an0 lsnd -- AnnDot-    return (HsForAllInvis an1 bndrs')---- -----------------------------------------------------------------------instance ExactPrint (HsDerivingClause GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (HsDerivingClause { deriv_clause_ext      = an-                          , deriv_clause_strategy = dcs-                          , deriv_clause_tys      = dct }) = do-    an0 <- markEpAnnL an lidl AnnDeriving-    dcs0 <- case dcs of-            Just (L _ ViaStrategy{}) -> return dcs-            _ -> mapM markAnnotated dcs-    dct' <- markAnnotated dct-    dcs1 <- case dcs0 of-            Just (L _ ViaStrategy{}) -> mapM markAnnotated dcs0-            _ -> return dcs0-    return (HsDerivingClause { deriv_clause_ext      = an0-                             , deriv_clause_strategy = dcs1-                             , deriv_clause_tys      = dct' })---- -----------------------------------------------------------------------instance ExactPrint (DerivStrategy GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (StockStrategy an)    = do-    an0 <- markEpAnnL an lid AnnStock-    return (StockStrategy an0)-  exact (AnyclassStrategy an) = do-    an0 <- markEpAnnL an lid AnnAnyclass-    return (AnyclassStrategy an0)-  exact (NewtypeStrategy an)  = do-    an0 <- markEpAnnL an lid AnnNewtype-    return (NewtypeStrategy an0)-  exact (ViaStrategy (XViaStrategyPs an ty)) = do-    an0 <- markEpAnnL an lid AnnVia-    ty' <- markAnnotated ty-    return (ViaStrategy (XViaStrategyPs an0 ty'))---- -----------------------------------------------------------------------instance (ExactPrint a) => ExactPrint (LocatedC a) where-  getAnnotationEntry (L sann _) = fromAnn sann-  setAnnotationAnchor = setAnchorAn--  exact (L (EpAnn anc (AnnContext ma opens closes) cs) a) = do-    opens' <- mapM (markKwA AnnOpenP) opens-    a' <- markAnnotated a-    closes' <- mapM (markKwA AnnCloseP) closes-    return (L (EpAnn anc (AnnContext ma opens' closes') cs) a')---- -----------------------------------------------------------------------instance ExactPrint (DerivClauseTys GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (DctSingle x ty) = do-    ty' <- markAnnotated ty-    return (DctSingle x ty')-  exact (DctMulti x tys) = do-    tys' <- markAnnotated tys-    return (DctMulti x tys')---- -----------------------------------------------------------------------instance ExactPrint (HsSigType GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (HsSig a bndrs ty) = do-    bndrs' <- markAnnotated bndrs-    ty' <- markAnnotated ty-    return (HsSig a bndrs' ty')---- -----------------------------------------------------------------------instance ExactPrint (LocatedN RdrName) where-  getAnnotationEntry (L sann _) = fromAnn sann-  setAnnotationAnchor = setAnchorAn--  exact (L (EpAnn anc ann cs) n) = do-    ann' <--      case ann of-        NameAnn a o l c t -> do-          mn <- markName a o (Just (l,n)) c-          case mn of-            (o', (Just (l',_n)), c') -> do-              return (NameAnn a o' l' c' t)-            _ -> error "ExactPrint (LocatedN RdrName)"-        NameAnnCommas a o commas c t -> do-          let (kwo,kwc) = adornments a-          (AddEpAnn _ o') <- markKwC NoCaptureComments (AddEpAnn kwo o)-          commas' <- forM commas (\loc -> locFromAdd <$> markKwC NoCaptureComments (AddEpAnn AnnComma loc))-          (AddEpAnn _ c') <- markKwC NoCaptureComments (AddEpAnn kwc c)-          return (NameAnnCommas a o' commas' c' t)-        NameAnnBars a o bars c t -> do-          let (kwo,kwc) = adornments a-          (AddEpAnn _ o') <- markKwC NoCaptureComments (AddEpAnn kwo o)-          bars' <- forM bars (\loc -> locFromAdd <$> markKwC NoCaptureComments (AddEpAnn AnnVbar loc))-          (AddEpAnn _ c') <- markKwC NoCaptureComments (AddEpAnn kwc c)-          return (NameAnnBars a o' bars' c' t)-        NameAnnOnly a o c t -> do-          (o',_,c') <- markName a o Nothing c-          return (NameAnnOnly a o' c' t)-        NameAnnRArrow unicode o nl c t -> do-          o' <- case o of-            Just o0 -> do-              (AddEpAnn _ o') <- markKwC NoCaptureComments (AddEpAnn AnnOpenP o0)-              return (Just o')-            Nothing -> return Nothing-          (AddEpAnn _ nl') <--            if unicode-              then markKwC NoCaptureComments (AddEpAnn AnnRarrowU nl)-              else markKwC NoCaptureComments (AddEpAnn AnnRarrow nl)-          c' <- case c of-            Just c0 -> do-              (AddEpAnn _ c') <- markKwC NoCaptureComments (AddEpAnn AnnCloseP c0)-              return (Just c')-            Nothing -> return Nothing-          return (NameAnnRArrow unicode o' nl' c' t)-        NameAnnQuote q name t -> do-          debugM $ "NameAnnQuote"-          (AddEpAnn _ q') <- markKwC NoCaptureComments (AddEpAnn AnnSimpleQuote q)-          (L name' _) <- markAnnotated (L name n)-          return (NameAnnQuote q' name' t)-        NameAnnTrailing t -> do-          _anc' <- printUnicode anc n-          return (NameAnnTrailing t)-    return (L (EpAnn anc ann' cs) n)--locFromAdd :: AddEpAnn -> EpaLocation-locFromAdd (AddEpAnn _ loc) = loc--printUnicode :: (Monad m, Monoid w) => Anchor -> RdrName -> EP w m Anchor-printUnicode anc n = do-  let str = case (showPprUnsafe n) of-            -- TODO: unicode support?-              "forall" -> if spanLength (anchor anc) == 1 then "∀" else "forall"-              s -> s-  loc <- printStringAtAAC NoCaptureComments (EpaDelta (SameLine 0) []) str-  case loc of-    EpaSpan _ -> return anc-    EpaDelta dp [] -> return $ EpaDelta dp []-    EpaDelta _ _cs -> error "printUnicode should not capture comments"---markName :: (Monad m, Monoid w)-  => NameAdornment -> EpaLocation -> Maybe (EpaLocation,RdrName) -> EpaLocation-  -> EP w m (EpaLocation, Maybe (EpaLocation,RdrName), EpaLocation)-markName adorn open mname close = do-  let (kwo,kwc) = adornments adorn-  (AddEpAnn _ open') <- markKwC CaptureComments (AddEpAnn kwo open)-  mname' <--    case mname of-      Nothing -> return Nothing-      Just (name, a) -> do-        name' <- printStringAtAAC CaptureComments name (showPprUnsafe a)-        return (Just (name',a))-  (AddEpAnn _ close') <- markKwC CaptureComments (AddEpAnn kwc close)-  return (open', mname', close')--adornments :: NameAdornment -> (AnnKeywordId, AnnKeywordId)-adornments NameParens     = (AnnOpenP, AnnCloseP)-adornments NameParensHash = (AnnOpenPH, AnnClosePH)-adornments NameBackquotes = (AnnBackquote, AnnBackquote)-adornments NameSquare     = (AnnOpenS, AnnCloseS)--markTrailing :: (Monad m, Monoid w) => [TrailingAnn] -> EP w m [TrailingAnn]-markTrailing ts = do-  p <- getPosP-  debugM $ "markTrailing:" ++ showPprUnsafe (p,ts)-  mapM markKwT ts---- ------------------------------------------------------------------------- based on pp_condecls in Decls.hs-exact_condecls :: (Monad m, Monoid w)-  => [AddEpAnn] -> [LConDecl GhcPs] -> EP w m ([AddEpAnn],[LConDecl GhcPs])-exact_condecls an cs-  | gadt_syntax                  -- In GADT syntax-  = do-      cs' <- mapM markAnnotated cs-      return (an, cs')-  | otherwise                    -- In H98 syntax-  = do-      an0 <- markEpAnnL an lidl AnnEqual-      cs' <- mapM markAnnotated cs-      return (an0, cs')-  where-    gadt_syntax = case cs of-      []                      -> False-      (L _ ConDeclH98{}  : _) -> False-      (L _ ConDeclGADT{} : _) -> True---- -----------------------------------------------------------------------instance ExactPrint (ConDecl GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a---- based on pprConDecl-  exact (ConDeclH98 { con_ext = an-                    , con_name = con-                    , con_forall = has_forall-                    , con_ex_tvs = ex_tvs-                    , con_mb_cxt = mcxt-                    , con_args = args-                    , con_doc = doc }) = do-    an0 <- if has_forall-      then markEpAnnL an lidl AnnForall-      else return an-    ex_tvs' <- mapM markAnnotated ex_tvs-    an1 <- if has_forall-      then markEpAnnL an0 lidl AnnDot-      else return an0-    mcxt' <- mapM markAnnotated mcxt-    an2 <- if (isJust mcxt)-      then markEpAnnL an1 lidl AnnDarrow-      else return an1--    (con', args') <- exact_details args-    return (ConDeclH98 { con_ext = an2-                       , con_name = con'-                       , con_forall = has_forall-                       , con_ex_tvs = ex_tvs'-                       , con_mb_cxt = mcxt'-                       , con_args = args'-                       , con_doc = doc })--    where-    -- In ppr_details: let's not print the multiplicities (they are always 1, by-    -- definition) as they do not appear in an actual declaration.-      exact_details (InfixCon t1 t2) = do-        t1' <- markAnnotated t1-        con' <- markAnnotated con-        t2' <- markAnnotated t2-        return (con', InfixCon t1' t2')-      exact_details (PrefixCon tyargs tys) = do-        con' <- markAnnotated con-        tyargs' <- markAnnotated tyargs-        tys' <- markAnnotated tys-        return (con', PrefixCon tyargs' tys')-      exact_details (RecCon fields) = do-        con' <- markAnnotated con-        fields' <- markAnnotated fields-        return (con', RecCon fields')--  -- -------------------------------------  exact (ConDeclGADT { con_g_ext = (dcol, an)-                     , con_names = cons-                     , con_bndrs = bndrs-                     , con_mb_cxt = mcxt, con_g_args = args-                     , con_res_ty = res_ty, con_doc = doc }) = do-    cons' <- mapM markAnnotated cons-    dcol' <- markEpUniToken dcol-    an1 <- annotationsToComments an lidl  [AnnOpenP, AnnCloseP]--    -- Work around https://gitlab.haskell.org/ghc/ghc/-/issues/20558-    bndrs' <- case bndrs of-      L _ (HsOuterImplicit _) -> return bndrs-      _ -> markAnnotated bndrs--    mcxt' <- mapM markAnnotated mcxt-    an2 <- if (isJust mcxt)-      then markEpAnnL an1 lidl AnnDarrow-      else return an1-    args' <--      case args of-          (PrefixConGADT x args0) -> do-            args0' <- mapM markAnnotated args0-            return (PrefixConGADT x args0')-          (RecConGADT rarr fields) -> do-            fields' <- markAnnotated fields-            rarr' <- markEpUniToken rarr-            return (RecConGADT rarr' fields')-    res_ty' <- markAnnotated res_ty-    return (ConDeclGADT { con_g_ext = (dcol', an2)-                        , con_names = cons'-                        , con_bndrs = bndrs'-                        , con_mb_cxt = mcxt', con_g_args = args'-                        , con_res_ty = res_ty', con_doc = doc })---- -----------------------------------------------------------------------instance ExactPrint Void where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact x = return x---- -----------------------------------------------------------------------instance ExactPrintTVFlag flag => ExactPrint (HsOuterTyVarBndrs flag GhcPs) where-  getAnnotationEntry (HsOuterImplicit _) = NoEntryVal-  getAnnotationEntry (HsOuterExplicit an _) = fromAnn an--  setAnnotationAnchor (HsOuterImplicit a) _ _ _ = HsOuterImplicit a-  setAnnotationAnchor (HsOuterExplicit an a) anc ts cs = HsOuterExplicit (setAnchorEpa an anc ts cs) a--  exact b@(HsOuterImplicit _) = pure b-  exact (HsOuterExplicit an bndrs) = do-    an0 <- markLensAA an lfst -- "forall"-    bndrs' <- markAnnotated bndrs-    an1 <- markLensAA an0 lsnd -- "."-    return (HsOuterExplicit an1 bndrs')---- -----------------------------------------------------------------------instance ExactPrint (ConDeclField GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (ConDeclField an names ftype mdoc) = do-    names' <- markAnnotated names-    an0 <- markEpAnnL an lidl AnnDcolon-    ftype' <- markAnnotated ftype-    return (ConDeclField an0 names' ftype' mdoc)---- -----------------------------------------------------------------------instance ExactPrint (FieldOcc GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (FieldOcc x n) = do-      n' <- markAnnotated n-      return (FieldOcc x n')---- -----------------------------------------------------------------------instance ExactPrint (AmbiguousFieldOcc GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact f@(Unambiguous _ n) = markAnnotated n >> return f-  exact f@(Ambiguous   _ n) = markAnnotated n >> return f---- -----------------------------------------------------------------------instance (ExactPrint a) => ExactPrint (HsScaled GhcPs a) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (HsScaled arr t) = do-    t' <- markAnnotated t-    arr' <- markArrow arr-    return (HsScaled arr' t')---- -----------------------------------------------------------------------instance ExactPrint (LocatedP CType) where-  getAnnotationEntry = entryFromLocatedA-  setAnnotationAnchor = setAnchorAn--  exact (L an (CType stp mh (stct,ct))) = do-    an0 <- markAnnOpenP an stp "{-# CTYPE"-    an1 <- case mh of-             Nothing -> return an0-             Just (Header srcH _h) ->-               markEpAnnLMS an0 lapr_rest AnnHeader (Just (toSourceTextWithSuffix srcH "" ""))-    an2 <- markEpAnnLMS an1 lapr_rest AnnVal (Just (toSourceTextWithSuffix stct (unpackFS ct) ""))-    an3 <- markAnnCloseP an2-    return (L an3 (CType stp mh (stct,ct)))---- -----------------------------------------------------------------------instance ExactPrint (SourceText, RuleName) where-  -- We end up at the right place from the Located wrapper-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (st, rn)-    = printStringAdvance (toSourceTextWithSuffix st (unpackFS rn) "")-      >> return (st, rn)----- =====================================================================--- LocatedL instances start -------- Each is dealt with specifically, as they have--- different wrapping annotations in the al_rest zone.------ In future, the annotation could perhaps be improved, with an--- 'al_pre' and 'al_post' set of annotations to be simply sorted and--- applied.--- -----------------------------------------------------------------------instance ExactPrint (LocatedL [LocatedA (IE GhcPs)]) where-  getAnnotationEntry = entryFromLocatedA-  setAnnotationAnchor = setAnchorAn--  exact (L an ies) = do-    debugM $ "LocatedL [LIE"-    an0 <- markEpAnnL' an lal_rest AnnHiding-    p <- getPosP-    debugM $ "LocatedL [LIE:p=" ++ showPprUnsafe p-    (an1, ies') <- markAnnList an0 (markAnnotated (filter notIEDoc ies))-    return (L an1 ies')--instance (ExactPrint (Match GhcPs (LocatedA body)))-   => ExactPrint (LocatedL [LocatedA (Match GhcPs (LocatedA body))]) where-  getAnnotationEntry = entryFromLocatedA-  setAnnotationAnchor = setAnchorAn-  exact (L an a) = do-    debugM $ "LocatedL [LMatch"-    -- TODO: markAnnList?-    an0 <- markEpAnnAllL an lal_rest AnnWhere-    an1 <- markLensMAA an0 lal_open-    an2 <- markEpAnnAllL an1 lal_rest AnnSemi-    a' <- markAnnotated a-    an3 <- markLensMAA an2 lal_close-    return (L an3 a')--instance ExactPrint (LocatedL [LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs)))]) where-  getAnnotationEntry = entryFromLocatedA-  setAnnotationAnchor = setAnchorAn-  exact (L an stmts) = do-    debugM $ "LocatedL [ExprLStmt"-    (an'', stmts') <- markAnnList an $ do-      case snocView stmts of-        Just (initStmts, ls@(L _ (LastStmt _ _body _ _))) -> do-          debugM $ "LocatedL [ExprLStmt: snocView"-          ls' <- markAnnotated ls-          initStmts' <- markAnnotated initStmts-          return (initStmts' ++ [ls'])-        _ -> do-          markAnnotated stmts-    return (L an'' stmts')--instance ExactPrint (LocatedL [LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsCmd GhcPs)))]) where-  getAnnotationEntry = entryFromLocatedA-  setAnnotationAnchor = setAnchorAn-  exact (L ann es) = do-    debugM $ "LocatedL [CmdLStmt"-    an0 <- markLensMAA ann lal_open-    es' <- mapM markAnnotated es-    an1 <- markLensMAA an0 lal_close-    return (L an1 es')--instance ExactPrint (LocatedL [LocatedA (ConDeclField GhcPs)]) where-  getAnnotationEntry = entryFromLocatedA-  setAnnotationAnchor = setAnchorAn-  exact (L an fs) = do-    debugM $ "LocatedL [LConDeclField"-    (an', fs') <- markAnnList an (markAnnotated fs)-    return (L an' fs')--instance ExactPrint (LocatedL (BF.BooleanFormula (LocatedN RdrName))) where-  getAnnotationEntry = entryFromLocatedA-  setAnnotationAnchor = setAnchorAn-  exact (L an bf) = do-    debugM $ "LocatedL [LBooleanFormula"-    (an', bf') <- markAnnList an (markAnnotated bf)-    return (L an' bf')---- ------------------------------------------------------------------------ LocatedL instances end ----- =====================================================================--instance ExactPrint (IE GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (IEVar depr ln doc) = do-    depr' <- markAnnotated depr-    ln' <- markAnnotated ln-    doc' <- markAnnotated doc-    return (IEVar depr' ln' doc')-  exact (IEThingAbs (depr, an) thing doc) = do-    depr' <- markAnnotated depr-    thing' <- markAnnotated thing-    doc' <- markAnnotated doc-    return (IEThingAbs (depr', an) thing' doc')-  exact (IEThingAll (depr, an) thing doc) = do-    depr' <- markAnnotated depr-    thing' <- markAnnotated thing-    an0 <- markEpAnnL an  lidl AnnOpenP-    an1 <- markEpAnnL an0 lidl AnnDotdot-    an2 <- markEpAnnL an1 lidl AnnCloseP-    doc' <- markAnnotated doc-    return (IEThingAll (depr', an2) thing' doc')--  exact (IEThingWith (depr, an) thing wc withs doc) = do-    depr' <- markAnnotated depr-    thing' <- markAnnotated thing-    an0 <- markEpAnnL an lidl AnnOpenP-    (an1, wc', withs') <--      case wc of-        NoIEWildcard -> do-          withs'' <- markAnnotated withs-          return (an0, wc, withs'')-        IEWildcard pos -> do-          let (bs, as) = splitAt pos withs-          bs' <- markAnnotated bs-          an1 <- markEpAnnL an0 lidl AnnDotdot-          an2 <- markEpAnnL an1 lidl AnnComma-          as' <- markAnnotated as-          return (an2, wc, bs'++as')-    an2 <- markEpAnnL an1 lidl AnnCloseP-    doc' <- markAnnotated doc-    return (IEThingWith (depr', an2) thing' wc' withs' doc')--  exact (IEModuleContents (depr, an) m) = do-    depr' <- markAnnotated depr-    an0 <- markEpAnnL an lidl AnnModule-    m' <- markAnnotated m-    return (IEModuleContents (depr', an0) m')--  -- These three exist to not error out, but are no-ops The contents-  -- appear as "normal" comments too, which we process instead.-  exact (IEGroup x lev doc) = do-    return (IEGroup x lev doc)-  exact (IEDoc x doc) = do-    return (IEDoc x doc)-  exact (IEDocNamed x str) = do-    return (IEDocNamed x str)---- -----------------------------------------------------------------------instance ExactPrint (IEWrappedName GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (IEName x n) = do-    n' <- markAnnotated n-    return (IEName x n')-  exact (IEPattern r n) = do-    r' <- printStringAtAA r "pattern"-    n' <- markAnnotated n-    return (IEPattern r' n')-  exact (IEType r n) = do-    r' <- printStringAtAA r "type"-    n' <- markAnnotated n-    return (IEType r' n')---- -----------------------------------------------------------------------instance ExactPrint (Pat GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (WildPat w) = do-    anchor' <- getAnchorU-    debugM $ "WildPat:anchor'=" ++ show anchor'-    _ <- printStringAtRs anchor' "_"-    return (WildPat w)-  exact (VarPat x n) = do-    -- The parser inserts a placeholder value for a record pun rhs. This must be-    -- filtered.-    let pun_RDR = "pun-right-hand-side"-    n' <- if (showPprUnsafe n /= pun_RDR)-      then markAnnotated n-      else return n-    return (VarPat x n')-  exact (LazyPat an pat) = do-    an0 <- markEpAnnL an lidl AnnTilde-    pat' <- markAnnotated pat-    return (LazyPat an0 pat')-  exact (AsPat at n pat) = do-    n' <- markAnnotated n-    at' <- markEpToken at-    pat' <- markAnnotated pat-    return (AsPat at' n' pat')-  exact (ParPat (lpar, rpar) pat) = do-    lpar' <- markEpToken lpar-    pat' <- markAnnotated pat-    rpar' <- markEpToken rpar-    return (ParPat (lpar', rpar') pat')--  exact (BangPat an pat) = do-    an0 <- markEpAnnL an lidl AnnBang-    pat' <- markAnnotated pat-    return (BangPat an0 pat')--  exact (ListPat an pats) = do-    (an', pats') <- markAnnList' an (markAnnotated pats)-    return (ListPat an' pats')--  exact (TuplePat an pats boxity) = do-    an0 <- case boxity of-             Boxed   -> markEpAnnL an lidl AnnOpenP-             Unboxed -> markEpAnnL an lidl AnnOpenPH-    pats' <- markAnnotated pats-    an1 <- case boxity of-             Boxed   -> markEpAnnL an0 lidl AnnCloseP-             Unboxed -> markEpAnnL an0 lidl AnnClosePH-    return (TuplePat an1 pats' boxity)--  exact (SumPat an pat alt arity) = do-    an0 <- markEpAnnL an lsumPatParens AnnOpenPH-    an1 <- markAnnKwAllL an0 lsumPatVbarsBefore AnnVbar-    pat' <- markAnnotated pat-    an2 <- markAnnKwAllL an1 lsumPatVbarsAfter AnnVbar-    an3 <- markEpAnnL an2 lsumPatParens AnnClosePH-    return (SumPat an3 pat' alt arity)--  exact (ConPat an con details) = do-    (an', con', details') <- exactUserCon an con details-    return (ConPat an' con' details')-  exact (ViewPat an expr pat) = do-    expr' <- markAnnotated expr-    an0 <- markEpAnnL an lidl AnnRarrow-    pat' <- markAnnotated pat-    return (ViewPat an0 expr' pat')-  exact (SplicePat x splice) = do-    splice' <- markAnnotated splice-    return (SplicePat x splice')-  exact p@(LitPat _ lit) = printStringAdvance (hsLit2String lit) >> return p-  exact (NPat an ol mn z) = do-    an0 <- if (isJust mn)-      then markEpAnnL an lidl AnnMinus-      else return an-    ol' <- markAnnotated ol-    return (NPat an0 ol' mn z)--  exact (NPlusKPat an n k lit2 a b) = do-    n' <- markAnnotated n-    an' <- printStringAtAAL an lid "+"-    k' <- markAnnotated k-    return (NPlusKPat an' n' k' lit2 a b)--  exact (SigPat an pat sig) = do-    pat' <- markAnnotated pat-    an0 <- markEpAnnL an lidl AnnDcolon-    sig' <- markAnnotated sig-    return (SigPat an0 pat' sig')--  exact (EmbTyPat toktype tp) = do-    toktype' <- markEpToken toktype-    tp' <- markAnnotated tp-    return (EmbTyPat toktype' tp')--  exact (InvisPat tokat tp) = do-    tokat' <- markEpToken tokat-    tp' <- markAnnotated tp-    pure (InvisPat tokat' tp')---- ------------------------------------------------------------------------- Note: Keep this section, for backport to GHC 9.10---- instance ExactPrint (ArgPat GhcPs) where---   getAnnotationEntry (VisPat _ pat) = getAnnotationEntry pat---   getAnnotationEntry InvisPat{}     = NoEntryVal----   setAnnotationAnchor (VisPat x pat) anc ts cs = VisPat x (setAnnotationAnchor pat anc ts cs)---   setAnnotationAnchor a@(InvisPat _ _) _ _ _   = a----   exact (VisPat x pat) = do---     pat' <- markAnnotated pat---     pure (VisPat x pat')----   exact (InvisPat tokat tp) = do---     tokat' <- markEpToken tokat---     tp' <- markAnnotated tp---     pure (InvisPat tokat' tp')---- -----------------------------------------------------------------------instance ExactPrint (HsPatSigType GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (HsPS an ty) = do-    ty' <- markAnnotated ty-    return (HsPS an ty')--instance ExactPrint (HsTyPat GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact (HsTP an ty) = do-    ty' <- markAnnotated ty-    return (HsTP an ty')---- -----------------------------------------------------------------------instance ExactPrint (HsOverLit GhcPs) where-  getAnnotationEntry = const NoEntryVal-  setAnnotationAnchor a _ _ _ = a--  exact ol =-    let str = case ol_val ol of-                HsIntegral   (IL src _ _) -> src-                HsFractional (FL{ fl_text = src }) -> src-                HsIsString src _ -> src-    in-      case str of-        SourceText s -> printStringAdvance (unpackFS s) >> return ol-        NoSourceText -> return ol---- -----------------------------------------------------------------------hsLit2String :: HsLit GhcPs -> String-hsLit2String lit =-  case lit of-    HsChar       src v   -> toSourceTextWithSuffix src v ""-    HsCharPrim   src p   -> toSourceTextWithSuffix src p ""-    HsString     src v   -> toSourceTextWithSuffix src v ""-    HsStringPrim src v   -> toSourceTextWithSuffix src v ""-    HsInt        _ (IL src _ v)   -> toSourceTextWithSuffix src v ""-    HsIntPrim    src v   -> toSourceTextWithSuffix src v ""-    HsWordPrim   src v   -> toSourceTextWithSuffix src v ""-    HsInt8Prim   src v   -> toSourceTextWithSuffix src v ""-    HsInt16Prim  src v   -> toSourceTextWithSuffix src v ""-    HsInt32Prim  src v   -> toSourceTextWithSuffix src v ""-    HsInt64Prim  src v   -> toSourceTextWithSuffix src v ""-    HsWord8Prim  src v   -> toSourceTextWithSuffix src v ""-    HsWord16Prim src v   -> toSourceTextWithSuffix src v ""-    HsWord32Prim src v   -> toSourceTextWithSuffix src v ""-    HsWord64Prim src v   -> toSourceTextWithSuffix src v ""-    HsInteger    src v _ -> toSourceTextWithSuffix src v ""-    HsRat        _ fl@(FL{fl_text = src }) _ -> toSourceTextWithSuffix src fl ""-    HsFloatPrim  _ fl@(FL{fl_text = src })   -> toSourceTextWithSuffix src fl "#"-    HsDoublePrim _ fl@(FL{fl_text = src })   -> toSourceTextWithSuffix src fl "##"--toSourceTextWithSuffix :: (Show a) => SourceText -> a -> String -> String-toSourceTextWithSuffix (NoSourceText)    alt suffix = show alt ++ suffix-toSourceTextWithSuffix (SourceText txt) _alt suffix = unpackFS txt ++ suffix--sourceTextToString :: SourceText -> String -> String-sourceTextToString NoSourceText alt   = alt-sourceTextToString (SourceText txt) _ = unpackFS txt---- -----------------------------------------------------------------------exactUserCon :: (Monad m, Monoid w, ExactPrint con)-  => [AddEpAnn] -> con -> HsConPatDetails GhcPs-  -> EP w m ([AddEpAnn], con, HsConPatDetails GhcPs)-exactUserCon an c (InfixCon p1 p2) = do-  p1' <- markAnnotated p1-  c' <- markAnnotated c-  p2' <- markAnnotated p2-  return (an, c', InfixCon p1' p2')-exactUserCon an c details = do-  c' <- markAnnotated c-  an0 <- markEpAnnL an lidl AnnOpenC-  details' <- exactConArgs details-  an1 <- markEpAnnL an0 lidl AnnCloseC-  return (an1, c', details')--instance ExactPrint (HsConPatTyArg GhcPs) where-  getAnnotationEntry _ = NoEntryVal-  setAnnotationAnchor a _ _ _ = a-  exact (HsConPatTyArg at tyarg) = do-    at' <- markEpToken at-    tyarg' <- markAnnotated tyarg-    return (HsConPatTyArg at' tyarg')--exactConArgs :: (Monad m, Monoid w)-  => HsConPatDetails GhcPs -> EP w m (HsConPatDetails GhcPs)-exactConArgs (PrefixCon tyargs pats) = do-  tyargs' <- markAnnotated tyargs-  pats' <- markAnnotated pats-  return (PrefixCon tyargs' pats')-exactConArgs (InfixCon p1 p2) = do-  p1' <- markAnnotated p1-  p2' <- markAnnotated p2-  return (InfixCon p1' p2')-exactConArgs (RecCon rpats) = do-  rpats' <- markAnnotated rpats-  return (RecCon rpats')---- -----------------------------------------------------------------------entryFromLocatedA :: (HasTrailing ann) => LocatedAn ann a -> Entry-entryFromLocatedA (L la _) = fromAnn la---- =====================================================================--- Utility stuff--- ------------------------------------------------------------------------- |This should be the final point where things are mode concrete,--- before output.--- NOTE: despite the name, this is the ghc-exactprint final output for--- the PRINT phase.-printStringAtLsDelta :: (Monad m, Monoid w) => DeltaPos -> String -> EP w m ()-printStringAtLsDelta cl s = do-  p <- getPosP-  colOffset <- getLayoutOffsetP-  if isGoodDeltaWithOffset cl colOffset-    then do-      printStringAt (undelta p cl colOffset) s-      p' <- getPosP-      d <- getPriorEndD-      debugM $ "printStringAtLsDelta:(pos,p,p',d,s):" ++ show (undelta p cl colOffset,p,p',d,s)-    else return () `debug` ("printStringAtLsDelta:bad delta for (mc,s):" ++ show (cl,s))---- -----------------------------------------------------------------------isGoodDeltaWithOffset :: DeltaPos -> LayoutStartCol -> Bool-isGoodDeltaWithOffset dp colOffset = isGoodDelta (deltaPos l c)-  where (l,c) = undelta (0,0) dp colOffset---- | Print a comment, using the current layout offset to convert the--- @DeltaPos@ to an absolute position.-printQueuedComment :: (Monad m, Monoid w) => Comment -> DeltaPos -> EP w m ()-printQueuedComment Comment{commentContents} dp = do-  p <- getPosP-  d <- getPriorEndD-  colOffset <- getLayoutOffsetP-  let (dr,dc) = undelta (0,0) dp colOffset-  -- do not lose comments against the left margin-  when (isGoodDelta (deltaPos dr (max 0 dc))) $ do-    printCommentAt (undelta p dp colOffset) commentContents-  p' <- getPosP-  d' <- getPriorEndD-  debugM $ "printQueuedComment: (p,p',d,d')=" ++ show (p,p',d,d')-  debugM $ "printQueuedComment: (p,p',dp,colOffset,undelta)=" ++ show (p,p',dp,colOffset,undelta p dp colOffset)----------------------------------------------------------------------------setLayoutBoth :: (Monad m, Monoid w) => EP w m a -> EP w m a-setLayoutBoth k = do-  oldLHS <- getLayoutOffsetD-  oldAnchorOffset <- getLayoutOffsetP-  debugM $ "setLayoutBoth: (oldLHS,oldAnchorOffset)=" ++ show (oldLHS,oldAnchorOffset)-  modify (\a -> a { dMarkLayout = True-                  , pMarkLayout = True } )-  let reset = do-        debugM $ "setLayoutBoth:reset: (oldLHS,oldAnchorOffset)=" ++ show (oldLHS,oldAnchorOffset)-        modify (\a -> a { dMarkLayout = False-                        , dLHS = oldLHS-                        , pMarkLayout = False-                        , pLHS = oldAnchorOffset} )-  k <* reset---- Use 'local', designed for this-setLayoutTopLevelP :: (Monad m, Monoid w) => EP w m a -> EP w m a-setLayoutTopLevelP k = do-  debugM $ "setLayoutTopLevelP entered"-  oldAnchorOffset <- getLayoutOffsetP-  modify (\a -> a { pMarkLayout = False-                  , pLHS = 0} )-  r <- k-  debugM $ "setLayoutTopLevelP:resetting"-  setLayoutOffsetP oldAnchorOffset-  return r----------------------------------------------------------------------------getPosP :: (Monad m, Monoid w) => EP w m Pos-getPosP = gets epPos--setPosP :: (Monad m, Monoid w) => Pos -> EP w m ()-setPosP l = do-  debugM $ "setPosP:" ++ show l-  modify (\s -> s {epPos = l})--getExtraDP :: (Monad m, Monoid w) => EP w m (Maybe Anchor)-getExtraDP = gets uExtraDP--setExtraDP :: (Monad m, Monoid w) => Maybe Anchor -> EP w m ()-setExtraDP md = do-  debugM $ "setExtraDP:" ++ show md-  modify (\s -> s {uExtraDP = md})--getExtraDPReturn :: (Monad m, Monoid w) => EP w m (Maybe DeltaPos)-getExtraDPReturn = gets uExtraDPReturn--setExtraDPReturn :: (Monad m, Monoid w) => Maybe DeltaPos -> EP w m ()+{-# LANGUAGE BlockArguments       #-}+{-# LANGUAGE DataKinds           #-}+{-# LANGUAGE DeriveDataTypeable   #-}+{-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE FlexibleInstances    #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiWayIf           #-}+{-# LANGUAGE NamedFieldPuns       #-}+{-# LANGUAGE RankNTypes           #-}+{-# LANGUAGE ScopedTypeVariables  #-}+{-# LANGUAGE StandaloneDeriving   #-}+{-# LANGUAGE TupleSections        #-}+{-# LANGUAGE TypeApplications     #-}+{-# LANGUAGE TypeFamilies         #-}+{-# LANGUAGE TypeOperators        #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE ViewPatterns         #-}+{-# LANGUAGE UndecidableInstances  #-} -- For the (StmtLR GhcPs GhcPs (LocatedA (body GhcPs))) ExactPrint instance+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns -Wno-incomplete-record-updates #-}++module Language.Haskell.GHC.ExactPrint.ExactPrint+  (+    ExactPrint(..)+  , exactPrint+  , exactPrintWithOptions+  , makeDeltaAst++  -- * Configuration+  , EPOptions(epTokenPrint, epWhitespacePrint)+  , stringOptions+  , epOptions+  , deltaOptions++  -- * Utility+  , setAnchorAn+  ) where++import GHC+import GHC.Base (NonEmpty(..))+import GHC.Core.Coercion.Axiom (Role(..))+import qualified GHC.Data.BooleanFormula as BF+import GHC.Data.FastString+import qualified GHC.Data.Strict as Strict+import GHC.TypeLits+import GHC.Types.Basic hiding (EP)+import GHC.Types.Fixity+import GHC.Types.ForeignCall+import GHC.Types.Name.Reader+import GHC.Types.PkgQual+import GHC.Types.SourceText+import GHC.Types.SrcLoc+import GHC.Types.Var+import GHC.Unit.Module.Warnings+import GHC.Utils.Misc+import GHC.Utils.Outputable hiding ( (<>) )+import GHC.Utils.Panic+++import Language.Haskell.Syntax.Basic (FieldLabelString(..))++import Control.Monad (forM, when, unless)+import Control.Monad.Identity (Identity(..))+import qualified Control.Monad.Reader as Reader+import Control.Monad.RWS (MonadReader, RWST, evalRWST, tell, modify, get, gets, ask)+import Control.Monad.Trans (lift)+import Data.Data ( Data )+import Data.Dynamic+import Data.Foldable+import Data.Functor.Const+import Data.Typeable+import Data.List ( partition, sort, sortBy)+import qualified Data.List.NonEmpty as NE+import qualified Data.Map.Strict as Map+import Data.Maybe ( isJust, mapMaybe )+import Data.Void++import Language.Haskell.GHC.ExactPrint.Utils+import Language.Haskell.GHC.ExactPrint.Types++-- ---------------------------------------------------------------------++exactPrint :: ExactPrint ast => ast -> String+exactPrint ast = snd $ runIdentity (runEP stringOptions (markAnnotated ast))++-- | The additional option to specify the printing configuration.+exactPrintWithOptions :: (ExactPrint ast, Monoid b, Monad m)+                      => EPOptions m b+                      -> ast+                      -> m (ast, b)+exactPrintWithOptions r ast =+    runEP r (markAnnotated ast)++-- | Transform concrete annotations into relative annotations.+-- This should be unnecessary from GHC 9.10+makeDeltaAst :: ExactPrint ast => ast -> ast+makeDeltaAst ast = fst $ runIdentity (runEP deltaOptions (markAnnotated ast))++------------------------------------------------------++type EP w m a = RWST (EPOptions m w) (EPWriter w) EPState m a++runEP :: (Monad m)+      => EPOptions m w+      -> EP w m a -> m (a, w)+runEP epReader action = do+  (ast, w) <- evalRWST action epReader defaultEPState+  return (ast, output w)++-- ---------------------------------------------------------------------++defaultEPState :: EPState+defaultEPState = EPState+             { epPos      = (1,1)+             , dLHS       = 0+             , pMarkLayout = False+             , pLHS = 0+             , dMarkLayout = False+             , dPriorEndPosition = (1,1)+             , uAnchorSpan = badRealSrcSpan+             , uExtraDP = Nothing+             , uExtraDPReturn = Nothing+             , pAcceptSpan = False+             , epComments = []+             , epCommentsApplied = []+             , epEof = Nothing+             }+++-- ---------------------------------------------------------------------+-- The EP monad and basic combinators++-- | The R part of RWS. The environment. Updated via 'local' as we+-- enter a new AST element, having a different anchor point.+data EPOptions m a = EPOptions+            { epTokenPrint :: String -> m a+            , epWhitespacePrint :: String -> m a+            }++-- | Helper to create a 'EPOptions'+epOptions :: (String -> m a)+          -> (String -> m a)+          -> EPOptions m a+epOptions tokenPrint wsPrint = EPOptions+             { epWhitespacePrint = wsPrint+             , epTokenPrint = tokenPrint+             }++-- | Options which can be used to print as a normal String.+stringOptions :: EPOptions Identity String+stringOptions = epOptions return return++-- | Options which can be used to simply update the AST to be in delta+-- form, without generating output+deltaOptions :: EPOptions Identity ()+deltaOptions = epOptions (\_ -> return ()) (\_ -> return ())++data EPWriter a = EPWriter+              { output :: !a }++instance Monoid w => Semigroup (EPWriter w) where+  (EPWriter a) <> (EPWriter b) = EPWriter (a <> b)++instance Monoid w => Monoid (EPWriter w) where+  mempty = EPWriter mempty++data EPState = EPState+             { uAnchorSpan :: !RealSrcSpan -- ^ in pre-changed AST+                                          -- reference frame, from+                                          -- Annotation+             , uExtraDP :: !(Maybe EpaLocation) -- ^ Used to anchor a+                                                -- list+             , uExtraDPReturn :: !(Maybe (SrcSpan, DeltaPos))+                  -- ^ Used to return Delta version of uExtraDP+             , pAcceptSpan :: Bool -- ^ When we have processed an+                                   -- entry of EpaDelta, accept the+                                   -- next `EpaSpan` start as the+                                   -- current output position. i.e. do+                                   -- not advance epPos. Achieved by+                                   -- setting dPriorEndPosition to the+                                   -- end of the span.++             -- Print phase+             , epPos        :: !Pos -- ^ Current output position+             , pMarkLayout  :: !Bool+             , pLHS   :: !LayoutStartCol++             -- Delta phase+             , dPriorEndPosition :: !Pos -- ^ End of Position reached+                                         -- when processing the+                                         -- preceding element+             , dMarkLayout :: !Bool+             , dLHS        :: !LayoutStartCol++             -- Shared+             , epComments :: ![Comment]+             , epCommentsApplied :: ![[Comment]]+             , epEof :: !(Maybe (RealSrcSpan, RealSrcSpan))+             }++-- ---------------------------------------------------------------------++-- AZ:TODO: this can just be a function :: (EpAnn a) -> Entry+class HasEntry ast where+  fromAnn :: ast -> Entry++class HasTrailing a where+  trailing :: a -> [TrailingAnn]+  setTrailing :: a -> [TrailingAnn] -> a++setAnchorEpa :: (HasTrailing an)+             => EpAnn an -> EpaLocation -> [TrailingAnn] -> EpAnnComments -> EpAnn an+setAnchorEpa (EpAnn _ an _) anc ts cs = EpAnn anc (setTrailing an ts)          cs++setAnchorHsModule :: HsModule GhcPs -> EpaLocation -> EpAnnComments -> HsModule GhcPs+setAnchorHsModule hsmod anc cs = hsmod { hsmodExt = (hsmodExt hsmod) {hsmodAnn = an'} }+  where+    anc' = anc+    an' = setAnchorEpa (hsmodAnn $ hsmodExt hsmod) anc' [] cs++setAnchorAn :: (HasTrailing an)+             => LocatedAn an a -> EpaLocation -> [TrailingAnn] -> EpAnnComments -> LocatedAn an a+setAnchorAn (L (EpAnn _ an _) a) anc ts cs = (L (EpAnn anc (setTrailing an ts) cs) a)+     -- `debug` ("setAnchorAn: anc=" ++ showAst anc)++setAnchorEpaL :: EpAnn (AnnList l) -> EpaLocation -> [TrailingAnn] -> EpAnnComments -> EpAnn (AnnList l)+setAnchorEpaL (EpAnn _ an _) anc ts cs = EpAnn anc (setTrailing (an {al_anchor = Nothing}) ts) cs++-- ---------------------------------------------------------------------++-- | Key entry point.  Switches to an independent AST element with its+-- own annotation, calculating new offsets, etc+markAnnotated :: (Monad m, Monoid w, ExactPrint a) => a -> EP w m a+markAnnotated a = enterAnn (getAnnotationEntry a) a++-- | For HsModule, because we do not have a proper SrcSpan, we must+-- indicate to flush trailing comments when done.+data FlushComments = FlushComments+                   | NoFlushComments+                   deriving (Eq, Show)++-- | For GenLocated SrcSpan, we construct an entry location but cannot update it.+data CanUpdateAnchor = CanUpdateAnchor+                     | CanUpdateAnchorOnly+                     | NoCanUpdateAnchor+                   deriving (Eq, Show, Data)++data Entry = Entry EpaLocation [TrailingAnn] EpAnnComments FlushComments CanUpdateAnchor+           | NoEntryVal++-- | For flagging whether to capture comments in an EpaDelta or not+data CaptureComments = CaptureComments+                     | NoCaptureComments++mkEntry :: EpaLocation -> [TrailingAnn] -> EpAnnComments -> Entry+mkEntry anc ts cs = Entry anc ts cs NoFlushComments CanUpdateAnchor++instance (HasTrailing a) => HasEntry (EpAnn a) where+  fromAnn (EpAnn anc a cs) = mkEntry anc (trailing a) cs++-- ---------------------------------------------------------------------++instance HasTrailing NoEpAnns where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing EpaLocation where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing EpAnnSumPat where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing (AnnList a) where+  trailing a = al_trailing a+  setTrailing a ts = a { al_trailing = ts }++instance HasTrailing AnnListItem where+  trailing a = lann_trailing a+  setTrailing a ts = a { lann_trailing = ts }++instance HasTrailing AnnPragma where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing AnnContext where+  trailing (AnnContext ma _opens _closes)+    = case ma of+      Just r -> [AddDarrowAnn r]+      _ -> []++  setTrailing a [AddDarrowAnn r] = a{ac_darrow = Just r}+  setTrailing a [] = a{ac_darrow = Nothing}+  setTrailing a ts = error $ "Cannot setTrailing " ++ showAst ts ++ " for " ++ showAst a+++instance HasTrailing AnnParen where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing AnnsIf where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing EpAnnHsCase where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing AnnFieldLabel where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing AnnProjection where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing AnnExplicitSum where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing (Maybe EpAnnUnboundVar) where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing GrhsAnn where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing AnnSig where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing HsRuleAnn where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing EpAnnImportDecl where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing AnnsModule where+  -- Report none, as all are used internally+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing NameAnn where+  trailing a = nann_trailing a+  setTrailing a ts = a { nann_trailing = ts }++instance HasTrailing Bool where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing (TokForall, TokRarrow) where+  trailing _ = []+  setTrailing a _ = a++instance HasTrailing (TokForall, EpToken ".") where+  trailing _ = []+  setTrailing a _ = a++-- ---------------------------------------------------------------------++fromAnn' :: (HasEntry a) => a -> Entry+fromAnn' an = case fromAnn an of+  NoEntryVal -> NoEntryVal+  Entry a ts c _ u -> Entry a ts c FlushComments u++-- ---------------------------------------------------------------------++astId :: (Typeable a) => a -> String+astId a = show (typeOf a)++cua :: (Monad m, Monoid w) => CanUpdateAnchor -> EP w m [a] -> EP w m [a]+cua CanUpdateAnchor f = f+cua CanUpdateAnchorOnly _ = return []+cua NoCanUpdateAnchor _ = return []++-- | "Enter" an annotation, by using the associated 'anchor' field as+-- the new reference point for calculating all DeltaPos positions.+-- This is the heart of the exact printing process.+--+-- This is combination of the ghc=exactprint Delta.withAST and+-- Print.exactPC functions and effectively does the delta processing+-- immediately followed by the print processing.  JIT ghc-exactprint.+enterAnn :: (Monad m, Monoid w, ExactPrint a) => Entry -> a -> EP w m a+enterAnn NoEntryVal a = do+  p <- getPosP+  debugM $ "enterAnn:starting:NO ANN:(p,a) =" ++ show (p, astId a)+  r <- exact a+  debugM $ "enterAnn:done:NO ANN:p =" ++ show (p, astId a)+  return r+enterAnn !(Entry anchor' trailing_anns cs flush canUpdateAnchor) a = do+  acceptSpan <- getAcceptSpan+  setAcceptSpan False+  case anchor' of+    EpaDelta _ _ _ -> setAcceptSpan True+    _              -> return ()+  p <- getPosP+  pe0 <- getPriorEndD+  debugM $ "enterAnn:starting:(anchor',p,pe,a) =" ++ show (showAst anchor', p, pe0, astId a)+  prevAnchor <- getAnchorU+  let curAnchor = case anchor' of+        EpaSpan (RealSrcSpan r _) -> r+        _ -> prevAnchor+  debugM $ "enterAnn:(curAnchor):=" ++ show (rs2range curAnchor)+  case canUpdateAnchor of+    CanUpdateAnchor -> pushAppliedComments+    _ -> return ()+  case anchor' of+    EpaDelta _ _ dcs -> do+      debugM $ "enterAnn:Delta:Flushing comments"+      flushComments []+      debugM $ "enterAnn:Delta:Printing prior comments:" ++ showGhc (priorComments cs)+      mapM_ printOneComment (concatMap tokComment $ priorComments cs)+      debugM $ "enterAnn:Delta:Printing EpaDelta comments:" ++ showGhc dcs+      mapM_ printOneComment (concatMap tokComment dcs)+    _ -> do+      debugM $ "enterAnn:Adding comments:" ++ showGhc (priorComments cs)+      addCommentsA (priorComments cs)+  debugM $ "enterAnn:Added comments"+  printCommentsBefore curAnchor+  priorCs <- cua canUpdateAnchor takeAppliedComments -- no pop+  -- -------------------------+  case anchor' of+    EpaDelta _ dp _ -> do+      debugM $ "enterAnn: EpaDelta:" ++ show dp+      -- Set the original anchor as prior end, so the rest of this AST+      -- fragment has a reference+      setPriorEndNoLayoutD (ss2pos curAnchor)+    _ -> do+      if acceptSpan+        then setPriorEndNoLayoutD (ss2pos curAnchor)+        else return ()++  -- -------------------------+  if ((fst $ fst $ rs2range curAnchor) >= 0)+    then+      setAnchorU curAnchor+    else+      debugM $ "enterAnn: not calling setAnchorU for : " ++ show (rs2range curAnchor)+  -- -------------------------------------------------------------------+  -- Make sure the running dPriorEndPosition gets updated according to+  -- the change in the current anchor.++  -- Compute the distance from dPriorEndPosition to the start of the new span.++  -- While processing in the context of the prior anchor, we choose to+  -- enter a new Anchor, which has a defined position relative to the+  -- prior anchor, even if we do not actively output anything at that+  -- point.+  -- Is this edp?++  -- -------------------------------------------------------------------+  -- The first part corresponds to the delta phase, so should only use+  -- delta phase variables -----------------------------------+  -- Calculate offset required to get to the start of the SrcSPan+  !off <- getLayoutOffsetD+  let spanStart = ss2pos curAnchor+  priorEndAfterComments <- getPriorEndD+  let edp' = adjustDeltaForOffset+               -- Use the propagated offset if one is set+               -- Note that we need to use the new offset if it has+               -- changed.+               off (ss2delta priorEndAfterComments curAnchor)+  debugM $ "enterAnn: (edp',off,priorEndAfterComments,curAnchor):" ++ show (edp',off,priorEndAfterComments,rs2range curAnchor)+  let edp'' = case anchor' of+        EpaDelta _ dp _ -> dp+        _ -> edp'+  -- ---------------------------------------------+  med <- getExtraDP+  setExtraDP Nothing+  let (edp, medr) = case med of+        Nothing -> (edp'', Nothing)+        Just (EpaDelta _ dp _) -> (dp, Nothing)+                   -- Replace original with desired one. Allows all+                   -- list entry values to be DP (1,0)+        Just (EpaSpan ss@(RealSrcSpan r _)) -> (dp, Just (ss, dp))+          where+            dp = adjustDeltaForOffset+                   off (ss2delta priorEndAfterComments r)+        Just (EpaSpan (UnhelpfulSpan r)) -> panic $ "enterAnn: UnhelpfulSpan:" ++ show r+  when (isJust med) $ debugM $ "enterAnn:(med,edp)=" ++ showAst (med,edp)+  when (isJust medr) $ setExtraDPReturn medr+  -- ---------------------------------------------+  -- Preparation complete, perform the action+  when (priorEndAfterComments < spanStart) (do+    debugM $ "enterAnn.dPriorEndPosition:spanStart=" ++ show spanStart+    modify (\s -> s { dPriorEndPosition    = spanStart } ))++  debugM $ "enterAnn: (anchor', curAnchor):" ++ show (anchor', rs2range curAnchor)+  -- debugM $ "enterAnn: (dLHS,spanStart,pec,edp)=" ++ show (off,spanStart,priorEndAfterComments,edp)+  p0 <- getPosP+  d <- getPriorEndD+  debugM $ "enterAnn: (posp, posd)=" ++ show (p0,d)++  -- end of delta phase processing+  -- -------------------------------------------------------------------+  -- start of print phase processing++  advance edp+  debugM $ "enterAnn:exact a starting:" ++ show (showAst anchor')+  a' <- exact a+  debugM $ "enterAnn:exact a done:" ++ show (showAst anchor')++  -- Core recursive exactprint done, start end of Entry processing++  when (flush == FlushComments) $ do+    debugM $ "flushing comments in enterAnn:" ++ showAst (cs, getFollowingComments cs)+    flushComments (getFollowingComments cs)+    debugM $ "flushing comments in enterAnn done"++  !eof <- getEofPos+  case eof of+    Nothing -> return ()+    Just (pos, prior) -> do+       let dp = if pos == prior+             then (DifferentLine 1 0)+             else origDelta pos prior+       debugM $ "EOF:(pos,posEnd,prior,dp) =" ++ showGhc (ss2pos pos, ss2posEnd pos, ss2pos prior, dp)+       printStringAtLsDelta dp ""+       setEofPos Nothing -- Only do this once++  -- Deal with exit from the current anchor+  when (flush == NoFlushComments) $ do+    printCommentsIn curAnchor -- Make sure all comments in the span are printed++  p1 <- getPosP+  pe1 <- getPriorEndD+  debugM $ "enterAnn:done:(anchor,p,pe,a) =" ++ show (showAst anchor', p1, pe1, astId a')++  case anchor' of+    EpaDelta _ _ _ -> return ()+    EpaSpan (RealSrcSpan rss _) -> do+      setAcceptSpan False+      setPriorEndD (snd $ rs2range rss)+    EpaSpan _ -> return ()++  -- Outside the anchor, mark any trailing+  postCs <- cua canUpdateAnchor takeAppliedCommentsPop+  following <- if (flush == NoFlushComments)+          then do+              let (before, after) = splitAfterTrailingAnns trailing_anns+                                                           (getFollowingComments cs)+              addCommentsA before+              return after+           else return []+  !trailing' <- markTrailing trailing_anns+  -- mapM_ printOneComment (concatMap tokComment $ following)+  addCommentsA following++  -- Update original anchor, comments based on the printing process+  -- TODO:AZ: probably need to put something appropriate in instead of noSrcSpan+  let newAnchor = case anchor' of+          EpaSpan s -> EpaDelta s         edp []+          _         -> EpaDelta noSrcSpan edp []+  let r = case canUpdateAnchor of+            CanUpdateAnchor -> setAnnotationAnchor a' newAnchor trailing' (mkEpaComments priorCs postCs)+            CanUpdateAnchorOnly -> setAnnotationAnchor a' newAnchor [] emptyComments+            NoCanUpdateAnchor -> a'+  return r++-- ---------------------------------------------------------------------++-- | Split the span following comments into ones that occur prior to+-- the last trailing ann, and ones after.+splitAfterTrailingAnns :: [TrailingAnn] -> [LEpaComment] -> ([LEpaComment], [LEpaComment])+splitAfterTrailingAnns [] cs = ([], cs)+splitAfterTrailingAnns tas cs = (before, after)+  where+    trailing_loc ta = case ta_location ta of+        EpaSpan (RealSrcSpan s _) -> [s]+        _ -> []+    (before, after) = case reverse (concatMap trailing_loc tas) of+        [] -> ([],cs)+        (s:_) -> (b,a)+          where+            s_pos = ss2pos s+            (b,a) = break (\(L ll _) -> (ss2pos $ epaLocationRealSrcSpan ll) > s_pos)+                          cs++-- ---------------------------------------------------------------------++addCommentsA :: (Monad m, Monoid w) => [LEpaComment] -> EP w m ()+addCommentsA csNew = addComments False (concatMap tokComment csNew)++{-+TODO: When we addComments, some may have an anchor that is no longer+valid, as it has been moved and has an anchor_op.++Does an Anchor even make sense for a comment, perhaps it should be an+EpaLocation?++How do we sort them? do we assign a location based on when we add them+to the list, based on the current output pos?  Except the offset is a+delta compared to a reference location.  Need to nail the concept of+the reference location.++By definition it is the current anchor, so work against that. And that+also means that the first entry comment that has moved should not have+a line offset.+-}+addComments :: (Monad m, Monoid w) => Bool -> [Comment] -> EP w m ()+addComments sortNeeded csNew = do+  debugM $ "addComments:csNew" ++ show csNew+  cs <- getUnallocatedComments+  debugM $ "addComments:cs" ++ show cs+  -- We can only sort the comments if we are in the first phase,+  -- where all comments have locations. If any have EpaDelta the+  -- sort will fail, so we do not try.+  if sortNeeded && all noDelta (csNew ++ cs)+    then putUnallocatedComments (sort (cs ++ csNew))+    else putUnallocatedComments (cs ++ csNew)++noDelta :: Comment -> Bool+noDelta c = case commentLoc c of+    EpaSpan _ -> True+    _ -> False++-- ---------------------------------------------------------------------++-- | Just before we print out the EOF comments, flush the remaining+-- ones in the state.+flushComments :: (Monad m, Monoid w) => [LEpaComment] -> EP w m ()+flushComments !trailing_anns = do+  debugM $ "flushComments entered: " ++ showAst trailing_anns+  addCommentsA trailing_anns+  debugM $ "flushComments after addCommentsA"+  cs <- getUnallocatedComments+  debugM $ "flushComments: got cs"+  debugM $ "flushing comments starting: cs" ++ showAst cs+  mapM_ printOneComment cs+  putUnallocatedComments []+  debugM $ "flushing comments done"++-- ---------------------------------------------------------------------++epTokensToComments :: (Monad m, Monoid w)+  => String -> [EpToken tok] -> EP w m ()+epTokensToComments kw toks+  = addComments True (concatMap (\tok ->+                                   case tok of+                                     EpTok ss -> [mkKWComment kw (epaToNoCommentsLocation ss)]+                                     NoEpTok -> []) toks)++-- ---------------------------------------------------------------------++-- Temporary function to simply reproduce the "normal" pretty printer output+withPpr :: (Monad m, Monoid w, Outputable a) => a -> EP w m a+withPpr a = do+  ss <- getAnchorU+  debugM $ "withPpr: ss=" ++ show ss+  printStringAtRs' ss (showPprUnsafe a)+  return a++-- ---------------------------------------------------------------------++-- | An AST fragment with an annotation must be able to return the+-- requirements for nesting another one, captured in an 'Entry', and+-- to be able to use the rest of the exactprint machinery to print the+-- element.  In the analogy to Outputable, 'exact' plays the role of+-- 'ppr'.+class (Typeable a) => ExactPrint a where+  getAnnotationEntry :: a -> Entry+  setAnnotationAnchor :: a -> EpaLocation -> [TrailingAnn] -> EpAnnComments -> a+  exact :: (Monad m, Monoid w) => a -> EP w m a++-- ---------------------------------------------------------------------+-- Start of utility functions+-- ---------------------------------------------------------------------++printSourceText :: (Monad m, Monoid w) => SourceText -> String -> EP w m ()+printSourceText (NoSourceText) txt   =  printStringAdvance txt >> return ()+printSourceText (SourceText   txt) _ =  printStringAdvance (unpackFS txt) >> return ()++printSourceTextAA :: (Monad m, Monoid w) => SourceText -> String -> EP w m ()+printSourceTextAA (NoSourceText) txt   = printStringAdvanceA  txt >> return ()+printSourceTextAA (SourceText   txt) _ = printStringAdvanceA  (unpackFS txt) >> return ()++-- ---------------------------------------------------------------------++printStringAtRs :: (Monad m, Monoid w) => RealSrcSpan -> String -> EP w m EpaLocation+printStringAtRs pa str = printStringAtRsC CaptureComments pa str++printStringAtRsC :: (Monad m, Monoid w)+  => CaptureComments -> RealSrcSpan -> String -> EP w m EpaLocation+printStringAtRsC capture pa str = do+  debugM $ "printStringAtRsC: pa=" ++ showAst pa+  printCommentsBefore pa+  pe <- getPriorEndD+  debugM $ "printStringAtRsC:pe=" ++ show pe+  let p = ss2delta pe pa+  p' <- adjustDeltaForOffsetM p+  debugM $ "printStringAtRsC:(p,p')=" ++ show (p,p')+  printStringAtLsDelta p' str+  setPriorEndASTD pa+  cs' <- case capture of+    CaptureComments -> takeAppliedComments+    NoCaptureComments -> return []+  debugM $ "printStringAtRsC:cs'=" ++ show cs'+  debugM $ "printStringAtRsC:p'=" ++ showAst p'+  debugM $ "printStringAtRsC: (EpaDelta p' [])=" ++ showAst (EpaDelta noSrcSpan p' NoComments)+  debugM $ "printStringAtRsC: (EpaDelta p' (map comment2LEpaComment cs'))=" ++ showAst (EpaDelta noSrcSpan p' (map comment2LEpaComment cs'))+  return (EpaDelta (RealSrcSpan pa Strict.Nothing) p' (map comment2LEpaComment cs'))++printStringAtRs' :: (Monad m, Monoid w) => RealSrcSpan -> String -> EP w m ()+printStringAtRs' pa str = printStringAtRsC NoCaptureComments pa str >> return ()++-- ---------------------------------------------------------------------++printStringAtMLoc' :: (Monad m, Monoid w)+  => Maybe EpaLocation -> String -> EP w m (Maybe EpaLocation)+printStringAtMLoc' (Just aa) s = Just <$> printStringAtAA aa s+printStringAtMLoc' Nothing s = do+  printStringAtLsDelta (SameLine 1) s+  return (Just (EpaDelta noSrcSpan (SameLine 1) []))++printStringAtMLocL :: (Monad m, Monoid w)+  => EpAnn a -> Lens a (Maybe EpaLocation) -> String -> EP w m (EpAnn a)+printStringAtMLocL (EpAnn anc an cs) l s = do+  r <- go (view l an) s+  return (EpAnn anc (set l r an) cs)+  where+    go (Just aa) str = Just <$> printStringAtAA aa str+    go Nothing str = do+      printStringAtLsDelta (SameLine 1) str+      return (Just (EpaDelta noSrcSpan (SameLine 1) []))++printStringAdvanceA :: (Monad m, Monoid w) => String -> EP w m ()+printStringAdvanceA str = printStringAtAA (EpaDelta noSrcSpan (SameLine 0) []) str >> return ()++printStringAtAA :: (Monad m, Monoid w) => EpaLocation -> String -> EP w m EpaLocation+printStringAtAA el str = printStringAtAAC CaptureComments el str++printStringAtNC :: (Monad m, Monoid w) => NoCommentsLocation -> String -> EP w m NoCommentsLocation+printStringAtNC el str = do+  el' <- printStringAtAAC NoCaptureComments (noCommentsToEpaLocation el) str+  return (epaToNoCommentsLocation el')++printStringAtAAC :: (Monad m, Monoid w)+  => CaptureComments -> EpaLocation -> String -> EP w m EpaLocation+printStringAtAAC capture (EpaSpan (RealSrcSpan r _)) s = printStringAtRsC capture r s+printStringAtAAC _capture (EpaSpan ss@(UnhelpfulSpan _)) _s = error $ "printStringAtAAC:ss=" ++ show ss+printStringAtAAC capture (EpaDelta ss d cs) s = do+  mapM_ printOneComment $ concatMap tokComment cs+  pe1 <- getPriorEndD+  p1 <- getPosP+  printStringAtLsDelta d s+  p2 <- getPosP+  pe2 <- getPriorEndD+  debugM $ "printStringAtAA:(pe1,pe2,p1,p2)=" ++ show (pe1,pe2,p1,p2)+  setPriorEndASTPD (pe1,pe2)+  cs' <- case capture of+    CaptureComments -> takeAppliedComments+    NoCaptureComments -> return []+  debugM $ "printStringAtAA:(pe1,pe2,p1,p2,cs')=" ++ show (pe1,pe2,p1,p2,cs')+  return (EpaDelta ss d (map comment2LEpaComment cs'))++-- ---------------------------------------------------------------------++markExternalSourceTextE :: (Monad m, Monoid w) => EpaLocation -> SourceText -> String -> EP w m EpaLocation+markExternalSourceTextE l NoSourceText txt   = printStringAtAA l txt+markExternalSourceTextE l (SourceText txt) _ = printStringAtAA l (unpackFS txt)++-- ---------------------------------------------------------------------++markLensBracketsO :: (Monad m, Monoid w)+  => EpAnn a -> Lens a AnnListBrackets -> EP w m (EpAnn a)+markLensBracketsO epann l = markLensBracketsO' epann (lepa . l)++markLensBracketsO' :: (Monad m, Monoid w)+  => a -> Lens a AnnListBrackets -> EP w m a+markLensBracketsO' a l =+  case view l a of+    ListParens o c -> do+      o' <- markEpToken o+      return (set l (ListParens o' c) a)+    ListBraces o c -> do+      o' <- markEpToken o+      return (set l (ListBraces o' c) a)+    ListSquare o c -> do+      o' <- markEpToken o+      return (set l (ListSquare o' c) a)+    ListBanana o c -> do+      o' <- markEpUniToken o+      return (set l (ListBanana o' c) a)+    ListNone -> return (set l ListNone a)++markLensBracketsC :: (Monad m, Monoid w)+  => EpAnn a -> Lens a AnnListBrackets -> EP w m (EpAnn a)+markLensBracketsC epann l = markLensBracketsC' epann (lepa . l)++markLensBracketsC' :: (Monad m, Monoid w)+  => a -> Lens a AnnListBrackets -> EP w m a+markLensBracketsC' a l =+  case view l a of+    ListParens o c -> do+      c' <- markEpToken c+      return (set l (ListParens o c') a)+    ListBraces o c -> do+      c' <- markEpToken c+      return (set l (ListBraces o c') a)+    ListSquare o c -> do+      c' <- markEpToken c+      return (set l (ListSquare o c') a)+    ListBanana o c -> do+      c' <- markEpUniToken c+      return (set l (ListBanana o c') a)+    ListNone -> return (set l ListNone a)+-- -------------------------------------++-- markEpTokenM :: forall m w tok . (Monad m, Monoid w, KnownSymbol tok)+--   => Maybe (EpToken tok) -> EP w m (Maybe (EpToken tok))++markEpToken :: forall m w tok . (Monad m, Monoid w, KnownSymbol tok)+  => EpToken tok -> EP w m (EpToken tok)+markEpToken NoEpTok = return NoEpTok+markEpToken (EpTok aa) = do+  aa' <- printStringAtAA aa (symbolVal (Proxy @tok))+  return (EpTok aa')++markEpToken1 :: forall m w tok . (Monad m, Monoid w, KnownSymbol tok)+  => [EpToken tok] -> EP w m [EpToken tok]+markEpToken1 [] = return []+markEpToken1 (h:t) = do+  h' <- markEpToken h+  return (h':t)++markEpUniToken :: forall m w tok utok . (Monad m, Monoid w, KnownSymbol tok, KnownSymbol utok)+  => EpUniToken tok utok -> EP w m (EpUniToken tok utok)+markEpUniToken NoEpUniTok = return NoEpUniTok+markEpUniToken (EpUniTok aa isUnicode)  = do+  aa' <- case isUnicode of+    NormalSyntax  -> printStringAtAA aa (symbolVal (Proxy @tok))+    UnicodeSyntax -> printStringAtAA aa (symbolVal (Proxy @utok))+  return (EpUniTok aa' isUnicode)++-- ---------------------------------------------------------------------++markArrow :: (Monad m, Monoid w, ExactPrint a) => HsArrowOf a GhcPs -> EP w m (HsArrowOf a GhcPs)+markArrow (HsUnrestrictedArrow arr) = do+  arr' <- markEpUniToken arr+  return (HsUnrestrictedArrow arr')+markArrow (HsLinearArrow (EpPct1 pct1 arr)) = do+  pct1' <- markEpToken pct1+  arr' <- markEpUniToken arr+  return (HsLinearArrow (EpPct1 pct1' arr'))+markArrow (HsLinearArrow (EpLolly arr)) = do+  arr' <- markEpToken arr+  return (HsLinearArrow (EpLolly arr'))+markArrow (HsExplicitMult (pct, arr) t) = do+  pct' <- markEpToken pct+  t' <- markAnnotated t+  arr' <- markEpUniToken arr+  return (HsExplicitMult (pct', arr') t')++-- ---------------------------------------------------------------------++markAnnOpen' :: (Monad m, Monoid w)+  => Maybe EpaLocation -> SourceText -> String -> EP w m (Maybe EpaLocation)+markAnnOpen' ms NoSourceText txt   = printStringAtMLoc' ms txt+markAnnOpen' ms (SourceText txt) _ = printStringAtMLoc' ms $ unpackFS txt++markAnnOpen'' :: (Monad m, Monoid w)+  => EpaLocation -> SourceText -> String -> EP w m EpaLocation+markAnnOpen'' el NoSourceText txt   = printStringAtAA el txt+markAnnOpen'' el (SourceText txt) _ = printStringAtAA el $ unpackFS txt++-- ---------------------------------------------------------------------++markOpeningParen, markClosingParen :: (Monad m, Monoid w) => AnnParen -> EP w m AnnParen+markOpeningParen an = markParenO an+markClosingParen an = markParenC an++markParenO :: (Monad m, Monoid w) => AnnParen -> EP w m AnnParen+markParenO (AnnParens o c) = do+  o' <- markEpToken o+  return (AnnParens o' c)+markParenO (AnnParensHash o c) = do+  o' <- markEpToken o+  return (AnnParensHash o' c)+markParenO (AnnParensSquare o c) = do+  o' <- markEpToken o+  return (AnnParensSquare o' c)++markParenC :: (Monad m, Monoid w) => AnnParen -> EP w m AnnParen+markParenC (AnnParens o c) = do+  c' <- markEpToken c+  return (AnnParens o c')+markParenC (AnnParensHash o c) = do+  c' <- markEpToken c+  return (AnnParensHash o c')+markParenC (AnnParensSquare o c) = do+  c' <- markEpToken c+  return (AnnParensSquare o c')++-- ---------------------------------------------------------------------+-- Bare bones Optics+-- Base on From https://hackage.haskell.org/package/lens-tutorial-1.0.3/docs/Control-Lens-Tutorial.html++type Lens    a b = forall f . Functor f => (b -> f        b) -> (a -> f        a)+type Getting a b =                         (b -> Const  b b) -> (a -> Const b  a)+type ASetter a b =                         (b -> Identity b) -> (a -> Identity a)++view :: MonadReader s m => Getting s a -> m a+view l = Reader.asks (getConst . l Const)+{-# INLINE view #-}++over :: ASetter a b -> (b -> b) -> (a -> a)+over l f = runIdentity . l (Identity . f)+{-# INLINE over #-}++set  :: Lens a b -> b -> a -> a+set lens b = over lens (\_ -> b)+{-# INLINE set #-}++{-+Question: How do I combine lenses?++Answer: You compose them, using function composition (Yes, really!)++You can think of the function composition operator as having this type:++(.) :: Lens' a b -> Lens' b c -> Lens' a c+-}++-- ---------------------------------------------------------------------+-- Lenses++-- data EpAnn ann+--   = EpAnn { entry   :: !Anchor+--            , anns     :: !ann+--            , comments :: !EpAnnComments+--            }++lepa :: Lens (EpAnn a) a+lepa k epAnn = fmap (\newAnns -> epAnn { anns = newAnns })+                    (k (anns epAnn))++-- data AnnsModule+--   = AnnsModule {+--     am_sig :: Maybe (EpToken "signature"),+--     am_mod :: Maybe (EpToken "module"),+--     am_where :: Maybe (EpToken "where"),+--     am_decls :: [TrailingAnn],+--     am_cs    :: [LEpaComment],+--     am_eof   :: Maybe (RealSrcSpan, RealSrcSpan)+--     } deriving (Data, Eq)++lam_mod :: Lens AnnsModule (EpToken "module")+lam_mod k annsModule = fmap (\newAnns -> annsModule { am_mod = newAnns })+                            (k (am_mod annsModule))++lam_where :: Lens AnnsModule (EpToken "where")+lam_where k annsModule = fmap (\newAnns -> annsModule { am_where = newAnns })+                              (k (am_where annsModule))++-- lam_decls :: Lens AnnsModule AnnList+-- lam_decls k annsModule = fmap (\newAnns -> annsModule { am_decls = newAnns })+--                               (k (am_decls annsModule))+++-- data EpAnnImportDecl = EpAnnImportDecl+--   { importDeclAnnImport    :: EpToken "import" -- ^ The location of the @import@ keyword+--   , importDeclAnnPragma    :: Maybe (EpaLocation, EpToken "#-}") -- ^ The locations of @{-# SOURCE@ and @#-}@ respectively+--   , importDeclAnnSafe      :: Maybe (EpToken "safe") -- ^ The location of the @safe@ keyword+--   , importDeclAnnQualified :: Maybe (EpToken "qualified") -- ^ The location of the @qualified@ keyword+--   , importDeclAnnPackage   :: Maybe EpaLocation -- ^ The location of the package name (when using @-XPackageImports@)+--   , importDeclAnnAs        :: Maybe (EpToken "as") -- ^ The location of the @as@ keyword+--   } deriving (Data)++limportDeclAnnImport :: Lens EpAnnImportDecl (EpToken "import")+limportDeclAnnImport k annImp = fmap (\new -> annImp { importDeclAnnImport = new })+                                     (k (importDeclAnnImport annImp))++-- limportDeclAnnPragma :: Lens EpAnnImportDecl (Maybe (EpaLocation, EpaLocation))+-- limportDeclAnnPragma k annImp = fmap (\new -> annImp { importDeclAnnPragma = new })+--                                      (k (importDeclAnnPragma annImp))++limportDeclAnnSafe :: Lens EpAnnImportDecl (Maybe (EpToken "safe"))+limportDeclAnnSafe k annImp = fmap (\new -> annImp { importDeclAnnSafe = new })+                                     (k (importDeclAnnSafe annImp))++limportDeclAnnQualified :: Lens EpAnnImportDecl (Maybe (EpToken "qualified"))+limportDeclAnnQualified k annImp = fmap (\new -> annImp { importDeclAnnQualified = new })+                                     (k (importDeclAnnQualified annImp))++limportDeclAnnPackage :: Lens EpAnnImportDecl (Maybe EpaLocation)+limportDeclAnnPackage k annImp = fmap (\new -> annImp { importDeclAnnPackage = new })+                                     (k (importDeclAnnPackage annImp))++-- limportDeclAnnAs :: Lens EpAnnImportDecl (Maybe EpaLocation)+-- limportDeclAnnAs k annImp = fmap (\new -> annImp { importDeclAnnAs = new })+--                                      (k (importDeclAnnAs annImp))++-- -------------------------------------++-- data AnnList+--   = AnnList {+--       al_anchor    :: Maybe Anchor, -- ^ start point of a list having layout+--       al_brackets  :: !AnnListBrackets,+--       al_semis     :: [EpToken ";"], -- decls+--       al_rest      :: !a,+--       al_trailing  :: [TrailingAnn] -- ^ items appearing after the+--                                     -- list, such as '=>' for a+--                                     -- context+--       } deriving (Data,Eq)++lal_brackets :: Lens (AnnList l) AnnListBrackets+lal_brackets k parent = fmap (\new -> parent { al_brackets = new })+                           (k (al_brackets parent))++lal_semis :: Lens (AnnList l) [EpToken ";"]+lal_semis k parent = fmap (\new -> parent { al_semis = new })+                           (k (al_semis parent))++lal_rest :: Lens (AnnList l) l+lal_rest k parent = fmap (\new -> parent { al_rest = new })+                           (k (al_rest parent))++-- -------------------------------------++lfst :: Lens (a,b) a+lfst k parent = fmap (\new -> (new, snd parent))+                     (k (fst parent))++lsnd :: Lens (b,a) a+lsnd k parent = fmap (\new -> (fst parent, new))+                     (k (snd parent))++-- -------------------------------------+-- data AnnExplicitSum+--   = AnnExplicitSum {+--       aesOpen       :: EpaLocation,+--       aesBarsBefore :: [EpToken "|"],+--       aesBarsAfter  :: [EpToken "|"],+--       aesClose      :: EpaLocation+--       } deriving Data++laesOpen :: Lens AnnExplicitSum EpaLocation+laesOpen k parent = fmap (\new -> parent { aesOpen = new })+                         (k (aesOpen parent))++laesBarsBefore :: Lens AnnExplicitSum [EpToken "|"]+laesBarsBefore k parent = fmap (\new -> parent { aesBarsBefore = new })+                               (k (aesBarsBefore parent))++laesBarsAfter :: Lens AnnExplicitSum [EpToken "|"]+laesBarsAfter k parent = fmap (\new -> parent { aesBarsAfter = new })+                               (k (aesBarsAfter parent))++laesClose :: Lens AnnExplicitSum EpaLocation+laesClose k parent = fmap (\new -> parent { aesClose = new })+                               (k (aesClose parent))++-- -------------------------------------+-- data AnnFieldLabel+--   = AnnFieldLabel {+--       afDot :: Maybe (EpToken ".")+--       } deriving Data++lafDot :: Lens AnnFieldLabel (Maybe (EpToken "."))+lafDot k parent = fmap (\new -> parent { afDot = new })+                         (k (afDot parent))++-- -------------------------------------+-- data AnnProjection+--   = AnnProjection {+--       apOpen  :: EpToken "(",+--       apClose :: EpToken ")"+--       } deriving Data++lapOpen :: Lens AnnProjection (EpToken "(")+lapOpen k parent = fmap (\new -> parent { apOpen = new })+                         (k (apOpen parent))++lapClose :: Lens AnnProjection (EpToken ")")+lapClose k parent = fmap (\new -> parent { apClose = new })+                         (k (apClose parent))++-- -------------------------------------+-- data AnnsIf+--   = AnnsIf {+--       aiIf       :: EpToken "if",+--       aiThen     :: EpToken "then",+--       aiElse     :: EpToken "else",+--       aiThenSemi :: Maybe (EpToken ";"),+--       aiElseSemi :: Maybe (EpToken ";")+--       } deriving Data++laiIf :: Lens AnnsIf (EpToken "if")+laiIf k parent = fmap (\new -> parent { aiIf = new })+                      (k (aiIf parent))++laiThen :: Lens AnnsIf (EpToken "then")+laiThen k parent = fmap (\new -> parent { aiThen = new })+                        (k (aiThen parent))++laiElse :: Lens AnnsIf (EpToken "else")+laiElse k parent = fmap (\new -> parent { aiElse = new })+                        (k (aiElse parent))++laiThenSemi :: Lens AnnsIf (Maybe (EpToken ";"))+laiThenSemi k parent = fmap (\new -> parent { aiThenSemi = new })+                            (k (aiThenSemi parent))++laiElseSemi :: Lens AnnsIf (Maybe (EpToken ";"))+laiElseSemi k parent = fmap (\new -> parent { aiElseSemi = new })+                            (k (aiElseSemi parent))++-- -------------------------------------++-- data AnnParen+--   = AnnParen {+--       ap_adornment :: ParenType,+--       ap_open      :: EpaLocation,+--       ap_close     :: EpaLocation+--       } deriving (Data)++-- lap_open :: Lens AnnParen EpaLocation+-- lap_open k parent = fmap (\new -> parent { ap_open = new })+--                          (k (ap_open parent))++-- lap_close :: Lens AnnParen EpaLocation+-- lap_close k parent = fmap (\new -> parent { ap_close = new })+--                           (k (ap_close parent))++-- -------------------------------------+-- data EpAnnHsCase = EpAnnHsCase+--       { hsCaseAnnCase :: EpToken "case"+--       , hsCaseAnnOf   :: EpToken "of"+--       } deriving Data++lhsCaseAnnCase :: Lens EpAnnHsCase (EpToken "case")+lhsCaseAnnCase k parent = fmap (\new -> parent { hsCaseAnnCase = new })+                               (k (hsCaseAnnCase parent))++lhsCaseAnnOf :: Lens EpAnnHsCase (EpToken "of")+lhsCaseAnnOf k parent = fmap (\new -> parent { hsCaseAnnOf = new })+                               (k (hsCaseAnnOf parent))++-- ---------------------------------------------------------------------++-- data HsRuleAnn+--   = HsRuleAnn+--        { ra_tyanns :: Maybe (TokForall, EpToken ".")+--        , ra_tmanns :: Maybe (TokForall, EpToken ".")+--        , ra_equal  :: EpToken "="+--        , ra_rest :: ActivationAnn+--        } deriving (Data, Eq)++lra_tyanns :: Lens HsRuleAnn (Maybe (TokForall, EpToken "."))+lra_tyanns k parent = fmap (\new -> parent { ra_tyanns = new })+                               (k (ra_tyanns parent))++ff :: Maybe (a,b) -> (Maybe a,Maybe b)+ff Nothing = (Nothing, Nothing)+ff (Just (a,b)) = (Just a, Just b)+++gg :: (Maybe a,Maybe b) -> Maybe (a,b)+gg (Nothing, Nothing) = Nothing+gg (Just a, Just b) = Just (a,b)+gg _ = error "gg:expecting two Nothing or two Just"++lff :: Lens (Maybe (a,b)) (Maybe a,Maybe b)+lff k parent = fmap (\new -> gg new)+                    (k (ff parent))++-- (.) :: Lens' a b -> Lens' b c -> Lens' a c+lra_tyanns_fst :: Lens HsRuleAnn (Maybe TokForall)+lra_tyanns_fst = lra_tyanns . lff . lfst++lra_tyanns_snd :: Lens HsRuleAnn (Maybe (EpToken "."))+lra_tyanns_snd = lra_tyanns . lff . lsnd++lra_tmanns :: Lens HsRuleAnn (Maybe (TokForall, EpToken "."))+lra_tmanns k parent = fmap (\new -> parent { ra_tmanns = new })+                               (k (ra_tmanns parent))++lra_tmanns_fst :: Lens HsRuleAnn (Maybe TokForall)+lra_tmanns_fst = lra_tmanns . lff . lfst++lra_tmanns_snd :: Lens HsRuleAnn (Maybe (EpToken "."))+lra_tmanns_snd = lra_tmanns . lff . lsnd++lra_equal :: Lens HsRuleAnn (EpToken "=")+lra_equal k parent = fmap (\new -> parent { ra_equal = new })+                                (k (ra_equal parent))++lra_rest :: Lens HsRuleAnn ActivationAnn+lra_rest k parent = fmap (\new -> parent { ra_rest = new })+                                (k (ra_rest parent))+++-- ---------------------------------------------------------------------+-- data GrhsAnn+--   = GrhsAnn {+--       ga_vbar :: Maybe (EpToken "|"),+--       ga_sep  :: Either (EpToken "=") TokRarrow -- ^ Match separator location, `=` or `->`+--       } deriving (Data)++lga_vbar :: Lens GrhsAnn (Maybe (EpToken "|"))+lga_vbar k parent = fmap (\new -> parent { ga_vbar = new })+                                (k (ga_vbar parent))++lga_sep :: Lens GrhsAnn (Either (EpToken "=") TokRarrow)+lga_sep k parent = fmap (\new -> parent { ga_sep = new })+                                (k (ga_sep parent))++-- ---------------------------------------------------------------------+-- data EpAnnSumPat = EpAnnSumPat+--       { sumPatParens      :: (EpaLocation, EpaLocation)+--       , sumPatVbarsBefore :: [EpToken "|"]+--       , sumPatVbarsAfter  :: [EpToken "|"]+--       } deriving Data++lsumPatParens :: Lens EpAnnSumPat (EpaLocation, EpaLocation)+lsumPatParens k parent = fmap (\new -> parent { sumPatParens = new })+                              (k (sumPatParens parent))++lsumPatVbarsBefore :: Lens EpAnnSumPat [EpToken "|"]+lsumPatVbarsBefore k parent = fmap (\new -> parent { sumPatVbarsBefore = new })+                              (k (sumPatVbarsBefore parent))++lsumPatVbarsAfter :: Lens EpAnnSumPat [EpToken "|"]+lsumPatVbarsAfter k parent = fmap (\new -> parent { sumPatVbarsAfter = new })+                              (k (sumPatVbarsAfter parent))++-- ---------------------------------------------------------------------+-- data EpAnnLam = EpAnnLam+--       { epl_lambda :: EpToken "\\"      -- ^ Location of '\' keyword+--       , epl_case   :: Maybe EpaLocation -- ^ Location of 'case' or+--                                         -- 'cases' keyword, depending+--                                         -- on related 'HsLamVariant'.+--       } deriving Data++lepl_lambda :: Lens EpAnnLam (EpToken "\\")+lepl_lambda k parent = fmap (\new -> parent { epl_lambda = new })+                            (k (epl_lambda parent))++lepl_case :: Lens EpAnnLam (Maybe EpaLocation)+lepl_case k parent = fmap (\new -> parent { epl_case = new })+                          (k (epl_case parent))+++-- End of lenses+-- ---------------------------------------------------------------------++-- markLensKw' :: (Monad m, Monoid w)+--   => EpAnn a -> Lens a EpaLocation -> AnnKeywordId -> EP w m (EpAnn a)+-- markLensKw' (EpAnn anc a cs) l kw = do+--   loc <- markKwA kw (view l a)+--   return (EpAnn anc (set l loc a) cs)++-- markLensKw :: (Monad m, Monoid w)+--   => a -> Lens a EpaLocation -> AnnKeywordId -> EP w m a+-- markLensKw a l kw = do+--   loc <- markKwA kw (view l a)+--   return (set l loc a)+++-- markLensKwM :: (Monad m, Monoid w)+--   => EpAnn a -> Lens a (Maybe EpaLocation) -> AnnKeywordId -> EP w m (EpAnn a)+-- markLensKwM (EpAnn anc a cs) l kw = do+--   new <- go (view l a)+--   return (EpAnn anc (set l new a) cs)+--   where+--     go Nothing = return Nothing+--     go (Just s) = Just <$> markKwA kw s++-- markLensKwM' :: (Monad m, Monoid w)+--   => a -> Lens a (Maybe EpaLocation) -> AnnKeywordId -> EP w m a+-- markLensKwM' a l kw = do+--   loc <- mapM (markKwA kw) (view l a)+--   return (set l loc a)++markLensTok :: (Monad m, Monoid w, KnownSymbol sym)+  => EpAnn a -> Lens a (EpToken sym) -> EP w m (EpAnn a)+markLensTok (EpAnn anc a cs) l = do+  new <- markEpToken (view l a)+  return (EpAnn anc (set l new a) cs)++-- ---------------------------------------------------------------------++markLensFun' :: (Monad m, Monoid w)+  => EpAnn ann -> Lens ann t -> (t -> EP w m t) -> EP w m (EpAnn ann)+markLensFun' epann l f = markLensFun epann (lepa . l) f++markLensFun :: (Monad m, Monoid w)+  => ann -> Lens ann t -> (t -> EP w m t) -> EP w m ann+markLensFun a l f = do+  t' <- f (view l a)+  return (set l t' a)++-- -------------------------------------++markEpAnnAllLT :: (Monad m, Monoid w, KnownSymbol tok)+  => EpAnn ann -> Lens ann [EpToken tok] -> EP w m (EpAnn ann)+markEpAnnAllLT (EpAnn anc a cs) l = do+  anns <- mapM markEpToken (view l a)+  return (EpAnn anc (set l anns a) cs)++markEpAnnAllLT' :: (Monad m, Monoid w, KnownSymbol tok)+  => ann -> Lens ann [EpToken tok] -> EP w m ann+markEpAnnAllLT' a l = do+  anns <- mapM markEpToken (view l a)+  return (set l anns a)++markEpaLocationAll :: (Monad m, Monoid w)+  => [EpaLocation] -> String -> EP w m [EpaLocation]+markEpaLocationAll locs str = mapM (\l -> printStringAtAA l str) locs++-- | Print a keyword encoded in a 'TrailingAnn'+markKwT :: (Monad m, Monoid w) => TrailingAnn -> EP w m TrailingAnn+markKwT (AddSemiAnn tok)    = AddSemiAnn    <$> markEpToken tok+markKwT (AddCommaAnn tok)   = AddCommaAnn   <$> markEpToken tok+markKwT (AddVbarAnn tok)    = AddVbarAnn    <$> markEpToken tok+markKwT (AddDarrowAnn tok)  = AddDarrowAnn  <$> markEpUniToken tok++-- ---------------------------------------------------------------------++markAnnList :: (Monad m, Monoid w)+  => EpAnn (AnnList l) -> EP w m a -> EP w m (EpAnn (AnnList l), a)+markAnnList ann action = do+  markAnnListA ann $ \a -> do+    r <- action+    return (a,r)++markAnnList' :: (Monad m, Monoid w)+  => AnnList l -> EP w m a -> EP w m (AnnList l, a)+markAnnList' ann action = do+  markAnnListA' ann $ \a -> do+    r <- action+    return (a,r)++markAnnListA :: (Monad m, Monoid w)+  => EpAnn (AnnList l)+  -> (EpAnn (AnnList l) -> EP w m (EpAnn (AnnList l), a))+  -> EP w m (EpAnn (AnnList l), a)+markAnnListA an action = do+  an0 <- markLensBracketsO an lal_brackets+  an1 <- markEpAnnAllLT an0 lal_semis+  (an2, r) <- action an1+  an3 <- markLensBracketsC an2 lal_brackets+  return (an3, r)++markAnnListA' :: (Monad m, Monoid w)+  => AnnList l+  -> (AnnList l -> EP w m (AnnList l, a))+  -> EP w m (AnnList l , a)+markAnnListA' an action = do+  an0 <- markLensBracketsO' an lal_brackets+  an1 <- markEpAnnAllLT' an0 lal_semis+  (an2, r) <- action an1+  an3 <- markLensBracketsC' an2 lal_brackets+  return (an3, r)++-- ---------------------------------------------------------------------++printCommentsBefore :: (Monad m, Monoid w) => RealSrcSpan -> EP w m ()+printCommentsBefore ss = do+  cs <- commentAllocationBefore ss+  debugM $ "printCommentsBefore: (ss): " ++ showPprUnsafe (rs2range ss)+  -- debugM $ "printComments: (ss,comment locations): " ++ showPprUnsafe (rs2range ss,map commentLoc cs)+  mapM_ printOneComment cs++printCommentsIn :: (Monad m, Monoid w) => RealSrcSpan -> EP w m ()+printCommentsIn ss = do+  cs <- commentAllocationIn ss+  debugM $ "printCommentsIn: (ss): " ++ showPprUnsafe (rs2range ss)+  -- debugM $ "printComments: (ss,comment locations): " ++ showPprUnsafe (rs2range ss,map commentLoc cs)+  mapM_ printOneComment cs+  debugM $ "printCommentsIn:done"++-- ---------------------------------------------------------------------++printOneComment :: (Monad m, Monoid w) => Comment -> EP w m ()+printOneComment c@(Comment _str loc _r _mo) = do+  debugM $ "printOneComment:c=" ++ showGhc c+  dp <-case loc of+    EpaDelta _ dp _ -> return dp+    EpaSpan (RealSrcSpan r _) -> do+        pe <- getPriorEndD+        debugM $ "printOneComment:pe=" ++ showGhc pe+        let dp = ss2delta pe r+        debugM $ "printOneComment:(dp,pe,loc)=" ++ showGhc (dp,pe,loc)+        adjustDeltaForOffsetM dp+    EpaSpan (UnhelpfulSpan _) -> return (SameLine 0)+  mep <- getExtraDP+  dp' <- case mep of+    Just (EpaDelta _ edp _) -> do+      debugM $ "printOneComment:edp=" ++ show edp+      adjustDeltaForOffsetM edp+    _ -> return dp+  -- Start of debug printing+  LayoutStartCol dOff <- getLayoutOffsetD+  debugM $ "printOneComment:(dp,dp',dOff,loc)=" ++ showGhc (dp,dp',dOff,loc)+  -- End of debug printing+  updateAndApplyComment c dp'+  printQueuedComment c dp'++updateAndApplyComment :: (Monad m, Monoid w) => Comment -> DeltaPos -> EP w m ()+updateAndApplyComment (Comment str anc pp mo) dp = do+  applyComment (Comment str anc' pp mo)+  where+    (r,c) = ss2posEnd pp+    dp'' = case anc of+      EpaDelta _ dp1 _ -> dp1+      EpaSpan (RealSrcSpan la _) ->+           if r == 0+             then (ss2delta (r,c+0) la)+             else (ss2delta (r,c)   la)+      EpaSpan (UnhelpfulSpan _) -> SameLine 0+    dp' = case anc of+      EpaSpan (RealSrcSpan r1 _) ->+          if pp == r1+                 then dp+                 else dp''+      _ -> dp''+    ss = case anc of+        EpaSpan ss' -> ss'+        _          -> noSrcSpan+    op' = case dp' of+            SameLine n -> if n >= 0+                            then EpaDelta ss dp' NoComments+                            else EpaDelta ss dp NoComments+            _ -> EpaDelta ss dp' NoComments+    anc' = if str == "" && op' == EpaDelta ss (SameLine 0) NoComments -- EOF comment+           then EpaDelta ss dp NoComments+           else EpaDelta ss dp NoComments++-- ---------------------------------------------------------------------++commentAllocationBefore :: (Monad m, Monoid w) => RealSrcSpan -> EP w m [Comment]+commentAllocationBefore ss = do+  cs <- getUnallocatedComments+  -- Note: The CPP comment injection may change the file name in the+  -- RealSrcSpan, which affects comparison, as the Ord instance for+  -- RealSrcSpan compares the file first. So we sort via ss2pos+  -- TODO: this is inefficient, use Pos all the way through+  let (earlier,later) = partition (\(Comment _str loc _r _mo) ->+                                     case loc of+                                       EpaSpan (RealSrcSpan r _) -> (ss2pos r) <= (ss2pos ss)+                                       _ -> True -- Choose one+                                  ) cs+  putUnallocatedComments later+  -- debugM $ "commentAllocation:(ss,earlier,later)" ++ show (rs2range ss,earlier,later)+  return earlier++commentAllocationIn :: (Monad m, Monoid w) => RealSrcSpan -> EP w m [Comment]+commentAllocationIn ss = do+  cs <- getUnallocatedComments+  -- Note: The CPP comment injection may change the file name in the+  -- RealSrcSpan, which affects comparison, as the Ord instance for+  -- RealSrcSpan compares the file first. So we sort via ss2pos+  -- TODO: this is inefficient, use Pos all the way through+  let (earlier,later) = partition (\(Comment _str loc _r _mo) ->+                                     case loc of+                                       EpaSpan (RealSrcSpan r _) -> (ss2posEnd r) <= (ss2posEnd ss)+                                       _ -> True -- Choose one+                                  ) cs+  putUnallocatedComments later+  -- debugM $ "commentAllocation:(ss,earlier,later)" ++ show (rs2range ss,earlier,later)+  return earlier+-- ---------------------------------------------------------------------++markAnnotatedWithLayout :: (Monad m, Monoid w) => ExactPrint ast => ast -> EP w m ast+markAnnotatedWithLayout a = setLayoutBoth $ markAnnotated a++-- ---------------------------------------------------------------------++markTopLevelList :: (Monad m, Monoid w) => ExactPrint ast => [ast] -> EP w m [ast]+markTopLevelList ls = mapM (\a -> setLayoutTopLevelP $ markAnnotated a) ls++-- ---------------------------------------------------------------------+-- End of utility functions+-- ---------------------------------------------------------------------+-- Start of ExactPrint instances+-- ---------------------------------------------------------------------++-- | Bare Located elements are simply stripped off without further+-- processing.+instance (ExactPrint a) => ExactPrint (Located a) where+  getAnnotationEntry (L l _) = case l of+    UnhelpfulSpan _ -> NoEntryVal+    _ -> Entry (EpaSpan l) [] emptyComments NoFlushComments CanUpdateAnchorOnly++  setAnnotationAnchor (L l a) _anc _ts _cs = L l a++  exact (L l a) = L l <$> markAnnotated a++instance (ExactPrint a) => ExactPrint (LocatedE a) where+  getAnnotationEntry (L l _) = Entry l [] emptyComments NoFlushComments CanUpdateAnchorOnly+  setAnnotationAnchor (L _ a) anc _ts _cs = L anc a++  exact (L la a) = do+    debugM $ "LocatedE a:la loc=" ++ show (ss2range $ locA la)+    a' <- markAnnotated a+    return (L la a')++instance (ExactPrint a) => ExactPrint (LocatedA a) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor la anc ts cs = setAnchorAn la anc ts cs+  exact (L la a) = do+    debugM $ "LocatedA a:la loc=" ++ show (ss2range $ locA la)+    a' <- markAnnotated a+    return (L la a')++instance (ExactPrint a) => ExactPrint (LocatedAn NoEpAnns a) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor la anc ts cs = setAnchorAn la anc ts cs+  exact (L la a) = do+    a' <- markAnnotated a+    return (L la a')++instance (ExactPrint a) => ExactPrint [a] where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor ls _ _ _ = ls+  exact ls = mapM markAnnotated ls++instance (ExactPrint a) => ExactPrint (Maybe a) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor ma _ _ _ = ma+  exact ma = mapM markAnnotated ma++-- ---------------------------------------------------------------------++-- | 'Located (HsModule GhcPs)' corresponds to 'ParsedSource'+instance ExactPrint (HsModule GhcPs) where+  getAnnotationEntry hsmod = fromAnn' (hsmodAnn $ hsmodExt hsmod)+  -- A bit pointless actually changing anything here+  setAnnotationAnchor hsmod anc _ts cs = setAnchorHsModule hsmod anc cs+                   `debug` ("setAnnotationAnchor hsmod called" ++ showAst (anc,cs))++  exact (HsModule (XModulePs an lo mdeprec mbDoc) mmn mexports imports decls) = do++    let mbDoc' = mbDoc++    (an0, mmn' , mdeprec', mexports') <-+      case mmn of+        Nothing -> return (an, mmn, mdeprec, mexports)+        Just m -> do+          an0 <- markLensTok an lam_mod+          m' <- markAnnotated m++          mdeprec' <- setLayoutTopLevelP $ markAnnotated mdeprec++          mexports' <- setLayoutTopLevelP $ markAnnotated mexports++          an1 <- setLayoutTopLevelP $ markLensTok an0 lam_where++          return (an1, Just m', mdeprec', mexports')++    lo0 <- case lo of+        EpExplicitBraces open close -> do+          open' <- markEpToken open+          return (EpExplicitBraces open' close)+        _ -> return lo++    am_decls' <- markTrailing (am_decls $ anns an0)++    mid <- markAnnotated (HsModuleImpDecls (am_cs $ anns an0) imports decls)+    let imports' = id_imps mid+    let decls' = id_decls mid++    lo1 <- case lo0 of+        EpExplicitBraces open close -> do+          close' <- markEpToken close+          return (EpExplicitBraces open close')+        _ -> return lo++    -- Print EOF+    case am_eof $ anns an of+      Nothing -> return ()+      Just (pos, prior) -> do+        debugM $ "am_eof:" ++ showGhc (pos, prior)+        setEofPos (Just (pos, prior))++    let anf = an0 { anns = (anns an0) { am_decls = am_decls', am_cs = [] }}+    debugM $ "HsModule, anf=" ++ showAst anf++    return (HsModule (XModulePs anf lo1 mdeprec' mbDoc') mmn' mexports' imports' decls')++-- ---------------------------------------------------------------------++-- | This is used to ensure the comments are updated into the right+-- place for makeDeltaAst.+data HsModuleImpDecls+    = HsModuleImpDecls {+        id_cs     :: [LEpaComment],+        id_imps   :: [LImportDecl GhcPs],+        id_decls  :: [LHsDecl GhcPs]+    } deriving Data++instance ExactPrint HsModuleImpDecls where+  -- Use an UnhelpfulSpan for the anchor, we are only interested in the comments+  getAnnotationEntry mid = mkEntry (EpaSpan (UnhelpfulSpan UnhelpfulNoLocationInfo)) [] (EpaComments (id_cs mid))+  setAnnotationAnchor mid _anc _ cs = mid { id_cs = priorComments cs ++ getFollowingComments cs }+     `debug` ("HsModuleImpDecls.setAnnotationAnchor:cs=" ++ showAst cs)+  exact (HsModuleImpDecls cs imports decls) = do+    imports' <- markTopLevelList imports+    decls' <- markTopLevelList (filter notDocDecl decls)+    return (HsModuleImpDecls cs imports' decls')+++-- ---------------------------------------------------------------------++instance ExactPrint ModuleName where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor n _anc _ cs = n+     `debug` ("ModuleName.setAnnotationAnchor:cs=" ++ showAst cs)+  exact n = do+    debugM $ "ModuleName: " ++ showPprUnsafe n+    withPpr n++-- ---------------------------------------------------------------------++instance ExactPrint (LocatedP (WarningTxt GhcPs)) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor = setAnchorAn++  exact (L (EpAnn l (AnnPragma o c (os,cs) l1 l2 t m) css) (WarningTxt mb_cat src ws)) = do+    o' <- markAnnOpen'' o src "{-# WARNING"+    mb_cat' <- markAnnotated mb_cat+    os' <- markEpToken os+    ws' <- markAnnotated ws+    cs' <- markEpToken cs+    c' <- markEpToken c+    return (L (EpAnn l (AnnPragma o' c' (os',cs') l1 l2 t m) css) (WarningTxt mb_cat' src ws'))++  exact (L (EpAnn l (AnnPragma o c (os,cs) l1 l2 t m) css) (DeprecatedTxt src ws)) = do+    o' <- markAnnOpen'' o src "{-# DEPRECATED"+    os' <- markEpToken os+    ws' <- markAnnotated ws+    cs' <- markEpToken cs+    c' <- markEpToken c+    return (L (EpAnn l (AnnPragma o' c' (os',cs') l1 l2 t m) css) (DeprecatedTxt src ws'))++instance ExactPrint InWarningCategory where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (InWarningCategory tkIn source (L l wc)) = do+      tkIn' <- markEpToken tkIn+      L l' (_,wc') <- markAnnotated (L l (source, wc))+      return (InWarningCategory tkIn' source (L l' wc'))++instance ExactPrint (SourceText, WarningCategory) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (st, WarningCategory wc) = do+      case st of+          NoSourceText -> printStringAdvance $ "\"" ++ (unpackFS wc) ++ "\""+          SourceText src -> printStringAdvance $ (unpackFS src)+      return (st, WarningCategory wc)++-- ---------------------------------------------------------------------++instance ExactPrint (ImportDecl GhcPs) where+  getAnnotationEntry idecl = fromAnn (ideclAnn $ ideclExt idecl)+  setAnnotationAnchor idecl anc ts cs = idecl { ideclExt+                    = (ideclExt idecl) { ideclAnn = setAnchorEpa (ideclAnn $ ideclExt idecl) anc ts cs} }++  exact (ImportDecl (XImportDeclPass ann msrc impl)+                     modname mpkg src safeflag qualFlag mAs hiding) = do++    ann0 <- markLensFun' ann limportDeclAnnImport markEpToken+    let (EpAnn _anc an _cs) = ann0++    -- "{-# SOURCE" and "#-}"+    importDeclAnnPragma' <-+      case msrc of+        SourceText _txt -> do+          debugM $ "ImportDecl sourcetext"+          case importDeclAnnPragma an of+            Just (mo, mc) -> do+              mo' <- markAnnOpen'' mo msrc "{-# SOURCE"+              mc' <- markEpToken mc+              return $ Just (mo', mc')+            Nothing ->  do+              _ <- markAnnOpen' Nothing msrc "{-# SOURCE"+              printStringAtLsDelta (SameLine 1) "#-}"+              return Nothing+        NoSourceText -> return (importDeclAnnPragma an)+    ann1 <- if safeflag+      then markLensFun' ann0 limportDeclAnnSafe (\mt -> mapM markEpToken mt)+      else return ann0+    ann2 <-+      case qualFlag of+        QualifiedPre  -- 'qualified' appears in prepositive position.+          -> markLensFun' ann1 limportDeclAnnQualified (\ml -> mapM markEpToken ml)+        _ -> return ann1+    ann3 <-+      case mpkg of+       RawPkgQual (StringLiteral src' v _) ->+         printStringAtMLocL ann2 limportDeclAnnPackage (sourceTextToString src' (show v))+       _ -> return ann2+    modname' <- markAnnotated modname++    ann4 <-+      case qualFlag of+        QualifiedPost  -- 'qualified' appears in postpositive position.+          -> markLensFun' ann3 limportDeclAnnQualified (\ml -> mapM markEpToken ml)+        _ -> return ann3++    (importDeclAnnAs', mAs') <-+      case mAs of+        Nothing -> return (importDeclAnnAs an, Nothing)+        Just m0 -> do+          a <- mapM markEpToken (importDeclAnnAs an)+          m'' <- markAnnotated m0+          return (a, Just m'')++    hiding' <-+      case hiding of+        Nothing -> return hiding+        Just (isHiding,lie) -> do+          lie' <- markAnnotated lie+          return (Just (isHiding, lie'))++    let (EpAnn anc' an' cs') = ann4+    let an2 = an' { importDeclAnnAs = importDeclAnnAs'+                  , importDeclAnnPragma = importDeclAnnPragma'+                  }++    return (ImportDecl (XImportDeclPass (EpAnn anc' an2 cs') msrc impl)+                     modname' mpkg src safeflag qualFlag mAs' hiding')+++-- ---------------------------------------------------------------------++instance ExactPrint HsDocString where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (MultiLineDocString decorator (x :| xs)) = do+    printStringAdvance ("-- " ++ printDecorator decorator)+    pe <- getPriorEndD+    debugM $ "MultiLineDocString: (pe,x)=" ++ showAst (pe,x)+    x' <- markAnnotated x+    xs' <- markAnnotated (map dedentDocChunk xs)+    return (MultiLineDocString decorator (x' :| xs'))+  exact x = do+    -- TODO: can this happen?+    debugM $ "Not exact printing:" ++ showAst x+    return x+++instance ExactPrint HsDocStringChunk where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact chunk = do+    printStringAdvance ("--" ++ unpackHDSC chunk)+    return chunk+++instance ExactPrint a => ExactPrint (WithHsDocIdentifiers a GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact (WithHsDocIdentifiers ds ids) = do+    ds' <- exact ds+    return (WithHsDocIdentifiers ds' ids)++-- ---------------------------------------------------------------------++instance ExactPrint (HsDecl GhcPs) where+  getAnnotationEntry (TyClD      _ _) = NoEntryVal+  getAnnotationEntry (InstD      _ _) = NoEntryVal+  getAnnotationEntry (DerivD     _ _) = NoEntryVal+  getAnnotationEntry (ValD       _ _) = NoEntryVal+  getAnnotationEntry (SigD       _ _) = NoEntryVal+  getAnnotationEntry (KindSigD   _ _) = NoEntryVal+  getAnnotationEntry (DefD       _ _) = NoEntryVal+  getAnnotationEntry (ForD       _ _) = NoEntryVal+  getAnnotationEntry (WarningD   _ _) = NoEntryVal+  getAnnotationEntry (AnnD       _ _) = NoEntryVal+  getAnnotationEntry (RuleD      _ _) = NoEntryVal+  getAnnotationEntry (SpliceD    _ _) = NoEntryVal+  getAnnotationEntry (DocD       _ _) = NoEntryVal+  getAnnotationEntry (RoleAnnotD _ _) = NoEntryVal++  -- We do not recurse, the generic traversal using this feature+  -- should do that for us.+  setAnnotationAnchor d _ _ _ = d++  exact (TyClD       x d) = TyClD       x <$> markAnnotated d+  exact (InstD       x d) = InstD       x <$> markAnnotated d+  exact (DerivD      x d) = DerivD      x <$> markAnnotated d+  exact (ValD        x d) = ValD        x <$> markAnnotated d+  exact (SigD        x d) = SigD        x <$> markAnnotated d+  exact (KindSigD    x d) = KindSigD    x <$> markAnnotated d+  exact (DefD        x d) = DefD        x <$> markAnnotated d+  exact (ForD        x d) = ForD        x <$> markAnnotated d+  exact (WarningD    x d) = WarningD    x <$> markAnnotated d+  exact (AnnD        x d) = AnnD        x <$> markAnnotated d+  exact (RuleD       x d) = RuleD       x <$> markAnnotated d+  exact (SpliceD     x d) = SpliceD     x <$> markAnnotated d+  exact (DocD        x d) = DocD        x <$> markAnnotated d+  exact (RoleAnnotD  x d) = RoleAnnotD  x <$> markAnnotated d++-- ---------------------------------------------------------------------++instance ExactPrint (InstDecl GhcPs) where+  getAnnotationEntry (ClsInstD     _ _) = NoEntryVal+  getAnnotationEntry (DataFamInstD _ _) = NoEntryVal+  getAnnotationEntry (TyFamInstD   _ _) = NoEntryVal++  setAnnotationAnchor d _ _ _ = d+++  exact (ClsInstD     a  cid) = do+    cid' <- markAnnotated cid+    return (ClsInstD     a  cid')+  exact (DataFamInstD a decl) = do+    decl' <- markAnnotated decl+    return (DataFamInstD a decl')+  exact (TyFamInstD a eqn) = do+    eqn' <- markAnnotated eqn+    return (TyFamInstD a eqn')++-- ---------------------------------------------------------------------++instance ExactPrint (DataFamInstDecl GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact d = do+    d' <- exactDataFamInstDecl d+    return d'++-- ---------------------------------------------------------------------++exactDataFamInstDecl :: (Monad m, Monoid w)+                     => DataFamInstDecl GhcPs+                     -> EP w m (DataFamInstDecl GhcPs)+exactDataFamInstDecl+  (DataFamInstDecl (FamEqn { feqn_ext    = (ops, cps, eq)+                           , feqn_tycon  = tycon+                           , feqn_bndrs  = bndrs+                           , feqn_pats   = pats+                           , feqn_fixity = fixity+                           , feqn_rhs    = defn })) = do+    ((ops', cps'), tycon', bndrs', pats', defn') <- exactDataDefn pp_hdr defn+    return+      (DataFamInstDecl ( FamEqn { feqn_ext    = (ops', cps', eq)+                                , feqn_tycon  = tycon'+                                , feqn_bndrs  = bndrs'+                                , feqn_pats   = pats'+                                , feqn_fixity = fixity+                                , feqn_rhs    = defn' }))+                    `debug` ("exactDataFamInstDecl: defn' derivs:" ++ showAst (dd_derivs defn'))+  where+    pp_hdr :: (Monad m, Monoid w)+           => Maybe (LHsContext GhcPs)+           -> EP w m ( ([EpToken "("], [EpToken ")"] )+                     , LocatedN RdrName+                     , HsOuterTyVarBndrs () GhcPs+                     , HsFamEqnPats GhcPs+                     , Maybe (LHsContext GhcPs))+    pp_hdr mctxt = exactHsFamInstLHS ops cps tycon bndrs pats fixity mctxt++-- ---------------------------------------------------------------------++instance ExactPrint (DerivDecl GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (DerivDecl (mw, (td,ti)) typ ms mov) = do+    td' <- markEpToken td+    ms' <- mapM markAnnotated ms+    ti' <- markEpToken ti+    mw' <- mapM markAnnotated mw+    mov' <- mapM markAnnotated mov+    typ' <- markAnnotated typ+    return (DerivDecl (mw', (td',ti')) typ' ms' mov')++-- ---------------------------------------------------------------------++instance ExactPrint (ForeignDecl GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (ForeignImport (tf,ti,td) n ty fimport) = do+    tf' <- markEpToken tf+    ti' <- markEpToken ti++    fimport' <- markAnnotated fimport++    n' <- markAnnotated n+    td' <- markEpUniToken td+    ty' <- markAnnotated ty+    return (ForeignImport (tf',ti',td') n' ty' fimport')++  exact (ForeignExport (tf,te,td) n ty fexport) = do+    tf' <- markEpToken tf+    te' <- markEpToken te+    fexport' <- markAnnotated fexport+    n' <- markAnnotated n+    td' <- markEpUniToken td+    ty' <- markAnnotated ty+    return (ForeignExport (tf',te',td') n' ty' fexport')++-- ---------------------------------------------------------------------++instance ExactPrint (ForeignImport GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact (CImport (L ls src) cconv safety@(L l _) mh imp) = do+    cconv' <- markAnnotated cconv+    safety' <- if notDodgyE l+        then markAnnotated safety+        else return safety+    ls' <- if notDodgyE ls+        then markExternalSourceTextE ls src ""+        else return ls+    return (CImport (L ls' src) cconv' safety' mh imp)++-- ---------------------------------------------------------------------++instance ExactPrint (ForeignExport GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact (CExport (L ls src) spec) = do+    debugM $ "CExport starting"+    spec' <- markAnnotated spec+    ls' <- if notDodgyE ls+        then markExternalSourceTextE ls src ""+        else return ls+    return (CExport (L ls' src) spec')++-- ---------------------------------------------------------------------++instance ExactPrint CExportSpec where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact (CExportStatic st lbl cconv) = do+    debugM $ "CExportStatic starting"+    cconv' <- markAnnotated cconv+    return (CExportStatic st lbl cconv')++-- ---------------------------------------------------------------------++instance ExactPrint Safety where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact = withPpr++-- ---------------------------------------------------------------------++instance ExactPrint CCallConv where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact = withPpr++-- ---------------------------------------------------------------------++instance ExactPrint (WarnDecls GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (Warnings ((o,c),src) warns) = do+    o' <- markAnnOpen'' o src "{-# WARNING" -- Note: might be {-# DEPRECATED+    warns' <- markAnnotated warns+    c' <- markEpToken c+    return (Warnings ((o',c'),src) warns')++-- ---------------------------------------------------------------------++instance ExactPrint (WarnDecl GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (Warning (ns_spec, (o,c)) lns  (WarningTxt mb_cat src ls )) = do+    mb_cat' <- markAnnotated mb_cat+    ns_spec' <- exactNsSpec ns_spec+    lns' <- markAnnotated lns+    o' <- markEpToken o+    ls' <- markAnnotated ls+    c' <- markEpToken c+    return (Warning (ns_spec', (o',c')) lns'  (WarningTxt mb_cat' src ls'))++  exact (Warning (ns_spec, (o,c)) lns (DeprecatedTxt src ls)) = do+    ns_spec' <- exactNsSpec ns_spec+    lns' <- markAnnotated lns+    o' <- markEpToken o+    ls' <- markAnnotated ls+    c' <- markEpToken c+    return (Warning (ns_spec', (o',c')) lns' (DeprecatedTxt src ls'))++exactNsSpec :: (Monad m, Monoid w) => NamespaceSpecifier -> EP w m NamespaceSpecifier+exactNsSpec NoNamespaceSpecifier = pure NoNamespaceSpecifier+exactNsSpec (TypeNamespaceSpecifier type_) = do+  type_' <- markEpToken type_+  pure (TypeNamespaceSpecifier type_')+exactNsSpec (DataNamespaceSpecifier data_) = do+  data_' <- markEpToken data_+  pure (DataNamespaceSpecifier data_')++-- ---------------------------------------------------------------------++instance ExactPrint StringLiteral where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (StringLiteral src fs mcomma) = do+    printSourceTextAA src (show (unpackFS fs))+    mcomma' <- mapM (\r -> printStringAtNC r ",") mcomma+    return (StringLiteral src fs mcomma')++-- ---------------------------------------------------------------------++instance ExactPrint FastString where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  -- TODO: https://ghc.haskell.org/trac/ghc/ticket/10313 applies.+  -- exact fs = printStringAdvance (show (unpackFS fs))+  exact fs = printStringAdvance (unpackFS fs) >> return fs++-- ---------------------------------------------------------------------++instance ExactPrint (RuleDecls GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact (HsRules ((o,c), src) rules) = do+    o' <-+      case src of+        NoSourceText      -> printStringAtAA o "{-# RULES"+        SourceText srcTxt -> printStringAtAA o (unpackFS srcTxt)+    rules' <- markAnnotated rules+    c' <- markEpToken c+    return (HsRules ((o',c'),src) rules')++-- ---------------------------------------------------------------------++instance ExactPrint (RuleDecl GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (HsRule (an,nsrc) (L ln n) act mtybndrs termbndrs lhs rhs) = do+    (L ln' _) <- markAnnotated (L ln (nsrc, n))+    an0 <- markActivationL an lra_rest act+    (an1, mtybndrs') <-+      case mtybndrs of+        Nothing -> return (an0, Nothing)+        Just bndrs -> do+          an1 <-  markLensFun an0 lra_tyanns_fst (\mt -> mapM markEpUniToken mt)  -- AnnForall+          bndrs' <- mapM markAnnotated bndrs+          an2 <- markLensFun an1 lra_tyanns_snd (\mt -> mapM markEpToken mt)  -- AnnDot+          return (an2, Just bndrs')++    an2 <- markLensFun an1 lra_tmanns_fst (\mt -> mapM markEpUniToken mt) -- AnnForall+    termbndrs' <- mapM markAnnotated termbndrs+    an3 <- markLensFun an2 lra_tmanns_snd (\mt -> mapM markEpToken mt)  -- AnnDot++    lhs' <- markAnnotated lhs+    an4 <- markLensFun an3 lra_equal markEpToken+    rhs' <- markAnnotated rhs+    return (HsRule (an4,nsrc) (L ln' n) act mtybndrs' termbndrs' lhs' rhs')+++markActivationL :: (Monad m, Monoid w)+  => a -> Lens a ActivationAnn -> Activation -> EP w m a+markActivationL a l act = do+  new <- markActivation (view l a) act+  return (set l new a)++markActivation :: (Monad m, Monoid w)+  => ActivationAnn -> Activation -> EP w m ActivationAnn+markActivation (ActivationAnn o c t v) act = do+  case act of+    ActiveBefore src phase -> do+      o' <- markEpToken o --  '['+      t' <- mapM markEpToken t -- ~+      v' <- mapM (\val -> printStringAtAA val (toSourceTextWithSuffix src (show phase) "")) v+      c' <- markEpToken c -- ']'+      return (ActivationAnn o' c' t' v')+    ActiveAfter src phase -> do+      o' <- markEpToken o --  '['+      v' <- mapM (\val -> printStringAtAA val (toSourceTextWithSuffix src (show phase) "")) v+      c' <- markEpToken c -- ']'+      return (ActivationAnn o' c' t v')+    NeverActive -> do+      o' <- markEpToken o --  '['+      t' <- mapM markEpToken t -- ~+      c' <- markEpToken c -- ']'+      return (ActivationAnn o' c' t' v)+    _ -> return (ActivationAnn o c t v)++-- ---------------------------------------------------------------------++instance ExactPrint (SpliceDecl GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (SpliceDecl x splice flag) = do+    splice' <- markAnnotated splice+    return (SpliceDecl x splice' flag)++-- ---------------------------------------------------------------------++instance ExactPrint (DocDecl GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  -- We print these as plain comments instead, do a NOP here.+  exact v = return v++-- ---------------------------------------------------------------------++instance ExactPrint (RoleAnnotDecl GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (RoleAnnotDecl (tt,tr) ltycon roles) = do+    tt' <- markEpToken tt+    tr' <- markEpToken tr+    ltycon' <- markAnnotated ltycon+    let markRole (L l (Just r)) = do+          (L l' r') <- markAnnotated (L l r)+          return (L l' (Just r'))+        markRole (L l Nothing) = do+          e' <- printStringAtAA  (entry l) "_"+          return (L (l { entry = e'}) Nothing)+    roles' <- mapM markRole roles+    return (RoleAnnotDecl (tt',tr') ltycon' roles')++-- ---------------------------------------------------------------------++instance ExactPrint Role where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact = withPpr++-- ---------------------------------------------------------------------++instance ExactPrint (RuleBndr GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (RuleBndr x ln) = do+    ln' <- markAnnotated ln+    return (RuleBndr x ln')+  exact (RuleBndrSig (AnnTyVarBndr os cs ap dc) ln (HsPS x ty)) = do+    os' <- markEpaLocationAll os "("+    ln' <- markAnnotated ln+    dc' <- markEpUniToken dc+    ty' <- markAnnotated ty+    cs' <- markEpaLocationAll cs ")"+    return (RuleBndrSig (AnnTyVarBndr os' cs' ap dc') ln' (HsPS x ty'))++-- ---------------------------------------------------------------------++instance (ExactPrint body) => ExactPrint (FamEqn GhcPs body) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor fe _ _ _s = fe+  exact (FamEqn { feqn_ext    = (ops, cps, eq)+                , feqn_tycon  = tycon+                , feqn_bndrs  = bndrs+                , feqn_pats   = pats+                , feqn_fixity = fixity+                , feqn_rhs    = rhs }) = do+    ((ops', cps'), tycon', bndrs', pats',_) <- exactHsFamInstLHS ops cps tycon bndrs pats fixity Nothing+    eq' <- markEpToken eq+    rhs' <- markAnnotated rhs+    return (FamEqn { feqn_ext    = (ops', cps', eq')+                   , feqn_tycon  = tycon'+                   , feqn_bndrs  = bndrs'+                   , feqn_pats   = pats'+                   , feqn_fixity = fixity+                   , feqn_rhs    = rhs' })++-- ---------------------------------------------------------------------++exactHsFamInstLHS ::+      (Monad m, Monoid w)+   => [EpToken "("]+   -> [EpToken ")"]+   -> LocatedN RdrName+   -> HsOuterTyVarBndrs () GhcPs+   -> HsFamEqnPats GhcPs+   -> LexicalFixity+   -> Maybe (LHsContext GhcPs)+   -> EP w m ( ([EpToken "("], [EpToken ")"])+             , LocatedN RdrName+             , HsOuterTyVarBndrs () GhcPs+             , HsFamEqnPats GhcPs, Maybe (LHsContext GhcPs))+exactHsFamInstLHS ops cps thing bndrs typats fixity mb_ctxt = do+  -- TODO:AZ: do these ans exist? They are in the binders now+  -- an0 <- markEpAnnL an lidl AnnForall+  bndrs' <- markAnnotated bndrs+  -- an1 <- markEpAnnL an0 lidl AnnDot+  mb_ctxt' <- mapM markAnnotated mb_ctxt+  (ops', cps', thing', typats') <- exact_pats ops cps typats+  return ((ops', cps'), thing', bndrs', typats', mb_ctxt')+  where+    exact_pats :: (Monad m, Monoid w)+      => [EpToken "("] -> [EpToken ")"] -> HsFamEqnPats GhcPs+      -> EP w m ([EpToken "("], [EpToken ")"], LocatedN RdrName, HsFamEqnPats GhcPs)+    exact_pats ops1 cps1 (patl:patr:pats)+      | Infix <- fixity+      = let exact_op_app = do+              ops' <- mapM markEpToken ops1+              patl' <- markAnnotated patl+              thing' <- markAnnotated thing+              patr' <- markAnnotated patr+              cps' <- mapM markEpToken cps1+              return (ops', cps', thing', [patl',patr'])+        in case pats of+             [] -> exact_op_app+             _  -> do+               (ops', cps', thing', p) <- exact_op_app+               pats' <- mapM markAnnotated pats+               return (ops', cps', thing', p++pats')++    exact_pats ops0 cps0 pats = do+      ops' <- mapM markEpToken ops0+      thing' <- markAnnotated thing+      pats' <- markAnnotated pats+      cps' <- mapM markEpToken cps0+      return (ops', cps', thing', pats')++-- ---------------------------------------------------------------------++instance (ExactPrint tm, ExactPrint ty, Outputable tm, Outputable ty)+     =>  ExactPrint (HsArg GhcPs tm ty) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (HsValArg x tm) = do+      tm' <- markAnnotated tm+      return (HsValArg x tm')+  exact (HsTypeArg at ty) = do+      at' <- markEpToken at+      ty' <- markAnnotated ty+      return (HsTypeArg at' ty')+  exact x@(HsArgPar _sp)    = withPpr x -- Does not appear in original source++-- ---------------------------------------------------------------------++instance ExactPrint (ClsInstDecl GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (ClsInstDecl { cid_ext = (mbWarn, AnnClsInstDecl i w oc semis cc, sortKey)+                     , cid_poly_ty = inst_ty, cid_binds = binds+                     , cid_sigs = sigs, cid_tyfam_insts = ats+                     , cid_overlap_mode = mbOverlap+                     , cid_datafam_insts = adts })+      = do+          (mbWarn', i', w', mbOverlap', inst_ty') <- top_matter+          oc' <- markEpToken oc+          semis' <- mapM markEpToken semis+          (sortKey', ds) <- withSortKey sortKey+                               [(ClsAtTag, prepareListAnnotationA ats),+                                (ClsAtdTag, prepareListAnnotationF adts),+                                (ClsMethodTag, prepareListAnnotationA binds),+                                (ClsSigTag, prepareListAnnotationA sigs)+                               ]+          cc' <- markEpToken cc+          let+            ats'   = undynamic ds+            adts'  = undynamic ds+            binds' = undynamic ds+            sigs'  = undynamic ds+          return (ClsInstDecl { cid_ext = (mbWarn', AnnClsInstDecl i' w' oc' semis' cc', sortKey')+                              , cid_poly_ty = inst_ty', cid_binds = binds'+                              , cid_sigs = sigs', cid_tyfam_insts = ats'+                              , cid_overlap_mode = mbOverlap'+                              , cid_datafam_insts = adts' })++      where+        top_matter = do+          i' <- markEpToken i+          mw <- mapM markAnnotated mbWarn+          mo <- mapM markAnnotated mbOverlap+          it <- markAnnotated inst_ty+          w' <- markEpToken w -- Optional+          return (mw, i', w', mo,it)++-- ---------------------------------------------------------------------++instance ExactPrint (TyFamInstDecl GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact d@(TyFamInstDecl { tfid_xtn = (tt,ti), tfid_eqn = eqn }) = do+    tt' <- markEpToken tt+    ti' <- markEpToken ti+    eqn' <- markAnnotated eqn+    return (d { tfid_xtn = (tt',ti'), tfid_eqn = eqn' })++-- ---------------------------------------------------------------------++instance ExactPrint (LocatedP OverlapMode) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor = setAnchorAn++  -- NOTE: NoOverlap is only used in the typechecker+  exact (L (EpAnn l (AnnPragma o c s l1 l2 t m) cs) (NoOverlap src)) = do+    o' <- markAnnOpen'' o src "{-# NO_OVERLAP"+    c' <- markEpToken c+    return (L (EpAnn l (AnnPragma o' c' s l1 l2 t m) cs) (NoOverlap src))++  exact (L (EpAnn l (AnnPragma o c s l1 l2 t m) cs) (Overlappable src)) = do+    o' <- markAnnOpen'' o src "{-# OVERLAPPABLE"+    c' <- markEpToken c+    return (L (EpAnn l (AnnPragma o' c' s l1 l2 t m) cs) (Overlappable src))++  exact (L (EpAnn l (AnnPragma o c s l1 l2 t m) cs) (Overlapping src)) = do+    o' <- markAnnOpen'' o src "{-# OVERLAPPING"+    c' <- markEpToken c+    return (L (EpAnn l (AnnPragma o' c' s l1 l2 t m) cs) (Overlapping src))++  exact (L (EpAnn l (AnnPragma o c s l1 l2 t m) cs) (Overlaps src)) = do+    o' <- markAnnOpen'' o src "{-# OVERLAPS"+    c' <- markEpToken c+    return (L (EpAnn l (AnnPragma o' c' s l1 l2 t m) cs) (Overlaps src))++  exact (L (EpAnn l (AnnPragma o c s l1 l2 t m) cs) (Incoherent src)) = do+    o' <- markAnnOpen'' o src "{-# INCOHERENT"+    c' <- markEpToken c+    return (L (EpAnn l (AnnPragma o' c' s l1 l2 t m) cs) (Incoherent src))++  exact (L (EpAnn l (AnnPragma o c s l1 l2 t m) cs) (NonCanonical src)) = do+    o' <- markAnnOpen'' o src "{-# INCOHERENT"+    c' <- markEpToken c+    return (L (EpAnn l (AnnPragma o' c' s l1 l2 t m) cs) (Incoherent src))++-- ---------------------------------------------------------------------++instance ExactPrint (HsBind GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (FunBind x fid matches) = do+    matches' <- markAnnotated matches+    let+      fun_id' = case unLoc (mg_alts matches') of+        [] -> fid+        (L _ m:_) -> case m_ctxt m of+          FunRhs f _ _ _ -> f+          _ -> fid+    return (FunBind x fun_id' matches')++  exact (PatBind x pat q grhss) = do+    q' <- markAnnotated q+    pat' <- markAnnotated pat+    grhss' <- markAnnotated grhss+    return (PatBind x pat' q' grhss')+  exact (PatSynBind x bind) = do+    bind' <- markAnnotated bind+    return (PatSynBind x bind')++  exact x = error $ "HsBind: exact for " ++ showAst x++instance ExactPrint (HsMultAnn GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (HsNoMultAnn x) = return (HsNoMultAnn x)+  exact (HsPct1Ann tok) = do+      tok' <- markEpToken tok+      return (HsPct1Ann tok')+  exact (HsMultAnn tok ty) = do+      tok' <- markEpToken tok+      ty' <- markAnnotated ty+      return (HsMultAnn tok' ty')++-- ---------------------------------------------------------------------++instance ExactPrint (PatSynBind GhcPs GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (PSB{ psb_ext = AnnPSB ap ao ac al ae+            , psb_id = psyn, psb_args = details+            , psb_def = pat+            , psb_dir = dir }) = do+    ap' <- markEpToken ap+    (ao', ac', psyn', details') <-+      case details of+        InfixCon v1 v2 -> do+          v1' <- markAnnotated v1+          psyn' <- markAnnotated psyn+          v2' <- markAnnotated v2+          return (ao, ac, psyn',InfixCon v1' v2')+        PrefixCon tvs vs -> do+          psyn' <- markAnnotated psyn+          tvs' <- markAnnotated tvs+          vs' <- markAnnotated vs+          return (ao, ac, psyn', PrefixCon tvs' vs')+        RecCon vs -> do+          psyn' <- markAnnotated psyn+          ao' <- mapM markEpToken ao+          vs' <- markAnnotated vs+          ac' <- mapM markEpToken ac+          return (ao', ac', psyn', RecCon vs')++    (al', ae', pat', dir') <-+      case dir of+        Unidirectional           -> do+          al' <- mapM markEpUniToken al+          pat' <- markAnnotated pat+          return (al', ae, pat', dir)+        ImplicitBidirectional    -> do+          ae' <- mapM markEpToken ae+          pat' <- markAnnotated pat+          return (al, ae', pat', dir)+        ExplicitBidirectional mg -> do+          al' <- mapM markEpUniToken al+          pat' <- markAnnotated pat+          mg' <- markAnnotated mg+          return (al', ae, pat', ExplicitBidirectional mg')++    return (PSB{ psb_ext = AnnPSB ap' ao' ac' al' ae'+               , psb_id = psyn', psb_args = details'+               , psb_def = pat'+               , psb_dir = dir' })+++-- ---------------------------------------------------------------------++instance ExactPrint (RecordPatSynField GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact (RecordPatSynField f v) = do+      f' <- markAnnotated f+      return (RecordPatSynField f' v)++-- ---------------------------------------------------------------------++instance ExactPrint (Match GhcPs (LocatedA (HsCmd GhcPs))) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (Match an mctxt pats grhss) =+    exactMatch (Match an mctxt pats grhss)++-- -------------------------------------++instance ExactPrint (Match GhcPs (LocatedA (HsExpr GhcPs))) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (Match an mctxt pats grhss) =+    exactMatch (Match an mctxt pats grhss)++-- ---------------------------------------------------------------------++exactMatch :: (Monad m, Monoid w, ExactPrint (GRHSs GhcPs body))+           => (Match GhcPs body) -> EP w m (Match GhcPs body)+exactMatch (Match an mctxt pats grhss) = do++  debugM $ "exact Match entered"++  (mctxt', pats') <-+    case mctxt of+      FunRhs fun fixity strictness (AnnFunRhs strict opens closes) -> do+        debugM $ "exact Match FunRhs:" ++ showPprUnsafe fun+        strict' <- markEpToken strict+        case fixity of+          Prefix -> do+            epTokensToComments "(" opens+            epTokensToComments ")" closes+            fun' <- markAnnotated fun+            pats' <- markAnnotated pats+            return (FunRhs fun' fixity strictness (AnnFunRhs strict' [] []), pats')+          Infix ->+            case pats of+              L l (p1:p2:rest)+                | null rest -> do+                    p1'  <- markAnnotated p1+                    fun' <- markAnnotated fun+                    p2'  <- markAnnotated p2+                    return (FunRhs fun' fixity strictness (AnnFunRhs strict' [] []), L l [p1',p2'])+                | otherwise -> do+                    opens' <- markEpToken1 opens+                    p1'  <- markAnnotated p1+                    fun' <- markAnnotated fun+                    p2'  <- markAnnotated p2+                    closes' <- markEpToken1 closes+                    rest' <- mapM markAnnotated rest+                    return (FunRhs fun' fixity strictness (AnnFunRhs strict' opens' closes'), L l (p1':p2':rest'))+              _ -> panic "FunRhs"++      LamAlt v -> do+        pats' <- markAnnotated pats+        return (LamAlt v, pats')++      CaseAlt -> do+        pats' <- markAnnotated pats+        return (CaseAlt, pats')++      _ -> do+        mctxt' <- withPpr mctxt+        return (mctxt', pats)++  grhss' <- markAnnotated grhss++  return (Match an mctxt' pats' grhss')++-- ---------------------------------------------------------------------++instance ExactPrint (GRHSs GhcPs (LocatedA (HsExpr GhcPs))) where+  getAnnotationEntry (GRHSs _ _ _) = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (GRHSs cs grhss binds) = do+    addCommentsA $ priorComments cs+    addCommentsA $ getFollowingComments cs+    grhss' <- markAnnotated grhss+    binds' <- markAnnotated binds+    -- The comments will be added back as they are printed+    return (GRHSs emptyComments grhss' binds')+++instance ExactPrint (GRHSs GhcPs (LocatedA (HsCmd GhcPs))) where+  getAnnotationEntry (GRHSs _ _ _) = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (GRHSs cs grhss binds) = do+    addCommentsA $ priorComments cs+    addCommentsA $ getFollowingComments cs+    grhss' <- markAnnotated grhss+    binds' <- markAnnotated binds+    -- The comments will be added back as they are printed+    return (GRHSs emptyComments grhss' binds')++-- ---------------------------------------------------------------------++instance ExactPrint (HsLocalBinds GhcPs) where+  getAnnotationEntry (HsValBinds an _) = fromAnn an+  getAnnotationEntry (HsIPBinds{}) = NoEntryVal+  getAnnotationEntry (EmptyLocalBinds{}) = NoEntryVal++  setAnnotationAnchor (HsValBinds an a) anc ts cs = HsValBinds (setAnchorEpaL an anc ts cs) a+  setAnnotationAnchor a _ _ _ = a++  exact (HsValBinds an valbinds) = do+    an0 <- markLensFun' an lal_rest markEpToken -- 'where'++    case al_anchor $ anns an of+      Just anc -> do+        when (not $ isEmptyValBinds valbinds) $ setExtraDP (Just anc)+      _ -> return ()++    (an1, valbinds') <- markAnnList an0 $ markAnnotatedWithLayout valbinds+    debugM $ "exact HsValBinds: an1=" ++ showAst an1+    medr <- getExtraDPReturn+    an2 <- case medr of+             Nothing -> return an1+             Just (ss,dp) -> do+                 setExtraDPReturn Nothing+                 return $ an1 { anns = (anns an1) { al_anchor = Just (EpaDelta ss dp []) }}+    return (HsValBinds an2 valbinds')++  exact (HsIPBinds an bs) = do+    (an2,bs') <- markAnnListA an $ \an0 -> do+                           an1 <- markLensFun' an0 lal_rest markEpToken+                           bs' <- markAnnotated bs+                           return (an1, bs')+    return (HsIPBinds an2 bs')+  exact b@(EmptyLocalBinds _) = return b+++-- ---------------------------------------------------------------------+instance ExactPrint (HsValBindsLR GhcPs GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (ValBinds sortKey binds sigs) = do+    decls <- setLayoutBoth $ mapM markAnnotated $ hsDeclsValBinds (ValBinds sortKey binds sigs)+    let+      binds' = concatMap decl2Bind decls+      sigs'  = concatMap decl2Sig decls+      sortKey' = captureOrderBinds decls+    return (ValBinds sortKey' binds' sigs')+  exact (XValBindsLR _) = panic "XValBindsLR"++undynamic :: Typeable a => [Dynamic] -> [a]+undynamic ds = mapMaybe fromDynamic ds++-- ---------------------------------------------------------------------++instance ExactPrint (HsIPBinds GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (IPBinds x binds) = setLayoutBoth $ do+      binds' <- markAnnotated binds+      return (IPBinds x binds')++-- ---------------------------------------------------------------------++instance ExactPrint (IPBind GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (IPBind an lr rhs) = do+    lr' <- markAnnotated lr+    an0 <- markEpToken an+    rhs' <- markAnnotated rhs+    return (IPBind an0 lr' rhs')+++-- ---------------------------------------------------------------------++instance ExactPrint HsIPName where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact i@(HsIPName fs) = printStringAdvanceA ("?" ++ (unpackFS fs)) >> return i++-- ---------------------------------------------------------------------+-- Managing lists which have been separated, e.g. Sigs and Binds++prepareListAnnotationF :: (Monad m, Monoid w) =>+  [LDataFamInstDecl GhcPs] -> [(RealSrcSpan,EP w m Dynamic)]+prepareListAnnotationF ls = map (\b -> (realSrcSpan $ getLocA b, go b)) ls+  where+    go (L l a) = do+      (L l' d') <- markAnnotated (L l a)+      return (toDyn (L l' d'))++prepareListAnnotationA :: (Monad m, Monoid w, ExactPrint (LocatedAn an a))+  => [LocatedAn an a] -> [(RealSrcSpan,EP w m Dynamic)]+prepareListAnnotationA ls = map (\b -> (realSrcSpan $ getLocA b,go b)) ls+  where+    go b = do+      b' <- markAnnotated b+      return (toDyn b')++withSortKey :: (Monad m, Monoid w)+  => AnnSortKey DeclTag -> [(DeclTag, [(RealSrcSpan, EP w m Dynamic)])]+  -> EP w m (AnnSortKey DeclTag, [Dynamic])+withSortKey annSortKey xs = do+  debugM $ "withSortKey:annSortKey=" ++ showAst annSortKey+  let (sk, ordered) = case annSortKey of+                  NoAnnSortKey -> (annSortKey', map snd os)+                    where+                      doOne (tag, ds) = map (\d -> (tag, d)) ds+                      xsExpanded = concatMap doOne xs+                      os = sortBy orderByFst $ xsExpanded+                      annSortKey' = AnnSortKey (map fst os)+                  AnnSortKey _keys -> (annSortKey, orderedDecls annSortKey (Map.fromList xs))+  ordered' <- mapM snd ordered+  return (sk, ordered')++orderByFst :: Ord a => (t, (a,b1)) -> (t, (a, b2)) -> Ordering+orderByFst (_,(a,_)) (_,(b,_)) = compare a b++-- ---------------------------------------------------------------------++instance ExactPrint (Sig GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (TypeSig (AnnSig dc mp md) vars ty)  = do+    (dc', vars', ty') <- exactVarSig dc vars ty+    return (TypeSig (AnnSig dc' mp md) vars' ty')++  exact (PatSynSig (AnnSig dc mp md) lns typ) = do+    mp' <- mapM markEpToken mp+    lns' <- markAnnotated lns+    dc' <- markEpUniToken dc+    typ' <- markAnnotated typ+    return (PatSynSig (AnnSig dc' mp' md) lns' typ')++  exact (ClassOpSig (AnnSig dc mp md) is_deflt vars ty)+    | is_deflt  = do+        md' <- mapM markEpToken md+        (dc', vars',ty') <- exactVarSig dc vars ty+        return (ClassOpSig (AnnSig dc' mp md') is_deflt vars' ty')+    | otherwise = do+        (dc', vars',ty') <- exactVarSig dc vars ty+        return (ClassOpSig (AnnSig dc' mp md) is_deflt vars' ty')++  exact (FixSig ((af, ma),src) (FixitySig ns names (Fixity v fdir))) = do+    let fixstr = case fdir of+         InfixL -> "infixl"+         InfixR -> "infixr"+         InfixN -> "infix"+    af' <- printStringAtAA af fixstr+    ma' <- mapM (\l -> printStringAtAA l (sourceTextToString src (show v))) ma+    ns' <- markAnnotated ns+    names' <- markAnnotated names+    return (FixSig ((af',ma'),src) (FixitySig ns' names' (Fixity v fdir)))++  exact (InlineSig (o,c,act) ln inl) = do+    o' <- markAnnOpen'' o (inl_src inl) "{-# INLINE"+    act' <- markActivation act (inl_act inl)+    ln' <- markAnnotated ln+    c' <- markEpToken c+    return (InlineSig (o', c', act') ln' inl)++  exact (SpecSig (AnnSpecSig o c dc act) ln typs inl) = do+    o' <- markAnnOpen'' o (inl_src inl) "{-# SPECIALISE" -- Note: may be {-# SPECIALISE_INLINE+    act' <- markActivation act (inl_act inl)+    ln' <- markAnnotated ln+    dc' <- markEpUniToken dc+    typs' <- markAnnotated typs+    c' <- markEpToken c+    return (SpecSig (AnnSpecSig o' c' dc' act') ln' typs' inl)++  exact (SpecInstSig ((o,i,c),src) typ) = do+    o' <- markAnnOpen'' o src "{-# SPECIALISE"+    i' <- markEpToken i+    typ' <- markAnnotated typ+    c' <- markEpToken c+    return (SpecInstSig ((o',i',c'),src) typ')++  exact (MinimalSig ((o,c),src) formula) = do+    o' <- markAnnOpen'' o src "{-# MINIMAL"+    formula' <- markAnnotated formula+    c' <- markEpToken c+    return (MinimalSig ((o',c'),src) formula')++  exact (SCCFunSig ((o,c),src) ln ml) = do+    o' <- markAnnOpen'' o src "{-# SCC"+    ln' <- markAnnotated ln+    ml' <- markAnnotated ml+    c' <- markEpToken c+    return (SCCFunSig ((o',c'),src) ln' ml')++  exact (CompleteMatchSig ((o,md,c),src) cs mty) = do+    o' <- markAnnOpen'' o src "{-# COMPLETE"+    cs' <- mapM markAnnotated cs+    (md', mty') <-+      case mty of+        Nothing -> return (md, mty)+        Just ty -> do+          md' <- mapM markEpUniToken md+          ty' <- markAnnotated ty+          return (md', Just ty')+    c' <- markEpToken c+    return (CompleteMatchSig ((o',md',c'),src) cs' mty')++-- ---------------------------------------------------------------------++instance ExactPrint NamespaceSpecifier where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact NoNamespaceSpecifier = return NoNamespaceSpecifier+  exact (TypeNamespaceSpecifier typeTok) = do+      typeTok' <- markEpToken typeTok+      return (TypeNamespaceSpecifier typeTok')+  exact (DataNamespaceSpecifier dataTok) = do+      dataTok' <- markEpToken dataTok+      return (DataNamespaceSpecifier dataTok')++-- ---------------------------------------------------------------------++exactVarSig :: (Monad m, Monoid w, ExactPrint a)+  => TokDcolon -> [LocatedN RdrName] -> a -> EP w m (TokDcolon, [LocatedN RdrName], a)+exactVarSig dc vars ty = do+  vars' <- mapM markAnnotated vars+  dc' <- markEpUniToken dc+  ty' <- markAnnotated ty+  return (dc', vars', ty')++-- ---------------------------------------------------------------------++instance ExactPrint (StandaloneKindSig GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (StandaloneKindSig (tt,td) vars sig) = do+    tt' <- markEpToken tt+    vars' <- markAnnotated vars+    td' <- markEpUniToken td+    sig' <- markAnnotated sig+    return (StandaloneKindSig (tt',td') vars' sig')++-- ---------------------------------------------------------------------++instance ExactPrint (DefaultDecl GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (DefaultDecl (d,op,cp) cl tys) = do+    d' <- markEpToken d+    op' <- markEpToken op+    cl' <- markAnnotated cl+    tys' <- markAnnotated tys+    cp' <- markEpToken cp+    return (DefaultDecl (d',op',cp') cl' tys')++-- ---------------------------------------------------------------------++instance ExactPrint (AnnDecl GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (HsAnnotation (AnnPragma o c s l1 l2 t m, src) prov e) = do+    o' <- markAnnOpen'' o src "{-# ANN"+    (t', m', prov') <-+      case prov of+        (ValueAnnProvenance n) -> do+          n' <- markAnnotated n+          return (t, m, ValueAnnProvenance n')+        (TypeAnnProvenance n) -> do+          t' <- markEpToken t+          n' <- markAnnotated n+          return (t', m, TypeAnnProvenance n')+        ModuleAnnProvenance -> do+          m' <- markEpToken m+          return (t, m', prov)++    e' <- markAnnotated e+    c' <- markEpToken c+    return (HsAnnotation (AnnPragma o' c' s l1 l2 t' m',src) prov' e')++-- ---------------------------------------------------------------------++instance ExactPrint (BF.BooleanFormula (LocatedN RdrName)) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (BF.Var x)  = do+    x' <- markAnnotated x+    return (BF.Var x')+  exact (BF.Or ls)  = do+    ls' <- markAnnotated ls+    return (BF.Or ls')+  exact (BF.And ls) = do+    ls' <- markAnnotated ls+    return (BF.And ls')+  exact (BF.Parens x)  = do+    x' <- markAnnotated x+    return (BF.Parens x')++-- ---------------------------------------------------------------------++instance (ExactPrint body) => ExactPrint (HsWildCardBndrs GhcPs body) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _= a+  exact (HsWC x ty) = do+    ty' <- markAnnotated ty+    return (HsWC x ty')++-- ---------------------------------------------------------------------++instance ExactPrint (GRHS GhcPs (LocatedA (HsExpr GhcPs))) where+  getAnnotationEntry (GRHS an _ _) = fromAnn an+  setAnnotationAnchor (GRHS an a b) anc ts cs = GRHS (setAnchorEpa an anc ts cs) a b++  exact (GRHS an guards expr) = do+    an0 <- if null guards+             then return an+             else markLensFun' an lga_vbar (\mt -> mapM markEpToken mt)+    guards' <- markAnnotated guards+    -- Mark the matchSeparator for these GRHSs+    an1 <- markLensFun' an0 lga_sep (\s -> case s of+                                       Left  tok -> Left  <$> markEpToken tok+                                       Right tok -> Right <$> markEpUniToken tok)+    expr' <- markAnnotated expr+    return (GRHS an1 guards' expr')++instance ExactPrint (GRHS GhcPs (LocatedA (HsCmd GhcPs))) where+  getAnnotationEntry (GRHS ann _ _) = fromAnn ann+  setAnnotationAnchor (GRHS an a b) anc ts cs = GRHS (setAnchorEpa an anc ts cs) a b++  exact (GRHS an guards expr) = do+    an0 <- markLensFun' an lga_vbar (\mt -> mapM markEpToken mt)+    guards' <- markAnnotated guards+    -- Mark the matchSeparator for these GRHSs+    an1 <- markLensFun' an0 lga_sep (\s -> case s of+                                       Left  tok -> Left  <$> markEpToken tok+                                       Right tok -> Right <$> markEpUniToken tok)+    expr' <- markAnnotated expr+    return (GRHS an1 guards' expr')++-- ---------------------------------------------------------------------++instance ExactPrint (HsExpr GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _s = a++  exact (HsVar x n) = do+    -- The parser inserts a placeholder value for a record pun rhs. This must be+    -- filtered.+    let pun_RDR = "pun-right-hand-side"+    n' <- if (showPprUnsafe n /= pun_RDR)+      then markAnnotated n+      else return n+    return (HsVar x n')+  exact (HsUnboundVar an n) = do+    case an of+      Just (EpAnnUnboundVar (ob,cb) l) -> do+        ob' <-  markEpToken ob+        l'  <- markEpToken l+        cb' <- markEpToken cb+        return (HsUnboundVar (Just (EpAnnUnboundVar (ob',cb') l')) n)+      _ -> do+        printStringAdvanceA "_" >> return ()+        return (HsUnboundVar an n)+  exact x@(HsOverLabel src l) = do+    printStringAdvanceA "#" >> return ()+    case src of+      NoSourceText   -> printStringAdvanceA (unpackFS l)  >> return ()+      SourceText txt -> printStringAdvanceA (unpackFS txt) >> return ()+    return x++  exact x@(HsIPVar _ (HsIPName n))+    = printStringAdvance ("?" ++ unpackFS n) >> return x++  exact x@(HsOverLit _an ol) = do+    let str = case ol_val ol of+                HsIntegral   (IL src _ _) -> src+                HsFractional (FL { fl_text = src }) -> src+                HsIsString src _          -> src+    case str of+      SourceText s -> printStringAdvance (unpackFS s) >> return ()+      NoSourceText -> withPpr x >> return ()+    return x++  exact (HsLit an lit) = do+    lit' <- withPpr lit+    return (HsLit an lit')++  exact (HsLam an lam_variant mg) = do+    an0 <- markLensFun an lepl_lambda markEpToken+    an1 <- case lam_variant of+             LamSingle -> return an0+             LamCase  -> markLensFun an0 lepl_case (\ml -> mapM (\l -> printStringAtAA l "case") ml)+             LamCases -> markLensFun an0 lepl_case (\ml -> mapM (\l -> printStringAtAA l "cases") ml)+    mg' <- markAnnotated mg+    return (HsLam an1 lam_variant mg')++  exact (HsApp an e1 e2) = do+    p <- getPosP+    debugM $ "HsApp entered. p=" ++ show p+    e1' <- markAnnotated e1+    e2' <- markAnnotated e2+    return (HsApp an e1' e2')+  exact (HsAppType at fun arg) = do+    fun' <- markAnnotated fun+    at' <- markEpToken at+    arg' <- markAnnotated arg+    return (HsAppType at' fun' arg')+  exact (OpApp x e1 e2 e3) = do+    e1' <- markAnnotated e1+    e2' <- markAnnotated e2+    e3' <- markAnnotated e3+    return (OpApp x e1' e2' e3')++  exact (NegApp an e s) = do+    an0 <- markEpToken an+    e' <- markAnnotated e+    return (NegApp an0 e' s)++  exact (HsPar (lpar, rpar) e) = do+    lpar' <- markEpToken lpar+    e' <- markAnnotated e+    debugM $ "HsPar closing paren"+    rpar' <- markEpToken rpar+    debugM $ "HsPar done"+    return (HsPar (lpar', rpar') e')++  exact (SectionL an expr op) = do+    expr' <- markAnnotated expr+    op' <- markAnnotated op+    return (SectionL an expr' op')++  exact (SectionR an op expr) = do+    op' <- markAnnotated op+    expr' <- markAnnotated expr+    return (SectionR an op' expr')++  exact (ExplicitTuple (o,c) args b) = do+    o0 <- if b == Boxed then printStringAtAA o "("+                        else printStringAtAA o "(#"++    args' <- mapM markAnnotated args++    c0 <- if b == Boxed then printStringAtAA c ")"+                        else printStringAtAA c "#)"+    debugM $ "ExplicitTuple done"+    return (ExplicitTuple (o0,c0) args' b)++  exact (ExplicitSum an alt arity expr) = do+    an0 <- markLensFun an laesOpen (\loc -> printStringAtAA loc "(#")+    an1 <- markLensFun an0 laesBarsBefore (\locs -> mapM markEpToken locs)+    expr' <- markAnnotated expr+    an2 <- markLensFun an1 laesBarsAfter (\locs -> mapM markEpToken locs)+    an3 <- markLensFun an2 laesClose (\loc -> printStringAtAA loc "#)")+    return (ExplicitSum an3 alt arity expr')++  exact (HsCase an e alts) = do+    an0 <- markLensFun an lhsCaseAnnCase markEpToken+    e' <- markAnnotated e+    an1 <- markLensFun an0 lhsCaseAnnOf markEpToken+    alts' <- setLayoutBoth $ markAnnotated alts+    return (HsCase an1 e' alts')++  exact (HsIf an e1 e2 e3) = do+    an0 <- markLensFun an laiIf markEpToken+    e1' <- markAnnotated e1+    an1 <- markLensFun an0 laiThenSemi (\mt -> mapM markEpToken mt)+    an2 <- markLensFun an1 laiThen markEpToken+    e2' <- markAnnotated e2+    an3 <- markLensFun an2 laiElseSemi (\mt -> mapM markEpToken mt)+    an4 <- markLensFun an3 laiElse markEpToken+    e3' <- markAnnotated e3+    return (HsIf an4 e1' e2' e3')++  exact (HsMultiIf (i,o,c) mg) = do+    i0 <- markEpToken i+    o0 <- markEpToken o+    mg' <- markAnnotated mg+    c0 <- markEpToken c+    return (HsMultiIf (i0,o0,c0) mg')++  exact (HsLet (tkLet, tkIn) binds e) = do+    setLayoutBoth $ do -- Make sure the 'in' gets indented too+      tkLet' <- markEpToken tkLet+      binds' <- setLayoutBoth $ markAnnotated binds+      tkIn' <- markEpToken tkIn+      e' <- markAnnotated e+      return (HsLet (tkLet',tkIn') binds' e')++  exact (HsDo an do_or_list_comp stmts) = do+    debugM $ "HsDo"+    (an',stmts') <- markAnnListA' an $ \a -> exactDo a do_or_list_comp stmts+    return (HsDo an' do_or_list_comp stmts')++  exact (ExplicitList an es) = do+    debugM $ "ExplicitList start"+    an0 <- markLensBracketsO' an lal_brackets+    es' <- markAnnotated es+    an1 <- markLensBracketsC' an0 lal_brackets+    debugM $ "ExplicitList end"+    return (ExplicitList an1 es')+  exact (RecordCon (open, close) con_id binds) = do+    con_id' <- markAnnotated con_id+    open' <- mapM markEpToken open+    binds' <- markAnnotated binds+    close' <- mapM markEpToken close+    return (RecordCon (open',close') con_id' binds')+  exact (RecordUpd (open, close) expr fields) = do+    expr' <- markAnnotated expr+    open' <- mapM markEpToken open+    fields' <- markAnnotated fields+    close' <- mapM markEpToken close+    return (RecordUpd (open', close') expr' fields')+  exact (HsGetField an expr field) = do+    expr' <- markAnnotated expr+    field' <- markAnnotated field+    return (HsGetField an expr' field')+  exact (HsProjection an flds) = do+    an0 <- markLensFun an lapOpen markEpToken+    flds' <- mapM markAnnotated flds+    an1 <- markLensFun an0 lapClose markEpToken+    return (HsProjection an1 flds')+  exact (ExprWithTySig an expr sig) = do+    expr' <- markAnnotated expr+    an0 <- markEpUniToken an+    sig' <- markAnnotated sig+    return (ExprWithTySig an0 expr' sig')+  exact (ArithSeq (AnnArithSeq o mc dd c) s seqInfo) = do+    o' <- markEpToken o+    (mc', dd', seqInfo') <-+      case seqInfo of+        From e -> do+          e' <- markAnnotated e+          dd' <- markEpToken dd+          return (mc, dd', From e')+        FromTo e1 e2 -> do+          e1' <- markAnnotated e1+          dd' <- markEpToken dd+          e2' <- markAnnotated e2+          return (mc, dd', FromTo e1' e2')+        FromThen e1 e2 -> do+          e1' <- markAnnotated e1+          mc' <- mapM markEpToken mc+          e2' <- markAnnotated e2+          dd' <- markEpToken dd+          return (mc', dd', FromThen e1' e2')+        FromThenTo e1 e2 e3 -> do+          e1' <- markAnnotated e1+          mc' <- mapM markEpToken mc+          e2' <- markAnnotated e2+          dd' <- markEpToken dd+          e3' <- markAnnotated e3+          return (mc', dd', FromThenTo e1' e2' e3')+    c' <- markEpToken c+    return (ArithSeq (AnnArithSeq o' mc' dd' c') s seqInfo')+++  exact (HsTypedBracket (o,c) e) = do+    o' <- case o of+      BracketNoE  t -> BracketNoE  <$> markEpToken t+      BracketHasE t -> BracketHasE <$> markEpToken t+    e' <- markAnnotated e+    c' <- markEpToken c+    return (HsTypedBracket (o',c') e')++  exact (HsUntypedBracket a (ExpBr (o,c) e)) = do+    o' <- case o of+      BracketNoE  t -> BracketNoE  <$> markEpUniToken t+      BracketHasE t -> BracketHasE <$> markEpToken t+    e' <- markAnnotated e+    c' <- markEpUniToken c+    return (HsUntypedBracket a (ExpBr (o',c') e'))++  exact (HsUntypedBracket a (PatBr (o,c) e)) = do+    o' <- markEpToken o+    e' <- markAnnotated e+    c' <- markEpUniToken c+    return (HsUntypedBracket a (PatBr (o',c') e'))++  exact (HsUntypedBracket a (DecBrL (o,c, (oc,cc)) e)) = do+    o' <- markEpToken o+    oc' <- markEpToken oc+    e' <- markAnnotated e+    cc' <- markEpToken cc+    c' <- markEpUniToken c+    return (HsUntypedBracket a (DecBrL (o',c',(oc',cc')) e'))++  exact (HsUntypedBracket a (TypBr (o,c) e)) = do+    o' <- markEpToken o+    e' <- markAnnotated e+    c' <- markEpUniToken c+    return (HsUntypedBracket a (TypBr (o',c') e'))++  exact (HsUntypedBracket a (VarBr an b e)) = do+    (an0, e') <- if b+      then do+        an' <- printStringAtAA an "'"+        e' <- markAnnotated e+        return (an', e')+      else do+        an' <- printStringAtAA an "''"+        e' <- markAnnotated e+        return (an', e')+    return (HsUntypedBracket a (VarBr an0 b e'))++  exact (HsTypedSplice an s)   = do+    an0 <- markEpToken an+    s' <- markAnnotated s+    return (HsTypedSplice an0 s')++  exact (HsUntypedSplice an s) = do+    s' <- markAnnotated s+    return (HsUntypedSplice an s')++  exact (HsProc (pr,r) p c) = do+    debugM $ "HsProc start"+    pr' <- markEpToken pr+    p' <- markAnnotated p+    r' <- markEpUniToken r+    c' <- markAnnotated c+    return (HsProc (pr',r') p' c')++  exact (HsStatic an e) = do+    an0 <- markEpToken an+    e' <- markAnnotated e+    return (HsStatic an0 e')++  exact (HsPragE a prag e) = do+    prag' <- markAnnotated prag+    e' <- markAnnotated e+    return (HsPragE a prag' e')++  exact (HsEmbTy toktype t) = do+    toktype' <- markEpToken toktype+    t' <- markAnnotated t+    return (HsEmbTy toktype' t')++  exact (HsFunArr _ mult arg res) = do+    arg' <- markAnnotated arg+    mult' <- markArrow mult+    res' <- markAnnotated res+    return (HsFunArr noExtField mult' arg' res')++  exact (HsForAll _ tele body) = do+    tele' <- markAnnotated tele+    body' <- markAnnotated body+    return (HsForAll noExtField tele' body')++  exact (HsQual _ ctxt body) = do+    ctxt' <- markAnnotated ctxt+    body' <- markAnnotated body+    return (HsQual noExtField ctxt' body')++  exact x = error $ "exact HsExpr for:" ++ showAst x++-- ---------------------------------------------------------------------++exactDo :: (Monad m, Monoid w, ExactPrint (LocatedAn an a))+        => AnnList EpaLocation -> HsDoFlavour -> LocatedAn an a+        -> EP w m (AnnList EpaLocation, LocatedAn an a)+exactDo an (DoExpr m)    stmts = exactMdo an m "do"          >>= \an0 -> markMaybeDodgyStmts an0 stmts+exactDo an GhciStmtCtxt  stmts = markLensFun an lal_rest (\l -> printStringAtAA l "do") >>=+                                 \an0 -> markMaybeDodgyStmts an0 stmts+exactDo an (MDoExpr m)   stmts = exactMdo an m  "mdo" >>= \an0 -> markMaybeDodgyStmts an0 stmts+exactDo an ListComp      stmts = markMaybeDodgyStmts an stmts+exactDo an MonadComp     stmts = markMaybeDodgyStmts an stmts++exactMdo :: (Monad m, Monoid w)+  => AnnList EpaLocation -> Maybe ModuleName -> String -> EP w m (AnnList EpaLocation)+exactMdo an Nothing            kw = markLensFun an lal_rest (\l -> printStringAtAA l kw)+exactMdo an (Just module_name) kw = markLensFun an lal_rest (\l -> printStringAtAA l n)+    where+      n = (moduleNameString module_name) ++ "." ++ kw++markMaybeDodgyStmts :: (Monad m, Monoid w, ExactPrint (LocatedAn an a))+  => AnnList l -> LocatedAn an a -> EP w m (AnnList l, LocatedAn an a)+markMaybeDodgyStmts an stmts =+  if notDodgy stmts+    then do+      r <- markAnnotatedWithLayout stmts+      return (an, r)+    else return (an, stmts)++notDodgy :: GenLocated (EpAnn ann) a -> Bool+notDodgy (L (EpAnn anc _ _) _) = notDodgyE anc++notDodgyE :: EpaLocation -> Bool+notDodgyE anc =+  case anc of+    EpaSpan s -> isGoodSrcSpan s+    EpaDelta{} -> True++-- ---------------------------------------------------------------------+instance ExactPrint (HsPragE GhcPs) where+  getAnnotationEntry HsPragSCC{}  = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (HsPragSCC (AnnPragma o c s l1 l2 t m,st) sl) = do+    o' <- markAnnOpen'' o st  "{-# SCC"+    l1' <- printStringAtAA l1 (sourceTextToString (sl_st sl) (unpackFS $ sl_fs sl))+    c' <- markEpToken c+    return (HsPragSCC (AnnPragma o' c' s l1' l2 t m,st) sl)+++-- ---------------------------------------------------------------------++instance ExactPrint (HsUntypedSplice GhcPs) where+  getAnnotationEntry _ = NoEntryVal++  setAnnotationAnchor a _ _  _= a++  exact (HsUntypedSpliceExpr an e) = do+    an0 <- markEpToken an+    e' <- markAnnotated e+    return (HsUntypedSpliceExpr an0 e')++  exact (HsQuasiQuote an q (L l fs)) = do+    -- The quasiquote string does not honour layout offsets. Store+    -- the colOffset for now.+    -- TODO: use local?+    oldOffset <- getLayoutOffsetP+    EPState{pMarkLayout} <- get+    unless pMarkLayout $ setLayoutOffsetP 0+    printStringAdvance+            -- Note: Lexer.x does not provide unicode alternative. 2017-02-26+            ("[" ++ (showPprUnsafe q) ++ "|" ++ (unpackFS fs) ++ "|]")+    unless pMarkLayout $ setLayoutOffsetP oldOffset+    return (HsQuasiQuote an q (L l fs))++-- ---------------------------------------------------------------------++-- TODO:AZ: combine these instances+instance ExactPrint (MatchGroup GhcPs (LocatedA (HsExpr GhcPs))) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact (MG x matches) = do+    -- TODO:AZ use SortKey, in MG ann.+    matches' <- markAnnotated matches+    return (MG x matches')++instance ExactPrint (MatchGroup GhcPs (LocatedA (HsCmd GhcPs))) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact (MG x matches) = do+    -- TODO:AZ use SortKey, in MG ann.+    matches' <- if notDodgy matches+      then markAnnotated matches+      else return matches+    return (MG x matches')++-- ---------------------------------------------------------------------++instance (ExactPrint body) => ExactPrint (HsRecFields GhcPs body) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact (HsRecFields x fields mdot) = do+    fields' <- markAnnotated fields+    mdot' <- case mdot of+      Nothing -> return Nothing+      Just (L ss d) -> do+        ss' <- printStringAtAA ss ".."+        return $ Just (L ss' d)+      -- Note: mdot contains the SrcSpan where the ".." appears, if present+    return (HsRecFields x fields' mdot')++-- ---------------------------------------------------------------------++instance (ExactPrint body)+    => ExactPrint (HsFieldBind (LocatedA (FieldOcc GhcPs)) body) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (HsFieldBind an f arg isPun) = do+    debugM $ "HsFieldBind"+    f' <- markAnnotated f+    (an0, arg') <- if isPun then return (an, arg)+             else do+               an0 <- mapM markEpToken an+               arg' <- markAnnotated arg+               return (an0, arg')+    return (HsFieldBind an0 f' arg' isPun)++-- ---------------------------------------------------------------------++instance (ExactPrint body)+    => ExactPrint (HsFieldBind (LocatedAn NoEpAnns (FieldLabelStrings GhcPs)) body) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (HsFieldBind an f arg isPun) = do+    debugM $ "HsFieldBind FieldLabelStrings"+    f' <- markAnnotated f+    (an0, arg') <- if isPun then return (an, arg)+             else do+               an0 <- mapM markEpToken an+               arg' <- markAnnotated arg+               return (an0, arg')+    return (HsFieldBind an0 f' arg' isPun)++-- ---------------------------------------------------------------------++instance ExactPrint (LHsRecUpdFields GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact flds@(RegularRecUpdFields    { recUpdFields  = rbinds }) = do+    debugM $ "RegularRecUpdFields"+    rbinds' <- markAnnotated rbinds+    return $ flds { recUpdFields = rbinds' }+  exact flds@(OverloadedRecUpdFields { olRecUpdFields = pbinds }) = do+    debugM $ "OverloadedRecUpdFields"+    pbinds' <- markAnnotated pbinds+    return $ flds { olRecUpdFields = pbinds' }++-- ---------------------------------------------------------------------++instance ExactPrint (FieldLabelStrings GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact (FieldLabelStrings fs) = FieldLabelStrings <$> markAnnotated fs++-- ---------------------------------------------------------------------++instance ExactPrint (DotFieldOcc GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (DotFieldOcc an (L loc (FieldLabelString fs))) = do+    an0 <- markLensFun an lafDot (\ml -> mapM markEpToken ml)+    -- The field name has a SrcSpanAnnN, print it as a+    -- LocatedN RdrName+    L loc' _ <- markAnnotated (L loc (mkVarUnqual fs))+    return (DotFieldOcc an0 (L loc' (FieldLabelString fs)))++-- ---------------------------------------------------------------------++instance ExactPrint (HsTupArg GhcPs) where+  getAnnotationEntry (Present _ _) = NoEntryVal+  getAnnotationEntry (Missing (EpAnn _ False _)) = NoEntryVal+  getAnnotationEntry (Missing an)   = fromAnn an++  setAnnotationAnchor (Present a b) _ _ _ = Present a b+  setAnnotationAnchor (Missing an)   anc ts cs = Missing (setAnchorEpa an anc ts cs)++  exact (Present a e) = Present a <$> markAnnotated e++  exact a@(Missing (EpAnn _ False _)) = return a+  exact a@(Missing _) = printStringAdvance "," >> return a++-- ---------------------------------------------------------------------++instance ExactPrint (HsCmdTop GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact (HsCmdTop a cmd) = HsCmdTop a <$> markAnnotated cmd++-- ---------------------------------------------------------------------++instance ExactPrint (HsCmd GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (HsCmdArrApp (isU, l) arr arg HsFirstOrderApp True) = do+    arr' <- markAnnotated arr+    l' <- case isU of+      UnicodeSyntax -> printStringAtAA l  "⤙"+      NormalSyntax -> printStringAtAA l  "-<"+    arg' <- markAnnotated arg+    return (HsCmdArrApp (isU, l') arr' arg' HsFirstOrderApp True)+  exact (HsCmdArrApp (isU, l) arr arg HsFirstOrderApp False) = do+    arg' <- markAnnotated arg+    l' <- case isU of+      UnicodeSyntax -> printStringAtAA l  "⤚"+      NormalSyntax -> printStringAtAA l  ">-"+    arr' <- markAnnotated arr+    return (HsCmdArrApp (isU, l') arr' arg' HsFirstOrderApp False)+  exact (HsCmdArrApp (isU, l) arr arg HsHigherOrderApp True) = do+    arr' <- markAnnotated arr+    l' <- case isU of+      UnicodeSyntax -> printStringAtAA l  "⤛"+      NormalSyntax -> printStringAtAA l  "-<<"+    arg' <- markAnnotated arg+    return (HsCmdArrApp (isU, l') arr' arg' HsHigherOrderApp True)+  exact (HsCmdArrApp (isU, l) arr arg HsHigherOrderApp False) = do+    arg' <- markAnnotated arg+    l' <- case isU of+      UnicodeSyntax -> printStringAtAA l  "⤜"+      NormalSyntax -> printStringAtAA l  ">>-"+    arr' <- markAnnotated arr+    return (HsCmdArrApp (isU, l') arr' arg' HsHigherOrderApp False)++  exact (HsCmdArrForm an e fixity cs) = do+    an0 <- markLensBracketsO' an lal_brackets+    (e',cs') <- case (fixity, cs) of+      (Infix, (arg1:argrest)) -> do+        arg1' <- markAnnotated arg1+        e' <- markAnnotated e+        argrest' <- markAnnotated argrest+        return (e', arg1':argrest')+      (Prefix, _) -> do+        e' <- markAnnotated e+        cs' <- markAnnotated cs+        return (e', cs')+      (Infix, []) -> error "Not possible"+    an1 <- markLensBracketsC' an0 lal_brackets+    return (HsCmdArrForm an1 e' fixity cs')++  exact (HsCmdApp an e1 e2) = do+    e1' <- markAnnotated e1+    e2' <- markAnnotated e2+    return (HsCmdApp an e1' e2')++  exact (HsCmdLam an lam_variant matches) = do+    an0 <- markLensFun an lepl_lambda markEpToken+    an1 <- case lam_variant of+             LamSingle -> return an0+             LamCase -> markLensFun an0 lepl_case (\ml -> mapM (\l -> printStringAtAA l "case") ml)+             LamCases -> markLensFun an0 lepl_case (\ml -> mapM (\l -> printStringAtAA l "cases") ml)+    matches' <- markAnnotated matches+    return (HsCmdLam an1 lam_variant matches')++  exact (HsCmdPar (lpar, rpar) e) = do+    lpar' <- markEpToken lpar+    e' <- markAnnotated e+    rpar' <- markEpToken rpar+    return (HsCmdPar (lpar', rpar') e')++  exact (HsCmdCase an e alts) = do+    an0 <- markLensFun an lhsCaseAnnCase markEpToken+    e' <- markAnnotated e+    an1 <- markLensFun an0 lhsCaseAnnOf markEpToken+    alts' <- markAnnotated alts+    return (HsCmdCase an1 e' alts')++  exact (HsCmdIf an a e1 e2 e3) = do+    an0 <- markLensFun an laiIf markEpToken+    e1' <- markAnnotated e1+    an1 <- markLensFun an0 laiThenSemi (\mt -> mapM markEpToken mt)+    an2 <- markLensFun an1 laiThen markEpToken+    e2' <- markAnnotated e2+    an3 <- markLensFun an2 laiElseSemi (\mt -> mapM markEpToken mt)+    an4 <- markLensFun an3 laiElse markEpToken+    e3' <- markAnnotated e3+    return (HsCmdIf an4 a e1' e2' e3')++  exact (HsCmdLet (tkLet, tkIn) binds e) = do+    setLayoutBoth $ do -- Make sure the 'in' gets indented too+      tkLet' <- markEpToken tkLet+      binds' <- setLayoutBoth $ markAnnotated binds+      tkIn' <- markEpToken tkIn+      e' <- markAnnotated e+      return (HsCmdLet (tkLet', tkIn') binds' e')++  exact (HsCmdDo an es) = do+    debugM $ "HsCmdDo"+    an0 <- markLensFun an lal_rest (\l -> printStringAtAA l "do")+    es' <- markAnnotated es+    return (HsCmdDo an0 es')++-- ---------------------------------------------------------------------++instance (+  ExactPrint (LocatedA (body GhcPs)),+                 Anno (StmtLR GhcPs GhcPs (LocatedA (body GhcPs))) ~ SrcSpanAnnA,+           Anno [GenLocated SrcSpanAnnA (StmtLR GhcPs GhcPs (LocatedA (body GhcPs)))] ~ SrcSpanAnnLW,+           (ExactPrint (LocatedLW [LocatedA (StmtLR GhcPs GhcPs (LocatedA (body GhcPs)))])))+   => ExactPrint (StmtLR GhcPs GhcPs (LocatedA (body GhcPs))) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _s = a++  exact (LastStmt a body b c) = do+    debugM $ "LastStmt"+    body' <- markAnnotated body+    return (LastStmt a body' b c)++  exact (BindStmt an pat body) = do+    debugM $ "BindStmt"+    pat' <- markAnnotated pat+    an0 <- markEpUniToken an+    body' <- markAnnotated body+    return (BindStmt an0 pat' body')++  exact (BodyStmt a body b c) = do+    debugM $ "BodyStmt"+    body' <- markAnnotated body+    return (BodyStmt a body' b c)++  exact (LetStmt tlet binds) = do+    debugM $ "LetStmt"+    tlet' <- markEpToken tlet+    binds' <- markAnnotated binds+    return (LetStmt tlet' binds')++  exact (ParStmt a pbs b c) = do+    debugM $ "ParStmt"+    pbs' <- markAnnotated pbs+    return (ParStmt a pbs' b c)++  exact (TransStmt an form stmts b using by c d e) = do+    debugM $ "TransStmt"+    stmts' <- markAnnotated stmts+    (an', by', using') <- exactTransStmt an by using form+    return (TransStmt an' form stmts' b using' by' c d e)++  exact (RecStmt an stmts a b c d e) = do+    debugM $ "RecStmt"+    an0 <- markLensFun an lal_rest markEpToken+    (an1, stmts') <- markAnnList' an0 (markAnnotated stmts)+    return (RecStmt an1 stmts' a b c d e)++-- ---------------------------------------------------------------------++instance ExactPrint (ParStmtBlock GhcPs GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact (ParStmtBlock a stmts b c) = do+    stmts' <- markAnnotated stmts+    return (ParStmtBlock a stmts' b c)++exactTransStmt :: (Monad m, Monoid w)+  => AnnTransStmt -> Maybe (LHsExpr GhcPs) -> (LHsExpr GhcPs) -> TransForm+  -> EP w m (AnnTransStmt, Maybe (LHsExpr GhcPs), (LHsExpr GhcPs))+exactTransStmt (AnnTransStmt at ag ab au) by using ThenForm = do+  debugM $ "exactTransStmt:ThenForm"+  at' <- markEpToken at+  using' <- markAnnotated using+  case by of+    Nothing -> return (AnnTransStmt at' ag ab au, by, using')+    Just b -> do+      ab' <- mapM markEpToken ab+      b' <- markAnnotated b+      return ((AnnTransStmt at' ag ab' au), Just b', using')+exactTransStmt (AnnTransStmt at ag ab au) by using GroupForm = do+  debugM $ "exactTransStmt:GroupForm"+  at' <- markEpToken at+  ag' <- mapM markEpToken ag+  (ab', by') <- case by of+    Nothing -> return (ab, by)+    Just b -> do+      ab0 <- mapM markEpToken ab+      b' <- markAnnotated b+      return (ab0, Just b')+  au' <- mapM markEpToken au+  using' <- markAnnotated using+  return (AnnTransStmt at' ag' ab' au', by', using')++-- ---------------------------------------------------------------------++instance ExactPrint (TyClDecl GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _s = a++  exact (FamDecl a decl) = do+    decl' <- markAnnotated decl+    return (FamDecl a decl')++  exact (SynDecl { tcdSExt = AnnSynDecl ops cps t eq+                 , tcdLName = ltycon, tcdTyVars = tyvars, tcdFixity = fixity+                 , tcdRhs = rhs }) = do+    -- There may be arbitrary parens around parts of the constructor+    -- that are infix.  Turn these into comments so that they feed+    -- into the right place automatically+    -- TODO: no longer sorting on insert. What now?+    epTokensToComments "(" ops+    epTokensToComments ")" cps+    t' <- markEpToken t++    (_,ltycon', tyvars',_,_) <- exactVanillaDeclHead ltycon tyvars fixity Nothing+    eq' <- markEpToken eq+    rhs' <- markAnnotated rhs+    return (SynDecl { tcdSExt = AnnSynDecl [] [] t' eq'+                    , tcdLName = ltycon', tcdTyVars = tyvars', tcdFixity = fixity+                    , tcdRhs = rhs' })++  exact (DataDecl { tcdDExt = x, tcdLName = ltycon, tcdTyVars = tyvars+                  , tcdFixity = fixity, tcdDataDefn = defn }) = do+    (_,ltycon', tyvars', _, defn') <-+      exactDataDefn (exactVanillaDeclHead ltycon tyvars fixity) defn+    return (DataDecl { tcdDExt = x, tcdLName = ltycon', tcdTyVars = tyvars'+                     , tcdFixity = fixity, tcdDataDefn = defn' })++  -- -----------------------------------++  exact (ClassDecl {tcdCExt = (AnnClassDecl c ops cps vb w oc cc semis, lo, sortKey),+                    tcdCtxt = context, tcdLName = lclas, tcdTyVars = tyvars,+                    tcdFixity = fixity,+                    tcdFDs  = fds,+                    tcdSigs = sigs, tcdMeths = methods,+                    tcdATs = ats, tcdATDefs = at_defs,+                    tcdDocs = _docs})+      -- TODO: add a test that demonstrates tcdDocs+      | null sigs && null methods && null ats && null at_defs -- No "where" part+      = do+          (c', w', vb', fds', lclas', tyvars',context') <- top_matter+          oc' <- markEpToken oc+          cc' <- markEpToken cc+          return (ClassDecl {tcdCExt = (AnnClassDecl c' [] [] vb' w' oc' cc' semis, lo, sortKey),+                             tcdCtxt = context', tcdLName = lclas', tcdTyVars = tyvars',+                             tcdFixity = fixity,+                             tcdFDs  = fds',+                             tcdSigs = sigs, tcdMeths = methods,+                             tcdATs = ats, tcdATDefs = at_defs,+                             tcdDocs = _docs})++      | otherwise       -- Laid out+      = do+          (c', w', vb', fds', lclas', tyvars',context') <- top_matter+          oc' <- markEpToken oc+          semis' <- mapM markEpToken semis+          (sortKey', ds) <- withSortKey sortKey+                               [(ClsSigTag, prepareListAnnotationA sigs),+                                (ClsMethodTag, prepareListAnnotationA methods),+                                (ClsAtTag, prepareListAnnotationA ats),+                                (ClsAtdTag, prepareListAnnotationA at_defs)+                             -- ++ prepareListAnnotation docs+                               ]+          cc' <- markEpToken cc+          let+            sigs'    = undynamic ds+            methods' = undynamic ds+            ats'     = undynamic ds+            at_defs' = undynamic ds+          return (ClassDecl {tcdCExt = (AnnClassDecl c' [] [] vb' w' oc' cc' semis', lo, sortKey'),+                             tcdCtxt = context', tcdLName = lclas', tcdTyVars = tyvars',+                             tcdFixity = fixity,+                             tcdFDs  = fds',+                             tcdSigs = sigs', tcdMeths = methods',+                             tcdATs = ats', tcdATDefs = at_defs',+                             tcdDocs = _docs})+      where+        top_matter = do+          epTokensToComments "(" ops+          epTokensToComments ")" cps+          c' <- markEpToken c+          (_,lclas', tyvars',_,context') <- exactVanillaDeclHead lclas tyvars fixity context+          (vb', fds') <- if (null fds)+            then return (vb, fds)+            else do+              vb' <- markEpToken vb+              fds' <- markAnnotated fds+              return (vb', fds')+          w' <- markEpToken w+          return (c', w', vb', fds', lclas', tyvars',context')+++-- ---------------------------------------------------------------------++instance ExactPrint (FunDep GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (FunDep an ls rs') = do+    ls' <- markAnnotated ls+    an0 <- markEpUniToken an+    rs'' <- markAnnotated rs'+    return (FunDep an0 ls' rs'')++-- ---------------------------------------------------------------------++instance ExactPrint (FamilyDecl GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (FamilyDecl { fdExt = AnnFamilyDecl ops cps t d f dc eq vb w oc dd cc+                    , fdInfo = info+                    , fdTopLevel = top_level+                    , fdLName = ltycon+                    , fdTyVars = tyvars+                    , fdFixity = fixity+                    , fdResultSig = L lr result+                    , fdInjectivityAnn = mb_inj }) = do+    (d',t') <- exactFlavour (d,t) info+    f' <- exact_top_level f++    epTokensToComments "(" ops+    epTokensToComments ")" cps+    (_,ltycon', tyvars',_,_) <- exactVanillaDeclHead ltycon tyvars fixity Nothing+    (dc', eq', result') <- exact_kind (dc, eq)+    (vb', mb_inj') <-+      case mb_inj of+        Nothing -> return (vb, mb_inj)+        Just inj -> do+          vb' <- markEpToken vb+          inj' <- markAnnotated inj+          return (vb', Just inj')+    (w', oc', dd', cc', info') <-+             case info of+               ClosedTypeFamily mb_eqns -> do+                 w' <- markEpToken w+                 oc' <- markEpToken oc+                 (dd', mb_eqns') <-+                   case mb_eqns of+                     Nothing -> do+                       dd' <- markEpToken dd+                       return (dd', mb_eqns)+                     Just eqns -> do+                       eqns' <- markAnnotated eqns+                       return (dd, Just eqns')+                 cc' <- markEpToken cc+                 return (w',oc',dd',cc', ClosedTypeFamily mb_eqns')+               _ -> return (w,oc,dd,cc, info)+    return (FamilyDecl { fdExt = AnnFamilyDecl [] [] t' d' f' dc' eq' vb' w' oc' dd' cc'+                       , fdInfo = info'+                       , fdTopLevel = top_level+                       , fdLName = ltycon'+                       , fdTyVars = tyvars'+                       , fdFixity = fixity+                       , fdResultSig = L lr result'+                       , fdInjectivityAnn = mb_inj' })+    where+      exact_top_level tfamily =+        case top_level of+          TopLevel    -> markEpToken tfamily+          NotTopLevel -> do+            -- It seems that in some kind of legacy+            -- mode the 'family' keyword is still+            -- accepted.+            markEpToken tfamily++      exact_kind (tdcolon, tequal) =+        case result of+          NoSig    _         -> return (tdcolon, tequal, result)+          KindSig  x kind    -> do+            tdcolon' <- markEpUniToken tdcolon+            kind' <- markAnnotated kind+            return (tdcolon', tequal, KindSig  x kind')+          TyVarSig x tv_bndr -> do+            tequal' <- markEpToken tequal+            tv_bndr' <- markAnnotated tv_bndr+            return (tdcolon, tequal', TyVarSig x tv_bndr')+++exactFlavour :: (Monad m, Monoid w) => (EpToken "data", EpToken "type") -> FamilyInfo GhcPs -> EP w m (EpToken "data", EpToken "type")+exactFlavour (td,tt) DataFamily            = (\td' -> (td',tt)) <$> markEpToken td+exactFlavour (td,tt) OpenTypeFamily        = (td,)              <$> markEpToken tt+exactFlavour (td,tt) (ClosedTypeFamily {}) = (td,)              <$> markEpToken tt++-- ---------------------------------------------------------------------++exactDataDefn+  :: (Monad m, Monoid w)+  => (Maybe (LHsContext GhcPs) -> EP w m (r+                                         , LocatedN RdrName+                                         , a+                                         , b+                                         , Maybe (LHsContext GhcPs))) -- Printing the header+  -> HsDataDefn GhcPs+  -> EP w m ( r -- ^ from exactHdr+            , LocatedN RdrName, a, b, HsDataDefn GhcPs)+exactDataDefn exactHdr+                 (HsDataDefn { dd_ext = AnnDataDefn ops cps t nt d i dc w oc cc eq+                             , dd_ctxt = context+                             , dd_cType = mb_ct+                             , dd_kindSig = mb_sig+                             , dd_cons = condecls, dd_derivs = derivings }) = do+++  epTokensToComments "(" ops+  epTokensToComments ")" cps++  (t',nt',d') <- case condecls of+    DataTypeCons is_type_data _ -> do+      t' <- if is_type_data+                then markEpToken t+                else return t+      d' <- markEpToken d+      return (t',nt,d')+    NewTypeCon   _ -> do+      nt' <- markEpToken nt+      return (t, nt', d)++  i' <- markEpToken i -- optional 'instance'+  mb_ct' <- mapM markAnnotated mb_ct+  (anx, ln', tvs', b, mctxt') <- exactHdr context+  (dc', mb_sig') <- case mb_sig of+    Nothing -> return (dc, Nothing)+    Just kind -> do+      dc' <- markEpUniToken dc+      kind' <- markAnnotated kind+      return (dc', Just kind')+  w' <- if (needsWhere condecls)+    then markEpToken w+    else return w+  oc' <- markEpToken oc+  (eq', condecls') <- exact_condecls eq (toList condecls)+  let condecls'' = case condecls of+        DataTypeCons td _ -> DataTypeCons td condecls'+        NewTypeCon _     -> case condecls' of+          [decl] -> NewTypeCon decl+          _ -> panic "exacprint NewTypeCon"+  cc' <- markEpToken cc+  derivings' <- mapM markAnnotated derivings+  return (anx, ln', tvs', b,+                 (HsDataDefn { dd_ext = AnnDataDefn [] [] t' nt' d' i' dc' w' oc' cc' eq'+                             , dd_ctxt = mctxt'+                             , dd_cType = mb_ct'+                             , dd_kindSig = mb_sig'+                             , dd_cons = condecls'', dd_derivs = derivings' }))+++exactVanillaDeclHead :: (Monad m, Monoid w)+                     => LocatedN RdrName+                     -> LHsQTyVars GhcPs+                     -> LexicalFixity+                     -> Maybe (LHsContext GhcPs)+                     -> EP w m ( () -- TO allow use in exactDataDefn+                               , LocatedN RdrName+                               , LHsQTyVars GhcPs+                               , (), Maybe (LHsContext GhcPs))+exactVanillaDeclHead thing tvs@(HsQTvs { hsq_explicit = tyvars }) fixity context = do+  let+    exact_tyvars (varl:varsr)+      | hvarsr : tvarsr@(_ : _) <- varsr+      , fixity == Infix = do+          varl' <- markAnnotated varl+          thing' <- markAnnotated thing+          hvarsr' <- markAnnotated hvarsr+          tvarsr' <- markAnnotated tvarsr+          return (thing', varl':hvarsr':tvarsr')+      | fixity == Infix = do+          varl' <- markAnnotated varl+          thing' <- markAnnotated thing+          varsr' <- markAnnotated varsr+          return (thing', varl':varsr')+      | otherwise = do+          thing' <- markAnnotated thing+          vs <- mapM markAnnotated (varl:varsr)+          return (thing', vs)+    exact_tyvars [] = do+      thing' <- markAnnotated thing+      return (thing', [])+  context' <- mapM markAnnotated context+  (thing', tyvars') <- exact_tyvars tyvars+  return ((), thing', tvs { hsq_explicit = tyvars' }, (), context')++-- ---------------------------------------------------------------------++instance ExactPrint (InjectivityAnn GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact (InjectivityAnn rarrow lhs rhs) = do+    lhs' <- markAnnotated lhs+    rarrow' <- markEpUniToken rarrow+    rhs' <- mapM markAnnotated rhs+    return (InjectivityAnn rarrow' lhs' rhs')++-- ---------------------------------------------------------------------++class Typeable flag => ExactPrintTVFlag flag where+  exactTVDelimiters :: (Monad m, Monoid w)+    => AnnTyVarBndr -> flag+    -> EP w m (HsTyVarBndr flag GhcPs)+    -> EP w m (AnnTyVarBndr, flag, HsTyVarBndr flag GhcPs)++instance ExactPrintTVFlag () where+  exactTVDelimiters (AnnTyVarBndr os cs ap dc) flag thing_inside = do+    os' <- markEpaLocationAll os "("+    r <- thing_inside+    cs' <- markEpaLocationAll cs ")"+    return (AnnTyVarBndr os' cs' ap dc, flag, r)++instance ExactPrintTVFlag Specificity where+  exactTVDelimiters (AnnTyVarBndr os cs ap dc) s thing_inside = do+    os' <- markEpaLocationAll os open+    r <- thing_inside+    cs' <- markEpaLocationAll cs close+    return (AnnTyVarBndr os' cs' ap dc, s, r)+    where+      (open, close) = case s of+        SpecifiedSpec -> ("(", ")")+        InferredSpec  -> ("{", "}")++instance ExactPrintTVFlag (HsBndrVis GhcPs) where+  exactTVDelimiters (AnnTyVarBndr os cs ap dc) bvis thing_inside = do+    bvis' <- case bvis of+      HsBndrRequired _ -> return bvis+      HsBndrInvisible at -> HsBndrInvisible <$> markEpToken at+    os' <- markEpaLocationAll os "("+    r <- thing_inside+    cs' <- markEpaLocationAll cs ")"+    return (AnnTyVarBndr os' cs' ap dc, bvis', r)++instance ExactPrintTVFlag flag => ExactPrint (HsTyVarBndr flag GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (HsTvb an flag n (HsBndrNoKind _)) = do+    r <- exactTVDelimiters an flag $  do+           n' <- markAnnotated n+           return (HsTvb an flag n' (HsBndrNoKind noExtField))+    case r of+      (an', flag', HsTvb _ _ n'' k'') -> return (HsTvb an' flag' n'' k'')++  exact (HsTvb an@(AnnTyVarBndr os cs ap dc) flag n (HsBndrKind _ k)) = do+    r <- exactTVDelimiters an flag $ do+          n' <- markAnnotated n+          dc' <- markEpUniToken dc+          k' <- markAnnotated k+          let an0 = AnnTyVarBndr os cs ap dc'+          return (HsTvb an0 flag n' (HsBndrKind noExtField k'))+    case r of+      (an',flag', HsTvb an1 _ n'' k'') -> return (HsTvb (an'{ atv_dcolon = atv_dcolon an1 }) flag' n'' k'')++instance ExactPrint (HsBndrVar GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (HsBndrVar x n) = do+    n' <- markAnnotated n+    return (HsBndrVar x n')+  exact (HsBndrWildCard t) = do+    t' <- markEpToken t+    return (HsBndrWildCard t')++-- ---------------------------------------------------------------------++instance ExactPrint (HsType GhcPs) where+  getAnnotationEntry _         = NoEntryVal+  setAnnotationAnchor a _ _ _s = a++  exact (HsForAllTy { hst_xforall = an+                    , hst_tele = tele, hst_body = ty }) = do+    tele' <- markAnnotated tele+    ty' <- markAnnotated ty+    return (HsForAllTy { hst_xforall = an+                       , hst_tele = tele', hst_body = ty' })++  exact (HsQualTy an ctxt ty) = do+    ctxt' <- markAnnotated ctxt+    ty' <- markAnnotated ty+    return (HsQualTy an ctxt' ty')+  exact (HsTyVar an promoted name) = do+    an0 <- if (promoted == IsPromoted)+             then markEpToken an+             else return an+    name' <- markAnnotated name+    return (HsTyVar an0 promoted name')+  exact (HsAppTy an t1 t2) = do+    t1' <- markAnnotated t1+    t2' <- markAnnotated t2+    return (HsAppTy an t1' t2')+  exact (HsAppKindTy at ty ki) = do+    ty' <- markAnnotated ty+    at' <- markEpToken at+    ki' <- markAnnotated ki+    return (HsAppKindTy at' ty' ki')+  exact (HsFunTy an mult ty1 ty2) = do+    ty1' <- markAnnotated ty1+    mult' <- markArrow mult+    ty2' <- markAnnotated ty2+    return (HsFunTy an mult' ty1' ty2')+  exact (HsListTy an tys) = do+    an0 <- markOpeningParen an+    tys' <- markAnnotated tys+    an1 <- markClosingParen an0+    return (HsListTy an1 tys')+  exact (HsTupleTy an con tys) = do+    an0 <- markOpeningParen an+    tys' <- markAnnotated tys+    an1 <- markClosingParen an0+    return (HsTupleTy an1 con tys')+  exact (HsSumTy an tys) = do+    an0 <- markOpeningParen an+    tys' <- markAnnotated tys+    an1 <- markClosingParen an0+    return (HsSumTy an1 tys')+  exact (HsOpTy x promoted t1 lo t2) = do+    t1' <- markAnnotated t1+    lo' <- markAnnotated lo+    t2' <- markAnnotated t2+    return (HsOpTy x promoted t1' lo' t2')+  exact (HsParTy (o,c) ty) = do+    o' <- markEpToken o+    ty' <- markAnnotated ty+    c' <- markEpToken c+    return (HsParTy (o',c') ty')+  exact (HsIParamTy an n t) = do+    n' <- markAnnotated n+    an0 <- markEpUniToken an+    t' <- markAnnotated t+    return (HsIParamTy an0 n' t')+  exact (HsStarTy an isUnicode) = do+    if isUnicode+        then printStringAdvance "\x2605" -- Unicode star+        else printStringAdvance "*"+    return (HsStarTy an isUnicode)+  exact (HsKindSig an ty k) = do+    ty' <- markAnnotated ty+    an0 <- markEpUniToken an+    k' <- markAnnotated k+    return (HsKindSig an0 ty' k')+  exact (HsSpliceTy a splice) = do+    splice' <- markAnnotated splice+    return (HsSpliceTy a splice')+  exact (HsDocTy an ty doc) = do+    ty' <- markAnnotated ty+    return (HsDocTy an ty' doc)+  exact (HsBangTy ((o,c,tk), mt) (HsBang up str) ty) = do+    (o',c') <-+      case mt of+        NoSourceText -> return (o,c)+        SourceText src -> do+          debugM $ "HsBangTy: src=" ++ showAst src+          o' <- printStringAtAA o (unpackFS src)+          c' <- markEpToken c+          return (o',c')+    tk' <-+      case str of+        SrcLazy     -> printStringAtAA tk "~"+        SrcStrict   -> printStringAtAA tk "!"+        NoSrcStrict -> return tk+    ty' <- markAnnotated ty+    return (HsBangTy ((o',c',tk'), mt) (HsBang up str) ty')+  exact (HsExplicitListTy (sq,o,c) prom tys) = do+    sq' <- if (isPromoted prom)+             then markEpToken sq+             else return sq+    o' <- markEpToken o+    tys' <- markAnnotated tys+    c' <- markEpToken c+    return (HsExplicitListTy (sq',o',c') prom tys')+  exact (HsExplicitTupleTy (sq, o, c) prom tys) = do+    sq' <- if (isPromoted prom)+              then markEpToken sq+              else return sq+    o' <- markEpToken o+    tys' <- markAnnotated tys+    c' <- markEpToken c+    return (HsExplicitTupleTy (sq', o', c') prom tys')+  exact (HsTyLit a lit) = do+    case lit of+      (HsNumTy src v) -> printSourceText src (show v)+      (HsStrTy src v) -> printSourceText src (show v)+      (HsCharTy src v) -> printSourceText src (show v)+    return (HsTyLit a lit)+  exact t@(HsWildCardTy _) = printStringAdvance "_" >> return t+  exact x = error $ "missing match for HsType:" ++ showAst x++-- ---------------------------------------------------------------------++instance ExactPrint (HsForAllTelescope GhcPs) where+  getAnnotationEntry (HsForAllVis an _)   = fromAnn an+  getAnnotationEntry (HsForAllInvis an _) = fromAnn an++  setAnnotationAnchor (HsForAllVis an a) anc ts cs = HsForAllVis (setAnchorEpa an anc ts cs) a+  setAnnotationAnchor (HsForAllInvis an a) anc ts cs = HsForAllInvis (setAnchorEpa an anc ts cs) a++  exact (HsForAllVis (EpAnn l (f,r) cs) bndrs)   = do+    f' <- markEpUniToken f+    bndrs' <- markAnnotated bndrs+    r' <- markEpUniToken r+    return (HsForAllVis (EpAnn l (f',r') cs) bndrs')++  exact (HsForAllInvis (EpAnn l (f,d) cs) bndrs) = do+    f' <- markEpUniToken f+    bndrs' <- markAnnotated bndrs+    d' <- markEpToken d+    return (HsForAllInvis (EpAnn l (f',d') cs) bndrs')++-- ---------------------------------------------------------------------++instance ExactPrint (HsDerivingClause GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (HsDerivingClause { deriv_clause_ext      = an+                          , deriv_clause_strategy = dcs+                          , deriv_clause_tys      = dct }) = do+    an0 <- markEpToken an+    dcs0 <- case dcs of+            Just (L _ ViaStrategy{}) -> return dcs+            _ -> mapM markAnnotated dcs+    dct' <- markAnnotated dct+    dcs1 <- case dcs0 of+            Just (L _ ViaStrategy{}) -> mapM markAnnotated dcs0+            _ -> return dcs0+    return (HsDerivingClause { deriv_clause_ext      = an0+                             , deriv_clause_strategy = dcs1+                             , deriv_clause_tys      = dct' })++-- ---------------------------------------------------------------------++instance ExactPrint (DerivStrategy GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (StockStrategy an)    = do+    an0 <- markEpToken an+    return (StockStrategy an0)+  exact (AnyclassStrategy an) = do+    an0 <- markEpToken an+    return (AnyclassStrategy an0)+  exact (NewtypeStrategy an)  = do+    an0 <- markEpToken an+    return (NewtypeStrategy an0)+  exact (ViaStrategy (XViaStrategyPs an ty)) = do+    an0 <- markEpToken an+    ty' <- markAnnotated ty+    return (ViaStrategy (XViaStrategyPs an0 ty'))++-- ---------------------------------------------------------------------++instance (ExactPrint a) => ExactPrint (LocatedC a) where+  getAnnotationEntry (L sann _) = fromAnn sann+  setAnnotationAnchor = setAnchorAn++  exact (L (EpAnn anc (AnnContext ma opens closes) cs) a) = do+    opens' <- mapM markEpToken opens+    a' <- markAnnotated a+    closes' <- mapM markEpToken closes+    return (L (EpAnn anc (AnnContext ma opens' closes') cs) a')++-- ---------------------------------------------------------------------++instance ExactPrint (DerivClauseTys GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (DctSingle x ty) = do+    ty' <- markAnnotated ty+    return (DctSingle x ty')+  exact (DctMulti x tys) = do+    tys' <- markAnnotated tys+    return (DctMulti x tys')++-- ---------------------------------------------------------------------++instance ExactPrint (HsSigType GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (HsSig a bndrs ty) = do+    bndrs' <- markAnnotated bndrs+    ty' <- markAnnotated ty+    return (HsSig a bndrs' ty')++-- ---------------------------------------------------------------------++instance ExactPrint (LocatedN RdrName) where+  getAnnotationEntry (L sann _) = fromAnn sann+  setAnnotationAnchor = setAnchorAn++  exact (L (EpAnn anc ann cs) n) = do+    ann' <-+      case ann of+        NameAnn a l t -> do+          mn <- markName a (Just (l,n))+          case mn of+            (a', (Just (l',_n))) -> do+              return (NameAnn a' l' t)+            _ -> error "ExactPrint (LocatedN RdrName)"+        NameAnnCommas a commas t -> do+          a0 <- markNameAdornmentO a+          commas' <- forM commas markEpToken+          a1 <- markNameAdornmentC a0+          return (NameAnnCommas a1 commas' t)+        NameAnnBars (o,c) bars t -> do+          o' <- markEpToken o+          bars' <- mapM markEpToken bars+          c' <- markEpToken c+          return (NameAnnBars (o',c') bars' t)+        NameAnnOnly a t -> do+          (a',_) <- markName a Nothing+          return (NameAnnOnly a' t)+        NameAnnRArrow o nl c t -> do+          o' <- mapM markEpToken o+          nl' <- markEpUniToken nl+          c' <- mapM markEpToken c+          return (NameAnnRArrow o' nl' c' t)+        NameAnnQuote q name t -> do+          debugM $ "NameAnnQuote"+          q' <- markEpToken q+          (L name' _) <- markAnnotated (L name n)+          return (NameAnnQuote q' name' t)+        NameAnnTrailing t -> do+          _anc' <- printUnicode anc n+          return (NameAnnTrailing t)+    return (L (EpAnn anc ann' cs) n)+++markNameAdornmentO :: (Monad m, Monoid w) => NameAdornment -> EP w m NameAdornment+markNameAdornmentO (NameParens o c) = do+  o' <- markEpToken o+  return (NameParens o' c)+markNameAdornmentO (NameParensHash o c) = do+  o' <- markEpToken o+  return (NameParensHash o' c)+markNameAdornmentO (NameBackquotes o c) = do+  o' <- markEpToken o+  return (NameBackquotes o' c)+markNameAdornmentO (NameSquare o c) = do+  o' <- markEpToken o+  return (NameSquare o' c)+markNameAdornmentO NameNoAdornment      = return NameNoAdornment++markNameAdornmentC :: (Monad m, Monoid w) => NameAdornment -> EP w m NameAdornment+markNameAdornmentC (NameParens o c) = do+  c' <- markEpToken c+  return (NameParens o c')+markNameAdornmentC (NameParensHash o c) = do+  c' <- markEpToken c+  return (NameParensHash o c')+markNameAdornmentC (NameBackquotes o c) = do+  c' <- markEpToken c+  return (NameBackquotes o c')+markNameAdornmentC (NameSquare o c) = do+  c' <- markEpToken c+  return (NameSquare o c')+markNameAdornmentC NameNoAdornment      = return NameNoAdornment++printUnicode :: (Monad m, Monoid w) => EpaLocation -> RdrName -> EP w m EpaLocation+printUnicode anc n = do+  let str = case (showPprUnsafe n) of+            -- TODO: unicode support?+              "forall" -> if spanLength (epaLocationRealSrcSpan anc) == 1 then "∀" else "forall"+              s -> s+  loc <- printStringAtAAC NoCaptureComments (EpaDelta (getHasLoc anc) (SameLine 0) []) str+  case loc of+    EpaSpan _ -> return anc+    EpaDelta ss dp [] -> return $ EpaDelta ss dp []+    EpaDelta _ _ _cs  -> error "printUnicode should not capture comments"+++markName :: (Monad m, Monoid w)+  => NameAdornment -> Maybe (EpaLocation,RdrName)+  -> EP w m (NameAdornment, Maybe (EpaLocation,RdrName))+markName adorn mname = do+  adorn0 <- markNameAdornmentO adorn+  mname' <-+    case mname of+      Nothing -> return Nothing+      Just (name, a) -> do+        name' <- printStringAtAAC CaptureComments name (showPprUnsafe a)+        return (Just (name',a))+  adorn1 <- markNameAdornmentC adorn0+  return (adorn1, mname')++markTrailing :: (Monad m, Monoid w) => [TrailingAnn] -> EP w m [TrailingAnn]+markTrailing ts = do+  p <- getPosP+  debugM $ "markTrailing:" ++ showPprUnsafe (p,ts)+  mapM markKwT ts++-- ---------------------------------------------------------------------++-- based on pp_condecls in Decls.hs+exact_condecls :: (Monad m, Monoid w)+  => EpToken "=" -> [LConDecl GhcPs] -> EP w m (EpToken "=",[LConDecl GhcPs])+exact_condecls eq cs+  | gadt_syntax                  -- In GADT syntax+  = do+      cs' <- mapM markAnnotated cs+      return (eq, cs')+  | otherwise                    -- In H98 syntax+  = do+      eq0 <- markEpToken eq+      cs' <- mapM markAnnotated cs+      return (eq0, cs')+  where+    gadt_syntax = case cs of+      []                      -> False+      (L _ ConDeclH98{}  : _) -> False+      (L _ ConDeclGADT{} : _) -> True++-- ---------------------------------------------------------------------++instance ExactPrint (ConDecl GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++-- based on pprConDecl+  exact (ConDeclH98 { con_ext = AnnConDeclH98 tforall tdot tdarrow+                    , con_name = con+                    , con_forall = has_forall+                    , con_ex_tvs = ex_tvs+                    , con_mb_cxt = mcxt+                    , con_args = args+                    , con_doc = doc }) = do+    tforall' <- if has_forall+      then markEpUniToken tforall+      else return tforall+    ex_tvs' <- mapM markAnnotated ex_tvs+    tdot' <- if has_forall+      then markEpToken tdot+      else return tdot+    mcxt' <- mapM markAnnotated mcxt+    tdarrow' <- if (isJust mcxt)+      then markEpUniToken tdarrow+      else return tdarrow++    (con', args') <- exact_details args+    return (ConDeclH98 { con_ext = AnnConDeclH98 tforall' tdot' tdarrow'+                       , con_name = con'+                       , con_forall = has_forall+                       , con_ex_tvs = ex_tvs'+                       , con_mb_cxt = mcxt'+                       , con_args = args'+                       , con_doc = doc })++    where+    -- In ppr_details: let's not print the multiplicities (they are always 1, by+    -- definition) as they do not appear in an actual declaration.+      exact_details (InfixCon t1 t2) = do+        t1' <- markAnnotated t1+        con' <- markAnnotated con+        t2' <- markAnnotated t2+        return (con', InfixCon t1' t2')+      exact_details (PrefixCon tyargs tys) = do+        con' <- markAnnotated con+        tyargs' <- markAnnotated tyargs+        tys' <- markAnnotated tys+        return (con', PrefixCon tyargs' tys')+      exact_details (RecCon fields) = do+        con' <- markAnnotated con+        fields' <- markAnnotated fields+        return (con', RecCon fields')++  -- -----------------------------------++  exact (ConDeclGADT { con_g_ext = AnnConDeclGADT ops cps dcol+                     , con_names = cons+                     , con_bndrs = bndrs+                     , con_mb_cxt = mcxt, con_g_args = args+                     , con_res_ty = res_ty, con_doc = doc }) = do+    cons' <- mapM markAnnotated cons+    dcol' <- markEpUniToken dcol+    epTokensToComments "(" ops+    epTokensToComments ")" cps++    -- Work around https://gitlab.haskell.org/ghc/ghc/-/issues/20558+    bndrs' <- case bndrs of+      L _ (HsOuterImplicit _) -> return bndrs+      _ -> markAnnotated bndrs++    mcxt' <- mapM markAnnotated mcxt+    args' <-+      case args of+          (PrefixConGADT x args0) -> do+            args0' <- mapM markAnnotated args0+            return (PrefixConGADT x args0')+          (RecConGADT rarr fields) -> do+            fields' <- markAnnotated fields+            rarr' <- markEpUniToken rarr+            return (RecConGADT rarr' fields')+    res_ty' <- markAnnotated res_ty+    return (ConDeclGADT { con_g_ext = AnnConDeclGADT [] [] dcol'+                        , con_names = cons'+                        , con_bndrs = bndrs'+                        , con_mb_cxt = mcxt', con_g_args = args'+                        , con_res_ty = res_ty', con_doc = doc })++-- ---------------------------------------------------------------------++instance ExactPrint Void where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact x = return x++-- ---------------------------------------------------------------------++instance ExactPrintTVFlag flag => ExactPrint (HsOuterTyVarBndrs flag GhcPs) where+  getAnnotationEntry (HsOuterImplicit _) = NoEntryVal+  getAnnotationEntry (HsOuterExplicit an _) = fromAnn an++  setAnnotationAnchor (HsOuterImplicit a) _ _ _ = HsOuterImplicit a+  setAnnotationAnchor (HsOuterExplicit an a) anc ts cs = HsOuterExplicit (setAnchorEpa an anc ts cs) a++  exact b@(HsOuterImplicit _) = pure b+  exact (HsOuterExplicit (EpAnn l (f,d) cs) bndrs) = do+    f' <- markEpUniToken f+    bndrs' <- markAnnotated bndrs+    d' <- markEpToken d+    return (HsOuterExplicit (EpAnn l (f',d') cs) bndrs')++-- ---------------------------------------------------------------------++instance ExactPrint (ConDeclField GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (ConDeclField td names ftype mdoc) = do+    names' <- markAnnotated names+    td' <- markEpUniToken td+    ftype' <- markAnnotated ftype+    return (ConDeclField td' names' ftype' mdoc)++-- ---------------------------------------------------------------------++instance ExactPrint (FieldOcc GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact (FieldOcc x n) = do+      n' <- markAnnotated n+      return (FieldOcc x n')++-- ---------------------------------------------------------------------++instance (ExactPrint a) => ExactPrint (HsScaled GhcPs a) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact (HsScaled arr t) = do+    t' <- markAnnotated t+    arr' <- markArrow arr+    return (HsScaled arr' t')++-- ---------------------------------------------------------------------++instance ExactPrint (LocatedP CType) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor = setAnchorAn++  exact (L (EpAnn l (AnnPragma o c s l1 l2 t m) cs) (CType stp mh (stct,ct))) = do+    o' <- markAnnOpen'' o stp "{-# CTYPE"+    l1' <- case mh of+             Nothing -> return l1+             Just (Header srcH _h) ->+               printStringAtAA l1 (toSourceTextWithSuffix srcH "" "")+    l2' <- printStringAtAA l2 (toSourceTextWithSuffix stct (unpackFS ct) "")+    c' <- markEpToken c+    return (L (EpAnn l (AnnPragma o' c' s l1' l2' t m) cs) (CType stp mh (stct,ct)))++-- ---------------------------------------------------------------------++instance ExactPrint (SourceText, RuleName) where+  -- We end up at the right place from the Located wrapper+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (st, rn)+    = printStringAdvance (toSourceTextWithSuffix st (unpackFS rn) "")+      >> return (st, rn)+++-- =====================================================================+-- LocatedL instances start --+--+-- Each is dealt with specifically, as they have+-- different wrapping annotations in the al_rest zone.+--+-- In future, the annotation could perhaps be improved, with an+-- 'al_pre' and 'al_post' set of annotations to be simply sorted and+-- applied.+-- ---------------------------------------------------------------------++instance ExactPrint (LocatedLI [LocatedA (IE GhcPs)]) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor = setAnchorAn++  exact (L an ies) = do+    debugM $ "LocatedL [LIE"+    an0 <- markLensFun' an (lal_rest . lfst) markEpToken+    p <- getPosP+    debugM $ "LocatedL [LIE:p=" ++ showPprUnsafe p+    (an1, ies') <- markAnnList an0 (markAnnotated (filter notIEDoc ies))+    return (L an1 ies')++instance (ExactPrint (Match GhcPs (LocatedA body)))+   => ExactPrint (LocatedLW [LocatedA (Match GhcPs (LocatedA body))]) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor = setAnchorAn+  exact (L an a) = do+    debugM $ "LocatedL [LMatch"+    -- TODO: markAnnList?+    an0 <- markLensFun' an lal_rest markEpToken+    an1 <- markLensBracketsO an0 lal_brackets+    an2 <- markEpAnnAllLT an1 lal_semis+    a' <- markAnnotated a+    an3 <- markLensBracketsC an2 lal_brackets+    return (L an3 a')++instance ExactPrint (LocatedLW [LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs)))]) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor = setAnchorAn+  exact (L an stmts) = do+    debugM $ "LocatedL [ExprLStmt"+    (an'', stmts') <- markAnnList an $ do+      case snocView stmts of+        Just (initStmts, ls@(L _ (LastStmt _ _body _ _))) -> do+          debugM $ "LocatedL [ExprLStmt: snocView"+          ls' <- markAnnotated ls+          initStmts' <- markAnnotated initStmts+          return (initStmts' ++ [ls'])+        _ -> do+          markAnnotated stmts+    return (L an'' stmts')++instance ExactPrint (LocatedLW [LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsCmd GhcPs)))]) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor = setAnchorAn+  exact (L ann es) = do+    debugM $ "LocatedL [CmdLStmt"+    an0 <- markLensBracketsO ann lal_brackets+    es' <- mapM markAnnotated es+    an1 <- markLensBracketsC an0 lal_brackets+    return (L an1 es')++instance ExactPrint (LocatedL [LocatedA (ConDeclField GhcPs)]) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor = setAnchorAn+  exact (L an fs) = do+    debugM $ "LocatedL [LConDeclField"+    (an', fs') <- markAnnList an (markAnnotated fs)+    return (L an' fs')++instance ExactPrint (LocatedL (BF.BooleanFormula (LocatedN RdrName))) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor = setAnchorAn+  exact (L an bf) = do+    debugM $ "LocatedL [LBooleanFormula"+    (an', bf') <- markAnnList an (markAnnotated bf)+    return (L an' bf')++-- ---------------------------------------------------------------------+-- LocatedL instances end --+-- =====================================================================++instance ExactPrint (IE GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (IEVar depr ln doc) = do+    depr' <- markAnnotated depr+    ln' <- markAnnotated ln+    doc' <- markAnnotated doc+    return (IEVar depr' ln' doc')+  exact (IEThingAbs depr thing doc) = do+    depr' <- markAnnotated depr+    thing' <- markAnnotated thing+    doc' <- markAnnotated doc+    return (IEThingAbs depr' thing' doc')+  exact (IEThingAll (depr, (op,dd,cp)) thing doc) = do+    depr' <- markAnnotated depr+    thing' <- markAnnotated thing+    op' <- markEpToken op+    dd' <- markEpToken dd+    cp' <- markEpToken cp+    doc' <- markAnnotated doc+    return (IEThingAll (depr', (op',dd',cp')) thing' doc')++  exact (IEThingWith (depr, (op,dd,c,cp)) thing wc withs doc) = do+    depr' <- markAnnotated depr+    thing' <- markAnnotated thing+    op' <- markEpToken op+    (dd',c', wc', withs') <-+      case wc of+        NoIEWildcard -> do+          withs'' <- markAnnotated withs+          return (dd, c, wc, withs'')+        IEWildcard pos -> do+          let (bs, as) = splitAt pos withs+          bs' <- markAnnotated bs+          dd' <- markEpToken dd+          c' <- markEpToken c+          as' <- markAnnotated as+          return (dd',c', wc, bs'++as')+    cp' <- markEpToken cp+    doc' <- markAnnotated doc+    return (IEThingWith (depr', (op',dd',c',cp')) thing' wc' withs' doc')++  exact (IEModuleContents (depr, an) m) = do+    depr' <- markAnnotated depr+    an0 <- markEpToken an+    m' <- markAnnotated m+    return (IEModuleContents (depr', an0) m')++  -- These three exist to not error out, but are no-ops The contents+  -- appear as "normal" comments too, which we process instead.+  exact (IEGroup x lev doc) = do+    return (IEGroup x lev doc)+  exact (IEDoc x doc) = do+    return (IEDoc x doc)+  exact (IEDocNamed x str) = do+    return (IEDocNamed x str)++-- ---------------------------------------------------------------------++instance ExactPrint (IEWrappedName GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (IEName x n) = do+    n' <- markAnnotated n+    return (IEName x n')+  exact (IEDefault r n) = do+    r' <- markEpToken r+    n' <- markAnnotated n+    return (IEDefault r' n')+  exact (IEPattern r n) = do+    r' <- markEpToken r+    n' <- markAnnotated n+    return (IEPattern r' n')+  exact (IEType r n) = do+    r' <- markEpToken r+    n' <- markAnnotated n+    return (IEType r' n')++-- ---------------------------------------------------------------------++instance ExactPrint (Pat GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (WildPat w) = do+    anchor' <- getAnchorU+    debugM $ "WildPat:anchor'=" ++ show anchor'+    _ <- printStringAtRs anchor' "_"+    return (WildPat w)+  exact (VarPat x n) = do+    -- The parser inserts a placeholder value for a record pun rhs. This must be+    -- filtered.+    let pun_RDR = "pun-right-hand-side"+    n' <- if (showPprUnsafe n /= pun_RDR)+      then markAnnotated n+      else return n+    return (VarPat x n')+  exact (LazyPat an pat) = do+    an0 <- markEpToken an+    pat' <- markAnnotated pat+    return (LazyPat an0 pat')+  exact (AsPat at n pat) = do+    n' <- markAnnotated n+    at' <- markEpToken at+    pat' <- markAnnotated pat+    return (AsPat at' n' pat')+  exact (ParPat (lpar, rpar) pat) = do+    lpar' <- markEpToken lpar+    pat' <- markAnnotated pat+    rpar' <- markEpToken rpar+    return (ParPat (lpar', rpar') pat')++  exact (BangPat an pat) = do+    an0 <- markEpToken an+    pat' <- markAnnotated pat+    return (BangPat an0 pat')++  exact (ListPat an pats) = do+    (an', pats') <- markAnnList' an (markAnnotated pats)+    return (ListPat an' pats')++  exact (TuplePat (o,c) pats boxity) = do+    o0 <- case boxity of+             Boxed   -> printStringAtAA o "("+             Unboxed -> printStringAtAA o "(#"+    pats' <- markAnnotated pats+    c0 <- case boxity of+             Boxed   -> printStringAtAA c ")"+             Unboxed -> printStringAtAA c "#)"+    return (TuplePat (o0,c0) pats' boxity)++  exact (SumPat an pat alt arity) = do+    an0 <- markLensFun an (lsumPatParens . lfst) (\loc -> printStringAtAA loc "(#")+    an1 <- markLensFun an0 lsumPatVbarsBefore (\locs -> mapM markEpToken locs)+    pat' <- markAnnotated pat+    an2 <- markLensFun an1 lsumPatVbarsAfter (\locs -> mapM markEpToken locs)+    an3 <- markLensFun an2 (lsumPatParens . lsnd)  (\loc -> printStringAtAA loc "#)")+    return (SumPat an3 pat' alt arity)++  exact (OrPat an pats) = do+    pats' <- markAnnotated (NE.toList pats)+    return (OrPat an (NE.fromList pats'))++  exact (ConPat an con details) = do+    (an', con', details') <- exactUserCon an con details+    return (ConPat an' con' details')+  exact (ViewPat tokarr expr pat) = do+    expr' <- markAnnotated expr+    an0 <- markEpUniToken tokarr+    pat' <- markAnnotated pat+    return (ViewPat an0 expr' pat')+  exact (SplicePat x splice) = do+    splice' <- markAnnotated splice+    return (SplicePat x splice')+  exact p@(LitPat _ lit) = printStringAdvance (hsLit2String lit) >> return p+  exact (NPat an ol mn z) = do+    an0 <- if (isJust mn)+      then markEpToken an+      else return an+    ol' <- markAnnotated ol+    return (NPat an0 ol' mn z)++  exact (NPlusKPat an n k lit2 a b) = do+    n' <- markAnnotated n+    an' <- markEpToken an+    k' <- markAnnotated k+    return (NPlusKPat an' n' k' lit2 a b)++  exact (SigPat an pat sig) = do+    pat' <- markAnnotated pat+    an0 <- markEpUniToken an+    sig' <- markAnnotated sig+    return (SigPat an0 pat' sig')++  exact (EmbTyPat toktype tp) = do+    toktype' <- markEpToken toktype+    tp' <- markAnnotated tp+    return (EmbTyPat toktype' tp')++  exact (InvisPat (tokat, spec) tp) = do+    tokat' <- markEpToken tokat+    tp' <- markAnnotated tp+    pure (InvisPat (tokat', spec) tp')++-- ---------------------------------------------------------------------++instance ExactPrint (HsPatSigType GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (HsPS an ty) = do+    ty' <- markAnnotated ty+    return (HsPS an ty')++instance ExactPrint (HsTyPat GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact (HsTP an ty) = do+    ty' <- markAnnotated ty+    return (HsTP an ty')++-- ---------------------------------------------------------------------++instance ExactPrint (HsOverLit GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ _ = a++  exact ol =+    let str = case ol_val ol of+                HsIntegral   (IL src _ _) -> src+                HsFractional (FL{ fl_text = src }) -> src+                HsIsString src _ -> src+    in+      case str of+        SourceText s -> printStringAdvance (unpackFS s) >> return ol+        NoSourceText -> return ol++-- ---------------------------------------------------------------------++hsLit2String :: HsLit GhcPs -> String+hsLit2String lit =+  case lit of+    HsChar       src v   -> toSourceTextWithSuffix src v ""+    HsCharPrim   src p   -> toSourceTextWithSuffix src p ""+    HsString     src v   -> toSourceTextWithSuffix src v ""+    HsMultilineString src v -> toSourceTextWithSuffix src v ""+    HsStringPrim src v   -> toSourceTextWithSuffix src v ""+    HsInt        _ (IL src _ v)   -> toSourceTextWithSuffix src v ""+    HsIntPrim    src v   -> toSourceTextWithSuffix src v ""+    HsWordPrim   src v   -> toSourceTextWithSuffix src v ""+    HsInt8Prim   src v   -> toSourceTextWithSuffix src v ""+    HsInt16Prim  src v   -> toSourceTextWithSuffix src v ""+    HsInt32Prim  src v   -> toSourceTextWithSuffix src v ""+    HsInt64Prim  src v   -> toSourceTextWithSuffix src v ""+    HsWord8Prim  src v   -> toSourceTextWithSuffix src v ""+    HsWord16Prim src v   -> toSourceTextWithSuffix src v ""+    HsWord32Prim src v   -> toSourceTextWithSuffix src v ""+    HsWord64Prim src v   -> toSourceTextWithSuffix src v ""+    HsInteger    src v _ -> toSourceTextWithSuffix src v ""+    HsRat        _ fl@(FL{fl_text = src }) _ -> toSourceTextWithSuffix src fl ""+    HsFloatPrim  _ fl@(FL{fl_text = src })   -> toSourceTextWithSuffix src fl "#"+    HsDoublePrim _ fl@(FL{fl_text = src })   -> toSourceTextWithSuffix src fl "##"++toSourceTextWithSuffix :: (Show a) => SourceText -> a -> String -> String+toSourceTextWithSuffix (NoSourceText)    alt suffix = show alt ++ suffix+toSourceTextWithSuffix (SourceText txt) _alt suffix = unpackFS txt ++ suffix++sourceTextToString :: SourceText -> String -> String+sourceTextToString NoSourceText alt   = alt+sourceTextToString (SourceText txt) _ = unpackFS txt++-- ---------------------------------------------------------------------++exactUserCon :: (Monad m, Monoid w, ExactPrint con)+  => (Maybe (EpToken "{"), Maybe (EpToken "}")) -> con -> HsConPatDetails GhcPs+  -> EP w m ((Maybe (EpToken "{"), Maybe (EpToken "}")), con, HsConPatDetails GhcPs)+exactUserCon an c (InfixCon p1 p2) = do+  p1' <- markAnnotated p1+  c' <- markAnnotated c+  p2' <- markAnnotated p2+  return (an, c', InfixCon p1' p2')+exactUserCon (open,close) c details = do+  c' <- markAnnotated c+  open' <- mapM markEpToken open+  details' <- exactConArgs details+  close' <- mapM markEpToken close+  return ((open', close'), c', details')++instance ExactPrint (HsConPatTyArg GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ _ = a+  exact (HsConPatTyArg at tyarg) = do+    at' <- markEpToken at+    tyarg' <- markAnnotated tyarg+    return (HsConPatTyArg at' tyarg')++exactConArgs :: (Monad m, Monoid w)+  => HsConPatDetails GhcPs -> EP w m (HsConPatDetails GhcPs)+exactConArgs (PrefixCon tyargs pats) = do+  tyargs' <- markAnnotated tyargs+  pats' <- markAnnotated pats+  return (PrefixCon tyargs' pats')+exactConArgs (InfixCon p1 p2) = do+  p1' <- markAnnotated p1+  p2' <- markAnnotated p2+  return (InfixCon p1' p2')+exactConArgs (RecCon rpats) = do+  rpats' <- markAnnotated rpats+  return (RecCon rpats')++-- ---------------------------------------------------------------------++entryFromLocatedA :: (HasTrailing ann) => LocatedAn ann a -> Entry+entryFromLocatedA (L la _) = fromAnn la++-- =====================================================================+-- Utility stuff+-- ---------------------------------------------------------------------++-- |This should be the final point where things are mode concrete,+-- before output.+-- NOTE: despite the name, this is the ghc-exactprint final output for+-- the PRINT phase.+printStringAtLsDelta :: (Monad m, Monoid w) => DeltaPos -> String -> EP w m ()+printStringAtLsDelta cl s = do+  p <- getPosP+  colOffset <- getLayoutOffsetP+  if isGoodDeltaWithOffset cl colOffset+    then do+      printStringAt (undelta p cl colOffset) s+      p' <- getPosP+      d <- getPriorEndD+      debugM $ "printStringAtLsDelta:(pos,p,p',d,s):" ++ show (undelta p cl colOffset,p,p',d,s)+    else return () `debug` ("printStringAtLsDelta:bad delta for (mc,s):" ++ show (cl,s))++-- ---------------------------------------------------------------------++isGoodDeltaWithOffset :: DeltaPos -> LayoutStartCol -> Bool+isGoodDeltaWithOffset dp colOffset = isGoodDelta (deltaPos l c)+  where (l,c) = undelta (0,0) dp colOffset++-- | Print a comment, using the current layout offset to convert the+-- @DeltaPos@ to an absolute position.+printQueuedComment :: (Monad m, Monoid w) => Comment -> DeltaPos -> EP w m ()+printQueuedComment Comment{commentContents} dp = do+  p <- getPosP+  d <- getPriorEndD+  colOffset <- getLayoutOffsetP+  let (dr,dc) = undelta (0,0) dp colOffset+  -- do not lose comments against the left margin+  when (isGoodDelta (deltaPos dr (max 0 dc))) $ do+    printCommentAt (undelta p dp colOffset) commentContents+  p' <- getPosP+  d' <- getPriorEndD+  debugM $ "printQueuedComment: (p,p',d,d')=" ++ show (p,p',d,d')+  debugM $ "printQueuedComment: (p,p',dp,colOffset,undelta)=" ++ show (p,p',dp,colOffset,undelta p dp colOffset)++------------------------------------------------------------------------++setLayoutBoth :: (Monad m, Monoid w) => EP w m a -> EP w m a+setLayoutBoth k = do+  oldLHS <- getLayoutOffsetD+  oldAnchorOffset <- getLayoutOffsetP+  debugM $ "setLayoutBoth: (oldLHS,oldAnchorOffset)=" ++ show (oldLHS,oldAnchorOffset)+  modify (\a -> a { dMarkLayout = True+                  , pMarkLayout = True } )+  let reset = do+        debugM $ "setLayoutBoth:reset: (oldLHS,oldAnchorOffset)=" ++ show (oldLHS,oldAnchorOffset)+        modify (\a -> a { dMarkLayout = False+                        , dLHS = oldLHS+                        , pMarkLayout = False+                        , pLHS = oldAnchorOffset} )+  k <* reset++-- Use 'local', designed for this+setLayoutTopLevelP :: (Monad m, Monoid w) => EP w m a -> EP w m a+setLayoutTopLevelP k = do+  debugM $ "setLayoutTopLevelP entered"+  oldAnchorOffset <- getLayoutOffsetP+  modify (\a -> a { pMarkLayout = False+                  , pLHS = 0} )+  r <- k+  debugM $ "setLayoutTopLevelP:resetting"+  setLayoutOffsetP oldAnchorOffset+  return r++------------------------------------------------------------------------++getPosP :: (Monad m, Monoid w) => EP w m Pos+getPosP = gets epPos++setPosP :: (Monad m, Monoid w) => Pos -> EP w m ()+setPosP l = do+  debugM $ "setPosP:" ++ show l+  modify (\s -> s {epPos = l})++getExtraDP :: (Monad m, Monoid w) => EP w m (Maybe EpaLocation)+getExtraDP = gets uExtraDP++setExtraDP :: (Monad m, Monoid w) => Maybe EpaLocation -> EP w m ()+setExtraDP md = do+  debugM $ "setExtraDP:" ++ show md+  modify (\s -> s {uExtraDP = md})++getExtraDPReturn :: (Monad m, Monoid w) => EP w m (Maybe (SrcSpan, DeltaPos))+getExtraDPReturn = gets uExtraDPReturn++setExtraDPReturn :: (Monad m, Monoid w) => Maybe (SrcSpan, DeltaPos) -> EP w m () setExtraDPReturn md = do   debugM $ "setExtraDPReturn:" ++ show md   modify (\s -> s {uExtraDPReturn = md})
− src/Language/Haskell/GHC/ExactPrint/Lookup.hs
@@ -1,125 +0,0 @@-module Language.Haskell.GHC.ExactPrint.Lookup-  (-    keywordToString-  , AnnKeywordId(..)-  , Comment(..)-  ) where--import GHC (AnnKeywordId(..))-import Language.Haskell.GHC.ExactPrint.Types---- | Maps `AnnKeywordId` to the corresponding String representation.--- There is no specific mapping for the following constructors.--- `AnnOpen`, `AnnClose`, `AnnVal`, `AnnPackageName`, `AnnHeader`, `AnnFunId`,--- `AnnInfix`-keywordToString :: AnnKeywordId -> String-keywordToString kw =-  let mkErr x = error $ "keywordToString: missing case for:" ++ show x-  in-  case kw of-      -- Specifically handle all cases so that there are pattern match-      -- warnings if new constructors are added.-      AnnAnyclass     -> "anyclass"-      AnnOpen         -> mkErr kw-      AnnClose        -> mkErr kw-      AnnVal          -> mkErr kw-      AnnPackageName  -> mkErr kw-      AnnHeader       -> mkErr kw-      AnnFunId        -> mkErr kw-      AnnInfix        -> mkErr kw-      AnnValStr       -> mkErr kw-      AnnName         -> mkErr kw-      AnnAs           -> "as"-      AnnBang         -> "!"-      AnnBackquote    -> "`"-      AnnBy           -> "by"-      AnnCase         -> "case"-      AnnCases        -> "cases"-      AnnClass        -> "class"-      AnnCloseB       -> "|)"-      AnnCloseBU      -> "⦈"-      AnnCloseC       -> "}"-      AnnCloseP       -> ")"-      AnnClosePH      -> "#)"-      AnnCloseQ       -> "|]"-      AnnCloseQU      -> "⟧"-      AnnCloseS       -> "]"-      AnnColon        -> ":"-      AnnComma        -> ","-      AnnCommaTuple   -> ","-      AnnDarrow       -> "=>"-      AnnData         -> "data"-      AnnDcolon       -> "::"-      AnnDefault      -> "default"-      AnnDeriving     -> "deriving"-      AnnDo           -> "do"-      AnnDot          -> "."-      AnnDotdot       -> ".."-      AnnElse         -> "else"-      AnnEqual        -> "="-      AnnExport       -> "export"-      AnnFamily       -> "family"-      AnnForall       -> "forall"-      AnnForeign      -> "foreign"-      AnnGroup        -> "group"-      AnnHiding       -> "hiding"-      AnnIf           -> "if"-      AnnImport       -> "import"-      AnnIn           -> "in"-      AnnInstance     -> "instance"-      AnnLam          -> "\\"-      AnnLarrow       -> "<-"-      AnnLet          -> "let"-      AnnLollyU       -> "⊸"-      AnnMdo          -> "mdo"-      AnnMinus        -> "-"-      AnnModule       -> "module"-      AnnNewtype      -> "newtype"-      AnnOf           -> "of"-      AnnOpenB        -> "(|"-      AnnOpenBU       ->  "⦇"-      AnnOpenC        -> "{"-      AnnOpenE        -> "[e|"-      AnnOpenEQ       -> "[|"-      AnnOpenEQU      ->  "⟦"-      AnnOpenP        -> "("-      AnnOpenPH       -> "(#"-      AnnOpenS        -> "["-      AnnPattern      -> "pattern"-      AnnPercent      -> "%"-      AnnPercentOne   -> "%1"-      AnnProc         -> "proc"-      AnnQualified    -> "qualified"-      AnnRarrow       -> "->"-      AnnRec          -> "rec"-      AnnRole         -> "role"-      AnnSafe         -> "safe"-      AnnSemi         -> ";"-      AnnSignature    -> "signature"-      AnnStock        -> "stock"-      AnnStatic       -> "static"-      AnnThen         -> "then"-      AnnTilde        -> "~"-      AnnType         -> "type"-      AnnUnit         -> "()"-      AnnUsing        -> "using"-      AnnVbar         -> "|"-      AnnWhere        -> "where"-      Annlarrowtail   -> "-<"-      Annrarrowtail   -> ">-"-      AnnLarrowtail   -> "-<<"-      AnnRarrowtail   -> ">>-"-      AnnSimpleQuote  -> "'"-      AnnThTyQuote    -> "''"-      AnnDollar       -> "$"-      AnnDollarDollar -> "$$"-      AnnDarrowU      -> "⇒"-      AnnDcolonU      -> "∷"-      AnnForallU      -> "∀"-      AnnLarrowU      -> "←"-      AnnLarrowtailU  -> "⤛"-      AnnRarrowU      -> "→"-      AnnRarrowtailU  -> "⤜"-      AnnlarrowtailU  -> "⤙"-      AnnrarrowtailU  -> "⤚"-      AnnVia          -> "via"
src/Language/Haskell/GHC/ExactPrint/Parsers.hs view
@@ -289,7 +289,8 @@             let               pc = GHC.priorComments cs               fc = GHC.getFollowingComments cs-              bf (GHC.L anc _) = GHC.anchor anc > ss+              bf (GHC.L anc _) = GHC.epaLocationRealSrcSpan anc > ss+               (prior,f) = break bf fc               cs'' = GHC.EpaCommentsBalanced (pc <> prior) f             in cs''@@ -310,7 +311,7 @@         -- Move any comments on the decl that occur prior to the location         pc = GHC.priorComments csd         fc = GHC.getFollowingComments csd-        bf (GHC.L anch _) = GHC.anchor anch > r+        bf (GHC.L anch _) = GHC.epaLocationRealSrcSpan anch > r         (move,keep) = break bf pc         csd' = GHC.EpaCommentsBalanced keep fc @@ -326,8 +327,8 @@               -> ([GHC.LHsDecl GHC.GhcPs], GHC.EpAnn GHC.AnnsModule)     rebalance (ds, GHC.EpAnn a an cs) = (ds1, GHC.EpAnn a an cs')       where-        (ds1,cs') = case break (\(GHC.AddEpAnn k _) -> k == GHC.AnnWhere) (GHC.am_main an) of-                     (_, (GHC.AddEpAnn _ whereLoc:_)) ->+        (ds1,cs') = case GHC.am_where an of+                     GHC.EpTok whereLoc ->                            case GHC.hsmodDecls p of                                (d:ds0) -> (d':ds0, cs0)                                    where (d',cs0) = moveComments whereLoc d cs
src/Language/Haskell/GHC/ExactPrint/Preprocess.hs view
@@ -24,7 +24,6 @@ import qualified GHC.Driver.Errors.Types as GHC import qualified GHC.Driver.Phases     as GHC import qualified GHC.Driver.Pipeline   as GHC-import qualified GHC.Fingerprint.Type  as GHC import qualified GHC.Parser.Lexer      as GHC import qualified GHC.Settings          as GHC import qualified GHC.Types.Error       as GHC@@ -232,24 +231,32 @@     $ msgs  injectCppOptions :: CppOptions -> GHC.DynFlags -> GHC.DynFlags-injectCppOptions CppOptions{..} dflags =-  foldr addOptP dflags (map mkDefine cppDefine ++ map mkIncludeDir cppInclude ++ map mkInclude cppFile)+injectCppOptions CppOptions{..} dflags = folded_opt   where     mkDefine = ("-D" ++)     mkIncludeDir = ("-I" ++)     mkInclude = ("-include" ++)-+    file_flags = map mkDefine cppDefine ++ map mkIncludeDir cppInclude ++ map mkInclude cppFile+    addFs = [addOptP, addOptJSP, addOptCmmP]+    folded_opt = foldr ($) dflags (addFs <*> file_flags)  addOptP :: String -> GHC.DynFlags -> GHC.DynFlags addOptP   f = alterToolSettings $ \s -> s           { GHC.toolSettings_opt_P   = f : GHC.toolSettings_opt_P s-          , GHC.toolSettings_opt_P_fingerprint = fingerprintStrings (f : GHC.toolSettings_opt_P s)+          , GHC.toolSettings_opt_P_fingerprint = GHC.fingerprintStrings (f : GHC.toolSettings_opt_P s)           }+addOptJSP :: String -> GHC.DynFlags -> GHC.DynFlags+addOptJSP f = alterToolSettings $ \s -> s+          { GHC.toolSettings_opt_JSP   = f : GHC.toolSettings_opt_JSP s+          , GHC.toolSettings_opt_JSP_fingerprint = GHC.fingerprintStrings (f : GHC.toolSettings_opt_JSP s)+          }+addOptCmmP :: String -> GHC.DynFlags -> GHC.DynFlags+addOptCmmP f = alterToolSettings $ \s -> s+          { GHC.toolSettings_opt_CmmP = f : GHC.toolSettings_opt_CmmP s+          , GHC.toolSettings_opt_CmmP_fingerprint = GHC.fingerprintStrings (f : GHC.toolSettings_opt_CmmP s)+          } alterToolSettings :: (GHC.ToolSettings -> GHC.ToolSettings) -> GHC.DynFlags -> GHC.DynFlags alterToolSettings f dynFlags = dynFlags { GHC.toolSettings = f (GHC.toolSettings dynFlags) }--fingerprintStrings :: [String] -> GHC.Fingerprint-fingerprintStrings ss = GHC.fingerprintFingerprints $ map GHC.fingerprintString ss  -- --------------------------------------------------------------------- 
src/Language/Haskell/GHC/ExactPrint/Transform.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}@@ -91,7 +92,6 @@ import qualified Control.Monad.Fail as Fail  import GHC  hiding (parseModule, parsedSource)-import GHC.Data.Bag import GHC.Data.FastString import GHC.Types.SrcLoc @@ -204,17 +204,18 @@ -- ---------------------------------------------------------------------  captureTypeSigSpacing :: LHsDecl GhcPs -> LHsDecl GhcPs-captureTypeSigSpacing (L l (SigD x (TypeSig (AnnSig dc rs') ns (HsWC xw ty))))-  = (L l (SigD x (TypeSig (AnnSig dc' rs') ns (HsWC xw ty'))))+captureTypeSigSpacing (L l (SigD x (TypeSig (AnnSig NoEpUniTok mp md) ns (HsWC xw ty))))+  = (L l (SigD x (TypeSig (AnnSig NoEpUniTok mp md) ns (HsWC xw ty))))+captureTypeSigSpacing (L l (SigD x (TypeSig (AnnSig (EpUniTok dca u) mp md) ns (HsWC xw ty))))+  = (L l (SigD x (TypeSig (AnnSig (EpUniTok dca' u) mp md) ns (HsWC xw ty'))))   where     -- we want DPs for the distance from the end of the ns to the     -- AnnDColon, and to the start of the ty-    AddEpAnn kw dca = dc     rd = case last ns of-      L (EpAnn anc' _ _) _ -> anchor anc' -- TODO MovedAnchor?-    dc' = case dca of-      EpaSpan (RealSrcSpan r _) -> AddEpAnn kw (EpaDelta (ss2delta (ss2posEnd rd) r) [])-      _                         -> AddEpAnn kw dca+      L (EpAnn anc' _ _) _ -> epaLocationRealSrcSpan anc'+    dca' = case dca of+          EpaSpan ss@(RealSrcSpan r _) -> (EpaDelta ss (ss2delta (ss2posEnd rd) r) [])+          _                            -> dca      -- --------------------------------- @@ -223,10 +224,10 @@       (L (EpAnn anc0 a c) b)         -> let               anc' = case anc0 of-                EpaDelta _ _ -> anc0+                EpaDelta _ _ _ -> anc0                 _ -> case dca of-                  EpaSpan _ -> EpaDelta (SameLine 1) []-                  EpaDelta _ cs0 -> EpaDelta (SameLine 1) cs0+                  EpaSpan ss -> EpaDelta ss (SameLine 1) []+                  EpaDelta ss _ cs0 -> EpaDelta ss (SameLine 1) cs0            in (L (EpAnn anc' a c) b)  captureTypeSigSpacing s = s@@ -249,19 +250,22 @@ -- |Set the true entry 'DeltaPos' from the annotation for a given AST -- element. This is the 'DeltaPos' ignoring any comments. setEntryDP :: LocatedAn t a -> DeltaPos -> LocatedAn t a-setEntryDP (L (EpAnn (EpaSpan (UnhelpfulSpan _)) an cs) a) dp-  = L (EpAnn (EpaDelta dp []) an cs) a-setEntryDP (L (EpAnn (EpaSpan _) an (EpaComments [])) a) dp-  = L (EpAnn (EpaDelta dp []) an (EpaComments [])) a-setEntryDP (L (EpAnn (EpaDelta d csd) an cs) a) dp-  = L (EpAnn (EpaDelta d' csd') an cs') a+setEntryDP (L (EpAnn (EpaSpan ss@(UnhelpfulSpan _)) an cs) a) dp+  = L (EpAnn (EpaDelta ss dp []) an cs) a+setEntryDP (L (EpAnn (EpaSpan ss) an (EpaComments [])) a) dp+  = L (EpAnn (EpaDelta ss dp []) an (EpaComments [])) a+setEntryDP (L (EpAnn (EpaDelta ss d csd) an cs) a) dp+  = L (EpAnn (EpaDelta ss d' csd') an cs') a   where+    -- I suspect we should assume the comments are already in the+    -- right place, and just set the entry DP for this case. This+    -- avoids suprises from the caller.     (d', csd', cs') = case cs of       EpaComments (h:t) ->         let           (dp0,c') = go h         in-          (dp0, c':t++csd, EpaComments [])+          (dp0, csd, EpaComments (c':t))       EpaComments [] ->           (dp, csd, cs)       EpaCommentsBalanced (h:t) ts ->@@ -278,67 +282,73 @@                 in                   (dp0, c':t, EpaCommentsBalanced [] ts)     go :: GenLocated NoCommentsLocation e -> (DeltaPos, GenLocated NoCommentsLocation e)-    go (L (EpaDelta _ c0) c) = (d,  L (EpaDelta dp c0) c)-    go (L (EpaSpan _)     c) = (d,  L (EpaDelta dp NoComments) c)-setEntryDP (L (EpAnn (EpaSpan (RealSrcSpan r _)) an cs) a) dp+    go (L (EpaDelta ss0 _ c0) c) = (d,  L (EpaDelta ss0 dp c0) c)+    go (L (EpaSpan ss0)       c) = (d,  L (EpaDelta ss0 dp NoComments) c)+setEntryDP (L (EpAnn (EpaSpan ss@(RealSrcSpan r _)) an cs) a) dp   = case sortEpaComments (priorComments cs) of       [] ->-        L (EpAnn (EpaDelta dp []) an cs) a+        L (EpAnn (EpaDelta ss dp []) an cs) a       (L ca c:cs') ->-        L (EpAnn (EpaDelta edp csd) an cs'') a+        L (EpAnn (EpaDelta ss edp csd) an cs'') a               where                 cs'' = setPriorComments cs []-                csd = L (EpaDelta dp NoComments) c:commentOrigDeltas cs'+                csd = L (EpaDelta ss dp NoComments) c:commentOrigDeltas cs'                 lc = last $ (L ca c:cs')                 delta = case getLoc lc of                           EpaSpan (RealSrcSpan rr _) -> ss2delta (ss2pos rr) r                           EpaSpan _ -> (SameLine 0)-                          EpaDelta _dp _ -> DifferentLine 1 0+                          EpaDelta _ _dp _ -> DifferentLine 1 0                 line = getDeltaLine delta                 col = deltaColumn delta                 edp' = if line == 0 then SameLine col                                     else DifferentLine line col-                edp = edp' `debug` ("setEntryDP :" ++ showGhc (edp', (ss2pos $ anchor $ getLoc lc), r))+                edp = edp' `debug` ("setEntryDP :" ++ showGhc (edp', (ss2pos $ epaLocationRealSrcSpan $ getLoc lc), r))   -- ---------------------------------------------------------------------  getEntryDP :: LocatedAn t a -> DeltaPos-getEntryDP (L (EpAnn (EpaDelta dp _) _ _) _) = dp+getEntryDP (L (EpAnn (EpaDelta _ dp _) _ _) _) = dp getEntryDP _ = SameLine 1  -- ---------------------------------------------------------------------  addEpaLocationDelta :: LayoutStartCol -> RealSrcSpan -> EpaLocation -> EpaLocation-addEpaLocationDelta _off _anc (EpaDelta d cs) = EpaDelta d cs-addEpaLocationDelta _off _anc (EpaSpan (UnhelpfulSpan _)) = EpaDelta (SameLine 0) []-addEpaLocationDelta  off  anc (EpaSpan (RealSrcSpan r _))-  = EpaDelta (adjustDeltaForOffset off (ss2deltaEnd anc r)) []+addEpaLocationDelta _off _anc (EpaDelta ss d cs) = EpaDelta ss d cs+addEpaLocationDelta _off _anc (EpaSpan ss@(UnhelpfulSpan _)) = EpaDelta ss (SameLine 0) []+addEpaLocationDelta  off  anc (EpaSpan ss@(RealSrcSpan r _))+  = EpaDelta ss (adjustDeltaForOffset off (ss2deltaEnd anc r)) []  -- Set the entry DP for an element coming after an existing keyword annotation setEntryDPFromAnchor :: LayoutStartCol -> EpaLocation -> LocatedA t -> LocatedA t-setEntryDPFromAnchor _off (EpaDelta _ _) (L la a) = L la a+setEntryDPFromAnchor _off (EpaDelta _ _ _) (L la a) = L la a setEntryDPFromAnchor _off (EpaSpan (UnhelpfulSpan _)) (L la a) = L la a setEntryDPFromAnchor  off (EpaSpan (RealSrcSpan anc _)) ll@(L la _) = setEntryDP ll dp'   where     dp' = case la of       (EpAnn (EpaSpan (RealSrcSpan r' _)) _ _) -> adjustDeltaForOffset off (ss2deltaEnd anc r')       (EpAnn (EpaSpan _) _ _)                  -> adjustDeltaForOffset off (SameLine 0)-      (EpAnn (EpaDelta dp _) _ _)              -> adjustDeltaForOffset off dp+      (EpAnn (EpaDelta _ dp _) _ _)            -> adjustDeltaForOffset off dp  -- --------------------------------------------------------------------- --- |Take the annEntryDelta associated with the first item and associate it with the second.--- Also transfer any comments occurring before it.+-- |Take the annEntryDelta associated with the first item and+-- associate it with the second. Also transfer any comments occurring+-- before it. transferEntryDP :: (Typeable t1, Typeable t2)   => LocatedAn t1 a -> LocatedAn t2 b -> (LocatedAn t2 b)-transferEntryDP (L (EpAnn anc1 an1 cs1) _) (L (EpAnn _anc2 an2 cs2) b) =+transferEntryDP (L (EpAnn anc1 an1 cs1) _) (L (EpAnn anc2 an2 cs2) b) =+  -- Note: the EpaDelta version of an EpaLocation contains the original+  -- SrcSpan. We must preserve that.+  let anc1' = case (anc1,anc2) of+          (EpaDelta _ dp cs, EpaDelta ss2 _ _) -> EpaDelta ss2 dp cs+          (_, _) -> anc1   -- Problem: if the original had preceding comments, blindly   -- transferring the location is not correct-  case priorComments cs1 of-    [] -> (L (EpAnn anc1 (combine an1 an2) cs2) b)+  in case priorComments cs1 of+    [] -> (L (EpAnn anc1' (combine an1 an2) cs2) b)     -- TODO: what happens if the receiving side already has comments?-    (L _ _:_) -> (L (EpAnn anc1 (combine an1 an2) (cs1 <> cs2)) b)+    (L _ _:_) -> (L (EpAnn anc1' (combine an1 an2) (cs1 <> cs2)) b)   -- |If a and b are the same type return first arg, else return second@@ -368,9 +378,14 @@  -- --------------------------------------------------------------------- --- | If we compile in haddock mode we get DocDecls, which we strip out--- while exact printing. Make sure we do not balance any comments on--- to them be stripping them out here already.+-- | If we compile in haddock mode, the haddock processing inserts+-- DocDecls to carry the Haddock Documentation. We ignore these in+-- exact printing, as all the comments are also available in their+-- normal location, and the haddock processing is lossy, in that it+-- does not preserve all haddock-like comments. When we balance+-- comments in a list, we migrate some to preceding or following+-- declarations in the list. We must make sure we do not move any to+-- these DocDecls, which are not printed. balanceCommentsList :: [LHsDecl GhcPs] -> [LHsDecl GhcPs] balanceCommentsList decls = balanceCommentsList' (filter notDocDecl decls) @@ -486,7 +501,7 @@       (L la d:ds) -> (an, L (addCommentsToEpAnn la cs) d:ds)     vb = case replaceDeclsValbinds w lb (reverse decls') of       (HsValBinds _ vb') -> vb'-      _ -> ValBinds NoAnnSortKey emptyBag []+      _ -> ValBinds NoAnnSortKey [] []   balanceCommentsListA :: [LocatedA a] -> [LocatedA a]@@ -544,15 +559,15 @@ trailingCommentsDeltas :: RealSrcSpan -> [LEpaComment]                -> [(Int, LEpaComment)] trailingCommentsDeltas _ [] = []-trailingCommentsDeltas r (la@(L (EpaDelta dp _) _):las)+trailingCommentsDeltas r (la@(L (EpaDelta _ dp _) _):las)   = (getDeltaLine dp, la): trailingCommentsDeltas r las trailingCommentsDeltas r (la@(L l _):las)-  = deltaComment r la : trailingCommentsDeltas (anchor l) las+  = deltaComment r la : trailingCommentsDeltas (epaLocationRealSrcSpan l) las   where     deltaComment rs' (L loc c) = (abs(ll - al), L loc c)       where         (al,_) = ss2posEnd rs'-        (ll,_) = ss2pos (anchor loc)+        (ll,_) = ss2pos (epaLocationRealSrcSpan loc)  priorCommentsDeltas :: RealSrcSpan -> [LEpaComment]                     -> [(Int, LEpaComment)]@@ -560,14 +575,14 @@   where     go :: RealSrcSpan -> [LEpaComment] -> [(Int, LEpaComment)]     go _   [] = []-    go _   (la@(L l@(EpaDelta dp _) _):las) = (deltaLine dp, la) : go (anchor l) las-    go rs' (la@(L l _):las) = deltaComment rs' la : go (anchor l) las+    go _   (la@(L l@(EpaDelta _ dp _) _):las) = (getDeltaLine dp, la) : go (epaLocationRealSrcSpan l) las+    go rs' (la@(L l _):las) = deltaComment rs' la : go (epaLocationRealSrcSpan l) las      deltaComment :: RealSrcSpan -> LEpaComment -> (Int, LEpaComment)     deltaComment rs' (L loc c) = (abs(ll - al), L loc c)       where         (al,_) = ss2pos rs'-        (ll,_) = ss2pos (anchor loc)+        (ll,_) = ss2pos (epaLocationRealSrcSpan loc)   -- ---------------------------------------------------------------------@@ -656,18 +671,17 @@ addCommentOrigDeltasAnn :: (EpAnn a) -> (EpAnn a) addCommentOrigDeltasAnn (EpAnn e a cs) = EpAnn e a (addCommentOrigDeltas cs) - -- TODO: this is replicating functionality in ExactPrint. Sort out the -- import loop` anchorFromLocatedA :: LocatedA a -> RealSrcSpan-anchorFromLocatedA (L (EpAnn anc _ _) _) = anchor anc+anchorFromLocatedA (L (EpAnn anc _ _) _) = epaLocationRealSrcSpan anc  -- | Get the full span of interest for comments from a LocatedA. -- This extends up to the last TrailingAnn fullSpanFromLocatedA :: LocatedA a -> RealSrcSpan fullSpanFromLocatedA (L (EpAnn anc (AnnListItem tas)  _) _) = rr   where-    r = anchor anc+    r = epaLocationRealSrcSpan anc     trailing_loc ta = case ta_location ta of         EpaSpan (RealSrcSpan s _) -> [s]         _ -> []@@ -691,7 +705,7 @@           (csp,csf) = case anc1 of             EpaComments cs -> ([],cs)             EpaCommentsBalanced p f -> (p,f)-          (move',stay') = break (simpleBreak 0) (trailingCommentsDeltas (anchor anc) csf)+          (move',stay') = break (simpleBreak 0) (trailingCommentsDeltas (epaLocationRealSrcSpan anc) csf)           move = map snd move'           stay = map snd stay'           cs1 = epaCommentsBalanced csp stay@@ -715,7 +729,7 @@ -- | Create a @SrcSpanAnn@ with a @MovedAnchor@ operation using the -- given @DeltaPos@. noAnnSrcSpanDP :: (NoAnn ann) => DeltaPos -> EpAnn ann-noAnnSrcSpanDP dp = EpAnn (EpaDelta dp []) noAnn emptyComments+noAnnSrcSpanDP dp = EpAnn (EpaDelta noSrcSpan dp []) noAnn emptyComments  noAnnSrcSpanDP0 :: (NoAnn ann) => EpAnn ann noAnnSrcSpanDP0 = noAnnSrcSpanDP (SameLine 0)@@ -727,17 +741,17 @@ noAnnSrcSpanDPn s = noAnnSrcSpanDP (SameLine s)  d0 :: EpaLocation-d0 = EpaDelta (SameLine 0) []+d0 = EpaDelta noSrcSpan (SameLine 0) []  d1 :: EpaLocation-d1 = EpaDelta (SameLine 1) []+d1 = EpaDelta noSrcSpan (SameLine 1) []  dn :: Int -> EpaLocation-dn n = EpaDelta (SameLine n) []+dn n = EpaDelta noSrcSpan (SameLine n) []  addComma :: SrcSpanAnnA -> SrcSpanAnnA addComma (EpAnn anc (AnnListItem as) cs)-  = EpAnn anc (AnnListItem (AddCommaAnn d0:as)) cs+  = EpAnn anc (AnnListItem (AddCommaAnn (EpTok d0):as)) cs  -- --------------------------------------------------------------------- @@ -807,7 +821,7 @@     hsDecls :: t -> [LHsDecl GhcPs]      -- | Replace the directly enclosed decl list by the given-    --  decl list. As parto of replacing it will update list order+    --  decl list. As part of replacing it will update list order     --  annotations, and rebalance comments and other layout changes as needed.     --     -- For example, a call on replaceDecls for a wrapped 'FunBind' having no@@ -886,8 +900,8 @@               off = case l of                       (EpaSpan (RealSrcSpan r _)) -> LayoutStartCol $ snd $ ss2pos r                       (EpaSpan (UnhelpfulSpan _)) -> LayoutStartCol 0-                      (EpaDelta (SameLine _) _) -> LayoutStartCol 0-                      (EpaDelta (DifferentLine _ c) _) -> LayoutStartCol c+                      (EpaDelta _ (SameLine _) _) -> LayoutStartCol 0+                      (EpaDelta _ (DifferentLine _ c) _) -> LayoutStartCol c               ex'' = setEntryDPFromAnchor off i ex               newDecls'' = case newDecls of                 [] -> newDecls@@ -1065,7 +1079,7 @@     = let         oldSpan = spanHsLocaLBinds b         an = oldWhereAnnotation a w (realSrcSpan oldSpan)-        decs = listToBag $ concatMap decl2Bind new+        decs = concatMap decl2Bind new         sigs = concatMap decl2Sig new         sortKey = captureOrderBinds new       in (HsValBinds an (ValBinds sortKey decs sigs))@@ -1073,40 +1087,39 @@ replaceDeclsValbinds w (EmptyLocalBinds _) new     = let         an = newWhereAnnotation w-        newBinds = concatMap decl2Bind new-        newSigs  = concatMap decl2Sig  new-        decs = listToBag $ newBinds-        sigs = newSigs+        decs = concatMap decl2Bind new+        sigs = concatMap decl2Sig  new         sortKey = captureOrderBinds new       in (HsValBinds an (ValBinds sortKey decs sigs)) -oldWhereAnnotation :: EpAnn AnnList -> WithWhere -> RealSrcSpan -> (EpAnn AnnList)+oldWhereAnnotation :: EpAnn (AnnList (EpToken "where"))+  -> WithWhere -> RealSrcSpan -> (EpAnn (AnnList (EpToken "where"))) oldWhereAnnotation (EpAnn anc an cs) ww _oldSpan = an'   -- TODO: when we set DP (0,0) for the HsValBinds EpEpaLocation,   -- change the AnnList anchor to have the correct DP too   where-    (AnnList ancl o c _r t) = an+    (AnnList ancl p s _r t) = an     w = case ww of-      WithWhere -> [AddEpAnn AnnWhere (EpaDelta (SameLine 0) [])]-      WithoutWhere -> []+      WithWhere -> EpTok (EpaDelta noSrcSpan (SameLine 0) [])+      WithoutWhere -> NoEpTok     (anc', ancl') =           case ww of             WithWhere -> (anc, ancl)             WithoutWhere -> (anc, ancl)     an' = EpAnn anc'-                (AnnList ancl' o c w t)+                (AnnList ancl' p s w t)                 cs -newWhereAnnotation :: WithWhere -> (EpAnn AnnList)+newWhereAnnotation :: WithWhere -> (EpAnn (AnnList (EpToken "where"))) newWhereAnnotation ww = an   where-  anc  = EpaDelta (DifferentLine 1 3) []-  anc2 = EpaDelta (DifferentLine 1 5) []+  anc  = EpaDelta noSrcSpan (DifferentLine 1 3) []+  anc2 = EpaDelta noSrcSpan (DifferentLine 1 5) []   w = case ww of-    WithWhere -> [AddEpAnn AnnWhere (EpaDelta (SameLine 0) [])]-    WithoutWhere -> []+    WithWhere -> EpTok (EpaDelta noSrcSpan (SameLine 0) [])+    WithoutWhere -> NoEpTok   an = EpAnn anc-              (AnnList (Just anc2) Nothing Nothing w [])+              (AnnList (Just anc2) ListNone [] w [])               emptyComments  -- ---------------------------------------------------------------------
src/Language/Haskell/GHC/ExactPrint/Types.hs view
@@ -29,7 +29,7 @@       commentContents   :: !String -- ^ The contents of the comment including separators     , commentLoc :: !NoCommentsLocation     , commentPriorTok :: !RealSrcSpan-    , commentOrigin :: !(Maybe AnnKeywordId) -- ^ We sometimes turn syntax into comments in order to process them properly.+    , commentOrigin :: !(Maybe String) -- ^ We sometimes turn syntax into comments in order to process them properly.     }   deriving (Data, Eq) @@ -41,7 +41,7 @@   -- When we have CPP injected comments with a fake filename, or LINE   -- pragma, the file name changes, so we need to compare the   -- locations only, with out the filename.-  compare (Comment _ ss1 _ _) (Comment _ ss2 _ _) = compare (ss2pos $ anchor ss1) (ss2pos $ anchor ss2)+  compare (Comment _ ss1 _ _) (Comment _ ss2 _ _) = compare (ss2pos $ epaLocationRealSrcSpan ss1) (ss2pos $ epaLocationRealSrcSpan ss2)     where       ss2pos ss = (srcSpanStartLine ss,srcSpanStartCol ss) 
src/Language/Haskell/GHC/ExactPrint/Utils.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE NamedFieldPuns #-}@@ -59,9 +60,7 @@ import qualified GHC import GHC hiding (EpaComment) import GHC.Base (NonEmpty(..))-import GHC.Data.Bag import GHC.Data.FastString-import qualified GHC.Data.Strict as Strict import GHC.Driver.Ppr import GHC.Hs.Dump import GHC.Parser.Lexer (allocateComments)@@ -69,7 +68,6 @@ import GHC.Types.Name.Reader import GHC.Types.SrcLoc -import Language.Haskell.GHC.ExactPrint.Lookup import Language.Haskell.GHC.ExactPrint.Types  import Debug.Trace@@ -169,13 +167,6 @@     fl = l + dl     fc = co + dc -undeltaSpan :: RealSrcSpan -> AnnKeywordId -> DeltaPos -> AddEpAnn-undeltaSpan anc kw dp = AddEpAnn kw (EpaSpan (RealSrcSpan sp Strict.Nothing))-  where-    (l,c) = undelta (ss2pos anc) dp (LayoutStartCol 0)-    len = length (keywordToString kw)-    sp = range2rs ((l,c),(l,c+len))- -- ---------------------------------------------------------------------  adjustDeltaForOffset :: LayoutStartCol -> DeltaPos -> DeltaPos@@ -233,8 +224,8 @@ -- `MovedAnchor` operation based on the original location, only if it -- does not already have one. commentOrigDelta :: LEpaComment -> LEpaComment-commentOrigDelta (L (EpaSpan (RealSrcSpan la _)) (GHC.EpaComment t pp))-  = (L (EpaDelta dp NoComments) (GHC.EpaComment t pp))+commentOrigDelta (L (EpaSpan ss@(RealSrcSpan la _)) (GHC.EpaComment t pp))+  = (L (EpaDelta ss dp NoComments) (GHC.EpaComment t pp))                   `debug` ("commentOrigDelta: (la, pp, r,c, dp)=" ++ showAst (la, pp, r,c, dp))   where         (r,c) = ss2posEnd pp@@ -275,7 +266,7 @@     addCommentsListItem :: EpAnn AnnListItem -> State [LEpaComment] (EpAnn AnnListItem)     addCommentsListItem = addComments -    addCommentsList :: EpAnn AnnList -> State [LEpaComment] (EpAnn AnnList)+    addCommentsList :: EpAnn (AnnList ()) -> State [LEpaComment] (EpAnn (AnnList ()))     addCommentsList = addComments      addCommentsGrhs :: EpAnn GrhsAnn -> State [LEpaComment] (EpAnn GrhsAnn)@@ -306,7 +297,7 @@                                         (sortEpaComments $ fc ++ cs_after)              where                (cs_before,cs_after)-                   = break (\(L ll _) -> (ss2pos $ anchor ll) > (ss2pos $ anchor ac) )+                   = break (\(L ll _) -> (ss2pos $ epaLocationRealSrcSpan ll) > (ss2pos $ epaLocationRealSrcSpan ac) )                            new  insertTopLevelCppComments ::  HsModule GhcPs -> [LEpaComment] -> (HsModule GhcPs, [LEpaComment])@@ -322,7 +313,7 @@         Just _ ->             -- We have a module name. Capture all comments up to the `where`             let-              (these, remaining) = splitOnWhere Before (am_main $ anns an) cs+              (these, remaining) = splitOnWhere Before (am_where $ anns an) cs               (EpAnn a anno ocs) = an :: EpAnn AnnsModule               anm = EpAnn a anno (workInComments ocs these)             in@@ -330,15 +321,15 @@     (an1,cs0a) = case lo of         EpExplicitBraces (EpTok (EpaSpan (RealSrcSpan s _))) _close ->             let-                (stay,cs0a') = break (\(L ll _) -> (ss2pos $ anchor ll) > (ss2pos $ s)) cs0+                (stay,cs0a') = break (\(L ll _) -> (ss2pos $ epaLocationRealSrcSpan ll) > (ss2pos $ s)) cs0                 cs' = workInComments (comments an0) stay             in (an0 { comments = cs' }, cs0a')         _ -> (an0,cs0)     -- Deal with possible leading semis     (an2, cs0b) = case am_decls $ anns an1 of-        (AddSemiAnn (EpaSpan (RealSrcSpan s _)):_) -> (an1 {comments = cs'}, cs0b')+        (AddSemiAnn (EpTok (EpaSpan (RealSrcSpan s _))):_) -> (an1 {comments = cs'}, cs0b')           where-            (stay,cs0b') = break (\(L ll _) -> (ss2pos $ anchor ll) > (ss2pos $ s)) cs0a+            (stay,cs0b') = break (\(L ll _) -> (ss2pos $ epaLocationRealSrcSpan ll) > (ss2pos $ s)) cs0a             cs' = workInComments (comments an1) stay         _ -> (an1,cs0a) @@ -349,10 +340,10 @@                          where                            hc1' = workInComments (comments an2) csh'                            an3' = an2 { comments = hc1' }-                           (csh', cs0b') = case al_open $ anns l of-                               Just (AddEpAnn _ (EpaSpan (RealSrcSpan s _))) ->(h, n)+                           (csh', cs0b') = case annListBracketsLocs $ al_brackets $ anns l of+                               (EpaSpan (RealSrcSpan s _),_) ->(h, n)                                  where-                                   (h,n) = break (\(L ll _) -> (ss2pos $ anchor ll) > (ss2pos s) )+                                   (h,n) = break (\(L ll _) -> (ss2pos $ epaLocationRealSrcSpan ll) > (ss2pos s) )                                        cs0b                                 _ -> ([], cs0b)@@ -366,9 +357,9 @@     -- Either hc0i or hc0d should have comments. Combine them     hc0 = hc0i ++ hc0d -    (hc1,hc_cs) = if null ( am_main $ anns an3)+    (hc1,hc_cs) = if NoEpTok == (am_where $ anns an3)         then (hc0,[])-        else splitOnWhere After (am_main $ anns an3)  hc0+        else splitOnWhere After (am_where $ anns an3)  hc0     hc2 = workInComments (comments an3) hc1     an4 = an3 { anns = (anns an3) {am_cs = hc_cs}, comments = hc2 } @@ -384,16 +375,23 @@         cs4' = workInComments cs4 these         (xs',rest') = allocPreceding xs rest +annListBracketsLocs :: AnnListBrackets -> (EpaLocation,EpaLocation)+annListBracketsLocs (ListParens o c) = (getEpTokenLoc o,    getEpTokenLoc c)+annListBracketsLocs (ListBraces o c) = (getEpTokenLoc o,    getEpTokenLoc c)+annListBracketsLocs (ListSquare o c) = (getEpTokenLoc o,    getEpTokenLoc c)+annListBracketsLocs (ListBanana o c) = (getEpUniTokenLoc o, getEpUniTokenLoc c)+annListBracketsLocs ListNone         = (noAnn,              noAnn)++ data SplitWhere = Before | After-splitOnWhere :: SplitWhere -> [AddEpAnn] -> [LEpaComment] -> ([LEpaComment], [LEpaComment])-splitOnWhere _ [] csIn = (csIn,[])-splitOnWhere w (AddEpAnn AnnWhere (EpaSpan (RealSrcSpan s _)):_) csIn = (hc, fc)++splitOnWhere :: SplitWhere -> EpToken "where" -> [LEpaComment] -> ([LEpaComment], [LEpaComment])+splitOnWhere w (EpTok (EpaSpan (RealSrcSpan s _))) csIn = (hc, fc)   where     splitFunc Before anc_pos c_pos = c_pos < anc_pos     splitFunc After  anc_pos c_pos = anc_pos < c_pos-    (hc,fc) = break (\(L ll _) ->  splitFunc w (ss2pos $ anchor ll) (ss2pos s)) csIn-splitOnWhere _ (AddEpAnn AnnWhere _:_) csIn = (csIn, [])-splitOnWhere f (_:as) csIn = splitOnWhere f as csIn+    (hc,fc) = break (\(L ll _) ->  splitFunc w (ss2pos $ epaLocationRealSrcSpan ll) (ss2pos s)) csIn+splitOnWhere _ _ csIn = (csIn,[])  balanceFirstLocatedAComments :: [LocatedA a] -> ([LocatedA a], [LEpaComment]) balanceFirstLocatedAComments [] = ([],[])@@ -403,7 +401,7 @@         EpaSpan (RealSrcSpan s _) -> (csd', hc)                `debug` ("balanceFirstLocatedAComments: (csd,csd',attached,header)=" ++ showAst (csd,csd',attached,header))           where-            (priors, inners) =  break (\(L ll _) -> (ss2pos $ anchor ll) > (ss2pos s) )+            (priors, inners) =  break (\(L ll _) -> (ss2pos $ epaLocationRealSrcSpan ll) > (ss2pos s) )                                        (priorComments csd)             pcds = priorCommentsDeltas' s priors             (attached, header) = break (\(d,_c) -> d /= 1) pcds@@ -419,14 +417,14 @@   where     go :: RealSrcSpan -> [LEpaComment] -> [(Int, LEpaComment)]     go _   [] = []-    go _   (la@(L l@(EpaDelta dp _) _):las) = (deltaLine dp, la) : go (anchor l) las-    go rs' (la@(L l _):las) = deltaComment rs' la : go (anchor l) las+    go _   (la@(L l@(EpaDelta _ dp _) _):las) = (getDeltaLine dp, la) : go (epaLocationRealSrcSpan l) las+    go rs' (la@(L l _):las) = deltaComment rs' la : go (epaLocationRealSrcSpan l) las      deltaComment :: RealSrcSpan -> LEpaComment -> (Int, LEpaComment)     deltaComment rs' (L loc c) = (abs(ll - al), L loc c)       where         (al,_) = ss2pos rs'-        (ll,_) = ss2pos (anchor loc)+        (ll,_) = ss2pos (epaLocationRealSrcSpan loc)  allocatePriorComments   :: Pos@@ -434,7 +432,7 @@   -> ([LEpaComment], [LEpaComment]) allocatePriorComments ss_loc comment_q =   let-    cmp (L l _) = ss2pos (anchor l) <= ss_loc+    cmp (L l _) = ss2pos (epaLocationRealSrcSpan l) <= ss_loc     (newAnns,after) = partition cmp comment_q   in     (after, newAnns)@@ -451,7 +449,7 @@             EpTok (EpaSpan (RealSrcSpan s _)) -> ss2pos s             _ -> (1,1)         _ -> (1,1)-    (new_before, new_after) = break (\(L ll _) -> (ss2pos $ anchor ll) > end_loc ) cs+    (new_before, new_after) = break (\(L ll _) -> (ss2pos $ epaLocationRealSrcSpan ll) > end_loc ) cs      addTrailingComments end_loc' cur new = epaCommentsBalanced pc' fc'       where@@ -462,8 +460,8 @@             (L ac _:_) -> (sortEpaComments $ pc ++ cs_before, sortEpaComments $ fc ++ cs_after)               where                (cs_before,cs_after)-                   = if (ss2pos $ anchor ac) > end_loc'-                       then break (\(L ll _) -> (ss2pos $ anchor ll) > (ss2pos $ anchor ac) ) new+                   = if (ss2pos $ epaLocationRealSrcSpan ac) > end_loc'+                       then break (\(L ll _) -> (ss2pos $ epaLocationRealSrcSpan ll) > (ss2pos $ epaLocationRealSrcSpan ac) ) new                        else (new_before, new_after)  -- ---------------------------------------------------------------------@@ -480,7 +478,7 @@     (GHC.EpaComment (EpaDocComment dc) pt) -> hsDocStringComments (noCommentsToEpaLocation lt) pt dc     _ -> [mkComment (normaliseCommentText (ghcCommentText t)) lt (ac_prior_tok c)] -hsDocStringComments :: Anchor -> RealSrcSpan -> GHC.HsDocString -> [Comment]+hsDocStringComments :: EpaLocation -> RealSrcSpan -> GHC.HsDocString -> [Comment] hsDocStringComments _ pt (MultiLineDocString dec (x :| xs)) =   let     decStr = printDecorator dec@@ -544,7 +542,7 @@  -- |Must compare without span filenames, for CPP injected comments with fake filename cmpComments :: Comment -> Comment -> Ordering-cmpComments (Comment _ l1 _ _) (Comment _ l2 _ _) = compare (ss2pos $ anchor l1) (ss2pos $ anchor l2)+cmpComments (Comment _ l1 _ _) (Comment _ l2 _ _) = compare (ss2pos $ epaLocationRealSrcSpan l1) (ss2pos $ epaLocationRealSrcSpan l2)  -- |Sort, comparing without span filenames, for CPP injected comments with fake filename sortComments :: [Comment] -> [Comment]@@ -554,19 +552,16 @@ sortEpaComments :: [LEpaComment] -> [LEpaComment] sortEpaComments cs = sortBy cmp cs   where-    cmp (L l1 _) (L l2 _) = compare (ss2pos $ anchor l1) (ss2pos $ anchor l2)+    cmp (L l1 _) (L l2 _) = compare (ss2pos $ epaLocationRealSrcSpan l1) (ss2pos $ epaLocationRealSrcSpan l2)  -- | Makes a comment which originates from a specific keyword.-mkKWComment :: AnnKeywordId -> NoCommentsLocation -> Comment-mkKWComment kw (EpaSpan (RealSrcSpan ss mb))-  = Comment (keywordToString kw) (EpaSpan (RealSrcSpan ss mb)) ss (Just kw)-mkKWComment kw (EpaSpan (UnhelpfulSpan _))-  = Comment (keywordToString kw) (EpaDelta (SameLine 0) NoComments) placeholderRealSpan (Just kw)-mkKWComment kw (EpaDelta dp cs)-  = Comment (keywordToString kw) (EpaDelta dp cs) placeholderRealSpan (Just kw)+mkKWComment :: String -> NoCommentsLocation -> Comment+mkKWComment kw (EpaSpan (RealSrcSpan ss mb)) = Comment kw (EpaSpan (RealSrcSpan ss mb)) ss (Just kw)+mkKWComment kw (EpaSpan (UnhelpfulSpan _))   = Comment kw (EpaDelta noSrcSpan (SameLine 0) NoComments) placeholderRealSpan (Just kw)+mkKWComment kw (EpaDelta ss dp cs)           = Comment kw (EpaDelta ss dp cs) placeholderRealSpan (Just kw) -sortAnchorLocated :: [GenLocated Anchor a] -> [GenLocated Anchor a]-sortAnchorLocated = sortBy (compare `on` (anchor . getLoc))+sortAnchorLocated :: [GenLocated EpaLocation a] -> [GenLocated EpaLocation a]+sortAnchorLocated = sortBy (compare `on` (epaLocationRealSrcSpan . getLoc))  -- | Calculates the distance from the start of a string to the end of -- a string.@@ -602,25 +597,6 @@  -- --------------------------------------------------------------------- -trailingAnnLoc :: TrailingAnn -> EpaLocation-trailingAnnLoc (AddSemiAnn ss)    = ss-trailingAnnLoc (AddCommaAnn ss)   = ss-trailingAnnLoc (AddVbarAnn ss)    = ss-trailingAnnLoc (AddDarrowAnn ss)  = ss-trailingAnnLoc (AddDarrowUAnn ss) = ss--setTrailingAnnLoc :: TrailingAnn -> EpaLocation -> TrailingAnn-setTrailingAnnLoc (AddSemiAnn _)    ss = (AddSemiAnn ss)-setTrailingAnnLoc (AddCommaAnn _)   ss = (AddCommaAnn ss)-setTrailingAnnLoc (AddVbarAnn _)    ss = (AddVbarAnn ss)-setTrailingAnnLoc (AddDarrowAnn _)  ss = (AddDarrowAnn ss)-setTrailingAnnLoc (AddDarrowUAnn _) ss = (AddDarrowUAnn ss)--addEpAnnLoc :: AddEpAnn -> EpaLocation-addEpAnnLoc (AddEpAnn _ l) = l---- ---------------------------------------------------------------------- type DeclsByTag a = Map.Map DeclTag [(RealSrcSpan, a)]  orderedDecls@@ -657,7 +633,7 @@       decls           = orderedDecls sortKey $ Map.fromList               [(ClsSigTag,    map (\(L l s) -> (srs l, L l (SigD noExtField s))) sigs),-               (ClsMethodTag, map (\(L l s) -> (srs l, L l (ValD noExtField s))) (bagToList methods)),+               (ClsMethodTag, map (\(L l s) -> (srs l, L l (ValD noExtField s))) methods),                (ClsAtTag,     map (\(L l s) -> (srs l, L l (TyClD noExtField $ FamDecl noExtField s))) ats),                (ClsAtdTag,    map (\(L l s) -> (srs l, L l (InstD noExtField $ TyFamInstD noExtField s))) at_defs)               ]@@ -681,12 +657,12 @@       [LTyFamInstDecl GhcPs], [LDataFamInstDecl GhcPs], [LDocDecl GhcPs]) partitionWithSortKey = go   where-    go [] = ([], emptyBag, [], [], [], [], [])+    go [] = ([], [], [], [], [], [], [])     go ((L l decl) : ds) =       let (tags, bs, ss, ts, tfis, dfis, docs) = go ds in       case decl of         ValD _ b-          -> (ClsMethodTag:tags, L l b `consBag` bs, ss, ts, tfis, dfis, docs)+          -> (ClsMethodTag:tags, L l b : bs, ss, ts, tfis, dfis, docs)         SigD _ s           -> (ClsSigTag:tags, bs, L l s : ss, ts, tfis, dfis, docs)         TyClD _ (FamDecl _ t)@@ -724,7 +700,7 @@ hsDeclsLocalBinds lb = case lb of     HsValBinds _ (ValBinds sortKey bs sigs) ->       let-        bds = map wrapDecl (bagToList bs)+        bds = map wrapDecl bs         sds = map wrapSig sigs       in         orderedDeclsBinds sortKey bds sds@@ -735,7 +711,7 @@ hsDeclsValBinds :: (HsValBindsLR GhcPs GhcPs) -> [LHsDecl GhcPs] hsDeclsValBinds (ValBinds sortKey bs sigs) =       let-        bds = map wrapDecl (bagToList bs)+        bds = map wrapDecl bs         sds = map wrapSig sigs       in         orderedDeclsBinds sortKey bds sds
tests/Test.hs view
@@ -28,32 +28,34 @@  -- --------------------------------------------------------------------- -data GHCVersion = GHC98-           | GHC910+data GHCVersion = GHC910+           | GHC912      deriving (Eq, Ord, Show)  ghcVersion :: GHCVersion-#if MIN_VERSION_ghc(9,10,0)-ghcVersion = GHC910+#if MIN_VERSION_ghc(9,12,0)+ghcVersion = GHC912 #else-ghcVersion = GHC98+ghcVersion = GHC910 #endif  -- | Directories to automatically find roundtrip tests testDirs :: [FilePath] testDirs =   case ghcVersion of-    GHC98 -> ["pre-ghc910"]     GHC910 -> ["pre-ghc910", "ghc910"]-    -- GHC910  -> ["ghc910"]-    -- GHC910  -> ["ghc910-copied"]-    -- GHC910  -> ["ghc910",  "ghc910-copied"]+    GHC912 -> ["pre-ghc910", "ghc910", "ghc912"]+    -- GHC912  -> ["ghc912"]+    -- GHC912  -> ["ghc912-copied"]+    -- GHC912  -> ["ghc912",  "ghc912-copied"]  -- ---------------------------------------------------------------------  main :: IO () main = hSilence [stderr] $ do   print ghcVersion+  cwd <- getCurrentDirectory+  putStrLn $ "cwd:" ++ show cwd   tests <- mkTests   cnts <- fst <$> runTestText (putTextToHandle stdout True) tests   putStrLn $ show cnts@@ -206,8 +208,15 @@     -- mkParserTest libdir "ghc910" "CppComment.hs"     -- mkParserTest libdir "ghc910" "Class.hs"     -- mkParserTest libdir "ghc910" "Test138.hs"-    mkParserTest libdir "vect" "DiophantineVect.hs"+    -- mkParserTest libdir "vect" "DiophantineVect.hs" +    -- mkParserTest libdir "pre-ghc910" "RandomPGC.hs"++    -- mkParserTest libdir "ghc912" "Module.hs"+    -- mkParserTest libdir "ghc912" "tests.hs"+    mkParserTestMD libdir "ghc912" "Fff.hs"+    -- mkParserTestMD libdir "ghc912" "Module.hs"+    -- mkParserTestMD libdir "ghc912" "Operator.hs"    -- Needs GHC changes  
tests/Test/Transform.hs view
@@ -13,7 +13,6 @@ import Language.Haskell.GHC.ExactPrint.Utils  import GHC                       as GHC-import GHC.Data.Bag              as GHC import GHC.Data.FastString       as GHC import GHC.Types.Name.Occurrence as GHC import GHC.Types.Name.Reader     as GHC@@ -131,15 +130,17 @@       replaceLocalBinds :: LMatch GhcPs (LHsExpr GhcPs)                         -> Transform (LMatch GhcPs (LHsExpr GhcPs))       replaceLocalBinds (L lm (Match ma mln pats (GRHSs _ rhs EmptyLocalBinds{}))) = do-        let anc = (EpaDelta (DifferentLine 1 3) [])-        let anc2 = (EpaDelta (DifferentLine 1 5) [])+        let anc = (EpaDelta noSrcSpan (DifferentLine 1 3) [])+        let anc2 = (EpaDelta noSrcSpan (DifferentLine 1 5) [])         let an = EpAnn anc-                        (AnnList (Just anc2) Nothing Nothing-                                 [AddEpAnn AnnWhere (EpaDelta (SameLine 0) [])] [])+                        (AnnList (Just anc2) ListNone+                                 []+                                 (EpTok (EpaDelta noSrcSpan (SameLine 0) []))+                                 [])                         emptyComments         let decls = [s,d]         let sortKey = captureOrderBinds decls-        let binds = (HsValBinds an (ValBinds sortKey (listToBag $ [decl'])+        let binds = (HsValBinds an (ValBinds sortKey [decl']                                     [sig']))         return (L lm (Match ma mln pats (GRHSs emptyComments rhs binds)))       replaceLocalBinds x = return x@@ -159,7 +160,7 @@       replaceLocalBinds :: LMatch GhcPs (LHsExpr GhcPs)                         -> Transform (LMatch GhcPs (LHsExpr GhcPs))       replaceLocalBinds (L lm (Match an mln pats (GRHSs _ rhs (HsValBinds van (ValBinds _ binds sigs))))) = do-        let oldDecls = sortLocatedA $ map wrapDecl (bagToList binds) ++ map wrapSig sigs+        let oldDecls = sortLocatedA $ map wrapDecl binds ++ map wrapSig sigs         let decls = s:d:oldDecls         let oldDecls' = captureLineSpacing oldDecls         let oldBinds     = concatMap decl2Bind oldDecls'@@ -167,11 +168,11 @@             os' = setEntryDP os (DifferentLine 2 0)         let sortKey = captureOrderBinds decls         let (EpAnn anc (AnnList (Just _) a b c dd) cs) = van-        let van' = (EpAnn anc (AnnList (Just (EpaDelta (DifferentLine 1 5) [])) a b c dd) cs)+        let van' = (EpAnn anc (AnnList (Just (EpaDelta noSrcSpan (DifferentLine 1 5) [])) a b c dd) cs)         -- let (EpAnn anc (AnnList (Just _) a b c dd) cs) = van         -- let van' = (EpAnn anc (AnnList (Just (EpaDelta (DifferentLine 1 5) [])) a b c dd) cs)         let binds' = (HsValBinds van'-                          (ValBinds sortKey (listToBag $ decl':oldBinds)+                          (ValBinds sortKey (decl':oldBinds)                                           (sig':os':oldSigs)))         return (L lm (Match an mln pats (GRHSs emptyComments rhs binds')))                    `debug` ("oldDecls=" ++ showAst oldDecls)@@ -263,13 +264,13 @@     replace :: HsExpr GhcPs -> HsExpr GhcPs     replace (HsLet (tkLet, _) localDecls expr)       =-         let (HsValBinds x (ValBinds xv bagDecls sigs)) = localDecls-             [l2,_l1] = map wrapDecl $ bagToList bagDecls-             bagDecls' = listToBag $ concatMap decl2Bind [l2]+         let (HsValBinds x (ValBinds xv decls sigs)) = localDecls+             [l2,_l1] = map wrapDecl decls+             bagDecls' = concatMap decl2Bind [l2]              (L _ e) = expr-             a = EpAnn (EpaDelta (SameLine 1) []) noAnn emptyComments+             a = EpAnn (EpaDelta noSrcSpan (SameLine 1) []) noAnn emptyComments              expr' = L a e-             tkIn' = EpTok (EpaDelta (DifferentLine 1 0) [])+             tkIn' = EpTok (EpaDelta noSrcSpan (DifferentLine 1 0) [])          in (HsLet (tkLet, tkIn')                 (HsValBinds x (ValBinds xv bagDecls' sigs)) expr') @@ -463,6 +464,7 @@   let (lp',_,_w) = runTransform doRmDecl   debugM $ "log:[\n" ++ intercalate "\n" _w ++ "]log end\n"   return lp'+ -- ---------------------------------------------------------------------  rmDecl3 :: Changer@@ -471,9 +473,9 @@       doRmDecl = replaceDecls lp [de1',sd1,d2]         where           [de1,d2] = hsDecls lp-          (de1',Just sd1) = modifyValD (getLocA de1) de1 $ \_m [sd1] ->+          (de1',Just sd1) = modifyValD (getLocA de1) de1 $ \_m [sd1a] ->                        let-                           sd1' = setEntryDP sd1 (DifferentLine 2 0)+                           sd1' = setEntryDP sd1a (DifferentLine 2 0)                        in ([],Just sd1')        lp' = doRmDecl@@ -487,10 +489,10 @@       doRmDecl = replaceDecls (anchorEof lp) [de1',sd1]         where          [de1] = hsDecls lp-         (de1',Just sd1) = modifyValD (getLocA de1) de1 $ \_m [sd1,sd2] ->+         (de1',Just sd1) = modifyValD (getLocA de1) de1 $ \_m [sd1a,sd2] ->            let-             sd2' = transferEntryDP' sd1 sd2-             sd1' = setEntryDP sd1 (DifferentLine 2 0)+             sd2' = transferEntryDP' sd1a sd2+             sd1' = setEntryDP sd1a (DifferentLine 2 0)            in ([sd2'],Just sd1')       lp' = doRmDecl   return lp'@@ -505,9 +507,7 @@           go :: HsExpr GhcPs -> Transform (HsExpr GhcPs)           go (HsLet (tkLet, tkIn) lb expr) = do             let decs = hsDeclsLocalBinds lb-            let hdecs : _ = decs             let dec = last decs-            -- _ <- transferEntryDP hdecs dec             let lb' = replaceDeclsValbinds WithoutWhere lb [dec]             return (HsLet (tkLet, tkIn) lb' expr)           go x = return x@@ -593,9 +593,9 @@           v2 = L (           noAnnSrcSpanDP0) (IEVar Nothing (L noAnnSrcSpanDP0 (IEName noExtField n2)) Nothing)           impHiding = L (EpAnn d0                                (AnnList Nothing-                                        (Just (AddEpAnn AnnOpenP  d1))-                                        (Just (AddEpAnn AnnCloseP d0))-                                        [(AddEpAnn AnnHiding d1)]+                                        (ListParens  (EpTok  d1) (EpTok d0))+                                        []+                                        (EpTok d1, [])                                         [])                                  emptyComments) [v1,v2]           imp1' = imp1 { ideclImportList = Just (EverythingBut,impHiding)}@@ -618,9 +618,9 @@           Just (_,L _lh ns) = ideclImportList imp1           lh' = (EpAnn d0                        (AnnList Nothing-                                (Just (AddEpAnn AnnOpenP  d1))-                                (Just (AddEpAnn AnnCloseP d0))-                                [(AddEpAnn AnnHiding d1)]+                                (ListParens (EpTok d1) (EpTok d0))+                                []+                                (EpTok d1, [])                                 [])                          emptyComments)           n1 = L (noAnnSrcSpanDP0) (mkVarUnqual (mkFastString "n1"))
+ tests/examples/ghc910/ConPat.hs view
@@ -0,0 +1,17 @@+module ConPat where+++++++++++++++yyy = let snd:fst:xs = flipFirst global+       in f fst snd
+ tests/examples/ghc910/Operator1.hs view
@@ -0,0 +1,7 @@+module Operator1 where++main :: IO ()+main = do+  putStrLn $ show {- c3 -} $ {- c4 -} foo {- c1 -} || {- c2 -} bar++{-# RULES "print" forall x. putStrLn $ show $ x = print $ x #-}
+ tests/examples/ghc912/Fff.hs view
@@ -0,0 +1,1 @@+test = foo . not . not
+ tests/examples/ghc912/Module.hs view
@@ -0,0 +1,7 @@+module Module where++fff = do+     let {+         ; (a, b) = foo+         }+     pure ()
+ tests/examples/ghc912/Operator.hs view
@@ -0,0 +1,54 @@+module Operator where++main :: IO ()+main = do+  print $ 3 + 4+  -- lets make sure+  print $ foo ||+    -- that comments end up in the right place+    bar ||+    baz &&+    -- even this one+    quux++  -- lets also make sure+  print $ foo+    -- that these comments end up in the right place+    || bar+    || baz+    -- even when the operator is leading+    && quux++  return ({- comment -} x >= 1 || y >= 2)++  print $ foo || bar+  print $ foo || bar+  print $ foo || bar+  print $  {- comment here -} foo || bar+  print $ foo {- comment here -} || bar+  print $ foo || {- comment here -} bar+  print $ foo || bar {- comment here -}++  print $ foo || bar+  print $ foo || bar++{-# RULES "print" forall x. putStrLn $ show $ x = print $ x #-}++f :: Int -> Bool+f x = x == 2++g :: Int -> Bool+g y = (y == 2) /= False++roundtrip :: IO [a]+roundtrip = return $ mconcat+  [ timeToText $ time_enrolled - mod time_enrolled t+  , ":"+  ]++-- Ensure local fixity declarations are handled properly+(.@@@) :: (a -> b) -> a -> b+f .@@@ x = f x++infixr 0 .@@@+{-# RULES "printAt" forall x. putStrLn .@@@ show .@@@ x = print $ x #-}
+ tests/examples/ghc912/T23501a.hs view
@@ -0,0 +1,140 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE TypeAbstractions #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE DataKinds, NoListTuplePuns #-}++module T23501a where++import Prelude.Experimental (List, Unit)+import Data.Kind (Type, Constraint)++----------------------------+--   Class declarations   --+----------------------------++class C1 (_ :: k) _   -- no SAKS+  where f1 :: k -> Unit++f1' :: C1 @k a b => k -> Unit+f1' @_ @a @b = f1 @_ @a @b++type C2 :: k1 -> k2 -> Constraint+class C2 (_ :: k) _ where+  f2 :: k -> Unit++f2' :: C2 @k1 @k2 a b => k1 -> Unit+f2' @_ @_ @a @b = f2 @_ @_ @a @b++type C3 :: k1 -> k2 -> Constraint+class C3 @k @_ _ _ where+  f3 :: k -> Unit++f3' :: C3 @k1 @k2 a b => k1 -> Unit+f3' @_ @_ @a @b = f3 @_ @_ @a @b++---------------------------+--   Data declarations   --+---------------------------++data D1 k (_ :: k) _  -- no SAKS+  where MkD1 :: k -> D1 k a b++mkD1 :: k -> D1 k a b+mkD1 = MkD1++type D2 :: forall (k1 :: Type) -> k1 -> k2 -> Type+data D2 k (_ :: k) _ where+  MkD2 :: k -> D2 k a b++mkD2 :: k -> D2 k a b+mkD2 = MkD2++type D3 :: k1 -> k2 -> Type+data D3 @k @_ _ _ = MkD3 k++data MProxy (_ :: Type) = MPrx+data CProxy (_ :: k -> Constraint) = CPrx++type Rec :: (k -> Type) -> List k -> Type+data Rec _ _ where+  RNil :: Rec f []+  (:&) :: f x -> Rec f xs -> Rec f (x:xs)++------------------+--   Newtypes   --+------------------++newtype N1 k (_ :: k) _   -- no SAKS+  = MkN1 k++mkN1 :: k -> N1 k a b+mkN1 = MkN1++type N2 :: forall (k1 :: Type) -> k1 -> k2 -> Type+newtype N2 k (_ :: k) _ = MkN2 k++mkN2 :: k -> N2 k a b+mkN2 = MkN2++----------------------------+--   Open type families   --+----------------------------++type family OTF1 (_ :: Type -> Type) _    -- no SAKS++type instance OTF1 f x = f x++otf1 :: OTF1 Maybe Int -> Int+otf1 Nothing = 0+otf1 (Just x) = x++type OTF2 :: (Type -> Type) -> Type -> Type+type family OTF2 (_ :: Type -> Type) _++type instance OTF2 f x = f x++otf2 :: OTF2 Maybe Int -> Int+otf2 Nothing = 0+otf2 (Just x) = x++------------------------------+--   Closed type families   --+------------------------------++type family CTF1 (_ :: Type -> Type) _  -- no SAKS+  where CTF1 f x = f x++ctf1 :: CTF1 Maybe Int -> Int+ctf1 Nothing = 0+ctf1 (Just x) = x++type CTF2 :: (Type -> Type) -> Type -> Type+type family CTF2 (_ :: Type -> Type) _ where+  CTF2 f x = f x++ctf2 :: CTF2 Maybe Int -> Int+ctf2 Nothing = 0+ctf2 (Just x) = x++type CTF3 :: k1 -> k2 -> Type+type family CTF3 @_ @k _ _+  where CTF3 @_ @k _ _ = k++ctf3 :: CTF3 a True -> Bool+ctf3 = id++-----------------------+--   Type synonyms   --+-----------------------++type T1 (_ :: Type -> Type) _ = ()   -- no SAKS++type T2 :: (Type -> Type) -> k -> Type+type T2 (_ :: Type -> Type) _ = Unit++type T3 :: k1 -> k2 -> Type+type T3 @_ @k _ _ = k++type FConst _ = ()+
− tests/examples/pre-ghc910/RandomPGC.hs
@@ -1,597 +0,0 @@-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 701-{-# LANGUAGE Trustworthy #-}-#endif---------------------------------------------------------------------------------- |--- Module      :  System.Random--- Copyright   :  (c) The University of Glasgow 2001--- License     :  BSD-style (see the file LICENSE in the 'random' repository)------ Maintainer  :  libraries@haskell.org--- Stability   :  stable--- Portability :  portable------ This library deals with the common task of pseudo-random number--- generation. The library makes it possible to generate repeatable--- results, by starting with a specified initial random number generator,--- or to get different results on each run by using the system-initialised--- generator or by supplying a seed from some other source.------ The library is split into two layers:------ * A core /random number generator/ provides a supply of bits.---   The class 'RandomGen' provides a common interface to such generators.---   The library provides one instance of 'RandomGen', the abstract---   data type 'StdGen'.  Programmers may, of course, supply their own---   instances of 'RandomGen'.------ * The class 'Random' provides a way to extract values of a particular---   type from a random number generator.  For example, the 'Float'---   instance of 'Random' allows one to generate random values of type---   'Float'.------ This implementation uses the Portable Combined Generator of L'Ecuyer--- ["System.Random\#LEcuyer"] for 32-bit computers, transliterated by--- Lennart Augustsson.  It has a period of roughly 2.30584e18.-----------------------------------------------------------------------------------#include "MachDeps.h"--module RandomPGC-        (--        -- $intro--        -- * Random number generators--#ifdef ENABLE_SPLITTABLEGEN-          RandomGen(next, genRange)-        , SplittableGen(split)-#else-          RandomGen(next, genRange, split)-#endif-        -- ** Standard random number generators-        , StdGen-        , mkStdGen--        -- ** The global random number generator--        -- $globalrng--        , getStdRandom-        , getStdGen-        , setStdGen-        , newStdGen--        -- * Random values of various types-        , Random ( random,   randomR,-                   randoms,  randomRs,-                   randomIO, randomRIO )--        -- * References-        -- $references--        ) where--import Prelude--import Data.Bits-import Data.Int-import Data.Word-import Foreign.C.Types--#ifdef __NHC__-import CPUTime          ( getCPUTime )-import Foreign.Ptr      ( Ptr, nullPtr )-import Foreign.C        ( CTime, CUInt )-#else-import System.CPUTime   ( getCPUTime )-import Data.Time        ( getCurrentTime, UTCTime(..) )-import Data.Ratio       ( numerator, denominator )-#endif-import Data.Char        ( isSpace, chr, ord )-import System.IO.Unsafe ( unsafePerformIO )-import Data.IORef       ( IORef, newIORef, readIORef, writeIORef )-import Data.IORef       ( atomicModifyIORef' )-import Numeric          ( readDec )--#ifdef __GLASGOW_HASKELL__-import GHC.Exts         ( build )-#else--- | A dummy variant of build without fusion.-{-# INLINE build #-}-build :: ((a -> [a] -> [a]) -> [a] -> [a]) -> [a]-build g = g (:) []-#endif---- The standard nhc98 implementation of Time.ClockTime does not match--- the extended one expected in this module, so we lash-up a quick--- replacement here.-#ifdef __NHC__-foreign import ccall "time.h time" readtime :: Ptr CTime -> IO CTime-getTime :: IO (Integer, Integer)-getTime = do CTime t <- readtime nullPtr;  return (toInteger t, 0)-#else-getTime :: IO (Integer, Integer)-getTime = do-  utc <- getCurrentTime-  let daytime = toRational $ utctDayTime utc-  return $ quotRem (numerator daytime) (denominator daytime)-#endif---- | The class 'RandomGen' provides a common interface to random number--- generators.----#ifdef ENABLE_SPLITTABLEGEN--- Minimal complete definition: 'next'.-#else--- Minimal complete definition: 'next' and 'split'.-#endif--class RandomGen g where--   -- |The 'next' operation returns an 'Int' that is uniformly distributed-   -- in the range returned by 'genRange' (including both end points),-   -- and a new generator.-   next     :: g -> (Int, g)--   -- |The 'genRange' operation yields the range of values returned by-   -- the generator.-   ---   -- It is required that:-   ---   -- * If @(a,b) = 'genRange' g@, then @a < b@.-   ---   -- * 'genRange' always returns a pair of defined 'Int's.-   ---   -- The second condition ensures that 'genRange' cannot examine its-   -- argument, and hence the value it returns can be determined only by the-   -- instance of 'RandomGen'.  That in turn allows an implementation to make-   -- a single call to 'genRange' to establish a generator's range, without-   -- being concerned that the generator returned by (say) 'next' might have-   -- a different range to the generator passed to 'next'.-   ---   -- The default definition spans the full range of 'Int'.-   genRange :: g -> (Int,Int)--   -- default method-   genRange _ = (minBound, maxBound)--#ifdef ENABLE_SPLITTABLEGEN--- | The class 'SplittableGen' proivides a way to specify a random number---   generator that can be split into two new generators.-class SplittableGen g where-#endif-   -- |The 'split' operation allows one to obtain two distinct random number-   -- generators. This is very useful in functional programs (for example, when-   -- passing a random number generator down to recursive calls), but very-   -- little work has been done on statistically robust implementations of-   -- 'split' (["System.Random\#Burton", "System.Random\#Hellekalek"]-   -- are the only examples we know of).-   split    :: g -> (g, g)--{- |-The 'StdGen' instance of 'RandomGen' has a 'genRange' of at least 30 bits.--The result of repeatedly using 'next' should be at least as statistically-robust as the /Minimal Standard Random Number Generator/ described by-["System.Random\#Park", "System.Random\#Carta"].-Until more is known about implementations of 'split', all we require is-that 'split' deliver generators that are (a) not identical and-(b) independently robust in the sense just given.--The 'Show' and 'Read' instances of 'StdGen' provide a primitive way to save the-state of a random number generator.-It is required that @'read' ('show' g) == g@.--In addition, 'reads' may be used to map an arbitrary string (not necessarily one-produced by 'show') onto a value of type 'StdGen'. In general, the 'Read'-instance of 'StdGen' has the following properties:--* It guarantees to succeed on any string.--* It guarantees to consume only a finite portion of the string.--* Different argument strings are likely to result in different results.---}--data StdGen- = StdGen !Int32 !Int32--instance RandomGen StdGen where-  next  = stdNext-  genRange _ = stdRange--#ifdef ENABLE_SPLITTABLEGEN-instance SplittableGen StdGen where-#endif-  split = stdSplit--instance Show StdGen where-  showsPrec p (StdGen s1 s2) =-     showsPrec p s1 .-     showChar ' ' .-     showsPrec p s2--instance Read StdGen where-  readsPrec _p = \ r ->-     case try_read r of-       r'@[_] -> r'-       _   -> [stdFromString r] -- because it shouldn't ever fail.-    where-      try_read r = do-         (s1, r1) <- readDec (dropWhile isSpace r)-         (s2, r2) <- readDec (dropWhile isSpace r1)-         return (StdGen s1 s2, r2)--{-- If we cannot unravel the StdGen from a string, create- one based on the string given.--}-stdFromString         :: String -> (StdGen, String)-stdFromString s        = (mkStdGen num, rest)-        where (cs, rest) = splitAt 6 s-              num        = foldl (\a x -> x + 3 * a) 1 (map ord cs)---{- |-The function 'mkStdGen' provides an alternative way of producing an initial-generator, by mapping an 'Int' into a generator. Again, distinct arguments-should be likely to produce distinct generators.--}-mkStdGen :: Int -> StdGen -- why not Integer ?-mkStdGen s = mkStdGen32 $ fromIntegral s--{--From ["System.Random\#LEcuyer"]: "The integer variables s1 and s2 ... must be-initialized to values in the range [1, 2147483562] and [1, 2147483398]-respectively."--}-mkStdGen32 :: Int32 -> StdGen-mkStdGen32 sMaybeNegative = StdGen (s1+1) (s2+1)-      where-        -- We want a non-negative number, but we can't just take the abs-        -- of sMaybeNegative as -minBound == minBound.-        s       = sMaybeNegative .&. maxBound-        (q, s1) = s `divMod` 2147483562-        s2      = q `mod` 2147483398--createStdGen :: Integer -> StdGen-createStdGen s = mkStdGen32 $ fromIntegral s--{- |-With a source of random number supply in hand, the 'Random' class allows the-programmer to extract random values of a variety of types.--Minimal complete definition: 'randomR' and 'random'.---}--class Random a where-  -- | Takes a range /(lo,hi)/ and a random number generator-  -- /g/, and returns a random value uniformly distributed in the closed-  -- interval /[lo,hi]/, together with a new generator. It is unspecified-  -- what happens if /lo>hi/. For continuous types there is no requirement-  -- that the values /lo/ and /hi/ are ever produced, but they may be,-  -- depending on the implementation and the interval.-  randomR :: RandomGen g => (a,a) -> g -> (a,g)--  -- | The same as 'randomR', but using a default range determined by the type:-  ---  -- * For bounded types (instances of 'Bounded', such as 'Char'),-  --   the range is normally the whole type.-  ---  -- * For fractional types, the range is normally the semi-closed interval-  -- @[0,1)@.-  ---  -- * For 'Integer', the range is (arbitrarily) the range of 'Int'.-  random  :: RandomGen g => g -> (a, g)--  -- | Plural variant of 'randomR', producing an infinite list of-  -- random values instead of returning a new generator.-  {-# INLINE randomRs #-}-  randomRs :: RandomGen g => (a,a) -> g -> [a]-  randomRs ival g = build (\cons _nil -> buildRandoms cons (randomR ival) g)--  -- | Plural variant of 'random', producing an infinite list of-  -- random values instead of returning a new generator.-  {-# INLINE randoms #-}-  randoms  :: RandomGen g => g -> [a]-  randoms  g      = build (\cons _nil -> buildRandoms cons random g)--  -- | A variant of 'randomR' that uses the global random number generator-  -- (see "System.Random#globalrng").-  randomRIO :: (a,a) -> IO a-  randomRIO range  = getStdRandom (randomR range)--  -- | A variant of 'random' that uses the global random number generator-  -- (see "System.Random#globalrng").-  randomIO  :: IO a-  randomIO         = getStdRandom random---- | Produce an infinite list-equivalent of random values.-{-# INLINE buildRandoms #-}-buildRandoms :: RandomGen g-             => (a -> as -> as)  -- ^ E.g. '(:)' but subject to fusion-             -> (g -> (a,g))     -- ^ E.g. 'random'-             -> g                -- ^ A 'RandomGen' instance-             -> as-buildRandoms cons rand = go-  where-    -- The seq fixes part of #4218 and also makes fused Core simpler.-    go g = x `seq` (x `cons` go g') where (x,g') = rand g---instance Random Integer where-  randomR ival g = randomIvalInteger ival g-  random g       = randomR (toInteger (minBound::Int), toInteger (maxBound::Int)) g--instance Random Int        where randomR = randomIvalIntegral; random = randomBounded-instance Random Int8       where randomR = randomIvalIntegral; random = randomBounded-instance Random Int16      where randomR = randomIvalIntegral; random = randomBounded-instance Random Int32      where randomR = randomIvalIntegral; random = randomBounded-instance Random Int64      where randomR = randomIvalIntegral; random = randomBounded--#ifndef __NHC__--- Word is a type synonym in nhc98.-instance Random Word       where randomR = randomIvalIntegral; random = randomBounded-#endif-instance Random Word8      where randomR = randomIvalIntegral; random = randomBounded-instance Random Word16     where randomR = randomIvalIntegral; random = randomBounded-instance Random Word32     where randomR = randomIvalIntegral; random = randomBounded-instance Random Word64     where randomR = randomIvalIntegral; random = randomBounded--instance Random CChar      where randomR = randomIvalIntegral; random = randomBounded-instance Random CSChar     where randomR = randomIvalIntegral; random = randomBounded-instance Random CUChar     where randomR = randomIvalIntegral; random = randomBounded-instance Random CShort     where randomR = randomIvalIntegral; random = randomBounded-instance Random CUShort    where randomR = randomIvalIntegral; random = randomBounded-instance Random CInt       where randomR = randomIvalIntegral; random = randomBounded-instance Random CUInt      where randomR = randomIvalIntegral; random = randomBounded-instance Random CLong      where randomR = randomIvalIntegral; random = randomBounded-instance Random CULong     where randomR = randomIvalIntegral; random = randomBounded-instance Random CPtrdiff   where randomR = randomIvalIntegral; random = randomBounded-instance Random CSize      where randomR = randomIvalIntegral; random = randomBounded-instance Random CWchar     where randomR = randomIvalIntegral; random = randomBounded-instance Random CSigAtomic where randomR = randomIvalIntegral; random = randomBounded-instance Random CLLong     where randomR = randomIvalIntegral; random = randomBounded-instance Random CULLong    where randomR = randomIvalIntegral; random = randomBounded-instance Random CIntPtr    where randomR = randomIvalIntegral; random = randomBounded-instance Random CUIntPtr   where randomR = randomIvalIntegral; random = randomBounded-instance Random CIntMax    where randomR = randomIvalIntegral; random = randomBounded-instance Random CUIntMax   where randomR = randomIvalIntegral; random = randomBounded--instance Random Char where-  randomR (a,b) g =-       case (randomIvalInteger (toInteger (ord a), toInteger (ord b)) g) of-         (x,g') -> (chr x, g')-  random g        = randomR (minBound,maxBound) g--instance Random Bool where-  randomR (a,b) g =-      case (randomIvalInteger (bool2Int a, bool2Int b) g) of-        (x, g') -> (int2Bool x, g')-       where-         bool2Int :: Bool -> Integer-         bool2Int False = 0-         bool2Int True  = 1--         int2Bool :: Int -> Bool-         int2Bool 0     = False-         int2Bool _     = True--  random g        = randomR (minBound,maxBound) g--{-# INLINE randomRFloating #-}-randomRFloating :: (Fractional a, Num a, Ord a, Random a, RandomGen g) => (a, a) -> g -> (a, g)-randomRFloating (l,h) g-    | l>h       = randomRFloating (h,l) g-    | otherwise = let (coef,g') = random g in-                  (2.0 * (0.5*l + coef * (0.5*h - 0.5*l)), g')  -- avoid overflow--instance Random Double where-  randomR = randomRFloating-  random rng     =-    case random rng of-      (x,rng') ->-          -- We use 53 bits of randomness corresponding to the 53 bit significand:-          ((fromIntegral (mask53 .&. (x::Int64)) :: Double)-           /  fromIntegral twoto53, rng')-   where-    twoto53 = (2::Int64) ^ (53::Int64)-    mask53 = twoto53 - 1--instance Random Float where-  randomR = randomRFloating-  random rng =-    -- TODO: Faster to just use 'next' IF it generates enough bits of randomness.-    case random rng of-      (x,rng') ->-          -- We use 24 bits of randomness corresponding to the 24 bit significand:-          ((fromIntegral (mask24 .&. (x::Int32)) :: Float)-           /  fromIntegral twoto24, rng')-         -- Note, encodeFloat is another option, but I'm not seeing slightly-         --  worse performance with the following [2011.06.25]:---         (encodeFloat rand (-24), rng')-   where-     mask24 = twoto24 - 1-     twoto24 = (2::Int32) ^ (24::Int32)---- CFloat/CDouble are basically the same as a Float/Double:-instance Random CFloat where-  randomR = randomRFloating-  random rng = case random rng of-                 (x,rng') -> (realToFrac (x::Float), rng')--instance Random CDouble where-  randomR = randomRFloating-  -- A MYSTERY:-  -- Presently, this is showing better performance than the Double instance:-  -- (And yet, if the Double instance uses randomFrac then its performance is much worse!)-  random  = randomFrac-  -- random rng = case random rng of-  --             (x,rng') -> (realToFrac (x::Double), rng')--mkStdRNG :: Integer -> IO StdGen-mkStdRNG o = do-    ct          <- getCPUTime-    (sec, psec) <- getTime-    return (createStdGen (sec * 12345 + psec + ct + o))--randomBounded :: (RandomGen g, Random a, Bounded a) => g -> (a, g)-randomBounded = randomR (minBound, maxBound)---- The two integer functions below take an [inclusive,inclusive] range.-randomIvalIntegral :: (RandomGen g, Integral a) => (a, a) -> g -> (a, g)-randomIvalIntegral (l,h) = randomIvalInteger (toInteger l, toInteger h)--{-# SPECIALIZE randomIvalInteger :: (Num a) =>-    (Integer, Integer) -> StdGen -> (a, StdGen) #-}--randomIvalInteger :: (RandomGen g, Num a) => (Integer, Integer) -> g -> (a, g)-randomIvalInteger (l,h) rng- | l > h     = randomIvalInteger (h,l) rng- | otherwise = case (f 1 0 rng) of (v, rng') -> (fromInteger (l + v `mod` k), rng')-     where-       (genlo, genhi) = genRange rng-       b = fromIntegral genhi - fromIntegral genlo + 1--       -- Probabilities of the most likely and least likely result-       -- will differ at most by a factor of (1 +- 1/q).  Assuming the RandomGen-       -- is uniform, of course--       -- On average, log q / log b more random values will be generated-       -- than the minimum-       q = 1000-       k = h - l + 1-       magtgt = k * q--       -- generate random values until we exceed the target magnitude-       f mag v g | mag >= magtgt = (v, g)-                 | otherwise = v' `seq`f (mag*b) v' g' where-                        (x,g') = next g-                        v' = (v * b + (fromIntegral x - fromIntegral genlo))----- The continuous functions on the other hand take an [inclusive,exclusive) range.-randomFrac :: (RandomGen g, Fractional a) => g -> (a, g)-randomFrac = randomIvalDouble (0::Double,1) realToFrac--randomIvalDouble :: (RandomGen g, Fractional a) => (Double, Double) -> (Double -> a) -> g -> (a, g)-randomIvalDouble (l,h) fromDouble rng-  | l > h     = randomIvalDouble (h,l) fromDouble rng-  | otherwise =-       case (randomIvalInteger (toInteger (minBound::Int32), toInteger (maxBound::Int32)) rng) of-         (x, rng') ->-            let-             scaled_x =-                fromDouble (0.5*l + 0.5*h) +                   -- previously (l+h)/2, overflowed-                fromDouble ((0.5*h - 0.5*l) / (0.5 * realToFrac int32Count)) *  -- avoid overflow-                fromIntegral (x::Int32)-            in-            (scaled_x, rng')--int32Count :: Integer-int32Count = toInteger (maxBound::Int32) - toInteger (minBound::Int32) + 1  -- GHC ticket #3982--stdRange :: (Int,Int)-stdRange = (1, 2147483562)--stdNext :: StdGen -> (Int, StdGen)--- Returns values in the range stdRange-stdNext (StdGen s1 s2) = (fromIntegral z', StdGen s1'' s2'')-        where   z'   = if z < 1 then z + 2147483562 else z-                z    = s1'' - s2''--                k    = s1 `quot` 53668-                s1'  = 40014 * (s1 - k * 53668) - k * 12211-                s1'' = if s1' < 0 then s1' + 2147483563 else s1'--                k'   = s2 `quot` 52774-                s2'  = 40692 * (s2 - k' * 52774) - k' * 3791-                s2'' = if s2' < 0 then s2' + 2147483399 else s2'--stdSplit            :: StdGen -> (StdGen, StdGen)-stdSplit std@(StdGen s1 s2)-                     = (left, right)-                       where-                        -- no statistical foundation for this!-                        left    = StdGen new_s1 t2-                        right   = StdGen t1 new_s2--                        new_s1 | s1 == 2147483562 = 1-                               | otherwise        = s1 + 1--                        new_s2 | s2 == 1          = 2147483398-                               | otherwise        = s2 - 1--                        StdGen t1 t2 = snd (next std)---- The global random number generator--{- $globalrng #globalrng#--There is a single, implicit, global random number generator of type-'StdGen', held in some global variable maintained by the 'IO' monad. It is-initialised automatically in some system-dependent fashion, for example, by-using the time of day, or Linux's kernel random number generator. To get-deterministic behaviour, use 'setStdGen'.--}---- |Sets the global random number generator.-setStdGen :: StdGen -> IO ()-setStdGen sgen = writeIORef theStdGen sgen---- |Gets the global random number generator.-getStdGen :: IO StdGen-getStdGen  = readIORef theStdGen--theStdGen :: IORef StdGen-theStdGen  = unsafePerformIO $ do-   rng <- mkStdRNG 0-   newIORef rng---- |Applies 'split' to the current global random generator,--- updates it with one of the results, and returns the other.-newStdGen :: IO StdGen-newStdGen = atomicModifyIORef' theStdGen split--{- |Uses the supplied function to get a value from the current global-random generator, and updates the global generator with the new generator-returned by the function. For example, @rollDice@ gets a random integer-between 1 and 6:-->  rollDice :: IO Int->  rollDice = getStdRandom (randomR (1,6))---}--getStdRandom :: (StdGen -> (a,StdGen)) -> IO a-getStdRandom f = atomicModifyIORef' theStdGen (swap . f)-  where swap (v,g) = (g,v)--{- $references--1. FW #Burton# Burton and RL Page, /Distributed random number generation/,-Journal of Functional Programming, 2(2):203-212, April 1992.--2. SK #Park# Park, and KW Miller, /Random number generators --good ones are hard to find/, Comm ACM 31(10), Oct 1988, pp1192-1201.--3. DG #Carta# Carta, /Two fast implementations of the minimal standard-random number generator/, Comm ACM, 33(1), Jan 1990, pp87-88.--4. P #Hellekalek# Hellekalek, /Don\'t trust parallel Monte Carlo/,-Department of Mathematics, University of Salzburg,-<http://random.mat.sbg.ac.at/~peter/pads98.ps>, 1998.--5. Pierre #LEcuyer# L'Ecuyer, /Efficient and portable combined random-number generators/, Comm ACM, 31(6), Jun 1988, pp742-749.--The Web site <http://random.mat.sbg.ac.at/> is a great source of information.---}
+ tests/examples/transform/AddArgFromWhereComments.hs view
@@ -0,0 +1,6 @@+foo -- c1+  -- | c2+  {- c3 -} True -- c4+  = new_def++foo False = False
+ tests/examples/transform/AddArgFromWhereComments.hs.expected view
@@ -0,0 +1,6 @@+foo -- c1+  -- | c2+  {- c3 -} True -- c4+  = new_def++foo False = False