Skip to content

Commit 60782e9

Browse files
committed
gopls/internal/lsp/source: eliminate a couple uses of posToMappedRange
Eliminate a couple uses of posToMappedRange, which potentially type-checks, where it is clearly unnecessary. Also improve test output for highlight. Updates golang/go#57987 Updates golang/go#54845 Change-Id: I5580bf6431def0a6ee635e394932934ec7fe1afb Reviewed-on: https://go-review.googlesource.com/c/tools/+/463556 TryBot-Result: Gopher Robot <[email protected]> gopls-CI: kokoro <[email protected]> Reviewed-by: Alan Donovan <[email protected]> Run-TryBot: Robert Findley <[email protected]>
1 parent 031e6e6 commit 60782e9

File tree

3 files changed

+58
-44
lines changed

3 files changed

+58
-44
lines changed

gopls/internal/lsp/lsp_test.go

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -771,45 +771,56 @@ func (r *runner) Implementation(t *testing.T, spn span.Span, wantSpans []span.Sp
771771
}
772772
}
773773

774-
func (r *runner) Highlight(t *testing.T, src span.Span, locations []span.Span) {
774+
func (r *runner) Highlight(t *testing.T, src span.Span, spans []span.Span) {
775775
m, err := r.data.Mapper(src.URI())
776776
if err != nil {
777777
t.Fatal(err)
778778
}
779779
loc, err := m.SpanLocation(src)
780780
if err != nil {
781-
t.Fatalf("failed for %v: %v", locations[0], err)
781+
t.Fatal(err)
782782
}
783783
tdpp := protocol.TextDocumentPositionParams{
784-
TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI},
785-
Position: loc.Range.Start,
784+
TextDocument: protocol.TextDocumentIdentifier{
785+
URI: loc.URI,
786+
},
787+
Position: loc.Range.Start,
788+
}
789+
if err != nil {
790+
t.Fatalf("Mapper.SpanDocumentPosition(%v) failed: %v", src, err)
786791
}
787792
params := &protocol.DocumentHighlightParams{
788793
TextDocumentPositionParams: tdpp,
789794
}
790795
highlights, err := r.server.DocumentHighlight(r.ctx, params)
791796
if err != nil {
792-
t.Fatal(err)
797+
t.Fatalf("DocumentHighlight(%v) failed: %v", params, err)
793798
}
794-
if len(highlights) != len(locations) {
795-
t.Fatalf("got %d highlights for highlight at %v:%v:%v, expected %d", len(highlights), src.URI().Filename(), src.Start().Line(), src.Start().Column(), len(locations))
799+
var got []protocol.Range
800+
for _, h := range highlights {
801+
got = append(got, h.Range)
796802
}
797-
// Check to make sure highlights have a valid range.
798-
var results []span.Span
799-
for i := range highlights {
800-
h, err := m.RangeSpan(highlights[i].Range)
803+
804+
var want []protocol.Range
805+
for _, s := range spans {
806+
rng, err := m.SpanRange(s)
801807
if err != nil {
802-
t.Fatalf("failed for %v: %v", highlights[i], err)
803-
}
804-
results = append(results, h)
805-
}
806-
// Sort results to make tests deterministic since DocumentHighlight uses a map.
807-
span.SortSpans(results)
808-
// Check to make sure all the expected highlights are found.
809-
for i := range results {
810-
if results[i] != locations[i] {
811-
t.Errorf("want %v, got %v\n", locations[i], results[i])
808+
t.Fatalf("Mapper.SpanRange(%v) failed: %v", s, err)
812809
}
810+
want = append(want, rng)
811+
}
812+
813+
sortRanges := func(s []protocol.Range) {
814+
sort.Slice(s, func(i, j int) bool {
815+
return protocol.CompareRange(s[i], s[j]) < 0
816+
})
817+
}
818+
819+
sortRanges(got)
820+
sortRanges(want)
821+
822+
if diff := cmp.Diff(want, got); diff != "" {
823+
t.Errorf("DocumentHighlight(%v) mismatch (-want +got):\n%s", src, diff)
813824
}
814825
}
815826

gopls/internal/lsp/source/highlight.go

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -48,36 +48,38 @@ func Highlight(ctx context.Context, snapshot Snapshot, fh FileHandle, position p
4848
}
4949
}
5050
}
51-
result, err := highlightPath(pkg, path)
51+
result, err := highlightPath(path, pgf.File, pkg.GetTypesInfo())
5252
if err != nil {
5353
return nil, err
5454
}
5555
var ranges []protocol.Range
5656
for rng := range result {
57-
mRng, err := posToMappedRange(ctx, snapshot, pkg, rng.start, rng.end)
57+
rng, err := pgf.PosRange(rng.start, rng.end)
5858
if err != nil {
5959
return nil, err
6060
}
61-
ranges = append(ranges, mRng.Range())
61+
ranges = append(ranges, rng)
6262
}
6363
return ranges, nil
6464
}
6565

66-
func highlightPath(pkg Package, path []ast.Node) (map[posRange]struct{}, error) {
66+
func highlightPath(path []ast.Node, file *ast.File, info *types.Info) (map[posRange]struct{}, error) {
6767
result := make(map[posRange]struct{})
6868
switch node := path[0].(type) {
6969
case *ast.BasicLit:
7070
if len(path) > 1 {
7171
if _, ok := path[1].(*ast.ImportSpec); ok {
72-
err := highlightImportUses(pkg, path, result)
72+
err := highlightImportUses(path, info, result)
7373
return result, err
7474
}
7575
}
7676
highlightFuncControlFlow(path, result)
7777
case *ast.ReturnStmt, *ast.FuncDecl, *ast.FuncType:
7878
highlightFuncControlFlow(path, result)
7979
case *ast.Ident:
80-
highlightIdentifiers(pkg, path, result)
80+
// Check if ident is inside return or func decl.
81+
highlightFuncControlFlow(path, result)
82+
highlightIdentifier(node, file, info, result)
8183
case *ast.ForStmt, *ast.RangeStmt:
8284
highlightLoopControlFlow(path, result)
8385
case *ast.SwitchStmt:
@@ -426,7 +428,7 @@ func labelDecl(n *ast.Ident) *ast.Ident {
426428
return stmt.Label
427429
}
428430

429-
func highlightImportUses(pkg Package, path []ast.Node, result map[posRange]struct{}) error {
431+
func highlightImportUses(path []ast.Node, info *types.Info, result map[posRange]struct{}) error {
430432
basicLit, ok := path[0].(*ast.BasicLit)
431433
if !ok {
432434
return fmt.Errorf("highlightImportUses called with an ast.Node of type %T", basicLit)
@@ -440,7 +442,7 @@ func highlightImportUses(pkg Package, path []ast.Node, result map[posRange]struc
440442
if !ok {
441443
return true
442444
}
443-
obj, ok := pkg.GetTypesInfo().ObjectOf(n).(*types.PkgName)
445+
obj, ok := info.ObjectOf(n).(*types.PkgName)
444446
if !ok {
445447
return true
446448
}
@@ -453,19 +455,16 @@ func highlightImportUses(pkg Package, path []ast.Node, result map[posRange]struc
453455
return nil
454456
}
455457

456-
func highlightIdentifiers(pkg Package, path []ast.Node, result map[posRange]struct{}) error {
457-
id, ok := path[0].(*ast.Ident)
458-
if !ok {
459-
return fmt.Errorf("highlightIdentifiers called with an ast.Node of type %T", id)
460-
}
461-
// Check if ident is inside return or func decl.
462-
highlightFuncControlFlow(path, result)
463-
464-
// TODO: maybe check if ident is a reserved word, if true then don't continue and return results.
465-
466-
idObj := pkg.GetTypesInfo().ObjectOf(id)
458+
func highlightIdentifier(id *ast.Ident, file *ast.File, info *types.Info, result map[posRange]struct{}) {
459+
// TODO(rfindley): idObj may be nil. Note that returning early in this case
460+
// causes tests to fail (because the nObj == idObj check below was succeeded
461+
// for nil == nil!)
462+
//
463+
// Revisit this. If ObjectOf is nil, there are type errors, and it seems
464+
// reasonable for identifier highlighting not to work.
465+
idObj := info.ObjectOf(id)
467466
pkgObj, isImported := idObj.(*types.PkgName)
468-
ast.Inspect(path[len(path)-1], func(node ast.Node) bool {
467+
ast.Inspect(file, func(node ast.Node) bool {
469468
if imp, ok := node.(*ast.ImportSpec); ok && isImported {
470469
highlightImport(pkgObj, imp, result)
471470
}
@@ -476,12 +475,11 @@ func highlightIdentifiers(pkg Package, path []ast.Node, result map[posRange]stru
476475
if n.Name != id.Name {
477476
return false
478477
}
479-
if nObj := pkg.GetTypesInfo().ObjectOf(n); nObj == idObj {
478+
if nObj := info.ObjectOf(n); nObj == idObj {
480479
result[posRange{start: n.Pos(), end: n.End()}] = struct{}{}
481480
}
482481
return false
483482
})
484-
return nil
485483
}
486484

487485
func highlightImport(obj *types.PkgName, imp *ast.ImportSpec, result map[posRange]struct{}) {

gopls/internal/lsp/source/references.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,12 @@ func references(ctx context.Context, snapshot Snapshot, qos []qualifiedObject, i
141141
continue
142142
}
143143
seen[key] = true
144-
rng, err := posToMappedRange(ctx, snapshot, pkg, ident.Pos(), ident.End())
144+
filename := pkg.FileSet().File(ident.Pos()).Name()
145+
pgf, err := pkg.File(span.URIFromPath(filename))
146+
if err != nil {
147+
return nil, err
148+
}
149+
rng, err := pgf.PosMappedRange(ident.Pos(), ident.End())
145150
if err != nil {
146151
return nil, err
147152
}

0 commit comments

Comments
 (0)