packages feed

hlint 2.1.24 → 2.1.25

raw patch · 8 files changed

+89/−9 lines, 8 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

CHANGES.txt view
@@ -1,5 +1,12 @@ Changelog for HLint (* = breaking change) +2.1.25, released 2019-06-26+    #681, fix for extensions on the command line not being used+    #686, suggest head (drop n x) ==> x !! max 0 n+    #683, add Use DerivingStrategies hint, ignored by default+    #685, skip running refactoring tool if there are no hints+    #675, warn about redundant fmaps on Eithers and Maybes+    Add back two $ hints removed in error 2.1.24, released 2019-06-10     Add Language.Haskell.HLint4     #658, ignore the previously undocumented {- LINT -} comments
data/hlint.yaml view
@@ -128,6 +128,7 @@     - warn: {lhs: "cycle [x]", rhs: repeat x}     - warn: {lhs: head (reverse x), rhs: last x}     - warn: {lhs: head (drop n x), rhs: x !! n, side: isNat n}+    - warn: {lhs: head (drop n x), rhs: x !! max 0 n, side: not (isNat n) && not (isNeg n)}     - warn: {lhs: reverse (tail (reverse x)), rhs: init x, note: IncreasesLaziness}     - warn: {lhs: reverse (reverse x), rhs: x, note: IncreasesLaziness, name: Avoid reverse}     - warn: {lhs: isPrefixOf (reverse x) (reverse y), rhs: isSuffixOf x y}@@ -264,6 +265,8 @@     - hint: {lhs: "\\x y -> f (x,y)", rhs: curry f}     - hint: {lhs: "\\(x,y) -> f x y", rhs: uncurry f, note: IncreasesLaziness}     - warn: {lhs: f (fst p) (snd p), rhs: uncurry f p}+    - warn: {lhs: ($) . f, rhs: f, name: Redundant $}+    - warn: {lhs: (f $), rhs: f, name: Redundant $}     - warn: {lhs: (Data.Function.& f), rhs: f, name: Redundant Data.Function.&}     - hint: {lhs: \x -> y, rhs: const y, side: isAtom y && not (isWildcard y)}         # If any isWildcard recursively then x may be used but not mentioned explicitly@@ -443,6 +446,7 @@     # LIST COMP      - hint: {lhs: "if b then [x] else []", rhs: "[x | b]", name: Use list comprehension}+    - hint: {lhs: "if b then [] else [x]", rhs: "[x | not b]", name: Use list comprehension}     - hint: {lhs: "[x | x <- y]", rhs: "y", side: isVar x, name: Redundant list comprehension}      # SEQ@@ -497,12 +501,22 @@     - hint: {lhs: maybe Nothing id, rhs: join}     - hint: {lhs: maybe Nothing f x, rhs: f =<< x}     - hint: {lhs: maybe (f x) (f . g), rhs: f . maybe x g, note: IncreasesLaziness, name: Too strict maybe}+    - warn: {lhs: maybe x f (fmap g y), rhs: maybe x (f . g) y, name: Redundant fmap}+    - warn: {lhs: isJust (fmap f x), rhs: isJust x}+    - warn: {lhs: isNothing (fmap f x), rhs: isNothing x}+    - warn: {lhs: fromJust (fmap f x), rhs: f (fromJust x)}+    - warn: {lhs: mapMaybe f (fmap g x), rhs: mapMaybe (f . g) x, name: Redundant fmap}      # EITHER      - warn: {lhs: "[a | Left a <- a]", rhs: lefts a}     - warn: {lhs: "[a | Right a <- a]", rhs: rights a}     - warn: {lhs: either Left (Right . f), rhs: fmap f}+    - warn: {lhs: either f g (fmap h x), rhs: either f (g . h) x, name: Redundant fmap}+    - warn: {lhs: isLeft (fmap f x), rhs: isLeft x}+    - warn: {lhs: isRight (fmap f x), rhs: isRight x}+    - warn: {lhs: fromLeft x (fmap f y), rhs: fromLeft x y}+    - warn: {lhs: fromRight x (fmap f y), rhs: either (const x) f y}      # INFIX @@ -759,6 +773,8 @@     rules:     - hint: {lhs: "x /= []", rhs: not (null x), name: Use null}     - hint: {lhs: "[] /= x", rhs: not (null x), name: Use null}+    - hint: {lhs: "not (x || y)", rhs: "not x && not y", name: Apply De Morgan law}+    - hint: {lhs: "not (x && y)", rhs: "not x || not y", name: Apply De Morgan law}   # <TEST>@@ -857,7 +873,7 @@ # fooer input = catMaybes . map Just $ input -- mapMaybe Just # yes = mapMaybe id -- catMaybes # main = print $ map (\_->5) [2,3,5] -- const 5-# main = head $ drop n x+# main = head $ drop n x -- x !! max 0 n # main = head $ drop (-3) x -- x # main = head $ drop 2 x -- x !! 2 # main = drop 0 x -- x
hlint.cabal view
@@ -1,7 +1,7 @@ cabal-version:      >= 1.18 build-type:         Simple name:               hlint-version:            2.1.24+version:            2.1.25 license:            BSD3 license-file:       LICENSE category:           Development
src/GHC/Util.hs view
@@ -11,6 +11,7 @@   , getMessages   , SDoc   , Located+  , hseToGhcExtension   -- Temporary : Export these so GHC doesn't consider them unused and   -- tell weeder to ignore them.   , isAtom, addParen, paren, isApp, isOpApp, isAnyApp, isDot, isSection, isDotApp@@ -38,6 +39,8 @@ import Data.List import System.FilePath import Language.Preprocessor.Unlit+import qualified Language.Haskell.Exts.Extension as HSE+import qualified Data.Map.Strict as Map  fakeSettings :: Settings fakeSettings = Settings@@ -83,13 +86,21 @@ baseDynFlags = foldl' xopt_set              (defaultDynFlags fakeSettings fakeLlvmConfig) enabledExtensions -parsePragmasIntoDynFlags ::-  DynFlags -> FilePath -> String -> IO (Either String DynFlags)-parsePragmasIntoDynFlags flags filepath str =+-- | Adjust the input 'DynFlags' to take into account language+-- extensions to explicitly enable/disable as well as language+-- extensions enabled by pragma in the source.+parsePragmasIntoDynFlags :: DynFlags+                         -> ([Extension], [Extension])+                         -> FilePath+                         -> String+                         -> IO (Either String DynFlags)+parsePragmasIntoDynFlags flags (enable, disable) filepath str =   catchErrors $ do     let opts = getOptions flags (stringToStringBuffer str) filepath     (flags, _, _) <- parseDynamicFilePragma flags opts-    return $ Right flags+    let flags' =  foldl' xopt_set flags enable+    let flags'' = foldl' xopt_unset flags' disable+    return $ Right flags''   where     catchErrors :: IO (Either String DynFlags) -> IO (Either String DynFlags)     catchErrors act = handleGhcException reportErr@@ -195,3 +206,12 @@ isDotApp :: HsExpr GhcPs -> Bool isDotApp (OpApp _ _ (L _ op) _) = isDot op isDotApp _ = False++-- | A mapping from 'HSE.KnownExtension' values to their+-- 'GHC.LanguageExtensions.Type.Extension' equivalents.+hseToGhcExtension :: Map.Map HSE.KnownExtension Extension+hseToGhcExtension =+  let ghcExts = Map.fromList [(show x, x) | x <- [Cpp .. StarIsType]]+  in+    Map.fromList [ (x, ext) | x <- [minBound .. maxBound]+                 , Just ext <- [Map.lookup (show x) ghcExts] ]
src/HLint.hs view
@@ -205,6 +205,7 @@         else ideas  handleRefactoring :: [Idea] -> [String] -> Cmd -> IO ()+handleRefactoring [] _ _ = pure () -- No refactorings to apply handleRefactoring ideas files cmd@CmdMain{..} =     case cmdFiles of         [file] -> do
src/HSE/All.hs view
@@ -24,6 +24,7 @@ import Data.Maybe import Timing import Language.Preprocessor.Cpphs+import Data.Either import Data.Set (Set) import qualified Data.Map as Map import qualified Data.Set as Set@@ -37,6 +38,7 @@ import qualified "ghc-lib-parser" SrcLoc as GHC import qualified "ghc-lib-parser" ErrUtils import qualified "ghc-lib-parser" Outputable+import qualified "ghc-lib-parser" GHC.LanguageExtensions.Type as GHC  vars :: FreeVars a => a -> [String] freeVars :: FreeVars a => a -> Set String@@ -229,6 +231,17 @@                ErrUtils.pprLocErrMsg (ErrUtils.mkPlainErrMsg baseDynFlags loc err)    return $ Left $ ParseError sl msg pe +-- | Produce a pair of lists from a 'ParseFlags' value representing+-- language extensions to explicitly enable/disable.+ghcExtensionsFromParseFlags :: ParseFlags+                             -> ([GHC.Extension], [GHC.Extension])+ghcExtensionsFromParseFlags ParseFlags {hseFlags=ParseMode {extensions=exts}}=+   partitionEithers $ mapMaybe toEither exts+   where+     toEither ke = case ke of+       EnableExtension e  -> Left  <$> Map.lookup e hseToGhcExtension+       DisableExtension e -> Right <$> Map.lookup e hseToGhcExtension+ -- | Parse a Haskell module. Applies the C pre processor, and uses -- best-guess fixity resolution if there are ambiguities.  The -- filename @-@ is treated as @stdin@. Requires some flags (often@@ -242,7 +255,8 @@                     | otherwise -> readFileUTF8' file         str <- return $ fromMaybe str $ stripPrefix "\65279" str -- remove the BOM if it exists, see #130         ppstr <- runCpp (cppFlags flags) file str-        dynFlags <- parsePragmasIntoDynFlags baseDynFlags file ppstr+        let enableDisableExts = ghcExtensionsFromParseFlags flags+        dynFlags <- parsePragmasIntoDynFlags baseDynFlags enableDisableExts file ppstr         case dynFlags of           Right ghcFlags ->             case (parseFileContentsWithComments (mkMode flags file) ppstr, parseFileGhcLib file ppstr ghcFlags) of
src/Hint/NewType.hs view
@@ -19,6 +19,9 @@ data A = A Int# {-# LANGUAGE UnboxedTuples #-}; data WithAnn x = WithAnn (# Ann, x #) data A = A () -- newtype A = A ()+newtype Foo = Foo Int deriving (Show, Eq) -- newtype Foo = Foo Int deriving newtype (Show, Eq)+newtype Foo = Foo { getFoo :: Int } deriving (Show, Eq) -- newtype Foo = Foo { getFoo :: Int } deriving newtype (Show, Eq)+newtype Foo = Foo Int deriving stock Show </TEST> -} module Hint.NewType (newtypeHint) where@@ -26,7 +29,7 @@ import Hint.Type  newtypeHint :: DeclHint-newtypeHint _ _ = newtypeHintDecl+newtypeHint _ _ x = newtypeHintDecl x ++ newTypeDerivingStrategiesHintDecl x  newtypeHintDecl :: Decl_ -> [Idea] newtypeHintDecl x@@ -44,3 +47,21 @@         f (RecDecl x1 x2 [FieldDecl y1 [y2] t]) = Just (t, \t -> RecDecl x1 x2 [FieldDecl y1 [y2] t])         f _ = Nothing singleSimpleField _ = Nothing++newTypeDerivingStrategiesHintDecl :: Decl_ -> [Idea]+newTypeDerivingStrategiesHintDecl x = [ignoreN "Use DerivingStrategies" x new | Just new <- [newtypeDecl x]]++newtypeDecl :: Decl_ -> Maybe Decl_+newtypeDecl (DataDecl x1 x2@(NewType _) x3 x4 x5 x6)+    | any hasNoStrategy x6 = Just $ DataDecl x1 x2 x3 x4 x5 (withNewtype <$> x6)+newtypeDecl (GDataDecl x1 x2@(NewType _) x3 x4 x5 x6 x7)+    | any hasNoStrategy x7 = Just $ GDataDecl x1 x2 x3 x4 x5 x6 (withNewtype <$> x7)+newtypeDecl _ = Nothing++hasNoStrategy :: Deriving a -> Bool+hasNoStrategy (Deriving _ Nothing _) = True+hasNoStrategy _                      = False++withNewtype :: Deriving a -> Deriving a+withNewtype (Deriving l Nothing rs)  = Deriving l (Just $ DerivNewtype l) rs+withNewtype d                        = d
src/Idea.hs view
@@ -3,7 +3,7 @@ module Idea(     Idea(..),     rawIdea, idea, suggest, warn, ignore,-    rawIdeaN, suggestN,+    rawIdeaN, suggestN, ignoreN,     showIdeasJson, showANSI,     Note(..), showNotes,     Severity(..)@@ -92,3 +92,4 @@ ideaN severity hint from to = idea severity hint from to []  suggestN = ideaN Suggestion+ignoreN = ideaN Ignore