{-# LANGUAGE PatternGuards, RecordWildCards #-}
module Language.Haskell.HLint(
hlint, applyHints,
Idea(..), Severity(..), Note(..),
Classify(..),
getHLintDataDir, autoSettings, argsSettings,
findSettings, readSettingsFile,
Hint,
ModuleEx, parseModuleEx, createModuleEx, ParseError(..),
defaultParseFlags,
ParseFlags(..), CppFlags(..), FixityInfo,
parseFlagsAddFixities,
) where
import Config.Type
import Config.Read
import Control.Exception.Extra
import Idea
import qualified Apply as H
import HLint
import Fixity
import HSE.All
import Hint.All hiding (resolveHints)
import qualified Hint.All as H
import qualified ApiAnnotation as GHC
import qualified GHC.Hs as GHC
import SrcLoc
import CmdLine
import Paths_hlint
import qualified Language.Haskell.GhclibParserEx.Fixity as GhclibParserEx
import Data.List.Extra
import Data.Maybe
import System.FilePath
import Data.Functor
import Prelude
getHLintDataDir :: IO FilePath
getHLintDataDir = getDataDir
autoSettings :: IO (ParseFlags, [Classify], Hint)
autoSettings = do
(fixities, classify, hints) <- findSettings (readSettingsFile Nothing) Nothing
pure (parseFlagsAddFixities fixities defaultParseFlags, classify, hints)
argsSettings :: [String] -> IO (ParseFlags, [Classify], Hint)
argsSettings args = do
cmd <- getCmd args
case cmd of
CmdMain{..} -> do
(_,settings) <- readAllSettings args cmd
let (fixities, classify, hints) = splitSettings settings
let flags = parseFlagsSetLanguage (cmdExtensions cmd) $ parseFlagsAddFixities fixities $
defaultParseFlags{cppFlags = cmdCpp cmd}
let ignore = [Classify Ignore x "" "" | x <- cmdIgnore]
pure (flags, classify ++ ignore, hints)
_ -> errorIO "Can only invoke autoSettingsArgs with the root process"
readSettingsFile :: Maybe FilePath -> String -> IO (FilePath, Maybe String)
readSettingsFile dir x
| takeExtension x `elem` [".yml",".yaml"] = do
dir <- maybe getHLintDataDir pure dir
pure (dir </> x, Nothing)
| Just x <- "HLint." `stripPrefix` x = do
dir <- maybe getHLintDataDir pure dir
pure (dir </> x <.> "hs", Nothing)
| otherwise = pure (x <.> "hs", Nothing)
findSettings :: (String -> IO (FilePath, Maybe String)) -> Maybe String -> IO ([FixityInfo], [Classify], Hint)
findSettings load start = do
(file,contents) <- load $ fromMaybe "hlint.yaml" start
splitSettings <$> readFilesConfig [(file,contents)]
splitSettings :: [Setting] -> ([FixityInfo], [Classify], Hint)
splitSettings xs =
([x | Infix x <- xs]
,[x | SettingClassify x <- xs]
,H.resolveHints $ [Right x | SettingMatchExp x <- xs] ++ map Left enumerate)
applyHints :: [Classify] -> Hint -> [ModuleEx] -> [Idea]
applyHints = H.applyHints
_docs :: IO ()
_docs = do
(flags, classify, hint) <- autoSettings
Right m <- parseModuleEx flags "MyFile.hs" Nothing
print $ applyHints classify hint [m]
createModuleEx:: GHC.ApiAnns -> Located (GHC.HsModule GHC.GhcPs) -> ModuleEx
createModuleEx anns ast =
ModuleEx (GhclibParserEx.applyFixities [] ast) anns