Skip to content

Commit cec9580

Browse files
committed
internal/lsp: add error handling for self imports
This change will provide a more useful error when you are self importing a package. It has TODOs in place to propagate the "import cycle not allowed" error from go list to the user. Updates golang/go#33085 Change-Id: Ia868a7c688b0f0a7a9689cfda5ea8cea8ae1faff Reviewed-on: https://go-review.googlesource.com/c/tools/+/209857 Run-TryBot: Rohan Challa <rohan@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
1 parent db903f3 commit cec9580

File tree

8 files changed

+57
-17
lines changed

8 files changed

+57
-17
lines changed

internal/lsp/cache/check.go

+7-10
Original file line numberDiff line numberDiff line change
@@ -331,18 +331,15 @@ func typeCheck(ctx context.Context, fset *token.FileSet, m *metadata, mode sourc
331331
return nil, ctx.Err()
332332
}
333333

334-
// We don't care about a package's errors unless we have parsed it in full.
335-
if mode == source.ParseFull {
336-
for _, e := range rawErrors {
337-
srcErr, err := sourceError(ctx, fset, pkg, e)
338-
if err != nil {
339-
log.Error(ctx, "unable to compute error positions", err, telemetry.Package.Of(pkg.ID()))
340-
continue
341-
}
342-
pkg.errors = append(pkg.errors, srcErr)
334+
// TODO(golang/go#35964): Propagate `go list` errors here when go/packages supports it.
335+
for _, e := range rawErrors {
336+
srcErr, err := sourceError(ctx, fset, pkg, e)
337+
if err != nil {
338+
log.Error(ctx, "unable to compute error positions", err, telemetry.Package.Of(pkg.ID()))
339+
continue
343340
}
341+
pkg.errors = append(pkg.errors, srcErr)
344342
}
345-
346343
return pkg, nil
347344
}
348345

internal/lsp/cache/errors.go

+8
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ func sourceError(ctx context.Context, fset *token.FileSet, pkg *pkg, e interface
3838
msg = e.Msg
3939
kind = toSourceErrorKind(e.Kind)
4040

41+
// If the range can't be derived from the parseGoListError function, then we do not have a valid position.
42+
if _, err := spanToRange(ctx, pkg, spn); err != nil && e.Pos == "" {
43+
return &source.Error{
44+
Message: msg,
45+
Kind: kind,
46+
}, nil
47+
}
48+
4149
case *scanner.Error:
4250
msg = e.Msg
4351
kind = source.ParseError

internal/lsp/cmd/test/check.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ func (r *runner) Diagnostics(t *testing.T, uri span.URI, want []source.Diagnosti
5050
expect = fmt.Sprintf("%v:%v: %v", uri.Filename(), diag.Range.Start.Line+1, diag.Message)
5151
}
5252
expect = r.NormalizePrefix(expect)
53-
// Skip the badimport test for now, until we do a better job with diagnostic ranges.
54-
if strings.Contains(uri.Filename(), "badimport") {
53+
// Skip the badimport and import cycle not allowed test for now, until we do a better job with diagnostic ranges.
54+
if strings.Contains(uri.Filename(), "badimport") || strings.Contains(expect, "import cycle") {
5555
continue
5656
}
5757
_, found := got[expect]
@@ -62,8 +62,8 @@ func (r *runner) Diagnostics(t *testing.T, uri span.URI, want []source.Diagnosti
6262
}
6363
}
6464
for extra := range got {
65-
// Skip the badimport test for now, until we do a better job with diagnostic ranges.
66-
if strings.Contains(extra, "badimport") {
65+
// Skip the badimport and import cycle not allowed test for now, until we do a better job with diagnostic ranges.
66+
if strings.Contains(extra, "badimport") || strings.Contains(extra, "import cycle") {
6767
continue
6868
}
6969
t.Errorf("extra diagnostic %q", extra)

internal/lsp/source/diagnostics.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,14 @@ func Diagnostics(ctx context.Context, snapshot Snapshot, f File, withAnalysis bo
7171
}
7272
// Prepare any additional reports for the errors in this package.
7373
for _, e := range pkg.GetErrors() {
74-
if e.Kind != ListError {
74+
// We only need to handle lower-level errors.
75+
if !(e.Kind == UnknownError || e.Kind == ListError) {
7576
continue
7677
}
78+
// If no file is associated with the error, default to the current file.
79+
if e.File.URI.Filename() == "" {
80+
e.File = fh.Identity()
81+
}
7782
clearReports(snapshot, reports, e.File)
7883
}
7984
// Run diagnostics for the package that this URI belongs to.
@@ -133,7 +138,7 @@ func diagnostics(ctx context.Context, snapshot Snapshot, pkg Package, reports ma
133138
case TypeError:
134139
set.typeErrors = append(set.typeErrors, diag)
135140
diag.Source = "compiler"
136-
case ListError:
141+
case ListError, UnknownError:
137142
set.listErrors = append(set.listErrors, diag)
138143
diag.Source = "go list"
139144
}

internal/lsp/testdata/circular/b/b.go

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package b //@diag("", "go list", "import cycle not allowed")
2+
3+
import (
4+
"golang.org/x/tools/internal/lsp/circular/one"
5+
)
6+
7+
func Test1() {
8+
one.Test()
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package one
2+
3+
import (
4+
"golang.org/x/tools/internal/lsp/circular/b"
5+
)
6+
7+
func Test() {
8+
b.Test1()
9+
}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package circular //@diag("", "go list", "import cycle not allowed")
2+
3+
import (
4+
"golang.org/x/tools/internal/lsp/circular"
5+
)
6+
7+
func print() {
8+
Test()
9+
}
10+
11+
func Test() {
12+
}

internal/lsp/testdata/summary.txt.golden

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ DeepCompletionsCount = 5
66
FuzzyCompletionsCount = 7
77
RankedCompletionsCount = 26
88
CaseSensitiveCompletionsCount = 4
9-
DiagnosticsCount = 22
9+
DiagnosticsCount = 24
1010
FoldingRangesCount = 2
1111
FormatCount = 6
1212
ImportCount = 7

0 commit comments

Comments
 (0)