{-# LANGUAGE RecordWildCards #-}moduleHLint(hlint,Suggestion,suggestionLocation,suggestionSeverity,Severity(..))whereimportControl.MonadimportData.ListimportData.MaybeimportSystem.ExitimportCmdLineimportSettingsimportReportimportIdeaimportApplyimportTestimportProofimportUtilimportParallelimportHSE.All-- | A suggestion - the @Show@ instance is of particular use.newtypeSuggestion=Suggestion{fromSuggestion::Idea}deriving(Eq,Ord)instanceShowSuggestionwhereshow=show.fromSuggestion-- | From a suggestion, extract the file location it refers to.suggestionLocation::Suggestion->SrcLocsuggestionLocation=loc.fromSuggestion-- | From a suggestion, determine how severe it is.suggestionSeverity::Suggestion->SeveritysuggestionSeverity=severity.fromSuggestion-- | This function takes a list of command line arguments, and returns the given suggestions.-- To see a list of arguments type @hlint --help@ at the console.-- This function writes to the stdout/stderr streams, unless @--quiet@ is specified.---- As an example:---- > do hints <- hlint ["src", "--ignore=Use map","--quiet"]-- > when (length hints > 3) $ error "Too many hints!"hlint::[String]->IO[Suggestion]hlintargs=docmd@Cmd{..}<-getCmdargsletflags=parseFlags{cppFlags=cmdCpp,encoding=cmdEncoding,language=cmdLanguage}ifcmdTestthendofailed<-test(\x->hlintx>>return())cmdDataDircmdGivenHintswhen(failed>0)exitFailurereturn[]elseifnotNullcmdProofthendos<-readAllSettingscmdflagsletreps=ifcmdReports==["report.html"]then["report.txt"]elsecmdReportsmapM_(proofrepss)cmdProofreturn[]elseifisNothingcmdFiles&&notNullcmdFindHintsthenmapM_(\x->putStrLn.fst=<<findSettingsflagsx)cmdFindHints>>return[]elseifisNothingcmdFilesthenexitWithHelpelseifcmdFiles==Just[]thenerror"No files found"elserunHintscmdflagsreadAllSettings::Cmd->ParseFlags->IO[Setting]readAllSettingsCmd{..}flags=dosettings1<-readSettingscmdDataDircmdHintFilescmdWithHintssettings2<-concatMapM(fmapsnd.findSettingsflags)cmdFindHintssettings3<-return[ClassifyIgnorex("","")|x<-cmdIgnore]return$settings1++settings2++settings3runHints::Cmd->ParseFlags->IO[Suggestion]runHintscmd@Cmd{..}flags=doletoutStrLnx=unlesscmdQuiet$putStrLnxsettings<-readAllSettingscmdflagsletfiles=fromMaybe[]cmdFilesideas<-ifcmdCrossthenapplyHintFilesflagssettingsfileselsefmapconcat$parallel[listM'=<<applyHintFileflagssettingsx|x<-files]let(showideas,hideideas)=partition(\i->cmdShowAll||severityi/=Ignore)ideasshowItem<-ifcmdColorthenshowANSIelsereturnshowmapM_(outStrLn.showItem)showideasifnullshowideasthenwhen(cmdReports/=[])$outStrLn"Skipping writing reports"elseforM_cmdReports$\x->dooutStrLn$"Writing report to "++x++" ..."writeReportcmdDataDirxshowideasoutStrLn$(leti=lengthshowideasinifi==0then"No suggestions"elseshowi++" suggestion"++['s'|i/=1])++(leti=lengthhideideasinifi==0then""else" ("++showi++" ignored)")return$mapSuggestionshowideas