Skip to content

Commit 0fd2d64

Browse files
committed
internal/lsp/lsprpc: add an LSP forwarder and regtest environment
Add a new Forwarder type to the lsprpc package, which implements the jsonrpc2.StreamServer interface. This will be used to establish some parity in the implementation of shared and singleton gopls servers. Much more testing is needed, as is handling for the many edge cases around forwarding the LSP, but since this is functionally equivalent to TCP forwarding (and the -remote flag was already broken), I went ahead and used the Forwarder to replace the forward method in the serve command. This means that we can now use the combination of -listen and -remote to chain together gopls servers... not that there's any reason to do this. Also, wrap the new regression tests with a focus on expressiveness when testing the happy path, as well as parameterizing them so that they can be run against different client/server execution environments. This started to be sizable enough to warrant moving them to a separate regtest package. The lsprpc package tests will instead focus on unit testing the client-server binding logic. Updates golang/go#36879 Updates golang/go#34111 Change-Id: Ib98131a58aabc69299845d2ecefceccfc1199574 Reviewed-on: https://go-review.googlesource.com/c/tools/+/218698 Run-TryBot: Robert Findley <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Heschi Kreinick <[email protected]>
1 parent 98b3097 commit 0fd2d64

File tree

10 files changed

+651
-440
lines changed

10 files changed

+651
-440
lines changed

Diff for: internal/lsp/cmd/serve.go

+4-24
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import (
88
"context"
99
"flag"
1010
"fmt"
11-
"io"
12-
"net"
1311
"os"
1412

1513
"golang.org/x/tools/internal/jsonrpc2"
@@ -64,11 +62,13 @@ func (s *Serve) Run(ctx context.Context, args ...string) error {
6462
s.app.debug.Serve(ctx)
6563
s.app.debug.MonitorMemory(ctx)
6664

65+
var ss jsonrpc2.StreamServer
6766
if s.app.Remote != "" {
68-
return s.forward()
67+
ss = lsprpc.NewForwarder(s.app.Remote, true)
68+
} else {
69+
ss = lsprpc.NewStreamServer(cache.New(s.app.options), true)
6970
}
7071

71-
ss := lsprpc.NewStreamServer(cache.New(s.app.options), true)
7272
if s.Address != "" {
7373
return jsonrpc2.ListenAndServe(ctx, s.Address, ss)
7474
}
@@ -82,23 +82,3 @@ func (s *Serve) Run(ctx context.Context, args ...string) error {
8282
}
8383
return ss.ServeStream(ctx, stream)
8484
}
85-
86-
func (s *Serve) forward() error {
87-
conn, err := net.Dial("tcp", s.app.Remote)
88-
if err != nil {
89-
return err
90-
}
91-
errc := make(chan error)
92-
93-
go func(conn net.Conn) {
94-
_, err := io.Copy(conn, os.Stdin)
95-
errc <- err
96-
}(conn)
97-
98-
go func(conn net.Conn) {
99-
_, err := io.Copy(os.Stdout, conn)
100-
errc <- err
101-
}(conn)
102-
103-
return <-errc
104-
}

Diff for: internal/lsp/fake/edit.go

+10
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ type Edit struct {
3636
Text string
3737
}
3838

39+
// NewEdit creates an edit replacing all content between
40+
// (startLine, startColumn) and (endLine, endColumn) with text.
41+
func NewEdit(startLine, startColumn, endLine, endColumn int, text string) Edit {
42+
return Edit{
43+
Start: Pos{Line: startLine, Column: startColumn},
44+
End: Pos{Line: endLine, Column: endColumn},
45+
Text: text,
46+
}
47+
}
48+
3949
func (e Edit) toProtocolChangeEvent() protocol.TextDocumentContentChangeEvent {
4050
return protocol.TextDocumentContentChangeEvent{
4151
Range: &protocol.Range{

Diff for: internal/lsp/lsprpc/definition_test.go

-101
This file was deleted.

0 commit comments

Comments
 (0)