Skip to content

Commit 9a2f372

Browse files
isovectorjneira
andauthored
Don't insert parentheses for top-level tactics holes (#1352)
* More tests of overlapping methods * Do a simplification pass of the extract * Do less work when simplifiying * Remove unnecessary parens simplification * Implement simplify as a fold over endos * Fix tests * Haddock for the new module * Minor note on implementation * Note a TODO * Use PatCompat to unpack patterns * Pull out codegen utilities to break a cyclic dependency * Re-export utils * No top-level parens for tactics * Try a different strategy for generalizing PatCompat * Could this be the answer we've all been waiting for? * Try, try again to compat * Reorganize imports * Fix test Co-authored-by: Javier Neira <[email protected]>
1 parent f17f425 commit 9a2f372

26 files changed

+96
-80
lines changed

ghcide/src/Development/IDE/GHC/ExactPrint.hs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
module Development.IDE.GHC.ExactPrint
99
( Graft(..),
1010
graft,
11+
graftWithoutParentheses,
1112
graftDecls,
1213
graftDeclsWithM,
1314
annotate,
@@ -179,8 +180,18 @@ graft ::
179180
SrcSpan ->
180181
Located ast ->
181182
Graft (Either String) a
182-
graft dst val = Graft $ \dflags a -> do
183-
(anns, val') <- annotate dflags $ maybeParensAST val
183+
graft dst = graftWithoutParentheses dst . maybeParensAST
184+
185+
-- | Like 'graft', but trusts that you have correctly inserted the parentheses
186+
-- yourself. If you haven't, the resulting AST will not be valid!
187+
graftWithoutParentheses ::
188+
forall ast a.
189+
(Data a, ASTElement ast) =>
190+
SrcSpan ->
191+
Located ast ->
192+
Graft (Either String) a
193+
graftWithoutParentheses dst val = Graft $ \dflags a -> do
194+
(anns, val') <- annotate dflags val
184195
modifyAnnsT $ mappend anns
185196
pure $
186197
everywhere'

plugins/hls-tactics-plugin/src/Ide/Plugin/Tactic.hs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import Control.Monad.Error.Class (MonadError(throwError))
2121
import Control.Monad.Trans
2222
import Control.Monad.Trans.Maybe
2323
import Data.Aeson
24+
import Data.Bool (bool)
2425
import Data.Coerce
2526
import Data.Functor ((<&>))
2627
import Data.Generics.Aliases (mkQ)
@@ -39,7 +40,8 @@ import Development.IDE.Core.Service (runAction)
3940
import Development.IDE.Core.Shake (useWithStale, IdeState (..))
4041
import Development.IDE.GHC.Compat
4142
import Development.IDE.GHC.Error (realSrcSpanToRange)
42-
import Development.IDE.GHC.ExactPrint (graft, transform, useAnnotatedSource)
43+
import Development.IDE.GHC.ExactPrint (graft, transform, useAnnotatedSource, maybeParensAST)
44+
import Development.IDE.GHC.ExactPrint (graftWithoutParentheses)
4345
import Development.IDE.Spans.LocalBindings (getDefiningBindings)
4446
import Development.Shake (Action)
4547
import DynFlags (xopt)
@@ -327,8 +329,11 @@ tacticCmd tac lf state (TacticParams uri range var_name)
327329
$ ResponseError InvalidRequest (T.pack $ show err) Nothing
328330
Right rtr -> do
329331
traceMX "solns" $ rtr_other_solns rtr
330-
traceMX "after simplification" $ rtr_extract rtr
331-
let g = graft (RealSrcSpan span) $ rtr_extract rtr
332+
traceMX "simplified" $ rtr_extract rtr
333+
let g = graftWithoutParentheses (RealSrcSpan span)
334+
-- Parenthesize the extract iff we're not in a top level hole
335+
$ bool maybeParensAST id (_jIsTopHole jdg)
336+
$ rtr_extract rtr
332337
response = transform dflags (clientCapabilities lf) uri g pm
333338
pure $ case response of
334339
Right res -> (Right Null , Just (WorkspaceApplyEdit, ApplyWorkspaceEditParams res))
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
fgmap :: (Functor f, Functor g) => (a -> b) -> (f (g a) -> f (g b))
2-
fgmap = (fmap . fmap)
2+
fgmap = fmap . fmap
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
fmapBoth :: (Functor f, Functor g) => (a -> b) -> (f a, g a) -> (f b, g b)
2-
fmapBoth = (\ fab p_faga
3-
-> case p_faga of { (fa, ga) -> (fmap fab fa, fmap fab ga) })
2+
fmapBoth = \ fab p_faga
3+
-> case p_faga of { (fa, ga) -> (fmap fab fa, fmap fab ga) }
44

test/testdata/tactic/GoldenArbitrary.hs.expected

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,31 @@ data Obj
2222

2323

2424
arbitrary :: Gen Obj
25-
arbitrary = (let
26-
terminal
27-
= [(Square <$> arbitrary) <*> arbitrary, Circle <$> arbitrary,
28-
Polygon <$> arbitrary, pure Empty, pure Full]
29-
in
30-
sized
31-
$ (\ n
32-
-> case n <= 1 of
33-
True -> oneof terminal
34-
False
35-
-> oneof
36-
$ ([(Rotate2 <$> arbitrary) <*> scale (subtract 1) arbitrary,
37-
Complement <$> scale (subtract 1) arbitrary,
38-
(UnionR <$> arbitrary) <*> scale (subtract 1) arbitrary,
39-
((DifferenceR <$> arbitrary) <*> scale (flip div 2) arbitrary)
40-
<*> scale (flip div 2) arbitrary,
41-
(IntersectR <$> arbitrary) <*> scale (subtract 1) arbitrary,
42-
((Translate <$> arbitrary) <*> arbitrary)
43-
<*> scale (subtract 1) arbitrary,
44-
((Scale <$> arbitrary) <*> arbitrary)
45-
<*> scale (subtract 1) arbitrary,
46-
((Mirror <$> arbitrary) <*> arbitrary)
47-
<*> scale (subtract 1) arbitrary,
48-
(Outset <$> arbitrary) <*> scale (subtract 1) arbitrary,
49-
(Shell <$> arbitrary) <*> scale (subtract 1) arbitrary,
50-
(WithRounding <$> arbitrary) <*> scale (subtract 1) arbitrary]
51-
<> terminal)))
25+
arbitrary = let
26+
terminal
27+
= [(Square <$> arbitrary) <*> arbitrary, Circle <$> arbitrary,
28+
Polygon <$> arbitrary, pure Empty, pure Full]
29+
in
30+
sized
31+
$ (\ n
32+
-> case n <= 1 of
33+
True -> oneof terminal
34+
False
35+
-> oneof
36+
$ ([(Rotate2 <$> arbitrary) <*> scale (subtract 1) arbitrary,
37+
Complement <$> scale (subtract 1) arbitrary,
38+
(UnionR <$> arbitrary) <*> scale (subtract 1) arbitrary,
39+
((DifferenceR <$> arbitrary) <*> scale (flip div 2) arbitrary)
40+
<*> scale (flip div 2) arbitrary,
41+
(IntersectR <$> arbitrary) <*> scale (subtract 1) arbitrary,
42+
((Translate <$> arbitrary) <*> arbitrary)
43+
<*> scale (subtract 1) arbitrary,
44+
((Scale <$> arbitrary) <*> arbitrary)
45+
<*> scale (subtract 1) arbitrary,
46+
((Mirror <$> arbitrary) <*> arbitrary)
47+
<*> scale (subtract 1) arbitrary,
48+
(Outset <$> arbitrary) <*> scale (subtract 1) arbitrary,
49+
(Shell <$> arbitrary) <*> scale (subtract 1) arbitrary,
50+
(WithRounding <$> arbitrary) <*> scale (subtract 1) arbitrary]
51+
<> terminal))
5252

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
-- There used to be a bug where we were unable to perform a nested split. The
22
-- more serious regression test of this is 'AutoTupleSpec'.
33
bigTuple :: (a, b, c, d) -> (a, b, (c, d))
4-
bigTuple = (\ pabcd -> case pabcd of { (a, b, c, d) -> (a, b, (c, d)) })
4+
bigTuple = \ pabcd -> case pabcd of { (a, b, c, d) -> (a, b, (c, d)) }
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
either' :: (a -> c) -> (b -> c) -> Either a b -> c
2-
either' = (\ fac fbc eab
3-
-> case eab of
4-
(Left a) -> fac a
5-
(Right b) -> fbc b)
2+
either' = \ fac fbc eab
3+
-> case eab of
4+
(Left a) -> fac a
5+
(Right b) -> fbc b
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
eitherSplit :: a -> Either (a -> b) (a -> c) -> Either b c
2-
eitherSplit = (\ a efabfac
3-
-> case efabfac of
4-
(Left fab) -> Left (fab a)
5-
(Right fac) -> Right (fac a))
2+
eitherSplit = \ a efabfac
3+
-> case efabfac of
4+
(Left fab) -> Left (fab a)
5+
(Right fac) -> Right (fac a)
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
data Tree a = Leaf a | Branch (Tree a) (Tree a)
22

33
instance Functor Tree where
4-
fmap = (\ fab ta
5-
-> case ta of
6-
(Leaf a) -> Leaf (fab a)
7-
(Branch ta2 ta3) -> Branch (fmap fab ta2) (fmap fab ta3))
4+
fmap = \ fab ta
5+
-> case ta of
6+
(Leaf a) -> Leaf (fab a)
7+
(Branch ta2 ta3) -> Branch (fmap fab ta2) (fmap fab ta3)
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
foldr2 :: (a -> b -> b) -> b -> [a] -> b
2-
foldr2 = (\ f_b b l_a
3-
-> case l_a of
4-
[] -> b
5-
(a : l_a4) -> f_b a (foldr2 f_b b l_a4))
2+
foldr2 = \ f_b b l_a
3+
-> case l_a of
4+
[] -> b
5+
(a : l_a4) -> f_b a (foldr2 f_b b l_a4)
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
fromMaybe :: a -> Maybe a -> a
2-
fromMaybe = (\ a ma
3-
-> case ma of
4-
Nothing -> a
5-
(Just a2) -> a2)
2+
fromMaybe = \ a ma
3+
-> case ma of
4+
Nothing -> a
5+
(Just a2) -> a2

test/testdata/tactic/GoldenGADTAuto.hs.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ data CtxGADT a where
44
MkCtxGADT :: (Show a, Eq a) => a -> CtxGADT a
55

66
ctxGADT :: CtxGADT ()
7-
ctxGADT = (MkCtxGADT ())
7+
ctxGADT = MkCtxGADT ()

test/testdata/tactic/GoldenGADTDestruct.hs.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ data CtxGADT where
44
MkCtxGADT :: (Show a, Eq a) => a -> CtxGADT
55

66
ctxGADT :: CtxGADT -> String
7-
ctxGADT gadt = (case gadt of { (MkCtxGADT a) -> _ })
7+
ctxGADT gadt = case gadt of { (MkCtxGADT a) -> _ }

test/testdata/tactic/GoldenGADTDestructCoercion.hs.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ data E a b where
55
E :: forall a b. (b ~ a, Ord a) => b -> E a [a]
66

77
ctxGADT :: E a b -> String
8-
ctxGADT gadt = (case gadt of { (E b) -> _ })
8+
ctxGADT gadt = case gadt of { (E b) -> _ }
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
data Ident a = Ident a
22
instance Functor Ident where
3-
fmap = (\ fab ia -> case ia of { (Ident a) -> Ident (fab a) })
3+
fmap = \ fab ia -> case ia of { (Ident a) -> Ident (fab a) }
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
blah :: Int -> Bool -> (a -> b) -> String -> Int
2-
blah = (\ i b fab l_c -> _)
2+
blah = \ i b fab l_c -> _
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
type Cont r a = ((a -> r) -> r)
22

33
joinCont :: Cont r (Cont r a) -> Cont r a
4-
joinCont = (\ f_r far -> f_r (\ f_r2 -> f_r2 far))
4+
joinCont = \ f_r far -> f_r (\ f_r2 -> f_r2 far)
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
fmapList :: (a -> b) -> [a] -> [b]
2-
fmapList = (\ fab l_a
3-
-> case l_a of
4-
[] -> []
5-
(a : l_a3) -> fab a : fmapList fab l_a3)
2+
fmapList = \ fab l_a
3+
-> case l_a of
4+
[] -> []
5+
(a : l_a3) -> fab a : fmapList fab l_a3
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
note :: e -> Maybe a -> Either e a
2-
note = (\ e ma
3-
-> case ma of
4-
Nothing -> Left e
5-
(Just a) -> Right a)
2+
note = \ e ma
3+
-> case ma of
4+
Nothing -> Left e
5+
(Just a) -> Right a
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
pureList :: a -> [a]
2-
pureList = (\ a -> a : [])
2+
pureList = \ a -> a : []
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
safeHead :: [x] -> Maybe x
2-
safeHead = (\ l_x
3-
-> case l_x of
4-
[] -> Nothing
5-
(x : l_x2) -> Just x)
2+
safeHead = \ l_x
3+
-> case l_x of
4+
[] -> Nothing
5+
(x : l_x2) -> Just x
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
showCompose :: Show a => (b -> a) -> b -> String
2-
showCompose = (\ fba -> show . fba)
2+
showCompose = \ fba -> show . fba
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
test :: Show a => a -> (String -> b) -> b
2-
test = (\ a fl_cb -> fl_cb (show a))
2+
test = \ a fl_cb -> fl_cb (show a)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
swap :: (a, b) -> (b, a)
2-
swap = (\ p_ab -> case p_ab of { (a, b) -> (b, a) })
2+
swap = \ p_ab -> case p_ab of { (a, b) -> (b, a) }
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
swapMany :: (a, b, c, d, e) -> (e, d, c, b, a)
2-
swapMany = (\ pabcde -> case pabcde of { (a, b, c, d, e) -> (e, d, c, b, a) })
2+
swapMany = \ pabcde -> case pabcde of { (a, b, c, d, e) -> (e, d, c, b, a) }

test/testdata/tactic/RecordCon.hs.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ data MyRecord a = Record
44
}
55

66
blah :: (a -> Int) -> a -> MyRecord a
7-
blah = (\ fai a -> Record {field1 = a, field2 = fai a})
7+
blah = \ fai a -> Record {field1 = a, field2 = fai a}
88

99

0 commit comments

Comments
 (0)