-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | GHC plugin to do inspection testing
--   
--   Some carefully crafted libraries make promises to their users beyond
--   functionality and performance.
--   
--   Examples are: Fusion libraries promise intermediate data structures to
--   be eliminated. Generic programming libraries promise that the generic
--   implementation is identical to the hand-written one. Some libraries
--   may promise allocation-free or branch-free code.
--   
--   Conventionally, the modus operandi in all these cases is that the
--   library author manually inspects the (intermediate or final) code
--   produced by the compiler. This is not only tedious, but makes it very
--   likely that some change, either in the library itself or the
--   surrounding eco-system, breaks the library’s promised without anyone
--   noticing.
--   
--   This package provides a disciplined way of specifying such properties,
--   and have them checked by the compiler. This way, this checking can be
--   part of the ususal development cycle and regressions caught early.
--   
--   See the documentation in <a>Test.Inspection</a> or the project webpage
--   for more examples and more information.
@package inspection-testing
@version 0.6.2


-- | This module supports the accompanying GHC plugin
--   <a>Test.Inspection.Plugin</a> and adds to GHC the ability to do
--   inspection testing.
module Test.Inspection

-- | As seen in the example above, the entry point to inspection testing is
--   the <a>inspect</a> function, to which you pass an <a>Obligation</a>.
--   It will report test failures at compile time.
inspect :: Obligation -> Q [Dec]

-- | This is a variant of <a>inspect</a> that allows compilation to succeed
--   in any case, and instead indicates the result as a value of type
--   <a>Result</a>, which allows seamless integration into test frameworks.
--   
--   This variant ignores the <a>expectFail</a> field of the obligation.
--   Instead, it is expected that you use the corresponding functionality
--   in your test framework (e.g. <a><tt>tasty-expected-failure</tt></a>)
inspectTest :: Obligation -> Q Exp

-- | The result of <a>inspectTest</a>, which has a more or less helpful
--   text message
data Result
Failure :: String -> Result
Success :: String -> Result

-- | This data type describes an inspection testing obligation.
--   
--   It is recommended to build it using <a>mkObligation</a>, for backwards
--   compatibility when new fields are added. You can also use the more
--   mnemonic convenience functions like <a>(===)</a> or <a>hasNoType</a>.
--   
--   The obligation needs to be passed to <a>inspect</a> or
--   <a>inspectTest</a>.
data Obligation
Obligation :: Name -> Property -> Maybe String -> Bool -> Maybe Loc -> Maybe String -> Obligation

-- | The target of a test obligation; invariably the name of a local
--   definition. To get the name of a function <tt>foo</tt>, write
--   <tt>'foo</tt>. This requires <tt>{-# LANGUAGE TemplateHaskell
--   #-}</tt>.
[target] :: Obligation -> Name

-- | The property of the target to be checked.
[property] :: Obligation -> Property

-- | An optional name for the test
[testName] :: Obligation -> Maybe String

-- | Do we expect this property to fail? (Only used by <a>inspect</a>, not
--   by <a>inspectTest</a>)
[expectFail] :: Obligation -> Bool

-- | The source location where this obligation is defined. This is filled
--   in by <a>inspect</a>.
[srcLoc] :: Obligation -> Maybe Loc

-- | If this is <a>Nothing</a>, then report errors during compilation.
--   Otherwise, update the top-level definition with this name.
[storeResult] :: Obligation -> Maybe String

-- | Creates an inspection obligation for the given function name with
--   default values for the optional fields.
mkObligation :: Name -> Property -> Obligation

-- | Equivalence of terms.
data Equivalence

-- | strict term equality
StrictEquiv :: Equivalence

-- | ignore types and hpc ticks during the comparison
IgnoreTypesAndTicksEquiv :: Equivalence

-- | allow permuted let bindings, ignore types and hpc tick during
--   comparison
UnorderedLetsEquiv :: Equivalence

-- | Properties of the obligation target to be checked.
data Property

-- | Are the two functions equal?
--   
--   More precisely: <tt>f</tt> is equal to <tt>g</tt> if either the
--   definition of <tt>f</tt> is <tt>f = g</tt>, or the definition of
--   <tt>g</tt> is <tt>g = f</tt>, or if the definitions are <tt>f = e</tt>
--   and <tt>g = e</tt>.
--   
--   In general <tt>f</tt> and <tt>g</tt> need to be defined in this
--   module, so that their actual defintions can be inspected.
--   
--   The <a>Equivalence</a> indicates how strict to check for equality
EqualTo :: Name -> Equivalence -> Property

-- | Do none of these types appear anywhere in the definition of the
--   function (neither locally bound nor passed as arguments)
NoTypes :: [Name] -> Property

-- | Does this function perform no heap allocations.
NoAllocation :: Property

-- | Does this value contain dictionaries (<i>except</i> of the listed
--   classes).
NoTypeClasses :: [Name] -> Property

-- | Does not contain this value (in terms or patterns)
NoUseOf :: [Name] -> Property

-- | Always satisfied, but dumps the value in non-quiet mode.
CoreOf :: Property

-- | Declare two functions to be equal (see <a>EqualTo</a>)
(===) :: Name -> Name -> Obligation
infix 9 ===

-- | Declare two functions to be equal, but ignoring type lambdas, type
--   arguments, type casts and hpc ticks (see <a>EqualTo</a>). Note that
--   <tt>-fhpc</tt> can prevent some optimizations; build without for more
--   reliable analysis.
(==-) :: Name -> Name -> Obligation
infix 9 ==-

-- | Declare two functions to be equal, but expect the test to fail (see
--   <a>EqualTo</a> and <a>expectFail</a>) (This is useful for
--   documentation purposes, or as a TODO list.)
(=/=) :: Name -> Name -> Obligation
infix 9 =/=

-- | Declare two functions to be equal up to types (see <a>(==-)</a>), but
--   expect the test to fail (see <a>expectFail</a>).
(=/-) :: Name -> Name -> Obligation
infix 9 =/-

-- | Declare two functions to be equal as <tt>(<a>==-</a>)</tt> but also
--   ignoring let bindings ordering (see <a>EqualTo</a>).
(==~) :: Name -> Name -> Obligation
infix 9 ==~

-- | Declare two functions to be equal up to let binding ordering (see
--   <a>(==~)</a>), but expect the test to fail (see <a>expectFail</a>).
(=/~) :: Name -> Name -> Obligation
infix 9 =/~

-- | Declare that in a function’s implementation, the given type does not
--   occur.
--   
--   More precisely: No locally bound variable (let-bound, lambda-bound or
--   pattern-bound) has a type that contains the given type constructor.
--   
--   <pre>
--   <a>inspect</a> $ fusedFunction <a>`hasNoType`</a> ''[]
--   </pre>
hasNoType :: Name -> Name -> Obligation

-- | Declare that a function’s implementation does not contain any generic
--   types. This is just <a>hasNoType</a> applied to the usual type
--   constructors used in <a>GHC.Generics</a>.
--   
--   <pre>
--   inspect $ hasNoGenerics genericFunction
--   </pre>
hasNoGenerics :: Name -> Obligation

-- | Declare that a function's implementation does not include
--   dictionaries.
--   
--   More precisely: No locally bound variable (let-bound, lambda-bound or
--   pattern-bound) has a type that contains a type that mentions a type
--   class.
--   
--   <pre>
--   <a>inspect</a> $ <a>hasNoTypeClasses</a> specializedFunction
--   </pre>
hasNoTypeClasses :: Name -> Obligation

-- | A variant of <a>hasNoTypeClasses</a>, which white-lists some
--   type-classes.
--   
--   <pre>
--   <a>inspect</a> $ fieldLens <a>`hasNoTypeClassesExcept`</a> [''Functor]
--   </pre>
hasNoTypeClassesExcept :: Name -> [Name] -> Obligation

-- | Declare that a function's implementation does not use the given
--   variable (either in terms or -- if it is a constructor -- in
--   patterns).
--   
--   <pre>
--   <a>inspect</a> $ foo <a>`doesNotUse`</a> 'error
--   </pre>
doesNotUse :: Name -> Name -> Obligation

-- | Dump the Core of the value.
--   
--   <pre>
--   <a>inspect</a> $ <a>coreOf</a> 'foo
--   </pre>
--   
--   This is useful when you need to inspect some values manually.
coreOf :: Name -> Obligation
instance GHC.Internal.Data.Data.Data Test.Inspection.Equivalence
instance GHC.Internal.Data.Data.Data Test.Inspection.Obligation
instance GHC.Internal.Data.Data.Data Test.Inspection.Property
instance GHC.Internal.Show.Show Test.Inspection.Result


-- | This module implements some analyses of Core expressions necessary for
--   <a>Test.Inspection</a>. Normally, users of this package can ignore
--   this module.
module Test.Inspection.Core

-- | Selects those bindings that define the given variable (with this
--   variable first)
slice :: [(Var, CoreExpr)] -> Var -> Slice

-- | Pretty-print a slice
pprSlice :: Slice -> SDoc

-- | Pretty-print two slices, after removing variables occurring in both
pprSliceDifference :: Slice -> Slice -> SDoc

-- | This is a heuristic, which only works if both slices have auxiliary
--   variables in the right order. (This is mostly to work-around the buggy
--   CSE in GHC-8.0) It also breaks if there is shadowing.
eqSlice :: Equivalence -> Slice -> Slice -> Bool

-- | Like <a>eqSlice</a> but also returns an explanation of inequality.
eqSlice' :: Equivalence -> Slice -> Slice -> Either SDoc ()

-- | Returns <tt>True</tt> if the given core expression mentions no type
--   constructor anywhere that has the given name.
freeOfType :: Slice -> [Name] -> Maybe (Var, CoreExpr)

-- | Returns <tt>True</tt> if the given core expression mentions no term
--   variable anywhere that has the given name.
freeOfTerm :: Slice -> [Name] -> Maybe (Var, CoreExpr)

-- | True if the given variable binding does not allocate, if called fully
--   satisfied.
--   
--   It currently does not look through function calls, which of course
--   could allocate. It should probably at least look through local
--   function calls.
--   
--   The variable is important to know the arity of the function.
doesNotAllocate :: Slice -> Maybe (Var, CoreExpr)
doesNotContainTypeClasses :: Slice -> [Name] -> Maybe (Var, CoreExpr, [TyCon])


-- | See <a>Test.Inspection</a>.
module Test.Inspection.Plugin

-- | The plugin. It supports some options:
--   
--   <ul>
--   <li><tt>-fplugin-opt=Test.Inspection.Plugin:keep-going</tt> to keep
--   building despite failing obligations</li>
--   <li><tt>-fplugin-opt=Test.Inspection.Plugin:keep-going-O0</tt> to keep
--   building despite failing obligations, when optimisations are off</li>
--   <li><tt>-fplugin-opt=Test.Inspection.Plugin:skip-O0</tt> to skip
--   performing inspections when optimisations are off</li>
--   <li><tt>-fplugin-opt=Test.Inspection.Plugin:quiet</tt> to be silent if
--   all obligations are fulfilled</li>
--   </ul>
--   
--   It makes sense to enable only one of <tt>keep-going</tt>,
--   <tt>keep-going-O0</tt> and <tt>skip-O0</tt> at a time.
--   <tt>skip-O0</tt> is useful when working with GHCi, to suppress
--   inspection failure messages and eliminate the overhead of inspection
--   when loading.
plugin :: Plugin
checkProperty :: ModGuts -> Name -> Property -> CoreM CheckResult
data CheckResult
ResSuccess :: CheckResult
ResSuccessWithMessage :: SDoc -> CheckResult
ResFailure :: SDoc -> CheckResult
prettyProperty :: (Name -> String) -> Name -> Property -> String
instance GHC.Internal.Enum.Bounded Test.Inspection.Plugin.Stat
instance GHC.Internal.Enum.Enum Test.Inspection.Plugin.Stat
instance GHC.Classes.Eq Test.Inspection.Plugin.ReportingMode
instance GHC.Classes.Eq Test.Inspection.Plugin.Stat
instance GHC.Classes.Eq Test.Inspection.Plugin.UponFailure
instance GHC.Classes.Ord Test.Inspection.Plugin.Stat
