{-# LANGUAGE OverloadedStrings #-}
module Tokstyle.Cimple.Analysis.LoggerCalls (analyse) where
import Control.Monad.State.Lazy (State)
import qualified Control.Monad.State.Lazy as State
import Data.Text (Text)
import qualified Data.Text as Text
import System.FilePath (takeFileName)
import Tokstyle.Cimple.AST (LiteralType (String), Node (..))
import qualified Tokstyle.Cimple.Diagnostics as Diagnostics
import Tokstyle.Cimple.Lexer (Lexeme (..))
import Tokstyle.Cimple.TraverseAst
linter :: FilePath -> AstActions (State [Text]) Text
linter file = defaultActions
{ doNode = \node act ->
case node of
FunctionCall _ (_:LiteralExpr String _:_) -> act
FunctionCall (LiteralExpr _ (L _ _ "LOGGER_ASSERT")) (_:_:LiteralExpr String _:_) -> act
FunctionCall (LiteralExpr _ name@(L _ _ func)) _ | Text.isPrefixOf "LOGGER_" func -> do
warn name $ "logger call `" <> func <> "' has a non-literal format argument"
act
_ -> act
}
where warn = Diagnostics.warn file
analyse :: FilePath -> [Node (Lexeme Text)] -> [Text]
analyse file _ | takeFileName file == "logger.h" = []
analyse file ast = reverse $ State.execState (traverseAst (linter file) ast) []