{-# LANGUAGE ViewPatterns, PatternGuards #-}
module Hint.Pattern(patternHint) where
import Hint.Type(DeclHint',Idea,ghcAnnotations,ideaTo,toSS',toRefactSrcSpan,ghcSpanToHSE,suggest',warn')
import Data.Generics.Uniplate.Operations
import Data.Function
import Data.List.Extra
import Data.Tuple
import Data.Maybe
import Data.Either
import Refact.Types hiding (RType(Pattern, Match), SrcSpan)
import qualified Refact.Types as R (RType(Pattern, Match), SrcSpan)
import HsSyn
import SrcLoc
import RdrName
import OccName
import Bag
import BasicTypes
import GHC.Util
import Language.Haskell.GhclibParserEx.GHC.Hs.Expr
patternHint :: DeclHint'
patternHint :: DeclHint'
patternHint _scope :: Scope'
_scope modu :: ModuleEx
modu x :: LHsDecl GhcPs
x =
((Pattern, String -> Pattern -> [Refactoring SrcSpan] -> Idea)
-> [Idea])
-> [(Pattern, String -> Pattern -> [Refactoring SrcSpan] -> Idea)]
-> [Idea]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (((String -> Pattern -> [Refactoring SrcSpan] -> Idea)
-> Pattern -> [Idea])
-> (String -> Pattern -> [Refactoring SrcSpan] -> Idea, Pattern)
-> [Idea]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (String -> Pattern -> [Refactoring SrcSpan] -> Idea)
-> Pattern -> [Idea]
hints ((String -> Pattern -> [Refactoring SrcSpan] -> Idea, Pattern)
-> [Idea])
-> ((Pattern, String -> Pattern -> [Refactoring SrcSpan] -> Idea)
-> (String -> Pattern -> [Refactoring SrcSpan] -> Idea, Pattern))
-> (Pattern, String -> Pattern -> [Refactoring SrcSpan] -> Idea)
-> [Idea]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Pattern, String -> Pattern -> [Refactoring SrcSpan] -> Idea)
-> (String -> Pattern -> [Refactoring SrcSpan] -> Idea, Pattern)
forall a b. (a, b) -> (b, a)
swap) (LHsDecl GhcPs
-> [(Pattern, String -> Pattern -> [Refactoring SrcSpan] -> Idea)]
asPattern LHsDecl GhcPs
x) [Idea] -> [Idea] -> [Idea]
forall a. [a] -> [a] -> [a]
++
(Pat GhcPs -> [Idea]) -> [Pat GhcPs] -> [Idea]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Bool -> Bool -> Pat GhcPs -> [Idea]
patHint Bool
strict Bool
False) ([Pat GhcPs] -> [Pat GhcPs]
forall p. [Pat p] -> [Pat p]
located [Pat GhcPs
p | PatBind _ p :: Pat GhcPs
p _ _ <- LHsDecl GhcPs -> [HsBindLR GhcPs GhcPs]
forall from to. Biplate from to => from -> [to]
universeBi LHsDecl GhcPs
x :: [HsBind GhcPs]]) [Idea] -> [Idea] -> [Idea]
forall a. [a] -> [a] -> [a]
++
(Pat GhcPs -> [Idea]) -> [Pat GhcPs] -> [Idea]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Bool -> Bool -> Pat GhcPs -> [Idea]
patHint Bool
strict Bool
True) ([Pat GhcPs] -> [Pat GhcPs]
forall p. [Pat p] -> [Pat p]
located (LHsDecl GhcPs -> [Pat GhcPs]
forall from to. Biplate from to => from -> [to]
universeBi (LHsDecl GhcPs -> [Pat GhcPs]) -> LHsDecl GhcPs -> [Pat GhcPs]
forall a b. (a -> b) -> a -> b
$ (LHsBind GhcPs -> LHsBind GhcPs) -> LHsDecl GhcPs -> LHsDecl GhcPs
forall from to. Biplate from to => (to -> to) -> from -> from
transformBi LHsBind GhcPs -> LHsBind GhcPs
noPatBind LHsDecl GhcPs
x)) [Idea] -> [Idea] -> [Idea]
forall a. [a] -> [a] -> [a]
++
(LHsExpr GhcPs -> [Idea]) -> [LHsExpr GhcPs] -> [Idea]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap LHsExpr GhcPs -> [Idea]
expHint (LHsDecl GhcPs -> [LHsExpr GhcPs]
forall from to. Biplate from to => from -> [to]
universeBi LHsDecl GhcPs
x)
where
located :: [Pat p] -> [Pat p]
located ps :: [Pat p]
ps = [Pat p
p | p :: Pat p
p@XPat{} <- [Pat p]
ps]
exts :: [String]
exts = [String] -> [String]
forall a. Ord a => [a] -> [a]
nubOrd ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ ((Located AnnotationComment, [String]) -> [String])
-> [(Located AnnotationComment, [String])] -> [String]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Located AnnotationComment, [String]) -> [String]
forall a b. (a, b) -> b
snd ([(Located AnnotationComment, String)]
-> [(Located AnnotationComment, [String])]
langExts (ApiAnns -> [(Located AnnotationComment, String)]
pragmas (ModuleEx -> ApiAnns
ghcAnnotations ModuleEx
modu)))
strict :: Bool
strict = "Strict" String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
exts
noPatBind :: LHsBind GhcPs -> LHsBind GhcPs
noPatBind :: LHsBind GhcPs -> LHsBind GhcPs
noPatBind (LL loc :: SrcSpan
loc a :: SrcSpanLess (LHsBind GhcPs)
a@PatBind{}) = SrcSpan -> SrcSpanLess (LHsBind GhcPs) -> LHsBind GhcPs
forall a. HasSrcSpan a => SrcSpan -> SrcSpanLess a -> a
cL SrcSpan
loc SrcSpanLess (LHsBind GhcPs)
HsBindLR GhcPs GhcPs
a{pat_lhs :: Pat GhcPs
pat_lhs=SrcSpanLess (Pat GhcPs) -> Pat GhcPs
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (XWildPat GhcPs -> Pat GhcPs
forall p. XWildPat p -> Pat p
WildPat NoExt
XWildPat GhcPs
noExt)}
noPatBind x :: LHsBind GhcPs
x = LHsBind GhcPs
x
hints :: (String -> Pattern -> [Refactoring R.SrcSpan] -> Idea) -> Pattern -> [Idea]
hints :: (String -> Pattern -> [Refactoring SrcSpan] -> Idea)
-> Pattern -> [Idea]
hints gen :: String -> Pattern -> [Refactoring SrcSpan] -> Idea
gen (Pattern l :: SrcSpan
l rtype :: RType
rtype pat :: [Pat GhcPs]
pat (GRHSs _ [LL _ (GRHS _ [] bod)] bind :: LHsLocalBinds GhcPs
bind))
| [LGRHS GhcPs (LHsExpr GhcPs)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [LGRHS GhcPs (LHsExpr GhcPs)]
guards Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 2 = [String -> Pattern -> [Refactoring SrcSpan] -> Idea
gen "Use guards" (SrcSpan
-> RType -> [Pat GhcPs] -> GRHSs GhcPs (LHsExpr GhcPs) -> Pattern
Pattern SrcSpan
l RType
rtype [Pat GhcPs]
pat (XCGRHSs GhcPs (LHsExpr GhcPs)
-> [LGRHS GhcPs (LHsExpr GhcPs)]
-> LHsLocalBinds GhcPs
-> GRHSs GhcPs (LHsExpr GhcPs)
forall p body.
XCGRHSs p body -> [LGRHS p body] -> LHsLocalBinds p -> GRHSs p body
GRHSs NoExt
XCGRHSs GhcPs (LHsExpr GhcPs)
noExt [LGRHS GhcPs (LHsExpr GhcPs)]
guards LHsLocalBinds GhcPs
bind)) [Refactoring SrcSpan
refactoring]]
where
rawGuards :: [(LHsExpr GhcPs, LHsExpr GhcPs)]
rawGuards :: [(LHsExpr GhcPs, LHsExpr GhcPs)]
rawGuards = LHsExpr GhcPs -> [(LHsExpr GhcPs, LHsExpr GhcPs)]
asGuards LHsExpr GhcPs
bod
mkGuard :: LHsExpr GhcPs -> (LHsExpr GhcPs -> GRHS GhcPs (LHsExpr GhcPs))
mkGuard :: LHsExpr GhcPs -> LHsExpr GhcPs -> GRHS GhcPs (LHsExpr GhcPs)
mkGuard a :: LHsExpr GhcPs
a = XCGRHS GhcPs (LHsExpr GhcPs)
-> [GuardLStmt GhcPs]
-> LHsExpr GhcPs
-> GRHS GhcPs (LHsExpr GhcPs)
forall p body.
XCGRHS p body -> [GuardLStmt p] -> body -> GRHS p body
GRHS NoExt
XCGRHS GhcPs (LHsExpr GhcPs)
noExt [SrcSpanLess (GuardLStmt GhcPs) -> GuardLStmt GhcPs
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (SrcSpanLess (GuardLStmt GhcPs) -> GuardLStmt GhcPs)
-> SrcSpanLess (GuardLStmt GhcPs) -> GuardLStmt GhcPs
forall a b. (a -> b) -> a -> b
$ XBodyStmt GhcPs GhcPs (LHsExpr GhcPs)
-> LHsExpr GhcPs
-> SyntaxExpr GhcPs
-> SyntaxExpr GhcPs
-> StmtLR GhcPs GhcPs (LHsExpr GhcPs)
forall idL idR body.
XBodyStmt idL idR body
-> body -> SyntaxExpr idR -> SyntaxExpr idR -> StmtLR idL idR body
BodyStmt NoExt
XBodyStmt GhcPs GhcPs (LHsExpr GhcPs)
noExt LHsExpr GhcPs
a SyntaxExpr GhcPs
forall (p :: Pass). SyntaxExpr (GhcPass p)
noSyntaxExpr SyntaxExpr GhcPs
forall (p :: Pass). SyntaxExpr (GhcPass p)
noSyntaxExpr]
guards :: [LGRHS GhcPs (LHsExpr GhcPs)]
guards :: [LGRHS GhcPs (LHsExpr GhcPs)]
guards = ((LHsExpr GhcPs, LHsExpr GhcPs) -> LGRHS GhcPs (LHsExpr GhcPs))
-> [(LHsExpr GhcPs, LHsExpr GhcPs)]
-> [LGRHS GhcPs (LHsExpr GhcPs)]
forall a b. (a -> b) -> [a] -> [b]
map (GRHS GhcPs (LHsExpr GhcPs) -> LGRHS GhcPs (LHsExpr GhcPs)
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (GRHS GhcPs (LHsExpr GhcPs) -> LGRHS GhcPs (LHsExpr GhcPs))
-> ((LHsExpr GhcPs, LHsExpr GhcPs) -> GRHS GhcPs (LHsExpr GhcPs))
-> (LHsExpr GhcPs, LHsExpr GhcPs)
-> LGRHS GhcPs (LHsExpr GhcPs)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LHsExpr GhcPs -> LHsExpr GhcPs -> GRHS GhcPs (LHsExpr GhcPs))
-> (LHsExpr GhcPs, LHsExpr GhcPs) -> GRHS GhcPs (LHsExpr GhcPs)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry LHsExpr GhcPs -> LHsExpr GhcPs -> GRHS GhcPs (LHsExpr GhcPs)
mkGuard) [(LHsExpr GhcPs, LHsExpr GhcPs)]
rawGuards
(lhs :: [LHsExpr GhcPs]
lhs, rhs :: [LHsExpr GhcPs]
rhs) = [(LHsExpr GhcPs, LHsExpr GhcPs)]
-> ([LHsExpr GhcPs], [LHsExpr GhcPs])
forall a b. [(a, b)] -> ([a], [b])
unzip [(LHsExpr GhcPs, LHsExpr GhcPs)]
rawGuards
mkTemplate :: String -> [e] -> [Either e (String, SrcSpan)]
mkTemplate c :: String
c ps :: [e]
ps =
(e -> Char -> Either e (String, SrcSpan))
-> [e] -> String -> [Either e (String, SrcSpan)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith e -> Char -> Either e (String, SrcSpan)
forall e. HasSrcSpan e => e -> Char -> Either e (String, SrcSpan)
checkLoc [e]
ps ['1' .. '9']
where
checkLoc :: e -> Char -> Either e (String, SrcSpan)
checkLoc p :: e
p@(LL l :: SrcSpan
l _) v :: Char
v = if SrcSpan
l SrcSpan -> SrcSpan -> Bool
forall a. Eq a => a -> a -> Bool
== SrcSpan
noSrcSpan then e -> Either e (String, SrcSpan)
forall a b. a -> Either a b
Left e
p else (String, SrcSpan) -> Either e (String, SrcSpan)
forall a b. b -> Either a b
Right (String
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
v], e -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' e
p)
checkLoc _ v :: Char
v = Either e (String, SrcSpan)
forall a. HasCallStack => a
undefined
patSubts :: [Either (Pat GhcPs) (String, SrcSpan)]
patSubts =
case [Pat GhcPs]
pat of
[p :: Pat GhcPs
p] -> [Pat GhcPs -> Either (Pat GhcPs) (String, SrcSpan)
forall a b. a -> Either a b
Left Pat GhcPs
p]
ps :: [Pat GhcPs]
ps -> String -> [Pat GhcPs] -> [Either (Pat GhcPs) (String, SrcSpan)]
forall e.
HasSrcSpan e =>
String -> [e] -> [Either e (String, SrcSpan)]
mkTemplate "p100" [Pat GhcPs]
ps
guardSubts :: [Either (LHsExpr GhcPs) (String, SrcSpan)]
guardSubts = String
-> [LHsExpr GhcPs] -> [Either (LHsExpr GhcPs) (String, SrcSpan)]
forall e.
HasSrcSpan e =>
String -> [e] -> [Either e (String, SrcSpan)]
mkTemplate "g100" [LHsExpr GhcPs]
lhs
exprSubts :: [Either (LHsExpr GhcPs) (String, SrcSpan)]
exprSubts = String
-> [LHsExpr GhcPs] -> [Either (LHsExpr GhcPs) (String, SrcSpan)]
forall e.
HasSrcSpan e =>
String -> [e] -> [Either e (String, SrcSpan)]
mkTemplate "e100" [LHsExpr GhcPs]
rhs
templateGuards :: [LGRHS GhcPs (LHsExpr GhcPs)]
templateGuards = (GRHS GhcPs (LHsExpr GhcPs) -> LGRHS GhcPs (LHsExpr GhcPs))
-> [GRHS GhcPs (LHsExpr GhcPs)] -> [LGRHS GhcPs (LHsExpr GhcPs)]
forall a b. (a -> b) -> [a] -> [b]
map GRHS GhcPs (LHsExpr GhcPs) -> LGRHS GhcPs (LHsExpr GhcPs)
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc ((Either (LHsExpr GhcPs) (String, SrcSpan)
-> Either (LHsExpr GhcPs) (String, SrcSpan)
-> GRHS GhcPs (LHsExpr GhcPs))
-> [Either (LHsExpr GhcPs) (String, SrcSpan)]
-> [Either (LHsExpr GhcPs) (String, SrcSpan)]
-> [GRHS GhcPs (LHsExpr GhcPs)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (LHsExpr GhcPs -> LHsExpr GhcPs -> GRHS GhcPs (LHsExpr GhcPs)
mkGuard (LHsExpr GhcPs -> LHsExpr GhcPs -> GRHS GhcPs (LHsExpr GhcPs))
-> (Either (LHsExpr GhcPs) (String, SrcSpan) -> LHsExpr GhcPs)
-> Either (LHsExpr GhcPs) (String, SrcSpan)
-> Either (LHsExpr GhcPs) (String, SrcSpan)
-> GRHS GhcPs (LHsExpr GhcPs)
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Either (LHsExpr GhcPs) (String, SrcSpan) -> LHsExpr GhcPs
forall b. Either (LHsExpr GhcPs) (String, b) -> LHsExpr GhcPs
toString) [Either (LHsExpr GhcPs) (String, SrcSpan)]
guardSubts [Either (LHsExpr GhcPs) (String, SrcSpan)]
exprSubts)
toString :: Either (LHsExpr GhcPs) (String, b) -> LHsExpr GhcPs
toString (Left e :: LHsExpr GhcPs
e) = LHsExpr GhcPs
e
toString (Right (v :: String
v, _)) = String -> LHsExpr GhcPs
strToVar String
v
toString' :: Either (Pat GhcPs) (String, b) -> Pat GhcPs
toString' (Left e :: Pat GhcPs
e) = Pat GhcPs
e
toString' (Right (v :: String
v, _)) = String -> Pat GhcPs
strToPat' String
v
template :: String
template = String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe "" (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ Idea -> Maybe String
ideaTo (String -> Pattern -> [Refactoring SrcSpan] -> Idea
gen "" (SrcSpan
-> RType -> [Pat GhcPs] -> GRHSs GhcPs (LHsExpr GhcPs) -> Pattern
Pattern SrcSpan
l RType
rtype ((Either (Pat GhcPs) (String, SrcSpan) -> Pat GhcPs)
-> [Either (Pat GhcPs) (String, SrcSpan)] -> [Pat GhcPs]
forall a b. (a -> b) -> [a] -> [b]
map Either (Pat GhcPs) (String, SrcSpan) -> Pat GhcPs
forall b. Either (Pat GhcPs) (String, b) -> Pat GhcPs
toString' [Either (Pat GhcPs) (String, SrcSpan)]
patSubts) (XCGRHSs GhcPs (LHsExpr GhcPs)
-> [LGRHS GhcPs (LHsExpr GhcPs)]
-> LHsLocalBinds GhcPs
-> GRHSs GhcPs (LHsExpr GhcPs)
forall p body.
XCGRHSs p body -> [LGRHS p body] -> LHsLocalBinds p -> GRHSs p body
GRHSs NoExt
XCGRHSs GhcPs (LHsExpr GhcPs)
noExt [LGRHS GhcPs (LHsExpr GhcPs)]
templateGuards LHsLocalBinds GhcPs
bind)) [])
f :: [Either a (String, R.SrcSpan)] -> [(String, R.SrcSpan)]
f :: [Either a (String, SrcSpan)] -> [(String, SrcSpan)]
f = [Either a (String, SrcSpan)] -> [(String, SrcSpan)]
forall a b. [Either a b] -> [b]
rights
refactoring :: Refactoring SrcSpan
refactoring = RType
-> SrcSpan -> [(String, SrcSpan)] -> String -> Refactoring SrcSpan
forall a. RType -> a -> [(String, a)] -> String -> Refactoring a
Replace RType
rtype (SrcSpan -> SrcSpan
toRefactSrcSpan(SrcSpan -> SrcSpan) -> SrcSpan -> SrcSpan
forall a b. (a -> b) -> a -> b
$ SrcSpan -> SrcSpan
ghcSpanToHSE SrcSpan
l) ([Either (Pat GhcPs) (String, SrcSpan)] -> [(String, SrcSpan)]
forall a. [Either a (String, SrcSpan)] -> [(String, SrcSpan)]
f [Either (Pat GhcPs) (String, SrcSpan)]
patSubts [(String, SrcSpan)] -> [(String, SrcSpan)] -> [(String, SrcSpan)]
forall a. [a] -> [a] -> [a]
++ [Either (LHsExpr GhcPs) (String, SrcSpan)] -> [(String, SrcSpan)]
forall a. [Either a (String, SrcSpan)] -> [(String, SrcSpan)]
f [Either (LHsExpr GhcPs) (String, SrcSpan)]
guardSubts [(String, SrcSpan)] -> [(String, SrcSpan)] -> [(String, SrcSpan)]
forall a. [a] -> [a] -> [a]
++ [Either (LHsExpr GhcPs) (String, SrcSpan)] -> [(String, SrcSpan)]
forall a. [Either a (String, SrcSpan)] -> [(String, SrcSpan)]
f [Either (LHsExpr GhcPs) (String, SrcSpan)]
exprSubts) String
template
hints gen :: String -> Pattern -> [Refactoring SrcSpan] -> Idea
gen (Pattern l :: SrcSpan
l t :: RType
t pats :: [Pat GhcPs]
pats o :: GRHSs GhcPs (LHsExpr GhcPs)
o@(GRHSs _ [LL _ (GRHS _ [test] bod)] bind :: LHsLocalBinds GhcPs
bind))
| GuardLStmt GhcPs -> String
forall a. Outputable a => a -> String
unsafePrettyPrint GuardLStmt GhcPs
test String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ["otherwise", "True"]
= [String -> Pattern -> [Refactoring SrcSpan] -> Idea
gen "Redundant guard" (SrcSpan
-> RType -> [Pat GhcPs] -> GRHSs GhcPs (LHsExpr GhcPs) -> Pattern
Pattern SrcSpan
l RType
t [Pat GhcPs]
pats GRHSs GhcPs (LHsExpr GhcPs)
o{grhssGRHSs :: [LGRHS GhcPs (LHsExpr GhcPs)]
grhssGRHSs=[SrcSpanLess (LGRHS GhcPs (LHsExpr GhcPs))
-> LGRHS GhcPs (LHsExpr GhcPs)
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (XCGRHS GhcPs (LHsExpr GhcPs)
-> [GuardLStmt GhcPs]
-> LHsExpr GhcPs
-> GRHS GhcPs (LHsExpr GhcPs)
forall p body.
XCGRHS p body -> [GuardLStmt p] -> body -> GRHS p body
GRHS NoExt
XCGRHS GhcPs (LHsExpr GhcPs)
noExt [] LHsExpr GhcPs
bod)]}) [RType -> SrcSpan -> Refactoring SrcSpan
forall a. RType -> a -> Refactoring a
Delete RType
Stmt (GuardLStmt GhcPs -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' GuardLStmt GhcPs
test)]]
hints gen :: String -> Pattern -> [Refactoring SrcSpan] -> Idea
gen (Pattern l :: SrcSpan
l t :: RType
t pats :: [Pat GhcPs]
pats bod :: GRHSs GhcPs (LHsExpr GhcPs)
bod@(GRHSs _ _ binds :: LHsLocalBinds GhcPs
binds)) | LHsLocalBinds GhcPs -> Bool
f LHsLocalBinds GhcPs
binds
= [String -> Pattern -> [Refactoring SrcSpan] -> Idea
gen "Redundant where" (SrcSpan
-> RType -> [Pat GhcPs] -> GRHSs GhcPs (LHsExpr GhcPs) -> Pattern
Pattern SrcSpan
l RType
t [Pat GhcPs]
pats GRHSs GhcPs (LHsExpr GhcPs)
bod{grhssLocalBinds :: LHsLocalBinds GhcPs
grhssLocalBinds=SrcSpanLess (LHsLocalBinds GhcPs) -> LHsLocalBinds GhcPs
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (XEmptyLocalBinds GhcPs GhcPs -> HsLocalBindsLR GhcPs GhcPs
forall idL idR. XEmptyLocalBinds idL idR -> HsLocalBindsLR idL idR
EmptyLocalBinds NoExt
XEmptyLocalBinds GhcPs GhcPs
noExt)}) []]
where
f :: LHsLocalBinds GhcPs -> Bool
f :: LHsLocalBinds GhcPs -> Bool
f (LL _ (HsValBinds _ (ValBinds _ bag _))) = Bag (LHsBind GhcPs) -> Bool
forall a. Bag a -> Bool
isEmptyBag Bag (LHsBind GhcPs)
bag
f (LL _ (HsIPBinds _ (IPBinds _ l))) = [LIPBind GhcPs] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [LIPBind GhcPs]
l
f _ = Bool
False
hints gen :: String -> Pattern -> [Refactoring SrcSpan] -> Idea
gen (Pattern l :: SrcSpan
l t :: RType
t pats :: [Pat GhcPs]
pats o :: GRHSs GhcPs (LHsExpr GhcPs)
o@(GRHSs _ ([LGRHS GhcPs (LHsExpr GhcPs)]
-> Maybe
([LGRHS GhcPs (LHsExpr GhcPs)], LGRHS GhcPs (LHsExpr GhcPs))
forall a. [a] -> Maybe ([a], a)
unsnoc -> Just (gs :: [LGRHS GhcPs (LHsExpr GhcPs)]
gs, LL _ (GRHS _ [test] bod))) binds :: LHsLocalBinds GhcPs
binds))
| GuardLStmt GhcPs -> String
forall a. Outputable a => a -> String
unsafePrettyPrint GuardLStmt GhcPs
test String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== "True"
= let tag :: Located RdrName
tag = SrcSpanLess (Located RdrName) -> Located RdrName
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (OccName -> RdrName
OccName -> SrcSpanLess (Located RdrName)
mkRdrUnqual (OccName -> SrcSpanLess (Located RdrName))
-> OccName -> SrcSpanLess (Located RdrName)
forall a b. (a -> b) -> a -> b
$ String -> OccName
mkVarOcc "otherwise")
otherwise_ :: GuardLStmt GhcPs
otherwise_ = SrcSpanLess (GuardLStmt GhcPs) -> GuardLStmt GhcPs
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (SrcSpanLess (GuardLStmt GhcPs) -> GuardLStmt GhcPs)
-> SrcSpanLess (GuardLStmt GhcPs) -> GuardLStmt GhcPs
forall a b. (a -> b) -> a -> b
$ XBodyStmt GhcPs GhcPs (LHsExpr GhcPs)
-> LHsExpr GhcPs
-> SyntaxExpr GhcPs
-> SyntaxExpr GhcPs
-> StmtLR GhcPs GhcPs (LHsExpr GhcPs)
forall idL idR body.
XBodyStmt idL idR body
-> body -> SyntaxExpr idR -> SyntaxExpr idR -> StmtLR idL idR body
BodyStmt NoExt
XBodyStmt GhcPs GhcPs (LHsExpr GhcPs)
noExt (SrcSpanLess (LHsExpr GhcPs) -> LHsExpr GhcPs
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (XVar GhcPs -> Located (IdP GhcPs) -> HsExpr GhcPs
forall p. XVar p -> Located (IdP p) -> HsExpr p
HsVar NoExt
XVar GhcPs
noExt Located RdrName
Located (IdP GhcPs)
tag)) SyntaxExpr GhcPs
forall (p :: Pass). SyntaxExpr (GhcPass p)
noSyntaxExpr SyntaxExpr GhcPs
forall (p :: Pass). SyntaxExpr (GhcPass p)
noSyntaxExpr in
[String -> Pattern -> [Refactoring SrcSpan] -> Idea
gen "Use otherwise" (SrcSpan
-> RType -> [Pat GhcPs] -> GRHSs GhcPs (LHsExpr GhcPs) -> Pattern
Pattern SrcSpan
l RType
t [Pat GhcPs]
pats GRHSs GhcPs (LHsExpr GhcPs)
o{grhssGRHSs :: [LGRHS GhcPs (LHsExpr GhcPs)]
grhssGRHSs = [LGRHS GhcPs (LHsExpr GhcPs)]
gs [LGRHS GhcPs (LHsExpr GhcPs)]
-> [LGRHS GhcPs (LHsExpr GhcPs)] -> [LGRHS GhcPs (LHsExpr GhcPs)]
forall a. [a] -> [a] -> [a]
++ [SrcSpanLess (LGRHS GhcPs (LHsExpr GhcPs))
-> LGRHS GhcPs (LHsExpr GhcPs)
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (XCGRHS GhcPs (LHsExpr GhcPs)
-> [GuardLStmt GhcPs]
-> LHsExpr GhcPs
-> GRHS GhcPs (LHsExpr GhcPs)
forall p body.
XCGRHS p body -> [GuardLStmt p] -> body -> GRHS p body
GRHS NoExt
XCGRHS GhcPs (LHsExpr GhcPs)
noExt [GuardLStmt GhcPs
otherwise_] LHsExpr GhcPs
bod)]}) [RType
-> SrcSpan -> [(String, SrcSpan)] -> String -> Refactoring SrcSpan
forall a. RType -> a -> [(String, a)] -> String -> Refactoring a
Replace RType
Expr (GuardLStmt GhcPs -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' GuardLStmt GhcPs
test) [] "otherwise"]]
hints _ _ = []
asGuards :: LHsExpr GhcPs -> [(LHsExpr GhcPs, LHsExpr GhcPs)]
asGuards :: LHsExpr GhcPs -> [(LHsExpr GhcPs, LHsExpr GhcPs)]
asGuards (LL _ (HsPar _ x)) = LHsExpr GhcPs -> [(LHsExpr GhcPs, LHsExpr GhcPs)]
asGuards LHsExpr GhcPs
x
asGuards (LL _ (HsIf _ _ a b c)) = (LHsExpr GhcPs
a, LHsExpr GhcPs
b) (LHsExpr GhcPs, LHsExpr GhcPs)
-> [(LHsExpr GhcPs, LHsExpr GhcPs)]
-> [(LHsExpr GhcPs, LHsExpr GhcPs)]
forall a. a -> [a] -> [a]
: LHsExpr GhcPs -> [(LHsExpr GhcPs, LHsExpr GhcPs)]
asGuards LHsExpr GhcPs
c
asGuards x :: LHsExpr GhcPs
x = [(SrcSpanLess (LHsExpr GhcPs) -> LHsExpr GhcPs
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (XVar GhcPs -> Located (IdP GhcPs) -> HsExpr GhcPs
forall p. XVar p -> Located (IdP p) -> HsExpr p
HsVar NoExt
XVar GhcPs
noExt (SrcSpanLess (Located RdrName) -> Located RdrName
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (OccName -> RdrName
OccName -> SrcSpanLess (Located RdrName)
mkRdrUnqual (OccName -> SrcSpanLess (Located RdrName))
-> OccName -> SrcSpanLess (Located RdrName)
forall a b. (a -> b) -> a -> b
$ String -> OccName
mkVarOcc "otherwise"))), LHsExpr GhcPs
x)]
data Pattern = Pattern SrcSpan R.RType [Pat GhcPs] (GRHSs GhcPs (LHsExpr GhcPs))
asPattern :: LHsDecl GhcPs -> [(Pattern, String -> Pattern -> [Refactoring R.SrcSpan] -> Idea)]
asPattern :: LHsDecl GhcPs
-> [(Pattern, String -> Pattern -> [Refactoring SrcSpan] -> Idea)]
asPattern (LL loc :: SrcSpan
loc x :: SrcSpanLess (LHsDecl GhcPs)
x) = (HsBindLR GhcPs GhcPs
-> [(Pattern, String -> Pattern -> [Refactoring SrcSpan] -> Idea)])
-> [HsBindLR GhcPs GhcPs]
-> [(Pattern, String -> Pattern -> [Refactoring SrcSpan] -> Idea)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap HsBindLR GhcPs GhcPs
-> [(Pattern, String -> Pattern -> [Refactoring SrcSpan] -> Idea)]
decl (HsDecl GhcPs -> [HsBindLR GhcPs GhcPs]
forall from to. Biplate from to => from -> [to]
universeBi SrcSpanLess (LHsDecl GhcPs)
HsDecl GhcPs
x)
where
decl :: HsBind GhcPs -> [(Pattern, String -> Pattern -> [Refactoring R.SrcSpan] -> Idea)]
decl :: HsBindLR GhcPs GhcPs
-> [(Pattern, String -> Pattern -> [Refactoring SrcSpan] -> Idea)]
decl o :: HsBindLR GhcPs GhcPs
o@(PatBind _ pat :: Pat GhcPs
pat rhs :: GRHSs GhcPs (LHsExpr GhcPs)
rhs _) = [(SrcSpan
-> RType -> [Pat GhcPs] -> GRHSs GhcPs (LHsExpr GhcPs) -> Pattern
Pattern SrcSpan
loc RType
Bind [Pat GhcPs
pat] GRHSs GhcPs (LHsExpr GhcPs)
rhs, \msg :: String
msg (Pattern _ _ [pat :: Pat GhcPs
pat] rhs :: GRHSs GhcPs (LHsExpr GhcPs)
rhs) rs :: [Refactoring SrcSpan]
rs -> String
-> LHsBind GhcPs -> LHsBind GhcPs -> [Refactoring SrcSpan] -> Idea
forall a b.
(HasSrcSpan a, Outputable a, HasSrcSpan b, Outputable b) =>
String -> a -> b -> [Refactoring SrcSpan] -> Idea
suggest' String
msg (SrcSpan -> SrcSpanLess (LHsBind GhcPs) -> LHsBind GhcPs
forall a. HasSrcSpan a => SrcSpan -> SrcSpanLess a -> a
cL SrcSpan
loc SrcSpanLess (LHsBind GhcPs)
HsBindLR GhcPs GhcPs
o :: LHsBind GhcPs) (SrcSpanLess (LHsBind GhcPs) -> LHsBind GhcPs
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (XPatBind GhcPs GhcPs
-> Pat GhcPs
-> GRHSs GhcPs (LHsExpr GhcPs)
-> ([Tickish Id], [[Tickish Id]])
-> HsBindLR GhcPs GhcPs
forall idL idR.
XPatBind idL idR
-> LPat idL
-> GRHSs idR (LHsExpr idR)
-> ([Tickish Id], [[Tickish Id]])
-> HsBindLR idL idR
PatBind NoExt
XPatBind GhcPs GhcPs
noExt Pat GhcPs
pat GRHSs GhcPs (LHsExpr GhcPs)
rhs ([], [])) :: LHsBind GhcPs) [Refactoring SrcSpan]
rs)]
decl (FunBind _ _ (MG _ (LL _ xs :: SrcSpanLess (Located [LMatch GhcPs (LHsExpr GhcPs)])
xs) _) _ _) = (LMatch GhcPs (LHsExpr GhcPs)
-> (Pattern, String -> Pattern -> [Refactoring SrcSpan] -> Idea))
-> [LMatch GhcPs (LHsExpr GhcPs)]
-> [(Pattern, String -> Pattern -> [Refactoring SrcSpan] -> Idea)]
forall a b. (a -> b) -> [a] -> [b]
map LMatch GhcPs (LHsExpr GhcPs)
-> (Pattern, String -> Pattern -> [Refactoring SrcSpan] -> Idea)
match [LMatch GhcPs (LHsExpr GhcPs)]
SrcSpanLess (Located [LMatch GhcPs (LHsExpr GhcPs)])
xs
decl _ = []
match :: LMatch GhcPs (LHsExpr GhcPs) -> (Pattern, String -> Pattern -> [Refactoring R.SrcSpan] -> Idea)
match :: LMatch GhcPs (LHsExpr GhcPs)
-> (Pattern, String -> Pattern -> [Refactoring SrcSpan] -> Idea)
match o :: LMatch GhcPs (LHsExpr GhcPs)
o@(LL loc :: SrcSpan
loc (Match _ ctx pats grhss)) = (SrcSpan
-> RType -> [Pat GhcPs] -> GRHSs GhcPs (LHsExpr GhcPs) -> Pattern
Pattern SrcSpan
loc RType
R.Match [Pat GhcPs]
pats GRHSs GhcPs (LHsExpr GhcPs)
grhss, \msg :: String
msg (Pattern _ _ pats :: [Pat GhcPs]
pats grhss :: GRHSs GhcPs (LHsExpr GhcPs)
grhss) rs :: [Refactoring SrcSpan]
rs -> String
-> LMatch GhcPs (LHsExpr GhcPs)
-> LMatch GhcPs (LHsExpr GhcPs)
-> [Refactoring SrcSpan]
-> Idea
forall a b.
(HasSrcSpan a, Outputable a, HasSrcSpan b, Outputable b) =>
String -> a -> b -> [Refactoring SrcSpan] -> Idea
suggest' String
msg LMatch GhcPs (LHsExpr GhcPs)
o (SrcSpanLess (LMatch GhcPs (LHsExpr GhcPs))
-> LMatch GhcPs (LHsExpr GhcPs)
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (XCMatch GhcPs (LHsExpr GhcPs)
-> HsMatchContext (NameOrRdrName (IdP GhcPs))
-> [Pat GhcPs]
-> GRHSs GhcPs (LHsExpr GhcPs)
-> Match GhcPs (LHsExpr GhcPs)
forall p body.
XCMatch p body
-> HsMatchContext (NameOrRdrName (IdP p))
-> [LPat p]
-> GRHSs p body
-> Match p body
Match NoExt
XCMatch GhcPs (LHsExpr GhcPs)
noExt HsMatchContext (NameOrRdrName (IdP GhcPs))
ctx [Pat GhcPs]
pats GRHSs GhcPs (LHsExpr GhcPs)
grhss) :: LMatch GhcPs (LHsExpr GhcPs)) [Refactoring SrcSpan]
rs)
match _ = (Pattern, String -> Pattern -> [Refactoring SrcSpan] -> Idea)
forall a. HasCallStack => a
undefined
asPattern _ = []
patHint :: Bool -> Bool -> Pat GhcPs -> [Idea]
patHint :: Bool -> Bool -> Pat GhcPs -> [Idea]
patHint _ _ o :: Pat GhcPs
o@(LL _ (ConPatIn name (PrefixCon args)))
| [Pat GhcPs] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Pat GhcPs]
args Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= 3 Bool -> Bool -> Bool
&& (Pat GhcPs -> Bool) -> [Pat GhcPs] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Pat GhcPs -> Bool
isPWildCard' [Pat GhcPs]
args =
let rec_fields :: HsRecFields GhcPs (Pat GhcPs)
rec_fields = [LHsRecField GhcPs (Pat GhcPs)]
-> Maybe Int -> HsRecFields GhcPs (Pat GhcPs)
forall p arg. [LHsRecField p arg] -> Maybe Int -> HsRecFields p arg
HsRecFields [] Maybe Int
forall a. Maybe a
Nothing :: HsRecFields GhcPs (Pat GhcPs)
new :: Pat GhcPs
new = Located (IdP GhcPs) -> HsConPatDetails GhcPs -> Pat GhcPs
forall p. Located (IdP p) -> HsConPatDetails p -> Pat p
ConPatIn Located (IdP GhcPs)
name (HsRecFields GhcPs (Pat GhcPs) -> HsConPatDetails GhcPs
forall arg rec. rec -> HsConDetails arg rec
RecCon HsRecFields GhcPs (Pat GhcPs)
rec_fields) :: Pat GhcPs
in
[String -> Pat GhcPs -> Pat GhcPs -> [Refactoring SrcSpan] -> Idea
forall a b.
(HasSrcSpan a, Outputable a, HasSrcSpan b, Outputable b) =>
String -> a -> b -> [Refactoring SrcSpan] -> Idea
suggest' "Use record patterns" Pat GhcPs
o Pat GhcPs
new [RType
-> SrcSpan -> [(String, SrcSpan)] -> String -> Refactoring SrcSpan
forall a. RType -> a -> [(String, a)] -> String -> Refactoring a
Replace RType
R.Pattern (Pat GhcPs -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' Pat GhcPs
o) [] (Pat GhcPs -> String
forall a. Outputable a => a -> String
unsafePrettyPrint Pat GhcPs
new)]]
patHint _ _ o :: Pat GhcPs
o@(LL _ (VarPat _ (L _ name)))
| OccName -> String
occNameString (RdrName -> OccName
rdrNameOcc RdrName
IdP GhcPs
name) String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== "otherwise" =
[String -> Pat GhcPs -> Pat GhcPs -> [Refactoring SrcSpan] -> Idea
forall a b.
(HasSrcSpan a, Outputable a, HasSrcSpan b, Outputable b) =>
String -> a -> b -> [Refactoring SrcSpan] -> Idea
warn' "Used otherwise as a pattern" Pat GhcPs
o (SrcSpanLess (Pat GhcPs) -> Pat GhcPs
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (XWildPat GhcPs -> Pat GhcPs
forall p. XWildPat p -> Pat p
WildPat NoExt
XWildPat GhcPs
noExt) :: Pat GhcPs) []]
patHint lang :: Bool
lang strict :: Bool
strict o :: Pat GhcPs
o@(LL _ (BangPat _ (LL _ x)))
| Bool
strict, Pat GhcPs -> Bool
f SrcSpanLess (Pat GhcPs)
Pat GhcPs
x = [String -> Pat GhcPs -> Pat GhcPs -> [Refactoring SrcSpan] -> Idea
forall a b.
(HasSrcSpan a, Outputable a, HasSrcSpan b, Outputable b) =>
String -> a -> b -> [Refactoring SrcSpan] -> Idea
warn' "Redundant bang pattern" Pat GhcPs
o SrcSpanLess (Pat GhcPs)
Pat GhcPs
x [Refactoring SrcSpan
r]]
where
f :: Pat GhcPs -> Bool
f :: Pat GhcPs -> Bool
f (ParPat _ (LL _ x :: SrcSpanLess (Pat GhcPs)
x)) = Pat GhcPs -> Bool
f SrcSpanLess (Pat GhcPs)
Pat GhcPs
x
f (AsPat _ _ (LL _ x :: SrcSpanLess (Pat GhcPs)
x)) = Pat GhcPs -> Bool
f SrcSpanLess (Pat GhcPs)
Pat GhcPs
x
f LitPat {} = Bool
True
f NPat {} = Bool
True
f ConPatIn {} = Bool
True
f TuplePat {} = Bool
True
f ListPat {} = Bool
True
f (SigPat _ (LL _ p :: SrcSpanLess (Pat GhcPs)
p) _) = Pat GhcPs -> Bool
f SrcSpanLess (Pat GhcPs)
Pat GhcPs
p
f _ = Bool
False
r :: Refactoring SrcSpan
r = RType
-> SrcSpan -> [(String, SrcSpan)] -> String -> Refactoring SrcSpan
forall a. RType -> a -> [(String, a)] -> String -> Refactoring a
Replace RType
R.Pattern (Pat GhcPs -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' Pat GhcPs
o) [("x", SrcSpanLess (Pat GhcPs) -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' SrcSpanLess (Pat GhcPs)
x)] "x"
patHint False _ o :: Pat GhcPs
o@(LL _ (LazyPat _ (LL _ x)))
| Pat GhcPs -> Bool
f SrcSpanLess (Pat GhcPs)
Pat GhcPs
x = [String -> Pat GhcPs -> Pat GhcPs -> [Refactoring SrcSpan] -> Idea
forall a b.
(HasSrcSpan a, Outputable a, HasSrcSpan b, Outputable b) =>
String -> a -> b -> [Refactoring SrcSpan] -> Idea
warn' "Redundant irrefutable pattern" Pat GhcPs
o SrcSpanLess (Pat GhcPs)
Pat GhcPs
x [Refactoring SrcSpan
r]]
where
f :: Pat GhcPs -> Bool
f :: Pat GhcPs -> Bool
f (ParPat _ (LL _ x :: SrcSpanLess (Pat GhcPs)
x)) = Pat GhcPs -> Bool
f SrcSpanLess (Pat GhcPs)
Pat GhcPs
x
f (AsPat _ _ (LL _ x :: SrcSpanLess (Pat GhcPs)
x)) = Pat GhcPs -> Bool
f SrcSpanLess (Pat GhcPs)
Pat GhcPs
x
f WildPat{} = Bool
True
f VarPat{} = Bool
True
f _ = Bool
False
r :: Refactoring SrcSpan
r = RType
-> SrcSpan -> [(String, SrcSpan)] -> String -> Refactoring SrcSpan
forall a. RType -> a -> [(String, a)] -> String -> Refactoring a
Replace RType
R.Pattern (Pat GhcPs -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' Pat GhcPs
o) [("x", SrcSpanLess (Pat GhcPs) -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' SrcSpanLess (Pat GhcPs)
x)] "x"
patHint _ _ o :: Pat GhcPs
o@(LL _ (AsPat _ v (LL _ (WildPat _)))) =
[String
-> Pat GhcPs -> Located RdrName -> [Refactoring SrcSpan] -> Idea
forall a b.
(HasSrcSpan a, Outputable a, HasSrcSpan b, Outputable b) =>
String -> a -> b -> [Refactoring SrcSpan] -> Idea
warn' "Redundant as-pattern" Pat GhcPs
o Located RdrName
Located (IdP GhcPs)
v []]
patHint _ _ _ = []
expHint :: LHsExpr GhcPs -> [Idea]
expHint :: LHsExpr GhcPs -> [Idea]
expHint o :: LHsExpr GhcPs
o@(LL _ (HsCase _ _ (MG _ (L _ [LL _ (Match _ CaseAlt [LL _ (WildPat _)] (GRHSs _ [LL _ (GRHS _ [] e)] (LL _ (EmptyLocalBinds _)))) ]) FromSource ))) =
[String
-> LHsExpr GhcPs -> LHsExpr GhcPs -> [Refactoring SrcSpan] -> Idea
forall a b.
(HasSrcSpan a, Outputable a, HasSrcSpan b, Outputable b) =>
String -> a -> b -> [Refactoring SrcSpan] -> Idea
suggest' "Redundant case" LHsExpr GhcPs
o LHsExpr GhcPs
e [Refactoring SrcSpan
r]]
where
r :: Refactoring SrcSpan
r = RType
-> SrcSpan -> [(String, SrcSpan)] -> String -> Refactoring SrcSpan
forall a. RType -> a -> [(String, a)] -> String -> Refactoring a
Replace RType
Expr (LHsExpr GhcPs -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' LHsExpr GhcPs
o) [("x", LHsExpr GhcPs -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' LHsExpr GhcPs
e)] "x"
expHint o :: LHsExpr GhcPs
o@(LL _ (HsCase _ (LL _ (HsVar _ (L _ x))) (MG _ (L _ [LL _ (Match _ CaseAlt [LL _ (VarPat _ (L _ y))] (GRHSs _ [LL _ (GRHS _ [] e)] (LL _ (EmptyLocalBinds _)))) ]) FromSource )))
| OccName -> String
occNameString (RdrName -> OccName
rdrNameOcc RdrName
IdP GhcPs
x) String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== OccName -> String
occNameString (RdrName -> OccName
rdrNameOcc RdrName
IdP GhcPs
y) =
[String
-> LHsExpr GhcPs -> LHsExpr GhcPs -> [Refactoring SrcSpan] -> Idea
forall a b.
(HasSrcSpan a, Outputable a, HasSrcSpan b, Outputable b) =>
String -> a -> b -> [Refactoring SrcSpan] -> Idea
suggest' "Redundant case" LHsExpr GhcPs
o LHsExpr GhcPs
e [Refactoring SrcSpan
r]]
where
r :: Refactoring SrcSpan
r = RType
-> SrcSpan -> [(String, SrcSpan)] -> String -> Refactoring SrcSpan
forall a. RType -> a -> [(String, a)] -> String -> Refactoring a
Replace RType
Expr (LHsExpr GhcPs -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' LHsExpr GhcPs
o) [("x", LHsExpr GhcPs -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' LHsExpr GhcPs
e)] "x"
expHint _ = []