module Seminal.Enumerator.Matches (
    enumerateChangesInMatch
) where
import Seminal.Enumerator.Enumerator (Enumerator)
import Seminal.Compiler.API
import Seminal.Change ((<&&>))
import Seminal.Enumerator.Patterns (enumerateChangesInPattern)
import Data.Functor ((<&>))
import Data.List.HT (splitEverywhere)
import Seminal.Enumerator.Expressions (enumerateChangesInExpression)
import Seminal.Enumerator.LocalBindings (enumerateChangesInLocalBinds)

-- | Enumerates changes for a single match
-- See [API doc](https://hackage.haskell.org/package/ghc-9.6.1/docs/Language-Haskell-Syntax-Expr.html#t:Match)
enumerateChangesInMatch :: Enumerator (Match GhcPs (LHsExpr GhcPs))
enumerateChangesInMatch :: Enumerator (Match GhcPs (LHsExpr GhcPs))
enumerateChangesInMatch (Match XCMatch GhcPs (LHsExpr GhcPs)
x HsMatchContext GhcPs
ctxt [LPat GhcPs]
pats (GRHSs XCGRHSs GhcPs (LHsExpr GhcPs)
ext [LGRHS GhcPs (LHsExpr GhcPs)]
grhss HsLocalBinds GhcPs
localBinds)) SrcSpan
_ = [Change (Match GhcPs (LHsExpr GhcPs))]
[Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
bindingChanges
    where
        -- | Changes for the left-hand side of the `=` symbol
        patChanges :: [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
patChanges = [[Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]]
-> [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]]
 -> [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))])
-> [[Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]]
-> [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
forall a b. (a -> b) -> a -> b
$ [GenLocated SrcSpanAnnA (Pat GhcPs)]
-> [([GenLocated SrcSpanAnnA (Pat GhcPs)],
     GenLocated SrcSpanAnnA (Pat GhcPs),
     [GenLocated SrcSpanAnnA (Pat GhcPs)])]
forall a. [a] -> [([a], a, [a])]
splitEverywhere [LPat GhcPs]
[GenLocated SrcSpanAnnA (Pat GhcPs)]
pats
            [([GenLocated SrcSpanAnnA (Pat GhcPs)],
  GenLocated SrcSpanAnnA (Pat GhcPs),
  [GenLocated SrcSpanAnnA (Pat GhcPs)])]
-> (([GenLocated SrcSpanAnnA (Pat GhcPs)],
     GenLocated SrcSpanAnnA (Pat GhcPs),
     [GenLocated SrcSpanAnnA (Pat GhcPs)])
    -> [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))])
-> [[Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]]
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> (\([GenLocated SrcSpanAnnA (Pat GhcPs)]
h, L SrcSpanAnnA
l Pat GhcPs
e, [GenLocated SrcSpanAnnA (Pat GhcPs)]
t) -> let (SrcSpanAnn EpAnn AnnListItem
_ SrcSpan
loc) = SrcSpanAnnA
l in Enumerator (Pat GhcPs)
enumerateChangesInPattern Pat GhcPs
e SrcSpan
loc
                    [Change (Pat GhcPs)]
-> (Pat GhcPs -> [GenLocated SrcSpanAnnA (Pat GhcPs)])
-> [Change [GenLocated SrcSpanAnnA (Pat GhcPs)]]
forall a b. [Change a] -> (a -> b) -> [Change b]
<&&> (\Pat GhcPs
r ->  [GenLocated SrcSpanAnnA (Pat GhcPs)]
h [GenLocated SrcSpanAnnA (Pat GhcPs)]
-> [GenLocated SrcSpanAnnA (Pat GhcPs)]
-> [GenLocated SrcSpanAnnA (Pat GhcPs)]
forall a. [a] -> [a] -> [a]
++ [SrcSpanAnnA -> Pat GhcPs -> GenLocated SrcSpanAnnA (Pat GhcPs)
forall l e. l -> e -> GenLocated l e
L SrcSpanAnnA
l Pat GhcPs
r] [GenLocated SrcSpanAnnA (Pat GhcPs)]
-> [GenLocated SrcSpanAnnA (Pat GhcPs)]
-> [GenLocated SrcSpanAnnA (Pat GhcPs)]
forall a. [a] -> [a] -> [a]
++ [GenLocated SrcSpanAnnA (Pat GhcPs)]
t)
                    [Change [GenLocated SrcSpanAnnA (Pat GhcPs)]]
-> ([GenLocated SrcSpanAnnA (Pat GhcPs)]
    -> Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
-> [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
forall a b. [Change a] -> (a -> b) -> [Change b]
<&&> (\[GenLocated SrcSpanAnnA (Pat GhcPs)]
newPats -> XCMatch GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
-> HsMatchContext GhcPs
-> [LPat GhcPs]
-> GRHSs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
-> Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
forall p body.
XCMatch p body
-> HsMatchContext p -> [LPat p] -> GRHSs p body -> Match p body
Match XCMatch GhcPs (LHsExpr GhcPs)
XCMatch GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
x HsMatchContext GhcPs
ctxt [LPat GhcPs]
[GenLocated SrcSpanAnnA (Pat GhcPs)]
newPats (XCGRHSs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
-> [LGRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))]
-> HsLocalBinds GhcPs
-> GRHSs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
forall p body.
XCGRHSs p body -> [LGRHS p body] -> HsLocalBinds p -> GRHSs p body
GRHSs XCGRHSs GhcPs (LHsExpr GhcPs)
XCGRHSs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
ext [LGRHS GhcPs (LHsExpr GhcPs)]
[LGRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))]
grhss HsLocalBinds GhcPs
localBinds))
            )
        -- | Changes for the right-hand side of the `=` symbol
        -- Note: GHRS is Guarded Right-Hand Side
        grhsChanges :: [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
grhsChanges = [[Change
    [GenLocated
       (SrcAnn NoEpAnns)
       (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]]]
-> [Change
      [GenLocated
         (SrcAnn NoEpAnns)
         (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([GenLocated
   (SrcAnn NoEpAnns)
   (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
-> [([GenLocated
        (SrcAnn NoEpAnns)
        (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))],
     GenLocated
       (SrcAnn NoEpAnns)
       (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))),
     [GenLocated
        (SrcAnn NoEpAnns)
        (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))])]
forall a. [a] -> [([a], a, [a])]
splitEverywhere [LGRHS GhcPs (LHsExpr GhcPs)]
[GenLocated
   (SrcAnn NoEpAnns)
   (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
grhss
            [([GenLocated
     (SrcAnn NoEpAnns)
     (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))],
  GenLocated
    (SrcAnn NoEpAnns)
    (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))),
  [GenLocated
     (SrcAnn NoEpAnns)
     (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))])]
-> (([GenLocated
        (SrcAnn NoEpAnns)
        (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))],
     GenLocated
       (SrcAnn NoEpAnns)
       (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))),
     [GenLocated
        (SrcAnn NoEpAnns)
        (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))])
    -> [Change
          [GenLocated
             (SrcAnn NoEpAnns)
             (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]])
-> [[Change
       [GenLocated
          (SrcAnn NoEpAnns)
          (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]]]
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> (\([GenLocated
   (SrcAnn NoEpAnns)
   (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
h, L SrcAnn NoEpAnns
l (GRHS XCGRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
grhsx [GuardLStmt GhcPs]
p (L SrcSpanAnnA
lbody HsExpr GhcPs
body)), [GenLocated
   (SrcAnn NoEpAnns)
   (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
t) ->  Enumerator (HsExpr GhcPs)
enumerateChangesInExpression HsExpr GhcPs
body (SrcSpanAnnA -> SrcSpan
forall a. SrcSpanAnn' a -> SrcSpan
locA SrcSpanAnnA
lbody)
                    [Change (HsExpr GhcPs)]
-> (HsExpr GhcPs -> GenLocated SrcSpanAnnA (HsExpr GhcPs))
-> [Change (GenLocated SrcSpanAnnA (HsExpr GhcPs))]
forall a b. [Change a] -> (a -> b) -> [Change b]
<&&> (SrcSpanAnnA
-> HsExpr GhcPs -> GenLocated SrcSpanAnnA (HsExpr GhcPs)
forall l e. l -> e -> GenLocated l e
L SrcSpanAnnA
lbody)
                    [Change (GenLocated SrcSpanAnnA (HsExpr GhcPs))]
-> (GenLocated SrcSpanAnnA (HsExpr GhcPs)
    -> GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
-> [Change (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
forall a b. [Change a] -> (a -> b) -> [Change b]
<&&> (XCGRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
-> [GuardLStmt GhcPs]
-> GenLocated SrcSpanAnnA (HsExpr GhcPs)
-> GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
forall p body.
XCGRHS p body -> [GuardLStmt p] -> body -> GRHS p body
GRHS XCGRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
grhsx [GuardLStmt GhcPs]
p)
                    [Change (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
-> (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
    -> GenLocated
         (SrcAnn NoEpAnns)
         (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))))
-> [Change
      (GenLocated
         (SrcAnn NoEpAnns)
         (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))))]
forall a b. [Change a] -> (a -> b) -> [Change b]
<&&> (SrcAnn NoEpAnns
-> GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
-> GenLocated
     (SrcAnn NoEpAnns)
     (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
forall l e. l -> e -> GenLocated l e
L SrcAnn NoEpAnns
l)
                    [Change
   (GenLocated
      (SrcAnn NoEpAnns)
      (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))))]
-> (GenLocated
      (SrcAnn NoEpAnns)
      (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    -> [GenLocated
          (SrcAnn NoEpAnns)
          (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))])
-> [Change
      [GenLocated
         (SrcAnn NoEpAnns)
         (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]]
forall a b. [Change a] -> (a -> b) -> [Change b]
<&&> (\GenLocated
  (SrcAnn NoEpAnns)
  (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
b -> [GenLocated
   (SrcAnn NoEpAnns)
   (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
h [GenLocated
   (SrcAnn NoEpAnns)
   (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
-> [GenLocated
      (SrcAnn NoEpAnns)
      (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
-> [GenLocated
      (SrcAnn NoEpAnns)
      (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
forall a. [a] -> [a] -> [a]
++ [GenLocated
  (SrcAnn NoEpAnns)
  (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
b] [GenLocated
   (SrcAnn NoEpAnns)
   (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
-> [GenLocated
      (SrcAnn NoEpAnns)
      (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
-> [GenLocated
      (SrcAnn NoEpAnns)
      (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
forall a. [a] -> [a] -> [a]
++ [GenLocated
   (SrcAnn NoEpAnns)
   (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
t)
            ))
            [Change
   [GenLocated
      (SrcAnn NoEpAnns)
      (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]]
-> ([GenLocated
       (SrcAnn NoEpAnns)
       (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    -> Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
-> [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
forall a b. [Change a] -> (a -> b) -> [Change b]
<&&> (\[GenLocated
   (SrcAnn NoEpAnns)
   (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
grhs -> XCMatch GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
-> HsMatchContext GhcPs
-> [LPat GhcPs]
-> GRHSs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
-> Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
forall p body.
XCMatch p body
-> HsMatchContext p -> [LPat p] -> GRHSs p body -> Match p body
Match XCMatch GhcPs (LHsExpr GhcPs)
XCMatch GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
x HsMatchContext GhcPs
ctxt [LPat GhcPs]
pats (XCGRHSs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
-> [LGRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))]
-> HsLocalBinds GhcPs
-> GRHSs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
forall p body.
XCGRHSs p body -> [LGRHS p body] -> HsLocalBinds p -> GRHSs p body
GRHSs XCGRHSs GhcPs (LHsExpr GhcPs)
XCGRHSs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
ext [LGRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))]
[GenLocated
   (SrcAnn NoEpAnns)
   (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
grhs HsLocalBinds GhcPs
localBinds))
        -- | The enumeration of changes for the `where` clause of the match
        localbindChanges :: [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
localbindChanges = Enumerator (HsLocalBinds GhcPs)
enumerateChangesInLocalBinds HsLocalBinds GhcPs
localBinds SrcSpan
noSrcSpan
            [Change (HsLocalBinds GhcPs)]
-> (HsLocalBinds GhcPs
    -> Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
-> [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
forall a b. [Change a] -> (a -> b) -> [Change b]
<&&> (XCMatch GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
-> HsMatchContext GhcPs
-> [LPat GhcPs]
-> GRHSs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
-> Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
forall p body.
XCMatch p body
-> HsMatchContext p -> [LPat p] -> GRHSs p body -> Match p body
Match XCMatch GhcPs (LHsExpr GhcPs)
XCMatch GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
x HsMatchContext GhcPs
ctxt [LPat GhcPs]
pats (GRHSs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
 -> Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
-> (HsLocalBinds GhcPs
    -> GRHSs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
-> HsLocalBinds GhcPs
-> Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XCGRHSs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
-> [LGRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))]
-> HsLocalBinds GhcPs
-> GRHSs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
forall p body.
XCGRHSs p body -> [LGRHS p body] -> HsLocalBinds p -> GRHSs p body
GRHSs XCGRHSs GhcPs (LHsExpr GhcPs)
XCGRHSs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
ext [LGRHS GhcPs (LHsExpr GhcPs)]
[LGRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))]
grhss)

        bindingChanges :: [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
bindingChanges = [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
patChanges [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
-> [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
-> [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
forall a. [a] -> [a] -> [a]
++ [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
grhsChanges [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
-> [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
-> [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
forall a. [a] -> [a] -> [a]
++ [Change (Match GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
localbindChanges