{-
    Copyright 2012-2019 Vidar Holen

    This file is part of ShellCheck.
    https://www.shellcheck.net

    ShellCheck is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    ShellCheck is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
-}
module ShellCheck.Analyzer (analyzeScript, ShellCheck.Analyzer.optionalChecks) where

import ShellCheck.Analytics
import ShellCheck.AnalyzerLib
import ShellCheck.Interface
import Data.List
import Data.Monoid
import qualified ShellCheck.Checks.Commands
import qualified ShellCheck.Checks.Custom
import qualified ShellCheck.Checks.ShellSupport


-- TODO: Clean up the cruft this is layered on
analyzeScript :: AnalysisSpec -> AnalysisResult
analyzeScript :: AnalysisSpec -> AnalysisResult
analyzeScript AnalysisSpec
spec = AnalysisResult
newAnalysisResult {
    arComments :: [TokenComment]
arComments =
        AnalysisSpec -> Parameters -> [TokenComment] -> [TokenComment]
filterByAnnotation AnalysisSpec
spec Parameters
params ([TokenComment] -> [TokenComment])
-> ([TokenComment] -> [TokenComment])
-> [TokenComment]
-> [TokenComment]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TokenComment] -> [TokenComment]
forall a. Eq a => [a] -> [a]
nub ([TokenComment] -> [TokenComment])
-> [TokenComment] -> [TokenComment]
forall a b. (a -> b) -> a -> b
$
            AnalysisSpec -> [TokenComment]
runAnalytics AnalysisSpec
spec
            [TokenComment] -> [TokenComment] -> [TokenComment]
forall a. [a] -> [a] -> [a]
++ Parameters -> Checker -> [TokenComment]
runChecker Parameters
params (AnalysisSpec -> Parameters -> Checker
checkers AnalysisSpec
spec Parameters
params)
}
  where
    params :: Parameters
params = AnalysisSpec -> Parameters
makeParameters AnalysisSpec
spec

checkers :: AnalysisSpec -> Parameters -> Checker
checkers AnalysisSpec
spec Parameters
params = [Checker] -> Checker
forall a. Monoid a => [a] -> a
mconcat ([Checker] -> Checker) -> [Checker] -> Checker
forall a b. (a -> b) -> a -> b
$ ((Parameters -> Checker) -> Checker)
-> [Parameters -> Checker] -> [Checker]
forall a b. (a -> b) -> [a] -> [b]
map ((Parameters -> Checker) -> Parameters -> Checker
forall a b. (a -> b) -> a -> b
$ Parameters
params) [
    AnalysisSpec -> Parameters -> Checker
ShellCheck.Checks.Commands.checker AnalysisSpec
spec,
    Parameters -> Checker
ShellCheck.Checks.Custom.checker,
    Parameters -> Checker
ShellCheck.Checks.ShellSupport.checker
    ]

optionalChecks :: [CheckDescription]
optionalChecks = [[CheckDescription]] -> [CheckDescription]
forall a. Monoid a => [a] -> a
mconcat ([[CheckDescription]] -> [CheckDescription])
-> [[CheckDescription]] -> [CheckDescription]
forall a b. (a -> b) -> a -> b
$ [
    [CheckDescription]
ShellCheck.Analytics.optionalChecks,
    [CheckDescription]
ShellCheck.Checks.Commands.optionalChecks
    ]