packages feed

ghc-exactprint 1.2.0 → 1.3.0

raw patch · 49 files changed

+6382/−4119 lines, 49 filesdep ~ghcPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: ghc

API changes (from Hackage documentation)

- Language.Haskell.GHC.ExactPrint.ExactPrint: instance GHC.Classes.Eq a => GHC.Classes.Eq (Language.Haskell.GHC.ExactPrint.ExactPrint.AnnotatedList a)
- Language.Haskell.GHC.ExactPrint.ExactPrint: instance GHC.Show.Show a => GHC.Show.Show (Language.Haskell.GHC.ExactPrint.ExactPrint.AnnotatedList a)
- Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint Language.Haskell.GHC.ExactPrint.ExactPrint.DataDefnWithContext
- Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint a => Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (Language.Haskell.GHC.ExactPrint.ExactPrint.AnnotatedList a)
- Language.Haskell.GHC.ExactPrint.Lookup: AnnComment :: Comment -> KeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnSemiSep :: KeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnString :: String -> KeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: AnnTypeApp :: KeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: G :: AnnKeywordId -> KeywordId
- Language.Haskell.GHC.ExactPrint.Lookup: data KeywordId
- Language.Haskell.GHC.ExactPrint.Types: AnnComment :: Comment -> KeywordId
- Language.Haskell.GHC.ExactPrint.Types: AnnSemiSep :: KeywordId
- Language.Haskell.GHC.ExactPrint.Types: AnnString :: String -> KeywordId
- Language.Haskell.GHC.ExactPrint.Types: AnnTypeApp :: KeywordId
- Language.Haskell.GHC.ExactPrint.Types: G :: AnnKeywordId -> KeywordId
- Language.Haskell.GHC.ExactPrint.Types: data KeywordId
- Language.Haskell.GHC.ExactPrint.Types: instance GHC.Classes.Eq Language.Haskell.GHC.ExactPrint.Types.KeywordId
- Language.Haskell.GHC.ExactPrint.Types: instance GHC.Show.Show Language.Haskell.GHC.ExactPrint.Types.KeywordId
- Language.Haskell.GHC.ExactPrint.Utils: comment2dp :: (Comment, DeltaPos) -> (KeywordId, DeltaPos)
+ Language.Haskell.GHC.ExactPrint: class (Typeable a) => ExactPrint a
+ Language.Haskell.GHC.ExactPrint: exact :: (ExactPrint a, Monad m, Monoid w) => a -> EP w m a
+ Language.Haskell.GHC.ExactPrint: getAnnotationEntry :: ExactPrint a => a -> Entry
+ Language.Haskell.GHC.ExactPrint: makeDeltaAst :: ExactPrint ast => ast -> ast
+ Language.Haskell.GHC.ExactPrint: setAnnotationAnchor :: ExactPrint a => a -> Anchor -> EpAnnComments -> a
+ Language.Haskell.GHC.ExactPrint.ExactPrint: data EPOptions m a
+ Language.Haskell.GHC.ExactPrint.ExactPrint: deltaOptions :: EPOptions Identity ()
+ Language.Haskell.GHC.ExactPrint.ExactPrint: epOptions :: (forall ast. Data ast => Located ast -> a -> m a) -> (String -> m a) -> (String -> m a) -> Rigidity -> Bool -> EPOptions m a
+ Language.Haskell.GHC.ExactPrint.ExactPrint: exactPrintWithOptions :: (ExactPrint ast, Monoid b, Monad m) => EPOptions m b -> ast -> m (ast, b)
+ Language.Haskell.GHC.ExactPrint.ExactPrint: instance GHC.Classes.Eq Language.Haskell.GHC.ExactPrint.ExactPrint.CanUpdateAnchor
+ Language.Haskell.GHC.ExactPrint.ExactPrint: instance GHC.Show.Show Language.Haskell.GHC.ExactPrint.ExactPrint.CanUpdateAnchor
+ Language.Haskell.GHC.ExactPrint.ExactPrint: instance Language.Haskell.GHC.ExactPrint.ExactPrint.ExactPrint (GHC.Base.NonEmpty (GHC.Types.SrcLoc.Located (Language.Haskell.Syntax.Expr.HsFieldLabel 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: makeDeltaAst :: ExactPrint ast => ast -> ast
+ Language.Haskell.GHC.ExactPrint.ExactPrint: setAnnotationAnchor :: ExactPrint a => a -> Anchor -> EpAnnComments -> a
+ Language.Haskell.GHC.ExactPrint.ExactPrint: stringOptions :: EPOptions Identity String
+ Language.Haskell.GHC.ExactPrint.Lookup: AnnAnyclass :: AnnKeywordId
+ Language.Haskell.GHC.ExactPrint.Lookup: AnnAs :: AnnKeywordId
+ Language.Haskell.GHC.ExactPrint.Lookup: AnnAt :: 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: 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: [commentPriorTok] :: Comment -> !RealSrcSpan
+ Language.Haskell.GHC.ExactPrint.Lookup: data AnnKeywordId
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Hs.AnnsModule
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Hs.Binds.AnnSig
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Hs.Decls.HsRuleAnn
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Hs.Expr.AnnExplicitSum
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Hs.Expr.AnnFieldLabel
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Hs.Expr.AnnProjection
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Hs.Expr.AnnsIf
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Hs.Expr.AnnsLet
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Hs.Expr.EpAnnHsCase
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Hs.Expr.EpAnnUnboundVar
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Hs.Expr.GrhsAnn
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Hs.ImpExp.EpAnnImportDecl
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Hs.Pat.EpAnnSumPat
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Parser.Annotation.AddEpAnn
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Parser.Annotation.AnnContext
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Parser.Annotation.AnnParen
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Parser.Annotation.AnnPragma
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Parser.Annotation.EpaLocation
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Parser.Annotation.NoEpAnns
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Monoid GHC.Parser.Annotation.TrailingAnn
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Hs.AnnsModule
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Hs.Binds.AnnSig
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Hs.Decls.HsRuleAnn
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Hs.Expr.AnnExplicitSum
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Hs.Expr.AnnFieldLabel
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Hs.Expr.AnnProjection
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Hs.Expr.AnnsIf
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Hs.Expr.AnnsLet
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Hs.Expr.EpAnnHsCase
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Hs.Expr.EpAnnUnboundVar
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Hs.Expr.GrhsAnn
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Hs.ImpExp.EpAnnImportDecl
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Hs.Pat.EpAnnSumPat
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Parser.Annotation.AddEpAnn
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Parser.Annotation.AnnContext
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Parser.Annotation.AnnParen
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Parser.Annotation.AnnPragma
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Parser.Annotation.EpaLocation
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Parser.Annotation.NoEpAnns
+ Language.Haskell.GHC.ExactPrint.Orphans: instance GHC.Base.Semigroup GHC.Parser.Annotation.TrailingAnn
+ Language.Haskell.GHC.ExactPrint.Transform: getEntryDP :: LocatedAn t a -> DeltaPos
+ Language.Haskell.GHC.ExactPrint.Transform: makeDeltaAst' :: forall a. Data a => a -> a
+ Language.Haskell.GHC.ExactPrint.Types: [commentPriorTok] :: Comment -> !RealSrcSpan
+ Language.Haskell.GHC.ExactPrint.Types: instance Data.Data.Data Language.Haskell.GHC.ExactPrint.Types.Comment
+ Language.Haskell.GHC.ExactPrint.Utils: addEpAnnLoc :: AddEpAnn -> EpaLocation
+ Language.Haskell.GHC.ExactPrint.Utils: anchorToEpaLocation :: Anchor -> EpaLocation
+ Language.Haskell.GHC.ExactPrint.Utils: cmpComments :: Comment -> Comment -> Ordering
+ Language.Haskell.GHC.ExactPrint.Utils: comment2LEpaComment :: Comment -> LEpaComment
+ Language.Haskell.GHC.ExactPrint.Utils: hackAnchorToSrcSpan :: Anchor -> SrcSpan
+ Language.Haskell.GHC.ExactPrint.Utils: hackSrcSpanToAnchor :: SrcSpan -> Anchor
+ Language.Haskell.GHC.ExactPrint.Utils: isKWComment :: Comment -> Bool
+ Language.Haskell.GHC.ExactPrint.Utils: mkEpaComments :: [Comment] -> [Comment] -> EpAnnComments
+ Language.Haskell.GHC.ExactPrint.Utils: moveAnchor :: Monoid b => SrcAnn a -> SrcAnn b
+ Language.Haskell.GHC.ExactPrint.Utils: noKWComments :: [Comment] -> [Comment]
+ Language.Haskell.GHC.ExactPrint.Utils: setAnchorAn :: Monoid an => LocatedAn an a -> Anchor -> EpAnnComments -> LocatedAn an a
+ Language.Haskell.GHC.ExactPrint.Utils: setAnchorEpa :: Monoid an => EpAnn an -> Anchor -> EpAnnComments -> EpAnn an
+ Language.Haskell.GHC.ExactPrint.Utils: setAnchorEpaL :: EpAnn AnnList -> Anchor -> EpAnnComments -> EpAnn AnnList
+ Language.Haskell.GHC.ExactPrint.Utils: setAnchorHsModule :: HsModule -> Anchor -> EpAnnComments -> HsModule
+ Language.Haskell.GHC.ExactPrint.Utils: setTrailingAnnLoc :: TrailingAnn -> EpaLocation -> TrailingAnn
+ Language.Haskell.GHC.ExactPrint.Utils: sortComments :: [Comment] -> [Comment]
+ Language.Haskell.GHC.ExactPrint.Utils: sortEpaComments :: [LEpaComment] -> [LEpaComment]
+ Language.Haskell.GHC.ExactPrint.Utils: trailingAnnLoc :: TrailingAnn -> EpaLocation
+ Language.Haskell.GHC.ExactPrint.Utils: trailingAnnToAddEpAnn :: TrailingAnn -> AddEpAnn
- Language.Haskell.GHC.ExactPrint: exactPrint :: ExactPrint ast => Located ast -> String
+ Language.Haskell.GHC.ExactPrint: exactPrint :: ExactPrint ast => ast -> String
- Language.Haskell.GHC.ExactPrint.ExactPrint: exact :: ExactPrint a => a -> Annotated ()
+ Language.Haskell.GHC.ExactPrint.ExactPrint: exact :: (ExactPrint a, Monad m, Monoid w) => a -> EP w m a
- Language.Haskell.GHC.ExactPrint.ExactPrint: exactPrint :: ExactPrint ast => Located ast -> String
+ Language.Haskell.GHC.ExactPrint.ExactPrint: exactPrint :: ExactPrint ast => ast -> String
- Language.Haskell.GHC.ExactPrint.Lookup: Comment :: !String -> !Anchor -> !Maybe AnnKeywordId -> Comment
+ Language.Haskell.GHC.ExactPrint.Lookup: Comment :: !String -> !Anchor -> !RealSrcSpan -> !Maybe AnnKeywordId -> Comment
- Language.Haskell.GHC.ExactPrint.Lookup: keywordToString :: KeywordId -> String
+ Language.Haskell.GHC.ExactPrint.Lookup: keywordToString :: AnnKeywordId -> String
- Language.Haskell.GHC.ExactPrint.Parsers: ghcWrapper :: FilePath -> Ghc a -> IO a
+ Language.Haskell.GHC.ExactPrint.Parsers: ghcWrapper :: LibDir -> Ghc a -> IO a
- Language.Haskell.GHC.ExactPrint.Parsers: parseModuleEpAnnsWithCpp :: FilePath -> CppOptions -> FilePath -> IO (Either ErrorMessages ([LEpaComment], DynFlags, ParsedSource))
+ Language.Haskell.GHC.ExactPrint.Parsers: parseModuleEpAnnsWithCpp :: LibDir -> CppOptions -> FilePath -> IO (Either ErrorMessages ([LEpaComment], DynFlags, ParsedSource))
- Language.Haskell.GHC.ExactPrint.Parsers: parseModuleFromString :: FilePath -> FilePath -> String -> IO (ParseResult ParsedSource)
+ Language.Haskell.GHC.ExactPrint.Parsers: parseModuleFromString :: LibDir -> FilePath -> String -> IO (ParseResult ParsedSource)
- Language.Haskell.GHC.ExactPrint.Parsers: parseModuleWithCpp :: FilePath -> CppOptions -> FilePath -> IO (ParseResult ParsedSource)
+ Language.Haskell.GHC.ExactPrint.Parsers: parseModuleWithCpp :: LibDir -> CppOptions -> FilePath -> IO (ParseResult ParsedSource)
- Language.Haskell.GHC.ExactPrint.Parsers: parseModuleWithOptions :: FilePath -> FilePath -> IO (ParseResult ParsedSource)
+ Language.Haskell.GHC.ExactPrint.Parsers: parseModuleWithOptions :: LibDir -> FilePath -> IO (ParseResult ParsedSource)
- Language.Haskell.GHC.ExactPrint.Parsers: withDynFlags :: FilePath -> (DynFlags -> a) -> IO a
+ Language.Haskell.GHC.ExactPrint.Parsers: withDynFlags :: LibDir -> (DynFlags -> a) -> IO a
- Language.Haskell.GHC.ExactPrint.Transform: captureLineSpacing :: Monoid t => [LocatedAn t e] -> [GenLocated (SrcSpanAnn' (EpAnn t)) e]
+ Language.Haskell.GHC.ExactPrint.Transform: captureLineSpacing :: Monoid t => [LocatedAn t e] -> [LocatedAn t e]
- Language.Haskell.GHC.ExactPrint.Transform: transferEntryDP :: (Monad m, Monoid t) => LocatedAn t a -> LocatedAn t b -> TransformT m (LocatedAn t b)
+ Language.Haskell.GHC.ExactPrint.Transform: transferEntryDP :: (Monad m, Monoid t2, Typeable t1, Typeable t2) => LocatedAn t1 a -> LocatedAn t2 b -> TransformT m (LocatedAn t2 b)
- Language.Haskell.GHC.ExactPrint.Types: Comment :: !String -> !Anchor -> !Maybe AnnKeywordId -> Comment
+ Language.Haskell.GHC.ExactPrint.Types: Comment :: !String -> !Anchor -> !RealSrcSpan -> !Maybe AnnKeywordId -> Comment
- Language.Haskell.GHC.ExactPrint.Utils: adjustDeltaForOffset :: Int -> LayoutStartCol -> DeltaPos -> DeltaPos
+ Language.Haskell.GHC.ExactPrint.Utils: adjustDeltaForOffset :: LayoutStartCol -> DeltaPos -> DeltaPos
- Language.Haskell.GHC.ExactPrint.Utils: mkComment :: String -> Anchor -> Comment
+ Language.Haskell.GHC.ExactPrint.Utils: mkComment :: String -> Anchor -> RealSrcSpan -> Comment
- Language.Haskell.GHC.ExactPrint.Utils: mkLEpaComment :: String -> Anchor -> LEpaComment
+ Language.Haskell.GHC.ExactPrint.Utils: mkLEpaComment :: String -> Anchor -> RealSrcSpan -> LEpaComment

Files

ChangeLog view
@@ -1,3 +1,6 @@+2021-11-23 v1.3+	* Update for GHC 9.2.1 as released+	* Introduce makeDeltaAst command to convert all EpaSpan's to equivalent EpaDelta versions 2021-08-23 v1.2 	* Remove types and functions from previous version, now obsolete 2021-08-23 v1.1
ghc-exactprint.cabal view
@@ -1,5 +1,5 @@ name:                ghc-exactprint-version:             1.2.0+version:             1.3.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@@ -15,8 +15,7 @@ maintainer:          alan.zimm@gmail.com category:            Development build-type:          Simple--- tested-with:         GHC == 9.2.1-tested-with:         GHC == 9.2.0.20210821+tested-with:         GHC == 9.2.1 extra-source-files:  ChangeLog                      tests/examples/failing/*.hs                      tests/examples/ghc710-only/*.hs@@ -58,6 +57,7 @@   exposed-modules:     Language.Haskell.GHC.ExactPrint                      , Language.Haskell.GHC.ExactPrint.ExactPrint                      , Language.Haskell.GHC.ExactPrint.Lookup+                     , Language.Haskell.GHC.ExactPrint.Orphans                      , Language.Haskell.GHC.ExactPrint.Parsers                      , Language.Haskell.GHC.ExactPrint.Preprocess                      , Language.Haskell.GHC.ExactPrint.Transform
src/Language/Haskell/GHC/ExactPrint.hs view
@@ -11,8 +11,11 @@         , module Language.Haskell.GHC.ExactPrint.Transform          -- * Printing+        , ExactPrint(..)         , exactPrint +        -- * Relativising+        , makeDeltaAst         ) where  import Language.Haskell.GHC.ExactPrint.ExactPrint
src/Language/Haskell/GHC/ExactPrint/ExactPrint.hs view
@@ -15,3438 +15,5137 @@   (     ExactPrint(..)   , exactPrint-  -- , exactPrintWithOptions-  ) where--import GHC-import GHC.Core.Coercion.Axiom (Role(..))-import GHC.Data.Bag-import qualified GHC.Data.BooleanFormula as BF-import GHC.Data.FastString-import GHC.Types.Basic hiding (EP)-import GHC.Types.Fixity-import GHC.Types.ForeignCall-import GHC.Types.SourceText-import GHC.Types.Var-import GHC.Utils.Outputable hiding ( (<>) )-import GHC.Unit.Module.Warnings-import GHC.Utils.Misc-import GHC.Utils.Panic--import Control.Monad.Identity-import Control.Monad.RWS-import Data.Data ( Data )-import Data.Foldable-import qualified Data.Set.Ordered as OSet-import Data.Typeable-import Data.List ( partition, sort, sortBy)-import Data.Maybe ( isJust )--import Data.Void--import Language.Haskell.GHC.ExactPrint.Lookup-import Language.Haskell.GHC.ExactPrint.Utils-import Language.Haskell.GHC.ExactPrint.Types---- import Debug.Trace---- -----------------------------------------------------------------------exactPrint :: ExactPrint ast => Located ast -> String-exactPrint ast = runIdentity (runEP stringOptions (markAnnotated ast))--type EP w m a = RWST (PrintOptions m w) (EPWriter w) EPState m a-type EPP a = EP String Identity a--runEP :: PrintOptions Identity String-      -> Annotated () -> Identity String-runEP epReader action =-  fmap (output . snd) .-    (\next -> execRWST next epReader defaultEPState)-    . xx $ action--xx :: Annotated () -> EP String Identity ()--- xx :: Annotated() -> RWST (PrintOptions m w) (EPWriter w) EPState m ()-xx = id---- -----------------------------------------------------------------------defaultEPState :: EPState-defaultEPState = EPState-             { epPos      = (1,1)-             , dLHS       = 0-             , pMarkLayout = False-             , pLHS = 0-             , dMarkLayout = False-             , dPriorEndPosition = (1,1)-             , uAnchorSpan = badRealSrcSpan-             , uExtraDP = Nothing-             , epComments = []-             }----- ------------------------------------------------------------------------ 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 PrintOptions m a = PrintOptions-            {-              epAstPrint :: forall ast . Data ast => GHC.Located ast -> a -> m a-            , epTokenPrint :: String -> m a-            , epWhitespacePrint :: String -> m a-            , epRigidity :: Rigidity-            }---- | Helper to create a 'PrintOptions'-printOptions ::-      (forall ast . Data ast => GHC.Located ast -> a -> m a)-      -> (String -> m a)-      -> (String -> m a)-      -> Rigidity-      -> PrintOptions m a-printOptions astPrint tokenPrint wsPrint rigidity = PrintOptions-             {-               epAstPrint = astPrint-             , epWhitespacePrint = wsPrint-             , epTokenPrint = tokenPrint-             , epRigidity = rigidity-             }---- | Options which can be used to print as a normal String.-stringOptions :: PrintOptions Identity String-stringOptions = printOptions (\_ b -> return b) return return NormalLayout--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--             -- 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]-             }---- ------------------------------------------------------------------------- AZ:TODO: this can just be a function :: (EpAnn a) -> Entry-class HasEntry ast where-  fromAnn :: ast -> Entry---- ------------------------------------------------------------------------- type Annotated = FreeT AnnotationF Identity-type Annotated a = EP String Identity a---- ------------------------------------------------------------------------- | Key entry point.  Switches to an independent AST element with its--- own annotation, calculating new offsets, etc-markAnnotated :: ExactPrint a => a -> Annotated ()-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)--data Entry = Entry Anchor EpAnnComments FlushComments-           | NoEntryVal--instance HasEntry (SrcSpanAnn' (EpAnn an)) where-  fromAnn (SrcSpanAnn EpAnnNotUsed ss) = Entry (spanAsAnchor ss) emptyComments NoFlushComments-  fromAnn (SrcSpanAnn an _) = fromAnn an--instance HasEntry (EpAnn a) where-  fromAnn (EpAnn anchor _ cs) = Entry anchor cs NoFlushComments-  fromAnn EpAnnNotUsed = NoEntryVal---- -----------------------------------------------------------------------fromAnn' :: (HasEntry a) => a -> Entry-fromAnn' an = case fromAnn an of-  NoEntryVal -> NoEntryVal-  Entry a c _ -> Entry a c FlushComments---- -----------------------------------------------------------------------astId :: (Typeable a) => a -> String-astId a = show (typeOf a)---- | "Enter" an annotation, by using the associated 'anchor' field as--- the new reference point for calculating all DeltaPos positions.------ 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 :: (ExactPrint a) => Entry -> a -> Annotated ()-enterAnn NoEntryVal a = do-  p <- getPosP-  debugM $ "enterAnn:NO ANN:(p,a) =" ++ show (p, astId a) ++ " starting"-  exact a-  debugM $ "enterAnn:NO ANN:p =" ++ show (p, astId a) ++ " done"-enterAnn (Entry anchor' cs flush) a = do-  p <- getPosP-  debugM $ "enterAnn:(p,a) =" ++ show (p, astId a) ++ " starting"-  -- debugM $ "enterAnn:(cs) =" ++ showGhc (cs)-  let curAnchor = anchor anchor' -- As a base for the current AST element-  debugM $ "enterAnn:(curAnchor):=" ++ show (rs2range curAnchor)-  addCommentsA (priorComments cs)-  printComments curAnchor-  -- --------------------------  case anchor_op anchor' of-    MovedAnchor dp -> do-      debugM $ "enterAnn: MovedAnchor:" ++ show dp-      -- Set the original anchor as prior end, so the rest of this AST-      -- fragment has a reference-      -- BUT: this means the entry DP can be calculated incorrectly too,-      -- for immediately nested items.-      setPriorEndNoLayoutD (ss2pos curAnchor)-    _ -> do-      return ()-  -- --------------------------  setAnchorU curAnchor-  -- --------------------------------------------------------------------  -- 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 <- gets dLHS-  let spanStart = ss2pos curAnchor-  priorEndAfterComments <- getPriorEndD-  let edp' = adjustDeltaForOffset 0-               -- 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_op anchor' of-        MovedAnchor dp -> dp-        _ -> edp'-  -- ----------------------------------------------  -- let edp = edp''-  med <- getExtraDP-  setExtraDP Nothing-  let edp = case med of-        Nothing -> edp''-        Just (Anchor _ (MovedAnchor dp)) -> dp-                   -- Replace original with desired one. Allows all-                   -- list entry values to be DP (1,0)-        Just (Anchor r _) -> dp-          where-            dp = adjustDeltaForOffset 0-                   off (ss2delta priorEndAfterComments r)-  when (isJust med) $ debugM $ "enterAnn:(med,edp)=" ++ show (med,edp)-  -- ----------------------------------------------  -- Preparation complete, perform the action-  when (priorEndAfterComments < spanStart) (do-    debugM $ "enterAnn.dPriorEndPosition:spanStart=" ++ show spanStart-    modify (\s -> s { dPriorEndPosition    = spanStart } ))--  debugM $ "enterAnn: (anchor_op, curAnchor):" ++ show (anchor_op anchor', rs2range curAnchor)-  debugM $ "enterAnn: (dLHS,spanStart,pec,edp)=" ++ show (off,spanStart,priorEndAfterComments,edp)--  -- end of delta phase processing-  -- --------------------------------------------------------------------  -- start of print phase processing--  let mflush = when (flush == FlushComments) $ do-        debugM $ "flushing comments in enterAnn"-        flushComments (getFollowingComments cs)-        -- flushComments []--  -- let-  --   st = annNone-  -- withOffset st (advance edp >> exact a >> mflush)-  (advance edp >> exact a >> mflush)--  when (flush == NoFlushComments) $ do-    when ((getFollowingComments cs) /= []) $ do-      debugM $ "starting trailing comments:" ++ showAst (getFollowingComments cs)-      mapM_ printOneComment (map tokComment $ getFollowingComments cs)-      debugM $ "ending trailing comments"---- -----------------------------------------------------------------------addCommentsA :: [LEpaComment] -> EPP ()-addCommentsA csNew = addComments (map tokComment csNew)--addComments :: [Comment] -> EPP ()-addComments csNew = do-  debugM $ "addComments:" ++ show csNew-  cs <- getUnallocatedComments-  -- Make sure we merge duplicates while sorting, needed until-  -- https://gitlab.haskell.org/ghc/ghc/-/issues/20239 is resolved-  let ocs = OSet.fromList cs-  let ncs = OSet.fromList csNew-  putUnallocatedComments (OSet.toAscList (ocs OSet.<>| ncs))----- ------------------------------------------------------------------------- | Just before we print out the EOF comments, flush the remaining--- ones in the state.-flushComments :: [LEpaComment] -> EPP ()-flushComments trailing = do-  addCommentsA trailing-  cs <- getUnallocatedComments-  -- Must compare without span filenames, for CPP injected comments with fake filename-  let cmp (Comment _ l1 _) (Comment _ l2 _) = compare (ss2pos $ anchor l1) (ss2pos $ anchor l2)-  debugM $ "flushing comments starting"-  mapM_ printOneComment (sortBy cmp cs)-  debugM $ "flushing comments done"---- ------------------------------------------------------------------------- |In order to interleave annotations into the stream, we turn them into--- comments.-annotationsToComments :: [AddEpAnn] -> [AnnKeywordId] -> EPP ()-annotationsToComments ans kws = do-  let-    getSpans _ [] = []-    getSpans k1 (AddEpAnn k2 ss:as)-      | k1 == k2 = ss : getSpans k1 as-      | otherwise = getSpans k1 as-    doOne :: AnnKeywordId -> EPP [Comment]-    doOne kw = do-      let sps =getSpans kw ans-      return $ map (mkKWComment kw ) sps-    -- TODO:AZ make sure these are sorted/merged properly when the invariant for-    -- allocateComments is re-established.-  newComments <- mapM doOne kws-  addComments (concat newComments)--annotationsToCommentsA :: EpAnn [AddEpAnn] -> [AnnKeywordId] -> EPP ()-annotationsToCommentsA EpAnnNotUsed _ = return ()-annotationsToCommentsA an kws = annotationsToComments (anns an) kws---- ------------------------------------------------------------------------- Temporary function to simply reproduce the "normal" pretty printer output-withPpr :: (Outputable a) => a -> Annotated ()-withPpr a = do-  ss <- getAnchorU-  debugM $ "withPpr: ss=" ++ show ss-  printStringAtKw' ss (showPprUnsafe a)---- ------------------------------------------------------------------------ Modeled on Outputable---- | 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-  exact :: a -> Annotated ()---- ------------------------------------------------------------------------- | Bare Located elements are simply stripped off without further--- processing.-instance (ExactPrint a) => ExactPrint (Located a) where-  getAnnotationEntry (L l _) = Entry (spanAsAnchor l) emptyComments NoFlushComments-  exact (L _ a) = markAnnotated a--instance (ExactPrint a) => ExactPrint (LocatedA a) where-  getAnnotationEntry = entryFromLocatedA-  exact (L la a) = do-    debugM $ "LocatedA a:la loc=" ++ show (ss2range $ locA la)-    markAnnotated a-    markALocatedA (ann la)--instance (ExactPrint a) => ExactPrint [a] where-  getAnnotationEntry = const NoEntryVal-  exact ls = mapM_ markAnnotated ls--instance (ExactPrint a) => ExactPrint (Maybe a) where-  getAnnotationEntry = const NoEntryVal-  exact Nothing = return ()-  exact (Just a) = markAnnotated a---- ------------------------------------------------------------------------- | 'Located (HsModule GhcPs)' corresponds to 'ParsedSource'-instance ExactPrint HsModule where-  getAnnotationEntry hsmod = fromAnn' (hsmodAnn hsmod)--  exact hsmod@(HsModule EpAnnNotUsed _ _ _ _ _ _ _) = withPpr hsmod-  exact (HsModule an _lo mmn mexports imports decls mdeprec mbDoc) = do--    markAnnotated mbDoc--    case mmn of-      Nothing -> return ()-      Just (L ln mn) -> do-        markEpAnn' an am_main AnnModule-        markAnnotated (L ln mn)--        -- forM_ mdeprec markLocated-        setLayoutTopLevelP $ markAnnotated mdeprec--        setLayoutTopLevelP $ markAnnotated mexports--        debugM $ "HsModule.AnnWhere coming"-        setLayoutTopLevelP $ markEpAnn' an am_main AnnWhere--    markAnnList' False (am_decls $ anns an) $ do-      markTopLevelList imports-      markTopLevelList decls---- ------------------------------------------------------------------------- TODO:AZ: do we *need* the following, or can we capture it in the AST?--- | We can have a list with its own entry point defined. Create a--- data structure to capture this, for defining an ExactPrint instance-data AnnotatedList a = AnnotatedList (Maybe Anchor) a-                     deriving (Eq,Show)--instance (ExactPrint a) => ExactPrint (AnnotatedList a) where-  getAnnotationEntry (AnnotatedList (Just anc) _) = Entry anc (EpaComments []) NoFlushComments-  getAnnotationEntry (AnnotatedList Nothing    _) = NoEntryVal--  exact (AnnotatedList an ls) = do-    debugM $ "AnnotatedList:an=" ++ show an-    markAnnotatedWithLayout ls----- ------------------------------------------------------------------------ Start of utility functions--- -----------------------------------------------------------------------printSourceText :: SourceText -> String -> EPP ()-printSourceText NoSourceText txt   =  printStringAdvance txt-printSourceText (SourceText txt) _ =  printStringAdvance txt---- -----------------------------------------------------------------------printStringAtRs :: RealSrcSpan -> String -> EPP ()-printStringAtRs ss str = printStringAtKw' ss str--printStringAtSs :: SrcSpan -> String -> EPP ()-printStringAtSs ss str = printStringAtKw' (realSrcSpan ss) str---- ------------------------------------------------------------------------- AZ:TODO get rid of this-printStringAtMkw :: Maybe EpaLocation -> String -> EPP ()-printStringAtMkw (Just aa) s = printStringAtAA aa s-printStringAtMkw Nothing s = printStringAtLsDelta (SameLine 1) s---printStringAtAA :: EpaLocation -> String -> EPP ()-printStringAtAA (EpaSpan r) s = printStringAtKw' r s-printStringAtAA (EpaDelta d) s = do-  pe <- getPriorEndD-  p1 <- getPosP-  printStringAtLsDelta d s-  p2 <- getPosP-  debugM $ "printStringAtAA:(pe,p1,p2)=" ++ show (pe,p1,p2)-  setPriorEndASTPD True (p1,p2)---- Based on Delta.addAnnotationWorker-printStringAtKw' :: RealSrcSpan -> String -> EPP ()-printStringAtKw' pa str = do-  printComments pa-  pe <- getPriorEndD-  debugM $ "printStringAtKw':pe=" ++ show pe-  let p = ss2delta pe pa-  p' <- adjustDeltaForOffsetM p-  printStringAtLsDelta p' str-  setPriorEndASTD True pa---- -----------------------------------------------------------------------markExternalSourceText :: SrcSpan -> SourceText -> String -> EPP ()-markExternalSourceText l NoSourceText txt   = printStringAtKw' (realSrcSpan l) txt-markExternalSourceText l (SourceText txt) _ = printStringAtKw' (realSrcSpan l) txt---- -----------------------------------------------------------------------markAddEpAnn :: AddEpAnn -> EPP ()-markAddEpAnn a@(AddEpAnn kw _) = mark [a] kw--markLocatedMAA :: EpAnn a -> (a -> Maybe AddEpAnn) -> EPP ()-markLocatedMAA EpAnnNotUsed  _  = return ()-markLocatedMAA (EpAnn _ a _) f =-  case f a of-    Nothing -> return ()-    Just aa -> markAddEpAnn aa--markLocatedAA :: EpAnn a -> (a -> AddEpAnn) -> EPP ()-markLocatedAA EpAnnNotUsed  _  = return ()-markLocatedAA (EpAnn _ a _) f = markKw (f a)--markLocatedAAL :: EpAnn a -> (a -> [AddEpAnn]) -> AnnKeywordId -> EPP ()-markLocatedAAL EpAnnNotUsed  _ _ = return ()-markLocatedAAL (EpAnn _ a _) f kw = go (f a)-  where-    go [] = return ()-    go (aa@(AddEpAnn kw' _):as)-      | kw' == kw = mark [aa] kw-      | otherwise = go as--markLocatedAALS :: EpAnn a -> (a -> [AddEpAnn]) -> AnnKeywordId -> Maybe String -> EPP ()-markLocatedAALS an f kw Nothing = markLocatedAAL an f kw-markLocatedAALS EpAnnNotUsed  _ _ _ = return ()-markLocatedAALS (EpAnn _ a _) f kw (Just str) = go (f a)-  where-    go [] = return ()-    go (AddEpAnn kw' r:as)-      | kw' == kw = printStringAtAA r str-      | otherwise = go as---- -----------------------------------------------------------------------markArrow :: EpAnn TrailingAnn -> HsArrow GhcPs -> EPP ()-markArrow an arr = do-  case arr of-    HsUnrestrictedArrow _u ->-      return ()-    HsLinearArrow _u ma -> do-      mapM_ markAddEpAnn ma-    HsExplicitMult _u ma t  -> do-      mapM_ markAddEpAnn ma-      markAnnotated t--  case an of-    EpAnnNotUsed -> pure ()-    _ -> markKwT (anns an)---- -----------------------------------------------------------------------markAnnCloseP :: EpAnn AnnPragma -> EPP ()-markAnnCloseP an = markLocatedAALS an (pure . apr_close) AnnClose (Just "#-}")--markAnnOpenP :: EpAnn AnnPragma -> SourceText -> String -> EPP ()-markAnnOpenP an NoSourceText txt   = markLocatedAALS an (pure . apr_open) AnnOpen (Just txt)-markAnnOpenP an (SourceText txt) _ = markLocatedAALS an (pure . apr_open) AnnOpen (Just txt)--markAnnOpen :: EpAnn [AddEpAnn] -> SourceText -> String -> EPP ()-markAnnOpen an NoSourceText txt   = markLocatedAALS an id AnnOpen (Just txt)-markAnnOpen an (SourceText txt) _ = markLocatedAALS an id AnnOpen (Just txt)--markAnnOpen' :: Maybe EpaLocation -> SourceText -> String -> EPP ()-markAnnOpen' ms NoSourceText txt   = printStringAtMkw ms txt-markAnnOpen' ms (SourceText txt) _ = printStringAtMkw ms txt---- -----------------------------------------------------------------------markOpeningParen, markClosingParen :: EpAnn AnnParen -> EPP ()-markOpeningParen an = markParen an fst-markClosingParen an = markParen an snd--markParen :: EpAnn AnnParen -> (forall a. (a,a) -> a) -> EPP ()-markParen EpAnnNotUsed _ = return ()-markParen (EpAnn _ (AnnParen pt o c) _) f = markKwA (f $ kw pt) (f (o, c))-  where-    kw AnnParens       = (AnnOpenP,  AnnCloseP)-    kw AnnParensHash   = (AnnOpenPH, AnnClosePH)-    kw AnnParensSquare = (AnnOpenS, AnnCloseS)---markAnnKw :: EpAnn a -> (a -> EpaLocation) -> AnnKeywordId -> EPP ()-markAnnKw EpAnnNotUsed  _ _  = return ()-markAnnKw (EpAnn _ a _) f kw = markKwA kw (f a)--markAnnKwAll :: EpAnn a -> (a -> [EpaLocation]) -> AnnKeywordId -> EPP ()-markAnnKwAll EpAnnNotUsed  _ _  = return ()-markAnnKwAll (EpAnn _ a _) f kw = mapM_ (markKwA kw) (sort (f a))--markAnnKwM :: EpAnn a -> (a -> Maybe EpaLocation) -> AnnKeywordId -> EPP ()-markAnnKwM EpAnnNotUsed  _ _ = return ()-markAnnKwM (EpAnn _ a _) f kw = go (f a)-  where-    go Nothing = return ()-    go (Just s) = markKwA kw s--markALocatedA :: EpAnn AnnListItem -> EPP ()-markALocatedA EpAnnNotUsed  = return ()-markALocatedA (EpAnn _ a _) = markTrailing (lann_trailing a)--markEpAnn :: EpAnn [AddEpAnn] -> AnnKeywordId -> EPP ()-markEpAnn EpAnnNotUsed _ = return ()-markEpAnn (EpAnn _ a _) kw = mark a kw--markEpAnn' :: EpAnn ann -> (ann -> [AddEpAnn]) -> AnnKeywordId -> EPP ()-markEpAnn' EpAnnNotUsed _ _ = return ()-markEpAnn' (EpAnn _ a _) f kw = mark (f a) kw--markEpAnnAll :: EpAnn ann -> (ann -> [AddEpAnn]) -> AnnKeywordId -> EPP ()-markEpAnnAll EpAnnNotUsed _ _ = return ()-markEpAnnAll (EpAnn _ a _) f kw = mapM_ markKw (sort anns)-  where-    anns = filter (\(AddEpAnn ka _) -> ka == kw) (f a)--markAnnAll :: [AddEpAnn] -> AnnKeywordId -> EPP ()-markAnnAll a kw = mapM_ markKw (sort anns)-  where-    anns = filter (\(AddEpAnn ka _) -> ka == kw) a--mark :: [AddEpAnn] -> AnnKeywordId -> EPP ()-mark anns kw = do-  case find (\(AddEpAnn k _) -> k == kw) anns of-    Just aa -> markKw aa-    Nothing -> case find (\(AddEpAnn k _) -> k == (unicodeAnn kw)) anns of-      Just aau -> markKw aau-      Nothing -> return ()--markKwT :: TrailingAnn -> EPP ()-markKwT (AddSemiAnn ss)    = markKwA AnnSemi ss-markKwT (AddCommaAnn ss)   = markKwA AnnComma ss-markKwT (AddVbarAnn ss)    = markKwA AnnVbar ss-markKwT (AddRarrowAnn ss)  = markKwA AnnRarrow ss-markKwT (AddRarrowAnnU ss) = markKwA AnnRarrowU ss-markKwT (AddLollyAnnU ss)  = markKwA AnnLollyU ss--markKw :: AddEpAnn -> EPP ()-markKw (AddEpAnn kw ss) = markKwA kw ss---- | This should be the main driver of the process, managing comments-markKwA :: AnnKeywordId -> EpaLocation -> EPP ()-markKwA kw aa = printStringAtAA aa (keywordToString (G kw))---- -----------------------------------------------------------------------markAnnList :: Bool -> EpAnn AnnList -> EPP () -> EPP ()-markAnnList _ EpAnnNotUsed action = action-markAnnList reallyTrail (EpAnn _ ann _) action = markAnnList' reallyTrail ann action--markAnnList' :: Bool -> AnnList -> EPP () -> EPP ()-markAnnList' reallyTrail ann action = do-  p <- getPosP-  debugM $ "markAnnList : " ++ showPprUnsafe (p, ann)-  mapM_ markAddEpAnn (al_open ann)-  unless reallyTrail $ markTrailing (al_trailing ann) -- Only makes sense for HsModule.-  markAnnAll (sort $ al_rest ann) AnnSemi-  action-  mapM_ markAddEpAnn (al_close ann)-  debugM $ "markAnnList: calling markTrailing with:" ++ showPprUnsafe (al_trailing ann)-  when reallyTrail $ markTrailing (al_trailing ann) -- normal case---- -----------------------------------------------------------------------printComments :: RealSrcSpan -> EPP ()-printComments ss = do-  cs <- commentAllocation ss-  debugM $ "printComments: (ss): " ++ showPprUnsafe (rs2range ss)-  -- debugM $ "printComments: (ss,comment locations): " ++ showPprUnsafe (rs2range ss,map commentAnchor cs)-  mapM_ printOneComment cs---- -----------------------------------------------------------------------printOneComment :: Comment -> EPP ()-printOneComment c@(Comment _str loc _mo) = do-  debugM $ "printOneComment:c=" ++ showGhc c-  dp <-case anchor_op loc of-    MovedAnchor dp -> return dp-    _ -> do-        pe <- getPriorEndD-        let dp = ss2delta pe (anchor loc)-        debugM $ "printOneComment:(dp,pe,anchor loc)=" ++ showGhc (dp,pe,ss2pos $ anchor loc)-        return dp-  dp'' <- adjustDeltaForOffsetM dp-  mep <- getExtraDP-  dp' <- case mep of-    Just (Anchor _ (MovedAnchor edp)) -> do-      debugM $ "printOneComment:edp=" ++ show edp-      return edp-    _ -> return dp''-  LayoutStartCol dOff <- gets dLHS-  debugM $ "printOneComment:(dp,dp',dp'',dOff)=" ++ showGhc (dp,dp',dp'',dOff)-  setPriorEndD (ss2posEnd (anchor loc))-  printQueuedComment (anchor loc) c dp'---- -----------------------------------------------------------------------commentAllocation :: RealSrcSpan -> EPP [Comment]-commentAllocation 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 _mo) -> (ss2pos $ anchor loc) <= (ss2pos ss)) cs-  putUnallocatedComments later-  -- debugM $ "commentAllocation:(ss,earlier,later)" ++ show (rs2range ss,earlier,later)-  return earlier---- ------------------------------------------------------------------------markAnnotatedWithLayout :: ExactPrint ast => ast -> EPP ()-markAnnotatedWithLayout a = setLayoutBoth $ markAnnotated a---- -----------------------------------------------------------------------markTopLevelList :: ExactPrint ast => [ast] -> EPP ()-markTopLevelList ls = mapM_ (\a -> setLayoutTopLevelP $ markAnnotated a) ls---- -----------------------------------------------------------------------instance ExactPrint ModuleName where-  getAnnotationEntry _ = NoEntryVal-  exact n = do-    debugM $ "ModuleName: " ++ showPprUnsafe n-    withPpr n---- -----------------------------------------------------------------------instance ExactPrint (LocatedP WarningTxt) where-  getAnnotationEntry = entryFromLocatedA-  exact (L (SrcSpanAnn an _) (WarningTxt (L _ src) ws)) = do-    markAnnOpenP an src "{-# WARNING"-    markLocatedAAL an apr_rest AnnOpenS-    markAnnotated ws-    markLocatedAAL an apr_rest AnnCloseS-    markAnnCloseP an--  exact (L (SrcSpanAnn an _) (DeprecatedTxt (L _ src) ws)) = do-    markAnnOpenP an src "{-# DEPRECATED"-    markLocatedAAL an apr_rest AnnOpenS-    markAnnotated ws-    markLocatedAAL an apr_rest AnnCloseS-    markAnnCloseP an---- -----------------------------------------------------------------------instance ExactPrint (ImportDecl GhcPs) where-  getAnnotationEntry idecl = fromAnn (ideclExt idecl)-  exact x@(ImportDecl EpAnnNotUsed _ _ _ _ _ _ _ _ _) = withPpr x-  exact (ImportDecl ann@(EpAnn _ an _) msrc (L lm modname) mpkg _src safeflag qualFlag _impl mAs hiding) = do--    markAnnKw ann importDeclAnnImport AnnImport--    -- "{-# SOURCE" and "#-}"-    case msrc of-      SourceText _txt -> do-        debugM $ "ImportDecl sourcetext"-        let mo = fmap fst $ importDeclAnnPragma an-        let mc = fmap snd $ importDeclAnnPragma an-        markAnnOpen' mo msrc "{-# SOURCE"-        printStringAtMkw mc "#-}"-      NoSourceText -> return ()-    when safeflag (markAnnKwM ann importDeclAnnSafe AnnSafe)-    case qualFlag of-      QualifiedPre  -- 'qualified' appears in prepositive position.-        -> printStringAtMkw (importDeclAnnQualified an) "qualified"-      _ -> return ()-    case mpkg of-     Just (StringLiteral src v _) ->-       printStringAtMkw (importDeclAnnPackage an) (sourceTextToString src (show v))-     _ -> return ()--    printStringAtKw' (realSrcSpan lm) (moduleNameString modname)--    case qualFlag of-      QualifiedPost  -- 'qualified' appears in postpositive position.-        -> printStringAtMkw (importDeclAnnQualified an) "qualified"-      _ -> return ()--    case mAs of-      Nothing -> return ()-      Just (L l mn) -> do-        printStringAtMkw (importDeclAnnAs an) "as"-        printStringAtKw' (realSrcSpan l) (moduleNameString mn)--    case hiding of-      Nothing -> return ()-      Just (_isHiding,lie) -> markAnnotated lie- --   markTrailingSemi----- -----------------------------------------------------------------------instance ExactPrint HsDocString where-  getAnnotationEntry _ = NoEntryVal-  exact = withPpr -- TODO:AZ use annotations---- -----------------------------------------------------------------------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--  exact (TyClD       _ d) = markAnnotated d-  exact (InstD       _ d) = markAnnotated d-  exact (DerivD      _ d) = markAnnotated d-  exact (ValD        _ d) = markAnnotated d-  exact (SigD        _ d) = markAnnotated d-  exact (KindSigD    _ d) = markAnnotated d-  exact (DefD        _ d) = markAnnotated d-  exact (ForD        _ d) = markAnnotated d-  exact (WarningD    _ d) = markAnnotated d-  exact (AnnD        _ d) = markAnnotated d-  exact (RuleD       _ d) = markAnnotated d-  exact (SpliceD     _ d) = markAnnotated d-  exact (DocD        _ d) = markAnnotated d-  exact (RoleAnnotD  _ d) = markAnnotated d---- -----------------------------------------------------------------------instance ExactPrint (InstDecl GhcPs) where-  getAnnotationEntry (ClsInstD     _  _) = NoEntryVal-  getAnnotationEntry (DataFamInstD an _) = fromAnn an-  getAnnotationEntry (TyFamInstD   _  _) = NoEntryVal---  exact (ClsInstD     _  cid) = markAnnotated cid-  exact (DataFamInstD an decl) = do-    exactDataFamInstDecl an TopLevel decl-  exact (TyFamInstD _ eqn) = do-    markAnnotated eqn---- -----------------------------------------------------------------------exactDataFamInstDecl :: EpAnn [AddEpAnn] -> TopLevelFlag -> (DataFamInstDecl GhcPs) -> EPP ()-exactDataFamInstDecl an top_lvl-  (DataFamInstDecl ( FamEqn { feqn_ext    = an2-                            , feqn_tycon  = tycon-                            , feqn_bndrs  = bndrs-                            , feqn_pats   = pats-                            , feqn_fixity = fixity-                            , feqn_rhs    = defn }))-  = markAnnotated (DataDefnWithContext an2 pp_hdr defn) -- See Note [an and an2 in exactDataFamInstDecl]-  where-    pp_hdr mctxt = do-      case top_lvl of-        TopLevel -> markEpAnn an AnnInstance -- TODO: maybe in toplevel-        NotTopLevel -> return ()-      exactHsFamInstLHS an 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 (DerivDecl {deriv_ext = an} ) = fromAnn an-  exact (DerivDecl an typ ms mov) = do-    markEpAnn an AnnDeriving-    mapM_ markAnnotated ms-    markEpAnn an AnnInstance-    mapM_ markAnnotated mov-    markAnnotated typ---- -----------------------------------------------------------------------instance ExactPrint (ForeignDecl GhcPs) where-  getAnnotationEntry (ForeignImport an _ _  _) = fromAnn an-  getAnnotationEntry (ForeignExport an _ _  _) = fromAnn an--  exact (ForeignImport an n ty fimport) = do-    markEpAnn an AnnForeign-    markEpAnn an AnnImport--    markAnnotated fimport--    markAnnotated n-    markEpAnn an AnnDcolon-    markAnnotated ty--  exact (ForeignExport an n ty fexport) = do-    markEpAnn an AnnForeign-    markEpAnn an AnnExport-    markAnnotated fexport-    markAnnotated n-    markEpAnn an AnnDcolon-    markAnnotated ty---- -----------------------------------------------------------------------instance ExactPrint ForeignImport where-  getAnnotationEntry = const NoEntryVal-  exact (CImport cconv safety@(L ll _) _mh _imp (L ls src)) = do-    markAnnotated cconv-    unless (ll == noSrcSpan) $ markAnnotated safety-    unless (ls == noSrcSpan) $ markExternalSourceText ls src ""---- -----------------------------------------------------------------------instance ExactPrint ForeignExport where-  getAnnotationEntry = const NoEntryVal-  exact (CExport spec (L ls src)) = do-    debugM $ "CExport starting"-    markAnnotated spec-    unless (ls == noSrcSpan) $ markExternalSourceText ls src ""---- -----------------------------------------------------------------------instance ExactPrint CExportSpec where-  getAnnotationEntry = const NoEntryVal-  exact (CExportStatic _st _lbl cconv) = do-    debugM $ "CExportStatic starting"-    markAnnotated cconv---- -----------------------------------------------------------------------instance ExactPrint Safety where-  getAnnotationEntry = const NoEntryVal-  exact = withPpr---- -----------------------------------------------------------------------instance ExactPrint CCallConv where-  getAnnotationEntry = const NoEntryVal-  exact = withPpr---- -----------------------------------------------------------------------instance ExactPrint (WarnDecls GhcPs) where-  getAnnotationEntry (Warnings an _ _) = fromAnn an-  exact (Warnings an src warns) = do-    markAnnOpen an src "{-# WARNING" -- Note: might be {-# DEPRECATED-    markAnnotated warns-    markLocatedAALS an id AnnClose (Just "#-}")---- -----------------------------------------------------------------------instance ExactPrint (WarnDecl GhcPs) where-  getAnnotationEntry (Warning an _ _) = fromAnn an--  exact (Warning an lns txt) = do-    markAnnotated lns-    markEpAnn an AnnOpenS -- "["-    case txt of-      WarningTxt    _src ls -> markAnnotated ls-      DeprecatedTxt _src ls -> markAnnotated ls-    markEpAnn an AnnCloseS -- "]"---- -----------------------------------------------------------------------instance ExactPrint StringLiteral where-  getAnnotationEntry = const NoEntryVal--  exact (StringLiteral src fs mcomma) = do-    printSourceText src (show (unpackFS fs))-    mapM_ (\r -> printStringAtKw' r ",") mcomma---- -----------------------------------------------------------------------instance ExactPrint FastString where-  getAnnotationEntry = const NoEntryVal--  -- TODO: https://ghc.haskell.org/trac/ghc/ticket/10313 applies.-  -- exact fs = printStringAdvance (show (unpackFS fs))-  exact fs = printStringAdvance (unpackFS fs)----- -----------------------------------------------------------------------instance ExactPrint (RuleDecls GhcPs) where-  getAnnotationEntry (HsRules an _ _) = fromAnn an-  exact (HsRules an src rules) = do-    case src of-      NoSourceText      -> markLocatedAALS an id AnnOpen  (Just "{-# RULES")-      SourceText srcTxt -> markLocatedAALS an id AnnOpen  (Just srcTxt)-    markAnnotated rules-    markLocatedAALS an id AnnClose (Just "#-}")-    -- markTrailingSemi---- -----------------------------------------------------------------------instance ExactPrint (RuleDecl GhcPs) where-  getAnnotationEntry (HsRule {rd_ext = an}) = fromAnn an-  exact (HsRule an ln act mtybndrs termbndrs lhs rhs) = do-    debugM "HsRule entered"-    markAnnotated ln-    debugM "HsRule after ln"-    markActivation an ra_rest act-    debugM "HsRule after act"-    case mtybndrs of-      Nothing -> return ()-      Just bndrs -> do-        markLocatedMAA an (\a -> fmap fst (ra_tyanns a))  -- AnnForall-        mapM_ markAnnotated bndrs-        markLocatedMAA an (\a -> fmap snd (ra_tyanns a))  -- AnnDot--    markLocatedMAA an (\a -> fmap fst (ra_tmanns a))  -- AnnForall-    mapM_ markAnnotated termbndrs-    markLocatedMAA an (\a -> fmap snd (ra_tmanns a))  -- AnnDot--    markAnnotated lhs-    markEpAnn' an ra_rest AnnEqual-    markAnnotated rhs--markActivation :: EpAnn a -> (a -> [AddEpAnn]) -> Activation -> Annotated ()-markActivation an fn act = do-  case act of-    ActiveBefore src phase -> do-      markEpAnn' an fn AnnOpenS --  '['-      markEpAnn' an fn AnnTilde -- ~-      markLocatedAALS an fn AnnVal (Just (toSourceTextWithSuffix src (show phase) ""))-      markEpAnn' an fn AnnCloseS -- ']'-    ActiveAfter src phase -> do-      markEpAnn' an fn AnnOpenS --  '['-      markLocatedAALS an fn AnnVal (Just (toSourceTextWithSuffix src (show phase) ""))-      markEpAnn' an fn AnnCloseS -- ']'-    NeverActive -> do-      markEpAnn' an fn AnnOpenS --  '['-      markEpAnn' an fn AnnTilde -- ~-      markEpAnn' an fn AnnCloseS -- ']'-    _ -> return ()---- -----------------------------------------------------------------------instance ExactPrint (SpliceDecl GhcPs) where-  getAnnotationEntry = const NoEntryVal--  exact (SpliceDecl _ splice _flag) = do-    markAnnotated splice---- -----------------------------------------------------------------------instance ExactPrint DocDecl where-  getAnnotationEntry = const NoEntryVal--  exact v =-    let str =-          case v of-            (DocCommentNext ds)     -> unpackHDS ds-            (DocCommentPrev ds)     -> unpackHDS ds-            (DocCommentNamed _s ds) -> unpackHDS ds-            (DocGroup _i ds)        -> unpackHDS ds-    in-      printStringAdvance str---- -----------------------------------------------------------------------instance ExactPrint (RoleAnnotDecl GhcPs) where-  getAnnotationEntry (RoleAnnotDecl an _ _) = fromAnn an-  exact (RoleAnnotDecl an ltycon roles) = do-    markEpAnn an AnnType-    markEpAnn an AnnRole-    markAnnotated ltycon-    let markRole (L l (Just r)) = markAnnotated (L l r)-        markRole (L l Nothing) = printStringAtSs l "_"-    mapM_ markRole roles---- -----------------------------------------------------------------------instance ExactPrint Role where-  getAnnotationEntry = const NoEntryVal-  exact = withPpr---- -----------------------------------------------------------------------instance ExactPrint (RuleBndr GhcPs) where-  getAnnotationEntry = const NoEntryVal--  exact (RuleBndr _ ln) = markAnnotated ln-  exact (RuleBndrSig an ln (HsPS _ ty)) = do-    markEpAnn an AnnOpenP -- "("-    markAnnotated ln-    markEpAnn an AnnDcolon-    markAnnotated ty-    markEpAnn an AnnCloseP -- ")"---- -----------------------------------------------------------------------instance (ExactPrint body) => ExactPrint (FamEqn GhcPs body) where-  getAnnotationEntry (FamEqn { feqn_ext = an}) = fromAnn an-  exact (FamEqn { feqn_ext = an-                , feqn_tycon  = tycon-                , feqn_bndrs  = bndrs-                , feqn_pats   = pats-                , feqn_fixity = fixity-                , feqn_rhs    = rhs }) = do-    exactHsFamInstLHS an tycon bndrs pats fixity Nothing-    markEpAnn an AnnEqual-    markAnnotated rhs---- -----------------------------------------------------------------------exactHsFamInstLHS ::-      EpAnn [AddEpAnn]-   -> LocatedN RdrName-   -> HsOuterTyVarBndrs () GhcPs-   -> HsTyPats GhcPs-   -> LexicalFixity-   -> Maybe (LHsContext GhcPs)-   -> EPP ()-exactHsFamInstLHS an thing bndrs typats fixity mb_ctxt = do-  markEpAnn an AnnForall-  markAnnotated bndrs-  markEpAnn an AnnDot-  mapM_ markAnnotated mb_ctxt-  exact_pats typats-  where-    exact_pats :: HsTyPats GhcPs -> EPP ()-    exact_pats (patl:patr:pats)-      | Infix <- fixity-      = let exact_op_app = do-              markAnnAll (epAnnAnns an) AnnOpenP-              markAnnotated patl-              markAnnotated thing-              markAnnotated patr-              markAnnAll (epAnnAnns an) AnnCloseP-        in case pats of-             [] -> exact_op_app-             _  -> do-               -- markEpAnn an AnnOpenP-               exact_op_app-               -- markEpAnn an AnnCloseP-               mapM_ markAnnotated pats--    exact_pats pats = do-      markAnnAll (epAnnAnns an) AnnOpenP-      markAnnotated thing-      markAnnotated pats-      markAnnAll (epAnnAnns an) AnnCloseP---- ------------------------------------------------------------------------- instance ExactPrint (LHsTypeArg GhcPs) where-instance (ExactPrint tm, ExactPrint ty, Outputable tm, Outputable ty)-     =>  ExactPrint (HsArg tm ty) where-  getAnnotationEntry = const NoEntryVal--  exact (HsValArg tm)    = markAnnotated tm-  exact (HsTypeArg ss ty) = printStringAtSs ss "@" >> markAnnotated ty-  exact x@(HsArgPar _sp)   = withPpr x -- Does not appear in original source---- -----------------------------------------------------------------------instance ExactPrint (ClsInstDecl GhcPs) where-  getAnnotationEntry cid = fromAnn (fst $ cid_ext cid)--  exact (ClsInstDecl { cid_ext = (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-          top_matter-          markEpAnn an AnnWhere-          markEpAnn an AnnOpenC-          markEpAnnAll an id AnnSemi-          withSortKey sortKey-                               (prepareListAnnotationA ats-                             ++ prepareListAnnotationF (exactDataFamInstDecl an NotTopLevel ) adts-                             ++ prepareListAnnotationA (bagToList binds)-                             ++ prepareListAnnotationA sigs-                               )-          markEpAnn an AnnCloseC -- '}'--      where-        top_matter = do-          markEpAnn an AnnInstance-          mapM_ markAnnotated mbOverlap-          markAnnotated inst_ty-          markEpAnn an AnnWhere -- Optional---- -----------------------------------------------------------------------instance ExactPrint (TyFamInstDecl GhcPs) where-  getAnnotationEntry (TyFamInstDecl an _) = fromAnn an--  exact (TyFamInstDecl { tfid_xtn = an, tfid_eqn = eqn }) = do-    markEpAnn an AnnType-    markEpAnn an AnnInstance-    markAnnotated eqn---- -----------------------------------------------------------------------instance ExactPrint (LocatedP OverlapMode) where-  getAnnotationEntry = entryFromLocatedA--  -- NOTE: NoOverlap is only used in the typechecker-  exact (L (SrcSpanAnn an _) (NoOverlap src)) = do-    markAnnOpenP an src "{-# NO_OVERLAP"-    markAnnCloseP an--  exact (L (SrcSpanAnn an _) (Overlappable src)) = do-    markAnnOpenP an src "{-# OVERLAPPABLE"-    markAnnCloseP an--  exact (L (SrcSpanAnn an _) (Overlapping src)) = do-    markAnnOpenP an src "{-# OVERLAPPING"-    markAnnCloseP an--  exact (L (SrcSpanAnn an _) (Overlaps src)) = do-    markAnnOpenP an src "{-# OVERLAPS"-    markAnnCloseP an--  exact (L (SrcSpanAnn an _) (Incoherent src)) = do-    markAnnOpenP an src "{-# INCOHERENT"-    markAnnCloseP an---- -----------------------------------------------------------------------instance ExactPrint (HsBind GhcPs) where-  getAnnotationEntry FunBind{} = NoEntryVal-  getAnnotationEntry PatBind{pat_ext=an} = fromAnn an-  getAnnotationEntry VarBind{} = NoEntryVal-  getAnnotationEntry AbsBinds{} = NoEntryVal-  getAnnotationEntry PatSynBind{} = NoEntryVal--  exact (FunBind _ _ matches _) = do-    markAnnotated matches-  exact (PatBind _ pat grhss _) = do-    markAnnotated pat-    markAnnotated grhss-  exact (PatSynBind _ bind) = markAnnotated bind--  exact x = error $ "HsBind: exact for " ++ showAst x---- -----------------------------------------------------------------------instance ExactPrint (PatSynBind GhcPs GhcPs) where-  getAnnotationEntry (PSB { psb_ext = an}) = fromAnn an--  exact (PSB{ psb_ext = an-            , psb_id = psyn, psb_args = details-            , psb_def = pat-            , psb_dir = dir }) = do-    markEpAnn an AnnPattern-    case details of-      InfixCon v1 v2 -> do-        markAnnotated v1-        markAnnotated psyn-        markAnnotated v2-      PrefixCon tvs vs -> do-        markAnnotated psyn-        markAnnotated tvs-        markAnnotated vs-      RecCon vs -> do-        markAnnotated psyn-        markEpAnn an AnnOpenC  -- '{'-        markAnnotated vs-        markEpAnn an AnnCloseC -- '}'--    case dir of-      Unidirectional           -> do-        markEpAnn an AnnLarrow-        markAnnotated pat-      ImplicitBidirectional    -> do-        markEpAnn an AnnEqual-        markAnnotated pat-      ExplicitBidirectional mg -> do-        markEpAnn an AnnLarrow-        markAnnotated pat-        markEpAnn an AnnWhere-        markAnnotated mg----- -----------------------------------------------------------------------instance ExactPrint (RecordPatSynField GhcPs) where-  getAnnotationEntry = const NoEntryVal-  exact (RecordPatSynField { recordPatSynField = v }) = markAnnotated v---- -----------------------------------------------------------------------instance ExactPrint (Match GhcPs (LocatedA (HsCmd GhcPs))) where-  getAnnotationEntry (Match ann _ _ _) = fromAnn ann--  exact (Match an mctxt pats grhss) = do-    exactMatch (Match an mctxt pats grhss)---- ---------------------------------------instance ExactPrint (Match GhcPs (LocatedA (HsExpr GhcPs))) where-  getAnnotationEntry (Match ann _ _ _) = fromAnn ann--  exact (Match an mctxt pats grhss) = do-    exactMatch (Match an mctxt pats grhss)---- -----------------------------------------------------------------------exactMatch :: (ExactPrint (GRHSs GhcPs body)) => (Match GhcPs body) -> Annotated ()-exactMatch (Match an mctxt pats grhss) = do--- Based on Expr.pprMatch--  debugM $ "exact Match entered"--  -- herald-  case mctxt of-    FunRhs fun fixity strictness -> do-      debugM $ "exact Match FunRhs:" ++ showPprUnsafe fun-      case strictness of-        SrcStrict -> markEpAnn an AnnBang-        _ -> pure ()-      case fixity of-        Prefix -> do-          annotationsToCommentsA an [AnnOpenP,AnnCloseP]-          markAnnotated fun-          markAnnotated pats-        Infix ->-          case pats of-            (p1:p2:rest)-              | null rest -> do-                  markAnnotated p1-                  markAnnotated fun-                  markAnnotated p2-              | otherwise -> do-                  markEpAnn an AnnOpenP-                  markAnnotated p1-                  markAnnotated fun-                  markAnnotated p2-                  markEpAnn an AnnCloseP-                  mapM_ markAnnotated rest-            _ -> panic "FunRhs"-    LambdaExpr -> do-      markEpAnn an AnnLam-      markAnnotated pats-    GHC.CaseAlt -> do-      markAnnotated pats-    _ -> withPpr mctxt--  markAnnotated grhss---- -----------------------------------------------------------------------instance ExactPrint (GRHSs GhcPs (LocatedA (HsExpr GhcPs))) where-  getAnnotationEntry (GRHSs _ _ _) = NoEntryVal--  exact (GRHSs _ grhss binds) = do-    markAnnotated grhss-    markAnnotated binds---instance ExactPrint (GRHSs GhcPs (LocatedA (HsCmd GhcPs))) where-  getAnnotationEntry (GRHSs _ _ _) = NoEntryVal--  exact (GRHSs _an grhss binds) = do-    markAnnotated grhss-    markAnnotated binds---- ------------------------------------------------------------------------- Temporary until https://gitlab.haskell.org/ghc/ghc/-/issues/20247--- is fixed-fixValbindsAnn :: EpAnn AnnList -> EpAnn AnnList-fixValbindsAnn EpAnnNotUsed = EpAnnNotUsed-fixValbindsAnn (EpAnn anchor (AnnList ma o c r t) cs)-  = (EpAnn (widenAnchor anchor (map toEpaAnn t)) (AnnList ma o c r t) cs)-  where-    toEpaAnn (AddSemiAnn ss)    = AddEpAnn AnnSemi ss-    toEpaAnn (AddCommaAnn ss)   = AddEpAnn AnnComma ss-    toEpaAnn (AddVbarAnn ss)    = AddEpAnn AnnVbar ss-    toEpaAnn (AddRarrowAnn ss)  = AddEpAnn AnnRarrow ss-    toEpaAnn (AddRarrowAnnU ss) = AddEpAnn AnnRarrowU ss-    toEpaAnn (AddLollyAnnU ss)  = AddEpAnn AnnLollyU ss---- See https://gitlab.haskell.org/ghc/ghc/-/issues/20256-fixAnnListAnn :: EpAnn AnnList -> EpAnn AnnList-fixAnnListAnn EpAnnNotUsed = EpAnnNotUsed-fixAnnListAnn (EpAnn anchor (AnnList ma o c r t) cs)-  = (EpAnn (widenAnchor anchor r) (AnnList ma o c r t) cs)---- See https://gitlab.haskell.org/ghc/ghc/-/issues/20256-fixSrcAnnL :: SrcSpanAnnL -> SrcSpanAnnL-fixSrcAnnL (SrcSpanAnn an l) = SrcSpanAnn (fixAnnListAnn an) l---- -----------------------------------------------------------------------instance ExactPrint (HsLocalBinds GhcPs) where-  getAnnotationEntry (HsValBinds an _) = fromAnn (fixValbindsAnn an)-  getAnnotationEntry (HsIPBinds{}) = NoEntryVal-  getAnnotationEntry (EmptyLocalBinds{}) = NoEntryVal--  exact (HsValBinds an' valbinds) = do-    let an = fixValbindsAnn an'-    markLocatedAAL an al_rest AnnWhere-    let manc = case an of-                 EpAnnNotUsed -> Nothing-                 _ -> al_anchor $ anns an--    case manc of-      Just anc -> do-        when (not $ isEmptyValBinds valbinds) $ setExtraDP (Just anc)-      _ -> return ()--    markAnnList False an $ markAnnotatedWithLayout valbinds--  exact (HsIPBinds an bs)-    = markAnnList True an (markLocatedAAL an al_rest AnnWhere >> markAnnotated bs)-  exact (EmptyLocalBinds _) = return ()----- ----------------------------------------------------------------------instance ExactPrint (HsValBindsLR GhcPs GhcPs) where-  getAnnotationEntry _ = NoEntryVal--  exact (ValBinds sortKey binds sigs) = do-    setLayoutBoth $ withSortKey sortKey-       (prepareListAnnotationA (bagToList binds)-     ++ prepareListAnnotationA sigs-       )-  exact (XValBindsLR _) = panic "XValBindsLR"---- -----------------------------------------------------------------------instance ExactPrint (HsIPBinds GhcPs) where-  getAnnotationEntry = const NoEntryVal--  exact (IPBinds _ binds) = setLayoutBoth $ markAnnotated binds---- -----------------------------------------------------------------------instance ExactPrint (IPBind GhcPs) where-  getAnnotationEntry (IPBind an _ _) = fromAnn an--  exact (IPBind an (Left lr) rhs) = do-    markAnnotated lr-    markEpAnn an AnnEqual-    markAnnotated rhs--  exact (IPBind _ (Right _) _) = error $ "ExactPrint IPBind: Right only after typechecker"---- -----------------------------------------------------------------------instance ExactPrint HsIPName where-  getAnnotationEntry = const NoEntryVal--  exact (HsIPName fs) = printStringAdvance ("?" ++ (unpackFS fs))---- ------------------------------------------------------------------------ Managing lists which have been separated, e.g. Sigs and Binds--prepareListAnnotationF :: (a -> EPP ()) -> [LocatedAn an a] -> [(RealSrcSpan,EPP ())]-prepareListAnnotationF f ls-  = map (\b -> (realSrcSpan $ getLocA b, f (unLoc b))) ls--prepareListAnnotationA :: ExactPrint (LocatedAn an a)-  => [LocatedAn an a] -> [(RealSrcSpan,EPP ())]-prepareListAnnotationA ls = map (\b -> (realSrcSpan $ getLocA b,markAnnotated b)) ls--withSortKey :: AnnSortKey -> [(RealSrcSpan, EPP ())] -> EPP ()-withSortKey annSortKey xs = do-  debugM $ "withSortKey:annSortKey=" ++ showAst annSortKey-  let ordered = case annSortKey of-                  NoAnnSortKey -> sortBy orderByFst xs-                  -- Just keys -> error $ "withSortKey: keys" ++ show keys-                  AnnSortKey keys -> orderByKey xs keys-                                -- `debug` ("withSortKey:" ++-                                --          showPprUnsafe (map fst (sortBy (comparing (flip elemIndex keys . fst)) xs),-                                --                  map fst xs,-                                --                  keys)-                                --          )-  mapM_ snd ordered--orderByFst :: Ord a => (a, b1) -> (a, b2) -> Ordering-orderByFst (a,_) (b,_) = compare a b---- -----------------------------------------------------------------------instance ExactPrint (Sig GhcPs) where-  getAnnotationEntry (TypeSig a _ _)  = fromAnn a-  getAnnotationEntry (PatSynSig a _ _) = fromAnn a-  getAnnotationEntry (ClassOpSig a _ _ _) = fromAnn a-  getAnnotationEntry (IdSig {}) = NoEntryVal-  getAnnotationEntry (FixSig a _) = fromAnn a-  getAnnotationEntry (InlineSig a _ _) = fromAnn a-  getAnnotationEntry (SpecSig a _ _ _) = fromAnn a-  getAnnotationEntry (SpecInstSig a _ _) = fromAnn a-  getAnnotationEntry (MinimalSig a _ _) = fromAnn a-  getAnnotationEntry (SCCFunSig a _ _ _) = fromAnn a-  getAnnotationEntry (CompleteMatchSig a _ _ _) = fromAnn a--  exact (TypeSig an vars ty)  = exactVarSig an vars ty--  exact (PatSynSig an lns typ) = do-    markLocatedAAL an asRest AnnPattern-    markAnnotated lns-    markLocatedAA an asDcolon-    markAnnotated typ--  exact (ClassOpSig an is_deflt vars ty)-    | is_deflt  = markLocatedAAL an asRest AnnDefault >> exactVarSig an vars ty-    | otherwise = exactVarSig an vars ty--  exact (FixSig an (FixitySig _ names (Fixity src v fdir))) = do-    let fixstr = case fdir of-         InfixL -> "infixl"-         InfixR -> "infixr"-         InfixN -> "infix"-    markLocatedAALS an id AnnInfix (Just fixstr)-    markLocatedAALS an id AnnVal (Just (sourceTextToString src (show v)))-    markAnnotated names---  exact (InlineSig an ln inl) = do-    markAnnOpen an (inl_src inl) "{-# INLINE"-    markActivation an id (inl_act inl)-    markAnnotated ln-    debugM $ "InlineSig:an=" ++ showAst an-    p <- getPosP-    debugM $ "InlineSig: p=" ++ show p-    markLocatedAALS an id AnnClose (Just "#-}")-    debugM $ "InlineSig:done"--  exact (SpecSig an ln typs inl) = do-    markAnnOpen an (inl_src inl) "{-# SPECIALISE" -- Note: may be {-# SPECIALISE_INLINE-    markActivation an id (inl_act inl)-    markAnnotated ln-    markEpAnn an AnnDcolon-    markAnnotated typs-    markLocatedAALS an id AnnClose (Just "#-}")--  exact (SpecInstSig an src typ) = do-    markAnnOpen an src "{-# SPECIALISE"-    markEpAnn an AnnInstance-    markAnnotated typ-    markLocatedAALS an id AnnClose (Just "#-}")---  exact (MinimalSig an src formula) = do-    markAnnOpen an src "{-# MINIMAL"-    markAnnotated formula-    markLocatedAALS an id AnnClose (Just "#-}")--  exact (SCCFunSig an src ln ml) = do-    markAnnOpen an src "{-# SCC"-    markAnnotated ln-    markAnnotated ml-    markLocatedAALS an id AnnClose (Just "#-}")--  exact (CompleteMatchSig an src cs mty) = do-    markAnnOpen an src "{-# COMPLETE"-    markAnnotated cs-    case mty of-      Nothing -> return ()-      Just ty -> do-        markEpAnn an AnnDcolon-        markAnnotated ty-    markLocatedAALS an id AnnClose (Just "#-}")--  exact x = error $ "exact Sig for:" ++ showAst x---- -----------------------------------------------------------------------exactVarSig :: (ExactPrint a) => EpAnn AnnSig -> [LocatedN RdrName] -> a -> EPP ()-exactVarSig an vars ty = do-  mapM_ markAnnotated vars-  markLocatedAA an asDcolon-  markAnnotated ty---- -----------------------------------------------------------------------instance ExactPrint (StandaloneKindSig GhcPs) where-  getAnnotationEntry (StandaloneKindSig an _ _) = fromAnn an--  exact (StandaloneKindSig an vars sig) = do-    markEpAnn an AnnType-    markAnnotated vars-    markEpAnn an AnnDcolon-    markAnnotated sig---- -----------------------------------------------------------------------instance ExactPrint (DefaultDecl GhcPs) where-  getAnnotationEntry (DefaultDecl an _) = fromAnn an--  exact (DefaultDecl an tys) = do-    markEpAnn an AnnDefault-    markEpAnn an AnnOpenP-    markAnnotated tys-    markEpAnn an AnnCloseP---- -----------------------------------------------------------------------instance ExactPrint (AnnDecl GhcPs) where-  getAnnotationEntry (HsAnnotation an _ _ _) = fromAnn an--  exact (HsAnnotation an src prov e) = do-    markAnnOpenP an src "{-# ANN"-    case prov of-      (ValueAnnProvenance n) -> markAnnotated n-      (TypeAnnProvenance n) -> do-        markLocatedAAL an apr_rest AnnType-        markAnnotated n-      ModuleAnnProvenance -> markLocatedAAL an apr_rest AnnModule--    markAnnotated e-    markAnnCloseP an---- -----------------------------------------------------------------------instance ExactPrint (BF.BooleanFormula (LocatedN RdrName)) where-  getAnnotationEntry = const NoEntryVal--  exact (BF.Var x)  = do-    markAnnotated x-  exact (BF.Or ls)  = markAnnotated ls-  exact (BF.And ls) = do-    markAnnotated ls-  exact (BF.Parens x)  = do-    markAnnotated x---- -----------------------------------------------------------------------instance (ExactPrint body) => ExactPrint (HsWildCardBndrs GhcPs body) where-  getAnnotationEntry = const NoEntryVal-  exact (HsWC _ ty) = markAnnotated ty---- -----------------------------------------------------------------------instance ExactPrint (GRHS GhcPs (LocatedA (HsExpr GhcPs))) where-  getAnnotationEntry (GRHS an _ _) = fromAnn an--  exact (GRHS an guards expr) = do-    debugM $ "GRHS comments:" ++ showGhc (comments an)-    markAnnKwM an ga_vbar AnnVbar-    markAnnotated guards-    debugM $ "GRHS before matchSeparator"-    markLocatedAA an ga_sep -- Mark the matchSeparator for these GRHSs-    debugM $ "GRHS after matchSeparator"-    markAnnotated expr--instance ExactPrint (GRHS GhcPs (LocatedA (HsCmd GhcPs))) where-  getAnnotationEntry (GRHS ann _ _) = fromAnn ann--  exact (GRHS an guards expr) = do-    markAnnKwM an ga_vbar AnnVbar-    markAnnotated guards-    markLocatedAA an ga_sep -- Mark the matchSeparator for these GRHSs-    markAnnotated expr---- -----------------------------------------------------------------------instance ExactPrint (HsExpr GhcPs) where-  getAnnotationEntry (HsVar{})                    = NoEntryVal-  getAnnotationEntry (HsUnboundVar an _)          = fromAnn an-  getAnnotationEntry (HsConLikeOut{})             = NoEntryVal-  getAnnotationEntry (HsRecFld{})                 = NoEntryVal-  getAnnotationEntry (HsOverLabel an _)           = fromAnn an-  getAnnotationEntry (HsIPVar an _)               = fromAnn an-  getAnnotationEntry (HsOverLit an _)             = fromAnn an-  getAnnotationEntry (HsLit an _)                 = fromAnn an-  getAnnotationEntry (HsLam _ _)                  = NoEntryVal-  getAnnotationEntry (HsLamCase an _)             = fromAnn an-  getAnnotationEntry (HsApp an _ _)               = fromAnn an-  getAnnotationEntry (HsAppType _ _ _)            = NoEntryVal-  getAnnotationEntry (OpApp an _ _ _)             = fromAnn an-  getAnnotationEntry (NegApp an _ _)              = fromAnn an-  getAnnotationEntry (HsPar an _)                 = fromAnn an-  getAnnotationEntry (SectionL an _ _)            = fromAnn an-  getAnnotationEntry (SectionR an _ _)            = fromAnn an-  getAnnotationEntry (ExplicitTuple an _ _)       = fromAnn an-  getAnnotationEntry (ExplicitSum an _ _ _)       = fromAnn an-  getAnnotationEntry (HsCase an _ _)              = fromAnn an-  getAnnotationEntry (HsIf an _ _ _)              = fromAnn an-  getAnnotationEntry (HsMultiIf an _)             = fromAnn an-  getAnnotationEntry (HsLet an _ _)               = fromAnn an-  getAnnotationEntry (HsDo an _ _)                = fromAnn an-  getAnnotationEntry (ExplicitList an _)          = fromAnn an-  getAnnotationEntry (RecordCon an _ _)           = fromAnn an-  getAnnotationEntry (RecordUpd an _ _)           = fromAnn an-  getAnnotationEntry (HsGetField an _ _)          = fromAnn an-  getAnnotationEntry (HsProjection an _)          = fromAnn an-  getAnnotationEntry (ExprWithTySig an _ _)       = fromAnn an-  getAnnotationEntry (ArithSeq an _ _)            = fromAnn an-  getAnnotationEntry (HsBracket an _)             = fromAnn an-  getAnnotationEntry (HsRnBracketOut{})           = NoEntryVal-  getAnnotationEntry (HsTcBracketOut{})           = NoEntryVal-  getAnnotationEntry (HsSpliceE an _)             = fromAnn an-  getAnnotationEntry (HsProc an _ _)              = fromAnn an-  getAnnotationEntry (HsStatic an _)              = fromAnn an-  getAnnotationEntry (HsTick {})                  = NoEntryVal-  getAnnotationEntry (HsBinTick {})               = NoEntryVal-  getAnnotationEntry (HsPragE{})                  = NoEntryVal---  exact (HsVar _ n) = markAnnotated n-  exact x@(HsUnboundVar an _v) = do-    case an of-      EpAnnNotUsed -> withPpr x-      EpAnn _ (EpAnnUnboundVar (ob,cb) l) _ -> do-        printStringAtAA ob "`"-        printStringAtAA l  "_"-        printStringAtAA cb "`"-  -- exact x@(HsConLikeOut{})             = withPpr x-  -- exact x@(HsRecFld{})                 = withPpr x-  exact x@(HsOverLabel _ _) = withPpr x--  exact (HsIPVar _ (HsIPName n))-    = printStringAdvance ("?" ++ unpackFS n)--  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-    -- markExternalSourceText l str ""-    case str of-      SourceText s -> printStringAdvance s-      NoSourceText -> withPpr x--  exact (HsLit _an lit) = withPpr lit-  exact (HsLam _ (MG _ (L _ [match]) _)) = do-    markAnnotated match-  exact (HsLam _ _) = error $ "HsLam with other than one match"--  exact (HsLamCase an mg) = do-    markEpAnn an AnnLam-    markEpAnn an AnnCase-    markAnnotated mg--  exact (HsApp _an e1 e2) = do-    p <- getPosP-    debugM $ "HsApp entered. p=" ++ show p-    markAnnotated e1-    markAnnotated e2-  exact (HsAppType ss fun arg) = do-    markAnnotated fun-    printStringAtSs ss "@"-    markAnnotated arg-  exact (OpApp _an e1 e2 e3) = do-    markAnnotated e1-    markAnnotated e2-    markAnnotated e3--  exact (NegApp an e _) = do-    markEpAnn an AnnMinus-    markAnnotated e--  exact (HsPar an e) = do-    markOpeningParen an-    markAnnotated e-    debugM $ "HsPar closing paren"-    markClosingParen an-    debugM $ "HsPar done"--  exact (SectionL _an expr op) = do-    markAnnotated expr-    markAnnotated op--  exact (SectionR _an op expr) = do-    markAnnotated op-    markAnnotated expr--  exact (ExplicitTuple an args b) = do-    if b == Boxed then markEpAnn an AnnOpenP-                  else markEpAnn an AnnOpenPH--    mapM_ markAnnotated args--    if b == Boxed then markEpAnn an AnnCloseP-                  else markEpAnn an AnnClosePH-    debugM $ "ExplicitTuple done"--  exact (ExplicitSum an _alt _arity expr) = do-    markAnnKw an aesOpen AnnOpenPH-    markAnnKwAll an aesBarsBefore AnnVbar-    markAnnotated expr-    markAnnKwAll an aesBarsAfter AnnVbar-    markAnnKw an aesClose AnnClosePH--  exact (HsCase an e alts) = do-    markAnnKw an hsCaseAnnCase AnnCase-    markAnnotated e-    markAnnKw an hsCaseAnnOf AnnOf-    markEpAnn' an hsCaseAnnsRest AnnOpenC-    markEpAnnAll an hsCaseAnnsRest AnnSemi-    setLayoutBoth $ markAnnotated alts-    markEpAnn' an hsCaseAnnsRest AnnCloseC--  exact (HsIf an e1 e2 e3) = do-    markAnnKw an aiIf AnnIf-    markAnnotated e1-    markAnnKwM an aiThenSemi AnnSemi-    markAnnKw an aiThen AnnThen-    markAnnotated e2-    markAnnKwM an aiElseSemi AnnSemi-    markAnnKw an aiElse AnnElse-    markAnnotated e3--  exact (HsMultiIf an mg) = do-    markEpAnn an AnnIf-    markEpAnn an AnnOpenC -- optional-    markAnnotated mg-    markEpAnn an AnnCloseC -- optional--  exact (HsLet an binds e) = do-    setLayoutBoth $ do -- Make sure the 'in' gets indented too-      markAnnKw an alLet AnnLet-      debugM $ "HSlet:binds coming"-      setLayoutBoth $ markAnnotated binds-      debugM $ "HSlet:binds done"-      markAnnKw an alIn AnnIn-      debugM $ "HSlet:expr coming"-      markAnnotated e--  exact (HsDo an do_or_list_comp stmts) = do-    debugM $ "HsDo"-    markAnnList True an $ exactDo an do_or_list_comp stmts--  exact (ExplicitList an es) = do-    debugM $ "ExplicitList start"-    markLocatedMAA an al_open-    markAnnotated es-    markLocatedMAA an al_close-    debugM $ "ExplicitList end"-  exact (RecordCon an con_id binds) = do-    markAnnotated con_id-    markEpAnn an AnnOpenC-    markAnnotated binds-    markEpAnn an AnnCloseC-  exact (RecordUpd an expr fields) = do-    markAnnotated expr-    markEpAnn an AnnOpenC-    markAnnotated fields-    markEpAnn an AnnCloseC-  exact (HsGetField _an expr field) = do-    markAnnotated expr-    markAnnotated field-  exact (HsProjection an flds) = do-    markAnnKw an apOpen AnnOpenP-    markAnnotated flds-    markAnnKw an apClose AnnCloseP-  exact (ExprWithTySig an expr sig) = do-    markAnnotated expr-    markEpAnn an AnnDcolon-    markAnnotated sig-  exact (ArithSeq an _ seqInfo) = do-    markEpAnn an AnnOpenS -- '['-    case seqInfo of-        From e -> do-          markAnnotated e-          markEpAnn an AnnDotdot-        FromTo e1 e2 -> do-          markAnnotated e1-          markEpAnn an AnnDotdot-          markAnnotated e2-        FromThen e1 e2 -> do-          markAnnotated e1-          markEpAnn an AnnComma-          markAnnotated e2-          markEpAnn an AnnDotdot-        FromThenTo e1 e2 e3 -> do-          markAnnotated e1-          markEpAnn an AnnComma-          markAnnotated e2-          markEpAnn an AnnDotdot-          markAnnotated e3-    markEpAnn an AnnCloseS -- ']'---  exact (HsBracket an (ExpBr _ e)) = do-    markEpAnn an AnnOpenEQ -- "[|"-    markEpAnn an AnnOpenE  -- "[e|" -- optional-    markAnnotated e-    markEpAnn an AnnCloseQ -- "|]"-  exact (HsBracket an (PatBr _ e)) = do-    markLocatedAALS an id AnnOpen (Just "[p|")-    markAnnotated e-    markEpAnn an AnnCloseQ -- "|]"-  exact (HsBracket an (DecBrL _ e)) = do--    markLocatedAALS an id AnnOpen (Just "[d|")-    -- See https://gitlab.haskell.org/ghc/ghc/-/issues/20257, we need-    -- to mark braces here for the time being-    markEpAnn an AnnOpenC -- "{"-    markAnnotated e-    markEpAnn an AnnCloseC -- "}"-    markEpAnn an AnnCloseQ -- "|]"-  -- -- exact (HsBracket an (DecBrG _ _)) =-  -- --   traceM "warning: DecBrG introduced after renamer"-  exact (HsBracket an (TypBr _ e)) = do-    markLocatedAALS an id AnnOpen (Just "[t|")-    markAnnotated e-    markEpAnn an AnnCloseQ -- "|]"-  exact (HsBracket an (VarBr _ b e)) = do-    if b-      then do-        markEpAnn an AnnSimpleQuote-        markAnnotated e-      else do-        markEpAnn an AnnThTyQuote-        markAnnotated e-  exact (HsBracket an (TExpBr _ e)) = do-    markLocatedAALS an id AnnOpen (Just "[||")-    markLocatedAALS an id AnnOpenE (Just "[e||")-    markAnnotated e-    markLocatedAALS an id AnnClose (Just "||]")---  -- exact x@(HsRnBracketOut{})           = withPpr x-  -- exact x@(HsTcBracketOut{})           = withPpr x-  exact (HsSpliceE _ sp) = markAnnotated sp--  exact (HsProc an p c) = do-    debugM $ "HsProc start"-    markEpAnn an AnnProc-    markAnnotated p-    markEpAnn an AnnRarrow-    debugM $ "HsProc after AnnRarrow"-    markAnnotated c--  exact (HsStatic an e) = do-    markEpAnn an AnnStatic-    markAnnotated e--  -- exact x@(HsTick {})                  = withPpr x-  -- exact x@(HsBinTick {})               = withPpr x-  exact (HsPragE _ prag e) = do-    markAnnotated prag-    markAnnotated e-  exact x = error $ "exact HsExpr for:" ++ showAst x---- -----------------------------------------------------------------------exactDo :: (ExactPrint body)-        => EpAnn AnnList -> (HsStmtContext any) -> body -> EPP ()-exactDo an (DoExpr m)    stmts = exactMdo an m AnnDo             >> markAnnotatedWithLayout stmts-exactDo an GhciStmtCtxt  stmts = markLocatedAAL an al_rest AnnDo >> markAnnotatedWithLayout stmts-exactDo an ArrowExpr     stmts = markLocatedAAL an al_rest AnnDo >> markAnnotatedWithLayout stmts-exactDo an (MDoExpr m)   stmts = exactMdo an m AnnMdo            >> markAnnotatedWithLayout stmts-exactDo _  ListComp      stmts = markAnnotatedWithLayout stmts-exactDo _  MonadComp     stmts = markAnnotatedWithLayout stmts-exactDo _  _             _     = panic "pprDo" -- PatGuard, ParStmtCxt--exactMdo :: EpAnn AnnList -> Maybe ModuleName -> AnnKeywordId -> EPP ()-exactMdo an Nothing            kw = markLocatedAAL  an al_rest kw-exactMdo an (Just module_name) kw = markLocatedAALS an al_rest kw (Just n)-    where-      n = (moduleNameString module_name) ++ "." ++ (keywordToString (G kw))----- ----------------------------------------------------------------------instance ExactPrint (HsPragE GhcPs) where-  getAnnotationEntry HsPragSCC{}  = NoEntryVal--  exact (HsPragSCC an st sl) = do-    markAnnOpenP an st "{-# SCC"-    let txt = sourceTextToString (sl_st sl) (unpackFS $ sl_fs sl)-    markLocatedAALS an apr_rest AnnVal    (Just txt) -- optional-    markLocatedAALS an apr_rest AnnValStr (Just txt) -- optional-    markAnnCloseP an----- -----------------------------------------------------------------------instance ExactPrint (HsSplice GhcPs) where-  getAnnotationEntry (HsTypedSplice an _ _ _)   = fromAnn an-  getAnnotationEntry (HsUntypedSplice an _ _ _) = fromAnn an-  getAnnotationEntry (HsQuasiQuote _ _ _ _ _)   = NoEntryVal-  getAnnotationEntry (HsSpliced _ _ _)          = NoEntryVal--  exact (HsTypedSplice an DollarSplice _n e) = do-    markEpAnn an AnnDollarDollar-    markAnnotated e--  exact (HsUntypedSplice an decoration _n b) = do-    when (decoration == DollarSplice) $ markEpAnn an AnnDollar-    markAnnotated b--  exact (HsQuasiQuote _ _ q ss 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-    p <- getPosP-    debugM $ "HsQuasiQuote:after:(p,ss)=" ++ show (p,ss2range ss)--  exact x = error $ "exact HsSplice for:" ++ showAst x---- ------------------------------------------------------------------------- TODO:AZ: combine these instances-instance ExactPrint (MatchGroup GhcPs (LocatedA (HsExpr GhcPs))) where-  getAnnotationEntry = const NoEntryVal-  exact (MG _ matches _) = do-    -- TODO:AZ use SortKey, in MG ann.-    markAnnotated matches--instance ExactPrint (MatchGroup GhcPs (LocatedA (HsCmd GhcPs))) where-  getAnnotationEntry = const NoEntryVal-  exact (MG _ matches _) = do-    -- TODO:AZ use SortKey, in MG ann.-    markAnnotated matches---- -----------------------------------------------------------------------instance (ExactPrint body) => ExactPrint (HsRecFields GhcPs body) where-  getAnnotationEntry = const NoEntryVal-  exact (HsRecFields fields mdot) = do-    markAnnotated fields-    case mdot of-      Nothing -> return ()-      Just (L ss _) ->-        printStringAtSs ss ".."-      -- Note: mdot contains the SrcSpan where the ".." appears, if present---- -----------------------------------------------------------------------instance (ExactPrint body)-    => ExactPrint (HsRecField' (FieldOcc GhcPs) body) where-  getAnnotationEntry x = fromAnn (hsRecFieldAnn x)-  exact (HsRecField an f arg isPun) = do-    debugM $ "HsRecField"-    markAnnotated f-    if isPun then return ()-             else do-      markEpAnn an AnnEqual-      markAnnotated arg---- -----------------------------------------------------------------------instance (ExactPrint body)-    => ExactPrint (HsRecField' (FieldLabelStrings GhcPs) body) where-  getAnnotationEntry x = fromAnn (hsRecFieldAnn x)-  exact (HsRecField an f arg isPun) = do-    debugM $ "HsRecField FieldLabelStrings"-    markAnnotated f-    if isPun then return ()-             else do-      markEpAnn an AnnEqual-      markAnnotated arg---- -----------------------------------------------------------------------instance (ExactPrint (LocatedA body))-    => ExactPrint (HsRecField' (AmbiguousFieldOcc GhcPs) (LocatedA body)) where-  getAnnotationEntry x = fromAnn (hsRecFieldAnn x)-  exact (HsRecField an f arg isPun) = do-    debugM $ "HsRecUpdField"-    markAnnotated f-    if isPun then return ()-             else markEpAnn an AnnEqual-    unless ((locA $ getLoc arg) == noSrcSpan ) $ markAnnotated arg---- ----------------------------------------------------------------------instance-    (ExactPrint (HsRecField' (a GhcPs) body),-     ExactPrint (HsRecField' (b GhcPs) body))-    => ExactPrint-         (Either [LocatedA (HsRecField' (a GhcPs) body)]-                 [LocatedA (HsRecField' (b GhcPs) body)]) where-  getAnnotationEntry = const NoEntryVal-  exact (Left rbinds) = markAnnotated rbinds-  exact (Right pbinds) = markAnnotated pbinds---- -----------------------------------------------------------------------instance ExactPrint (FieldLabelStrings GhcPs) where-  getAnnotationEntry = const NoEntryVal-  exact (FieldLabelStrings fs) = markAnnotated fs---- -----------------------------------------------------------------------instance ExactPrint (HsFieldLabel GhcPs) where-  getAnnotationEntry (HsFieldLabel an _) = fromAnn an--  exact (HsFieldLabel an fs) = do-    markAnnKwM an afDot  AnnDot-    markAnnotated fs---- -----------------------------------------------------------------------instance ExactPrint (HsTupArg GhcPs) where-  getAnnotationEntry (Present an _) = fromAnn an-  getAnnotationEntry (Missing an)   = fromAnn an--  exact (Present _ e) = markAnnotated e--  exact (Missing EpAnnNotUsed) = return ()-  exact (Missing _) = printStringAdvance ","---- -----------------------------------------------------------------------instance ExactPrint (HsCmdTop GhcPs) where-  getAnnotationEntry = const NoEntryVal-  exact (HsCmdTop _ cmd) = markAnnotated cmd---- -----------------------------------------------------------------------instance ExactPrint (HsCmd GhcPs) where-  getAnnotationEntry (HsCmdArrApp an _ _ _ _)   = fromAnn an-  getAnnotationEntry (HsCmdArrForm an _ _ _ _ ) = fromAnn an-  getAnnotationEntry (HsCmdApp an _ _ )         = fromAnn an-  getAnnotationEntry (HsCmdLam {})              = NoEntryVal-  getAnnotationEntry (HsCmdPar an _)            = fromAnn an-  getAnnotationEntry (HsCmdCase an _ _)         = fromAnn an-  getAnnotationEntry (HsCmdLamCase an _)        = fromAnn an-  getAnnotationEntry (HsCmdIf an _ _ _ _)       = fromAnn an-  getAnnotationEntry (HsCmdLet an _ _)          = fromAnn an-  getAnnotationEntry (HsCmdDo an _)             = fromAnn an----  exact (HsCmdArrApp an arr arg _o isRightToLeft) = do-    if isRightToLeft-      then do-        markAnnotated arr-        markKw (anns an)-        markAnnotated arg-      else do-        markAnnotated arg-        markKw (anns an)-        markAnnotated arr--  exact (HsCmdArrForm an e fixity _mf cs) = do-    markLocatedMAA an al_open-    case (fixity, cs) of-      (Infix, (arg1:argrest)) -> do-        markAnnotated arg1-        markAnnotated e-        markAnnotated argrest-      (Prefix, _) -> do-        markAnnotated e-        markAnnotated cs-      (Infix, []) -> error "Not possible"-    markLocatedMAA an al_close--  exact (HsCmdApp _an e1 e2) = do-    markAnnotated e1-    markAnnotated e2--  exact (HsCmdLam _ match) = markAnnotated match--  exact (HsCmdPar an e) = do-    markOpeningParen an-    markAnnotated e-    markClosingParen an--  exact (HsCmdCase an e alts) = do-    markAnnKw an hsCaseAnnCase AnnCase-    markAnnotated e-    markAnnKw an hsCaseAnnOf AnnOf-    markEpAnn' an hsCaseAnnsRest AnnOpenC-    markEpAnnAll an hsCaseAnnsRest AnnSemi-    markAnnotated alts-    markEpAnn' an hsCaseAnnsRest AnnCloseC--  exact (HsCmdLamCase an matches) = do-    markEpAnn an AnnLam-    markEpAnn an AnnCase-    markAnnotated matches--  exact (HsCmdIf an _ e1 e2 e3) = do-    markAnnKw an aiIf AnnIf-    markAnnotated e1-    markAnnKwM an aiThenSemi AnnSemi-    markAnnKw an aiThen AnnThen-    markAnnotated e2-    markAnnKwM an aiElseSemi AnnSemi-    markAnnKw an aiElse AnnElse-    markAnnotated e3--  exact (HsCmdLet an binds e) = do-    markAnnKw an alLet AnnLet-    markAnnotated binds-    markAnnKw an alIn AnnIn-    markAnnotated e--  exact (HsCmdDo an es) = do-    debugM $ "HsCmdDo"-    markEpAnn' an al_rest AnnDo-    markAnnotated es--  -- exact x = error $ "exact HsCmd for:" ++ showAst x---- -----------------------------------------------------------------------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 (LastStmt _ _ _ _)             = NoEntryVal-  getAnnotationEntry (BindStmt an _ _)              = fromAnn an-  getAnnotationEntry (ApplicativeStmt _ _ _)        = NoEntryVal-  getAnnotationEntry (BodyStmt _ _ _ _)             = NoEntryVal-  getAnnotationEntry (LetStmt an _)                 = fromAnn an-  getAnnotationEntry (ParStmt _ _ _ _)              = NoEntryVal-  getAnnotationEntry (TransStmt an _ _ _ _ _ _ _ _) = fromAnn an-  getAnnotationEntry (RecStmt an _ _ _ _ _ _)       = fromAnn an--  -------------------------------------------------------------------  exact (LastStmt _ body _ _) = do-    debugM $ "LastStmt"-    markAnnotated body--  exact (BindStmt an pat body) = do-    debugM $ "BindStmt"-    markAnnotated pat-    markEpAnn an AnnLarrow-    markAnnotated body--  exact (ApplicativeStmt _ _body _) = do-    debugM $ "ApplicativeStmt"-    -- TODO: ApplicativeStmt-    -- markAnnotated body-    error $ "need to complete ApplicativeStmt"--  exact (BodyStmt _ body _ _) = do-    debugM $ "BodyStmt"-    markAnnotated body--  exact (LetStmt an binds) = do-    debugM $ "LetStmt"-    markEpAnn an AnnLet-    markAnnotated binds--  exact (ParStmt _ pbs _ _) = do-    debugM $ "ParStmt"-    markAnnotated pbs---  exact (TransStmt an form stmts _b using by _ _ _) = do-    debugM $ "TransStmt"-    markAnnotated stmts-    exactTransStmt an by using form---  exact (RecStmt an stmts _ _ _ _ _) = do-    debugM $ "RecStmt"-    markLocatedAAL an al_rest AnnRec-    markAnnList True an (markAnnotated stmts)--  -- exact x = error $ "exact CmdLStmt for:" ++ showAst x-  -- exact x = error $ "exact CmdLStmt for:"----- -----------------------------------------------------------------------instance ExactPrint (ParStmtBlock GhcPs GhcPs) where-  getAnnotationEntry = const NoEntryVal-  exact (ParStmtBlock _ stmts _ _) = markAnnotated stmts--exactTransStmt :: EpAnn [AddEpAnn] -> Maybe (LHsExpr GhcPs) -> (LHsExpr GhcPs) -> TransForm -> EPP ()-exactTransStmt an by using ThenForm = do-  debugM $ "exactTransStmt:ThenForm"-  markEpAnn an AnnThen-  markAnnotated using-  case by of-    Nothing -> return ()-    Just b -> do-      markEpAnn an AnnBy-      markAnnotated b-exactTransStmt an by using GroupForm = do-  debugM $ "exactTransStmt:GroupForm"-  markEpAnn an AnnThen-  markEpAnn an AnnGroup-  case by of-    Just b -> do-      markEpAnn an AnnBy-      markAnnotated b-    Nothing -> return ()-  markEpAnn an AnnUsing-  markAnnotated using---- -----------------------------------------------------------------------instance ExactPrint (TyClDecl GhcPs) where-  getAnnotationEntry (FamDecl   { })                      = NoEntryVal-  getAnnotationEntry (SynDecl   { tcdSExt = an })         = fromAnn an-  getAnnotationEntry (DataDecl  { tcdDExt = an })         = fromAnn an-  getAnnotationEntry (ClassDecl { tcdCExt = (an, _, _) }) = fromAnn an--  exact (FamDecl _ decl) = do-    markAnnotated 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-    annotationsToComments (epAnnAnns an) [AnnOpenP,AnnCloseP]-    markEpAnn an AnnType--    exactVanillaDeclHead ltycon tyvars fixity Nothing-    markEpAnn an AnnEqual-    markAnnotated rhs--  exact (DataDecl { tcdDExt = an, tcdLName = ltycon, tcdTyVars = tyvars-                  , tcdFixity = fixity, tcdDataDefn = defn }) =-    exactDataDefn an (exactVanillaDeclHead ltycon tyvars fixity) defn--  -- -------------------------------------  exact (ClassDecl {tcdCExt = (an, 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-          top_matter-          markEpAnn an AnnOpenC-          markEpAnn an AnnCloseC--      | otherwise       -- Laid out-      = do-          top_matter-          markEpAnn an AnnOpenC-          markEpAnnAll an id AnnSemi-          withSortKey sortKey-                               (prepareListAnnotationA sigs-                             ++ prepareListAnnotationA (bagToList methods)-                             ++ prepareListAnnotationA ats-                             ++ prepareListAnnotationA at_defs-                             -- ++ prepareListAnnotation docs-                               )-          markEpAnn an AnnCloseC-      where-        top_matter = do-          annotationsToComments (epAnnAnns an)  [AnnOpenP, AnnCloseP]-          markEpAnn an AnnClass-          exactVanillaDeclHead lclas tyvars fixity context-          unless (null fds) $ do-            markEpAnn an AnnVbar-            markAnnotated fds-          markEpAnn an AnnWhere---- -----------------------------------------------------------------------instance ExactPrint (FunDep GhcPs) where-  getAnnotationEntry (FunDep an _ _) = fromAnn an--  exact (FunDep an ls rs') = do-    markAnnotated ls-    markEpAnn an AnnRarrow-    markAnnotated rs'---- -----------------------------------------------------------------------instance ExactPrint (FamilyDecl GhcPs) where-  getAnnotationEntry (FamilyDecl { fdExt = an }) = fromAnn an--  exact (FamilyDecl { fdExt = an-                    , fdInfo = info-                    , fdTopLevel = top_level-                    , fdLName = ltycon-                    , fdTyVars = tyvars-                    , fdFixity = fixity-                    , fdResultSig = L _ result-                    , fdInjectivityAnn = mb_inj }) = do-    -- = vcat [ pprFlavour info <+> pp_top_level <+>-    --          pp_vanilla_decl_head ltycon tyvars fixity Nothing <+>-    --          pp_kind <+> pp_inj <+> pp_where-    --        , nest 2 $ pp_eqns ]-    exactFlavour an info-    exact_top_level-    annotationsToCommentsA an [AnnOpenP,AnnCloseP]-    exactVanillaDeclHead ltycon tyvars fixity Nothing-    exact_kind-    case mb_inj of-      Nothing -> return ()-      Just inj -> do-        markEpAnn an AnnVbar-        markAnnotated inj-    case info of-      ClosedTypeFamily mb_eqns -> do-        markEpAnn an AnnWhere-        markEpAnn an AnnOpenC-        case mb_eqns of-          Nothing -> markEpAnn an AnnDotdot-          Just eqns -> markAnnotated eqns-        markEpAnn an AnnCloseC-      _ -> return ()-    where-      exact_top_level = case top_level of-                          TopLevel    -> markEpAnn an AnnFamily-                          NotTopLevel -> do-                            -- It seems that in some kind of legacy-                            -- mode the 'family' keyword is still-                            -- accepted.-                            markEpAnn an AnnFamily-                            return ()--      exact_kind = case result of-                     NoSig    _         -> return ()-                     KindSig  _ kind    -> markEpAnn an AnnDcolon >> markAnnotated kind-                     TyVarSig _ tv_bndr -> markEpAnn an AnnEqual >> markAnnotated tv_bndr---exactFlavour :: EpAnn [AddEpAnn] -> FamilyInfo GhcPs -> EPP ()-exactFlavour an DataFamily            = markEpAnn an AnnData-exactFlavour an OpenTypeFamily        = markEpAnn an AnnType-exactFlavour an (ClosedTypeFamily {}) = markEpAnn an AnnType---- -----------------------------------------------------------------------data DataDefnWithContext-  = DataDefnWithContext-  { ddwc_an :: EpAnn [AddEpAnn]-  , ddwc_hdr:: (Maybe (LHsContext GhcPs) -> EPP ()) -- Printing the header-  , ddwc_defn:: HsDataDefn GhcPs-  }--instance ExactPrint DataDefnWithContext where-  getAnnotationEntry DataDefnWithContext{ddwc_an = an} = fromAnn an--  exact (DataDefnWithContext an exactHdr defn)-    = exactDataDefn an exactHdr defn--exactDataDefn :: EpAnn [AddEpAnn]-              -> (Maybe (LHsContext GhcPs) -> EPP ()) -- Printing the header-              -> HsDataDefn GhcPs-              -> EPP ()-exactDataDefn an exactHdr-                 (HsDataDefn { dd_ND = new_or_data, dd_ctxt = context-                             , dd_cType = mb_ct-                             , dd_kindSig = mb_sig-                             , dd_cons = condecls, dd_derivs = derivings }) = do-  annotationsToComments (epAnnAnns an) [AnnOpenP, AnnCloseP]-  if new_or_data == DataType-    then markEpAnn an AnnData-    else markEpAnn an AnnNewtype-  markEpAnn an AnnInstance -- optional-  mapM_ markAnnotated mb_ct-  exactHdr context-  case mb_sig of-    Nothing -> return ()-    Just kind -> do-      markEpAnn an AnnDcolon-      markAnnotated kind-  when (isGadt condecls) $ markEpAnn an AnnWhere-  markEpAnn an AnnOpenC-  exact_condecls an condecls-  markEpAnn an AnnCloseC-  mapM_ markAnnotated derivings-  return ()---exactVanillaDeclHead :: LocatedN RdrName-                     -> LHsQTyVars GhcPs-                     -> LexicalFixity-                     -> Maybe (LHsContext GhcPs)-                     -> EPP ()-exactVanillaDeclHead thing (HsQTvs { hsq_explicit = tyvars }) fixity context = do-  let-    exact_tyvars :: [LHsTyVarBndr () GhcPs] -> EPP ()-    exact_tyvars (varl:varsr)-      | fixity == Infix && length varsr > 1 = do-          markAnnotated varl-          markAnnotated thing-          markAnnotated (head varsr)-          markAnnotated (tail varsr)-          return ()-      | fixity == Infix = do-          markAnnotated varl-          markAnnotated thing-          markAnnotated varsr-          return ()-      | otherwise = do-          markAnnotated thing-          mapM_ markAnnotated (varl:varsr)-          return ()-    exact_tyvars [] = do-      markAnnotated thing-  mapM_ markAnnotated context-  exact_tyvars tyvars---- -----------------------------------------------------------------------instance ExactPrint (InjectivityAnn GhcPs) where-  getAnnotationEntry (InjectivityAnn an _ _) = fromAnn an-  exact (InjectivityAnn an lhs rhs) = do-    markEpAnn an AnnVbar-    markAnnotated lhs-    markEpAnn an AnnRarrow-    mapM_ markAnnotated rhs---- -----------------------------------------------------------------------class Typeable flag => ExactPrintTVFlag flag where-  exactTVDelimiters :: EpAnn [AddEpAnn] -> flag -> Annotated () -> Annotated ()--instance ExactPrintTVFlag () where-  exactTVDelimiters an _ thing_inside = do-    markEpAnnAll an id AnnOpenP-    thing_inside-    markEpAnnAll an id AnnCloseP--instance ExactPrintTVFlag Specificity where-  exactTVDelimiters an s thing_inside = do-    markEpAnnAll an id open-    thing_inside-    markEpAnnAll an id close-    where-      (open, close) = case s of-        SpecifiedSpec -> (AnnOpenP, AnnCloseP)-        InferredSpec  -> (AnnOpenC, AnnCloseC)--instance ExactPrintTVFlag flag => ExactPrint (HsTyVarBndr flag GhcPs) where-  getAnnotationEntry (UserTyVar an _ _)     = fromAnn an-  getAnnotationEntry (KindedTyVar an _ _ _) = fromAnn an--  exact (UserTyVar an flag n) =-    exactTVDelimiters an flag $ markAnnotated n-  exact (KindedTyVar an flag n k) = exactTVDelimiters an flag $ do-    markAnnotated n-    markEpAnn an AnnDcolon-    markAnnotated k---- -----------------------------------------------------------------------instance ExactPrint (HsType GhcPs) where-  getAnnotationEntry (HsForAllTy _ _ _)        = NoEntryVal-  getAnnotationEntry (HsQualTy _ _ _)          = NoEntryVal-  getAnnotationEntry (HsTyVar an _ _)          = fromAnn an-  getAnnotationEntry (HsAppTy _ _ _)           = NoEntryVal-  getAnnotationEntry (HsAppKindTy _ _ _)       = NoEntryVal-  getAnnotationEntry (HsFunTy an _ _ _)        = fromAnn an-  getAnnotationEntry (HsListTy an _)           = fromAnn an-  getAnnotationEntry (HsTupleTy an _ _)        = fromAnn an-  getAnnotationEntry (HsSumTy an _)            = fromAnn an-  getAnnotationEntry (HsOpTy _ _ _ _)          = NoEntryVal-  getAnnotationEntry (HsParTy an _)            = fromAnn an-  getAnnotationEntry (HsIParamTy an _ _)       = fromAnn an-  getAnnotationEntry (HsStarTy _ _)            = NoEntryVal-  getAnnotationEntry (HsKindSig an _ _)        = fromAnn an-  getAnnotationEntry (HsSpliceTy _ _)          = NoEntryVal-  getAnnotationEntry (HsDocTy an _ _)          = fromAnn an-  getAnnotationEntry (HsBangTy an _ _)         = fromAnn an-  getAnnotationEntry (HsRecTy an _)            = fromAnn an-  getAnnotationEntry (HsExplicitListTy an _ _) = fromAnn an-  getAnnotationEntry (HsExplicitTupleTy an _)  = fromAnn an-  getAnnotationEntry (HsTyLit _ _)             = NoEntryVal-  getAnnotationEntry (HsWildCardTy _)          = NoEntryVal-  getAnnotationEntry (XHsType _)               = NoEntryVal---  exact (HsForAllTy { hst_xforall = _an-                    , hst_tele = tele, hst_body = ty }) = do-    markAnnotated tele-    markAnnotated ty--  exact (HsQualTy _ ctxt ty) = do-    markAnnotated ctxt-    markAnnotated ty-  exact (HsTyVar an promoted name) = do-    when (promoted == IsPromoted) $ markEpAnn an AnnSimpleQuote-    markAnnotated name--  exact (HsAppTy _ t1 t2) = markAnnotated t1 >> markAnnotated t2-  exact (HsAppKindTy ss ty ki) = do-    markAnnotated ty-    printStringAtSs ss "@"-    markAnnotated ki-  exact (HsFunTy an mult ty1 ty2) = do-    markAnnotated ty1-    markArrow an mult-    markAnnotated ty2-  exact (HsListTy an tys) = do-    markOpeningParen an-    markAnnotated tys-    markClosingParen an-  exact (HsTupleTy an _con tys) = do-    markOpeningParen an-    markAnnotated tys-    markClosingParen an-  exact (HsSumTy an tys) = do-    markOpeningParen an-    markAnnotated tys-    markClosingParen an-  exact (HsOpTy _an t1 lo t2) = do-    markAnnotated t1-    markAnnotated lo-    markAnnotated t2-  exact (HsParTy an ty) = do-    markOpeningParen an-    markAnnotated ty-    markClosingParen an-  exact (HsIParamTy an n t) = do-      markAnnotated n-      markEpAnn an AnnDcolon-      markAnnotated t-  exact (HsStarTy _an isUnicode)-    = if isUnicode-        then printStringAdvance "\x2605" -- Unicode star-        else printStringAdvance "*"-  exact (HsKindSig an ty k) = do-    markAnnotated ty-    markEpAnn an AnnDcolon-    markAnnotated k-  exact (HsSpliceTy _ splice) = do-    markAnnotated splice-  -- exact x@(HsDocTy an _ _)          = withPpr x-  exact (HsBangTy an (HsSrcBang mt _up str) ty) = do-    case mt of-      NoSourceText -> return ()-      SourceText src -> do-        debugM $ "HsBangTy: src=" ++ showAst src-        markLocatedAALS an id AnnOpen  (Just src)-        markLocatedAALS an id AnnClose (Just "#-}")-        debugM $ "HsBangTy: done unpackedness"-    case str of-      SrcLazy     -> markEpAnn an AnnTilde-      SrcStrict   -> markEpAnn an AnnBang-      NoSrcStrict -> return ()-    markAnnotated ty-  -- exact x@(HsRecTy an _)            = withPpr x-  exact (HsExplicitListTy an prom tys) = do-    when (isPromoted prom) $ markEpAnn an AnnSimpleQuote-    markEpAnn an AnnOpenS-    markAnnotated tys-    markEpAnn an AnnCloseS-  exact (HsExplicitTupleTy an tys) = do-    markEpAnn an AnnSimpleQuote-    markEpAnn an AnnOpenP-    markAnnotated tys-    markEpAnn an AnnCloseP-  exact (HsTyLit _ 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)-  exact (HsWildCardTy _) = printStringAdvance "_"-  exact x = error $ "missing match for HsType:" ++ showAst x---- -----------------------------------------------------------------------instance ExactPrint (HsForAllTelescope GhcPs) where-  getAnnotationEntry (HsForAllVis an _)   = fromAnn an-  getAnnotationEntry (HsForAllInvis an _) = fromAnn an--  exact (HsForAllVis an bndrs)   = do-    markLocatedAA an fst -- AnnForall-    markAnnotated bndrs-    markLocatedAA an snd -- AnnRarrow--  exact (HsForAllInvis an bndrs) = do-    markLocatedAA an fst -- AnnForall-    markAnnotated bndrs-    markLocatedAA an snd -- AnnDot---- -----------------------------------------------------------------------instance ExactPrint (HsDerivingClause GhcPs) where-  getAnnotationEntry d@(HsDerivingClause{}) = fromAnn (deriv_clause_ext d)--  exact (HsDerivingClause { deriv_clause_ext      = an-                          , deriv_clause_strategy = dcs-                          , deriv_clause_tys      = dct }) = do-    markEpAnn an AnnDeriving-    exact_strat_before-    markAnnotated dct-    exact_strat_after-      where-        -- -- This complexity is to distinguish between-        -- --    deriving Show-        -- --    deriving (Show)-        -- pp_dct [HsIB { hsib_body = ty }]-        --          = ppr (parenthesizeHsType appPrec ty)-        -- pp_dct _ = parens (interpp'SP dct)--        -- @via@ is unique in that in comes /after/ the class being derived,-        -- so we must special-case it.-        (exact_strat_before, exact_strat_after) =-          case dcs of-            Just v@(L _ ViaStrategy{}) -> (pure (), markAnnotated v)-            _                          -> (mapM_ markAnnotated dcs, pure ())---- -----------------------------------------------------------------------instance ExactPrint (DerivStrategy GhcPs) where-  getAnnotationEntry (StockStrategy an)    = fromAnn an-  getAnnotationEntry (AnyclassStrategy an) = fromAnn an-  getAnnotationEntry (NewtypeStrategy an)  = fromAnn an-  getAnnotationEntry (ViaStrategy (XViaStrategyPs an  _)) = fromAnn an--  exact (StockStrategy an)    = markEpAnn an AnnStock-  exact (AnyclassStrategy an) = markEpAnn an AnnAnyclass-  exact (NewtypeStrategy an)  = markEpAnn an AnnNewtype-  exact (ViaStrategy (XViaStrategyPs an ty))-    = markEpAnn an AnnVia >> markAnnotated ty---- -----------------------------------------------------------------------instance (ExactPrint a) => ExactPrint (LocatedC a) where-  getAnnotationEntry (L sann _) = fromAnn sann--  exact (L (SrcSpanAnn EpAnnNotUsed _) a) = markAnnotated a-  exact (L (SrcSpanAnn (EpAnn _ (AnnContext ma opens closes) _) _) a) = do-    mapM_ (markKwA AnnOpenP) (sort opens)-    markAnnotated a-    mapM_ (markKwA AnnCloseP) (sort closes)-    case ma of-      Just (UnicodeSyntax, r) -> markKwA AnnDarrowU r-      Just (NormalSyntax,  r) -> markKwA AnnDarrow  r-      Nothing -> pure ()---- -----------------------------------------------------------------------instance ExactPrint (DerivClauseTys GhcPs) where-  getAnnotationEntry = const NoEntryVal--  exact (DctSingle _ ty) = markAnnotated ty-  exact (DctMulti _ tys) = do-    markAnnotated tys---- -----------------------------------------------------------------------instance ExactPrint (HsSigType GhcPs) where-  getAnnotationEntry = const NoEntryVal--  exact (HsSig _ bndrs ty) = do-    markAnnotated bndrs-    markAnnotated ty---- -----------------------------------------------------------------------instance ExactPrint (LocatedN RdrName) where-  getAnnotationEntry (L sann _) = fromAnn sann--  exact (L (SrcSpanAnn EpAnnNotUsed l) n) = do-    p <- getPosP-    debugM $ "LocatedN RdrName:NOANN: (p,l,str)=" ++ show (p,ss2range l, showPprUnsafe n)-    let str = case (showPprUnsafe n) of-              -- TODO: unicode support?-                "forall" -> if spanLength (realSrcSpan l) == 1 then "∀" else "forall"-                s -> s-    printStringAtSs l str-  exact (L (SrcSpanAnn (EpAnn _anchor ann _cs) _ll) n) = do-    case ann of-      NameAnn a o l c t -> do-        markName a o (Just (l,n)) c-        markTrailing t-      NameAnnCommas a o cs c t -> do-        let (kwo,kwc) = adornments a-        markKw (AddEpAnn kwo o)-        forM_ cs (\loc -> markKw (AddEpAnn AnnComma loc))-        markKw (AddEpAnn kwc c)-        markTrailing t-      NameAnnOnly a o c t -> do-        markName a o Nothing c-        markTrailing t-      NameAnnRArrow nl t -> do-        markKw (AddEpAnn AnnRarrow nl)-        markTrailing t-      NameAnnQuote q name t -> do-        debugM $ "NameAnnQuote"-        markKw (AddEpAnn AnnSimpleQuote q)-        markAnnotated (L name n)-        markTrailing t-      NameAnnTrailing t -> do-        printStringAdvance (showPprUnsafe n)-        markTrailing t--markName :: NameAdornment-         -> EpaLocation -> Maybe (EpaLocation,RdrName) -> EpaLocation -> EPP ()-markName adorn open mname close = do-  let (kwo,kwc) = adornments adorn-  markKw (AddEpAnn kwo open)-  case mname of-    Nothing -> return ()-    Just (name, a) -> printStringAtAA name (showPprUnsafe a)-  markKw (AddEpAnn kwc close)--adornments :: NameAdornment -> (AnnKeywordId, AnnKeywordId)-adornments NameParens     = (AnnOpenP, AnnCloseP)-adornments NameParensHash = (AnnOpenPH, AnnClosePH)-adornments NameBackquotes = (AnnBackquote, AnnBackquote)-adornments NameSquare     = (AnnOpenS, AnnCloseS)--markTrailing :: [TrailingAnn] -> EPP ()-markTrailing ts = do-  p <- getPosP-  debugM $ "markTrailing:" ++ showPprUnsafe (p,ts)-  mapM_ markKwT (sort ts)---- ------------------------------------------------------------------------- based on pp_condecls in Decls.hs-exact_condecls :: EpAnn [AddEpAnn] -> [LConDecl GhcPs] -> EPP ()-exact_condecls an cs-  | gadt_syntax                  -- In GADT syntax-  = do-      mapM_ markAnnotated cs-  | otherwise                    -- In H98 syntax-  = do-      markEpAnn an AnnEqual-      mapM_ markAnnotated cs-  where-    gadt_syntax = case cs of-      []                      -> False-      (L _ ConDeclH98{}  : _) -> False-      (L _ ConDeclGADT{} : _) -> True---- -----------------------------------------------------------------------instance ExactPrint (ConDecl GhcPs) where-  getAnnotationEntry x@(ConDeclGADT{}) = fromAnn (con_g_ext x)-  getAnnotationEntry x@(ConDeclH98{})  = fromAnn (con_ext x)---- 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-    mapM_ markAnnotated doc-    when has_forall $ markEpAnn an AnnForall-    mapM_ markAnnotated ex_tvs-    when has_forall $ markEpAnn an AnnDot-    mapM_ markAnnotated mcxt-    when (isJust mcxt) $ markEpAnn an AnnDarrow--    exact_details args--    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-        markAnnotated t1-        markAnnotated con-        markAnnotated t2-      exact_details (PrefixCon tyargs tys) = do-        markAnnotated con-        markAnnotated tyargs-        markAnnotated tys-      exact_details (RecCon fields) = do-        markAnnotated con-        markAnnotated fields--  -- -------------------------------------  exact (ConDeclGADT { con_g_ext = an-                     , con_names = cons-                     , con_bndrs = bndrs-                     , con_mb_cxt = mcxt, con_g_args = args-                     , con_res_ty = res_ty, con_doc = doc }) = do-    mapM_ markAnnotated doc-    mapM_ markAnnotated cons-    markEpAnn an AnnDcolon-    annotationsToComments (epAnnAnns an)  [AnnOpenP, AnnCloseP]-    markAnnotated bndrs-    mapM_ markAnnotated mcxt-    when (isJust mcxt) $ markEpAnn an AnnDarrow-    case args of-        (PrefixConGADT args') -> mapM_ markScaled args'-        (RecConGADT fields)   -> markAnnotated fields-    markAnnotated res_ty---- -----------------------------------------------------------------------instance ExactPrint Void where-  getAnnotationEntry = const NoEntryVal-  exact _ = return ()---- -----------------------------------------------------------------------instance ExactPrintTVFlag flag => ExactPrint (HsOuterTyVarBndrs flag GhcPs) where-  getAnnotationEntry (HsOuterImplicit _) = NoEntryVal-  getAnnotationEntry (HsOuterExplicit an _) = fromAnn an--  exact (HsOuterImplicit _) = pure ()-  exact (HsOuterExplicit an bndrs) = do-    markLocatedAA an fst -- "forall"-    markAnnotated bndrs-    markLocatedAA an snd -- "."---- -----------------------------------------------------------------------instance ExactPrint (ConDeclField GhcPs) where-  getAnnotationEntry f@(ConDeclField{}) = fromAnn (cd_fld_ext f)--  exact (ConDeclField an names ftype mdoc) = do-    markAnnotated names-    markEpAnn an AnnDcolon-    markAnnotated ftype-    mapM_ markAnnotated mdoc---- -----------------------------------------------------------------------instance ExactPrint (FieldOcc GhcPs) where-  getAnnotationEntry = const NoEntryVal-  exact (FieldOcc _ n) = markAnnotated n---- -----------------------------------------------------------------------instance ExactPrint (AmbiguousFieldOcc GhcPs) where-  getAnnotationEntry = const NoEntryVal-  exact (Unambiguous _ n) = markAnnotated n-  exact (Ambiguous   _ n) = markAnnotated n---- -----------------------------------------------------------------------markScaled :: (HsScaled GhcPs (LBangType GhcPs)) -> Annotated ()-markScaled (HsScaled arr (L l c)) =-  markAnnotated ((L l (HsScaled arr (L (noAnnSrcSpan $ locA l) c)))-                 :: LocatedA (HsScaled GhcPs (LBangType GhcPs)))--instance (ExactPrint a) => ExactPrint (HsScaled GhcPs a) where-  getAnnotationEntry = const NoEntryVal-  exact (HsScaled arr t) = do-    markAnnotated t-    markArrow EpAnnNotUsed arr---- -----------------------------------------------------------------------instance ExactPrint (LocatedP CType) where-  getAnnotationEntry = entryFromLocatedA--  exact (L (SrcSpanAnn EpAnnNotUsed _) ct) = withPpr ct-  exact (L (SrcSpanAnn an _ll)-         (CType stp mh (stct,ct))) = do-    markAnnOpenP an stp "{-# CTYPE"-    case mh of-      Nothing -> return ()-      Just (Header srcH _h) ->-         markLocatedAALS an apr_rest AnnHeader (Just (toSourceTextWithSuffix srcH "" ""))-    markLocatedAALS an apr_rest AnnVal (Just (toSourceTextWithSuffix stct (unpackFS ct) ""))-    markAnnCloseP an---- -----------------------------------------------------------------------instance ExactPrint (SourceText, RuleName) where-  -- We end up at the right place from the Located wrapper-  getAnnotationEntry = const NoEntryVal--  exact (st, rn)-    = printStringAdvance (toSourceTextWithSuffix st (unpackFS 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--  exact (L (SrcSpanAnn ann _) ies) = do-    debugM $ "LocatedL [LIE"-    markLocatedAAL ann al_rest AnnHiding-    p <- getPosP-    debugM $ "LocatedL [LIE:p=" ++ showPprUnsafe p-    markAnnList True ann (markAnnotated ies)--instance (ExactPrint (Match GhcPs (LocatedA body)))-   => ExactPrint (LocatedL [LocatedA (Match GhcPs (LocatedA body))]) where-  getAnnotationEntry = entryFromLocatedA-  exact (L la a) = do-    debugM $ "LocatedL [LMatch"-    -- TODO: markAnnList?-    markEpAnnAll (ann la) al_rest AnnWhere-    markLocatedMAA (ann la) al_open-    markEpAnnAll (ann la) al_rest AnnSemi-    markAnnotated a-    markLocatedMAA (ann la) al_close---- instance ExactPrint (LocatedL [ExprLStmt GhcPs]) where-instance ExactPrint (LocatedL [LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs)))]) where-  getAnnotationEntry = entryFromLocatedAFixed-  exact (L (SrcSpanAnn an' _) stmts) = do-    let an = fixAnnListAnn an'-    debugM $ "LocatedL [ExprLStmt"-    markAnnList True an $ do-      -- markLocatedMAA an al_open-      case snocView stmts of-        Just (initStmts, ls@(L _ (LastStmt _ _body _ _))) -> do-          debugM $ "LocatedL [ExprLStmt: snocView"-          markAnnotated ls-          markAnnotated initStmts-        _ -> markAnnotated stmts-        -- x -> error $ "pprDo:ListComp" ++ showAst x-      -- markLocatedMAA an al_close---- instance ExactPrint (LocatedL [CmdLStmt GhcPs]) where-instance ExactPrint (LocatedL [LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsCmd GhcPs)))]) where-  getAnnotationEntry = entryFromLocatedAFixed-  exact (L (SrcSpanAnn ann' _) es) = do-    let ann = fixAnnListAnn ann'-    debugM $ "LocatedL [CmdLStmt"-    markLocatedMAA ann al_open-    mapM_ markAnnotated es-    markLocatedMAA ann al_close--instance ExactPrint (LocatedL [LocatedA (ConDeclField GhcPs)]) where-  getAnnotationEntry = entryFromLocatedA-  exact (L (SrcSpanAnn an _) fs) = do-    debugM $ "LocatedL [LConDeclField"-    markAnnList True an (mapM_ markAnnotated fs) -- AZ:TODO get rid of mapM_--instance ExactPrint (LocatedL (BF.BooleanFormula (LocatedN RdrName))) where-  getAnnotationEntry = entryFromLocatedA-  exact (L (SrcSpanAnn an _) bf) = do-    debugM $ "LocatedL [LBooleanFormula"-    markAnnList True an (markAnnotated bf)---- ------------------------------------------------------------------------ LocatedL instances end ----- =====================================================================--instance ExactPrint (IE GhcPs) where-  getAnnotationEntry (IEVar _ _)            = NoEntryVal-  getAnnotationEntry (IEThingAbs an _)      = fromAnn an-  getAnnotationEntry (IEThingAll an _)      = fromAnn an-  getAnnotationEntry (IEThingWith an _ _ _) = fromAnn an-  getAnnotationEntry (IEModuleContents an _)= fromAnn an-  getAnnotationEntry (IEGroup _ _ _)        = NoEntryVal-  getAnnotationEntry (IEDoc _ _)            = NoEntryVal-  getAnnotationEntry (IEDocNamed _ _)       = NoEntryVal--  exact (IEVar _ ln) = markAnnotated ln-  exact (IEThingAbs _ thing) = markAnnotated thing-  exact (IEThingAll an thing) = do-    markAnnotated thing-    markEpAnn an AnnOpenP-    markEpAnn an AnnDotdot-    markEpAnn an AnnCloseP--  exact (IEThingWith an thing wc withs) = do-    markAnnotated thing-    markEpAnn an AnnOpenP-    case wc of-      NoIEWildcard -> markAnnotated withs-      IEWildcard pos -> do-        let (bs, as) = splitAt pos withs-        markAnnotated bs-        markEpAnn an AnnDotdot-        markEpAnn an AnnComma-        markAnnotated as-    markEpAnn an AnnCloseP--  exact (IEModuleContents an (L lm mn)) = do-    markEpAnn an AnnModule-    printStringAtSs lm (moduleNameString mn)--  -- exact (IEGroup _ _ _)          = NoEntryVal-  -- exact (IEDoc _ _)              = NoEntryVal-  -- exact (IEDocNamed _ _)         = NoEntryVal-  exact x = error $ "missing match for IE:" ++ showAst x---- -----------------------------------------------------------------------instance ExactPrint (IEWrappedName RdrName) where-  getAnnotationEntry = const NoEntryVal--  exact (IEName n) = markAnnotated n-  exact (IEPattern r n) = do-    printStringAtAA r "pattern"-    markAnnotated n-  exact (IEType r n) = do-    printStringAtAA r "type"-    markAnnotated n---- -----------------------------------------------------------------------instance ExactPrint (Pat GhcPs) where-  getAnnotationEntry (WildPat _)              = NoEntryVal-  getAnnotationEntry (VarPat _ _)             = NoEntryVal-  getAnnotationEntry (LazyPat an _)           = fromAnn an-  getAnnotationEntry (AsPat an _ _)           = fromAnn an-  getAnnotationEntry (ParPat an _)            = fromAnn an-  getAnnotationEntry (BangPat an _)           = fromAnn an-  getAnnotationEntry (ListPat an _)           = fromAnn an-  getAnnotationEntry (TuplePat an _ _)        = fromAnn an-  getAnnotationEntry (SumPat an _ _ _)        = fromAnn an-  getAnnotationEntry (ConPat an _ _)          = fromAnn an-  getAnnotationEntry (ViewPat an _ _)         = fromAnn an-  getAnnotationEntry (SplicePat _ _)          = NoEntryVal-  getAnnotationEntry (LitPat _ _)             = NoEntryVal-  getAnnotationEntry (NPat an _ _ _)          = fromAnn an-  getAnnotationEntry (NPlusKPat an _ _ _ _ _) = fromAnn an-  getAnnotationEntry (SigPat an _ _)          = fromAnn an--  exact (WildPat _) = do-    anchor <- getAnchorU-    debugM $ "WildPat:anchor=" ++ show anchor-    printStringAtRs anchor "_"-  exact (VarPat _ n) = do-        -- The parser inserts a placeholder value for a record pun rhs. This must be-        -- filtered.-        let pun_RDR = "pun-right-hand-side"-        when (showPprUnsafe n /= pun_RDR) $ markAnnotated n-  exact (LazyPat an pat) = do-    markEpAnn an AnnTilde-    markAnnotated pat-  exact (AsPat an n pat) = do-    markAnnotated n-    markEpAnn an AnnAt-    markAnnotated pat-  exact (ParPat an pat) = do-    markAnnKw an ap_open AnnOpenP-    markAnnotated pat-    markAnnKw an ap_close AnnCloseP--  exact (BangPat an pat) = do-    markEpAnn an AnnBang-    markAnnotated pat--  exact (ListPat an pats) = markAnnList True an (markAnnotated pats)--  exact (TuplePat an pats boxity) = do-    case boxity of-      Boxed   -> markEpAnn an AnnOpenP-      Unboxed -> markEpAnn an AnnOpenPH-    markAnnotated pats-    case boxity of-      Boxed   -> markEpAnn an AnnCloseP-      Unboxed -> markEpAnn an AnnClosePH--  exact (SumPat an pat _alt _arity) = do-    markLocatedAAL an sumPatParens AnnOpenPH-    markAnnKwAll an sumPatVbarsBefore AnnVbar-    markAnnotated pat-    markAnnKwAll an sumPatVbarsAfter AnnVbar-    markLocatedAAL an sumPatParens AnnClosePH--  -- | ConPat an con args)-  exact (ConPat an con details) = exactUserCon an con details-  exact (ViewPat an expr pat) = do-    markAnnotated expr-    markEpAnn an AnnRarrow-    markAnnotated pat-  exact (SplicePat _ splice) = markAnnotated splice-  exact (LitPat _ lit) = printStringAdvance (hsLit2String lit)-  exact (NPat an ol mn _) = do-    when (isJust mn) $ markEpAnn an AnnMinus-    markAnnotated ol--  -- | NPlusKPat an n lit1 lit2 _ _)-  exact (NPlusKPat an n k lit2 _ _) = do-    markAnnotated n-    -- We need a fix for-    -- https://gitlab.haskell.org/ghc/ghc/-/issues/20243 to complete-    -- this-    markAnnotated k--  exact (SigPat an pat sig) = do-    markAnnotated pat-    markEpAnn an AnnDcolon-    markAnnotated sig-  -- exact x = error $ "missing match for Pat:" ++ showAst x---- -----------------------------------------------------------------------instance ExactPrint (HsPatSigType GhcPs) where-  getAnnotationEntry = const NoEntryVal--  exact (HsPS an ty) = do-    markAnnKw an id AnnAt-    markAnnotated ty---- -----------------------------------------------------------------------instance ExactPrint (HsOverLit GhcPs) where-  getAnnotationEntry = const NoEntryVal--  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 s-        NoSourceText -> return ()---- -----------------------------------------------------------------------hsLit2String :: HsLit GhcPs -> String-hsLit2String lit =-  case lit of-    HsChar       src v   -> toSourceTextWithSuffix src v ""-    -- It should be included here-    -- https://github.com/ghc/ghc/blob/master/compiler/parser/Lexer.x#L1471-    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 ""-    HsInt64Prim  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 "##"-    -- (XLit x) -> error $ "got XLit for:" ++ showPprUnsafe x--toSourceTextWithSuffix :: (Show a) => SourceText -> a -> String -> String-toSourceTextWithSuffix (NoSourceText)    alt suffix = show alt ++ suffix-toSourceTextWithSuffix (SourceText txt) _alt suffix = txt ++ suffix--sourceTextToString :: SourceText -> String -> String-sourceTextToString NoSourceText alt   = alt-sourceTextToString (SourceText txt) _ = txt---- -----------------------------------------------------------------------exactUserCon :: (ExactPrint con) => EpAnn [AddEpAnn] -> con -> HsConPatDetails GhcPs -> EPP ()-exactUserCon _  c (InfixCon p1 p2) = markAnnotated p1 >> markAnnotated c >> markAnnotated p2-exactUserCon an c details          = do-  markAnnotated c-  markEpAnn an AnnOpenC-  exactConArgs details-  markEpAnn an AnnCloseC---exactConArgs ::HsConPatDetails GhcPs -> EPP ()-exactConArgs (PrefixCon tyargs pats) = markAnnotated tyargs >> markAnnotated pats-exactConArgs (InfixCon p1 p2) = markAnnotated p1 >> markAnnotated p2-exactConArgs (RecCon rpats)   = markAnnotated rpats---- -----------------------------------------------------------------------entryFromLocatedA :: LocatedAn ann a -> Entry-entryFromLocatedA (L la _) = fromAnn la---- See https://gitlab.haskell.org/ghc/ghc/-/issues/20256-entryFromLocatedAFixed :: LocatedL a -> Entry-entryFromLocatedAFixed (L la _)-  = fromAnn (fixSrcAnnL 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-        `debug` ("printStringAtLsDelta:(pos,s):" ++ show (undelta p cl colOffset,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--printQueuedComment :: (Monad m, Monoid w) => RealSrcSpan -> Comment -> DeltaPos -> EP w m ()-printQueuedComment loc Comment{commentContents} dp = do-  p <- getPosP-  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-    setPriorEndASTD False loc-  p' <- getPosP-  debugM $ "printQueuedComment: (p,p',dp,colOffset,undelta)=" ++ show (p,p',dp,colOffset,undelta p dp colOffset)----------------------------------------------------------------------------setLayoutBoth :: (Monad m, Monoid w) => EP w m () -> EP w m ()-setLayoutBoth k = do-  oldLHS <- gets dLHS-  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 () -> EP w m ()-setLayoutTopLevelP k = do-  debugM $ "setLayoutTopLevelP entered"-  oldAnchorOffset <- getLayoutOffsetP-  modify (\a -> a { pMarkLayout = False-                  , pLHS = 0} )-  k-  debugM $ "setLayoutTopLevelP:resetting"-  setLayoutOffsetP oldAnchorOffset----------------------------------------------------------------------------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})--getPriorEndD :: (Monad m, Monoid w) => EP w m Pos-getPriorEndD = gets dPriorEndPosition--getAnchorU :: (Monad m, Monoid w) => EP w m RealSrcSpan-getAnchorU = gets uAnchorSpan--setPriorEndD :: (Monad m, Monoid w) => Pos -> EP w m ()-setPriorEndD pe = do-  -- setLayoutStartIfNeededD (snd pe)-  setPriorEndNoLayoutD pe--setPriorEndNoLayoutD :: (Monad m, Monoid w) => Pos -> EP w m ()-setPriorEndNoLayoutD pe = do-  debugM $ "setPriorEndNoLayout:pe=" ++ show pe-  modify (\s -> s { dPriorEndPosition = pe })--setPriorEndASTD :: (Monad m, Monoid w) => Bool -> RealSrcSpan -> EP w m ()-setPriorEndASTD layout pe = setPriorEndASTPD layout (rs2range pe)--setPriorEndASTPD :: (Monad m, Monoid w) => Bool -> (Pos,Pos) -> EP w m ()-setPriorEndASTPD layout pe@(fm,to) = do-  debugM $ "setPriorEndASTD:pe=" ++ show pe-  when layout $ setLayoutStartD (snd fm)-  modify (\s -> s { dPriorEndPosition = to } )--setLayoutStartD :: (Monad m, Monoid w) => Int -> EP w m ()-setLayoutStartD p = do-  EPState{dMarkLayout} <- get-  when dMarkLayout $ do-    debugM $ "setLayoutStartD: setting dLHS=" ++ show p-    modify (\s -> s { dMarkLayout = False-                    , dLHS = LayoutStartCol p})--setAnchorU :: (Monad m, Monoid w) => RealSrcSpan -> EP w m ()-setAnchorU rss = do-  debugM $ "setAnchorU:" ++ show (rs2range rss)-  modify (\s -> s { uAnchorSpan = rss })--getUnallocatedComments :: (Monad m, Monoid w) => EP w m [Comment]-getUnallocatedComments = gets epComments--putUnallocatedComments :: (Monad m, Monoid w) => [Comment] -> EP w m ()-putUnallocatedComments cs = modify (\s -> s { epComments = cs } )--getLayoutOffsetP :: (Monad m, Monoid w) => EP w m LayoutStartCol-getLayoutOffsetP = gets pLHS--setLayoutOffsetP :: (Monad m, Monoid w) => LayoutStartCol -> EP w m ()-setLayoutOffsetP c = do-  debugM $ "setLayoutOffsetP:" ++ show c-  modify (\s -> s { pLHS = c })----- -----------------------------------------------------------------------advance :: (Monad m, Monoid w) => DeltaPos -> EP w m ()-advance dp = do-  p <- getPosP-  colOffset <- getLayoutOffsetP-  debugM $ "advance:(p,dp,colOffset,ws)=" ++ show (p,dp,colOffset,undelta p dp colOffset)-  printWhitespace (undelta p dp colOffset)---- -----------------------------------------------------------------------adjustDeltaForOffsetM :: DeltaPos -> EPP DeltaPos-adjustDeltaForOffsetM dp = do-  colOffset <- gets dLHS-  return (adjustDeltaForOffset 0 colOffset dp)---- ------------------------------------------------------------------------ Printing functions--printString :: (Monad m, Monoid w) => Bool -> String -> EP w m ()-printString layout str = do-  EPState{epPos = (_,c), pMarkLayout} <- get-  PrintOptions{epTokenPrint, epWhitespacePrint} <- ask-  when (pMarkLayout && layout) $ do-    debugM $ "printString: setting pLHS to " ++ show c-    modify (\s -> s { pLHS = LayoutStartCol c, pMarkLayout = False } )--  -- Advance position, taking care of any newlines in the string-  let strDP = dpFromString str-      cr = getDeltaLine strDP-  p <- getPosP-  colOffset <- getLayoutOffsetP-  -- debugM $ "printString:(p,colOffset,strDP,cr)="  ++ show (p,colOffset,strDP,cr)-  if cr == 0-    then setPosP (undelta p strDP colOffset)-    else setPosP (undelta p strDP 1)--  -- Debug stuff-  -- pp <- getPosP-  -- debugM $ "printString: (p,pp,str)" ++ show (p,pp,str)-  -- Debug end--  ---  if not layout && c == 0-    then lift (epWhitespacePrint str) >>= \s -> tell EPWriter { output = s}-    else lift (epTokenPrint      str) >>= \s -> tell EPWriter { output = s}------------------------------------------------------------printStringAdvance :: String -> EPP ()-printStringAdvance str = do-  ss <- getAnchorU-  printStringAtKw' ss str------------------------------------------------------------newLine :: (Monad m, Monoid w) => EP w m ()-newLine = do-    (l,_) <- getPosP-    printString False "\n"-    setPosP (l+1,1)+  , exactPrintWithOptions+  , makeDeltaAst++  -- * Configuration+  , EPOptions(epRigidity, epAstPrint, epTokenPrint, epWhitespacePrint, epUpdateAnchors)+  , 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.Types.Basic hiding (EP)+import GHC.Types.Fixity+import GHC.Types.ForeignCall+import GHC.Types.SourceText+import GHC.Types.Var+import GHC.Utils.Outputable hiding ( (<>) )+import GHC.Unit.Module.Warnings+import GHC.Utils.Misc+import GHC.Utils.Panic++import Control.Monad.Identity+import qualified Control.Monad.Reader as Reader+import Control.Monad.RWS+import Data.Data ( Data )+import Data.Dynamic+import Data.Foldable+import Data.Functor.Const+import qualified Data.Set.Ordered as OSet+import qualified Data.Set as Set+import Data.Typeable+import Data.List ( partition, sortBy)+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++-- import Debug.Trace++-- ---------------------------------------------------------------------++exactPrint :: ExactPrint ast => ast -> String+exactPrint ast = snd $ runIdentity (runEP stringOptions (markAnnotated ast))++-- | The additional option to specify the rigidity and printing+-- configuration.+exactPrintWithOptions :: (ExactPrint ast, Monoid b, Monad m)+                      => EPOptions m b+                      -> ast+                      -> m (ast, b)+exactPrintWithOptions r ast =+    runEP r (markAnnotated ast)++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+             , epComments = []+             , epCommentsApplied = []+             }+++-- ---------------------------------------------------------------------+-- 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+            {+              epAstPrint :: forall ast . Data ast => GHC.Located ast -> a -> m a+            , epTokenPrint :: String -> m a+            , epWhitespacePrint :: String -> m a+            , epRigidity :: Rigidity+            , epUpdateAnchors :: Bool+            }++-- | Helper to create a 'EPOptions'+epOptions ::+      (forall ast . Data ast => GHC.Located ast -> a -> m a)+      -> (String -> m a)+      -> (String -> m a)+      -> Rigidity+      -> Bool+      -> EPOptions m a+epOptions astPrint tokenPrint wsPrint rigidity delta = EPOptions+             {+               epAstPrint = astPrint+             , epWhitespacePrint = wsPrint+             , epTokenPrint = tokenPrint+             , epRigidity = rigidity+             , epUpdateAnchors = delta+             }++-- | Options which can be used to print as a normal String.+stringOptions :: EPOptions Identity String+stringOptions = epOptions (\_ b -> return b) return return NormalLayout False++-- | 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 ()) (\_ -> return ()) NormalLayout True++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++             -- 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]]+             }++-- ---------------------------------------------------------------------++-- AZ:TODO: this can just be a function :: (EpAnn a) -> Entry+class HasEntry ast where+  fromAnn :: ast -> Entry++-- ---------------------------------------------------------------------++-- type Annotated = FreeT AnnotationF Identity+-- type Annotated a = EP w m a++-- ---------------------------------------------------------------------++-- | 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 Entry = Entry Anchor EpAnnComments FlushComments CanUpdateAnchor+           | NoEntryVal++-- | For flagging whether to capture comments in an EpaDelta or not+data CaptureComments = CaptureComments+                     | NoCaptureComments++mkEntry :: Anchor -> EpAnnComments -> Entry+mkEntry anc cs = Entry anc cs NoFlushComments CanUpdateAnchor++instance HasEntry (SrcSpanAnn' (EpAnn an)) where+  fromAnn (SrcSpanAnn EpAnnNotUsed ss) = mkEntry (spanAsAnchor ss) emptyComments+  fromAnn (SrcSpanAnn an _) = fromAnn an++instance HasEntry (EpAnn a) where+  fromAnn (EpAnn anchor _ cs) = mkEntry anchor cs+  fromAnn EpAnnNotUsed = NoEntryVal++-- ---------------------------------------------------------------------++fromAnn' :: (HasEntry a) => a -> Entry+fromAnn' an = case fromAnn an of+  NoEntryVal -> NoEntryVal+  Entry a c _ u -> Entry a 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 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' cs flush canUpdateAnchor) a = do+  p <- getPosP+  debugM $ "enterAnn:starting:(p,a) =" ++ show (p, astId a)+  -- debugM $ "enterAnn:(cs) =" ++ showGhc (cs)+  let curAnchor = anchor anchor' -- As a base for the current AST element+  debugM $ "enterAnn:(curAnchor):=" ++ show (rs2range curAnchor)+  case canUpdateAnchor of+    CanUpdateAnchor -> pushAppliedComments+    _ -> return ()+  addCommentsA (priorComments cs)+  debugM $ "enterAnn:Added comments"+  printComments curAnchor+  priorCs <- cua canUpdateAnchor takeAppliedComments -- no pop+  -- -------------------------+  case anchor_op anchor' of+    MovedAnchor dp -> do+      debugM $ "enterAnn: MovedAnchor:" ++ show dp+      -- Set the original anchor as prior end, so the rest of this AST+      -- fragment has a reference+      setPriorEndNoLayoutD (ss2pos curAnchor)+    _ -> do+      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_op anchor' of+        MovedAnchor dp -> dp+        _ -> edp'+  -- ---------------------------------------------+  -- let edp = edp''+  med <- getExtraDP+  setExtraDP Nothing+  let edp = case med of+        Nothing -> edp''+        Just (Anchor _ (MovedAnchor dp)) -> dp+                   -- Replace original with desired one. Allows all+                   -- list entry values to be DP (1,0)+        Just (Anchor r _) -> dp+          where+            dp = adjustDeltaForOffset+                   off (ss2delta priorEndAfterComments r)+  when (isJust med) $ debugM $ "enterAnn:(med,edp)=" ++ show (med,edp)+  -- ---------------------------------------------+  -- Preparation complete, perform the action+  when (priorEndAfterComments < spanStart) (do+    debugM $ "enterAnn.dPriorEndPosition:spanStart=" ++ show spanStart+    modify (\s -> s { dPriorEndPosition    = spanStart } ))++  debugM $ "enterAnn: (anchor_op, curAnchor):" ++ show (anchor_op anchor', rs2range curAnchor)+  debugM $ "enterAnn: (dLHS,spanStart,pec,edp)=" ++ show (off,spanStart,priorEndAfterComments,edp)+  p <- getPosP+  d <- getPriorEndD+  debugM $ "enterAnn: (posp, posd)=" ++ show (p,d)++  -- end of delta phase processing+  -- -------------------------------------------------------------------+  -- start of print phase processing++  let mflush = when (flush == FlushComments) $ do+        debugM $ "flushing comments in enterAnn"+        flushComments (getFollowingComments cs)++  -- let+  --   st = annNone+  -- withOffset st (advance edp >> exact a >> mflush)+-- local :: (r -> r) -> RWST r w s m a -> RWST r w s m a+  advance edp+  a' <- exact a+  mflush++  -- end of sub-Anchor processing, start of tail end processing+  postCs <- cua canUpdateAnchor takeAppliedCommentsPop+  when (flush == NoFlushComments) $ do+    when ((getFollowingComments cs) /= []) $ do+      debugM $ "starting trailing comments:" ++ showAst (getFollowingComments cs)+      mapM_ printOneComment (map tokComment $ getFollowingComments cs)+      debugM $ "ending trailing comments"++  let newAchor = anchor' { anchor_op = MovedAnchor edp }+  let r = case canUpdateAnchor of+            CanUpdateAnchor -> setAnnotationAnchor a' newAchor (mkEpaComments (priorCs++ postCs) [])+            CanUpdateAnchorOnly -> setAnnotationAnchor a' newAchor emptyComments+            NoCanUpdateAnchor -> a'+  -- let r = (setAnnotationAnchor a' newAchor (mkEpaComments [] postCs))+  pure () -- monadic action to flush debugM+  -- debugM $ "calling setAnnotationAnchor:(curAnchor, newAchor,priorCs,postCs)=" ++ showAst (show (rs2range curAnchor), newAchor, priorCs, postCs)+  -- debugM $ "calling setAnnotationAnchor:(newAchor,postCs)=" ++ showAst (newAchor, postCs)+  debugM $ "enterAnn:done:(p,a) =" ++ show (p, astId a')+  return r++-- ---------------------------------------------------------------------++-- withComments :: (Monad m, Monoid w) => Annotation -> (EP w m a -> EP w m a)+-- withComments a =+--   local (\s -> s { epAnn = a, epContext = pushAcs (epContext s) })+++-- ---------------------------------------------------------------------++addCommentsA :: (Monad m, Monoid w) => [LEpaComment] -> EP w m ()+addCommentsA csNew = addComments (map 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) => [Comment] -> EP w m ()+addComments csNew = do+  -- debugM $ "addComments:" ++ show csNew+  cs <- getUnallocatedComments+  -- Make sure we merge duplicates while sorting, needed until+  -- https://gitlab.haskell.org/ghc/ghc/-/issues/20239 is resolved+  let ocs = OSet.fromList cs+  let ncs = OSet.fromList csNew+  putUnallocatedComments (OSet.toAscList (ocs OSet.<>| ncs))+++-- ---------------------------------------------------------------------++-- | 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 = do+  addCommentsA trailing+  cs <- getUnallocatedComments+  debugM $ "flushing comments starting"+  mapM_ printOneComment (sortComments cs)+  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)+  => EpAnn a -> Lens a [AddEpAnn] -> [AnnKeywordId] -> EP w m (EpAnn a)+annotationsToComments EpAnnNotUsed _ _kws = return EpAnnNotUsed+annotationsToComments (EpAnn anc a cs) l kws = do+  let (newComments, newAnns) = go ([],[]) (view l a)+  addComments newComments+  return (EpAnn anc (set l (reverse newAnns) a) cs)+  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 ss):cs', ans) ls+      | otherwise             = go (cs', (AddEpAnn k ss):ans)    ls+++-- -- |In order to interleave annotations into the stream, we turn them into+-- -- comments.+-- annotationsToComments' :: (Monad m, Monoid w) => [AddEpAnn] -> [AnnKeywordId] -> EP w m ()+-- annotationsToComments' ans kws = do+--   let+--     getSpans _ [] = []+--     getSpans k1 (AddEpAnn k2 ss:as)+--       | k1 == k2 = ss : getSpans k1 as+--       | otherwise = getSpans k1 as+--     doOne :: (Monad m, Monoid w) => AnnKeywordId -> EP w m [Comment]+--     doOne kw = do+--       let sps =getSpans kw ans+--       return $ map (mkKWComment kw ) sps+--     -- TODO:AZ make sure these are sorted/merged properly when the invariant for+--     -- allocateComments is re-established.+--   newComments <- mapM doOne kws+--   addComments (concat newComments)++-- annotationsToCommentsA :: (Monad m, Monoid w) => EpAnn [AddEpAnn] -> [AnnKeywordId] -> EP w m ()+-- annotationsToCommentsA EpAnnNotUsed _ = return ()+-- annotationsToCommentsA an kws = annotationsToComments' (anns an) kws++-- ---------------------------------------------------------------------++-- 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 -> 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 txt >> return ()++-- ---------------------------------------------------------------------++printStringAtSs :: (Monad m, Monoid w) => SrcSpan -> String -> EP w m ()+printStringAtSs ss str = printStringAtRs (realSrcSpan ss) str >> 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+  printComments pa+  pe <- getPriorEndD+  debugM $ "printStringAtRs:pe=" ++ show pe+  let p = ss2delta pe pa+  p' <- adjustDeltaForOffsetM p+  printStringAtLsDelta p' str+  setPriorEndASTD True pa+  cs' <- case capture of+    CaptureComments -> takeAppliedComments+    NoCaptureComments -> return []+  debugM $ "printStringAtRs:cs'=" ++ show cs'+  -- return (EpaDelta p' (map comment2LEpaComment (noKWComments 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 ()++-- ---------------------------------------------------------------------++-- AZ:TODO get rid of this+printStringAtMLoc :: (Monad m, Monoid w) => Maybe EpaLocation -> String -> EP w m ()+printStringAtMLoc (Just aa) s = printStringAtAA aa s >> return ()+printStringAtMLoc Nothing s = printStringAtLsDelta (SameLine 1) s >> 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 EpAnnNotUsed _ _ = return EpAnnNotUsed+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) []))++printStringAtAA :: (Monad m, Monoid w) => EpaLocation -> String -> EP w m EpaLocation+printStringAtAA el str = printStringAtAAC CaptureComments el str++printStringAtAAL :: (Monad m, Monoid w)+  => EpAnn a -> Lens a EpaLocation -> String -> EP w m (EpAnn a)+printStringAtAAL EpAnnNotUsed _ _ = return EpAnnNotUsed+printStringAtAAL (EpAnn anc an cs) l str = do+  r <- printStringAtAAC CaptureComments (view l an) str+  return (EpAnn anc (set l r an) cs)++printStringAtAAC :: (Monad m, Monoid w)+  => CaptureComments -> EpaLocation -> String -> EP w m EpaLocation+printStringAtAAC capture (EpaSpan r) s = printStringAtRsC capture r s+printStringAtAAC capture (EpaDelta d cs) s = do+  mapM_ (printOneComment . 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 True (p1,p2)+  setPriorEndASTPD True (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 (noKWComments cs')))+  return (EpaDelta d (map comment2LEpaComment cs'))+++-- ---------------------------------------------------------------------++markExternalSourceText :: (Monad m, Monoid w) => SrcSpan -> SourceText -> String -> EP w m ()+markExternalSourceText l NoSourceText txt   = printStringAtRs (realSrcSpan l) txt >> return ()+markExternalSourceText l (SourceText txt) _ = printStringAtRs (realSrcSpan l) txt >> return ()++-- ---------------------------------------------------------------------++-- -- TODO: remove in favour of markLensMAA+-- markLocatedMAA :: (Monad m, Monoid w) => EpAnn a -> (a -> Maybe AddEpAnn) -> EP w m ()+-- markLocatedMAA EpAnnNotUsed  _  = return ()+-- markLocatedMAA (EpAnn _ a _) f =+--   case f a of+--     Nothing -> return ()+--     Just aa -> markAddEpAnn aa >> return ()++markLensMAA :: (Monad m, Monoid w) => EpAnn a -> Lens a (Maybe AddEpAnn) -> EP w m (EpAnn a)+markLensMAA EpAnnNotUsed  _  = return EpAnnNotUsed+markLensMAA (EpAnn anc a cs) l =+  case view l a of+    Nothing -> return (EpAnn anc a cs)+    Just aa -> do+      aa' <- markAddEpAnn aa+      return (EpAnn anc (set l (Just aa') a) cs)++markLensAA :: (Monad m, Monoid w) => EpAnn a -> Lens a AddEpAnn -> EP w m (EpAnn a)+markLensAA EpAnnNotUsed  _  = return EpAnnNotUsed+markLensAA (EpAnn anc a cs) l = do+  a' <- markKw (view l a)+  return (EpAnn anc (set l a' a) cs)+++-- TODO: removein favour of markEpAnnL+markLocatedAAL :: (Monad m, Monoid w) => EpAnn a -> (a -> [AddEpAnn]) -> AnnKeywordId -> EP w m Int+markLocatedAAL EpAnnNotUsed  _ _ = return 1+markLocatedAAL (EpAnn _ a _) f kw = go (f a)+  where+    go [] = return 1+    go (aa@(AddEpAnn kw' _):as)+      | kw' == kw = mark [aa] kw+      | otherwise = go as+++markEpAnnLMS :: (Monad m, Monoid w)+  => EpAnn a -> Lens a [AddEpAnn] -> AnnKeywordId -> Maybe String -> EP w m (EpAnn a)+markEpAnnLMS an l kw Nothing = markEpAnnL an l kw+markEpAnnLMS EpAnnNotUsed  _ _ _ = return EpAnnNotUsed+markEpAnnLMS (EpAnn anc a cs) l kw (Just str) = do+  anns <- mapM go (view l a)+  return (EpAnn anc (set l anns a) cs)+  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 Nothing = markLensKwA an l+markEpAnnLMS' EpAnnNotUsed  _ _ _ = return EpAnnNotUsed+markEpAnnLMS' (EpAnn anc a cs) l kw (Just str) = do+  anns <- go (view l a)+  return (EpAnn anc (set l anns a) cs)+  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)++-- ---------------------------------------------------------------------++markArrow :: (Monad m, Monoid w)+  => EpAnn TrailingAnn -> HsArrow GhcPs -> EP w m (EpAnn TrailingAnn, HsArrow GhcPs)+markArrow an arr = do+  arr' <-+    case arr of+      HsUnrestrictedArrow _u ->+        return arr+      HsLinearArrow u ma -> do+        ma' <- mapM markAddEpAnn ma+        return (HsLinearArrow u ma')+      HsExplicitMult u ma t  -> do+        ma' <- mapM markAddEpAnn ma+        t' <- markAnnotated t+        return (HsExplicitMult u ma' t')++  an' <- case an of+           EpAnnNotUsed -> pure EpAnnNotUsed+           EpAnn anc a cs -> do+             a' <- markKwT a+             return (EpAnn anc a' cs)+  return (an', arr')++-- ---------------------------------------------------------------------++markAnnCloseP :: (Monad m, Monoid w) => EpAnn AnnPragma -> EP w m (EpAnn AnnPragma)+markAnnCloseP an = markEpAnnLMS' 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 txt)++markAnnOpen :: (Monad m, Monoid w) => EpAnn [AddEpAnn] -> SourceText -> String -> EP w m (EpAnn [AddEpAnn])+markAnnOpen an NoSourceText txt   = markEpAnnLMS an lidl AnnOpen (Just txt)+markAnnOpen an (SourceText txt) _ = markEpAnnLMS an lidl AnnOpen (Just 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 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 txt++-- ---------------------------------------------------------------------+{-+data AnnParen+  = AnnParen {+      ap_adornment :: ParenType,+      ap_open      :: EpaLocation,+      ap_close     :: EpaLocation+      } deriving (Data)+-}+markOpeningParen, markClosingParen :: (Monad m, Monoid w) => EpAnn AnnParen -> EP w m (EpAnn AnnParen)+markOpeningParen an = markParen an lfst+markClosingParen an = markParen an lsnd++markParen :: (Monad m, Monoid w) => EpAnn AnnParen -> (forall a. Lens (a,a) a) -> EP w m (EpAnn AnnParen)+markParen EpAnnNotUsed _ = return (EpAnnNotUsed)+markParen (EpAnn anc (AnnParen pt o c) cs) l = do+  loc' <- markKwA (view l $ kw pt) (view l (o, c))+  let (o',c') = set l loc' (o,c)+  return (EpAnn anc (AnnParen pt o' c') cs)+  where+    kw AnnParens       = (AnnOpenP,  AnnCloseP)+    kw AnnParensHash   = (AnnOpenPH, AnnClosePH)+    kw AnnParensSquare = (AnnOpenS, AnnCloseS)+-- markParen' :: (Monad m, Monoid w) => EpAnn AnnParen -> (forall a. (a,a) -> a) -> EP w m (EpAnn AnnParen)+-- markParen' EpAnnNotUsed _ = return (EpAnnNotUsed)+-- markParen' (EpAnn anc (AnnParen pt o c) cs) f = do+--   markKwA (f $ kw pt) (f (o, c))+--   return (EpAnn anc (AnnParen pt o c) cs)+--   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)+view l = Reader.asks (getConst . l Const)+{-# INLINE view #-}++over :: ASetter a b -> (b -> b) -> (a -> a)+-- over l f = runIdentity #. l (Identity #. f)+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++lalLet :: Lens AnnsLet EpaLocation+lalLet k annsLet = fmap (\newLoc -> annsLet { alLet = newLoc })+                        (k (alLet annsLet))++lalIn :: Lens AnnsLet EpaLocation+lalIn k annsLet = fmap (\newLoc -> annsLet { alIn = newLoc })+                       (k (alIn annsLet))+-- 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)+  => EpAnn a -> Lens a AddEpAnn -> EP w m (EpAnn a)+markLensKwA EpAnnNotUsed  _    = return EpAnnNotUsed+markLensKwA (EpAnn anc a cs) l = do+  loc <- markKw (view l a)+  return (EpAnn anc (set l loc a) cs)++markLensKw :: (Monad m, Monoid w)+  => EpAnn a -> Lens a EpaLocation -> AnnKeywordId -> EP w m (EpAnn a)+markLensKw EpAnnNotUsed  _ _  = return EpAnnNotUsed+markLensKw (EpAnn anc a cs) l kw = do+  loc <- markKwA kw (view l a)+  return (EpAnn anc (set l loc a) cs)++markAnnKwL :: (Monad m, Monoid w)+  => EpAnn a -> Lens a EpaLocation -> AnnKeywordId -> EP w m (EpAnn a)+markAnnKwL = markLensKw++markAnnKwAllL :: (Monad m, Monoid w)+  => EpAnn a -> Lens a [EpaLocation] -> AnnKeywordId -> EP w m (EpAnn a)+markAnnKwAllL EpAnnNotUsed  _ _  = return EpAnnNotUsed+-- markAnnKwAllL (EpAnn _ a _) f kw = mapM_ (markKwA kw) (sort (f a))+markAnnKwAllL (EpAnn anc a cs) l kw = do+  -- anns <- mapM (markKwA kw) (sort (view l a))+  anns <- mapM (markKwA kw) (view l a)+  return (EpAnn anc (set l anns a) cs)++markLensKwM :: (Monad m, Monoid w)+  => EpAnn a -> Lens a (Maybe EpaLocation) -> AnnKeywordId -> EP w m (EpAnn a)+markLensKwM EpAnnNotUsed  _ _ = return EpAnnNotUsed+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++-- ---------------------------------------------------------------------++markALocatedA :: (Monad m, Monoid w) => EpAnn AnnListItem -> EP w m (EpAnn AnnListItem)+markALocatedA EpAnnNotUsed  = return EpAnnNotUsed+markALocatedA (EpAnn anc a cs) = do+  t <- markTrailing (lann_trailing a)+  return (EpAnn anc (a { lann_trailing = t }) cs)++-- Deprecate in favour of markEpAnnL+markEpAnn :: (Monad m, Monoid w)+  => EpAnn [AddEpAnn] -> AnnKeywordId -> EP w m Int -- Return something to trigger not used warning+markEpAnn EpAnnNotUsed _ = return 1+markEpAnn (EpAnn _ a _) kw = mark a kw >> return 1++-- -- Deprecate in favour of markEpAnnL+-- markEpAnn' :: (Monad m, Monoid w)+--   => EpAnn ann -> (ann -> [AddEpAnn]) -> AnnKeywordId -> EP w m ()+-- markEpAnn' EpAnnNotUsed _ _ = return ()+-- markEpAnn' (EpAnn _anc a _cs) f kw = mark' (f a) kw >> return ()++markEpAnnL :: (Monad m, Monoid w)+  => EpAnn ann -> Lens ann [AddEpAnn] -> AnnKeywordId -> EP w m (EpAnn ann)+markEpAnnL EpAnnNotUsed _ _ = return EpAnnNotUsed+markEpAnnL (EpAnn anc a cs) l kw = do+  anns <- mark' (view l a) kw+  return (EpAnn anc (set l anns a) cs)++markEpAnnAllL :: (Monad m, Monoid w)+  => EpAnn ann -> Lens ann [AddEpAnn] -> AnnKeywordId -> EP w m (EpAnn ann)+markEpAnnAllL EpAnnNotUsed _ _ = return EpAnnNotUsed+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++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 Int+mark anns kw = do+  case find (\(AddEpAnn k _) -> k == kw) anns of+    Just aa -> markKw aa >> return 1+    Nothing -> case find (\(AddEpAnn k _) -> k == (unicodeAnn kw)) anns of+      Just aau -> markKw aau >> return 1+      Nothing -> return 1++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 (AddRarrowAnn ss)  = AddRarrowAnn  <$> markKwA AnnRarrow ss+markKwT (AddRarrowAnnU ss) = AddRarrowAnnU <$> markKwA AnnRarrowU ss+markKwT (AddLollyAnnU ss)  = AddLollyAnnU  <$> markKwA AnnLollyU ss++-- ---------------------------------------------------------------------++markAnnList :: (Monad m, Monoid w)+  => Bool -> EpAnn AnnList -> EP w m a -> EP w m (EpAnn AnnList, a)+markAnnList reallyTrail ann action = do+  markAnnListA reallyTrail ann $ \a -> do+    r <- action+    return (a,r)++markAnnListA :: (Monad m, Monoid w)+  => Bool -> EpAnn AnnList+  -> (EpAnn AnnList -> EP w m (EpAnn AnnList, a))+  -> EP w m (EpAnn AnnList, a)+markAnnListA _ EpAnnNotUsed action = do+  action EpAnnNotUsed+markAnnListA reallyTrail an action = do+  debugM $ "markAnnListA: an=" ++ showAst an+  an0 <- markLensMAA an lal_open+  an1 <- if (not reallyTrail)+           then markTrailingL an0 lal_trailing+           else return an0+  an2 <- markEpAnnAllL an1 lal_rest AnnSemi+  (an3, r) <- action an2+  an4 <- markLensMAA an3 lal_close+  an5 <- if reallyTrail+           then markTrailingL an4 lal_trailing+           else return an4+  debugM $ "markAnnListA: an5=" ++ showAst an+  return (an5, r)+++markAnnList' :: (Monad m, Monoid w)+  => Bool -> EpAnn AnnList -> EP w m a -> EP w m (EpAnn AnnList, a)+markAnnList' reallyTrail an action = do+  p <- getPosP+  debugM $ "markAnnList : " ++ showPprUnsafe (p, an)+  an0 <- markLensMAA an lal_open+  an1 <- if (not reallyTrail)+           then markTrailingL an0 lal_trailing+           else return an0+  an2 <- markEpAnnAllL an1 lal_rest AnnSemi+  r <- action+  an3 <- markLensMAA an2 lal_close+  an4 <- if reallyTrail+           then markTrailingL an3 lal_trailing+           else return an3+  return (an4, r)++-- ---------------------------------------------------------------------++printComments :: (Monad m, Monoid w) => RealSrcSpan -> EP w m ()+printComments ss = do+  cs <- commentAllocation ss+  debugM $ "printComments: (ss): " ++ showPprUnsafe (rs2range ss)+  -- debugM $ "printComments: (ss,comment locations): " ++ showPprUnsafe (rs2range ss,map commentAnchor cs)+  mapM_ printOneComment cs++-- ---------------------------------------------------------------------++printOneComment :: (Monad m, Monoid w) => Comment -> EP w m ()+printOneComment c@(Comment _str loc _r _mo) = do+  debugM $ "printOneComment:c=" ++ showGhc c+  dp <-case anchor_op loc of+    MovedAnchor dp -> return dp+    _ -> do+        pe <- getPriorEndD+        let dp = ss2delta pe (anchor loc)+        debugM $ "printOneComment:(dp,pe,anchor loc)=" ++ showGhc (dp,pe,ss2pos $ anchor loc)+        adjustDeltaForOffsetM dp+  mep <- getExtraDP+  dp' <- case mep of+    Just (Anchor _ (MovedAnchor edp)) -> do+      debugM $ "printOneComment:edp=" ++ show edp+      adjustDeltaForOffsetM edp+    _ -> return dp+  -- Start of debug printing+  -- LayoutStartCol dOff <- getLayoutOffsetD+  -- debugM $ "printOneComment:(dp,dp',dOff)=" ++ showGhc (dp,dp',dOff)+  -- End of debug printing+  -- setPriorEndD (ss2posEnd (anchor loc))+  updateAndApplyComment c dp'+  printQueuedComment (anchor loc) c dp'++updateAndApplyComment :: (Monad m, Monoid w) => Comment -> DeltaPos -> EP w m ()+updateAndApplyComment co@(Comment str anc pp mo) dp = do+  -- debugM $ "updateAndApplyComment: (dp,anc',co)=" ++ showAst (dp,anc',co)+  applyComment (Comment str anc' pp mo)+  where+    -- anc' = anc { anchor_op = MovedAnchor dp }+    anc' = anc { anchor_op = op}++    (r,c) = ss2posEnd pp+    la = anchor anc+    dp'' = if r == 0+           then (ss2delta (r,c+1) la)+           else (ss2delta (r,c)   la)+    dp' = if pp == anchor anc+             then dp+             else dp''+    op' = case dp' of+            SameLine n -> if n >= 0+                            then MovedAnchor dp'+                            else MovedAnchor dp+            _ -> MovedAnchor dp'+    op = if str == "" && op' == MovedAnchor (SameLine 0) -- EOF comment+           then MovedAnchor dp+           -- else op'+           else MovedAnchor dp++-- ---------------------------------------------------------------------++commentAllocation :: (Monad m, Monoid w) => RealSrcSpan -> EP w m [Comment]+commentAllocation 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) -> (ss2pos $ anchor loc) <= (ss2pos ss)) 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 _) = Entry (spanAsAnchor l) emptyComments NoFlushComments NoCanUpdateAnchor+  getAnnotationEntry (L l _) = case l of+    UnhelpfulSpan _ -> NoEntryVal+    _ -> Entry (hackSrcSpanToAnchor l) emptyComments NoFlushComments CanUpdateAnchorOnly+  -- getAnnotationEntry (L l _) = NoEntryVal++  -- setAnnotationAnchor _la _anc _cs = error "should not be called:setAnnotationAnchor (Located a)"+  setAnnotationAnchor (L _ a) anc _cs = L (hackAnchorToSrcSpan anc) a++  exact (L l a) = L l <$> markAnnotated a++instance (ExactPrint a) => ExactPrint (LocatedA a) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor la anc cs = setAnchorAn la anc cs+  exact (L la a) = do+    debugM $ "LocatedA a:la loc=" ++ show (ss2range $ locA la)+    a' <- markAnnotated a+    ann' <- markALocatedA (ann la)+    return (L (la { ann = ann'}) 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 where+  getAnnotationEntry hsmod = fromAnn' (hsmodAnn hsmod)+  -- A bit pointless actually changing anything here+  setAnnotationAnchor hsmod anc cs = setAnchorHsModule hsmod anc cs+                   `debug` ("setAnnotationAnchor hsmod called" ++ showAst (anc,cs))++  exact hsmod@(HsModule EpAnnNotUsed _ _ _ _ _ _ _) = withPpr hsmod >> return hsmod+  exact (HsModule an lo mmn mexports imports decls mdeprec mbDoc) = do++    debugM "HsModule Entered"++    mbDoc' <- markAnnotated 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++          debugM $ "HsModule.AnnWhere coming"+          an1 <- setLayoutTopLevelP $ markEpAnnL an0 lam_main AnnWhere+          debugM $ "HsModule.AnnWhere done, an1=" ++ showAst (anns an1)++          return (an1, Just m', mdeprec', mexports')++    -- debugM $ "After HsModule.AnnWhere done, an0=" ++ showAst (anns an0)+    let ann_decls = EpAnn (entry an) (am_decls $ anns an0) emptyComments+    (ann_decls', (decls', imports')) <- markAnnList' False ann_decls $ do+      imports' <- markTopLevelList imports+      decls' <- markTopLevelList decls+      return (decls', imports')+    let am_decls' = case ann_decls' of+          EpAnnNotUsed -> (am_decls $ anns an0)+          EpAnn _ r _ -> r++    let anf = an0 { anns = (anns an0) { am_decls = am_decls' }}+    debugM $ "HsModule, anf=" ++ showAst anf++    return (HsModule anf lo mmn' mexports' imports' decls' mdeprec' mbDoc')++-- ---------------------------------------------------------------------++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) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor = setAnchorAn++  exact (L (SrcSpanAnn an l) (WarningTxt (L la src) ws)) = do+    an0 <- markAnnOpenP an src "{-# WARNING"+    an1 <- markEpAnnL an0 lapr_rest AnnOpenS+    ws' <- markAnnotated ws+    an2 <- markEpAnnL an1 lapr_rest AnnCloseS+    an3 <- markAnnCloseP an2+    return (L (SrcSpanAnn an3 l) (WarningTxt (L la src) ws'))++  exact (L (SrcSpanAnn an l) (DeprecatedTxt (L ls 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 (SrcSpanAnn an3 l) (DeprecatedTxt (L ls src) ws'))++-- ---------------------------------------------------------------------++instance ExactPrint (ImportDecl GhcPs) where+  getAnnotationEntry idecl = fromAnn (ideclExt idecl)+  setAnnotationAnchor idecl anc cs = idecl { ideclExt = setAnchorEpa (ideclExt idecl) anc cs }++  exact x@(ImportDecl EpAnnNotUsed _ _ _ _ _ _ _ _ _) = withPpr x+  exact (ImportDecl ann msrc m mpkg src safeflag qualFlag impl 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"+              printStringAtMLoc Nothing "#-}"+              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+       Just (StringLiteral src' v _) ->+         printStringAtMLocL ann2 limportDeclAnnPackage (sourceTextToString src' (show v))+       _ -> return ann2++    m' <- markAnnotated m++    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 (EpAnn anc' an2 cs') msrc m' mpkg src safeflag qualFlag impl mAs' hiding')+++-- ---------------------------------------------------------------------++instance ExactPrint HsDocString where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ = a+  exact = withPpr -- TODO:AZ use annotations++-- ---------------------------------------------------------------------++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 an _) = fromAnn an+  getAnnotationEntry (TyFamInstD   _  _) = NoEntryVal++  setAnnotationAnchor (DataFamInstD an d) anc cs = DataFamInstD (setAnchorEpa an anc cs) d+  setAnnotationAnchor d _ _ = d+++  exact (ClsInstD     a  cid) = do+    cid' <- markAnnotated cid+    return (ClsInstD     a  cid')+  exact (DataFamInstD an decl) = do+    d' <- markAnnotated (DataFamInstDeclWithContext an TopLevel decl)+    return (DataFamInstD an (dc_d d'))+  exact (TyFamInstD a eqn) = do+    eqn' <- markAnnotated eqn+    return (TyFamInstD a eqn')++-- ---------------------------------------------------------------------++data DataFamInstDeclWithContext+  = DataFamInstDeclWithContext+    { _dc_a :: EpAnn [AddEpAnn]+    , _dc_f :: TopLevelFlag+    , dc_d :: DataFamInstDecl GhcPs+    }++instance ExactPrint DataFamInstDeclWithContext where+  getAnnotationEntry (DataFamInstDeclWithContext _ _ (DataFamInstDecl (FamEqn { feqn_ext = an})))+    = fromAnn an+  setAnnotationAnchor (DataFamInstDeclWithContext a c (DataFamInstDecl fe)) anc cs+    = (DataFamInstDeclWithContext a c (DataFamInstDecl (fe { feqn_ext = (setAnchorEpa (feqn_ext fe) anc cs)})))+  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)+                     => EpAnn [AddEpAnn] -> TopLevelFlag -> DataFamInstDecl GhcPs+                     -> EP w m (EpAnn [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', _,  _mc, defn') <- exactDataDefn an2 pp_hdr defn+    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 ( EpAnn [AddEpAnn]+                     , LocatedN RdrName+                     , HsOuterTyVarBndrs () GhcPs+                     , HsTyPats 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 (DerivDecl {deriv_ext = an} ) = fromAnn an+  setAnnotationAnchor dd anc cs = dd { deriv_ext = setAnchorEpa (deriv_ext dd) anc cs }+  exact (DerivDecl an typ ms mov) = do+    an0 <- markEpAnnL an lidl AnnDeriving+    ms' <- mapM markAnnotated ms+    an1 <- markEpAnnL an0 lidl AnnInstance+    mov' <- mapM markAnnotated mov+    typ' <- markAnnotated typ+    return (DerivDecl an1 typ' ms' mov')++-- ---------------------------------------------------------------------++instance ExactPrint (ForeignDecl GhcPs) where+  getAnnotationEntry (ForeignImport an _ _  _) = fromAnn an+  getAnnotationEntry (ForeignExport an _ _  _) = fromAnn an++  setAnnotationAnchor (ForeignImport an a b c) anc cs = ForeignImport (setAnchorEpa an anc cs) a b c+  setAnnotationAnchor (ForeignExport an a b c) anc cs = ForeignExport (setAnchorEpa an anc cs) a b c++  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 where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ = a+  exact (CImport cconv safety@(L ll _) mh imp (L ls src)) = do+    cconv' <- markAnnotated cconv+    unless (ll == noSrcSpan) $ markAnnotated safety >> return ()+    unless (ls == noSrcSpan) $ markExternalSourceText ls src "" >> return ()+    return (CImport cconv' safety mh imp (L ls src))++-- ---------------------------------------------------------------------++instance ExactPrint ForeignExport where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ = a+  exact (CExport spec (L ls src)) = do+    debugM $ "CExport starting"+    spec' <- markAnnotated spec+    unless (ls == noSrcSpan) $ markExternalSourceText ls src ""+    return (CExport spec' (L ls src))++-- ---------------------------------------------------------------------++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 (Warnings an _ _) = fromAnn an+  setAnnotationAnchor (Warnings an a b) anc cs = Warnings (setAnchorEpa an anc cs) a b++  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 (Warning an _ _) = fromAnn an+  setAnnotationAnchor (Warning an a b) anc cs = Warning (setAnchorEpa an anc cs) a b++  exact (Warning an lns txt) = do+    lns' <- markAnnotated lns+    an0 <- markEpAnnL an lidl AnnOpenS -- "["+    txt' <-+      case txt of+        WarningTxt    src ls -> do+          ls' <- markAnnotated ls+          return (WarningTxt    src ls')+        DeprecatedTxt src ls -> do+          ls' <- markAnnotated ls+          return (DeprecatedTxt src ls')+    an1 <- markEpAnnL an0 lidl AnnCloseS -- "]"+    return (Warning an1 lns' txt')++-- ---------------------------------------------------------------------++instance ExactPrint StringLiteral where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ = a++  exact l@(StringLiteral src fs mcomma) = do+    printSourceText src (show (unpackFS fs))+    mapM_ (\r -> printStringAtRs r ",") mcomma+    return l++-- ---------------------------------------------------------------------++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 (HsRules an _ _) = fromAnn an+  setAnnotationAnchor (HsRules an a b) anc cs = HsRules (setAnchorEpa an anc cs) a b+  exact (HsRules an src rules) = do+    an0 <-+      case src of+        NoSourceText      -> markEpAnnLMS an lidl AnnOpen  (Just "{-# RULES")+        SourceText srcTxt -> markEpAnnLMS an lidl AnnOpen  (Just srcTxt)+    rules' <- markAnnotated rules+    an1 <- markEpAnnLMS an0 lidl AnnClose (Just "#-}")+    return (HsRules an1 src rules')++-- ---------------------------------------------------------------------++instance ExactPrint (RuleDecl GhcPs) where+  getAnnotationEntry (HsRule {rd_ext = an}) = fromAnn an+  setAnnotationAnchor r anc cs = r { rd_ext = setAnchorEpa (rd_ext r) anc cs}+  exact (HsRule an ln act mtybndrs termbndrs lhs rhs) = do+    debugM "HsRule entered"+    ln' <- markAnnotated ln+    debugM "HsRule after ln"+    an0 <- markActivation an lra_rest act+    debugM "HsRule after act"+    (an1, mtybndrs') <-+      case mtybndrs of+        Nothing -> return (an0, Nothing)+        Just bndrs -> do+          -- an1 <-  markLensMAA an0 (\a -> fmap fst (ra_tyanns a))  -- AnnForall+          an1 <-  markLensMAA an0 lra_tyanns_fst  -- AnnForall+          bndrs' <- mapM markAnnotated bndrs+          -- an2 <- markLensMAA an1 (\a -> fmap snd (ra_tyanns a))  -- AnnDot+          an2 <- markLensMAA an1 lra_tyanns_snd  -- AnnDot+          return (an2, Just bndrs')++    -- an2 <- markLensMAA an1 (\a -> fmap fst (ra_tmanns a))  -- AnnForall+    an2 <- markLensMAA an1 lra_tmanns_fst  -- AnnForall+    termbndrs' <- mapM markAnnotated termbndrs+    -- an3 <- markLensMAA an2 (\a -> fmap snd (ra_tmanns a))  -- AnnDot+    an3 <- markLensMAA an2 lra_tmanns_snd  -- AnnDot++    lhs' <- markAnnotated lhs+    an4 <- markEpAnnL an3 lra_rest AnnEqual+    rhs' <- markAnnotated rhs+    return (HsRule an4 ln' act mtybndrs' termbndrs' lhs' rhs')++markActivation :: (Monad m, Monoid w)+  => EpAnn a -> Lens a [AddEpAnn] -> Activation -> EP w m (EpAnn 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 where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ = a++  exact v =+    let str =+          case v of+            (DocCommentNext ds)     -> unpackHDS ds+            (DocCommentPrev ds)     -> unpackHDS ds+            (DocCommentNamed _s ds) -> unpackHDS ds+            (DocGroup _i ds)        -> unpackHDS ds+    in+      printStringAdvance str >> return v++-- ---------------------------------------------------------------------++instance ExactPrint (RoleAnnotDecl GhcPs) where+  getAnnotationEntry (RoleAnnotDecl an _ _) = fromAnn an+  setAnnotationAnchor (RoleAnnotDecl an a b) anc cs = RoleAnnotDecl (setAnchorEpa an anc cs) a b+  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 _ r') <- markAnnotated (L l r)+          return (L l (Just r'))+        markRole (L l Nothing) = do+          printStringAtSs l "_"+          return (L l 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 (FamEqn { feqn_ext = an}) = fromAnn an+  setAnnotationAnchor fe anc cs = fe {feqn_ext = setAnchorEpa (feqn_ext fe) anc cs}+  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)+   => EpAnn [AddEpAnn]+   -> LocatedN RdrName+   -> HsOuterTyVarBndrs () GhcPs+   -> HsTyPats GhcPs+   -> LexicalFixity+   -> Maybe (LHsContext GhcPs)+   -> EP w m ( EpAnn [AddEpAnn]+             , LocatedN RdrName+             , HsOuterTyVarBndrs () GhcPs+             , HsTyPats 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)+      => EpAnn [AddEpAnn] -> HsTyPats GhcPs -> EP w m (EpAnn [AddEpAnn], LocatedN RdrName, HsTyPats 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 (LHsTypeArg GhcPs) where+instance (ExactPrint tm, ExactPrint ty, Outputable tm, Outputable ty)+     =>  ExactPrint (HsArg tm ty) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ = a++  exact a@(HsValArg tm)    = markAnnotated tm >> return a+  exact a@(HsTypeArg ss ty) = printStringAtSs ss "@" >> markAnnotated ty >> return a+  exact x@(HsArgPar _sp)   = withPpr x -- Does not appear in original source++-- ---------------------------------------------------------------------++instance ExactPrint (ClsInstDecl GhcPs) where+  getAnnotationEntry cid = fromAnn (fst $ cid_ext cid)+  setAnnotationAnchor cid anc cs+    = cid { cid_ext = (setAnchorEpa (fst $ cid_ext cid) anc cs, (snd $ cid_ext cid)) }++  exact (ClsInstDecl { cid_ext = (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+          (an0, mbOverlap', inst_ty') <- top_matter+          -- an0 <- markEpAnnL an' lidl AnnWhere+          an1 <- markEpAnnL an0 lidl AnnOpenC+          an2 <- markEpAnnAllL an1 lid AnnSemi+          ds <- withSortKey sortKey+                               (prepareListAnnotationA ats+                             ++ prepareListAnnotationF an adts+                             ++ prepareListAnnotationA (bagToList binds)+                             ++ 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 = (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+          mo <- mapM markAnnotated mbOverlap+          it <- markAnnotated inst_ty+          an1 <- markEpAnnL an0 lidl AnnWhere -- Optional+          return (an1, mo,it)++-- ---------------------------------------------------------------------++instance ExactPrint (TyFamInstDecl GhcPs) where+  getAnnotationEntry (TyFamInstDecl an _) = fromAnn an+  setAnnotationAnchor (TyFamInstDecl an a) anc cs = TyFamInstDecl (setAnchorEpa an anc cs) 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 (SrcSpanAnn an l) (NoOverlap src)) = do+    an0 <- markAnnOpenP an src "{-# NO_OVERLAP"+    an1 <- markAnnCloseP an0+    return (L (SrcSpanAnn an1 l) (NoOverlap src))++  exact (L (SrcSpanAnn an l) (Overlappable src)) = do+    an0 <- markAnnOpenP an src "{-# OVERLAPPABLE"+    an1 <- markAnnCloseP an0+    return (L (SrcSpanAnn an1 l) (Overlappable src))++  exact (L (SrcSpanAnn an l) (Overlapping src)) = do+    an0 <- markAnnOpenP an src "{-# OVERLAPPING"+    an1 <- markAnnCloseP an0+    return (L (SrcSpanAnn an1 l) (Overlapping src))++  exact (L (SrcSpanAnn an l) (Overlaps src)) = do+    an0 <- markAnnOpenP an src "{-# OVERLAPS"+    an1 <- markAnnCloseP an0+    return (L (SrcSpanAnn an1 l) (Overlaps src))++  exact (L (SrcSpanAnn an l) (Incoherent src)) = do+    an0 <- markAnnOpenP an src "{-# INCOHERENT"+    an1 <- markAnnCloseP an0+    return (L (SrcSpanAnn an1 l) (Incoherent src))++-- ---------------------------------------------------------------------++instance ExactPrint (HsBind GhcPs) where+  getAnnotationEntry FunBind{} = NoEntryVal+  getAnnotationEntry PatBind{pat_ext=an} = fromAnn an+  getAnnotationEntry VarBind{} = NoEntryVal+  getAnnotationEntry AbsBinds{} = NoEntryVal+  getAnnotationEntry PatSynBind{} = NoEntryVal++  setAnnotationAnchor pb@PatBind{} anc cs = pb { pat_ext = setAnchorEpa (pat_ext pb) anc cs}+  setAnnotationAnchor a _ _ = a++  exact (FunBind x fid matches t) = 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' t)+  exact (PatBind x pat grhss t) = do+    pat' <- markAnnotated pat+    grhss' <- markAnnotated grhss+    return (PatBind x pat' grhss' t)+  exact (PatSynBind x bind) = do+    bind' <- markAnnotated bind+    return (PatSynBind x bind')++  exact x = error $ "HsBind: exact for " ++ showAst x++-- ---------------------------------------------------------------------++instance ExactPrint (PatSynBind GhcPs GhcPs) where+  getAnnotationEntry (PSB { psb_ext = an}) = fromAnn an+  setAnnotationAnchor p anc cs = p { psb_ext = setAnchorEpa (psb_ext p) anc cs}++  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 r@(RecordPatSynField { recordPatSynField = v }) = markAnnotated v+        >> return r++-- ---------------------------------------------------------------------++instance ExactPrint (Match GhcPs (LocatedA (HsCmd GhcPs))) where+  getAnnotationEntry (Match ann _ _ _) = fromAnn ann+  setAnnotationAnchor (Match an a b c) anc cs = Match (setAnchorEpa an anc cs) a b c++  exact (Match an mctxt pats grhss) =+    exactMatch (Match an mctxt pats grhss)++-- -------------------------------------++instance ExactPrint (Match GhcPs (LocatedA (HsExpr GhcPs))) where+  getAnnotationEntry (Match ann _ _ _) = fromAnn ann+  setAnnotationAnchor (Match an a b c) anc cs = Match (setAnchorEpa an anc cs) a b c++  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"+      LambdaExpr -> do+        an0' <- markEpAnnL an lidl AnnLam+        pats' <- markAnnotated pats+        return (an0', LambdaExpr, 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')++-- ---------------------------------------------------------------------++-- Temporary until https://gitlab.haskell.org/ghc/ghc/-/issues/20247+-- is fixed+fixValbindsAnn :: EpAnn AnnList -> EpAnn AnnList+fixValbindsAnn EpAnnNotUsed = EpAnnNotUsed+fixValbindsAnn (EpAnn anchor (AnnList ma o c r t) cs)+  = (EpAnn (widenAnchor anchor (map trailingAnnToAddEpAnn t)) (AnnList ma o c r t) cs)+++-- See https://gitlab.haskell.org/ghc/ghc/-/issues/20256+fixAnnListAnn :: EpAnn AnnList -> EpAnn AnnList+fixAnnListAnn EpAnnNotUsed = EpAnnNotUsed+fixAnnListAnn (EpAnn anchor (AnnList ma o c r t) cs)+  = (EpAnn (widenAnchor anchor r) (AnnList ma o c r t) cs)++-- See https://gitlab.haskell.org/ghc/ghc/-/issues/20256+fixSrcAnnL :: SrcSpanAnnL -> SrcSpanAnnL+fixSrcAnnL (SrcSpanAnn an l) = SrcSpanAnn (fixAnnListAnn an) l++-- ---------------------------------------------------------------------++instance ExactPrint (HsLocalBinds GhcPs) where+  getAnnotationEntry (HsValBinds an _) = fromAnn (fixValbindsAnn an)+  getAnnotationEntry (HsIPBinds{}) = NoEntryVal+  getAnnotationEntry (EmptyLocalBinds{}) = NoEntryVal++  setAnnotationAnchor (HsValBinds an a) anc cs = HsValBinds (setAnchorEpaL an anc cs) a+  setAnnotationAnchor a _ _ = a++  exact (HsValBinds an' valbinds) = do+    let an = fixValbindsAnn an'+    debugM $ "exact HsValBinds: an=" ++ showAst an+    an0 <- markEpAnnL an lal_rest AnnWhere++    let manc = case an of+                 EpAnnNotUsed -> Nothing+                 _ -> al_anchor $ anns an++    case manc of+      Just anc -> do+        when (not $ isEmptyValBinds valbinds) $ setExtraDP (Just anc)+      _ -> return ()++    (an1, valbinds') <- markAnnList False an0 $ markAnnotatedWithLayout valbinds+    debugM $ "exact HsValBinds: an1=" ++ showAst an1+    return (HsValBinds an1 valbinds')++  exact (HsIPBinds an bs) = do+    (as, ipb) <- markAnnList True an (markLocatedAAL an al_rest AnnWhere+                           >> markAnnotated bs+                           >>= \bs' -> return (HsIPBinds an bs'::HsLocalBinds GhcPs))+    case ipb of+      HsIPBinds _ bs' -> return (HsIPBinds as bs'::HsLocalBinds GhcPs)+      _ -> error "should not happen HsIPBinds"+  exact b@(EmptyLocalBinds _) = return b+++-- ---------------------------------------------------------------------+instance ExactPrint (HsValBindsLR GhcPs GhcPs) where+  getAnnotationEntry _ = NoEntryVal+  setAnnotationAnchor a _ _ = a++  exact (ValBinds sortKey binds sigs) = do+    ds <- setLayoutBoth $ withSortKey sortKey+       (prepareListAnnotationA (bagToList binds)+     ++ prepareListAnnotationA sigs+       )+    let+      binds' = listToBag $ undynamic ds+      sigs'  = undynamic ds+    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 b@(IPBinds _ binds) = setLayoutBoth $ markAnnotated binds >> return b++-- ---------------------------------------------------------------------++instance ExactPrint (IPBind GhcPs) where+  getAnnotationEntry (IPBind an _ _) = fromAnn an+  setAnnotationAnchor (IPBind an a b) anc cs = IPBind (setAnchorEpa an anc cs) a b++  exact (IPBind an (Left lr) rhs) = do+    lr' <- markAnnotated lr+    an0 <- markEpAnnL an lidl AnnEqual+    rhs' <- markAnnotated rhs+    return (IPBind an0 (Left lr') rhs')++  exact (IPBind _ (Right _) _) = error $ "ExactPrint IPBind: Right only after typechecker"++-- ---------------------------------------------------------------------++instance ExactPrint HsIPName where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ = a++  exact i@(HsIPName fs) = printStringAdvance ("?" ++ (unpackFS fs)) >> return i++-- ---------------------------------------------------------------------+-- Managing lists which have been separated, e.g. Sigs and Binds++prepareListAnnotationF :: (Monad m, Monoid w) =>+  EpAnn [AddEpAnn] -> [LDataFamInstDecl GhcPs] -> [(RealSrcSpan,EP w m Dynamic)]+prepareListAnnotationF an ls = map (\b -> (realSrcSpan $ getLocA b, go b)) ls+  where+    go (L l a) = do+      -- d' <- markAnnotated (DataFamInstDeclWithContext an TopLevel a)+      d' <- markAnnotated (DataFamInstDeclWithContext an 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 -> [(RealSrcSpan, EP w m Dynamic)] -> EP w m [Dynamic]+withSortKey annSortKey xs = do+  debugM $ "withSortKey:annSortKey=" ++ showAst annSortKey+  let ordered = case annSortKey of+                  NoAnnSortKey -> sortBy orderByFst xs+                  -- Just keys -> error $ "withSortKey: keys" ++ show keys+                  AnnSortKey keys -> orderByKey xs keys+                                -- `debug` ("withSortKey:" +++                                --          showPprUnsafe (map fst (sortBy (comparing (flip elemIndex keys . fst)) xs),+                                --                  map fst xs,+                                --                  keys)+                                --          )+  mapM snd ordered++orderByFst :: Ord a => (a, b1) -> (a, b2) -> Ordering+orderByFst (a,_) (b,_) = compare a b++-- ---------------------------------------------------------------------++instance ExactPrint (Sig GhcPs) where+  getAnnotationEntry (TypeSig a _ _)  = fromAnn a+  getAnnotationEntry (PatSynSig a _ _) = fromAnn a+  getAnnotationEntry (ClassOpSig a _ _ _) = fromAnn a+  getAnnotationEntry (IdSig {}) = NoEntryVal+  getAnnotationEntry (FixSig a _) = fromAnn a+  getAnnotationEntry (InlineSig a _ _) = fromAnn a+  getAnnotationEntry (SpecSig a _ _ _) = fromAnn a+  getAnnotationEntry (SpecInstSig a _ _) = fromAnn a+  getAnnotationEntry (MinimalSig a _ _) = fromAnn a+  getAnnotationEntry (SCCFunSig a _ _ _) = fromAnn a+  getAnnotationEntry (CompleteMatchSig a _ _ _) = fromAnn a++  setAnnotationAnchor (TypeSig a x y)  anc           cs = (TypeSig (setAnchorEpa a anc cs) x y)+  setAnnotationAnchor (PatSynSig a x y) anc          cs = (PatSynSig (setAnchorEpa a anc cs) x y)+  setAnnotationAnchor (ClassOpSig a x y z) anc       cs = (ClassOpSig (setAnchorEpa a anc cs) x y z)+  setAnnotationAnchor i@(IdSig {}) _ _s = i+  setAnnotationAnchor (FixSig a x) anc               cs = (FixSig (setAnchorEpa a anc cs) x)+  setAnnotationAnchor (InlineSig a x y) anc          cs = (InlineSig (setAnchorEpa a anc cs) x y)+  setAnnotationAnchor (SpecSig a x y z) anc          cs = (SpecSig (setAnchorEpa a anc cs) x y z)+  setAnnotationAnchor (SpecInstSig a x y) anc        cs = (SpecInstSig (setAnchorEpa a anc cs) x y)+  setAnnotationAnchor (MinimalSig a x y) anc         cs = (MinimalSig (setAnchorEpa a anc cs) x y)+  setAnnotationAnchor (SCCFunSig a x y z) anc        cs = (SCCFunSig (setAnchorEpa a anc cs) x y z)+  setAnnotationAnchor (CompleteMatchSig a x y z) anc cs = (CompleteMatchSig (setAnchorEpa a anc cs) x y z)++  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 x 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)))+    names' <- markAnnotated names+    return (FixSig an1 (FixitySig x 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+    debugM $ "InlineSig:an=" ++ showAst an+    p <- getPosP+    debugM $ "InlineSig: p=" ++ show p+    an2 <- markEpAnnLMS an1 lidl AnnClose (Just "#-}")+    debugM $ "InlineSig:done"+    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' <- 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')++  exact x = error $ "exact Sig for:" ++ showAst x++-- ---------------------------------------------------------------------++exactVarSig :: (Monad m, Monoid w, ExactPrint a)+  => EpAnn AnnSig -> [LocatedN RdrName] -> a -> EP w m (EpAnn 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 (StandaloneKindSig an _ _) = fromAnn an+  setAnnotationAnchor (StandaloneKindSig an a b) anc cs = StandaloneKindSig (setAnchorEpa an anc cs) a b++  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 (DefaultDecl an _) = fromAnn an+  setAnnotationAnchor (DefaultDecl an a) anc cs = DefaultDecl (setAnchorEpa an anc cs) 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 (HsAnnotation an _ _ _) = fromAnn an+  setAnnotationAnchor (HsAnnotation an a b c) anc cs = HsAnnotation (setAnchorEpa an anc cs) a b c++  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 an 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 cs = GRHS (setAnchorEpa an anc cs) a b++  exact (GRHS an guards expr) = do+    debugM $ "GRHS comments:" ++ showGhc (comments an)+    an0 <- markLensKwM an lga_vbar AnnVbar+    guards' <- markAnnotated guards+    debugM $ "GRHS before matchSeparator"+    an1 <- markLensAA an0 lga_sep -- Mark the matchSeparator for these GRHSs+    debugM $ "GRHS after matchSeparator"+    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 cs = GRHS (setAnchorEpa an anc 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 (HsVar{})                    = NoEntryVal+  getAnnotationEntry (HsUnboundVar an _)          = fromAnn an+  getAnnotationEntry (HsConLikeOut{})             = NoEntryVal+  getAnnotationEntry (HsRecFld{})                 = NoEntryVal+  getAnnotationEntry (HsOverLabel an _)           = fromAnn an+  getAnnotationEntry (HsIPVar an _)               = fromAnn an+  getAnnotationEntry (HsOverLit an _)             = fromAnn an+  getAnnotationEntry (HsLit an _)                 = fromAnn an+  getAnnotationEntry (HsLam _ _)                  = NoEntryVal+  getAnnotationEntry (HsLamCase an _)             = fromAnn an+  getAnnotationEntry (HsApp an _ _)               = fromAnn an+  getAnnotationEntry (HsAppType _ _ _)            = NoEntryVal+  getAnnotationEntry (OpApp an _ _ _)             = fromAnn an+  getAnnotationEntry (NegApp an _ _)              = fromAnn an+  getAnnotationEntry (HsPar an _)                 = fromAnn an+  getAnnotationEntry (SectionL an _ _)            = fromAnn an+  getAnnotationEntry (SectionR an _ _)            = fromAnn an+  getAnnotationEntry (ExplicitTuple an _ _)       = fromAnn an+  getAnnotationEntry (ExplicitSum an _ _ _)       = fromAnn an+  getAnnotationEntry (HsCase an _ _)              = fromAnn an+  getAnnotationEntry (HsIf an _ _ _)              = fromAnn an+  getAnnotationEntry (HsMultiIf an _)             = fromAnn an+  getAnnotationEntry (HsLet an _ _)               = fromAnn an+  getAnnotationEntry (HsDo an _ _)                = fromAnn an+  getAnnotationEntry (ExplicitList an _)          = fromAnn an+  getAnnotationEntry (RecordCon an _ _)           = fromAnn an+  getAnnotationEntry (RecordUpd an _ _)           = fromAnn an+  getAnnotationEntry (HsGetField an _ _)          = fromAnn an+  getAnnotationEntry (HsProjection an _)          = fromAnn an+  getAnnotationEntry (ExprWithTySig an _ _)       = fromAnn an+  getAnnotationEntry (ArithSeq an _ _)            = fromAnn an+  getAnnotationEntry (HsBracket an _)             = fromAnn an+  getAnnotationEntry (HsRnBracketOut{})           = NoEntryVal+  getAnnotationEntry (HsTcBracketOut{})           = NoEntryVal+  getAnnotationEntry (HsSpliceE an _)             = fromAnn an+  getAnnotationEntry (HsProc an _ _)              = fromAnn an+  getAnnotationEntry (HsStatic an _)              = fromAnn an+  getAnnotationEntry (HsTick {})                  = NoEntryVal+  getAnnotationEntry (HsBinTick {})               = NoEntryVal+  getAnnotationEntry (HsPragE{})                  = NoEntryVal++  setAnnotationAnchor a@(HsVar{})              _ _s = a+  setAnnotationAnchor (HsUnboundVar an a)    anc cs = (HsUnboundVar (setAnchorEpa an anc cs) a)+  setAnnotationAnchor a@(HsConLikeOut{})       _ _s = a+  setAnnotationAnchor a@(HsRecFld{})           _ _s = a+  setAnnotationAnchor (HsOverLabel an a)     anc cs = (HsOverLabel (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (HsIPVar an a)         anc cs = (HsIPVar (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (HsOverLit an a)       anc cs = (HsOverLit (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (HsLit an a)           anc cs = (HsLit (setAnchorEpa an anc cs) a)+  setAnnotationAnchor a@(HsLam _ _)            _ _s = a+  setAnnotationAnchor (HsLamCase an a)       anc cs = (HsLamCase (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (HsApp an a b)         anc cs = (HsApp (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor a@(HsAppType _ _ _)      _ _s = a+  setAnnotationAnchor (OpApp an a b c)       anc cs = (OpApp (setAnchorEpa an anc cs) a b c)+  setAnnotationAnchor (NegApp an a b)        anc cs = (NegApp (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (HsPar an a)           anc cs = (HsPar (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (SectionL an a b)      anc cs = (SectionL (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (SectionR an a b)      anc cs = (SectionR (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (ExplicitTuple an a b) anc cs = (ExplicitTuple (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (ExplicitSum an a b c) anc cs = (ExplicitSum (setAnchorEpa an anc cs) a b c)+  setAnnotationAnchor (HsCase an a b)        anc cs = (HsCase (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (HsIf an a b c)        anc cs = (HsIf (setAnchorEpa an anc cs) a b c)+  setAnnotationAnchor (HsMultiIf an a)       anc cs = (HsMultiIf (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (HsLet an a b)         anc cs = (HsLet (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (HsDo an a b)          anc cs = (HsDo (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (ExplicitList an a)    anc cs = (ExplicitList (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (RecordCon an a b)     anc cs = (RecordCon (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (RecordUpd an a b)     anc cs = (RecordUpd (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (HsGetField an a b)    anc cs = (HsGetField (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (HsProjection an a)    anc cs = (HsProjection (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (ExprWithTySig an a b) anc cs = (ExprWithTySig (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (ArithSeq an a b)      anc cs = (ArithSeq (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (HsBracket an a)       anc cs = (HsBracket (setAnchorEpa an anc cs) a)+  setAnnotationAnchor a@(HsRnBracketOut{})     _ _s = a+  setAnnotationAnchor a@(HsTcBracketOut{})     _ _s = a+  setAnnotationAnchor (HsSpliceE an a)       anc cs = (HsSpliceE (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (HsProc an a b)        anc cs = (HsProc (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (HsStatic an a)        anc cs = (HsStatic (setAnchorEpa an anc cs) a)+  setAnnotationAnchor a@(HsTick {})            _ _s = a+  setAnnotationAnchor a@(HsBinTick {})         _ _s = a+  setAnnotationAnchor a@(HsPragE{})            _ _s = a++  exact (HsVar x n) = do+    n' <- markAnnotated n+    return (HsVar x n')+  exact x@(HsUnboundVar an _) = do+    case an of+      EpAnnNotUsed -> withPpr x+      EpAnn _ (EpAnnUnboundVar (ob,cb) l) _ -> do+        printStringAtAA ob "`" >> return ()+        printStringAtAA l  "_" >> return ()+        printStringAtAA cb "`" >> return ()+        return x+  -- exact x@(HsConLikeOut{})             = withPpr x+  -- exact x@(HsRecFld{})                 = withPpr x+  exact x@(HsOverLabel _ _) = withPpr 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+    -- markExternalSourceText l str ""+    case str of+      SourceText s -> printStringAdvance s >> return ()+      NoSourceText -> withPpr x >> return ()+    return x++  exact (HsLit an lit) = do+    lit' <- withPpr lit+    return (HsLit an lit')+  exact (HsLam x mg) = do+    mg' <- markAnnotated mg+    return (HsLam x mg')++  exact (HsLamCase an mg) = do+    an0 <- markEpAnnL an lidl AnnLam+    an1 <- markEpAnnL an0 lidl AnnCase+    mg' <- markAnnotated mg+    return (HsLamCase an1 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 ss fun arg) = do+    fun' <- markAnnotated fun+    printStringAtSs ss "@"+    arg' <- markAnnotated arg+    return (HsAppType ss 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 an e) = do+    an0 <- markOpeningParen an+    e' <- markAnnotated e+    debugM $ "HsPar closing paren"+    an1 <- markClosingParen an0+    debugM $ "HsPar done"+    return (HsPar an1 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 <- markAnnKwL an lhsCaseAnnCase AnnCase+    e' <- markAnnotated e+    an1 <- markAnnKwL 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 <- markAnnKwL an laiIf AnnIf+    e1' <- markAnnotated e1+    an1 <- markLensKwM an0 laiThenSemi AnnSemi+    an2 <- markAnnKwL an1 laiThen AnnThen+    e2' <- markAnnotated e2+    an3 <- markLensKwM an2 laiElseSemi AnnSemi+    an4 <- markAnnKwL 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 an binds e) = do+    setLayoutBoth $ do -- Make sure the 'in' gets indented too+      an0 <- markLensKw an lalLet AnnLet+      debugM $ "HSlet:binds coming"+      binds' <- setLayoutBoth $ markAnnotated binds+      debugM $ "HSlet:binds done"+      an1 <- markLensKw an0 lalIn AnnIn+      debugM $ "HSlet:expr coming"+      e' <- markAnnotated e+      return (HsLet an1 binds' e')++  exact (HsDo an do_or_list_comp stmts) = do+    debugM $ "HsDo"+    (an',stmts') <- markAnnListA True 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 <- markAnnKwL an lapOpen AnnOpenP+    flds' <- markAnnotated flds+    an1 <- markAnnKwL 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 (HsBracket 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 (HsBracket an2 (ExpBr a e'))+  exact (HsBracket an (PatBr a e)) = do+    an0 <- markEpAnnLMS an lidl AnnOpen (Just "[p|")+    e' <- markAnnotated e+    an1 <- markEpAnnL an0 lidl AnnCloseQ -- "|]"+    return (HsBracket an1 (PatBr a e'))+  exact (HsBracket an (DecBrL a e)) = do+    an0 <- markEpAnnLMS an lidl AnnOpen (Just "[d|")+    -- See https://gitlab.haskell.org/ghc/ghc/-/issues/20257, we need+    -- to mark braces here for the time being+    an1 <- markEpAnnL an0 lidl AnnOpenC -- "{"+    e' <- markAnnotated e+    an2 <- markEpAnnL an1 lidl AnnCloseC -- "}"+    an3 <- markEpAnnL an2 lidl AnnCloseQ -- "|]"+    return (HsBracket an3 (DecBrL a e'))+  -- -- exact (HsBracket an (DecBrG _ _)) =+  -- --   traceM "warning: DecBrG introduced after renamer"+  exact (HsBracket an (TypBr a e)) = do+    an0 <- markEpAnnLMS an lidl AnnOpen (Just "[t|")+    e' <- markAnnotated e+    an1 <- markEpAnnL an0 lidl AnnCloseQ -- "|]"+    return (HsBracket an1 (TypBr a e'))+  exact (HsBracket 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 (HsBracket an0 (VarBr a b e'))+  exact (HsBracket an (TExpBr a 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 (HsBracket an2 (TExpBr a e'))+++  -- exact x@(HsRnBracketOut{})           = withPpr x+  -- exact x@(HsTcBracketOut{})           = withPpr x+  exact (HsSpliceE a sp) = do+    sp' <- markAnnotated sp+    return (HsSpliceE a sp')++  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 x@(HsTick {})                  = withPpr x+  -- exact x@(HsBinTick {})               = withPpr x+  exact (HsPragE a prag e) = do+    prag' <- markAnnotated prag+    e' <- markAnnotated e+    return (HsPragE a prag' e')+  exact x = error $ "exact HsExpr for:" ++ showAst x++-- ---------------------------------------------------------------------++exactDo :: (Monad m, Monoid w, ExactPrint (LocatedAn an a))+        => EpAnn AnnList -> HsStmtContext any -> LocatedAn an a+        -> EP w m (EpAnn 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 ArrowExpr     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+exactDo _  _             _     = panic "pprDo" -- PatGuard, ParStmtCxt++exactMdo :: (Monad m, Monoid w)+  => EpAnn AnnList -> Maybe ModuleName -> AnnKeywordId -> EP w m (EpAnn 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))+  => EpAnn AnnList -> LocatedAn an a -> EP w m (EpAnn AnnList, LocatedAn an a)+markMaybeDodgyStmts an stmts =+  if isGoodSrcSpan (getLocA stmts)+    then do+      r <- markAnnotatedWithLayout stmts+      return (an, r)+    else return (an, stmts)++-- ---------------------------------------------------------------------+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 (HsSplice GhcPs) where+  getAnnotationEntry (HsTypedSplice an _ _ _)   = fromAnn an+  getAnnotationEntry (HsUntypedSplice an _ _ _) = fromAnn an+  getAnnotationEntry (HsQuasiQuote _ _ _ _ _)   = NoEntryVal+  getAnnotationEntry (HsSpliced _ _ _)          = NoEntryVal++  setAnnotationAnchor (HsTypedSplice an a b c)   anc cs = (HsTypedSplice (setAnchorEpa an anc cs) a b c)+  setAnnotationAnchor (HsUntypedSplice an a b c) anc cs = (HsUntypedSplice (setAnchorEpa an anc cs) a b c)+  setAnnotationAnchor a@(HsQuasiQuote _ _ _ _ _) _ _ = a+  setAnnotationAnchor a@(HsSpliced _ _ _)        _ _ = a++  exact (HsTypedSplice an DollarSplice n e) = do+    an0 <- markEpAnnL an lidl AnnDollarDollar+    e' <- markAnnotated e+    return (HsTypedSplice an0 DollarSplice n e')++  exact (HsUntypedSplice an decoration n b) = do+    an0 <- if (decoration == DollarSplice)+             then markEpAnnL an lidl AnnDollar+             else return an+    b' <- markAnnotated b+    return (HsUntypedSplice an0 decoration n b')++  exact (HsQuasiQuote a b q ss 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+    p <- getPosP+    debugM $ "HsQuasiQuote:after:(p,ss)=" ++ show (p,ss2range ss)+    return (HsQuasiQuote a b q ss fs)++  exact x = error $ "exact HsSplice for:" ++ showAst x++-- ---------------------------------------------------------------------++-- TODO:AZ: combine these instances+instance ExactPrint (MatchGroup GhcPs (LocatedA (HsExpr GhcPs))) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ = a+  exact (MG x matches o) = do+    -- TODO:AZ use SortKey, in MG ann.+    -- matches' <- markAnnotated matches+    matches' <- if isGoodSrcSpan (getLocA matches)+      then markAnnotated matches+      else return matches+    return (MG x matches' o)++instance ExactPrint (MatchGroup GhcPs (LocatedA (HsCmd GhcPs))) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ = a+  exact (MG x matches o) = do+    -- TODO:AZ use SortKey, in MG ann.+    matches' <- if isGoodSrcSpan (getLocA matches)+      then markAnnotated matches+      else return matches+    return (MG x matches' o)++-- ---------------------------------------------------------------------++instance (ExactPrint body) => ExactPrint (HsRecFields GhcPs body) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ = a+  exact (HsRecFields fields mdot) = do+    fields' <- markAnnotated fields+    case mdot of+      Nothing -> return ()+      Just (L ss _) ->+        printStringAtSs ss ".." >> return ()+      -- Note: mdot contains the SrcSpan where the ".." appears, if present+    return (HsRecFields fields' mdot)++-- ---------------------------------------------------------------------++instance (ExactPrint body)+    => ExactPrint (HsRecField' (FieldOcc GhcPs) body) where+  getAnnotationEntry x = fromAnn (hsRecFieldAnn x)+  setAnnotationAnchor x anc cs = x { hsRecFieldAnn = setAnchorEpa (hsRecFieldAnn x) anc cs}+  exact (HsRecField an f arg isPun) = do+    debugM $ "HsRecField"+    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 (HsRecField an0 f' arg' isPun)++-- ---------------------------------------------------------------------++instance (ExactPrint body)+    => ExactPrint (HsRecField' (FieldLabelStrings GhcPs) body) where+  getAnnotationEntry x = fromAnn (hsRecFieldAnn x)+  setAnnotationAnchor x anc cs = x { hsRecFieldAnn = setAnchorEpa (hsRecFieldAnn x) anc cs}+  exact (HsRecField an f arg isPun) = do+    debugM $ "HsRecField 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 (HsRecField an0 f' arg' isPun)++-- ---------------------------------------------------------------------++instance (ExactPrint (LocatedA body))+    => ExactPrint (HsRecField' (AmbiguousFieldOcc GhcPs) (LocatedA body)) where+  getAnnotationEntry x = fromAnn (hsRecFieldAnn x)+  setAnnotationAnchor x anc cs = x { hsRecFieldAnn = setAnchorEpa (hsRecFieldAnn x) anc cs}+  exact (HsRecField an f arg isPun) = do+    debugM $ "HsRecUpdField"+    f' <- markAnnotated f+    an0 <- if isPun then return an+                    else markEpAnnL an lidl AnnEqual+    arg' <- if ((locA $ getLoc arg) == noSrcSpan )+      then return arg+      else markAnnotated arg+    return (HsRecField an0 f' arg' isPun)++-- ---------------------------------------------------------------------++instance+    (ExactPrint (HsRecField' (a GhcPs) body),+     ExactPrint (HsRecField' (b GhcPs) body))+    => ExactPrint+         (Either [LocatedA (HsRecField' (a GhcPs) body)]+                 [LocatedA (HsRecField' (b GhcPs) body)]) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ = a+  exact (Left rbinds) = do+    rbinds' <- markAnnotated rbinds+    return (Left rbinds')+  exact (Right pbinds) = do+    pbinds' <- markAnnotated pbinds+    return (Right pbinds')++-- ---------------------------------------------------------------------++instance ExactPrint (FieldLabelStrings GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ = a+  exact (FieldLabelStrings fs) = FieldLabelStrings <$> markAnnotated fs++-- ---------------------------------------------------------------------++instance ExactPrint (NonEmpty (Located (HsFieldLabel GhcPs))) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ = a+  exact (h :| t) = do+    h' <- markAnnotated h+    t' <- markAnnotated t+    return (h' :| t')++-- ---------------------------------------------------------------------++instance ExactPrint (HsFieldLabel GhcPs) where+  getAnnotationEntry (HsFieldLabel an _) = fromAnn an+  setAnnotationAnchor (HsFieldLabel an a) anc cs = HsFieldLabel (setAnchorEpa an anc cs) a++  exact (HsFieldLabel an fs) = do+    an0 <- markLensKwM an lafDot  AnnDot+    fs' <- markAnnotated fs+    return (HsFieldLabel an0 fs')++-- ---------------------------------------------------------------------++instance ExactPrint (HsTupArg GhcPs) where+  getAnnotationEntry (Present an _) = fromAnn an+  getAnnotationEntry (Missing an)   = fromAnn an++  setAnnotationAnchor (Present an a) anc cs = Present (setAnchorEpa an anc cs) a+  setAnnotationAnchor (Missing an)   anc cs = Missing (setAnchorEpa an anc cs)++  exact (Present a e) = Present a <$> markAnnotated e++  exact a@(Missing EpAnnNotUsed) = 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 (HsCmdArrApp an _ _ _ _)   = fromAnn an+  getAnnotationEntry (HsCmdArrForm an _ _ _ _ ) = fromAnn an+  getAnnotationEntry (HsCmdApp an _ _ )         = fromAnn an+  getAnnotationEntry (HsCmdLam {})              = NoEntryVal+  getAnnotationEntry (HsCmdPar an _)            = fromAnn an+  getAnnotationEntry (HsCmdCase an _ _)         = fromAnn an+  getAnnotationEntry (HsCmdLamCase an _)        = fromAnn an+  getAnnotationEntry (HsCmdIf an _ _ _ _)       = fromAnn an+  getAnnotationEntry (HsCmdLet an _ _)          = fromAnn an+  getAnnotationEntry (HsCmdDo an _)             = fromAnn an++  setAnnotationAnchor (HsCmdArrApp an a b c d)   anc cs = (HsCmdArrApp (setAnchorEpa an anc cs) a b c d)+  setAnnotationAnchor (HsCmdArrForm an a b c d ) anc cs = (HsCmdArrForm (setAnchorEpa an anc cs) a b c d )+  setAnnotationAnchor (HsCmdApp an a b )         anc cs = (HsCmdApp (setAnchorEpa an anc cs) a b )+  setAnnotationAnchor a@(HsCmdLam {})              _ _s = a+  setAnnotationAnchor (HsCmdPar an a)            anc cs = (HsCmdPar (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (HsCmdCase an a b)         anc cs = (HsCmdCase (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (HsCmdLamCase an a)        anc cs = (HsCmdLamCase (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (HsCmdIf an a b c d)       anc cs = (HsCmdIf (setAnchorEpa an anc cs) a b c d)+  setAnnotationAnchor (HsCmdLet an a b)          anc cs = (HsCmdLet (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (HsCmdDo an a)             anc cs = (HsCmdDo (setAnchorEpa an anc cs) a)++  exact (HsCmdArrApp an arr arg o isRightToLeft) = do+    if isRightToLeft+      then do+        arr' <- markAnnotated arr+        an0 <- markKw (anns an)+        arg' <- markAnnotated arg+        let an1 = an{anns = an0}+        return (HsCmdArrApp an1 arr' arg' o isRightToLeft)+      else do+        arg' <- markAnnotated arg+        an0 <- markKw (anns an)+        arr' <- markAnnotated arr+        let an1 = an{anns = an0}+        return (HsCmdArrApp an1 arr' arg' o isRightToLeft)++  exact (HsCmdArrForm an e fixity mf cs) = do+    -- markLocatedMAA an al_open+    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 a match) = do+    match' <- markAnnotated match+    return (HsCmdLam a match')++  exact (HsCmdPar an e) = do+    an0 <- markOpeningParen an+    e' <- markAnnotated e+    an1 <- markClosingParen an0+    return (HsCmdPar an1 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 (HsCmdLamCase an matches) = do+    an0 <- markEpAnnL an lidl AnnLam+    an1 <- markEpAnnL an0 lidl AnnCase+    matches' <- markAnnotated matches+    return (HsCmdLamCase an1 matches')++  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 an binds e) = do+    an0 <- markLensKw an lalLet AnnLet+    binds' <- markAnnotated binds+    an1 <- markLensKw an0 lalIn AnnIn+    e' <- markAnnotated e+    return (HsCmdLet an1 binds' e')++  exact (HsCmdDo an es) = do+    debugM $ "HsCmdDo"+    an0 <- markEpAnnL an lal_rest AnnDo+    es' <- markAnnotated es+    return (HsCmdDo an0 es')++  -- exact x = error $ "exact HsCmd for:" ++ showAst x++-- ---------------------------------------------------------------------++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 (LastStmt _ _ _ _)             = NoEntryVal+  getAnnotationEntry (BindStmt an _ _)              = fromAnn an+  getAnnotationEntry (ApplicativeStmt _ _ _)        = NoEntryVal+  getAnnotationEntry (BodyStmt _ _ _ _)             = NoEntryVal+  getAnnotationEntry (LetStmt an _)                 = fromAnn an+  getAnnotationEntry (ParStmt _ _ _ _)              = NoEntryVal+  getAnnotationEntry (TransStmt an _ _ _ _ _ _ _ _) = fromAnn an+  getAnnotationEntry (RecStmt an _ _ _ _ _ _)       = fromAnn an++  -----------------------------------------------------------------++  setAnnotationAnchor a@(LastStmt _ _ _ _)             _ _s = a+  setAnnotationAnchor (BindStmt an a b)              anc cs = (BindStmt (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor a@(ApplicativeStmt _ _ _)        _ _s = a+  setAnnotationAnchor a@(BodyStmt _ _ _ _)             _ _s = a+  setAnnotationAnchor (LetStmt an a)                 anc cs = (LetStmt (setAnchorEpa an anc cs) a)+  setAnnotationAnchor a@(ParStmt _ _ _ _)              _ _s = a+  setAnnotationAnchor (TransStmt an a b c d e f g h) anc cs = (TransStmt (setAnchorEpa an anc cs) a b c d e f g h)+  setAnnotationAnchor (RecStmt an a b c d e f)       anc cs = (RecStmt (setAnchorEpa an anc cs) a b c d e f)++  -----------------------------------------------------------------++  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+    debugM $ "ApplicativeStmt"+    -- TODO: ApplicativeStmt+    -- markAnnotated body+    error $ "need to complete ApplicativeStmt"++  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"+    -- markLocatedAAL an al_rest AnnRec+    an0 <- markEpAnnL an lal_rest AnnRec+    (an1, stmts') <- markAnnList True an0 (markAnnotated stmts)+    return (RecStmt an1 stmts' a b c d e)++  -- exact x = error $ "exact CmdLStmt for:" ++ showAst x+  -- exact x = error $ "exact CmdLStmt for:"+++-- ---------------------------------------------------------------------++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)+  => EpAnn [AddEpAnn] -> Maybe (LHsExpr GhcPs) -> (LHsExpr GhcPs) -> TransForm+  -> EP w m (EpAnn [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 (FamDecl   { })                      = NoEntryVal+  getAnnotationEntry (SynDecl   { tcdSExt = an })         = fromAnn an+  getAnnotationEntry (DataDecl  { tcdDExt = an })         = fromAnn an+  getAnnotationEntry (ClassDecl { tcdCExt = (an, _, _) }) = fromAnn an++  setAnnotationAnchor a@FamDecl{}     _ _s = a+  setAnnotationAnchor x@SynDecl{}   anc cs = x { tcdSExt = setAnchorEpa (tcdSExt x) anc cs }+  setAnnotationAnchor x@DataDecl{}  anc cs = x { tcdDExt = setAnchorEpa (tcdDExt x) anc cs }+  setAnnotationAnchor x@ClassDecl{} anc cs = x { tcdCExt = (setAnchorEpa an anc cs, a, b) }+    where+      (an,a,b) = tcdCExt x++  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+    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', _, _mctxt', defn') <-+      exactDataDefn an (exactVanillaDeclHead ltycon tyvars fixity) defn+    return (DataDecl { tcdDExt = an', tcdLName = ltycon', tcdTyVars = tyvars'+                     , tcdFixity = fixity, tcdDataDefn = defn' })++  -- -----------------------------------++  exact (ClassDecl {tcdCExt = (an, sortKey, lo),+                    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, sortKey, lo),+                             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+          ds <- withSortKey sortKey+                               (prepareListAnnotationA sigs+                             ++ prepareListAnnotationA (bagToList methods)+                             ++ prepareListAnnotationA ats+                             ++ 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, sortKey, lo),+                             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 (FunDep an _ _) = fromAnn an+  setAnnotationAnchor (FunDep an a b) anc cs = FunDep (setAnchorEpa an anc cs) a b++  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 (FamilyDecl { fdExt = an }) = fromAnn an+  setAnnotationAnchor x anc cs = x { fdExt = setAnchorEpa (fdExt x) anc cs}++  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) => EpAnn [AddEpAnn] -> FamilyInfo GhcPs -> EP w m (EpAnn [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)+  => EpAnn [AddEpAnn]+  -> (Maybe (LHsContext GhcPs) -> EP w m (EpAnn [AddEpAnn]+                                         , LocatedN RdrName+                                         , a+                                         , b+                                         , Maybe (LHsContext GhcPs))) -- Printing the header+  -> HsDataDefn GhcPs+  -> EP w m ( EpAnn [AddEpAnn] -- ^ from exactHdr+            , EpAnn [AddEpAnn] -- ^ updated one passed in+            , LocatedN RdrName, a, b, Maybe (LHsContext GhcPs), HsDataDefn GhcPs)+exactDataDefn an exactHdr+                 (HsDataDefn { dd_ext = x, dd_ND = new_or_data, 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 <- if new_or_data == DataType+    then markEpAnnL an' lidl AnnData+    else markEpAnnL an' lidl AnnNewtype+  an1 <- markEpAnnL an0 lidl AnnInstance -- optional+  mb_ct' <- mapM markAnnotated mb_ct+  (anx, ln', tvs', b, mctxt') <- 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 (isGadt condecls)+    then markEpAnnL an2 lidl AnnWhere+    else return an2+  an4 <- markEpAnnL an3 lidl AnnOpenC+  (an5, condecls') <- exact_condecls an4 condecls+  an6 <- markEpAnnL an5 lidl AnnCloseC+  derivings' <- mapM markAnnotated derivings+  return (anx, an6, ln', tvs', b, mctxt',+                 (HsDataDefn { dd_ext = x, dd_ND = new_or_data, 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 ( EpAnn [AddEpAnn]+                               , LocatedN RdrName+                               , LHsQTyVars GhcPs+                               , (), Maybe (LHsContext GhcPs))+exactVanillaDeclHead thing tvs@(HsQTvs { hsq_explicit = tyvars }) fixity context = do+  let+    exact_tyvars (varl:varsr)+      | fixity == Infix && length varsr > 1 = do+          varl' <- markAnnotated varl+          thing' <- markAnnotated thing+          hvarsr <- markAnnotated (head varsr)+          tvarsr <- markAnnotated (tail varsr)+          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 (EpAnnNotUsed, thing', tvs { hsq_explicit = tyvars' }, (), context')++-- ---------------------------------------------------------------------++instance ExactPrint (InjectivityAnn GhcPs) where+  getAnnotationEntry (InjectivityAnn an _ _) = fromAnn an+  setAnnotationAnchor (InjectivityAnn an a b) anc cs = InjectivityAnn (setAnchorEpa an anc cs) a b+  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)+    => EpAnn [AddEpAnn] -> flag -> EP w m (HsTyVarBndr flag GhcPs)+    -> EP w m (EpAnn [AddEpAnn], (HsTyVarBndr flag GhcPs))++instance ExactPrintTVFlag () where+  exactTVDelimiters an _ thing_inside = do+    an0 <- markEpAnnAllL an lid AnnOpenP+    r <- thing_inside+    an1 <- markEpAnnAllL an0 lid AnnCloseP+    return (an1, r)++instance ExactPrintTVFlag Specificity where+  exactTVDelimiters an s thing_inside = do+    an0 <- markEpAnnAllL an lid open+    r <- thing_inside+    an1 <- markEpAnnAllL an0 lid close+    return (an1, r)+    where+      (open, close) = case s of+        SpecifiedSpec -> (AnnOpenP, AnnCloseP)+        InferredSpec  -> (AnnOpenC, AnnCloseC)++instance ExactPrintTVFlag flag => ExactPrint (HsTyVarBndr flag GhcPs) where+  getAnnotationEntry (UserTyVar an _ _)     = fromAnn an+  getAnnotationEntry (KindedTyVar an _ _ _) = fromAnn an++  setAnnotationAnchor (UserTyVar an a b)     anc cs = UserTyVar (setAnchorEpa an anc cs) a b+  setAnnotationAnchor (KindedTyVar an a b c) anc cs = KindedTyVar (setAnchorEpa an anc cs) a b c++  exact (UserTyVar an flag n) = do+    r <- exactTVDelimiters an flag $ do+           n' <- markAnnotated n+           return (UserTyVar an flag n')+    case r of+      (an', UserTyVar _ flag'' n'') -> return (UserTyVar an' flag'' n'')+      _ -> error "KindedTyVar should never happen here"+  exact (KindedTyVar an flag n k) = do+    r <- exactTVDelimiters an flag $ do+          n' <- markAnnotated n+          an0 <- markEpAnnL an lidl AnnDcolon+          k' <- markAnnotated k+          return (KindedTyVar an0 flag n' k')+    case r of+      (an',KindedTyVar _ flag'' n'' k'') -> return (KindedTyVar an' flag'' n'' k'')+      _ -> error "UserTyVar should never happen here"++-- ---------------------------------------------------------------------++instance ExactPrint (HsType GhcPs) where+  getAnnotationEntry (HsForAllTy _ _ _)        = NoEntryVal+  getAnnotationEntry (HsQualTy _ _ _)          = NoEntryVal+  getAnnotationEntry (HsTyVar an _ _)          = fromAnn an+  getAnnotationEntry (HsAppTy _ _ _)           = NoEntryVal+  getAnnotationEntry (HsAppKindTy _ _ _)       = NoEntryVal+  getAnnotationEntry (HsFunTy an _ _ _)        = fromAnn an+  getAnnotationEntry (HsListTy an _)           = fromAnn an+  getAnnotationEntry (HsTupleTy an _ _)        = fromAnn an+  getAnnotationEntry (HsSumTy an _)            = fromAnn an+  getAnnotationEntry (HsOpTy _ _ _ _)          = NoEntryVal+  getAnnotationEntry (HsParTy an _)            = fromAnn an+  getAnnotationEntry (HsIParamTy an _ _)       = fromAnn an+  getAnnotationEntry (HsStarTy _ _)            = NoEntryVal+  getAnnotationEntry (HsKindSig an _ _)        = fromAnn an+  getAnnotationEntry (HsSpliceTy _ _)          = NoEntryVal+  getAnnotationEntry (HsDocTy an _ _)          = fromAnn an+  getAnnotationEntry (HsBangTy an _ _)         = fromAnn an+  getAnnotationEntry (HsRecTy an _)            = fromAnn an+  getAnnotationEntry (HsExplicitListTy an _ _) = fromAnn an+  getAnnotationEntry (HsExplicitTupleTy an _)  = fromAnn an+  getAnnotationEntry (HsTyLit _ _)             = NoEntryVal+  getAnnotationEntry (HsWildCardTy _)          = NoEntryVal+  getAnnotationEntry (XHsType _)               = NoEntryVal++  setAnnotationAnchor a@(HsForAllTy _ _ _)        _ _s = a+  setAnnotationAnchor a@(HsQualTy _ _ _)          _ _s = a+  setAnnotationAnchor (HsTyVar an a b)          anc cs = (HsTyVar (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor a@(HsAppTy _ _ _)           _ _s = a+  setAnnotationAnchor a@(HsAppKindTy _ _ _)       _ _s = a+  setAnnotationAnchor (HsFunTy an a b c)        anc cs = (HsFunTy (setAnchorEpa an anc cs) a b c)+  setAnnotationAnchor (HsListTy an a)           anc cs = (HsListTy (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (HsTupleTy an a b)        anc cs = (HsTupleTy (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (HsSumTy an a)            anc cs = (HsSumTy (setAnchorEpa an anc cs) a)+  setAnnotationAnchor a@(HsOpTy _ _ _ _)          _ _s = a+  setAnnotationAnchor (HsParTy an a)            anc cs = (HsParTy (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (HsIParamTy an a b)       anc cs = (HsIParamTy (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor a@(HsStarTy _ _)            _ _s = a+  setAnnotationAnchor (HsKindSig an a b)        anc cs = (HsKindSig (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor a@(HsSpliceTy _ _)          _ _s = a+  setAnnotationAnchor (HsDocTy an a b)          anc cs = (HsDocTy (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (HsBangTy an a b)         anc cs = (HsBangTy (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (HsRecTy an a)            anc cs = (HsRecTy (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (HsExplicitListTy an a b) anc cs = (HsExplicitListTy (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (HsExplicitTupleTy an a)  anc cs = (HsExplicitTupleTy (setAnchorEpa an anc cs) a)+  setAnnotationAnchor a@(HsTyLit _ _)             _ _s = a+  setAnnotationAnchor a@(HsWildCardTy _)          _ _s = a+  setAnnotationAnchor a@(XHsType _)               _ _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 ss ty ki) = do+    ty' <- markAnnotated ty+    printStringAtSs ss "@"+    ki' <- markAnnotated ki+    return (HsAppKindTy ss ty' ki')+  exact (HsFunTy an mult ty1 ty2) = do+    ty1' <- markAnnotated ty1+    (an', mult') <- markArrow an 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 t1 lo t2) = do+    t1' <- markAnnotated t1+    lo' <- markAnnotated lo+    t2' <- markAnnotated t2+    return (HsOpTy an 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 x@(HsDocTy an _ _)          = withPpr x+  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 <- markEpAnnLMS an lid AnnOpen  (Just src)+          an1 <- markEpAnnLMS an0 lid AnnClose (Just "#-}")+          debugM $ "HsBangTy: done unpackedness"+          return an1+    an1 <-+      case str of+        SrcLazy     -> markEpAnnL an0 lidl AnnTilde+        SrcStrict   -> markEpAnnL an0 lidl AnnBang+        NoSrcStrict -> return an0+    ty' <- markAnnotated ty+    return (HsBangTy an1 (HsSrcBang mt up str) ty')+  -- exact x@(HsRecTy an _)            = withPpr x+  exact (HsExplicitListTy an prom tys) = do+    an0 <- if (isPromoted prom)+             then markEpAnnL an lidl AnnSimpleQuote+             else return an+    an1 <- markEpAnnL an0 lidl AnnOpenS+    tys' <- markAnnotated tys+    an2 <- markEpAnnL an1 lidl AnnCloseS+    return (HsExplicitListTy an2 prom tys')+  exact (HsExplicitTupleTy an tys) = do+    an0 <- markEpAnnL an lidl AnnSimpleQuote+    an1 <- markEpAnnL an0 lidl AnnOpenP+    tys' <- markAnnotated tys+    an2 <- markEpAnnL an1 lidl 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 cs = HsForAllVis (setAnchorEpa an anc cs) a+  setAnnotationAnchor (HsForAllInvis an a) anc cs = HsForAllInvis (setAnchorEpa an anc 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 d@(HsDerivingClause{}) = fromAnn (deriv_clause_ext d)+  setAnnotationAnchor x anc cs = (x { deriv_clause_ext = setAnchorEpa (deriv_clause_ext x) anc cs})+                                   `debug` ("setAnnotationAnchor HsDerivingClause: (anc,cs):" ++ showAst (anc,cs))++  exact (HsDerivingClause { deriv_clause_ext      = an+                          , deriv_clause_strategy = dcs+                          , deriv_clause_tys      = dct }) = do+    an0 <- markEpAnnL an lidl AnnDeriving+    exact_strat_before+    dct' <- markAnnotated dct+    exact_strat_after+    return (HsDerivingClause { deriv_clause_ext      = an0+                             , deriv_clause_strategy = dcs+                             , deriv_clause_tys      = dct' })+      where+        -- -- This complexity is to distinguish between+        -- --    deriving Show+        -- --    deriving (Show)+        -- pp_dct [HsIB { hsib_body = ty }]+        --          = ppr (parenthesizeHsType appPrec ty)+        -- pp_dct _ = parens (interpp'SP dct)++        -- @via@ is unique in that in comes /after/ the class being derived,+        -- so we must special-case it.+        (exact_strat_before, exact_strat_after) =+          case dcs of+            Just v@(L _ ViaStrategy{}) -> (pure (), markAnnotated v >> pure ())+            _                          -> (mapM_ markAnnotated dcs, pure ())++-- ---------------------------------------------------------------------++instance ExactPrint (DerivStrategy GhcPs) where+  getAnnotationEntry (StockStrategy an)    = fromAnn an+  getAnnotationEntry (AnyclassStrategy an) = fromAnn an+  getAnnotationEntry (NewtypeStrategy an)  = fromAnn an+  getAnnotationEntry (ViaStrategy (XViaStrategyPs an  _)) = fromAnn an++  setAnnotationAnchor (StockStrategy an)    anc cs = (StockStrategy (setAnchorEpa an anc cs))+  setAnnotationAnchor (AnyclassStrategy an) anc cs = (AnyclassStrategy (setAnchorEpa an anc cs))+  setAnnotationAnchor (NewtypeStrategy an)  anc cs = (NewtypeStrategy (setAnchorEpa an anc cs))+  setAnnotationAnchor (ViaStrategy (XViaStrategyPs an  a)) anc cs = (ViaStrategy (XViaStrategyPs (setAnchorEpa an anc cs)  a))++  exact s@(StockStrategy an)    = markEpAnn an AnnStock >> return s+  exact s@(AnyclassStrategy an) = markEpAnn an AnnAnyclass >> return s+  exact s@(NewtypeStrategy an)  = markEpAnn an AnnNewtype >> return s+  exact s@(ViaStrategy (XViaStrategyPs an ty))+    = markEpAnn an AnnVia >> markAnnotated ty >> return s++-- ---------------------------------------------------------------------++instance (ExactPrint a) => ExactPrint (LocatedC a) where+  getAnnotationEntry (L sann _) = fromAnn sann+  setAnnotationAnchor = setAnchorAn++  exact (L (SrcSpanAnn EpAnnNotUsed l) a) = do+    a' <- markAnnotated a+    return (L (SrcSpanAnn EpAnnNotUsed l) a')+  exact (L (SrcSpanAnn (EpAnn anc (AnnContext ma opens closes) cs) l) a) = do+    -- mapM_ (markKwA AnnOpenP) (sort opens)+    mapM_ (markKwA AnnOpenP) opens+    a' <- markAnnotated a+    -- mapM_ (markKwA AnnCloseP) (sort closes)+    mapM_ (markKwA AnnCloseP) closes+    case ma of+      Just (UnicodeSyntax, r) -> markKwA AnnDarrowU r >> pure ()+      Just (NormalSyntax,  r) -> markKwA AnnDarrow  r >> pure ()+      Nothing -> pure ()+    return (L (SrcSpanAnn (EpAnn anc (AnnContext ma opens closes) cs) l) 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 x@(L (SrcSpanAnn EpAnnNotUsed l) n) = do+    printUnicode (spanAsAnchor l) n+    return x+  exact (L (SrcSpanAnn (EpAnn anc ann cs) ll) n) = do+    ann' <-+      case ann of+        NameAnn a o l c t -> do+          mn <- markName a o (Just (l,n)) c+          -- let (o', (Just (l',_)), c') =+          --       case mn of+          --        (o', (Just (l',n')), c') -> (o', (Just (l',n')), c')+          --        _ -> error "ExactPrint (LocatedN RdrName)"+          -- t' <- markTrailing t+          -- return (NameAnn a o' l' c' t')+          case mn of+            (o', (Just (l',_n)), c') -> do -- (o', (Just (l',n')), c')+              t' <- markTrailing t+              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)+          t' <- markTrailing t+          return (NameAnnCommas a o' commas' c' t')+        NameAnnOnly a o c t -> do+          (o',_,c') <- markName a o Nothing c+          t' <- markTrailing t+          return (NameAnnOnly a o' c' t')+        NameAnnRArrow nl t -> do+          (AddEpAnn _ nl') <- markKwC NoCaptureComments (AddEpAnn AnnRarrow nl)+          t' <- markTrailing t+          return (NameAnnRArrow nl' t')+        NameAnnQuote q name t -> do+          debugM $ "NameAnnQuote"+          (AddEpAnn _ q') <- markKwC NoCaptureComments (AddEpAnn AnnSimpleQuote q)+          (L name' _) <- markAnnotated (L name n)+          t' <- markTrailing t+          return (NameAnnQuote q' name' t')+        NameAnnTrailing t -> do+          anc' <- printUnicode anc n+          t' <- markTrailing t+          return (NameAnnTrailing t')+    return (L (SrcSpanAnn (EpAnn anc ann' cs) ll) 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 anc { anchor_op = MovedAnchor 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)+++markTrailingL :: (Monad m, Monoid w) => EpAnn a -> Lens a [TrailingAnn] -> EP w m (EpAnn a)+markTrailingL EpAnnNotUsed _ = return EpAnnNotUsed+markTrailingL (EpAnn anc an cs) l = do+  ts <- mapM markKwT (view l an)+  return (EpAnn anc (set l ts an) cs)++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)+  => EpAnn [AddEpAnn] -> [LConDecl GhcPs] -> EP w m (EpAnn [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 x@(ConDeclGADT{}) = fromAnn (con_g_ext x)+  getAnnotationEntry x@(ConDeclH98{})  = fromAnn (con_ext x)++  setAnnotationAnchor x@ConDeclGADT{} anc cs = x { con_g_ext = setAnchorEpa (con_g_ext x) anc cs}+  setAnnotationAnchor x@ConDeclH98{}  anc cs = x { con_ext   = setAnchorEpa (con_ext x) anc cs}++-- 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+    doc' <- mapM markAnnotated doc+    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 = an+                     , con_names = cons+                     , con_bndrs = bndrs+                     , con_mb_cxt = mcxt, con_g_args = args+                     , con_res_ty = res_ty, con_doc = doc }) = do+    doc' <- mapM markAnnotated doc+    cons' <- mapM markAnnotated cons+    an0 <- markEpAnnL an lidl AnnDcolon+    an1 <- annotationsToComments an0 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 args0) -> do+            args0' <- mapM markScaled args0+            return (PrefixConGADT args0')+          (RecConGADT fields) -> do+            fields' <- markAnnotated fields+            return (RecConGADT fields')+    res_ty' <- markAnnotated res_ty+    return (ConDeclGADT { con_g_ext = 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 cs = HsOuterExplicit (setAnchorEpa an anc 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 f@(ConDeclField{}) = fromAnn (cd_fld_ext f)++  setAnnotationAnchor x anc cs = x { cd_fld_ext = setAnchorEpa (cd_fld_ext x) anc cs}++  exact (ConDeclField an names ftype mdoc) = do+    names' <- markAnnotated names+    an0 <- markEpAnnL an lidl AnnDcolon+    ftype' <- markAnnotated ftype+    mdoc' <- mapM markAnnotated mdoc+    return (ConDeclField an0 names' ftype' mdoc')++-- ---------------------------------------------------------------------++instance ExactPrint (FieldOcc GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ = a+  exact f@(FieldOcc _ n) = markAnnotated n >> return f++-- ---------------------------------------------------------------------++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++-- ---------------------------------------------------------------------++markScaled :: (Monad m, Monoid w)+  => HsScaled GhcPs (LBangType GhcPs) -> EP w m (HsScaled GhcPs (LBangType GhcPs))+markScaled (HsScaled arr (L l c)) = do+  (L l1 (HsScaled arr' (L l2 c'))) <- markAnnotated (L l (HsScaled arr (L (noAnnSrcSpan $ locA l) c))+                 :: LocatedA (HsScaled GhcPs (LBangType GhcPs)))+  let l' = l1 <> l2+  return (HsScaled arr' (L l' c'))++instance (ExactPrint a) => ExactPrint (HsScaled GhcPs a) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ = a+  exact (HsScaled arr t) = do+    t' <- markAnnotated t+    (_, arr') <- markArrow EpAnnNotUsed arr+    return (HsScaled arr' t')++-- ---------------------------------------------------------------------++instance ExactPrint (LocatedP CType) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor = setAnchorAn++  exact x@(L (SrcSpanAnn EpAnnNotUsed _) ct) = withPpr ct >> return x+  exact (L (SrcSpanAnn an ll)+         (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 (SrcSpanAnn an3 ll)+         (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 (SrcSpanAnn an l) ies) = do+    debugM $ "LocatedL [LIE"+    an0 <- markEpAnnL an lal_rest AnnHiding+    p <- getPosP+    debugM $ "LocatedL [LIE:p=" ++ showPprUnsafe p+    (an1, ies') <- markAnnList True an0 (markAnnotated ies)+    return (L (SrcSpanAnn an1 l) ies')++instance (ExactPrint (Match GhcPs (LocatedA body)))+   => ExactPrint (LocatedL [LocatedA (Match GhcPs (LocatedA body))]) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor = setAnchorAn+  exact (L la a) = do+    let an = ann la+    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 (la { ann = an3}) a')++-- instance ExactPrint (LocatedL [ExprLStmt GhcPs]) where+instance ExactPrint (LocatedL [LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs)))]) where+  getAnnotationEntry = entryFromLocatedAFixed+  setAnnotationAnchor = setAnchorAn+  exact (L (SrcSpanAnn an' l) stmts) = do+    let an = fixAnnListAnn an'+    debugM $ "LocatedL [ExprLStmt"+    (an'', stmts') <- markAnnList True an $ do+      -- markLocatedMAA an al_open+      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+        -- x -> error $ "pprDo:ListComp" ++ showAst x+      -- markLocatedMAA an al_close+    return (L (SrcSpanAnn an'' l) stmts')++-- instance ExactPrint (LocatedL [CmdLStmt GhcPs]) where+instance ExactPrint (LocatedL [LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsCmd GhcPs)))]) where+  getAnnotationEntry = entryFromLocatedAFixed+  setAnnotationAnchor = setAnchorAn+  exact (L (SrcSpanAnn ann' l) es) = do+    let ann = fixAnnListAnn ann'+    debugM $ "LocatedL [CmdLStmt"+    an0 <- markLensMAA ann lal_open+    es' <- mapM markAnnotated es+    an1 <- markLensMAA an0 lal_close+    return (L (SrcSpanAnn an1 l) es')++instance ExactPrint (LocatedL [LocatedA (ConDeclField GhcPs)]) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor = setAnchorAn+  exact (L (SrcSpanAnn an l) fs) = do+    debugM $ "LocatedL [LConDeclField"+    (an', fs') <- markAnnList True an (markAnnotated fs)+    return (L (SrcSpanAnn an' l) fs')++instance ExactPrint (LocatedL (BF.BooleanFormula (LocatedN RdrName))) where+  getAnnotationEntry = entryFromLocatedA+  setAnnotationAnchor = setAnchorAn+  exact (L (SrcSpanAnn an l) bf) = do+    debugM $ "LocatedL [LBooleanFormula"+    (an', bf') <- markAnnList True an (markAnnotated bf)+    return (L (SrcSpanAnn an' l) bf')++-- ---------------------------------------------------------------------+-- LocatedL instances end --+-- =====================================================================++instance ExactPrint (IE GhcPs) where+  getAnnotationEntry (IEVar _ _)            = NoEntryVal+  getAnnotationEntry (IEThingAbs an _)      = fromAnn an+  getAnnotationEntry (IEThingAll an _)      = fromAnn an+  getAnnotationEntry (IEThingWith an _ _ _) = fromAnn an+  getAnnotationEntry (IEModuleContents an _)= fromAnn an+  getAnnotationEntry (IEGroup _ _ _)        = NoEntryVal+  getAnnotationEntry (IEDoc _ _)            = NoEntryVal+  getAnnotationEntry (IEDocNamed _ _)       = NoEntryVal++  setAnnotationAnchor a@(IEVar _ _)             _ _s = a+  setAnnotationAnchor (IEThingAbs an a)       anc cs = (IEThingAbs (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (IEThingAll an a)       anc cs = (IEThingAll (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (IEThingWith an a b c)  anc cs = (IEThingWith (setAnchorEpa an anc cs) a b c)+  setAnnotationAnchor (IEModuleContents an a) anc cs = (IEModuleContents (setAnchorEpa an anc cs) a)+  setAnnotationAnchor a@(IEGroup _ _ _)         _ _s = a+  setAnnotationAnchor a@(IEDoc _ _)             _ _s = a+  setAnnotationAnchor a@(IEDocNamed _ _)        _ _s = a++  exact (IEVar x ln) = do+    ln' <- markAnnotated ln+    return (IEVar x ln')+  exact (IEThingAbs x thing) = do+    thing' <- markAnnotated thing+    return (IEThingAbs x thing')+  exact (IEThingAll an thing) = do+    thing' <- markAnnotated thing+    an0 <- markEpAnnL an  lidl AnnOpenP+    an1 <- markEpAnnL an0 lidl AnnDotdot+    an2 <- markEpAnnL an1 lidl AnnCloseP+    return (IEThingAll an2 thing')++  exact (IEThingWith an thing wc withs) = do+    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+    return (IEThingWith an2 thing' wc' withs')++  exact (IEModuleContents an m) = do+    an0 <- markEpAnnL an lidl AnnModule+    m' <- markAnnotated m+    return (IEModuleContents an0 m')++  -- exact (IEGroup _ _ _)          = NoEntryVal+  -- exact (IEDoc _ _)              = NoEntryVal+  -- exact (IEDocNamed _ _)         = NoEntryVal+  exact x = error $ "missing match for IE:" ++ showAst x++-- ---------------------------------------------------------------------++instance ExactPrint (IEWrappedName RdrName) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ = a++  exact (IEName n) = do+    n' <- markAnnotated n+    return (IEName 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 (WildPat _)              = NoEntryVal+  getAnnotationEntry (VarPat _ _)             = NoEntryVal+  getAnnotationEntry (LazyPat an _)           = fromAnn an+  getAnnotationEntry (AsPat an _ _)           = fromAnn an+  getAnnotationEntry (ParPat an _)            = fromAnn an+  getAnnotationEntry (BangPat an _)           = fromAnn an+  getAnnotationEntry (ListPat an _)           = fromAnn an+  getAnnotationEntry (TuplePat an _ _)        = fromAnn an+  getAnnotationEntry (SumPat an _ _ _)        = fromAnn an+  getAnnotationEntry (ConPat an _ _)          = fromAnn an+  getAnnotationEntry (ViewPat an _ _)         = fromAnn an+  getAnnotationEntry (SplicePat _ _)          = NoEntryVal+  getAnnotationEntry (LitPat _ _)             = NoEntryVal+  getAnnotationEntry (NPat an _ _ _)          = fromAnn an+  getAnnotationEntry (NPlusKPat an _ _ _ _ _) = fromAnn an+  getAnnotationEntry (SigPat an _ _)          = fromAnn an++  setAnnotationAnchor a@(WildPat _)              _ _s = a+  setAnnotationAnchor a@(VarPat _ _)             _ _s = a+  setAnnotationAnchor (LazyPat an a)            anc cs = (LazyPat (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (AsPat an a b)            anc cs = (AsPat (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (ParPat an a)             anc cs = (ParPat (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (BangPat an a)            anc cs = (BangPat (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (ListPat an a)            anc cs = (ListPat (setAnchorEpa an anc cs) a)+  setAnnotationAnchor (TuplePat an a b)         anc cs = (TuplePat (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (SumPat an a b c)         anc cs = (SumPat (setAnchorEpa an anc cs) a b c)+  setAnnotationAnchor (ConPat an a b)           anc cs = (ConPat (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor (ViewPat an a b)          anc cs = (ViewPat (setAnchorEpa an anc cs) a b)+  setAnnotationAnchor a@(SplicePat _ _)         _ _s = a+  setAnnotationAnchor a@(LitPat _ _)            _ _s = a+  setAnnotationAnchor (NPat an a b c)          anc cs = (NPat (setAnchorEpa an anc cs) a b c)+  setAnnotationAnchor (NPlusKPat an a b c d e) anc cs = (NPlusKPat (setAnchorEpa an anc cs) a b c d e)+  setAnnotationAnchor (SigPat an a b)          anc cs = (SigPat (setAnchorEpa an anc cs) a b)++  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 an n pat) = do+    n' <- markAnnotated n+    an0 <- markEpAnnL an lidl AnnAt+    pat' <- markAnnotated pat+    return (AsPat an0 n' pat')+  exact (ParPat an pat) = do+    an0 <- markAnnKwL an lap_open AnnOpenP+    pat' <- markAnnotated pat+    an1 <- markAnnKwL an0 lap_close AnnCloseP+    return (ParPat an1 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 True 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)++  -- | ConPat an con args)+  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)++  -- | NPlusKPat an n lit1 lit2 _ _)+  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')++-- ---------------------------------------------------------------------++instance ExactPrint (HsPatSigType GhcPs) where+  getAnnotationEntry = const NoEntryVal+  setAnnotationAnchor a _ _ = a++  exact (HsPS an ty) = do+    an0 <- markAnnKwL an lid AnnAt+    ty' <- markAnnotated ty+    return (HsPS an0 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 s >> return ol+        NoSourceText -> return ol++-- ---------------------------------------------------------------------++hsLit2String :: HsLit GhcPs -> String+hsLit2String lit =+  case lit of+    HsChar       src v   -> toSourceTextWithSuffix src v ""+    -- It should be included here+    -- https://github.com/ghc/ghc/blob/master/compiler/parser/Lexer.x#L1471+    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 ""+    HsInt64Prim  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 "##"+    -- (XLit x) -> error $ "got XLit for:" ++ showPprUnsafe x++toSourceTextWithSuffix :: (Show a) => SourceText -> a -> String -> String+toSourceTextWithSuffix (NoSourceText)    alt suffix = show alt ++ suffix+toSourceTextWithSuffix (SourceText txt) _alt suffix = txt ++ suffix++sourceTextToString :: SourceText -> String -> String+sourceTextToString NoSourceText alt   = alt+sourceTextToString (SourceText txt) _ = txt++-- ---------------------------------------------------------------------++exactUserCon :: (Monad m, Monoid w, ExactPrint con)+  => EpAnn [AddEpAnn] -> con -> HsConPatDetails GhcPs+  -> EP w m (EpAnn [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')++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 :: LocatedAn ann a -> Entry+entryFromLocatedA (L la _) = fromAnn la++-- See https://gitlab.haskell.org/ghc/ghc/-/issues/20256+entryFromLocatedAFixed :: LocatedL a -> Entry+entryFromLocatedAFixed (L la _)+  = fromAnn (fixSrcAnnL 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+        -- `debug` ("printStringAtLsDelta:(pos,s):" ++ show (undelta p cl colOffset,s))+      p' <- getPosP+      d <- getPriorEndD+      debugM $ "printStringAtLsDelta:(pos,p',d,s):" ++ show (undelta p cl colOffset,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) => RealSrcSpan -> Comment -> DeltaPos -> EP w m ()+printQueuedComment loc 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+    -- setPriorEndASTD False loc+  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})++getPriorEndD :: (Monad m, Monoid w) => EP w m Pos+getPriorEndD = gets dPriorEndPosition++getAnchorU :: (Monad m, Monoid w) => EP w m RealSrcSpan+getAnchorU = gets uAnchorSpan++setPriorEndD :: (Monad m, Monoid w) => Pos -> EP w m ()+setPriorEndD pe = do+  setPriorEndNoLayoutD pe++setPriorEndNoLayoutD :: (Monad m, Monoid w) => Pos -> EP w m ()+setPriorEndNoLayoutD pe = do+  debugM $ "setPriorEndNoLayoutD:pe=" ++ show pe+  modify (\s -> s { dPriorEndPosition = pe })++setPriorEndASTD :: (Monad m, Monoid w) => Bool -> RealSrcSpan -> EP w m ()+setPriorEndASTD layout pe = setPriorEndASTPD layout (rs2range pe)++setPriorEndASTPD :: (Monad m, Monoid w) => Bool -> (Pos,Pos) -> EP w m ()+setPriorEndASTPD layout pe@(fm,to) = do+  debugM $ "setPriorEndASTD:pe=" ++ show pe+  when layout $ setLayoutStartD (snd fm)+  modify (\s -> s { dPriorEndPosition = to } )++setLayoutStartD :: (Monad m, Monoid w) => Int -> EP w m ()+setLayoutStartD p = do+  EPState{dMarkLayout} <- get+  when dMarkLayout $ do+    debugM $ "setLayoutStartD: setting dLHS=" ++ show p+    modify (\s -> s { dMarkLayout = False+                    , dLHS = LayoutStartCol p})++getLayoutOffsetD :: (Monad m, Monoid w) => EP w m LayoutStartCol+getLayoutOffsetD = gets dLHS++setAnchorU :: (Monad m, Monoid w) => RealSrcSpan -> EP w m ()+setAnchorU rss = do+  debugM $ "setAnchorU:" ++ show (rs2range rss)+  modify (\s -> s { uAnchorSpan = rss })++getUnallocatedComments :: (Monad m, Monoid w) => EP w m [Comment]+getUnallocatedComments = gets epComments++putUnallocatedComments :: (Monad m, Monoid w) => [Comment] -> EP w m ()+putUnallocatedComments cs = modify (\s -> s { epComments = cs } )++-- | Push a fresh stack frame for the applied comments gatherer+pushAppliedComments  :: (Monad m, Monoid w) => EP w m ()+pushAppliedComments = modify (\s -> s { epCommentsApplied = []:(epCommentsApplied s) })++-- | Return the comments applied since the last call+-- takeAppliedComments, and clear them, not popping the stack+takeAppliedComments :: (Monad m, Monoid w) => EP w m [Comment]+takeAppliedComments = do+  ccs <- gets epCommentsApplied+  case ccs of+    [] -> do+      modify (\s -> s { epCommentsApplied = [] })+      return []+    h:t -> do+      modify (\s -> s { epCommentsApplied = []:t })+      return (reverse h)++-- | Return the comments applied since the last call+-- takeAppliedComments, and clear them, popping the stack+takeAppliedCommentsPop :: (Monad m, Monoid w) => EP w m [Comment]+takeAppliedCommentsPop = do+  ccs <- gets epCommentsApplied+  case ccs of+    [] -> do+      modify (\s -> s { epCommentsApplied = [] })+      return []+    h:t -> do+      modify (\s -> s { epCommentsApplied = t })+      return (reverse h)++-- | Mark a comment as being applied.  This is used to update comments+-- when doing delta processing+applyComment :: (Monad m, Monoid w) => Comment -> EP w m ()+applyComment c = do+  ccs <- gets epCommentsApplied+  case ccs of+    []    -> modify (\s -> s { epCommentsApplied = [[c]] } )+    (h:t) -> modify (\s -> s { epCommentsApplied = (c:h):t } )++getLayoutOffsetP :: (Monad m, Monoid w) => EP w m LayoutStartCol+getLayoutOffsetP = gets pLHS++setLayoutOffsetP :: (Monad m, Monoid w) => LayoutStartCol -> EP w m ()+setLayoutOffsetP c = do+  debugM $ "setLayoutOffsetP:" ++ show c+  modify (\s -> s { pLHS = c })+++-- ---------------------------------------------------------------------++advance :: (Monad m, Monoid w) => DeltaPos -> EP w m ()+advance dp = do+  p <- getPosP+  colOffset <- getLayoutOffsetP+  debugM $ "advance:(p,dp,colOffset,ws)=" ++ show (p,dp,colOffset,undelta p dp colOffset)+  if isGoodDelta dp+    then do+      printWhitespace (undelta p dp colOffset)+      -- Sync point. We only call advance as we start the sub-span+      -- processing, so force the dPriorEndPosition to ???+      p <- getPosP+      d <- getPriorEndD+      r <- getAnchorU+      setPriorEndD (fst $ rs2range r)+      debugM $ "advance:after: (posp, posd, posd')=" ++ show (p,d,fst $ rs2range r)+    else+      return ()++-- ---------------------------------------------------------------------++adjustDeltaForOffsetM :: (Monad m, Monoid w) => DeltaPos -> EP w m DeltaPos+adjustDeltaForOffsetM dp = do+  colOffset <- getLayoutOffsetD+  return (adjustDeltaForOffset colOffset dp)++-- ---------------------------------------------------------------------+-- Printing functions++printString :: (Monad m, Monoid w) => Bool -> String -> EP w m ()+printString layout str = do+  EPState{epPos = (_,c), pMarkLayout} <- get+  EPOptions{epTokenPrint, epWhitespacePrint} <- ask+  when (pMarkLayout && layout) $ do+    debugM $ "printString: setting pLHS to " ++ show c+    modify (\s -> s { pLHS = LayoutStartCol c, pMarkLayout = False } )++  -- Advance position, taking care of any newlines in the string+  let strDP = dpFromString str+      cr = getDeltaLine strDP+  p <- getPosP+  d <- getPriorEndD+  colOffsetP <- getLayoutOffsetP+  colOffsetD <- getLayoutOffsetD+  -- debugM $ "printString:(p,colOffset,strDP,cr)="  ++ show (p,colOffset,strDP,cr)+  if cr == 0+    then do+      setPosP      (undelta p strDP colOffsetP)+      setPriorEndD (undelta d strDP colOffsetD)+    else do+      setPosP      (undelta p strDP 1)+      setPriorEndD (undelta d strDP 1)++  -- Debug stuff+  -- pp <- getPosP+  -- debugM $ "printString: (p,pp,str)" ++ show (p,pp,str)+  -- Debug end++  --+  if not layout && c == 0+    then lift (epWhitespacePrint str) >>= \s -> tell EPWriter { output = s}+    else lift (epTokenPrint      str) >>= \s -> tell EPWriter { output = s}++--------------------------------------------------------++printStringAdvance :: (Monad m, Monoid w) => String -> EP w m ()+printStringAdvance str = do+  ss <- getAnchorU+  _ <- printStringAtRs ss str+  return ()++--------------------------------------------------------++newLine :: (Monad m, Monoid w) => EP w m ()+newLine = do+    (l,_) <- getPosP+    (ld,_) <- getPriorEndD+    printString False "\n"+    setPosP (l+1,1)+    setPriorEndNoLayoutD (ld+1,1)  padUntil :: (Monad m, Monoid w) => Pos -> EP w m () padUntil (l,c) = do
src/Language/Haskell/GHC/ExactPrint/Lookup.hs view
@@ -1,7 +1,7 @@ module Language.Haskell.GHC.ExactPrint.Lookup   (     keywordToString-  , KeywordId(..)+  , AnnKeywordId(..)   , Comment(..)   ) where @@ -12,118 +12,115 @@ -- There is no specific mapping for the following constructors. -- `AnnOpen`, `AnnClose`, `AnnVal`, `AnnPackageName`, `AnnHeader`, `AnnFunId`, -- `AnnInfix`-keywordToString :: KeywordId -> String+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.-      AnnComment _      -> mkErr kw-      AnnString _       -> mkErr kw-      AnnSemiSep        -> ";"-      (G AnnAnyclass) -> "anyclass"-      (G AnnOpen  ) -> mkErr kw-      (G AnnClose ) -> mkErr kw-      (G AnnVal   ) -> mkErr kw-      (G AnnPackageName) -> mkErr kw-      (G AnnHeader ) -> mkErr kw-      (G AnnFunId  ) -> mkErr kw-      (G AnnInfix  ) -> mkErr kw-      (G AnnValStr ) -> mkErr kw-      (G AnnName   ) -> mkErr kw-      (G AnnAs     ) -> "as"-      (G AnnAt     ) -> "@"-      (G AnnBang   ) -> "!"-      (G AnnBackquote ) -> "`"-      (G AnnBy     ) -> "by"-      (G AnnCase   ) -> "case"-      (G AnnClass   ) -> "class"-      (G AnnCloseB  ) -> "|)"-      (G AnnCloseBU ) -> "⦈"-      (G AnnCloseC  ) -> "}"-      (G AnnCloseP  ) -> ")"-      (G AnnClosePH ) -> "#)"-      (G AnnCloseQ  ) -> "|]"-      (G AnnCloseQU ) -> "⟧"-      (G AnnCloseS  ) -> "]"-      (G AnnColon   ) -> ":"-      (G AnnComma   ) -> ","-      (G AnnCommaTuple ) -> ","-      (G AnnDarrow  ) -> "=>"-      (G AnnData    ) -> "data"-      (G AnnDcolon  ) -> "::"-      (G AnnDefault ) -> "default"-      (G AnnDeriving ) -> "deriving"-      (G AnnDo       ) -> "do"-      (G AnnDot      ) -> "."-      (G AnnDotdot   ) -> ".."-      (G AnnElse     ) -> "else"-      (G AnnEqual    ) -> "="-      (G AnnExport   ) -> "export"-      (G AnnFamily   ) -> "family"-      (G AnnForall   ) -> "forall"-      (G AnnForeign  ) -> "foreign"-      (G AnnGroup    ) -> "group"-      (G AnnHiding   ) -> "hiding"-      (G AnnIf       ) -> "if"-      (G AnnImport   ) -> "import"-      (G AnnIn       ) -> "in"-      (G AnnInstance ) -> "instance"-      (G AnnLam      ) -> "\\"-      (G AnnLarrow   ) -> "<-"-      (G AnnLet      ) -> "let"-      (G AnnLollyU   ) -> "⊸"-      (G AnnMdo      ) -> "mdo"-      (G AnnMinus    ) -> "-"-      (G AnnModule   ) -> "module"-      (G AnnNewtype  ) -> "newtype"-      (G AnnOf       ) -> "of"-      (G AnnOpenB    ) -> "(|"-      (G AnnOpenBU   ) ->  "⦇"-      (G AnnOpenC    ) -> "{"-      (G AnnOpenE    ) -> "[e|"-      (G AnnOpenEQ   ) -> "[|"-      (G AnnOpenEQU  ) ->  "⟦"-      (G AnnOpenP    ) -> "("-      (G AnnOpenPH   ) -> "(#"-      (G AnnOpenS    ) -> "["-      (G AnnPattern  ) -> "pattern"-      (G AnnPercent   ) -> "%"-      (G AnnPercentOne) -> "%1"-      (G AnnProc     ) -> "proc"-      (G AnnQualified ) -> "qualified"-      (G AnnRarrow   ) -> "->"-      (G AnnRec      ) -> "rec"-      (G AnnRole     ) -> "role"-      (G AnnSafe     ) -> "safe"-      (G AnnSemi     ) -> ";"-      (G AnnSignature) -> "signature"-      (G AnnStock    ) -> "stock"-      (G AnnStatic   ) -> "static"-      (G AnnThen     ) -> "then"-      (G AnnTilde    ) -> "~"-      (G AnnType     ) -> "type"-      (G AnnUnit     ) -> "()"-      (G AnnUsing    ) -> "using"-      (G AnnVbar     ) -> "|"-      (G AnnWhere    ) -> "where"-      (G Annlarrowtail ) -> "-<"-      (G Annrarrowtail ) -> ">-"-      (G AnnLarrowtail ) -> "-<<"-      (G AnnRarrowtail ) -> ">>-"-      (G AnnSimpleQuote  ) -> "'"-      (G AnnThTyQuote    ) -> "''"-      (G AnnDollar       ) -> "$"-      (G AnnDollarDollar ) -> "$$"-      (G AnnDarrowU) -> "⇒"-      (G AnnDcolonU) -> "∷"-      (G AnnForallU) -> "∀"-      (G AnnLarrowU) -> "←"-      (G AnnLarrowtailU) -> "⤛"-      (G AnnRarrowU) -> "→"-      (G AnnRarrowtailU) -> "⤜"-      (G AnnlarrowtailU) -> "⤙"-      (G AnnrarrowtailU) -> "⤚"-      AnnTypeApp             -> "@"-      (G AnnVia) -> "via"+      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"+      AnnAt    -> "@"+      AnnBang  -> "!"+      AnnBackquote-> "`"+      AnnBy    -> "by"+      AnnCase  -> "case"+      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 -> "⤚"+      -- AnnTypeApp             -> "@"+      AnnVia -> "via"
+ src/Language/Haskell/GHC/ExactPrint/Orphans.hs view
@@ -0,0 +1,108 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}++module Language.Haskell.GHC.ExactPrint.Orphans where++import GHC hiding (EpaComment)++-- ---------------------------------------------------------------------+-- Orphan Monoid instances. See https://gitlab.haskell.org/ghc/ghc/-/issues/20372++instance Semigroup AnnPragma where+  (<>) = error "unimplemented"+instance Monoid AnnPragma where+  mempty = error "meaningless"++instance Semigroup EpAnnImportDecl where+  (<>) = error "unimplemented"+instance Monoid EpAnnImportDecl where+  mempty = error "meaningless"++instance Semigroup HsRuleAnn where+  (<>) = error "unimplemented"+instance Monoid HsRuleAnn where+  mempty = error "meaningless"++instance Semigroup AnnSig where+  (<>) = error "unimplemented"+instance Monoid AnnSig where+  mempty = error "meaningless"++instance Semigroup GrhsAnn where+  (<>) = error "unimplemented"+instance Monoid GrhsAnn where+  mempty = error "meaningless"++instance Semigroup EpAnnUnboundVar where+  (<>) = error "unimplemented"+instance Monoid EpAnnUnboundVar where+  mempty = error "meaningless"++instance Semigroup NoEpAnns where+  (<>) = error "unimplemented"+instance Monoid NoEpAnns where+  mempty = error "meaningless"++instance Semigroup AnnParen where+  (<>) = error "unimplemented"+instance Monoid AnnParen where+  mempty = error "meaningless"++instance Semigroup AnnExplicitSum where+  (<>) = error "unimplemented"+instance Monoid AnnExplicitSum where+  mempty = error "meaningless"++instance Semigroup EpAnnHsCase where+  (<>) = error "unimplemented"+instance Monoid EpAnnHsCase where+  mempty = error "meaningless"++instance Semigroup AnnsIf where+  (<>) = error "unimplemented"+instance Monoid AnnsIf where+  mempty = error "meaningless"++instance Semigroup AnnsLet where+  (<>) = error "unimplemented"+instance Monoid AnnsLet where+  mempty = error "meaningless"++instance Semigroup AnnProjection where+  (<>) = error "unimplemented"+instance Monoid AnnProjection where+  mempty = error "meaningless"++instance Semigroup AnnFieldLabel where+  (<>) = error "unimplemented"+instance Monoid AnnFieldLabel where+  mempty = error "meaningless"++instance Semigroup EpaLocation where+  (<>) = error "unimplemented"+instance Monoid EpaLocation where+  mempty = error "meaningless"++instance Semigroup AddEpAnn where+  (<>) = error "unimplemented"+instance Monoid AddEpAnn where+  mempty = error "meaningless"++instance Semigroup TrailingAnn where+  (<>) = error "unimplemented"+instance Monoid TrailingAnn where+  mempty = error "meaningless"++instance Semigroup AnnContext where+  (<>) = error "unimplemented"+instance Monoid AnnContext where+  mempty = AnnContext Nothing [] []++instance Semigroup EpAnnSumPat where+  (<>) = error "unimplemented"+instance Monoid EpAnnSumPat where+  mempty = error "meaningless"++instance Semigroup AnnsModule where+  (<>) = error "unimplemented"+instance Monoid AnnsModule where+  mempty = error "meaningless"
src/Language/Haskell/GHC/ExactPrint/Parsers.hs view
@@ -111,7 +111,7 @@ -- @ -- myParser fname expr = withDynFlags (\\d -> parseExpr d fname expr) -- @-withDynFlags :: FilePath -> (GHC.DynFlags -> a) -> IO a+withDynFlags :: LibDir -> (GHC.DynFlags -> a) -> IO a withDynFlags libdir action = ghcWrapper libdir $ do   dflags <- GHC.getSessionDynFlags   void $ GHC.setSessionDynFlags dflags@@ -171,7 +171,7 @@ -- string; the `FilePath` parameter solely exists to provide a name -- in source location annotations. parseModuleFromString-  :: FilePath -- GHC libdir+  :: LibDir -- GHC libdir   -> FilePath   -> String   -> IO (ParseResult GHC.ParsedSource)@@ -188,7 +188,7 @@         GHC.POk     _  pmod -> Right (lp, dflags, pmod)   in  postParseTransform res -parseModuleWithOptions :: FilePath -- ^ GHC libdir+parseModuleWithOptions :: LibDir -- ^ GHC libdir                        -> FilePath                        -> IO (ParseResult GHC.ParsedSource) parseModuleWithOptions libdir fp =@@ -197,7 +197,7 @@  -- | Parse a module with specific instructions for the C pre-processor. parseModuleWithCpp-  :: FilePath -- ^ GHC libdir+  :: LibDir -- ^ GHC libdir   -> CppOptions   -> FilePath -- ^ File to be parsed   -> IO (ParseResult GHC.ParsedSource)@@ -211,7 +211,7 @@ -- It is advised to use 'parseModule' or 'parseModuleWithCpp' instead of -- this function. parseModuleEpAnnsWithCpp-  :: FilePath -- ^ GHC libdir+  :: LibDir -- ^ GHC libdir   -> CppOptions   -> FilePath -- ^ File to be parsed   -> IO@@ -224,7 +224,7 @@   parseModuleEpAnnsWithCppInternal cppOptions dflags file  -- | Internal function. Default runner of GHC.Ghc action in IO.-ghcWrapper :: FilePath -> GHC.Ghc a -> IO a+ghcWrapper :: LibDir -> GHC.Ghc a -> IO a ghcWrapper libdir a =   GHC.defaultErrorHandler GHC.defaultFatalMessager GHC.defaultFlushOut     $ GHC.runGhc (Just libdir) a
src/Language/Haskell/GHC/ExactPrint/Preprocess.hs view
@@ -76,14 +76,14 @@            size   = length pragma            mSrcLoc = mkSrcLoc (mkFastString "LINE")            ss     = mkSrcSpan (mSrcLoc line 1) (mSrcLoc line (size+1))-       in (res, Just $ mkLEpaComment pragma (GHC.spanAsAnchor ss))+       in (res, Just $ mkLEpaComment pragma (GHC.spanAsAnchor ss) (GHC.realSrcSpan ss))   -- Deal with shebang/cpp directives too   -- x |  "#" `isPrefixOf` s = ("",Just $ Comment ((line, 1), (line, length s)) s)   |  "#!" `isPrefixOf` s =     let mSrcLoc = mkSrcLoc (mkFastString "SHEBANG")         ss = mkSrcSpan (mSrcLoc line 1) (mSrcLoc line (length s))     in-    ("",Just $ mkLEpaComment s (GHC.spanAsAnchor ss))+    ("",Just $ mkLEpaComment s (GHC.spanAsAnchor ss) (GHC.realSrcSpan ss))   | otherwise = (s, Nothing)  getPragma :: String -> (String, String)@@ -126,8 +126,8 @@ goodComment c = isGoodComment (tokComment c)   where     isGoodComment :: Comment -> Bool-    isGoodComment (Comment "" _ _) = False-    isGoodComment _              = True+    isGoodComment (Comment "" _ _ _) = False+    isGoodComment _                  = True   toRealLocated :: GHC.Located a -> GHC.RealLocated a@@ -169,7 +169,7 @@     missingAsComments = map mkCommentTok missingToks       where         mkCommentTok :: (GHC.Located GHC.Token,String) -> (GHC.Located GHC.Token,String)-        mkCommentTok (GHC.L l _,s) = (GHC.L l (GHC.ITlineComment s placeholderBufSpan),s)+        mkCommentTok (GHC.L l _,s) = (GHC.L l (GHC.ITlineComment s (makeBufSpan l)),s)      toks = mergeBy locFn directiveToks missingAsComments @@ -258,7 +258,7 @@   let directives = filter (\(_lineNum,line) -> line /= [] && head line == '#')                     $ zip [1..] (lines fcontents) -  let mkTok (lineNum,line) = (GHC.L l (GHC.ITlineComment line placeholderBufSpan),line)+  let mkTok (lineNum,line) = (GHC.L l (GHC.ITlineComment line (makeBufSpan l)),line)        where          start = GHC.mkSrcLoc (GHC.mkFastString srcFile) lineNum 1          end   = GHC.mkSrcLoc (GHC.mkFastString srcFile) lineNum (length line)@@ -267,11 +267,11 @@   let toks = map mkTok directives   return toks -placeholderBufSpan :: GHC.PsSpan-placeholderBufSpan = pspan+makeBufSpan :: GHC.SrcSpan -> GHC.PsSpan+makeBufSpan ss = pspan   where     bl = GHC.BufPos 0-    pspan = GHC.PsSpan GHC.placeholderRealSpan (GHC.BufSpan bl bl)+    pspan = GHC.PsSpan (GHC.realSrcSpan ss) (GHC.BufSpan bl bl)  -- --------------------------------------------------------------------- 
src/Language/Haskell/GHC/ExactPrint/Transform.hs view
@@ -5,6 +5,7 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-} {-# LANGUAGE ViewPatterns #-} ----------------------------------------------------------------------------- -- |@@ -19,8 +20,10 @@ ----------------------------------------------------------------------------- module Language.Haskell.GHC.ExactPrint.Transform         (+        -- * Delta is still here+          makeDeltaAst'         -- * The Transform Monad-          Transform+        , Transform         , TransformT(..)         , hoistTransform         , runTransform@@ -77,6 +80,7 @@          -- * Pure functions         , setEntryDP+        , getEntryDP         , transferEntryDP         , transferEntryDP'         , wrapSig, wrapDecl@@ -93,13 +97,13 @@ import GHC.Data.Bag import GHC.Data.FastString +import Data.Maybe import Data.Generics import Data.List (sort, sortBy)  import Data.Functor.Identity import Control.Monad.State - ------------------------------------------------------------------------------ -- Transformation of source elements @@ -188,7 +192,7 @@ captureMatchLineSpacing d = d  captureLineSpacing :: Monoid t-                   => [LocatedAn t e] -> [GenLocated (SrcSpanAnn' (EpAnn t)) e]+                   => [LocatedAn t e] -> [LocatedAn t e] captureLineSpacing [] = [] captureLineSpacing [d] = [d] captureLineSpacing (de1:d2:ds) = de1:captureLineSpacing (d2':ds)@@ -211,8 +215,8 @@       L (SrcSpanAnn (EpAnn anc' _ _) _) _ -> anchor anc' -- TODO MovedAnchor?     -- DP (line, col) = ss2delta (ss2pos $ anchor $ getLoc lc) r     dc' = case dca of-      EpaSpan r -> AddEpAnn kw (EpaDelta $ ss2delta (ss2posEnd rd) r)-      EpaDelta _ -> AddEpAnn kw dca+      EpaSpan r -> AddEpAnn kw (EpaDelta (ss2delta (ss2posEnd rd) r) [])+      EpaDelta _ _ -> AddEpAnn kw dca      -- --------------------------------- @@ -222,7 +226,7 @@         -> let              op = case dca of                EpaSpan r -> MovedAnchor (ss2delta (ss2posEnd r) (realSrcSpan ll))-               EpaDelta _ -> MovedAnchor (SameLine 1)+               EpaDelta _ _ -> MovedAnchor (SameLine 1)            in (L (SrcSpanAnn (EpAnn (Anchor (realSrcSpan ll) op) mempty emptyComments) ll) b)       (L (SrcSpanAnn (EpAnn (Anchor r op) a c) ll) b)         -> let@@ -230,7 +234,7 @@                 MovedAnchor _ -> op                 _ -> case dca of                   EpaSpan dcr -> MovedAnchor (ss2delta (ss2posEnd dcr) r)-                  EpaDelta _ -> MovedAnchor (SameLine 1)+                  EpaDelta _ _ -> MovedAnchor (SameLine 1)            in (L (SrcSpanAnn (EpAnn (Anchor r op') a c) ll) b)  captureTypeSigSpacing s = s@@ -289,8 +293,32 @@   = L (SrcSpanAnn            (EpAnn (Anchor r (MovedAnchor dp)) an (EpaComments []))            l) a+setEntryDP (L (SrcSpanAnn (EpAnn (Anchor r (MovedAnchor d)) an cs) l) a) dp+  = L (SrcSpanAnn+           (EpAnn (Anchor r (MovedAnchor d')) an cs')+           l) a+  where+    (d',cs') = case cs of+      EpaComments (h:t) ->+        let+          (dp0,c') = go h+        in+          (dp0, EpaComments (c':t))+      EpaCommentsBalanced (h:t) ts ->+        let+          (dp0,c') = go h+        in+          (dp0, EpaCommentsBalanced (c':t) ts)+      _ -> (dp, cs)+    -- go (L (Anchor rr (MovedAnchor ma)) c) = (dp, L (Anchor rr (MovedAnchor ma)) c)+    go (L (Anchor rr (MovedAnchor ma)) c) = (d,  L (Anchor rr (MovedAnchor ma)) c)+    go (L (Anchor rr                _) c) = (d,  L (Anchor rr (MovedAnchor dp)) c)+-- setEntryDP (L (SrcSpanAnn (EpAnn (Anchor r (MovedAnchor _)) an cs) l) a) dp+--   = L (SrcSpanAnn+--            (EpAnn (Anchor r (MovedAnchor dp)) an cs)+--            l) a setEntryDP (L (SrcSpanAnn (EpAnn (Anchor r _) an cs) l) a) dp-  = case sort (priorComments cs) of+  = case sortEpaComments (priorComments cs) of       [] ->         L (SrcSpanAnn                (EpAnn (Anchor r (MovedAnchor dp)) an cs)@@ -305,49 +333,57 @@                 delta = ss2delta (ss2pos $ anchor $ getLoc lc) r                 line = getDeltaLine delta                 col = deltaColumn delta-                -- TODO: this adjustment by 1 happens all over the place. Generalise it                 edp' = if line == 0 then SameLine col                                     else DifferentLine line col                 edp = edp' `debug` ("setEntryDP :" ++ showGhc (edp', (ss2pos $ anchor $ getLoc lc), r)) + -- --------------------------------------------------------------------- +getEntryDP :: LocatedAn t a -> DeltaPos+getEntryDP (L (SrcSpanAnn (EpAnn (Anchor _ (MovedAnchor dp)) _ _) _) _) = dp+getEntryDP _ = SameLine 1++-- ---------------------------------------------------------------------+ addEpaLocationDelta :: LayoutStartCol -> RealSrcSpan -> EpaLocation -> EpaLocation-addEpaLocationDelta _off _anc (EpaDelta d) = EpaDelta d+addEpaLocationDelta _off _anc (EpaDelta d cs) = EpaDelta d cs addEpaLocationDelta  off  anc (EpaSpan r)-  = EpaDelta (adjustDeltaForOffset 0 off (ss2deltaEnd anc r))+  = EpaDelta (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 anc) ll@(L la _) = setEntryDP ll dp'   where     r = case la of       (SrcSpanAnn EpAnnNotUsed l) -> realSrcSpan l       (SrcSpanAnn (EpAnn (Anchor r' _) _ _) _) -> r'-    dp' = adjustDeltaForOffset 0 off (ss2deltaEnd anc r)+    dp' = adjustDeltaForOffset off (ss2deltaEnd anc r)  -- ---------------------------------------------------------------------  -- |Take the annEntryDelta associated with the first item and associate it with the second. -- Also transfer any comments occuring before it.-transferEntryDP :: (Monad m, Monoid t) => LocatedAn t a -> LocatedAn t b -> TransformT m (LocatedAn t b)+transferEntryDP :: (Monad m, Monoid t2, Typeable t1, Typeable t2)+  => LocatedAn t1 a -> LocatedAn t2 b -> TransformT m (LocatedAn t2 b) transferEntryDP (L (SrcSpanAnn EpAnnNotUsed l1) _) (L (SrcSpanAnn EpAnnNotUsed _) b) = do   logTr $ "transferEntryDP': EpAnnNotUsed,EpAnnNotUsed"   return (L (SrcSpanAnn EpAnnNotUsed l1) b) transferEntryDP (L (SrcSpanAnn (EpAnn anc _an cs) _l1) _) (L (SrcSpanAnn EpAnnNotUsed l2) b) = do   logTr $ "transferEntryDP': EpAnn,EpAnnNotUsed"   return (L (SrcSpanAnn (EpAnn anc mempty cs) l2) b)-transferEntryDP (L (SrcSpanAnn (EpAnn anc1 _an1 cs1) _l1) _) (L (SrcSpanAnn (EpAnn _anc2 an2 cs2) l2) b) = do+transferEntryDP (L (SrcSpanAnn (EpAnn anc1 an1 cs1) _l1) _) (L (SrcSpanAnn (EpAnn _anc2 an2 cs2) l2) b) = do   logTr $ "transferEntryDP': EpAnn,EpAnn"   -- Problem: if the original had preceding comments, blindly   -- transferring the location is not correct   case priorComments cs1 of-    [] -> return (L (SrcSpanAnn (EpAnn anc1 an2 cs2) l2) b)+    [] -> return (L (SrcSpanAnn (EpAnn anc1 (combine an1 an2) cs2) l2) b)     -- TODO: what happens if the receiving side already has comments?     (L anc _:_) -> do       logDataWithAnnsTr "transferEntryDP':priorComments anc=" anc-      return (L (SrcSpanAnn (EpAnn anc an2 cs2) l2) b)+      -- return (L (SrcSpanAnn (EpAnn anc an2 cs2) l2) b)+      return (L (SrcSpanAnn (EpAnn anc1 (combine an1 an2) (cs1 <> cs2)) l2) b) transferEntryDP (L (SrcSpanAnn EpAnnNotUsed _l1) _) (L (SrcSpanAnn (EpAnn anc2 an2 cs2) l2) b) = do   logTr $ "transferEntryDP': EpAnnNotUsed,EpAnn"   return (L (SrcSpanAnn (EpAnn anc2' an2 cs2) l2) b)@@ -355,6 +391,11 @@       anc2' = case anc2 of         Anchor _a op   -> Anchor (realSrcSpan l2) op ++-- |If a and b are the same type return first arg, else return second+combine :: (Typeable a, Typeable b) => a -> b -> b+combine x y = fromMaybe y (cast x)+ -- |Take the annEntryDelta associated with the first item and associate it with the second. -- Also transfer any comments occuring before it. -- TODO: call transferEntryDP, and use pushDeclDP@@ -378,11 +419,14 @@ -- ---------------------------------------------------------------------  balanceCommentsList :: (Monad m) => [LHsDecl GhcPs] -> TransformT m [LHsDecl GhcPs]-balanceCommentsList [] = return []-balanceCommentsList [x] = return [x]-balanceCommentsList (a:b:ls) = do+balanceCommentsList ds = balanceCommentsList'' (map tweakListComments ds)++balanceCommentsList'' :: (Monad m) => [LHsDecl GhcPs] -> TransformT m [LHsDecl GhcPs]+balanceCommentsList'' [] = return []+balanceCommentsList'' [x] = return [x]+balanceCommentsList'' (a:b:ls) = do   (a',b') <- balanceComments a b-  r <- balanceCommentsList (b':ls)+  r <- balanceCommentsList'' (b':ls)   return (a':r)  -- |The GHC parser puts all comments appearing between the end of one AST@@ -411,14 +455,37 @@   => LHsBind GhcPs -> LocatedA b -> TransformT m (LHsBind GhcPs, LocatedA b) balanceCommentsFB (L lf (FunBind x n (MG mx (L lm matches) o) t)) second = do   logTr $ "balanceCommentsFB entered: " ++ showGhc (ss2range $ locA lf)-  matches' <- balanceCommentsList' matches-  let (m,ms) = case reverse matches' of-                 (m':ms') -> (m',ms')+  -- There are comments on lf.  We need to+  -- + Keep the prior ones here+  -- + move the interior ones to the first match,+  -- + move the trailing ones to the last match.+  let+    split = splitCommentsEnd (realSrcSpan $ locA lf) (epAnnComments $ ann lf)+    split2 = splitCommentsStart (realSrcSpan $ locA lf)  (EpaComments (sortEpaComments $ priorComments split))++    before = sortEpaComments $ priorComments split2+    middle = sortEpaComments $ getFollowingComments split2+    after  = sortEpaComments $ getFollowingComments split++    lf' = setCommentsSrcAnn lf (EpaComments before)+  logTr $ "balanceCommentsFB (before, after): " ++ showAst (before, after)+  let matches' = case matches of+                    (L lm' m':ms') ->+                      (L (addCommentsToSrcAnn lm' (EpaComments middle )) m':ms')+                    _ -> error "balanceCommentsFB"+  matches'' <- balanceCommentsList' matches'+  let (m,ms) = case reverse matches'' of+                 (L lm' m':ms') ->+                   (L (addCommentsToSrcAnn lm' (EpaCommentsBalanced [] after)) m',ms')                  _ -> error "balanceCommentsFB"   (m',second') <- balanceComments' m second   m'' <- balanceCommentsMatch m'+  let (m''',lf'') = case ms of+        [] -> moveLeadingComments m'' lf'+        _  -> (m'',lf')   logTr $ "balanceCommentsMatch done"-  return (L lf (FunBind x n (MG mx (L lm (reverse (m'':ms))) o) t), second')+  -- return (L lf'' (FunBind x n (MG mx (L lm (reverse (m''':ms))) o) t), second')+  balanceComments' (L lf'' (FunBind x n (MG mx (L lm (reverse (m''':ms))) o) t)) second' balanceCommentsFB f s = balanceComments' f s  -- | Move comments on the same line as the end of the match into the@@ -427,10 +494,11 @@   => LMatch GhcPs (LHsExpr GhcPs) -> TransformT m (LMatch GhcPs (LHsExpr GhcPs)) balanceCommentsMatch (L l (Match am mctxt pats (GRHSs xg grhss binds))) = do   logTr $ "balanceCommentsMatch: (loc1)=" ++ showGhc (ss2range (locA l))-  logTr $ "balanceCommentsMatch: (move',stay')=" ++ showAst (move',stay')+  -- logTr $ "balanceCommentsMatch: (move',stay')=" ++ showAst (move',stay')   logTr $ "balanceCommentsMatch: (logInfo)=" ++ showAst (logInfo)-  logTr $ "balanceCommentsMatch: (loc1)=" ++ showGhc (ss2range (locA l))+  -- logTr $ "balanceCommentsMatch: (loc1)=" ++ showGhc (ss2range (locA l))   logTr $ "balanceCommentsMatch: (anc1,cs1f)=" ++ showAst (anc1,cs1f)+  logTr $ "balanceCommentsMatch: (move,stay)=" ++ showAst (move,stay)   logTr $ "balanceCommentsMatch: (l'', grhss')=" ++ showAst (l'', grhss')   return (L l'' (Match am mctxt pats (GRHSs xg grhss' binds')))   where@@ -455,7 +523,7 @@               -- ---------------------------------                (EpAnn anc an lgc) = ag-              lgc' = splitComments (realSrcSpan lg) $ addCommentOrigDeltas lgc+              lgc' = splitCommentsEnd (realSrcSpan lg) $ addCommentOrigDeltas lgc               ag' = if moved                       then EpAnn anc an lgc'                       else EpAnn anc an (lgc' <> (EpaCommentsBalanced [] move))@@ -473,7 +541,7 @@     (an', decls') = case reverse decls of       [] -> (addCommentsToEpAnn (spanHsLocaLBinds lb) an cs, decls)       (L la d:ds) -> (an, L (addCommentsToSrcAnn la cs) d:ds)-    (vb,_ws2) = case runTransform (replaceDeclsValbinds w lb decls') of+    (vb,_ws2) = case runTransform (replaceDeclsValbinds w lb (reverse decls')) of       ((HsValBinds _ vb'), _, ws2') -> (vb', ws2')       _ -> (ValBinds NoAnnSortKey emptyBag [], []) @@ -496,11 +564,11 @@ balanceComments' :: (Monad m) => LocatedA a -> LocatedA b -> TransformT m (LocatedA a, LocatedA b) balanceComments' la1 la2 = do   logTr $ "balanceComments': (loc1,loc2)=" ++ showGhc (ss2range loc1,ss2range loc2)-  logTr $ "balanceComments': (anchorFromLocatedA la1)=" ++ showGhc (anchorFromLocatedA la1)-  logTr $ "balanceComments': (sort cs2b)=" ++ showAst (sort cs2b)-  logTr $ "balanceComments': (move',stay')=" ++ showAst (move',stay')-  logTr $ "balanceComments': (move'',stay'')=" ++ showAst (move'',stay'')-  logTr $ "balanceComments': (move,stay)=" ++ showAst (move,stay)+  logTr $ "balanceComments': (anc1)=" ++ showAst (anc1)+  logTr $ "balanceComments': (cs1s)=" ++ showAst (cs1s)+  logTr $ "balanceComments': (sort cs1f)=" ++ showAst (sort cs1f)+  logTr $ "balanceComments': (cs1stay,cs1move)=" ++ showAst (cs1stay,cs1move)+  logTr $ "balanceComments': (an1',an2')=" ++ showAst (an1',an2')   return (la1', la2')   where     simpleBreak n (r,_) = r > n@@ -508,19 +576,27 @@     L (SrcSpanAnn an2 loc2) s = la2     anc1 = addCommentOrigDeltas $ epAnnComments an1     anc2 = addCommentOrigDeltas $ epAnnComments an2-    cs1f = getFollowingComments anc1-    cs2b = priorComments anc2-    (stay'',move') = break (simpleBreak 1) (priorCommentsDeltas (anchorFromLocatedA la2) cs2b)++    cs1s = splitCommentsEnd (anchorFromLocatedA la1) anc1+    cs1p = priorCommentsDeltas    (anchorFromLocatedA la1) (priorComments        cs1s)+    cs1f = trailingCommentsDeltas (anchorFromLocatedA la1) (getFollowingComments cs1s)++    cs2s = splitCommentsEnd (anchorFromLocatedA la2) anc2+    cs2p = priorCommentsDeltas    (anchorFromLocatedA la2) (priorComments        cs2s)+    cs2f = trailingCommentsDeltas (anchorFromLocatedA la2) (getFollowingComments cs2s)++    -- Split cs1f into those that belong on an1 and ones that must move to an2+    (cs1move,cs1stay) = break (simpleBreak 1) cs1f++    (stay'',move') = break (simpleBreak 1) cs2p     -- Need to also check for comments more closely attached to la1,     -- ie trailing on the same line     (move'',stay') = break (simpleBreak 0) (trailingCommentsDeltas (anchorFromLocatedA la1) (map snd stay''))-    move = map snd (move'' ++ move')-    stay = map snd stay'-    cs1 = setFollowingComments anc1 (sort $ cs1f ++ move)-    cs2 = setPriorComments anc2 stay+    move = sortEpaComments $ map snd (cs1move ++ move'' ++ move')+    stay = sortEpaComments $ map snd (cs1stay ++ stay') -    an1' = setCommentsSrcAnn (getLoc la1) cs1-    an2' = setCommentsSrcAnn (getLoc la2) cs2+    an1' = setCommentsSrcAnn (getLoc la1) (EpaCommentsBalanced (map snd cs1p) move)+    an2' = setCommentsSrcAnn (getLoc la2) (EpaCommentsBalanced stay (map snd cs2f))     la1' = L an1' f     la2' = L an2' s @@ -539,7 +615,7 @@ -- AZ:TODO: this is identical to commentsDeltas priorCommentsDeltas :: RealSrcSpan -> [LEpaComment]                     -> [(Int, LEpaComment)]-priorCommentsDeltas anc cs = go anc (reverse $ sort cs)+priorCommentsDeltas anc cs = go anc (reverse $ sortEpaComments cs)   where     go :: RealSrcSpan -> [LEpaComment] -> [(Int, LEpaComment)]     go _ [] = []@@ -554,21 +630,54 @@  -- | Split comments into ones occuring before the end of the reference -- span, and those after it.-splitComments :: RealSrcSpan -> EpAnnComments -> EpAnnComments-splitComments p (EpaComments cs) = cs'+splitCommentsEnd :: RealSrcSpan -> EpAnnComments -> EpAnnComments+splitCommentsEnd p (EpaComments cs) = cs'   where-    cmp (L (Anchor l _) _) = ss2pos l < ss2posEnd p+    cmp (L (Anchor l _) _) = ss2pos l > ss2posEnd p     (before, after) = break cmp cs     cs' = case after of       [] -> EpaComments cs       _ -> EpaCommentsBalanced before after-splitComments p (EpaCommentsBalanced cs ts) = EpaCommentsBalanced cs' ts'+splitCommentsEnd p (EpaCommentsBalanced cs ts) = EpaCommentsBalanced cs' ts'   where-    cmp (L (Anchor l _) _) = ss2pos l < ss2posEnd p+    cmp (L (Anchor l _) _) = ss2pos l > ss2posEnd p     (before, after) = break cmp cs     cs' = before     ts' = after <> ts +-- | Split comments into ones occuring before the start of the reference+-- span, and those after it.+splitCommentsStart :: RealSrcSpan -> EpAnnComments -> EpAnnComments+splitCommentsStart p (EpaComments cs) = cs'+  where+    cmp (L (Anchor l _) _) = ss2pos l > ss2pos p+    (before, after) = break cmp cs+    cs' = case after of+      [] -> EpaComments cs+      _ -> EpaCommentsBalanced before after+splitCommentsStart p (EpaCommentsBalanced cs ts) = EpaCommentsBalanced cs' ts'+  where+    cmp (L (Anchor l _) _) = ss2pos l > ss2pos p+    (before, after) = break cmp cs+    cs' = before+    ts' = after <> ts++moveLeadingComments :: (Data t, Data u, Monoid t, Monoid u)+  => LocatedAn t a -> SrcAnn u -> (LocatedAn t a, SrcAnn u)+moveLeadingComments from@(L (SrcSpanAnn EpAnnNotUsed _) _) to = (from, to)+moveLeadingComments (L la a) lb = (L la' a, lb')+  `debug` ("moveLeadingComments: (before, after, la', lb'):" ++ showAst (before, after, la', lb'))+  where+    split = splitCommentsEnd (realSrcSpan $ locA la) (epAnnComments $ ann la)+    before = sortEpaComments $ priorComments split+    after = sortEpaComments $ getFollowingComments split++    -- TODO: need to set an entry delta on lb' to zero, and move the+    -- original spacing to the first comment.++    la' = setCommentsSrcAnn la (EpaComments after)+    lb' = addCommentsToSrcAnn lb (EpaCommentsBalanced before [])+ -- | A GHC comment includes the span of the preceding (non-comment) -- token.  Takes an original list of comments, and converts the -- 'Anchor's to have a have a `MovedAnchor` operation based on the@@ -610,8 +719,110 @@                then MovedAnchor (DifferentLine 1 0)                else op' +spanOrigDelta :: RealSrcSpan -> RealSrcSpan -> DeltaPos+spanOrigDelta prior cur = dp+  where+    (r,c) = ss2posEnd prior+    dp = if r == 0+           then (ss2delta (r,c+1) cur)+           else (ss2delta (r,c)   cur)+ -- --------------------------------------------------------------------- +-- TODO: Until https://gitlab.haskell.org/ghc/ghc/-/issues/20715 is+-- fixed we have to special-case a funbind.  Damn.+tweakListComments :: LHsDecl GhcPs -> LHsDecl GhcPs+tweakListComments a@(L l (ValD x fb@(FunBind{}))) = tweakListCommentsFB a+tweakListComments a = tweakListComments' a++-- A LocatedA item may have both trailing comments and trailing list items.+-- Move any relevant comments preceding a list item into an EpaDelta instead.+tweakListComments' :: LocatedA a -> LocatedA a+tweakListComments' (L (SrcSpanAnn EpAnnNotUsed l) a) = L (SrcSpanAnn EpAnnNotUsed l) a+tweakListComments' (L (SrcSpanAnn (EpAnn anc an cs) l) a) = L (SrcSpanAnn (EpAnn anc an' cs') l) a+  where+    -- Note: until https://gitlab.haskell.org/ghc/ghc/-/issues/20718 is+    -- resolved, the comments may be in reverse order.+    (an', cs') = case cs of+      EpaComments [] -> (an,cs)+      EpaComments c -> go (\cc -> EpaComments cc) an (sortEpaComments c)+      EpaCommentsBalanced _ [] -> (an,cs)+      EpaCommentsBalanced p c -> go (\cc -> EpaCommentsBalanced (sortEpaComments p) cc) an (sortEpaComments c)++    go :: Data b => ([LEpaComment] -> b)+                      -> AnnListItem+                      -> [LEpaComment]+                      -> (AnnListItem, b)+    go f (AnnListItem []) c = (AnnListItem [], f c)+    go f (AnnListItem lis) c = process f ([],[]) lis (sortEpaComments c)++    process :: Data b => ([LEpaComment] -> b)+            -> ([TrailingAnn], [LEpaComment])+            -> [TrailingAnn]+            -> [LEpaComment]+            -> (AnnListItem, b)+    process f (ll,cc) [] cs = (AnnListItem (reverse ll), f (cc++cs))+    process f (ll,cc) li [] = (AnnListItem (reverse $ ll++li), f cc)+    process f (ll,cc) (l:li) cs@(L lc c:_) = r+      where+        r = case trailingAnnLoc l of+          EpaSpan s -> r+            where+              condp (L lc _) = anchor lc >= anchor anc+              (before,rest) = break condp cs+              cond (L lc _) = anchor lc >= s+              (these,those) = break cond rest+              r = case these of+                [] -> process f (l:ll,cc) li cs+                priors ->+                      -- We have at least one comment preceding the list item+                      let+                        -- dp is the delta from the end of the last comment to+                        -- the start of the AddXXXAnn delta+                        dp = spanOrigDelta (anchor $ getLoc $ last priors) s++                        l' = EpaDelta dp (commentOrigDeltas these)+                        cs' = those+                      in+                        process f (setTrailingAnnLoc l l':ll,before++cc) li cs'+          EpaDelta d' cs' -> process f (l:ll,cc) li cs+++-- TODO: Until https://gitlab.haskell.org/ghc/ghc/-/issues/20715 is+-- fixed we have to special-case a funbind.  Damn.+-- The problem seems to depend on whether the funbind has params+-- or not.  If not, we can do a normal tweakListComments.+tweakListCommentsFB :: LHsDecl GhcPs -> LHsDecl GhcPs+tweakListCommentsFB (L l (ValD xv (FunBind x n (MG mx (L lm matches) o) t))) = r+  where+    -- We need to pass any comments from the outer location into the+    -- first match for processing+    (l',matches') = case matches of+      [] -> (l,matches)+      (L lm m:ms) -> (l', L lm' m:ms)+                          `debug` ("tweakListCommentsFB:(l',lm')=" ++ showAst (l',lm'))+      -- (L lm m:ms) -> error $ "lm'=\n" ++ showAst lm'+        where+          (l',cs',as) = case l of+            SrcSpanAnn EpAnnNotUsed _ -> (l,[], [])+            SrcSpanAnn (EpAnn anc an (EpaComments cs))            l+              -> (SrcSpanAnn (EpAnn anc (AnnListItem []) (EpaComments [])) l, cs, lann_trailing an)+            SrcSpanAnn (EpAnn anc an (EpaCommentsBalanced ls ts)) l+              -> (SrcSpanAnn (EpAnn anc (AnnListItem []) (EpaCommentsBalanced ls [])) l, ts, lann_trailing an)++          lm' = case lm of+            SrcSpanAnn EpAnnNotUsed                               l+              -> SrcSpanAnn (EpAnn (spanAsAnchor l) (AnnListItem as) (EpaComments cs')) l+            SrcSpanAnn (EpAnn anc (AnnListItem is) (EpaComments cs))            l+              -> SrcSpanAnn (EpAnn anc (AnnListItem (as<>is)) (EpaComments (cs'<>cs))) l+            SrcSpanAnn (EpAnn anc (AnnListItem is) (EpaCommentsBalanced ls ts)) l+              -> SrcSpanAnn (EpAnn anc (AnnListItem (as<>is)) (EpaCommentsBalanced (cs'<>ls) ts)) l++    r = (L l' (ValD xv (FunBind x n (MG mx (L lm (map tweakListComments' matches')) o) t)))+tweakListCommentsFB x = error $ "tweakListCommentsFB for " ++ showAst x++-- ---------------------------------------------------------------------+ balanceSameLineComments :: (Monad m)   => LMatch GhcPs (LHsExpr GhcPs) -> TransformT m (LMatch GhcPs (LHsExpr GhcPs)) balanceSameLineComments (L la (Match anm mctxt pats (GRHSs x grhss lb))) = do@@ -638,7 +849,7 @@            gac = addCommentOrigDeltas $ epAnnComments ga           gfc = getFollowingComments gac-          gac' = setFollowingComments gac (sort $ gfc ++ move)+          gac' = setFollowingComments gac (sortEpaComments $ gfc ++ move)           ga' = (EpAnn anc an gac')            an1' = setCommentsSrcAnn la cs1@@ -653,6 +864,22 @@  -- --------------------------------------------------------------------- +commentsOrigDeltasDecl :: LHsDecl GhcPs -> LHsDecl GhcPs+commentsOrigDeltasDecl (L (SrcSpanAnn an l) d) = L (SrcSpanAnn an' l) d+  where+    an' = addCommentOrigDeltasAnn an++-- ---------------------------------------------------------------------++-- | Take an anchor and a preceding location, and generate an+-- equivalent one with a 'MovedAnchor' delta.+deltaAnchor :: Anchor -> RealSrcSpan -> Anchor+deltaAnchor (Anchor anc _) ss = Anchor anc (MovedAnchor dp)+  where+    dp = pos2delta (ss2pos ss) (ss2pos anc)++-- ---------------------------------------------------------------------+ -- | Create a @SrcSpanAnn@ with a @MovedAnchor@ operation using the -- given @DeltaPos@. noAnnSrcSpanDP :: (Monoid ann) => SrcSpan -> DeltaPos -> SrcSpanAnn' (EpAnn ann)@@ -669,13 +896,13 @@ noAnnSrcSpanDPn l s = noAnnSrcSpanDP l (SameLine s)  d0 :: EpaLocation-d0 = EpaDelta $ SameLine 0+d0 = EpaDelta (SameLine 0) []  d1 :: EpaLocation-d1 = EpaDelta $ SameLine 1+d1 = EpaDelta (SameLine 1) []  dn :: Int -> EpaLocation-dn n = EpaDelta $ SameLine n+dn n = EpaDelta (SameLine n) []  m0 :: AnchorOperation m0 = MovedAnchor $ SameLine 0@@ -705,7 +932,9 @@               -> Transform ast insertAt f t decl = do   oldDecls <- hsDecls t-  replaceDecls t (f decl oldDecls)+  oldDeclsb <- balanceCommentsList oldDecls+  let oldDecls' = map commentsOrigDeltasDecl oldDeclsb+  replaceDecls t (f decl oldDecls')  -- |Insert a declaration at the beginning or end of the subdecls of the given -- AST item@@ -836,8 +1065,8 @@                 let                   off = case l of                           (EpaSpan r) -> LayoutStartCol $ snd $ ss2pos r-                          (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@@ -1003,7 +1232,7 @@ oldWhereAnnotation EpAnnNotUsed ww _oldSpan = do   newSpan <- uniqueSrcSpanT   let w = case ww of-        WithWhere -> [AddEpAnn AnnWhere (EpaDelta (SameLine 0))]+        WithWhere -> [AddEpAnn AnnWhere (EpaDelta (SameLine 0) [])]         WithoutWhere -> []   let anc2' = Anchor (rs newSpan) (MovedAnchor (SameLine 1))   (anc, anc2) <- do@@ -1018,7 +1247,7 @@   -- TODO: when we set DP (0,0) for the HsValBinds EpEpaLocation, change the AnnList anchor to have the correct DP too   let (AnnList ancl o c _r t) = an   let w = case ww of-        WithWhere -> [AddEpAnn AnnWhere (EpaDelta (SameLine 0))]+        WithWhere -> [AddEpAnn AnnWhere (EpaDelta (SameLine 0) [])]         WithoutWhere -> []   (anc', ancl') <- do         case ww of@@ -1035,7 +1264,7 @@   let anc  = Anchor (rs newSpan) (MovedAnchor (DifferentLine 1 3))   let anc2 = Anchor (rs newSpan) (MovedAnchor (DifferentLine 1 5))   let w = case ww of-        WithWhere -> [AddEpAnn AnnWhere (EpaDelta (SameLine 0))]+        WithWhere -> [AddEpAnn AnnWhere (EpaDelta (SameLine 0) [])]         WithoutWhere -> []   let an = EpAnn anc                   (AnnList (Just anc2) Nothing Nothing w [])@@ -1098,5 +1327,79 @@   decls <- liftT $ hsDecls t   decls' <- action decls   liftT $ replaceDecls t decls'++-- ---------------------------------------------------------------------++-- type RWS r w s = RWST r w s Identity+-- runRWS :: Monoid w => RWS r w s a -> r -> s -> (a, s, w)+-- rws :: Monoid w => (r -> s -> (a, s, w)) -> RWS r w s a++-- -- | Evaluate a computation with the given initial state and environment,+-- -- returning the final value and output, discarding the final state.+-- evalRWS :: (Monoid w)+--         => RWS r w s a  -- ^RWS computation to execute+--         -> r            -- ^initial environment+--         -> s            -- ^initial value+--         -> (a, w)       -- ^final value and output++-- mkM :: (Monad m, Typeable a, Typeable b) => (b -> m b) -> a -> m a++type Delta a = RWS () [String] (Maybe Anchor) a+++-- | Generic top-down traversal through the given AST fragment,+-- converting all ExactPrint Anchor's into ones with an equivalent+-- MovedAnchor operation.  Initially ignores comments+makeDeltaAst' :: forall a. (Data a) => a -> a+makeDeltaAst' a = fst $ evalRWS (go a) () Nothing+  where+    go :: a -> Delta a+    go = everywhereM' (mkM   (locatedAnnImpl @AnnListItem) -- LocatedA+                      `extM` (locatedAnnImpl @NameAnn)     -- LocatedN+                      `extM` (locatedAnnImpl @AnnList)     -- LocatedL+                      `extM` (locatedAnnImpl @AnnPragma)   -- LocatedP+                      `extM` (locatedAnnImpl @AnnContext)  -- LocatedC+                      )++    locatedAnnImpl :: forall an. (Monoid an)+      => SrcAnn an -> Delta (SrcAnn an)+    locatedAnnImpl (SrcSpanAnn (EpAnn anc@(Anchor loc _op) an cs) l) = do+      -- error "locatedAnnImpl:EpAnn"+      ma <- get+      put (Just anc)+      let anchor' = case ma of+                      Nothing -> (Anchor loc (MovedAnchor (SameLine 0)))+                      Just (Anchor rl _op) -> deltaAnchor anc rl+      let cs' = case ma of+            Nothing -> cs <> mkComments ("from anc:Nothing") (Anchor loc UnchangedAnchor)+            Just anc' -> cs <> mkComments ("from anc:" ++ showGhc anc') anc'+      return (SrcSpanAnn (EpAnn anchor' an cs') l)++    locatedAnnImpl (SrcSpanAnn EpAnnNotUsed l) = do+      -- error $ "EpAnnNotUsed: " ++ showGhc l+      ma <- get+      let anc = spanAsAnchor l+      put (Just anc)+      let anchor' = case ma of+                      Nothing -> Anchor (realSrcSpan l) (MovedAnchor (SameLine 0))+                      Just (Anchor rl _op) -> deltaAnchor anc rl+      let cs' = case ma of+            Nothing -> mkComments ("EpAnnNotUsed:from anc:Nothing") (spanAsAnchor l)+            Just anc' -> mkComments ("EpAnnNotUsed:from anc:" ++ showGhc anc') anc'+      return (SrcSpanAnn (EpAnn anchor' mempty cs') l)++-- | Monadic variation on everywhere', so Apply a monadic+-- transformation everywhere in top-down manner+everywhereM' :: Monad m => GenericM m -> GenericM m+everywhereM' f x+  = do x' <- f x+       gmapM (everywhereM' f) x'+++mkComments  :: String -> Anchor -> EpAnnComments+mkComments str anc = EpaComments [mkCommentAnc str anc]++mkCommentAnc :: String -> Anchor -> LEpaComment+mkCommentAnc str anc = L anc (EpaComment (EpaLineComment str) (anchor anc) )  -- ---------------------------------------------------------------------
src/Language/Haskell/GHC/ExactPrint/Types.hs view
@@ -11,6 +11,7 @@ module Language.Haskell.GHC.ExactPrint.Types   where +import Data.Data hiding (Fixity) import GHC hiding (EpaComment) import GHC.Utils.Outputable hiding ( (<>) ) @@ -30,47 +31,26 @@ data Comment = Comment     {       commentContents   :: !String -- ^ The contents of the comment including separators--    -- AZ:TODO: commentIdentifier is a misnomer, should be commentSrcSpan, it is-    -- the thing we use to decide where in the output stream the comment should-    -- go.     , commentAnchor :: !Anchor+    , commentPriorTok :: !RealSrcSpan     , commentOrigin :: !(Maybe AnnKeywordId) -- ^ We sometimes turn syntax into comments in order to process them properly.     }-  deriving Eq+  deriving (Data, Eq)  instance Show Comment where-  show (Comment cs ss o) = "(Comment " ++ show cs ++ " " ++ showPprUnsafe ss ++ " " ++ show o ++ ")"+  show (Comment cs ss r o)+    = "(Comment " ++ show cs ++ " " ++ showPprUnsafe ss ++ " " ++ show r ++ " " ++ show o ++ ")"  instance Ord Comment where   -- 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 $ anchor ss1) (ss2pos $ anchor ss2)     where       ss2pos ss = (srcSpanStartLine ss,srcSpanStartCol ss)  instance Outputable Comment where   ppr x = text (show x)---- | The different syntactic elements which are not represented in the--- AST.-data KeywordId = G AnnKeywordId  -- ^ A normal keyword-               | AnnSemiSep          -- ^ A separating comma-               | AnnTypeApp          -- ^ Visible type application annotation-               | AnnComment Comment-               | AnnString String    -- ^ Used to pass information from-                                     -- Delta to Print when we have to work-                                     -- out details from the original-                                     -- SrcSpan.-               deriving (Eq)--instance Show KeywordId where-  show (G gc)          = "(G " ++ show gc ++ ")"-  show AnnSemiSep      = "AnnSemiSep"-  show AnnTypeApp      = "AnnTypeApp"-  show (AnnComment dc) = "(AnnComment " ++ show dc ++ ")"-  show (AnnString s)   = "(AnnString " ++ s ++ ")"  -- | Marks the start column of a layout block. newtype LayoutStartCol = LayoutStartCol { getLayoutStartCol :: Int }
src/Language/Haskell/GHC/ExactPrint/Utils.hs view
@@ -19,12 +19,14 @@   where import Control.Monad.State import Data.Function+import Data.Maybe import Data.Ord (comparing)  import Data.Generics  import GHC.Hs.Dump import Language.Haskell.GHC.ExactPrint.Lookup+import Language.Haskell.GHC.ExactPrint.Orphans ()  import GHC hiding (EpaComment) import qualified GHC@@ -34,8 +36,6 @@ import GHC.Data.FastString import GHC.Utils.Outputable (showSDocUnsafe, showPprUnsafe) -import Control.Arrow- import Data.List (sortBy, elemIndex)  import Debug.Trace@@ -80,12 +80,13 @@ -- | A good delta has no negative values. isGoodDelta :: DeltaPos -> Bool isGoodDelta (SameLine co) = co >= 0-isGoodDelta (DifferentLine ro co) = ro > 0 && co >= 0+-- isGoodDelta (DifferentLine ro co) = ro > 0 && co >= 0+isGoodDelta (DifferentLine ro co) = ro > 0   -- Note: DifferentLine invariant is ro is nonzero and positive   -- | Create a delta from the current position to the start of the given--- @SrcSpan@.+-- @RealSrcSpan@. ss2delta :: Pos -> RealSrcSpan -> DeltaPos ss2delta ref ss = pos2delta ref (ss2pos ss) @@ -134,15 +135,15 @@ undeltaSpan anchor kw dp = AddEpAnn kw (EpaSpan sp)   where     (l,c) = undelta (ss2pos anchor) dp (LayoutStartCol 0)-    len = length (keywordToString (G kw))+    len = length (keywordToString kw)     sp = range2rs ((l,c),(l,c+len))  -- --------------------------------------------------------------------- -adjustDeltaForOffset :: Int -> LayoutStartCol -> DeltaPos -> DeltaPos-adjustDeltaForOffset _ _colOffset                      dp@(SameLine _) = dp-adjustDeltaForOffset d (LayoutStartCol colOffset) (DifferentLine l c)-  = DifferentLine l (c - colOffset - d)+adjustDeltaForOffset :: LayoutStartCol -> DeltaPos -> DeltaPos+adjustDeltaForOffset _colOffset                      dp@(SameLine _) = dp+adjustDeltaForOffset (LayoutStartCol colOffset) (DifferentLine l c)+  = DifferentLine l (c - colOffset)  -- --------------------------------------------------------------------- @@ -224,31 +225,58 @@ ghcCommentText (L _ (GHC.EpaComment (EpaEofComment) _))        = ""  tokComment :: LEpaComment -> Comment-tokComment t@(L lt _) = mkComment (normaliseCommentText $ ghcCommentText t) lt+tokComment t@(L lt c) = mkComment (normaliseCommentText $ ghcCommentText t) lt (ac_prior_tok c) -mkLEpaComment :: String -> Anchor -> LEpaComment--- Note: fudging the ac_prior_tok value, hope it does not cause a problem-mkLEpaComment s anc = (L anc (GHC.EpaComment (EpaLineComment s) (anchor anc)))+mkEpaComments :: [Comment] -> [Comment] -> EpAnnComments+mkEpaComments priorCs []+  = EpaComments (map comment2LEpaComment priorCs)+mkEpaComments priorCs postCs+  = EpaCommentsBalanced (map comment2LEpaComment priorCs) (map comment2LEpaComment postCs) -mkComment :: String -> Anchor -> Comment-mkComment c anc = Comment c anc Nothing+comment2LEpaComment :: Comment -> LEpaComment+comment2LEpaComment (Comment s anc r _mk) = mkLEpaComment s anc r ++mkLEpaComment :: String -> Anchor -> RealSrcSpan -> LEpaComment+mkLEpaComment s anc r = (L anc (GHC.EpaComment (EpaLineComment s) r))++mkComment :: String -> Anchor -> RealSrcSpan -> Comment+mkComment c anc r = Comment c anc r Nothing+ -- Windows comments include \r in them from the lexer. normaliseCommentText :: String -> String normaliseCommentText [] = [] normaliseCommentText ('\r':xs) = normaliseCommentText xs normaliseCommentText (x:xs) = x:normaliseCommentText xs +-- |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)++-- |Sort, comparing without span filenames, for CPP injected comments with fake filename+sortComments :: [Comment] -> [Comment]+sortComments cs = sortBy cmpComments cs++-- |Sort, comparing without span filenames, for CPP injected comments with fake filename+sortEpaComments :: [LEpaComment] -> [LEpaComment]+sortEpaComments cs = sortBy cmp cs+  where+    cmp (L l1 _) (L l2 _) = compare (ss2pos $ anchor l1) (ss2pos $ anchor l2)+ -- | Makes a comment which originates from a specific keyword. mkKWComment :: AnnKeywordId -> EpaLocation -> Comment mkKWComment kw (EpaSpan ss)-  = Comment (keywordToString $ G kw) (Anchor ss UnchangedAnchor) (Just kw)-mkKWComment kw (EpaDelta dp)-  = Comment (keywordToString $ G kw) (Anchor placeholderRealSpan (MovedAnchor dp)) (Just kw)+  = Comment (keywordToString kw) (Anchor ss UnchangedAnchor) ss (Just kw)+mkKWComment kw (EpaDelta dp _)+  = Comment (keywordToString kw) (Anchor placeholderRealSpan (MovedAnchor dp)) placeholderRealSpan (Just kw) -comment2dp :: (Comment,  DeltaPos) -> (KeywordId, DeltaPos)-comment2dp = first AnnComment+-- | Detects a comment which originates from a specific keyword.+isKWComment :: Comment -> Bool+isKWComment c = isJust (commentOrigin c) +noKWComments :: [Comment] -> [Comment]+noKWComments = filter (\c -> not (isKWComment c))+ sortAnchorLocated :: [GenLocated Anchor a] -> [GenLocated Anchor a] sortAnchorLocated = sortBy (compare `on` (anchor . getLoc)) @@ -287,9 +315,119 @@ locatedAnAnchor (L (SrcSpanAnn EpAnnNotUsed l) _) = realSrcSpan l locatedAnAnchor (L (SrcSpanAnn (EpAnn a _ _) _) _) = anchor a - -- ---------------------------------------------------------------------+-- ---------------------------------------------------------------------  showAst :: (Data a) => a -> String showAst ast   = showSDocUnsafe     $ showAstData NoBlankSrcSpan NoBlankEpAnnotations ast++-- ---------------------------------------------------------------------++setAnchorAn :: (Monoid an) => LocatedAn an a -> Anchor -> EpAnnComments -> LocatedAn an a+setAnchorAn (L (SrcSpanAnn EpAnnNotUsed l)    a) anc cs+  = (L (SrcSpanAnn (EpAnn anc mempty cs) l) a)+     `debug` ("setAnchorAn: anc=" ++ showAst anc)+setAnchorAn (L (SrcSpanAnn (EpAnn _ an _) l) a) anc cs+  = (L (SrcSpanAnn (EpAnn anc an cs) l) a)+     `debug` ("setAnchorAn: anc=" ++ showAst anc)++setAnchorEpa :: (Monoid an) => EpAnn an -> Anchor -> EpAnnComments -> EpAnn an+setAnchorEpa EpAnnNotUsed   anc cs = EpAnn anc mempty cs+setAnchorEpa (EpAnn _ an _) anc cs = EpAnn anc an     cs++setAnchorEpaL :: EpAnn AnnList -> Anchor -> EpAnnComments -> EpAnn AnnList+setAnchorEpaL EpAnnNotUsed   anc cs = EpAnn anc mempty cs+setAnchorEpaL (EpAnn _ an _) anc cs = EpAnn anc (an {al_anchor = Nothing}) cs++setAnchorHsModule :: HsModule -> Anchor -> EpAnnComments -> HsModule+setAnchorHsModule hsmod anc cs = hsmod { hsmodAnn = an' }+  where+    -- anc' = anc { anchor_op = MovedAnchor (SameLine 0)}+    anc' = anc { anchor_op = UnchangedAnchor }+    an' = setAnchorEpa (hsmodAnn hsmod) anc' cs++-- |Version of l2l that preserves the anchor, immportant if it has an+-- updated AnchorOperation+moveAnchor :: Monoid b => SrcAnn a -> SrcAnn b+moveAnchor (SrcSpanAnn EpAnnNotUsed l) = noAnnSrcSpan l+moveAnchor (SrcSpanAnn (EpAnn anc _ cs) l) = SrcSpanAnn (EpAnn anc mempty cs) l++-- ---------------------------------------------------------------------+trailingAnnToAddEpAnn :: TrailingAnn -> AddEpAnn+trailingAnnToAddEpAnn (AddSemiAnn ss)    = AddEpAnn AnnSemi ss+trailingAnnToAddEpAnn (AddCommaAnn ss)   = AddEpAnn AnnComma ss+trailingAnnToAddEpAnn (AddVbarAnn ss)    = AddEpAnn AnnVbar ss+trailingAnnToAddEpAnn (AddRarrowAnn ss)  = AddEpAnn AnnRarrow ss+trailingAnnToAddEpAnn (AddRarrowAnnU ss) = AddEpAnn AnnRarrowU ss+trailingAnnToAddEpAnn (AddLollyAnnU ss)  = AddEpAnn AnnLollyU ss++trailingAnnLoc :: TrailingAnn -> EpaLocation+trailingAnnLoc (AddSemiAnn ss)    = ss+trailingAnnLoc (AddCommaAnn ss)   = ss+trailingAnnLoc (AddVbarAnn ss)    = ss+trailingAnnLoc (AddRarrowAnn ss)  = ss+trailingAnnLoc (AddRarrowAnnU ss) = ss+trailingAnnLoc (AddLollyAnnU ss)  = ss++setTrailingAnnLoc :: TrailingAnn -> EpaLocation -> TrailingAnn+setTrailingAnnLoc (AddSemiAnn _)    ss = (AddSemiAnn ss)+setTrailingAnnLoc (AddCommaAnn _)   ss = (AddCommaAnn ss)+setTrailingAnnLoc (AddVbarAnn _)    ss = (AddVbarAnn ss)+setTrailingAnnLoc (AddRarrowAnn _)  ss = (AddRarrowAnn ss)+setTrailingAnnLoc (AddRarrowAnnU _) ss = (AddRarrowAnnU ss)+setTrailingAnnLoc (AddLollyAnnU _)  ss = (AddLollyAnnU ss)+++addEpAnnLoc :: AddEpAnn -> EpaLocation+addEpAnnLoc (AddEpAnn _ l) = l++-- ---------------------------------------------------------------------++-- TODO: move this to GHC+anchorToEpaLocation :: Anchor -> EpaLocation+anchorToEpaLocation (Anchor r UnchangedAnchor) = EpaSpan r+anchorToEpaLocation (Anchor _ (MovedAnchor dp)) = EpaDelta dp []++-- ---------------------------------------------------------------------+-- Horrible hack for dealing with some things still having a SrcSpan,+-- not an Anchor.++{-+A SrcSpan is defined as++data SrcSpan =+    RealSrcSpan !RealSrcSpan !(Maybe BufSpan)  -- See Note [Why Maybe BufPos]+  | UnhelpfulSpan !UnhelpfulSpanReason++data BufSpan =+  BufSpan { bufSpanStart, bufSpanEnd :: {-# UNPACK #-} !BufPos }+  deriving (Eq, Ord, Show)++newtype BufPos = BufPos { bufPos :: Int }+++We use the BufPos to encode a delta, using bufSpanStart for the line,+and bufSpanEnd for the col.++To be absolutely sure, we make the delta versions use -ve values.++-}++hackSrcSpanToAnchor :: SrcSpan -> Anchor+hackSrcSpanToAnchor (UnhelpfulSpan s) = error $ "hackSrcSpanToAnchor : UnhelpfulSpan:" ++ show s+hackSrcSpanToAnchor (RealSrcSpan r Nothing) = Anchor r UnchangedAnchor+hackSrcSpanToAnchor (RealSrcSpan r (Just (BufSpan (BufPos s) (BufPos e))))+  = if s <= 0 && e <= 0+    then Anchor r (MovedAnchor (deltaPos (-s) (-e)))+    else Anchor r UnchangedAnchor++hackAnchorToSrcSpan :: Anchor -> SrcSpan+hackAnchorToSrcSpan (Anchor r UnchangedAnchor) = RealSrcSpan r Nothing+hackAnchorToSrcSpan (Anchor r (MovedAnchor dp))+  = RealSrcSpan r (Just (BufSpan (BufPos s) (BufPos e)))+  where+    s = - (getDeltaLine dp)+    e = - (deltaColumn dp)++-- ---------------------------------------------------------------------
tests/Test.hs view
@@ -27,7 +27,7 @@  -- --------------------------------------------------------------------- -data GHCVersion = GHC710 | GHC80 | GHC82 | GHC84 | GHC86 | GHC88 | GHC810 | GHC90 | GHC92+data GHCVersion = GHC92      deriving (Eq, Ord, Show)  ghcVersion :: GHCVersion@@ -37,7 +37,6 @@ testDirs :: [FilePath] testDirs =   case ghcVersion of-    GHC90  -> ["ghc710", "ghc80", "ghc82", "ghc84", "ghc86", "ghc88", "ghc810", "ghc90"]     GHC92  -> ["ghc710", "ghc80", "ghc82", "ghc84", "ghc86", "ghc88", "ghc810", "ghc90", "ghc92"]      -- GHC92  -> ["ghc92-copied"]@@ -70,6 +69,30 @@ findTests libdir   = testList "Round-trip tests" <$> mapM (findTestsDir id (mkParserTest libdir)) testDirs +findTestsBC :: LibDir -> IO Test+findTestsBC libdir+  = testList "Balance comments tests" <$> mapM (findTestsDir filterBC (mkParserTestBC libdir)) testDirs++-- | Filter out tests that are known to fail, for particular compilers+filterBC :: [FilePath] -> [FilePath]+filterBC fps = sort $ Set.toList $ Set.difference (Set.fromList fps) skipped+-- filterBC fps = error $ "filterBC:fps=" ++ show fps+  where+  skipped = Set.fromList+    [+    "Control.hs",+    "Internals.hs",+    "LinePragma.hs",+    "QuasiQuote.hs",+    "RandomPGC.hs",+    "HashTab.hs",+    "LinePragmas.hs"+    ]++findTestsMD :: LibDir -> IO Test+findTestsMD libdir+  = testList "Make Delta tests" <$> mapM (findTestsDir id (mkParserTestMD libdir)) testDirs+ findPrettyTests :: LibDir -> IO Test findPrettyTests libdir =   testList "Default Annotations round-trip tests"@@ -105,38 +128,46 @@   -- listTests   let libdir = GHC.Paths.libdir   roundTripTests <- findTests libdir-  prettyRoundTripTests <- findPrettyTests libdir+  roundTripBalanceCommentsTests <- findTestsBC libdir+  roundTripMakeDeltaTests <- findTestsMD libdir+  -- prettyRoundTripTests <- findPrettyTests libdir   return $ TestList [-                      internalTests,-                      roundTripTests-                    ,+                    --   internalTests,+                    --   roundTripTests+                    -- ,                       (transformTests libdir)                     , (failingTests libdir)+                    -- ,+                    --   roundTripBalanceCommentsTests+                    -- ,+                    --   roundTripMakeDeltaTests+                    ]++-- Tests that are no longer needed                     -- , noAnnotationTests                     -- ,                     --   prettyRoundTripTests-                    ]+                    -- ,  failingTests :: LibDir -> Test failingTests libdir = testList "Failing tests"   [   -- Tests requiring future GHC modifications -    -- https://gitlab.haskell.org/ghc/ghc/-/issues/20243-    mkTestModBad libdir "n-plus-k-patterns.hs"--    -- https://gitlab.haskell.org/ghc/ghc/-/issues/20258-  , mkTestModBad libdir "TopLevelSemis.hs"-   -- We do not capture EOF location very well any more-  , mkTestModBad libdir "T10970a.hs"-+    mkTestModBad libdir "T10970a.hs"   ]   mkParserTest :: LibDir -> FilePath -> FilePath -> Test mkParserTest libdir dir fp = mkParsingTest (roundTripTest libdir) dir fp +mkParserTestBC :: LibDir -> FilePath -> FilePath -> Test+mkParserTestBC libdir dir fp = mkParsingTest (roundTripTestBC libdir) dir fp++mkParserTestMD :: LibDir -> FilePath -> FilePath -> Test+mkParserTestMD libdir dir fp = mkParsingTest (roundTripTestMD libdir) dir fp+ -- ---------------------------------------------------------------------  formatTT :: ([([Char], Bool)], [([Char], Bool)]) -> IO ()@@ -160,134 +191,12 @@   let libdir = GHC.Paths.libdir   runTestText (putTextToHandle stdout True) $ TestList [ -    -- mkTestModChange libdir changeRenameCase1 "RenameCase1.hs"--    -- mkParserTest libdir      "ghc710" "UnicodeSyntaxFailure.hs"-    -- mkParserTest libdir      "ghc80" "Class.hs"-    -- mkParserTest libdir      "ghc82" "Completesig03A.hs"-    -- mkParserTest libdir      "ghc82" "brackets.hs"-    -- mkParserTest libdir      "ghc84" "T13747.hs"-    -- mkParserTest libdir      "ghc86" "SlidingTypeSyn.hs"--    -- mkParserTest libdir      "ghc86" "dynamic-paper.hs"-    -- mkParserTest libdir      "ghc90" "ArrowLambdaCase.hs"-    -- mkParserTest libdir      "ghc80" "T6018failclosed.hs"-    -- mkParserTest libdir      "failing" "InfixOperator.hs"--    -- mkParserTest libdir      "ghc92-copied" "AddLocalDecl5.expected.hs"-    -- mkParserTest libdir      "ghc92" "ScopesBug.hs"-    -- mkParserTest libdir      "ghc92-copied" "T10279.hs"-    -- mkParserTest libdir      "ghc92-copied" "T10891.hs"-    -- mkParserTest libdir      "ghc92-copied" "T2632.hs"-    -- mkParserTest libdir      "ghc92-copied" "T4442.hs"-    -- mkParserTest libdir      "ghc92-copied" "TH_reifyExplicitForAllFams.hs"-    -- mkParserTest libdir      "ghc92-copied" "TH_unresolvedInfix.hs"-    -- mkParserTest libdir      "ghc92-copied" "regalloc_unit_tests.hs"--    -- mkParserTest libdir      "ghc92" "Checkpoint.hs"-    -- mkParserTest libdir      "ghc710" "MultiLineCommentWithPragmas.hs"--    -- mkParserTest libdir      "ghc710" "Process.hs"-    -- mkParserTest libdir      "ghc92" "PostgreSQL.hs"-    -- mkParserTest libdir      "ghc92" "Main.hs"-    -- mkParserTest libdir      "ghc92" "MainHareTest.hs"-    -- mkParserTest libdir      "ghc92" "TH.hs"-    -- mkParserTest libdir      "ghc92" "LeapSeconds.hs"-    -- mkParserTest libdir      "ghc92" "proc-lets.hs"-    -- mkParserTest libdir      "ghc92" "n-plus-k-patterns.hs"-    -- mkParserTest libdir      "ghc92" "TopLevelSemis.hs"-    -- mkParserTest libdir      "ghc92" "MiniBall.hs"--    mkParserTest libdir      "ghc80" "T10970a.hs"---    -- mkTestModChange libdir rmDecl1  "RmDecl1.hs"--    -- mkParserTest libdir      "ghc92" "LinearArrow.hs"-    -- mkParserTest libdir      "transform" "AddLocalDecl5.1.hs"-    -- mkTestModChange libdir addLocaLDecl5  "AddLocalDecl5.hs"-    -- mkTestModChange libdir changeLocalDecls2  "LocalDecls2.hs"-    -- mkTestModChange libdir addLocaLDecl1  "AddLocalDecl1.hs"-    {--    ### Failure in: 1:Round-trip tests:1:ghc80:27:Decision.hs-    ### Failure in: 2:transformation tests:0:Low level transformations:15-    AddLocalDecl1.hs-    AddLocalDecl4.hs-    AddLocalDecl5.hs-    AddLocalDecl6.hs-    -}--    -- mkParserTest libdir      "ghc710" "EmptyMostly.hs"--    -- comment problem-    -- mkParserTest libdir      "ghc710" "Move1.hs"-    -- mkParserTest libdir      "ghc80" "Decision.hs"-    -- mkParserTest libdir      "ghc80" "RandomPGC.hs"-    -- mkParserTest libdir      "ghc92" "BlockComment.hs"-    -- mkParserTest libdir      "ghc92" "CommentPlacement.hs"-    -- mkParserTest libdir      "ghc92" "CommentPlacement2.hs"-    -- mkParserTest libdir      "ghc80" "Decision.hs"--    -- mkParserTest libdir      "ghc92-copied" "AddLocalDecl5.expected.hs"-    -- mkParserTest libdir      "ghc92-copied" "AtomicPrimops.hs"-    -- mkParserTest libdir      "ghc92-copied" "BinaryLiterals0.hs"-    -- mkParserTest libdir      "ghc92-copied" "CountDeps.hs"-    -- mkParserTest libdir      "ghc92-copied" "regalloc_unit_tests.hs"------ ### Failure in: 1:Round-trip tests:0:ghc710:20:Control.hs--- ### Failure in: 1:Round-trip tests:0:ghc710:21:CoreIr.hs--- ### Failure in: 1:Round-trip tests:0:ghc710:23:Cpp.hs--- ### Failure in: 1:Round-trip tests:0:ghc710:38:EmptyMostly.hs--- ### Failure in: 1:Round-trip tests:0:ghc710:39:EmptyMostly2.hs--- ### Failure in: 1:Round-trip tests:0:ghc710:40:EmptyMostlyInst.hs--- ### Failure in: 1:Round-trip tests:0:ghc710:41:EmptyMostlyNoSemis.hs--- ### Error in:   1:Round-trip tests:0:ghc710:50:ForeignDecl.hs--    -- mkParserTest libdir      "ghc710" "BracesSemiDataDecl.hs"-    -- mkParserTest libdir      "ghc710" "GADTRecords.hs"-    -- mkParserTest libdir      "ghc710" "RdrNames.hs"-    -- mkParserTest libdir      "ghc710" "RdrNames1.hs"--    -- mkParserTest libdir      "ghc80" "T11010.hs"-    -- mkParserTest libdir      "ghc80" "Test10399.hs"-    -- mkParserTest libdir      "ghc90" "Linear12.hs"-    -- mkParserTest libdir      "ghc90" "T17544_kw.hs"--    -- mkParserTest libdir      "ghc90" "FromManual.hs"-    -- mkPrettyRoundtrip libdir  "ghc90" "FromManual.hs"--    -- mkParserTest libdir       "ghc90" "Linear1Rule.hs"-    -- mkPrettyRoundtrip libdir  "ghc90" "Linear1Rule.hs"--    -- mkParserTest libdir       "ghc80" "Test11018.hs"-    -- mkPrettyRoundtrip libdir  "ghc80" "Test11018.hs"--    -- mkParserTest libdir       "ghc86" "UnicodeSyntax.hs"-    -- mkPrettyRoundtrip libdir  "ghc86" "UnicodeSyntax.hs"--    -- mkParserTest libdir       "ghc86" "empty-foralls.hs"-    -- mkPrettyRoundtrip libdir  "ghc86" "empty-foralls.hs"--    -- mkParserTest libdir       "ghc710" "PatSynBind.hs"-    -- mkPrettyRoundtrip libdir  "ghc710" "PatSynBind.hs"--    -- -----------------------------------------------    -- mkParserTest libdir       "ghc86" "Webhook.hs"--    -- mkParserTest libdir       "ghc710" "TypeBrackets2.hs"-    -- mkPrettyRoundtrip libdir  "ghc710" "TypeBrackets2.hs"--    -- mkParserTest libdir       "ghc710" "DataDecl.hs"-    -- mkPrettyRoundtrip libdir  "ghc710" "DataDecl.hs"--    -- mkParserTest libdir      "ghc90" "BaseDescriptor.hs"-    -- mkPrettyRoundtrip libdir "ghc90" "BaseDescriptor.hs"+    mkTestModChange libdir rmDecl7 "RmDecl7.hs" -    -- mkParserTest libdir      "ghc90" "BaseDescriptors2.hs"-    -- mkPrettyRoundtrip libdir "ghc90" "BaseDescriptors2.hs"+    -- mkTestModChange libdir changeLayoutLet2 "LayoutLet2.hs"+    -- mkParserTestMD libdir      "transform" "LayoutLet2.hs"+    -- mkParserTest libdir      "ghc80" "T10970a.hs"+    -- mkParserTestBC libdir "ghc710" "Control.hs"     -- Needs GHC changes 
tests/Test/Common.hs view
@@ -12,6 +12,8 @@               , ParseFailure(..)               , ReportType(..)               , roundTripTest+              , roundTripTestBC+              , roundTripTestMD               , mkParsingTest               , getModSummaryForFile @@ -20,6 +22,7 @@               , Changer               , genTest               , noChange+              , changeMakeDelta               , mkDebugOutput               , showErrorMessages               , LibDir@@ -31,31 +34,23 @@ import Language.Haskell.GHC.ExactPrint.Utils import Language.Haskell.GHC.ExactPrint.Parsers import Language.Haskell.GHC.ExactPrint.Preprocess--- import Language.Haskell.GHC.ExactPrint.Types  import qualified Control.Monad.IO.Class as GHC import qualified GHC           as GHC hiding (parseModule) import qualified GHC.Data.Bag          as GHC import qualified GHC.Driver.Session    as GHC import qualified GHC.Utils.Error       as GHC--- import qualified GHC.Utils.Outputable  as GHC--- import qualified GHC.Hs.Dump           as GHC  import qualified GHC.LanguageExtensions as LangExt --- import qualified Data.Map as Map- import Control.Monad import Data.List hiding (find)  import System.Directory --- import Test.Consistency- import Test.HUnit import System.FilePath --- import Debug.Trace testPrefix :: FilePath testPrefix = "." </> "tests" </> "examples" @@ -81,29 +76,16 @@    Success  | RoundTripFailure deriving (Eq, Show) -{--runParser :: GHC.P a -> GHC.DynFlags -> FilePath -> String -> GHC.ParseResult a-runParser parser flags filename str = GHC.unP parser parseState-    where-      location = GHC.mkRealSrcLoc (GHC.mkFastString filename) 1 1-      buffer = GHC.stringToStringBuffer str-      parseState = GHC.mkPState flags buffer location -parseFile :: GHC.DynFlags -> FilePath -> String -> GHC.ParseResult (GHC.Located (GHC.HsModule GhcPs))-parseFile = runParser GHC.parseModule--mkApiAnns :: GHC.PState -> GHC.ApiAnns-mkApiAnns pstate = (Map.fromListWith (++) . GHC.annotations $ pstate-                   , Map.fromList ((GHC.noSrcSpan, GHC.comment_q pstate) : (GHC.annotations_comments pstate)))--removeSpaces :: String -> String-removeSpaces = map (\case {'\160' -> ' '; s -> s})--}- roundTripTest :: LibDir -> FilePath -> IO Report roundTripTest libdir f = genTest libdir noChange f f +roundTripTestBC :: LibDir -> FilePath -> IO Report+roundTripTestBC libdir f = genTest libdir changeBalanceComments f f +roundTripTestMD :: LibDir -> FilePath -> IO Report+roundTripTestMD libdir f = genTest libdir changeMakeDelta f f+ mkParsingTest :: (FilePath -> IO Report) -> FilePath -> FilePath -> Test mkParsingTest tester dir fp =   let basename       = testPrefix </> dir </> fp@@ -118,14 +100,23 @@                  forM_ (cppStatus r) writeHsPP                  assertBool fp (status r == Success)) ---- type Changer = (Anns -> GHC.ParsedSource -> IO (Anns,GHC.ParsedSource))--- First param is libdir type Changer = LibDir -> (GHC.ParsedSource -> IO GHC.ParsedSource)  noChange :: Changer noChange _libdir parsed = return parsed +changeBalanceComments :: Changer+changeBalanceComments _libdir (GHC.L l p) = do+  let decls0 = GHC.hsmodDecls p+      (decls,_,w) = runTransform (balanceCommentsList decls0)+  let p2 = p { GHC.hsmodDecls = decls}+  debugM $ "changeBalanceComments:\n" ++ unlines w+  return (GHC.L l p2)++changeMakeDelta :: Changer+changeMakeDelta _libdir m = do+  return (makeDeltaAst m)+ genTest :: LibDir -> Changer -> FilePath -> FilePath -> IO Report genTest libdir f origFile expectedFile  = do       res <- parseModuleEpAnnsWithCpp libdir defaultCppOptions origFile@@ -212,14 +203,5 @@  showErrorMessages :: GHC.ErrorMessages -> String showErrorMessages m = show $ GHC.bagToList m---- ------------------------------------------------------------------------- instance GHC.Outputable GHC.ApiAnns where---   ppr (GHC.ApiAnns items eof comments rogueComments)---     = GHC.text "ApiAnns" GHC.<+> GHC.ppr items---                          GHC.<+> GHC.ppr eof---                          GHC.<+> GHC.ppr comments---                          GHC.<+> GHC.ppr rogueComments  -- ---------------------------------------------------------------------
tests/Test/NoAnnotations.hs view
@@ -90,7 +90,7 @@   let priorComments = GHC.priorComments $ GHC.epAnnComments $ GHC.hsmodAnn $ GHC.unLoc parsedOrig   -- let comments = map tokComment $ GHC.sortRealLocated priorComments   let comments = map tokComment priorComments-  let pragmas = filter (\(Comment c _ _) -> isPrefixOf "{-#" c ) comments+  let pragmas = filter (\(Comment c _ _ _) -> isPrefixOf "{-#" c ) comments   let pragmaStr = intercalate "\n" $ map commentContents pragmas    let !printed = pragmaStr ++ "\n" ++ exactPrint parsedOrig
tests/Test/Transform.hs view
@@ -1,6 +1,9 @@ {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-}++ -- Many of the tests match on a specific expected value,the other patterns should trigger a fail+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module Test.Transform where  import Language.Haskell.GHC.ExactPrint@@ -68,6 +71,9 @@ mkTestModBad libdir file   = mkTestMod libdir "bad" "failing" noChange file +mkTestModBadMD :: LibDir -> FilePath -> Test+mkTestModBadMD libdir file+  = mkTestMod libdir "bad" "failing" changeMakeDelta file  mkTestMod :: LibDir -> String -> FilePath -> Changer -> FilePath ->  Test mkTestMod libdir suffix dir f fp =@@ -169,13 +175,13 @@ -- | Add a local declaration with signature to LocalDecl, where there was no -- prior local decl. So it adds a "where" annotation. changeLocalDecls2 :: Changer-changeLocalDecls2 libdir (L l p) = do+changeLocalDecls2 libdir top = do   Right d@(L ld (ValD _ decl)) <- withDynFlags libdir (\df -> parseDecl df "decl" "nn = 2")   Right s@(L ls (SigD _ sig))  <- withDynFlags libdir (\df -> parseDecl df "sig"  "nn :: Int")-  let decl' = setEntryDP (L ld decl) (DifferentLine 1 0)-  let  sig' = setEntryDP (L ls  sig) (SameLine 2)-  let (p',_,_w) = runTransform doAddLocal-      doAddLocal = everywhereM (mkM replaceLocalBinds) p+  let decl' = setEntryDP (makeDeltaAst (L ld decl)) (DifferentLine 1 0)+  let  sig' = setEntryDP (makeDeltaAst (L ls  sig)) (SameLine 2)+  let (top',_,_w) = runTransform doAddLocal+      doAddLocal = everywhereM (mkM replaceLocalBinds) (makeDeltaAst top)       replaceLocalBinds :: LMatch GhcPs (LHsExpr GhcPs)                         -> Transform (LMatch GhcPs (LHsExpr GhcPs))       replaceLocalBinds (L lm (Match ma mln pats (GRHSs _ rhs EmptyLocalBinds{}))) = do@@ -184,15 +190,16 @@         let anc2 = (Anchor (rs newSpan) (MovedAnchor (DifferentLine 1 5)))         let an = EpAnn anc                         (AnnList (Just anc2) Nothing Nothing-                                 [(undeltaSpan (rs newSpan) AnnWhere (SameLine 0))] [])+                                 [AddEpAnn AnnWhere (EpaDelta (SameLine 0) [])] [])                         emptyComments         let decls = [s,d]         let sortKey = captureOrder decls         let binds = (HsValBinds an (ValBinds sortKey (listToBag $ [decl'])                                     [sig']))-        return (L lm (Match ma mln pats (GRHSs noExtField rhs binds)))+        return (L lm (Match ma mln pats (GRHSs emptyComments rhs binds)))       replaceLocalBinds x = return x-  return (L l p')+  -- return (L l p')+  return top'  -- --------------------------------------------------------------------- @@ -233,13 +240,14 @@  -- | Add a local declaration with signature to LocalDecl changeLocalDecls :: Changer-changeLocalDecls libdir (L l p) = do+changeLocalDecls libdir top = do   Right s@(L ls (SigD _ sig))  <- withDynFlags libdir (\df -> parseDecl df "sig"  "nn :: Int")   Right d@(L ld (ValD _ decl)) <- withDynFlags libdir (\df -> parseDecl df "decl" "nn = 2")-  let decl' = setEntryDP (L ld decl) (DifferentLine 1 0)-  let  sig' = setEntryDP (L ls sig)  (SameLine 0)-  let (p',_,_w) = runTransform doAddLocal-      doAddLocal = everywhereM (mkM replaceLocalBinds) p+  let decl' = setEntryDP (makeDeltaAst (L ld decl)) (DifferentLine 1 0)+  let  sig' = setEntryDP (makeDeltaAst (L ls sig))  (SameLine 0)+  -- let (p',_,_w) = runTransform doAddLocal+  let (top',_,_w) = runTransform doAddLocal+      doAddLocal = everywhereM (mkM replaceLocalBinds) (makeDeltaAst top)       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@@ -250,15 +258,18 @@             (os:oldSigs) = concatMap decl2Sig  oldDecls'             os' = setEntryDP os (DifferentLine 2 0)         let sortKey = captureOrder decls-        let (EpAnn anc (AnnList (Just (Anchor anc2 _)) a b c dd) cs) = van-        let van' = (EpAnn anc (AnnList (Just (Anchor anc2 (MovedAnchor (DifferentLine 1 5)))) a b c dd) cs)+        -- let (EpAnn anc (AnnList (Just (Anchor anc2 _)) a b c dd) cs) = van+        -- let van' = (EpAnn anc (AnnList (Just (Anchor anc2 (MovedAnchor (DifferentLine 1 5)))) a b c dd) cs)+        let (EpAnn anc (AnnList _ a b c dd) cs) = van+        let van' = (EpAnn anc (AnnList (Just (Anchor (anchor anc) (MovedAnchor (DifferentLine 1 5)))) a b c dd) cs)         let binds' = (HsValBinds van'                           (ValBinds sortKey                                     (listToBag $ decl':oldBinds)                                     (sig':os':oldSigs)))-        return (L lm (Match an mln pats (GRHSs noExtField rhs binds')))+        return (L lm (Match an mln pats (GRHSs emptyComments rhs binds')))       replaceLocalBinds x = return x-  return (L l p')+  -- return (L l p')+  return top'  -- --------------------------------------------------------------------- @@ -280,9 +291,11 @@ changeAddDecl :: Changer changeAddDecl libdir top = do   Right decl <- withDynFlags libdir (\df -> parseDecl df "<interactive>" "nn = n2")-  let decl' = setEntryDP decl (DifferentLine 2 0)+  -- let decl' = setEntryDP decl (DifferentLine 2 0)+  let decl' = setEntryDP (makeDeltaAst decl) (DifferentLine 2 0)    let (p',_,_) = runTransform doAddDecl+      -- doAddDecl = everywhereM (mkM replaceTopLevelDecls) (makeDeltaAst top)       doAddDecl = everywhereM (mkM replaceTopLevelDecls) top       replaceTopLevelDecls :: ParsedSource -> Transform ParsedSource       replaceTopLevelDecls m = insertAtStart m decl'@@ -342,9 +355,9 @@ changeLayoutLet5 _libdir parsed = return (rename "x" [((7,5),(7,8)),((9,14),(9,17))] parsed)  -rename :: (Data a) => String -> [(Pos, Pos)] -> a -> a+rename :: (ExactPrint a, Data a) => String -> [(Pos, Pos)] -> a -> a rename newNameStr spans' a-  = everywhere (mkT replaceRdr) a+  = everywhere (mkT replaceRdr) (makeDeltaAst a)   where     newName = mkRdrUnqual (mkVarOcc newNameStr) @@ -370,7 +383,7 @@  changeWhereIn4 :: Changer changeWhereIn4 _libdir parsed-  = return (everywhere (mkT replace) parsed)+  = return (everywhere (mkT replace) (makeDeltaAst parsed))   where     replace :: LocatedN RdrName -> LocatedN RdrName     replace (L ln _n)@@ -393,7 +406,7 @@  changeLetIn1 :: Changer changeLetIn1 _libdir parsed-  = return (everywhere (mkT replace) parsed)+  = return (everywhere (mkT replace) (makeDeltaAst parsed))   where     replace :: HsExpr GhcPs -> HsExpr GhcPs     replace (HsLet (EpAnn anc (AnnsLet l _i) cs) localDecls expr)@@ -404,7 +417,7 @@              (L (SrcSpanAnn _ le) e) = expr              a = (SrcSpanAnn (EpAnn (Anchor (realSrcSpan le) (MovedAnchor (SameLine 1))) mempty emptyComments) le)              expr' = L a e-         in (HsLet (EpAnn anc (AnnsLet l (EpaDelta (DifferentLine 1 0))) cs)+         in (HsLet (EpAnn anc (AnnsLet l (EpaDelta (DifferentLine 1 0) [])) cs)                 (HsValBinds x (ValBinds xv bagDecls' sigs)) expr')      replace x = x@@ -427,8 +440,10 @@   , mkTestModChange libdir rmDecl4 "RmDecl4.hs"   , mkTestModChange libdir rmDecl5 "RmDecl5.hs"   , mkTestModChange libdir rmDecl6 "RmDecl6.hs"-  , mkTestModChange libdir rmDecl7 "RmDecl7.hs" +  -- Currently failing, arguable output+  -- , mkTestModChange libdir rmDecl7 "RmDecl7.hs"+   , mkTestModChange libdir rmTypeSig1 "RmTypeSig1.hs"   , mkTestModChange libdir rmTypeSig2 "RmTypeSig2.hs" @@ -458,9 +473,9 @@ addLocaLDecl1 :: Changer addLocaLDecl1 libdir lp = do   Right (L ld (ValD _ decl)) <- withDynFlags libdir (\df -> parseDecl df "decl" "nn = 2")-  let decl' = setEntryDP (L ld decl) (DifferentLine 1 5)+  let decl' = setEntryDP (makeDeltaAst (L ld decl)) (DifferentLine 1 5)       doAddLocal = do-        (de1:d2:d3:_) <- hsDecls lp+        (de1:d2:d3:_) <- hsDecls (makeDeltaAst lp)         (de1'',d2') <- balanceComments de1 d2         (de1',_) <- modifyValD (getLocA de1'') de1'' $ \_m d -> do           return ((wrapDecl decl' : d),Nothing)@@ -496,11 +511,12 @@   Right newDecl <- withDynFlags libdir (\df -> parseDecl df "decl" "nn = 2")   let       doAddLocal = do+         -- (de1:d2:_) <- hsDecls (makeDeltaAst lp)          (de1:d2:_) <- hsDecls lp          (de1'',d2') <- balanceComments de1 d2           (parent',_) <- modifyValD (getLocA de1) de1'' $ \_m (d:ds) -> do-           newDecl' <- transferEntryDP' d newDecl+           newDecl' <- transferEntryDP' d (makeDeltaAst newDecl)            let d' = setEntryDP d (DifferentLine 1 0)            return ((newDecl':d':ds),Nothing) @@ -539,11 +555,11 @@   Right newDecl <- withDynFlags libdir (\df -> parseDecl df "decl" "nn = 2")   let       doAddLocal = do-         (de1:d2:_) <- hsDecls lp+         (de1:d2:_) <- hsDecls (makeDeltaAst lp)          (de1'',d2') <- balanceComments de1 d2           (parent',_) <- modifyValD (getLocA de1) de1'' $ \_m (d:ds) -> do-           let newDecl' = setEntryDP newDecl (DifferentLine 1 0)+           let newDecl' = setEntryDP (makeDeltaAst newDecl) (DifferentLine 1 0)            return (((d:ds) ++ [newDecl']),Nothing)           replaceDecls (anchorEof lp) [parent',d2']@@ -583,10 +599,10 @@   Right newSig  <- withDynFlags libdir (\df -> parseDecl df "sig"  "nn :: Int")   let       doAddLocal = do-         (parent:ds) <- hsDecls lp+         (parent:ds) <- hsDecls (makeDeltaAst lp) -         let newDecl' = setEntryDP newDecl (DifferentLine 1 0)-         let newSig'  = setEntryDP newSig  (DifferentLine 1 5)+         let newDecl' = setEntryDP (makeDeltaAst newDecl) (DifferentLine 1 0)+         let newSig'  = setEntryDP (makeDeltaAst newSig)  (DifferentLine 1 5)           (parent',_) <- modifyValD (getLocA parent) parent $ \_m decls -> do            return ((decls++[newSig',newDecl']),Nothing)@@ -619,7 +635,7 @@ addLocaLDecl5 _libdir lp = do   let       doAddLocal = do-         decls <- hsDecls lp+         decls <- hsDecls (makeDeltaAst lp)          [s1,de1,d2,d3] <- balanceCommentsList decls           let d3' = setEntryDP d3 (DifferentLine 2 0)@@ -659,8 +675,9 @@ addLocaLDecl6 libdir lp = do   Right newDecl <- withDynFlags libdir (\df -> parseDecl df "decl" "x = 3")   let-      newDecl' = setEntryDP newDecl (DifferentLine 1 5)+      newDecl' = setEntryDP (makeDeltaAst newDecl) (DifferentLine 1 5)       doAddLocal = do+        -- decls0 <- hsDecls (makeDeltaAst lp)         decls0 <- hsDecls lp         [de1'',d2] <- balanceCommentsList decls0 @@ -675,40 +692,18 @@   (lp',_,_w) <- runTransformT doAddLocal   debugM $ "log:[\n" ++ intercalate "\n" _w ++ "]log end\n"   return lp'--- --------------------------------------------------------------------- --- rmDecl1 :: Changer--- rmDecl1 ans lp = do---   let doRmDecl = do---          tlDecs <- hsDecls lp---          let (d1:s1:d2:ds) = tlDecs----          -- First delete the decl (d2) only---          balanceComments s1 d2 -- ++AZ++---          balanceComments d2 (head ds)---          lp1 <- replaceDecls lp (d1:s1:ds)---          -- return lp1----          -- Then delete the sig separately---          tlDecs1 <- hsDecls lp1---          let (d1':s1':ds') = tlDecs1---          -- transferEntryDPT s1' (head ds')  -- required in HaRe.---          balanceComments d1' s1'---          balanceComments s1' (head ds')---          transferEntryDPT s1' (head ds')  -- required in HaRe.---          replaceDecls lp (d1':ds')----   (lp',(ans',_),_w) <- runTransformT ans doRmDecl---   return (ans',lp')+-- ---------------------------------------------------------------------  rmDecl1 :: Changer rmDecl1 _libdir lp = do   let doRmDecl = do          tlDecs0 <- hsDecls lp-         tlDecs <- balanceCommentsList $ captureLineSpacing tlDecs0-         let (de1:_s1:_d2:ds) = tlDecs+         tlDecs <- balanceCommentsList tlDecs0+         let (de1:_s1:_d2:d3:ds) = tlDecs+         let d3' = setEntryDP d3 (DifferentLine 2 0) -         replaceDecls lp (de1:ds)+         replaceDecls lp (de1:d3':ds)    (lp',_,_w) <- runTransformT doRmDecl   debugM $ "log:[\n" ++ intercalate "\n" _w ++ "]log end\n"@@ -747,7 +742,7 @@             return e'           go x = return x -        everywhereM (mkM go) lp+        everywhereM (mkM go) (makeDeltaAst lp)    let (lp',_,_w) = runTransform doRmDecl   debugM $ "log:[\n" ++ intercalate "\n" _w ++ "]log end\n"@@ -774,6 +769,7 @@ rmDecl3 _libdir lp = do   let       doRmDecl = do+         -- [de1,d2] <- hsDecls (makeDeltaAst lp)          [de1,d2] <- hsDecls lp           (de1',Just sd1) <- modifyValD (getLocA de1) de1 $ \_m [sd1] -> do@@ -810,7 +806,8 @@ rmDecl4 _libdir lp = do   let       doRmDecl = do-         [de1] <- hsDecls lp+         let lpd = (makeDeltaAst lp)+         [de1] <- hsDecls lpd           (de1',Just sd1) <- modifyValD (getLocA de1) de1 $ \_m [sd1,sd2] -> do            sd2' <- transferEntryDP' sd1 sd2@@ -818,11 +815,12 @@            let sd1' = setEntryDP sd1 (DifferentLine 2 0)            return ([sd2'],Just sd1') -         replaceDecls (anchorEof lp) [de1',sd1]+         replaceDecls (anchorEof lpd) [de1',sd1]    (lp',_,_w) <- runTransformT doRmDecl   debugM $ "log:[\n" ++ intercalate "\n" _w ++ "]log end\n"   return lp'+ -- ---------------------------------------------------------------------  -- rmDecl5 :: Changer@@ -859,6 +857,7 @@             return (HsLet a lb' expr)           go x = return x +        -- everywhereM (mkM go) (makeDeltaAst lp)         everywhereM (mkM go) lp    let (lp',_,_w) = runTransform doRmDecl@@ -889,7 +888,7 @@ rmDecl6 _libdir lp = do   let       doRmDecl = do-         [de1] <- hsDecls lp+         [de1] <- hsDecls (makeDeltaAst lp)           (de1',_) <- modifyValD (getLocA de1) de1 $ \_m subDecs -> do            let (ss1:_sd1:sd2:sds) = subDecs@@ -926,6 +925,7 @@ rmDecl7 _libdir lp = do   let       doRmDecl = do+         -- tlDecs <- hsDecls (makeDeltaAst lp)          tlDecs <- hsDecls lp          [s1,de1,d2,d3] <- balanceCommentsList tlDecs @@ -952,6 +952,7 @@ rmTypeSig1 :: Changer rmTypeSig1 _libdir lp = do   let doRmDecl = do+         -- tlDecs <- hsDecls (makeDeltaAst lp)          tlDecs <- hsDecls lp          let (s0:de1:d2) = tlDecs              s1 = captureTypeSigSpacing s0@@ -984,10 +985,11 @@ rmTypeSig2 :: Changer rmTypeSig2 _libdir lp = do   let doRmDecl = do+         -- tlDecs <- hsDecls (makeDeltaAst lp)          tlDecs <- hsDecls lp          let [de1] = tlDecs -         (de1',_) <- modifyValD (getLocA de1) de1 $ \_m [s,d] -> do+         (de1',_) <- modifyValD (getLocA de1) de1 $ \_m [_s,d] -> do            return ([d],Nothing)          replaceDecls lp [de1'] @@ -1080,11 +1082,11 @@         let           [L li imp1] = hsmodImports p           Just (_,L lh ns) = ideclHiding imp1-          lh' = (SrcSpanAnn (EpAnn (Anchor (realSrcSpan (locA lh)) m0)+          lh' = (SrcSpanAnn (EpAnn (Anchor (realSrcSpan (locA lh)) m1)                                      (AnnList Nothing                                               (Just (AddEpAnn AnnOpenP  d1))                                               (Just (AddEpAnn AnnCloseP d0))-                                              [(AddEpAnn AnnHiding d1)]+                                              [(AddEpAnn AnnHiding d0)]                                               [])                                        emptyComments) (locA lh))           n1 = L (noAnnSrcSpanDP0 l1) (mkVarUnqual (mkFastString "n1"))@@ -1105,7 +1107,7 @@ cloneDecl1 :: Changer cloneDecl1 _libdir lp = do   let doChange = do-         tlDecs <- hsDecls lp+         tlDecs <- hsDecls (makeDeltaAst lp)          let (d1':d2:ds) = tlDecs          -- d2' <- fst <$> cloneT d2          let d2' = d2
− tests/examples/failing/TopLevelSemis.hs
@@ -1,80 +0,0 @@-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE StandaloneKindSignatures #-}-{-# LANGUAGE TemplateHaskell #-}-module Network.MoHWS.HTTP.Header  where--x = 1---- Comment-;--data Foo = Foo---- After TyClD-;--instance Monoid CIRB where-  mempty = CIRB mempty mempty mempty mempty---- After InstD-;--deriving instance Eq (GenTickish 'TickishPassCore)---- After DerivD-;--transferCodingStr DeflateTransferCoding  = "deflate"---- After ValD-;--getContentType :: Int---- After SigD-;--type MyMaybe :: Type -> Type---- After KindSigD-;--default (Integer)---- After DefD-;--foreign import ccall unsafe "isDoubleFinite" isDoubleFinite :: Double -> Int---- After ForD-;--{-# DEPRECATED foo2 [] #-}---- After WarningD-;--{-# ANN module FromA #-}---- After AnnD-;--{-# RULES "myrule2" id f = f #-}---- After RuleD-;--$foo---- After SpliceD-;--type role Representational representational---- After RoleAnnotD-;--getContentType = 1---- Note: skipping DocD, only generated in haddock mode-
− tests/examples/failing/TopLevelSemis.hs.bad
@@ -1,94 +0,0 @@-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE StandaloneKindSignatures #-}-{-# LANGUAGE TemplateHaskell #-}-module Network.MoHWS.HTTP.Header  where--x = 1---;---data Foo = Foo---;---instance Monoid CIRB where-  mempty = CIRB mempty mempty mempty mempty---;---deriving instance Eq (GenTickish 'TickishPassCore)---;---transferCodingStr DeflateTransferCoding  = "deflate"---;---getContentType :: Int---;---type MyMaybe :: Type -> Type---;---default (Integer)---;---foreign import ccall unsafe "isDoubleFinite" isDoubleFinite :: Double -> Int---;---{-# DEPRECATED foo2 [] #-}---;---{-# ANN module FromA #-}---;---{-# RULES "myrule2" id f = f #-}---;---$foo---;---type role Representational representational---;---getContentType = 1---- Note: skipping DocD, only generated in haddock mode-
− tests/examples/failing/n-plus-k-patterns.hs
@@ -1,11 +0,0 @@-{-# LANGUAGE NPlusKPatterns #-}-singleline :: Int-singleline (n + 1) = n--multiline :: Int-multiline(n-  + 1) = n--n :: Int-(n + 1) = 3-
− tests/examples/failing/n-plus-k-patterns.hs.bad
@@ -1,11 +0,0 @@-{-# LANGUAGE NPlusKPatterns #-}-singleline :: Int-singleline (n   1) = n--multiline :: Int-multiline(n-    1) = n--n :: Int-(n   1) = 3-
tests/examples/ghc710/Stmts.hs view
@@ -1,22 +1,26 @@ module Stmts where  -- Make sure we get all the semicolons in statements-+;;;;  ;;+import Data.List+; ; ;+import Data.Maybe+   ; ;; foo :: IO () foo = do   do { ;;;; a }   a-+; ;; bar :: IO () bar = do-  { ;+  { ;  ;     a ;;     b   }-+ ; ;;  ; baz :: IO () baz = do { ;; s ; s ; ; s ;; }-+; a = undefined b = undefined s = undefined
+ tests/examples/ghc92/AdhocRule.hs view
@@ -0,0 +1,3 @@+{-# RULES "adhoc1" forall r i. r { rOne = i } = r { rOne = i + 12 } #-}+{-# RULES "adhoc2" forall s. Record { rTwo = s } = Record { rTwo = s ++ s } #-}+
+ tests/examples/ghc92/BalanceComments1.hs view
@@ -0,0 +1,11 @@+module BalanceComments1 where++-- Captured in https://gitlab.haskell.org/ghc/ghc/-/issues/20297+-- The '-- do stuff' comment is attached to the wrong annotation++-- Chris done comment attachment problem+foo = x+  where -- do stuff+        doStuff = do stuff+x = 1+stuff = 4
+ tests/examples/ghc92/CommentOrder.hs view
@@ -0,0 +1,7 @@+module CommentOrder where++x = 1++-- First+-- Second+-- Third
+ tests/examples/ghc92/CommentPlacement3.hs view
@@ -0,0 +1,7 @@+module CommentPlacement where++--a comment+x = y1+--b comment+y = x1+--c comment
+ tests/examples/ghc92/ConPat.hs view
@@ -0,0 +1,5 @@+module ConPat where++{-# RULES+"infix" forall a. let x1:x2:xs = flipFirst a in f x2 x1 = let x1:x2:xs = a in f x1 x2+  #-}
+ tests/examples/ghc92/ConstructorComment.hs view
@@ -0,0 +1,7 @@+module ConstructorComment where+++data instance Method PGMigration = MigrationQuery Query+                                 -- ^ Run a query against the database+                                 | MigrationCode (Connection -> IO (Either String ()))+                                 -- ^ Run any arbitrary IO code
+ tests/examples/ghc92/DataDecl.hs view
@@ -0,0 +1,9 @@+module DataDecl where++data FileGlob+   -- | No glob at all, just an ordinary file+   = NoGlob FilePath++   -- | dir prefix and extension, like @\"foo\/bar\/\*.baz\"@ corresponds to+   --    @FileGlob \"foo\/bar\" \".baz\"@+   | FileGlob FilePath String
+ tests/examples/ghc92/DependentStmt.hs view
@@ -0,0 +1,10 @@+module DependentStmt where++-- This test rewrites foo to baz, but only in scope of 'y'.++main :: IO ()+main = do+  x <- bar 7+  foo x+  y <- bar 54+  baz y
+ tests/examples/ghc92/Import.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE ImportQualifiedPost #-}+module Import where++import safe A+import qualified B as B+import B qualified as B+import C hiding (a,b)+import D (x,y)+import Data.List as L ( intersperse )+import "base" Prelude hiding (String)
+ tests/examples/ghc92/IndentedComments.hs view
@@ -0,0 +1,12 @@+module IndentedComments where++-- | 'ls_get strsMany n' ls_get strs 'n' elements in order, without blowing the stack.+ls_getMany strs n = go [] n+ where+    go xs 0 = return $! reverse xs+    go xs i = do x <- ls_get strs+                 -- indented comment+                 x `seq` go (x:xs) (i-1)++-- compat newtype for deserialization of v2-v4 CaptureData+newtype IntLen a = IntLen { fromIntLen :: a }
+ tests/examples/ghc92/LinePragmas.hs view
@@ -0,0 +1,7 @@+module LinePragmas where++x = 1+-- Comment 1+{-# LINE 93 "Foo.chs" #-}+-- Comment 2+y = 2
+ tests/examples/ghc92/ListComments.hs view
@@ -0,0 +1,5 @@+module ListComments where++foo :: Int -- nonterm+    -> IO Int+foo = undefined
+ tests/examples/ghc92/Observer1.hs view
@@ -0,0 +1,10 @@+module Observer1 where++instance HasPdu (ObserverRegistry event) where+  data Pdu (ObserverRegistry event) r where+    --a comment+    RegisterObserver :: Int+    --b comment+    ForgetObserver :: Int+    --c comment+    deriving (Typeable)
+ tests/examples/ghc92/ParensGADT.hs view
@@ -0,0 +1,12 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeOperators #-}+module ParensGADT where++-- | Base Descriptor Class Tags TODO rename to xxxTag+data ClassTag (tag :: Nat) where+  M4MuxChannelDescr                ::ClassTag 0x69+  ExtDescrTag :: ( forall (n :: Nat) . (0x6A <= n, n <= 0xFE) =>  ClassTag n)+  OCIDescrTag :: ((forall (n :: Nat) . (0x40 <= n, n <= 0x5F) =>  ClassTag n))++-- End of file comment
+ tests/examples/ghc92/PragmaSpans.hs view
@@ -0,0 +1,6 @@+{-# LANGUAGE GADTs #-}+module PragmaSpans where++-- The following pragma gets the wrong previous span.+-- See https://gitlab.haskell.org/ghc/ghc/-/issues/20720+{-# LANGUAGE TypeFamilies #-}
+ tests/examples/ghc92/Records.hs view
@@ -0,0 +1,14 @@+module Records where++data Record = Record+  { rOne :: Int+  , rTwo :: String+  }++defR :: Record+defR = Record 1 "record"++main :: IO ()+main = do+  print $ defR { rOne = 42 }+  print $ Record { rTwo = "foo" }
+ tests/examples/ghc92/Records2.hs view
@@ -0,0 +1,14 @@+module Records where++data Record = Record+  { rOne :: Int+  , rTwo :: String+  }++defR :: Record+defR = Record 1 "record"++main :: IO ()+main = do+  print $ defR { rOne = 42 + 12 }+  print $ Record { rTwo = "foo" ++ "foo" }
+ tests/examples/ghc92/Retrie.hs view
@@ -0,0 +1,11 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UnboxedSums #-}+module Types4a where++import Data.Maybe hiding (f1,f2,n1,n2)++type Foo5 = forall r (a :: Type) (b :: TYPE r). (a -> b) -> a -> b++foo5 :: forall s (c :: Type) (d :: TYPE s). (c -> d) -> c -> d+foo5 = ($)
+ tests/examples/ghc92/RmDecl4.hs view
@@ -0,0 +1,9 @@+module RmDecl4 where++-- Remove first declaration from a where clause, last should still be indented+ff y = y + zz + xx+  where+    zz = 1 -- comment+    xx = 2++-- EOF
+ tests/examples/ghc92/TH2.hs view
@@ -0,0 +1,8 @@+{- Bloc comment+-}++{-# LANGUAGE PolyKinds                 #-}++module Language.Grammars.AspectAG.TH where++import Data.GenRec
+ tests/examples/ghc92/TH_reifyDecl1a.hs view
@@ -0,0 +1,12 @@+{-# LANGUAGE TypeFamilies, TypeApplications, PolyKinds #-}+{-# LANGUAGE TemplateHaskell #-}+module TH_reifyDecl1 where++test :: ()+test = $(let+      display :: Name -> Q ()+      display q = do { i <- reify q; runIO $ hPutStrLn stderr (pprint i) }+    in do { display ''T+          ; display ''DF3+          ; [| () |] })+
+ tests/examples/ghc92/TopLevelSemis.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE StandaloneKindSignatures #-}+{-# LANGUAGE TemplateHaskell #-}+module Network.MoHWS.HTTP.Header  where++x = 1++-- Comment+;++data Foo = Foo++-- After TyClD+;++instance Monoid CIRB where+  mempty = CIRB mempty mempty mempty mempty++-- After InstD+;++deriving instance Eq (GenTickish 'TickishPassCore)++-- After DerivD+;++transferCodingStr DeflateTransferCoding  = "deflate"++-- After ValD+;++getContentType :: Int++-- After SigD+;++type MyMaybe :: Type -> Type++-- After KindSigD+;++default (Integer)++-- After DefD+;++foreign import ccall unsafe "isDoubleFinite" isDoubleFinite :: Double -> Int++-- After ForD+;++{-# DEPRECATED foo2 [] #-}++-- After WarningD+;++{-# ANN module FromA #-}++-- After AnnD+;++{-# RULES "myrule2" id f = f #-}++-- After RuleD+;++$foo++-- After SpliceD+;++type role Representational representational++-- After RoleAnnotD+;++getContentType = 1++-- Note: skipping DocD, only generated in haddock mode+
+ tests/examples/ghc92/TopLevelSemis1.hs view
@@ -0,0 +1,14 @@+module TopLevelSemis1  where++x = 1++-- C1+-- C2+;+-- C3+;+-- C4++data Foo = Foo++-- After TyClD
+ tests/examples/ghc92/TopLevelSemis2.hs view
@@ -0,0 +1,25 @@+module TopLevelSemis2  where++x = 1+;++-- foo: two matches, with params+foo [] = []+-- After foo1+;++foo x = x+-- After foo2+;++-- bar: one match, with params+bar a = a+-- after bar+;++-- baz: one match, no params+baz = 2+-- after baz+;++y = 3
+ tests/examples/ghc92/TopLevelSemis3.hs view
@@ -0,0 +1,7 @@+module TopLevelSemis3  where+   {+     x = 1;+   -- Comment+    class Foo a where {+    };+}
+ tests/examples/ghc92/TypeFamilies.hs view
@@ -0,0 +1,7 @@+{-# LANGUAGE TypeFamilies, DataKinds, PolyKinds, UndecidableInstances #-}++module TypeFamilies where++type family F a b  = r | r -> a b where+  F a      IO      = IO a   -- (1)+  F Char   b       = b Int  -- (2)
+ tests/examples/ghc92/n-plus-k-patterns.hs view
@@ -0,0 +1,11 @@+{-# LANGUAGE NPlusKPatterns #-}+singleline :: Int+singleline (n + 1) = n++multiline :: Int+multiline(n+  + 1) = n++n :: Int+(n + 1) = 3+
tests/examples/transform/LocalDecls2.hs.expected view
@@ -4,5 +4,3 @@   where     nn :: Int     nn = 2--
tests/examples/transform/RmDecl4.hs.expected view