packages feed

hlint 2.1.6 → 2.1.7

raw patch · 14 files changed

+67/−163 lines, 14 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Language.Haskell.HLint3: Hint :: ([Setting] -> [(Scope, Module SrcSpanInfo)] -> [Idea]) -> ([Setting] -> Scope -> Module SrcSpanInfo -> [Idea]) -> ([Setting] -> Scope -> Module SrcSpanInfo -> Decl SrcSpanInfo -> [Idea]) -> ([Setting] -> Comment -> [Idea]) -> Hint
+ Language.Haskell.HLint3: Hint :: [Setting] -> [(Scope, Module SrcSpanInfo)] -> [Idea] -> [Setting] -> Scope -> Module SrcSpanInfo -> [Idea] -> [Setting] -> Scope -> Module SrcSpanInfo -> Decl SrcSpanInfo -> [Idea] -> [Setting] -> Comment -> [Idea] -> Hint

Files

CHANGES.txt view
@@ -1,5 +1,20 @@ Changelog for HLint (* = breaking change) +2.1.7, released 2018-07-03+    #483, don't break quasi quotes when suggesting const+    #404, remove the "Unnecessary hiding" hint introduced in #338+    #162, make avoiding lambda with `infix` give a different name+    #507, rename id x ==> x to redundant id+    #286, improve the duplicate pragma message+    #399, suggest (& f) ==> f+    #136, don't suggest eta-reducing runST+    #345, add catMaybes/fmap ==> mapMaybe+    #345, add foldMap id ==> fold+    #364, suggest >> instead of >>= \_ ->+    #502, DeriveTraversable implies DeriveFoldable and DeriveFunctor+    Add hints about fusing traverse/map+    Better names for mapM/map fusion hints and others+    #498, change the output to say "Perhaps:" rather than "Why not:" 2.1.6, released 2018-06-16     Match on explicit brackets at the root of a match expression     #470, suggest TupleSections
README.md view
@@ -16,6 +16,7 @@ * Some transformed programs may require additional type signatures, particularly if the transformations trigger the monomorphism restriction or involve rank-2 types. * The `RebindableSyntax` extension can cause HLint to suggest incorrect changes. * HLint turns on many language extensions so it can parse more documents, occasionally some break otherwise legal syntax - e.g. `{-#INLINE foo#-}` doesn't work with `MagicHash`, `foo $bar` means something different with `TemplateHaskell`. These extensions can be disabled with `-XNoMagicHash` or `-XNoTemplateHaskell` etc.+* HLint doesn't run any custom preprocessors, e.g. [markdown-unlit](https://hackage.haskell.org/package/markdown-unlit) or [record-dot-preprocessor](https://hackage.haskell.org/package/record-dot-preprocessor), so code making use of them will usually fail to parse.  ## Installing and running HLint @@ -29,19 +30,19 @@ darcs-2.1.2\src\CommandLine.lhs:94:1: Warning: Use concatMap Found:     concat $ map escapeC s-Why not:+Perhaps:     concatMap escapeC s  darcs-2.1.2\src\CommandLine.lhs:103:1: Suggestion: Use fewer brackets Found:     ftable ++ (map (\ (c, x) -> (toUpper c, urlEncode x)) ftable)-Why not:+Perhaps:     ftable ++ map (\ (c, x) -> (toUpper c, urlEncode x)) ftable  darcs-2.1.2\src\Darcs\Patch\Test.lhs:306:1: Warning: Use a more efficient monadic variant Found:     mapM (delete_line (fn2fp f) line) old-Why not:+Perhaps:     mapM_ (delete_line (fn2fp f) line) old  ... lots more hints ...
data/hlint.yaml view
@@ -95,7 +95,7 @@     - warn: {lhs: reverse (sortOn f x), rhs: sortOn (Data.Ord.Down . f) x, name: Avoid reverse}     - warn: {lhs: reverse (sort x), rhs: sortOn Data.Ord.Down x, name: Avoid reverse}     - hint: {lhs: flip (g `on` h), rhs: flip g `on` h, name: Move flip}-    - hint: {lhs: (f `on` g) `on` h, rhs: f `on` (g . h)}+    - hint: {lhs: (f `on` g) `on` h, rhs: f `on` (g . h), name: Fuse on/on}       # READ/SHOW@@ -153,7 +153,7 @@     - warn: {lhs: map (uncurry f) (zip x y), rhs: zipWith f x y}     - hint: {lhs: map f (zip x y), rhs: zipWith (curry f) x y, side: isVar f}     - warn: {lhs: not (elem x y), rhs: notElem x y}-    - hint: {lhs: foldr f z (map g x), rhs: foldr (f . g) z x}+    - hint: {lhs: foldr f z (map g x), rhs: foldr (f . g) z x, name: Fuse foldr/map}     - warn: {lhs: "x ++ concatMap (' ':) y", rhs: "unwords (x:y)"}     - warn: {lhs: intercalate " ", rhs: unwords}     - hint: {lhs: concat (intersperse x y), rhs: intercalate x y, side: notEq x " "}@@ -198,6 +198,7 @@     - warn: {lhs: sequence (fmap f x), rhs: traverse f x}     - warn: {lhs: sequenceA_ (map f x), rhs: traverse_ f x}     - warn: {lhs: sequenceA_ (fmap f x), rhs: traverse_ f x}+    - warn: {lhs: foldMap id, rhs: fold}      # BY @@ -246,10 +247,11 @@     - hint: {lhs: "\\(x,y) -> f x y", rhs: uncurry f, note: IncreasesLaziness, name: Use uncurry}     - 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)}         # isWildcard because some people like to put brackets round them even though they are atomic     - warn: {lhs: flip f x y, rhs: f y x, side: isApp original, name: Redundant flip}-    - warn: {lhs: id x, rhs: x, side: not (isTypeApp x), name: Evaluate}+    - warn: {lhs: id x, rhs: x, side: not (isTypeApp x), name: Redundant id}     - warn: {lhs: id . x, rhs: x, name: Redundant id}     - warn: {lhs: x . id, rhs: x, name: Redundant id}     - warn: {lhs: "((,) x)", rhs: "(_noParen_ x,)", name: Use tuple-section, note: RequiresExtension TupleSections}@@ -365,6 +367,7 @@     - warn: {lhs: mapM (uncurry f) (zip l m), rhs: zipWithM f l m}     - warn: {lhs: mapM_ (void . f), rhs: mapM_ f}     - warn: {lhs: forM_ x (void . f), rhs: forM_ x f}+    - warn: {lhs: a >>= \_ -> b, rhs: a >> b}      # STATE MONAD @@ -380,8 +383,10 @@     - warn: {lhs: sequence_ (replicate n x), rhs: Control.Monad.replicateM_ n x}     - warn: {lhs: mapM f (replicate n x), rhs: Control.Monad.replicateM n (f x)}     - warn: {lhs: mapM_ f (replicate n x), rhs: Control.Monad.replicateM_ n (f x)}-    - warn: {lhs: mapM f (map g x), rhs: mapM (f . g) x}-    - warn: {lhs: mapM_ f (map g x), rhs: mapM_ (f . g) x}+    - warn: {lhs: mapM f (map g x), rhs: mapM (f . g) x, name: Fuse mapM/map}+    - warn: {lhs: mapM_ f (map g x), rhs: mapM_ (f . g) x, name: Fuse mapM_/map}+    - warn: {lhs: traverse f (map g x), rhs: traverse (f . g) x, name: Fuse traverse/map}+    - warn: {lhs: traverse_ f (map g x), rhs: traverse_ (f . g) x, name: Fuse traverse_/map}     - warn: {lhs: mapM id, rhs: sequence}     - warn: {lhs: mapM_ id, rhs: sequence_}     - warn: {lhs: sequence (return a), rhs: return <$> a}@@ -431,6 +436,7 @@     - warn: {lhs: not (isJust x), rhs: isNothing x}     - warn: {lhs: "maybe [] (:[])", rhs: maybeToList}     - warn: {lhs: catMaybes (map f x), rhs: mapMaybe f x}+    - warn: {lhs: catMaybes (fmap f x), rhs: mapMaybe f x}     - hint: {lhs: case x of Nothing -> y; Just a -> a , rhs: fromMaybe y x}     - warn: {lhs: if isNothing x then y else f (fromJust x), rhs: maybe y f x}     - warn: {lhs: if isJust x then f (fromJust x) else y, rhs: maybe y f x}@@ -447,7 +453,7 @@     - warn: {lhs: if isNothing x then y else fromJust x, rhs: fromMaybe y x}     - warn: {lhs: if isJust x then fromJust x else y, rhs: fromMaybe y x}     - warn: {lhs: isJust x && (fromJust x == y), rhs: x == Just y}-    - warn: {lhs: mapMaybe f (map g x), rhs: mapMaybe (f . g) x}+    - warn: {lhs: mapMaybe f (map g x), rhs: mapMaybe (f . g) x, name: Fuse mapMaybe/map}     - warn: {lhs: fromMaybe a (fmap f x), rhs: maybe a f x}     - warn: {lhs: fromMaybe a (f <$> x), rhs: maybe a f x}     - warn: {lhs: mapMaybe id, rhs: catMaybes}@@ -809,6 +815,7 @@ # yes = foldr (\ curr acc -> (+ 1) curr : acc) [] -- map (\ curr -> (+ 1) curr) # yes = foldr (\ curr acc -> curr + curr : acc) [] -- map (\ curr -> curr + curr) # no = foo $ (,) x $ do {this is a test; and another test}+# {-# LANGUAGE QuasiQuotes #-}; no = f (\url -> [hamlet|foo @{url}|]) # # import Prelude \ # yes = flip mapM -- Control.Monad.forM
data/hs-lint.el view
@@ -12,7 +12,7 @@ ;; /Users/ott/projects/lang-exp/haskell/test.hs:52:1: Eta reduce ;; Found: ;;   count1 p l = length (filter p l)-;; Why not:+;; Perhaps: ;;   count1 p = length . filter p  @@ -52,11 +52,11 @@ ;; ^\(.*?\):\([0-9]+\):\([0-9]+\): .* ;; Found: ;; \s +\(.*\)-;; Why not:+;; Perhaps: ;; \s +\(.*\)  (defvar hs-lint-regex-  "^\\(.*?\\):\\([0-9]+\\):\\([0-9]+\\): .*[\n\C-m]Found:[\n\C-m]\\s +\\(.*\\)[\n\C-m]Why not:[\n\C-m]\\s +\\(.*\\)[\n\C-m]"+  "^\\(.*?\\):\\([0-9]+\\):\\([0-9]+\\): .*[\n\C-m]Found:[\n\C-m]\\s +\\(.*\\)[\n\C-m]Perhaps:[\n\C-m]\\s +\\(.*\\)[\n\C-m]"   "Regex for HLint messages")  (defun make-short-string (str maxlen)
hlint.cabal view
@@ -1,7 +1,7 @@ cabal-version:      >= 1.18 build-type:         Simple name:               hlint-version:            2.1.6+version:            2.1.7 license:            BSD3 license-file:       LICENSE category:           Development
src/CC.hs view
@@ -99,7 +99,7 @@         , T.pack from         , "```"         , ""-        , "Why not"+        , "Perhaps"         , ""         , "```"         , T.pack to
src/Hint/Extensions.hs view
@@ -210,7 +210,7 @@ used DeriveDataTypeable = hasDerive ["Data","Typeable"] used DeriveFunctor = hasDerive ["Functor"] used DeriveFoldable = hasDerive ["Foldable"]-used DeriveTraversable = hasDerive ["Traversable"]+used DeriveTraversable = hasDerive ["Traversable","Foldable","Functor"] used DeriveGeneric = hasDerive ["Generic","Generic1"] used GeneralizedNewtypeDeriving = not . null . derivesNewtype . derives used LambdaCase = hasS isLCase
src/Hint/Import.hs view
@@ -33,73 +33,6 @@ import Char(foo) -- import Data.Char(foo) import IO(foo) import IO as X -- import System.IO as X; import System.IO.Error as X; import Control.Exception  as X (bracket,bracket_)-import A hiding (a) -- import A-import A hiding (a, b); foo = a -- import A hiding (a)-import A hiding (a, b); foo = A.a -- import A hiding (a)-import A as B hiding (a) -- import A as B-import A as B hiding (a, b); foo = a -- import A as B hiding (a)-import A as B hiding (a, b); foo = B.a -- import A as B hiding (a)-import qualified A hiding (a) -- import qualified A-import qualified A hiding (a, b); foo = A.a -- import qualified A hiding (a)-import qualified A as B hiding (a, b); foo = B.a -- import qualified A as B hiding (a)-import A hiding ((+)) -- import A-import A hiding ((+), (*)); foo = (+) -- import A hiding ((+))-import A hiding ((+), (*)); foo = (+x) -- import A hiding ((+))-import A hiding ((+), (*)); foo = (x+) -- import A hiding ((+))-import A hiding ((+), (*)); foo = x+y -- import A hiding ((+))-import A hiding ((+), (*)); foo = (A.+) -- import A hiding ((+))-import A hiding ((+), (*)); foo = (A.+ x) -- import A hiding ((+))-import A hiding ((+), (*)); foo = (x A.+) -- import A hiding ((+))-import A hiding ((+), (*)); foo = x A.+ y -- import A hiding ((+))-import A as B hiding ((+)) -- import A as B-import A as B hiding ((+), (*)); foo = (+) -- import A as B hiding ((+))-import A as B hiding ((+), (*)); foo = (x+) -- import A as B hiding ((+))-import A as B hiding ((+), (*)); foo = (+x) -- import A as B hiding ((+))-import A as B hiding ((+), (*)); foo = x+y -- import A as B hiding ((+))-import A as B hiding ((+), (*)); foo = (B.+) -- import A as B hiding ((+))-import A as B hiding ((+), (*)); foo = (x B.+) -- import A as B hiding ((+))-import A as B hiding ((+), (*)); foo = (B.+ x) -- import A as B hiding ((+))-import A as B hiding ((+), (*)); foo = x B.+ y -- import A as B hiding ((+))-import qualified A hiding ((+)) -- import qualified A-import qualified A hiding ((+), (*)); foo = (A.+) -- import qualified A hiding ((+))-import qualified A hiding ((+), (*)); foo = (x A.+) -- import qualified A hiding ((+))-import qualified A hiding ((+), (*)); foo = (A.+ x) -- import qualified A hiding ((+))-import qualified A hiding ((+), (*)); foo = x A.+ y -- import qualified A hiding ((+))-import qualified A as B hiding ((+), (*)); foo = (B.+) -- import qualified A as B hiding ((+))-import qualified A as B hiding ((+), (*)); foo = (x B.+) -- import qualified A as B hiding ((+))-import qualified A as B hiding ((+), (*)); foo = (B.+ x) -- import qualified A as B hiding ((+))-import qualified A as B hiding ((+), (*)); foo = x B.+ y -- import qualified A as B hiding ((+))-module Foo (a) where; import A hiding (a)-module Foo (a) where; import A hiding (a, b) -- import A hiding (a)-module Foo (A.a) where; import A hiding (a, b) -- import A hiding (a)-module Foo (a) where; import A as B hiding (a)-module Foo (a) where; import A as B hiding (a, b) -- import A as B hiding (a)-module Foo (B.a) where; import A as B hiding (a, b) -- import A as B hiding (a)-module Foo (a) where; import qualified A hiding (a) -- import qualified A-module Foo (A.a) where; import qualified A hiding (a, b) -- import qualified A hiding (a)-module Foo (B.a) where; import qualified A as B hiding (a, b) -- import qualified A as B hiding (a)-module Foo (module A) where; import A hiding (a, b, c)-module Foo (module B) where; import A as B hiding (a, b, c)-module Foo (module A) where; import qualified A hiding (a, b, c) -- import qualified A-module Foo (module B) where; import qualified A as B hiding (a, b, c) -- import qualified A as B-module Foo ((+)) where; import A hiding ((+))-module Foo ((+)) where; import A hiding ((+), (*)) -- import A hiding ((+))-module Foo ((A.+)) where; import A hiding ((+), (*)) -- import A hiding ((+))-module Foo ((+)) where; import A as B hiding ((+))-module Foo ((+)) where; import A as B hiding ((+), (*)) -- import A as B hiding ((+))-module Foo ((B.+)) where; import A as B hiding ((+), (*)) -- import A as B hiding ((+))-module Foo ((+)) where; import qualified A hiding ((+)) -- import qualified A-module Foo ((A.+)) where; import qualified A hiding ((+), (*)) -- import qualified A hiding ((+))-module Foo ((B.+)) where; import qualified A as B hiding ((+), (*)) -- import qualified A as B hiding ((+))-module Foo (module A) where; import A hiding ((+), (*), (/))-module Foo (module B) where; import A as B hiding ((+), (*), (/))-module Foo (module A) where; import qualified A hiding ((+), (*), (/)) -- import qualified A-module Foo (module B) where; import qualified A as B hiding ((+), (*), (/)) -- import qualified A as B-{-# LANGUAGE QuasiQuotes #-}; import A hiding (a); [a||]-{-# LANGUAGE QuasiQuotes #-}; import A hiding (a); [A.a||]-{-# LANGUAGE QuasiQuotes #-}; import A as B hiding (a); [B.a||]-{-# LANGUAGE QuasiQuotes #-}; import qualified A hiding (a); [A.a||]-{-# LANGUAGE QuasiQuotes #-}; import qualified A as B hiding (a); [B.a||] </TEST> -} @@ -112,53 +45,16 @@ import Refact.Types hiding (ModuleName) import qualified Refact.Types as R import Data.List.Extra-import Data.Either (partitionEithers) import Data.Maybe import Prelude-import Data.Map (Map)-import qualified Data.Map as Map-import Data.Set (Set)-import qualified Data.Set as Set   importHint :: ModuHint importHint _ x = concatMap (wrap . snd) (groupSort                  [((fromNamed $ importModule i,importPkg i),i) | i <- universeBi x, not $ importSrc i]) ++-                 concatMap (\x -> hierarchy x ++ combine1 x ++ hidden reexported unqual quals x) (universeBi x)-    where-        -- Names of all re-exported modules-        reexported :: Set String-        reexported = Set.fromList [ fromModuleName n | EModuleContents _ n <- universeBi x ]+                 concatMap (\x -> hierarchy x ++ combine1 x) (universeBi x) -        -- Unqualified expressions and exported expressions-        unqual :: Set String-        unqual = Set.fromList (mapMaybe f qnames) `Set.union` Set.fromList qqUnqual-            where f :: QName S -> Maybe String-                  f (UnQual _ n) = Just (fromNamed n)-                  f _ = Nothing -        -- Qualified expressions and exported expressions-        quals :: Map String (Set String)-        quals = Map.fromListWith Set.union (map (second Set.singleton) qqQuals ++ mapMaybe f qnames)-            where f (Qual _ m n) = Just (fromModuleName m, Set.singleton (fromNamed n))-                  f _ = Nothing--        -- Unqualified quasi-quoters like [foo|...|]-        qqUnqual :: [String]-        -- Qualified quasi-quoters like [Foo.bar|...|]-        qqQuals :: [(String, String)]-        (qqUnqual, qqQuals) = partitionEithers [ f n | QuasiQuote (_ :: S) n _ <- universeBi x ]-            where f :: String -> Either String (String, String)-                  f n = maybe (Left n) Right (stripInfixEnd "." n)--        qnames :: [QName S]-        qnames = concat-            [ [ n | Var      (_ :: S) n <- universeBi x ]-            , [ n | VarQuote (_ :: S) n <- universeBi x ]-            , [ n | QVarOp   (_ :: S) n <- universeBi x ]-            , [ n | EVar     (_ :: S) n <- universeBi x ]-            ]- wrap :: [ImportDecl S] -> [Idea] wrap o = [ rawIdea Warning "Use fewer imports" (srcInfoSpan $ ann $ head o) (f o) (Just $ f x) [] rs          | Just (x, rs) <- [simplify o]]@@ -215,7 +111,7 @@     ,"Data" * "Ratio"     ,"System" * "Directory" -    -- Special, see bug #393+    -- Special, see bug https://code.google.com/archive/p/ndmitchell/issues/393     -- ,"System" * "IO"      -- Do not encourage use of old-locale/old-time over haskell98@@ -247,36 +143,3 @@ desugarQual :: ImportDecl S -> ImportDecl S desugarQual x | importQualified x && isNothing (importAs x) = x{importAs=Just (importModule x)}               | otherwise = x---- Suggest removing unnecessary "hiding" clauses in imports. Currently this only--- works for expressions.-hidden :: Set String -> Set String -> Map String (Set String) -> ImportDecl S -> [Idea]-hidden reexported unqual quals i@ImportDecl{importSpecs = Just (ImportSpecList loc True xs)}-    -- If the module is re-exported and not imported qualified, we can't prune-    -- any identifiers from the hiding clause-    | not (importQualified i) && as `Set.member` reexported = []-    | otherwise =-        case partition isUsed xs of-            (_, []) -> []-            ([], _) -> [suggest "Unnecessary hiding" i i{importSpecs = Nothing} [Delete Import (toSS i)]]-            (xs, _) ->-                let newImp = i{importSpecs = Just (ImportSpecList loc True xs)}-                in [suggest "Unnecessary hiding" i newImp [Replace Import (toSS i) [] (prettyPrint newImp)]]-    where-        isUsed :: ImportSpec S -> Bool-        isUsed (IVar _ n) = Set.member (fromNamed n) vars-        isUsed _ = True--        vars :: Set String-        vars =-          if importQualified i-            then qual-            else qual `Set.union` unqual--        qual :: Set String-        qual = fromMaybe Set.empty (Map.lookup as quals)--        as :: String-        as = fromModuleName (fromMaybe (importModule i) (importAs i))--hidden _ _ _ _ = []
src/Hint/Lambda.hs view
@@ -31,9 +31,13 @@ fun mr = y mr fun x = f . g $ x -- fun = f . g f = foo (\y -> g x . h $ y) -- g x . h+f = foo (\y -> g x . h $ y) -- @Message Avoid lambda f = foo ((*) x) -- (x *) f = (*) x f = foo (flip op x) -- (`op` x)+f = foo (flip op x) -- @Message Use section+foo x = bar (\ d -> search d table) -- (`search` table)+foo x = bar (\ d -> search d table) -- @Message Avoid lambda using `infix` f = flip op x f = foo (flip (*) x) -- (* x) f = foo (flip (-) x)@@ -70,6 +74,7 @@ no = blah (\ x -> case x of A -> a x; B -> b x) yes = blah (\ x -> (y, x, z+q)) -- (y, , z+q) yes = blah (\ x -> (y, x, z+x))+tmp = map (\ x -> runST $ action x) {-# LANGUAGE QuasiQuotes #-}; authOAuth2 name = authOAuth2Widget [whamlet|Login via #{name}|] name {-# LANGUAGE QuasiQuotes #-}; authOAuth2 = foo (\name -> authOAuth2Widget [whamlet|Login via #{name}|] name) </TEST>@@ -83,6 +88,7 @@ import Util import Data.List.Extra import Data.Maybe+import qualified Data.Set as Set import Refact.Types hiding (RType(Match))  @@ -138,8 +144,12 @@ --      subts = [("a", toSS y), ("*", toSS v)] lambdaExp p o@(Paren _ (App _ (App _ (view -> Var_ "flip") (Var _ x)) y)) | allowRightSection $ fromNamed x =     [suggestN "Use section" o $ RightSection an (QVarOp an x) y]-lambdaExp p o@Lambda{} | maybe True (not . isInfixApp) p, (res, refact) <- niceLambdaR [] o, not $ isLambda res, not $ any isQuasiQuote $ universe res =-    [(if isVar res || isCon res then warn else suggest) "Avoid lambda" o res (refact $ toSS o)]+lambdaExp p o@Lambda{}+    | maybe True (not . isInfixApp) p, (res, refact) <- niceLambdaR [] o+    , not $ isLambda res, not $ any isQuasiQuote $ universe res, not $ "runST" `Set.member` freeVars o+    , let name = "Avoid lambda" ++ (if countInfixNames res > countInfixNames o then " using `infix`" else "") =+    [(if isVar res || isCon res then warn else suggest) name o res (refact $ toSS o)]+    where countInfixNames x = length [() | RightSection _ (QVarOp _ (UnQual _ (Ident _ _))) _ <- universe x] lambdaExp p o@(Lambda _ pats x) | isLambda (fromParen x), null (universeBi pats :: [Exp_]), maybe True (not . isLambda) p =     [suggest "Collapse lambdas" o (Lambda an pats body) [Replace Expr (toSS o) subts template]]     where
src/Hint/Match.hs view
@@ -111,6 +111,12 @@     guard $ (freeVars e Set.\\ Set.filter (not . isUnifyVar) (freeVars hintRuleRHS))             `Set.isSubsetOf` freeVars x         -- check no unexpected new free variables++    -- check it isn't going to get broken by QuasiQuotes as per #483+    -- if we have lambdas we might be moving, and QuasiQuotes, we might inadvertantly break free vars+    -- because quasi quotes don't show what free vars they make use of+    guard $ not (any isLambda $ universe hintRuleLHS) || not (any isQuasiQuote $ universe x)+     guard $ checkSide hintRuleSide $ ("original",x) : ("result",res) : fromSubst u     guard $ checkDefine decl parent res     return (res, hintRuleNotes, [(s, toSS pos) | (s, pos) <- fromSubst u, ann pos /= an])
src/Hint/Pragma.hs view
@@ -68,21 +68,22 @@ pragmaIdea pidea =   case pidea of     SingleComment old new ->-      mkIdea (srcInfoSpan . ann $ old)+      mkFewer (srcInfoSpan . ann $ old)         (prettyPrint old) (Just $ prettyPrint new) []         [ModifyComment (toSS old) (prettyPrint new)]     MultiComment repl delete new ->-      mkIdea (srcInfoSpan . ann $ repl)+      mkFewer (srcInfoSpan . ann $ repl)         (f [repl, delete]) (Just $ prettyPrint new) []         [ ModifyComment (toSS repl) (prettyPrint new)         , ModifyComment (toSS delete) ""]     OptionsToComment old new r ->-      mkIdea (srcInfoSpan . ann . head $ old)+      mkLanguage (srcInfoSpan . ann . head $ old)         (f old) (Just $ f new) []         r     where           f = unlines . map prettyPrint-          mkIdea = rawIdea Warning "Use better pragmas"+          mkFewer = rawIdea Warning "Use fewer LANGUAGE pragmas"+          mkLanguage = rawIdea Warning "Use LANGUAGE pragmas"   languageDupes :: [ModulePragma S] -> [Idea]
src/Idea.hs view
@@ -70,11 +70,11 @@ showEx :: (String -> String) -> Idea -> String showEx tt Idea{..} = unlines $     [showSrcLoc (getPointLoc ideaSpan) ++ ": " ++ (if ideaHint == "" then "" else show ideaSeverity ++ ": " ++ ideaHint)] ++-    f "Found" (Just ideaFrom) ++ f "Why not" ideaTo +++    f "Found" (Just ideaFrom) ++ f "Perhaps" ideaTo ++     ["Note: " ++ n | let n = showNotes ideaNote, n /= ""]     where         f msg Nothing = []-        f msg (Just x) | null xs = [msg ++ " remove it."]+        f msg (Just x) | null xs = [msg ++ " you should remove it."]                        | otherwise = (msg ++ ":") : map ("  "++) xs             where xs = lines $ tt x 
src/Report.hs view
@@ -56,7 +56,7 @@     (case ideaTo of         Nothing -> []         Just to ->-            ["Why not" ++ (if to == "" then " remove it." else "") ++ "<br/>"+            ["Perhaps" ++ (if to == "" then " you should remove it." else "") ++ "<br/>"             ,hsColourHTML to]) ++     [let n = showNotes ideaNote in if n /= "" then "<span class='note'>Note: " ++ writeNote n ++ "</span>" else ""     ,"</div>"
src/Test/Annotations.hs view
@@ -56,6 +56,7 @@             if null bad then passed else sequence_ bad          match "???" _ = True+        match (word1 -> ("@Message",msg)) i = ideaHint i == msg         match (word1 -> ("@Note",note)) i = map show (ideaNote i) == [note]         match "@NoNote" i = null (ideaNote i)         match (word1 -> ('@':sev, msg)) i = sev == show (ideaSeverity i) && match msg i