{-# LANGUAGE CPP #-}
module Seminal.Enumerator.Bindings (
    enumerateChangesInBinding,
    enumerateChangesInFuncBinding
) where
import Seminal.Compiler.API 
import Seminal.Enumerator.Enumerator (Enumerator)
import Seminal.Change ((<&&>))
import Seminal.Enumerator.Patterns (enumerateChangesInPattern)
import Data.Functor ((<&>))
import Data.List.HT (splitEverywhere)
import {-# SOURCE #-} Seminal.Enumerator.Matches (enumerateChangesInMatch)

-- | Enumeration of changes for bindings, i.e. anything with an `=`
-- See [API doc](https://hackage.haskell.org/package/ghc-9.6.1/docs/Language-Haskell-Syntax-Binds.html#t:HsBindLR)
enumerateChangesInBinding :: Enumerator (HsBind GhcPs)
#if MIN_VERSION_ghc(9,6,1)
enumerateChangesInBinding (FunBind a b c) l = enumerateChangesInFuncBinding (FunBind a b c) l
#else
enumerateChangesInBinding :: Enumerator (HsBind GhcPs)
enumerateChangesInBinding (FunBind XFunBind GhcPs GhcPs
a LIdP GhcPs
b MatchGroup GhcPs (LHsExpr GhcPs)
c [CoreTickish]
d) SrcSpan
l = Enumerator (HsBind GhcPs)
enumerateChangesInFuncBinding (XFunBind GhcPs GhcPs
-> LIdP GhcPs
-> MatchGroup GhcPs (LHsExpr GhcPs)
-> [CoreTickish]
-> HsBind GhcPs
forall idL idR.
XFunBind idL idR
-> LIdP idL
-> MatchGroup idR (LHsExpr idR)
-> [CoreTickish]
-> HsBindLR idL idR
FunBind XFunBind GhcPs GhcPs
a LIdP GhcPs
b MatchGroup GhcPs (LHsExpr GhcPs)
c [CoreTickish]
d) SrcSpan
l
#endif
#if MIN_VERSION_ghc(9,6,1)
enumerateChangesInBinding (PatBind a (L loc pat) c) _ =
#else
enumerateChangesInBinding (PatBind XPatBind GhcPs GhcPs
a (L SrcSpanAnn' (EpAnn AnnListItem)
loc Pat GhcPs
pat) GRHSs GhcPs (LHsExpr GhcPs)
c ([CoreTickish], [[CoreTickish]])
d) SrcSpan
_ =
#endif
    Enumerator (Pat GhcPs)
enumerateChangesInPattern Pat GhcPs
pat (SrcSpanAnn' (EpAnn AnnListItem) -> SrcSpan
forall a. SrcSpanAnn' a -> SrcSpan
locA SrcSpanAnn' (EpAnn AnnListItem)
loc)
        [Change (Pat GhcPs)]
-> (Pat GhcPs
    -> GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (Pat GhcPs))
-> [Change
      (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (Pat GhcPs))]
forall a b. [Change a] -> (a -> b) -> [Change b]
<&&> (SrcSpanAnn' (EpAnn AnnListItem)
-> Pat GhcPs
-> GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (Pat GhcPs)
forall l e. l -> e -> GenLocated l e
L SrcSpanAnn' (EpAnn AnnListItem)
loc)
#if MIN_VERSION_ghc(9,6,1)
        <&&> (\b -> PatBind a b c)
#else
        [Change (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (Pat GhcPs))]
-> (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (Pat GhcPs)
    -> HsBind GhcPs)
-> [Change (HsBind GhcPs)]
forall a b. [Change a] -> (a -> b) -> [Change b]
<&&> (\GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (Pat GhcPs)
b -> XPatBind GhcPs GhcPs
-> LPat GhcPs
-> GRHSs GhcPs (LHsExpr GhcPs)
-> ([CoreTickish], [[CoreTickish]])
-> HsBind GhcPs
forall idL idR.
XPatBind idL idR
-> LPat idL
-> GRHSs idR (LHsExpr idR)
-> ([CoreTickish], [[CoreTickish]])
-> HsBindLR idL idR
PatBind XPatBind GhcPs GhcPs
a LPat GhcPs
GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (Pat GhcPs)
b GRHSs GhcPs (LHsExpr GhcPs)
c ([CoreTickish], [[CoreTickish]])
d)
#endif
enumerateChangesInBinding HsBind GhcPs
_ SrcSpan
_ = []

-- | Enumerates changes to apply on function binding, e.g. `a True = True`.
-- One function binding groups all the matches
-- Basically get changes for each match
enumerateChangesInFuncBinding :: Enumerator (HsBind GhcPs)
#if MIN_VERSION_ghc(9,6,1)
enumerateChangesInFuncBinding (FunBind a b (MG c1 (L la ats))) _ =
#else
enumerateChangesInFuncBinding :: Enumerator (HsBind GhcPs)
enumerateChangesInFuncBinding (FunBind XFunBind GhcPs GhcPs
a LIdP GhcPs
b (MG XMG GhcPs (LHsExpr GhcPs)
c1 (L SrcSpanAnnL
la [GenLocated
   (SrcSpanAnn' (EpAnn AnnListItem))
   (Match
      GhcPs
      (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
ats) Origin
c3) [CoreTickish]
d) SrcSpan
_ =
#endif
    [[Change (HsBind GhcPs)]] -> [Change (HsBind GhcPs)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Change (HsBind GhcPs)]] -> [Change (HsBind GhcPs)])
-> [[Change (HsBind GhcPs)]] -> [Change (HsBind GhcPs)]
forall a b. (a -> b) -> a -> b
$ [GenLocated
   (SrcSpanAnn' (EpAnn AnnListItem))
   (Match
      GhcPs
      (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
-> [([GenLocated
        (SrcSpanAnn' (EpAnn AnnListItem))
        (Match
           GhcPs
           (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))],
     GenLocated
       (SrcSpanAnn' (EpAnn AnnListItem))
       (Match
          GhcPs
          (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs))),
     [GenLocated
        (SrcSpanAnn' (EpAnn AnnListItem))
        (Match
           GhcPs
           (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))])]
forall a. [a] -> [([a], a, [a])]
splitEverywhere [GenLocated
   (SrcSpanAnn' (EpAnn AnnListItem))
   (Match
      GhcPs
      (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
ats
        [([GenLocated
     (SrcSpanAnn' (EpAnn AnnListItem))
     (Match
        GhcPs
        (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))],
  GenLocated
    (SrcSpanAnn' (EpAnn AnnListItem))
    (Match
       GhcPs
       (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs))),
  [GenLocated
     (SrcSpanAnn' (EpAnn AnnListItem))
     (Match
        GhcPs
        (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))])]
-> (([GenLocated
        (SrcSpanAnn' (EpAnn AnnListItem))
        (Match
           GhcPs
           (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))],
     GenLocated
       (SrcSpanAnn' (EpAnn AnnListItem))
       (Match
          GhcPs
          (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs))),
     [GenLocated
        (SrcSpanAnn' (EpAnn AnnListItem))
        (Match
           GhcPs
           (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))])
    -> [Change (HsBind GhcPs)])
-> [[Change (HsBind GhcPs)]]
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> (\([GenLocated
   (SrcSpanAnn' (EpAnn AnnListItem))
   (Match
      GhcPs
      (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
h, L SrcSpanAnn' (EpAnn AnnListItem)
l Match
  GhcPs (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs))
e, [GenLocated
   (SrcSpanAnn' (EpAnn AnnListItem))
   (Match
      GhcPs
      (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
t) -> let (SrcSpanAnn EpAnn AnnListItem
_ SrcSpan
loc) = SrcSpanAnn' (EpAnn AnnListItem)
l in Enumerator (Match GhcPs (LHsExpr GhcPs))
enumerateChangesInMatch Match GhcPs (LHsExpr GhcPs)
Match
  GhcPs (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs))
e SrcSpan
loc
                [Change
   (Match
      GhcPs
      (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
-> (Match
      GhcPs (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs))
    -> [GenLocated
          (SrcSpanAnn' (EpAnn AnnListItem))
          (Match
             GhcPs
             (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))])
-> [Change
      [GenLocated
         (SrcSpanAnn' (EpAnn AnnListItem))
         (Match
            GhcPs
            (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]]
forall a b. [Change a] -> (a -> b) -> [Change b]
<&&> (\Match
  GhcPs (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs))
r ->  [GenLocated
   (SrcSpanAnn' (EpAnn AnnListItem))
   (Match
      GhcPs
      (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
h [GenLocated
   (SrcSpanAnn' (EpAnn AnnListItem))
   (Match
      GhcPs
      (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
-> [GenLocated
      (SrcSpanAnn' (EpAnn AnnListItem))
      (Match
         GhcPs
         (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
-> [GenLocated
      (SrcSpanAnn' (EpAnn AnnListItem))
      (Match
         GhcPs
         (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
forall a. [a] -> [a] -> [a]
++ [SrcSpanAnn' (EpAnn AnnListItem)
-> Match
     GhcPs (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs))
-> GenLocated
     (SrcSpanAnn' (EpAnn AnnListItem))
     (Match
        GhcPs
        (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))
forall l e. l -> e -> GenLocated l e
L SrcSpanAnn' (EpAnn AnnListItem)
l Match
  GhcPs (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs))
r] [GenLocated
   (SrcSpanAnn' (EpAnn AnnListItem))
   (Match
      GhcPs
      (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
-> [GenLocated
      (SrcSpanAnn' (EpAnn AnnListItem))
      (Match
         GhcPs
         (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
-> [GenLocated
      (SrcSpanAnn' (EpAnn AnnListItem))
      (Match
         GhcPs
         (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
forall a. [a] -> [a] -> [a]
++ [GenLocated
   (SrcSpanAnn' (EpAnn AnnListItem))
   (Match
      GhcPs
      (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
t)
#if MIN_VERSION_ghc(9,6,1)
                <&&> (\c2 -> FunBind a b (MG c1 (L la c2)))
#else
                [Change
   [GenLocated
      (SrcSpanAnn' (EpAnn AnnListItem))
      (Match
         GhcPs
         (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]]
-> ([GenLocated
       (SrcSpanAnn' (EpAnn AnnListItem))
       (Match
          GhcPs
          (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
    -> HsBind GhcPs)
-> [Change (HsBind GhcPs)]
forall a b. [Change a] -> (a -> b) -> [Change b]
<&&> (\[GenLocated
   (SrcSpanAnn' (EpAnn AnnListItem))
   (Match
      GhcPs
      (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
c2 -> XFunBind GhcPs GhcPs
-> LIdP GhcPs
-> MatchGroup GhcPs (LHsExpr GhcPs)
-> [CoreTickish]
-> HsBind GhcPs
forall idL idR.
XFunBind idL idR
-> LIdP idL
-> MatchGroup idR (LHsExpr idR)
-> [CoreTickish]
-> HsBindLR idL idR
FunBind XFunBind GhcPs GhcPs
a LIdP GhcPs
b (XMG
  GhcPs (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs))
-> XRec
     GhcPs
     [LMatch
        GhcPs
        (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs))]
-> Origin
-> MatchGroup
     GhcPs (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs))
forall p body.
XMG p body -> XRec p [LMatch p body] -> Origin -> MatchGroup p body
MG XMG GhcPs (LHsExpr GhcPs)
XMG
  GhcPs (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs))
c1 (SrcSpanAnnL
-> [GenLocated
      (SrcSpanAnn' (EpAnn AnnListItem))
      (Match
         GhcPs
         (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
-> GenLocated
     SrcSpanAnnL
     [GenLocated
        (SrcSpanAnn' (EpAnn AnnListItem))
        (Match
           GhcPs
           (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
forall l e. l -> e -> GenLocated l e
L SrcSpanAnnL
la [GenLocated
   (SrcSpanAnn' (EpAnn AnnListItem))
   (Match
      GhcPs
      (GenLocated (SrcSpanAnn' (EpAnn AnnListItem)) (HsExpr GhcPs)))]
c2) Origin
c3) [CoreTickish]
d)
#endif
        )
enumerateChangesInFuncBinding HsBind GhcPs
_ SrcSpan
_ = []