module Dhall.LSP.Backend.Linting
( Suggestion(..)
, suggest
, Dhall.lint
)
where
import Dhall.Parser (Src)
import Dhall.Core ( Expr(..), Binding(..), MultiLet(..), Import
, subExpressions, multiLet, wrapInLets)
import qualified Dhall.Lint as Dhall
import Dhall.LSP.Backend.Diagnostics
import qualified Data.List.NonEmpty as NonEmpty
import Data.Maybe (maybeToList)
import Data.Monoid ((<>))
import Data.Text (Text)
import Control.Lens (universeOf)
data Suggestion = Suggestion {
range :: Range,
suggestion :: Text
}
diagLetInLet :: Expr Src a -> Maybe Suggestion
diagLetInLet (Note _ (Let b e)) = case multiLet b e of
MultiLet _ (Note src (Let {})) ->
Just (Suggestion (rangeFromDhall src) "Superfluous 'in' before nested let binding")
_ -> Nothing
diagLetInLet _ = Nothing
unusedBindings :: Eq a => MultiLet s a -> [Text]
unusedBindings (MultiLet bindings d) =
let go bs@(Binding { variable = var} : _) | Just _ <- Dhall.removeUnusedBindings (wrapInLets bs d) = [var]
go _ = []
in foldMap go (NonEmpty.tails bindings)
diagUnusedBindings :: Eq a => Expr Src a -> [Suggestion]
diagUnusedBindings (Note src (Let b e)) = map
(\var ->
Suggestion (rangeFromDhall src) ("Unused let binding '" <> var <> "'"))
(unusedBindings (multiLet b e))
diagUnusedBindings _ = []
suggest :: Expr Src Import -> [Suggestion]
suggest expr = concat [ maybeToList (diagLetInLet e) ++ diagUnusedBindings e
| e <- universeOf subExpressions expr ]