@@ -1,5 +1,6 @@
11{-# LANGUAGE DeriveDataTypeable #-}
22{-# LANGUAGE RankNTypes #-}
3+{-# LANGUAGE RecordWildCards #-}
34
45-- | Diffing GHC ASTs modulo span positions.
56
@@ -9,8 +10,11 @@ module Ormolu.Diff
910where
1011
1112import Data.Generics
13+import Data.Maybe (mapMaybe)
1214import GHC
1315import Language.Haskell.GHC.ExactPrint.Types
16+import Ormolu.Comments
17+import qualified Data.Map.Strict as M
1418
1519-- | Return 'False' of two annotated ASTs are the same modulo span
1620-- positions.
@@ -19,17 +23,39 @@ diff
1923 :: (Anns, ParsedSource) -- ^ First annotated AST
2024 -> (Anns, ParsedSource) -- ^ Second annotated AST
2125 -> Bool
22−diff (_, ps0) (_, ps1) =
23− not (matchParsedSources ps0 ps1)
26+diff (anns0, ps0) (anns1, ps1) =
27+ not (matchIgnoringSrcSpans (simplifyAnns anns0) (simplifyAnns anns1))
28+ || not (matchIgnoringSrcSpans ps0 ps1)
2429
2530-- | Compare two 'ParsedSource' values disregarding differences in
2631-- 'SrcSpan's.
2732
28−matchParsedSources :: ParsedSource -> ParsedSource -> Bool
29−matchParsedSources x0 y0 = geq' x0 y0
33+matchIgnoringSrcSpans :: Data a => a -> a -> Bool
34+matchIgnoringSrcSpans x0 y0 = geq' x0 y0
3035 where
3136 geq' :: GenericQ (GenericQ Bool)
3237 geq' x y = (toConstr x == toConstr y)
3338 && and (gzipWithQ (geq' `extQ` srcSpanEq) x y)
3439 srcSpanEq :: SrcSpan -> GenericQ Bool
3540 srcSpanEq _ _ = True
41+
42+-- | Simplified collection of 'Comment's.
43+
44+data Comments = Comments [Comment] [Comment] [Comment]
45+ deriving (Show, Typeable, Data)
46+
47+-- | Simplify a collection of annotations.
48+
49+simplifyAnns :: Anns -> [Comments]
50+simplifyAnns = fmap simplifyAnn . M.elems
51+
52+-- | Simplify single annotation.
53+
54+simplifyAnn :: Annotation -> Comments
55+simplifyAnn Ann {..} = Comments
56+ (f . fst <$> annPriorComments)
57+ (f . fst <$> annFollowingComments)
58+ (mapMaybe (fmap f . annComment) (fst <$> annsDP))
59+ where
60+ f (Comment str i o) =
61+ Comment (unlines $ normalizeComment str) i o