{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE Strict #-} module Tokstyle.Linter.CompoundInit (descr) where import Control.Monad.State.Strict (State) import qualified Control.Monad.State.Strict as State import Data.Fix (Fix (..)) import Data.Text (Text) import qualified Data.Text as Text import Language.Cimple (Lexeme (..), Node, NodeF (..)) import Language.Cimple.Diagnostics (warn) import Language.Cimple.TraverseAst (AstActions, astActions, doNode, traverseAst) linter :: AstActions (State [Text]) Text linter :: AstActions (State [Text]) Text linter = AstActions (State [Text]) Text forall (f :: * -> *) text. Applicative f => AstActions f text astActions { doNode :: FilePath -> Node (Lexeme Text) -> State [Text] () -> State [Text] () doNode = \FilePath file Node (Lexeme Text) node State [Text] () act -> case Node (Lexeme Text) -> NodeF (Lexeme Text) (Node (Lexeme Text)) forall (f :: * -> *). Fix f -> f (Fix f) unFix Node (Lexeme Text) node of VarDeclStmt Node (Lexeme Text) _ (Just (Fix CompoundLiteral{})) -> FilePath -> Node (Lexeme Text) -> Text -> State [Text] () forall at diags. (HasLocation at, HasDiagnostics diags) => FilePath -> at -> Text -> DiagnosticsT diags () warn FilePath file Node (Lexeme Text) node Text "don't use compound literals in initialisations; use simple `Type var = {0};`" NodeF (Lexeme Text) (Node (Lexeme Text)) _ -> State [Text] () act } analyse :: (FilePath, [Node (Lexeme Text)]) -> [Text] analyse :: (FilePath, [Node (Lexeme Text)]) -> [Text] analyse = [Text] -> [Text] forall a. [a] -> [a] reverse ([Text] -> [Text]) -> ((FilePath, [Node (Lexeme Text)]) -> [Text]) -> (FilePath, [Node (Lexeme Text)]) -> [Text] forall b c a. (b -> c) -> (a -> b) -> a -> c . (State [Text] () -> [Text] -> [Text]) -> [Text] -> State [Text] () -> [Text] forall a b c. (a -> b -> c) -> b -> a -> c flip State [Text] () -> [Text] -> [Text] forall s a. State s a -> s -> s State.execState [] (State [Text] () -> [Text]) -> ((FilePath, [Node (Lexeme Text)]) -> State [Text] ()) -> (FilePath, [Node (Lexeme Text)]) -> [Text] forall b c a. (b -> c) -> (a -> b) -> a -> c . AstActions (State [Text]) Text -> (FilePath, [Node (Lexeme Text)]) -> State [Text] () forall text a (f :: * -> *). (TraverseAst text a, Applicative f) => AstActions f text -> a -> f () traverseAst AstActions (State [Text]) Text linter descr :: ((FilePath, [Node (Lexeme Text)]) -> [Text], (Text, Text)) descr :: ((FilePath, [Node (Lexeme Text)]) -> [Text], (Text, Text)) descr = ((FilePath, [Node (Lexeme Text)]) -> [Text] analyse, (Text "compound-init", [Text] -> Text Text.unlines [ Text "Checks that compound literals aren't used in initialisations. E.g.:" , Text "" , Text "```cpp" , Text "Foo foo = (Foo){0};" , Text "```" , Text "" , Text "should be written as:" , Text "" , Text "```cpp" , Text "Foo foo = {0};" , Text "```" , Text "" , Text "**Reason:** compound literals aren't needed in initialisations. Without them," , Text "the code is clearer." ]))