mirror of https://github.com/golang/go.git
internal/lsp: create parseModHandle for storing go.mod data
Created an analogous data structure for go.mod files when we parse them using the golang.org/x/mod package. Gopls can now access the data within a go.mod file using a parseModHandle and the corresponding parseModData object. This will help down the road when it is time to implement the lsp functions for go.mod files. Updates golang/go#31999 Change-Id: Ibd4d64569bbe3df61b203490b63399d479e7d794 Reviewed-on: https://go-review.googlesource.com/c/tools/+/211303 Run-TryBot: Rohan Challa <rohan@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
parent
7ebc6af015
commit
56463cc14b
3
go.mod
3
go.mod
|
|
@ -3,7 +3,8 @@ module golang.org/x/tools
|
|||
go 1.11
|
||||
|
||||
require (
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898
|
||||
)
|
||||
|
|
|
|||
9
go.sum
9
go.sum
|
|
@ -1,10 +1,15 @@
|
|||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
|
|||
|
|
@ -19,7 +19,10 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy
|
|||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
|
|
@ -29,6 +32,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ func (c *cache) shouldLoad(ctx context.Context, s *snapshot, originalFH, current
|
|||
if originalFH == nil {
|
||||
return true
|
||||
}
|
||||
// If the file is a mod file, we should always load.
|
||||
if originalFH.Identity().Kind == currentFH.Identity().Kind && currentFH.Identity().Kind == source.Mod {
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,10 +47,6 @@ type parseGoData struct {
|
|||
err error
|
||||
}
|
||||
|
||||
func (pgh *parseGoHandle) String() string {
|
||||
return pgh.File().Identity().URI.Filename()
|
||||
}
|
||||
|
||||
func (c *cache) ParseGoHandle(fh source.FileHandle, mode source.ParseMode) source.ParseGoHandle {
|
||||
key := parseKey{
|
||||
file: fh.Identity(),
|
||||
|
|
@ -69,6 +65,10 @@ func (c *cache) ParseGoHandle(fh source.FileHandle, mode source.ParseMode) sourc
|
|||
}
|
||||
}
|
||||
|
||||
func (pgh *parseGoHandle) String() string {
|
||||
return pgh.File().Identity().URI.Filename()
|
||||
}
|
||||
|
||||
func (pgh *parseGoHandle) File() source.FileHandle {
|
||||
return pgh.file
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/tools/internal/lsp/source"
|
||||
"golang.org/x/tools/internal/lsp/telemetry"
|
||||
"golang.org/x/tools/internal/memoize"
|
||||
"golang.org/x/tools/internal/telemetry/trace"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type parseModHandle struct {
|
||||
handle *memoize.Handle
|
||||
file source.FileHandle
|
||||
}
|
||||
|
||||
type parseModData struct {
|
||||
memoize.NoCopy
|
||||
|
||||
modfile *modfile.File
|
||||
err error
|
||||
}
|
||||
|
||||
func (c *cache) ParseModHandle(fh source.FileHandle) source.ParseModHandle {
|
||||
key := parseKey{
|
||||
file: fh.Identity(),
|
||||
mode: source.ParseFull,
|
||||
}
|
||||
h := c.store.Bind(key, func(ctx context.Context) interface{} {
|
||||
data := &parseModData{}
|
||||
data.modfile, data.err = parseMod(ctx, fh)
|
||||
return data
|
||||
})
|
||||
return &parseModHandle{
|
||||
handle: h,
|
||||
file: fh,
|
||||
}
|
||||
}
|
||||
|
||||
func parseMod(ctx context.Context, fh source.FileHandle) (modifle *modfile.File, err error) {
|
||||
ctx, done := trace.StartSpan(ctx, "cache.parseMod", telemetry.File.Of(fh.Identity().URI.Filename()))
|
||||
defer done()
|
||||
|
||||
buf, _, err := fh.Read(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f, err := modfile.Parse(fh.Identity().URI.Filename(), buf, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (pgh *parseModHandle) String() string {
|
||||
return pgh.File().Identity().URI.Filename()
|
||||
}
|
||||
|
||||
func (pgh *parseModHandle) File() source.FileHandle {
|
||||
return pgh.file
|
||||
}
|
||||
|
||||
func (pgh *parseModHandle) Parse(ctx context.Context) (*modfile.File, error) {
|
||||
v := pgh.handle.Get(ctx)
|
||||
if v == nil {
|
||||
return nil, errors.Errorf("no parsed file for %s", pgh.File().Identity().URI)
|
||||
}
|
||||
data := v.(*parseModData)
|
||||
return data.modfile, data.err
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"go/token"
|
||||
"go/types"
|
||||
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/tools/go/analysis"
|
||||
"golang.org/x/tools/go/packages"
|
||||
"golang.org/x/tools/internal/imports"
|
||||
|
|
@ -224,6 +225,9 @@ type Cache interface {
|
|||
// FileSet returns the shared fileset used by all files in the system.
|
||||
FileSet() *token.FileSet
|
||||
|
||||
// ParseGoHandle returns a go.mod ParseGoHandle for the given file handle.
|
||||
ParseModHandle(fh FileHandle) ParseModHandle
|
||||
|
||||
// ParseGoHandle returns a ParseGoHandle for the given file handle.
|
||||
ParseGoHandle(fh FileHandle, mode ParseMode) ParseGoHandle
|
||||
}
|
||||
|
|
@ -250,6 +254,16 @@ type ParseGoHandle interface {
|
|||
Cached() (*ast.File, *protocol.ColumnMapper, error, error)
|
||||
}
|
||||
|
||||
// ParseModHandle represents a handle to the modfile for a go.mod.
|
||||
type ParseModHandle interface {
|
||||
// File returns a file handle for which to get the modfile.
|
||||
File() FileHandle
|
||||
|
||||
// Parse returns the parsed modifle for the go.mod file.
|
||||
// If the file is not available, returns nil and an error.
|
||||
Parse(ctx context.Context) (*modfile.File, error)
|
||||
}
|
||||
|
||||
// ParseMode controls the content of the AST produced when parsing a source file.
|
||||
type ParseMode int
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue