diff options
author | Alan Zimmerman <alan.zimm@gmail.com> | 2021-10-11 23:05:08 +0100 |
---|---|---|
committer | Alan Zimmerman <alan.zimm@gmail.com> | 2021-10-14 08:51:26 +0100 |
commit | 81d65ed2b1b688240741fa5ca70d6a738db1c873 (patch) | |
tree | cbb62c1165af33303f5bec4aadc277859d052d0a /compiler/GHC/Parser/Annotation.hs | |
parent | 245ab1662edd91a82c17de110c79450fec3f7b82 (diff) | |
download | haskell-81d65ed2b1b688240741fa5ca70d6a738db1c873.tar.gz |
EPA: Preserve semicolon order in annotationswip/az/epa-semis-order
Ensure the AddSemiAnn items appear in increasing order, so that if
they are converted to delta format they are still in the correct
order.
Prior to this the exact printer sorted by Span, which is meaningless
for EpaDelta locations.
Diffstat (limited to 'compiler/GHC/Parser/Annotation.hs')
-rw-r--r-- | compiler/GHC/Parser/Annotation.hs | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/compiler/GHC/Parser/Annotation.hs b/compiler/GHC/Parser/Annotation.hs index 1692d394b5..9555291530 100644 --- a/compiler/GHC/Parser/Annotation.hs +++ b/compiler/GHC/Parser/Annotation.hs @@ -100,7 +100,7 @@ import qualified GHC.Data.Strict as Strict {- Note [exact print annotations] -~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Given a parse tree of a Haskell module, how can we reconstruct the original Haskell source code, retaining all whitespace and source code comments? We need to track the locations of all @@ -394,7 +394,7 @@ instance Outputable EpaComment where -- The usual way an 'AddEpAnn' is created is using the 'mj' ("make -- jump") function, and then it can be inserted into the appropriate -- annotation. -data AddEpAnn = AddEpAnn AnnKeywordId EpaLocation deriving (Data,Eq,Ord) +data AddEpAnn = AddEpAnn AnnKeywordId EpaLocation deriving (Data,Eq) -- | The anchor for an @'AnnKeywordId'@. The Parser inserts the -- @'EpaSpan'@ variant, giving the exact location of the original item @@ -460,6 +460,9 @@ instance Outputable EpaLocation where instance Outputable AddEpAnn where ppr (AddEpAnn kw ss) = text "AddEpAnn" <+> ppr kw <+> ppr ss +instance Ord AddEpAnn where + compare (AddEpAnn kw1 loc1) (AddEpAnn kw2 loc2) = compare (loc1, kw1) (loc2,kw2) + -- --------------------------------------------------------------------- -- | The exact print annotations (EPAs) are kept in the HsSyn AST for @@ -802,7 +805,8 @@ addTrailingAnnToL s t cs EpAnnNotUsed addTrailingAnnToL _ t cs n = n { anns = addTrailing (anns n) , comments = comments n <> cs } where - addTrailing n = n { al_trailing = t : al_trailing n } + -- See Note [list append in addTrailing*] + addTrailing n = n { al_trailing = al_trailing n ++ [t]} -- | Helper function used in the parser to add a 'TrailingAnn' items -- to an existing annotation. @@ -813,7 +817,8 @@ addTrailingAnnToA s t cs EpAnnNotUsed addTrailingAnnToA _ t cs n = n { anns = addTrailing (anns n) , comments = comments n <> cs } where - addTrailing n = n { lann_trailing = t : lann_trailing n } + -- See Note [list append in addTrailing*] + addTrailing n = n { lann_trailing = lann_trailing n ++ [t] } -- | Helper function used in the parser to add a comma location to an -- existing annotation. @@ -822,8 +827,29 @@ addTrailingCommaToN s EpAnnNotUsed l = EpAnn (spanAsAnchor s) (NameAnnTrailing [AddCommaAnn l]) emptyComments addTrailingCommaToN _ n l = n { anns = addTrailing (anns n) l } where + -- See Note [list append in addTrailing*] addTrailing :: NameAnn -> EpaLocation -> NameAnn - addTrailing n l = n { nann_trailing = AddCommaAnn l : nann_trailing n } + addTrailing n l = n { nann_trailing = nann_trailing n ++ [AddCommaAnn l]} + +{- +Note [list append in addTrailing*] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The addTrailingAnnToL, addTrailingAnnToA and addTrailingCommaToN +functions are used to add a separator for an item when it occurs in a +list. So they are used to capture a comma, vbar, semicolon and similar. + +In general, a given element will have zero or one of these. In +extreme (test) cases, there may be multiple semicolons. + +In exact printing we sometimes convert the EpaLocation variant for an +trailing annotation to the EpaDelta variant, which cannot be sorted. + +Hence it is critical that these annotations are captured in the order +they appear in the original source file. + +And so we use the less efficient list append to preserve the order, +knowing that in most cases the original list is empty. +-} -- --------------------------------------------------------------------- |