internal/lsp: remove cachedFileToMapper function

This function incorrectly used cached packages to get ASTs and type
information that should have been directly found from the origin
package. Shift to using pkg.FindFile instead.

Change-Id: I9f73209bb1a1343f53b430150e78ffd180e14a44
Reviewed-on: https://go-review.googlesource.com/c/tools/+/195797
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
This commit is contained in:
Rebecca Stambler 2019-09-16 18:17:51 -04:00
parent 5999de1043
commit 2dc213d980
14 changed files with 170 additions and 139 deletions

View File

@ -21,6 +21,10 @@ func (b *builtinPkg) Lookup(name string) *ast.Object {
return b.pkg.Scope.Lookup(name)
}
func (b *builtinPkg) Files() []source.ParseGoHandle {
return b.files
}
// buildBuiltinPkg builds the view's builtin package.
// It assumes that the view is not active yet,
// i.e. it has not been added to the session's list of views.

View File

@ -202,7 +202,12 @@ func (pkg *pkg) GetDiagnostics() []source.Diagnostic {
return diags
}
func (p *pkg) FindFile(ctx context.Context, uri span.URI) (source.ParseGoHandle, *ast.File, source.Package, error) {
func (p *pkg) FindFile(ctx context.Context, uri span.URI) (source.ParseGoHandle, source.Package, error) {
// Special case for ignored files.
if p.view.Ignore(uri) {
return p.view.findIgnoredFile(ctx, uri)
}
queue := []*pkg{p}
seen := make(map[string]bool)
@ -213,11 +218,7 @@ func (p *pkg) FindFile(ctx context.Context, uri span.URI) (source.ParseGoHandle,
for _, ph := range pkg.files {
if ph.File().Identity().URI == uri {
file, _, err := ph.Cached(ctx)
if file == nil {
return nil, nil, nil, err
}
return ph, file, pkg, nil
return ph, pkg, nil
}
}
for _, dep := range pkg.imports {
@ -226,5 +227,5 @@ func (p *pkg) FindFile(ctx context.Context, uri span.URI) (source.ParseGoHandle,
}
}
}
return nil, nil, nil, errors.Errorf("no file for %s", uri)
return nil, nil, errors.Errorf("no file for %s", uri)
}

View File

@ -23,6 +23,7 @@ import (
"golang.org/x/tools/internal/lsp/telemetry"
"golang.org/x/tools/internal/span"
"golang.org/x/tools/internal/telemetry/log"
errors "golang.org/x/xerrors"
)
type view struct {
@ -282,6 +283,16 @@ func (v *view) Ignore(uri span.URI) bool {
return ok
}
func (v *view) findIgnoredFile(ctx context.Context, uri span.URI) (source.ParseGoHandle, source.Package, error) {
// Check the builtin package.
for _, h := range v.BuiltinPackage().Files() {
if h.File().Identity().URI == uri {
return h, nil, nil
}
}
return nil, nil, errors.Errorf("no ignored file for %s", uri)
}
func (v *view) BackgroundContext() context.Context {
v.mu.Lock()
defer v.mu.Unlock()

View File

@ -125,10 +125,14 @@ func (c *completer) item(cand candidate) (CompletionItem, error) {
}
uri := span.FileURI(pos.Filename)
_, file, pkg, err := c.pkg.FindFile(c.ctx, uri)
ph, pkg, err := c.pkg.FindFile(c.ctx, uri)
if err != nil {
return CompletionItem{}, err
}
file, _, err := ph.Cached(c.ctx)
if file == nil {
return CompletionItem{}, err
}
if !(file.Pos() <= obj.Pos() && obj.Pos() <= file.End()) {
return CompletionItem{}, errors.Errorf("no file for %s", obj.Name())
}

View File

@ -245,10 +245,6 @@ func toDiagnostic(ctx context.Context, view View, diag analysis.Diagnostic, cate
if diag.Category != "" {
category += "." + category
}
ca, err := getCodeActions(ctx, view, diag)
if err != nil {
return Diagnostic{}, err
}
f, err := view.GetFile(ctx, spn.URI())
if err != nil {
return Diagnostic{}, err
@ -263,6 +259,11 @@ func toDiagnostic(ctx context.Context, view View, diag analysis.Diagnostic, cate
if err != nil {
return Diagnostic{}, err
}
ca, err := getCodeActions(ctx, view, pkg, diag)
if err != nil {
return Diagnostic{}, err
}
rng, err := spanToRange(ctx, view, pkg, spn, false)
if err != nil {
return Diagnostic{}, err

View File

@ -19,10 +19,16 @@ func Highlight(ctx context.Context, view View, uri span.URI, pos protocol.Positi
ctx, done := trace.StartSpan(ctx, "source.Highlight")
defer done()
file, _, m, err := fileToMapper(ctx, view, uri)
f, err := view.GetFile(ctx, uri)
if err != nil {
return nil, err
}
fh := f.Handle(ctx)
ph := view.Session().Cache().ParseGoHandle(fh, ParseFull)
file, m, err := ph.Parse(ctx)
if file == nil {
return nil, err
}
spn, err := m.PointSpan(pos)
if err != nil {
return nil, err
@ -43,7 +49,7 @@ func Highlight(ctx context.Context, view View, uri span.URI, pos protocol.Positi
if id.Obj != nil {
ast.Inspect(path[len(path)-1], func(n ast.Node) bool {
if n, ok := n.(*ast.Ident); ok && n.Obj == id.Obj {
rng, err := nodeToProtocolRange(ctx, view, n)
rng, err := nodeToProtocolRange(ctx, view, m, n)
if err == nil {
result = append(result, rng)
}

View File

@ -48,10 +48,25 @@ type Declaration struct {
// Identifier returns identifier information for a position
// in a file, accounting for a potentially incomplete selector.
func Identifier(ctx context.Context, view View, f GoFile, pos protocol.Position) (*IdentifierInfo, error) {
file, pkgs, m, err := fileToMapper(ctx, view, f.URI())
pkgs, err := f.GetPackages(ctx)
if err != nil {
return nil, err
}
pkg, err := bestPackage(f.URI(), pkgs)
if err != nil {
return nil, err
}
var ph ParseGoHandle
for _, h := range pkg.GetHandles() {
if h.File().Identity().URI == f.URI() {
ph = h
break
}
}
file, m, err := ph.Cached(ctx)
if file == nil {
return nil, err
}
spn, err := m.PointSpan(pos)
if err != nil {
return nil, err
@ -121,7 +136,7 @@ func identifier(ctx context.Context, view View, pkgs []Package, file *ast.File,
}
}
result.Name = result.ident.Name
if result.mappedRange, err = posToRange(ctx, view, result.ident.Pos(), result.ident.End()); err != nil {
if result.mappedRange, err = posToMappedRange(ctx, view, pkg, result.ident.Pos(), result.ident.End()); err != nil {
return nil, err
}
result.Declaration.obj = pkg.GetTypesInfo().ObjectOf(result.ident)
@ -152,7 +167,7 @@ func identifier(ctx context.Context, view View, pkgs []Package, file *ast.File,
return nil, errors.Errorf("no declaration for %s", result.Name)
}
result.Declaration.node = decl
if result.Declaration.mappedRange, err = nameToMappedRange(ctx, view, decl.Pos(), result.Name); err != nil {
if result.Declaration.mappedRange, err = nameToMappedRange(ctx, view, pkg, decl.Pos(), result.Name); err != nil {
return nil, err
}
return result, nil
@ -177,7 +192,7 @@ func identifier(ctx context.Context, view View, pkgs []Package, file *ast.File,
}
}
if result.Declaration.mappedRange, err = objToMappedRange(ctx, view, result.Declaration.obj); err != nil {
if result.Declaration.mappedRange, err = objToMappedRange(ctx, view, pkg, result.Declaration.obj); err != nil {
return nil, err
}
if result.Declaration.node, err = objToNode(ctx, view, pkg, result.Declaration.obj); err != nil {
@ -194,7 +209,7 @@ func identifier(ctx context.Context, view View, pkgs []Package, file *ast.File,
if hasErrorType(result.Type.Object) {
return result, nil
}
if result.Type.mappedRange, err = objToMappedRange(ctx, view, result.Type.Object); err != nil {
if result.Type.mappedRange, err = objToMappedRange(ctx, view, pkg, result.Type.Object); err != nil {
return nil, err
}
}
@ -230,7 +245,11 @@ func hasErrorType(obj types.Object) bool {
func objToNode(ctx context.Context, view View, pkg Package, obj types.Object) (ast.Decl, error) {
uri := span.FileURI(view.Session().Cache().FileSet().Position(obj.Pos()).Filename)
_, declAST, _, err := pkg.FindFile(ctx, uri)
ph, _, err := pkg.FindFile(ctx, uri)
if err != nil {
return nil, err
}
declAST, _, err := ph.Cached(ctx)
if declAST == nil {
return nil, err
}
@ -291,7 +310,7 @@ func importSpec(ctx context.Context, view View, fAST *ast.File, pkgs []Package,
Name: importPath,
pkgs: pkgs,
}
if result.mappedRange, err = posToRange(ctx, view, imp.Path.Pos(), imp.Path.End()); err != nil {
if result.mappedRange, err = posToMappedRange(ctx, view, pkg, imp.Path.Pos(), imp.Path.End()); err != nil {
return nil, err
}
// Consider the "declaration" of an import spec to be the imported package.
@ -312,7 +331,7 @@ func importSpec(ctx context.Context, view View, fAST *ast.File, pkgs []Package,
if dest == nil {
return nil, errors.Errorf("package %q has no files", importPath)
}
if result.Declaration.mappedRange, err = posToRange(ctx, view, dest.Pos(), dest.End()); err != nil {
if result.Declaration.mappedRange, err = posToMappedRange(ctx, view, pkg, dest.Pos(), dest.End()); err != nil {
return nil, err
}
result.Declaration.node = imp

View File

@ -56,7 +56,7 @@ func (i *IdentifierInfo) References(ctx context.Context) ([]*ReferenceInfo, erro
if obj == nil || !sameObj(obj, i.Declaration.obj) {
continue
}
rng, err := posToRange(ctx, i.View, ident.Pos(), ident.End())
rng, err := posToMappedRange(ctx, i.View, pkg, ident.Pos(), ident.End())
if err != nil {
return nil, err
}
@ -74,7 +74,7 @@ func (i *IdentifierInfo) References(ctx context.Context) ([]*ReferenceInfo, erro
if obj == nil || !sameObj(obj, i.Declaration.obj) {
continue
}
rng, err := posToRange(ctx, i.View, ident.Pos(), ident.End())
rng, err := posToMappedRange(ctx, i.View, pkg, ident.Pos(), ident.End())
if err != nil {
return nil, err
}

View File

@ -149,13 +149,25 @@ func (i *IdentifierInfo) Rename(ctx context.Context, view View, newName string)
}
result := make(map[span.URI][]protocol.TextEdit)
for uri, edits := range changes {
// Sort the edits first.
diff.SortTextEdits(edits)
_, m, err := cachedFileToMapper(ctx, view, uri)
// These edits should really be associated with FileHandles for maximal correctness.
// For now, this is good enough.
f, err := view.GetFile(ctx, uri)
if err != nil {
return nil, err
}
fh := f.Handle(ctx)
data, _, err := fh.Read(ctx)
if err != nil {
return nil, err
}
converter := span.NewContentConverter(uri.Filename(), data)
m := &protocol.ColumnMapper{
URI: uri,
Converter: converter,
Content: data,
}
// Sort the edits first.
diff.SortTextEdits(edits)
protocolEdits, err := ToProtocolEdits(m, edits)
if err != nil {
return nil, err
@ -218,14 +230,13 @@ func getPkgNameIdentifier(ctx context.Context, ident *IdentifierInfo, pkgName *t
obj: pkgName,
wasImplicit: true,
}
var err error
if decl.mappedRange, err = objToMappedRange(ctx, ident.View, decl.obj); err != nil {
return nil, err
}
pkg, err := bestPackage(ident.File.File().Identity().URI, ident.pkgs)
if err != nil {
return nil, err
}
if decl.mappedRange, err = objToMappedRange(ctx, ident.View, pkg, decl.obj); err != nil {
return nil, err
}
if decl.node, err = objToNode(ctx, ident.View, pkg, decl.obj); err != nil {
return nil, err
}

View File

@ -31,7 +31,7 @@ func SignatureHelp(ctx context.Context, view View, f GoFile, pos protocol.Positi
ctx, done := trace.StartSpan(ctx, "source.SignatureHelp")
defer done()
file, pkgs, m, err := fileToMapper(ctx, view, f.URI())
pkgs, err := f.GetPackages(ctx)
if err != nil {
return nil, err
}
@ -39,6 +39,17 @@ func SignatureHelp(ctx context.Context, view View, f GoFile, pos protocol.Positi
if err != nil {
return nil, err
}
var ph ParseGoHandle
for _, h := range pkg.GetHandles() {
if h.File().Identity().URI == f.URI() {
ph = h
break
}
}
file, m, err := ph.Cached(ctx)
if file == nil {
return nil, err
}
spn, err := m.PointSpan(pos)
if err != nil {
return nil, err
@ -113,7 +124,7 @@ FindCall:
if err != nil {
return nil, err
}
rng, err := objToMappedRange(ctx, view, obj)
rng, err := objToMappedRange(ctx, view, pkg, obj)
if err != nil {
return nil, err
}

View File

@ -5,14 +5,24 @@ import (
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/internal/lsp/protocol"
"golang.org/x/tools/internal/span"
)
func getCodeActions(ctx context.Context, view View, diag analysis.Diagnostic) ([]SuggestedFix, error) {
func getCodeActions(ctx context.Context, view View, pkg Package, diag analysis.Diagnostic) ([]SuggestedFix, error) {
var fixes []SuggestedFix
for _, fix := range diag.SuggestedFixes {
var edits []protocol.TextEdit
for _, e := range fix.TextEdits {
mrng, err := posToRange(ctx, view, e.Pos, e.End)
posn := view.Session().Cache().FileSet().Position(e.Pos)
ph, _, err := pkg.FindFile(ctx, span.FileURI(posn.Filename))
if err != nil {
return nil, err
}
_, m, err := ph.Cached(ctx)
if m == nil {
return nil, err
}
mrng, err := posToRange(ctx, view, m, e.Pos, e.End)
if err != nil {
return nil, err
}

View File

@ -22,10 +22,13 @@ func DocumentSymbols(ctx context.Context, view View, f GoFile) ([]protocol.Docum
if err != nil {
return nil, err
}
var file *ast.File
var (
file *ast.File
m *protocol.ColumnMapper
)
for _, ph := range pkg.GetHandles() {
if ph.File().Identity().URI == f.URI() {
file, _, err = ph.Cached(ctx)
file, m, err = ph.Cached(ctx)
}
}
if file == nil {
@ -42,7 +45,7 @@ func DocumentSymbols(ctx context.Context, view View, f GoFile) ([]protocol.Docum
switch decl := decl.(type) {
case *ast.FuncDecl:
if obj := info.ObjectOf(decl.Name); obj != nil {
if fs := funcSymbol(ctx, view, decl, obj, q); fs.Kind == protocol.Method {
if fs := funcSymbol(ctx, view, m, decl, obj, q); fs.Kind == protocol.Method {
// Store methods separately, as we want them to appear as children
// of the corresponding type (which we may not have seen yet).
rtype := obj.Type().(*types.Signature).Recv().Type()
@ -56,14 +59,14 @@ func DocumentSymbols(ctx context.Context, view View, f GoFile) ([]protocol.Docum
switch spec := spec.(type) {
case *ast.TypeSpec:
if obj := info.ObjectOf(spec.Name); obj != nil {
ts := typeSymbol(ctx, view, info, spec, obj, q)
ts := typeSymbol(ctx, view, m, info, spec, obj, q)
symbols = append(symbols, ts)
symbolsToReceiver[obj.Type()] = len(symbols) - 1
}
case *ast.ValueSpec:
for _, name := range spec.Names {
if obj := info.ObjectOf(name); obj != nil {
symbols = append(symbols, varSymbol(ctx, view, decl, name, obj, q))
symbols = append(symbols, varSymbol(ctx, view, m, decl, name, obj, q))
}
}
}
@ -87,15 +90,15 @@ func DocumentSymbols(ctx context.Context, view View, f GoFile) ([]protocol.Docum
return symbols, nil
}
func funcSymbol(ctx context.Context, view View, decl *ast.FuncDecl, obj types.Object, q types.Qualifier) protocol.DocumentSymbol {
func funcSymbol(ctx context.Context, view View, m *protocol.ColumnMapper, decl *ast.FuncDecl, obj types.Object, q types.Qualifier) protocol.DocumentSymbol {
s := protocol.DocumentSymbol{
Name: obj.Name(),
Kind: protocol.Function,
}
if span, err := nodeToProtocolRange(ctx, view, decl); err == nil {
if span, err := nodeToProtocolRange(ctx, view, m, decl); err == nil {
s.Range = span
}
if span, err := nodeToProtocolRange(ctx, view, decl.Name); err == nil {
if span, err := nodeToProtocolRange(ctx, view, m, decl.Name); err == nil {
s.SelectionRange = span
}
sig, _ := obj.Type().(*types.Signature)
@ -148,17 +151,17 @@ func setKind(s *protocol.DocumentSymbol, typ types.Type, q types.Qualifier) {
}
}
func typeSymbol(ctx context.Context, view View, info *types.Info, spec *ast.TypeSpec, obj types.Object, q types.Qualifier) protocol.DocumentSymbol {
func typeSymbol(ctx context.Context, view View, m *protocol.ColumnMapper, info *types.Info, spec *ast.TypeSpec, obj types.Object, q types.Qualifier) protocol.DocumentSymbol {
s := protocol.DocumentSymbol{
Name: obj.Name(),
}
s.Detail, _ = formatType(obj.Type(), q)
setKind(&s, obj.Type(), q)
if span, err := nodeToProtocolRange(ctx, view, spec); err == nil {
if span, err := nodeToProtocolRange(ctx, view, m, spec); err == nil {
s.Range = span
}
if span, err := nodeToProtocolRange(ctx, view, spec.Name); err == nil {
if span, err := nodeToProtocolRange(ctx, view, m, spec.Name); err == nil {
s.SelectionRange = span
}
t, objIsStruct := obj.Type().Underlying().(*types.Struct)
@ -173,10 +176,10 @@ func typeSymbol(ctx context.Context, view View, info *types.Info, spec *ast.Type
child.Detail, _ = formatType(f.Type(), q)
spanNode, selectionNode := nodesForStructField(i, st)
if span, err := nodeToProtocolRange(ctx, view, spanNode); err == nil {
if span, err := nodeToProtocolRange(ctx, view, m, spanNode); err == nil {
child.Range = span
}
if span, err := nodeToProtocolRange(ctx, view, selectionNode); err == nil {
if span, err := nodeToProtocolRange(ctx, view, m, selectionNode); err == nil {
child.SelectionRange = span
}
s.Children = append(s.Children, child)
@ -203,10 +206,10 @@ func typeSymbol(ctx context.Context, view View, info *types.Info, spec *ast.Type
}
}
}
if span, err := nodeToProtocolRange(ctx, view, spanNode); err == nil {
if span, err := nodeToProtocolRange(ctx, view, m, spanNode); err == nil {
child.Range = span
}
if span, err := nodeToProtocolRange(ctx, view, selectionNode); err == nil {
if span, err := nodeToProtocolRange(ctx, view, m, selectionNode); err == nil {
child.SelectionRange = span
}
s.Children = append(s.Children, child)
@ -235,10 +238,10 @@ func typeSymbol(ctx context.Context, view View, info *types.Info, spec *ast.Type
break Embeddeds
}
}
if rng, err := nodeToProtocolRange(ctx, view, spanNode); err == nil {
if rng, err := nodeToProtocolRange(ctx, view, m, spanNode); err == nil {
child.Range = rng
}
if span, err := nodeToProtocolRange(ctx, view, selectionNode); err == nil {
if span, err := nodeToProtocolRange(ctx, view, m, selectionNode); err == nil {
child.SelectionRange = span
}
s.Children = append(s.Children, child)
@ -267,7 +270,7 @@ func nodesForStructField(i int, st *ast.StructType) (span, selection ast.Node) {
return nil, nil
}
func varSymbol(ctx context.Context, view View, decl ast.Node, name *ast.Ident, obj types.Object, q types.Qualifier) protocol.DocumentSymbol {
func varSymbol(ctx context.Context, view View, m *protocol.ColumnMapper, decl ast.Node, name *ast.Ident, obj types.Object, q types.Qualifier) protocol.DocumentSymbol {
s := protocol.DocumentSymbol{
Name: obj.Name(),
Kind: protocol.Variable,
@ -275,10 +278,10 @@ func varSymbol(ctx context.Context, view View, decl ast.Node, name *ast.Ident, o
if _, ok := obj.(*types.Const); ok {
s.Kind = protocol.Constant
}
if rng, err := nodeToProtocolRange(ctx, view, decl); err == nil {
if rng, err := nodeToProtocolRange(ctx, view, m, decl); err == nil {
s.Range = rng
}
if span, err := nodeToProtocolRange(ctx, view, name); err == nil {
if span, err := nodeToProtocolRange(ctx, view, m, name); err == nil {
s.SelectionRange = span
}
s.Detail = types.TypeString(obj.Type(), q)

View File

@ -69,73 +69,6 @@ func bestPackage(uri span.URI, pkgs []Package) (Package, error) {
return result, nil
}
func fileToMapper(ctx context.Context, view View, uri span.URI) (*ast.File, []Package, *protocol.ColumnMapper, error) {
f, err := view.GetFile(ctx, uri)
if err != nil {
return nil, nil, nil, err
}
gof, ok := f.(GoFile)
if !ok {
return nil, nil, nil, errors.Errorf("%s is not a Go file", f.URI())
}
pkgs, err := gof.GetPackages(ctx)
if err != nil {
return nil, nil, nil, err
}
pkg, err := bestPackage(f.URI(), pkgs)
if err != nil {
return nil, nil, nil, err
}
file, m, err := pkgToMapper(ctx, view, pkg, f.URI())
if err != nil {
return nil, nil, nil, err
}
return file, pkgs, m, nil
}
func cachedFileToMapper(ctx context.Context, view View, uri span.URI) (*ast.File, *protocol.ColumnMapper, error) {
f, err := view.GetFile(ctx, uri)
if err != nil {
return nil, nil, err
}
gof, ok := f.(GoFile)
if !ok {
return nil, nil, errors.Errorf("%s is not a Go file", f.URI())
}
pkg, err := gof.GetCachedPackage(ctx)
if err == nil {
file, m, err := pkgToMapper(ctx, view, pkg, f.URI())
if err != nil {
return nil, nil, err
}
return file, m, nil
}
// Fallback to just looking for the AST.
ph := view.Session().Cache().ParseGoHandle(gof.Handle(ctx), ParseFull)
file, m, err := ph.Cached(ctx)
if file == nil {
return nil, nil, err
}
return file, m, nil
}
func pkgToMapper(ctx context.Context, view View, pkg Package, uri span.URI) (*ast.File, *protocol.ColumnMapper, error) {
var ph ParseGoHandle
for _, h := range pkg.GetHandles() {
if h.File().Identity().URI == uri {
ph = h
}
}
if ph == nil {
return nil, nil, errors.Errorf("no ParseGoHandle for %s", uri)
}
file, m, err := ph.Cached(ctx)
if file == nil {
return nil, nil, err
}
return file, m, nil
}
func IsGenerated(ctx context.Context, view View, uri span.URI) bool {
f, err := view.GetFile(ctx, uri)
if err != nil {
@ -163,15 +96,15 @@ func IsGenerated(ctx context.Context, view View, uri span.URI) bool {
return false
}
func nodeToProtocolRange(ctx context.Context, view View, n ast.Node) (protocol.Range, error) {
mrng, err := nodeToMappedRange(ctx, view, n)
func nodeToProtocolRange(ctx context.Context, view View, m *protocol.ColumnMapper, n ast.Node) (protocol.Range, error) {
mrng, err := nodeToMappedRange(ctx, view, m, n)
if err != nil {
return protocol.Range{}, err
}
return mrng.Range()
}
func objToMappedRange(ctx context.Context, view View, obj types.Object) (mappedRange, error) {
func objToMappedRange(ctx context.Context, view View, pkg Package, obj types.Object) (mappedRange, error) {
if pkgName, ok := obj.(*types.PkgName); ok {
// An imported Go package has a package-local, unqualified name.
// When the name matches the imported package name, there is no
@ -184,38 +117,54 @@ func objToMappedRange(ctx context.Context, view View, obj types.Object) (mappedR
// When the identifier does not appear in the source, have the range
// of the object be the point at the beginning of the declaration.
if pkgName.Imported().Name() == pkgName.Name() {
return nameToMappedRange(ctx, view, obj.Pos(), "")
return nameToMappedRange(ctx, view, pkg, obj.Pos(), "")
}
}
return nameToMappedRange(ctx, view, obj.Pos(), obj.Name())
return nameToMappedRange(ctx, view, pkg, obj.Pos(), obj.Name())
}
func nameToMappedRange(ctx context.Context, view View, pos token.Pos, name string) (mappedRange, error) {
return posToRange(ctx, view, pos, pos+token.Pos(len(name)))
func nameToMappedRange(ctx context.Context, view View, pkg Package, pos token.Pos, name string) (mappedRange, error) {
return posToMappedRange(ctx, view, pkg, pos, pos+token.Pos(len(name)))
}
func nodeToMappedRange(ctx context.Context, view View, n ast.Node) (mappedRange, error) {
return posToRange(ctx, view, n.Pos(), n.End())
func nodeToMappedRange(ctx context.Context, view View, m *protocol.ColumnMapper, n ast.Node) (mappedRange, error) {
return posToRange(ctx, view, m, n.Pos(), n.End())
}
func posToRange(ctx context.Context, view View, pos, end token.Pos) (mappedRange, error) {
func posToMappedRange(ctx context.Context, view View, pkg Package, pos, end token.Pos) (mappedRange, error) {
m, err := posToMapper(ctx, view, pkg, pos)
if err != nil {
return mappedRange{}, err
}
return posToRange(ctx, view, m, pos, end)
}
func posToRange(ctx context.Context, view View, m *protocol.ColumnMapper, pos, end token.Pos) (mappedRange, error) {
if !pos.IsValid() {
return mappedRange{}, errors.Errorf("invalid position for %v", pos)
}
if !end.IsValid() {
return mappedRange{}, errors.Errorf("invalid position for %v", end)
}
posn := view.Session().Cache().FileSet().Position(pos)
_, m, err := cachedFileToMapper(ctx, view, span.FileURI(posn.Filename))
if err != nil {
return mappedRange{}, err
}
return mappedRange{
m: m,
spanRange: span.NewRange(view.Session().Cache().FileSet(), pos, end),
}, nil
}
func posToMapper(ctx context.Context, view View, pkg Package, pos token.Pos) (*protocol.ColumnMapper, error) {
posn := view.Session().Cache().FileSet().Position(pos)
ph, _, err := pkg.FindFile(ctx, span.FileURI(posn.Filename))
if err != nil {
return nil, err
}
_, m, err := ph.Cached(ctx)
if m == nil {
return nil, err
}
return m, nil
}
// Matches cgo generated comment as well as the proposed standard:
// https://golang.org/s/generatedcode
var generatedRx = regexp.MustCompile(`// .*DO NOT EDIT\.?`)

View File

@ -319,9 +319,10 @@ type Package interface {
// FindFile returns the AST and type information for a file that may
// belong to or be part of a dependency of the given package.
FindFile(ctx context.Context, uri span.URI) (ParseGoHandle, *ast.File, Package, error)
FindFile(ctx context.Context, uri span.URI) (ParseGoHandle, Package, error)
}
type BuiltinPackage interface {
Lookup(name string) *ast.Object
Files() []ParseGoHandle
}