{-# LANGUAGE RecordWildCards #-} module HLint(hlint) where import Control.Arrow import Control.Monad import Data.List import Data.Maybe import CmdLine import Settings import Report import Type import Hint import Test import FindHints import Util import Parallel import Hint.All import HSE.All -- | This function takes the command line arguments, and returns the number -- of errors reported. hlint :: [String] -> IO Int hlint args = do cmd@Cmd{..} <- getCmd args let flags = parseFlags{cpphs=Just cmdCpphs, encoding=cmdEncoding} if cmdTest then test cmdDataDir else if not $ null cmdFindHints then mapM_ (findHints flags) cmdFindHints >> return 0 else if null cmdFiles then exitWithHelp else runHints cmd flags runHints :: Cmd -> ParseFlags -> IO Int runHints Cmd{..} flags = do settings <- readSettings cmdDataDir cmdHintFiles let extra = [Classify Ignore x ("","") | x <- cmdIgnore] let apply :: FilePath -> IO [Idea] apply = applyHint flags (allHints settings) (filter isClassify settings ++ extra) ideas <- fmap concat $ parallel [listM' =<< apply x | x <- cmdFiles] let visideas = filter (\i -> cmdShowAll || rank i /= Ignore) ideas showItem <- if cmdColor then showANSI else return show mapM_ (putStrLn . showItem) visideas -- figure out statistics let counts = map (head &&& length) $ group $ sort $ map rank ideas let [ignore,warn,err] = map (fromMaybe 0 . flip lookup counts) [Ignore,Warning,Error] let total = ignore + warn + err let shown = if cmdShowAll then total else total - ignore let ignored = [show i ++ " ignored" | let i = total - shown, i /= 0] let errors = [show err ++ " error" ++ ['s'|err/=1] | err /= 0] if shown == 0 then do when (cmdReports /= []) $ putStrLn "Skipping writing reports" printMsg "No relevant suggestions" ignored else do forM_ cmdReports $ \x -> do putStrLn $ "Writing report to " ++ x ++ " ..." writeReport cmdDataDir x visideas printMsg ("Found " ++ show shown ++ " suggestion" ++ ['s'|shown/=1]) (errors++ignored) return err printMsg :: String -> [String] -> IO () printMsg msg xs = putStrLn $ msg ++ if null xs then "" else " (" ++ intercalate ", " xs ++ ")"