packages feed

hlint 2.0.2 → 2.0.3

raw patch · 15 files changed

+91/−46 lines, 15 filesdep ~cpphsPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: cpphs

API changes (from Hackage documentation)

Files

CHANGES.txt view
@@ -1,5 +1,10 @@ Changelog for HLint +2.0.3+    #312, suggest removing the DeriveAnyClass extension+    Suggest removing the DeriveLift extension+    Remove redundant parts from list comprehensions, e.g. [a | True]+    #326, fix up the bounds on the eta-reduce hint 2.0.2     #323, try and avoid malformatted JSON     #324, use `backticks` in notes
hlint.cabal view
@@ -1,7 +1,7 @@ cabal-version:      >= 1.18 build-type:         Simple name:               hlint-version:            2.0.2+version:            2.0.3 license:            BSD3 license-file:       LICENSE category:           Development@@ -56,10 +56,6 @@         ansi-terminal >= 0.6.2,         extra >= 1.4.9,         refact >= 0.3--    -- Workaround for https://github.com/malcolmwallace/cpphs/issues/9-    if impl(ghc < 7.6)-        build-depends: cpphs < 1.20.4      if flag(gpl)         build-depends: hscolour >= 1.21
src/HSE/Match.hs view
@@ -3,7 +3,7 @@ module HSE.Match(     View(..), Named(..),     (~=), isSym,-    App2(..), PVar_(..), Var_(..), PApp_(..)+    App2(App2), PVar_(PVar_), Var_(Var_), PApp_(PApp_)     ) where  import Data.Char
src/HSE/Util.hs view
@@ -87,7 +87,6 @@ isCon Con{} = True; isCon _ = False isApp App{} = True; isApp _ = False isInfixApp InfixApp{} = True; isInfixApp _ = False-isList List{} = True; isList _ = False isAnyApp x = isApp x || isInfixApp x isParen Paren{} = True; isParen _ = False isIf If{} = True; isIf _ = False@@ -283,9 +282,6 @@     where f (x:y:zs) | isPathSeparator x && isPathSeparator y = f $ x:zs           f (x:xs) = x : f xs           f [] = []--toSrcSpan :: SrcSpanInfo -> SrcSpan-toSrcSpan (SrcSpanInfo x _) = x  nullSrcLoc :: SrcLoc nullSrcLoc = SrcLoc "" 0 0
src/Hint/Duplicate.hs view
@@ -37,7 +37,7 @@         "Reduce duplication" p1         (unlines $ map (prettyPrint . fmap (const p1)) xs)         (Just $ "Combine with " ++ showSrcLoc (getPointLoc p2)) []-    | (p1,p2,xs) <- duplicateOrdered 3 $ map (map (toSrcSpan . ann &&& dropAnn)) ys]+    | (p1,p2,xs) <- duplicateOrdered 3 $ map (map (srcInfoSpan . ann &&& dropAnn)) ys]   ---------------------------------------------------------------------
src/Hint/Extensions.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE RecordWildCards #-} {-     Suggest removal of unnecessary extensions     i.e. They have {-# LANGUAGE RecursiveDo #-} but no mdo keywords@@ -91,6 +92,12 @@ main = "test" {-# LANGUAGE OverloadedStrings #-} \ main = id --+{-# LANGUAGE DeriveAnyClass #-} \+main = id --+{-# LANGUAGE DeriveAnyClass #-} \+data Foo = Foo deriving Bob+{-# LANGUAGE DeriveAnyClass #-} \+data Foo a = Foo a deriving (Eq,Data,Functor) -- </TEST> -} @@ -102,10 +109,12 @@ import Data.List.Extra import Data.Ratio import Refact.Types+import Data.Monoid+import Prelude   extensionsHint :: ModuHint-extensionsHint _ x = [rawIdea Warning "Unused LANGUAGE pragma" (toSrcSpan sl)+extensionsHint _ x = [rawIdea Warning "Unused LANGUAGE pragma" (srcInfoSpan sl)           (prettyPrint o) (Just newPragma)           (warnings old new) [refact]     | not $ used TemplateHaskell x -- if TH is on, can use all other extensions programmatically@@ -128,14 +137,26 @@ warnings _ _ = []  --- | Classes that don't work with newtype deriving-noNewtypeDeriving :: [String]-noNewtypeDeriving = ["Read","Show","Data","Typeable","Generic","Generic1"]+deriveHaskell = ["Eq","Ord","Enum","Ix","Bounded","Read","Show"]+deriveGenerics = ["Data","Typeable","Generic","Generic1","Lift"]+deriveCategory = ["Functor","Foldable","Traversable"] +-- | Classes that can't require newtype deriving+noGeneralizedNewtypeDeriving =+    delete "Enum" deriveHaskell ++ -- Enum can't always be derived on a newtype+    deriveGenerics -- Generics stuff can't newtype derive since it has the ctor in it +-- | Classes that can't require DeriveAnyClass+noDeriveAnyClass = deriveHaskell ++ deriveGenerics ++ deriveCategory++ usedExt :: Extension -> Module_ -> Bool usedExt (EnableExtension x) = used x usedExt (UnknownExtension "NumDecimals") = hasS isWholeFrac+usedExt (UnknownExtension "DeriveLift") = hasDerive ["Lift"]+usedExt (UnknownExtension "DeriveAnyClass") =+    any (`notElem` noDeriveAnyClass) .+    (\Derives{..} -> derivesNewType ++ derivesData) . derives usedExt _ = const True  @@ -175,7 +196,9 @@ used DeriveFoldable = hasDerive ["Foldable"] used DeriveTraversable = hasDerive ["Traversable"] used DeriveGeneric = hasDerive ["Generic","Generic1"]-used GeneralizedNewtypeDeriving = any (`notElem` noNewtypeDeriving) . fst . derives+used GeneralizedNewtypeDeriving =+    any (`notElem` noGeneralizedNewtypeDeriving) .+    (\Derives{..} -> derivesNewType ++ derivesStandalone) . derives used LambdaCase = hasS isLCase used TupleSections = hasS isTupleSection used OverloadedStrings = hasS isString@@ -195,30 +218,39 @@   hasDerive :: [String] -> Module_ -> Bool-hasDerive want m = any (`elem` want) $ new ++ dat-    where (new,dat) = derives m+hasDerive want m = any (`elem` want) $ derivesNewType ++ derivesData ++ derivesStandalone+    where Derives{..} = derives m  +data Derives = Derives+    {derivesNewType :: [String]+    ,derivesData :: [String]+    ,derivesStandalone :: [String]+    }+instance Monoid Derives where+    mempty = Derives [] [] []+    mappend (Derives x1 x2 x3) (Derives y1 y2 y3) =+        Derives (x1++y1) (x2++y2) (x3++y3)+ -- | What is derived on newtype, and on data type --   'deriving' declarations may be on either, so we approximate as both newtype and data-derives :: Module_ -> ([String],[String])-derives m = concatUnzip $ map decl (childrenBi m) ++ map idecl (childrenBi m)+derives :: Module_ -> Derives+derives m = mconcat $ map decl (childrenBi m) ++ map idecl (childrenBi m)     where-        idecl :: InstDecl S -> ([String], [String])+        idecl :: InstDecl S -> Derives         idecl (InsData _ dn _ _ ds) = g dn ds         idecl (InsGData _ dn _ _ _ ds) = g dn ds-        idecl _ = ([], [])+        idecl _ = mempty -        decl :: Decl_ -> ([String], [String])+        decl :: Decl_ -> Derives         decl (DataDecl _ dn _ _ _ ds) = g dn ds         decl (GDataDecl _ dn _ _ _ _ ds) = g dn ds         decl (DataInsDecl _ dn _ _ ds) = g dn ds         decl (GDataInsDecl _ dn _ _ _ ds) = g dn ds-        decl (DerivDecl _ _ hd) = (xs, xs) -- don't know whether this was on newtype or not-            where xs = [ir hd]-        decl _ = ([], [])+        decl (DerivDecl _ _ hd) = mempty{derivesStandalone=[ir hd]}+        decl _ = mempty -        g dn ds = if isNewType dn then (xs,[]) else ([],xs)+        g dn ds = if isNewType dn then mempty{derivesNewType=xs} else mempty{derivesData=xs}             where xs = maybe [] (map ir . fromDeriving) ds          ir (IRule _ _ _ x) = ih x
src/Hint/Import.hs view
@@ -56,7 +56,7 @@   wrap :: [ImportDecl S] -> [Idea]-wrap o = [ rawIdea Warning "Use fewer imports" (toSrcSpan $ ann $ head o) (f o) (Just $ f x) [] rs+wrap o = [ rawIdea Warning "Use fewer imports" (srcInfoSpan $ ann $ head o) (f o) (Just $ f x) [] rs          | Just (x, rs) <- [simplify o]]     where f = unlines . map prettyPrint @@ -131,7 +131,7 @@ -- import IO is equivalent to -- import System.IO, import System.IO.Error, import Control.Exception(bracket, bracket_) hierarchy i@ImportDecl{importModule=ModuleName _ "IO", importSpecs=Nothing,importPkg=Nothing}-    = [rawIdeaN Suggestion "Use hierarchical imports" (toSrcSpan $ ann i) (trimStart $ prettyPrint i) (+    = [rawIdeaN Suggestion "Use hierarchical imports" (srcInfoSpan $ ann i) (trimStart $ prettyPrint i) (           Just $ unlines $ map (trimStart . prettyPrint)           [f "System.IO" Nothing, f "System.IO.Error" Nothing           ,f "Control.Exception" $ Just $ ImportSpecList an False [IVar an $ toNamed x | x <- ["bracket","bracket_"]]]) []]
src/Hint/Lambda.hs view
@@ -85,7 +85,7 @@   lambdaDecl :: Decl_ -> [Idea]-lambdaDecl (toFunBind -> o@(FunBind loc [Match _ name pats (UnGuardedRhs _ bod) bind]))+lambdaDecl (toFunBind -> o@(FunBind loc1 [Match _ name pats (UnGuardedRhs loc2 bod) bind]))     | isNothing bind, isLambda $ fromParen bod, null (universeBi pats :: [Exp_]) =       [warn "Redundant lambda" o (gen pats bod) [Replace Decl (toSS o) s1 t1]]     | length pats2 < length pats, pvars (drop (length pats2) pats) `disjoint` varss bind@@ -94,6 +94,7 @@               -- Replace Decl (toSS $ reform pats bod) s2 t2]]             ]]         where reform p b = FunBind loc [Match an name p (UnGuardedRhs an b) Nothing]+              loc = setSpanInfoEnd loc1 $ srcSpanEnd $ srcInfoSpan loc2               gen ps = uncurry reform . fromLambda . Lambda an ps               (finalpats, body) = fromLambda . Lambda an pats $ bod               (pats2, bod2) = etaReduce pats bod@@ -108,6 +109,8 @@               --t2 = template pats2 bod2  lambdaDecl _ = []++setSpanInfoEnd ssi (line, col) = ssi{srcInfoSpan = (srcInfoSpan ssi){srcSpanEndLine=line, srcSpanEndColumn=col}}   etaReduce :: [Pat_] -> Exp_ -> ([Pat_], Exp_)
src/Hint/List.hs view
@@ -21,14 +21,16 @@ yes = y :: [Char] -> a -- String -> a instance C [Char] foo = [a b] ++ xs -- a b : xs+foo = [myexpr | True, a] -- [myexpr | a]+foo = [myexpr | False] -- [] </TEST> -} - module Hint.List(listHint) where  import Control.Applicative import Hint.Type+import Data.Maybe import Prelude import Refact.Types @@ -37,8 +39,23 @@ listHint _ _ = listDecl  listDecl :: Decl_ -> [Idea]-listDecl x = concatMap (listExp False) (childrenBi x) ++ stringType x ++ concatMap listPat (childrenBi x)+listDecl x =+    concatMap (listExp False) (childrenBi x) +++    stringType x +++    concatMap listPat (childrenBi x) +++    concatMap listComp (universeBi x) +listComp :: Exp_ -> [Idea]+listComp o@(ListComp a e xs)+    | "False" `elem` cons = [suggest "Short-circuited list comprehension" o (List an []) []]+    | "True" `elem` cons = [suggest "Redundant True guards" o o2 []]+    where+        o2 = ListComp a e $ filter ((/= Just "True") . qualCon) xs+        cons = mapMaybe qualCon xs+        qualCon (QualStmt _ (Qualifier _ (Con _ x))) = Just $ fromNamed x+        qualCon _ = Nothing+listComp _ = []+ -- boolean = are you in a ++ chain listExp :: Bool -> Exp_ -> [Idea] listExp b (fromParen -> x) =@@ -140,5 +157,4 @@         g e@(fromTyParen -> x) = [suggest "Use String" x (transform f x)                                     rs | not . null $ rs]             where f x = if x =~= typeListChar then typeString else x-                  toSS = toRefactSrcSpan . toSrcSpan . ann                   rs = [Replace Type (toSS t) [] (prettyPrint typeString) | t <- universe x, t =~= typeListChar]
src/Hint/Pattern.hs view
@@ -102,7 +102,7 @@           template = fromMaybe "" $ ideaTo (gen "" (Pattern l rtype (map toString patSubts) (GuardedRhss d templateGuards) bind) [])           f :: [Either a (String, R.SrcSpan)] -> [(String, R.SrcSpan)]           f = rights-          refactoring = Replace rtype (toRefactSrcSpan . toSrcSpan $ l) (f patSubts ++ f guardSubts ++ f exprSubts) template+          refactoring = Replace rtype (toRefactSrcSpan $ srcInfoSpan l) (f patSubts ++ f guardSubts ++ f exprSubts) template  {- -- Do not suggest view patterns, they aren't something everyone likes sufficiently
src/Hint/Pragma.hs view
@@ -68,16 +68,16 @@ pragmaIdea pidea =   case pidea of     SingleComment old new ->-      mkIdea (toSrcSpan . ann $ old)+      mkIdea (srcInfoSpan . ann $ old)         (prettyPrint old) (Just $ prettyPrint new) []         [ModifyComment (toSS old) (prettyPrint new)]     MultiComment repl delete new ->-      mkIdea (toSrcSpan . ann $ repl)+      mkIdea (srcInfoSpan . ann $ repl)         (f [repl, delete]) (Just $ prettyPrint new) []         [ ModifyComment (toSS repl) (prettyPrint new)         , ModifyComment (toSS delete) ""]     OptionsToComment old new r ->-      mkIdea (toSrcSpan . ann . head $ old)+      mkIdea (srcInfoSpan . ann . head $ old)         (f old) (Just $ f new) []         r     where
src/Hint/Unsafe.hs view
@@ -25,7 +25,7 @@  unsafeHint :: ModuHint unsafeHint _ m =-        [ rawIdea Warning "Missing NOINLINE pragma" (toSrcSpan $ ann d)+        [ rawIdea Warning "Missing NOINLINE pragma" (srcInfoSpan $ ann d)             (prettyPrint d)             (Just $ dropWhile isSpace (prettyPrint $ gen x) ++ "\n" ++ prettyPrint d)             [] [InsertComment (toSS d) (prettyPrint $ gen x)]
src/Hint/Util.hs view
@@ -37,7 +37,7 @@     (apps e2, \s -> [Replace Expr s [("x", pos)] "x"])     where (e',xs') = splitAt (length e - length xs) e           (e2, xs2) = (map fst e', map fst xs')-          pos      = toRefactSrcSpan . toSrcSpan $ snd (last e')+          pos      = toRefactSrcSpan . srcInfoSpan $ snd (last e')  -- \x y -> x + y ==> (+) niceLambdaR [x,y] (InfixApp _ (view -> Var_ x1) (opExp -> op) (view -> Var_ y1))@@ -71,7 +71,7 @@         factor _ = Nothing         mkRefact :: [S] -> R.SrcSpan -> Refactoring R.SrcSpan         mkRefact subts s =-          let tempSubts = zipWith (\a b -> ([a], toRefactSrcSpan . toSrcSpan $ b)) ['a' .. 'z'] subts+          let tempSubts = zipWith (\a b -> ([a], toRefactSrcSpan $ srcInfoSpan b)) ['a' .. 'z'] subts               template = dotApps (map (toNamed . fst) tempSubts)           in Replace Expr s tempSubts (prettyPrint template) 
src/Idea.hs view
@@ -3,7 +3,7 @@ module Idea(     Idea(..),     rawIdea, idea, suggest, warn, ignore,-    rawIdeaN, suggestN, warnN,+    rawIdeaN, suggestN,     showIdeasJson, showANSI,     Note(..), showNotes,     Severity(..)@@ -87,7 +87,7 @@ rawIdea = Idea "" "" rawIdeaN a b c d e f = Idea "" "" a b c d e f [] -idea severity hint from to = rawIdea severity hint (toSrcSpan $ ann from) (f from) (Just $ f to) []+idea severity hint from to = rawIdea severity hint (srcInfoSpan $ ann from) (f from) (Just $ f to) []     where f = trimStart . prettyPrint  suggest = idea Suggestion@@ -97,4 +97,3 @@ ideaN severity hint from to = idea severity hint from to []  suggestN = ideaN Suggestion-warnN = ideaN Warning
src/Refact.hs view
@@ -10,6 +10,4 @@                                (srcSpanEndColumn ss)  toSS :: Annotated a => a S -> R.SrcSpan-toSS = toRefactSrcSpan . toSrcSpan . ann--+toSS = toRefactSrcSpan . srcInfoSpan . ann