mirror of
https://github.com/golang/go
synced 2024-11-18 23:34:45 -07:00
2208e1677e
This change eliminates the extra step of calling GetFile on the view and getting the FileHandle from the snapshot. It also eliminiates the redundant source.File type. Follow up changes will clean up the file kind handling, since it still exists on the fileBase type. Change-Id: I635ab8632821b36e062be5151eaab425a5698f60 Reviewed-on: https://go-review.googlesource.com/c/tools/+/211778 Run-TryBot: Rebecca Stambler <rstambler@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com>
97 lines
2.3 KiB
Go
97 lines
2.3 KiB
Go
// Copyright 2019 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package lsp
|
|
|
|
import (
|
|
"context"
|
|
|
|
"golang.org/x/tools/internal/lsp/protocol"
|
|
"golang.org/x/tools/internal/lsp/source"
|
|
"golang.org/x/tools/internal/span"
|
|
"golang.org/x/tools/internal/telemetry/log"
|
|
"golang.org/x/tools/internal/telemetry/tag"
|
|
)
|
|
|
|
func (s *Server) references(ctx context.Context, params *protocol.ReferenceParams) ([]protocol.Location, error) {
|
|
uri := span.NewURI(params.TextDocument.URI)
|
|
view, err := s.session.ViewOf(uri)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
snapshot := view.Snapshot()
|
|
fh, err := snapshot.GetFile(ctx, uri)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// Find all references to the identifier at the position.
|
|
if fh.Identity().Kind != source.Go {
|
|
return nil, nil
|
|
}
|
|
phs, err := snapshot.PackageHandles(ctx, fh)
|
|
if err != nil {
|
|
return nil, nil
|
|
}
|
|
|
|
// Get the location of each reference to return as the result.
|
|
var (
|
|
locations []protocol.Location
|
|
seen = make(map[span.Span]bool)
|
|
lastIdent *source.IdentifierInfo
|
|
)
|
|
for _, ph := range phs {
|
|
ident, err := source.Identifier(ctx, snapshot, fh, params.Position, source.SpecificPackageHandle(ph.ID()))
|
|
if err != nil {
|
|
if err == source.ErrNoIdentFound {
|
|
return nil, err
|
|
}
|
|
log.Error(ctx, "no identifier", err, tag.Of("Identifier", ident.Name))
|
|
continue
|
|
}
|
|
|
|
lastIdent = ident
|
|
|
|
references, err := ident.References(ctx)
|
|
if err != nil {
|
|
log.Error(ctx, "no references", err, tag.Of("Identifier", ident.Name))
|
|
continue
|
|
}
|
|
|
|
for _, ref := range references {
|
|
refSpan, err := ref.Span()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if seen[refSpan] {
|
|
continue // already added this location
|
|
}
|
|
seen[refSpan] = true
|
|
refRange, err := ref.Range()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
locations = append(locations, protocol.Location{
|
|
URI: protocol.NewURI(ref.URI()),
|
|
Range: refRange,
|
|
})
|
|
}
|
|
}
|
|
|
|
// Only add the identifier's declaration if the client requests it.
|
|
if params.Context.IncludeDeclaration && lastIdent != nil {
|
|
rng, err := lastIdent.Declaration.Range()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
locations = append([]protocol.Location{
|
|
{
|
|
URI: protocol.NewURI(lastIdent.Declaration.URI()),
|
|
Range: rng,
|
|
},
|
|
}, locations...)
|
|
}
|
|
|
|
return locations, nil
|
|
}
|