tokstyle-0.0.6: src/Tokstyle/Cimple/Analysis/DeclaredOnce.hs
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StrictData #-}
module Tokstyle.Cimple.Analysis.DeclaredOnce (analyse) where
import qualified Control.Monad.State.Lazy as State
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Text (Text)
import Language.Cimple (AstActions, Lexeme (..),
LexemeClass (..), Node (..),
defaultActions, doNode,
traverseAst)
import Language.Cimple.Diagnostics (HasDiagnostics (..), warn)
data Linter = Linter
{ diags :: [Text]
, decls :: Map Text (FilePath, Lexeme Text)
}
empty :: Linter
empty = Linter [] Map.empty
instance HasDiagnostics Linter where
addDiagnostic diag l@Linter{diags} = l{diags = addDiagnostic diag diags}
linter :: AstActions Linter
linter = defaultActions
{ doNode = \file node act ->
case node of
FunctionDecl _ (FunctionPrototype _ fn@(L _ IdVar fname) _) _ -> do
l@Linter{decls} <- State.get
case Map.lookup fname decls of
Nothing -> State.put l{decls = Map.insert fname (file, fn) decls }
Just (file', fn') -> do
warn file' fn' $ "duplicate declaration of function `" <> fname <> "'"
warn file fn $ "function `" <> fname <> "' also declared here"
act
_ -> act
}
analyse :: [(FilePath, [Node () (Lexeme Text)])] -> [Text]
analyse tus = reverse . diags $ State.execState (traverseAst linter tus) empty