module Language.Haskell.Inspector (
hasComposition,
hasGuards,
hasIf,
hasConditional,
hasLambda,
hasDirectRecursion,
hasUsage,
hasComprehension,
hasBinding,
hasTypeDeclaration,
hasTypeSignature,
hasExpression,
hasDecl,
hasRhs,
isParseable,
Inspection,
GlobalInspection
) where
import Language.Haskell.Syntax
import Language.Haskell.Names (isName)
import Language.Haskell.Explorer
type Inspection = Binding -> Code -> Bool
type GlobalInspection = Code -> Bool
hasComposition :: Inspection
hasComposition = hasExpression f
where f (O (HsQVarOp (UnQual (HsSymbol ".")))) = True
f _ = False
hasGuards :: Inspection
hasGuards = hasRhs f
where f (HsGuardedRhss _) = True
f _ = False
hasIf :: Inspection
hasIf = hasExpression f
where f (E (HsIf _ _ _)) = True
f _ = False
hasConditional :: Inspection
hasConditional target code = hasIf target code || hasGuards target code
hasLambda :: Inspection
hasLambda = hasExpression f
where f (E (HsLambda _ _ _)) = True
f _ = False
hasDirectRecursion :: Inspection
hasDirectRecursion binding = hasUsage binding binding
hasUsage :: String -> Inspection
hasUsage target = hasExpression f
where f expr | (Just n) <- expressionToBinding expr = n == target
| otherwise = False
hasComprehension :: Inspection
hasComprehension = hasExpression f
where f (E (HsListComp _ _)) = True
f _ = False
hasBinding :: Inspection
hasBinding binding = not.null.rhssOf binding
hasTypeDeclaration :: Inspection
hasTypeDeclaration binding = hasDecl f
where f (HsTypeDecl _ hsName _ _) = isName binding hsName
f _ = False
hasTypeSignature :: Inspection
hasTypeSignature binding = hasDecl f
where f (HsTypeSig _ [hsName] _) = isName binding hsName
f _ = False
hasExpression :: (Expression -> Bool) -> Inspection
hasExpression f binding = has f (expressionsOf binding)
hasRhs :: (HsRhs -> Bool)-> Inspection
hasRhs f binding = has f (rhssOf binding)
isParseable :: GlobalInspection
isParseable = not.null.parseDecls
hasDecl :: (HsDecl -> Bool) -> GlobalInspection
hasDecl f = has f parseDecls
has f g = any f . g