mirror of
https://github.com/golang/go.git
synced 2025-05-05 23:53:05 +00:00
internal/lsp: don't associate package with snapshot
This change effectively reverts CL 202039. This CL was a mistake, as it creates a cycle. Snapshots hold CheckPackageHandles, which in turn hold pkgs. Change-Id: I944304cb365f0ef98b5e54ea38edea6cece40453 Reviewed-on: https://go-review.googlesource.com/c/tools/+/202740 Run-TryBot: Rebecca Stambler <rstambler@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com>
This commit is contained in:
parent
c8fcd6ab79
commit
2b779830f9
2
internal/lsp/cache/check.go
vendored
2
internal/lsp/cache/check.go
vendored
@ -270,7 +270,7 @@ func (imp *importer) typeCheck(ctx context.Context, cph *checkPackageHandle) (*p
|
|||||||
}
|
}
|
||||||
|
|
||||||
pkg := &pkg{
|
pkg := &pkg{
|
||||||
snapshot: imp.snapshot,
|
view: imp.snapshot.view,
|
||||||
id: cph.m.id,
|
id: cph.m.id,
|
||||||
mode: cph.mode,
|
mode: cph.mode,
|
||||||
pkgPath: cph.m.pkgPath,
|
pkgPath: cph.m.pkgPath,
|
||||||
|
16
internal/lsp/cache/errors.go
vendored
16
internal/lsp/cache/errors.go
vendored
@ -27,7 +27,7 @@ func sourceError(ctx context.Context, pkg *pkg, e interface{}) (*source.Error, e
|
|||||||
fixes []source.SuggestedFix
|
fixes []source.SuggestedFix
|
||||||
related []source.RelatedInformation
|
related []source.RelatedInformation
|
||||||
)
|
)
|
||||||
fset := pkg.snapshot.view.session.cache.fset
|
fset := pkg.view.session.cache.fset
|
||||||
switch e := e.(type) {
|
switch e := e.(type) {
|
||||||
case packages.Error:
|
case packages.Error:
|
||||||
if e.Pos == "" {
|
if e.Pos == "" {
|
||||||
@ -64,18 +64,18 @@ func sourceError(ctx context.Context, pkg *pkg, e interface{}) (*source.Error, e
|
|||||||
spn, err = typeErrorRange(ctx, fset, pkg, e.Pos)
|
spn, err = typeErrorRange(ctx, fset, pkg, e.Pos)
|
||||||
|
|
||||||
case *analysis.Diagnostic:
|
case *analysis.Diagnostic:
|
||||||
spn, err = span.NewRange(pkg.snapshot.view.session.cache.fset, e.Pos, e.End).Span()
|
spn, err = span.NewRange(fset, e.Pos, e.End).Span()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
msg = e.Message
|
msg = e.Message
|
||||||
kind = source.Analysis
|
kind = source.Analysis
|
||||||
category = e.Category
|
category = e.Category
|
||||||
fixes, err = suggestedFixes(ctx, pkg, e)
|
fixes, err = suggestedFixes(ctx, fset, pkg, e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
related, err = relatedInformation(ctx, pkg, e)
|
related, err = relatedInformation(ctx, fset, pkg, e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -95,12 +95,12 @@ func sourceError(ctx context.Context, pkg *pkg, e interface{}) (*source.Error, e
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func suggestedFixes(ctx context.Context, pkg *pkg, diag *analysis.Diagnostic) ([]source.SuggestedFix, error) {
|
func suggestedFixes(ctx context.Context, fset *token.FileSet, pkg *pkg, diag *analysis.Diagnostic) ([]source.SuggestedFix, error) {
|
||||||
var fixes []source.SuggestedFix
|
var fixes []source.SuggestedFix
|
||||||
for _, fix := range diag.SuggestedFixes {
|
for _, fix := range diag.SuggestedFixes {
|
||||||
edits := make(map[span.URI][]protocol.TextEdit)
|
edits := make(map[span.URI][]protocol.TextEdit)
|
||||||
for _, e := range fix.TextEdits {
|
for _, e := range fix.TextEdits {
|
||||||
spn, err := span.NewRange(pkg.Snapshot().View().Session().Cache().FileSet(), e.Pos, e.End).Span()
|
spn, err := span.NewRange(fset, e.Pos, e.End).Span()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -121,10 +121,10 @@ func suggestedFixes(ctx context.Context, pkg *pkg, diag *analysis.Diagnostic) ([
|
|||||||
return fixes, nil
|
return fixes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func relatedInformation(ctx context.Context, pkg *pkg, diag *analysis.Diagnostic) ([]source.RelatedInformation, error) {
|
func relatedInformation(ctx context.Context, fset *token.FileSet, pkg *pkg, diag *analysis.Diagnostic) ([]source.RelatedInformation, error) {
|
||||||
var out []source.RelatedInformation
|
var out []source.RelatedInformation
|
||||||
for _, related := range diag.Related {
|
for _, related := range diag.Related {
|
||||||
spn, err := span.NewRange(pkg.Snapshot().View().Session().Cache().FileSet(), related.Pos, related.End).Span()
|
spn, err := span.NewRange(fset, related.Pos, related.End).Span()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
10
internal/lsp/cache/pkg.go
vendored
10
internal/lsp/cache/pkg.go
vendored
@ -19,7 +19,7 @@ import (
|
|||||||
|
|
||||||
// pkg contains the type information needed by the source package.
|
// pkg contains the type information needed by the source package.
|
||||||
type pkg struct {
|
type pkg struct {
|
||||||
snapshot *snapshot
|
view *view
|
||||||
|
|
||||||
// ID and package path have their own types to avoid being used interchangeably.
|
// ID and package path have their own types to avoid being used interchangeably.
|
||||||
id packageID
|
id packageID
|
||||||
@ -43,8 +43,8 @@ type pkg struct {
|
|||||||
type packageID string
|
type packageID string
|
||||||
type packagePath string
|
type packagePath string
|
||||||
|
|
||||||
func (p *pkg) Snapshot() source.Snapshot {
|
func (p *pkg) View() source.View {
|
||||||
return p.snapshot
|
return p.view
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pkg) ID() string {
|
func (p *pkg) ID() string {
|
||||||
@ -139,8 +139,8 @@ func (p *pkg) FindDiagnostic(pdiag protocol.Diagnostic) (*source.Diagnostic, err
|
|||||||
|
|
||||||
func (p *pkg) FindFile(ctx context.Context, uri span.URI) (source.ParseGoHandle, source.Package, error) {
|
func (p *pkg) FindFile(ctx context.Context, uri span.URI) (source.ParseGoHandle, source.Package, error) {
|
||||||
// Special case for ignored files.
|
// Special case for ignored files.
|
||||||
if p.snapshot.view.Ignore(uri) {
|
if p.view.Ignore(uri) {
|
||||||
return p.snapshot.view.findIgnoredFile(ctx, uri)
|
return p.view.findIgnoredFile(ctx, uri)
|
||||||
}
|
}
|
||||||
|
|
||||||
queue := []*pkg{p}
|
queue := []*pkg{p}
|
||||||
|
@ -136,7 +136,7 @@ func (c *completer) item(cand candidate) (CompletionItem, error) {
|
|||||||
if !(file.Pos() <= obj.Pos() && obj.Pos() <= file.End()) {
|
if !(file.Pos() <= obj.Pos() && obj.Pos() <= file.End()) {
|
||||||
return CompletionItem{}, errors.Errorf("no file for %s", obj.Name())
|
return CompletionItem{}, errors.Errorf("no file for %s", obj.Name())
|
||||||
}
|
}
|
||||||
ident, err := findIdentifier(c.ctx, pkg, file, obj.Pos())
|
ident, err := findIdentifier(c.ctx, c.snapshot, pkg, file, obj.Pos())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return CompletionItem{}, err
|
return CompletionItem{}, err
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ func (i *IdentifierInfo) Hover(ctx context.Context) (*HoverInformation, error) {
|
|||||||
switch x := h.source.(type) {
|
switch x := h.source.(type) {
|
||||||
case ast.Node:
|
case ast.Node:
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
if err := format.Node(&b, i.Snapshot().View().Session().Cache().FileSet(), x); err != nil {
|
if err := format.Node(&b, i.Snapshot.View().Session().Cache().FileSet(), x); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
h.Signature = b.String()
|
h.Signature = b.String()
|
||||||
|
@ -20,8 +20,9 @@ import (
|
|||||||
|
|
||||||
// IdentifierInfo holds information about an identifier in Go source.
|
// IdentifierInfo holds information about an identifier in Go source.
|
||||||
type IdentifierInfo struct {
|
type IdentifierInfo struct {
|
||||||
Name string
|
Name string
|
||||||
File ParseGoHandle
|
File ParseGoHandle
|
||||||
|
Snapshot Snapshot
|
||||||
mappedRange
|
mappedRange
|
||||||
|
|
||||||
Type struct {
|
Type struct {
|
||||||
@ -37,10 +38,6 @@ type IdentifierInfo struct {
|
|||||||
qf types.Qualifier
|
qf types.Qualifier
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IdentifierInfo) Snapshot() Snapshot {
|
|
||||||
return i.pkg.Snapshot()
|
|
||||||
}
|
|
||||||
|
|
||||||
type Declaration struct {
|
type Declaration struct {
|
||||||
mappedRange
|
mappedRange
|
||||||
node ast.Node
|
node ast.Node
|
||||||
@ -51,7 +48,7 @@ type Declaration struct {
|
|||||||
// Identifier returns identifier information for a position
|
// Identifier returns identifier information for a position
|
||||||
// in a file, accounting for a potentially incomplete selector.
|
// in a file, accounting for a potentially incomplete selector.
|
||||||
func Identifier(ctx context.Context, view View, f File, pos protocol.Position) (*IdentifierInfo, error) {
|
func Identifier(ctx context.Context, view View, f File, pos protocol.Position) (*IdentifierInfo, error) {
|
||||||
_, cphs, err := view.CheckPackageHandles(ctx, f)
|
snapshot, cphs, err := view.CheckPackageHandles(ctx, f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -79,17 +76,17 @@ func Identifier(ctx context.Context, view View, f File, pos protocol.Position) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return findIdentifier(ctx, pkg, file, rng.Start)
|
return findIdentifier(ctx, snapshot, pkg, file, rng.Start)
|
||||||
}
|
}
|
||||||
|
|
||||||
func findIdentifier(ctx context.Context, pkg Package, file *ast.File, pos token.Pos) (*IdentifierInfo, error) {
|
func findIdentifier(ctx context.Context, snapshot Snapshot, pkg Package, file *ast.File, pos token.Pos) (*IdentifierInfo, error) {
|
||||||
if result, err := identifier(ctx, pkg, file, pos); err != nil || result != nil {
|
if result, err := identifier(ctx, snapshot, pkg, file, pos); err != nil || result != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
// If the position is not an identifier but immediately follows
|
// If the position is not an identifier but immediately follows
|
||||||
// an identifier or selector period (as is common when
|
// an identifier or selector period (as is common when
|
||||||
// requesting a completion), use the path to the preceding node.
|
// requesting a completion), use the path to the preceding node.
|
||||||
ident, err := identifier(ctx, pkg, file, pos-1)
|
ident, err := identifier(ctx, snapshot, pkg, file, pos-1)
|
||||||
if ident == nil && err == nil {
|
if ident == nil && err == nil {
|
||||||
err = errors.New("no identifier found")
|
err = errors.New("no identifier found")
|
||||||
}
|
}
|
||||||
@ -97,21 +94,21 @@ func findIdentifier(ctx context.Context, pkg Package, file *ast.File, pos token.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// identifier checks a single position for a potential identifier.
|
// identifier checks a single position for a potential identifier.
|
||||||
func identifier(ctx context.Context, pkg Package, file *ast.File, pos token.Pos) (*IdentifierInfo, error) {
|
func identifier(ctx context.Context, snapshot Snapshot, pkg Package, file *ast.File, pos token.Pos) (*IdentifierInfo, error) {
|
||||||
ctx, done := trace.StartSpan(ctx, "source.identifier")
|
ctx, done := trace.StartSpan(ctx, "source.identifier")
|
||||||
defer done()
|
defer done()
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// Handle import specs separately, as there is no formal position for a package declaration.
|
// Handle import specs separately, as there is no formal position for a package declaration.
|
||||||
if result, err := importSpec(ctx, pkg, file, pos); result != nil || err != nil {
|
if result, err := importSpec(ctx, snapshot, pkg, file, pos); result != nil || err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
path, _ := astutil.PathEnclosingInterval(file, pos, pos)
|
path, _ := astutil.PathEnclosingInterval(file, pos, pos)
|
||||||
if path == nil {
|
if path == nil {
|
||||||
return nil, errors.Errorf("can't find node enclosing position")
|
return nil, errors.Errorf("can't find node enclosing position")
|
||||||
}
|
}
|
||||||
view := pkg.Snapshot().View()
|
view := pkg.View()
|
||||||
uri := span.FileURI(view.Session().Cache().FileSet().Position(pos).Filename)
|
uri := span.FileURI(view.Session().Cache().FileSet().Position(pos).Filename)
|
||||||
var ph ParseGoHandle
|
var ph ParseGoHandle
|
||||||
for _, h := range pkg.Files() {
|
for _, h := range pkg.Files() {
|
||||||
@ -120,10 +117,11 @@ func identifier(ctx context.Context, pkg Package, file *ast.File, pos token.Pos)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
result := &IdentifierInfo{
|
result := &IdentifierInfo{
|
||||||
File: ph,
|
File: ph,
|
||||||
qf: qualifier(file, pkg.GetTypes(), pkg.GetTypesInfo()),
|
Snapshot: snapshot,
|
||||||
pkg: pkg,
|
qf: qualifier(file, pkg.GetTypes(), pkg.GetTypesInfo()),
|
||||||
ident: searchForIdent(path[0]),
|
pkg: pkg,
|
||||||
|
ident: searchForIdent(path[0]),
|
||||||
}
|
}
|
||||||
// No identifier at the given position.
|
// No identifier at the given position.
|
||||||
if result.ident == nil {
|
if result.ident == nil {
|
||||||
@ -244,7 +242,7 @@ func hasErrorType(obj types.Object) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func objToNode(ctx context.Context, pkg Package, obj types.Object) (ast.Decl, error) {
|
func objToNode(ctx context.Context, pkg Package, obj types.Object) (ast.Decl, error) {
|
||||||
view := pkg.Snapshot().View()
|
view := pkg.View()
|
||||||
uri := span.FileURI(view.Session().Cache().FileSet().Position(obj.Pos()).Filename)
|
uri := span.FileURI(view.Session().Cache().FileSet().Position(obj.Pos()).Filename)
|
||||||
ph, _, err := pkg.FindFile(ctx, uri)
|
ph, _, err := pkg.FindFile(ctx, uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -280,7 +278,7 @@ func objToNode(ctx context.Context, pkg Package, obj types.Object) (ast.Decl, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// importSpec handles positions inside of an *ast.ImportSpec.
|
// importSpec handles positions inside of an *ast.ImportSpec.
|
||||||
func importSpec(ctx context.Context, pkg Package, file *ast.File, pos token.Pos) (*IdentifierInfo, error) {
|
func importSpec(ctx context.Context, snapshot Snapshot, pkg Package, file *ast.File, pos token.Pos) (*IdentifierInfo, error) {
|
||||||
var imp *ast.ImportSpec
|
var imp *ast.ImportSpec
|
||||||
for _, spec := range file.Imports {
|
for _, spec := range file.Imports {
|
||||||
if spec.Path.Pos() <= pos && pos < spec.Path.End() {
|
if spec.Path.Pos() <= pos && pos < spec.Path.End() {
|
||||||
@ -294,7 +292,7 @@ func importSpec(ctx context.Context, pkg Package, file *ast.File, pos token.Pos)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("import path not quoted: %s (%v)", imp.Path.Value, err)
|
return nil, errors.Errorf("import path not quoted: %s (%v)", imp.Path.Value, err)
|
||||||
}
|
}
|
||||||
uri := span.FileURI(pkg.Snapshot().View().Session().Cache().FileSet().Position(pos).Filename)
|
uri := span.FileURI(pkg.View().Session().Cache().FileSet().Position(pos).Filename)
|
||||||
var ph ParseGoHandle
|
var ph ParseGoHandle
|
||||||
for _, h := range pkg.Files() {
|
for _, h := range pkg.Files() {
|
||||||
if h.File().Identity().URI == uri {
|
if h.File().Identity().URI == uri {
|
||||||
@ -302,9 +300,10 @@ func importSpec(ctx context.Context, pkg Package, file *ast.File, pos token.Pos)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
result := &IdentifierInfo{
|
result := &IdentifierInfo{
|
||||||
File: ph,
|
File: ph,
|
||||||
Name: importPath,
|
Snapshot: snapshot,
|
||||||
pkg: pkg,
|
Name: importPath,
|
||||||
|
pkg: pkg,
|
||||||
}
|
}
|
||||||
if result.mappedRange, err = posToMappedRange(ctx, pkg, imp.Path.Pos(), imp.Path.End()); err != nil {
|
if result.mappedRange, err = posToMappedRange(ctx, pkg, imp.Path.Pos(), imp.Path.End()); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -151,7 +151,7 @@ func (i *IdentifierInfo) Rename(ctx context.Context, view View, newName string)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
fh := i.Snapshot().Handle(ctx, f)
|
fh := i.Snapshot.Handle(ctx, f)
|
||||||
data, _, err := fh.Read(ctx)
|
data, _, err := fh.Read(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -225,6 +225,7 @@ func getPkgNameIdentifier(ctx context.Context, ident *IdentifierInfo, pkgName *t
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &IdentifierInfo{
|
return &IdentifierInfo{
|
||||||
|
Snapshot: ident.Snapshot,
|
||||||
Name: pkgName.Name(),
|
Name: pkgName.Name(),
|
||||||
mappedRange: decl.mappedRange,
|
mappedRange: decl.mappedRange,
|
||||||
File: ident.File,
|
File: ident.File,
|
||||||
|
@ -159,7 +159,7 @@ func posToMappedRange(ctx context.Context, pkg Package, pos, end token.Pos) (map
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return mappedRange{}, err
|
return mappedRange{}, err
|
||||||
}
|
}
|
||||||
return posToRange(ctx, pkg.Snapshot().View(), m, pos, end)
|
return posToRange(ctx, pkg.View(), m, pos, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
func posToRange(ctx context.Context, view View, m *protocol.ColumnMapper, pos, end token.Pos) (mappedRange, error) {
|
func posToRange(ctx context.Context, view View, m *protocol.ColumnMapper, pos, end token.Pos) (mappedRange, error) {
|
||||||
@ -176,7 +176,7 @@ func posToRange(ctx context.Context, view View, m *protocol.ColumnMapper, pos, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func posToMapper(ctx context.Context, pkg Package, pos token.Pos) (*protocol.ColumnMapper, error) {
|
func posToMapper(ctx context.Context, pkg Package, pos token.Pos) (*protocol.ColumnMapper, error) {
|
||||||
posn := pkg.Snapshot().View().Session().Cache().FileSet().Position(pos)
|
posn := pkg.View().Session().Cache().FileSet().Position(pos)
|
||||||
ph, _, err := pkg.FindFile(ctx, span.FileURI(posn.Filename))
|
ph, _, err := pkg.FindFile(ctx, span.FileURI(posn.Filename))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -274,7 +274,6 @@ type File interface {
|
|||||||
// Package represents a Go package that has been type-checked. It maintains
|
// Package represents a Go package that has been type-checked. It maintains
|
||||||
// only the relevant fields of a *go/packages.Package.
|
// only the relevant fields of a *go/packages.Package.
|
||||||
type Package interface {
|
type Package interface {
|
||||||
Snapshot() Snapshot
|
|
||||||
ID() string
|
ID() string
|
||||||
PkgPath() string
|
PkgPath() string
|
||||||
Files() []ParseGoHandle
|
Files() []ParseGoHandle
|
||||||
@ -295,6 +294,8 @@ type Package interface {
|
|||||||
// FindFile returns the AST and type information for a file that may
|
// FindFile returns the AST and type information for a file that may
|
||||||
// belong to or be part of a dependency of the given package.
|
// belong to or be part of a dependency of the given package.
|
||||||
FindFile(ctx context.Context, uri span.URI) (ParseGoHandle, Package, error)
|
FindFile(ctx context.Context, uri span.URI) (ParseGoHandle, Package, error)
|
||||||
|
|
||||||
|
View() View
|
||||||
}
|
}
|
||||||
|
|
||||||
type Error struct {
|
type Error struct {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user