{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}

module GHC.Util.FreeVars (
    vars, varss, pvars,
    Vars (..), FreeVars(..) , AllVars (..)
  ) where

import GHC.Types.Name.Reader
import GHC.Types.Name.Occurrence
import GHC.Types.Name
import GHC.Hs
import GHC.Types.SrcLoc
import GHC.Data.Bag (bagToList)

import Data.Generics.Uniplate.DataOnly
import Data.Monoid
import Data.Semigroup
import Data.List.Extra
import Data.Set (Set)
import Data.Set qualified as Set
import Prelude

( ^+ ) :: Set OccName -> Set OccName -> Set OccName
( ^+ ) = forall a. Ord a => Set a -> Set a -> Set a
Set.union
( ^- ) :: Set OccName -> Set OccName -> Set OccName
( ^- ) = forall a. Ord a => Set a -> Set a -> Set a
Set.difference

-- See [Note : Space leaks lurking here?] below.
data Vars = Vars{Vars -> Set OccName
bound :: Set OccName, Vars -> Set OccName
free :: Set OccName}

-- Useful for debugging.
instance Show Vars where
  show :: Vars -> String
show (Vars Set OccName
bs Set OccName
fs) = String
"bound : " forall a. [a] -> [a] -> [a]
++
    forall a. Show a => a -> String
show (forall a b. (a -> b) -> [a] -> [b]
map OccName -> String
occNameString (forall a. Set a -> [a]
Set.toList Set OccName
bs)) forall a. [a] -> [a] -> [a]
++
    String
", free : " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (forall a b. (a -> b) -> [a] -> [b]
map OccName -> String
occNameString (forall a. Set a -> [a]
Set.toList Set OccName
fs))

instance Semigroup Vars where
    Vars Set OccName
x1 Set OccName
x2 <> :: Vars -> Vars -> Vars
<> Vars Set OccName
y1 Set OccName
y2 = Set OccName -> Set OccName -> Vars
Vars (Set OccName
x1 Set OccName -> Set OccName -> Set OccName
^+ Set OccName
y1) (Set OccName
x2 Set OccName -> Set OccName -> Set OccName
^+ Set OccName
y2)

instance Monoid Vars where
    mempty :: Vars
mempty = Set OccName -> Set OccName -> Vars
Vars forall a. Set a
Set.empty forall a. Set a
Set.empty
    mconcat :: [Vars] -> Vars
mconcat [Vars]
vs = Set OccName -> Set OccName -> Vars
Vars (forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map Vars -> Set OccName
bound [Vars]
vs) (forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map Vars -> Set OccName
free [Vars]
vs)

-- A type `a` is a model of `AllVars a` if exists a function
-- `allVars` for producing a pair of the bound and free variable
-- sets in a value of `a`.
class AllVars a where
    -- | Return the variables, erring on the side of more free
    -- variables.
    allVars :: a -> Vars

-- A type `a` is a model of `FreeVars a` if exists a function
-- `freeVars` for producing a set of free variables of a value of
-- `a`.
class FreeVars a where
    -- | Return the variables, erring on the side of more free
    -- variables.
    freeVars :: a -> Set OccName

-- Trivial instances.
instance AllVars Vars  where allVars :: Vars -> Vars
allVars = forall a. a -> a
id
instance FreeVars (Set OccName) where freeVars :: Set OccName -> Set OccName
freeVars = forall a. a -> a
id
-- [Note : Space leaks lurking here?]
-- ==================================
-- We make use of `foldr`. @cocreature suggests we want bangs on `data
-- Vars` and replace usages of `mconcat` with `foldl`.
instance (AllVars a) => AllVars [a] where  allVars :: [a] -> Vars
allVars = forall b a. Monoid b => (a -> b) -> [a] -> b
mconcatMap forall a. AllVars a => a -> Vars
allVars
instance (FreeVars a) => FreeVars [a] where  freeVars :: [a] -> Set OccName
freeVars = forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall a. FreeVars a => a -> Set OccName
freeVars

-- Construct a `Vars` value with no bound vars.
freeVars_ :: (FreeVars a) => a -> Vars
freeVars_ :: forall a. FreeVars a => a -> Vars
freeVars_ = Set OccName -> Set OccName -> Vars
Vars forall a. Set a
Set.empty forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FreeVars a => a -> Set OccName
freeVars

-- `inFree a b` is the set of free variables in a together with the
-- free variables in b not bound in a.
inFree :: (AllVars a, FreeVars b) => a -> b -> Set OccName
inFree :: forall a b. (AllVars a, FreeVars b) => a -> b -> Set OccName
inFree a
a b
b = Vars -> Set OccName
free Vars
aa Set OccName -> Set OccName -> Set OccName
^+ (forall a. FreeVars a => a -> Set OccName
freeVars b
b Set OccName -> Set OccName -> Set OccName
^- Vars -> Set OccName
bound Vars
aa)
    where aa :: Vars
aa = forall a. AllVars a => a -> Vars
allVars a
a

-- `inVars a b` is a value of `Vars_` with bound variables the union
-- of the bound variables of a and b and free variables the union
-- of the free variables of a and the free variables of b not
-- bound by a.
inVars :: (AllVars a, AllVars b) => a -> b -> Vars
inVars :: forall a b. (AllVars a, AllVars b) => a -> b -> Vars
inVars a
a b
b =
  Set OccName -> Set OccName -> Vars
Vars (Vars -> Set OccName
bound Vars
aa Set OccName -> Set OccName -> Set OccName
^+ Vars -> Set OccName
bound Vars
bb) (Vars -> Set OccName
free Vars
aa Set OccName -> Set OccName -> Set OccName
^+ (Vars -> Set OccName
free Vars
bb Set OccName -> Set OccName -> Set OccName
^- Vars -> Set OccName
bound Vars
aa))
    where aa :: Vars
aa = forall a. AllVars a => a -> Vars
allVars a
a
          bb :: Vars
bb = forall a. AllVars a => a -> Vars
allVars b
b

-- Get an `OccName` out of a reader name.
unqualNames :: LocatedN RdrName -> [OccName]
unqualNames :: LocatedN RdrName -> [OccName]
unqualNames (L SrcSpanAnnN
_ (Unqual OccName
x)) = [OccName
x]
unqualNames (L SrcSpanAnnN
_ (Exact Name
x)) = [Name -> OccName
nameOccName Name
x]
unqualNames LocatedN RdrName
_ = []

instance FreeVars (LocatedA (HsExpr GhcPs)) where
  freeVars :: LocatedA (HsExpr GhcPs) -> Set OccName
freeVars (L SrcSpanAnnA
_ (HsVar XVar GhcPs
_ LIdP GhcPs
x)) = forall a. Ord a => [a] -> Set a
Set.fromList forall a b. (a -> b) -> a -> b
$ LocatedN RdrName -> [OccName]
unqualNames LIdP GhcPs
x -- Variable.
  freeVars (L SrcSpanAnnA
_ (HsUnboundVar XUnboundVar GhcPs
_ RdrName
x)) = forall a. Ord a => [a] -> Set a
Set.fromList [RdrName -> OccName
rdrNameOcc RdrName
x] -- Unbound variable; also used for "holes".
  freeVars (L SrcSpanAnnA
_ (HsLam XLam GhcPs
_ MatchGroup GhcPs (LHsExpr GhcPs)
mg)) = Vars -> Set OccName
free (forall a. AllVars a => a -> Vars
allVars MatchGroup GhcPs (LHsExpr GhcPs)
mg) -- Lambda abstraction. Currently always a single match.
  freeVars (L SrcSpanAnnA
_ (HsLamCase XLamCase GhcPs
_ LamCaseVariant
_ MG{mg_alts :: forall p body. MatchGroup p body -> XRec p [LMatch p body]
mg_alts=(L SrcSpanAnnL
_ [GenLocated SrcSpanAnnA (Match GhcPs (LocatedA (HsExpr GhcPs)))]
ms)})) = Vars -> Set OccName
free (forall a. AllVars a => a -> Vars
allVars [GenLocated SrcSpanAnnA (Match GhcPs (LocatedA (HsExpr GhcPs)))]
ms) -- Lambda case
  freeVars (L SrcSpanAnnA
_ (HsCase XCase GhcPs
_ LHsExpr GhcPs
of_ MG{mg_alts :: forall p body. MatchGroup p body -> XRec p [LMatch p body]
mg_alts=(L SrcSpanAnnL
_ [GenLocated SrcSpanAnnA (Match GhcPs (LocatedA (HsExpr GhcPs)))]
ms)})) = forall a. FreeVars a => a -> Set OccName
freeVars LHsExpr GhcPs
of_ Set OccName -> Set OccName -> Set OccName
^+ Vars -> Set OccName
free (forall a. AllVars a => a -> Vars
allVars [GenLocated SrcSpanAnnA (Match GhcPs (LocatedA (HsExpr GhcPs)))]
ms) -- Case expr.
  freeVars (L SrcSpanAnnA
_ (HsLet XLet GhcPs
_ LHsToken "let" GhcPs
_ HsLocalBinds GhcPs
binds LHsToken "in" GhcPs
_ LHsExpr GhcPs
e)) = forall a b. (AllVars a, FreeVars b) => a -> b -> Set OccName
inFree HsLocalBinds GhcPs
binds LHsExpr GhcPs
e -- Let (rec).
  freeVars (L SrcSpanAnnA
_ (HsDo XDo GhcPs
_ HsDoFlavour
ctxt (L SrcSpanAnnL
_ [LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs)))]
stmts))) = forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (Set OccName, Set OccName)
-> LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs)))
-> (Set OccName, Set OccName)
alg forall a. Monoid a => a
mempty [LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs)))]
stmts -- Do block.
    where
      alg ::
        (Set OccName, Set OccName) ->
        LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs))) ->
        (Set OccName, Set OccName)
      alg :: (Set OccName, Set OccName)
-> LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs)))
-> (Set OccName, Set OccName)
alg (Set OccName
accBound0, Set OccName
accFree0) LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs)))
stmt = (Set OccName
accBound, Set OccName
accFree)
        where
          accBound :: Set OccName
accBound =
            Set OccName
accBound0
              Set OccName -> Set OccName -> Set OccName
^+ ( case LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs)))
stmt of
                     L SrcSpanAnnA
_ (BindStmt XBindStmt GhcPs GhcPs (LocatedA (HsExpr GhcPs))
_ LPat GhcPs
pat LocatedA (HsExpr GhcPs)
_) -> Vars -> Set OccName
bound (forall a. AllVars a => a -> Vars
allVars LPat GhcPs
pat)
                     L SrcSpanAnnA
_ (LetStmt XLetStmt GhcPs GhcPs (LocatedA (HsExpr GhcPs))
_ HsLocalBinds GhcPs
binds) -> Vars -> Set OccName
bound (forall a. AllVars a => a -> Vars
allVars HsLocalBinds GhcPs
binds)
                     LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs)))
_ -> forall a. Monoid a => a
mempty
                 )
          accFree :: Set OccName
accFree = Set OccName
accFree0 Set OccName -> Set OccName -> Set OccName
^+ (Vars -> Set OccName
free (forall a. AllVars a => a -> Vars
allVars LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs)))
stmt) Set OccName -> Set OccName -> Set OccName
^- Set OccName
accBound0)
  freeVars (L SrcSpanAnnA
_ (RecordCon XRecordCon GhcPs
_ XRec GhcPs (ConLikeP GhcPs)
_ (HsRecFields [LHsRecField GhcPs (LHsExpr GhcPs)]
flds Maybe (XRec GhcPs RecFieldsDotDot)
_))) = forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall a. FreeVars a => a -> Set OccName
freeVars [LHsRecField GhcPs (LHsExpr GhcPs)]
flds -- Record construction.
  freeVars (L SrcSpanAnnA
_ (RecordUpd XRecordUpd GhcPs
_ LHsExpr GhcPs
e Either [LHsRecUpdField GhcPs] [LHsRecUpdProj GhcPs]
flds)) =
    case Either [LHsRecUpdField GhcPs] [LHsRecUpdProj GhcPs]
flds of
      Left [LHsRecUpdField GhcPs]
fs -> forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions forall a b. (a -> b) -> a -> b
$ forall a. FreeVars a => a -> Set OccName
freeVars LHsExpr GhcPs
e forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map forall a. FreeVars a => a -> Set OccName
freeVars [LHsRecUpdField GhcPs]
fs
      Right [LHsRecUpdProj GhcPs]
ps -> forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions forall a b. (a -> b) -> a -> b
$ forall a. FreeVars a => a -> Set OccName
freeVars LHsExpr GhcPs
e forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map forall a. FreeVars a => a -> Set OccName
freeVars [LHsRecUpdProj GhcPs]
ps
  freeVars (L SrcSpanAnnA
_ (HsMultiIf XMultiIf GhcPs
_ [LGRHS GhcPs (LHsExpr GhcPs)]
grhss)) = Vars -> Set OccName
free (forall a. AllVars a => a -> Vars
allVars [LGRHS GhcPs (LHsExpr GhcPs)]
grhss) -- Multi-way if.
  freeVars (L SrcSpanAnnA
_ (HsTypedBracket XTypedBracket GhcPs
_ LHsExpr GhcPs
e)) = forall a. FreeVars a => a -> Set OccName
freeVars LHsExpr GhcPs
e
  freeVars (L SrcSpanAnnA
_ (HsUntypedBracket XUntypedBracket GhcPs
_ (ExpBr XExpBr GhcPs
_ LHsExpr GhcPs
e))) = forall a. FreeVars a => a -> Set OccName
freeVars LHsExpr GhcPs
e
  freeVars (L SrcSpanAnnA
_ (HsUntypedBracket XUntypedBracket GhcPs
_ (VarBr XVarBr GhcPs
_ Bool
_ LIdP GhcPs
v))) = forall a. Ord a => [a] -> Set a
Set.fromList [forall name. HasOccName name => name -> OccName
occName (forall l e. GenLocated l e -> e
unLoc LIdP GhcPs
v)]

  freeVars (L SrcSpanAnnA
_ HsRecSel{}) = forall a. Monoid a => a
mempty -- Variable pointing to a record selector.
  freeVars (L SrcSpanAnnA
_ HsOverLabel{}) = forall a. Monoid a => a
mempty -- Overloaded label. The id of the in-scope fromLabel.
  freeVars (L SrcSpanAnnA
_ HsIPVar{}) = forall a. Monoid a => a
mempty -- Implicit parameter.
  freeVars (L SrcSpanAnnA
_ HsOverLit{}) = forall a. Monoid a => a
mempty -- Overloaded literal.
  freeVars (L SrcSpanAnnA
_ HsLit{}) = forall a. Monoid a => a
mempty -- Simple literal.

  -- freeVars (e@(L _ HsAppType{})) = freeVars $ children e -- Visible type application e.g. f @ Int x y.
  -- freeVars (e@(L _ HsApp{})) = freeVars $ children e -- Application.
  -- freeVars (e@(L _ OpApp{})) = freeVars $ children e -- Operator application.
  -- freeVars (e@(L _ NegApp{})) = freeVars $ children e -- Negation operator.
  -- freeVars (e@(L _ HsPar{})) = freeVars $ children e -- Parenthesized expr.
  -- freeVars (e@(L _ SectionL{})) = freeVars $ children e -- Left section.
  -- freeVars (e@(L _ SectionR{})) = freeVars $ children e -- Right section.
  -- freeVars (e@(L _ ExplicitTuple{})) = freeVars $ children e -- Explicit tuple and sections thereof.
  -- freeVars (e@(L _ ExplicitSum{})) = freeVars $ children e -- Used for unboxed sum types.
  -- freeVars (e@(L _ HsIf{})) = freeVars $ children e -- If.
  -- freeVars (e@(L _ ExplicitList{})) = freeVars $ children e -- Syntactic list e.g. [a, b, c].
  -- freeVars (e@(L _ ExprWithTySig{})) = freeVars $ children e -- Expr with type signature.
  -- freeVars (e@(L _ ArithSeq {})) = freeVars $ children e -- Arithmetic sequence.
  -- freeVars (e@(L _ HsSCC{})) = freeVars $ children e -- Set cost center pragma (expr whose const is to be measured).
  -- freeVars (e@(L _ HsCoreAnn{})) = freeVars $ children e -- Pragma.
  -- freeVars (e@(L _ HsBracket{})) = freeVars $ children e -- Haskell bracket.
  -- freeVars (e@(L _ HsSpliceE{})) = freeVars $ children e -- Template haskell splice expr.
  -- freeVars (e@(L _ HsProc{})) = freeVars $ children e -- Proc notation for arrows.
  -- freeVars (e@(L _ HsStatic{})) = freeVars $ children e -- Static pointers extension.
  -- freeVars (e@(L _ HsArrApp{})) = freeVars $ children e -- Arrow tail or arrow application.
  -- freeVars (e@(L _ HsArrForm{})) = freeVars $ children e -- Come back to it. Arrow tail or arrow application.
  -- freeVars (e@(L _ HsTick{})) = freeVars $ children e -- Haskell program coverage (Hpc) support.
  -- freeVars (e@(L _ HsBinTick{})) = freeVars $ children e -- Haskell program coverage (Hpc) support.
  -- freeVars (e@(L _ HsTickPragma{})) = freeVars $ children e -- Haskell program coverage (Hpc) support.
  -- freeVars (e@(L _ EAsPat{})) = freeVars $ children e -- Expr as pat.
  -- freeVars (e@(L _ EViewPat{})) = freeVars $ children e -- View pattern.
  -- freeVars (e@(L _ ELazyPat{})) = freeVars $ children e -- Lazy pattern.

  freeVars LocatedA (HsExpr GhcPs)
e = forall a. FreeVars a => a -> Set OccName
freeVars forall a b. (a -> b) -> a -> b
$ forall on. Uniplate on => on -> [on]
children LocatedA (HsExpr GhcPs)
e

instance FreeVars (HsTupArg GhcPs) where
  freeVars :: HsTupArg GhcPs -> Set OccName
freeVars (Present XPresent GhcPs
_ LHsExpr GhcPs
args) = forall a. FreeVars a => a -> Set OccName
freeVars LHsExpr GhcPs
args
  freeVars HsTupArg GhcPs
_ = forall a. Monoid a => a
mempty

instance FreeVars (LocatedA (HsFieldBind (LocatedAn NoEpAnns (FieldOcc GhcPs)) (LocatedA (HsExpr GhcPs)))) where
   freeVars :: GenLocated
  SrcSpanAnnA
  (HsFieldBind
     (GenLocated (SrcAnn NoEpAnns) (FieldOcc GhcPs))
     (LocatedA (HsExpr GhcPs)))
-> Set OccName
freeVars o :: GenLocated
  SrcSpanAnnA
  (HsFieldBind
     (GenLocated (SrcAnn NoEpAnns) (FieldOcc GhcPs))
     (LocatedA (HsExpr GhcPs)))
o@(L SrcSpanAnnA
_ (HsFieldBind XHsFieldBind (GenLocated (SrcAnn NoEpAnns) (FieldOcc GhcPs))
_ GenLocated (SrcAnn NoEpAnns) (FieldOcc GhcPs)
x LocatedA (HsExpr GhcPs)
_ Bool
True)) = forall a. a -> Set a
Set.singleton forall a b. (a -> b) -> a -> b
$ forall name. HasOccName name => name -> OccName
occName forall a b. (a -> b) -> a -> b
$ forall l e. GenLocated l e -> e
unLoc forall a b. (a -> b) -> a -> b
$ forall pass. FieldOcc pass -> XRec pass RdrName
foLabel forall a b. (a -> b) -> a -> b
$ forall l e. GenLocated l e -> e
unLoc GenLocated (SrcAnn NoEpAnns) (FieldOcc GhcPs)
x -- a pun
   freeVars o :: GenLocated
  SrcSpanAnnA
  (HsFieldBind
     (GenLocated (SrcAnn NoEpAnns) (FieldOcc GhcPs))
     (LocatedA (HsExpr GhcPs)))
o@(L SrcSpanAnnA
_ (HsFieldBind XHsFieldBind (GenLocated (SrcAnn NoEpAnns) (FieldOcc GhcPs))
_ GenLocated (SrcAnn NoEpAnns) (FieldOcc GhcPs)
_ LocatedA (HsExpr GhcPs)
x Bool
_)) = forall a. FreeVars a => a -> Set OccName
freeVars LocatedA (HsExpr GhcPs)
x

instance FreeVars (LocatedA (HsFieldBind (LocatedAn NoEpAnns (AmbiguousFieldOcc GhcPs)) (LocatedA (HsExpr GhcPs)))) where
  freeVars :: GenLocated
  SrcSpanAnnA
  (HsFieldBind
     (GenLocated (SrcAnn NoEpAnns) (AmbiguousFieldOcc GhcPs))
     (LocatedA (HsExpr GhcPs)))
-> Set OccName
freeVars (L SrcSpanAnnA
_ (HsFieldBind XHsFieldBind
  (GenLocated (SrcAnn NoEpAnns) (AmbiguousFieldOcc GhcPs))
_ GenLocated (SrcAnn NoEpAnns) (AmbiguousFieldOcc GhcPs)
x LocatedA (HsExpr GhcPs)
_ Bool
True)) = forall a. a -> Set a
Set.singleton forall a b. (a -> b) -> a -> b
$ RdrName -> OccName
rdrNameOcc forall a b. (a -> b) -> a -> b
$ forall (p :: Pass). AmbiguousFieldOcc (GhcPass p) -> RdrName
rdrNameAmbiguousFieldOcc forall a b. (a -> b) -> a -> b
$ forall l e. GenLocated l e -> e
unLoc GenLocated (SrcAnn NoEpAnns) (AmbiguousFieldOcc GhcPs)
x -- a pun
  freeVars (L SrcSpanAnnA
_ (HsFieldBind XHsFieldBind
  (GenLocated (SrcAnn NoEpAnns) (AmbiguousFieldOcc GhcPs))
_ GenLocated (SrcAnn NoEpAnns) (AmbiguousFieldOcc GhcPs)
_ LocatedA (HsExpr GhcPs)
x Bool
_)) = forall a. FreeVars a => a -> Set OccName
freeVars LocatedA (HsExpr GhcPs)
x

instance FreeVars (LocatedA (HsFieldBind (LocatedAn NoEpAnns (FieldLabelStrings GhcPs)) (LocatedA (HsExpr GhcPs)))) where
  freeVars :: GenLocated
  SrcSpanAnnA
  (HsFieldBind
     (GenLocated (SrcAnn NoEpAnns) (FieldLabelStrings GhcPs))
     (LocatedA (HsExpr GhcPs)))
-> Set OccName
freeVars (L SrcSpanAnnA
_ (HsFieldBind XHsFieldBind
  (GenLocated (SrcAnn NoEpAnns) (FieldLabelStrings GhcPs))
_ GenLocated (SrcAnn NoEpAnns) (FieldLabelStrings GhcPs)
_ LocatedA (HsExpr GhcPs)
x Bool
_)) = forall a. FreeVars a => a -> Set OccName
freeVars LocatedA (HsExpr GhcPs)
x

instance AllVars (LocatedA (Pat GhcPs)) where
  allVars :: GenLocated SrcSpanAnnA (Pat GhcPs) -> Vars
allVars (L SrcSpanAnnA
_ (VarPat XVarPat GhcPs
_ (L SrcSpanAnnN
_ RdrName
x))) = Set OccName -> Set OccName -> Vars
Vars (forall a. a -> Set a
Set.singleton forall a b. (a -> b) -> a -> b
$ RdrName -> OccName
rdrNameOcc RdrName
x) forall a. Set a
Set.empty -- Variable pattern.
  allVars (L SrcSpanAnnA
_ (AsPat XAsPat GhcPs
_  LIdP GhcPs
n LHsToken "@" GhcPs
_ LPat GhcPs
x)) = forall a. AllVars a => a -> Vars
allVars (forall a an. a -> LocatedAn an a
noLocA forall a b. (a -> b) -> a -> b
$ forall p. XVarPat p -> LIdP p -> Pat p
VarPat NoExtField
noExtField LIdP GhcPs
n :: LocatedA (Pat GhcPs)) forall a. Semigroup a => a -> a -> a
<> forall a. AllVars a => a -> Vars
allVars LPat GhcPs
x -- As pattern.
  allVars (L SrcSpanAnnA
_ (ConPat XConPat GhcPs
_ XRec GhcPs (ConLikeP GhcPs)
_ (RecCon (HsRecFields [LHsRecField GhcPs (LPat GhcPs)]
flds Maybe (XRec GhcPs RecFieldsDotDot)
_)))) = forall a. AllVars a => a -> Vars
allVars [LHsRecField GhcPs (LPat GhcPs)]
flds
  allVars (L SrcSpanAnnA
_ (NPlusKPat XNPlusKPat GhcPs
_ LIdP GhcPs
n XRec GhcPs (HsOverLit GhcPs)
_ HsOverLit GhcPs
_ SyntaxExpr GhcPs
_ SyntaxExpr GhcPs
_)) = forall a. AllVars a => a -> Vars
allVars (forall a an. a -> LocatedAn an a
noLocA forall a b. (a -> b) -> a -> b
$ forall p. XVarPat p -> LIdP p -> Pat p
VarPat NoExtField
noExtField LIdP GhcPs
n :: LocatedA (Pat GhcPs)) -- n+k pattern.
  allVars (L SrcSpanAnnA
_ (ViewPat XViewPat GhcPs
_ LHsExpr GhcPs
e LPat GhcPs
p)) = forall a. FreeVars a => a -> Vars
freeVars_ LHsExpr GhcPs
e forall a. Semigroup a => a -> a -> a
<> forall a. AllVars a => a -> Vars
allVars LPat GhcPs
p -- View pattern.

  allVars (L SrcSpanAnnA
_ WildPat{}) = forall a. Monoid a => a
mempty -- Wildcard pattern.
  allVars (L SrcSpanAnnA
_ LitPat{}) = forall a. Monoid a => a
mempty -- Literal pattern.
  allVars (L SrcSpanAnnA
_ NPat{}) = forall a. Monoid a => a
mempty -- Natural pattern.

  -- allVars p@SplicePat{} = allVars $ children p -- Splice pattern (includes quasi-quotes).
  -- allVars p@SigPat{} = allVars $ children p -- Pattern with a type signature.
  -- allVars p@CoPat{} = allVars $ children p -- Coercion pattern.
  -- allVars p@LazyPat{} = allVars $ children p -- Lazy pattern.
  -- allVars p@ParPat{} = allVars $ children p -- Parenthesized pattern.
  -- allVars p@BangPat{} = allVars $ children p -- Bang pattern.
  -- allVars p@ListPat{} = allVars $ children p -- Syntactic list.
  -- allVars p@TuplePat{} = allVars $ children p -- Tuple sub patterns.
  -- allVars p@SumPat{} = allVars $ children p -- Anonymous sum pattern.

  allVars GenLocated SrcSpanAnnA (Pat GhcPs)
p = forall a. AllVars a => a -> Vars
allVars forall a b. (a -> b) -> a -> b
$ forall on. Uniplate on => on -> [on]
children GenLocated SrcSpanAnnA (Pat GhcPs)
p

instance AllVars (LocatedA (HsFieldBind (LocatedAn NoEpAnns (FieldOcc GhcPs)) (LocatedA (Pat GhcPs)))) where
   allVars :: GenLocated
  SrcSpanAnnA
  (HsFieldBind
     (GenLocated (SrcAnn NoEpAnns) (FieldOcc GhcPs))
     (GenLocated SrcSpanAnnA (Pat GhcPs)))
-> Vars
allVars (L SrcSpanAnnA
_ (HsFieldBind XHsFieldBind (GenLocated (SrcAnn NoEpAnns) (FieldOcc GhcPs))
_ GenLocated (SrcAnn NoEpAnns) (FieldOcc GhcPs)
_ GenLocated SrcSpanAnnA (Pat GhcPs)
x Bool
_)) = forall a. AllVars a => a -> Vars
allVars GenLocated SrcSpanAnnA (Pat GhcPs)
x

instance AllVars (LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs)))) where
  allVars :: LocatedA (StmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs))) -> Vars
allVars (L SrcSpanAnnA
_ (LastStmt XLastStmt GhcPs GhcPs (LocatedA (HsExpr GhcPs))
_ LocatedA (HsExpr GhcPs)
expr Maybe Bool
_ SyntaxExpr GhcPs
_)) = forall a. FreeVars a => a -> Vars
freeVars_ LocatedA (HsExpr GhcPs)
expr -- The last stmt of a ListComp, MonadComp, DoExpr,MDoExpr.
  allVars (L SrcSpanAnnA
_ (BindStmt XBindStmt GhcPs GhcPs (LocatedA (HsExpr GhcPs))
_ LPat GhcPs
pat LocatedA (HsExpr GhcPs)
expr)) = forall a. AllVars a => a -> Vars
allVars LPat GhcPs
pat forall a. Semigroup a => a -> a -> a
<> forall a. FreeVars a => a -> Vars
freeVars_ LocatedA (HsExpr GhcPs)
expr -- A generator e.g. x <- [1, 2, 3].
  allVars (L SrcSpanAnnA
_ (BodyStmt XBodyStmt GhcPs GhcPs (LocatedA (HsExpr GhcPs))
_ LocatedA (HsExpr GhcPs)
expr SyntaxExpr GhcPs
_ SyntaxExpr GhcPs
_)) = forall a. FreeVars a => a -> Vars
freeVars_ LocatedA (HsExpr GhcPs)
expr -- A boolean guard e.g. even x.
  allVars (L SrcSpanAnnA
_ (LetStmt XLetStmt GhcPs GhcPs (LocatedA (HsExpr GhcPs))
_ HsLocalBinds GhcPs
binds)) = forall a. AllVars a => a -> Vars
allVars HsLocalBinds GhcPs
binds -- A local declaration e.g. let y = x + 1
  allVars (L SrcSpanAnnA
_ (TransStmt XTransStmt GhcPs GhcPs (LocatedA (HsExpr GhcPs))
_ TransForm
_ [ExprLStmt GhcPs]
stmts [(IdP GhcPs, IdP GhcPs)]
_ LHsExpr GhcPs
using Maybe (LHsExpr GhcPs)
by SyntaxExpr GhcPs
_ SyntaxExpr GhcPs
_ HsExpr GhcPs
fmap_)) = forall a. AllVars a => a -> Vars
allVars [ExprLStmt GhcPs]
stmts forall a. Semigroup a => a -> a -> a
<> forall a. FreeVars a => a -> Vars
freeVars_ LHsExpr GhcPs
using forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall a. FreeVars a => a -> Vars
freeVars_ Maybe (LHsExpr GhcPs)
by forall a. Semigroup a => a -> a -> a
<> forall a. FreeVars a => a -> Vars
freeVars_ (forall a an. a -> LocatedAn an a
noLocA HsExpr GhcPs
fmap_ :: LocatedA (HsExpr GhcPs)) -- Apply a function to a list of statements in order.
  allVars (L SrcSpanAnnA
_ (RecStmt XRecStmt GhcPs GhcPs (LocatedA (HsExpr GhcPs))
_ XRec GhcPs [LStmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs))]
stmts [IdP GhcPs]
_ [IdP GhcPs]
_ SyntaxExpr GhcPs
_ SyntaxExpr GhcPs
_ SyntaxExpr GhcPs
_)) = forall a. AllVars a => a -> Vars
allVars (forall l e. GenLocated l e -> e
unLoc XRec GhcPs [LStmtLR GhcPs GhcPs (LocatedA (HsExpr GhcPs))]
stmts) -- A recursive binding for a group of arrows.

  allVars (L SrcSpanAnnA
_ ApplicativeStmt{}) = forall a. Monoid a => a
mempty -- Generated by the renamer.
  allVars (L SrcSpanAnnA
_ ParStmt{}) = forall a. Monoid a => a
mempty -- Parallel list thing. Come back to it.

instance AllVars (HsLocalBinds GhcPs) where
  allVars :: HsLocalBinds GhcPs -> Vars
allVars (HsValBinds XHsValBinds GhcPs GhcPs
_ (ValBinds XValBinds GhcPs GhcPs
_ LHsBindsLR GhcPs GhcPs
binds [LSig GhcPs]
_)) = forall a. AllVars a => a -> Vars
allVars (forall a. Bag a -> [a]
bagToList LHsBindsLR GhcPs GhcPs
binds) -- Value bindings.
  allVars (HsIPBinds XHsIPBinds GhcPs GhcPs
_ (IPBinds XIPBinds GhcPs
_ [LIPBind GhcPs]
binds)) = forall a. AllVars a => a -> Vars
allVars [LIPBind GhcPs]
binds -- Implicit parameter bindings.
  allVars EmptyLocalBinds{} =  forall a. Monoid a => a
mempty -- The case of no local bindings (signals the empty `let` or `where` clause).
  allVars HsLocalBinds GhcPs
_ = forall a. Monoid a => a
mempty -- extension points

instance AllVars (LocatedA (IPBind GhcPs)) where
  allVars :: GenLocated SrcSpanAnnA (IPBind GhcPs) -> Vars
allVars (L SrcSpanAnnA
_ (IPBind XCIPBind GhcPs
_ XRec GhcPs HsIPName
_ LHsExpr GhcPs
e)) = forall a. FreeVars a => a -> Vars
freeVars_ LHsExpr GhcPs
e

instance AllVars (LocatedA (HsBindLR GhcPs GhcPs)) where
  allVars :: GenLocated SrcSpanAnnA (HsBindLR GhcPs GhcPs) -> Vars
allVars (L SrcSpanAnnA
_ FunBind{fun_id :: forall idL idR. HsBindLR idL idR -> LIdP idL
fun_id=LIdP GhcPs
n, fun_matches :: forall idL idR. HsBindLR idL idR -> MatchGroup idR (LHsExpr idR)
fun_matches=MG{mg_alts :: forall p body. MatchGroup p body -> XRec p [LMatch p body]
mg_alts=(L SrcSpanAnnL
_ [GenLocated SrcSpanAnnA (Match GhcPs (LocatedA (HsExpr GhcPs)))]
ms)}}) = forall a. AllVars a => a -> Vars
allVars (forall a an. a -> LocatedAn an a
noLocA forall a b. (a -> b) -> a -> b
$ forall p. XVarPat p -> LIdP p -> Pat p
VarPat NoExtField
noExtField LIdP GhcPs
n :: LocatedA (Pat GhcPs)) forall a. Semigroup a => a -> a -> a
<> forall a. AllVars a => a -> Vars
allVars [GenLocated SrcSpanAnnA (Match GhcPs (LocatedA (HsExpr GhcPs)))]
ms -- Function bindings and simple variable bindings e.g. f x = e, f !x = 3, f = e, !x = e, x `f` y = e
  allVars (L SrcSpanAnnA
_ PatBind{pat_lhs :: forall idL idR. HsBindLR idL idR -> LPat idL
pat_lhs=LPat GhcPs
n, pat_rhs :: forall idL idR. HsBindLR idL idR -> GRHSs idR (LHsExpr idR)
pat_rhs=GRHSs GhcPs (LHsExpr GhcPs)
grhss}) = forall a. AllVars a => a -> Vars
allVars LPat GhcPs
n forall a. Semigroup a => a -> a -> a
<> forall a. AllVars a => a -> Vars
allVars GRHSs GhcPs (LHsExpr GhcPs)
grhss -- Ctor patterns and some other interesting cases e.g. Just x = e, (x) = e, x :: Ty = e.

  allVars (L SrcSpanAnnA
_ (PatSynBind XPatSynBind GhcPs GhcPs
_ PSB{})) = forall a. Monoid a => a
mempty -- Come back to it.

instance AllVars (MatchGroup GhcPs (LocatedA (HsExpr GhcPs))) where
  allVars :: MatchGroup GhcPs (LocatedA (HsExpr GhcPs)) -> Vars
allVars (MG XMG GhcPs (LocatedA (HsExpr GhcPs))
_ _alts :: XRec GhcPs [LMatch GhcPs (LocatedA (HsExpr GhcPs))]
_alts@(L SrcSpanAnnL
_ [GenLocated SrcSpanAnnA (Match GhcPs (LocatedA (HsExpr GhcPs)))]
alts)) = forall a b. (AllVars a, AllVars b) => a -> b -> Vars
inVars (forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (forall a. AllVars a => a -> Vars
allVars forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall p body. Match p body -> [LPat p]
m_pats) [Match GhcPs (LocatedA (HsExpr GhcPs))]
ms) (forall a. AllVars a => a -> Vars
allVars (forall a b. (a -> b) -> [a] -> [b]
map forall p body. Match p body -> GRHSs p body
m_grhss [Match GhcPs (LocatedA (HsExpr GhcPs))]
ms))
    where ms :: [Match GhcPs (LocatedA (HsExpr GhcPs))]
ms = forall a b. (a -> b) -> [a] -> [b]
map forall l e. GenLocated l e -> e
unLoc [GenLocated SrcSpanAnnA (Match GhcPs (LocatedA (HsExpr GhcPs)))]
alts

instance AllVars (LocatedA (Match GhcPs (LocatedA (HsExpr GhcPs)))) where
  allVars :: GenLocated SrcSpanAnnA (Match GhcPs (LocatedA (HsExpr GhcPs)))
-> Vars
allVars (L SrcSpanAnnA
_ (Match XCMatch GhcPs (LocatedA (HsExpr GhcPs))
_ FunRhs {mc_fun :: forall p. HsMatchContext p -> LIdP (NoGhcTc p)
mc_fun=LIdP (NoGhcTc GhcPs)
name} [LPat GhcPs]
pats GRHSs GhcPs (LocatedA (HsExpr GhcPs))
grhss)) = forall a. AllVars a => a -> Vars
allVars (forall a an. a -> LocatedAn an a
noLocA forall a b. (a -> b) -> a -> b
$ forall p. XVarPat p -> LIdP p -> Pat p
VarPat NoExtField
noExtField LIdP (NoGhcTc GhcPs)
name :: LocatedA (Pat GhcPs)) forall a. Semigroup a => a -> a -> a
<> forall a. AllVars a => a -> Vars
allVars [LPat GhcPs]
pats forall a. Semigroup a => a -> a -> a
<> forall a. AllVars a => a -> Vars
allVars GRHSs GhcPs (LocatedA (HsExpr GhcPs))
grhss -- A pattern matching on an argument of a function binding.
  allVars (L SrcSpanAnnA
_ (Match XCMatch GhcPs (LocatedA (HsExpr GhcPs))
_ (StmtCtxt HsStmtContext GhcPs
ctxt) [LPat GhcPs]
pats GRHSs GhcPs (LocatedA (HsExpr GhcPs))
grhss)) = forall a. AllVars a => a -> Vars
allVars HsStmtContext GhcPs
ctxt forall a. Semigroup a => a -> a -> a
<> forall a. AllVars a => a -> Vars
allVars [LPat GhcPs]
pats forall a. Semigroup a => a -> a -> a
<> forall a. AllVars a => a -> Vars
allVars GRHSs GhcPs (LocatedA (HsExpr GhcPs))
grhss -- Pattern of a do-stmt, list comprehension, pattern guard etc.
  allVars (L SrcSpanAnnA
_ (Match XCMatch GhcPs (LocatedA (HsExpr GhcPs))
_ HsMatchContext GhcPs
_ [LPat GhcPs]
pats GRHSs GhcPs (LocatedA (HsExpr GhcPs))
grhss)) = forall a b. (AllVars a, AllVars b) => a -> b -> Vars
inVars (forall a. AllVars a => a -> Vars
allVars [LPat GhcPs]
pats) (forall a. AllVars a => a -> Vars
allVars GRHSs GhcPs (LocatedA (HsExpr GhcPs))
grhss) -- Everything else.

instance AllVars (HsStmtContext GhcPs) where
  allVars :: HsStmtContext GhcPs -> Vars
allVars (PatGuard FunRhs{mc_fun :: forall p. HsMatchContext p -> LIdP (NoGhcTc p)
mc_fun=LIdP (NoGhcTc GhcPs)
n}) = forall a. AllVars a => a -> Vars
allVars (forall a an. a -> LocatedAn an a
noLocA forall a b. (a -> b) -> a -> b
$ forall p. XVarPat p -> LIdP p -> Pat p
VarPat NoExtField
noExtField LIdP (NoGhcTc GhcPs)
n :: LocatedA (Pat GhcPs))
  allVars ParStmtCtxt{} = forall a. Monoid a => a
mempty -- Come back to it.
  allVars TransStmtCtxt{}  = forall a. Monoid a => a
mempty -- Come back to it.
  allVars HsStmtContext GhcPs
_ = forall a. Monoid a => a
mempty

instance AllVars (GRHSs GhcPs (LocatedA (HsExpr GhcPs))) where
  allVars :: GRHSs GhcPs (LocatedA (HsExpr GhcPs)) -> Vars
allVars (GRHSs XCGRHSs GhcPs (LocatedA (HsExpr GhcPs))
_ [LGRHS GhcPs (LocatedA (HsExpr GhcPs))]
grhss HsLocalBinds GhcPs
binds) = forall a b. (AllVars a, AllVars b) => a -> b -> Vars
inVars HsLocalBinds GhcPs
binds (forall b a. Monoid b => (a -> b) -> [a] -> b
mconcatMap forall a. AllVars a => a -> Vars
allVars [LGRHS GhcPs (LocatedA (HsExpr GhcPs))]
grhss)

instance AllVars (LocatedAn NoEpAnns (GRHS GhcPs (LocatedA (HsExpr GhcPs)))) where
  allVars :: GenLocated (SrcAnn NoEpAnns) (GRHS GhcPs (LocatedA (HsExpr GhcPs)))
-> Vars
allVars (L SrcAnn NoEpAnns
_ (GRHS XCGRHS GhcPs (LocatedA (HsExpr GhcPs))
_ [ExprLStmt GhcPs]
guards LocatedA (HsExpr GhcPs)
expr)) = Set OccName -> Set OccName -> Vars
Vars (Vars -> Set OccName
bound Vars
gs) (Vars -> Set OccName
free Vars
gs Set OccName -> Set OccName -> Set OccName
^+ (forall a. FreeVars a => a -> Set OccName
freeVars LocatedA (HsExpr GhcPs)
expr Set OccName -> Set OccName -> Set OccName
^- Vars -> Set OccName
bound Vars
gs)) where gs :: Vars
gs = forall a. AllVars a => a -> Vars
allVars [ExprLStmt GhcPs]
guards

instance AllVars (LocatedA (HsDecl GhcPs)) where
  allVars :: LocatedA (HsDecl GhcPs) -> Vars
allVars (L SrcSpanAnnA
l (ValD XValD GhcPs
_ HsBindLR GhcPs GhcPs
bind)) = forall a. AllVars a => a -> Vars
allVars (forall l e. l -> e -> GenLocated l e
L SrcSpanAnnA
l HsBindLR GhcPs GhcPs
bind :: LocatedA (HsBindLR GhcPs GhcPs))
  allVars LocatedA (HsDecl GhcPs)
_ = forall a. Monoid a => a
mempty


vars :: FreeVars a => a -> [String]
vars :: forall a. FreeVars a => a -> [String]
vars = forall a. Set a -> [a]
Set.toList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map OccName -> String
occNameString forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FreeVars a => a -> Set OccName
freeVars

varss :: AllVars a => a -> [String]
varss :: forall a. AllVars a => a -> [String]
varss = forall a. Set a -> [a]
Set.toList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map OccName -> String
occNameString forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vars -> Set OccName
free forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. AllVars a => a -> Vars
allVars

pvars :: AllVars a => a -> [String]
pvars :: forall a. AllVars a => a -> [String]
pvars = forall a. Set a -> [a]
Set.toList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map OccName -> String
occNameString forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vars -> Set OccName
bound forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. AllVars a => a -> Vars
allVars