Skip to content

Commit d4e2a6f

Browse files
authored
Wingman: Code lens for empty lambda case (#1956)
* Support empty lambdacase * Add test
1 parent 0d9ba15 commit d4e2a6f

File tree

6 files changed

+39
-4
lines changed

6 files changed

+39
-4
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ needsParensSpace ::
188188
-- | (Needs parens, needs space)
189189
(All, All)
190190
needsParensSpace HsLam{} = (All False, All False)
191-
needsParensSpace HsLamCase{} = (All False, All False)
191+
needsParensSpace HsLamCase{} = (All False, All True)
192192
needsParensSpace HsApp{} = mempty
193193
needsParensSpace HsAppType{} = mempty
194194
needsParensSpace OpApp{} = mempty

plugins/hls-tactics-plugin/src/Wingman/EmptyCase.hs

+20-3
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ codeLensProvider state plId (CodeLensParams _ _ (TextDocumentIdentifier uri))
9393
codeLensProvider _ _ _ = pure $ Right $ List []
9494

9595

96+
scrutinzedType :: EmptyCaseSort Type -> Maybe Type
97+
scrutinzedType (EmptyCase ty) = pure ty
98+
scrutinzedType (EmptyLamCase ty) =
99+
case tacticsSplitFunTy ty of
100+
(_, _, tys, _) -> listToMaybe tys
101+
102+
96103
------------------------------------------------------------------------------
97104
-- | The description for the empty case lens.
98105
mkEmptyCaseLensDesc :: Type -> T.Text
@@ -119,6 +126,8 @@ graftMatchGroup ss l =
119126
hoistGraft (runExcept . runExceptString) $ graftExprWithM ss $ \case
120127
L span (HsCase ext scrut mg@_) -> do
121128
pure $ Just $ L span $ HsCase ext scrut $ mg { mg_alts = l }
129+
L span (HsLamCase ext mg@_) -> do
130+
pure $ Just $ L span $ HsLamCase ext $ mg { mg_alts = l }
122131
(_ :: LHsExpr GhcPs) -> pure Nothing
123132

124133

@@ -142,18 +151,26 @@ emptyCaseScrutinees state nfp = do
142151

143152
let scrutinees = traverse (emptyCaseQ . tcg_binds) tcg
144153
for scrutinees $ \aged@(unTrack -> (ss, scrutinee)) -> do
145-
ty <- MaybeT $ typeCheck (hscEnv $ untrackedStaleValue hscenv) tcg' scrutinee
154+
ty <- MaybeT
155+
. fmap (scrutinzedType <=< sequence)
156+
. traverse (typeCheck (hscEnv $ untrackedStaleValue hscenv) tcg')
157+
$ scrutinee
146158
case ss of
147159
RealSrcSpan r -> do
148160
rss' <- liftMaybe $ mapAgeTo tcg_map $ unsafeCopyAge aged r
149161
pure (rss', ty)
150162
UnhelpfulSpan _ -> empty
151163

164+
data EmptyCaseSort a
165+
= EmptyCase a
166+
| EmptyLamCase a
167+
deriving (Eq, Ord, Show, Functor, Foldable, Traversable)
152168

153169
------------------------------------------------------------------------------
154170
-- | Get the 'SrcSpan' and scrutinee of every empty case.
155-
emptyCaseQ :: GenericQ [(SrcSpan, HsExpr GhcTc)]
171+
emptyCaseQ :: GenericQ [(SrcSpan, EmptyCaseSort (HsExpr GhcTc))]
156172
emptyCaseQ = everything (<>) $ mkQ mempty $ \case
157-
L new_span (Case scrutinee []) -> pure (new_span, scrutinee)
173+
L new_span (Case scrutinee []) -> pure (new_span, EmptyCase scrutinee)
174+
L new_span (expr@(LamCase [])) -> pure (new_span, EmptyLamCase expr)
158175
(_ :: LHsExpr GhcTc) -> mempty
159176

plugins/hls-tactics-plugin/src/Wingman/GHC.hs

+7
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,13 @@ pattern Case scrutinee matches <-
252252
HsCase _ (L _ scrutinee)
253253
(MG {mg_alts = L _ (fmap unLoc -> unpackMatches -> Just matches)})
254254

255+
------------------------------------------------------------------------------
256+
-- | Like 'Case', but for lambda cases.
257+
pattern LamCase :: PatCompattable p => [(Pat p, LHsExpr p)] -> HsExpr p
258+
pattern LamCase matches <-
259+
HsLamCase _
260+
(MG {mg_alts = L _ (fmap unLoc -> unpackMatches -> Just matches)})
261+
255262

256263
------------------------------------------------------------------------------
257264
-- | Can ths type be lambda-cased?

plugins/hls-tactics-plugin/test/CodeLens/EmptyCaseSpec.hs

+1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ spec = do
1717
test "EmptyCaseNested"
1818
test "EmptyCaseApply"
1919
test "EmptyCaseGADT"
20+
test "EmptyCaseLamCase"
2021

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{-# LANGUAGE LambdaCase #-}
2+
3+
test :: Bool -> Bool
4+
test = \case
5+
False -> _
6+
True -> _
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{-# LANGUAGE LambdaCase #-}
2+
3+
test :: Bool -> Bool
4+
test = \case

0 commit comments

Comments
 (0)