Skip to content

Commit 9febbbd

Browse files
committed
internal/lsp: error handling
1 parent 8dcb7bc commit 9febbbd

14 files changed

+197
-68
lines changed

internal/lsp/cache/file.go

+24-19
Original file line numberDiff line numberDiff line change
@@ -25,63 +25,68 @@ type File struct {
2525
}
2626

2727
// GetContent returns the contents of the file, reading it from file system if needed.
28-
func (f *File) GetContent() []byte {
28+
func (f *File) GetContent() ([]byte, error) {
2929
f.view.mu.Lock()
3030
defer f.view.mu.Unlock()
31-
f.read()
32-
return f.content
31+
if f.content != nil {
32+
return f.content, nil
33+
}
34+
content, err := f.read()
35+
if err != nil {
36+
return nil, err
37+
}
38+
f.content = content
39+
return f.content, nil
3340
}
3441

3542
func (f *File) GetFileSet() *token.FileSet {
3643
return f.view.Config.Fset
3744
}
3845

39-
func (f *File) GetToken() *token.File {
46+
func (f *File) GetToken() (*token.File, error) {
4047
f.view.mu.Lock()
4148
defer f.view.mu.Unlock()
4249
if f.token == nil {
4350
if err := f.view.parse(f.URI); err != nil {
44-
return nil
51+
return nil, err
4552
}
4653
}
47-
return f.token
54+
return f.token, nil
4855
}
4956

50-
func (f *File) GetAST() *ast.File {
57+
func (f *File) GetAST() (*ast.File, error) {
5158
f.view.mu.Lock()
5259
defer f.view.mu.Unlock()
5360
if f.ast == nil {
5461
if err := f.view.parse(f.URI); err != nil {
55-
return nil
62+
return nil, err
5663
}
5764
}
58-
return f.ast
65+
return f.ast, nil
5966
}
6067

61-
func (f *File) GetPackage() *packages.Package {
68+
func (f *File) GetPackage() (*packages.Package, error) {
6269
f.view.mu.Lock()
6370
defer f.view.mu.Unlock()
6471
if f.pkg == nil {
6572
if err := f.view.parse(f.URI); err != nil {
66-
return nil
73+
return nil, err
6774
}
6875
}
69-
return f.pkg
76+
return f.pkg, nil
7077
}
7178

7279
// read is the internal part of Read that presumes the lock is already held
73-
func (f *File) read() {
74-
if f.content != nil {
75-
return
76-
}
80+
func (f *File) read() ([]byte, error) {
7781
// we don't know the content yet, so read it
7882
filename, err := f.URI.Filename()
7983
if err != nil {
80-
return
84+
return nil, err
8185
}
8286
content, err := ioutil.ReadFile(filename)
8387
if err != nil {
84-
return
88+
return nil, err
8589
}
86-
f.content = content
90+
// f.content = content
91+
return content, nil
8792
}

internal/lsp/cmd/definition.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ func (d *definition) Run(ctx context.Context, args ...string) error {
6565
if err != nil {
6666
return err
6767
}
68-
tok := f.GetToken()
68+
tok, err := f.GetToken()
69+
if err != nil {
70+
return err
71+
}
6972
pos := tok.Pos(from.Start.Offset)
7073
ident, err := source.Identifier(ctx, view, f, pos)
7174
if err != nil {
@@ -115,7 +118,10 @@ func buildDefinition(view source.View, ident *source.IdentifierInfo) (*Definitio
115118

116119
func buildGuruDefinition(view source.View, ident *source.IdentifierInfo) (*guru.Definition, error) {
117120
loc := newLocation(view.FileSet(), ident.Declaration.Range)
118-
pkg := ident.File.GetPackage()
121+
pkg, err := ident.File.GetPackage()
122+
if err != nil {
123+
return nil, err
124+
}
119125
// guru does not support ranges
120126
loc.End = loc.Start
121127
// Behavior that attempts to match the expected output for guru. For an example

internal/lsp/diagnostics.go

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package lsp
66

77
import (
88
"context"
9+
"fmt"
910
"sort"
1011

1112
"golang.org/x/tools/internal/lsp/protocol"

internal/lsp/format.go

+22-7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package lsp
22

33
import (
44
"context"
5+
"errors"
56

67
"golang.org/x/tools/internal/lsp/protocol"
78
"golang.org/x/tools/internal/lsp/source"
@@ -17,7 +18,10 @@ func formatRange(ctx context.Context, v source.View, uri protocol.DocumentURI, r
1718
if err != nil {
1819
return nil, err
1920
}
20-
tok := f.GetToken()
21+
tok, err := f.GetToken()
22+
if err != nil {
23+
return nil, err
24+
}
2125
var r source.Range
2226
if rng == nil {
2327
r.Start = tok.Pos(0)
@@ -29,15 +33,26 @@ func formatRange(ctx context.Context, v source.View, uri protocol.DocumentURI, r
2933
if err != nil {
3034
return nil, err
3135
}
32-
return toProtocolEdits(f, edits), nil
36+
37+
protocolEdits, err := toProtocolEdits(f, edits)
38+
if err != nil {
39+
return nil, err
40+
}
41+
return protocolEdits, nil
3342
}
3443

35-
func toProtocolEdits(f source.File, edits []source.TextEdit) []protocol.TextEdit {
44+
func toProtocolEdits(f source.File, edits []source.TextEdit) ([]protocol.TextEdit, error) {
3645
if edits == nil {
37-
return nil
46+
return nil, errors.New("toProtocolEdits, edits == nil")
47+
}
48+
tok, err := f.GetToken()
49+
if err != nil {
50+
return nil, err
51+
}
52+
content, err := f.GetContent()
53+
if err != nil {
54+
return nil, err
3855
}
39-
tok := f.GetToken()
40-
content := f.GetContent()
4156
// When a file ends with an empty line, the newline character is counted
4257
// as part of the previous line. This causes the formatter to insert
4358
// another unnecessary newline on each formatting. We handle this case by
@@ -56,5 +71,5 @@ func toProtocolEdits(f source.File, edits []source.TextEdit) []protocol.TextEdit
5671
NewText: edit.NewText,
5772
}
5873
}
59-
return result
74+
return result, nil
6075
}

internal/lsp/imports.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ func organizeImports(ctx context.Context, v source.View, uri protocol.DocumentUR
2020
if err != nil {
2121
return nil, err
2222
}
23-
tok := f.GetToken()
23+
tok, err := f.GetToken()
24+
if err != nil {
25+
return nil, err
26+
}
2427
r := source.Range{
2528
Start: tok.Pos(0),
2629
End: tok.Pos(tok.Size()),
@@ -29,5 +32,9 @@ func organizeImports(ctx context.Context, v source.View, uri protocol.DocumentUR
2932
if err != nil {
3033
return nil, err
3134
}
32-
return toProtocolEdits(f, edits), nil
35+
protocolEdits, err := toProtocolEdits(f, edits)
36+
if err != nil {
37+
return nil, err
38+
}
39+
return protocolEdits, nil
3340
}

internal/lsp/lsp_test.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,11 @@ func (f formats) test(t *testing.T, s *server) {
396396
})
397397
}
398398
}
399-
split := strings.SplitAfter(string(f.GetContent()), "\n")
399+
contents, err := f.GetContent()
400+
if err != nil {
401+
t.Error(err)
402+
}
403+
split := strings.SplitAfter(string(contents), "\n")
400404
got := strings.Join(diff.ApplyEdits(split, ops), "")
401405
if gofmted != got {
402406
t.Errorf("format failed for %s: expected '%v', got '%v'", filename, gofmted, got)

internal/lsp/position.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ func fromProtocolLocation(ctx context.Context, v *cache.View, loc protocol.Locat
3636
if err != nil {
3737
return source.Range{}, err
3838
}
39-
tok := f.GetToken()
39+
tok, err := f.GetToken()
40+
if err != nil {
41+
return source.Range{}, err
42+
}
4043
return fromProtocolRange(tok, loc.Range), nil
4144
}
4245

internal/lsp/server.go

+31-9
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ func (s *server) Initialize(ctx context.Context, params *protocol.InitializePara
7979
}
8080
s.initialized = true // mark server as initialized now
8181

82+
if params.Trace != "verbose" {
83+
params.Trace = "verbose"
84+
}
85+
8286
// Check if the client supports snippets in completion items.
8387
s.snippetsSupported = params.Capabilities.TextDocument.Completion.CompletionItem.SnippetSupport
8488
s.signatureHelpEnabled = true
@@ -108,7 +112,7 @@ func (s *server) Initialize(ctx context.Context, params *protocol.InitializePara
108112
Tests: true,
109113
})
110114

111-
return &protocol.InitializeResult{
115+
initializeResult := &protocol.InitializeResult{
112116
Capabilities: protocol.ServerCapabilities{
113117
CodeActionProvider: true,
114118
CompletionProvider: protocol.CompletionOptions{
@@ -127,7 +131,9 @@ func (s *server) Initialize(ctx context.Context, params *protocol.InitializePara
127131
},
128132
TypeDefinitionProvider: true,
129133
},
130-
}, nil
134+
}
135+
136+
return initializeResult, nil
131137
}
132138

133139
func (s *server) Initialized(context.Context, *protocol.InitializedParams) error {
@@ -220,7 +226,10 @@ func (s *server) Completion(ctx context.Context, params *protocol.CompletionPara
220226
if err != nil {
221227
return nil, err
222228
}
223-
tok := f.GetToken()
229+
tok, err := f.GetToken()
230+
if err != nil {
231+
return nil, err
232+
}
224233
pos := fromProtocolPosition(tok, params.Position)
225234
items, prefix, err := source.Completion(ctx, f, pos)
226235
if err != nil {
@@ -245,7 +254,10 @@ func (s *server) Hover(ctx context.Context, params *protocol.TextDocumentPositio
245254
if err != nil {
246255
return nil, err
247256
}
248-
tok := f.GetToken()
257+
tok, err := f.GetToken()
258+
if err != nil {
259+
return nil, err
260+
}
249261
pos := fromProtocolPosition(tok, params.Position)
250262
ident, err := source.Identifier(ctx, s.view, f, pos)
251263
if err != nil {
@@ -256,13 +268,14 @@ func (s *server) Hover(ctx context.Context, params *protocol.TextDocumentPositio
256268
return nil, err
257269
}
258270
markdown := "```go\n" + content + "\n```"
259-
return &protocol.Hover{
271+
hover := &protocol.Hover{
260272
Contents: protocol.MarkupContent{
261273
Kind: protocol.Markdown,
262274
Value: markdown,
263275
},
264276
Range: toProtocolRange(tok, ident.Range),
265-
}, nil
277+
}
278+
return hover, nil
266279
}
267280

268281
func (s *server) SignatureHelp(ctx context.Context, params *protocol.TextDocumentPositionParams) (*protocol.SignatureHelp, error) {
@@ -274,7 +287,10 @@ func (s *server) SignatureHelp(ctx context.Context, params *protocol.TextDocumen
274287
if err != nil {
275288
return nil, err
276289
}
277-
tok := f.GetToken()
290+
tok, err := f.GetToken()
291+
if err != nil {
292+
return nil, err
293+
}
278294
pos := fromProtocolPosition(tok, params.Position)
279295
info, err := source.SignatureHelp(ctx, f, pos)
280296
if err != nil {
@@ -292,7 +308,10 @@ func (s *server) Definition(ctx context.Context, params *protocol.TextDocumentPo
292308
if err != nil {
293309
return nil, err
294310
}
295-
tok := f.GetToken()
311+
tok, err := f.GetToken()
312+
if err != nil {
313+
return nil, err
314+
}
296315
pos := fromProtocolPosition(tok, params.Position)
297316
ident, err := source.Identifier(ctx, s.view, f, pos)
298317
if err != nil {
@@ -310,7 +329,10 @@ func (s *server) TypeDefinition(ctx context.Context, params *protocol.TextDocume
310329
if err != nil {
311330
return nil, err
312331
}
313-
tok := f.GetToken()
332+
tok, err := f.GetToken()
333+
if err != nil {
334+
return nil, err
335+
}
314336
pos := fromProtocolPosition(tok, params.Position)
315337
ident, err := source.Identifier(ctx, s.view, f, pos)
316338
if err != nil {

internal/lsp/source/completion.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,14 @@ type finder func(types.Object, float64, []CompletionItem) []CompletionItem
4747
// completion. For instance, some clients may tolerate imperfect matches as
4848
// valid completion results, since users may make typos.
4949
func Completion(ctx context.Context, f File, pos token.Pos) (items []CompletionItem, prefix string, err error) {
50-
file := f.GetAST()
51-
pkg := f.GetPackage()
50+
file, err := f.GetAST()
51+
if err != nil {
52+
return nil, "", err
53+
}
54+
pkg, err := f.GetPackage()
55+
if err != nil {
56+
return nil, "", err
57+
}
5258
path, _ := astutil.PathEnclosingInterval(file, pos, pos)
5359
if path == nil {
5460
return nil, "", fmt.Errorf("cannot find node enclosing position")

0 commit comments

Comments
 (0)