Skip to content

Commit be27dec

Browse files
committed
[gopls-release-branch.0.5] all: merge master into gopls-release-branch.0.5
a9763ab internal/lsp: refactor code action go command calls 5bad459 internal/lsp: fix godef for embedded type aliases 45586dd internal/lsp: nest the workspace root if there is only one module 780cb80 internal/lsp: fix go.mod parse error parsing to show diagnostics 20be4ac internal/lsp: remove workspace packages as needed 6d15148 internal/lsp/cache: only invalidate metadata for go.mod files on save a738094 internal/lsp: pass a parsed module to go mod tidy c0d5e89 internal/lsp/fake: hold the mutex for all of SaveBufferWithoutActions be796f8 gopls/internal/regtest: handle flake in TestCRLF 0557df3 internal/lsp/source: set experimentalPackageCacheKey to true by default 4783bc9 Handle BareInits option in ssa.BuilderMode 25dc3e1 internal/lsp: handle deletion of a directory on disk 4d9c4f8 internal/lsp/mod: speed up and simplify go.mod code lenses 1727ee1 internal/lsp/cache: fix a staticcheck warning by handling error 6ed8ff9 internal/lsp: support unimported completions in multi-module mode 598b068 internal/lsp: fix end positions for multi-line comments with CRLF lines bd56c0a internal/lsp: use a marker test for struct field ranking test 74a3905 internal/lsp: order struct fields completions by definition f544f6c gopls/internal/regtest: eliminate log duplication 9036a0f Revert "internal/lsp: explicitly watch all known directories" 3c3a812 internal/lsp: explicitly watch all known directories 74f2986 internal/lsp: show critical error pop-ups as progress reports 1d69943 go/packages: handle variation an an error message 6f6c72a internal/lsp: fix capability registration for semantic tokens d68bbb5 internal/gocommand: improve debug string 247bdb2 go/packages: start with empty environment 1a2739c internal/lsp: get debug pages limping along again ac45abd gopls/internal/regtest: update TestEditFile to use a modified buffer 9712d02 internal/lsp: add ?utm_source=gopls to links to pkg.go.dev 61ea331 internal/lsp/source: handle nil pointer exception in completion 1643af1 internal/regtest: refactor diagnostic expectation implementation 559c4ac internal/lsp: make log message for debug server clickable eeaa07d internal/lsp: remove gopls-<name> configuration b389559 internal/lsp/cache: fix InDir error comment 41a3a58 internal/lsp: fix recursive go generate pattern 5794f8b internal/lsp: trim progress report messages 69daaf9 internal/lsp: do not treat failed go test commands as errors 7099162 internal/lsp: remove dead code 092357f internal/lsp/cache: disable GOPACKAGESDRIVER f6c1dd6 internal/lsp/cache: suppress Load log spam 53e0aa8 gopls/internal/regtest: add an option to nest the workdir 079ba7b internal/typesinternal: add a copy of the Go 1.16 go/types error codes 169ad6d internal/lsp: avoid diagnosing unopened non-workspace packages Change-Id: If0097a1f85b583a1dc7400924df43920b9cf42f9
2 parents ae6603b + a9763ab commit be27dec

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+2919
-911
lines changed

go/internal/packagesdriver/sizes.go

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -6,80 +6,16 @@
66
package packagesdriver
77

88
import (
9-
"bytes"
109
"context"
11-
"encoding/json"
1210
"fmt"
1311
"go/types"
14-
"os/exec"
1512
"strings"
1613

1714
"golang.org/x/tools/internal/gocommand"
1815
)
1916

2017
var debug = false
2118

22-
func GetSizes(ctx context.Context, buildFlags, env []string, gocmdRunner *gocommand.Runner, dir string) (types.Sizes, error) {
23-
// TODO(matloob): Clean this up. This code is mostly a copy of packages.findExternalDriver.
24-
const toolPrefix = "GOPACKAGESDRIVER="
25-
tool := ""
26-
for _, env := range env {
27-
if val := strings.TrimPrefix(env, toolPrefix); val != env {
28-
tool = val
29-
}
30-
}
31-
32-
if tool == "" {
33-
var err error
34-
tool, err = exec.LookPath("gopackagesdriver")
35-
if err != nil {
36-
// We did not find the driver, so use "go list".
37-
tool = "off"
38-
}
39-
}
40-
41-
if tool == "off" {
42-
inv := gocommand.Invocation{
43-
BuildFlags: buildFlags,
44-
Env: env,
45-
WorkingDir: dir,
46-
}
47-
return GetSizesGolist(ctx, inv, gocmdRunner)
48-
}
49-
50-
req, err := json.Marshal(struct {
51-
Command string `json:"command"`
52-
Env []string `json:"env"`
53-
BuildFlags []string `json:"build_flags"`
54-
}{
55-
Command: "sizes",
56-
Env: env,
57-
BuildFlags: buildFlags,
58-
})
59-
if err != nil {
60-
return nil, fmt.Errorf("failed to encode message to driver tool: %v", err)
61-
}
62-
63-
buf := new(bytes.Buffer)
64-
cmd := exec.CommandContext(ctx, tool)
65-
cmd.Dir = dir
66-
cmd.Env = env
67-
cmd.Stdin = bytes.NewReader(req)
68-
cmd.Stdout = buf
69-
cmd.Stderr = new(bytes.Buffer)
70-
if err := cmd.Run(); err != nil {
71-
return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr)
72-
}
73-
var response struct {
74-
// Sizes, if not nil, is the types.Sizes to use when type checking.
75-
Sizes *types.StdSizes
76-
}
77-
if err := json.Unmarshal(buf.Bytes(), &response); err != nil {
78-
return nil, err
79-
}
80-
return response.Sizes, nil
81-
}
82-
8319
func GetSizesGolist(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (types.Sizes, error) {
8420
inv.Verb = "list"
8521
inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"}

go/packages/external.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func findExternalDriver(cfg *Config) driver {
8989
return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr)
9090
}
9191
if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTDRIVERERRORS") != "" {
92-
fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd, words...), stderr)
92+
fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd), stderr)
9393
}
9494

9595
var response driverResponse

go/packages/golist.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,7 @@ func (state *golistState) cfgInvocation() gocommand.Invocation {
827827
BuildFlags: cfg.BuildFlags,
828828
ModFile: cfg.modFile,
829829
ModFlag: cfg.modFlag,
830+
CleanEnv: cfg.Env != nil,
830831
Env: cfg.Env,
831832
Logf: cfg.Logf,
832833
WorkingDir: cfg.Dir,
@@ -901,8 +902,13 @@ func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer,
901902
return unicode.IsOneOf([]*unicode.RangeTable{unicode.L, unicode.M, unicode.N, unicode.P, unicode.S}, r) &&
902903
!strings.ContainsRune("!\"#$%&'()*,:;<=>?[\\]^`{|}\uFFFD", r)
903904
}
905+
// golang/go#36770: Handle case where cmd/go prints module download messages before the error.
906+
msg := stderr.String()
907+
for strings.HasPrefix(msg, "go: downloading") {
908+
msg = msg[strings.IndexRune(msg, '\n')+1:]
909+
}
904910
if len(stderr.String()) > 0 && strings.HasPrefix(stderr.String(), "# ") {
905-
msg := stderr.String()[len("# "):]
911+
msg := msg[len("# "):]
906912
if strings.HasPrefix(strings.TrimLeftFunc(msg, isPkgPathRune), "\n") {
907913
return stdout, nil
908914
}
@@ -1069,17 +1075,22 @@ func containsGoFile(s []string) bool {
10691075
return false
10701076
}
10711077

1072-
func cmdDebugStr(cmd *exec.Cmd, args ...string) string {
1078+
func cmdDebugStr(cmd *exec.Cmd) string {
10731079
env := make(map[string]string)
10741080
for _, kv := range cmd.Env {
1075-
split := strings.Split(kv, "=")
1081+
split := strings.SplitN(kv, "=", 2)
10761082
k, v := split[0], split[1]
10771083
env[k] = v
10781084
}
1079-
var quotedArgs []string
1080-
for _, arg := range args {
1081-
quotedArgs = append(quotedArgs, strconv.Quote(arg))
1082-
}
10831085

1084-
return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v PWD=%v go %s", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["PWD"], strings.Join(quotedArgs, " "))
1086+
var args []string
1087+
for _, arg := range cmd.Args {
1088+
quoted := strconv.Quote(arg)
1089+
if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") {
1090+
args = append(args, quoted)
1091+
} else {
1092+
args = append(args, arg)
1093+
}
1094+
}
1095+
return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " "))
10851096
}

go/packages/packages_test.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ func TestLoadZeroConfig(t *testing.T) {
8686
hash := initial[0]
8787
// Even though the hash package has imports,
8888
// they are not reported.
89-
got := fmt.Sprintf("iamashamedtousethedisabledqueryname=%s srcs=%v imports=%v", hash.Name, srcs(hash), hash.Imports)
90-
want := "iamashamedtousethedisabledqueryname=hash srcs=[hash.go] imports=map[]"
89+
got := fmt.Sprintf("srcs=%v imports=%v", srcs(hash), hash.Imports)
90+
want := "srcs=[hash.go] imports=map[]"
9191
if got != want {
9292
t.Fatalf("got %s, want %s", got, want)
9393
}
@@ -2628,6 +2628,16 @@ func main() {
26282628
}
26292629
}
26302630

2631+
func TestEmptyEnvironment(t *testing.T) {
2632+
cfg := &packages.Config{
2633+
Env: []string{"FOO=BAR"},
2634+
}
2635+
_, err := packages.Load(cfg, "fmt")
2636+
if err == nil {
2637+
t.Fatal("Load with explicitly empty environment should fail")
2638+
}
2639+
}
2640+
26312641
func errorMessages(errors []packages.Error) []string {
26322642
var msgs []string
26332643
for _, err := range errors {

go/ssa/mode.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ func (m BuilderMode) String() string {
6666
if m&BuildSerially != 0 {
6767
buf.WriteByte('L')
6868
}
69+
if m&BareInits != 0 {
70+
buf.WriteByte('I')
71+
}
6972
return buf.String()
7073
}
7174

@@ -88,6 +91,8 @@ func (m *BuilderMode) Set(s string) error {
8891
mode |= NaiveForm
8992
case 'L':
9093
mode |= BuildSerially
94+
case 'I':
95+
mode |= BareInits
9196
default:
9297
return fmt.Errorf("unknown BuilderMode option: %q", c)
9398
}

gopls/doc/settings.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,12 @@ semantic tokens to the client.
249249

250250
Default: `false`.
251251
### **expandWorkspaceToModule** *bool*
252-
expandWorkspaceToModule instructs `gopls` to expand the scope of the workspace to include the
253-
modules containing the workspace folders. Set this to false to avoid loading
254-
your entire module. This is particularly useful for those working in a monorepo.
252+
expandWorkspaceToModule instructs `gopls` to adjust the scope of the
253+
workspace to find the best available module root. `gopls` first looks for
254+
a go.mod file in any parent directory of the workspace folder, expanding
255+
the scope to that directory if it exists. If no viable parent directory is
256+
found, gopls will check if there is exactly one child directory containing
257+
a go.mod file, narrowing the scope to that directory if it exists.
255258

256259

257260
Default: `true`.
@@ -281,7 +284,7 @@ by an experiment because caching behavior is subtle and difficult to
281284
comprehensively test.
282285

283286

284-
Default: `false`.
287+
Default: `true`.
285288
<!-- END Experimental: DO NOT MANUALLY EDIT THIS SECTION -->
286289

287290
## Debugging

gopls/internal/regtest/diagnostics_test.go

Lines changed: 80 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -852,28 +852,29 @@ func TestHello(t *testing.T) {
852852

853853
// Reproduce golang/go#40690.
854854
func TestCreateOnlyXTest(t *testing.T) {
855-
t.Skip("golang/go#40690 is not resolved yet.")
856-
857855
const mod = `
858-
-- go.mod --
859-
module mod.com
860-
-- foo/foo.go --
861-
package foo
862-
-- foo/bar_test.go --
863-
`
856+
-- go.mod --
857+
module mod.com
858+
-- foo/foo.go --
859+
package foo
860+
-- foo/bar_test.go --
861+
`
864862
run(t, mod, func(t *testing.T, env *Env) {
865863
env.OpenFile("foo/bar_test.go")
866-
env.EditBuffer("foo/bar_test.go", fake.NewEdit(0, 0, 0, 0, `package foo
867-
`))
864+
env.EditBuffer("foo/bar_test.go", fake.NewEdit(0, 0, 0, 0, "package foo"))
868865
env.Await(
869866
CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChange), 1),
870867
)
871-
env.RegexpReplace("foo/bar_test.go", "package foo", "package foo_test")
868+
env.RegexpReplace("foo/bar_test.go", "package foo", `package foo_test
869+
870+
import "testing"
871+
872+
func TestX(t *testing.T) {
873+
var x int
874+
}
875+
`)
872876
env.Await(
873-
OnceMet(
874-
CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChange), 2),
875-
NoErrorLogs(),
876-
),
877+
env.DiagnosticAtRegexp("foo/bar_test.go", "x"),
877878
)
878879
})
879880
}
@@ -1246,7 +1247,7 @@ func main() {
12461247
env.DiagnosticAtRegexp("main.go", "x"),
12471248
)
12481249
})
1249-
withOptions(WithRootPath("a"), WithLimitWorkspaceScope()).run(t, mod, func(t *testing.T, env *Env) {
1250+
withOptions(WithRootPath("a"), LimitWorkspaceScope()).run(t, mod, func(t *testing.T, env *Env) {
12501251
env.OpenFile("a/main.go")
12511252
env.Await(
12521253
NoDiagnostics("main.go"),
@@ -1422,7 +1423,7 @@ func main() {
14221423
env.Await(
14231424
OnceMet(
14241425
InitialWorkspaceLoad,
1425-
NoDiagnosticWithMessage("illegal character U+0023 '#'"),
1426+
NoDiagnosticWithMessage("", "illegal character U+0023 '#'"),
14261427
),
14271428
)
14281429
})
@@ -1452,3 +1453,65 @@ package foo_`
14521453
)
14531454
})
14541455
}
1456+
1457+
// TestProgressBarErrors confirms that critical workspace load errors are shown
1458+
// and updated via progress reports.
1459+
func TestProgressBarErrors(t *testing.T) {
1460+
testenv.NeedsGo1Point(t, 14)
1461+
1462+
const pkg = `
1463+
-- go.mod --
1464+
modul mod.com
1465+
1466+
go 1.12
1467+
-- main.go --
1468+
package main
1469+
`
1470+
run(t, pkg, func(t *testing.T, env *Env) {
1471+
env.OpenFile("go.mod")
1472+
env.Await(
1473+
OutstandingWork("Error loading workspace", "unknown directive"),
1474+
)
1475+
env.EditBuffer("go.mod", fake.NewEdit(0, 0, 3, 0, `module mod.com
1476+
1477+
go 1.hello
1478+
`))
1479+
env.Await(
1480+
OutstandingWork("Error loading workspace", "invalid go version"),
1481+
)
1482+
env.RegexpReplace("go.mod", "go 1.hello", "go 1.12")
1483+
env.Await(
1484+
NoOutstandingWork(),
1485+
)
1486+
})
1487+
}
1488+
1489+
func TestDeleteDirectory(t *testing.T) {
1490+
testenv.NeedsGo1Point(t, 14)
1491+
1492+
const mod = `
1493+
-- bob/bob.go --
1494+
package bob
1495+
1496+
func Hello() {
1497+
var x int
1498+
}
1499+
-- go.mod --
1500+
module mod.com
1501+
-- main.go --
1502+
package main
1503+
1504+
import "mod.com/bob"
1505+
1506+
func main() {
1507+
bob.Hello()
1508+
}
1509+
`
1510+
run(t, mod, func(t *testing.T, env *Env) {
1511+
env.RemoveWorkspaceFile("bob")
1512+
env.Await(
1513+
env.DiagnosticAtRegexp("main.go", `"mod.com/bob"`),
1514+
EmptyDiagnostics("bob/bob.go"),
1515+
)
1516+
})
1517+
}

gopls/internal/regtest/env.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ type State struct {
5858
}
5959

6060
type workProgress struct {
61-
title string
62-
percent float64
61+
title, msg string
62+
percent float64
6363
}
6464

6565
func (s State) String() string {
@@ -200,10 +200,16 @@ func (e *Env) onProgress(_ context.Context, m *protocol.ProgressParams) error {
200200
switch kind := v["kind"]; kind {
201201
case "begin":
202202
work.title = v["title"].(string)
203+
if msg, ok := v["message"]; ok {
204+
work.msg = msg.(string)
205+
}
203206
case "report":
204207
if pct, ok := v["percentage"]; ok {
205208
work.percent = pct.(float64)
206209
}
210+
if msg, ok := v["message"]; ok {
211+
work.msg = msg.(string)
212+
}
207213
case "end":
208214
title := e.state.outstandingWork[m.Token].title
209215
e.state.completedWork[title] = e.state.completedWork[title] + 1

0 commit comments

Comments
 (0)