internal/lsp: remove view.FindPosInPackage and view.FindMapperInPackage

There is no reason for these functions to live on the view. They make
more sense as unexported functions in internal/lsp/source.

Initially, I had to propagate contexts through a lot of functions in
internal/lsp/source, but instead I removed the unused contexts forom
snapshot.GetFile.

Change-Id: I8323419d0356feb2010091fe8d3ed35e511f801a
Reviewed-on: https://go-review.googlesource.com/c/tools/+/214384
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
This commit is contained in:
Rebecca Stambler 2020-01-10 17:37:29 -05:00
parent 30cae5f2fb
commit 4a54ec1d38
30 changed files with 181 additions and 171 deletions

View File

@ -221,7 +221,7 @@ func (ph *packageHandle) cached() (*pkg, error) {
func (s *snapshot) parseGoHandles(ctx context.Context, files []span.URI, mode source.ParseMode) ([]source.ParseGoHandle, error) {
phs := make([]source.ParseGoHandle, 0, len(files))
for _, uri := range files {
fh, err := s.GetFile(ctx, uri)
fh, err := s.GetFile(uri)
if err != nil {
return nil, err
}

View File

@ -247,6 +247,27 @@ func spanToRange(ctx context.Context, pkg *pkg, spn span.Span) (protocol.Range,
return m.Range(spn)
}
func findFileInPackage(pkg source.Package, uri span.URI) (source.ParseGoHandle, source.Package, error) {
queue := []source.Package{pkg}
seen := make(map[string]bool)
for len(queue) > 0 {
pkg := queue[0]
queue = queue[1:]
seen[pkg.ID()] = true
if f, err := pkg.File(uri); err == nil {
return f, pkg, nil
}
for _, dep := range pkg.Imports() {
if !seen[dep.ID()] {
queue = append(queue, dep)
}
}
}
return nil, nil, errors.Errorf("no file for %s in package %s", uri, pkg.ID())
}
// parseGoListError attempts to parse a standard `go list` error message
// by stripping off the trailing error message.
//

View File

@ -273,7 +273,7 @@ func (s *session) DidModifyFile(ctx context.Context, c source.FileModification)
return nil, errors.Errorf("ignored file %v", c.URI)
}
// Make sure to add the file to the view.
if _, err := view.getFileLocked(ctx, c.URI); err != nil {
if _, err := view.getFileLocked(c.URI); err != nil {
return nil, err
}
snapshots = append(snapshots, view.invalidateContent(ctx, c.URI, kind, c.Action))
@ -303,7 +303,7 @@ func (s *session) DidChangeOutOfBand(ctx context.Context, uri span.URI, action s
return false
}
// Make sure that the file is part of the view.
if _, err := view.getFileLocked(ctx, uri); err != nil {
if _, err := view.getFileLocked(uri); err != nil {
return false
}
// TODO(golang/go#31553): Remove this when this issue has been resolved.

View File

@ -72,7 +72,7 @@ func (s *snapshot) ModFiles(ctx context.Context) (source.FileHandle, source.File
if s.view.modfiles == nil {
return nil, nil, nil
}
realfh, err := s.GetFile(ctx, span.FileURI(s.view.modfiles.real))
realfh, err := s.GetFile(span.FileURI(s.view.modfiles.real))
if err != nil {
return nil, nil, err
}
@ -523,25 +523,25 @@ func (s *snapshot) getFileURIs() []span.URI {
}
// FindFile returns the file if the given URI is already a part of the view.
func (s *snapshot) FindFile(ctx context.Context, uri span.URI) source.FileHandle {
f, err := s.view.findFileLocked(ctx, uri)
func (s *snapshot) FindFile(uri span.URI) source.FileHandle {
f, err := s.view.findFileLocked(uri)
if f == nil || err != nil {
return nil
}
return s.getFileHandle(ctx, f)
return s.getFileHandle(f)
}
// GetFile returns a File for the given URI. It will always succeed because it
// adds the file to the managed set if needed.
func (s *snapshot) GetFile(ctx context.Context, uri span.URI) (source.FileHandle, error) {
f, err := s.view.getFileLocked(ctx, uri)
func (s *snapshot) GetFile(uri span.URI) (source.FileHandle, error) {
f, err := s.view.getFileLocked(uri)
if err != nil {
return nil, err
}
return s.getFileHandle(ctx, f), nil
return s.getFileHandle(f), nil
}
func (s *snapshot) getFileHandle(ctx context.Context, f *fileBase) source.FileHandle {
func (s *snapshot) getFileHandle(f *fileBase) source.FileHandle {
s.mu.Lock()
defer s.mu.Unlock()

View File

@ -21,7 +21,6 @@ import (
"golang.org/x/tools/go/packages"
"golang.org/x/tools/internal/imports"
"golang.org/x/tools/internal/lsp/debug"
"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"
@ -344,7 +343,7 @@ func basename(filename string) string {
}
// FindFile returns the file if the given URI is already a part of the view.
func (v *view) findFileLocked(ctx context.Context, uri span.URI) (*fileBase, error) {
func (v *view) findFileLocked(uri span.URI) (*fileBase, error) {
v.mu.Lock()
defer v.mu.Unlock()
@ -353,15 +352,15 @@ func (v *view) findFileLocked(ctx context.Context, uri span.URI) (*fileBase, err
// getFileLocked returns a File for the given URI. It will always succeed because it
// adds the file to the managed set if needed.
func (v *view) getFileLocked(ctx context.Context, uri span.URI) (*fileBase, error) {
func (v *view) getFileLocked(uri span.URI) (*fileBase, error) {
v.mu.Lock()
defer v.mu.Unlock()
return v.getFile(ctx, uri)
return v.getFile(uri)
}
// getFile is the unlocked internal implementation of GetFile.
func (v *view) getFile(ctx context.Context, uri span.URI) (*fileBase, error) {
func (v *view) getFile(uri span.URI) (*fileBase, error) {
f, err := v.findFile(uri)
if err != nil {
return nil, err
@ -535,89 +534,6 @@ func (v *view) cancelBackground() {
v.backgroundCtx, v.cancel = context.WithCancel(v.baseCtx)
}
func (v *view) FindPosInPackage(searchpkg source.Package, pos token.Pos) (*ast.File, source.Package, error) {
tok := v.session.cache.fset.File(pos)
if tok == nil {
return nil, nil, errors.Errorf("no file for pos in package %s", searchpkg.ID())
}
uri := span.FileURI(tok.Name())
// Special case for ignored files.
var (
ph source.ParseGoHandle
pkg source.Package
err error
)
if v.Ignore(uri) {
ph, pkg, err = v.findIgnoredFile(uri)
} else {
ph, pkg, err = findFileInPackage(searchpkg, uri)
}
if err != nil {
return nil, nil, err
}
file, _, _, err := ph.Cached()
if err != nil {
return nil, nil, err
}
if !(file.Pos() <= pos && pos <= file.End()) {
return nil, nil, fmt.Errorf("pos %v, apparently in file %q, is not between %v and %v", pos, ph.File().Identity().URI, file.Pos(), file.End())
}
return file, pkg, nil
}
func (v *view) FindMapperInPackage(searchpkg source.Package, uri span.URI) (*protocol.ColumnMapper, error) {
// Special case for ignored files.
var (
ph source.ParseGoHandle
err error
)
if v.Ignore(uri) {
ph, _, err = v.findIgnoredFile(uri)
} else {
ph, _, err = findFileInPackage(searchpkg, uri)
}
if err != nil {
return nil, err
}
_, m, _, err := ph.Cached()
if err != nil {
return nil, err
}
return m, nil
}
func (v *view) findIgnoredFile(uri span.URI) (source.ParseGoHandle, source.Package, error) {
// Check the builtin package.
for _, h := range v.BuiltinPackage().CompiledGoFiles() {
if h.File().Identity().URI == uri {
return h, nil, nil
}
}
return nil, nil, errors.Errorf("no ignored file for %s", uri)
}
func findFileInPackage(pkg source.Package, uri span.URI) (source.ParseGoHandle, source.Package, error) {
queue := []source.Package{pkg}
seen := make(map[string]bool)
for len(queue) > 0 {
pkg := queue[0]
queue = queue[1:]
seen[pkg.ID()] = true
if f, err := pkg.File(uri); err == nil {
return f, pkg, nil
}
for _, dep := range pkg.Imports() {
if !seen[dep.ID()] {
queue = append(queue, dep)
}
}
}
return nil, nil, errors.Errorf("no file for %s in package %s", uri, pkg.ID())
}
func (v *view) getBuildCachePath(ctx context.Context) (string, error) {
v.mu.Lock()
defer v.mu.Unlock()

View File

@ -26,7 +26,7 @@ func (s *Server) codeAction(ctx context.Context, params *protocol.CodeActionPara
return nil, err
}
snapshot := view.Snapshot()
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return nil, err
}
@ -228,7 +228,7 @@ func quickFixes(ctx context.Context, snapshot source.Snapshot, fh source.FileHan
Edit: protocol.WorkspaceEdit{},
}
for uri, edits := range fix.Edits {
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
log.Error(ctx, "no file", err, telemetry.URI.Of(uri))
continue

View File

@ -21,7 +21,7 @@ func (s *Server) executeCommand(ctx context.Context, params *protocol.ExecuteCom
if err != nil {
return nil, err
}
fh, err := view.Snapshot().GetFile(ctx, uri)
fh, err := view.Snapshot().GetFile(uri)
if err != nil {
return nil, err
}

View File

@ -25,7 +25,7 @@ func (s *Server) completion(ctx context.Context, params *protocol.CompletionPara
}
snapshot := view.Snapshot()
options := view.Options()
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return nil, err
}

View File

@ -19,7 +19,7 @@ func (s *Server) definition(ctx context.Context, params *protocol.DefinitionPara
return nil, err
}
snapshot := view.Snapshot()
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return nil, err
}
@ -49,7 +49,7 @@ func (s *Server) typeDefinition(ctx context.Context, params *protocol.TypeDefini
return nil, err
}
snapshot := view.Snapshot()
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return nil, err
}

View File

@ -15,7 +15,7 @@ func (s *Server) foldingRange(ctx context.Context, params *protocol.FoldingRange
return nil, err
}
snapshot := view.Snapshot()
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return nil, err
}

View File

@ -19,7 +19,7 @@ func (s *Server) formatting(ctx context.Context, params *protocol.DocumentFormat
return nil, err
}
snapshot := view.Snapshot()
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return nil, err
}

View File

@ -21,7 +21,7 @@ func (s *Server) documentHighlight(ctx context.Context, params *protocol.Documen
return nil, err
}
snapshot := view.Snapshot()
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return nil, err
}

View File

@ -19,7 +19,7 @@ func (s *Server) hover(ctx context.Context, params *protocol.HoverParams) (*prot
return nil, err
}
snapshot := view.Snapshot()
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return nil, err
}

View File

@ -19,7 +19,7 @@ func (s *Server) implementation(ctx context.Context, params *protocol.Implementa
return nil, err
}
snapshot := view.Snapshot()
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return nil, err
}

View File

@ -26,7 +26,7 @@ func (s *Server) documentLink(ctx context.Context, params *protocol.DocumentLink
if err != nil {
return nil, err
}
fh, err := view.Snapshot().GetFile(ctx, uri)
fh, err := view.Snapshot().GetFile(uri)
if err != nil {
return nil, err
}

View File

@ -85,7 +85,7 @@ func testLSP(t *testing.T, exporter packagestest.Exporter) {
// TODO: Actually test the LSP diagnostics function in this test.
func (r *runner) Diagnostics(t *testing.T, uri span.URI, want []source.Diagnostic) {
v := r.server.session.View(viewName)
fh, err := v.Snapshot().GetFile(r.ctx, uri)
fh, err := v.Snapshot().GetFile(uri)
if err != nil {
t.Fatal(err)
}
@ -339,7 +339,7 @@ func (r *runner) SuggestedFix(t *testing.T, spn span.Span) {
t.Fatal(err)
}
snapshot := view.Snapshot()
fh, err := snapshot.GetFile(r.ctx, spn.URI())
fh, err := snapshot.GetFile(spn.URI())
if err != nil {
t.Fatal(err)
}

View File

@ -19,7 +19,7 @@ func (s *Server) references(ctx context.Context, params *protocol.ReferenceParam
return nil, err
}
snapshot := view.Snapshot()
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return nil, err
}

View File

@ -19,7 +19,7 @@ func (s *Server) rename(ctx context.Context, params *protocol.RenameParams) (*pr
return nil, err
}
snapshot := view.Snapshot()
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return nil, err
}
@ -36,7 +36,7 @@ func (s *Server) rename(ctx context.Context, params *protocol.RenameParams) (*pr
}
var docChanges []protocol.TextDocumentEdit
for uri, e := range edits {
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return nil, err
}
@ -54,7 +54,7 @@ func (s *Server) prepareRename(ctx context.Context, params *protocol.PrepareRena
return nil, err
}
snapshot := view.Snapshot()
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return nil, err
}

View File

@ -21,7 +21,7 @@ func (s *Server) signatureHelp(ctx context.Context, params *protocol.SignatureHe
return nil, err
}
snapshot := view.Snapshot()
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return nil, err
}

View File

@ -186,7 +186,7 @@ func (c *completer) item(cand candidate) (CompletionItem, error) {
if cand.imp != nil && cand.imp.pkg != nil {
searchPkg = cand.imp.pkg
}
file, pkg, err := c.snapshot.View().FindPosInPackage(searchPkg, obj.Pos())
file, pkg, err := findPosInPackage(c.snapshot.View(), searchPkg, obj.Pos())
if err != nil {
return item, nil
}

View File

@ -137,7 +137,7 @@ Outer:
result := make(map[protocol.Range]bool)
// Highlight the correct argument in the function declaration return types.
if resultsList != nil && -1 < index && index < len(resultsList.List) {
rng, err := nodeToProtocolRange(ctx, snapshot.View(), m, resultsList.List[index])
rng, err := nodeToProtocolRange(snapshot.View(), m, resultsList.List[index])
if err != nil {
log.Error(ctx, "Error getting range for node", err)
} else {
@ -174,7 +174,7 @@ Outer:
toAdd = n.Results[index]
}
if toAdd != nil {
rng, err := nodeToProtocolRange(ctx, snapshot.View(), m, toAdd)
rng, err := nodeToProtocolRange(snapshot.View(), m, toAdd)
if err != nil {
log.Error(ctx, "Error getting range for node", err)
} else {
@ -223,7 +223,7 @@ Outer:
}
// Add all branch statements in same scope as the identified one.
if n, ok := n.(*ast.BranchStmt); ok {
rng, err := nodeToProtocolRange(ctx, snapshot.View(), m, n)
rng, err := nodeToProtocolRange(snapshot.View(), m, n)
if err != nil {
log.Error(ctx, "Error getting range for node", err)
return false
@ -262,7 +262,7 @@ func highlightIdentifiers(ctx context.Context, snapshot Snapshot, m *protocol.Co
if nObj := pkg.GetTypesInfo().ObjectOf(n); nObj != idObj {
return false
}
if rng, err := nodeToProtocolRange(ctx, snapshot.View(), m, n); err == nil {
if rng, err := nodeToProtocolRange(snapshot.View(), m, n); err == nil {
result[rng] = true
} else {
log.Error(ctx, "Error getting range for node", err)

View File

@ -252,7 +252,7 @@ func hasErrorType(obj types.Object) bool {
}
func objToNode(v View, pkg Package, obj types.Object) (ast.Decl, error) {
declAST, _, err := v.FindPosInPackage(pkg, obj.Pos())
declAST, _, err := findPosInPackage(v, pkg, obj.Pos())
if err != nil {
return nil, err
}

View File

@ -155,7 +155,7 @@ func (i *IdentifierInfo) Rename(ctx context.Context, newName string) (map[span.U
for uri, edits := range changes {
// These edits should really be associated with FileHandles for maximal correctness.
// For now, this is good enough.
fh, err := i.Snapshot.GetFile(ctx, uri)
fh, err := i.Snapshot.GetFile(uri)
if err != nil {
return nil, err
}

View File

@ -80,7 +80,7 @@ func testSource(t *testing.T, exporter packagestest.Exporter) {
func (r *runner) Diagnostics(t *testing.T, uri span.URI, want []source.Diagnostic) {
snapshot := r.view.Snapshot()
fh, err := snapshot.GetFile(r.ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
t.Fatal(err)
}
@ -233,7 +233,7 @@ func (r *runner) RankCompletion(t *testing.T, src span.Span, test tests.Completi
}
func (r *runner) callCompletion(t *testing.T, src span.Span, options source.CompletionOptions) (string, []protocol.CompletionItem) {
fh, err := r.view.Snapshot().GetFile(r.ctx, src.URI())
fh, err := r.view.Snapshot().GetFile(src.URI())
if err != nil {
t.Fatal(err)
}
@ -277,7 +277,7 @@ func (r *runner) callCompletion(t *testing.T, src span.Span, options source.Comp
func (r *runner) FoldingRanges(t *testing.T, spn span.Span) {
uri := spn.URI()
fh, err := r.view.Snapshot().GetFile(r.ctx, spn.URI())
fh, err := r.view.Snapshot().GetFile(spn.URI())
if err != nil {
t.Fatal(err)
}
@ -417,7 +417,7 @@ func (r *runner) Format(t *testing.T, spn span.Span) {
out, _ := cmd.Output() // ignore error, sometimes we have intentionally ungofmt-able files
return out, nil
}))
fh, err := r.view.Snapshot().GetFile(r.ctx, spn.URI())
fh, err := r.view.Snapshot().GetFile(spn.URI())
if err != nil {
t.Fatal(err)
}
@ -447,7 +447,7 @@ func (r *runner) Format(t *testing.T, spn span.Span) {
}
func (r *runner) Import(t *testing.T, spn span.Span) {
fh, err := r.view.Snapshot().GetFile(r.ctx, spn.URI())
fh, err := r.view.Snapshot().GetFile(spn.URI())
if err != nil {
t.Fatal(err)
}
@ -483,7 +483,7 @@ func (r *runner) Definition(t *testing.T, spn span.Span, d tests.Definition) {
if err != nil {
t.Fatal(err)
}
fh, err := r.view.Snapshot().GetFile(r.ctx, spn.URI())
fh, err := r.view.Snapshot().GetFile(spn.URI())
if err != nil {
t.Fatal(err)
}
@ -543,7 +543,7 @@ func (r *runner) Implementation(t *testing.T, spn span.Span, impls []span.Span)
if err != nil {
t.Fatalf("failed for %v: %v", spn, err)
}
fh, err := r.view.Snapshot().GetFile(r.ctx, spn.URI())
fh, err := r.view.Snapshot().GetFile(spn.URI())
if err != nil {
t.Fatal(err)
}
@ -587,7 +587,7 @@ func (r *runner) Highlight(t *testing.T, src span.Span, locations []span.Span) {
if err != nil {
t.Fatal(err)
}
fh, err := r.view.Snapshot().GetFile(r.ctx, src.URI())
fh, err := r.view.Snapshot().GetFile(src.URI())
if err != nil {
t.Fatal(err)
}
@ -625,7 +625,7 @@ func (r *runner) References(t *testing.T, src span.Span, itemList []span.Span) {
if err != nil {
t.Fatal(err)
}
fh, err := r.view.Snapshot().GetFile(r.ctx, src.URI())
fh, err := r.view.Snapshot().GetFile(src.URI())
if err != nil {
t.Fatal(err)
}
@ -669,7 +669,7 @@ func (r *runner) Rename(t *testing.T, spn span.Span, newText string) {
if err != nil {
t.Fatal(err)
}
fh, err := r.view.Snapshot().GetFile(r.ctx, spn.URI())
fh, err := r.view.Snapshot().GetFile(spn.URI())
if err != nil {
t.Fatal(err)
}
@ -691,7 +691,7 @@ func (r *runner) Rename(t *testing.T, spn span.Span, newText string) {
var res []string
for editURI, edits := range changes {
fh, err := r.view.Snapshot().GetFile(r.ctx, editURI)
fh, err := r.view.Snapshot().GetFile(editURI)
if err != nil {
t.Fatal(err)
}
@ -756,7 +756,7 @@ func (r *runner) PrepareRename(t *testing.T, src span.Span, want *source.Prepare
t.Fatal(err)
}
// Find the identifier at the position.
fh, err := r.view.Snapshot().GetFile(r.ctx, src.URI())
fh, err := r.view.Snapshot().GetFile(src.URI())
if err != nil {
t.Fatal(err)
}
@ -798,7 +798,7 @@ func (r *runner) PrepareRename(t *testing.T, src span.Span, want *source.Prepare
}
func (r *runner) Symbols(t *testing.T, uri span.URI, expectedSymbols []protocol.DocumentSymbol) {
fh, err := r.view.Snapshot().GetFile(r.ctx, uri)
fh, err := r.view.Snapshot().GetFile(uri)
if err != nil {
t.Fatal(err)
}
@ -863,7 +863,7 @@ func (r *runner) SignatureHelp(t *testing.T, spn span.Span, expectedSignature *s
if err != nil {
t.Fatal(err)
}
fh, err := r.view.Snapshot().GetFile(r.ctx, spn.URI())
fh, err := r.view.Snapshot().GetFile(spn.URI())
if err != nil {
t.Fatal(err)
}

View File

@ -99,11 +99,11 @@ func funcSymbol(ctx context.Context, view View, m *protocol.ColumnMapper, decl *
Kind: protocol.Function,
}
var err error
s.Range, err = nodeToProtocolRange(ctx, view, m, decl)
s.Range, err = nodeToProtocolRange(view, m, decl)
if err != nil {
return protocol.DocumentSymbol{}, err
}
s.SelectionRange, err = nodeToProtocolRange(ctx, view, m, decl.Name)
s.SelectionRange, err = nodeToProtocolRange(view, m, decl.Name)
if err != nil {
return protocol.DocumentSymbol{}, err
}
@ -165,11 +165,11 @@ func typeSymbol(ctx context.Context, view View, m *protocol.ColumnMapper, info *
setKind(&s, obj.Type(), q)
var err error
s.Range, err = nodeToProtocolRange(ctx, view, m, spec)
s.Range, err = nodeToProtocolRange(view, m, spec)
if err != nil {
return protocol.DocumentSymbol{}, err
}
s.SelectionRange, err = nodeToProtocolRange(ctx, view, m, spec.Name)
s.SelectionRange, err = nodeToProtocolRange(view, m, spec.Name)
if err != nil {
return protocol.DocumentSymbol{}, err
}
@ -185,10 +185,10 @@ func typeSymbol(ctx context.Context, view View, m *protocol.ColumnMapper, info *
child.Detail, _ = formatType(f.Type(), q)
spanNode, selectionNode := nodesForStructField(i, st)
if span, err := nodeToProtocolRange(ctx, view, m, spanNode); err == nil {
if span, err := nodeToProtocolRange(view, m, spanNode); err == nil {
child.Range = span
}
if span, err := nodeToProtocolRange(ctx, view, m, selectionNode); err == nil {
if span, err := nodeToProtocolRange(view, m, selectionNode); err == nil {
child.SelectionRange = span
}
s.Children = append(s.Children, child)
@ -215,11 +215,11 @@ func typeSymbol(ctx context.Context, view View, m *protocol.ColumnMapper, info *
}
}
}
child.Range, err = nodeToProtocolRange(ctx, view, m, spanNode)
child.Range, err = nodeToProtocolRange(view, m, spanNode)
if err != nil {
return protocol.DocumentSymbol{}, err
}
child.SelectionRange, err = nodeToProtocolRange(ctx, view, m, selectionNode)
child.SelectionRange, err = nodeToProtocolRange(view, m, selectionNode)
if err != nil {
return protocol.DocumentSymbol{}, err
}
@ -249,11 +249,11 @@ func typeSymbol(ctx context.Context, view View, m *protocol.ColumnMapper, info *
break Embeddeds
}
}
child.Range, err = nodeToProtocolRange(ctx, view, m, spanNode)
child.Range, err = nodeToProtocolRange(view, m, spanNode)
if err != nil {
return protocol.DocumentSymbol{}, err
}
child.SelectionRange, err = nodeToProtocolRange(ctx, view, m, selectionNode)
child.SelectionRange, err = nodeToProtocolRange(view, m, selectionNode)
if err != nil {
return protocol.DocumentSymbol{}, err
}
@ -292,11 +292,11 @@ func varSymbol(ctx context.Context, view View, m *protocol.ColumnMapper, decl as
s.Kind = protocol.Constant
}
var err error
s.Range, err = nodeToProtocolRange(ctx, view, m, decl)
s.Range, err = nodeToProtocolRange(view, m, decl)
if err != nil {
return protocol.DocumentSymbol{}, err
}
s.SelectionRange, err = nodeToProtocolRange(ctx, view, m, name)
s.SelectionRange, err = nodeToProtocolRange(view, m, name)
if err != nil {
return protocol.DocumentSymbol{}, err
}

View File

@ -142,7 +142,7 @@ func SpecificPackageHandle(desiredID string) PackagePolicy {
}
func IsGenerated(ctx context.Context, view View, uri span.URI) bool {
fh, err := view.Snapshot().GetFile(ctx, uri)
fh, err := view.Snapshot().GetFile(uri)
if err != nil {
return false
}
@ -168,7 +168,7 @@ func IsGenerated(ctx context.Context, view View, uri span.URI) bool {
return false
}
func nodeToProtocolRange(ctx context.Context, view View, m *protocol.ColumnMapper, n ast.Node) (protocol.Range, error) {
func nodeToProtocolRange(view View, m *protocol.ColumnMapper, n ast.Node) (protocol.Range, error) {
mrng, err := nodeToMappedRange(view, m, n)
if err != nil {
return protocol.Range{}, err
@ -205,7 +205,7 @@ func nodeToMappedRange(view View, m *protocol.ColumnMapper, n ast.Node) (mappedR
func posToMappedRange(v View, pkg Package, pos, end token.Pos) (mappedRange, error) {
logicalFilename := v.Session().Cache().FileSet().File(pos).Position(pos).Filename
m, err := v.FindMapperInPackage(pkg, span.FileURI(logicalFilename))
m, err := findMapperInPackage(v, pkg, span.FileURI(logicalFilename))
if err != nil {
return mappedRange{}, err
}
@ -512,7 +512,7 @@ func formatParams(s Snapshot, pkg Package, sig *types.Signature, qf types.Qualif
}
func formatFieldType(s Snapshot, srcpkg Package, obj types.Object, qf types.Qualifier) (string, error) {
file, pkg, err := s.View().FindPosInPackage(srcpkg, obj.Pos())
file, pkg, err := findPosInPackage(s.View(), srcpkg, obj.Pos())
if err != nil {
return "", err
}
@ -628,3 +628,84 @@ func CompareDiagnostic(a, b Diagnostic) int {
}
return 1
}
func findPosInPackage(v View, searchpkg Package, pos token.Pos) (*ast.File, Package, error) {
tok := v.Session().Cache().FileSet().File(pos)
if tok == nil {
return nil, nil, errors.Errorf("no file for pos in package %s", searchpkg.ID())
}
uri := span.FileURI(tok.Name())
var (
ph ParseGoHandle
pkg Package
err error
)
// Special case for ignored files.
if v.Ignore(uri) {
ph, err = findIgnoredFile(v, uri)
} else {
ph, pkg, err = findFileInPackage(searchpkg, uri)
}
if err != nil {
return nil, nil, err
}
file, _, _, err := ph.Cached()
if err != nil {
return nil, nil, err
}
if !(file.Pos() <= pos && pos <= file.End()) {
return nil, nil, fmt.Errorf("pos %v, apparently in file %q, is not between %v and %v", pos, ph.File().Identity().URI, file.Pos(), file.End())
}
return file, pkg, nil
}
func findMapperInPackage(v View, searchpkg Package, uri span.URI) (*protocol.ColumnMapper, error) {
var (
ph ParseGoHandle
err error
)
// Special case for ignored files.
if v.Ignore(uri) {
ph, err = findIgnoredFile(v, uri)
} else {
ph, _, err = findFileInPackage(searchpkg, uri)
}
if err != nil {
return nil, err
}
_, m, _, err := ph.Cached()
if err != nil {
return nil, err
}
return m, nil
}
func findIgnoredFile(v View, uri span.URI) (ParseGoHandle, error) {
fh, err := v.Snapshot().GetFile(uri)
if err != nil {
return nil, err
}
return v.Session().Cache().ParseGoHandle(fh, ParseFull), nil
}
func findFileInPackage(pkg Package, uri span.URI) (ParseGoHandle, Package, error) {
queue := []Package{pkg}
seen := make(map[string]bool)
for len(queue) > 0 {
pkg := queue[0]
queue = queue[1:]
seen[pkg.ID()] = true
if f, err := pkg.File(uri); err == nil {
return f, pkg, nil
}
for _, dep := range pkg.Imports() {
if !seen[dep.ID()] {
queue = append(queue, dep)
}
}
}
return nil, nil, errors.Errorf("no file for %s in package %s", uri, pkg.ID())
}

View File

@ -26,11 +26,11 @@ type Snapshot interface {
// GetFile returns the file object for a given URI, initializing it
// if it is not already part of the view.
GetFile(ctx context.Context, uri span.URI) (FileHandle, error)
GetFile(uri span.URI) (FileHandle, error)
// FindFile returns the file object for a given URI if it is
// already part of the view.
FindFile(ctx context.Context, uri span.URI) FileHandle
FindFile(uri span.URI) FileHandle
// Analyze runs the analyses for the given package at this snapshot.
Analyze(ctx context.Context, id string, analyzers []*analysis.Analyzer) ([]*Error, error)
@ -122,14 +122,6 @@ type View interface {
// original one will be.
SetOptions(context.Context, Options) (View, error)
// FindFileInPackage returns the AST and type information for a file that may
// belong to or be part of a dependency of the given package.
FindPosInPackage(pkg Package, pos token.Pos) (*ast.File, Package, error)
// FindMapperInPackage returns the mapper associated with a file that may belong to
// the given package or one of its dependencies.
FindMapperInPackage(pkg Package, uri span.URI) (*protocol.ColumnMapper, error)
// WorkspacePackageIDs returns the ids of the packages at the top-level
// of the snapshot's view.
WorkspacePackageIDs(ctx context.Context) ([]string, error)

View File

@ -25,7 +25,7 @@ func (s *Server) documentSymbol(ctx context.Context, params *protocol.DocumentSy
return nil, err
}
snapshot := view.Snapshot()
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return nil, err
}

View File

@ -33,7 +33,7 @@ func (s *Server) didOpen(ctx context.Context, params *protocol.DidOpenTextDocume
if err != nil {
return err
}
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return err
}
@ -72,7 +72,7 @@ func (s *Server) didChange(ctx context.Context, params *protocol.DidChangeTextDo
Type: protocol.Warning,
})
}
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return err
}

View File

@ -32,7 +32,7 @@ func (s *Server) didChangeWatchedFiles(ctx context.Context, params *protocol.Did
// If we had been tracking the given file,
// recompute diagnostics to reflect updated file contents.
snapshot := view.Snapshot()
fh, err := snapshot.GetFile(ctx, uri)
fh, err := snapshot.GetFile(uri)
if err != nil {
return err
}
@ -47,7 +47,7 @@ func (s *Server) didChangeWatchedFiles(ctx context.Context, params *protocol.Did
}
case source.Delete:
snapshot := view.Snapshot()
fh := snapshot.FindFile(ctx, uri)
fh := snapshot.FindFile(uri)
// If we have never seen this file before, there is nothing to do.
if fh == nil {
continue
@ -69,7 +69,7 @@ func (s *Server) didChangeWatchedFiles(ctx context.Context, params *protocol.Did
if pgh.File().Identity().URI == fh.Identity().URI {
continue
}
if f := snapshot.FindFile(ctx, pgh.File().Identity().URI); f != nil && s.session.IsOpen(fh.Identity().URI) {
if f := snapshot.FindFile(pgh.File().Identity().URI); f != nil && s.session.IsOpen(fh.Identity().URI) {
otherFile = f
break
}