Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deps: update x/tools and gopls to 65435275 #1002

Merged
merged 2 commits into from
Dec 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions cmd/govim/gopls.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,13 @@ func (g *govimplugin) startGopls() error {
if conf.SymbolStyle != nil {
goplsConfig[goplsSymbolStyle] = *conf.SymbolStyle
}

// TODO: This option was introduced as a way to opt-out from the changes introduced in CL 268597.
// According to CL 274532 (that added this opt-out), it is intended to be removed - "Ideally
// we'll be able to remove them in a few months after things stabilize.". We need to handle that
// case before it is removed.
goplsConfig["allowModfileModifications"] = true

initParams.InitializationOptions = goplsConfig

if _, err := g.server.Initialize(context.Background(), initParams); err != nil {
Expand Down
4 changes: 2 additions & 2 deletions cmd/govim/gopls_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const (
goplsVerboseOutput = "verboseOutput"
goplsEnv = "env"
goplsAnalyses = "analyses"
goplsCodeLens = "codelens"
goplsCodeLenses = "codelenses"
goplsSymbolMatcher = "symbolMatcher"
goplsSymbolStyle = "symbolStyle"
)
Expand Down Expand Up @@ -171,7 +171,7 @@ func (g *govimplugin) Configuration(ctxt context.Context, params *protocol.Param
if conf.Analyses != nil {
goplsConfig[goplsAnalyses] = *conf.Analyses
}
goplsConfig[goplsCodeLens] = map[string]bool{
goplsConfig[goplsCodeLenses] = map[string]bool{
source.CommandToggleDetails.Name: true, // gc_details
}
if g.vimstate.config.GoplsEnv != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/govim/internal/golang_org_x_tools/event/core/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/event/label"
)

// Event holds the information about an event of note that ocurred.
// Event holds the information about an event of note that occurred.
type Event struct {
at time.Time

Expand Down
7 changes: 7 additions & 0 deletions cmd/govim/internal/golang_org_x_tools/lsp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# lsp

internal/lsp provides much of the Language Server Protocol (lsp) implementation
for gopls.

Documentation for users and contributors can be found in the
[`gopls/doc`](../../gopls/doc) directory.
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
expr := n.(*ast.CompositeLit)

// TODO: Handle partially-filled structs as well.
if len(expr.Elts) != 0 {
return
}

var file *ast.File
for _, f := range pass.Files {
if f.Pos() <= expr.Pos() && expr.Pos() <= f.End() {
Expand Down Expand Up @@ -90,10 +85,10 @@ func run(pass *analysis.Pass) (interface{}, error) {
if fieldCount == 0 || fieldCount == len(expr.Elts) {
return
}

var fillable bool
for i := 0; i < fieldCount; i++ {
field := obj.Field(i)

// Ignore fields that are not accessible in the current package.
if field.Pkg() != nil && field.Pkg() != pass.Pkg && !field.Exported() {
continue
Expand Down Expand Up @@ -137,6 +132,7 @@ func SuggestedFix(fset *token.FileSet, rng span.Range, content []byte, file *ast
break
}
}

if info == nil {
return nil, fmt.Errorf("nil types.Info")
}
Expand All @@ -161,6 +157,17 @@ func SuggestedFix(fset *token.FileSet, rng span.Range, content []byte, file *ast
}
fieldCount := obj.NumFields()

// Check which types have already been filled in. (we only want to fill in
// the unfilled types, or else we'll blat user-supplied details)
prefilledTypes := map[string]ast.Expr{}
for _, e := range expr.Elts {
if kv, ok := e.(*ast.KeyValueExpr); ok {
if key, ok := kv.Key.(*ast.Ident); ok {
prefilledTypes[key.Name] = kv.Value
}
}
}

// Use a new fileset to build up a token.File for the new composite
// literal. We need one line for foo{, one line for }, and one line for
// each field we're going to set. format.Node only cares about line
Expand All @@ -186,21 +193,6 @@ func SuggestedFix(fset *token.FileSet, rng span.Range, content []byte, file *ast
if fieldTyp == nil {
continue
}
idents, ok := matches[fieldTyp]
if !ok {
return nil, fmt.Errorf("invalid struct field type: %v", fieldTyp)
}

// Find the identifer whose name is most similar to the name of the field's key.
// If we do not find any identifer that matches the pattern, generate a new value.
// NOTE: We currently match on the name of the field key rather than the field type.
value := analysisinternal.FindBestMatch(obj.Field(i).Name(), idents)
if value == nil {
value = populateValue(fset, file, pkg, fieldTyp)
}
if value == nil {
return nil, nil
}

tok.AddLine(line - 1) // add 1 byte per line
if line > tok.LineCount() {
Expand All @@ -214,7 +206,27 @@ func SuggestedFix(fset *token.FileSet, rng span.Range, content []byte, file *ast
Name: obj.Field(i).Name(),
},
Colon: pos,
Value: value,
}
if expr, ok := prefilledTypes[obj.Field(i).Name()]; ok {
kv.Value = expr
} else {
idents, ok := matches[fieldTyp]
if !ok {
return nil, fmt.Errorf("invalid struct field type: %v", fieldTyp)
}

// Find the identifer whose name is most similar to the name of the field's key.
// If we do not find any identifer that matches the pattern, generate a new value.
// NOTE: We currently match on the name of the field key rather than the field type.
value := analysisinternal.FindBestMatch(obj.Field(i).Name(), idents)
if value == nil {
value = populateValue(fset, file, pkg, fieldTyp)
}
if value == nil {
return nil, nil
}

kv.Value = value
}
elts = append(elts, kv)
line++
Expand Down Expand Up @@ -251,33 +263,53 @@ func SuggestedFix(fset *token.FileSet, rng span.Range, content []byte, file *ast
index := bytes.Index(firstLine, trimmed)
whitespace := firstLine[:index]

var newExpr bytes.Buffer
if err := format.Node(&newExpr, fakeFset, cl); err != nil {
return nil, fmt.Errorf("failed to format %s: %v", cl.Type, err)
// First pass through the formatter: turn the expr into a string.
var formatBuf bytes.Buffer
if err := format.Node(&formatBuf, fakeFset, cl); err != nil {
return nil, fmt.Errorf("failed to run first format on:\n%s\ngot err: %v", cl.Type, err)
}
split = bytes.Split(newExpr.Bytes(), []byte("\n"))
newText := bytes.NewBuffer(nil)
for i, s := range split {
// Don't add the extra indentation to the first line.
if i != 0 {
newText.Write(whitespace)
}
newText.Write(s)
if i < len(split)-1 {
newText.WriteByte('\n')
sug := indent(formatBuf.Bytes(), whitespace)

if len(prefilledTypes) > 0 {
// Attempt a second pass through the formatter to line up columns.
sourced, err := format.Source(sug)
if err == nil {
sug = indent(sourced, whitespace)
}
}

return &analysis.SuggestedFix{
TextEdits: []analysis.TextEdit{
{
Pos: expr.Pos(),
End: expr.End(),
NewText: newText.Bytes(),
NewText: sug,
},
},
}, nil
}

// indent works line by line through str, indenting (prefixing) each line with
// ind.
func indent(str, ind []byte) []byte {
split := bytes.Split(str, []byte("\n"))
newText := bytes.NewBuffer(nil)
for i, s := range split {
if len(s) == 0 {
continue
}
// Don't add the extra indentation to the first line.
if i != 0 {
newText.Write(ind)
}
newText.Write(s)
if i < len(split)-1 {
newText.WriteByte('\n')
}
}
return newText.Bytes()
}

// populateValue constructs an expression to fill the value of a struct field.
//
// When the type of a struct field is a basic literal or interface, we return
Expand Down
4 changes: 4 additions & 0 deletions cmd/govim/internal/golang_org_x_tools/lsp/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ type fileHandle struct {
err error
}

func (h *fileHandle) Saved() bool {
return true
}

func (c *Cache) GetFile(ctx context.Context, uri span.URI) (source.FileHandle, error) {
return c.getFile(ctx, uri)
}
Expand Down
21 changes: 20 additions & 1 deletion cmd/govim/internal/golang_org_x_tools/lsp/cache/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"go/ast"
"go/types"
"path"
"path/filepath"
"sort"
"strings"
"sync"
Expand Down Expand Up @@ -407,7 +408,7 @@ func typeCheck(ctx context.Context, snapshot *snapshot, m *metadata, mode source
}
dep := resolveImportPath(pkgPath, pkg, deps)
if dep == nil {
return nil, errors.Errorf("no package for import %s", pkgPath)
return nil, snapshot.missingPkgError(pkgPath)
}
if !isValidImport(m.pkgPath, dep.m.pkgPath) {
return nil, errors.Errorf("invalid use of internal package %s", pkgPath)
Expand Down Expand Up @@ -453,6 +454,24 @@ func typeCheck(ctx context.Context, snapshot *snapshot, m *metadata, mode source
return pkg, nil
}

// missingPkgError returns an error message for a missing package that varies
// based on the user's workspace mode.
func (s *snapshot) missingPkgError(pkgPath string) error {
if s.workspaceMode()&moduleMode != 0 {
return fmt.Errorf("no required module provides package %q", pkgPath)
}
gorootSrcPkg := filepath.FromSlash(filepath.Join(s.view.goroot, "src", pkgPath))

var b strings.Builder
b.WriteString(fmt.Sprintf("cannot find package %q in any of \n\t%s (from $GOROOT)", pkgPath, gorootSrcPkg))

for _, gopath := range strings.Split(s.view.gopath, ":") {
gopathSrcPkg := filepath.FromSlash(filepath.Join(gopath, "src", pkgPath))
b.WriteString(fmt.Sprintf("\n\t%s (from $GOPATH)", gopathSrcPkg))
}
return errors.New(b.String())
}

type extendedError struct {
primary types.Error
secondaries []types.Error
Expand Down
4 changes: 2 additions & 2 deletions cmd/govim/internal/golang_org_x_tools/lsp/cache/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func sourceError(ctx context.Context, snapshot *snapshot, pkg *pkg, e interface{
msg = e.Message
kind = source.Analysis
category = e.Category
fixes, err = suggestedFixes(snapshot, pkg, e)
fixes, err = suggestedAnalysisFixes(snapshot, pkg, e)
if err != nil {
return nil, err
}
Expand All @@ -154,7 +154,7 @@ func sourceError(ctx context.Context, snapshot *snapshot, pkg *pkg, e interface{
}, nil
}

func suggestedFixes(snapshot *snapshot, pkg *pkg, diag *analysis.Diagnostic) ([]source.SuggestedFix, error) {
func suggestedAnalysisFixes(snapshot *snapshot, pkg *pkg, diag *analysis.Diagnostic) ([]source.SuggestedFix, error) {
var fixes []source.SuggestedFix
for _, fix := range diag.SuggestedFixes {
edits := make(map[span.URI][]protocol.TextEdit)
Expand Down
Loading