module Dhall.LSP.Backend.Linting
( Suggestion(..)
, suggest
, Dhall.lint
)
where
import Dhall.Parser (Src)
import Dhall.Core (Expr(..), Binding(..), Var(..), subExpressions, freeIn, Import)
import qualified Dhall.Lint as Dhall
import Dhall.LSP.Backend.Diagnostics
import Data.Monoid ((<>))
import Data.Text (Text)
import Data.List.NonEmpty (NonEmpty(..), tails, toList)
import Control.Lens (universeOf)
data Suggestion = Suggestion {
range :: Range,
suggestion :: Text
}
diagLetInLet :: Expr Src a -> [Suggestion]
diagLetInLet (Note _ (Let _ (Note src (Let _ _)))) =
[Suggestion (rangeFromDhall src) "Superfluous 'in' before nested let binding"]
diagLetInLet _ = []
unusedBindings :: Eq a => Expr s a -> [Text]
unusedBindings (Note _ (Let bindings d)) = concatMap
(\case
Binding var _ _ : [] | not (V var 0 `freeIn` d) -> [var]
Binding var _ _ : (b : bs) | not (V var 0 `freeIn` Let (b :| bs) d) -> [var]
_ -> [])
(toList $ tails bindings)
unusedBindings _ = []
diagUnusedBinding :: Eq a => Expr Src a -> [Suggestion]
diagUnusedBinding e@(Note src (Let _ _)) = map
(\var ->
Suggestion (rangeFromDhall src) ("Unused let binding '" <> var <> "'"))
(unusedBindings e)
diagUnusedBinding _ = []
suggest :: Expr Src Import -> [Suggestion]
suggest expr = concat [ diagLetInLet e ++ diagUnusedBinding e
| e <- universeOf subExpressions expr ]