mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
internal/lsp: remove the GetToken and GetAST functions
Change-Id: Iddbdde5f47a31da9baab6539cd2b5bd858e7f811 Reviewed-on: https://go-review.googlesource.com/c/tools/+/194057 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
27d1b4e4f3
commit
cdebb59945
49
internal/lsp/cache/gofile.go
vendored
49
internal/lsp/cache/gofile.go
vendored
@ -7,7 +7,6 @@ package cache
|
||||
import (
|
||||
"context"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/tools/internal/lsp/source"
|
||||
@ -49,36 +48,6 @@ func (f *goFile) metadata() []*metadata {
|
||||
return result
|
||||
}
|
||||
|
||||
func (f *goFile) GetToken(ctx context.Context) (*token.File, error) {
|
||||
file, err := f.GetAST(ctx, source.ParseFull)
|
||||
if file == nil {
|
||||
return nil, err
|
||||
}
|
||||
tok := f.view.session.cache.fset.File(file.Pos())
|
||||
if tok == nil {
|
||||
return nil, errors.Errorf("no token.File for %s", f.URI())
|
||||
}
|
||||
return tok, nil
|
||||
}
|
||||
|
||||
func (f *goFile) GetAST(ctx context.Context, mode source.ParseMode) (*ast.File, error) {
|
||||
ctx = telemetry.File.With(ctx, f.URI())
|
||||
fh := f.Handle(ctx)
|
||||
|
||||
if f.isDirty(ctx, fh) || f.wrongParseMode(ctx, fh, mode) {
|
||||
if err := f.view.loadParseTypecheck(ctx, f, fh); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// Check for a cached AST first, in case getting a trimmed version would actually cause a re-parse.
|
||||
cached, err := f.view.session.cache.cachedAST(fh, mode)
|
||||
if cached != nil || err != nil {
|
||||
return cached, err
|
||||
}
|
||||
ph := f.view.session.cache.ParseGoHandle(fh, mode)
|
||||
return ph.Parse(ctx)
|
||||
}
|
||||
|
||||
func (cache *cache) cachedAST(fh source.FileHandle, mode source.ParseMode) (*ast.File, error) {
|
||||
for _, m := range []source.ParseMode{
|
||||
source.ParseHeader,
|
||||
@ -175,6 +144,24 @@ func (f *goFile) GetCachedPackage(ctx context.Context) (source.Package, error) {
|
||||
return cph.Cached(ctx)
|
||||
}
|
||||
|
||||
func (f *goFile) GetCachedPackages(ctx context.Context) ([]source.Package, error) {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
|
||||
var pkgs []source.Package
|
||||
for _, cph := range f.pkgs {
|
||||
pkg, err := cph.Cached(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pkgs = append(pkgs, pkg)
|
||||
}
|
||||
if len(pkgs) == 0 {
|
||||
return nil, errors.Errorf("no CheckPackageHandles for %s", f.URI())
|
||||
}
|
||||
return pkgs, nil
|
||||
}
|
||||
|
||||
// bestCheckPackageHandle picks the "narrowest" package for a given file.
|
||||
//
|
||||
// By "narrowest" package, we mean the package with the fewest number of files
|
||||
|
@ -27,16 +27,17 @@ func (s *Server) documentLink(ctx context.Context, params *protocol.DocumentLink
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, _, err := f.Handle(ctx).Read(ctx)
|
||||
fh := f.Handle(ctx)
|
||||
data, _, err := fh.Read(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
file, err := f.GetAST(ctx, source.ParseFull)
|
||||
file, err := view.Session().Cache().ParseGoHandle(fh, source.ParseFull).Parse(ctx)
|
||||
if file == nil {
|
||||
return nil, err
|
||||
}
|
||||
tok := view.Session().Cache().FileSet().File(file.Pos())
|
||||
m := protocol.NewColumnMapper(f.URI(), f.URI().Filename(), f.FileSet(), tok, data)
|
||||
m := protocol.NewColumnMapper(f.URI(), f.URI().Filename(), view.Session().Cache().FileSet(), tok, data)
|
||||
|
||||
var links []protocol.DocumentLink
|
||||
ast.Inspect(file, func(node ast.Node) bool {
|
||||
|
@ -26,7 +26,7 @@ func (s *Server) references(ctx context.Context, params *protocol.ReferenceParam
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
references, err := ident.References(ctx, view)
|
||||
references, err := ident.References(ctx)
|
||||
if err != nil {
|
||||
log.Error(ctx, "no references", err, tag.Of("Identifier", ident.Name))
|
||||
}
|
||||
|
@ -19,15 +19,16 @@ type FoldingRangeInfo struct {
|
||||
func FoldingRange(ctx context.Context, view View, f GoFile, lineFoldingOnly bool) (ranges []*FoldingRangeInfo, err error) {
|
||||
// TODO(suzmue): consider limiting the number of folding ranges returned, and
|
||||
// implement a way to prioritize folding ranges in that case.
|
||||
fset := f.FileSet()
|
||||
file, err := f.GetAST(ctx, ParseFull)
|
||||
fh := f.Handle(ctx)
|
||||
file, err := view.Session().Cache().ParseGoHandle(fh, ParseFull).Parse(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, _, err := f.Handle(ctx).Read(ctx)
|
||||
data, _, err := fh.Read(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fset := view.Session().Cache().FileSet()
|
||||
m := protocol.NewColumnMapper(f.URI(), f.URI().Filename(), fset, fset.File(file.Pos()), data)
|
||||
|
||||
// Get folding ranges for comments separately as they are not walked by ast.Inspect.
|
||||
|
@ -8,6 +8,7 @@ package source
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"go/ast"
|
||||
"go/format"
|
||||
"go/token"
|
||||
|
||||
@ -29,14 +30,19 @@ func Format(ctx context.Context, view View, f File) ([]protocol.TextEdit, error)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("formatting is not supported for non-Go files")
|
||||
}
|
||||
file, err := gof.GetAST(ctx, ParseFull)
|
||||
if file == nil {
|
||||
return nil, err
|
||||
}
|
||||
pkg, err := gof.GetPackage(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var file *ast.File
|
||||
for _, ph := range pkg.GetHandles() {
|
||||
if ph.File().Identity().URI == f.URI() {
|
||||
file, err = ph.Cached(ctx)
|
||||
}
|
||||
}
|
||||
if file == nil {
|
||||
return nil, err
|
||||
}
|
||||
if hasListErrors(pkg.GetErrors()) || hasParseErrors(pkg, f.URI()) {
|
||||
// Even if this package has list or parse errors, this file may not
|
||||
// have any parse errors and can still be formatted. Using format.Node
|
||||
@ -49,7 +55,7 @@ func Format(ctx context.Context, view View, f File) ([]protocol.TextEdit, error)
|
||||
return computeTextEdits(ctx, view.Session().Cache().FileSet(), f, string(formatted))
|
||||
}
|
||||
|
||||
fset := f.FileSet()
|
||||
fset := view.Session().Cache().FileSet()
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
// format.Node changes slightly from one release to another, so the version
|
||||
|
@ -46,7 +46,7 @@ func (i *IdentifierInfo) Hover(ctx context.Context) (*HoverInformation, error) {
|
||||
switch x := h.source.(type) {
|
||||
case ast.Node:
|
||||
var b strings.Builder
|
||||
if err := format.Node(&b, i.File.FileSet(), x); err != nil {
|
||||
if err := format.Node(&b, i.View.Session().Cache().FileSet(), x); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
h.Signature = b.String()
|
||||
|
@ -21,8 +21,9 @@ import (
|
||||
// IdentifierInfo holds information about an identifier in Go source.
|
||||
type IdentifierInfo struct {
|
||||
Name string
|
||||
mappedRange
|
||||
View View
|
||||
File GoFile
|
||||
mappedRange
|
||||
|
||||
Type struct {
|
||||
mappedRange
|
||||
@ -69,11 +70,11 @@ func findIdentifier(ctx context.Context, view View, f GoFile, pkg Package, file
|
||||
// If the position is not an identifier but immediately follows
|
||||
// an identifier or selector period (as is common when
|
||||
// requesting a completion), use the path to the preceding node.
|
||||
result, err := identifier(ctx, view, f, pkg, file, pos-1)
|
||||
if result == nil && err == nil {
|
||||
err = errors.Errorf("no identifier found for %s", f.FileSet().Position(pos))
|
||||
ident, err := identifier(ctx, view, f, pkg, file, pos-1)
|
||||
if ident == nil && err == nil {
|
||||
err = errors.New("no identifier found")
|
||||
}
|
||||
return result, err
|
||||
return ident, err
|
||||
}
|
||||
|
||||
// identifier checks a single position for a potential identifier.
|
||||
@ -92,6 +93,7 @@ func identifier(ctx context.Context, view View, f GoFile, pkg Package, file *ast
|
||||
return nil, errors.Errorf("can't find node enclosing position")
|
||||
}
|
||||
result := &IdentifierInfo{
|
||||
View: view,
|
||||
File: f,
|
||||
qf: qualifier(file, pkg.GetTypes(), pkg.GetTypesInfo()),
|
||||
pkg: pkg,
|
||||
@ -168,7 +170,7 @@ func identifier(ctx context.Context, view View, f GoFile, pkg Package, file *ast
|
||||
if result.Declaration.mappedRange, err = objToMappedRange(ctx, view, result.Declaration.obj); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if result.Declaration.node, err = objToNode(ctx, f.View(), pkg.GetTypes(), result.Declaration.obj, result.Declaration.mappedRange.spanRange); err != nil {
|
||||
if result.Declaration.node, err = objToNode(ctx, view, pkg.GetTypes(), result.Declaration.obj, result.Declaration.mappedRange.spanRange); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
typ := pkg.GetTypesInfo().TypeOf(result.ident)
|
||||
@ -268,6 +270,7 @@ func importSpec(ctx context.Context, view View, f GoFile, fAST *ast.File, pkg Pa
|
||||
return nil, errors.Errorf("import path not quoted: %s (%v)", imp.Path.Value, err)
|
||||
}
|
||||
result := &IdentifierInfo{
|
||||
View: view,
|
||||
File: f,
|
||||
Name: importPath,
|
||||
pkg: pkg,
|
||||
|
@ -25,7 +25,7 @@ type ReferenceInfo struct {
|
||||
|
||||
// References returns a list of references for a given identifier within the packages
|
||||
// containing i.File. Declarations appear first in the result.
|
||||
func (i *IdentifierInfo) References(ctx context.Context, view View) ([]*ReferenceInfo, error) {
|
||||
func (i *IdentifierInfo) References(ctx context.Context) ([]*ReferenceInfo, error) {
|
||||
ctx, done := trace.StartSpan(ctx, "source.References")
|
||||
defer done()
|
||||
var references []*ReferenceInfo
|
||||
@ -34,8 +34,7 @@ func (i *IdentifierInfo) References(ctx context.Context, view View) ([]*Referenc
|
||||
if i.Declaration.obj == nil {
|
||||
return nil, errors.Errorf("no references for an import spec")
|
||||
}
|
||||
|
||||
pkgs, err := i.File.GetPackages(ctx)
|
||||
pkgs, err := i.File.GetCachedPackages(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -61,7 +60,7 @@ func (i *IdentifierInfo) References(ctx context.Context, view View) ([]*Referenc
|
||||
if obj == nil || !sameObj(obj, i.Declaration.obj) {
|
||||
continue
|
||||
}
|
||||
rng, err := posToRange(ctx, view, ident.Pos(), ident.End())
|
||||
rng, err := posToRange(ctx, i.View, ident.Pos(), ident.End())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -79,7 +78,7 @@ func (i *IdentifierInfo) References(ctx context.Context, view View) ([]*Referenc
|
||||
if obj == nil || !sameObj(obj, i.Declaration.obj) {
|
||||
continue
|
||||
}
|
||||
rng, err := posToRange(ctx, view, ident.Pos(), ident.End())
|
||||
rng, err := posToRange(ctx, i.View, ident.Pos(), ident.End())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -110,14 +110,14 @@ func (i *IdentifierInfo) Rename(ctx context.Context, view View, newName string)
|
||||
return nil, errors.Errorf("failed to rename because %q is declared in package %q", i.Name, i.Declaration.obj.Pkg().Name())
|
||||
}
|
||||
|
||||
refs, err := i.References(ctx, view)
|
||||
refs, err := i.References(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r := renamer{
|
||||
ctx: ctx,
|
||||
fset: i.File.FileSet(),
|
||||
fset: view.Session().Cache().FileSet(),
|
||||
refs: refs,
|
||||
objsToUpdate: make(map[types.Object]bool),
|
||||
from: i.Name,
|
||||
@ -164,8 +164,16 @@ func (i *IdentifierInfo) Rename(ctx context.Context, view View, newName string)
|
||||
// getPkgName gets the pkg name associated with an identifer representing
|
||||
// the import path in an import spec.
|
||||
func (i *IdentifierInfo) getPkgName(ctx context.Context) (*IdentifierInfo, error) {
|
||||
file, err := i.File.GetAST(ctx, ParseHeader)
|
||||
if err != nil {
|
||||
var (
|
||||
file *ast.File
|
||||
err error
|
||||
)
|
||||
for _, ph := range i.pkg.GetHandles() {
|
||||
if ph.File().Identity().URI == i.File.URI() {
|
||||
file, err = ph.Cached(ctx)
|
||||
}
|
||||
}
|
||||
if file == nil {
|
||||
return nil, err
|
||||
}
|
||||
var namePos token.Pos
|
||||
@ -211,6 +219,7 @@ func getPkgNameIdentifier(ctx context.Context, ident *IdentifierInfo, pkgName *t
|
||||
}
|
||||
return &IdentifierInfo{
|
||||
Name: pkgName.Name(),
|
||||
View: ident.View,
|
||||
mappedRange: decl.mappedRange,
|
||||
File: ident.File,
|
||||
Declaration: decl,
|
||||
|
@ -461,11 +461,12 @@ func (r *runner) Import(t *testing.T, data tests.Imports) {
|
||||
if err != nil {
|
||||
t.Fatalf("failed for %v: %v", spn, err)
|
||||
}
|
||||
tok, err := f.(source.GoFile).GetToken(ctx)
|
||||
fh := f.Handle(ctx)
|
||||
tok, err := r.view.Session().Cache().TokenHandle(fh).Token(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get token for %s: %v", spn.URI(), err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
rng, err := spn.Range(span.NewTokenConverter(f.FileSet(), tok))
|
||||
rng, err := spn.Range(span.NewTokenConverter(r.data.Exported.ExpectFileSet, tok))
|
||||
if err != nil {
|
||||
t.Fatalf("failed for %v: %v", spn, err)
|
||||
}
|
||||
@ -476,7 +477,7 @@ func (r *runner) Import(t *testing.T, data tests.Imports) {
|
||||
}
|
||||
continue
|
||||
}
|
||||
data, _, err := f.Handle(ctx).Read(ctx)
|
||||
data, _, err := fh.Read(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
@ -596,7 +597,7 @@ func (r *runner) Reference(t *testing.T, data tests.References) {
|
||||
want[pos] = true
|
||||
}
|
||||
|
||||
refs, err := ident.References(ctx, r.view)
|
||||
refs, err := ident.References(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("failed for %v: %v", src, err)
|
||||
}
|
||||
|
@ -18,14 +18,20 @@ func DocumentSymbols(ctx context.Context, view View, f GoFile) ([]protocol.Docum
|
||||
ctx, done := trace.StartSpan(ctx, "source.DocumentSymbols")
|
||||
defer done()
|
||||
|
||||
file, err := f.GetAST(ctx, ParseFull)
|
||||
if file == nil {
|
||||
return nil, err
|
||||
}
|
||||
pkg, err := f.GetPackage(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var file *ast.File
|
||||
for _, ph := range pkg.GetHandles() {
|
||||
if ph.File().Identity().URI == f.URI() {
|
||||
file, err = ph.Cached(ctx)
|
||||
}
|
||||
}
|
||||
if file == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := pkg.GetTypesInfo()
|
||||
q := qualifier(file, pkg.GetTypes(), info)
|
||||
|
||||
|
@ -259,8 +259,6 @@ type File interface {
|
||||
URI() span.URI
|
||||
View() View
|
||||
Handle(ctx context.Context) FileHandle
|
||||
FileSet() *token.FileSet
|
||||
GetToken(ctx context.Context) (*token.File, error)
|
||||
}
|
||||
|
||||
// GoFile represents a Go source file that has been type-checked.
|
||||
@ -269,12 +267,12 @@ type GoFile interface {
|
||||
|
||||
Builtin() (*ast.File, bool)
|
||||
|
||||
// GetAST returns the AST for the file, at or above the given mode.
|
||||
GetAST(ctx context.Context, mode ParseMode) (*ast.File, error)
|
||||
|
||||
// GetCachedPackage returns the cached package for the file, if any.
|
||||
GetCachedPackage(ctx context.Context) (Package, error)
|
||||
|
||||
// GetCachedPackage returns the cached package for the file, if any.
|
||||
GetCachedPackages(ctx context.Context) ([]Package, error)
|
||||
|
||||
// GetPackage returns the CheckPackageHandle for the package that this file belongs to.
|
||||
GetCheckPackageHandle(ctx context.Context) (CheckPackageHandle, error)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user