mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
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:
parent
5999de1043
commit
2dc213d980
4
internal/lsp/cache/builtin.go
vendored
4
internal/lsp/cache/builtin.go
vendored
@ -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.
|
||||
|
15
internal/lsp/cache/pkg.go
vendored
15
internal/lsp/cache/pkg.go
vendored
@ -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)
|
||||
}
|
||||
|
11
internal/lsp/cache/view.go
vendored
11
internal/lsp/cache/view.go
vendored
@ -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()
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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\.?`)
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user