module Hint.Bracket where
import Type
import Hint
import HSE.All
import Data.Maybe
bracketHint :: DeclHint
bracketHint _ _ x =
concatMap (\x -> bracket True x ++ dollar x) (childrenBi x :: [Exp_]) ++
concatMap (bracket False) (childrenBi x :: [Type_]) ++
concatMap (bracket False) (childrenBi x :: [Pat_])
bracket :: (Annotated a, Uniplate (a S), Pretty (a S), Brackets (a S)) => Bool -> a S -> [Idea]
bracket bad = f Nothing
where
msg = "Redundant bracket"
f Just{} o@(remParen -> Just x) | isAtom x = err msg o x : g x
f Nothing o@(remParen -> Just x) | bad = warn msg o x : g x
f (Just (i,o,gen)) (remParen -> Just x) | not $ needBracket i o x = warn msg o (gen x) : g x
f _ x = g x
g :: (Annotated a, Uniplate (a S), Pretty (a S), Brackets (a S)) => a S -> [Idea]
g o = concat [f (Just (i,o,gen)) x | (i,(x,gen)) <- zip [0..] $ holes o]
dollar :: Exp_ -> [Idea]
dollar = concatMap f . universe
where
msg = warn "Redundant $"
f x = [msg x y | InfixApp _ a d b <- [x], opExp d ~= "$"
,let y = App an a b, not $ needBracket 0 y a, not $ needBracket 1 y b]
++
[msg x (t y) |(t, Paren _ (InfixApp _ a1 op1 a2)) <- infixes x
,opExp op1 ~= "$", isVar a1 || isApp a1 || isParen a1, not $ isAtom a2
,let y = App an a1 (Paren an a2)]
infixes :: Exp_ -> [(Exp_ -> Exp_, Exp_)]
infixes (InfixApp s a b c) = [(InfixApp s a b, c), (\a -> InfixApp s a b c, a)]
infixes _ = []