packages feed

hlint-1.0.0.1: src/Ignore.hs

{-# LANGUAGE ViewPatterns #-}

module Ignore(ignore) where

import qualified Data.Map as Map
import Data.Char
import Data.List
import Type


type Ignore = Map.Map String [String]


ignore :: [FilePath] -> [String] -> IO (Idea -> Bool)
ignore files extra = do
    src <- mapM readFile files
    let src2 = filter (\x -> not $ null x || "#" `isPrefixOf` x) $ map (dropWhile isSpace) $ concatMap lines src
    let mp = foldl' addIgnore Map.empty $ src2 ++ extra
    let always = Map.findWithDefault [] "" mp
    return $ \i ->
        let check = any (`isPrefixOf` dropMain (key i)) 
        in check always ||
            case Map.lookup (text i) mp of
                Nothing -> False
                Just v -> null v || check v


addIgnore :: Ignore -> String -> Ignore
addIgnore mp s
    | null opts && invert = Map.delete key mp
    | null opts           = Map.insert key [] mp
    | invert    = Map.adjust (\\ opts) key mp
    | otherwise = Map.insertWith (++) key opts mp
    where (invert,key,opts) = parseIgnore s


parseIgnore :: String -> (Bool,String,[String])
parseIgnore ('!':xs) = let (_,a,b) = parseIgnore (dropWhile isSpace xs) in (True,a,b)
parseIgnore ('{':(break (=='}') -> (keys, '}':text))) = (False, dropWhile isSpace text, map dropMain $ words keys)
parseIgnore x = (False, x, [])


dropMain x = if "Main." `isPrefixOf` x then drop 5 x else x