{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}
{-# OPTIONS_GHC -Wno-incomplete-patterns #-}
module HLint(hlint, readAllSettings) where
import Control.Applicative
import Control.Monad.Extra
import Control.Exception.Extra
import Control.Concurrent.Extra
import System.Console.CmdArgs.Verbosity
import GHC.Util.DynFlags
import Data.List.Extra
import GHC.Conc
import System.Directory
import System.Exit
import System.IO.Extra
import System.Time.Extra
import Data.Tuple.Extra
import Data.Bifunctor (bimap)
import Prelude
import CmdLine
import Config.Read
import Config.Type
import Config.Compute
import Report
import Summary
import Idea
import Apply
import Test.All
import Hint.All
import Refact
import Timing
import Parallel
import GHC.All
import CC
import EmbedData
import SARIF qualified
hlint :: [String] -> IO [Idea]
hlint :: [String] -> IO [Idea]
hlint [String]
args = do
IO ()
startTimings
Cmd
cmd <- [String] -> IO Cmd
getCmd [String]
args
String -> String -> IO () -> IO ()
forall a. String -> String -> IO a -> IO a
timedIO String
"Initialise" String
"global flags" IO ()
initGlobalDynFlags
if Cmd -> Bool
cmdTest Cmd
cmd then
Cmd -> IO ()
hlintTest Cmd
cmd IO () -> IO [Idea] -> IO [Idea]
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Idea] -> IO [Idea]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
else do
(Seconds
time, [Idea]
xs) <- IO [Idea] -> IO (Seconds, [Idea])
forall (m :: * -> *) a. MonadIO m => m a -> m (Seconds, a)
duration (IO [Idea] -> IO (Seconds, [Idea]))
-> IO [Idea] -> IO (Seconds, [Idea])
forall a b. (a -> b) -> a -> b
$ [String] -> Cmd -> IO [Idea]
hlintMain [String]
args Cmd
cmd
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Cmd -> Bool
cmdTiming Cmd
cmd) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
IO ()
printTimings
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Took " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Seconds -> String
showDuration Seconds
time
[Idea] -> IO [Idea]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Idea] -> IO [Idea]) -> [Idea] -> IO [Idea]
forall a b. (a -> b) -> a -> b
$ if Cmd -> Bool
cmdNoExitCode Cmd
cmd then [] else [Idea]
xs
hlintTest :: Cmd -> IO ()
hlintTest :: Cmd -> IO ()
hlintTest cmd :: Cmd
cmd@CmdMain{Bool
Int
String
[String]
[Severity]
ColorMode
cmdTest :: Cmd -> Bool
cmdTiming :: Cmd -> Bool
cmdNoExitCode :: Cmd -> Bool
cmdFiles :: [String]
cmdReports :: [String]
cmdGivenHints :: [String]
cmdWithGroups :: [String]
cmdGit :: Bool
cmdColor :: ColorMode
cmdThreads :: Int
cmdIgnore :: [String]
cmdShowAll :: Bool
cmdIgnoreSuggestions :: Bool
cmdExtension :: [String]
cmdLanguage :: [String]
cmdCross :: Bool
cmdFindHints :: [String]
cmdDataDir :: String
cmdDefault :: Bool
cmdPath :: [String]
cmdCppDefine :: [String]
cmdCppInclude :: [String]
cmdCppFile :: [String]
cmdCppSimple :: Bool
cmdCppAnsi :: Bool
cmdJson :: Bool
cmdCC :: Bool
cmdSARIF :: Bool
cmdNoSummary :: Bool
cmdOnly :: [String]
cmdNoExitCode :: Bool
cmdTiming :: Bool
cmdSerialise :: Bool
cmdRefactor :: Bool
cmdRefactorOptions :: String
cmdWithRefactor :: String
cmdIgnoreGlob :: [String]
cmdGenerateMdSummary :: [String]
cmdGenerateJsonSummary :: [String]
cmdGenerateExhaustiveConf :: [Severity]
cmdTest :: Bool
cmdFiles :: Cmd -> [String]
cmdReports :: Cmd -> [String]
cmdGivenHints :: Cmd -> [String]
cmdWithGroups :: Cmd -> [String]
cmdGit :: Cmd -> Bool
cmdColor :: Cmd -> ColorMode
cmdThreads :: Cmd -> Int
cmdIgnore :: Cmd -> [String]
cmdShowAll :: Cmd -> Bool
cmdIgnoreSuggestions :: Cmd -> Bool
cmdExtension :: Cmd -> [String]
cmdLanguage :: Cmd -> [String]
cmdCross :: Cmd -> Bool
cmdFindHints :: Cmd -> [String]
cmdDataDir :: Cmd -> String
cmdDefault :: Cmd -> Bool
cmdPath :: Cmd -> [String]
cmdCppDefine :: Cmd -> [String]
cmdCppInclude :: Cmd -> [String]
cmdCppFile :: Cmd -> [String]
cmdCppSimple :: Cmd -> Bool
cmdCppAnsi :: Cmd -> Bool
cmdJson :: Cmd -> Bool
cmdCC :: Cmd -> Bool
cmdSARIF :: Cmd -> Bool
cmdNoSummary :: Cmd -> Bool
cmdOnly :: Cmd -> [String]
cmdSerialise :: Cmd -> Bool
cmdRefactor :: Cmd -> Bool
cmdRefactorOptions :: Cmd -> String
cmdWithRefactor :: Cmd -> String
cmdIgnoreGlob :: Cmd -> [String]
cmdGenerateMdSummary :: Cmd -> [String]
cmdGenerateJsonSummary :: Cmd -> [String]
cmdGenerateExhaustiveConf :: Cmd -> [Severity]
..} = do
Int
failed <- Cmd -> ([String] -> IO ()) -> String -> [String] -> IO Int
test Cmd
cmd (\[String]
args -> do [Idea]
errs <- [String] -> IO [Idea]
hlint [String]
args; Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([Idea] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Idea]
errs) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ ExitCode -> IO ()
forall a. ExitCode -> IO a
exitWith (ExitCode -> IO ()) -> ExitCode -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> ExitCode
ExitFailure Int
1) String
cmdDataDir [String]
cmdGivenHints
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
failed Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0) IO ()
forall a. IO a
exitFailure
cmdParseFlags :: Cmd -> ParseFlags
cmdParseFlags :: Cmd -> ParseFlags
cmdParseFlags Cmd
cmd = (Maybe Language, ([Extension], [Extension]))
-> ParseFlags -> ParseFlags
parseFlagsSetLanguage (Cmd -> (Maybe Language, ([Extension], [Extension]))
cmdExtensions Cmd
cmd) (ParseFlags -> ParseFlags) -> ParseFlags -> ParseFlags
forall a b. (a -> b) -> a -> b
$ ParseFlags
defaultParseFlags{cppFlags=cmdCpp cmd}
withVerbosity :: Verbosity -> IO a -> IO a
withVerbosity :: forall a. Verbosity -> IO a -> IO a
withVerbosity Verbosity
new IO a
act = do
Verbosity
old <- IO Verbosity
getVerbosity
(Verbosity -> IO ()
setVerbosity Verbosity
new IO () -> IO a -> IO a
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO a
act) IO a -> IO () -> IO a
forall a b. IO a -> IO b -> IO a
`finally` Verbosity -> IO ()
setVerbosity Verbosity
old
hlintMain :: [String] -> Cmd -> IO [Idea]
hlintMain :: [String] -> Cmd -> IO [Idea]
hlintMain [String]
args cmd :: Cmd
cmd@CmdMain{Bool
Int
String
[String]
[Severity]
ColorMode
cmdTest :: Cmd -> Bool
cmdTiming :: Cmd -> Bool
cmdNoExitCode :: Cmd -> Bool
cmdFiles :: Cmd -> [String]
cmdReports :: Cmd -> [String]
cmdGivenHints :: Cmd -> [String]
cmdWithGroups :: Cmd -> [String]
cmdGit :: Cmd -> Bool
cmdColor :: Cmd -> ColorMode
cmdThreads :: Cmd -> Int
cmdIgnore :: Cmd -> [String]
cmdShowAll :: Cmd -> Bool
cmdIgnoreSuggestions :: Cmd -> Bool
cmdExtension :: Cmd -> [String]
cmdLanguage :: Cmd -> [String]
cmdCross :: Cmd -> Bool
cmdFindHints :: Cmd -> [String]
cmdDataDir :: Cmd -> String
cmdDefault :: Cmd -> Bool
cmdPath :: Cmd -> [String]
cmdCppDefine :: Cmd -> [String]
cmdCppInclude :: Cmd -> [String]
cmdCppFile :: Cmd -> [String]
cmdCppSimple :: Cmd -> Bool
cmdCppAnsi :: Cmd -> Bool
cmdJson :: Cmd -> Bool
cmdCC :: Cmd -> Bool
cmdSARIF :: Cmd -> Bool
cmdNoSummary :: Cmd -> Bool
cmdOnly :: Cmd -> [String]
cmdSerialise :: Cmd -> Bool
cmdRefactor :: Cmd -> Bool
cmdRefactorOptions :: Cmd -> String
cmdWithRefactor :: Cmd -> String
cmdIgnoreGlob :: Cmd -> [String]
cmdGenerateMdSummary :: Cmd -> [String]
cmdGenerateJsonSummary :: Cmd -> [String]
cmdGenerateExhaustiveConf :: Cmd -> [Severity]
cmdFiles :: [String]
cmdReports :: [String]
cmdGivenHints :: [String]
cmdWithGroups :: [String]
cmdGit :: Bool
cmdColor :: ColorMode
cmdThreads :: Int
cmdIgnore :: [String]
cmdShowAll :: Bool
cmdIgnoreSuggestions :: Bool
cmdExtension :: [String]
cmdLanguage :: [String]
cmdCross :: Bool
cmdFindHints :: [String]
cmdDataDir :: String
cmdDefault :: Bool
cmdPath :: [String]
cmdCppDefine :: [String]
cmdCppInclude :: [String]
cmdCppFile :: [String]
cmdCppSimple :: Bool
cmdCppAnsi :: Bool
cmdJson :: Bool
cmdCC :: Bool
cmdSARIF :: Bool
cmdNoSummary :: Bool
cmdOnly :: [String]
cmdNoExitCode :: Bool
cmdTiming :: Bool
cmdSerialise :: Bool
cmdRefactor :: Bool
cmdRefactorOptions :: String
cmdWithRefactor :: String
cmdIgnoreGlob :: [String]
cmdGenerateMdSummary :: [String]
cmdGenerateJsonSummary :: [String]
cmdGenerateExhaustiveConf :: [Severity]
cmdTest :: Bool
..}
| Bool
cmdDefault = do
[Idea]
ideas <- if [String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
cmdFiles then [Idea] -> IO [Idea]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [] else Verbosity -> IO [Idea] -> IO [Idea]
forall a. Verbosity -> IO a -> IO a
withVerbosity Verbosity
Quiet (IO [Idea] -> IO [Idea]) -> IO [Idea] -> IO [Idea]
forall a b. (a -> b) -> a -> b
$
[String] -> Cmd -> Maybe String -> IO [Idea]
runHlintMain [String]
args Cmd
cmd{cmdJson=False,cmdSerialise=False,cmdRefactor=False} Maybe String
forall a. Maybe a
Nothing
let bad :: [[String]]
bad = [String] -> [[String]]
forall a. Eq a => [a] -> [[a]]
group ([String] -> [[String]]) -> [String] -> [[String]]
forall a b. (a -> b) -> a -> b
$ [String] -> [String]
forall a. Ord a => [a] -> [a]
sort ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ (Idea -> String) -> [Idea] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Idea -> String
ideaHint [Idea]
ideas
if [[String]] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[String]]
bad then String -> IO ()
putStr String
defaultYaml else do
let [String]
group1:[[String]]
groups = [String] -> [String] -> [[String]]
forall a. (HasCallStack, Eq a) => [a] -> [a] -> [[a]]
splitOn [String
"",String
""] ([String] -> [[String]]) -> [String] -> [[String]]
forall a b. (a -> b) -> a -> b
$ String -> [String]
lines String
defaultYaml
let group2 :: [String]
group2 = String
"# Warnings currently triggered by your code" String -> [String] -> [String]
forall a. a -> [a] -> [a]
:
[String
"- ignore: {name: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"} # "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ if [String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
tl then String
"1 hint" else Int -> String
forall a. Show a => a -> String
show ([String] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
xs) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" hints"
| xs :: [String]
xs@(String
x : [String]
tl) <- [[String]]
bad
]
String -> IO ()
putStr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ [String] -> [[String]] -> [String]
forall a. [a] -> [[a]] -> [a]
intercalate [String
"",String
""] ([[String]] -> [String]) -> [[String]] -> [String]
forall a b. (a -> b) -> a -> b
$ [String]
group1[String] -> [[String]] -> [[String]]
forall a. a -> [a] -> [a]
:[String]
group2[String] -> [[String]] -> [[String]]
forall a. a -> [a] -> [a]
:[[String]]
groups
[Idea] -> IO [Idea]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
| [String]
cmdGenerateMdSummary [String] -> [String] -> Bool
forall a. Eq a => a -> a -> Bool
/= [] = do
[String] -> (String -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [String]
cmdGenerateMdSummary ((String -> IO ()) -> IO ()) -> (String -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \String
file -> String -> String -> IO () -> IO ()
forall a. String -> String -> IO a -> IO a
timedIO String
"Summary" String
file (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
IO () -> IO ()
whenNormal (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Writing Markdown summary to " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
file String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" ..."
String
summary <- [Setting] -> IO String
generateMdSummary ([Setting] -> IO String)
-> ((Cmd, [Setting]) -> [Setting]) -> (Cmd, [Setting]) -> IO String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Cmd, [Setting]) -> [Setting]
forall a b. (a, b) -> b
snd ((Cmd, [Setting]) -> IO String) -> IO (Cmd, [Setting]) -> IO String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [String] -> Cmd -> IO (Cmd, [Setting])
readAllSettings [String]
args Cmd
cmd
String -> String -> IO ()
writeFileBinary String
file String
summary
[Idea] -> IO [Idea]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
| [String]
cmdGenerateJsonSummary [String] -> [String] -> Bool
forall a. Eq a => a -> a -> Bool
/= [] = do
[String] -> (String -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [String]
cmdGenerateJsonSummary ((String -> IO ()) -> IO ()) -> (String -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \String
file -> String -> String -> IO () -> IO ()
forall a. String -> String -> IO a -> IO a
timedIO String
"Summary" String
file (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
IO () -> IO ()
whenNormal (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Writing JSON summary to " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
file String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" ..."
String
summary <- [Setting] -> IO String
generateJsonSummary ([Setting] -> IO String)
-> ((Cmd, [Setting]) -> [Setting]) -> (Cmd, [Setting]) -> IO String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Cmd, [Setting]) -> [Setting]
forall a b. (a, b) -> b
snd ((Cmd, [Setting]) -> IO String) -> IO (Cmd, [Setting]) -> IO String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [String] -> Cmd -> IO (Cmd, [Setting])
readAllSettings [String]
args Cmd
cmd
String -> String -> IO ()
writeFileBinary String
file String
summary
[Idea] -> IO [Idea]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
| [Severity]
cmdGenerateExhaustiveConf [Severity] -> [Severity] -> Bool
forall a. Eq a => a -> a -> Bool
/= [] = do
[Severity] -> (Severity -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Severity]
cmdGenerateExhaustiveConf ((Severity -> IO ()) -> IO ()) -> (Severity -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Severity
severity ->
let file :: String
file = Severity -> String
forall a. Show a => a -> String
show Severity
severity String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-all.yaml"
in String -> String -> IO () -> IO ()
forall a. String -> String -> IO a -> IO a
timedIO String
"Exhaustive config file" String
file (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
IO () -> IO ()
whenNormal (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Writing " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Severity -> String
forall a. Show a => a -> String
show Severity
severity String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-all list to " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
file String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" ..."
String
exhaustiveConfig <- Severity -> [Setting] -> IO String
generateExhaustiveConfig Severity
severity ([Setting] -> IO String)
-> ((Cmd, [Setting]) -> [Setting]) -> (Cmd, [Setting]) -> IO String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Cmd, [Setting]) -> [Setting]
forall a b. (a, b) -> b
snd ((Cmd, [Setting]) -> IO String) -> IO (Cmd, [Setting]) -> IO String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [String] -> Cmd -> IO (Cmd, [Setting])
readAllSettings [String]
args Cmd
cmd
String -> String -> IO ()
writeFileBinary String
file String
exhaustiveConfig
[Idea] -> IO [Idea]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
| [String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
cmdFiles Bool -> Bool -> Bool
&& Bool -> Bool
not ([String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
cmdFindHints) = do
[String]
hints <- (String -> IO [String]) -> [String] -> IO [String]
forall (m :: * -> *) a b. Monad m => (a -> m [b]) -> [a] -> m [b]
concatMapM (Cmd -> Maybe String -> String -> IO [String]
resolveFile Cmd
cmd Maybe String
forall a. Maybe a
Nothing) [String]
cmdFindHints
(String -> IO ()) -> [String] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (String -> IO ()
putStrLn (String -> IO ())
-> ((String, [Setting]) -> String) -> (String, [Setting]) -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String, [Setting]) -> String
forall a b. (a, b) -> a
fst ((String, [Setting]) -> IO ())
-> (String -> IO (String, [Setting])) -> String -> IO ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< ParseFlags -> String -> IO (String, [Setting])
computeSettings (Cmd -> ParseFlags
cmdParseFlags Cmd
cmd)) [String]
hints IO () -> IO [Idea] -> IO [Idea]
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Idea] -> IO [Idea]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
| [String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
cmdFiles =
IO [Idea]
forall a. IO a
exitWithHelp
| Bool
cmdRefactor =
(String -> IO [Idea]) -> IO [Idea]
forall a. (String -> IO a) -> IO a
withTempFile ((String -> IO [Idea]) -> IO [Idea])
-> (String -> IO [Idea]) -> IO [Idea]
forall a b. (a -> b) -> a -> b
$ [String] -> Cmd -> Maybe String -> IO [Idea]
runHlintMain [String]
args Cmd
cmd (Maybe String -> IO [Idea])
-> (String -> Maybe String) -> String -> IO [Idea]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe String
forall a. a -> Maybe a
Just
| Bool
otherwise =
[String] -> Cmd -> Maybe String -> IO [Idea]
runHlintMain [String]
args Cmd
cmd Maybe String
forall a. Maybe a
Nothing
runHlintMain :: [String] -> Cmd -> Maybe FilePath -> IO [Idea]
runHlintMain :: [String] -> Cmd -> Maybe String -> IO [Idea]
runHlintMain [String]
args Cmd
cmd Maybe String
tmpFile = do
(Cmd
cmd, [Setting]
settings) <- [String] -> Cmd -> IO (Cmd, [Setting])
readAllSettings [String]
args Cmd
cmd
[String] -> [Setting] -> Cmd -> IO [Idea]
runHints [String]
args [Setting]
settings (Cmd -> IO [Idea]) -> IO Cmd -> IO [Idea]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Cmd -> Maybe String -> IO Cmd
resolveFiles Cmd
cmd Maybe String
tmpFile
resolveFiles :: Cmd -> Maybe FilePath -> IO Cmd
resolveFiles :: Cmd -> Maybe String -> IO Cmd
resolveFiles cmd :: Cmd
cmd@CmdMain{Bool
Int
String
[String]
[Severity]
ColorMode
cmdTest :: Cmd -> Bool
cmdTiming :: Cmd -> Bool
cmdNoExitCode :: Cmd -> Bool
cmdFiles :: Cmd -> [String]
cmdReports :: Cmd -> [String]
cmdGivenHints :: Cmd -> [String]
cmdWithGroups :: Cmd -> [String]
cmdGit :: Cmd -> Bool
cmdColor :: Cmd -> ColorMode
cmdThreads :: Cmd -> Int
cmdIgnore :: Cmd -> [String]
cmdShowAll :: Cmd -> Bool
cmdIgnoreSuggestions :: Cmd -> Bool
cmdExtension :: Cmd -> [String]
cmdLanguage :: Cmd -> [String]
cmdCross :: Cmd -> Bool
cmdFindHints :: Cmd -> [String]
cmdDataDir :: Cmd -> String
cmdDefault :: Cmd -> Bool
cmdPath :: Cmd -> [String]
cmdCppDefine :: Cmd -> [String]
cmdCppInclude :: Cmd -> [String]
cmdCppFile :: Cmd -> [String]
cmdCppSimple :: Cmd -> Bool
cmdCppAnsi :: Cmd -> Bool
cmdJson :: Cmd -> Bool
cmdCC :: Cmd -> Bool
cmdSARIF :: Cmd -> Bool
cmdNoSummary :: Cmd -> Bool
cmdOnly :: Cmd -> [String]
cmdSerialise :: Cmd -> Bool
cmdRefactor :: Cmd -> Bool
cmdRefactorOptions :: Cmd -> String
cmdWithRefactor :: Cmd -> String
cmdIgnoreGlob :: Cmd -> [String]
cmdGenerateMdSummary :: Cmd -> [String]
cmdGenerateJsonSummary :: Cmd -> [String]
cmdGenerateExhaustiveConf :: Cmd -> [Severity]
cmdFiles :: [String]
cmdReports :: [String]
cmdGivenHints :: [String]
cmdWithGroups :: [String]
cmdGit :: Bool
cmdColor :: ColorMode
cmdThreads :: Int
cmdIgnore :: [String]
cmdShowAll :: Bool
cmdIgnoreSuggestions :: Bool
cmdExtension :: [String]
cmdLanguage :: [String]
cmdCross :: Bool
cmdFindHints :: [String]
cmdDataDir :: String
cmdDefault :: Bool
cmdPath :: [String]
cmdCppDefine :: [String]
cmdCppInclude :: [String]
cmdCppFile :: [String]
cmdCppSimple :: Bool
cmdCppAnsi :: Bool
cmdJson :: Bool
cmdCC :: Bool
cmdSARIF :: Bool
cmdNoSummary :: Bool
cmdOnly :: [String]
cmdNoExitCode :: Bool
cmdTiming :: Bool
cmdSerialise :: Bool
cmdRefactor :: Bool
cmdRefactorOptions :: String
cmdWithRefactor :: String
cmdIgnoreGlob :: [String]
cmdGenerateMdSummary :: [String]
cmdGenerateJsonSummary :: [String]
cmdGenerateExhaustiveConf :: [Severity]
cmdTest :: Bool
..} Maybe String
tmpFile = do
[String]
cmdFiles <- if Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [String
"lint"] [String] -> [String] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` [String]
cmdFiles then [String] -> IO [String]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [String]
cmdFiles else do
Bool
b <- String -> IO Bool
doesDirectoryExist String
"lint"
[String] -> IO [String]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([String] -> IO [String]) -> [String] -> IO [String]
forall a b. (a -> b) -> a -> b
$ if Bool
b then [String]
cmdFiles else [String] -> [String]
forall a. [a] -> [a]
drop1 [String]
cmdFiles
[String]
files <- (String -> IO [String]) -> [String] -> IO [String]
forall (m :: * -> *) a b. Monad m => (a -> m [b]) -> [a] -> m [b]
concatMapM (Cmd -> Maybe String -> String -> IO [String]
resolveFile Cmd
cmd Maybe String
tmpFile) [String]
cmdFiles
if [String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
files
then String -> IO Cmd
forall a. HasCallStack => String -> a
error String
"No files found"
else Cmd -> IO Cmd
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Cmd
cmd { cmdFiles = files }
readAllSettings :: [String] -> Cmd -> IO (Cmd, [Setting])
readAllSettings :: [String] -> Cmd -> IO (Cmd, [Setting])
readAllSettings [String]
args1 cmd :: Cmd
cmd@CmdMain{Bool
Int
String
[String]
[Severity]
ColorMode
cmdTest :: Cmd -> Bool
cmdTiming :: Cmd -> Bool
cmdNoExitCode :: Cmd -> Bool
cmdFiles :: Cmd -> [String]
cmdReports :: Cmd -> [String]
cmdGivenHints :: Cmd -> [String]
cmdWithGroups :: Cmd -> [String]
cmdGit :: Cmd -> Bool
cmdColor :: Cmd -> ColorMode
cmdThreads :: Cmd -> Int
cmdIgnore :: Cmd -> [String]
cmdShowAll :: Cmd -> Bool
cmdIgnoreSuggestions :: Cmd -> Bool
cmdExtension :: Cmd -> [String]
cmdLanguage :: Cmd -> [String]
cmdCross :: Cmd -> Bool
cmdFindHints :: Cmd -> [String]
cmdDataDir :: Cmd -> String
cmdDefault :: Cmd -> Bool
cmdPath :: Cmd -> [String]
cmdCppDefine :: Cmd -> [String]
cmdCppInclude :: Cmd -> [String]
cmdCppFile :: Cmd -> [String]
cmdCppSimple :: Cmd -> Bool
cmdCppAnsi :: Cmd -> Bool
cmdJson :: Cmd -> Bool
cmdCC :: Cmd -> Bool
cmdSARIF :: Cmd -> Bool
cmdNoSummary :: Cmd -> Bool
cmdOnly :: Cmd -> [String]
cmdSerialise :: Cmd -> Bool
cmdRefactor :: Cmd -> Bool
cmdRefactorOptions :: Cmd -> String
cmdWithRefactor :: Cmd -> String
cmdIgnoreGlob :: Cmd -> [String]
cmdGenerateMdSummary :: Cmd -> [String]
cmdGenerateJsonSummary :: Cmd -> [String]
cmdGenerateExhaustiveConf :: Cmd -> [Severity]
cmdFiles :: [String]
cmdReports :: [String]
cmdGivenHints :: [String]
cmdWithGroups :: [String]
cmdGit :: Bool
cmdColor :: ColorMode
cmdThreads :: Int
cmdIgnore :: [String]
cmdShowAll :: Bool
cmdIgnoreSuggestions :: Bool
cmdExtension :: [String]
cmdLanguage :: [String]
cmdCross :: Bool
cmdFindHints :: [String]
cmdDataDir :: String
cmdDefault :: Bool
cmdPath :: [String]
cmdCppDefine :: [String]
cmdCppInclude :: [String]
cmdCppFile :: [String]
cmdCppSimple :: Bool
cmdCppAnsi :: Bool
cmdJson :: Bool
cmdCC :: Bool
cmdSARIF :: Bool
cmdNoSummary :: Bool
cmdOnly :: [String]
cmdNoExitCode :: Bool
cmdTiming :: Bool
cmdSerialise :: Bool
cmdRefactor :: Bool
cmdRefactorOptions :: String
cmdWithRefactor :: String
cmdIgnoreGlob :: [String]
cmdGenerateMdSummary :: [String]
cmdGenerateJsonSummary :: [String]
cmdGenerateExhaustiveConf :: [Severity]
cmdTest :: Bool
..} = do
[(String, Maybe String)]
files <- Cmd -> IO [(String, Maybe String)]
cmdHintFiles Cmd
cmd
[Setting]
settings1 <-
[(String, Maybe String)] -> IO [Setting]
readFilesConfig ([(String, Maybe String)] -> IO [Setting])
-> [(String, Maybe String)] -> IO [Setting]
forall a b. (a -> b) -> a -> b
$
[(String, Maybe String)]
files
[(String, Maybe String)]
-> [(String, Maybe String)] -> [(String, Maybe String)]
forall a. [a] -> [a] -> [a]
++ [(String
"CommandLine.yaml",String -> Maybe String
forall a. a -> Maybe a
Just (String -> String
enableGroup String
x)) | String
x <- [String]
cmdWithGroups]
let args2 :: [String]
args2 = [String
x | SettingArgument String
x <- [Setting]
settings1]
cmd :: Cmd
cmd@CmdMain{Bool
Int
String
[String]
[Severity]
ColorMode
cmdTest :: Cmd -> Bool
cmdTiming :: Cmd -> Bool
cmdNoExitCode :: Cmd -> Bool
cmdFiles :: Cmd -> [String]
cmdReports :: Cmd -> [String]
cmdGivenHints :: Cmd -> [String]
cmdWithGroups :: Cmd -> [String]
cmdGit :: Cmd -> Bool
cmdColor :: Cmd -> ColorMode
cmdThreads :: Cmd -> Int
cmdIgnore :: Cmd -> [String]
cmdShowAll :: Cmd -> Bool
cmdIgnoreSuggestions :: Cmd -> Bool
cmdExtension :: Cmd -> [String]
cmdLanguage :: Cmd -> [String]
cmdCross :: Cmd -> Bool
cmdFindHints :: Cmd -> [String]
cmdDataDir :: Cmd -> String
cmdDefault :: Cmd -> Bool
cmdPath :: Cmd -> [String]
cmdCppDefine :: Cmd -> [String]
cmdCppInclude :: Cmd -> [String]
cmdCppFile :: Cmd -> [String]
cmdCppSimple :: Cmd -> Bool
cmdCppAnsi :: Cmd -> Bool
cmdJson :: Cmd -> Bool
cmdCC :: Cmd -> Bool
cmdSARIF :: Cmd -> Bool
cmdNoSummary :: Cmd -> Bool
cmdOnly :: Cmd -> [String]
cmdSerialise :: Cmd -> Bool
cmdRefactor :: Cmd -> Bool
cmdRefactorOptions :: Cmd -> String
cmdWithRefactor :: Cmd -> String
cmdIgnoreGlob :: Cmd -> [String]
cmdGenerateMdSummary :: Cmd -> [String]
cmdGenerateJsonSummary :: Cmd -> [String]
cmdGenerateExhaustiveConf :: Cmd -> [Severity]
cmdFiles :: [String]
cmdReports :: [String]
cmdGivenHints :: [String]
cmdWithGroups :: [String]
cmdGit :: Bool
cmdColor :: ColorMode
cmdThreads :: Int
cmdIgnore :: [String]
cmdShowAll :: Bool
cmdIgnoreSuggestions :: Bool
cmdExtension :: [String]
cmdLanguage :: [String]
cmdCross :: Bool
cmdFindHints :: [String]
cmdDataDir :: String
cmdDefault :: Bool
cmdPath :: [String]
cmdCppDefine :: [String]
cmdCppInclude :: [String]
cmdCppFile :: [String]
cmdCppSimple :: Bool
cmdCppAnsi :: Bool
cmdJson :: Bool
cmdCC :: Bool
cmdSARIF :: Bool
cmdNoSummary :: Bool
cmdOnly :: [String]
cmdNoExitCode :: Bool
cmdTiming :: Bool
cmdSerialise :: Bool
cmdRefactor :: Bool
cmdRefactorOptions :: String
cmdWithRefactor :: String
cmdIgnoreGlob :: [String]
cmdGenerateMdSummary :: [String]
cmdGenerateJsonSummary :: [String]
cmdGenerateExhaustiveConf :: [Severity]
cmdTest :: Bool
..} <- if [String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
args2 then Cmd -> IO Cmd
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Cmd
cmd else [String] -> IO Cmd
getCmd ([String] -> IO Cmd) -> [String] -> IO Cmd
forall a b. (a -> b) -> a -> b
$ [String]
args2 [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
args1
[Setting]
settings2 <- (String -> IO [Setting]) -> [String] -> IO [Setting]
forall (m :: * -> *) a b. Monad m => (a -> m [b]) -> [a] -> m [b]
concatMapM (((String, [Setting]) -> [Setting])
-> IO (String, [Setting]) -> IO [Setting]
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String, [Setting]) -> [Setting]
forall a b. (a, b) -> b
snd (IO (String, [Setting]) -> IO [Setting])
-> (String -> IO (String, [Setting])) -> String -> IO [Setting]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParseFlags -> String -> IO (String, [Setting])
computeSettings (Cmd -> ParseFlags
cmdParseFlags Cmd
cmd)) [String]
cmdFindHints
let settings3 :: [Setting]
settings3 = [Classify -> Setting
SettingClassify (Classify -> Setting) -> Classify -> Setting
forall a b. (a -> b) -> a -> b
$ Severity -> String -> String -> String -> Classify
Classify Severity
Ignore String
x String
"" String
"" | String
x <- [String]
cmdIgnore]
Int
cmdThreads <- if Int
cmdThreads Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then IO Int
getNumProcessors else Int -> IO Int
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
cmdThreads
Cmd
cmd <- Cmd -> IO Cmd
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CmdMain {Bool
Int
String
[String]
[Severity]
ColorMode
cmdTest :: Bool
cmdTiming :: Bool
cmdNoExitCode :: Bool
cmdFiles :: [String]
cmdReports :: [String]
cmdGivenHints :: [String]
cmdWithGroups :: [String]
cmdGit :: Bool
cmdColor :: ColorMode
cmdThreads :: Int
cmdIgnore :: [String]
cmdShowAll :: Bool
cmdIgnoreSuggestions :: Bool
cmdExtension :: [String]
cmdLanguage :: [String]
cmdCross :: Bool
cmdFindHints :: [String]
cmdDataDir :: String
cmdDefault :: Bool
cmdPath :: [String]
cmdCppDefine :: [String]
cmdCppInclude :: [String]
cmdCppFile :: [String]
cmdCppSimple :: Bool
cmdCppAnsi :: Bool
cmdJson :: Bool
cmdCC :: Bool
cmdSARIF :: Bool
cmdNoSummary :: Bool
cmdOnly :: [String]
cmdSerialise :: Bool
cmdRefactor :: Bool
cmdRefactorOptions :: String
cmdWithRefactor :: String
cmdIgnoreGlob :: [String]
cmdGenerateMdSummary :: [String]
cmdGenerateJsonSummary :: [String]
cmdGenerateExhaustiveConf :: [Severity]
cmdFiles :: [String]
cmdReports :: [String]
cmdGivenHints :: [String]
cmdWithGroups :: [String]
cmdGit :: Bool
cmdColor :: ColorMode
cmdIgnore :: [String]
cmdShowAll :: Bool
cmdIgnoreSuggestions :: Bool
cmdExtension :: [String]
cmdLanguage :: [String]
cmdCross :: Bool
cmdFindHints :: [String]
cmdDataDir :: String
cmdDefault :: Bool
cmdPath :: [String]
cmdCppDefine :: [String]
cmdCppInclude :: [String]
cmdCppFile :: [String]
cmdCppSimple :: Bool
cmdCppAnsi :: Bool
cmdJson :: Bool
cmdCC :: Bool
cmdSARIF :: Bool
cmdNoSummary :: Bool
cmdOnly :: [String]
cmdNoExitCode :: Bool
cmdTiming :: Bool
cmdSerialise :: Bool
cmdRefactor :: Bool
cmdRefactorOptions :: String
cmdWithRefactor :: String
cmdIgnoreGlob :: [String]
cmdGenerateMdSummary :: [String]
cmdGenerateJsonSummary :: [String]
cmdGenerateExhaustiveConf :: [Severity]
cmdTest :: Bool
cmdThreads :: Int
..}
(Cmd, [Setting]) -> IO (Cmd, [Setting])
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Cmd
cmd, [Setting]
settings1 [Setting] -> [Setting] -> [Setting]
forall a. [a] -> [a] -> [a]
++ [Setting]
settings2 [Setting] -> [Setting] -> [Setting]
forall a. [a] -> [a] -> [a]
++ [Setting]
settings3)
where
enableGroup :: String -> String
enableGroup String
groupName =
[String] -> String
unlines
[String
"- group:"
,String
" name: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
groupName
,String
" enabled: true"
]
runHints :: [String] -> [Setting] -> Cmd -> IO [Idea]
runHints :: [String] -> [Setting] -> Cmd -> IO [Idea]
runHints [String]
args [Setting]
settings cmd :: Cmd
cmd@CmdMain{Bool
Int
String
[String]
[Severity]
ColorMode
cmdTest :: Cmd -> Bool
cmdTiming :: Cmd -> Bool
cmdNoExitCode :: Cmd -> Bool
cmdFiles :: Cmd -> [String]
cmdReports :: Cmd -> [String]
cmdGivenHints :: Cmd -> [String]
cmdWithGroups :: Cmd -> [String]
cmdGit :: Cmd -> Bool
cmdColor :: Cmd -> ColorMode
cmdThreads :: Cmd -> Int
cmdIgnore :: Cmd -> [String]
cmdShowAll :: Cmd -> Bool
cmdIgnoreSuggestions :: Cmd -> Bool
cmdExtension :: Cmd -> [String]
cmdLanguage :: Cmd -> [String]
cmdCross :: Cmd -> Bool
cmdFindHints :: Cmd -> [String]
cmdDataDir :: Cmd -> String
cmdDefault :: Cmd -> Bool
cmdPath :: Cmd -> [String]
cmdCppDefine :: Cmd -> [String]
cmdCppInclude :: Cmd -> [String]
cmdCppFile :: Cmd -> [String]
cmdCppSimple :: Cmd -> Bool
cmdCppAnsi :: Cmd -> Bool
cmdJson :: Cmd -> Bool
cmdCC :: Cmd -> Bool
cmdSARIF :: Cmd -> Bool
cmdNoSummary :: Cmd -> Bool
cmdOnly :: Cmd -> [String]
cmdSerialise :: Cmd -> Bool
cmdRefactor :: Cmd -> Bool
cmdRefactorOptions :: Cmd -> String
cmdWithRefactor :: Cmd -> String
cmdIgnoreGlob :: Cmd -> [String]
cmdGenerateMdSummary :: Cmd -> [String]
cmdGenerateJsonSummary :: Cmd -> [String]
cmdGenerateExhaustiveConf :: Cmd -> [Severity]
cmdFiles :: [String]
cmdReports :: [String]
cmdGivenHints :: [String]
cmdWithGroups :: [String]
cmdGit :: Bool
cmdColor :: ColorMode
cmdThreads :: Int
cmdIgnore :: [String]
cmdShowAll :: Bool
cmdIgnoreSuggestions :: Bool
cmdExtension :: [String]
cmdLanguage :: [String]
cmdCross :: Bool
cmdFindHints :: [String]
cmdDataDir :: String
cmdDefault :: Bool
cmdPath :: [String]
cmdCppDefine :: [String]
cmdCppInclude :: [String]
cmdCppFile :: [String]
cmdCppSimple :: Bool
cmdCppAnsi :: Bool
cmdJson :: Bool
cmdCC :: Bool
cmdSARIF :: Bool
cmdNoSummary :: Bool
cmdOnly :: [String]
cmdNoExitCode :: Bool
cmdTiming :: Bool
cmdSerialise :: Bool
cmdRefactor :: Bool
cmdRefactorOptions :: String
cmdWithRefactor :: String
cmdIgnoreGlob :: [String]
cmdGenerateMdSummary :: [String]
cmdGenerateJsonSummary :: [String]
cmdGenerateExhaustiveConf :: [Severity]
cmdTest :: Bool
..} =
Int -> IO [Idea] -> IO [Idea]
forall a. Int -> IO a -> IO a
withNumCapabilities Int
cmdThreads (IO [Idea] -> IO [Idea]) -> IO [Idea] -> IO [Idea]
forall a b. (a -> b) -> a -> b
$ do
let outStrLn :: String -> IO ()
outStrLn = IO () -> IO ()
whenNormal (IO () -> IO ()) -> (String -> IO ()) -> String -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ()
putStrLn
[Idea]
ideas <- [Idea] -> [Idea]
filterIdeas ([Idea] -> [Idea]) -> IO [Idea] -> IO [Idea]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Cmd -> [Setting] -> IO [Idea]
getIdeas Cmd
cmd [Setting]
settings
if Bool
cmdJson then
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ [Idea] -> String
showIdeasJson [Idea]
ideas
else if Bool
cmdCC then
(Idea -> IO ()) -> [Idea] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Issue -> IO ()
printIssue (Issue -> IO ()) -> (Idea -> Issue) -> Idea -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Idea -> Issue
fromIdea) [Idea]
ideas
else if Bool
cmdSARIF then
[Idea] -> IO ()
SARIF.printIdeas [Idea]
ideas
else if Bool
cmdSerialise then do
Handle -> BufferMode -> IO ()
hSetBuffering Handle
stdout BufferMode
NoBuffering
[(String, [Refactoring SrcSpan])] -> IO ()
forall a. Show a => a -> IO ()
print ([(String, [Refactoring SrcSpan])] -> IO ())
-> [(String, [Refactoring SrcSpan])] -> IO ()
forall a b. (a -> b) -> a -> b
$ (Idea -> (String, [Refactoring SrcSpan]))
-> [Idea] -> [(String, [Refactoring SrcSpan])]
forall a b. (a -> b) -> [a] -> [b]
map (Idea -> String
forall a. Show a => a -> String
show (Idea -> String)
-> (Idea -> [Refactoring SrcSpan])
-> Idea
-> (String, [Refactoring SrcSpan])
forall a b c. (a -> b) -> (a -> c) -> a -> (b, c)
&&& Idea -> [Refactoring SrcSpan]
ideaRefactoring) [Idea]
ideas
else if Bool
cmdRefactor then
[Idea] -> [String] -> Cmd -> IO ()
handleRefactoring [Idea]
ideas [String]
cmdFiles Cmd
cmd
else do
Bool
usecolour <- Cmd -> IO Bool
cmdUseColour Cmd
cmd
let showItem :: Idea -> String
showItem = if Bool
usecolour then Idea -> String
showIdeaANSI else Idea -> String
forall a. Show a => a -> String
show
(Idea -> IO ()) -> [Idea] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (String -> IO ()
outStrLn (String -> IO ()) -> (Idea -> String) -> Idea -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Idea -> String
showItem) [Idea]
ideas
[Idea] -> Cmd -> IO ()
handleReporting [Idea]
ideas Cmd
cmd
[Idea] -> IO [Idea]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Idea]
ideas
where
filteredSeverities :: [Severity]
filteredSeverities
| Bool
cmdShowAll = []
| Bool
cmdIgnoreSuggestions = [Severity
Ignore, Severity
Suggestion]
| Bool
otherwise = [Severity
Ignore]
filterIdeas :: [Idea] -> [Idea]
filterIdeas = (Idea -> Bool) -> [Idea] -> [Idea]
forall a. (a -> Bool) -> [a] -> [a]
filter (\Idea
i -> Idea -> Severity
ideaSeverity Idea
i Severity -> [Severity] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Severity]
filteredSeverities)
getIdeas :: Cmd -> [Setting] -> IO [Idea]
getIdeas :: Cmd -> [Setting] -> IO [Idea]
getIdeas cmd :: Cmd
cmd@CmdMain{Bool
Int
String
[String]
[Severity]
ColorMode
cmdTest :: Cmd -> Bool
cmdTiming :: Cmd -> Bool
cmdNoExitCode :: Cmd -> Bool
cmdFiles :: Cmd -> [String]
cmdReports :: Cmd -> [String]
cmdGivenHints :: Cmd -> [String]
cmdWithGroups :: Cmd -> [String]
cmdGit :: Cmd -> Bool
cmdColor :: Cmd -> ColorMode
cmdThreads :: Cmd -> Int
cmdIgnore :: Cmd -> [String]
cmdShowAll :: Cmd -> Bool
cmdIgnoreSuggestions :: Cmd -> Bool
cmdExtension :: Cmd -> [String]
cmdLanguage :: Cmd -> [String]
cmdCross :: Cmd -> Bool
cmdFindHints :: Cmd -> [String]
cmdDataDir :: Cmd -> String
cmdDefault :: Cmd -> Bool
cmdPath :: Cmd -> [String]
cmdCppDefine :: Cmd -> [String]
cmdCppInclude :: Cmd -> [String]
cmdCppFile :: Cmd -> [String]
cmdCppSimple :: Cmd -> Bool
cmdCppAnsi :: Cmd -> Bool
cmdJson :: Cmd -> Bool
cmdCC :: Cmd -> Bool
cmdSARIF :: Cmd -> Bool
cmdNoSummary :: Cmd -> Bool
cmdOnly :: Cmd -> [String]
cmdSerialise :: Cmd -> Bool
cmdRefactor :: Cmd -> Bool
cmdRefactorOptions :: Cmd -> String
cmdWithRefactor :: Cmd -> String
cmdIgnoreGlob :: Cmd -> [String]
cmdGenerateMdSummary :: Cmd -> [String]
cmdGenerateJsonSummary :: Cmd -> [String]
cmdGenerateExhaustiveConf :: Cmd -> [Severity]
cmdFiles :: [String]
cmdReports :: [String]
cmdGivenHints :: [String]
cmdWithGroups :: [String]
cmdGit :: Bool
cmdColor :: ColorMode
cmdThreads :: Int
cmdIgnore :: [String]
cmdShowAll :: Bool
cmdIgnoreSuggestions :: Bool
cmdExtension :: [String]
cmdLanguage :: [String]
cmdCross :: Bool
cmdFindHints :: [String]
cmdDataDir :: String
cmdDefault :: Bool
cmdPath :: [String]
cmdCppDefine :: [String]
cmdCppInclude :: [String]
cmdCppFile :: [String]
cmdCppSimple :: Bool
cmdCppAnsi :: Bool
cmdJson :: Bool
cmdCC :: Bool
cmdSARIF :: Bool
cmdNoSummary :: Bool
cmdOnly :: [String]
cmdNoExitCode :: Bool
cmdTiming :: Bool
cmdSerialise :: Bool
cmdRefactor :: Bool
cmdRefactorOptions :: String
cmdWithRefactor :: String
cmdIgnoreGlob :: [String]
cmdGenerateMdSummary :: [String]
cmdGenerateJsonSummary :: [String]
cmdGenerateExhaustiveConf :: [Severity]
cmdTest :: Bool
..} [Setting]
settings = do
[Setting]
settings <- [Setting] -> IO [Setting]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Setting] -> IO [Setting]) -> [Setting] -> IO [Setting]
forall a b. (a -> b) -> a -> b
$ [Setting]
settings [Setting] -> [Setting] -> [Setting]
forall a. [a] -> [a] -> [a]
++ ((String, Hint) -> Setting) -> [(String, Hint)] -> [Setting]
forall a b. (a -> b) -> [a] -> [b]
map (String -> Setting
Builtin (String -> Setting)
-> ((String, Hint) -> String) -> (String, Hint) -> Setting
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String, Hint) -> String
forall a b. (a, b) -> a
fst) [(String, Hint)]
builtinHints
let flags :: ParseFlags
flags = Cmd -> ParseFlags
cmdParseFlags Cmd
cmd
[Idea]
ideas <- if Bool
cmdCross
then ParseFlags -> [Setting] -> [String] -> IO [Idea]
applyHintFiles ParseFlags
flags [Setting]
settings [String]
cmdFiles
else [[Idea]] -> [Idea]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Idea]] -> [Idea]) -> IO [[Idea]] -> IO [Idea]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> [IO [Idea]] -> IO [[Idea]]
forall a. Int -> [IO a] -> IO [a]
parallel Int
cmdThreads [[Idea] -> IO [Idea]
forall a. [a] -> IO [a]
evaluateList ([Idea] -> IO [Idea]) -> IO [Idea] -> IO [Idea]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ParseFlags -> [Setting] -> String -> Maybe String -> IO [Idea]
applyHintFile ParseFlags
flags [Setting]
settings String
x Maybe String
forall a. Maybe a
Nothing | String
x <- [String]
cmdFiles]
[Idea] -> IO [Idea]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Idea] -> IO [Idea]) -> [Idea] -> IO [Idea]
forall a b. (a -> b) -> a -> b
$ if Bool -> Bool
not ([String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
cmdOnly)
then [Idea
i | Idea
i <- [Idea]
ideas, Idea -> String
ideaHint Idea
i String -> [String] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
cmdOnly]
else [Idea]
ideas
handleRefactoring :: [Idea] -> [String] -> Cmd -> IO ()
handleRefactoring :: [Idea] -> [String] -> Cmd -> IO ()
handleRefactoring [Idea]
ideas [String]
files cmd :: Cmd
cmd@CmdMain{Bool
Int
String
[String]
[Severity]
ColorMode
cmdTest :: Cmd -> Bool
cmdTiming :: Cmd -> Bool
cmdNoExitCode :: Cmd -> Bool
cmdFiles :: Cmd -> [String]
cmdReports :: Cmd -> [String]
cmdGivenHints :: Cmd -> [String]
cmdWithGroups :: Cmd -> [String]
cmdGit :: Cmd -> Bool
cmdColor :: Cmd -> ColorMode
cmdThreads :: Cmd -> Int
cmdIgnore :: Cmd -> [String]
cmdShowAll :: Cmd -> Bool
cmdIgnoreSuggestions :: Cmd -> Bool
cmdExtension :: Cmd -> [String]
cmdLanguage :: Cmd -> [String]
cmdCross :: Cmd -> Bool
cmdFindHints :: Cmd -> [String]
cmdDataDir :: Cmd -> String
cmdDefault :: Cmd -> Bool
cmdPath :: Cmd -> [String]
cmdCppDefine :: Cmd -> [String]
cmdCppInclude :: Cmd -> [String]
cmdCppFile :: Cmd -> [String]
cmdCppSimple :: Cmd -> Bool
cmdCppAnsi :: Cmd -> Bool
cmdJson :: Cmd -> Bool
cmdCC :: Cmd -> Bool
cmdSARIF :: Cmd -> Bool
cmdNoSummary :: Cmd -> Bool
cmdOnly :: Cmd -> [String]
cmdSerialise :: Cmd -> Bool
cmdRefactor :: Cmd -> Bool
cmdRefactorOptions :: Cmd -> String
cmdWithRefactor :: Cmd -> String
cmdIgnoreGlob :: Cmd -> [String]
cmdGenerateMdSummary :: Cmd -> [String]
cmdGenerateJsonSummary :: Cmd -> [String]
cmdGenerateExhaustiveConf :: Cmd -> [Severity]
cmdFiles :: [String]
cmdReports :: [String]
cmdGivenHints :: [String]
cmdWithGroups :: [String]
cmdGit :: Bool
cmdColor :: ColorMode
cmdThreads :: Int
cmdIgnore :: [String]
cmdShowAll :: Bool
cmdIgnoreSuggestions :: Bool
cmdExtension :: [String]
cmdLanguage :: [String]
cmdCross :: Bool
cmdFindHints :: [String]
cmdDataDir :: String
cmdDefault :: Bool
cmdPath :: [String]
cmdCppDefine :: [String]
cmdCppInclude :: [String]
cmdCppFile :: [String]
cmdCppSimple :: Bool
cmdCppAnsi :: Bool
cmdJson :: Bool
cmdCC :: Bool
cmdSARIF :: Bool
cmdNoSummary :: Bool
cmdOnly :: [String]
cmdNoExitCode :: Bool
cmdTiming :: Bool
cmdSerialise :: Bool
cmdRefactor :: Bool
cmdRefactorOptions :: String
cmdWithRefactor :: String
cmdIgnoreGlob :: [String]
cmdGenerateMdSummary :: [String]
cmdGenerateJsonSummary :: [String]
cmdGenerateExhaustiveConf :: [Severity]
cmdTest :: Bool
..} =
case [String]
cmdFiles of
[String
file] -> do
String
path <- Maybe String -> IO String
checkRefactor (if String
cmdWithRefactor String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"" then Maybe String
forall a. Maybe a
Nothing else String -> Maybe String
forall a. a -> Maybe a
Just String
cmdWithRefactor)
let hints :: String
hints = [(String, [Refactoring SrcSpan])] -> String
forall a. Show a => a -> String
show ([(String, [Refactoring SrcSpan])] -> String)
-> [(String, [Refactoring SrcSpan])] -> String
forall a b. (a -> b) -> a -> b
$ (Idea -> (String, [Refactoring SrcSpan]))
-> [Idea] -> [(String, [Refactoring SrcSpan])]
forall a b. (a -> b) -> [a] -> [b]
map (Idea -> String
forall a. Show a => a -> String
show (Idea -> String)
-> (Idea -> [Refactoring SrcSpan])
-> Idea
-> (String, [Refactoring SrcSpan])
forall a b c. (a -> b) -> (a -> c) -> a -> (b, c)
&&& Idea -> [Refactoring SrcSpan]
ideaRefactoring) [Idea]
ideas
(String -> IO ()) -> IO ()
forall a. (String -> IO a) -> IO a
withTempFile ((String -> IO ()) -> IO ()) -> (String -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \String
f -> do
String -> String -> IO ()
writeFile String
f String
hints
let ParseFlags{[Extension]
enabledExtensions :: [Extension]
enabledExtensions :: ParseFlags -> [Extension]
enabledExtensions, [Extension]
disabledExtensions :: [Extension]
disabledExtensions :: ParseFlags -> [Extension]
disabledExtensions} = Cmd -> ParseFlags
cmdParseFlags Cmd
cmd
ExitCode -> IO ()
forall a. ExitCode -> IO a
exitWith (ExitCode -> IO ()) -> IO ExitCode -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String
-> String
-> String
-> [Extension]
-> [Extension]
-> String
-> IO ExitCode
runRefactoring String
path String
file String
f [Extension]
enabledExtensions [Extension]
disabledExtensions String
cmdRefactorOptions
[String]
_ -> String -> IO ()
forall a. HasCallStack => String -> IO a
errorIO String
"Refactor flag can only be used with an individual file"
handleReporting :: [Idea] -> Cmd -> IO ()
handleReporting :: [Idea] -> Cmd -> IO ()
handleReporting [Idea]
showideas cmd :: Cmd
cmd@CmdMain{Bool
Int
String
[String]
[Severity]
ColorMode
cmdTest :: Cmd -> Bool
cmdTiming :: Cmd -> Bool
cmdNoExitCode :: Cmd -> Bool
cmdFiles :: Cmd -> [String]
cmdReports :: Cmd -> [String]
cmdGivenHints :: Cmd -> [String]
cmdWithGroups :: Cmd -> [String]
cmdGit :: Cmd -> Bool
cmdColor :: Cmd -> ColorMode
cmdThreads :: Cmd -> Int
cmdIgnore :: Cmd -> [String]
cmdShowAll :: Cmd -> Bool
cmdIgnoreSuggestions :: Cmd -> Bool
cmdExtension :: Cmd -> [String]
cmdLanguage :: Cmd -> [String]
cmdCross :: Cmd -> Bool
cmdFindHints :: Cmd -> [String]
cmdDataDir :: Cmd -> String
cmdDefault :: Cmd -> Bool
cmdPath :: Cmd -> [String]
cmdCppDefine :: Cmd -> [String]
cmdCppInclude :: Cmd -> [String]
cmdCppFile :: Cmd -> [String]
cmdCppSimple :: Cmd -> Bool
cmdCppAnsi :: Cmd -> Bool
cmdJson :: Cmd -> Bool
cmdCC :: Cmd -> Bool
cmdSARIF :: Cmd -> Bool
cmdNoSummary :: Cmd -> Bool
cmdOnly :: Cmd -> [String]
cmdSerialise :: Cmd -> Bool
cmdRefactor :: Cmd -> Bool
cmdRefactorOptions :: Cmd -> String
cmdWithRefactor :: Cmd -> String
cmdIgnoreGlob :: Cmd -> [String]
cmdGenerateMdSummary :: Cmd -> [String]
cmdGenerateJsonSummary :: Cmd -> [String]
cmdGenerateExhaustiveConf :: Cmd -> [Severity]
cmdFiles :: [String]
cmdReports :: [String]
cmdGivenHints :: [String]
cmdWithGroups :: [String]
cmdGit :: Bool
cmdColor :: ColorMode
cmdThreads :: Int
cmdIgnore :: [String]
cmdShowAll :: Bool
cmdIgnoreSuggestions :: Bool
cmdExtension :: [String]
cmdLanguage :: [String]
cmdCross :: Bool
cmdFindHints :: [String]
cmdDataDir :: String
cmdDefault :: Bool
cmdPath :: [String]
cmdCppDefine :: [String]
cmdCppInclude :: [String]
cmdCppFile :: [String]
cmdCppSimple :: Bool
cmdCppAnsi :: Bool
cmdJson :: Bool
cmdCC :: Bool
cmdSARIF :: Bool
cmdNoSummary :: Bool
cmdOnly :: [String]
cmdNoExitCode :: Bool
cmdTiming :: Bool
cmdSerialise :: Bool
cmdRefactor :: Bool
cmdRefactorOptions :: String
cmdWithRefactor :: String
cmdIgnoreGlob :: [String]
cmdGenerateMdSummary :: [String]
cmdGenerateJsonSummary :: [String]
cmdGenerateExhaustiveConf :: [Severity]
cmdTest :: Bool
..} = do
let outStrLn :: String -> IO ()
outStrLn = IO () -> IO ()
whenNormal (IO () -> IO ()) -> (String -> IO ()) -> String -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ()
putStrLn
[String] -> (String -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [String]
cmdReports ((String -> IO ()) -> IO ()) -> (String -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \String
x -> do
String -> IO ()
outStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Writing report to " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" ..."
String -> String -> [Idea] -> IO ()
writeReport String
cmdDataDir String
x [Idea]
showideas
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
cmdNoSummary (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let (Int
nbErrors, Int
nbHints) = ([Idea] -> Int)
-> ([Idea] -> Int) -> ([Idea], [Idea]) -> (Int, Int)
forall a b c d. (a -> b) -> (c -> d) -> (a, c) -> (b, d)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap [Idea] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Idea] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (([Idea], [Idea]) -> (Int, Int)) -> ([Idea], [Idea]) -> (Int, Int)
forall a b. (a -> b) -> a -> b
$ (Idea -> Bool) -> [Idea] -> ([Idea], [Idea])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (\Idea
idea -> Idea -> Severity
ideaSeverity Idea
idea Severity -> Severity -> Bool
forall a. Eq a => a -> a -> Bool
== Severity
Error) [Idea]
showideas
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
nbErrors Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0) (String -> IO ()
outStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> String -> String
formatOutput Int
nbErrors String
"error")
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
nbErrors Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& Int
nbHints Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (String -> IO ()
outStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> String -> String
formatOutput Int
nbHints String
"hint")
where
formatOutput :: Int -> String -> String
formatOutput :: Int -> String -> String
formatOutput Int
number String
name =
if Int
number Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then String
"No " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"s" else Int -> String
forall a. Show a => a -> String
show Int
number String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
's' | Int
numberInt -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/=Int
1]
evaluateList :: [a] -> IO [a]
evaluateList :: forall a. [a] -> IO [a]
evaluateList [a]
xs = do
Int -> IO Int
forall a. a -> IO a
evaluate (Int -> IO Int) -> Int -> IO Int
forall a b. (a -> b) -> a -> b
$ [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs
[a] -> IO [a]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [a]
xs