module Hint.Type(
    DeclHint, DeclHint', ModuHint, CrossHint, Hint(..),
    module Export
    ) where

import Data.Semigroup
import Config.Type
import HSE.All  as Export
import Idea     as Export
import Prelude
import Refact   as Export
import HsExtension
import HsDecls
import GHC.Util.Scope

type DeclHint = Scope -> ModuleEx -> Decl_ -> [Idea]
type DeclHint' = Scope' -> ModuleEx -> LHsDecl GhcPs -> [Idea]
type ModuHint = Scope -> ModuleEx -> [Idea]
type CrossHint = [(Scope, ModuleEx)] -> [Idea]

-- | Functions to generate hints, combined using the 'Monoid' instance.
data Hint {- PUBLIC -} = Hint
    { Hint -> [Setting] -> [(Scope, ModuleEx)] -> [Idea]
hintModules :: [Setting] -> [(Scope, ModuleEx)] -> [Idea] -- ^ Given a list of modules (and their scope information) generate some 'Idea's.
    , Hint -> [Setting] -> Scope -> ModuleEx -> [Idea]
hintModule :: [Setting] -> Scope -> ModuleEx -> [Idea] -- ^ Given a single module and its scope information generate some 'Idea's.
    , Hint
-> [Setting] -> Scope -> ModuleEx -> Decl SrcSpanInfo -> [Idea]
hintDecl :: [Setting] -> Scope -> ModuleEx -> Decl SrcSpanInfo -> [Idea]
    , Hint -> [Setting] -> Scope' -> ModuleEx -> LHsDecl GhcPs -> [Idea]
hintDecl' :: [Setting] -> Scope' -> ModuleEx -> LHsDecl GhcPs -> [Idea]
        -- ^ Given a declaration (with a module and scope) generate some 'Idea's.
        --   This function will be partially applied with one module/scope, then used on multiple 'Decl' values.
    }

instance Semigroup Hint where
    Hint x1 :: [Setting] -> [(Scope, ModuleEx)] -> [Idea]
x1 x2 :: [Setting] -> Scope -> ModuleEx -> [Idea]
x2 x3 :: [Setting] -> Scope -> ModuleEx -> Decl SrcSpanInfo -> [Idea]
x3 x4 :: [Setting] -> Scope' -> ModuleEx -> LHsDecl GhcPs -> [Idea]
x4 <> :: Hint -> Hint -> Hint
<> Hint y1 :: [Setting] -> [(Scope, ModuleEx)] -> [Idea]
y1 y2 :: [Setting] -> Scope -> ModuleEx -> [Idea]
y2 y3 :: [Setting] -> Scope -> ModuleEx -> Decl SrcSpanInfo -> [Idea]
y3 y4 :: [Setting] -> Scope' -> ModuleEx -> LHsDecl GhcPs -> [Idea]
y4 = ([Setting] -> [(Scope, ModuleEx)] -> [Idea])
-> ([Setting] -> Scope -> ModuleEx -> [Idea])
-> ([Setting] -> Scope -> ModuleEx -> Decl SrcSpanInfo -> [Idea])
-> ([Setting] -> Scope' -> ModuleEx -> LHsDecl GhcPs -> [Idea])
-> Hint
Hint
        (\a :: [Setting]
a b :: [(Scope, ModuleEx)]
b -> [Setting] -> [(Scope, ModuleEx)] -> [Idea]
x1 [Setting]
a [(Scope, ModuleEx)]
b [Idea] -> [Idea] -> [Idea]
forall a. [a] -> [a] -> [a]
++ [Setting] -> [(Scope, ModuleEx)] -> [Idea]
y1 [Setting]
a [(Scope, ModuleEx)]
b)
        (\a :: [Setting]
a b :: Scope
b c :: ModuleEx
c -> [Setting] -> Scope -> ModuleEx -> [Idea]
x2 [Setting]
a Scope
b ModuleEx
c [Idea] -> [Idea] -> [Idea]
forall a. [a] -> [a] -> [a]
++ [Setting] -> Scope -> ModuleEx -> [Idea]
y2 [Setting]
a Scope
b ModuleEx
c)
        (\a :: [Setting]
a b :: Scope
b c :: ModuleEx
c d :: Decl SrcSpanInfo
d -> [Setting] -> Scope -> ModuleEx -> Decl SrcSpanInfo -> [Idea]
x3 [Setting]
a Scope
b ModuleEx
c Decl SrcSpanInfo
d [Idea] -> [Idea] -> [Idea]
forall a. [a] -> [a] -> [a]
++ [Setting] -> Scope -> ModuleEx -> Decl SrcSpanInfo -> [Idea]
y3 [Setting]
a Scope
b ModuleEx
c Decl SrcSpanInfo
d)
        (\a :: [Setting]
a b :: Scope'
b c :: ModuleEx
c d :: LHsDecl GhcPs
d -> [Setting] -> Scope' -> ModuleEx -> LHsDecl GhcPs -> [Idea]
x4 [Setting]
a Scope'
b ModuleEx
c LHsDecl GhcPs
d [Idea] -> [Idea] -> [Idea]
forall a. [a] -> [a] -> [a]
++ [Setting] -> Scope' -> ModuleEx -> LHsDecl GhcPs -> [Idea]
y4 [Setting]
a Scope'
b ModuleEx
c LHsDecl GhcPs
d)

instance Monoid Hint where
    mempty :: Hint
mempty = ([Setting] -> [(Scope, ModuleEx)] -> [Idea])
-> ([Setting] -> Scope -> ModuleEx -> [Idea])
-> ([Setting] -> Scope -> ModuleEx -> Decl SrcSpanInfo -> [Idea])
-> ([Setting] -> Scope' -> ModuleEx -> LHsDecl GhcPs -> [Idea])
-> Hint
Hint (\_ _ -> []) (\_ _ _ -> []) (\_ _ _ _ -> []) (\_ _ _ _ -> [])
    mappend :: Hint -> Hint -> Hint
mappend = Hint -> Hint -> Hint
forall a. Semigroup a => a -> a -> a
(<>)