Skip to content

EPA : Clean up and support RenamedSource

I am contemplating the next steps for EPA.

There are some issues around using the current version in tooling, from being limited to ParsedSource

  1. The fixities are not resolved in the ParsedSource. This means multiple tools have separately implemented a way to impose limited fixity adjustments, mostly based on known fixities from base.
  2. Names are not yet resolved. So any tool-driven AST modification needs to link up the name in the ParsedSource to the one in RenamedSource, which is currently done using the wrapped SrcSpan, included on every name for this very purpose.

These can both be improved if we can also exact print the RenamedSource. But to do so we need to make sure that we bring over the required exact print annotations, as well as any missing information from the renamer transformation. What exactly is missing is currently unknown.

But before tackling this, I propose a cleanup/simplification of the exact print annotations, especially with respect to doubling up on the SrcSpan for location.

The first step would be to simplify LocatedN to correspond to the EpAnn constructor in EpAnn only.

So instead of the complex structure listed in #21264 (comment 416594), we have

type instance XRec (GhcPass p) a = GenLocated (Anno a) a

type instance Anno RdrName = EpAnnS NameAnn
type instance Anno Name    = EpAnnS NameAnn
type instance Anno Id      = EpAnnS NameAnn

data NameAnn = ...quite an elaborate type...

data EpAnnS ann = EpAnn { entry:: !Anchor, anns:: !ann, comments :: !EpAnnComments}

And in general we can migrate to using Anchor instead of SrcSpan for locations throughout. We need the following attributes on it

  1. It must correspond to the SrcSpan.RealSrcSpan constructor, i.e. must contain a RealSrcSpan and Maybe BufSpan, for use in haddock comment attachment.
  2. It should have the AnchorOperation, so we can edit the AST and still print it if it has moved.

So

data Anchor = Anchor { anchor :: !RealSrcSpan
                          -- ^ Base location for the start of
                          -- the syntactic element holding
                          -- the annotations 
                     , anchor_bufspan :: !(Strict.Maybe BufSpan)
                          -- ^ Needed to be able to convert
                          -- back to a @SrcSpan@ while parsing.
                     , anchor_op :: !AnchorOperation }
        deriving (Data, Eq, Show)

At the moment, we have

data EpAnn ann
  = EpAnn { ... same as `EpAnnS` }
  | EpAnnNotUsed

If we do this, we can possibly get rid of the EpAnnNotUsed constructor completely so use EpAnn only not EpAnnS as a separate type.

Note: We add the anchor_bufspan field to Anchor because it is not in RealSrcSpan. An alternative would be to modify SrcLoc

data RealSrcSpan
  = RealSrcSpan'
        { srcSpanFile     :: !FastString,
          srcSpanSLine    :: {-# UNPACK #-} !Int,
          srcSpanSCol     :: {-# UNPACK #-} !Int,
          srcSpanELine    :: {-# UNPACK #-} !Int,
          srcSpanECol     :: {-# UNPACK #-} !Int, 
          srcSpanBufSpan  :: !(Strict.Maybe BufSpan)
        }
  deriving Eq

data SrcSpan =
    RealSrcSpan !RealSrcSpan
  | UnhelpfulSpan !UnhelpfulSpanReason
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information