Skip to content

Commit d98af68

Browse files
committed
Switch to normal field selectors and generic-lens
This adopts the approach discussed here: #465 (comment) That is: - We export normal, non-prefixed record selectors (still using `DuplicateRecordFields`, of course). - Users who want lenses can use `generic-lens`; `lsp` and `lsp-test` do this. - It's sensible for `lsp-types` to define some useful lenses that aren't derived from fields; these go in a `lsp-types-lens` component. I think the result is... fine? kcsongor/generic-lens#96 is a pain in some cases, but by and large using the generic lenses is quite nice. I also tried to just use `OverloadedRecordDot` instead of lenses where I could, since we now support 9.2 as our earliest version. I couldn't quite get rid of `lens` in `lsp`, it's too useful. I did get rid of it entirely in `lsp-types`, which was quite painful in at least one place. This would obviously be a huge breaking change, but I think it's the right direction.
1 parent f1c17c3 commit d98af68

File tree

402 files changed

+2000
-2031
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

402 files changed

+2000
-2031
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ hie
2121
hie.yaml
2222
.envrc
2323
**/.golden/*/actual
24+
.jj

lsp-test/bench/SimpleBench.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ main = do
6161
replicateM_ n $ do
6262
v <- liftIO $ readIORef i
6363
liftIO $ when (v `mod` 1000 == 0) $ putStrLn $ show v
64-
TResponseMessage{_result = Right (InL _)} <-
64+
TResponseMessage{result = Right (InL _)} <-
6565
Test.request SMethod_TextDocumentHover $
6666
HoverParams (TextDocumentIdentifier $ Uri "test") (Position 1 100) Nothing
67-
TResponseMessage{_result = Right (InL _)} <-
67+
TResponseMessage{result = Right (InL _)} <-
6868
Test.request SMethod_TextDocumentDefinition $
6969
DefinitionParams (TextDocumentIdentifier $ Uri "test") (Position 1000 100) Nothing Nothing
7070

lsp-test/func-test/FuncTest.hs

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
{-# LANGUAGE DataKinds #-}
2+
{-# LANGUAGE DuplicateRecordFields #-}
23
{-# LANGUAGE GADTs #-}
4+
{-# LANGUAGE OverloadedLabels #-}
35
{-# LANGUAGE OverloadedStrings #-}
46
{-# LANGUAGE ViewPatterns #-}
57

@@ -14,10 +16,13 @@ import Control.Lens hiding (Iso, List)
1416
import Control.Monad
1517
import Control.Monad.IO.Class
1618
import Data.Aeson qualified as J
19+
import Data.Generics.Labels ()
20+
import Data.Generics.Product.Fields (field')
1721
import Data.Maybe
1822
import Data.Proxy
19-
import Language.LSP.Protocol.Lens qualified as L
20-
import Language.LSP.Protocol.Message
23+
import Data.Set qualified as Set
24+
import Language.LSP.Protocol.Lens
25+
import Language.LSP.Protocol.Message hiding (error)
2126
import Language.LSP.Protocol.Types
2227
import Language.LSP.Server
2328
import Language.LSP.Test qualified as Test
@@ -90,36 +95,36 @@ spec = do
9095
-- has happened and the server has been able to send us a begin message
9196
skipManyTill Test.anyMessage $ do
9297
x <- Test.message SMethod_Progress
93-
guard $ has (L.params . L.value . _workDoneProgressBegin) x
98+
guard $ has (field' @"params" . #value . workDoneProgressBegin) x
9499

95100
-- allow the hander to send us updates
96101
liftIO $ signalBarrier startBarrier ()
97102

98103
do
99104
u <- Test.message SMethod_Progress
100105
liftIO $ do
101-
u ^? L.params . L.value . _workDoneProgressReport . L.message `shouldBe` Just (Just "step1")
102-
u ^? L.params . L.value . _workDoneProgressReport . L.percentage `shouldBe` Just (Just 25)
106+
u ^? field' @"params" . #value . workDoneProgressReport . #message `shouldBe` Just (Just "step1")
107+
u ^? field' @"params" . #value . workDoneProgressReport . #percentage `shouldBe` Just (Just 25)
103108
liftIO $ signalBarrier b1 ()
104109

105110
do
106111
u <- Test.message SMethod_Progress
107112
liftIO $ do
108-
u ^? L.params . L.value . _workDoneProgressReport . L.message `shouldBe` Just (Just "step2")
109-
u ^? L.params . L.value . _workDoneProgressReport . L.percentage `shouldBe` Just (Just 50)
113+
u ^? field' @"params" . #value . workDoneProgressReport . #message `shouldBe` Just (Just "step2")
114+
u ^? field' @"params" . #value . workDoneProgressReport . #percentage `shouldBe` Just (Just 50)
110115
liftIO $ signalBarrier b2 ()
111116

112117
do
113118
u <- Test.message SMethod_Progress
114119
liftIO $ do
115-
u ^? L.params . L.value . _workDoneProgressReport . L.message `shouldBe` Just (Just "step3")
116-
u ^? L.params . L.value . _workDoneProgressReport . L.percentage `shouldBe` Just (Just 75)
120+
u ^? field' @"params" . #value . workDoneProgressReport . #message `shouldBe` Just (Just "step3")
121+
u ^? field' @"params" . #value . workDoneProgressReport . #percentage `shouldBe` Just (Just 75)
117122
liftIO $ signalBarrier b3 ()
118123

119124
-- Then make sure we get a $/progress end notification
120125
skipManyTill Test.anyMessage $ do
121126
x <- Test.message SMethod_Progress
122-
guard $ has (L.params . L.value . _workDoneProgressEnd) x
127+
guard $ has (field' @"params" . #value . workDoneProgressEnd) x
123128

124129
it "handles cancellation" $ do
125130
wasCancelled <- newMVar False
@@ -150,19 +155,19 @@ spec = do
150155
-- Wait until we have created the progress so the updates will be sent individually
151156
token <- skipManyTill Test.anyMessage $ do
152157
x <- Test.message SMethod_WindowWorkDoneProgressCreate
153-
pure $ x ^. L.params . L.token
158+
pure $ x ^. field' @"params" . #token
154159

155160
-- First make sure that we get a $/progress begin notification
156161
skipManyTill Test.anyMessage $ do
157162
x <- Test.message SMethod_Progress
158-
guard $ has (L.params . L.value . _workDoneProgressBegin) x
163+
guard $ has (field' @"params" . #value . workDoneProgressBegin) x
159164

160165
Test.sendNotification SMethod_WindowWorkDoneProgressCancel (WorkDoneProgressCancelParams token)
161166

162167
-- Then make sure we still get a $/progress end notification
163168
skipManyTill Test.anyMessage $ do
164169
x <- Test.message SMethod_Progress
165-
guard $ has (L.params . L.value . _workDoneProgressEnd) x
170+
guard $ has (field' @"params" . #value . workDoneProgressEnd) x
166171

167172
c <- readMVar wasCancelled
168173
c `shouldBe` True
@@ -194,15 +199,15 @@ spec = do
194199
-- First make sure that we get a $/progress begin notification
195200
skipManyTill Test.anyMessage $ do
196201
x <- Test.message SMethod_Progress
197-
guard $ has (L.params . L.value . _workDoneProgressBegin) x
202+
guard $ has (field' @"params" . #value . workDoneProgressBegin) x
198203

199204
-- Then kill the thread
200205
liftIO $ putMVar killVar ()
201206

202207
-- Then make sure we still get a $/progress end notification
203208
skipManyTill Test.anyMessage $ do
204209
x <- Test.message SMethod_Progress
205-
guard $ has (L.params . L.value . _workDoneProgressEnd) x
210+
guard $ has (field' @"params" . #value . workDoneProgressEnd) x
206211

207212
describe "client-initiated progress reporting" $ do
208213
it "sends updates" $ do
@@ -226,7 +231,7 @@ spec = do
226231
handlers :: Handlers (LspM ())
227232
handlers =
228233
requestHandler SMethod_TextDocumentCodeLens $ \req resp -> void $ forkIO $ do
229-
withProgress "Doing something" (req ^. L.params . L.workDoneToken) NotCancellable $ \updater -> do
234+
withProgress "Doing something" (req ^. field' @"params" . #workDoneToken) NotCancellable $ \updater -> do
230235
liftIO $ waitBarrier startBarrier
231236
updater $ ProgressAmount (Just 25) (Just "step1")
232237
liftIO $ waitBarrier b1
@@ -241,35 +246,35 @@ spec = do
241246
-- First make sure that we get a $/progress begin notification
242247
skipManyTill Test.anyMessage $ do
243248
x <- Test.message SMethod_Progress
244-
guard $ has (L.params . L.value . _workDoneProgressBegin) x
249+
guard $ has (field' @"params" . #value . workDoneProgressBegin) x
245250

246251
liftIO $ signalBarrier startBarrier ()
247252

248253
do
249254
u <- Test.message SMethod_Progress
250255
liftIO $ do
251-
u ^? L.params . L.value . _workDoneProgressReport . L.message `shouldBe` Just (Just "step1")
252-
u ^? L.params . L.value . _workDoneProgressReport . L.percentage `shouldBe` Just (Just 25)
256+
u ^? field' @"params" . #value . workDoneProgressReport . #message `shouldBe` Just (Just "step1")
257+
u ^? field' @"params" . #value . workDoneProgressReport . #percentage `shouldBe` Just (Just 25)
253258
liftIO $ signalBarrier b1 ()
254259

255260
do
256261
u <- Test.message SMethod_Progress
257262
liftIO $ do
258-
u ^? L.params . L.value . _workDoneProgressReport . L.message `shouldBe` Just (Just "step2")
259-
u ^? L.params . L.value . _workDoneProgressReport . L.percentage `shouldBe` Just (Just 50)
263+
u ^? field' @"params" . #value . workDoneProgressReport . #message `shouldBe` Just (Just "step2")
264+
u ^? field' @"params" . #value . workDoneProgressReport . #percentage `shouldBe` Just (Just 50)
260265
liftIO $ signalBarrier b2 ()
261266

262267
do
263268
u <- Test.message SMethod_Progress
264269
liftIO $ do
265-
u ^? L.params . L.value . _workDoneProgressReport . L.message `shouldBe` Just (Just "step3")
266-
u ^? L.params . L.value . _workDoneProgressReport . L.percentage `shouldBe` Just (Just 75)
270+
u ^? field' @"params" . #value . workDoneProgressReport . #message `shouldBe` Just (Just "step3")
271+
u ^? field' @"params" . #value . workDoneProgressReport . #percentage `shouldBe` Just (Just 75)
267272
liftIO $ signalBarrier b3 ()
268273

269274
-- Then make sure we get a $/progress end notification
270275
skipManyTill Test.anyMessage $ do
271276
x <- Test.message SMethod_Progress
272-
guard $ has (L.params . L.value . _workDoneProgressEnd) x
277+
guard $ has (field' @"params" . #value . workDoneProgressEnd) x
273278

274279
describe "workspace folders" $
275280
it "keeps track of open workspace folders" $ do

lsp-test/lsp-test.cabal

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
cabal-version: 2.4
1+
cabal-version: 3.0
22
name: lsp-test
33
version: 0.17.1.0
44
synopsis: Functional test framework for LSP servers.
@@ -62,11 +62,13 @@ library
6262
, exceptions ^>=0.10
6363
, extra ^>=1.7
6464
, filepath >=1.4 && < 1.6
65+
, generic-lens ^>=2.2
6566
, Glob >=0.9 && <0.11
6667
, lens >=5.1 && <5.4
6768
, lens-aeson ^>=1.2
6869
, lsp ^>=2.7
6970
, lsp-types ^>=2.3
71+
, lsp-types:lsp-types-lens
7072
, mtl >=2.2 && <2.4
7173
, parser-combinators ^>=1.3
7274
, process ^>=1.6
@@ -108,6 +110,7 @@ test-suite tests
108110
, directory
109111
, extra
110112
, filepath
113+
, generic-lens
111114
, hspec
112115
, lens
113116
, lsp
@@ -128,11 +131,14 @@ test-suite func-test
128131
, base
129132
, aeson
130133
, co-log-core
134+
, containers
131135
, extra
136+
, generic-lens
132137
, hspec
133138
, lens
134139
, lsp
135140
, lsp-test
141+
, lsp-types:lsp-types-lens
136142
, parser-combinators
137143
, process
138144
, unliftio

0 commit comments

Comments
 (0)