{-# LANGUAGE RecordWildCards #-}
module Dhall.Lint
(
lint
, removeUnusedBindings
) where
import Control.Applicative ((<|>))
import Dhall.Core (Binding(..), Expr(..), Import, Var(..), subExpressions)
import qualified Dhall.Core
import qualified Dhall.Optics
import qualified Lens.Family
lint :: Expr s Import -> Expr t Import
lint =
Dhall.Optics.rewriteOf
subExpressions
(\e -> fixAsserts e <|> removeUnusedBindings e)
. removeLetInLet
removeUnusedBindings :: Eq a => Expr s a -> Maybe (Expr s a)
removeUnusedBindings (Let (Binding _ _ _ _ _ e) _)
| isOrContainsAssert e = Nothing
removeUnusedBindings (Let (Binding _ a _ _ _ _) d)
| not (V a 0 `Dhall.Core.freeIn` d) =
Just (Dhall.Core.shift (-1) (V a 0) d)
removeUnusedBindings _ = Nothing
fixAsserts :: Expr s a -> Maybe (Expr s a)
fixAsserts (Let (Binding { value = Equivalent x y, ..}) body) =
Just (Let (Binding { value = Assert (Equivalent x y), .. }) body)
fixAsserts _ =
Nothing
isOrContainsAssert :: Expr s a -> Bool
isOrContainsAssert (Assert _) = True
isOrContainsAssert e = Lens.Family.anyOf subExpressions isOrContainsAssert e
removeLetInLet :: Expr s a -> Expr t a
removeLetInLet = Dhall.Core.denote