diff --git a/internal/lsp/fake/editor.go b/internal/lsp/fake/editor.go index 14ab7ef3eb..79be3a8712 100644 --- a/internal/lsp/fake/editor.go +++ b/internal/lsp/fake/editor.go @@ -288,7 +288,10 @@ func (e *Editor) SaveBuffer(ctx context.Context, path string) error { if err := e.FormatBuffer(ctx, path); err != nil { return fmt.Errorf("formatting before save: %w", err) } + return e.SaveBufferWithoutActions(ctx, path) +} +func (e *Editor) SaveBufferWithoutActions(ctx context.Context, path string) error { e.mu.Lock() buf, ok := e.buffers[path] if !ok { diff --git a/internal/lsp/regtest/diagnostics_114_test.go b/internal/lsp/regtest/diagnostics_114_test.go index 39f5667d53..5a8540951b 100644 --- a/internal/lsp/regtest/diagnostics_114_test.go +++ b/internal/lsp/regtest/diagnostics_114_test.go @@ -2,13 +2,14 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build 1.14 +//+build go1.14 package regtest import ( "testing" + "golang.org/x/tools/internal/lsp" "golang.org/x/tools/internal/lsp/fake" "golang.org/x/tools/internal/lsp/protocol" ) @@ -122,3 +123,40 @@ func main() { ) }, WithProxy(ardanLabsProxy)) } + +func TestNewFileBadImports_Issue36960(t *testing.T) { + const simplePackage = ` +-- go.mod -- +module mod.com + +go 1.14 +-- a/a1.go -- +package a + +import "fmt" + +func _() { + fmt.Println("hi") +} +` + runner.Run(t, simplePackage, func(t *testing.T, env *Env) { + env.OpenFile("a/a1.go") + env.CreateBuffer("a/a2.go", ``) + if err := env.Editor.SaveBufferWithoutActions(env.Ctx, "a/a2.go"); err != nil { + t.Fatal(err) + } + env.Await( + OnceMet( + CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidSave), 1), + NoDiagnostics("a/a1.go"), + ), + ) + env.EditBuffer("a/a2.go", fake.NewEdit(0, 0, 0, 0, `package a`)) + env.Await( + OnceMet( + CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChange), 1), + NoDiagnostics("a/a1.go"), + ), + ) + }) +} diff --git a/internal/lsp/regtest/diagnostics_test.go b/internal/lsp/regtest/diagnostics_test.go index 6a5f016e51..6c77725bdf 100644 --- a/internal/lsp/regtest/diagnostics_test.go +++ b/internal/lsp/regtest/diagnostics_test.go @@ -293,8 +293,10 @@ func main() {} // package renaming was fully processed. Therefore, in order for this // test to actually exercise the bug, we must wait until that work has // completed. - NoDiagnostics("a.go"), - CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChange), 1), + OnceMet( + CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChange), 1), + NoDiagnostics("a.go"), + ), ) }) } @@ -473,7 +475,13 @@ func f() { ` runner.Run(t, noModule, func(t *testing.T, env *Env) { env.OpenFile("a.go") - env.Await(NoDiagnostics("a.go"), EmptyShowMessage("")) + env.Await( + OnceMet( + CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidOpen), 1), + NoDiagnostics("a.go"), + ), + EmptyShowMessage(""), + ) // introduce an error, expect no Show Message env.RegexpReplace("a.go", "func", "fun") env.Await(env.DiagnosticAtRegexp("a.go", "fun"), EmptyShowMessage("")) @@ -514,7 +522,10 @@ func main() { } badFile := fmt.Sprintf("%s/found packages main (main.go) and x (x.go) in %s/src/x", dir, env.Sandbox.GOPATH()) env.Await( - EmptyDiagnostics("x/main.go"), + OnceMet( + CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChange), 1), + EmptyDiagnostics("x/main.go"), + ), NoDiagnostics(badFile), ) }, InGOPATH()) diff --git a/internal/lsp/regtest/env.go b/internal/lsp/regtest/env.go index 08fc842100..b81a1aa729 100644 --- a/internal/lsp/regtest/env.go +++ b/internal/lsp/regtest/env.go @@ -479,7 +479,9 @@ func EmptyDiagnostics(name string) Expectation { } // NoDiagnostics asserts that no diagnostics are sent for the -// workspace-relative path name. +// workspace-relative path name. It should be used primarily in conjunction +// with a OnceMet, as it has to check that all outstanding diagnostics have +// already been delivered. func NoDiagnostics(name string) Expectation { check := func(s State) (Verdict, interface{}) { if _, ok := s.diagnostics[name]; !ok { @@ -489,7 +491,7 @@ func NoDiagnostics(name string) Expectation { } return SimpleExpectation{ check: check, - description: "empty diagnostics", + description: "no diagnostics", } }