packages feed

hlint 1.8.8 → 1.8.9

raw patch · 14 files changed

+125/−67 lines, 14 filesdep ~haskell-src-extsPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: haskell-src-exts

API changes (from Hackage documentation)

Files

data/Default.hs view
@@ -197,6 +197,7 @@ error = (if isNothing x then y else fromJust x) ==> fromMaybe y x error = (if isJust x then fromJust x else y) ==> fromMaybe y x error = isJust x && (fromJust x == y) ==> x == Just y+error = mapMaybe f (map g x) ==> mapMaybe (f . g) x  -- INFIX 
hlint.cabal view
@@ -1,7 +1,7 @@ cabal-version:      >= 1.6 build-type:         Simple name:               hlint-version:            1.8.8+version:            1.8.9 -- license is GPL v2 only license:            GPL license-file:       LICENSE@@ -38,7 +38,7 @@         transformers >= 0.0 && < 0.3,         hscolour == 1.17.*,         cpphs == 1.11.*,-        haskell-src-exts >= 1.9.6 && < 1.11,+        haskell-src-exts >= 1.11 && < 1.12,         uniplate >= 1.5 && < 1.7      hs-source-dirs:     src
src/Apply.hs view
@@ -1,8 +1,9 @@ -module Apply(applyHint, applyHintStr) where+module Apply(applyHintFile, applyHintFiles, applyHintString) where  import HSE.All import Hint.All+import Control.Arrow import Data.Char import Data.List import Data.Maybe@@ -12,32 +13,72 @@ import Util  -applyHint :: ParseFlags -> [Setting] -> FilePath -> IO [Idea]-applyHint flags s file = do+-- | Apply hints to a single file.+applyHintFile :: ParseFlags -> [Setting] -> FilePath -> IO [Idea]+applyHintFile flags s file = do+    res <- parseModuleFile flags s file+    return $ case res of+        Left err -> [err]+        Right m -> executeHints s [m]+++-- | Apply hints to the contents of a single file.+applyHintString :: ParseFlags -> [Setting] -> FilePath -> String -> IO [Idea]+applyHintString flags s file src = do+    res <- parseModuleString flags s file src+    return $ case res of+        Left err -> [err]+        Right m -> executeHints s [m]+++-- | Apply hints to multiple files, allowing cross-file hints to fire.+applyHintFiles :: ParseFlags -> [Setting] -> [FilePath] -> IO [Idea]+applyHintFiles flags s files = do+    (err, ms) <- fmap unzipEither $ mapM (parseModuleFile flags s) files+    return $ err ++ executeHints s ms+++-- | Given a list of settings (a way to classify) and a list of hints, run them over a list of modules.+executeHints :: [Setting] -> [Module_] -> [Idea]+executeHints s ms = concat $+    [ map (classify $ s ++ mapMaybe readPragma (moduleDecls m)) $+        order "" [i | ModuHint h <- hints, i <- h nm m] +++        concat [order (fromNamed d) [i | h <- decHints, i <- h d] | d <- moduleDecls m]+    | (nm,m) <- mns+    , let decHints = [h nm m | DeclHint h <- hints] -- partially apply+    , let order n = map (\i -> i{func = (moduleName m,n)}) . sortBy (comparing loc)] +++    [map (classify s) $ op mns | CrossHint op <- hints]+    where+        mns = map (moduleScope &&& id) ms++        hints = for (allHints s) $ \x -> case x of+            CrossHint op | length ms <= 1 -> ModuHint $ \a b -> op [(a,b)]+            _ -> x+++-- | Like 'parseModuleString', but also load the file from disk.+parseModuleFile :: ParseFlags -> [Setting] -> FilePath -> IO (Either Idea Module_)+parseModuleFile flags s file = do     src <- readFileEncoding (encoding flags) file-    applyHintStr flags s file src+    parseModuleString flags s file src  -applyHintStr :: ParseFlags -> [Setting] -> FilePath -> String -> IO [Idea]-applyHintStr flags s file src = do+-- | Return either an idea (a parse error) or the module. In IO because might call the C pre processor.+parseModuleString :: ParseFlags -> [Setting] -> FilePath -> String -> IO (Either Idea Module_)+parseModuleString flags s file src = do     res <- parseString flags{infixes=[x | Infix x <- s]} file src     case snd res of-        ParseFailed sl msg | length src `seq` True -> map (classify s) `fmap` parseFailed flags sl msg src-        ParseOk m -> return $-            let settings = mapMaybe readPragma $ moduleDecls m-            in map (classify $ s ++ settings) $ parseOk (allHints s) m---parseFailed :: ParseFlags -> SrcLoc -> String -> String -> IO [Idea]-parseFailed flags sl msg src = do-    -- figure out the best line number to grab context from, by reparsing-    (str2,pr2) <- parseString (parseFlagsNoLocations flags) "" src-    let ctxt = case pr2 of-            ParseFailed sl2 _ -> context (srcLine sl2) str2-            _ -> context (srcLine sl) src-    return [ParseError Warning "Parse error" sl msg ctxt]+        ParseOk m -> return $ Right m+        ParseFailed sl msg | length src `seq` True -> do+            -- figure out the best line number to grab context from, by reparsing+            (str2,pr2) <- parseString (parseFlagsNoLocations flags) "" src+            let ctxt = case pr2 of+                    ParseFailed sl2 _ -> context (srcLine sl2) str2+                    _ -> context (srcLine sl) src+            return $ Left $ classify s $ ParseError Warning "Parse error" sl msg ctxt  +-- | Given a line number, and some source code, put bird ticks around the appropriate bit. context :: Int -> String -> String context lineNo src =     unlines $ trimBy (all isSpace) $@@ -45,22 +86,14 @@     where ticks = ["  ","  ","> ","  ","  "]  -parseOk :: [Hint] -> Module_ -> [Idea]-parseOk h m =-        order "" [i | ModuHint h <- h, i <- h nm m] ++-        concat [order (fromNamed d) [i | h <- decHints, i <- h d] | d <- moduleDecls m]-    where-        decHints = [h nm m | DeclHint h <- h] -- partially apply-        order n = map (\i -> i{func = (moduleName m,n)}) . sortBy (comparing loc)-        nm = moduleScope m--+-- | Find which hints a list of settings implies. allHints :: [Setting] -> [Hint] allHints xs = dynamicHints xs : map f builtin     where builtin = nub $ concat [if x == "All" then map fst staticHints else [x] | Builtin x <- xs]           f x = fromMaybe (error $ "Unknown builtin hints: HLint.Builtin." ++ x) $ lookup x staticHints  +-- | Given some settings, make sure the severity field of the Idea is correct. classify :: [Setting] -> Idea -> Idea classify xs i = i{severity = foldl' (f i) (severity i) $ filter isClassify xs}     where
src/CmdLine.hs view
@@ -35,10 +35,11 @@     ,cmdColor :: Bool                -- ^ color the result     ,cmdCpp :: CppFlags              -- ^ options for CPP     ,cmdDataDir :: FilePath          -- ^ the data directory-    ,cmdEncoding :: Encoding           -- ^ the text encoding+    ,cmdEncoding :: Encoding         -- ^ the text encoding     ,cmdFindHints :: [FilePath]      -- ^ source files to look for hints in     ,cmdLanguage :: [Extension]      -- ^ the extensions (may be prefixed by "No")     ,cmdQuiet :: Bool                -- ^ supress all console output+    ,cmdCross :: Bool                -- ^ work between source files     }  @@ -59,6 +60,7 @@           | FindHints FilePath           | Language String           | Quiet+          | Cross             deriving Eq  @@ -73,6 +75,7 @@        ,Option "X" ["language"] (ReqArg Language "lang") "Language extensions (Arrows, NoCPP)"        ,Option "u" ["utf8"] (NoArg $ Encoding "UTF-8") "Use UTF-8 text encoding"        ,Option ""  ["encoding"] (ReqArg Encoding "encoding") "Choose the text encoding"+       ,Option "x" ["cross"] (NoArg Cross) "Work between modules"        ,Option "f" ["find"] (ReqArg FindHints "file") "Find hints in a Haskell file"        ,Option "t" ["test"] (NoArg Test) "Run in test mode"        ,Option "d" ["datadir"] (ReqArg DataDir "dir") "Override the data directory"@@ -137,6 +140,7 @@         ,cmdFindHints = findHints         ,cmdLanguage = languages         ,cmdQuiet = Quiet `elem` opt+        ,cmdCross = Cross `elem` opt         }  
src/HLint.hs view
@@ -67,7 +67,10 @@     settings3 <- return [Classify Ignore x ("","") | x <- cmdIgnore]     let settings = settings1 ++ settings2 ++ settings3 -    ideas <- fmap concat $ parallel [listM' =<< applyHint flags settings x | x <- fromMaybe [] cmdFiles]+    let files = fromMaybe [] cmdFiles+    ideas <- if cmdCross+        then applyHintFiles flags settings files+        else fmap concat $ parallel [listM' =<< applyHintFile flags settings x | x <- files]     let (showideas,hideideas) = partition (\i -> cmdShowAll || severity i /= Ignore) ideas     showItem <- if cmdColor then showANSI else return show     mapM_ (outStrLn . showItem) showideas
src/HSE/All.hs view
@@ -1,23 +1,20 @@  module HSE.All(-    module HSE.Util, module HSE.Evaluate,-    module HSE.Bracket, module HSE.Match,-    module HSE.Type,-    module HSE.NameMatch,+    module X,     ParseFlags(..), parseFlags, parseFlagsNoLocations,     parseFile, parseString, parseResult     ) where +import HSE.Util as X+import HSE.Evaluate as X+import HSE.Type as X+import HSE.Bracket as X+import HSE.Match as X+import HSE.NameMatch as X import Util import CmdLine import Data.List import Data.Maybe-import HSE.Util-import HSE.Evaluate-import HSE.Type-import HSE.Bracket-import HSE.Match-import HSE.NameMatch import Language.Preprocessor.Cpphs  @@ -52,7 +49,7 @@         mode = defaultParseMode             {parseFilename = file             ,extensions = language flags-            ,fixities = []+            ,fixities = Nothing             ,ignoreLinePragmas = False             } 
src/HSE/Util.hs view
@@ -7,7 +7,7 @@ import Data.Maybe import System.FilePath import HSE.Type-import Language.Haskell.Exts.Annotated.Simplify(sOp, sAssoc)+import Language.Haskell.Exts.Annotated.Simplify(sQName, sAssoc)   ---------------------------------------------------------------------@@ -302,5 +302,7 @@ -- FIXITIES  getFixity :: Decl a -> [Fixity]-getFixity (InfixDecl _ a mp ops) = [Fixity (sAssoc a) (fromMaybe 9 mp) (sOp op) | op <- ops]+getFixity (InfixDecl sl a mp ops) = [Fixity (sAssoc a) (fromMaybe 9 mp) (sQName $ UnQual sl $ f op) | op <- ops]+    where f (VarOp _ x) = x+          f (ConOp _ x) = x getFixity _ = []
src/Hint/All.hs view
@@ -23,19 +23,22 @@  staticHints :: [(String,Hint)] staticHints =-    let x*y = (x,DeclHint y) ; x+y = (x,ModuHint y) in-    ["List"       * listHint-    ,"ListRec"    * listRecHint-    ,"Monad"      * monadHint-    ,"Lambda"     * lambdaHint-    ,"Bracket"    * bracketHint-    ,"Naming"     * namingHint-    ,"Structure"  * structureHint+    ["List"       ! listHint+    ,"ListRec"    ! listRecHint+    ,"Monad"      ! monadHint+    ,"Lambda"     ! lambdaHint+    ,"Bracket"    ! bracketHint+    ,"Naming"     ! namingHint+    ,"Structure"  ! structureHint     ,"Import"     + importHint     ,"Pragma"     + pragmaHint     ,"Extensions" + extensionsHint-    ,"Duplicate"  + duplicateHint+    ,"Duplicate"  * duplicateHint     ]+    where+        x!y = (x,DeclHint y)+        x+y = (x,ModuHint y)+        x*y = (x,CrossHint y)  dynamicHints :: [Setting] -> Hint dynamicHints = DeclHint . readMatch
src/Hint/Duplicate.hs view
@@ -24,10 +24,11 @@ import qualified Data.Map as Map  -duplicateHint :: ModuHint-duplicateHint _ modu =+duplicateHint :: CrossHint+duplicateHint ms =     dupes [y | Do _ y :: Exp S <- universeBi modu] ++     dupes [y | BDecls l y :: Binds S <- universeBi modu]+    where modu = map snd ms   dupes ys =
src/Hint/Extensions.hs view
@@ -27,6 +27,8 @@ record field = Record{..} {-# LANGUAGE RecordWildCards #-} \ record = 1 --+{-# LANGUAGE UnboxedTuples #-} \+record = 1 -- </TEST> -} @@ -55,7 +57,7 @@  minimalExtensions :: Module_ -> [Extension] -> [Extension] minimalExtensions x es = nub $ concatMap f es-    where f e = if used e x then [e] else []+    where f e = [e | used e x]   -- RecordWildCards implies DisambiguateRecordFields, but most people probably don't want it
src/Hint/List.hs view
@@ -17,6 +17,7 @@ yes = if x == e then l2 ++ xs else [x] ++ check_elem xs -- x : check_elem xs data Yes = Yes (Maybe [Char]) -- Maybe String yes = y :: [Char] -> a -- String -> a+instance C [Char] </TEST> -} @@ -30,8 +31,7 @@ listHint _ _ = listDecl  listDecl :: Decl_ -> [Idea]-listDecl x = concatMap (listExp False) (childrenBi x) ++-             concatMap stringType (childrenBi x)+listDecl x = concatMap (listExp False) (childrenBi x) ++ stringType x  -- boolean = are you in a ++ chain listExp :: Bool -> Exp_ -> [Idea]@@ -76,6 +76,13 @@ typeString = TyCon an (toNamed "String")  -stringType :: Type_ -> [Idea]-stringType (fromTyParen -> x) = [warn "Use String" x (transform f x) | any (=~= typeListChar) $ universe x]-    where f x = if x =~= typeListChar then typeString else x+stringType :: Decl_ -> [Idea]+stringType x = case x of+    InstDecl _ _ _ x -> f x+    _ -> f x+    where+        f x = concatMap g $ childrenBi x++        g :: Type_ -> [Idea]+        g (fromTyParen -> x) = [warn "Use String" x (transform f x) | any (=~= typeListChar) $ universe x]+            where f x = if x =~= typeListChar then typeString else x
src/Hint/Type.hs view
@@ -7,5 +7,8 @@  type DeclHint = Scope -> Module_ -> Decl_ -> [Idea] type ModuHint = Scope -> Module_          -> [Idea]+type CrossHint = [(Scope, Module_)] -> [Idea] -data Hint = DeclHint {declHint :: DeclHint} | ModuHint {moduHint :: ModuHint}+data Hint = DeclHint {declHint :: DeclHint}+          | ModuHint {moduHint :: ModuHint}+          | CrossHint {crossHint :: CrossHint}
src/Test.hs view
@@ -138,7 +138,7 @@     return $ Result (length failures) (length tests)     where         f (Test loc inp out) = do-            ideas <- applyHintStr parseFlags setting file inp+            ideas <- applyHintString parseFlags setting file inp             let good = case out of                     Nothing -> null ideas                     Just x -> length ideas == 1 &&@@ -201,7 +201,7 @@         else error "checkInputOutput, couldn't find or figure out flags"      got <- fmap (fmap lines) $ captureOutput $-        handle (\(e::SomeException) -> print $ e) $+        handle (\(e::SomeException) -> print e) $         handle (\(e::ExitCode) -> return ()) $         main flags     want <- fmap lines $ reader "output"
src/Util.hs view
@@ -81,6 +81,8 @@ unzipEither [] = ([], [])  +for = flip map+ --------------------------------------------------------------------- -- DATA.STRING