- remove
makeDeltaAst, otherwise there will be noSrcSpananywhere in the AST (but when ready to make a change, using it to capture spacing of the local thing being edited may help) EpAnnNotUsedis gone, usenoAnninsteaduniqueSrcSpanTis no longer needed, use an appropriateEpaDeltalocation insteadEpaDelta (DifferentLine row col)interpretscoldifferently. You must add 1 to get the prior spacing.- If you add something to a list (possible via
hsDecls/replaceDecls), the following item only needs to havesetEntryDPcalled on it, to get the spacing right
We have taken a more principled approach relating to the location and function of annotation types.
-
Located (EpAnn ann) acarries positioning and comments, and some limited annotations, such as trailing ones. -
Annotations within
a, no locations or comments, just keywords etc
EpAnnNotUsed is gone
Anchor is now EpaLocation
type LocatedAn an = GenLocated (EpAnn an)SrcAnn is gone
It provides a generalisation of getLoc, and getLocA is now defined as a synonym for it.
class HasLoc a where
-- ^ conveniently calculate locations for things without locations attached
getHasLoc :: a -> SrcSpangetLocA :: (HasLoc a) => GenLocated a e -> SrcSpan
getLocA = getHasLocThis also allowed getting rid of the zoo of conversion functions. All that remains is l2l, la2la, reLoc.
Below are examples of the generalisations this allows (see NoAnn details below)
sortLocatedA :: (HasLoc (EpAnn a)) => [GenLocated (EpAnn a) e] -> [GenLocated (EpAnn a) e]
sortLocatedA = sortBy (leftmost_smallest `on` getLocA)
mapLocA :: (NoAnn ann) => (a -> b) -> GenLocated SrcSpan a -> GenLocated (EpAnn ann) b
mapLocA f (L l a) = L (noAnnSrcSpan l) (f a)
combineLocsA :: Semigroup a => GenLocated (EpAnn a) e1 -> GenLocated (EpAnn a) e2 -> EpAnn a
combineLocsA (L a _) (L b _) = combineSrcSpansA a b
combineSrcSpansA :: Semigroup a => EpAnn a -> EpAnn a -> EpAnn a
combineSrcSpansA aa ab = aa <> abWhere HasLoc provides a way of getting a SrcSpan out of a thing, HasAnnotation does the reverse, creating a thing with a SrcSpan in it.
class HasAnnotation e where
noAnnSrcSpan :: SrcSpan -> enoLocA :: (HasAnnotation e) => a -> GenLocated e a
noLocA = L (noAnnSrcSpan noSrcSpan)
getLocA :: (HasLoc a) => GenLocated a e -> SrcSpan
getLocA = getHasLoc
noSrcSpanA :: (HasAnnotation e) => e
noSrcSpanA = noAnnSrcSpan noSrcSpanclass NoAnn a where
-- | equivalent of `mempty`, but does not need Semigroup
noAnn :: ainstance (Semigroup a) => Semigroup (EpAnn a) where
(EpAnn l1 a1 b1) <> (EpAnn l2 a2 b2) = EpAnn (l1 <> l2) (a1 <> a2) (b1 <> b2)
-- The critical part about the anchor is its left edge, and all
-- annotations must follow it. So we combine them which yields the
-- largest span-- | A token stored in the syntax tree. For example, when parsing a
-- let-expression, we store @EpToken "let"@ and @EpToken "in"@.
-- The locations of those tokens can be used to faithfully reproduce
-- (exactprint) the original program text.
data EpToken (tok :: Symbol)
= NoEpTok
| EpTok !EpaLocation
-- | With @UnicodeSyntax@, there might be multiple ways to write the same
-- token. For example an arrow could be either @->@ or @→@. This choice must be
-- recorded in order to exactprint such tokens, so instead of @EpToken "->"@ we
-- introduce @EpUniToken "->" "→"@.
data EpUniToken (tok :: Symbol) (utok :: Symbol)
= NoEpUniTok
| EpUniTok !EpaLocation !IsUnicodeSyntax
deriving instance Eq (EpToken tok)
deriving instance KnownSymbol tok => Data (EpToken tok)
deriving instance (KnownSymbol tok, KnownSymbol utok) => Data (EpUniToken tok utok)
Note: first thing to do when porting, remove initial call to
makeDeltaAst