diff --git a/go/private/repositories.bzl b/go/private/repositories.bzl index 8ee2fb9b82..c00824dab9 100644 --- a/go/private/repositories.bzl +++ b/go/private/repositories.bzl @@ -64,13 +64,13 @@ def go_rules_dependencies(force = False): wrapper( http_archive, name = "org_golang_x_tools", - # v0.14.0, latest as of 2023-10-29 + # v0.15.0, latest as of 2023-11-12 urls = [ - "https://mirror.bazel.build/github.com/golang/tools/archive/refs/tags/v0.14.0.zip", - "https://github.com/golang/tools/archive/refs/tags/v0.14.0.zip", + "https://mirror.bazel.build/github.com/golang/tools/archive/refs/tags/v0.15.0.zip", + "https://github.com/golang/tools/archive/refs/tags/v0.15.0.zip", ], - sha256 = "9c71911c61a791d8b13368ffbc409a0b38859cac80a4b5039487d2a27399e8b9", - strip_prefix = "tools-0.14.0", + sha256 = "e76a03b11719138502c7fef44d5e1dc4469f8c2fcb2ee4a1d96fb09aaea13362", + strip_prefix = "tools-0.15.0", patches = [ # deletegopls removes the gopls subdirectory. It contains a nested # module with additional dependencies. It's not needed by rules_go. diff --git a/go/tools/builders/nogo_main.go b/go/tools/builders/nogo_main.go index 4f65f117f8..17ff5314c7 100644 --- a/go/tools/builders/nogo_main.go +++ b/go/tools/builders/nogo_main.go @@ -234,7 +234,7 @@ func checkPackage(analyzers []*analysis.Analyzer, packagePath string, packageFil // Process diagnostics and encode facts for importers of this package. diagnostics := checkAnalysisResults(roots, pkg) - facts := pkg.facts.Encode(true/* skipMethodSorting */) + facts := pkg.facts.Encode() return diagnostics, facts, nil } @@ -396,7 +396,7 @@ func load(packagePath string, imp *importer, filenames []string) (*goPackage, er } pkg.types, pkg.typesInfo = types, info - pkg.facts, err = facts.NewDecoder(pkg.types).Decode(true/* skipMethodSorting */, imp.readFacts) + pkg.facts, err = facts.NewDecoder(pkg.types).Decode(imp.readFacts) if err != nil { return nil, fmt.Errorf("internal error decoding facts: %v", err) } diff --git a/tests/integration/popular_repos/BUILD.bazel b/tests/integration/popular_repos/BUILD.bazel index 79c1d68b88..93f4f94747 100644 --- a/tests/integration/popular_repos/BUILD.bazel +++ b/tests/integration/popular_repos/BUILD.bazel @@ -186,7 +186,6 @@ test_suite( "@org_golang_x_tools//internal/event/export/ocagent:ocagent_test", "@org_golang_x_tools//internal/event/export/ocagent/wire:wire_test", "@org_golang_x_tools//internal/event/label:label_test", - "@org_golang_x_tools//internal/fastwalk:fastwalk_test", "@org_golang_x_tools//internal/fuzzy:fuzzy_test", "@org_golang_x_tools//internal/gopathwalk:gopathwalk_test", "@org_golang_x_tools//internal/jsonrpc2:jsonrpc2_test", diff --git a/tests/integration/popular_repos/README.rst b/tests/integration/popular_repos/README.rst index 446f1215cb..4a0130a8be 100644 --- a/tests/integration/popular_repos/README.rst +++ b/tests/integration/popular_repos/README.rst @@ -184,7 +184,6 @@ This runs tests from the repository `golang.org/x/tools * @org_golang_x_mod//sumdb/dirhash:dirhash_test * @org_golang_x_mod//sumdb/note:note_test * @org_golang_x_mod//sumdb/storage:storage_test - - diff --git a/third_party/org_golang_x_tools-deletegopls.patch b/third_party/org_golang_x_tools-deletegopls.patch index e15c915fe1..2d740d7116 100644 --- a/third_party/org_golang_x_tools-deletegopls.patch +++ b/third_party/org_golang_x_tools-deletegopls.patch @@ -1,142 +1,6 @@ -diff -urN a/gopls/README.md b/gopls/README.md ---- a/gopls/README.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/README.md 1970-01-01 08:00:00 -@@ -1,132 +0,0 @@ --# `gopls`, the Go language server -- --[![PkgGoDev](https://pkg.go.dev/badge/golang.org/x/tools/gopls)](https://pkg.go.dev/golang.org/x/tools/gopls) -- --`gopls` (pronounced "Go please") is the official Go [language server] developed --by the Go team. It provides IDE features to any [LSP]-compatible editor. -- -- -- --You should not need to interact with `gopls` directly--it will be automatically --integrated into your editor. The specific features and settings vary slightly --by editor, so we recommend that you proceed to the --[documentation for your editor](#editors) below. -- --## Editors -- --To get started with `gopls`, install an LSP plugin in your editor of choice. -- --* [VS Code](https://github.com/golang/vscode-go/blob/master/README.md) --* [Vim / Neovim](doc/vim.md) --* [Emacs](doc/emacs.md) --* [Atom](https://github.com/MordFustang21/ide-gopls) --* [Sublime Text](doc/subl.md) --* [Acme](https://github.com/fhs/acme-lsp) --* [Lapce](https://github.com/lapce-community/lapce-go) -- --If you use `gopls` with an editor that is not on this list, please send us a CL --[updating this documentation](doc/contributing.md). -- --## Installation -- --For the most part, you should not need to install or update `gopls`. Your --editor should handle that step for you. -- --If you do want to get the latest stable version of `gopls`, run the following --command: -- --```sh --go install golang.org/x/tools/gopls@latest --``` -- --Learn more in the --[advanced installation instructions](doc/advanced.md#installing-unreleased-versions). -- --Learn more about gopls releases in the [release policy](doc/releases.md). -- --## Setting up your workspace -- --`gopls` supports both Go module, multi-module and GOPATH modes. See the --[workspace documentation](doc/workspace.md) for information on supported --workspace layouts. -- --## Configuration -- --You can configure `gopls` to change your editor experience or view additional --debugging information. Configuration options will be made available by your --editor, so see your [editor's instructions](#editors) for specific details. A --full list of `gopls` settings can be found in the [settings documentation](doc/settings.md). -- --### Environment variables -- --`gopls` inherits your editor's environment, so be aware of any environment --variables you configure. Some editors, such as VS Code, allow users to --selectively override the values of some environment variables. -- --## Support Policy -- --Gopls is maintained by engineers on the --[Go tools team](https://github.com/orgs/golang/teams/tools-team/members), --who actively monitor the --[Go](https://github.com/golang/go/issues?q=is%3Aissue+is%3Aopen+label%3Agopls) --and --[VS Code Go](https://github.com/golang/vscode-go/issues) issue trackers. -- --### Supported Go versions -- --`gopls` follows the --[Go Release Policy](https://golang.org/doc/devel/release.html#policy), --meaning that it officially supports the last 2 major Go releases. Per --[issue #39146](https://go.dev/issues/39146), we attempt to maintain best-effort --support for the last 4 major Go releases, but this support extends only to not --breaking the build and avoiding easily fixable regressions. -- --In the context of this discussion, gopls "supports" a Go version if it supports --being built with that Go version as well as integrating with the `go` command --of that Go version. -- --The following table shows the final gopls version that supports a given Go --version. Go releases more recent than any in the table can be used with any --version of gopls. -- --| Go Version | Final gopls version with support (without warnings) | --| ----------- | --------------------------------------------------- | --| Go 1.12 | [gopls@v0.7.5](https://github.com/golang/tools/releases/tag/gopls%2Fv0.7.5) | --| Go 1.15 | [gopls@v0.9.5](https://github.com/golang/tools/releases/tag/gopls%2Fv0.9.5) | --| Go 1.17 | [gopls@v0.11.0](https://github.com/golang/tools/releases/tag/gopls%2Fv0.11.0) | -- --Our extended support is enforced via [continuous integration with older Go --versions](doc/contributing.md#ci). This legacy Go CI may not block releases: --test failures may be skipped rather than fixed. Furthermore, if a regression in --an older Go version causes irreconcilable CI failures, we may drop support for --that Go version in CI if it is 3 or 4 Go versions old. -- --### Supported build systems -- --`gopls` currently only supports the `go` command, so if you are using --a different build system, `gopls` will not work well. Bazel is not officially --supported, but may be made to work with an appropriately configured --`go/packages` driver. See --[bazelbuild/rules_go#512](https://github.com/bazelbuild/rules_go/issues/512) --for more information. --You can follow [these instructions](https://github.com/bazelbuild/rules_go/wiki/Editor-setup) --to configure your `gopls` to work with Bazel. -- --### Troubleshooting -- --If you are having issues with `gopls`, please follow the steps described in the --[troubleshooting guide](doc/troubleshooting.md). -- --## Additional information -- --* [Features](doc/features.md) --* [Command-line interface](doc/command-line.md) --* [Advanced topics](doc/advanced.md) --* [Contributing to `gopls`](doc/contributing.md) --* [Integrating `gopls` with an editor](doc/design/integrating.md) --* [Design requirements and decisions](doc/design/design.md) --* [Implementation details](doc/design/implementation.md) --* [Open issues](https://github.com/golang/go/issues?q=is%3Aissue+is%3Aopen+label%3Agopls) -- --[language server]: https://langserver.org --[LSP]: https://microsoft.github.io/language-server-protocol/ diff -urN a/gopls/api-diff/api_diff.go b/gopls/api-diff/api_diff.go --- a/gopls/api-diff/api_diff.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/api-diff/api_diff.go 1970-01-01 08:00:00 ++++ b/gopls/api-diff/api_diff.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -229,7 +93,7 @@ diff -urN a/gopls/api-diff/api_diff.go b/gopls/api-diff/api_diff.go -} diff -urN a/gopls/doc/advanced.md b/gopls/doc/advanced.md --- a/gopls/doc/advanced.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/advanced.md 1970-01-01 08:00:00 ++++ b/gopls/doc/advanced.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -# Advanced topics - @@ -313,7 +177,7 @@ diff -urN a/gopls/doc/advanced.md b/gopls/doc/advanced.md -[Go project]: https://go.googlesource.com/go diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md --- a/gopls/doc/analyzers.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/analyzers.md 1970-01-01 08:00:00 ++++ b/gopls/doc/analyzers.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,837 +0,0 @@ -# Analyzers - @@ -703,7 +567,7 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md - panic(p) - } - --**Disabled by default. Enable it by setting `"analyses": {"nilness": true}`.** +-**Enabled by default.** - -## **printf** - @@ -1154,7 +1018,7 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md - diff -urN a/gopls/doc/command-line.md b/gopls/doc/command-line.md --- a/gopls/doc/command-line.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/command-line.md 1970-01-01 08:00:00 ++++ b/gopls/doc/command-line.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -# Command line - @@ -1173,8 +1037,8 @@ diff -urN a/gopls/doc/command-line.md b/gopls/doc/command-line.md -It is not a goal of `gopls` to be a high performance command line tool. Its command line is intended for single file/package user interaction speeds, not bulk processing. diff -urN a/gopls/doc/commands.md b/gopls/doc/commands.md --- a/gopls/doc/commands.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/commands.md 1970-01-01 08:00:00 -@@ -1,586 +0,0 @@ ++++ b/gopls/doc/commands.md 1970-01-01 00:00:00.000000000 +0000 +@@ -1,606 +0,0 @@ -# Commands - -This document describes the LSP-level commands supported by `gopls`. They cannot be invoked directly by users, and all the details are subject to change, so nobody should rely on this information. @@ -1261,6 +1125,26 @@ diff -urN a/gopls/doc/commands.md b/gopls/doc/commands.md -} -``` - +-### **performs a "change signature" refactoring.** +-Identifier: `gopls.change_signature` +- +-This command is experimental, currently only supporting parameter removal. +-Its signature will certainly change in the future (pun intended). +- +-Args: +- +-``` +-{ +- "RemoveParameter": { +- "uri": string, +- "range": { +- "start": { ... }, +- "end": { ... }, +- }, +- }, +-} +-``` +- -### **Check for upgrades** -Identifier: `gopls.check_upgrades` - @@ -1763,7 +1647,7 @@ diff -urN a/gopls/doc/commands.md b/gopls/doc/commands.md - diff -urN a/gopls/doc/contributing.md b/gopls/doc/contributing.md --- a/gopls/doc/contributing.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/contributing.md 1970-01-01 08:00:00 ++++ b/gopls/doc/contributing.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,165 +0,0 @@ -# Documentation for contributors - @@ -1932,7 +1816,7 @@ diff -urN a/gopls/doc/contributing.md b/gopls/doc/contributing.md -[issue-wanted]: https://github.com/golang/go/issues?utf8=✓&q=is%3Aissue+is%3Aopen+label%3Agopls+label%3A"help+wanted" "help wanted" diff -urN a/gopls/doc/daemon.md b/gopls/doc/daemon.md --- a/gopls/doc/daemon.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/daemon.md 1970-01-01 08:00:00 ++++ b/gopls/doc/daemon.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,183 +0,0 @@ -# Running gopls as a daemon - @@ -2119,7 +2003,7 @@ diff -urN a/gopls/doc/daemon.md b/gopls/doc/daemon.md -that actually starts the daemon. diff -urN a/gopls/doc/design/design.md b/gopls/doc/design/design.md --- a/gopls/doc/design/design.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/design/design.md 1970-01-01 08:00:00 ++++ b/gopls/doc/design/design.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,394 +0,0 @@ -# `gopls` design documentation - @@ -2517,7 +2401,7 @@ diff -urN a/gopls/doc/design/design.md b/gopls/doc/design/design.md -[`workspace/didChangeWatchedFiles`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#workspace_didChangeWatchedFiles diff -urN a/gopls/doc/design/implementation.md b/gopls/doc/design/implementation.md --- a/gopls/doc/design/implementation.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/design/implementation.md 1970-01-01 08:00:00 ++++ b/gopls/doc/design/implementation.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -# gopls implementation documentation - @@ -2569,7 +2453,7 @@ diff -urN a/gopls/doc/design/implementation.md b/gopls/doc/design/implementation -[x/tools]: https://github.com/golang/tools diff -urN a/gopls/doc/design/integrating.md b/gopls/doc/design/integrating.md --- a/gopls/doc/design/integrating.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/design/integrating.md 1970-01-01 08:00:00 ++++ b/gopls/doc/design/integrating.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -# Documentation for plugin authors - @@ -2664,7 +2548,7 @@ diff -urN a/gopls/doc/design/integrating.md b/gopls/doc/design/integrating.md -[#31526]: https://github.com/golang/go/issues/31526 diff -urN a/gopls/doc/emacs.md b/gopls/doc/emacs.md --- a/gopls/doc/emacs.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/emacs.md 1970-01-01 08:00:00 ++++ b/gopls/doc/emacs.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,183 +0,0 @@ -# Emacs - @@ -2851,7 +2735,7 @@ diff -urN a/gopls/doc/emacs.md b/gopls/doc/emacs.md -[Gophers slack]: https://invite.slack.golangbridge.org/ diff -urN a/gopls/doc/features.md b/gopls/doc/features.md --- a/gopls/doc/features.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/features.md 1970-01-01 08:00:00 ++++ b/gopls/doc/features.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -# Features - @@ -2910,7 +2794,7 @@ diff -urN a/gopls/doc/features.md b/gopls/doc/features.md - diff -urN a/gopls/doc/generate.go b/gopls/doc/generate.go --- a/gopls/doc/generate.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/generate.go 1970-01-01 08:00:00 ++++ b/gopls/doc/generate.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,786 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -3700,7 +3584,7 @@ diff -urN a/gopls/doc/generate.go b/gopls/doc/generate.go -} diff -urN a/gopls/doc/generate_test.go b/gopls/doc/generate_test.go --- a/gopls/doc/generate_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/generate_test.go 1970-01-01 08:00:00 ++++ b/gopls/doc/generate_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -3732,7 +3616,7 @@ diff -urN a/gopls/doc/generate_test.go b/gopls/doc/generate_test.go -} diff -urN a/gopls/doc/inlayHints.md b/gopls/doc/inlayHints.md --- a/gopls/doc/inlayHints.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/inlayHints.md 1970-01-01 08:00:00 ++++ b/gopls/doc/inlayHints.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -# Hints - @@ -3814,9 +3698,176 @@ diff -urN a/gopls/doc/inlayHints.md b/gopls/doc/inlayHints.md -**Disabled by default. Enable it by setting `"hints": {"rangeVariableTypes": true}`.** - - +Binary files a/gopls/doc/inline-after.png and b/gopls/doc/inline-after.png differ +Binary files a/gopls/doc/inline-before.png and b/gopls/doc/inline-before.png differ +diff -urN a/gopls/doc/refactor-inline.md b/gopls/doc/refactor-inline.md +--- a/gopls/doc/refactor-inline.md 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/doc/refactor-inline.md 1970-01-01 00:00:00.000000000 +0000 +@@ -1,161 +0,0 @@ +- +-Gopls v0.14 supports a new refactoring operation: +-inlining of function calls. +- +-You can find it in VS Code by selecting a static call to a function or +-method f and choosing the `Refactor...` command followed by `Inline +-call to f`. +-Other editors and LSP clients have their own idiomatic command for it; +-for example, in Emacs with Eglot it is +-[`M-x eglot-code-action-inline`](https://joaotavora.github.io/eglot/#index-M_002dx-eglot_002dcode_002daction_002dinline) +-and in Vim with coc.nvim it is `coc-rename`. +- +- +-![Before: select Refactor... Inline call to sum](inline-before.png) +-![After: the call has been replaced by the sum logic](inline-after.png) +- +-Inlining replaces the call expression by a copy of the function body, +-with parameters replaced by arguments. +-Inlining is useful for a number of reasons. +-Perhaps you want to eliminate a call to a deprecated +-function such as `ioutil.ReadFile` by replacing it with a call to the +-newer `os.ReadFile`; inlining will do that for you. +-Or perhaps you want to copy and modify an existing function in some +-way; inlining can provide a starting point. +-The inlining logic also provides a building block for +-other refactorings to come, such as "change signature". +- +-Not every call can be inlined. +-Of course, the tool needs to know which function is being called, so +-you can't inline a dynamic call through a function value or interface +-method; but static calls to methods are fine. +-Nor can you inline a call if the callee is declared in another package +-and refers to non-exported parts of that package, or to [internal +-packages](https://go.dev/doc/go1.4#internalpackages) that are +-inaccessible to the caller. +- +-When inlining is possible, it's critical that the tool preserve +-the original behavior of the program. +-We don't want refactoring to break the build, or, worse, to introduce +-subtle latent bugs. +-This is especially important when inlining tools are used to perform +-automated clean-ups in large code bases. +-We must be able to trust the tool. +-Our inliner is very careful not to make guesses or unsound +-assumptions about the behavior of the code. +-However, that does mean it sometimes produces a change that differs +-from what someone with expert knowledge of the same code might have +-written by hand. +- +-In the most difficult cases, especially with complex control flow, it +-may not be safe to eliminate the function call at all. +-For example, the behavior of a `defer` statement is intimately tied to +-its enclosing function call, and `defer` is the only control +-construct that can be used to handle panics, so it cannot be reduced +-into simpler constructs. +-So, for example, given a function f defined as: +- +-```go +-func f(s string) { +- defer fmt.Println("goodbye") +- fmt.Println(s) +-} +-``` +-a call `f("hello")` will be inlined to: +-```go +- func() { +- defer fmt.Println("goodbye") +- fmt.Println("hello") +- }() +-``` +-Although the parameter was eliminated, the function call remains. +- +-An inliner is a bit like an optimizing compiler. +-A compiler is considered "correct" if it doesn't change the meaning of +-the program in translation from source language to target language. +-An _optimizing_ compiler exploits the particulars of the input to +-generate better code, where "better" usually means more efficient. +-As users report inputs that cause the compiler to emit suboptimal +-code, the compiler is improved to recognize more cases, or more rules, +-and more exceptions to rules---but this process has no end. +-Inlining is similar, except that "better" code means tidier code. +-The most conservative translation provides a simple but (hopefully!) +-correct foundation, on top of which endless rules, and exceptions to +-rules, can embellish and improve the quality of the output. +- +-The following section lists some of the technical +-challenges involved in sound inlining: +- +-- **Effects:** When replacing a parameter by its argument expression, +- we must be careful not to change the effects of the call. For +- example, if we call a function `func twice(x int) int { return x + x }` +- with `twice(g())`, we do not want to see `g() + g()`, which would +- cause g's effects to occur twice, and potentially each call might +- return a different value. All effects must occur the same number of +- times, and in the same order. This requires analyzing both the +- arguments and the callee function to determine whether they are +- "pure", whether they read variables, or whether (and when) they +- update them too. The inliner will introduce a declaration such as +- `var x int = g()` when it cannot prove that it is safe to substitute +- the argument throughout. +- +-- **Constants:** If inlining always replaced a parameter by its argument +- when the value is constant, some programs would no longer build +- because checks previously done at run time would happen at compile time. +- For example `func index(s string, i int) byte { return s[i] }` +- is a valid function, but if inlining were to replace the call `index("abc", 3)` +- by the expression `"abc"[3]`, the compiler will report that the +- index `3` is out of bounds for the string `"abc"`. +- The inliner will prevent substitution of parameters by problematic +- constant arguments, again introducing a `var` declaration instead. +- +-- **Referential integrity:** When a parameter variable is replaced by +- its argument expression, we must ensure that any names in the +- argument expression continue to refer to the same thing---not to a +- different declaration in the callee function body that happens to +- use the same name! The inliner must replace local references such as +- `Printf` by qualified references such as `fmt.Printf`, and add an +- import of package `fmt` as needed. +- +-- **Implicit conversions:** When passing an argument to a function, it +- is implicitly converted to the parameter type. +- If we eliminate the parameter variable, we don't want to +- lose the conversion as it may be important. +- For example, in `func f(x any) { y := x; fmt.Printf("%T", &y) }` the +- type of variable y is `any`, so the program prints `"*interface{}"`. +- But if inlining the call `f(1)` were to produce the statement `y := +- 1`, then the type of y would have changed to `int`, which could +- cause a compile error or, as in this case, a bug, as the program +- now prints `"*int"`. When the inliner substitutes a parameter variable +- by its argument value, it may need to introduce explicit conversions +- of each value to the original parameter type, such as `y := any(1)`. +- +-- **Last reference:** When an argument expression has no effects +- and its corresponding parameter is never used, the expression +- may be eliminated. However, if the expression contains the last +- reference to a local variable at the caller, this may cause a compile +- error because the variable is now unused! So the inliner must be +- cautious about eliminating references to local variables. +- +-This is just a taste of the problem domain. If you're curious, the +-documentation for [golang.org/x/tools/internal/refactor/inline](https://pkg.go.dev/golang.org/x/tools/internal/refactor/inline) has +-more detail. All of this is to say, it's a complex problem, and we aim +-for correctness first of all. We've already implemented a number of +-important "tidiness optimizations" and we expect more to follow. +- +-Please give the inliner a try, and if you find any bugs (where the +-transformation is incorrect), please do report them. We'd also like to +-hear what "optimizations" you'd like to see next. diff -urN a/gopls/doc/releases.md b/gopls/doc/releases.md --- a/gopls/doc/releases.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/releases.md 1970-01-01 08:00:00 ++++ b/gopls/doc/releases.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -# Gopls release policy - @@ -3845,7 +3896,7 @@ diff -urN a/gopls/doc/releases.md b/gopls/doc/releases.md -For more background on this policy, see https://go.dev/issue/55267. diff -urN a/gopls/doc/semantictokens.md b/gopls/doc/semantictokens.md --- a/gopls/doc/semantictokens.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/semantictokens.md 1970-01-01 08:00:00 ++++ b/gopls/doc/semantictokens.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ -# Semantic Tokens - @@ -3971,8 +4022,8 @@ diff -urN a/gopls/doc/semantictokens.md b/gopls/doc/semantictokens.md \ No newline at end of file diff -urN a/gopls/doc/settings.md b/gopls/doc/settings.md --- a/gopls/doc/settings.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/settings.md 1970-01-01 08:00:00 -@@ -1,567 +0,0 @@ ++++ b/gopls/doc/settings.md 1970-01-01 00:00:00.000000000 +0000 +@@ -1,581 +0,0 @@ -# Settings - - @@ -4329,6 +4380,20 @@ diff -urN a/gopls/doc/settings.md b/gopls/doc/settings.md - -Default: `"1s"`. - +-##### **diagnosticsTrigger** *enum* +- +-**This setting is experimental and may be deleted.** +- +-diagnosticsTrigger controls when to run diagnostics. +- +-Must be one of: +- +-* `"Edit"`: Trigger diagnostics on file edit and save. (default) +-* `"Save"`: Trigger diagnostics only on file save. Events like initial workspace load +-or configuration change will still trigger diagnostics. +- +-Default: `"Edit"`. +- -##### **analysisProgressReporting** *bool* - -analysisProgressReporting controls whether gopls sends progress @@ -4542,7 +4607,7 @@ diff -urN a/gopls/doc/settings.md b/gopls/doc/settings.md - diff -urN a/gopls/doc/subl.md b/gopls/doc/subl.md --- a/gopls/doc/subl.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/subl.md 1970-01-01 08:00:00 ++++ b/gopls/doc/subl.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -# Sublime Text - @@ -4627,7 +4692,7 @@ diff -urN a/gopls/doc/subl.md b/gopls/doc/subl.md -[LSP]: https://packagecontrol.io/packages/LSP diff -urN a/gopls/doc/troubleshooting.md b/gopls/doc/troubleshooting.md --- a/gopls/doc/troubleshooting.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/troubleshooting.md 1970-01-01 08:00:00 ++++ b/gopls/doc/troubleshooting.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -# Troubleshooting - @@ -4679,7 +4744,7 @@ diff -urN a/gopls/doc/troubleshooting.md b/gopls/doc/troubleshooting.md -`gopls` automatically writes out memory debug information when your usage exceeds 1GB. This information can be found in your temporary directory with names like `gopls.1234-5GiB-withnames.zip`. On Windows, your temporary directory will be located at `%TMP%`, and on Unixes, it will be `$TMPDIR`, which is usually `/tmp`. Please [file an issue](#file-an-issue) with this memory debug information attached. If you are uncomfortable sharing the package names of your code, you can share the `-nonames` zip instead, but it's much less useful. diff -urN a/gopls/doc/vim.md b/gopls/doc/vim.md --- a/gopls/doc/vim.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/vim.md 1970-01-01 08:00:00 ++++ b/gopls/doc/vim.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,234 +0,0 @@ -# Vim / Neovim - @@ -4917,7 +4982,7 @@ diff -urN a/gopls/doc/vim.md b/gopls/doc/vim.md -[nvim-lspconfig-imports]: https://github.com/neovim/nvim-lspconfig/issues/115 diff -urN a/gopls/doc/workspace.md b/gopls/doc/workspace.md --- a/gopls/doc/workspace.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/doc/workspace.md 1970-01-01 08:00:00 ++++ b/gopls/doc/workspace.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -# Setting up your workspace - @@ -5022,7 +5087,7 @@ diff -urN a/gopls/doc/workspace.md b/gopls/doc/workspace.md -[file a new issue](https://github.com/golang/go/issues/new). diff -urN a/gopls/go.mod b/gopls/go.mod --- a/gopls/go.mod 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/go.mod 1970-01-01 08:00:00 ++++ b/gopls/go.mod 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -module golang.org/x/tools/gopls - @@ -5033,11 +5098,11 @@ diff -urN a/gopls/go.mod b/gopls/go.mod - github.com/jba/printsrc v0.2.2 - github.com/jba/templatecheck v0.6.0 - github.com/sergi/go-diff v1.1.0 -- golang.org/x/mod v0.13.0 -- golang.org/x/sync v0.4.0 -- golang.org/x/sys v0.13.0 -- golang.org/x/telemetry v0.0.0-20231003223302-0168ef4ebbd3 -- golang.org/x/text v0.13.0 +- golang.org/x/mod v0.14.0 +- golang.org/x/sync v0.5.0 +- golang.org/x/sys v0.14.0 +- golang.org/x/telemetry v0.0.0-20231011160506-788d5629a052 +- golang.org/x/text v0.14.0 - golang.org/x/tools v0.13.1-0.20230920233436-f9b8da7b22be - golang.org/x/vuln v1.0.1 - gopkg.in/yaml.v3 v3.0.1 @@ -5056,7 +5121,7 @@ diff -urN a/gopls/go.mod b/gopls/go.mod -replace golang.org/x/tools => ../ diff -urN a/gopls/go.sum b/gopls/go.sum --- a/gopls/go.sum 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/go.sum 1970-01-01 08:00:00 ++++ b/gopls/go.sum 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= -github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= @@ -5089,29 +5154,29 @@ diff -urN a/gopls/go.sum b/gopls/go.sum -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= --golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +-golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= -golang.org/x/exp/typeparams v0.0.0-20221212164502-fae10dda9338 h1:2O2DON6y3XMJiQRAS1UWU+54aec2uopH3x7MAiqGW6Y= -golang.org/x/exp/typeparams v0.0.0-20221212164502-fae10dda9338/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= --golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= --golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +-golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +-golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= --golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +-golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= --golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= --golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +-golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +-golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= --golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= --golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= --golang.org/x/telemetry v0.0.0-20231003223302-0168ef4ebbd3 h1:vxxQvncMbcRAtqHV5HsHGJkbya+BIOYIY+y6cdPZhzk= --golang.org/x/telemetry v0.0.0-20231003223302-0168ef4ebbd3/go.mod h1:ppZ76JTkRgJC2GQEgtVY3fiuJR+N8FU2MAlp+gfN1E4= +-golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +-golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +-golang.org/x/telemetry v0.0.0-20231011160506-788d5629a052 h1:1baVNneD/IRxmu8JQdBuki78zUqBtZxq8smZXQj0X2Y= +-golang.org/x/telemetry v0.0.0-20231011160506-788d5629a052/go.mod h1:6p4ScoNeC2dhpQ1nSSMmkZ7mEj5JQUSCyc0uExBp5T4= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= --golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +-golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= --golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= --golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/vuln v1.0.1 h1:KUas02EjQK5LTuIx1OylBQdKKZ9jeugs+HiqO5HormU= -golang.org/x/vuln v1.0.1/go.mod h1:bb2hMwln/tqxg32BNY4CcxHWtHXuYa3SbIBmtsyjxtM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -5130,80 +5195,9 @@ diff -urN a/gopls/go.sum b/gopls/go.sum -mvdan.cc/gofumpt v0.4.0/go.mod h1:PljLOHDeZqgS8opHRKLzp2It2VBuSdteAgqUfzMTxlQ= -mvdan.cc/xurls/v2 v2.4.0 h1:tzxjVAj+wSBmDcF6zBB7/myTy3gX9xvi8Tyr28AuQgc= -mvdan.cc/xurls/v2 v2.4.0/go.mod h1:+GEjq9uNjqs8LQfM9nVnM8rff0OQ5Iash5rzX+N1CSg= -diff -urN a/gopls/integration/govim/Dockerfile b/gopls/integration/govim/Dockerfile ---- a/gopls/integration/govim/Dockerfile 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/integration/govim/Dockerfile 1970-01-01 08:00:00 -@@ -1,16 +0,0 @@ --# 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. -- --# govim requires a more recent version of vim than is available in most --# distros, so we build from their base image. --FROM govim/govim:latest-vim --ARG GOVIM_REF -- --ENV GOPROXY=https://proxy.golang.org GOPATH=/go VIM_FLAVOR=vim --WORKDIR /src -- --# Clone govim. In order to use the go command for resolving latest, we download --# a redundant copy of govim to the build cache using `go mod download`. --RUN git clone https://github.com/govim/govim /src/govim && cd /src/govim && \ -- git checkout $GOVIM_REF -diff -urN a/gopls/integration/govim/README.md b/gopls/integration/govim/README.md ---- a/gopls/integration/govim/README.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/integration/govim/README.md 1970-01-01 08:00:00 -@@ -1,47 +0,0 @@ --# govim integration tests -- --Files in this directory configure Cloud Build to run [govim] integration tests --against a gopls binary built from source. -- --## Running on GCP -- --To run these integration tests in Cloud Build, use the following steps. Here --we assume that `$PROJECT_ID` is a valid GCP project and `$BUCKET` is a cloud --storage bucket owned by that project. -- --- `cd` to the root directory of the tools project. --- (at least once per GCP project) Build the test harness: --``` --$ gcloud builds submit \ -- --project="${PROJECT_ID}" \ -- --config=gopls/integration/govim/cloudbuild.harness.yaml --``` --- Run the integration tests: --``` --$ gcloud builds submit \ -- --project="${PROJECT_ID}" \ -- --config=gopls/integration/govim/cloudbuild.yaml \ -- --substitutions=_RESULT_BUCKET="${BUCKET}" --``` -- --## Fetching Artifacts -- --Assuming the artifacts bucket is world readable, you can fetch integration from --GCS. They are located at: -- --- logs: `https://storage.googleapis.com/${BUCKET}/log-${EVALUATION_ID}.txt` --- artifact tarball: `https://storage.googleapis.com/${BUCKET}/govim/${EVALUATION_ID}/artifacts.tar.gz` -- --The `artifacts.go` command can be used to fetch both artifacts using an --evaluation id. -- --## Running locally -- --Run `gopls/integration/govim/run_local.sh`. This may take a while the first --time it is run, as it will require building the test harness. This script --accepts two flags to modify its behavior: -- --**--sudo**: run docker with `sudo` --**--short**: run `go test -short` -- --[govim]: https://github.com/govim/govim diff -urN a/gopls/integration/govim/artifacts.go b/gopls/integration/govim/artifacts.go --- a/gopls/integration/govim/artifacts.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/integration/govim/artifacts.go 1970-01-01 08:00:00 ++++ b/gopls/integration/govim/artifacts.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -5274,7 +5268,7 @@ diff -urN a/gopls/integration/govim/artifacts.go b/gopls/integration/govim/artif -} diff -urN a/gopls/integration/govim/cloudbuild.harness.yaml b/gopls/integration/govim/cloudbuild.harness.yaml --- a/gopls/integration/govim/cloudbuild.harness.yaml 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/integration/govim/cloudbuild.harness.yaml 1970-01-01 08:00:00 ++++ b/gopls/integration/govim/cloudbuild.harness.yaml 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -# Copyright 2019 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style @@ -5299,7 +5293,7 @@ diff -urN a/gopls/integration/govim/cloudbuild.harness.yaml b/gopls/integration/ - - gcr.io/$PROJECT_ID/govim-harness diff -urN a/gopls/integration/govim/cloudbuild.yaml b/gopls/integration/govim/cloudbuild.yaml --- a/gopls/integration/govim/cloudbuild.yaml 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/integration/govim/cloudbuild.yaml 1970-01-01 08:00:00 ++++ b/gopls/integration/govim/cloudbuild.yaml 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -# Copyright 2019 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style @@ -5352,9 +5346,80 @@ diff -urN a/gopls/integration/govim/cloudbuild.yaml b/gopls/integration/govim/cl -# Write build logs to the same bucket as artifacts, so they can be more easily -# shared. -logsBucket: 'gs://${_RESULT_BUCKET}' +diff -urN a/gopls/integration/govim/Dockerfile b/gopls/integration/govim/Dockerfile +--- a/gopls/integration/govim/Dockerfile 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/integration/govim/Dockerfile 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +-# 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. +- +-# govim requires a more recent version of vim than is available in most +-# distros, so we build from their base image. +-FROM govim/govim:latest-vim +-ARG GOVIM_REF +- +-ENV GOPROXY=https://proxy.golang.org GOPATH=/go VIM_FLAVOR=vim +-WORKDIR /src +- +-# Clone govim. In order to use the go command for resolving latest, we download +-# a redundant copy of govim to the build cache using `go mod download`. +-RUN git clone https://github.com/govim/govim /src/govim && cd /src/govim && \ +- git checkout $GOVIM_REF +diff -urN a/gopls/integration/govim/README.md b/gopls/integration/govim/README.md +--- a/gopls/integration/govim/README.md 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/integration/govim/README.md 1970-01-01 00:00:00.000000000 +0000 +@@ -1,47 +0,0 @@ +-# govim integration tests +- +-Files in this directory configure Cloud Build to run [govim] integration tests +-against a gopls binary built from source. +- +-## Running on GCP +- +-To run these integration tests in Cloud Build, use the following steps. Here +-we assume that `$PROJECT_ID` is a valid GCP project and `$BUCKET` is a cloud +-storage bucket owned by that project. +- +-- `cd` to the root directory of the tools project. +-- (at least once per GCP project) Build the test harness: +-``` +-$ gcloud builds submit \ +- --project="${PROJECT_ID}" \ +- --config=gopls/integration/govim/cloudbuild.harness.yaml +-``` +-- Run the integration tests: +-``` +-$ gcloud builds submit \ +- --project="${PROJECT_ID}" \ +- --config=gopls/integration/govim/cloudbuild.yaml \ +- --substitutions=_RESULT_BUCKET="${BUCKET}" +-``` +- +-## Fetching Artifacts +- +-Assuming the artifacts bucket is world readable, you can fetch integration from +-GCS. They are located at: +- +-- logs: `https://storage.googleapis.com/${BUCKET}/log-${EVALUATION_ID}.txt` +-- artifact tarball: `https://storage.googleapis.com/${BUCKET}/govim/${EVALUATION_ID}/artifacts.tar.gz` +- +-The `artifacts.go` command can be used to fetch both artifacts using an +-evaluation id. +- +-## Running locally +- +-Run `gopls/integration/govim/run_local.sh`. This may take a while the first +-time it is run, as it will require building the test harness. This script +-accepts two flags to modify its behavior: +- +-**--sudo**: run docker with `sudo` +-**--short**: run `go test -short` +- +-[govim]: https://github.com/govim/govim diff -urN a/gopls/integration/govim/run_local.sh b/gopls/integration/govim/run_local.sh --- a/gopls/integration/govim/run_local.sh 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/integration/govim/run_local.sh 1970-01-01 08:00:00 ++++ b/gopls/integration/govim/run_local.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ -#!/bin/bash -e - @@ -5454,7 +5519,7 @@ diff -urN a/gopls/integration/govim/run_local.sh b/gopls/integration/govim/run_l - -gopls "/src/tools/gopls/${temp_gopls_name}" diff -urN a/gopls/integration/govim/run_tests_for_cloudbuild.sh b/gopls/integration/govim/run_tests_for_cloudbuild.sh --- a/gopls/integration/govim/run_tests_for_cloudbuild.sh 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/integration/govim/run_tests_for_cloudbuild.sh 1970-01-01 08:00:00 ++++ b/gopls/integration/govim/run_tests_for_cloudbuild.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -#!/bin/bash - @@ -5486,7 +5551,7 @@ diff -urN a/gopls/integration/govim/run_tests_for_cloudbuild.sh b/gopls/integrat -fi diff -urN a/gopls/internal/astutil/purge.go b/gopls/internal/astutil/purge.go --- a/gopls/internal/astutil/purge.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/astutil/purge.go 1970-01-01 08:00:00 ++++ b/gopls/internal/astutil/purge.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -5564,7 +5629,7 @@ diff -urN a/gopls/internal/astutil/purge.go b/gopls/internal/astutil/purge.go -} diff -urN a/gopls/internal/astutil/purge_test.go b/gopls/internal/astutil/purge_test.go --- a/gopls/internal/astutil/purge_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/astutil/purge_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/astutil/purge_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -5657,7 +5722,7 @@ diff -urN a/gopls/internal/astutil/purge_test.go b/gopls/internal/astutil/purge_ -} diff -urN a/gopls/internal/astutil/util.go b/gopls/internal/astutil/util.go --- a/gopls/internal/astutil/util.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/astutil/util.go 1970-01-01 08:00:00 ++++ b/gopls/internal/astutil/util.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -5722,7 +5787,7 @@ diff -urN a/gopls/internal/astutil/util.go b/gopls/internal/astutil/util.go -} diff -urN a/gopls/internal/bug/bug.go b/gopls/internal/bug/bug.go --- a/gopls/internal/bug/bug.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/bug/bug.go 1970-01-01 08:00:00 ++++ b/gopls/internal/bug/bug.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,142 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -5868,7 +5933,7 @@ diff -urN a/gopls/internal/bug/bug.go b/gopls/internal/bug/bug.go -} diff -urN a/gopls/internal/bug/bug_test.go b/gopls/internal/bug/bug_test.go --- a/gopls/internal/bug/bug_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/bug/bug_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/bug/bug_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -5963,7 +6028,7 @@ diff -urN a/gopls/internal/bug/bug_test.go b/gopls/internal/bug/bug_test.go -} diff -urN a/gopls/internal/coverage/coverage.go b/gopls/internal/coverage/coverage.go --- a/gopls/internal/coverage/coverage.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/coverage/coverage.go 1970-01-01 08:00:00 ++++ b/gopls/internal/coverage/coverage.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,266 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -6233,7 +6298,7 @@ diff -urN a/gopls/internal/coverage/coverage.go b/gopls/internal/coverage/covera -} diff -urN a/gopls/internal/hooks/analysis_116.go b/gopls/internal/hooks/analysis_116.go --- a/gopls/internal/hooks/analysis_116.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/hooks/analysis_116.go 1970-01-01 08:00:00 ++++ b/gopls/internal/hooks/analysis_116.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -6251,7 +6316,7 @@ diff -urN a/gopls/internal/hooks/analysis_116.go b/gopls/internal/hooks/analysis -} diff -urN a/gopls/internal/hooks/analysis_119.go b/gopls/internal/hooks/analysis_119.go --- a/gopls/internal/hooks/analysis_119.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/hooks/analysis_119.go 1970-01-01 08:00:00 ++++ b/gopls/internal/hooks/analysis_119.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -6317,7 +6382,7 @@ diff -urN a/gopls/internal/hooks/analysis_119.go b/gopls/internal/hooks/analysis -} diff -urN a/gopls/internal/hooks/diff.go b/gopls/internal/hooks/diff.go --- a/gopls/internal/hooks/diff.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/hooks/diff.go 1970-01-01 08:00:00 ++++ b/gopls/internal/hooks/diff.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,168 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -6489,7 +6554,7 @@ diff -urN a/gopls/internal/hooks/diff.go b/gopls/internal/hooks/diff.go -} diff -urN a/gopls/internal/hooks/diff_test.go b/gopls/internal/hooks/diff_test.go --- a/gopls/internal/hooks/diff_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/hooks/diff_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/hooks/diff_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -6525,7 +6590,7 @@ diff -urN a/gopls/internal/hooks/diff_test.go b/gopls/internal/hooks/diff_test.g -} diff -urN a/gopls/internal/hooks/gen-licenses.sh b/gopls/internal/hooks/gen-licenses.sh --- a/gopls/internal/hooks/gen-licenses.sh 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/hooks/gen-licenses.sh 1970-01-01 08:00:00 ++++ b/gopls/internal/hooks/gen-licenses.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -#!/bin/bash -eu - @@ -6568,7 +6633,7 @@ diff -urN a/gopls/internal/hooks/gen-licenses.sh b/gopls/internal/hooks/gen-lice \ No newline at end of file diff -urN a/gopls/internal/hooks/gofumpt_117.go b/gopls/internal/hooks/gofumpt_117.go --- a/gopls/internal/hooks/gofumpt_117.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/hooks/gofumpt_117.go 1970-01-01 08:00:00 ++++ b/gopls/internal/hooks/gofumpt_117.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -6585,7 +6650,7 @@ diff -urN a/gopls/internal/hooks/gofumpt_117.go b/gopls/internal/hooks/gofumpt_1 -} diff -urN a/gopls/internal/hooks/gofumpt_118.go b/gopls/internal/hooks/gofumpt_118.go --- a/gopls/internal/hooks/gofumpt_118.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/hooks/gofumpt_118.go 1970-01-01 08:00:00 ++++ b/gopls/internal/hooks/gofumpt_118.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -6667,7 +6732,7 @@ diff -urN a/gopls/internal/hooks/gofumpt_118.go b/gopls/internal/hooks/gofumpt_1 -} diff -urN a/gopls/internal/hooks/gofumpt_118_test.go b/gopls/internal/hooks/gofumpt_118_test.go --- a/gopls/internal/hooks/gofumpt_118_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/hooks/gofumpt_118_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/hooks/gofumpt_118_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -6724,7 +6789,7 @@ diff -urN a/gopls/internal/hooks/gofumpt_118_test.go b/gopls/internal/hooks/gofu -} diff -urN a/gopls/internal/hooks/hooks.go b/gopls/internal/hooks/hooks.go --- a/gopls/internal/hooks/hooks.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/hooks/hooks.go 1970-01-01 08:00:00 ++++ b/gopls/internal/hooks/hooks.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -6759,7 +6824,7 @@ diff -urN a/gopls/internal/hooks/hooks.go b/gopls/internal/hooks/hooks.go -} diff -urN a/gopls/internal/hooks/licenses.go b/gopls/internal/hooks/licenses.go --- a/gopls/internal/hooks/licenses.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/hooks/licenses.go 1970-01-01 08:00:00 ++++ b/gopls/internal/hooks/licenses.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,169 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -6932,7 +6997,7 @@ diff -urN a/gopls/internal/hooks/licenses.go b/gopls/internal/hooks/licenses.go -` diff -urN a/gopls/internal/hooks/licenses_test.go b/gopls/internal/hooks/licenses_test.go --- a/gopls/internal/hooks/licenses_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/hooks/licenses_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/hooks/licenses_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -6981,20 +7046,9 @@ diff -urN a/gopls/internal/hooks/licenses_test.go b/gopls/internal/hooks/license - t.Error("combined license text needs updating. Run: `go generate ./internal/hooks` from the gopls module.") - } -} -diff -urN a/gopls/internal/lsp/README.md b/gopls/internal/lsp/README.md ---- a/gopls/internal/lsp/README.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/README.md 1970-01-01 08:00:00 -@@ -1,7 +0,0 @@ --# 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. diff -urN a/gopls/internal/lsp/analysis/deprecated/deprecated.go b/gopls/internal/lsp/analysis/deprecated/deprecated.go --- a/gopls/internal/lsp/analysis/deprecated/deprecated.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/deprecated/deprecated.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/deprecated/deprecated.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,270 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -7268,7 +7322,7 @@ diff -urN a/gopls/internal/lsp/analysis/deprecated/deprecated.go b/gopls/interna -} diff -urN a/gopls/internal/lsp/analysis/deprecated/deprecated_test.go b/gopls/internal/lsp/analysis/deprecated/deprecated_test.go --- a/gopls/internal/lsp/analysis/deprecated/deprecated_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/deprecated/deprecated_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/deprecated/deprecated_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -7290,7 +7344,7 @@ diff -urN a/gopls/internal/lsp/analysis/deprecated/deprecated_test.go b/gopls/in -} diff -urN a/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a.go b/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a.go --- a/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -7311,7 +7365,7 @@ diff -urN a/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a.go b/gopls/i -func Legacy() {} // want Legacy:"Deprecated: use X instead." diff -urN a/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a_test.go b/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a_test.go --- a/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -7327,8 +7381,8 @@ diff -urN a/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a_test.go b/go -} diff -urN a/gopls/internal/lsp/analysis/embeddirective/embeddirective.go b/gopls/internal/lsp/analysis/embeddirective/embeddirective.go --- a/gopls/internal/lsp/analysis/embeddirective/embeddirective.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/embeddirective/embeddirective.go 1970-01-01 08:00:00 -@@ -1,134 +0,0 @@ ++++ b/gopls/internal/lsp/analysis/embeddirective/embeddirective.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,162 +0,0 @@ -// Copyright 2022 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. @@ -7340,6 +7394,7 @@ diff -urN a/gopls/internal/lsp/analysis/embeddirective/embeddirective.go b/gopls -import ( - "go/ast" - "go/token" +- "go/types" - "strings" - - "golang.org/x/tools/go/analysis" @@ -7398,10 +7453,12 @@ diff -urN a/gopls/internal/lsp/analysis/embeddirective/embeddirective.go b/gopls - switch { - case spec == nil: - report(`go:embed directives must precede a "var" declaration`) -- case len(spec.Names) > 1: +- case len(spec.Names) != 1: - report("declarations following go:embed directives must define a single variable") - case len(spec.Values) > 0: - report("declarations following go:embed directives must not specify a value") +- case !embeddableType(pass.TypesInfo.Defs[spec.Names[0]]): +- report("declarations following go:embed directives must be of type string, []byte or embed.FS") - } - } - } @@ -7463,9 +7520,34 @@ diff -urN a/gopls/internal/lsp/analysis/embeddirective/embeddirective.go b/gopls - } - return spec -} +- +-// embeddableType in go:embed directives are string, []byte or embed.FS. +-func embeddableType(o types.Object) bool { +- if o == nil { +- return false +- } +- +- // For embed.FS the underlying type is an implementation detail. +- // As long as the named type resolves to embed.FS, it is OK. +- if named, ok := o.Type().(*types.Named); ok { +- obj := named.Obj() +- if obj.Pkg() != nil && obj.Pkg().Path() == "embed" && obj.Name() == "FS" { +- return true +- } +- } +- +- switch v := o.Type().Underlying().(type) { +- case *types.Basic: +- return types.Identical(v, types.Typ[types.String]) +- case *types.Slice: +- return types.Identical(v.Elem(), types.Typ[types.Byte]) +- } +- +- return false +-} diff -urN a/gopls/internal/lsp/analysis/embeddirective/embeddirective_test.go b/gopls/internal/lsp/analysis/embeddirective/embeddirective_test.go --- a/gopls/internal/lsp/analysis/embeddirective/embeddirective_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/embeddirective/embeddirective_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/embeddirective/embeddirective_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -7491,13 +7573,13 @@ diff -urN a/gopls/internal/lsp/analysis/embeddirective/embeddirective_test.go b/ -} diff -urN a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/embedText b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/embedText --- a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/embedText 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/embedText 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/embedText 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Hello World \ No newline at end of file diff -urN a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_missing.go b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_missing.go --- a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_missing.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_missing.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_missing.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -7518,8 +7600,8 @@ diff -urN a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_mis -} diff -urN a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present.go b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present.go --- a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present.go 1970-01-01 08:00:00 -@@ -1,73 +0,0 @@ ++++ b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,129 +0,0 @@ -// Copyright 2022 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. @@ -7530,62 +7612,118 @@ diff -urN a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_pre -//go:embed embedText // want "go:embed directives must precede a \"var\" declaration" - -import ( +- "embed" +- embedPkg "embed" - "fmt" - - _ "embed" -) - -//go:embed embedText // ok --var s string +-var e1 string - -// The analyzer does not check for many directives using the same var. -// -//go:embed embedText // ok -//go:embed embedText // ok --var s string +-var e2 string - --// Comments and blank lines between are OK. +-// Comments and blank lines between are OK. All types OK. -// -//go:embed embedText // ok -// -// foo - --var s string +-var e3 string +- +-//go:embed embedText //ok +-var e4 []byte +- +-//go:embed embedText //ok +-var e5 embed.FS - -// Followed by wrong kind of decl. -// -//go:embed embedText // want "go:embed directives must precede a \"var\" declaration" --func foo() +-func fooFunc() {} - -// Multiple variable specs. -// -//go:embed embedText // want "declarations following go:embed directives must define a single variable" --var foo, bar []byte +-var e6, e7 []byte - -// Specifying a value is not allowed. -// -//go:embed embedText // want "declarations following go:embed directives must not specify a value" --var s string = "foo" +-var e8 string = "foo" - -// TODO: This should not be OK, misplaced according to compiler. -// -//go:embed embedText // ok -var ( -- s string -- x string +- e9 string +- e10 string -) - +-// Type definition. +-type fooType []byte +- +-//go:embed embedText //ok +-var e11 fooType +- +-// Type alias. +-type barType = string +- +-//go:embed embedText //ok +-var e12 barType +- +-// Renamed embed package. +- +-//go:embed embedText //ok +-var e13 embedPkg.FS +- +-// Renamed embed package alias. +-type embedAlias = embedPkg.FS +- +-//go:embed embedText //ok +-var e14 embedAlias +- -// var blocks are OK as long as the variable following the directive is OK. -var ( - x, y, z string - //go:embed embedText // ok -- s string +- e20 string - q, r, t string -) - -//go:embed embedText // want "go:embed directives must precede a \"var\" declaration" -var () - +-// Incorrect types. +- +-//go:embed embedText // want `declarations following go:embed directives must be of type string, \[\]byte or embed.FS` +-var e16 byte +- +-//go:embed embedText // want `declarations following go:embed directives must be of type string, \[\]byte or embed.FS` +-var e17 []string +- +-//go:embed embedText // want `declarations following go:embed directives must be of type string, \[\]byte or embed.FS` +-var e18 embed.Foo +- +-//go:embed embedText // want `declarations following go:embed directives must be of type string, \[\]byte or embed.FS` +-var e19 foo.FS +- +-type byteAlias byte +- +-//go:embed embedText // want `declarations following go:embed directives must be of type string, \[\]byte or embed.FS` +-var e15 byteAlias +- +-// A type declaration of embed.FS is not accepted by the compiler, in contrast to an alias. +-type embedDecl embed.FS +- +-//go:embed embedText // want `declarations following go:embed directives must be of type string, \[\]byte or embed.FS` +-var e16 embedDecl +- -// This is main function -func main() { - fmt.Println(s) @@ -7595,7 +7733,7 @@ diff -urN a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_pre -//go:embed embedText // want "go:embed directives must precede a \"var\" declaration" diff -urN a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present_go120.go b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present_go120.go --- a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present_go120.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present_go120.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present_go120.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -7610,7 +7748,7 @@ diff -urN a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_pre - // Okay directive wise but the compiler will complain that - // imports must appear before other declarations. - //go:embed embedText // ok -- "foo" +- foo string -) - -import ( @@ -7625,7 +7763,7 @@ diff -urN a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_pre -} diff -urN a/gopls/internal/lsp/analysis/fillreturns/fillreturns.go b/gopls/internal/lsp/analysis/fillreturns/fillreturns.go --- a/gopls/internal/lsp/analysis/fillreturns/fillreturns.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/fillreturns/fillreturns.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/fillreturns/fillreturns.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,279 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -7908,7 +8046,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillreturns/fillreturns.go b/gopls/inter -} diff -urN a/gopls/internal/lsp/analysis/fillreturns/fillreturns_test.go b/gopls/internal/lsp/analysis/fillreturns/fillreturns_test.go --- a/gopls/internal/lsp/analysis/fillreturns/fillreturns_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/fillreturns/fillreturns_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/fillreturns/fillreturns_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -7934,7 +8072,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillreturns/fillreturns_test.go b/gopls/ -} diff -urN a/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/a.go b/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/a.go --- a/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/a.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/a.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,139 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -8077,7 +8215,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/a.go b/gopls/ -} diff -urN a/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/a.go.golden b/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/a.go.golden --- a/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/a.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/a.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,139 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -8220,7 +8358,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/a.go.golden b -} diff -urN a/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/typeparams/a.go b/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/typeparams/a.go --- a/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/typeparams/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/typeparams/a.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/typeparams/a.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -package fillreturns - @@ -8229,7 +8367,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/typeparams/a. -} diff -urN a/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/typeparams/a.go.golden b/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/typeparams/a.go.golden --- a/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/typeparams/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/typeparams/a.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/typeparams/a.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -package fillreturns - @@ -8238,7 +8376,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/typeparams/a. -} diff -urN a/gopls/internal/lsp/analysis/fillstruct/fillstruct.go b/gopls/internal/lsp/analysis/fillstruct/fillstruct.go --- a/gopls/internal/lsp/analysis/fillstruct/fillstruct.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/fillstruct/fillstruct.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/fillstruct/fillstruct.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,515 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -8599,7 +8737,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillstruct/fillstruct.go b/gopls/interna - case u.Kind() == types.UnsafePointer: - return ast.NewIdent("nil") - default: -- panic("unknown basic type") +- panic(fmt.Sprintf("unknown basic type %v", u)) - } - - case *types.Map: @@ -8757,7 +8895,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillstruct/fillstruct.go b/gopls/interna -} diff -urN a/gopls/internal/lsp/analysis/fillstruct/fillstruct_test.go b/gopls/internal/lsp/analysis/fillstruct/fillstruct_test.go --- a/gopls/internal/lsp/analysis/fillstruct/fillstruct_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/fillstruct/fillstruct_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/fillstruct/fillstruct_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -8783,7 +8921,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillstruct/fillstruct_test.go b/gopls/in -} diff -urN a/gopls/internal/lsp/analysis/fillstruct/testdata/src/a/a.go b/gopls/internal/lsp/analysis/fillstruct/testdata/src/a/a.go --- a/gopls/internal/lsp/analysis/fillstruct/testdata/src/a/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/fillstruct/testdata/src/a/a.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/fillstruct/testdata/src/a/a.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,113 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -8900,7 +9038,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillstruct/testdata/src/a/a.go b/gopls/i -var _ = unsafeStruct{} // want `Fill unsafeStruct` diff -urN a/gopls/internal/lsp/analysis/fillstruct/testdata/src/b/b.go b/gopls/internal/lsp/analysis/fillstruct/testdata/src/b/b.go --- a/gopls/internal/lsp/analysis/fillstruct/testdata/src/b/b.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/fillstruct/testdata/src/b/b.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/fillstruct/testdata/src/b/b.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -package fillstruct - @@ -8910,7 +9048,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillstruct/testdata/src/b/b.go b/gopls/i -} diff -urN a/gopls/internal/lsp/analysis/fillstruct/testdata/src/typeparams/typeparams.go b/gopls/internal/lsp/analysis/fillstruct/testdata/src/typeparams/typeparams.go --- a/gopls/internal/lsp/analysis/fillstruct/testdata/src/typeparams/typeparams.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/fillstruct/testdata/src/typeparams/typeparams.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/fillstruct/testdata/src/typeparams/typeparams.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -8964,7 +9102,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillstruct/testdata/src/typeparams/typep -} diff -urN a/gopls/internal/lsp/analysis/infertypeargs/infertypeargs.go b/gopls/internal/lsp/analysis/infertypeargs/infertypeargs.go --- a/gopls/internal/lsp/analysis/infertypeargs/infertypeargs.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/infertypeargs/infertypeargs.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/infertypeargs/infertypeargs.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9015,7 +9153,7 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/infertypeargs.go b/gopls/i -} diff -urN a/gopls/internal/lsp/analysis/infertypeargs/infertypeargs_test.go b/gopls/internal/lsp/analysis/infertypeargs/infertypeargs_test.go --- a/gopls/internal/lsp/analysis/infertypeargs/infertypeargs_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/infertypeargs/infertypeargs_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/infertypeargs/infertypeargs_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9040,7 +9178,7 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/infertypeargs_test.go b/go -} diff -urN a/gopls/internal/lsp/analysis/infertypeargs/run_go117.go b/gopls/internal/lsp/analysis/infertypeargs/run_go117.go --- a/gopls/internal/lsp/analysis/infertypeargs/run_go117.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/infertypeargs/run_go117.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/infertypeargs/run_go117.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9066,7 +9204,7 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/run_go117.go b/gopls/inter -} diff -urN a/gopls/internal/lsp/analysis/infertypeargs/run_go118.go b/gopls/internal/lsp/analysis/infertypeargs/run_go118.go --- a/gopls/internal/lsp/analysis/infertypeargs/run_go118.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/infertypeargs/run_go118.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/infertypeargs/run_go118.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9190,7 +9328,7 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/run_go118.go b/gopls/inter -} diff -urN a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/basic.go b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/basic.go --- a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/basic.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/basic.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/basic.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9214,7 +9352,7 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/basic.go b/ -} diff -urN a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/basic.go.golden b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/basic.go.golden --- a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/basic.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/basic.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/basic.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9238,7 +9376,7 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/basic.go.go -} diff -urN a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported/imported.go b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported/imported.go --- a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported/imported.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported/imported.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported/imported.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9249,7 +9387,7 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported/im -func F[T any](T) {} diff -urN a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported.go b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported.go --- a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9265,7 +9403,7 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported.go -} diff -urN a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported.go.golden b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported.go.golden --- a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9281,7 +9419,7 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/imported.go -} diff -urN a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/notypechange.go b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/notypechange.go --- a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/notypechange.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/notypechange.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/notypechange.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9311,7 +9449,7 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/notypechang -} diff -urN a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/notypechange.go.golden b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/notypechange.go.golden --- a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/notypechange.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/notypechange.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/notypechange.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9341,7 +9479,7 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/testdata/src/a/notypechang -} diff -urN a/gopls/internal/lsp/analysis/nonewvars/nonewvars.go b/gopls/internal/lsp/analysis/nonewvars/nonewvars.go --- a/gopls/internal/lsp/analysis/nonewvars/nonewvars.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/nonewvars/nonewvars.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/nonewvars/nonewvars.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9440,7 +9578,7 @@ diff -urN a/gopls/internal/lsp/analysis/nonewvars/nonewvars.go b/gopls/internal/ -} diff -urN a/gopls/internal/lsp/analysis/nonewvars/nonewvars_test.go b/gopls/internal/lsp/analysis/nonewvars/nonewvars_test.go --- a/gopls/internal/lsp/analysis/nonewvars/nonewvars_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/nonewvars/nonewvars_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/nonewvars/nonewvars_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9466,7 +9604,7 @@ diff -urN a/gopls/internal/lsp/analysis/nonewvars/nonewvars_test.go b/gopls/inte -} diff -urN a/gopls/internal/lsp/analysis/nonewvars/testdata/src/a/a.go b/gopls/internal/lsp/analysis/nonewvars/testdata/src/a/a.go --- a/gopls/internal/lsp/analysis/nonewvars/testdata/src/a/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/nonewvars/testdata/src/a/a.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/nonewvars/testdata/src/a/a.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9486,7 +9624,7 @@ diff -urN a/gopls/internal/lsp/analysis/nonewvars/testdata/src/a/a.go b/gopls/in -} diff -urN a/gopls/internal/lsp/analysis/nonewvars/testdata/src/a/a.go.golden b/gopls/internal/lsp/analysis/nonewvars/testdata/src/a/a.go.golden --- a/gopls/internal/lsp/analysis/nonewvars/testdata/src/a/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/nonewvars/testdata/src/a/a.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/nonewvars/testdata/src/a/a.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9506,7 +9644,7 @@ diff -urN a/gopls/internal/lsp/analysis/nonewvars/testdata/src/a/a.go.golden b/g -} diff -urN a/gopls/internal/lsp/analysis/nonewvars/testdata/src/typeparams/a.go b/gopls/internal/lsp/analysis/nonewvars/testdata/src/typeparams/a.go --- a/gopls/internal/lsp/analysis/nonewvars/testdata/src/typeparams/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/nonewvars/testdata/src/typeparams/a.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/nonewvars/testdata/src/typeparams/a.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -package nonewvars - @@ -9516,7 +9654,7 @@ diff -urN a/gopls/internal/lsp/analysis/nonewvars/testdata/src/typeparams/a.go b -} diff -urN a/gopls/internal/lsp/analysis/nonewvars/testdata/src/typeparams/a.go.golden b/gopls/internal/lsp/analysis/nonewvars/testdata/src/typeparams/a.go.golden --- a/gopls/internal/lsp/analysis/nonewvars/testdata/src/typeparams/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/nonewvars/testdata/src/typeparams/a.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/nonewvars/testdata/src/typeparams/a.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -package nonewvars - @@ -9526,7 +9664,7 @@ diff -urN a/gopls/internal/lsp/analysis/nonewvars/testdata/src/typeparams/a.go.g -} diff -urN a/gopls/internal/lsp/analysis/noresultvalues/noresultvalues.go b/gopls/internal/lsp/analysis/noresultvalues/noresultvalues.go --- a/gopls/internal/lsp/analysis/noresultvalues/noresultvalues.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/noresultvalues/noresultvalues.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/noresultvalues/noresultvalues.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9622,7 +9760,7 @@ diff -urN a/gopls/internal/lsp/analysis/noresultvalues/noresultvalues.go b/gopls -} diff -urN a/gopls/internal/lsp/analysis/noresultvalues/noresultvalues_test.go b/gopls/internal/lsp/analysis/noresultvalues/noresultvalues_test.go --- a/gopls/internal/lsp/analysis/noresultvalues/noresultvalues_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/noresultvalues/noresultvalues_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/noresultvalues/noresultvalues_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9648,7 +9786,7 @@ diff -urN a/gopls/internal/lsp/analysis/noresultvalues/noresultvalues_test.go b/ -} diff -urN a/gopls/internal/lsp/analysis/noresultvalues/testdata/src/a/a.go b/gopls/internal/lsp/analysis/noresultvalues/testdata/src/a/a.go --- a/gopls/internal/lsp/analysis/noresultvalues/testdata/src/a/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/noresultvalues/testdata/src/a/a.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/noresultvalues/testdata/src/a/a.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9661,7 +9799,7 @@ diff -urN a/gopls/internal/lsp/analysis/noresultvalues/testdata/src/a/a.go b/gop -func y() { return nil, "hello" } // want `no result values expected|too many return values` diff -urN a/gopls/internal/lsp/analysis/noresultvalues/testdata/src/a/a.go.golden b/gopls/internal/lsp/analysis/noresultvalues/testdata/src/a/a.go.golden --- a/gopls/internal/lsp/analysis/noresultvalues/testdata/src/a/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/noresultvalues/testdata/src/a/a.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/noresultvalues/testdata/src/a/a.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9674,7 +9812,7 @@ diff -urN a/gopls/internal/lsp/analysis/noresultvalues/testdata/src/a/a.go.golde -func y() { return } // want `no result values expected|too many return values` diff -urN a/gopls/internal/lsp/analysis/noresultvalues/testdata/src/typeparams/a.go b/gopls/internal/lsp/analysis/noresultvalues/testdata/src/typeparams/a.go --- a/gopls/internal/lsp/analysis/noresultvalues/testdata/src/typeparams/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/noresultvalues/testdata/src/typeparams/a.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/noresultvalues/testdata/src/typeparams/a.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -package noresult - @@ -9684,7 +9822,7 @@ diff -urN a/gopls/internal/lsp/analysis/noresultvalues/testdata/src/typeparams/a -} diff -urN a/gopls/internal/lsp/analysis/noresultvalues/testdata/src/typeparams/a.go.golden b/gopls/internal/lsp/analysis/noresultvalues/testdata/src/typeparams/a.go.golden --- a/gopls/internal/lsp/analysis/noresultvalues/testdata/src/typeparams/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/noresultvalues/testdata/src/typeparams/a.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/noresultvalues/testdata/src/typeparams/a.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -package noresult - @@ -9694,7 +9832,7 @@ diff -urN a/gopls/internal/lsp/analysis/noresultvalues/testdata/src/typeparams/a -} diff -urN a/gopls/internal/lsp/analysis/simplifycompositelit/simplifycompositelit.go b/gopls/internal/lsp/analysis/simplifycompositelit/simplifycompositelit.go --- a/gopls/internal/lsp/analysis/simplifycompositelit/simplifycompositelit.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/simplifycompositelit/simplifycompositelit.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/simplifycompositelit/simplifycompositelit.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,196 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9894,7 +10032,7 @@ diff -urN a/gopls/internal/lsp/analysis/simplifycompositelit/simplifycompositeli -) diff -urN a/gopls/internal/lsp/analysis/simplifycompositelit/simplifycompositelit_test.go b/gopls/internal/lsp/analysis/simplifycompositelit/simplifycompositelit_test.go --- a/gopls/internal/lsp/analysis/simplifycompositelit/simplifycompositelit_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/simplifycompositelit/simplifycompositelit_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/simplifycompositelit/simplifycompositelit_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -9915,7 +10053,7 @@ diff -urN a/gopls/internal/lsp/analysis/simplifycompositelit/simplifycompositeli -} diff -urN a/gopls/internal/lsp/analysis/simplifycompositelit/testdata/src/a/a.go b/gopls/internal/lsp/analysis/simplifycompositelit/testdata/src/a/a.go --- a/gopls/internal/lsp/analysis/simplifycompositelit/testdata/src/a/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/simplifycompositelit/testdata/src/a/a.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/simplifycompositelit/testdata/src/a/a.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,234 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -10153,7 +10291,7 @@ diff -urN a/gopls/internal/lsp/analysis/simplifycompositelit/testdata/src/a/a.go -} diff -urN a/gopls/internal/lsp/analysis/simplifycompositelit/testdata/src/a/a.go.golden b/gopls/internal/lsp/analysis/simplifycompositelit/testdata/src/a/a.go.golden --- a/gopls/internal/lsp/analysis/simplifycompositelit/testdata/src/a/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/simplifycompositelit/testdata/src/a/a.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/simplifycompositelit/testdata/src/a/a.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,234 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -10391,7 +10529,7 @@ diff -urN a/gopls/internal/lsp/analysis/simplifycompositelit/testdata/src/a/a.go -} diff -urN a/gopls/internal/lsp/analysis/simplifyrange/simplifyrange.go b/gopls/internal/lsp/analysis/simplifyrange/simplifyrange.go --- a/gopls/internal/lsp/analysis/simplifyrange/simplifyrange.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/simplifyrange/simplifyrange.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/simplifyrange/simplifyrange.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,116 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -10511,7 +10649,7 @@ diff -urN a/gopls/internal/lsp/analysis/simplifyrange/simplifyrange.go b/gopls/i -} diff -urN a/gopls/internal/lsp/analysis/simplifyrange/simplifyrange_test.go b/gopls/internal/lsp/analysis/simplifyrange/simplifyrange_test.go --- a/gopls/internal/lsp/analysis/simplifyrange/simplifyrange_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/simplifyrange/simplifyrange_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/simplifyrange/simplifyrange_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -10532,7 +10670,7 @@ diff -urN a/gopls/internal/lsp/analysis/simplifyrange/simplifyrange_test.go b/go -} diff -urN a/gopls/internal/lsp/analysis/simplifyrange/testdata/src/a/a.go b/gopls/internal/lsp/analysis/simplifyrange/testdata/src/a/a.go --- a/gopls/internal/lsp/analysis/simplifyrange/testdata/src/a/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/simplifyrange/testdata/src/a/a.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/simplifyrange/testdata/src/a/a.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -10552,7 +10690,7 @@ diff -urN a/gopls/internal/lsp/analysis/simplifyrange/testdata/src/a/a.go b/gopl -} diff -urN a/gopls/internal/lsp/analysis/simplifyrange/testdata/src/a/a.go.golden b/gopls/internal/lsp/analysis/simplifyrange/testdata/src/a/a.go.golden --- a/gopls/internal/lsp/analysis/simplifyrange/testdata/src/a/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/simplifyrange/testdata/src/a/a.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/simplifyrange/testdata/src/a/a.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -10572,7 +10710,7 @@ diff -urN a/gopls/internal/lsp/analysis/simplifyrange/testdata/src/a/a.go.golden -} diff -urN a/gopls/internal/lsp/analysis/simplifyslice/simplifyslice.go b/gopls/internal/lsp/analysis/simplifyslice/simplifyslice.go --- a/gopls/internal/lsp/analysis/simplifyslice/simplifyslice.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/simplifyslice/simplifyslice.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/simplifyslice/simplifyslice.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,94 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -10670,7 +10808,7 @@ diff -urN a/gopls/internal/lsp/analysis/simplifyslice/simplifyslice.go b/gopls/i -} diff -urN a/gopls/internal/lsp/analysis/simplifyslice/simplifyslice_test.go b/gopls/internal/lsp/analysis/simplifyslice/simplifyslice_test.go --- a/gopls/internal/lsp/analysis/simplifyslice/simplifyslice_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/simplifyslice/simplifyslice_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/simplifyslice/simplifyslice_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -10696,7 +10834,7 @@ diff -urN a/gopls/internal/lsp/analysis/simplifyslice/simplifyslice_test.go b/go -} diff -urN a/gopls/internal/lsp/analysis/simplifyslice/testdata/src/a/a.go b/gopls/internal/lsp/analysis/simplifyslice/testdata/src/a/a.go --- a/gopls/internal/lsp/analysis/simplifyslice/testdata/src/a/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/simplifyslice/testdata/src/a/a.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/simplifyslice/testdata/src/a/a.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -10770,7 +10908,7 @@ diff -urN a/gopls/internal/lsp/analysis/simplifyslice/testdata/src/a/a.go b/gopl -} diff -urN a/gopls/internal/lsp/analysis/simplifyslice/testdata/src/a/a.go.golden b/gopls/internal/lsp/analysis/simplifyslice/testdata/src/a/a.go.golden --- a/gopls/internal/lsp/analysis/simplifyslice/testdata/src/a/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/simplifyslice/testdata/src/a/a.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/simplifyslice/testdata/src/a/a.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -10844,7 +10982,7 @@ diff -urN a/gopls/internal/lsp/analysis/simplifyslice/testdata/src/a/a.go.golden -} diff -urN a/gopls/internal/lsp/analysis/simplifyslice/testdata/src/typeparams/typeparams.go b/gopls/internal/lsp/analysis/simplifyslice/testdata/src/typeparams/typeparams.go --- a/gopls/internal/lsp/analysis/simplifyslice/testdata/src/typeparams/typeparams.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/simplifyslice/testdata/src/typeparams/typeparams.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/simplifyslice/testdata/src/typeparams/typeparams.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -10887,7 +11025,7 @@ diff -urN a/gopls/internal/lsp/analysis/simplifyslice/testdata/src/typeparams/ty -} diff -urN a/gopls/internal/lsp/analysis/simplifyslice/testdata/src/typeparams/typeparams.go.golden b/gopls/internal/lsp/analysis/simplifyslice/testdata/src/typeparams/typeparams.go.golden --- a/gopls/internal/lsp/analysis/simplifyslice/testdata/src/typeparams/typeparams.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/simplifyslice/testdata/src/typeparams/typeparams.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/simplifyslice/testdata/src/typeparams/typeparams.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -10930,7 +11068,7 @@ diff -urN a/gopls/internal/lsp/analysis/simplifyslice/testdata/src/typeparams/ty -} diff -urN a/gopls/internal/lsp/analysis/stubmethods/stubmethods.go b/gopls/internal/lsp/analysis/stubmethods/stubmethods.go --- a/gopls/internal/lsp/analysis/stubmethods/stubmethods.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/stubmethods/stubmethods.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/stubmethods/stubmethods.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,449 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -11383,7 +11521,7 @@ diff -urN a/gopls/internal/lsp/analysis/stubmethods/stubmethods.go b/gopls/inter -} diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/a.go b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/a.go --- a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/a.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/a.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -11415,7 +11553,7 @@ diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/a.go b/gop -} diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/channels.go b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/channels.go --- a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/channels.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/channels.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/channels.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -11432,7 +11570,7 @@ diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/channels.g -} diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/consecutive_params.go b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/consecutive_params.go --- a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/consecutive_params.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/consecutive_params.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/consecutive_params.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -11446,7 +11584,7 @@ diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/consecutiv -} diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/error_param.go b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/error_param.go --- a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/error_param.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/error_param.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/error_param.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -11460,7 +11598,7 @@ diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/error_para -} diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/literals.go b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/literals.go --- a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/literals.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/literals.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/literals.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -11475,7 +11613,7 @@ diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/literals.g -} diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/operation.go b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/operation.go --- a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/operation.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/operation.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/operation.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -11490,7 +11628,7 @@ diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/operation. -} diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/selector.go b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/selector.go --- a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/selector.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/selector.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/selector.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -11504,7 +11642,7 @@ diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/selector.g -} diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/slice.go b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/slice.go --- a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/slice.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/slice.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/slice.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -11517,7 +11655,7 @@ diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/slice.go b -} diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/tuple.go b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/tuple.go --- a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/tuple.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/tuple.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/tuple.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -11534,7 +11672,7 @@ diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/tuple.go b -} diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/unique_params.go b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/unique_params.go --- a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/unique_params.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/unique_params.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/unique_params.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -11549,7 +11687,7 @@ diff -urN a/gopls/internal/lsp/analysis/undeclaredname/testdata/src/a/unique_par -} diff -urN a/gopls/internal/lsp/analysis/undeclaredname/undeclared.go b/gopls/internal/lsp/analysis/undeclaredname/undeclared.go --- a/gopls/internal/lsp/analysis/undeclaredname/undeclared.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/undeclaredname/undeclared.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/undeclaredname/undeclared.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,347 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -11900,7 +12038,7 @@ diff -urN a/gopls/internal/lsp/analysis/undeclaredname/undeclared.go b/gopls/int -} diff -urN a/gopls/internal/lsp/analysis/undeclaredname/undeclared_test.go b/gopls/internal/lsp/analysis/undeclaredname/undeclared_test.go --- a/gopls/internal/lsp/analysis/undeclaredname/undeclared_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/undeclaredname/undeclared_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/undeclaredname/undeclared_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -11919,9 +12057,26 @@ diff -urN a/gopls/internal/lsp/analysis/undeclaredname/undeclared_test.go b/gopl - testdata := analysistest.TestData() - analysistest.Run(t, testdata, undeclaredname.Analyzer, "a") -} +diff -urN a/gopls/internal/lsp/analysis/unusedparams/cmd/main.go b/gopls/internal/lsp/analysis/unusedparams/cmd/main.go +--- a/gopls/internal/lsp/analysis/unusedparams/cmd/main.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/analysis/unusedparams/cmd/main.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-// Copyright 2023 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. +- +-// The stringintconv command runs the stringintconv analyzer. +-package main +- +-import ( +- "golang.org/x/tools/go/analysis/singlechecker" +- "golang.org/x/tools/gopls/internal/lsp/analysis/unusedparams" +-) +- +-func main() { singlechecker.Main(unusedparams.Analyzer) } diff -urN a/gopls/internal/lsp/analysis/unusedparams/testdata/src/a/a.go b/gopls/internal/lsp/analysis/unusedparams/testdata/src/a/a.go --- a/gopls/internal/lsp/analysis/unusedparams/testdata/src/a/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/unusedparams/testdata/src/a/a.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/unusedparams/testdata/src/a/a.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -11980,7 +12135,7 @@ diff -urN a/gopls/internal/lsp/analysis/unusedparams/testdata/src/a/a.go b/gopls -} diff -urN a/gopls/internal/lsp/analysis/unusedparams/testdata/src/a/a.go.golden b/gopls/internal/lsp/analysis/unusedparams/testdata/src/a/a.go.golden --- a/gopls/internal/lsp/analysis/unusedparams/testdata/src/a/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/unusedparams/testdata/src/a/a.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/unusedparams/testdata/src/a/a.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -12039,7 +12194,7 @@ diff -urN a/gopls/internal/lsp/analysis/unusedparams/testdata/src/a/a.go.golden -} diff -urN a/gopls/internal/lsp/analysis/unusedparams/testdata/src/typeparams/typeparams.go b/gopls/internal/lsp/analysis/unusedparams/testdata/src/typeparams/typeparams.go --- a/gopls/internal/lsp/analysis/unusedparams/testdata/src/typeparams/typeparams.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/unusedparams/testdata/src/typeparams/typeparams.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/unusedparams/testdata/src/typeparams/typeparams.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -12098,7 +12253,7 @@ diff -urN a/gopls/internal/lsp/analysis/unusedparams/testdata/src/typeparams/typ -} diff -urN a/gopls/internal/lsp/analysis/unusedparams/testdata/src/typeparams/typeparams.go.golden b/gopls/internal/lsp/analysis/unusedparams/testdata/src/typeparams/typeparams.go.golden --- a/gopls/internal/lsp/analysis/unusedparams/testdata/src/typeparams/typeparams.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/unusedparams/testdata/src/typeparams/typeparams.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/unusedparams/testdata/src/typeparams/typeparams.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -12157,8 +12312,8 @@ diff -urN a/gopls/internal/lsp/analysis/unusedparams/testdata/src/typeparams/typ -} diff -urN a/gopls/internal/lsp/analysis/unusedparams/unusedparams.go b/gopls/internal/lsp/analysis/unusedparams/unusedparams.go --- a/gopls/internal/lsp/analysis/unusedparams/unusedparams.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/unusedparams/unusedparams.go 1970-01-01 08:00:00 -@@ -1,152 +0,0 @@ ++++ b/gopls/internal/lsp/analysis/unusedparams/unusedparams.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,166 +0,0 @@ -// Copyright 2020 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. @@ -12189,11 +12344,20 @@ diff -urN a/gopls/internal/lsp/analysis/unusedparams/unusedparams.go b/gopls/int -- functions in test files -- functions with empty bodies or those with just a return stmt` - --var Analyzer = &analysis.Analyzer{ -- Name: "unusedparams", -- Doc: Doc, -- Requires: []*analysis.Analyzer{inspect.Analyzer}, -- Run: run, +-var ( +- Analyzer = &analysis.Analyzer{ +- Name: "unusedparams", +- Doc: Doc, +- Requires: []*analysis.Analyzer{inspect.Analyzer}, +- Run: run, +- } +- inspectLits bool +- inspectWrappers bool +-) +- +-func init() { +- Analyzer.Flags.BoolVar(&inspectLits, "lits", true, "inspect function literals") +- Analyzer.Flags.BoolVar(&inspectWrappers, "wrappers", false, "inspect functions whose body consists of a single return statement") -} - -type paramData struct { @@ -12206,7 +12370,9 @@ diff -urN a/gopls/internal/lsp/analysis/unusedparams/unusedparams.go b/gopls/int - inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - nodeFilter := []ast.Node{ - (*ast.FuncDecl)(nil), -- (*ast.FuncLit)(nil), +- } +- if inspectLits { +- nodeFilter = append(nodeFilter, (*ast.FuncLit)(nil)) - } - - inspect.Preorder(nodeFilter, func(n ast.Node) { @@ -12223,6 +12389,7 @@ diff -urN a/gopls/internal/lsp/analysis/unusedparams/unusedparams.go b/gopls/int - if f.Recv != nil { - return - } +- - // Ignore functions in _test.go files to reduce false positives. - if file := pass.Fset.File(n.Pos()); file != nil && strings.HasSuffix(file.Name(), "_test.go") { - return @@ -12237,8 +12404,10 @@ diff -urN a/gopls/internal/lsp/analysis/unusedparams/unusedparams.go b/gopls/int - - switch expr := body.List[0].(type) { - case *ast.ReturnStmt: -- // Ignore functions that only contain a return statement to reduce false positives. -- return +- if !inspectWrappers { +- // Ignore functions that only contain a return statement to reduce false positives. +- return +- } - case *ast.ExprStmt: - callExpr, ok := expr.X.(*ast.CallExpr) - if !ok || len(body.List) > 1 { @@ -12313,7 +12482,7 @@ diff -urN a/gopls/internal/lsp/analysis/unusedparams/unusedparams.go b/gopls/int -} diff -urN a/gopls/internal/lsp/analysis/unusedparams/unusedparams_test.go b/gopls/internal/lsp/analysis/unusedparams/unusedparams_test.go --- a/gopls/internal/lsp/analysis/unusedparams/unusedparams_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/unusedparams/unusedparams_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/unusedparams/unusedparams_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -12339,7 +12508,7 @@ diff -urN a/gopls/internal/lsp/analysis/unusedparams/unusedparams_test.go b/gopl -} diff -urN a/gopls/internal/lsp/analysis/unusedvariable/testdata/src/assign/a.go b/gopls/internal/lsp/analysis/unusedvariable/testdata/src/assign/a.go --- a/gopls/internal/lsp/analysis/unusedvariable/testdata/src/assign/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/unusedvariable/testdata/src/assign/a.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/unusedvariable/testdata/src/assign/a.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -12417,7 +12586,7 @@ diff -urN a/gopls/internal/lsp/analysis/unusedvariable/testdata/src/assign/a.go -} diff -urN a/gopls/internal/lsp/analysis/unusedvariable/testdata/src/assign/a.go.golden b/gopls/internal/lsp/analysis/unusedvariable/testdata/src/assign/a.go.golden --- a/gopls/internal/lsp/analysis/unusedvariable/testdata/src/assign/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/unusedvariable/testdata/src/assign/a.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/unusedvariable/testdata/src/assign/a.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -12480,7 +12649,7 @@ diff -urN a/gopls/internal/lsp/analysis/unusedvariable/testdata/src/assign/a.go. -} diff -urN a/gopls/internal/lsp/analysis/unusedvariable/testdata/src/decl/a.go b/gopls/internal/lsp/analysis/unusedvariable/testdata/src/decl/a.go --- a/gopls/internal/lsp/analysis/unusedvariable/testdata/src/decl/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/unusedvariable/testdata/src/decl/a.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/unusedvariable/testdata/src/decl/a.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -12514,7 +12683,7 @@ diff -urN a/gopls/internal/lsp/analysis/unusedvariable/testdata/src/decl/a.go b/ -} diff -urN a/gopls/internal/lsp/analysis/unusedvariable/testdata/src/decl/a.go.golden b/gopls/internal/lsp/analysis/unusedvariable/testdata/src/decl/a.go.golden --- a/gopls/internal/lsp/analysis/unusedvariable/testdata/src/decl/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/unusedvariable/testdata/src/decl/a.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/unusedvariable/testdata/src/decl/a.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -12542,7 +12711,7 @@ diff -urN a/gopls/internal/lsp/analysis/unusedvariable/testdata/src/decl/a.go.go -} diff -urN a/gopls/internal/lsp/analysis/unusedvariable/unusedvariable.go b/gopls/internal/lsp/analysis/unusedvariable/unusedvariable.go --- a/gopls/internal/lsp/analysis/unusedvariable/unusedvariable.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/unusedvariable/unusedvariable.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/unusedvariable/unusedvariable.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,300 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -12846,7 +13015,7 @@ diff -urN a/gopls/internal/lsp/analysis/unusedvariable/unusedvariable.go b/gopls -} diff -urN a/gopls/internal/lsp/analysis/unusedvariable/unusedvariable_test.go b/gopls/internal/lsp/analysis/unusedvariable/unusedvariable_test.go --- a/gopls/internal/lsp/analysis/unusedvariable/unusedvariable_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/unusedvariable/unusedvariable_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/unusedvariable/unusedvariable_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -12874,7 +13043,7 @@ diff -urN a/gopls/internal/lsp/analysis/unusedvariable/unusedvariable_test.go b/ -} diff -urN a/gopls/internal/lsp/analysis/useany/testdata/src/a/a.go b/gopls/internal/lsp/analysis/useany/testdata/src/a/a.go --- a/gopls/internal/lsp/analysis/useany/testdata/src/a/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/useany/testdata/src/a/a.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/useany/testdata/src/a/a.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -12903,7 +13072,7 @@ diff -urN a/gopls/internal/lsp/analysis/useany/testdata/src/a/a.go b/gopls/inter -type _[T any] int diff -urN a/gopls/internal/lsp/analysis/useany/testdata/src/a/a.go.golden b/gopls/internal/lsp/analysis/useany/testdata/src/a/a.go.golden --- a/gopls/internal/lsp/analysis/useany/testdata/src/a/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/useany/testdata/src/a/a.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/useany/testdata/src/a/a.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -12932,7 +13101,7 @@ diff -urN a/gopls/internal/lsp/analysis/useany/testdata/src/a/a.go.golden b/gopl -type _[T any] int diff -urN a/gopls/internal/lsp/analysis/useany/useany.go b/gopls/internal/lsp/analysis/useany/useany.go --- a/gopls/internal/lsp/analysis/useany/useany.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/useany/useany.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/useany/useany.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,102 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -13038,7 +13207,7 @@ diff -urN a/gopls/internal/lsp/analysis/useany/useany.go b/gopls/internal/lsp/an -} diff -urN a/gopls/internal/lsp/analysis/useany/useany_test.go b/gopls/internal/lsp/analysis/useany/useany_test.go --- a/gopls/internal/lsp/analysis/useany/useany_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/useany/useany_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/analysis/useany/useany_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -13061,15 +13230,9 @@ diff -urN a/gopls/internal/lsp/analysis/useany/useany_test.go b/gopls/internal/l - testdata := analysistest.TestData() - analysistest.RunWithSuggestedFixes(t, testdata, useany.Analyzer, "a") -} -diff -urN a/gopls/internal/lsp/browser/README.md b/gopls/internal/lsp/browser/README.md ---- a/gopls/internal/lsp/browser/README.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/browser/README.md 1970-01-01 08:00:00 -@@ -1 +0,0 @@ --This package is a copy of cmd/internal/browser from the go distribution -\ No newline at end of file diff -urN a/gopls/internal/lsp/browser/browser.go b/gopls/internal/lsp/browser/browser.go --- a/gopls/internal/lsp/browser/browser.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/browser/browser.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/browser/browser.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -13138,10 +13301,16 @@ diff -urN a/gopls/internal/lsp/browser/browser.go b/gopls/internal/lsp/browser/b - return err == nil - } -} +diff -urN a/gopls/internal/lsp/browser/README.md b/gopls/internal/lsp/browser/README.md +--- a/gopls/internal/lsp/browser/README.md 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/browser/README.md 1970-01-01 00:00:00.000000000 +0000 +@@ -1 +0,0 @@ +-This package is a copy of cmd/internal/browser from the go distribution +\ No newline at end of file diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/analysis.go --- a/gopls/internal/lsp/cache/analysis.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/analysis.go 1970-01-01 08:00:00 -@@ -1,1515 +0,0 @@ ++++ b/gopls/internal/lsp/cache/analysis.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,1553 +0,0 @@ -// 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. @@ -13163,6 +13332,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - "go/types" - "log" - urlpkg "net/url" +- "path/filepath" - "reflect" - "runtime" - "runtime/debug" @@ -13311,9 +13481,6 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal -// The analyzers list must be duplicate free; order does not matter. -// -// Notifications of progress may be sent to the optional reporter. --// --// Precondition: all analyzers within the process have distinct names. --// (The names are relied on by the serialization logic.) -func (snapshot *snapshot) Analyze(ctx context.Context, pkgs map[PackageID]unit, analyzers []*source.Analyzer, reporter *progress.Tracker) ([]*source.Diagnostic, error) { - start := time.Now() // for progress reporting - @@ -13336,7 +13503,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - toSrc := make(map[*analysis.Analyzer]*source.Analyzer) - var enabled []*analysis.Analyzer // enabled subset + transitive requirements - for _, a := range analyzers { -- if a.IsEnabled(snapshot.options) { +- if a.IsEnabled(snapshot.Options()) { - toSrc[a.Analyzer] = a - enabled = append(enabled, a.Analyzer) - } @@ -13346,10 +13513,22 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - }) - analyzers = nil // prevent accidental use - -- // Register fact types of required analyzers. - enabled = requiredAnalyzers(enabled) +- +- // Perform basic sanity checks. +- // (Ideally we would do this only once.) +- if err := analysis.Validate(enabled); err != nil { +- return nil, fmt.Errorf("invalid analyzer configuration: %v", err) +- } +- +- stableNames := make(map[*analysis.Analyzer]string) +- - var facty []*analysis.Analyzer // facty subset of enabled + transitive requirements - for _, a := range enabled { +- // TODO(adonovan): reject duplicate stable names (very unlikely). +- stableNames[a] = stableName(a) +- +- // Register fact types of all required analyzers. - if len(a.FactTypes) > 0 { - facty = append(facty, a) - for _, f := range a.FactTypes { @@ -13383,11 +13562,12 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - // -- preorder -- - - an = &analysisNode{ -- fset: fset, -- m: m, -- analyzers: facty, // all nodes run at least the facty analyzers -- allDeps: make(map[PackagePath]*analysisNode), -- exportDeps: make(map[PackagePath]*analysisNode), +- fset: fset, +- m: m, +- analyzers: facty, // all nodes run at least the facty analyzers +- allDeps: make(map[PackagePath]*analysisNode), +- exportDeps: make(map[PackagePath]*analysisNode), +- stableNames: stableNames, - } - nodes[id] = an - @@ -13453,7 +13633,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - // Now that we have read all files, - // we no longer need the snapshot. - // (but options are needed for progress reporting) -- options := snapshot.options +- options := snapshot.Options() - snapshot = nil - - // Progress reporting. If supported, gopls reports progress on analysis @@ -13575,10 +13755,10 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - if !ok { - // Although this 'skip' operation is logically sound, - // it is nonetheless surprising that its absence should -- // cause #60909 since none of the analyzers added for +- // cause #60909 since none of the analyzers currently added for - // requirements (e.g. ctrlflow, inspect, buildssa) - // is capable of reporting diagnostics. -- if summary := root.summary.Actions[a.Name]; summary != nil { +- if summary := root.summary.Actions[stableNames[a]]; summary != nil { - if n := len(summary.Diagnostics); n > 0 { - bug.Reportf("Internal error: got %d unexpected diagnostics from analyzer %s. This analyzer was added only to fulfil the requirements of the requested set of analyzers, and it is not expected that such analyzers report diagnostics. Please report this in issue #60909.", n, a) - } @@ -13587,10 +13767,10 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - } - - // Inv: root.summary is the successful result of run (via runCached). -- summary, ok := root.summary.Actions[a.Name] +- summary, ok := root.summary.Actions[stableNames[a]] - if summary == nil { - panic(fmt.Sprintf("analyzeSummary.Actions[%q] = (nil, %t); got %v (#60551)", -- a.Name, ok, root.summary.Actions)) +- stableNames[a], ok, root.summary.Actions)) - } - if summary.Err != "" { - continue // action failed @@ -13644,6 +13824,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - allDeps map[PackagePath]*analysisNode // all dependencies including self - exportDeps map[PackagePath]*analysisNode // subset of allDeps ref'd by export data (+self) - summary *analyzeSummary // serializable result of analyzing this package +- stableNames map[*analysis.Analyzer]string // cross-process stable names for Analyzers - - typesOnce sync.Once // guards lazy population of types and typesErr fields - types *types.Package // type information lazily imported from summary @@ -13712,16 +13893,16 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - Export []byte // encoded types of package - DeepExportHash source.Hash // hash of reflexive transitive closure of export data - Compiles bool // transitively free of list/parse/type errors -- Actions actionsMap // map from analyzer name to analysis results (*actionSummary) +- Actions actionMap // maps analyzer stablename to analysis results (*actionSummary) -} - --// actionsMap defines a stable Gob encoding for a map. +-// actionMap defines a stable Gob encoding for a map. -// TODO(adonovan): generalize and move to a library when we can use generics. --type actionsMap map[string]*actionSummary +-type actionMap map[string]*actionSummary - -var ( -- _ gob.GobEncoder = (actionsMap)(nil) -- _ gob.GobDecoder = (*actionsMap)(nil) +- _ gob.GobEncoder = (actionMap)(nil) +- _ gob.GobDecoder = (*actionMap)(nil) -) - -type actionsMapEntry struct { @@ -13729,7 +13910,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - V *actionSummary -} - --func (m actionsMap) GobEncode() ([]byte, error) { +-func (m actionMap) GobEncode() ([]byte, error) { - entries := make([]actionsMapEntry, 0, len(m)) - for k, v := range m { - entries = append(entries, actionsMapEntry{k, v}) @@ -13742,12 +13923,12 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - return buf.Bytes(), err -} - --func (m *actionsMap) GobDecode(data []byte) error { +-func (m *actionMap) GobDecode(data []byte) error { - var entries []actionsMapEntry - if err := gob.NewDecoder(bytes.NewReader(data)).Decode(&entries); err != nil { - return err - } -- *m = make(actionsMap, len(entries)) +- *m = make(actionMap, len(entries)) - for _, e := range entries { - (*m)[e.K] = e.V - } @@ -13993,7 +14174,13 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - for _, req := range a.Requires { - hdeps = append(hdeps, mkAction(req)) - } -- act = &action{a: a, pkg: pkg, vdeps: an.succs, hdeps: hdeps} +- act = &action{ +- a: a, +- stableName: an.stableNames[a], +- pkg: pkg, +- vdeps: an.succs, +- hdeps: hdeps, +- } - actions[a] = act - } - return act @@ -14020,7 +14207,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - if root.summary == nil { - panic("root has nil action.summary (#60551)") - } -- summaries[root.a.Name] = root.summary +- summaries[root.stableName] = root.summary - } - - return &analyzeSummary{ @@ -14239,11 +14426,12 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal -// package (as different analyzers are applied, either in sequence or -// parallel), and across packages (as dependencies are analyzed). -type action struct { -- once sync.Once -- a *analysis.Analyzer -- pkg *analysisPackage -- hdeps []*action // horizontal dependencies -- vdeps map[PackageID]*analysisNode // vertical dependencies +- once sync.Once +- a *analysis.Analyzer +- stableName string // cross-process stable name of analyzer +- pkg *analysisPackage +- hdeps []*action // horizontal dependencies +- vdeps map[PackageID]*analysisNode // vertical dependencies - - // results of action.exec(): - result interface{} // result of Run function, of type a.ResultType @@ -14302,7 +14490,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - if hasFacts { - // TODO(adonovan): use deterministic order. - for _, vdep := range act.vdeps { -- if summ := vdep.summary.Actions[analyzer.Name]; summ.Err != "" { +- if summ := vdep.summary.Actions[act.stableName]; summ.Err != "" { - return nil, nil, errors.New(summ.Err) - } - } @@ -14345,7 +14533,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - // by "deep" export data. Better still, use a "shallow" approach. - - // Read and decode analysis facts for each direct import. -- factset, err := pkg.factsDecoder.Decode(true, func(pkgPath string) ([]byte, error) { +- factset, err := pkg.factsDecoder.Decode(func(pkgPath string) ([]byte, error) { - if !hasFacts { - return nil, nil // analyzer doesn't use facts, so no vdeps - } @@ -14376,7 +14564,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - return nil, bug.Errorf("internal error in %s: missing vdep for id=%s", pkg.types.Path(), id) - } - -- return vdep.summary.Actions[analyzer.Name].Facts, nil +- return vdep.summary.Actions[act.stableName].Facts, nil - }) - if err != nil { - return nil, nil, fmt.Errorf("internal error decoding analysis facts: %w", err) @@ -14487,7 +14675,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - panic(fmt.Sprintf("%v: Pass.ExportPackageFact(%T) called after Run", act, fact)) - } - -- factsdata := factset.Encode(true) +- factsdata := factset.Encode() - return result, &actionSummary{ - Diagnostics: diagnostics, - Facts: factsdata, @@ -14657,9 +14845,28 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - } - return u -} +- +-// stableName returns a name for the analyzer that is unique and +-// stable across address spaces. +-// +-// Analyzer names are not unique. For example, gopls includes +-// both x/tools/passes/nilness and staticcheck/nilness. +-// For serialization, we must assign each analyzer a unique identifier +-// that two gopls processes accessing the cache can agree on. +-func stableName(a *analysis.Analyzer) string { +- // Incorporate the file and line of the analyzer's Run function. +- addr := reflect.ValueOf(a.Run).Pointer() +- fn := runtime.FuncForPC(addr) +- file, line := fn.FileLine(addr) +- +- // It is tempting to use just a.Name as the stable name when +- // it is unique, but making them always differ helps avoid +- // name/stablename confusion. +- return fmt.Sprintf("%s(%s:%d)", a.Name, filepath.Base(file), line) +-} diff -urN a/gopls/internal/lsp/cache/cache.go b/gopls/internal/lsp/cache/cache.go --- a/gopls/internal/lsp/cache/cache.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/cache.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/cache.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -14743,8 +14950,8 @@ diff -urN a/gopls/internal/lsp/cache/cache.go b/gopls/internal/lsp/cache/cache.g -} diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.go --- a/gopls/internal/lsp/cache/check.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/check.go 1970-01-01 08:00:00 -@@ -1,1863 +0,0 @@ ++++ b/gopls/internal/lsp/cache/check.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,1864 +0,0 @@ -// 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. @@ -16089,8 +16296,8 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - depsByImpPath: m.DepsByImpPath, - goVersion: goVersion, - -- relatedInformation: s.options.RelatedInformationSupported, -- linkTarget: s.options.LinkTarget, +- relatedInformation: s.Options().RelatedInformationSupported, +- linkTarget: s.Options().LinkTarget, - moduleMode: s.view.moduleMode(), - }, nil -} @@ -16234,6 +16441,7 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - return pkg, nil -} - +-// TODO(golang/go#63472): this looks wrong with the new Go version syntax. -var goVersionRx = regexp.MustCompile(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`) - -func doTypeCheck(ctx context.Context, b *typeCheckBatch, inputs typeCheckInputs) (*syntaxPackage, error) { @@ -16610,7 +16818,7 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g -func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) } diff -urN a/gopls/internal/lsp/cache/constraints.go b/gopls/internal/lsp/cache/constraints.go --- a/gopls/internal/lsp/cache/constraints.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/constraints.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/constraints.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -16675,7 +16883,7 @@ diff -urN a/gopls/internal/lsp/cache/constraints.go b/gopls/internal/lsp/cache/c -} diff -urN a/gopls/internal/lsp/cache/constraints_test.go b/gopls/internal/lsp/cache/constraints_test.go --- a/gopls/internal/lsp/cache/constraints_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/constraints_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/constraints_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -16775,7 +16983,7 @@ diff -urN a/gopls/internal/lsp/cache/constraints_test.go b/gopls/internal/lsp/ca -} diff -urN a/gopls/internal/lsp/cache/cycle_test.go b/gopls/internal/lsp/cache/cycle_test.go --- a/gopls/internal/lsp/cache/cycle_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/cycle_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/cycle_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,181 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -16960,7 +17168,7 @@ diff -urN a/gopls/internal/lsp/cache/cycle_test.go b/gopls/internal/lsp/cache/cy -} diff -urN a/gopls/internal/lsp/cache/debug.go b/gopls/internal/lsp/cache/debug.go --- a/gopls/internal/lsp/cache/debug.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/debug.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/debug.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -16976,7 +17184,7 @@ diff -urN a/gopls/internal/lsp/cache/debug.go b/gopls/internal/lsp/cache/debug.g -} diff -urN a/gopls/internal/lsp/cache/errors.go b/gopls/internal/lsp/cache/errors.go --- a/gopls/internal/lsp/cache/errors.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/errors.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/errors.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,545 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -17525,7 +17733,7 @@ diff -urN a/gopls/internal/lsp/cache/errors.go b/gopls/internal/lsp/cache/errors -} diff -urN a/gopls/internal/lsp/cache/errors_test.go b/gopls/internal/lsp/cache/errors_test.go --- a/gopls/internal/lsp/cache/errors_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/errors_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/errors_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,130 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -17659,7 +17867,7 @@ diff -urN a/gopls/internal/lsp/cache/errors_test.go b/gopls/internal/lsp/cache/e -} diff -urN a/gopls/internal/lsp/cache/filemap.go b/gopls/internal/lsp/cache/filemap.go --- a/gopls/internal/lsp/cache/filemap.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/filemap.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/filemap.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,151 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -17814,8 +18022,8 @@ diff -urN a/gopls/internal/lsp/cache/filemap.go b/gopls/internal/lsp/cache/filem -} diff -urN a/gopls/internal/lsp/cache/filemap_test.go b/gopls/internal/lsp/cache/filemap_test.go --- a/gopls/internal/lsp/cache/filemap_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/filemap_test.go 1970-01-01 08:00:00 -@@ -1,108 +0,0 @@ ++++ b/gopls/internal/lsp/cache/filemap_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,112 +0,0 @@ -// Copyright 2023 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. @@ -17825,7 +18033,6 @@ diff -urN a/gopls/internal/lsp/cache/filemap_test.go b/gopls/internal/lsp/cache/ -import ( - "path/filepath" - "sort" -- "strings" - "testing" - - "github.com/google/go-cmp/cmp" @@ -17874,7 +18081,12 @@ diff -urN a/gopls/internal/lsp/cache/filemap_test.go b/gopls/internal/lsp/cache/ - - // Normalize paths for windows compatibility. - normalize := func(path string) string { -- return strings.TrimPrefix(filepath.ToSlash(path), "C:") // the span packages adds 'C:' +- y := filepath.ToSlash(path) +- // Windows paths may start with a drive letter +- if len(y) > 2 && y[1] == ':' && y[0] >= 'A' && y[0] <= 'Z' { +- y = y[2:] +- } +- return y - } - - for _, test := range tests { @@ -17926,7 +18138,7 @@ diff -urN a/gopls/internal/lsp/cache/filemap_test.go b/gopls/internal/lsp/cache/ -} diff -urN a/gopls/internal/lsp/cache/fs_memoized.go b/gopls/internal/lsp/cache/fs_memoized.go --- a/gopls/internal/lsp/cache/fs_memoized.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/fs_memoized.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/fs_memoized.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,167 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -18097,7 +18309,7 @@ diff -urN a/gopls/internal/lsp/cache/fs_memoized.go b/gopls/internal/lsp/cache/f -} diff -urN a/gopls/internal/lsp/cache/fs_overlay.go b/gopls/internal/lsp/cache/fs_overlay.go --- a/gopls/internal/lsp/cache/fs_overlay.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/fs_overlay.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/fs_overlay.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -18179,7 +18391,7 @@ diff -urN a/gopls/internal/lsp/cache/fs_overlay.go b/gopls/internal/lsp/cache/fs -func (o *Overlay) Kind() source.FileKind { return o.kind } diff -urN a/gopls/internal/lsp/cache/graph.go b/gopls/internal/lsp/cache/graph.go --- a/gopls/internal/lsp/cache/graph.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/graph.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/graph.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,364 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -18547,7 +18759,7 @@ diff -urN a/gopls/internal/lsp/cache/graph.go b/gopls/internal/lsp/cache/graph.g -} diff -urN a/gopls/internal/lsp/cache/imports.go b/gopls/internal/lsp/cache/imports.go --- a/gopls/internal/lsp/cache/imports.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/imports.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/imports.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,182 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -18605,13 +18817,13 @@ diff -urN a/gopls/internal/lsp/cache/imports.go b/gopls/internal/lsp/cache/impor - - // view.goEnv is immutable -- changes make a new view. Options can change. - // We can't compare build flags directly because we may add -modfile. -- localPrefix := snapshot.options.Local -- currentBuildFlags := snapshot.options.BuildFlags -- currentDirectoryFilters := snapshot.options.DirectoryFilters +- localPrefix := snapshot.Options().Local +- currentBuildFlags := snapshot.Options().BuildFlags +- currentDirectoryFilters := snapshot.Options().DirectoryFilters - changed := !reflect.DeepEqual(currentBuildFlags, s.cachedBuildFlags) || -- snapshot.options.VerboseOutput != (s.processEnv.Logf != nil) || +- snapshot.Options().VerboseOutput != (s.processEnv.Logf != nil) || - modFileHash != s.cachedModFileHash || -- !reflect.DeepEqual(snapshot.options.DirectoryFilters, s.cachedDirectoryFilters) +- !reflect.DeepEqual(snapshot.Options().DirectoryFilters, s.cachedDirectoryFilters) - - // If anything relevant to imports has changed, clear caches and - // update the processEnv. Clearing caches blocks on any background @@ -18669,7 +18881,7 @@ diff -urN a/gopls/internal/lsp/cache/imports.go b/gopls/internal/lsp/cache/impor - ctx, done := event.Start(ctx, "cache.populateProcessEnvFromSnapshot") - defer done() - -- if snapshot.options.VerboseOutput { +- if snapshot.Options().VerboseOutput { - pe.Logf = func(format string, args ...interface{}) { - event.Log(ctx, fmt.Sprintf(format, args...)) - } @@ -18733,7 +18945,7 @@ diff -urN a/gopls/internal/lsp/cache/imports.go b/gopls/internal/lsp/cache/impor -} diff -urN a/gopls/internal/lsp/cache/keys.go b/gopls/internal/lsp/cache/keys.go --- a/gopls/internal/lsp/cache/keys.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/keys.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/keys.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -18789,8 +19001,8 @@ diff -urN a/gopls/internal/lsp/cache/keys.go b/gopls/internal/lsp/cache/keys.go -} diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go --- a/gopls/internal/lsp/cache/load.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/load.go 1970-01-01 08:00:00 -@@ -1,762 +0,0 @@ ++++ b/gopls/internal/lsp/cache/load.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,766 +0,0 @@ -// 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. @@ -18868,7 +19080,7 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - if err != nil { - continue - } -- if isStandaloneFile(contents, s.options.StandaloneTags) { +- if isStandaloneFile(contents, s.Options().StandaloneTags) { - standalone = true - query = append(query, uri.Filename()) - } else { @@ -18953,7 +19165,7 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - } - - moduleErrs := make(map[string][]packages.Error) // module path -> errors -- filterFunc := s.filterFunc() +- filterFunc := s.view.filterFunc() - newMetadata := make(map[PackageID]*source.Metadata) - for _, pkg := range pkgs { - // The Go command returns synthetic list results for module queries that @@ -18971,7 +19183,7 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - continue - } - -- if !containsDir || s.options.VerboseOutput { +- if !containsDir || s.Options().VerboseOutput { - event.Log(ctx, eventName, append( - source.SnapshotLabels(s), - tag.Package.Of(pkg.ID), @@ -19206,6 +19418,10 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - return - } - +- if pkg.TypesSizes == nil { +- panic(id + ".TypeSizes is nil") +- } +- - // Recreate the metadata rather than reusing it to avoid locking. - m := &source.Metadata{ - ID: id, @@ -19409,7 +19625,7 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - uris[uri] = struct{}{} - } - -- filterFunc := s.filterFunc() +- filterFunc := s.view.filterFunc() - for uri := range uris { - // Don't use view.contains here. go.work files may include modules - // outside of the workspace folder. @@ -19420,7 +19636,7 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - return false - } - -- return containsFileInWorkspaceLocked(s, m) +- return containsFileInWorkspaceLocked(s.view, m) -} - -// containsOpenFileLocked reports whether any file referenced by m is open in @@ -19449,7 +19665,7 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go -// workspace of the snapshot s. -// -// s.mu must be held while calling this function. --func containsFileInWorkspaceLocked(s *snapshot, m *source.Metadata) bool { +-func containsFileInWorkspaceLocked(v *View, m *source.Metadata) bool { - uris := map[span.URI]struct{}{} - for _, uri := range m.CompiledGoFiles { - uris[uri] = struct{}{} @@ -19464,7 +19680,7 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - - // The package's files are in this view. It may be a workspace package. - // Vendored packages are not likely to be interesting to the user. -- if !strings.Contains(string(uri), "/vendor/") && s.contains(uri) { +- if !strings.Contains(string(uri), "/vendor/") && v.contains(uri) { - return true - } - } @@ -19555,7 +19771,7 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go -} diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go --- a/gopls/internal/lsp/cache/mod.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/mod.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/mod.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,518 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -20077,7 +20293,7 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go -} diff -urN a/gopls/internal/lsp/cache/mod_tidy.go b/gopls/internal/lsp/cache/mod_tidy.go --- a/gopls/internal/lsp/cache/mod_tidy.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/mod_tidy.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/mod_tidy.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,501 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -20582,7 +20798,7 @@ diff -urN a/gopls/internal/lsp/cache/mod_tidy.go b/gopls/internal/lsp/cache/mod_ -} diff -urN a/gopls/internal/lsp/cache/mod_vuln.go b/gopls/internal/lsp/cache/mod_vuln.go --- a/gopls/internal/lsp/cache/mod_vuln.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/mod_vuln.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/mod_vuln.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -20634,7 +20850,7 @@ diff -urN a/gopls/internal/lsp/cache/mod_vuln.go b/gopls/internal/lsp/cache/mod_ -} diff -urN a/gopls/internal/lsp/cache/os_darwin.go b/gopls/internal/lsp/cache/os_darwin.go --- a/gopls/internal/lsp/cache/os_darwin.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/os_darwin.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/os_darwin.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -20697,7 +20913,7 @@ diff -urN a/gopls/internal/lsp/cache/os_darwin.go b/gopls/internal/lsp/cache/os_ -} diff -urN a/gopls/internal/lsp/cache/os_windows.go b/gopls/internal/lsp/cache/os_windows.go --- a/gopls/internal/lsp/cache/os_windows.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/os_windows.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/os_windows.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -20755,9 +20971,668 @@ diff -urN a/gopls/internal/lsp/cache/os_windows.go b/gopls/internal/lsp/cache/os - } - return nil -} +diff -urN a/gopls/internal/lsp/cache/parse_cache.go b/gopls/internal/lsp/cache/parse_cache.go +--- a/gopls/internal/lsp/cache/parse_cache.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/cache/parse_cache.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,418 +0,0 @@ +-// Copyright 2023 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 ( +- "bytes" +- "container/heap" +- "context" +- "fmt" +- "go/parser" +- "go/token" +- "math/bits" +- "runtime" +- "sync" +- "time" +- +- "golang.org/x/sync/errgroup" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/memoize" +- "golang.org/x/tools/internal/tokeninternal" +-) +- +-// This file contains an implementation of an LRU parse cache, that offsets the +-// base token.Pos value of each cached file so that they may be later described +-// by a single dedicated FileSet. +-// +-// This is achieved by tracking a monotonic offset in the token.Pos space, that +-// is incremented before parsing allow room for the resulting parsed file. +- +-// reservedForParsing defines the room in the token.Pos space reserved for +-// cached parsed files. +-// +-// Files parsed through the parseCache are guaranteed not to have overlapping +-// spans: the parseCache tracks a monotonic base for newly parsed files. +-// +-// By offsetting the initial base of a FileSet, we can allow other operations +-// accepting the FileSet (such as the gcimporter) to add new files using the +-// normal FileSet APIs without overlapping with cached parsed files. +-// +-// Note that 1<<60 represents an exabyte of parsed data, more than any gopls +-// process can ever parse. +-// +-// On 32-bit systems we don't cache parse results (see parseFiles). +-const reservedForParsing = 1 << (bits.UintSize - 4) +- +-// fileSetWithBase returns a new token.FileSet with Base() equal to the +-// requested base. +-// +-// If base < 1, fileSetWithBase panics. +-// (1 is the smallest permitted FileSet base). +-func fileSetWithBase(base int) *token.FileSet { +- fset := token.NewFileSet() +- if base > 1 { +- // Add a dummy file to set the base of fset. We won't ever use the +- // resulting FileSet, so it doesn't matter how we achieve this. +- // +- // FileSets leave a 1-byte padding between files, so we set the base by +- // adding a zero-length file at base-1. +- fset.AddFile("", base-1, 0) +- } +- if fset.Base() != base { +- panic("unexpected FileSet.Base") +- } +- return fset +-} +- +-const ( +- // Always keep 100 recent files, independent of their wall-clock age, to +- // optimize the case where the user resumes editing after a delay. +- parseCacheMinFiles = 100 +-) +- +-// parsePadding is additional padding allocated to allow for increases in +-// length (such as appending missing braces) caused by fixAST. +-// +-// This is used to mitigate a chicken and egg problem: we must know the base +-// offset of the file we're about to parse, before we start parsing, and yet +-// src fixups may affect the actual size of the parsed content (and therefore +-// the offsets of subsequent files). +-// +-// When we encounter a file that no longer fits in its allocated space in the +-// fileset, we have no choice but to re-parse it. Leaving a generous padding +-// reduces the likelihood of this "slow path". +-// +-// This value is mutable for testing, so that we can exercise the slow path. +-var parsePadding = 1000 // mutable for testing +- +-// A parseCache holds recently accessed parsed Go files. After new files are +-// stored, older files may be evicted from the cache via garbage collection. +-// +-// The parseCache.parseFiles method exposes a batch API for parsing (and +-// caching) multiple files. This is necessary for type-checking, where files +-// must be parsed in a common fileset. +-type parseCache struct { +- expireAfter time.Duration // interval at which to collect expired cache entries +- done chan struct{} // closed when GC is stopped +- +- mu sync.Mutex +- m map[parseKey]*parseCacheEntry +- lru queue // min-atime priority queue of *parseCacheEntry +- clock uint64 // clock time, incremented when the cache is updated +- nextBase int // base offset for the next parsed file +-} +- +-// newParseCache creates a new parse cache and starts a goroutine to garbage +-// collect entries whose age is at least expireAfter. +-// +-// Callers must call parseCache.stop when the parse cache is no longer in use. +-func newParseCache(expireAfter time.Duration) *parseCache { +- c := &parseCache{ +- expireAfter: expireAfter, +- m: make(map[parseKey]*parseCacheEntry), +- done: make(chan struct{}), +- } +- go c.gc() +- return c +-} +- +-// stop causes the GC goroutine to exit. +-func (c *parseCache) stop() { +- close(c.done) +-} +- +-// parseKey uniquely identifies a parsed Go file. +-type parseKey struct { +- uri span.URI +- mode parser.Mode +- purgeFuncBodies bool +-} +- +-type parseCacheEntry struct { +- key parseKey +- hash source.Hash +- promise *memoize.Promise // memoize.Promise[*source.ParsedGoFile] +- atime uint64 // clock time of last access, for use in LRU sorting +- walltime time.Time // actual time of last access, for use in time-based eviction; too coarse for LRU on some systems +- lruIndex int // owned by the queue implementation +-} +- +-// startParse prepares a parsing pass, creating new promises in the cache for +-// any cache misses. +-// +-// The resulting slice has an entry for every given file handle, though some +-// entries may be nil if there was an error reading the file (in which case the +-// resulting error will be non-nil). +-func (c *parseCache) startParse(mode parser.Mode, purgeFuncBodies bool, fhs ...source.FileHandle) ([]*memoize.Promise, error) { +- c.mu.Lock() +- defer c.mu.Unlock() +- +- // Any parsing pass increments the clock, as we'll update access times. +- // (technically, if fhs is empty this isn't necessary, but that's a degenerate case). +- // +- // All entries parsed from a single call get the same access time. +- c.clock++ +- walltime := time.Now() +- +- // Read file data and collect cacheable files. +- var ( +- data = make([][]byte, len(fhs)) // file content for each readable file +- promises = make([]*memoize.Promise, len(fhs)) +- firstReadError error // first error from fh.Read, or nil +- ) +- for i, fh := range fhs { +- content, err := fh.Content() +- if err != nil { +- if firstReadError == nil { +- firstReadError = err +- } +- continue +- } +- data[i] = content +- +- key := parseKey{ +- uri: fh.URI(), +- mode: mode, +- purgeFuncBodies: purgeFuncBodies, +- } +- +- if e, ok := c.m[key]; ok { +- if e.hash == fh.FileIdentity().Hash { // cache hit +- e.atime = c.clock +- e.walltime = walltime +- heap.Fix(&c.lru, e.lruIndex) +- promises[i] = e.promise +- continue +- } else { +- // A cache hit, for a different version. Delete it. +- delete(c.m, e.key) +- heap.Remove(&c.lru, e.lruIndex) +- } +- } +- +- uri := fh.URI() +- promise := memoize.NewPromise("parseCache.parse", func(ctx context.Context, _ interface{}) interface{} { +- // Allocate 2*len(content)+parsePadding to allow for re-parsing once +- // inside of parseGoSrc without exceeding the allocated space. +- base, nextBase := c.allocateSpace(2*len(content) + parsePadding) +- +- pgf, fixes1 := ParseGoSrc(ctx, fileSetWithBase(base), uri, content, mode, purgeFuncBodies) +- file := pgf.Tok +- if file.Base()+file.Size()+1 > nextBase { +- // The parsed file exceeds its allocated space, likely due to multiple +- // passes of src fixing. In this case, we have no choice but to re-do +- // the operation with the correct size. +- // +- // Even though the final successful parse requires only file.Size() +- // bytes of Pos space, we need to accommodate all the missteps to get +- // there, as parseGoSrc will repeat them. +- actual := file.Base() + file.Size() - base // actual size consumed, after re-parsing +- base2, nextBase2 := c.allocateSpace(actual) +- pgf2, fixes2 := ParseGoSrc(ctx, fileSetWithBase(base2), uri, content, mode, purgeFuncBodies) +- +- // In golang/go#59097 we observed that this panic condition was hit. +- // One bug was found and fixed, but record more information here in +- // case there is still a bug here. +- if end := pgf2.Tok.Base() + pgf2.Tok.Size(); end != nextBase2-1 { +- var errBuf bytes.Buffer +- fmt.Fprintf(&errBuf, "internal error: non-deterministic parsing result:\n") +- fmt.Fprintf(&errBuf, "\t%q (%d-%d) does not span %d-%d\n", uri, pgf2.Tok.Base(), base2, end, nextBase2-1) +- fmt.Fprintf(&errBuf, "\tfirst %q (%d-%d)\n", pgf.URI, pgf.Tok.Base(), pgf.Tok.Base()+pgf.Tok.Size()) +- fmt.Fprintf(&errBuf, "\tfirst space: (%d-%d), second space: (%d-%d)\n", base, nextBase, base2, nextBase2) +- fmt.Fprintf(&errBuf, "\tfirst mode: %v, second mode: %v", pgf.Mode, pgf2.Mode) +- fmt.Fprintf(&errBuf, "\tfirst err: %v, second err: %v", pgf.ParseErr, pgf2.ParseErr) +- fmt.Fprintf(&errBuf, "\tfirst fixes: %v, second fixes: %v", fixes1, fixes2) +- panic(errBuf.String()) +- } +- pgf = pgf2 +- } +- return pgf +- }) +- promises[i] = promise +- +- // add new entry; entries are gc'ed asynchronously +- e := &parseCacheEntry{ +- key: key, +- hash: fh.FileIdentity().Hash, +- promise: promise, +- atime: c.clock, +- walltime: walltime, +- } +- c.m[e.key] = e +- heap.Push(&c.lru, e) +- } +- +- if len(c.m) != len(c.lru) { +- panic("map and LRU are inconsistent") +- } +- +- return promises, firstReadError +-} +- +-func (c *parseCache) gc() { +- const period = 10 * time.Second // gc period +- timer := time.NewTicker(period) +- defer timer.Stop() +- +- for { +- select { +- case <-c.done: +- return +- case <-timer.C: +- } +- +- c.gcOnce() +- } +-} +- +-func (c *parseCache) gcOnce() { +- now := time.Now() +- c.mu.Lock() +- defer c.mu.Unlock() +- +- for len(c.m) > parseCacheMinFiles { +- e := heap.Pop(&c.lru).(*parseCacheEntry) +- if now.Sub(e.walltime) >= c.expireAfter { +- delete(c.m, e.key) +- } else { +- heap.Push(&c.lru, e) +- break +- } +- } +-} +- +-// allocateSpace reserves the next n bytes of token.Pos space in the +-// cache. +-// +-// It returns the resulting file base, next base, and an offset FileSet to use +-// for parsing. +-func (c *parseCache) allocateSpace(size int) (int, int) { +- c.mu.Lock() +- defer c.mu.Unlock() +- +- if c.nextBase == 0 { +- // FileSet base values must be at least 1. +- c.nextBase = 1 +- } +- base := c.nextBase +- c.nextBase += size + 1 +- return base, c.nextBase +-} +- +-// parseFiles returns a ParsedGoFile for each file handle in fhs, in the +-// requested parse mode. +-// +-// For parsed files that already exists in the cache, access time will be +-// updated. For others, parseFiles will parse and store as many results in the +-// cache as space allows. +-// +-// The token.File for each resulting parsed file will be added to the provided +-// FileSet, using the tokeninternal.AddExistingFiles API. Consequently, the +-// given fset should only be used in other APIs if its base is >= +-// reservedForParsing. +-// +-// If parseFiles returns an error, it still returns a slice, +-// but with a nil entry for each file that could not be parsed. +-func (c *parseCache) parseFiles(ctx context.Context, fset *token.FileSet, mode parser.Mode, purgeFuncBodies bool, fhs ...source.FileHandle) ([]*source.ParsedGoFile, error) { +- pgfs := make([]*source.ParsedGoFile, len(fhs)) +- +- // Temporary fall-back for 32-bit systems, where reservedForParsing is too +- // small to be viable. We don't actually support 32-bit systems, so this +- // workaround is only for tests and can be removed when we stop running +- // 32-bit TryBots for gopls. +- if bits.UintSize == 32 { +- for i, fh := range fhs { +- var err error +- pgfs[i], err = parseGoImpl(ctx, fset, fh, mode, purgeFuncBodies) +- if err != nil { +- return pgfs, err +- } +- } +- return pgfs, nil +- } +- +- promises, firstErr := c.startParse(mode, purgeFuncBodies, fhs...) +- +- // Await all parsing. +- var g errgroup.Group +- g.SetLimit(runtime.GOMAXPROCS(-1)) // parsing is CPU-bound. +- for i, promise := range promises { +- if promise == nil { +- continue +- } +- i := i +- promise := promise +- g.Go(func() error { +- result, err := promise.Get(ctx, nil) +- if err != nil { +- return err +- } +- pgfs[i] = result.(*source.ParsedGoFile) +- return nil +- }) +- } +- +- if err := g.Wait(); err != nil && firstErr == nil { +- firstErr = err +- } +- +- // Augment the FileSet to map all parsed files. +- var tokenFiles []*token.File +- for _, pgf := range pgfs { +- if pgf == nil { +- continue +- } +- tokenFiles = append(tokenFiles, pgf.Tok) +- } +- tokeninternal.AddExistingFiles(fset, tokenFiles) +- +- const debugIssue59080 = true +- if debugIssue59080 { +- for _, f := range tokenFiles { +- pos := token.Pos(f.Base()) +- f2 := fset.File(pos) +- if f2 != f { +- panic(fmt.Sprintf("internal error: File(%d (start)) = %v, not %v", pos, f2, f)) +- } +- pos = token.Pos(f.Base() + f.Size()) +- f2 = fset.File(pos) +- if f2 != f { +- panic(fmt.Sprintf("internal error: File(%d (end)) = %v, not %v", pos, f2, f)) +- } +- } +- } +- +- return pgfs, firstErr +-} +- +-// -- priority queue boilerplate -- +- +-// queue is a min-atime prority queue of cache entries. +-type queue []*parseCacheEntry +- +-func (q queue) Len() int { return len(q) } +- +-func (q queue) Less(i, j int) bool { return q[i].atime < q[j].atime } +- +-func (q queue) Swap(i, j int) { +- q[i], q[j] = q[j], q[i] +- q[i].lruIndex = i +- q[j].lruIndex = j +-} +- +-func (q *queue) Push(x interface{}) { +- e := x.(*parseCacheEntry) +- e.lruIndex = len(*q) +- *q = append(*q, e) +-} +- +-func (q *queue) Pop() interface{} { +- last := len(*q) - 1 +- e := (*q)[last] +- (*q)[last] = nil // aid GC +- *q = (*q)[:last] +- return e +-} +diff -urN a/gopls/internal/lsp/cache/parse_cache_test.go b/gopls/internal/lsp/cache/parse_cache_test.go +--- a/gopls/internal/lsp/cache/parse_cache_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/cache/parse_cache_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,233 +0,0 @@ +-// Copyright 2023 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" +- "fmt" +- "go/token" +- "math/bits" +- "testing" +- "time" +- +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/span" +-) +- +-func skipIfNoParseCache(t *testing.T) { +- if bits.UintSize == 32 { +- t.Skip("the parse cache is not supported on 32-bit systems") +- } +-} +- +-func TestParseCache(t *testing.T) { +- skipIfNoParseCache(t) +- +- ctx := context.Background() +- uri := span.URI("file:///myfile") +- fh := makeFakeFileHandle(uri, []byte("package p\n\nconst _ = \"foo\"")) +- fset := token.NewFileSet() +- +- cache := newParseCache(0) +- pgfs1, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh) +- if err != nil { +- t.Fatal(err) +- } +- pgf1 := pgfs1[0] +- pgfs2, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh) +- pgf2 := pgfs2[0] +- if err != nil { +- t.Fatal(err) +- } +- if pgf1 != pgf2 { +- t.Errorf("parseFiles(%q): unexpected cache miss on repeated call", uri) +- } +- +- // Fill up the cache with other files, but don't evict the file above. +- cache.gcOnce() +- files := []source.FileHandle{fh} +- files = append(files, dummyFileHandles(parseCacheMinFiles-1)...) +- +- pgfs3, err := cache.parseFiles(ctx, fset, source.ParseFull, false, files...) +- if err != nil { +- t.Fatal(err) +- } +- pgf3 := pgfs3[0] +- if pgf3 != pgf1 { +- t.Errorf("parseFiles(%q, ...): unexpected cache miss", uri) +- } +- if pgf3.Tok.Base() != pgf1.Tok.Base() || pgf3.Tok.Size() != pgf1.Tok.Size() { +- t.Errorf("parseFiles(%q, ...): result.Tok has base: %d, size: %d, want (%d, %d)", uri, pgf3.Tok.Base(), pgf3.Tok.Size(), pgf1.Tok.Base(), pgf1.Tok.Size()) +- } +- if tok := fset.File(token.Pos(pgf3.Tok.Base())); tok != pgf3.Tok { +- t.Errorf("parseFiles(%q, ...): result.Tok not contained in FileSet", uri) +- } +- +- // Now overwrite the cache, after which we should get new results. +- cache.gcOnce() +- files = dummyFileHandles(parseCacheMinFiles) +- _, err = cache.parseFiles(ctx, fset, source.ParseFull, false, files...) +- if err != nil { +- t.Fatal(err) +- } +- // force a GC, which should collect the recently parsed files +- cache.gcOnce() +- pgfs4, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh) +- if err != nil { +- t.Fatal(err) +- } +- if pgfs4[0] == pgf1 { +- t.Errorf("parseFiles(%q): unexpected cache hit after overwriting cache", uri) +- } +-} +- +-func TestParseCache_Reparsing(t *testing.T) { +- skipIfNoParseCache(t) +- +- defer func(padding int) { +- parsePadding = padding +- }(parsePadding) +- parsePadding = 0 +- +- files := dummyFileHandles(parseCacheMinFiles) +- danglingSelector := []byte("package p\nfunc _() {\n\tx.\n}") +- files = append(files, makeFakeFileHandle("file:///bad1", danglingSelector)) +- files = append(files, makeFakeFileHandle("file:///bad2", danglingSelector)) +- +- // Parsing should succeed even though we overflow the padding. +- cache := newParseCache(0) +- _, err := cache.parseFiles(context.Background(), token.NewFileSet(), source.ParseFull, false, files...) +- if err != nil { +- t.Fatal(err) +- } +-} +- +-// Re-parsing the first file should not panic. +-func TestParseCache_Issue59097(t *testing.T) { +- skipIfNoParseCache(t) +- +- defer func(padding int) { +- parsePadding = padding +- }(parsePadding) +- parsePadding = 0 +- +- danglingSelector := []byte("package p\nfunc _() {\n\tx.\n}") +- files := []source.FileHandle{makeFakeFileHandle("file:///bad", danglingSelector)} +- +- // Parsing should succeed even though we overflow the padding. +- cache := newParseCache(0) +- _, err := cache.parseFiles(context.Background(), token.NewFileSet(), source.ParseFull, false, files...) +- if err != nil { +- t.Fatal(err) +- } +-} +- +-func TestParseCache_TimeEviction(t *testing.T) { +- skipIfNoParseCache(t) +- +- ctx := context.Background() +- fset := token.NewFileSet() +- uri := span.URI("file:///myfile") +- fh := makeFakeFileHandle(uri, []byte("package p\n\nconst _ = \"foo\"")) +- +- const gcDuration = 10 * time.Millisecond +- cache := newParseCache(gcDuration) +- cache.stop() // we'll manage GC manually, for testing. +- +- pgfs0, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh, fh) +- if err != nil { +- t.Fatal(err) +- } +- +- files := dummyFileHandles(parseCacheMinFiles) +- _, err = cache.parseFiles(ctx, fset, source.ParseFull, false, files...) +- if err != nil { +- t.Fatal(err) +- } +- +- // Even after filling up the 'min' files, we get a cache hit for our original file. +- pgfs1, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh, fh) +- if err != nil { +- t.Fatal(err) +- } +- +- if pgfs0[0] != pgfs1[0] { +- t.Errorf("before GC, got unexpected cache miss") +- } +- +- // But after GC, we get a cache miss. +- _, err = cache.parseFiles(ctx, fset, source.ParseFull, false, files...) // mark dummy files as newer +- if err != nil { +- t.Fatal(err) +- } +- time.Sleep(gcDuration) +- cache.gcOnce() +- +- pgfs2, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh, fh) +- if err != nil { +- t.Fatal(err) +- } +- +- if pgfs0[0] == pgfs2[0] { +- t.Errorf("after GC, got unexpected cache hit for %s", pgfs0[0].URI) +- } +-} +- +-func TestParseCache_Duplicates(t *testing.T) { +- skipIfNoParseCache(t) +- +- ctx := context.Background() +- uri := span.URI("file:///myfile") +- fh := makeFakeFileHandle(uri, []byte("package p\n\nconst _ = \"foo\"")) +- +- cache := newParseCache(0) +- pgfs, err := cache.parseFiles(ctx, token.NewFileSet(), source.ParseFull, false, fh, fh) +- if err != nil { +- t.Fatal(err) +- } +- if pgfs[0] != pgfs[1] { +- t.Errorf("parseFiles(fh, fh): = [%p, %p], want duplicate files", pgfs[0].File, pgfs[1].File) +- } +-} +- +-func dummyFileHandles(n int) []source.FileHandle { +- var fhs []source.FileHandle +- for i := 0; i < n; i++ { +- uri := span.URI(fmt.Sprintf("file:///_%d", i)) +- src := []byte(fmt.Sprintf("package p\nvar _ = %d", i)) +- fhs = append(fhs, makeFakeFileHandle(uri, src)) +- } +- return fhs +-} +- +-func makeFakeFileHandle(uri span.URI, src []byte) fakeFileHandle { +- return fakeFileHandle{ +- uri: uri, +- data: src, +- hash: source.HashOf(src), +- } +-} +- +-type fakeFileHandle struct { +- source.FileHandle +- uri span.URI +- data []byte +- hash source.Hash +-} +- +-func (h fakeFileHandle) URI() span.URI { +- return h.uri +-} +- +-func (h fakeFileHandle) Content() ([]byte, error) { +- return h.data, nil +-} +- +-func (h fakeFileHandle) FileIdentity() source.FileIdentity { +- return source.FileIdentity{ +- URI: h.uri, +- Hash: h.hash, +- } +-} diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.go --- a/gopls/internal/lsp/cache/parse.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/parse.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/parse.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,969 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -21728,668 +22603,9 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g - - return false -} -diff -urN a/gopls/internal/lsp/cache/parse_cache.go b/gopls/internal/lsp/cache/parse_cache.go ---- a/gopls/internal/lsp/cache/parse_cache.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/parse_cache.go 1970-01-01 08:00:00 -@@ -1,418 +0,0 @@ --// Copyright 2023 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 ( -- "bytes" -- "container/heap" -- "context" -- "fmt" -- "go/parser" -- "go/token" -- "math/bits" -- "runtime" -- "sync" -- "time" -- -- "golang.org/x/sync/errgroup" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/memoize" -- "golang.org/x/tools/internal/tokeninternal" --) -- --// This file contains an implementation of an LRU parse cache, that offsets the --// base token.Pos value of each cached file so that they may be later described --// by a single dedicated FileSet. --// --// This is achieved by tracking a monotonic offset in the token.Pos space, that --// is incremented before parsing allow room for the resulting parsed file. -- --// reservedForParsing defines the room in the token.Pos space reserved for --// cached parsed files. --// --// Files parsed through the parseCache are guaranteed not to have overlapping --// spans: the parseCache tracks a monotonic base for newly parsed files. --// --// By offsetting the initial base of a FileSet, we can allow other operations --// accepting the FileSet (such as the gcimporter) to add new files using the --// normal FileSet APIs without overlapping with cached parsed files. --// --// Note that 1<<60 represents an exabyte of parsed data, more than any gopls --// process can ever parse. --// --// On 32-bit systems we don't cache parse results (see parseFiles). --const reservedForParsing = 1 << (bits.UintSize - 4) -- --// fileSetWithBase returns a new token.FileSet with Base() equal to the --// requested base. --// --// If base < 1, fileSetWithBase panics. --// (1 is the smallest permitted FileSet base). --func fileSetWithBase(base int) *token.FileSet { -- fset := token.NewFileSet() -- if base > 1 { -- // Add a dummy file to set the base of fset. We won't ever use the -- // resulting FileSet, so it doesn't matter how we achieve this. -- // -- // FileSets leave a 1-byte padding between files, so we set the base by -- // adding a zero-length file at base-1. -- fset.AddFile("", base-1, 0) -- } -- if fset.Base() != base { -- panic("unexpected FileSet.Base") -- } -- return fset --} -- --const ( -- // Always keep 100 recent files, independent of their wall-clock age, to -- // optimize the case where the user resumes editing after a delay. -- parseCacheMinFiles = 100 --) -- --// parsePadding is additional padding allocated to allow for increases in --// length (such as appending missing braces) caused by fixAST. --// --// This is used to mitigate a chicken and egg problem: we must know the base --// offset of the file we're about to parse, before we start parsing, and yet --// src fixups may affect the actual size of the parsed content (and therefore --// the offsets of subsequent files). --// --// When we encounter a file that no longer fits in its allocated space in the --// fileset, we have no choice but to re-parse it. Leaving a generous padding --// reduces the likelihood of this "slow path". --// --// This value is mutable for testing, so that we can exercise the slow path. --var parsePadding = 1000 // mutable for testing -- --// A parseCache holds recently accessed parsed Go files. After new files are --// stored, older files may be evicted from the cache via garbage collection. --// --// The parseCache.parseFiles method exposes a batch API for parsing (and --// caching) multiple files. This is necessary for type-checking, where files --// must be parsed in a common fileset. --type parseCache struct { -- expireAfter time.Duration // interval at which to collect expired cache entries -- done chan struct{} // closed when GC is stopped -- -- mu sync.Mutex -- m map[parseKey]*parseCacheEntry -- lru queue // min-atime priority queue of *parseCacheEntry -- clock uint64 // clock time, incremented when the cache is updated -- nextBase int // base offset for the next parsed file --} -- --// newParseCache creates a new parse cache and starts a goroutine to garbage --// collect entries whose age is at least expireAfter. --// --// Callers must call parseCache.stop when the parse cache is no longer in use. --func newParseCache(expireAfter time.Duration) *parseCache { -- c := &parseCache{ -- expireAfter: expireAfter, -- m: make(map[parseKey]*parseCacheEntry), -- done: make(chan struct{}), -- } -- go c.gc() -- return c --} -- --// stop causes the GC goroutine to exit. --func (c *parseCache) stop() { -- close(c.done) --} -- --// parseKey uniquely identifies a parsed Go file. --type parseKey struct { -- uri span.URI -- mode parser.Mode -- purgeFuncBodies bool --} -- --type parseCacheEntry struct { -- key parseKey -- hash source.Hash -- promise *memoize.Promise // memoize.Promise[*source.ParsedGoFile] -- atime uint64 // clock time of last access, for use in LRU sorting -- walltime time.Time // actual time of last access, for use in time-based eviction; too coarse for LRU on some systems -- lruIndex int // owned by the queue implementation --} -- --// startParse prepares a parsing pass, creating new promises in the cache for --// any cache misses. --// --// The resulting slice has an entry for every given file handle, though some --// entries may be nil if there was an error reading the file (in which case the --// resulting error will be non-nil). --func (c *parseCache) startParse(mode parser.Mode, purgeFuncBodies bool, fhs ...source.FileHandle) ([]*memoize.Promise, error) { -- c.mu.Lock() -- defer c.mu.Unlock() -- -- // Any parsing pass increments the clock, as we'll update access times. -- // (technically, if fhs is empty this isn't necessary, but that's a degenerate case). -- // -- // All entries parsed from a single call get the same access time. -- c.clock++ -- walltime := time.Now() -- -- // Read file data and collect cacheable files. -- var ( -- data = make([][]byte, len(fhs)) // file content for each readable file -- promises = make([]*memoize.Promise, len(fhs)) -- firstReadError error // first error from fh.Read, or nil -- ) -- for i, fh := range fhs { -- content, err := fh.Content() -- if err != nil { -- if firstReadError == nil { -- firstReadError = err -- } -- continue -- } -- data[i] = content -- -- key := parseKey{ -- uri: fh.URI(), -- mode: mode, -- purgeFuncBodies: purgeFuncBodies, -- } -- -- if e, ok := c.m[key]; ok { -- if e.hash == fh.FileIdentity().Hash { // cache hit -- e.atime = c.clock -- e.walltime = walltime -- heap.Fix(&c.lru, e.lruIndex) -- promises[i] = e.promise -- continue -- } else { -- // A cache hit, for a different version. Delete it. -- delete(c.m, e.key) -- heap.Remove(&c.lru, e.lruIndex) -- } -- } -- -- uri := fh.URI() -- promise := memoize.NewPromise("parseCache.parse", func(ctx context.Context, _ interface{}) interface{} { -- // Allocate 2*len(content)+parsePadding to allow for re-parsing once -- // inside of parseGoSrc without exceeding the allocated space. -- base, nextBase := c.allocateSpace(2*len(content) + parsePadding) -- -- pgf, fixes1 := ParseGoSrc(ctx, fileSetWithBase(base), uri, content, mode, purgeFuncBodies) -- file := pgf.Tok -- if file.Base()+file.Size()+1 > nextBase { -- // The parsed file exceeds its allocated space, likely due to multiple -- // passes of src fixing. In this case, we have no choice but to re-do -- // the operation with the correct size. -- // -- // Even though the final successful parse requires only file.Size() -- // bytes of Pos space, we need to accommodate all the missteps to get -- // there, as parseGoSrc will repeat them. -- actual := file.Base() + file.Size() - base // actual size consumed, after re-parsing -- base2, nextBase2 := c.allocateSpace(actual) -- pgf2, fixes2 := ParseGoSrc(ctx, fileSetWithBase(base2), uri, content, mode, purgeFuncBodies) -- -- // In golang/go#59097 we observed that this panic condition was hit. -- // One bug was found and fixed, but record more information here in -- // case there is still a bug here. -- if end := pgf2.Tok.Base() + pgf2.Tok.Size(); end != nextBase2-1 { -- var errBuf bytes.Buffer -- fmt.Fprintf(&errBuf, "internal error: non-deterministic parsing result:\n") -- fmt.Fprintf(&errBuf, "\t%q (%d-%d) does not span %d-%d\n", uri, pgf2.Tok.Base(), base2, end, nextBase2-1) -- fmt.Fprintf(&errBuf, "\tfirst %q (%d-%d)\n", pgf.URI, pgf.Tok.Base(), pgf.Tok.Base()+pgf.Tok.Size()) -- fmt.Fprintf(&errBuf, "\tfirst space: (%d-%d), second space: (%d-%d)\n", base, nextBase, base2, nextBase2) -- fmt.Fprintf(&errBuf, "\tfirst mode: %v, second mode: %v", pgf.Mode, pgf2.Mode) -- fmt.Fprintf(&errBuf, "\tfirst err: %v, second err: %v", pgf.ParseErr, pgf2.ParseErr) -- fmt.Fprintf(&errBuf, "\tfirst fixes: %v, second fixes: %v", fixes1, fixes2) -- panic(errBuf.String()) -- } -- pgf = pgf2 -- } -- return pgf -- }) -- promises[i] = promise -- -- // add new entry; entries are gc'ed asynchronously -- e := &parseCacheEntry{ -- key: key, -- hash: fh.FileIdentity().Hash, -- promise: promise, -- atime: c.clock, -- walltime: walltime, -- } -- c.m[e.key] = e -- heap.Push(&c.lru, e) -- } -- -- if len(c.m) != len(c.lru) { -- panic("map and LRU are inconsistent") -- } -- -- return promises, firstReadError --} -- --func (c *parseCache) gc() { -- const period = 10 * time.Second // gc period -- timer := time.NewTicker(period) -- defer timer.Stop() -- -- for { -- select { -- case <-c.done: -- return -- case <-timer.C: -- } -- -- c.gcOnce() -- } --} -- --func (c *parseCache) gcOnce() { -- now := time.Now() -- c.mu.Lock() -- defer c.mu.Unlock() -- -- for len(c.m) > parseCacheMinFiles { -- e := heap.Pop(&c.lru).(*parseCacheEntry) -- if now.Sub(e.walltime) >= c.expireAfter { -- delete(c.m, e.key) -- } else { -- heap.Push(&c.lru, e) -- break -- } -- } --} -- --// allocateSpace reserves the next n bytes of token.Pos space in the --// cache. --// --// It returns the resulting file base, next base, and an offset FileSet to use --// for parsing. --func (c *parseCache) allocateSpace(size int) (int, int) { -- c.mu.Lock() -- defer c.mu.Unlock() -- -- if c.nextBase == 0 { -- // FileSet base values must be at least 1. -- c.nextBase = 1 -- } -- base := c.nextBase -- c.nextBase += size + 1 -- return base, c.nextBase --} -- --// parseFiles returns a ParsedGoFile for each file handle in fhs, in the --// requested parse mode. --// --// For parsed files that already exists in the cache, access time will be --// updated. For others, parseFiles will parse and store as many results in the --// cache as space allows. --// --// The token.File for each resulting parsed file will be added to the provided --// FileSet, using the tokeninternal.AddExistingFiles API. Consequently, the --// given fset should only be used in other APIs if its base is >= --// reservedForParsing. --// --// If parseFiles returns an error, it still returns a slice, --// but with a nil entry for each file that could not be parsed. --func (c *parseCache) parseFiles(ctx context.Context, fset *token.FileSet, mode parser.Mode, purgeFuncBodies bool, fhs ...source.FileHandle) ([]*source.ParsedGoFile, error) { -- pgfs := make([]*source.ParsedGoFile, len(fhs)) -- -- // Temporary fall-back for 32-bit systems, where reservedForParsing is too -- // small to be viable. We don't actually support 32-bit systems, so this -- // workaround is only for tests and can be removed when we stop running -- // 32-bit TryBots for gopls. -- if bits.UintSize == 32 { -- for i, fh := range fhs { -- var err error -- pgfs[i], err = parseGoImpl(ctx, fset, fh, mode, purgeFuncBodies) -- if err != nil { -- return pgfs, err -- } -- } -- return pgfs, nil -- } -- -- promises, firstErr := c.startParse(mode, purgeFuncBodies, fhs...) -- -- // Await all parsing. -- var g errgroup.Group -- g.SetLimit(runtime.GOMAXPROCS(-1)) // parsing is CPU-bound. -- for i, promise := range promises { -- if promise == nil { -- continue -- } -- i := i -- promise := promise -- g.Go(func() error { -- result, err := promise.Get(ctx, nil) -- if err != nil { -- return err -- } -- pgfs[i] = result.(*source.ParsedGoFile) -- return nil -- }) -- } -- -- if err := g.Wait(); err != nil && firstErr == nil { -- firstErr = err -- } -- -- // Augment the FileSet to map all parsed files. -- var tokenFiles []*token.File -- for _, pgf := range pgfs { -- if pgf == nil { -- continue -- } -- tokenFiles = append(tokenFiles, pgf.Tok) -- } -- tokeninternal.AddExistingFiles(fset, tokenFiles) -- -- const debugIssue59080 = true -- if debugIssue59080 { -- for _, f := range tokenFiles { -- pos := token.Pos(f.Base()) -- f2 := fset.File(pos) -- if f2 != f { -- panic(fmt.Sprintf("internal error: File(%d (start)) = %v, not %v", pos, f2, f)) -- } -- pos = token.Pos(f.Base() + f.Size()) -- f2 = fset.File(pos) -- if f2 != f { -- panic(fmt.Sprintf("internal error: File(%d (end)) = %v, not %v", pos, f2, f)) -- } -- } -- } -- -- return pgfs, firstErr --} -- --// -- priority queue boilerplate -- -- --// queue is a min-atime prority queue of cache entries. --type queue []*parseCacheEntry -- --func (q queue) Len() int { return len(q) } -- --func (q queue) Less(i, j int) bool { return q[i].atime < q[j].atime } -- --func (q queue) Swap(i, j int) { -- q[i], q[j] = q[j], q[i] -- q[i].lruIndex = i -- q[j].lruIndex = j --} -- --func (q *queue) Push(x interface{}) { -- e := x.(*parseCacheEntry) -- e.lruIndex = len(*q) -- *q = append(*q, e) --} -- --func (q *queue) Pop() interface{} { -- last := len(*q) - 1 -- e := (*q)[last] -- (*q)[last] = nil // aid GC -- *q = (*q)[:last] -- return e --} -diff -urN a/gopls/internal/lsp/cache/parse_cache_test.go b/gopls/internal/lsp/cache/parse_cache_test.go ---- a/gopls/internal/lsp/cache/parse_cache_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/parse_cache_test.go 1970-01-01 08:00:00 -@@ -1,233 +0,0 @@ --// Copyright 2023 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" -- "fmt" -- "go/token" -- "math/bits" -- "testing" -- "time" -- -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/span" --) -- --func skipIfNoParseCache(t *testing.T) { -- if bits.UintSize == 32 { -- t.Skip("the parse cache is not supported on 32-bit systems") -- } --} -- --func TestParseCache(t *testing.T) { -- skipIfNoParseCache(t) -- -- ctx := context.Background() -- uri := span.URI("file:///myfile") -- fh := makeFakeFileHandle(uri, []byte("package p\n\nconst _ = \"foo\"")) -- fset := token.NewFileSet() -- -- cache := newParseCache(0) -- pgfs1, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh) -- if err != nil { -- t.Fatal(err) -- } -- pgf1 := pgfs1[0] -- pgfs2, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh) -- pgf2 := pgfs2[0] -- if err != nil { -- t.Fatal(err) -- } -- if pgf1 != pgf2 { -- t.Errorf("parseFiles(%q): unexpected cache miss on repeated call", uri) -- } -- -- // Fill up the cache with other files, but don't evict the file above. -- cache.gcOnce() -- files := []source.FileHandle{fh} -- files = append(files, dummyFileHandles(parseCacheMinFiles-1)...) -- -- pgfs3, err := cache.parseFiles(ctx, fset, source.ParseFull, false, files...) -- if err != nil { -- t.Fatal(err) -- } -- pgf3 := pgfs3[0] -- if pgf3 != pgf1 { -- t.Errorf("parseFiles(%q, ...): unexpected cache miss", uri) -- } -- if pgf3.Tok.Base() != pgf1.Tok.Base() || pgf3.Tok.Size() != pgf1.Tok.Size() { -- t.Errorf("parseFiles(%q, ...): result.Tok has base: %d, size: %d, want (%d, %d)", uri, pgf3.Tok.Base(), pgf3.Tok.Size(), pgf1.Tok.Base(), pgf1.Tok.Size()) -- } -- if tok := fset.File(token.Pos(pgf3.Tok.Base())); tok != pgf3.Tok { -- t.Errorf("parseFiles(%q, ...): result.Tok not contained in FileSet", uri) -- } -- -- // Now overwrite the cache, after which we should get new results. -- cache.gcOnce() -- files = dummyFileHandles(parseCacheMinFiles) -- _, err = cache.parseFiles(ctx, fset, source.ParseFull, false, files...) -- if err != nil { -- t.Fatal(err) -- } -- // force a GC, which should collect the recently parsed files -- cache.gcOnce() -- pgfs4, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh) -- if err != nil { -- t.Fatal(err) -- } -- if pgfs4[0] == pgf1 { -- t.Errorf("parseFiles(%q): unexpected cache hit after overwriting cache", uri) -- } --} -- --func TestParseCache_Reparsing(t *testing.T) { -- skipIfNoParseCache(t) -- -- defer func(padding int) { -- parsePadding = padding -- }(parsePadding) -- parsePadding = 0 -- -- files := dummyFileHandles(parseCacheMinFiles) -- danglingSelector := []byte("package p\nfunc _() {\n\tx.\n}") -- files = append(files, makeFakeFileHandle("file:///bad1", danglingSelector)) -- files = append(files, makeFakeFileHandle("file:///bad2", danglingSelector)) -- -- // Parsing should succeed even though we overflow the padding. -- cache := newParseCache(0) -- _, err := cache.parseFiles(context.Background(), token.NewFileSet(), source.ParseFull, false, files...) -- if err != nil { -- t.Fatal(err) -- } --} -- --// Re-parsing the first file should not panic. --func TestParseCache_Issue59097(t *testing.T) { -- skipIfNoParseCache(t) -- -- defer func(padding int) { -- parsePadding = padding -- }(parsePadding) -- parsePadding = 0 -- -- danglingSelector := []byte("package p\nfunc _() {\n\tx.\n}") -- files := []source.FileHandle{makeFakeFileHandle("file:///bad", danglingSelector)} -- -- // Parsing should succeed even though we overflow the padding. -- cache := newParseCache(0) -- _, err := cache.parseFiles(context.Background(), token.NewFileSet(), source.ParseFull, false, files...) -- if err != nil { -- t.Fatal(err) -- } --} -- --func TestParseCache_TimeEviction(t *testing.T) { -- skipIfNoParseCache(t) -- -- ctx := context.Background() -- fset := token.NewFileSet() -- uri := span.URI("file:///myfile") -- fh := makeFakeFileHandle(uri, []byte("package p\n\nconst _ = \"foo\"")) -- -- const gcDuration = 10 * time.Millisecond -- cache := newParseCache(gcDuration) -- cache.stop() // we'll manage GC manually, for testing. -- -- pgfs0, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh, fh) -- if err != nil { -- t.Fatal(err) -- } -- -- files := dummyFileHandles(parseCacheMinFiles) -- _, err = cache.parseFiles(ctx, fset, source.ParseFull, false, files...) -- if err != nil { -- t.Fatal(err) -- } -- -- // Even after filling up the 'min' files, we get a cache hit for our original file. -- pgfs1, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh, fh) -- if err != nil { -- t.Fatal(err) -- } -- -- if pgfs0[0] != pgfs1[0] { -- t.Errorf("before GC, got unexpected cache miss") -- } -- -- // But after GC, we get a cache miss. -- _, err = cache.parseFiles(ctx, fset, source.ParseFull, false, files...) // mark dummy files as newer -- if err != nil { -- t.Fatal(err) -- } -- time.Sleep(gcDuration) -- cache.gcOnce() -- -- pgfs2, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh, fh) -- if err != nil { -- t.Fatal(err) -- } -- -- if pgfs0[0] == pgfs2[0] { -- t.Errorf("after GC, got unexpected cache hit for %s", pgfs0[0].URI) -- } --} -- --func TestParseCache_Duplicates(t *testing.T) { -- skipIfNoParseCache(t) -- -- ctx := context.Background() -- uri := span.URI("file:///myfile") -- fh := makeFakeFileHandle(uri, []byte("package p\n\nconst _ = \"foo\"")) -- -- cache := newParseCache(0) -- pgfs, err := cache.parseFiles(ctx, token.NewFileSet(), source.ParseFull, false, fh, fh) -- if err != nil { -- t.Fatal(err) -- } -- if pgfs[0] != pgfs[1] { -- t.Errorf("parseFiles(fh, fh): = [%p, %p], want duplicate files", pgfs[0].File, pgfs[1].File) -- } --} -- --func dummyFileHandles(n int) []source.FileHandle { -- var fhs []source.FileHandle -- for i := 0; i < n; i++ { -- uri := span.URI(fmt.Sprintf("file:///_%d", i)) -- src := []byte(fmt.Sprintf("package p\nvar _ = %d", i)) -- fhs = append(fhs, makeFakeFileHandle(uri, src)) -- } -- return fhs --} -- --func makeFakeFileHandle(uri span.URI, src []byte) fakeFileHandle { -- return fakeFileHandle{ -- uri: uri, -- data: src, -- hash: source.HashOf(src), -- } --} -- --type fakeFileHandle struct { -- source.FileHandle -- uri span.URI -- data []byte -- hash source.Hash --} -- --func (h fakeFileHandle) URI() span.URI { -- return h.uri --} -- --func (h fakeFileHandle) Content() ([]byte, error) { -- return h.data, nil --} -- --func (h fakeFileHandle) FileIdentity() source.FileIdentity { -- return source.FileIdentity{ -- URI: h.uri, -- Hash: h.hash, -- } --} diff -urN a/gopls/internal/lsp/cache/pkg.go b/gopls/internal/lsp/cache/pkg.go --- a/gopls/internal/lsp/cache/pkg.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/pkg.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/pkg.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,177 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -22570,8 +22786,8 @@ diff -urN a/gopls/internal/lsp/cache/pkg.go b/gopls/internal/lsp/cache/pkg.go -} diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/session.go --- a/gopls/internal/lsp/cache/session.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/session.go 1970-01-01 08:00:00 -@@ -1,715 +0,0 @@ ++++ b/gopls/internal/lsp/cache/session.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,704 +0,0 @@ -// 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. @@ -22650,15 +22866,19 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi -// of its gopls workspace module in that directory, so that client tooling -// can execute in the same main module. On success it also returns a release -// function that must be called when the Snapshot is no longer needed. --func (s *Session) NewView(ctx context.Context, name string, folder span.URI, options *source.Options) (*View, source.Snapshot, func(), error) { +-func (s *Session) NewView(ctx context.Context, folder *Folder) (*View, source.Snapshot, func(), error) { - s.viewMu.Lock() - defer s.viewMu.Unlock() - for _, view := range s.views { -- if span.SameExistingFile(view.folder, folder) { +- if span.SameExistingFile(view.folder.Dir, folder.Dir) { - return nil, nil, nil, source.ErrViewExists - } - } -- view, snapshot, release, err := s.createView(ctx, name, folder, options, 0) +- info, err := getWorkspaceInformation(ctx, s.gocmdRunner, s, folder) +- if err != nil { +- return nil, nil, nil, err +- } +- view, snapshot, release, err := s.createView(ctx, info, folder, 0) - if err != nil { - return nil, nil, nil, err - } @@ -22671,15 +22891,9 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi -// TODO(rfindley): clarify that createView can never be cancelled (with the -// possible exception of server shutdown). -// On success, the caller becomes responsible for calling the release function once. --func (s *Session) createView(ctx context.Context, name string, folder span.URI, options *source.Options, seqID uint64) (*View, *snapshot, func(), error) { +-func (s *Session) createView(ctx context.Context, info *workspaceInformation, folder *Folder, seqID uint64) (*View, *snapshot, func(), error) { - index := atomic.AddInt64(&viewIndex, 1) - -- // Get immutable workspace information. -- info, err := s.getWorkspaceInformation(ctx, folder, options) -- if err != nil { -- return nil, nil, nil, err -- } -- - gowork, _ := info.GOWORK() - wsModFiles, wsModFilesErr := computeWorkspaceModFiles(ctx, info.gomod, gowork, info.effectiveGO111MODULE(), s) - @@ -22691,11 +22905,9 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - v := &View{ - id: strconv.FormatInt(index, 10), - gocmdRunner: s.gocmdRunner, -- lastOptions: options, +- folder: folder, - initialWorkspaceLoad: make(chan struct{}), - initializationSema: make(chan struct{}, 1), -- baseCtx: baseCtx, -- name: name, - moduleUpgrades: map[span.URI]map[string]string{}, - vulns: map[span.URI]*vulncheck.Result{}, - parseCache: s.parseCache, @@ -22703,16 +22915,16 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - workspaceInformation: info, - } - v.importsState = &importsState{ -- ctx: backgroundCtx, +- ctx: baseCtx, - processEnv: &imports.ProcessEnv{ - GocmdRunner: s.gocmdRunner, - SkipPathInScan: func(dir string) bool { -- prefix := strings.TrimSuffix(string(v.folder), "/") + "/" +- prefix := strings.TrimSuffix(string(v.folder.Dir), "/") + "/" - uri := strings.TrimSuffix(string(span.URIFromPath(dir)), "/") - if !strings.HasPrefix(uri+"/", prefix) { - return false - } -- filterer := source.NewFilterer(options.DirectoryFilters) +- filterer := source.NewFilterer(folder.Options.DirectoryFilters) - rel := strings.TrimPrefix(uri, prefix) - disallow := filterer.Disallow(rel) - return disallow @@ -22741,7 +22953,6 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - workspaceModFiles: wsModFiles, - workspaceModFilesErr: wsModFilesErr, - pkgIndex: typerefs.NewPackageIndex(), -- options: options, - } - // Save one reference in the view. - v.releaseSnapshot = v.snapshot.Acquire() @@ -22830,15 +23041,9 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - } - // TODO(rfindley): this should consider the workspace layout (i.e. - // go.work). -- snapshot, release, err := view.getSnapshot() -- if err != nil { -- // view is shutdown -- continue -- } -- if snapshot.contains(uri) { +- if view.contains(uri) { - longest = view - } -- release() - } - if longest != nil { - return longest @@ -22871,28 +23076,34 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi -// -// If the resulting error is non-nil, the view may or may not have already been -// dropped from the session. --func (s *Session) updateViewLocked(ctx context.Context, view *View, options *source.Options) error { +-func (s *Session) updateViewLocked(ctx context.Context, view *View, info *workspaceInformation, folder *Folder) (*View, error) { - // Preserve the snapshot ID if we are recreating the view. - view.snapshotMu.Lock() - if view.snapshot == nil { - view.snapshotMu.Unlock() - panic("updateView called after View was already shut down") - } +- // TODO(rfindley): we should probably increment the sequence ID here. - seqID := view.snapshot.sequenceID // Preserve sequence IDs when updating a view in place. - view.snapshotMu.Unlock() - - i := s.dropView(view) - if i == -1 { -- return fmt.Errorf("view %q not found", view.id) +- return nil, fmt.Errorf("view %q not found", view.id) - } - -- v, snapshot, release, err := s.createView(ctx, view.name, view.folder, options, seqID) +- var ( +- snapshot *snapshot +- release func() +- err error +- ) +- view, snapshot, release, err = s.createView(ctx, info, folder, seqID) - if err != nil { - // we have dropped the old view, but could not create the new one - // this should not happen and is very bad, but we still need to clean - // up the view array if it happens - s.views = removeElement(s.views, i) -- return err +- return nil, err - } - defer release() - @@ -22902,13 +23113,13 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - // behavior when configuration is changed mid-session. - // - // Ensure the new snapshot observes all open files. -- for _, o := range v.fs.Overlays() { +- for _, o := range view.fs.Overlays() { - _, _ = snapshot.ReadFile(ctx, o.URI()) - } - - // substitute the new view into the array where the old view was -- s.views[i] = v -- return nil +- s.views[i] = view +- return view, nil -} - -// removeElement removes the ith element from the slice replacing it with the last element. @@ -22946,6 +23157,14 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - return err -} - +-// ResetView resets the best view for the given URI. +-func (s *Session) ResetView(ctx context.Context, uri span.URI) (*View, error) { +- s.viewMu.Lock() +- defer s.viewMu.Unlock() +- v := bestViewForURI(uri, s.views) +- return s.updateViewLocked(ctx, v, v.workspaceInformation, v.folder) +-} +- -// DidModifyFiles reports a file modification to the session. It returns -// the new snapshots after the modifications have been applied, paired with -// the affected file URIs for those snapshots. @@ -22985,7 +23204,6 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - // Change, InvalidateMetadata, and UnknownFileAction actions do not cause - // us to re-evaluate views. - redoViews := (c.Action != source.Change && -- c.Action != source.InvalidateMetadata && - c.Action != source.UnknownFileAction) - - if redoViews { @@ -23001,7 +23219,7 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - // synchronously to change processing? Can we assume that the env did not - // change, and derive go.work using a combination of the configured - // GOWORK value and filesystem? -- info, err := s.getWorkspaceInformation(ctx, view.folder, view.lastOptions) +- info, err := getWorkspaceInformation(ctx, s.gocmdRunner, s, view.folder) - if err != nil { - // Catastrophic failure, equivalent to a failure of session - // initialization and therefore should almost never happen. One @@ -23012,10 +23230,8 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - // TODO(rfindley): consider surfacing this error more loudly. We - // could report a bug, but it's not really a bug. - event.Error(ctx, "fetching workspace information", err) -- } -- -- if info != view.workspaceInformation { -- if err := s.updateViewLocked(ctx, view, view.lastOptions); err != nil { +- } else if *info != *view.workspaceInformation { +- if _, err := s.updateViewLocked(ctx, view, info, view.folder); err != nil { - // More catastrophic failure. The view may or may not still exist. - // The best we can do is log and move on. - event.Error(ctx, "recreating view", err) @@ -23027,13 +23243,7 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - // Collect information about views affected by these changes. - views := make(map[*View]map[span.URI]source.FileHandle) - affectedViews := map[span.URI][]*View{} -- // forceReloadMetadata records whether any change is the magic -- // source.InvalidateMetadata action. -- forceReloadMetadata := false - for _, c := range changes { -- if c.Action == source.InvalidateMetadata { -- forceReloadMetadata = true -- } - // Build the list of affected views. - var changedViews []*View - for _, view := range s.views { @@ -23073,7 +23283,7 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - var releases []func() - viewToSnapshot := map[*View]*snapshot{} - for view, changed := range views { -- snapshot, release := view.invalidateContent(ctx, changed, nil, forceReloadMetadata) +- snapshot, release := view.invalidateContent(ctx, changed) - releases = append(releases, release) - viewToSnapshot[view] = snapshot - } @@ -23160,11 +23370,6 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - defer fs.mu.Unlock() - - for _, c := range changes { -- // Don't update overlays for metadata invalidations. -- if c.Action == source.InvalidateMetadata { -- continue -- } -- - o, ok := fs.overlays[c.URI] - - // If the file is not opened in an overlay and the change is on disk, @@ -23289,8 +23494,8 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi -} diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snapshot.go --- a/gopls/internal/lsp/cache/snapshot.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/snapshot.go 1970-01-01 08:00:00 -@@ -1,2472 +0,0 @@ ++++ b/gopls/internal/lsp/cache/snapshot.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,2464 +0,0 @@ -// 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. @@ -23338,6 +23543,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - "golang.org/x/tools/internal/packagesinternal" - "golang.org/x/tools/internal/persistent" - "golang.org/x/tools/internal/typesinternal" +- "golang.org/x/tools/internal/xcontext" -) - -type snapshot struct { @@ -23468,10 +23674,6 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - // detect ignored files. - ignoreFilterOnce sync.Once - ignoreFilter *ignoreFilter -- -- // options holds the user configuration at the time this snapshot was -- // created. -- options *source.Options -} - -var globalSnapshotID uint64 @@ -23581,7 +23783,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - case ".work": - return source.Work - } -- exts := s.options.TemplateExtensions +- exts := s.Options().TemplateExtensions - for _, ext := range exts { - if fext == ext || fext == "."+ext { - return source.Tmpl @@ -23592,7 +23794,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap -} - -func (s *snapshot) Options() *source.Options { -- return s.options // temporarily return view options. +- return s.view.folder.Options -} - -func (s *snapshot) BackgroundContext() context.Context { @@ -23666,7 +23868,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - return mode - } - mode |= moduleMode -- if s.options.TempModfile { +- if s.Options().TempModfile { - mode |= tempModfile - } - return mode @@ -23701,7 +23903,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - panic("go/packages must not be used to parse files") - }, - Logf: func(format string, args ...interface{}) { -- if s.options.VerboseOutput { +- if s.Options().VerboseOutput { - event.Log(ctx, fmt.Sprintf(format, args...)) - } - }, @@ -23783,16 +23985,16 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap -// it used only after call to tempModFile. Clarify that it is only -// non-nil on success. -func (s *snapshot) goCommandInvocation(ctx context.Context, flags source.InvocationFlags, inv *gocommand.Invocation) (tmpURI span.URI, updatedInv *gocommand.Invocation, cleanup func(), err error) { -- allowModfileModificationOption := s.options.AllowModfileModifications -- allowNetworkOption := s.options.AllowImplicitNetworkAccess +- allowModfileModificationOption := s.Options().AllowModfileModifications +- allowNetworkOption := s.Options().AllowImplicitNetworkAccess - - // TODO(rfindley): this is very hard to follow, and may not even be doing the - // right thing: should inv.Env really trample view.options? Do we ever invoke - // this with a non-empty inv.Env? - // - // We should refactor to make it clearer that the correct env is being used. -- inv.Env = append(append(append(os.Environ(), s.options.EnvSlice()...), inv.Env...), "GO111MODULE="+s.view.GO111MODULE()) -- inv.BuildFlags = append([]string{}, s.options.BuildFlags...) +- inv.Env = append(append(append(os.Environ(), s.Options().EnvSlice()...), inv.Env...), "GO111MODULE="+s.view.GO111MODULE()) +- inv.BuildFlags = append([]string{}, s.Options().BuildFlags...) - cleanup = func() {} // fallback - - // All logic below is for module mode. @@ -23952,7 +24154,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - perFile[diag.URI] = append(perFile[diag.URI], diag) - } - } -- pre := func(i int, ph *packageHandle) bool { +- pre := func(_ int, ph *packageHandle) bool { - data, err := filecache.Get(diagnosticsKind, ph.key) - if err == nil { // hit - collect(ph.m.Diagnostics) @@ -24210,7 +24412,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - - // If GOWORK is outside the folder, ensure we are watching it. - gowork, _ := s.view.GOWORK() -- if gowork != "" && !source.InDir(s.view.folder.Filename(), gowork.Filename()) { +- if gowork != "" && !source.InDir(s.view.folder.Dir.Filename(), gowork.Filename()) { - patterns[gowork.Filename()] = struct{}{} - } - @@ -24219,7 +24421,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - for _, dir := range dirs { - // If the directory is within the view's folder, we're already watching - // it with the first pattern above. -- if source.InDir(s.view.folder.Filename(), dir) { +- if source.InDir(s.view.folder.Dir.Filename(), dir) { - continue - } - // TODO(rstambler): If microsoft/vscode#3025 is resolved before @@ -24276,7 +24478,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - - // Dirs should, at the very least, contain the working directory and folder. - dirSet[s.view.goCommandDir.Filename()] = unit{} -- dirSet[s.view.folder.Filename()] = unit{} +- dirSet[s.view.folder.Dir.Filename()] = unit{} - - // Additionally, if e.g. go.work indicates other workspace modules, we should - // include their directories too. @@ -24299,7 +24501,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap -// Code) that do not send notifications for individual files in a directory -// when the entire directory is deleted. -func (s *snapshot) watchSubdirs() bool { -- switch p := s.options.SubdirWatchPatterns; p { +- switch p := s.Options().SubdirWatchPatterns; p { - case source.SubdirWatchPatternsOn: - return true - case source.SubdirWatchPatternsOff: @@ -24312,7 +24514,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - // requirements that client names do not change. We should update the VS - // Code extension to set a default value of "subdirWatchPatterns" to "on", - // so that this workaround is only temporary. -- if s.options.ClientInfo != nil && s.options.ClientInfo.Name == "Visual Studio Code" { +- if s.Options().ClientInfo != nil && s.Options().ClientInfo.Name == "Visual Studio Code" { - return true - } - return false @@ -24977,7 +25179,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - if goMod, err := nearestModFile(ctx, fh.URI(), s); err == nil && goMod != "" { - if _, ok := loadedModFiles[goMod]; !ok { - modDir := filepath.Dir(goMod.Filename()) -- viewDir := s.view.folder.Filename() +- viewDir := s.view.folder.Dir.Filename() - - // When the module is underneath the view dir, we offer - // "use all modules" quick-fixes. @@ -25110,20 +25312,20 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - return found && strings.Contains(after, "/") -} - --func (s *snapshot) clone(ctx, bgCtx context.Context, changes map[span.URI]source.FileHandle, newOptions *source.Options, forceReloadMetadata bool) (*snapshot, func()) { +-func (s *snapshot) clone(ctx context.Context, changes map[span.URI]source.FileHandle) (*snapshot, func()) { - ctx, done := event.Start(ctx, "cache.snapshot.clone") - defer done() - - s.mu.Lock() - defer s.mu.Unlock() - -- bgCtx, cancel := context.WithCancel(bgCtx) +- backgroundCtx, cancel := context.WithCancel(event.Detach(xcontext.Detach(s.backgroundCtx))) - result := &snapshot{ - sequenceID: s.sequenceID + 1, - globalID: nextSnapshotID(), - store: s.store, - view: s.view, -- backgroundCtx: bgCtx, +- backgroundCtx: backgroundCtx, - cancel: cancel, - builtin: s.builtin, - initialized: s.initialized, @@ -25143,11 +25345,6 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - workspaceModFilesErr: s.workspaceModFilesErr, - importGraph: s.importGraph, - pkgIndex: s.pkgIndex, -- options: s.options, -- } -- -- if newOptions != nil { -- result.options = newOptions - } - - // Create a lease on the new snapshot. @@ -25277,7 +25474,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - result.unloadableFiles.Remove(uri) - } - -- invalidateMetadata = invalidateMetadata || forceReloadMetadata || reinit +- invalidateMetadata = invalidateMetadata || reinit - anyImportDeleted = anyImportDeleted || importDeleted - - // Mark all of the package IDs containing the given file. @@ -25732,7 +25929,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - s.mu.Unlock() - - if builtin == "" { -- return nil, fmt.Errorf("no builtin package for view %s", s.view.name) +- return nil, fmt.Errorf("no builtin package for view %s", s.view.folder.Name) - } - - fh, err := s.ReadFile(ctx, builtin) @@ -25765,7 +25962,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap -} diff -urN a/gopls/internal/lsp/cache/symbols.go b/gopls/internal/lsp/cache/symbols.go --- a/gopls/internal/lsp/cache/symbols.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/symbols.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/symbols.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,192 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -25961,8 +26158,8 @@ diff -urN a/gopls/internal/lsp/cache/symbols.go b/gopls/internal/lsp/cache/symbo -} diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go --- a/gopls/internal/lsp/cache/view.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/view.go 1970-01-01 08:00:00 -@@ -1,1286 +0,0 @@ ++++ b/gopls/internal/lsp/cache/view.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,1234 +0,0 @@ -// Copyright 2018 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. @@ -25979,7 +26176,6 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - "os" - "path" - "path/filepath" -- "reflect" - "regexp" - "sort" - "strings" @@ -25999,28 +26195,31 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - "golang.org/x/tools/internal/xcontext" -) - +-// A Folder represents an LSP workspace folder, together with its per-folder +-// options. +-// +-// Folders (Name and Dir) are specified by the 'initialize' and subsequent +-// 'didChangeWorkspaceFolders' requests; their options come from +-// didChangeConfiguration. +-// +-// Folders must not be mutated, as they may be shared across multiple views. +-type Folder struct { +- Dir span.URI +- Name string +- Options *source.Options +-} +- -type View struct { - id string - - gocmdRunner *gocommand.Runner // limits go command concurrency - -- // baseCtx is the context handed to NewView. This is the parent of all -- // background contexts created for this view. -- baseCtx context.Context -- -- // name is the user-specified name of this view. -- name string -- -- // lastOptions holds the most recent options on this view, used for detecting -- // major changes. -- // -- // Guarded by Session.viewMu. -- lastOptions *source.Options +- folder *Folder - - // Workspace information. The fields below are immutable, and together with - // options define the build list. Any change to these fields results in a new - // View. -- workspaceInformation // Go environment information +- *workspaceInformation // Go environment information - - importsState *importsState - @@ -26081,9 +26280,6 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go -// -// This type is compared to see if the View needs to be reconstructed. -type workspaceInformation struct { -- // folder is the LSP workspace folder. -- folder span.URI -- - // `go env` variables that need to be tracked by gopls. - goEnv - @@ -26372,52 +26568,12 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - -// Name returns the user visible name of this view. -func (v *View) Name() string { -- return v.name +- return v.folder.Name -} - -// Folder returns the folder at the base of this view. -func (v *View) Folder() span.URI { -- return v.folder --} -- --func minorOptionsChange(a, b *source.Options) bool { -- // TODO(rfindley): this function detects whether a view should be recreated, -- // but this is also checked by the getWorkspaceInformation logic. -- // -- // We should eliminate this redundancy. -- // -- // Additionally, this function has existed for a long time, but git history -- // suggests that it was added arbitrarily, not due to an actual performance -- // problem. -- // -- // Especially now that we have optimized reinitialization of the session, we -- // should consider just always creating a new view on any options change. -- -- // Check if any of the settings that modify our understanding of files have -- // been changed. -- if !reflect.DeepEqual(a.Env, b.Env) { -- return false -- } -- if !reflect.DeepEqual(a.DirectoryFilters, b.DirectoryFilters) { -- return false -- } -- if !reflect.DeepEqual(a.StandaloneTags, b.StandaloneTags) { -- return false -- } -- if a.ExpandWorkspaceToModule != b.ExpandWorkspaceToModule { -- return false -- } -- if a.MemoryMode != b.MemoryMode { -- return false -- } -- aBuildFlags := make([]string, len(a.BuildFlags)) -- bBuildFlags := make([]string, len(b.BuildFlags)) -- copy(aBuildFlags, a.BuildFlags) -- copy(bBuildFlags, b.BuildFlags) -- sort.Strings(aBuildFlags) -- sort.Strings(bBuildFlags) -- // the rest of the options are benign -- return reflect.DeepEqual(aBuildFlags, bBuildFlags) +- return v.folder.Dir -} - -// SetFolderOptions updates the options of each View associated with the folder @@ -26430,8 +26586,14 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - defer s.viewMu.Unlock() - - for _, v := range s.views { -- if v.folder == uri { -- if err := s.setViewOptions(ctx, v, options); err != nil { +- if v.folder.Dir == uri { +- folder2 := *v.folder +- folder2.Options = options +- info, err := getWorkspaceInformation(ctx, s.gocmdRunner, s, &folder2) +- if err != nil { +- return err +- } +- if _, err := s.updateViewLocked(ctx, v, info, &folder2); err != nil { - return err - } - } @@ -26439,23 +26601,12 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - return nil -} - --func (s *Session) setViewOptions(ctx context.Context, v *View, options *source.Options) error { -- // no need to rebuild the view if the options were not materially changed -- if minorOptionsChange(v.lastOptions, options) { -- _, release := v.invalidateContent(ctx, nil, options, false) -- release() -- v.lastOptions = options -- return nil -- } -- return s.updateViewLocked(ctx, v, options) --} -- -// viewEnv returns a string describing the environment of a newly created view. -// -// It must not be called concurrently with any other view methods. -func viewEnv(v *View) string { -- env := v.snapshot.options.EnvSlice() -- buildFlags := append([]string{}, v.snapshot.options.BuildFlags...) +- env := v.folder.Options.EnvSlice() +- buildFlags := append([]string{}, v.folder.Options.BuildFlags...) - - var buf bytes.Buffer - fmt.Fprintf(&buf, `go info for %v @@ -26465,7 +26616,7 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go -(build flags: %v) -(selected go env: %v) -`, -- v.folder.Filename(), +- v.folder.Dir.Filename(), - v.goCommandDir.Filename(), - strings.TrimRight(v.workspaceInformation.goversionOutput, "\n"), - v.snapshot.validBuildConfiguration(), @@ -26504,14 +26655,14 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go -// locateTemplateFiles ensures that the snapshot has mapped template files -// within the workspace folder. -func (s *snapshot) locateTemplateFiles(ctx context.Context) { -- if len(s.options.TemplateExtensions) == 0 { +- suffixes := s.Options().TemplateExtensions +- if len(suffixes) == 0 { - return - } -- suffixes := s.options.TemplateExtensions - - searched := 0 -- filterFunc := s.filterFunc() -- err := filepath.WalkDir(s.view.folder.Filename(), func(path string, entry os.DirEntry, err error) error { +- filterFunc := s.view.filterFunc() +- err := filepath.WalkDir(s.view.folder.Dir.Filename(), func(path string, entry os.DirEntry, err error) error { - if err != nil { - return err - } @@ -26544,33 +26695,34 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - } -} - --func (s *snapshot) contains(uri span.URI) bool { +-func (v *View) contains(uri span.URI) bool { - // If we've expanded the go dir to a parent directory, consider if the - // expanded dir contains the uri. - // TODO(rfindley): should we ignore the root here? It is not provided by the - // user. It would be better to explicitly consider the set of active modules - // wherever relevant. - inGoDir := false -- if source.InDir(s.view.goCommandDir.Filename(), s.view.folder.Filename()) { -- inGoDir = source.InDir(s.view.goCommandDir.Filename(), uri.Filename()) +- if source.InDir(v.goCommandDir.Filename(), v.folder.Dir.Filename()) { +- inGoDir = source.InDir(v.goCommandDir.Filename(), uri.Filename()) - } -- inFolder := source.InDir(s.view.folder.Filename(), uri.Filename()) +- inFolder := source.InDir(v.folder.Dir.Filename(), uri.Filename()) - - if !inGoDir && !inFolder { - return false - } - -- return !s.filterFunc()(uri) +- return !v.filterFunc()(uri) -} - -// filterFunc returns a func that reports whether uri is filtered by the currently configured -// directoryFilters. --func (s *snapshot) filterFunc() func(span.URI) bool { -- filterer := buildFilterer(s.view.folder.Filename(), s.view.gomodcache, s.options) +-func (v *View) filterFunc() func(span.URI) bool { +- folderDir := v.folder.Dir.Filename() +- filterer := buildFilterer(folderDir, v.gomodcache, v.folder.Options) - return func(uri span.URI) bool { - // Only filter relative to the configured root directory. -- if source.InDir(s.view.folder.Filename(), uri.Filename()) { -- return pathExcludedByFilter(strings.TrimPrefix(uri.Filename(), s.view.folder.Filename()), filterer) +- if source.InDir(folderDir, uri.Filename()) { +- return pathExcludedByFilter(strings.TrimPrefix(uri.Filename(), folderDir), filterer) - } - return false - } @@ -26597,12 +26749,7 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - // had neither test nor associated issue, and cited only emacs behavior, this - // logic was deleted. - -- snapshot, release, err := v.getSnapshot() -- if err != nil { -- return false // view was shut down -- } -- defer release() -- return snapshot.contains(c.URI) +- return v.contains(c.URI) -} - -func (v *View) markKnown(uri span.URI) { @@ -26882,7 +27029,7 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go -// a callback which the caller must invoke to release that snapshot. -// -// newOptions may be nil, in which case options remain unchanged. --func (v *View) invalidateContent(ctx context.Context, changes map[span.URI]source.FileHandle, newOptions *source.Options, forceReloadMetadata bool) (*snapshot, func()) { +-func (v *View) invalidateContent(ctx context.Context, changes map[span.URI]source.FileHandle) (*snapshot, func()) { - // Detach the context so that content invalidation cannot be canceled. - ctx = xcontext.Detach(ctx) - @@ -26904,7 +27051,7 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - prevSnapshot.AwaitInitialized(ctx) - - // Save one lease of the cloned snapshot in the view. -- v.snapshot, v.releaseSnapshot = prevSnapshot.clone(ctx, v.baseCtx, changes, newOptions, forceReloadMetadata) +- v.snapshot, v.releaseSnapshot = prevSnapshot.clone(ctx, changes) - - prevReleaseSnapshot() - v.destroy(prevSnapshot, "View.invalidateContent") @@ -26913,27 +27060,25 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - return v.snapshot, v.snapshot.Acquire() -} - --func (s *Session) getWorkspaceInformation(ctx context.Context, folder span.URI, options *source.Options) (workspaceInformation, error) { -- if err := checkPathCase(folder.Filename()); err != nil { -- return workspaceInformation{}, fmt.Errorf("invalid workspace folder path: %w; check that the casing of the configured workspace folder path agrees with the casing reported by the operating system", err) +-func getWorkspaceInformation(ctx context.Context, runner *gocommand.Runner, fs source.FileSource, folder *Folder) (*workspaceInformation, error) { +- if err := checkPathCase(folder.Dir.Filename()); err != nil { +- return nil, fmt.Errorf("invalid workspace folder path: %w; check that the casing of the configured workspace folder path agrees with the casing reported by the operating system", err) - } +- info := new(workspaceInformation) - var err error -- info := workspaceInformation{ -- folder: folder, -- } - inv := gocommand.Invocation{ -- WorkingDir: folder.Filename(), -- Env: options.EnvSlice(), +- WorkingDir: folder.Dir.Filename(), +- Env: folder.Options.EnvSlice(), - } -- info.goversion, err = gocommand.GoVersion(ctx, inv, s.gocmdRunner) +- info.goversion, err = gocommand.GoVersion(ctx, inv, runner) - if err != nil { - return info, err - } -- info.goversionOutput, err = gocommand.GoVersionOutput(ctx, inv, s.gocmdRunner) +- info.goversionOutput, err = gocommand.GoVersionOutput(ctx, inv, runner) - if err != nil { - return info, err - } -- if err := info.load(ctx, folder.Filename(), options.EnvSlice(), s.gocmdRunner); err != nil { +- if err := info.load(ctx, folder.Dir.Filename(), folder.Options.EnvSlice(), runner); err != nil { - return info, err - } - // The value of GOPACKAGESDRIVER is not returned through the go command. @@ -26945,15 +27090,15 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - - // filterFunc is the path filter function for this workspace folder. Notably, - // it is relative to folder (which is specified by the user), not root. -- filterFunc := pathExcludedByFilterFunc(folder.Filename(), info.gomodcache, options) -- info.gomod, err = findWorkspaceModFile(ctx, folder, s, filterFunc) +- filterFunc := pathExcludedByFilterFunc(folder.Dir.Filename(), info.gomodcache, folder.Options) +- info.gomod, err = findWorkspaceModFile(ctx, folder.Dir, fs, filterFunc) - if err != nil { - return info, err - } - - // Check if the workspace is within any GOPATH directory. - for _, gp := range filepath.SplitList(info.gopath) { -- if source.InDir(filepath.Join(gp, "src"), folder.Filename()) { +- if source.InDir(filepath.Join(gp, "src"), folder.Dir.Filename()) { - info.inGOPATH = true - break - } @@ -26967,10 +27112,10 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - // - // TODO(golang/go#57514): eliminate the expandWorkspaceToModule setting - // entirely. -- if options.ExpandWorkspaceToModule && info.gomod != "" { +- if folder.Options.ExpandWorkspaceToModule && info.gomod != "" { - info.goCommandDir = span.URIFromPath(filepath.Dir(info.gomod.Filename())) - } else { -- info.goCommandDir = folder +- info.goCommandDir = folder.Dir - } - return info, nil -} @@ -27251,7 +27396,7 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go -} diff -urN a/gopls/internal/lsp/cache/view_test.go b/gopls/internal/lsp/cache/view_test.go --- a/gopls/internal/lsp/cache/view_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/view_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/view_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,303 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -27558,7 +27703,7 @@ diff -urN a/gopls/internal/lsp/cache/view_test.go b/gopls/internal/lsp/cache/vie -} diff -urN a/gopls/internal/lsp/cache/workspace.go b/gopls/internal/lsp/cache/workspace.go --- a/gopls/internal/lsp/cache/workspace.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/workspace.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cache/workspace.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,133 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -27695,7 +27840,7 @@ diff -urN a/gopls/internal/lsp/cache/workspace.go b/gopls/internal/lsp/cache/wor -} diff -urN a/gopls/internal/lsp/call_hierarchy.go b/gopls/internal/lsp/call_hierarchy.go --- a/gopls/internal/lsp/call_hierarchy.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/call_hierarchy.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/call_hierarchy.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -27751,7 +27896,7 @@ diff -urN a/gopls/internal/lsp/call_hierarchy.go b/gopls/internal/lsp/call_hiera -} diff -urN a/gopls/internal/lsp/cmd/call_hierarchy.go b/gopls/internal/lsp/cmd/call_hierarchy.go --- a/gopls/internal/lsp/cmd/call_hierarchy.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/call_hierarchy.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/call_hierarchy.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,144 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -27899,7 +28044,7 @@ diff -urN a/gopls/internal/lsp/cmd/call_hierarchy.go b/gopls/internal/lsp/cmd/ca -} diff -urN a/gopls/internal/lsp/cmd/capabilities_test.go b/gopls/internal/lsp/cmd/capabilities_test.go --- a/gopls/internal/lsp/cmd/capabilities_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/capabilities_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/capabilities_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,176 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -28079,7 +28224,7 @@ diff -urN a/gopls/internal/lsp/cmd/capabilities_test.go b/gopls/internal/lsp/cmd -} diff -urN a/gopls/internal/lsp/cmd/check.go b/gopls/internal/lsp/cmd/check.go --- a/gopls/internal/lsp/cmd/check.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/check.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/check.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -28156,7 +28301,7 @@ diff -urN a/gopls/internal/lsp/cmd/check.go b/gopls/internal/lsp/cmd/check.go -} diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go --- a/gopls/internal/lsp/cmd/cmd.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/cmd.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/cmd.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,801 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -28770,7 +28915,7 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go - } - - if flags.Diff { -- unified, err := diff.ToUnified(filename+".orig", filename, string(mapper.Content), renameEdits) +- unified, err := diff.ToUnified(filename+".orig", filename, string(mapper.Content), renameEdits, diff.DefaultContextLines) - if err != nil { - return err - } @@ -28961,7 +29106,7 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go -} diff -urN a/gopls/internal/lsp/cmd/definition.go b/gopls/internal/lsp/cmd/definition.go --- a/gopls/internal/lsp/cmd/definition.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/definition.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/definition.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,138 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -29103,7 +29248,7 @@ diff -urN a/gopls/internal/lsp/cmd/definition.go b/gopls/internal/lsp/cmd/defini -} diff -urN a/gopls/internal/lsp/cmd/folding_range.go b/gopls/internal/lsp/cmd/folding_range.go --- a/gopls/internal/lsp/cmd/folding_range.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/folding_range.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/folding_range.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -29179,7 +29324,7 @@ diff -urN a/gopls/internal/lsp/cmd/folding_range.go b/gopls/internal/lsp/cmd/fol -} diff -urN a/gopls/internal/lsp/cmd/format.go b/gopls/internal/lsp/cmd/format.go --- a/gopls/internal/lsp/cmd/format.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/format.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/format.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -29259,7 +29404,7 @@ diff -urN a/gopls/internal/lsp/cmd/format.go b/gopls/internal/lsp/cmd/format.go -} diff -urN a/gopls/internal/lsp/cmd/help_test.go b/gopls/internal/lsp/cmd/help_test.go --- a/gopls/internal/lsp/cmd/help_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/help_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/help_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,84 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -29347,7 +29492,7 @@ diff -urN a/gopls/internal/lsp/cmd/help_test.go b/gopls/internal/lsp/cmd/help_te -} diff -urN a/gopls/internal/lsp/cmd/highlight.go b/gopls/internal/lsp/cmd/highlight.go --- a/gopls/internal/lsp/cmd/highlight.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/highlight.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/highlight.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -29433,7 +29578,7 @@ diff -urN a/gopls/internal/lsp/cmd/highlight.go b/gopls/internal/lsp/cmd/highlig -} diff -urN a/gopls/internal/lsp/cmd/implementation.go b/gopls/internal/lsp/cmd/implementation.go --- a/gopls/internal/lsp/cmd/implementation.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/implementation.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/implementation.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -29524,7 +29669,7 @@ diff -urN a/gopls/internal/lsp/cmd/implementation.go b/gopls/internal/lsp/cmd/im -} diff -urN a/gopls/internal/lsp/cmd/imports.go b/gopls/internal/lsp/cmd/imports.go --- a/gopls/internal/lsp/cmd/imports.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/imports.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/imports.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -29609,7 +29754,7 @@ diff -urN a/gopls/internal/lsp/cmd/imports.go b/gopls/internal/lsp/cmd/imports.g -} diff -urN a/gopls/internal/lsp/cmd/info.go b/gopls/internal/lsp/cmd/info.go --- a/gopls/internal/lsp/cmd/info.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/info.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/info.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,311 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -29924,7 +30069,7 @@ diff -urN a/gopls/internal/lsp/cmd/info.go b/gopls/internal/lsp/cmd/info.go -} diff -urN a/gopls/internal/lsp/cmd/links.go b/gopls/internal/lsp/cmd/links.go --- a/gopls/internal/lsp/cmd/links.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/links.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/links.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -30005,7 +30150,7 @@ diff -urN a/gopls/internal/lsp/cmd/links.go b/gopls/internal/lsp/cmd/links.go -} diff -urN a/gopls/internal/lsp/cmd/prepare_rename.go b/gopls/internal/lsp/cmd/prepare_rename.go --- a/gopls/internal/lsp/cmd/prepare_rename.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/prepare_rename.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/prepare_rename.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -30089,7 +30234,7 @@ diff -urN a/gopls/internal/lsp/cmd/prepare_rename.go b/gopls/internal/lsp/cmd/pr -} diff -urN a/gopls/internal/lsp/cmd/references.go b/gopls/internal/lsp/cmd/references.go --- a/gopls/internal/lsp/cmd/references.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/references.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/references.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -30185,7 +30330,7 @@ diff -urN a/gopls/internal/lsp/cmd/references.go b/gopls/internal/lsp/cmd/refere -} diff -urN a/gopls/internal/lsp/cmd/remote.go b/gopls/internal/lsp/cmd/remote.go --- a/gopls/internal/lsp/cmd/remote.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/remote.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/remote.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,164 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -30353,7 +30498,7 @@ diff -urN a/gopls/internal/lsp/cmd/remote.go b/gopls/internal/lsp/cmd/remote.go -} diff -urN a/gopls/internal/lsp/cmd/rename.go b/gopls/internal/lsp/cmd/rename.go --- a/gopls/internal/lsp/cmd/rename.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/rename.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/rename.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -30431,7 +30576,7 @@ diff -urN a/gopls/internal/lsp/cmd/rename.go b/gopls/internal/lsp/cmd/rename.go -} diff -urN a/gopls/internal/lsp/cmd/semantictokens.go b/gopls/internal/lsp/cmd/semantictokens.go --- a/gopls/internal/lsp/cmd/semantictokens.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/semantictokens.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/semantictokens.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,224 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -30659,7 +30804,7 @@ diff -urN a/gopls/internal/lsp/cmd/semantictokens.go b/gopls/internal/lsp/cmd/se -} diff -urN a/gopls/internal/lsp/cmd/serve.go b/gopls/internal/lsp/cmd/serve.go --- a/gopls/internal/lsp/cmd/serve.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/serve.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/serve.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,146 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -30809,7 +30954,7 @@ diff -urN a/gopls/internal/lsp/cmd/serve.go b/gopls/internal/lsp/cmd/serve.go -} diff -urN a/gopls/internal/lsp/cmd/signature.go b/gopls/internal/lsp/cmd/signature.go --- a/gopls/internal/lsp/cmd/signature.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/signature.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/signature.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -30901,8 +31046,8 @@ diff -urN a/gopls/internal/lsp/cmd/signature.go b/gopls/internal/lsp/cmd/signatu -} diff -urN a/gopls/internal/lsp/cmd/stats.go b/gopls/internal/lsp/cmd/stats.go --- a/gopls/internal/lsp/cmd/stats.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/stats.go 1970-01-01 08:00:00 -@@ -1,271 +0,0 @@ ++++ b/gopls/internal/lsp/cmd/stats.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,274 +0,0 @@ -// Copyright 2023 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. @@ -30975,11 +31120,12 @@ diff -urN a/gopls/internal/lsp/cmd/stats.go b/gopls/internal/lsp/cmd/stats.go - } - - stats := GoplsStats{ -- GOOS: runtime.GOOS, -- GOARCH: runtime.GOARCH, -- GOPLSCACHE: os.Getenv("GOPLSCACHE"), -- GoVersion: runtime.Version(), -- GoplsVersion: debug.Version(), +- GOOS: runtime.GOOS, +- GOARCH: runtime.GOARCH, +- GOPLSCACHE: os.Getenv("GOPLSCACHE"), +- GoVersion: runtime.Version(), +- GoplsVersion: debug.Version(), +- GOPACKAGESDRIVER: os.Getenv("GOPACKAGESDRIVER"), - } - - opts := s.app.options @@ -31103,11 +31249,12 @@ diff -urN a/gopls/internal/lsp/cmd/stats.go b/gopls/internal/lsp/cmd/stats.go - if !token.IsExported(f.Name) { - continue - } -- if s.Anon && f.Tag.Get("anon") != "ok" { +- vf := v.FieldByName(f.Name) +- if s.Anon && f.Tag.Get("anon") != "ok" && !vf.IsZero() { - // Fields that can be served with -anon must be explicitly marked as OK. +- // But, if it's zero value, it's ok to print. - continue - } -- vf := v.FieldByName(f.Name) - okFields[f.Name] = vf.Interface() - } - } @@ -31132,6 +31279,7 @@ diff -urN a/gopls/internal/lsp/cmd/stats.go b/gopls/internal/lsp/cmd/stats.go - GOPLSCACHE string - GoVersion string `anon:"ok"` - GoplsVersion string `anon:"ok"` +- GOPACKAGESDRIVER string - InitialWorkspaceLoadDuration string `anon:"ok"` // in time.Duration string form - CacheDir string - BugReports []goplsbug.Bug @@ -31176,7 +31324,7 @@ diff -urN a/gopls/internal/lsp/cmd/stats.go b/gopls/internal/lsp/cmd/stats.go -} diff -urN a/gopls/internal/lsp/cmd/subcommands.go b/gopls/internal/lsp/cmd/subcommands.go --- a/gopls/internal/lsp/cmd/subcommands.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/subcommands.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/subcommands.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -31239,7 +31387,7 @@ diff -urN a/gopls/internal/lsp/cmd/subcommands.go b/gopls/internal/lsp/cmd/subco -} diff -urN a/gopls/internal/lsp/cmd/suggested_fix.go b/gopls/internal/lsp/cmd/suggested_fix.go --- a/gopls/internal/lsp/cmd/suggested_fix.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/suggested_fix.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/suggested_fix.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,193 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -31436,7 +31584,7 @@ diff -urN a/gopls/internal/lsp/cmd/suggested_fix.go b/gopls/internal/lsp/cmd/sug -} diff -urN a/gopls/internal/lsp/cmd/symbols.go b/gopls/internal/lsp/cmd/symbols.go --- a/gopls/internal/lsp/cmd/symbols.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/symbols.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/symbols.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,116 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -31556,8 +31704,8 @@ diff -urN a/gopls/internal/lsp/cmd/symbols.go b/gopls/internal/lsp/cmd/symbols.g -} diff -urN a/gopls/internal/lsp/cmd/test/integration_test.go b/gopls/internal/lsp/cmd/test/integration_test.go --- a/gopls/internal/lsp/cmd/test/integration_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/test/integration_test.go 1970-01-01 08:00:00 -@@ -1,1024 +0,0 @@ ++++ b/gopls/internal/lsp/cmd/test/integration_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,1048 +0,0 @@ -// Copyright 2023 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. @@ -32320,6 +32468,7 @@ diff -urN a/gopls/internal/lsp/cmd/test/integration_test.go b/gopls/internal/lsp - { - res2 := gopls(t, tree, "stats", "-anon") - res2.checkExit(true) +- - var stats2 cmd.GoplsStats - if err := json.Unmarshal([]byte(res2.stdout), &stats2); err != nil { - t.Fatalf("failed to unmarshal JSON output of stats command: %v", err) @@ -32327,6 +32476,29 @@ diff -urN a/gopls/internal/lsp/cmd/test/integration_test.go b/gopls/internal/lsp - if got := len(stats2.BugReports); got > 0 { - t.Errorf("Got %d bug reports with -anon, want 0. Reports:%+v", got, stats2.BugReports) - } +- var stats2AsMap map[string]interface{} +- if err := json.Unmarshal([]byte(res2.stdout), &stats2AsMap); err != nil { +- t.Fatalf("failed to unmarshal JSON output of stats command: %v", err) +- } +- // GOPACKAGESDRIVER is user information, but is ok to print zero value. +- if v, ok := stats2AsMap["GOPACKAGESDRIVER"]; !ok || v != "" { +- t.Errorf(`Got GOPACKAGESDRIVER=(%q, %v); want ("", true(found))`, v, ok) +- } +- } +- +- // Check that -anon suppresses fields containing non-zero user information. +- { +- res3 := goplsWithEnv(t, tree, []string{"GOPACKAGESDRIVER=off"}, "stats", "-anon") +- res3.checkExit(true) +- +- var statsAsMap3 map[string]interface{} +- if err := json.Unmarshal([]byte(res3.stdout), &statsAsMap3); err != nil { +- t.Fatalf("failed to unmarshal JSON output of stats command: %v", err) +- } +- // GOPACKAGESDRIVER is user information, want non-empty value to be omitted. +- if v, ok := statsAsMap3["GOPACKAGESDRIVER"]; ok { +- t.Errorf(`Got GOPACKAGESDRIVER=(%q, %v); want ("", false(not found))`, v, ok) +- } - } -} - @@ -32584,7 +32756,7 @@ diff -urN a/gopls/internal/lsp/cmd/test/integration_test.go b/gopls/internal/lsp -} diff -urN a/gopls/internal/lsp/cmd/usage/api-json.hlp b/gopls/internal/lsp/cmd/usage/api-json.hlp --- a/gopls/internal/lsp/cmd/usage/api-json.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/api-json.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/api-json.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -print json describing gopls API - @@ -32592,7 +32764,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/api-json.hlp b/gopls/internal/lsp/cmd/u - gopls [flags] api-json diff -urN a/gopls/internal/lsp/cmd/usage/bug.hlp b/gopls/internal/lsp/cmd/usage/bug.hlp --- a/gopls/internal/lsp/cmd/usage/bug.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/bug.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/bug.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -report a bug in gopls - @@ -32600,7 +32772,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/bug.hlp b/gopls/internal/lsp/cmd/usage/ - gopls [flags] bug diff -urN a/gopls/internal/lsp/cmd/usage/call_hierarchy.hlp b/gopls/internal/lsp/cmd/usage/call_hierarchy.hlp --- a/gopls/internal/lsp/cmd/usage/call_hierarchy.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/call_hierarchy.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/call_hierarchy.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -display selected identifier's call hierarchy - @@ -32614,7 +32786,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/call_hierarchy.hlp b/gopls/internal/lsp - $ gopls call_hierarchy helper/helper.go:#53 diff -urN a/gopls/internal/lsp/cmd/usage/check.hlp b/gopls/internal/lsp/cmd/usage/check.hlp --- a/gopls/internal/lsp/cmd/usage/check.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/check.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/check.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -show diagnostic results for the specified file - @@ -32626,7 +32798,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/check.hlp b/gopls/internal/lsp/cmd/usag - $ gopls check internal/lsp/cmd/check.go diff -urN a/gopls/internal/lsp/cmd/usage/definition.hlp b/gopls/internal/lsp/cmd/usage/definition.hlp --- a/gopls/internal/lsp/cmd/usage/definition.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/definition.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/definition.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -show declaration of selected identifier - @@ -32645,7 +32817,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/definition.hlp b/gopls/internal/lsp/cmd - support markdown in responses diff -urN a/gopls/internal/lsp/cmd/usage/fix.hlp b/gopls/internal/lsp/cmd/usage/fix.hlp --- a/gopls/internal/lsp/cmd/usage/fix.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/fix.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/fix.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -apply suggested fixes - @@ -32693,7 +32865,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/fix.hlp b/gopls/internal/lsp/cmd/usage/ - write edited content to source files diff -urN a/gopls/internal/lsp/cmd/usage/folding_ranges.hlp b/gopls/internal/lsp/cmd/usage/folding_ranges.hlp --- a/gopls/internal/lsp/cmd/usage/folding_ranges.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/folding_ranges.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/folding_ranges.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -display selected file's folding ranges - @@ -32705,7 +32877,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/folding_ranges.hlp b/gopls/internal/lsp - $ gopls folding_ranges helper/helper.go diff -urN a/gopls/internal/lsp/cmd/usage/format.hlp b/gopls/internal/lsp/cmd/usage/format.hlp --- a/gopls/internal/lsp/cmd/usage/format.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/format.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/format.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -format the code according to the go standard - @@ -32729,7 +32901,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/format.hlp b/gopls/internal/lsp/cmd/usa - write edited content to source files diff -urN a/gopls/internal/lsp/cmd/usage/help.hlp b/gopls/internal/lsp/cmd/usage/help.hlp --- a/gopls/internal/lsp/cmd/usage/help.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/help.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/help.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -print usage information for subcommands - @@ -32743,7 +32915,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/help.hlp b/gopls/internal/lsp/cmd/usage -$ gopls help remote sessions # help on 'remote sessions' subcommand diff -urN a/gopls/internal/lsp/cmd/usage/highlight.hlp b/gopls/internal/lsp/cmd/usage/highlight.hlp --- a/gopls/internal/lsp/cmd/usage/highlight.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/highlight.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/highlight.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -display selected identifier's highlights - @@ -32757,7 +32929,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/highlight.hlp b/gopls/internal/lsp/cmd/ - $ gopls highlight helper/helper.go:#53 diff -urN a/gopls/internal/lsp/cmd/usage/implementation.hlp b/gopls/internal/lsp/cmd/usage/implementation.hlp --- a/gopls/internal/lsp/cmd/usage/implementation.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/implementation.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/implementation.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -display selected identifier's implementation - @@ -32771,7 +32943,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/implementation.hlp b/gopls/internal/lsp - $ gopls implementation helper/helper.go:#53 diff -urN a/gopls/internal/lsp/cmd/usage/imports.hlp b/gopls/internal/lsp/cmd/usage/imports.hlp --- a/gopls/internal/lsp/cmd/usage/imports.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/imports.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/imports.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -updates import statements - @@ -32793,7 +32965,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/imports.hlp b/gopls/internal/lsp/cmd/us - write edited content to source files diff -urN a/gopls/internal/lsp/cmd/usage/inspect.hlp b/gopls/internal/lsp/cmd/usage/inspect.hlp --- a/gopls/internal/lsp/cmd/usage/inspect.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/inspect.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/inspect.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -interact with the gopls daemon (deprecated: use 'remote') - @@ -32805,7 +32977,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/inspect.hlp b/gopls/internal/lsp/cmd/us - debug start the debug server diff -urN a/gopls/internal/lsp/cmd/usage/licenses.hlp b/gopls/internal/lsp/cmd/usage/licenses.hlp --- a/gopls/internal/lsp/cmd/usage/licenses.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/licenses.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/licenses.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -print licenses of included software - @@ -32813,7 +32985,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/licenses.hlp b/gopls/internal/lsp/cmd/u - gopls [flags] licenses diff -urN a/gopls/internal/lsp/cmd/usage/links.hlp b/gopls/internal/lsp/cmd/usage/links.hlp --- a/gopls/internal/lsp/cmd/usage/links.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/links.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/links.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -list links in a file - @@ -32829,7 +33001,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/links.hlp b/gopls/internal/lsp/cmd/usag - emit document links in JSON format diff -urN a/gopls/internal/lsp/cmd/usage/prepare_rename.hlp b/gopls/internal/lsp/cmd/usage/prepare_rename.hlp --- a/gopls/internal/lsp/cmd/usage/prepare_rename.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/prepare_rename.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/prepare_rename.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -test validity of a rename operation at location - @@ -32843,7 +33015,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/prepare_rename.hlp b/gopls/internal/lsp - $ gopls prepare_rename helper/helper.go:#53 diff -urN a/gopls/internal/lsp/cmd/usage/references.hlp b/gopls/internal/lsp/cmd/usage/references.hlp --- a/gopls/internal/lsp/cmd/usage/references.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/references.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/references.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -display selected identifier's references - @@ -32861,7 +33033,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/references.hlp b/gopls/internal/lsp/cmd - include the declaration of the specified identifier in the results diff -urN a/gopls/internal/lsp/cmd/usage/remote.hlp b/gopls/internal/lsp/cmd/usage/remote.hlp --- a/gopls/internal/lsp/cmd/usage/remote.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/remote.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/remote.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -interact with the gopls daemon - @@ -32873,7 +33045,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/remote.hlp b/gopls/internal/lsp/cmd/usa - debug start the debug server diff -urN a/gopls/internal/lsp/cmd/usage/rename.hlp b/gopls/internal/lsp/cmd/usage/rename.hlp --- a/gopls/internal/lsp/cmd/usage/rename.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/rename.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/rename.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -rename selected identifier - @@ -32897,7 +33069,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/rename.hlp b/gopls/internal/lsp/cmd/usa - write edited content to source files diff -urN a/gopls/internal/lsp/cmd/usage/semtok.hlp b/gopls/internal/lsp/cmd/usage/semtok.hlp --- a/gopls/internal/lsp/cmd/usage/semtok.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/semtok.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/semtok.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -show semantic tokens for the specified file - @@ -32909,7 +33081,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/semtok.hlp b/gopls/internal/lsp/cmd/usa - $ gopls semtok internal/lsp/cmd/semtok.go diff -urN a/gopls/internal/lsp/cmd/usage/serve.hlp b/gopls/internal/lsp/cmd/usage/serve.hlp --- a/gopls/internal/lsp/cmd/usage/serve.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/serve.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/serve.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -run a server for Go code using the Language Server Protocol - @@ -32943,7 +33115,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/serve.hlp b/gopls/internal/lsp/cmd/usag - print the full rpc trace in lsp inspector format diff -urN a/gopls/internal/lsp/cmd/usage/signature.hlp b/gopls/internal/lsp/cmd/usage/signature.hlp --- a/gopls/internal/lsp/cmd/usage/signature.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/signature.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/signature.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -display selected identifier's signature - @@ -32957,7 +33129,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/signature.hlp b/gopls/internal/lsp/cmd/ - $ gopls signature helper/helper.go:#53 diff -urN a/gopls/internal/lsp/cmd/usage/stats.hlp b/gopls/internal/lsp/cmd/usage/stats.hlp --- a/gopls/internal/lsp/cmd/usage/stats.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/stats.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/stats.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -print workspace statistics - @@ -32978,7 +33150,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/stats.hlp b/gopls/internal/lsp/cmd/usag - hide any fields that may contain user names, file names, or source code diff -urN a/gopls/internal/lsp/cmd/usage/symbols.hlp b/gopls/internal/lsp/cmd/usage/symbols.hlp --- a/gopls/internal/lsp/cmd/usage/symbols.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/symbols.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/symbols.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -display selected file's symbols - @@ -32987,10 +33159,10 @@ diff -urN a/gopls/internal/lsp/cmd/usage/symbols.hlp b/gopls/internal/lsp/cmd/us - -Example: - $ gopls symbols helper/helper.go -diff -urN a/gopls/internal/lsp/cmd/usage/usage-v.hlp b/gopls/internal/lsp/cmd/usage/usage-v.hlp ---- a/gopls/internal/lsp/cmd/usage/usage-v.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/usage-v.hlp 1970-01-01 08:00:00 -@@ -1,82 +0,0 @@ +diff -urN a/gopls/internal/lsp/cmd/usage/usage.hlp b/gopls/internal/lsp/cmd/usage/usage.hlp +--- a/gopls/internal/lsp/cmd/usage/usage.hlp 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/cmd/usage/usage.hlp 1970-01-01 00:00:00.000000000 +0000 +@@ -1,79 +0,0 @@ - -gopls is a Go language server. - @@ -33032,9 +33204,6 @@ diff -urN a/gopls/internal/lsp/cmd/usage/usage-v.hlp b/gopls/internal/lsp/cmd/us - fix apply suggested fixes - symbols display selected file's symbols - workspace_symbol search symbols in workspace -- --Internal Use Only -- vulncheck run vulncheck analysis (internal-use only) - -flags: - -debug=string @@ -33073,10 +33242,10 @@ diff -urN a/gopls/internal/lsp/cmd/usage/usage-v.hlp b/gopls/internal/lsp/cmd/us - verbose output - -vv,-veryverbose - very verbose output -diff -urN a/gopls/internal/lsp/cmd/usage/usage.hlp b/gopls/internal/lsp/cmd/usage/usage.hlp ---- a/gopls/internal/lsp/cmd/usage/usage.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/usage.hlp 1970-01-01 08:00:00 -@@ -1,79 +0,0 @@ +diff -urN a/gopls/internal/lsp/cmd/usage/usage-v.hlp b/gopls/internal/lsp/cmd/usage/usage-v.hlp +--- a/gopls/internal/lsp/cmd/usage/usage-v.hlp 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/cmd/usage/usage-v.hlp 1970-01-01 00:00:00.000000000 +0000 +@@ -1,82 +0,0 @@ - -gopls is a Go language server. - @@ -33118,6 +33287,9 @@ diff -urN a/gopls/internal/lsp/cmd/usage/usage.hlp b/gopls/internal/lsp/cmd/usag - fix apply suggested fixes - symbols display selected file's symbols - workspace_symbol search symbols in workspace +- +-Internal Use Only +- vulncheck run vulncheck analysis (internal-use only) - -flags: - -debug=string @@ -33158,7 +33330,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/usage.hlp b/gopls/internal/lsp/cmd/usag - very verbose output diff -urN a/gopls/internal/lsp/cmd/usage/version.hlp b/gopls/internal/lsp/cmd/usage/version.hlp --- a/gopls/internal/lsp/cmd/usage/version.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/version.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/version.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -print the gopls version information - @@ -33168,7 +33340,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/version.hlp b/gopls/internal/lsp/cmd/us - outputs in json format. diff -urN a/gopls/internal/lsp/cmd/usage/vulncheck.hlp b/gopls/internal/lsp/cmd/usage/vulncheck.hlp --- a/gopls/internal/lsp/cmd/usage/vulncheck.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/vulncheck.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/vulncheck.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -run vulncheck analysis (internal-use only) - @@ -33185,7 +33357,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/vulncheck.hlp b/gopls/internal/lsp/cmd/ - diff -urN a/gopls/internal/lsp/cmd/usage/workspace_symbol.hlp b/gopls/internal/lsp/cmd/usage/workspace_symbol.hlp --- a/gopls/internal/lsp/cmd/usage/workspace_symbol.hlp 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/usage/workspace_symbol.hlp 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/usage/workspace_symbol.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -search symbols in workspace - @@ -33202,7 +33374,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/workspace_symbol.hlp b/gopls/internal/l - The default is caseinsensitive. diff -urN a/gopls/internal/lsp/cmd/vulncheck.go b/gopls/internal/lsp/cmd/vulncheck.go --- a/gopls/internal/lsp/cmd/vulncheck.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/vulncheck.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/vulncheck.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -33253,7 +33425,7 @@ diff -urN a/gopls/internal/lsp/cmd/vulncheck.go b/gopls/internal/lsp/cmd/vulnche -} diff -urN a/gopls/internal/lsp/cmd/workspace_symbol.go b/gopls/internal/lsp/cmd/workspace_symbol.go --- a/gopls/internal/lsp/cmd/workspace_symbol.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/workspace_symbol.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/cmd/workspace_symbol.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -33346,8 +33518,8 @@ diff -urN a/gopls/internal/lsp/cmd/workspace_symbol.go b/gopls/internal/lsp/cmd/ -} diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.go --- a/gopls/internal/lsp/code_action.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/code_action.go 1970-01-01 08:00:00 -@@ -1,655 +0,0 @@ ++++ b/gopls/internal/lsp/code_action.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,715 +0,0 @@ -// Copyright 2018 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. @@ -33780,6 +33952,26 @@ diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.g - rerr = bug.Errorf("refactor.rewrite code actions panicked: %v", r) - } - }() +- +- var actions []protocol.CodeAction +- +- if canRemoveParameter(pkg, pgf, rng) { +- cmd, err := command.NewChangeSignatureCommand("remove unused parameter", command.ChangeSignatureArgs{ +- RemoveParameter: protocol.Location{ +- URI: protocol.URIFromSpanURI(pgf.URI), +- Range: rng, +- }, +- }) +- if err != nil { +- return nil, err +- } +- actions = append(actions, protocol.CodeAction{ +- Title: "Refactor: remove unused parameter", +- Kind: protocol.RefactorRewrite, +- Command: &cmd, +- }) +- } +- - start, end, err := pgf.RangePos(rng) - if err != nil { - return nil, err @@ -33821,7 +34013,6 @@ diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.g - } - } - -- var actions []protocol.CodeAction - for i := range commands { - actions = append(actions, protocol.CodeAction{ - Title: commands[i].Title, @@ -33860,6 +34051,47 @@ diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.g - return actions, nil -} - +-// canRemoveParameter reports whether we can remove the function parameter +-// indicated by the given [start, end) range. +-// +-// This is true if: +-// - [start, end) is contained within an unused field or parameter name +-// - ... of a non-method function declaration. +-func canRemoveParameter(pkg source.Package, pgf *source.ParsedGoFile, rng protocol.Range) bool { +- info := source.FindParam(pgf, rng) +- if info.Decl == nil || info.Field == nil { +- return false +- } +- +- if info.Decl.Body == nil { +- return false // external function +- } +- +- if len(info.Field.Names) == 0 { +- return true // no names => field is unused +- } +- if info.Name == nil { +- return false // no name is indicated +- } +- if info.Name.Name == "_" { +- return true // trivially unused +- } +- +- obj := pkg.GetTypesInfo().Defs[info.Name] +- if obj == nil { +- return false // something went wrong +- } +- +- used := false +- ast.Inspect(info.Decl.Body, func(node ast.Node) bool { +- if n, ok := node.(*ast.Ident); ok && pkg.GetTypesInfo().Uses[n] == obj { +- used = true +- } +- return !used // keep going until we find a use +- }) +- return !used +-} +- -// refactorInline returns inline actions available at the specified range. -func refactorInline(ctx context.Context, snapshot source.Snapshot, pkg source.Package, pgf *source.ParsedGoFile, fh source.FileHandle, rng protocol.Range) ([]protocol.CodeAction, error) { - var commands []protocol.Command @@ -33968,7 +34200,7 @@ diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.g -} - -func goTest(ctx context.Context, snapshot source.Snapshot, pkg source.Package, pgf *source.ParsedGoFile, rng protocol.Range) ([]protocol.CodeAction, error) { -- fns, err := source.TestsAndBenchmarks(ctx, snapshot, pkg, pgf) +- fns, err := source.TestsAndBenchmarks(pkg, pgf) - if err != nil { - return nil, err - } @@ -34005,7 +34237,7 @@ diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.g -type unit = struct{} diff -urN a/gopls/internal/lsp/code_lens.go b/gopls/internal/lsp/code_lens.go --- a/gopls/internal/lsp/code_lens.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/code_lens.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/code_lens.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -34070,8 +34302,8 @@ diff -urN a/gopls/internal/lsp/code_lens.go b/gopls/internal/lsp/code_lens.go -} diff -urN a/gopls/internal/lsp/command/command_gen.go b/gopls/internal/lsp/command/command_gen.go --- a/gopls/internal/lsp/command/command_gen.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/command/command_gen.go 1970-01-01 08:00:00 -@@ -1,621 +0,0 @@ ++++ b/gopls/internal/lsp/command/command_gen.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,641 +0,0 @@ -// Copyright 2021 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. @@ -34097,6 +34329,7 @@ diff -urN a/gopls/internal/lsp/command/command_gen.go b/gopls/internal/lsp/comma - AddImport Command = "add_import" - AddTelemetryCounters Command = "add_telemetry_counters" - ApplyFix Command = "apply_fix" +- ChangeSignature Command = "change_signature" - CheckUpgrades Command = "check_upgrades" - EditGoDirective Command = "edit_go_directive" - FetchVulncheckResult Command = "fetch_vulncheck_result" @@ -34130,6 +34363,7 @@ diff -urN a/gopls/internal/lsp/command/command_gen.go b/gopls/internal/lsp/comma - AddImport, - AddTelemetryCounters, - ApplyFix, +- ChangeSignature, - CheckUpgrades, - EditGoDirective, - FetchVulncheckResult, @@ -34184,6 +34418,12 @@ diff -urN a/gopls/internal/lsp/command/command_gen.go b/gopls/internal/lsp/comma - return nil, err - } - return nil, s.ApplyFix(ctx, a0) +- case "gopls.change_signature": +- var a0 ChangeSignatureArgs +- if err := UnmarshalArgs(params.Arguments, &a0); err != nil { +- return nil, err +- } +- return nil, s.ChangeSignature(ctx, a0) - case "gopls.check_upgrades": - var a0 CheckUpgradesArgs - if err := UnmarshalArgs(params.Arguments, &a0); err != nil { @@ -34382,6 +34622,18 @@ diff -urN a/gopls/internal/lsp/command/command_gen.go b/gopls/internal/lsp/comma - }, nil -} - +-func NewChangeSignatureCommand(title string, a0 ChangeSignatureArgs) (protocol.Command, error) { +- args, err := MarshalArgs(a0) +- if err != nil { +- return protocol.Command{}, err +- } +- return protocol.Command{ +- Title: title, +- Command: "gopls.change_signature", +- Arguments: args, +- }, nil +-} +- -func NewCheckUpgradesCommand(title string, a0 CheckUpgradesArgs) (protocol.Command, error) { - args, err := MarshalArgs(a0) - if err != nil { @@ -34695,7 +34947,7 @@ diff -urN a/gopls/internal/lsp/command/command_gen.go b/gopls/internal/lsp/comma -} diff -urN a/gopls/internal/lsp/command/commandmeta/meta.go b/gopls/internal/lsp/command/commandmeta/meta.go --- a/gopls/internal/lsp/command/commandmeta/meta.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/command/commandmeta/meta.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/command/commandmeta/meta.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,259 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -34958,7 +35210,7 @@ diff -urN a/gopls/internal/lsp/command/commandmeta/meta.go b/gopls/internal/lsp/ -} diff -urN a/gopls/internal/lsp/command/gen/gen.go b/gopls/internal/lsp/command/gen/gen.go --- a/gopls/internal/lsp/command/gen/gen.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/command/gen/gen.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/command/gen/gen.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,155 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -35117,7 +35369,7 @@ diff -urN a/gopls/internal/lsp/command/gen/gen.go b/gopls/internal/lsp/command/g -} diff -urN a/gopls/internal/lsp/command/generate.go b/gopls/internal/lsp/command/generate.go --- a/gopls/internal/lsp/command/generate.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/command/generate.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/command/generate.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -35146,8 +35398,8 @@ diff -urN a/gopls/internal/lsp/command/generate.go b/gopls/internal/lsp/command/ -} diff -urN a/gopls/internal/lsp/command/interface.go b/gopls/internal/lsp/command/interface.go --- a/gopls/internal/lsp/command/interface.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/command/interface.go 1970-01-01 08:00:00 -@@ -1,521 +0,0 @@ ++++ b/gopls/internal/lsp/command/interface.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,532 +0,0 @@ -// Copyright 2021 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. @@ -35351,6 +35603,12 @@ diff -urN a/gopls/internal/lsp/command/interface.go b/gopls/internal/lsp/command - // the user to ask if they want to enable Go telemetry uploading. If the user - // responds 'Yes', the telemetry mode is set to "on". - MaybePromptForTelemetry(context.Context) error +- +- // ChangeSignature: performs a "change signature" refactoring. +- // +- // This command is experimental, currently only supporting parameter removal. +- // Its signature will certainly change in the future (pun intended). +- ChangeSignature(context.Context, ChangeSignatureArgs) error -} - -type RunTestsArgs struct { @@ -35669,9 +35927,14 @@ diff -urN a/gopls/internal/lsp/command/interface.go b/gopls/internal/lsp/command - Names []string // Name of counters. - Values []int64 // Values added to the corresponding counters. Must be non-negative. -} +- +-// ChangeSignatureArgs specifies a "change signature" refactoring to perform. +-type ChangeSignatureArgs struct { +- RemoveParameter protocol.Location +-} diff -urN a/gopls/internal/lsp/command/interface_test.go b/gopls/internal/lsp/command/interface_test.go --- a/gopls/internal/lsp/command/interface_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/command/interface_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/command/interface_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -35707,7 +35970,7 @@ diff -urN a/gopls/internal/lsp/command/interface_test.go b/gopls/internal/lsp/co -} diff -urN a/gopls/internal/lsp/command/util.go b/gopls/internal/lsp/command/util.go --- a/gopls/internal/lsp/command/util.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/command/util.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/command/util.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -35775,8 +36038,8 @@ diff -urN a/gopls/internal/lsp/command/util.go b/gopls/internal/lsp/command/util -} diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go --- a/gopls/internal/lsp/command.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/command.go 1970-01-01 08:00:00 -@@ -1,1212 +0,0 @@ ++++ b/gopls/internal/lsp/command.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,1260 +0,0 @@ -// Copyright 2020 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. @@ -35796,6 +36059,7 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - "runtime/pprof" - "sort" - "strings" +- "sync" - - "golang.org/x/mod/modfile" - "golang.org/x/tools/go/ast/astutil" @@ -35993,12 +36257,37 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go -func (c *commandHandler) RegenerateCgo(ctx context.Context, args command.URIArg) error { - return c.run(ctx, commandConfig{ - progress: "Regenerating Cgo", -- }, func(ctx context.Context, deps commandDeps) error { -- mod := source.FileModification{ -- URI: args.URI.SpanURI(), -- Action: source.InvalidateMetadata, +- }, func(ctx context.Context, _ commandDeps) error { +- var wg sync.WaitGroup // tracks work done on behalf of this function, incl. diagnostics +- wg.Add(1) +- defer wg.Done() +- +- // Track progress on this operation for testing. +- if c.s.Options().VerboseWorkDoneProgress { +- work := c.s.progress.Start(ctx, DiagnosticWorkTitle(FromRegenerateCgo), "Calculating file diagnostics...", nil, nil) +- go func() { +- wg.Wait() +- work.End(ctx, "Done.") +- }() +- } +- +- // Resetting the view causes cgo to be regenerated via `go list`. +- v, err := c.s.session.ResetView(ctx, args.URI.SpanURI()) +- if err != nil { +- return err - } -- return c.s.didModifyFiles(ctx, []source.FileModification{mod}, FromRegenerateCgo) +- +- snapshot, release, err := v.Snapshot() +- if err != nil { +- return err +- } +- wg.Add(1) +- go func() { +- c.s.diagnoseSnapshot(snapshot, nil, true, 0) +- release() +- wg.Done() +- }() +- return nil - }) -} - @@ -36989,9 +37278,31 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - event.Log(ctx, fmt.Sprintf("client declined to open document %v", url)) - } -} +- +-func (c *commandHandler) ChangeSignature(ctx context.Context, args command.ChangeSignatureArgs) error { +- return c.run(ctx, commandConfig{ +- forURI: args.RemoveParameter.URI, +- }, func(ctx context.Context, deps commandDeps) error { +- // For now, gopls only supports removing unused parameters. +- changes, err := source.RemoveUnusedParameter(ctx, deps.fh, args.RemoveParameter.Range, deps.snapshot) +- if err != nil { +- return err +- } +- r, err := c.s.client.ApplyEdit(ctx, &protocol.ApplyWorkspaceEditParams{ +- Edit: protocol.WorkspaceEdit{ +- DocumentChanges: changes, +- }, +- }) +- if !r.Applied { +- return fmt.Errorf("failed to apply edits: %v", r.FailureReason) +- } +- +- return nil +- }) +-} diff -urN a/gopls/internal/lsp/completion.go b/gopls/internal/lsp/completion.go --- a/gopls/internal/lsp/completion.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/completion.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/completion.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,149 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -37142,187 +37453,10 @@ diff -urN a/gopls/internal/lsp/completion.go b/gopls/internal/lsp/completion.go - } - return items -} -diff -urN a/gopls/internal/lsp/completion_test.go b/gopls/internal/lsp/completion_test.go ---- a/gopls/internal/lsp/completion_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/completion_test.go 1970-01-01 08:00:00 -@@ -1,173 +0,0 @@ --// 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 lsp -- --import ( -- "fmt" -- "strings" -- "testing" -- -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/lsp/source/completion" -- "golang.org/x/tools/gopls/internal/lsp/tests" -- "golang.org/x/tools/gopls/internal/span" --) -- --func (r *runner) Completion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) { -- got := r.callCompletion(t, src, func(opts *source.Options) { -- opts.DeepCompletion = false -- opts.Matcher = source.CaseInsensitive -- opts.CompleteUnimported = false -- opts.InsertTextFormat = protocol.SnippetTextFormat -- opts.LiteralCompletions = strings.Contains(string(src.URI()), "literal") -- opts.ExperimentalPostfixCompletions = strings.Contains(string(src.URI()), "postfix") -- }) -- got = tests.FilterBuiltins(src, got) -- want := expected(t, test, items) -- if diff := tests.DiffCompletionItems(want, got); diff != "" { -- t.Errorf("mismatching completion items (-want +got):\n%s", diff) -- } --} -- --func (r *runner) CompletionSnippet(t *testing.T, src span.Span, expected tests.CompletionSnippet, placeholders bool, items tests.CompletionItems) { -- list := r.callCompletion(t, src, func(opts *source.Options) { -- opts.UsePlaceholders = placeholders -- opts.DeepCompletion = true -- opts.Matcher = source.Fuzzy -- opts.CompleteUnimported = false -- }) -- got := tests.FindItem(list, *items[expected.CompletionItem]) -- want := expected.PlainSnippet -- if placeholders { -- want = expected.PlaceholderSnippet -- } -- if diff := tests.DiffSnippets(want, got); diff != "" { -- t.Errorf("%s", diff) -- } --} -- --func (r *runner) DeepCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) { -- got := r.callCompletion(t, src, func(opts *source.Options) { -- opts.DeepCompletion = true -- opts.Matcher = source.CaseInsensitive -- opts.CompleteUnimported = false -- }) -- got = tests.FilterBuiltins(src, got) -- want := expected(t, test, items) -- if diff := tests.DiffCompletionItems(want, got); diff != "" { -- t.Errorf("mismatching completion items (-want +got):\n%s", diff) -- } --} -- --func (r *runner) FuzzyCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) { -- got := r.callCompletion(t, src, func(opts *source.Options) { -- opts.DeepCompletion = true -- opts.Matcher = source.Fuzzy -- opts.CompleteUnimported = false -- }) -- got = tests.FilterBuiltins(src, got) -- want := expected(t, test, items) -- if diff := tests.DiffCompletionItems(want, got); diff != "" { -- t.Errorf("mismatching completion items (-want +got):\n%s", diff) -- } --} -- --func (r *runner) CaseSensitiveCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) { -- got := r.callCompletion(t, src, func(opts *source.Options) { -- opts.Matcher = source.CaseSensitive -- opts.CompleteUnimported = false -- }) -- got = tests.FilterBuiltins(src, got) -- want := expected(t, test, items) -- if diff := tests.DiffCompletionItems(want, got); diff != "" { -- t.Errorf("mismatching completion items (-want +got):\n%s", diff) -- } --} -- --func (r *runner) RankCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) { -- got := r.callCompletion(t, src, func(opts *source.Options) { -- opts.DeepCompletion = true -- opts.Matcher = source.Fuzzy -- opts.CompleteUnimported = false -- opts.LiteralCompletions = true -- opts.ExperimentalPostfixCompletions = true -- }) -- want := expected(t, test, items) -- if msg := tests.CheckCompletionOrder(want, got, true); msg != "" { -- t.Errorf("%s", msg) -- } --} -- --func expected(t *testing.T, test tests.Completion, items tests.CompletionItems) []protocol.CompletionItem { -- t.Helper() -- -- toProtocolCompletionItem := func(item *completion.CompletionItem) protocol.CompletionItem { -- pItem := protocol.CompletionItem{ -- Label: item.Label, -- Kind: item.Kind, -- Detail: item.Detail, -- Tags: []protocol.CompletionItemTag{}, // must be a slice -- Documentation: &protocol.Or_CompletionItem_documentation{ -- Value: item.Documentation, -- }, -- InsertText: item.InsertText, -- TextEdit: &protocol.TextEdit{ -- NewText: item.Snippet(), -- }, -- // Negate score so best score has lowest sort text like real API. -- SortText: fmt.Sprint(-item.Score), -- } -- if pItem.InsertText == "" { -- pItem.InsertText = pItem.Label -- } -- return pItem -- } -- -- var want []protocol.CompletionItem -- for _, pos := range test.CompletionItems { -- want = append(want, toProtocolCompletionItem(items[pos])) -- } -- return want --} -- --func (r *runner) callCompletion(t *testing.T, src span.Span, options func(*source.Options)) []protocol.CompletionItem { -- t.Helper() -- cleanup := r.toggleOptions(t, src.URI(), options) -- defer cleanup() -- -- list, err := r.server.Completion(r.ctx, &protocol.CompletionParams{ -- TextDocumentPositionParams: protocol.TextDocumentPositionParams{ -- TextDocument: protocol.TextDocumentIdentifier{ -- URI: protocol.URIFromSpanURI(src.URI()), -- }, -- Position: protocol.Position{ -- Line: uint32(src.Start().Line() - 1), -- Character: uint32(src.Start().Column() - 1), -- }, -- }, -- }) -- if err != nil { -- t.Fatal(err) -- } -- return list.Items --} -- --func (r *runner) toggleOptions(t *testing.T, uri span.URI, options func(*source.Options)) (reset func()) { -- view, err := r.server.session.ViewOf(uri) -- if err != nil { -- t.Fatal(err) -- } -- folder := view.Folder() -- -- modified := r.server.Options().Clone() -- options(modified) -- if err = r.server.session.SetFolderOptions(r.ctx, folder, modified); err != nil { -- t.Fatal(err) -- } -- return func() { -- r.server.session.SetFolderOptions(r.ctx, folder, r.server.Options()) -- } --} diff -urN a/gopls/internal/lsp/debug/info.go b/gopls/internal/lsp/debug/info.go --- a/gopls/internal/lsp/debug/info.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/debug/info.go 1970-01-01 08:00:00 -@@ -1,258 +0,0 @@ ++++ b/gopls/internal/lsp/debug/info.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,159 +0,0 @@ -// 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. @@ -37336,13 +37470,9 @@ diff -urN a/gopls/internal/lsp/debug/info.go b/gopls/internal/lsp/debug/info.go - "fmt" - "io" - "os" -- "reflect" - "runtime" - "runtime/debug" -- "sort" - "strings" -- -- "golang.org/x/tools/gopls/internal/lsp/source" -) - -type PrintMode int @@ -37480,110 +37610,15 @@ diff -urN a/gopls/internal/lsp/debug/info.go b/gopls/internal/lsp/debug/info.go - -var fields []field - --// find all the options. The presumption is that the Options are nested structs --// and that pointers don't need to be dereferenced --func swalk(t reflect.Type, ix []int, indent string) { -- switch t.Kind() { -- case reflect.Struct: -- for i := 0; i < t.NumField(); i++ { -- fld := t.Field(i) -- ixx := append(append([]int{}, ix...), i) -- swalk(fld.Type, ixx, indent+". ") -- } -- default: -- // everything is either a struct or a field (that's an assumption about Options) -- fields = append(fields, field{ix}) -- } --} -- -type sessionOption struct { - Name string - Type string - Current string - Default string -} -- --func showOptions(o *source.Options) []sessionOption { -- var out []sessionOption -- t := reflect.TypeOf(*o) -- swalk(t, []int{}, "") -- v := reflect.ValueOf(*o) -- do := reflect.ValueOf(*source.DefaultOptions()) -- for _, f := range fields { -- val := v.FieldByIndex(f.index) -- def := do.FieldByIndex(f.index) -- tx := t.FieldByIndex(f.index) -- is := strVal(val) -- was := strVal(def) -- out = append(out, sessionOption{ -- Name: tx.Name, -- Type: tx.Type.String(), -- Current: is, -- Default: was, -- }) -- } -- sort.Slice(out, func(i, j int) bool { -- rd := out[i].Current == out[i].Default -- ld := out[j].Current == out[j].Default -- if rd != ld { -- return ld -- } -- return out[i].Name < out[j].Name -- }) -- return out --} -- --func strVal(val reflect.Value) string { -- switch val.Kind() { -- case reflect.Bool: -- return fmt.Sprintf("%v", val.Interface()) -- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: -- return fmt.Sprintf("%v", val.Interface()) -- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: -- return fmt.Sprintf("%v", val.Interface()) -- case reflect.Uintptr, reflect.UnsafePointer: -- return fmt.Sprintf("0x%x", val.Pointer()) -- case reflect.Complex64, reflect.Complex128: -- return fmt.Sprintf("%v", val.Complex()) -- case reflect.Array, reflect.Slice: -- ans := []string{} -- for i := 0; i < val.Len(); i++ { -- ans = append(ans, strVal(val.Index(i))) -- } -- sort.Strings(ans) -- return fmt.Sprintf("%v", ans) -- case reflect.Chan, reflect.Func, reflect.Ptr: -- return val.Kind().String() -- case reflect.Struct: -- var x source.Analyzer -- if val.Type() != reflect.TypeOf(x) { -- return val.Kind().String() -- } -- // this is sort of ugly, but usable -- str := val.FieldByName("Analyzer").Elem().FieldByName("Doc").String() -- ix := strings.Index(str, "\n") -- if ix == -1 { -- ix = len(str) -- } -- return str[:ix] -- case reflect.String: -- return fmt.Sprintf("%q", val.Interface()) -- case reflect.Map: -- ans := []string{} -- iter := val.MapRange() -- for iter.Next() { -- k := iter.Key() -- v := iter.Value() -- ans = append(ans, fmt.Sprintf("%s:%s, ", strVal(k), strVal(v))) -- } -- sort.Strings(ans) -- return fmt.Sprintf("%v", ans) -- } -- return fmt.Sprintf("??%s??", val.Type()) --} diff -urN a/gopls/internal/lsp/debug/info_test.go b/gopls/internal/lsp/debug/info_test.go --- a/gopls/internal/lsp/debug/info_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/debug/info_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/debug/info_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -37635,7 +37670,7 @@ diff -urN a/gopls/internal/lsp/debug/info_test.go b/gopls/internal/lsp/debug/inf -} diff -urN a/gopls/internal/lsp/debug/log/log.go b/gopls/internal/lsp/debug/log/log.go --- a/gopls/internal/lsp/debug/log/log.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/debug/log/log.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/debug/log/log.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -37682,7 +37717,7 @@ diff -urN a/gopls/internal/lsp/debug/log/log.go b/gopls/internal/lsp/debug/log/l -} diff -urN a/gopls/internal/lsp/debug/metrics.go b/gopls/internal/lsp/debug/metrics.go --- a/gopls/internal/lsp/debug/metrics.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/debug/metrics.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/debug/metrics.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -37744,7 +37779,7 @@ diff -urN a/gopls/internal/lsp/debug/metrics.go b/gopls/internal/lsp/debug/metri -} diff -urN a/gopls/internal/lsp/debug/rpc.go b/gopls/internal/lsp/debug/rpc.go --- a/gopls/internal/lsp/debug/rpc.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/debug/rpc.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/debug/rpc.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,239 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -37987,7 +38022,7 @@ diff -urN a/gopls/internal/lsp/debug/rpc.go b/gopls/internal/lsp/debug/rpc.go -} diff -urN a/gopls/internal/lsp/debug/serve.go b/gopls/internal/lsp/debug/serve.go --- a/gopls/internal/lsp/debug/serve.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/debug/serve.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/debug/serve.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,864 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -38855,7 +38890,7 @@ diff -urN a/gopls/internal/lsp/debug/serve.go b/gopls/internal/lsp/debug/serve.g -`)) diff -urN a/gopls/internal/lsp/debug/trace.go b/gopls/internal/lsp/debug/trace.go --- a/gopls/internal/lsp/debug/trace.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/debug/trace.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/debug/trace.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,320 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -39179,7 +39214,7 @@ diff -urN a/gopls/internal/lsp/debug/trace.go b/gopls/internal/lsp/debug/trace.g -} diff -urN a/gopls/internal/lsp/definition.go b/gopls/internal/lsp/definition.go --- a/gopls/internal/lsp/definition.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/definition.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/definition.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -39243,8 +39278,8 @@ diff -urN a/gopls/internal/lsp/definition.go b/gopls/internal/lsp/definition.go -} diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.go --- a/gopls/internal/lsp/diagnostics.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/diagnostics.go 1970-01-01 08:00:00 -@@ -1,862 +0,0 @@ ++++ b/gopls/internal/lsp/diagnostics.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,870 +0,0 @@ -// Copyright 2018 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. @@ -39402,9 +39437,12 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - return fmt.Sprintf("%x", h.Sum(nil)) -} - --func (s *Server) diagnoseSnapshots(snapshots map[source.Snapshot][]span.URI, onDisk bool) { +-func (s *Server) diagnoseSnapshots(snapshots map[source.Snapshot][]span.URI, onDisk bool, cause ModificationSource) { - var diagnosticWG sync.WaitGroup - for snapshot, uris := range snapshots { +- if snapshot.Options().DiagnosticsTrigger == source.DiagnosticsOnSave && cause == FromDidChange { +- continue // user requested to update the diagnostics only on save. do not diagnose yet. +- } - diagnosticWG.Add(1) - go func(snapshot source.Snapshot, uris []span.URI) { - defer diagnosticWG.Done() @@ -39422,6 +39460,9 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g -// If changedURIs is non-empty, it is a set of recently changed files that -// should be diagnosed immediately, and onDisk reports whether these file -// changes came from a change to on-disk files. +-// +-// TODO(rfindley): eliminate the onDisk parameter, which looks misplaced. If we +-// don't want to diagnose changes on disk, filter out the changedURIs. -func (s *Server) diagnoseSnapshot(snapshot source.Snapshot, changedURIs []span.URI, onDisk bool, delay time.Duration) { - ctx := snapshot.BackgroundContext() - ctx, done := event.Start(ctx, "Server.diagnoseSnapshot", source.SnapshotLabels(snapshot)...) @@ -39447,8 +39488,10 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - return - } - -- s.diagnoseChangedFiles(ctx, snapshot, changedURIs, onDisk) -- s.publishDiagnostics(ctx, false, snapshot) +- if len(changedURIs) > 0 { +- s.diagnoseChangedFiles(ctx, snapshot, changedURIs, onDisk) +- s.publishDiagnostics(ctx, false, snapshot) +- } - - if delay < minDelay { - delay = 0 @@ -40109,7 +40152,7 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g -} diff -urN a/gopls/internal/lsp/fake/client.go b/gopls/internal/lsp/fake/client.go --- a/gopls/internal/lsp/fake/client.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/fake/client.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/fake/client.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,193 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -40306,7 +40349,7 @@ diff -urN a/gopls/internal/lsp/fake/client.go b/gopls/internal/lsp/fake/client.g -} diff -urN a/gopls/internal/lsp/fake/doc.go b/gopls/internal/lsp/fake/doc.go --- a/gopls/internal/lsp/fake/doc.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/fake/doc.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/fake/doc.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -40329,7 +40372,7 @@ diff -urN a/gopls/internal/lsp/fake/doc.go b/gopls/internal/lsp/fake/doc.go -package fake diff -urN a/gopls/internal/lsp/fake/edit.go b/gopls/internal/lsp/fake/edit.go --- a/gopls/internal/lsp/fake/edit.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/fake/edit.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/fake/edit.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -40382,110 +40425,10 @@ diff -urN a/gopls/internal/lsp/fake/edit.go b/gopls/internal/lsp/fake/edit.go - } - return patched, nil -} -diff -urN a/gopls/internal/lsp/fake/edit_test.go b/gopls/internal/lsp/fake/edit_test.go ---- a/gopls/internal/lsp/fake/edit_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/fake/edit_test.go 1970-01-01 08:00:00 -@@ -1,96 +0,0 @@ --// Copyright 2020 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 fake -- --import ( -- "testing" -- -- "golang.org/x/tools/gopls/internal/lsp/protocol" --) -- --func TestApplyEdits(t *testing.T) { -- tests := []struct { -- label string -- content string -- edits []protocol.TextEdit -- want string -- wantErr bool -- }{ -- { -- label: "empty content", -- }, -- { -- label: "empty edit", -- content: "hello", -- edits: []protocol.TextEdit{}, -- want: "hello", -- }, -- { -- label: "unicode edit", -- content: "hello, 日本語", -- edits: []protocol.TextEdit{ -- NewEdit(0, 7, 0, 10, "world"), -- }, -- want: "hello, world", -- }, -- { -- label: "range edit", -- content: "ABC\nDEF\nGHI\nJKL", -- edits: []protocol.TextEdit{ -- NewEdit(1, 1, 2, 3, "12\n345"), -- }, -- want: "ABC\nD12\n345\nJKL", -- }, -- { -- label: "regression test for issue #57627", -- content: "go 1.18\nuse moda/a", -- edits: []protocol.TextEdit{ -- NewEdit(1, 0, 1, 0, "\n"), -- NewEdit(2, 0, 2, 0, "\n"), -- }, -- want: "go 1.18\n\nuse moda/a\n", -- }, -- { -- label: "end before start", -- content: "ABC\nDEF\nGHI\nJKL", -- edits: []protocol.TextEdit{ -- NewEdit(2, 3, 1, 1, "12\n345"), -- }, -- wantErr: true, -- }, -- { -- label: "out of bounds line", -- content: "ABC\nDEF\nGHI\nJKL", -- edits: []protocol.TextEdit{ -- NewEdit(1, 1, 4, 3, "12\n345"), -- }, -- wantErr: true, -- }, -- { -- label: "out of bounds column", -- content: "ABC\nDEF\nGHI\nJKL", -- edits: []protocol.TextEdit{ -- NewEdit(1, 4, 2, 3, "12\n345"), -- }, -- wantErr: true, -- }, -- } -- -- for _, test := range tests { -- test := test -- t.Run(test.label, func(t *testing.T) { -- got, err := applyEdits(protocol.NewMapper("", []byte(test.content)), test.edits, false) -- if (err != nil) != test.wantErr { -- t.Errorf("got err %v, want error: %t", err, test.wantErr) -- } -- if err != nil { -- return -- } -- if got := string(got); got != test.want { -- t.Errorf("got %q, want %q", got, test.want) -- } -- }) -- } --} diff -urN a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.go --- a/gopls/internal/lsp/fake/editor.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/fake/editor.go 1970-01-01 08:00:00 -@@ -1,1494 +0,0 @@ ++++ b/gopls/internal/lsp/fake/editor.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,1571 +0,0 @@ -// Copyright 2020 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. @@ -40532,7 +40475,8 @@ diff -urN a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.g - config EditorConfig // editor configuration - buffers map[string]buffer // open buffers (relative path -> buffer content) - serverCapabilities protocol.ServerCapabilities // capabilities / options -- watchPatterns []*glob.Glob // glob patterns to watch +- semTokOpts protocol.SemanticTokensOptions +- watchPatterns []*glob.Glob // glob patterns to watch - - // Call metrics for the purpose of expectations. This is done in an ad-hoc - // manner for now. Perhaps in the future we should do something more @@ -40794,8 +40738,13 @@ diff -urN a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.g - if err != nil { - return fmt.Errorf("initialize: %w", err) - } +- semTokOpts, err := marshalUnmarshal[protocol.SemanticTokensOptions](resp.Capabilities.SemanticTokensProvider) +- if err != nil { +- return fmt.Errorf("unmarshalling semantic tokens options: %v", err) +- } - e.mu.Lock() - e.serverCapabilities = resp.Capabilities +- e.semTokOpts = semTokOpts - e.mu.Unlock() - - if err := e.Server.Initialized(ctx, &protocol.InitializedParams{}); err != nil { @@ -40806,6 +40755,19 @@ diff -urN a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.g - return nil -} - +-// marshalUnmarshal is a helper to json Marshal and then Unmarshal as a +-// different type. Used to work around cases where our protocol types are not +-// specific. +-func marshalUnmarshal[T any](v any) (T, error) { +- var t T +- data, err := json.Marshal(v) +- if err != nil { +- return t, err +- } +- err = json.Unmarshal(data, &t) +- return t, err +-} +- -// HasCommand reports whether the connected server supports the command with the given ID. -func (e *Editor) HasCommand(id string) bool { - for _, command := range e.serverCapabilities.ExecuteCommandProvider.Commands { @@ -41980,9 +41942,67 @@ diff -urN a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.g - - return e.Server.DocumentHighlight(ctx, params) -} +- +-// SemanticTokens invokes textDocument/semanticTokens/full, and interprets its +-// result. +-func (e *Editor) SemanticTokens(ctx context.Context, path string) ([]SemanticToken, error) { +- p := &protocol.SemanticTokensParams{ +- TextDocument: protocol.TextDocumentIdentifier{ +- URI: e.sandbox.Workdir.URI(path), +- }, +- } +- resp, err := e.Server.SemanticTokensFull(ctx, p) +- if err != nil { +- return nil, err +- } +- content, ok := e.BufferText(path) +- if !ok { +- return nil, fmt.Errorf("buffer %s is not open", path) +- } +- return e.interpretTokens(resp.Data, content), nil +-} +- +-// A SemanticToken is an interpreted semantic token value. +-type SemanticToken struct { +- Token string +- TokenType string +- Mod string +-} +- +-// Note: previously this function elided comment, string, and number tokens. +-// Instead, filtering of token types should be done by the caller. +-func (e *Editor) interpretTokens(x []uint32, contents string) []SemanticToken { +- e.mu.Lock() +- legend := e.semTokOpts.Legend +- e.mu.Unlock() +- lines := strings.Split(contents, "\n") +- ans := []SemanticToken{} +- line, col := 1, 1 +- for i := 0; i < len(x); i += 5 { +- line += int(x[i]) +- col += int(x[i+1]) +- if x[i] != 0 { // new line +- col = int(x[i+1]) + 1 // 1-based column numbers +- } +- sz := x[i+2] +- t := legend.TokenTypes[x[i+3]] +- l := x[i+4] +- var mods []string +- for i, mod := range legend.TokenModifiers { +- if l&(1<= 3 { +- ops = append(ops, op{data[0]%2 == 0, data[1], data[2]}) +- data = data[3:] +- } +- cache := lru.New(100) +- var reference [256]byte +- for _, op := range ops { +- if op.set { +- reference[op.key] = op.value +- cache.Set(op.key, op.value, 1) +- } else { +- if v := cache.Get(op.key); v != nil && v != reference[op.key] { +- t.Fatalf("cache.Get(%d) = %d, want %d", op.key, v, reference[op.key]) +- } +- } +- } +- }) +-} diff -urN a/gopls/internal/lsp/lru/lru.go b/gopls/internal/lsp/lru/lru.go --- a/gopls/internal/lsp/lru/lru.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lru/lru.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/lru/lru.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,151 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -46764,54 +46929,9 @@ diff -urN a/gopls/internal/lsp/lru/lru.go b/gopls/internal/lsp/lru/lru.go - *q = (*q)[:last] - return e -} -diff -urN a/gopls/internal/lsp/lru/lru_fuzz_test.go b/gopls/internal/lsp/lru/lru_fuzz_test.go ---- a/gopls/internal/lsp/lru/lru_fuzz_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lru/lru_fuzz_test.go 1970-01-01 08:00:00 -@@ -1,41 +0,0 @@ --// Copyright 2023 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. -- --//go:build go1.18 --// +build go1.18 -- --package lru_test -- --import ( -- "testing" -- -- "golang.org/x/tools/gopls/internal/lsp/lru" --) -- --// Simple fuzzing test for consistency. --func FuzzCache(f *testing.F) { -- type op struct { -- set bool -- key, value byte -- } -- f.Fuzz(func(t *testing.T, data []byte) { -- var ops []op -- for len(data) >= 3 { -- ops = append(ops, op{data[0]%2 == 0, data[1], data[2]}) -- data = data[3:] -- } -- cache := lru.New(100) -- var reference [256]byte -- for _, op := range ops { -- if op.set { -- reference[op.key] = op.value -- cache.Set(op.key, op.value, 1) -- } else { -- if v := cache.Get(op.key); v != nil && v != reference[op.key] { -- t.Fatalf("cache.Get(%d) = %d, want %d", op.key, v, reference[op.key]) -- } -- } -- } -- }) --} diff -urN a/gopls/internal/lsp/lru/lru_test.go b/gopls/internal/lsp/lru/lru_test.go --- a/gopls/internal/lsp/lru/lru_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lru/lru_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/lru/lru_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,154 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -46967,773 +47087,9 @@ diff -urN a/gopls/internal/lsp/lru/lru_test.go b/gopls/internal/lsp/lru/lru_test - } - return -} -diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go ---- a/gopls/internal/lsp/lsp_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lsp_test.go 1970-01-01 08:00:00 -@@ -1,760 +0,0 @@ --// Copyright 2018 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 lsp -- --import ( -- "bytes" -- "context" -- "fmt" -- "os" -- "path/filepath" -- "sort" -- "strings" -- "testing" -- -- "golang.org/x/tools/gopls/internal/bug" -- "golang.org/x/tools/gopls/internal/lsp/cache" -- "golang.org/x/tools/gopls/internal/lsp/command" -- "golang.org/x/tools/gopls/internal/lsp/debug" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/lsp/tests" -- "golang.org/x/tools/gopls/internal/lsp/tests/compare" -- "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/testenv" --) -- --func TestMain(m *testing.M) { -- bug.PanicOnBugs = true -- testenv.ExitIfSmallMachine() -- -- os.Exit(m.Run()) --} -- --// TestLSP runs the marker tests in files beneath testdata/ using --// implementations of each of the marker operations that make LSP RPCs to a --// gopls server. --func TestLSP(t *testing.T) { -- tests.RunTests(t, "testdata", true, testLSP) --} -- --func testLSP(t *testing.T, datum *tests.Data) { -- ctx := tests.Context(t) -- -- // Setting a debug instance suppresses logging to stderr, but ensures that we -- // still e.g. convert events into runtime/trace/instrumentation. -- // -- // Previously, we called event.SetExporter(nil), which turns off all -- // instrumentation. -- ctx = debug.WithInstance(ctx, "", "off") -- -- session := cache.NewSession(ctx, cache.New(nil)) -- options := source.DefaultOptions(tests.DefaultOptions) -- options.SetEnvSlice(datum.Config.Env) -- view, snapshot, release, err := session.NewView(ctx, datum.Config.Dir, span.URIFromPath(datum.Config.Dir), options) -- if err != nil { -- t.Fatal(err) -- } -- -- defer session.RemoveView(view) -- -- // Only run the -modfile specific tests in module mode with Go 1.14 or above. -- datum.ModfileFlagAvailable = len(snapshot.ModFiles()) > 0 && testenv.Go1Point() >= 14 -- release() -- -- // Open all files for performance reasons, because gopls only -- // keeps active packages (those with open files) in memory. -- // -- // In practice clients will only send document-oriented requests for open -- // files. -- var modifications []source.FileModification -- for _, module := range datum.Exported.Modules { -- for name := range module.Files { -- filename := datum.Exported.File(module.Name, name) -- if filepath.Ext(filename) != ".go" { -- continue -- } -- content, err := datum.Exported.FileContents(filename) -- if err != nil { -- t.Fatal(err) -- } -- modifications = append(modifications, source.FileModification{ -- URI: span.URIFromPath(filename), -- Action: source.Open, -- Version: -1, -- Text: content, -- LanguageID: "go", -- }) -- } -- } -- for filename, content := range datum.Config.Overlay { -- if filepath.Ext(filename) != ".go" { -- continue -- } -- modifications = append(modifications, source.FileModification{ -- URI: span.URIFromPath(filename), -- Action: source.Open, -- Version: -1, -- Text: content, -- LanguageID: "go", -- }) -- } -- if err := session.ModifyFiles(ctx, modifications); err != nil { -- t.Fatal(err) -- } -- r := &runner{ -- data: datum, -- ctx: ctx, -- editRecv: make(chan map[span.URI][]byte, 1), -- } -- -- r.server = NewServer(session, testClient{runner: r}, options) -- tests.Run(t, r, datum) --} -- --// runner implements tests.Tests by making LSP RPCs to a gopls server. --type runner struct { -- server *Server -- data *tests.Data -- diagnostics map[span.URI][]*source.Diagnostic -- ctx context.Context -- editRecv chan map[span.URI][]byte --} -- --// testClient stubs any client functions that may be called by LSP functions. --type testClient struct { -- protocol.Client -- runner *runner --} -- --func (c testClient) Close() error { -- return nil --} -- --// Trivially implement PublishDiagnostics so that we can call --// server.publishReports below to de-dup sent diagnostics. --func (c testClient) PublishDiagnostics(context.Context, *protocol.PublishDiagnosticsParams) error { -- return nil --} -- --func (c testClient) ShowMessage(context.Context, *protocol.ShowMessageParams) error { -- return nil --} -- --func (c testClient) ApplyEdit(ctx context.Context, params *protocol.ApplyWorkspaceEditParams) (*protocol.ApplyWorkspaceEditResult, error) { -- res, err := applyTextDocumentEdits(c.runner, params.Edit.DocumentChanges) -- if err != nil { -- return nil, err -- } -- c.runner.editRecv <- res -- return &protocol.ApplyWorkspaceEditResult{Applied: true}, nil --} -- --func (r *runner) CallHierarchy(t *testing.T, spn span.Span, expectedCalls *tests.CallHierarchyResult) { -- mapper, err := r.data.Mapper(spn.URI()) -- if err != nil { -- t.Fatal(err) -- } -- loc, err := mapper.SpanLocation(spn) -- if err != nil { -- t.Fatalf("failed for %v: %v", spn, err) -- } -- -- params := &protocol.CallHierarchyPrepareParams{ -- TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(loc), -- } -- -- items, err := r.server.PrepareCallHierarchy(r.ctx, params) -- if err != nil { -- t.Fatal(err) -- } -- if len(items) == 0 { -- t.Fatalf("expected call hierarchy item to be returned for identifier at %v\n", loc.Range) -- } -- -- callLocation := protocol.Location{ -- URI: items[0].URI, -- Range: items[0].Range, -- } -- if callLocation != loc { -- t.Fatalf("expected server.PrepareCallHierarchy to return identifier at %v but got %v\n", loc, callLocation) -- } -- -- incomingCalls, err := r.server.IncomingCalls(r.ctx, &protocol.CallHierarchyIncomingCallsParams{Item: items[0]}) -- if err != nil { -- t.Error(err) -- } -- var incomingCallItems []protocol.CallHierarchyItem -- for _, item := range incomingCalls { -- incomingCallItems = append(incomingCallItems, item.From) -- } -- msg := tests.DiffCallHierarchyItems(incomingCallItems, expectedCalls.IncomingCalls) -- if msg != "" { -- t.Errorf("incoming calls: %s", msg) -- } -- -- outgoingCalls, err := r.server.OutgoingCalls(r.ctx, &protocol.CallHierarchyOutgoingCallsParams{Item: items[0]}) -- if err != nil { -- t.Error(err) -- } -- var outgoingCallItems []protocol.CallHierarchyItem -- for _, item := range outgoingCalls { -- outgoingCallItems = append(outgoingCallItems, item.To) -- } -- msg = tests.DiffCallHierarchyItems(outgoingCallItems, expectedCalls.OutgoingCalls) -- if msg != "" { -- t.Errorf("outgoing calls: %s", msg) -- } --} -- --func (r *runner) SemanticTokens(t *testing.T, spn span.Span) { -- uri := spn.URI() -- filename := uri.Filename() -- // this is called solely for coverage in semantic.go -- _, err := r.server.semanticTokensFull(r.ctx, &protocol.SemanticTokensParams{ -- TextDocument: protocol.TextDocumentIdentifier{ -- URI: protocol.URIFromSpanURI(uri), -- }, -- }) -- if err != nil { -- t.Errorf("%v for %s", err, filename) -- } -- _, err = r.server.semanticTokensRange(r.ctx, &protocol.SemanticTokensRangeParams{ -- TextDocument: protocol.TextDocumentIdentifier{ -- URI: protocol.URIFromSpanURI(uri), -- }, -- // any legal range. Just to exercise the call. -- Range: protocol.Range{ -- Start: protocol.Position{ -- Line: 0, -- Character: 0, -- }, -- End: protocol.Position{ -- Line: 2, -- Character: 0, -- }, -- }, -- }) -- if err != nil { -- t.Errorf("%v for Range %s", err, filename) -- } --} -- --func (r *runner) SuggestedFix(t *testing.T, spn span.Span, actionKinds []tests.SuggestedFix, expectedActions int) { -- uri := spn.URI() -- view, err := r.server.session.ViewOf(uri) -- if err != nil { -- t.Fatal(err) -- } -- -- m, err := r.data.Mapper(uri) -- if err != nil { -- t.Fatal(err) -- } -- rng, err := m.SpanRange(spn) -- if err != nil { -- t.Fatal(err) -- } -- // Get the diagnostics for this view if we have not done it before. -- r.collectDiagnostics(view) -- var diagnostics []protocol.Diagnostic -- for _, d := range r.diagnostics[uri] { -- // Compare the start positions rather than the entire range because -- // some diagnostics have a range with the same start and end position (8:1-8:1). -- // The current marker functionality prevents us from having a range of 0 length. -- if protocol.ComparePosition(d.Range.Start, rng.Start) == 0 { -- diagnostics = append(diagnostics, toProtocolDiagnostics([]*source.Diagnostic{d})...) -- break -- } -- } -- var codeActionKinds []protocol.CodeActionKind -- for _, k := range actionKinds { -- codeActionKinds = append(codeActionKinds, protocol.CodeActionKind(k.ActionKind)) -- } -- allActions, err := r.server.CodeAction(r.ctx, &protocol.CodeActionParams{ -- TextDocument: protocol.TextDocumentIdentifier{ -- URI: protocol.URIFromSpanURI(uri), -- }, -- Range: rng, -- Context: protocol.CodeActionContext{ -- Only: codeActionKinds, -- Diagnostics: diagnostics, -- }, -- }) -- if err != nil { -- t.Fatalf("CodeAction %s failed: %v", spn, err) -- } -- var actions []protocol.CodeAction -- for _, action := range allActions { -- for _, fix := range actionKinds { -- if strings.Contains(action.Title, fix.Title) { -- actions = append(actions, action) -- break -- } -- } -- -- } -- if len(actions) != expectedActions { -- var summaries []string -- for _, a := range actions { -- summaries = append(summaries, fmt.Sprintf("%q (%s)", a.Title, a.Kind)) -- } -- t.Fatalf("CodeAction(...): got %d code actions (%v), want %d", len(actions), summaries, expectedActions) -- } -- action := actions[0] -- var match bool -- for _, k := range codeActionKinds { -- if action.Kind == k { -- match = true -- break -- } -- } -- if !match { -- t.Fatalf("unexpected kind for code action %s, got %v, want one of %v", action.Title, action.Kind, codeActionKinds) -- } -- var res map[span.URI][]byte -- if cmd := action.Command; cmd != nil { -- _, err := r.server.ExecuteCommand(r.ctx, &protocol.ExecuteCommandParams{ -- Command: action.Command.Command, -- Arguments: action.Command.Arguments, -- }) -- if err != nil { -- t.Fatalf("error converting command %q to edits: %v", action.Command.Command, err) -- } -- res = <-r.editRecv -- } else { -- res, err = applyTextDocumentEdits(r, action.Edit.DocumentChanges) -- if err != nil { -- t.Fatal(err) -- } -- } -- for u, got := range res { -- want := r.data.Golden(t, "suggestedfix_"+tests.SpanName(spn), u.Filename(), func() ([]byte, error) { -- return got, nil -- }) -- if diff := compare.Bytes(want, got); diff != "" { -- t.Errorf("suggested fixes failed for %s:\n%s", u.Filename(), diff) -- } -- } --} -- --func (r *runner) MethodExtraction(t *testing.T, start span.Span, end span.Span) { -- uri := start.URI() -- m, err := r.data.Mapper(uri) -- if err != nil { -- t.Fatal(err) -- } -- spn := span.New(start.URI(), start.Start(), end.End()) -- rng, err := m.SpanRange(spn) -- if err != nil { -- t.Fatal(err) -- } -- actionsRaw, err := r.server.CodeAction(r.ctx, &protocol.CodeActionParams{ -- TextDocument: protocol.TextDocumentIdentifier{ -- URI: protocol.URIFromSpanURI(uri), -- }, -- Range: rng, -- Context: protocol.CodeActionContext{ -- Only: []protocol.CodeActionKind{"refactor.extract"}, -- }, -- }) -- if err != nil { -- t.Fatal(err) -- } -- var actions []protocol.CodeAction -- for _, action := range actionsRaw { -- if action.Command.Title == "Extract method" { -- actions = append(actions, action) -- } -- } -- // Hack: We assume that we only get one matching code action per range. -- // TODO(rstambler): Support multiple code actions per test. -- if len(actions) == 0 || len(actions) > 1 { -- t.Fatalf("unexpected number of code actions, want 1, got %v", len(actions)) -- } -- _, err = r.server.ExecuteCommand(r.ctx, &protocol.ExecuteCommandParams{ -- Command: actions[0].Command.Command, -- Arguments: actions[0].Command.Arguments, -- }) -- if err != nil { -- t.Fatal(err) -- } -- res := <-r.editRecv -- for u, got := range res { -- want := r.data.Golden(t, "methodextraction_"+tests.SpanName(spn), u.Filename(), func() ([]byte, error) { -- return got, nil -- }) -- if diff := compare.Bytes(want, got); diff != "" { -- t.Errorf("method extraction failed for %s:\n%s", u.Filename(), diff) -- } -- } --} -- --func (r *runner) InlayHints(t *testing.T, spn span.Span) { -- uri := spn.URI() -- filename := uri.Filename() -- -- hints, err := r.server.InlayHint(r.ctx, &protocol.InlayHintParams{ -- TextDocument: protocol.TextDocumentIdentifier{ -- URI: protocol.URIFromSpanURI(uri), -- }, -- // TODO: add Range -- }) -- if err != nil { -- t.Fatal(err) -- } -- -- // Map inlay hints to text edits. -- edits := make([]protocol.TextEdit, len(hints)) -- for i, hint := range hints { -- var paddingLeft, paddingRight string -- if hint.PaddingLeft { -- paddingLeft = " " -- } -- if hint.PaddingRight { -- paddingRight = " " -- } -- edits[i] = protocol.TextEdit{ -- Range: protocol.Range{Start: hint.Position, End: hint.Position}, -- NewText: fmt.Sprintf("<%s%s%s>", paddingLeft, hint.Label[0].Value, paddingRight), -- } -- } -- -- m, err := r.data.Mapper(uri) -- if err != nil { -- t.Fatal(err) -- } -- got, _, err := source.ApplyProtocolEdits(m, edits) -- if err != nil { -- t.Error(err) -- } -- -- withinlayHints := r.data.Golden(t, "inlayHint", filename, func() ([]byte, error) { -- return got, nil -- }) -- -- if !bytes.Equal(withinlayHints, got) { -- t.Errorf("inlay hints failed for %s, expected:\n%s\ngot:\n%s", filename, withinlayHints, got) -- } --} -- --func (r *runner) Rename(t *testing.T, spn span.Span, newText string) { -- tag := fmt.Sprintf("%s-rename", newText) -- -- uri := spn.URI() -- filename := uri.Filename() -- sm, err := r.data.Mapper(uri) -- if err != nil { -- t.Fatal(err) -- } -- loc, err := sm.SpanLocation(spn) -- if err != nil { -- t.Fatalf("failed for %v: %v", spn, err) -- } -- -- wedit, err := r.server.Rename(r.ctx, &protocol.RenameParams{ -- TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI}, -- Position: loc.Range.Start, -- NewName: newText, -- }) -- if err != nil { -- renamed := string(r.data.Golden(t, tag, filename, func() ([]byte, error) { -- return []byte(err.Error()), nil -- })) -- if err.Error() != renamed { -- t.Errorf("%s: rename failed for %s, expected:\n%v\ngot:\n%v\n", spn, newText, renamed, err) -- } -- return -- } -- res, err := applyTextDocumentEdits(r, wedit.DocumentChanges) -- if err != nil { -- t.Fatal(err) -- } -- var orderedURIs []string -- for uri := range res { -- orderedURIs = append(orderedURIs, string(uri)) -- } -- sort.Strings(orderedURIs) -- -- // Print the name and content of each modified file, -- // concatenated, and compare against the golden. -- var buf bytes.Buffer -- for i := 0; i < len(res); i++ { -- if i != 0 { -- buf.WriteByte('\n') -- } -- uri := span.URIFromURI(orderedURIs[i]) -- if len(res) > 1 { -- buf.WriteString(filepath.Base(uri.Filename())) -- buf.WriteString(":\n") -- } -- buf.Write(res[uri]) -- } -- got := buf.Bytes() -- want := r.data.Golden(t, tag, filename, func() ([]byte, error) { -- return got, nil -- }) -- if diff := compare.Bytes(want, got); diff != "" { -- t.Errorf("rename failed for %s:\n%s", newText, diff) -- } --} -- --func (r *runner) PrepareRename(t *testing.T, src span.Span, want *source.PrepareItem) { -- m, err := r.data.Mapper(src.URI()) -- if err != nil { -- t.Fatal(err) -- } -- loc, err := m.SpanLocation(src) -- if err != nil { -- t.Fatalf("failed for %v: %v", src, err) -- } -- params := &protocol.PrepareRenameParams{ -- TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(loc), -- } -- got, err := r.server.PrepareRename(context.Background(), params) -- if err != nil { -- t.Errorf("prepare rename failed for %v: got error: %v", src, err) -- return -- } -- -- // TODO(rfindley): can we consolidate on a single representation for -- // PrepareRename results, and use cmp.Diff here? -- -- // PrepareRename may fail with no error if there was no object found at the -- // position. -- if got == nil { -- if want.Text != "" { // expected an ident. -- t.Errorf("prepare rename failed for %v: got nil", src) -- } -- return -- } -- if got.Range.Start == got.Range.End { -- // Special case for 0-length ranges. Marks can't specify a 0-length range, -- // so just compare the start. -- if got.Range.Start != want.Range.Start { -- t.Errorf("prepare rename failed: incorrect point, got %v want %v", got.Range.Start, want.Range.Start) -- } -- } else { -- if got.Range != want.Range { -- t.Errorf("prepare rename failed: incorrect range got %v want %v", got.Range, want.Range) -- } -- } -- if got.Placeholder != want.Text { -- t.Errorf("prepare rename failed: incorrect text got %v want %v", got.Placeholder, want.Text) -- } --} -- --func applyTextDocumentEdits(r *runner, edits []protocol.DocumentChanges) (map[span.URI][]byte, error) { -- res := make(map[span.URI][]byte) -- for _, docEdits := range edits { -- if docEdits.TextDocumentEdit != nil { -- uri := docEdits.TextDocumentEdit.TextDocument.URI.SpanURI() -- var m *protocol.Mapper -- // If we have already edited this file, we use the edited version (rather than the -- // file in its original state) so that we preserve our initial changes. -- if content, ok := res[uri]; ok { -- m = protocol.NewMapper(uri, content) -- } else { -- var err error -- if m, err = r.data.Mapper(uri); err != nil { -- return nil, err -- } -- } -- patched, _, err := source.ApplyProtocolEdits(m, docEdits.TextDocumentEdit.Edits) -- if err != nil { -- return nil, err -- } -- res[uri] = patched -- } -- } -- return res, nil --} -- --func (r *runner) SignatureHelp(t *testing.T, spn span.Span, want *protocol.SignatureHelp) { -- m, err := r.data.Mapper(spn.URI()) -- if err != nil { -- t.Fatal(err) -- } -- loc, err := m.SpanLocation(spn) -- if err != nil { -- t.Fatalf("failed for %v: %v", loc, err) -- } -- params := &protocol.SignatureHelpParams{ -- TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(loc), -- } -- got, err := r.server.SignatureHelp(r.ctx, params) -- if err != nil { -- // Only fail if we got an error we did not expect. -- if want != nil { -- t.Fatal(err) -- } -- return -- } -- if want == nil { -- if got != nil { -- t.Errorf("expected no signature, got %v", got) -- } -- return -- } -- if got == nil { -- t.Fatalf("expected %v, got nil", want) -- } -- if diff := tests.DiffSignatures(spn, want, got); diff != "" { -- t.Error(diff) -- } --} -- --func (r *runner) Link(t *testing.T, uri span.URI, wantLinks []tests.Link) { -- m, err := r.data.Mapper(uri) -- if err != nil { -- t.Fatal(err) -- } -- got, err := r.server.DocumentLink(r.ctx, &protocol.DocumentLinkParams{ -- TextDocument: protocol.TextDocumentIdentifier{ -- URI: protocol.URIFromSpanURI(uri), -- }, -- }) -- if err != nil { -- t.Fatal(err) -- } -- if diff := tests.DiffLinks(m, wantLinks, got); diff != "" { -- t.Error(diff) -- } --} -- --func (r *runner) AddImport(t *testing.T, uri span.URI, expectedImport string) { -- cmd, err := command.NewListKnownPackagesCommand("List Known Packages", command.URIArg{ -- URI: protocol.URIFromSpanURI(uri), -- }) -- if err != nil { -- t.Fatal(err) -- } -- resp, err := r.server.executeCommand(r.ctx, &protocol.ExecuteCommandParams{ -- Command: cmd.Command, -- Arguments: cmd.Arguments, -- }) -- if err != nil { -- t.Fatal(err) -- } -- res := resp.(command.ListKnownPackagesResult) -- var hasPkg bool -- for _, p := range res.Packages { -- if p == expectedImport { -- hasPkg = true -- break -- } -- } -- if !hasPkg { -- t.Fatalf("%s: got %v packages\nwant contains %q", command.ListKnownPackages, res.Packages, expectedImport) -- } -- cmd, err = command.NewAddImportCommand("Add Imports", command.AddImportArgs{ -- URI: protocol.URIFromSpanURI(uri), -- ImportPath: expectedImport, -- }) -- if err != nil { -- t.Fatal(err) -- } -- _, err = r.server.executeCommand(r.ctx, &protocol.ExecuteCommandParams{ -- Command: cmd.Command, -- Arguments: cmd.Arguments, -- }) -- if err != nil { -- t.Fatal(err) -- } -- got := (<-r.editRecv)[uri] -- want := r.data.Golden(t, "addimport", uri.Filename(), func() ([]byte, error) { -- return []byte(got), nil -- }) -- if want == nil { -- t.Fatalf("golden file %q not found", uri.Filename()) -- } -- if diff := compare.Bytes(want, got); diff != "" { -- t.Errorf("%s mismatch\n%s", command.AddImport, diff) -- } --} -- --func (r *runner) SelectionRanges(t *testing.T, spn span.Span) { -- uri := spn.URI() -- sm, err := r.data.Mapper(uri) -- if err != nil { -- t.Fatal(err) -- } -- loc, err := sm.SpanLocation(spn) -- if err != nil { -- t.Error(err) -- } -- -- ranges, err := r.server.selectionRange(r.ctx, &protocol.SelectionRangeParams{ -- TextDocument: protocol.TextDocumentIdentifier{ -- URI: protocol.URIFromSpanURI(uri), -- }, -- Positions: []protocol.Position{loc.Range.Start}, -- }) -- if err != nil { -- t.Fatal(err) -- } -- -- sb := &strings.Builder{} -- for i, path := range ranges { -- fmt.Fprintf(sb, "Ranges %d: ", i) -- rng := path -- for { -- s, e, err := sm.RangeOffsets(rng.Range) -- if err != nil { -- t.Error(err) -- } -- -- var snippet string -- if e-s < 30 { -- snippet = string(sm.Content[s:e]) -- } else { -- snippet = string(sm.Content[s:s+15]) + "..." + string(sm.Content[e-15:e]) -- } -- -- fmt.Fprintf(sb, "\n\t%v %q", rng.Range, strings.ReplaceAll(snippet, "\n", "\\n")) -- -- if rng.Parent == nil { -- break -- } -- rng = *rng.Parent -- } -- sb.WriteRune('\n') -- } -- got := sb.String() -- -- testName := "selectionrange_" + tests.SpanName(spn) -- want := r.data.Golden(t, testName, uri.Filename(), func() ([]byte, error) { -- return []byte(got), nil -- }) -- if want == nil { -- t.Fatalf("golden file %q not found", uri.Filename()) -- } -- if diff := compare.Text(got, string(want)); diff != "" { -- t.Errorf("%s mismatch\n%s", testName, diff) -- } --} -- --func (r *runner) collectDiagnostics(view *cache.View) { -- if r.diagnostics != nil { -- return -- } -- r.diagnostics = make(map[span.URI][]*source.Diagnostic) -- -- snapshot, release, err := view.Snapshot() -- if err != nil { -- panic(err) -- } -- defer release() -- -- // Always run diagnostics with analysis. -- r.server.diagnose(r.ctx, snapshot, analyzeEverything) -- for uri, reports := range r.server.diagnostics { -- for _, report := range reports.reports { -- for _, d := range report.diags { -- r.diagnostics[uri] = append(r.diagnostics[uri], d) -- } -- } -- } --} diff -urN a/gopls/internal/lsp/lsprpc/autostart_default.go b/gopls/internal/lsp/lsprpc/autostart_default.go --- a/gopls/internal/lsp/lsprpc/autostart_default.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lsprpc/autostart_default.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/lsprpc/autostart_default.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -47776,7 +47132,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/autostart_default.go b/gopls/internal/lsp/ -} diff -urN a/gopls/internal/lsp/lsprpc/autostart_posix.go b/gopls/internal/lsp/lsprpc/autostart_posix.go --- a/gopls/internal/lsp/lsprpc/autostart_posix.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lsprpc/autostart_posix.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/lsprpc/autostart_posix.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -47877,7 +47233,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/autostart_posix.go b/gopls/internal/lsp/ls -} diff -urN a/gopls/internal/lsp/lsprpc/binder.go b/gopls/internal/lsp/lsprpc/binder.go --- a/gopls/internal/lsp/lsprpc/binder.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lsprpc/binder.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/lsprpc/binder.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,148 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -48029,7 +47385,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/binder.go b/gopls/internal/lsp/lsprpc/bind -} diff -urN a/gopls/internal/lsp/lsprpc/binder_test.go b/gopls/internal/lsp/lsprpc/binder_test.go --- a/gopls/internal/lsp/lsprpc/binder_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lsprpc/binder_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/lsprpc/binder_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -48180,7 +47536,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/binder_test.go b/gopls/internal/lsp/lsprpc -} diff -urN a/gopls/internal/lsp/lsprpc/commandinterceptor.go b/gopls/internal/lsp/lsprpc/commandinterceptor.go --- a/gopls/internal/lsp/lsprpc/commandinterceptor.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lsprpc/commandinterceptor.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/lsprpc/commandinterceptor.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -48228,7 +47584,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/commandinterceptor.go b/gopls/internal/lsp -} diff -urN a/gopls/internal/lsp/lsprpc/commandinterceptor_test.go b/gopls/internal/lsp/lsprpc/commandinterceptor_test.go --- a/gopls/internal/lsp/lsprpc/commandinterceptor_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lsprpc/commandinterceptor_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/lsprpc/commandinterceptor_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -48274,7 +47630,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/commandinterceptor_test.go b/gopls/interna -} diff -urN a/gopls/internal/lsp/lsprpc/dialer.go b/gopls/internal/lsp/lsprpc/dialer.go --- a/gopls/internal/lsp/lsprpc/dialer.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lsprpc/dialer.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/lsprpc/dialer.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,114 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -48392,7 +47748,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/dialer.go b/gopls/internal/lsp/lsprpc/dial -} diff -urN a/gopls/internal/lsp/lsprpc/goenv.go b/gopls/internal/lsp/lsprpc/goenv.go --- a/gopls/internal/lsp/lsprpc/goenv.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lsprpc/goenv.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/lsprpc/goenv.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -48492,7 +47848,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/goenv.go b/gopls/internal/lsp/lsprpc/goenv -} diff -urN a/gopls/internal/lsp/lsprpc/goenv_test.go b/gopls/internal/lsp/lsprpc/goenv_test.go --- a/gopls/internal/lsp/lsprpc/goenv_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lsprpc/goenv_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/lsprpc/goenv_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -48564,7 +47920,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/goenv_test.go b/gopls/internal/lsp/lsprpc/ -} diff -urN a/gopls/internal/lsp/lsprpc/lsprpc.go b/gopls/internal/lsp/lsprpc/lsprpc.go --- a/gopls/internal/lsp/lsprpc/lsprpc.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lsprpc/lsprpc.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/lsprpc/lsprpc.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,545 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -49113,7 +48469,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/lsprpc.go b/gopls/internal/lsp/lsprpc/lspr -} diff -urN a/gopls/internal/lsp/lsprpc/lsprpc_test.go b/gopls/internal/lsp/lsprpc/lsprpc_test.go --- a/gopls/internal/lsp/lsprpc/lsprpc_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lsprpc/lsprpc_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/lsprpc/lsprpc_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,376 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -49493,7 +48849,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/lsprpc_test.go b/gopls/internal/lsp/lsprpc -} diff -urN a/gopls/internal/lsp/lsprpc/middleware.go b/gopls/internal/lsp/lsprpc/middleware.go --- a/gopls/internal/lsp/lsprpc/middleware.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lsprpc/middleware.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/lsprpc/middleware.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,142 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -49639,7 +48995,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/middleware.go b/gopls/internal/lsp/lsprpc/ -} diff -urN a/gopls/internal/lsp/lsprpc/middleware_test.go b/gopls/internal/lsp/lsprpc/middleware_test.go --- a/gopls/internal/lsp/lsprpc/middleware_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/lsprpc/middleware_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/lsprpc/middleware_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -49734,9 +49090,629 @@ diff -urN a/gopls/internal/lsp/lsprpc/middleware_test.go b/gopls/internal/lsp/ls - delay *= 4 - } -} +diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go +--- a/gopls/internal/lsp/lsp_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/lsp_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,616 +0,0 @@ +-// Copyright 2018 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 lsp +- +-import ( +- "bytes" +- "context" +- "fmt" +- "os" +- "path/filepath" +- "sort" +- "strings" +- "testing" +- +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/lsp/cache" +- "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp/debug" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/lsp/tests" +- "golang.org/x/tools/gopls/internal/lsp/tests/compare" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/testenv" +-) +- +-func TestMain(m *testing.M) { +- bug.PanicOnBugs = true +- testenv.ExitIfSmallMachine() +- +- os.Exit(m.Run()) +-} +- +-// TestLSP runs the marker tests in files beneath testdata/ using +-// implementations of each of the marker operations that make LSP RPCs to a +-// gopls server. +-func TestLSP(t *testing.T) { +- tests.RunTests(t, "testdata", true, testLSP) +-} +- +-func testLSP(t *testing.T, datum *tests.Data) { +- ctx := tests.Context(t) +- +- // Setting a debug instance suppresses logging to stderr, but ensures that we +- // still e.g. convert events into runtime/trace/instrumentation. +- // +- // Previously, we called event.SetExporter(nil), which turns off all +- // instrumentation. +- ctx = debug.WithInstance(ctx, "", "off") +- +- session := cache.NewSession(ctx, cache.New(nil)) +- options := source.DefaultOptions(tests.DefaultOptions) +- options.SetEnvSlice(datum.Config.Env) +- folder := &cache.Folder{ +- Dir: span.URIFromPath(datum.Config.Dir), +- Name: datum.Config.Dir, +- Options: options, +- } +- view, snapshot, release, err := session.NewView(ctx, folder) +- if err != nil { +- t.Fatal(err) +- } +- +- defer session.RemoveView(view) +- +- // Only run the -modfile specific tests in module mode with Go 1.14 or above. +- datum.ModfileFlagAvailable = len(snapshot.ModFiles()) > 0 && testenv.Go1Point() >= 14 +- release() +- +- // Open all files for performance reasons, because gopls only +- // keeps active packages (those with open files) in memory. +- // +- // In practice clients will only send document-oriented requests for open +- // files. +- var modifications []source.FileModification +- for _, module := range datum.Exported.Modules { +- for name := range module.Files { +- filename := datum.Exported.File(module.Name, name) +- if filepath.Ext(filename) != ".go" { +- continue +- } +- content, err := datum.Exported.FileContents(filename) +- if err != nil { +- t.Fatal(err) +- } +- modifications = append(modifications, source.FileModification{ +- URI: span.URIFromPath(filename), +- Action: source.Open, +- Version: -1, +- Text: content, +- LanguageID: "go", +- }) +- } +- } +- for filename, content := range datum.Config.Overlay { +- if filepath.Ext(filename) != ".go" { +- continue +- } +- modifications = append(modifications, source.FileModification{ +- URI: span.URIFromPath(filename), +- Action: source.Open, +- Version: -1, +- Text: content, +- LanguageID: "go", +- }) +- } +- if err := session.ModifyFiles(ctx, modifications); err != nil { +- t.Fatal(err) +- } +- r := &runner{ +- data: datum, +- ctx: ctx, +- editRecv: make(chan map[span.URI][]byte, 1), +- } +- +- r.server = NewServer(session, testClient{runner: r}, options) +- tests.Run(t, r, datum) +-} +- +-// runner implements tests.Tests by making LSP RPCs to a gopls server. +-type runner struct { +- server *Server +- data *tests.Data +- diagnostics map[span.URI][]*source.Diagnostic +- ctx context.Context +- editRecv chan map[span.URI][]byte +-} +- +-// testClient stubs any client functions that may be called by LSP functions. +-type testClient struct { +- protocol.Client +- runner *runner +-} +- +-func (c testClient) Close() error { +- return nil +-} +- +-// Trivially implement PublishDiagnostics so that we can call +-// server.publishReports below to de-dup sent diagnostics. +-func (c testClient) PublishDiagnostics(context.Context, *protocol.PublishDiagnosticsParams) error { +- return nil +-} +- +-func (c testClient) ShowMessage(context.Context, *protocol.ShowMessageParams) error { +- return nil +-} +- +-func (c testClient) ApplyEdit(ctx context.Context, params *protocol.ApplyWorkspaceEditParams) (*protocol.ApplyWorkspaceEditResult, error) { +- res, err := applyTextDocumentEdits(c.runner, params.Edit.DocumentChanges) +- if err != nil { +- return nil, err +- } +- c.runner.editRecv <- res +- return &protocol.ApplyWorkspaceEditResult{Applied: true}, nil +-} +- +-func (r *runner) CallHierarchy(t *testing.T, spn span.Span, expectedCalls *tests.CallHierarchyResult) { +- mapper, err := r.data.Mapper(spn.URI()) +- if err != nil { +- t.Fatal(err) +- } +- loc, err := mapper.SpanLocation(spn) +- if err != nil { +- t.Fatalf("failed for %v: %v", spn, err) +- } +- +- params := &protocol.CallHierarchyPrepareParams{ +- TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(loc), +- } +- +- items, err := r.server.PrepareCallHierarchy(r.ctx, params) +- if err != nil { +- t.Fatal(err) +- } +- if len(items) == 0 { +- t.Fatalf("expected call hierarchy item to be returned for identifier at %v\n", loc.Range) +- } +- +- callLocation := protocol.Location{ +- URI: items[0].URI, +- Range: items[0].Range, +- } +- if callLocation != loc { +- t.Fatalf("expected server.PrepareCallHierarchy to return identifier at %v but got %v\n", loc, callLocation) +- } +- +- incomingCalls, err := r.server.IncomingCalls(r.ctx, &protocol.CallHierarchyIncomingCallsParams{Item: items[0]}) +- if err != nil { +- t.Error(err) +- } +- var incomingCallItems []protocol.CallHierarchyItem +- for _, item := range incomingCalls { +- incomingCallItems = append(incomingCallItems, item.From) +- } +- msg := tests.DiffCallHierarchyItems(incomingCallItems, expectedCalls.IncomingCalls) +- if msg != "" { +- t.Errorf("incoming calls: %s", msg) +- } +- +- outgoingCalls, err := r.server.OutgoingCalls(r.ctx, &protocol.CallHierarchyOutgoingCallsParams{Item: items[0]}) +- if err != nil { +- t.Error(err) +- } +- var outgoingCallItems []protocol.CallHierarchyItem +- for _, item := range outgoingCalls { +- outgoingCallItems = append(outgoingCallItems, item.To) +- } +- msg = tests.DiffCallHierarchyItems(outgoingCallItems, expectedCalls.OutgoingCalls) +- if msg != "" { +- t.Errorf("outgoing calls: %s", msg) +- } +-} +- +-func (r *runner) SemanticTokens(t *testing.T, spn span.Span) { +- uri := spn.URI() +- filename := uri.Filename() +- // this is called solely for coverage in semantic.go +- _, err := r.server.semanticTokensFull(r.ctx, &protocol.SemanticTokensParams{ +- TextDocument: protocol.TextDocumentIdentifier{ +- URI: protocol.URIFromSpanURI(uri), +- }, +- }) +- if err != nil { +- t.Errorf("%v for %s", err, filename) +- } +- _, err = r.server.semanticTokensRange(r.ctx, &protocol.SemanticTokensRangeParams{ +- TextDocument: protocol.TextDocumentIdentifier{ +- URI: protocol.URIFromSpanURI(uri), +- }, +- // any legal range. Just to exercise the call. +- Range: protocol.Range{ +- Start: protocol.Position{ +- Line: 0, +- Character: 0, +- }, +- End: protocol.Position{ +- Line: 2, +- Character: 0, +- }, +- }, +- }) +- if err != nil { +- t.Errorf("%v for Range %s", err, filename) +- } +-} +- +-func (r *runner) SuggestedFix(t *testing.T, spn span.Span, actionKinds []tests.SuggestedFix, expectedActions int) { +- uri := spn.URI() +- view, err := r.server.session.ViewOf(uri) +- if err != nil { +- t.Fatal(err) +- } +- +- m, err := r.data.Mapper(uri) +- if err != nil { +- t.Fatal(err) +- } +- rng, err := m.SpanRange(spn) +- if err != nil { +- t.Fatal(err) +- } +- // Get the diagnostics for this view if we have not done it before. +- r.collectDiagnostics(view) +- var diagnostics []protocol.Diagnostic +- for _, d := range r.diagnostics[uri] { +- // Compare the start positions rather than the entire range because +- // some diagnostics have a range with the same start and end position (8:1-8:1). +- // The current marker functionality prevents us from having a range of 0 length. +- if protocol.ComparePosition(d.Range.Start, rng.Start) == 0 { +- diagnostics = append(diagnostics, toProtocolDiagnostics([]*source.Diagnostic{d})...) +- break +- } +- } +- var codeActionKinds []protocol.CodeActionKind +- for _, k := range actionKinds { +- codeActionKinds = append(codeActionKinds, protocol.CodeActionKind(k.ActionKind)) +- } +- allActions, err := r.server.CodeAction(r.ctx, &protocol.CodeActionParams{ +- TextDocument: protocol.TextDocumentIdentifier{ +- URI: protocol.URIFromSpanURI(uri), +- }, +- Range: rng, +- Context: protocol.CodeActionContext{ +- Only: codeActionKinds, +- Diagnostics: diagnostics, +- }, +- }) +- if err != nil { +- t.Fatalf("CodeAction %s failed: %v", spn, err) +- } +- var actions []protocol.CodeAction +- for _, action := range allActions { +- for _, fix := range actionKinds { +- if strings.Contains(action.Title, fix.Title) { +- actions = append(actions, action) +- break +- } +- } +- +- } +- if len(actions) != expectedActions { +- var summaries []string +- for _, a := range actions { +- summaries = append(summaries, fmt.Sprintf("%q (%s)", a.Title, a.Kind)) +- } +- t.Fatalf("CodeAction(...): got %d code actions (%v), want %d", len(actions), summaries, expectedActions) +- } +- action := actions[0] +- var match bool +- for _, k := range codeActionKinds { +- if action.Kind == k { +- match = true +- break +- } +- } +- if !match { +- t.Fatalf("unexpected kind for code action %s, got %v, want one of %v", action.Title, action.Kind, codeActionKinds) +- } +- var res map[span.URI][]byte +- if cmd := action.Command; cmd != nil { +- _, err := r.server.ExecuteCommand(r.ctx, &protocol.ExecuteCommandParams{ +- Command: action.Command.Command, +- Arguments: action.Command.Arguments, +- }) +- if err != nil { +- t.Fatalf("error converting command %q to edits: %v", action.Command.Command, err) +- } +- res = <-r.editRecv +- } else { +- res, err = applyTextDocumentEdits(r, action.Edit.DocumentChanges) +- if err != nil { +- t.Fatal(err) +- } +- } +- for u, got := range res { +- want := r.data.Golden(t, "suggestedfix_"+tests.SpanName(spn), u.Filename(), func() ([]byte, error) { +- return got, nil +- }) +- if diff := compare.Bytes(want, got); diff != "" { +- t.Errorf("suggested fixes failed for %s:\n%s", u.Filename(), diff) +- } +- } +-} +- +-func (r *runner) InlayHints(t *testing.T, spn span.Span) { +- uri := spn.URI() +- filename := uri.Filename() +- +- hints, err := r.server.InlayHint(r.ctx, &protocol.InlayHintParams{ +- TextDocument: protocol.TextDocumentIdentifier{ +- URI: protocol.URIFromSpanURI(uri), +- }, +- // TODO: add Range +- }) +- if err != nil { +- t.Fatal(err) +- } +- +- // Map inlay hints to text edits. +- edits := make([]protocol.TextEdit, len(hints)) +- for i, hint := range hints { +- var paddingLeft, paddingRight string +- if hint.PaddingLeft { +- paddingLeft = " " +- } +- if hint.PaddingRight { +- paddingRight = " " +- } +- edits[i] = protocol.TextEdit{ +- Range: protocol.Range{Start: hint.Position, End: hint.Position}, +- NewText: fmt.Sprintf("<%s%s%s>", paddingLeft, hint.Label[0].Value, paddingRight), +- } +- } +- +- m, err := r.data.Mapper(uri) +- if err != nil { +- t.Fatal(err) +- } +- got, _, err := source.ApplyProtocolEdits(m, edits) +- if err != nil { +- t.Error(err) +- } +- +- withinlayHints := r.data.Golden(t, "inlayHint", filename, func() ([]byte, error) { +- return got, nil +- }) +- +- if !bytes.Equal(withinlayHints, got) { +- t.Errorf("inlay hints failed for %s, expected:\n%s\ngot:\n%s", filename, withinlayHints, got) +- } +-} +- +-func (r *runner) Rename(t *testing.T, spn span.Span, newText string) { +- tag := fmt.Sprintf("%s-rename", newText) +- +- uri := spn.URI() +- filename := uri.Filename() +- sm, err := r.data.Mapper(uri) +- if err != nil { +- t.Fatal(err) +- } +- loc, err := sm.SpanLocation(spn) +- if err != nil { +- t.Fatalf("failed for %v: %v", spn, err) +- } +- +- wedit, err := r.server.Rename(r.ctx, &protocol.RenameParams{ +- TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI}, +- Position: loc.Range.Start, +- NewName: newText, +- }) +- if err != nil { +- renamed := string(r.data.Golden(t, tag, filename, func() ([]byte, error) { +- return []byte(err.Error()), nil +- })) +- if err.Error() != renamed { +- t.Errorf("%s: rename failed for %s, expected:\n%v\ngot:\n%v\n", spn, newText, renamed, err) +- } +- return +- } +- res, err := applyTextDocumentEdits(r, wedit.DocumentChanges) +- if err != nil { +- t.Fatal(err) +- } +- var orderedURIs []string +- for uri := range res { +- orderedURIs = append(orderedURIs, string(uri)) +- } +- sort.Strings(orderedURIs) +- +- // Print the name and content of each modified file, +- // concatenated, and compare against the golden. +- var buf bytes.Buffer +- for i := 0; i < len(res); i++ { +- if i != 0 { +- buf.WriteByte('\n') +- } +- uri := span.URIFromURI(orderedURIs[i]) +- if len(res) > 1 { +- buf.WriteString(filepath.Base(uri.Filename())) +- buf.WriteString(":\n") +- } +- buf.Write(res[uri]) +- } +- got := buf.Bytes() +- want := r.data.Golden(t, tag, filename, func() ([]byte, error) { +- return got, nil +- }) +- if diff := compare.Bytes(want, got); diff != "" { +- t.Errorf("rename failed for %s:\n%s", newText, diff) +- } +-} +- +-func applyTextDocumentEdits(r *runner, edits []protocol.DocumentChanges) (map[span.URI][]byte, error) { +- res := make(map[span.URI][]byte) +- for _, docEdits := range edits { +- if docEdits.TextDocumentEdit != nil { +- uri := docEdits.TextDocumentEdit.TextDocument.URI.SpanURI() +- var m *protocol.Mapper +- // If we have already edited this file, we use the edited version (rather than the +- // file in its original state) so that we preserve our initial changes. +- if content, ok := res[uri]; ok { +- m = protocol.NewMapper(uri, content) +- } else { +- var err error +- if m, err = r.data.Mapper(uri); err != nil { +- return nil, err +- } +- } +- patched, _, err := source.ApplyProtocolEdits(m, docEdits.TextDocumentEdit.Edits) +- if err != nil { +- return nil, err +- } +- res[uri] = patched +- } +- } +- return res, nil +-} +- +-func (r *runner) AddImport(t *testing.T, uri span.URI, expectedImport string) { +- cmd, err := command.NewListKnownPackagesCommand("List Known Packages", command.URIArg{ +- URI: protocol.URIFromSpanURI(uri), +- }) +- if err != nil { +- t.Fatal(err) +- } +- resp, err := r.server.executeCommand(r.ctx, &protocol.ExecuteCommandParams{ +- Command: cmd.Command, +- Arguments: cmd.Arguments, +- }) +- if err != nil { +- t.Fatal(err) +- } +- res := resp.(command.ListKnownPackagesResult) +- var hasPkg bool +- for _, p := range res.Packages { +- if p == expectedImport { +- hasPkg = true +- break +- } +- } +- if !hasPkg { +- t.Fatalf("%s: got %v packages\nwant contains %q", command.ListKnownPackages, res.Packages, expectedImport) +- } +- cmd, err = command.NewAddImportCommand("Add Imports", command.AddImportArgs{ +- URI: protocol.URIFromSpanURI(uri), +- ImportPath: expectedImport, +- }) +- if err != nil { +- t.Fatal(err) +- } +- _, err = r.server.executeCommand(r.ctx, &protocol.ExecuteCommandParams{ +- Command: cmd.Command, +- Arguments: cmd.Arguments, +- }) +- if err != nil { +- t.Fatal(err) +- } +- got := (<-r.editRecv)[uri] +- want := r.data.Golden(t, "addimport", uri.Filename(), func() ([]byte, error) { +- return []byte(got), nil +- }) +- if want == nil { +- t.Fatalf("golden file %q not found", uri.Filename()) +- } +- if diff := compare.Bytes(want, got); diff != "" { +- t.Errorf("%s mismatch\n%s", command.AddImport, diff) +- } +-} +- +-func (r *runner) SelectionRanges(t *testing.T, spn span.Span) { +- uri := spn.URI() +- sm, err := r.data.Mapper(uri) +- if err != nil { +- t.Fatal(err) +- } +- loc, err := sm.SpanLocation(spn) +- if err != nil { +- t.Error(err) +- } +- +- ranges, err := r.server.selectionRange(r.ctx, &protocol.SelectionRangeParams{ +- TextDocument: protocol.TextDocumentIdentifier{ +- URI: protocol.URIFromSpanURI(uri), +- }, +- Positions: []protocol.Position{loc.Range.Start}, +- }) +- if err != nil { +- t.Fatal(err) +- } +- +- sb := &strings.Builder{} +- for i, path := range ranges { +- fmt.Fprintf(sb, "Ranges %d: ", i) +- rng := path +- for { +- s, e, err := sm.RangeOffsets(rng.Range) +- if err != nil { +- t.Error(err) +- } +- +- var snippet string +- if e-s < 30 { +- snippet = string(sm.Content[s:e]) +- } else { +- snippet = string(sm.Content[s:s+15]) + "..." + string(sm.Content[e-15:e]) +- } +- +- fmt.Fprintf(sb, "\n\t%v %q", rng.Range, strings.ReplaceAll(snippet, "\n", "\\n")) +- +- if rng.Parent == nil { +- break +- } +- rng = *rng.Parent +- } +- sb.WriteRune('\n') +- } +- got := sb.String() +- +- testName := "selectionrange_" + tests.SpanName(spn) +- want := r.data.Golden(t, testName, uri.Filename(), func() ([]byte, error) { +- return []byte(got), nil +- }) +- if want == nil { +- t.Fatalf("golden file %q not found", uri.Filename()) +- } +- if diff := compare.Text(got, string(want)); diff != "" { +- t.Errorf("%s mismatch\n%s", testName, diff) +- } +-} +- +-func (r *runner) collectDiagnostics(view *cache.View) { +- if r.diagnostics != nil { +- return +- } +- r.diagnostics = make(map[span.URI][]*source.Diagnostic) +- +- snapshot, release, err := view.Snapshot() +- if err != nil { +- panic(err) +- } +- defer release() +- +- // Always run diagnostics with analysis. +- r.server.diagnose(r.ctx, snapshot, analyzeEverything) +- for uri, reports := range r.server.diagnostics { +- for _, report := range reports.reports { +- for _, d := range report.diags { +- r.diagnostics[uri] = append(r.diagnostics[uri], d) +- } +- } +- } +-} diff -urN a/gopls/internal/lsp/mod/code_lens.go b/gopls/internal/lsp/mod/code_lens.go --- a/gopls/internal/lsp/mod/code_lens.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/mod/code_lens.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/mod/code_lens.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,191 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -49931,7 +49907,7 @@ diff -urN a/gopls/internal/lsp/mod/code_lens.go b/gopls/internal/lsp/mod/code_le -} diff -urN a/gopls/internal/lsp/mod/diagnostics.go b/gopls/internal/lsp/mod/diagnostics.go --- a/gopls/internal/lsp/mod/diagnostics.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/mod/diagnostics.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/mod/diagnostics.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,559 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -50494,7 +50470,7 @@ diff -urN a/gopls/internal/lsp/mod/diagnostics.go b/gopls/internal/lsp/mod/diagn -} diff -urN a/gopls/internal/lsp/mod/format.go b/gopls/internal/lsp/mod/format.go --- a/gopls/internal/lsp/mod/format.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/mod/format.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/mod/format.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -50528,7 +50504,7 @@ diff -urN a/gopls/internal/lsp/mod/format.go b/gopls/internal/lsp/mod/format.go -} diff -urN a/gopls/internal/lsp/mod/hover.go b/gopls/internal/lsp/mod/hover.go --- a/gopls/internal/lsp/mod/hover.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/mod/hover.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/mod/hover.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,378 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -50910,7 +50886,7 @@ diff -urN a/gopls/internal/lsp/mod/hover.go b/gopls/internal/lsp/mod/hover.go -} diff -urN a/gopls/internal/lsp/mod/inlayhint.go b/gopls/internal/lsp/mod/inlayhint.go --- a/gopls/internal/lsp/mod/inlayhint.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/mod/inlayhint.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/mod/inlayhint.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -51014,7 +50990,7 @@ diff -urN a/gopls/internal/lsp/mod/inlayhint.go b/gopls/internal/lsp/mod/inlayhi -} diff -urN a/gopls/internal/lsp/progress/progress.go b/gopls/internal/lsp/progress/progress.go --- a/gopls/internal/lsp/progress/progress.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/progress/progress.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/progress/progress.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,283 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -51301,7 +51277,7 @@ diff -urN a/gopls/internal/lsp/progress/progress.go b/gopls/internal/lsp/progres -} diff -urN a/gopls/internal/lsp/progress/progress_test.go b/gopls/internal/lsp/progress/progress_test.go --- a/gopls/internal/lsp/progress/progress_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/progress/progress_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/progress/progress_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,161 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -51466,7 +51442,7 @@ diff -urN a/gopls/internal/lsp/progress/progress_test.go b/gopls/internal/lsp/pr -} diff -urN a/gopls/internal/lsp/prompt.go b/gopls/internal/lsp/prompt.go --- a/gopls/internal/lsp/prompt.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/prompt.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/prompt.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,317 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -51787,7 +51763,7 @@ diff -urN a/gopls/internal/lsp/prompt.go b/gopls/internal/lsp/prompt.go -} diff -urN a/gopls/internal/lsp/prompt_test.go b/gopls/internal/lsp/prompt_test.go --- a/gopls/internal/lsp/prompt_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/prompt_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/prompt_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -51873,7 +51849,7 @@ diff -urN a/gopls/internal/lsp/prompt_test.go b/gopls/internal/lsp/prompt_test.g -} diff -urN a/gopls/internal/lsp/protocol/codeactionkind.go b/gopls/internal/lsp/protocol/codeactionkind.go --- a/gopls/internal/lsp/protocol/codeactionkind.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/codeactionkind.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/codeactionkind.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -51888,7 +51864,7 @@ diff -urN a/gopls/internal/lsp/protocol/codeactionkind.go b/gopls/internal/lsp/p -) diff -urN a/gopls/internal/lsp/protocol/context.go b/gopls/internal/lsp/protocol/context.go --- a/gopls/internal/lsp/protocol/context.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/context.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/context.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -51937,7 +51913,7 @@ diff -urN a/gopls/internal/lsp/protocol/context.go b/gopls/internal/lsp/protocol -} diff -urN a/gopls/internal/lsp/protocol/doc.go b/gopls/internal/lsp/protocol/doc.go --- a/gopls/internal/lsp/protocol/doc.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/doc.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/doc.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -51959,8 +51935,8 @@ diff -urN a/gopls/internal/lsp/protocol/doc.go b/gopls/internal/lsp/protocol/doc -package protocol diff -urN a/gopls/internal/lsp/protocol/enums.go b/gopls/internal/lsp/protocol/enums.go --- a/gopls/internal/lsp/protocol/enums.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/enums.go 1970-01-01 08:00:00 -@@ -1,231 +0,0 @@ ++++ b/gopls/internal/lsp/protocol/enums.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,174 +0,0 @@ -// Copyright 2018 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. @@ -52092,257 +52068,52 @@ diff -urN a/gopls/internal/lsp/protocol/enums.go b/gopls/internal/lsp/protocol/e - } -} - --func parseEnum(s string, names []string) int { -- for i, name := range names { -- if s == name { -- return i -- } -- } -- return 0 --} -- -func (e TextDocumentSyncKind) Format(f fmt.State, c rune) { - formatEnum(f, c, int(e), namesTextDocumentSyncKind[:], "TextDocumentSyncKind") -} - --func ParseTextDocumentSyncKind(s string) TextDocumentSyncKind { -- return TextDocumentSyncKind(parseEnum(s, namesTextDocumentSyncKind[:])) --} -- -func (e MessageType) Format(f fmt.State, c rune) { - formatEnum(f, c, int(e), namesMessageType[:], "MessageType") -} - --func ParseMessageType(s string) MessageType { -- return MessageType(parseEnum(s, namesMessageType[:])) --} -- -func (e FileChangeType) Format(f fmt.State, c rune) { - formatEnum(f, c, int(e), namesFileChangeType[:], "FileChangeType") -} - --func ParseFileChangeType(s string) FileChangeType { -- return FileChangeType(parseEnum(s, namesFileChangeType[:])) --} -- --func ParseWatchKind(s string) WatchKind { -- return WatchKind(parseEnum(s, namesWatchKind[:])) --} -- -func (e CompletionTriggerKind) Format(f fmt.State, c rune) { - formatEnum(f, c, int(e), namesCompletionTriggerKind[:], "CompletionTriggerKind") -} - --func ParseCompletionTriggerKind(s string) CompletionTriggerKind { -- return CompletionTriggerKind(parseEnum(s, namesCompletionTriggerKind[:])) --} -- -func (e DiagnosticSeverity) Format(f fmt.State, c rune) { - formatEnum(f, c, int(e), namesDiagnosticSeverity[:], "DiagnosticSeverity") -} - --func ParseDiagnosticSeverity(s string) DiagnosticSeverity { -- return DiagnosticSeverity(parseEnum(s, namesDiagnosticSeverity[:])) --} -- -func (e DiagnosticTag) Format(f fmt.State, c rune) { - formatEnum(f, c, int(e), namesDiagnosticTag[:], "DiagnosticTag") -} - --func ParseDiagnosticTag(s string) DiagnosticTag { -- return DiagnosticTag(parseEnum(s, namesDiagnosticTag[:])) --} -- -func (e CompletionItemKind) Format(f fmt.State, c rune) { - formatEnum(f, c, int(e), namesCompletionItemKind[:], "CompletionItemKind") -} - --func ParseCompletionItemKind(s string) CompletionItemKind { -- return CompletionItemKind(parseEnum(s, namesCompletionItemKind[:])) --} -- -func (e InsertTextFormat) Format(f fmt.State, c rune) { - formatEnum(f, c, int(e), namesInsertTextFormat[:], "InsertTextFormat") -} - --func ParseInsertTextFormat(s string) InsertTextFormat { -- return InsertTextFormat(parseEnum(s, namesInsertTextFormat[:])) --} -- -func (e DocumentHighlightKind) Format(f fmt.State, c rune) { - formatEnum(f, c, int(e), namesDocumentHighlightKind[:], "DocumentHighlightKind") -} - --func ParseDocumentHighlightKind(s string) DocumentHighlightKind { -- return DocumentHighlightKind(parseEnum(s, namesDocumentHighlightKind[:])) --} -- -func (e SymbolKind) Format(f fmt.State, c rune) { - formatEnum(f, c, int(e), namesSymbolKind[:], "SymbolKind") -} - --func ParseSymbolKind(s string) SymbolKind { -- return SymbolKind(parseEnum(s, namesSymbolKind[:])) --} -- -func (e TextDocumentSaveReason) Format(f fmt.State, c rune) { - formatEnum(f, c, int(e), namesTextDocumentSaveReason[:], "TextDocumentSaveReason") -} -- --func ParseTextDocumentSaveReason(s string) TextDocumentSaveReason { -- return TextDocumentSaveReason(parseEnum(s, namesTextDocumentSaveReason[:])) --} -diff -urN a/gopls/internal/lsp/protocol/generate/README.md b/gopls/internal/lsp/protocol/generate/README.md ---- a/gopls/internal/lsp/protocol/generate/README.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/generate/README.md 1970-01-01 08:00:00 -@@ -1,144 +0,0 @@ --# LSP Support for gopls -- --## The protocol -- --The LSP protocol exchanges json-encoded messages between the client and the server. --(gopls is the server.) The messages are either Requests, which require Responses, or --Notifications, which generate no response. Each Request or Notification has a method name --such as "textDocument/hover" that indicates its meaning and determines which function in the server will handle it. --The protocol is described in a --[web page](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/), --in words, and in a json file (metaModel.json) available either linked towards the bottom of the --web page, or in the vscode-languageserver-node repository. This code uses the latter so the --exact version can be tied to a githash. By default, the command will download the `github.com/microsoft/vscode-languageserver-node` repository to a temporary directory. -- --The specification has five sections -- --1. Requests, which describe the Request and Response types for request methods (e.g., *textDocument/didChange*), --2. Notifications, which describe the Request types for notification methods, --3. Structures, which describe named struct-like types, --4. TypeAliases, which describe type aliases, --5. Enumerations, which describe named constants. -- --Requests and Notifications are tagged with a Method (e.g., `"textDocument/hover"`). --The specification does not specify the names of the functions that handle the messages. These --names are specified by the `methodNames` map. Enumerations generate Go `const`s, but --in Typescript they are scoped to namespaces, while in Go they are scoped to a package, so the Go names --may need to be modified to avoid name collisions. (See the `disambiguate` map, and its use.) -- --Finally, the specified types are Typescript types, which are quite different from Go types. -- --### Optionality -- --The specification can mark fields in structs as Optional. The client distinguishes between missing --fields and `null` fields in some cases. The Go translation for an optional type --should be making sure the field's value --can be `nil`, and adding the json tag `,omitempty`. The former condition would be satisfied by --adding `*` to the field's type if the type is not a reference type. -- --### Types -- --The specification uses a number of different types, only a few of which correspond directly to Go types. --The specification's types are "base", "reference", "map", "literal", "stringLiteral", "tuple", "and", "or". --The "base" types correspond directly to Go types, although some Go types needs to be chosen for `URI` and `DocumentUri`. (The "base" types`RegExp`, `BooleanLiteral`, `NumericLiteral` never occur.) -- --"reference" types are the struct-like types in the Structures section of the specification. The given --names are suitable for Go to use, except the code needs to change names like `_Initialze` to `XInitialize` so --they are exported for json marshaling and unmarshaling. -- --"map" types are just like Go. (The key type in all of them is `DocumentUri`.) -- --"stringLiteral" types are types whose type name and value are a single string. The chosen Go equivalent --is to make the type `string` and the value a constant. (The alternative would be to generate a new --named type, which seemed redundant.) -- --"literal" types are like Go anonymous structs, so they have to be given a name. (All instances --of the remaining types have to be given names. One approach is to construct the name from the components --of the type, but this leads to misleading punning, and is unstable if components are added. The other approach --is to construct the name from the context of the definition, that is, from the types it is defined within. --For instance `Lit__InitializeParams_clientInfo` is the "literal" type at the --`clientInfo` field in the `_InitializeParams` --struct. Although this choice is sensitive to the ordering of the components, the code uses this approach, --presuming that reordering components is an unlikely protocol change.) -- --"tuple" types are generated as Go structs. (There is only one, with two `uint32` fields.) -- --"and" types are Go structs with embedded type names. (There is only one, `And_Param_workspace_configuration`.) -- --"or" types are the most complicated. There are a lot of them and there is no simple Go equivalent. --They are defined as structs with a single `Value interface{}` field and custom json marshaling --and unmarshaling code. Users can assign anything to `Value` but the type will be checked, and --correctly marshaled, by the custom marshaling code. The unmarshaling code checks types, so `Value` --will have one of the permitted types. (`nil` is always allowed.) There are about 40 "or" types that --have a single non-null component, and these are converted to the component type. -- --## Processing -- --The code parses the json specification file, and scans all the types. It assigns names, as described --above, to the types that are unnamed in the specification, and constructs Go equivalents as required. --(Most of this code is in typenames.go.) -- --There are four output files. tsclient.go and tsserver.go contain the definition and implementation --of the `protocol.Client` and `protocol.Server` types and the code that dispatches on the Method --of the Request or Notification. tsjson.go contains the custom marshaling and unmarshaling code. --And tsprotocol.go contains the type and const definitions. -- --### Accommodating gopls -- --As the code generates output, mostly in generateoutput.go and main.go, --it makes adjustments so that no changes are required to the existing Go code. --(Organizing the computation this way makes the code's structure simpler, but results in --a lot of unused types.) --There are three major classes of these adjustments, and leftover special cases. -- --The first major --adjustment is to change generated type names to the ones gopls expects. Some of these don't change the --semantics of the type, just the name. --But for historical reasons a lot of them replace "or" types by a single --component of the type. (Until fairly recently Go only saw or used only one of components.) --The `goplsType` map in tables.go controls this process. -- --The second major adjustment is to the types of fields of structs, which is done using the --`renameProp` map in tables.go. -- --The third major adjustment handles optionality, controlling `*` and `,omitempty` placement when --the default rules don't match what gopls is expecting. (The map is `goplsStar`, also in tables.go) --(If the intermediate components in expressions of the form `A.B.C.S` were optional, the code would need --a lot of useless checking for nils. Typescript has a language construct to avoid most checks.) -- --Then there are some additional special cases. There are a few places with adjustments to avoid --recursive types. For instance `LSPArray` is `[]LSPAny`, but `LSPAny` is an "or" type including `LSPArray`. --The solution is to make `LSPAny` an `interface{}`. Another instance is `_InitializeParams.trace` --whose type is an "or" of 3 stringLiterals, which just becomes a `string`. -- --### Checking -- --`TestAll(t *testing.T)` checks that there are no unexpected fields in the json specification. -- --While the code is executing, it checks that all the entries in the maps in tables.go are used. --It also checks that the entries in `renameProp` and `goplsStar` are not redundant. -- --As a one-time check on the first release of this code, diff-ing the existing and generated tsclient.go --and tsserver.go code results in only whitespace and comment diffs. The existing and generated --tsprotocol.go differ in whitespace and comments, and in a substantial number of new type definitions --that the older, more heuristic, code did not generate. (And the unused type `_InitializeParams` differs --slightly between the new and the old, and is not worth fixing.) -- --### Some history -- --The original stub code was written by hand, but with the protocol under active development, that --couldn't last. The web page existed before the json specification, but it lagged the implementation --and was hard to process by machine. So the earlier version of the generating code was written in Typescript, and --used the Typescript compiler's API to parse the protocol code in the repository. --It then used a set of heuristics --to pick out the elements of the protocol, and another set of overlapping heuristics to create the Go code. --The output was functional, but idiosyncratic, and the code was fragile and barely maintainable. -- --### The future -- --Most of the adjustments using the maps in tables.go could be removed by making changes, mostly to names, --in the gopls code. Using more "or" types in gopls requires more elaborate, but stereotyped, changes. --But even without all the adjustments, making this its own module would face problems; a number of --dependencies would have to be factored out. And, it is fragile. The custom unmarshaling code knows what --types it expects. A design that return an 'any' on unexpected types would match the json --'ignore unexpected values' philosophy better, but the Go code would need extra checking. diff -urN a/gopls/internal/lsp/protocol/generate/generate.go b/gopls/internal/lsp/protocol/generate/generate.go --- a/gopls/internal/lsp/protocol/generate/generate.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/generate/generate.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/generate/generate.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -52467,7 +52238,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/generate.go b/gopls/internal/ls -} diff -urN a/gopls/internal/lsp/protocol/generate/main.go b/gopls/internal/lsp/protocol/generate/main.go --- a/gopls/internal/lsp/protocol/generate/main.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/generate/main.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/generate/main.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,390 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -52861,7 +52632,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/main.go b/gopls/internal/lsp/pr -} diff -urN a/gopls/internal/lsp/protocol/generate/main_test.go b/gopls/internal/lsp/protocol/generate/main_test.go --- a/gopls/internal/lsp/protocol/generate/main_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/generate/main_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/generate/main_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,119 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -52984,7 +52755,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/main_test.go b/gopls/internal/l -} diff -urN a/gopls/internal/lsp/protocol/generate/output.go b/gopls/internal/lsp/protocol/generate/output.go --- a/gopls/internal/lsp/protocol/generate/output.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/generate/output.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/generate/output.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,427 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -53413,9 +53184,157 @@ diff -urN a/gopls/internal/lsp/protocol/generate/output.go b/gopls/internal/lsp/ - // that's all the cases that occur currently - return false -} +diff -urN a/gopls/internal/lsp/protocol/generate/README.md b/gopls/internal/lsp/protocol/generate/README.md +--- a/gopls/internal/lsp/protocol/generate/README.md 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/protocol/generate/README.md 1970-01-01 00:00:00.000000000 +0000 +@@ -1,144 +0,0 @@ +-# LSP Support for gopls +- +-## The protocol +- +-The LSP protocol exchanges json-encoded messages between the client and the server. +-(gopls is the server.) The messages are either Requests, which require Responses, or +-Notifications, which generate no response. Each Request or Notification has a method name +-such as "textDocument/hover" that indicates its meaning and determines which function in the server will handle it. +-The protocol is described in a +-[web page](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/), +-in words, and in a json file (metaModel.json) available either linked towards the bottom of the +-web page, or in the vscode-languageserver-node repository. This code uses the latter so the +-exact version can be tied to a githash. By default, the command will download the `github.com/microsoft/vscode-languageserver-node` repository to a temporary directory. +- +-The specification has five sections +- +-1. Requests, which describe the Request and Response types for request methods (e.g., *textDocument/didChange*), +-2. Notifications, which describe the Request types for notification methods, +-3. Structures, which describe named struct-like types, +-4. TypeAliases, which describe type aliases, +-5. Enumerations, which describe named constants. +- +-Requests and Notifications are tagged with a Method (e.g., `"textDocument/hover"`). +-The specification does not specify the names of the functions that handle the messages. These +-names are specified by the `methodNames` map. Enumerations generate Go `const`s, but +-in Typescript they are scoped to namespaces, while in Go they are scoped to a package, so the Go names +-may need to be modified to avoid name collisions. (See the `disambiguate` map, and its use.) +- +-Finally, the specified types are Typescript types, which are quite different from Go types. +- +-### Optionality +- +-The specification can mark fields in structs as Optional. The client distinguishes between missing +-fields and `null` fields in some cases. The Go translation for an optional type +-should be making sure the field's value +-can be `nil`, and adding the json tag `,omitempty`. The former condition would be satisfied by +-adding `*` to the field's type if the type is not a reference type. +- +-### Types +- +-The specification uses a number of different types, only a few of which correspond directly to Go types. +-The specification's types are "base", "reference", "map", "literal", "stringLiteral", "tuple", "and", "or". +-The "base" types correspond directly to Go types, although some Go types needs to be chosen for `URI` and `DocumentUri`. (The "base" types`RegExp`, `BooleanLiteral`, `NumericLiteral` never occur.) +- +-"reference" types are the struct-like types in the Structures section of the specification. The given +-names are suitable for Go to use, except the code needs to change names like `_Initialze` to `XInitialize` so +-they are exported for json marshaling and unmarshaling. +- +-"map" types are just like Go. (The key type in all of them is `DocumentUri`.) +- +-"stringLiteral" types are types whose type name and value are a single string. The chosen Go equivalent +-is to make the type `string` and the value a constant. (The alternative would be to generate a new +-named type, which seemed redundant.) +- +-"literal" types are like Go anonymous structs, so they have to be given a name. (All instances +-of the remaining types have to be given names. One approach is to construct the name from the components +-of the type, but this leads to misleading punning, and is unstable if components are added. The other approach +-is to construct the name from the context of the definition, that is, from the types it is defined within. +-For instance `Lit__InitializeParams_clientInfo` is the "literal" type at the +-`clientInfo` field in the `_InitializeParams` +-struct. Although this choice is sensitive to the ordering of the components, the code uses this approach, +-presuming that reordering components is an unlikely protocol change.) +- +-"tuple" types are generated as Go structs. (There is only one, with two `uint32` fields.) +- +-"and" types are Go structs with embedded type names. (There is only one, `And_Param_workspace_configuration`.) +- +-"or" types are the most complicated. There are a lot of them and there is no simple Go equivalent. +-They are defined as structs with a single `Value interface{}` field and custom json marshaling +-and unmarshaling code. Users can assign anything to `Value` but the type will be checked, and +-correctly marshaled, by the custom marshaling code. The unmarshaling code checks types, so `Value` +-will have one of the permitted types. (`nil` is always allowed.) There are about 40 "or" types that +-have a single non-null component, and these are converted to the component type. +- +-## Processing +- +-The code parses the json specification file, and scans all the types. It assigns names, as described +-above, to the types that are unnamed in the specification, and constructs Go equivalents as required. +-(Most of this code is in typenames.go.) +- +-There are four output files. tsclient.go and tsserver.go contain the definition and implementation +-of the `protocol.Client` and `protocol.Server` types and the code that dispatches on the Method +-of the Request or Notification. tsjson.go contains the custom marshaling and unmarshaling code. +-And tsprotocol.go contains the type and const definitions. +- +-### Accommodating gopls +- +-As the code generates output, mostly in generateoutput.go and main.go, +-it makes adjustments so that no changes are required to the existing Go code. +-(Organizing the computation this way makes the code's structure simpler, but results in +-a lot of unused types.) +-There are three major classes of these adjustments, and leftover special cases. +- +-The first major +-adjustment is to change generated type names to the ones gopls expects. Some of these don't change the +-semantics of the type, just the name. +-But for historical reasons a lot of them replace "or" types by a single +-component of the type. (Until fairly recently Go only saw or used only one of components.) +-The `goplsType` map in tables.go controls this process. +- +-The second major adjustment is to the types of fields of structs, which is done using the +-`renameProp` map in tables.go. +- +-The third major adjustment handles optionality, controlling `*` and `,omitempty` placement when +-the default rules don't match what gopls is expecting. (The map is `goplsStar`, also in tables.go) +-(If the intermediate components in expressions of the form `A.B.C.S` were optional, the code would need +-a lot of useless checking for nils. Typescript has a language construct to avoid most checks.) +- +-Then there are some additional special cases. There are a few places with adjustments to avoid +-recursive types. For instance `LSPArray` is `[]LSPAny`, but `LSPAny` is an "or" type including `LSPArray`. +-The solution is to make `LSPAny` an `interface{}`. Another instance is `_InitializeParams.trace` +-whose type is an "or" of 3 stringLiterals, which just becomes a `string`. +- +-### Checking +- +-`TestAll(t *testing.T)` checks that there are no unexpected fields in the json specification. +- +-While the code is executing, it checks that all the entries in the maps in tables.go are used. +-It also checks that the entries in `renameProp` and `goplsStar` are not redundant. +- +-As a one-time check on the first release of this code, diff-ing the existing and generated tsclient.go +-and tsserver.go code results in only whitespace and comment diffs. The existing and generated +-tsprotocol.go differ in whitespace and comments, and in a substantial number of new type definitions +-that the older, more heuristic, code did not generate. (And the unused type `_InitializeParams` differs +-slightly between the new and the old, and is not worth fixing.) +- +-### Some history +- +-The original stub code was written by hand, but with the protocol under active development, that +-couldn't last. The web page existed before the json specification, but it lagged the implementation +-and was hard to process by machine. So the earlier version of the generating code was written in Typescript, and +-used the Typescript compiler's API to parse the protocol code in the repository. +-It then used a set of heuristics +-to pick out the elements of the protocol, and another set of overlapping heuristics to create the Go code. +-The output was functional, but idiosyncratic, and the code was fragile and barely maintainable. +- +-### The future +- +-Most of the adjustments using the maps in tables.go could be removed by making changes, mostly to names, +-in the gopls code. Using more "or" types in gopls requires more elaborate, but stereotyped, changes. +-But even without all the adjustments, making this its own module would face problems; a number of +-dependencies would have to be factored out. And, it is fragile. The custom unmarshaling code knows what +-types it expects. A design that return an 'any' on unexpected types would match the json +-'ignore unexpected values' philosophy better, but the Go code would need extra checking. diff -urN a/gopls/internal/lsp/protocol/generate/tables.go b/gopls/internal/lsp/protocol/generate/tables.go --- a/gopls/internal/lsp/protocol/generate/tables.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/generate/tables.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/generate/tables.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,341 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -53760,7 +53679,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/tables.go b/gopls/internal/lsp/ -} diff -urN a/gopls/internal/lsp/protocol/generate/typenames.go b/gopls/internal/lsp/protocol/generate/typenames.go --- a/gopls/internal/lsp/protocol/generate/typenames.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/generate/typenames.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/generate/typenames.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,184 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -53948,7 +53867,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/typenames.go b/gopls/internal/l -} diff -urN a/gopls/internal/lsp/protocol/generate/types.go b/gopls/internal/lsp/protocol/generate/types.go --- a/gopls/internal/lsp/protocol/generate/types.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/generate/types.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/generate/types.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,170 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -54122,7 +54041,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/types.go b/gopls/internal/lsp/p -} diff -urN a/gopls/internal/lsp/protocol/log.go b/gopls/internal/lsp/protocol/log.go --- a/gopls/internal/lsp/protocol/log.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/log.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/log.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,136 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -54262,7 +54181,7 @@ diff -urN a/gopls/internal/lsp/protocol/log.go b/gopls/internal/lsp/protocol/log -} diff -urN a/gopls/internal/lsp/protocol/mapper.go b/gopls/internal/lsp/protocol/mapper.go --- a/gopls/internal/lsp/protocol/mapper.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/mapper.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/mapper.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,529 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -54795,7 +54714,7 @@ diff -urN a/gopls/internal/lsp/protocol/mapper.go b/gopls/internal/lsp/protocol/ -} diff -urN a/gopls/internal/lsp/protocol/mapper_test.go b/gopls/internal/lsp/protocol/mapper_test.go --- a/gopls/internal/lsp/protocol/mapper_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/mapper_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/mapper_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,439 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -55238,7 +55157,7 @@ diff -urN a/gopls/internal/lsp/protocol/mapper_test.go b/gopls/internal/lsp/prot -} diff -urN a/gopls/internal/lsp/protocol/protocol.go b/gopls/internal/lsp/protocol/protocol.go --- a/gopls/internal/lsp/protocol/protocol.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/protocol.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/protocol.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,284 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -55526,8 +55445,8 @@ diff -urN a/gopls/internal/lsp/protocol/protocol.go b/gopls/internal/lsp/protoco -} diff -urN a/gopls/internal/lsp/protocol/span.go b/gopls/internal/lsp/protocol/span.go --- a/gopls/internal/lsp/protocol/span.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/span.go 1970-01-01 08:00:00 -@@ -1,118 +0,0 @@ ++++ b/gopls/internal/lsp/protocol/span.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,114 +0,0 @@ -// Copyright 2018 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. @@ -55553,10 +55472,6 @@ diff -urN a/gopls/internal/lsp/protocol/span.go b/gopls/internal/lsp/protocol/sp - return span.URIFromURI(string(u)) // normalizing conversion -} - --func IsPoint(r Range) bool { -- return r.Start.Line == r.End.Line && r.Start.Character == r.End.Character --} -- -// CompareLocation defines a three-valued comparison over locations, -// lexicographically ordered by (URI, Range). -func CompareLocation(x, y Location) int { @@ -55648,7 +55563,7 @@ diff -urN a/gopls/internal/lsp/protocol/span.go b/gopls/internal/lsp/protocol/sp -} diff -urN a/gopls/internal/lsp/protocol/tsclient.go b/gopls/internal/lsp/protocol/tsclient.go --- a/gopls/internal/lsp/protocol/tsclient.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/tsclient.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/tsclient.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,249 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -55901,7 +55816,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsclient.go b/gopls/internal/lsp/protoco -} diff -urN a/gopls/internal/lsp/protocol/tsdocument_changes.go b/gopls/internal/lsp/protocol/tsdocument_changes.go --- a/gopls/internal/lsp/protocol/tsdocument_changes.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/tsdocument_changes.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/tsdocument_changes.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -55947,7 +55862,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsdocument_changes.go b/gopls/internal/l -} diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/tsjson.go --- a/gopls/internal/lsp/protocol/tsjson.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/tsjson.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/tsjson.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,2090 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -58041,7 +57956,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ -} diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/protocol/tsprotocol.go --- a/gopls/internal/lsp/protocol/tsprotocol.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/tsprotocol.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/tsprotocol.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,5642 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -63687,7 +63602,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -) diff -urN a/gopls/internal/lsp/protocol/tsserver.go b/gopls/internal/lsp/protocol/tsserver.go --- a/gopls/internal/lsp/protocol/tsserver.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/protocol/tsserver.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/protocol/tsserver.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,1196 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -64885,9 +64800,20 @@ diff -urN a/gopls/internal/lsp/protocol/tsserver.go b/gopls/internal/lsp/protoco - } - return result, nil -} +diff -urN a/gopls/internal/lsp/README.md b/gopls/internal/lsp/README.md +--- a/gopls/internal/lsp/README.md 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/README.md 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-# 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. diff -urN a/gopls/internal/lsp/references.go b/gopls/internal/lsp/references.go --- a/gopls/internal/lsp/references.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/references.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/references.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -64927,7 +64853,7 @@ diff -urN a/gopls/internal/lsp/references.go b/gopls/internal/lsp/references.go -} diff -urN a/gopls/internal/lsp/regtest/doc.go b/gopls/internal/lsp/regtest/doc.go --- a/gopls/internal/lsp/regtest/doc.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/regtest/doc.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/regtest/doc.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -65088,7 +65014,7 @@ diff -urN a/gopls/internal/lsp/regtest/doc.go b/gopls/internal/lsp/regtest/doc.g -package regtest diff -urN a/gopls/internal/lsp/regtest/env.go b/gopls/internal/lsp/regtest/env.go --- a/gopls/internal/lsp/regtest/env.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/regtest/env.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/regtest/env.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,403 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -65495,7 +65421,7 @@ diff -urN a/gopls/internal/lsp/regtest/env.go b/gopls/internal/lsp/regtest/env.g -} diff -urN a/gopls/internal/lsp/regtest/env_test.go b/gopls/internal/lsp/regtest/env_test.go --- a/gopls/internal/lsp/regtest/env_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/regtest/env_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/regtest/env_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -65565,7 +65491,7 @@ diff -urN a/gopls/internal/lsp/regtest/env_test.go b/gopls/internal/lsp/regtest/ -} diff -urN a/gopls/internal/lsp/regtest/expectation.go b/gopls/internal/lsp/regtest/expectation.go --- a/gopls/internal/lsp/regtest/expectation.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/regtest/expectation.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/regtest/expectation.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,807 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -66376,8 +66302,8 @@ diff -urN a/gopls/internal/lsp/regtest/expectation.go b/gopls/internal/lsp/regte -} diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/marker.go --- a/gopls/internal/lsp/regtest/marker.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/regtest/marker.go 1970-01-01 08:00:00 -@@ -1,2227 +0,0 @@ ++++ b/gopls/internal/lsp/regtest/marker.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,2366 +0,0 @@ -// Copyright 2023 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. @@ -66416,6 +66342,7 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/lsp/tests" - "golang.org/x/tools/gopls/internal/lsp/tests/compare" +- "golang.org/x/tools/internal/diff" - "golang.org/x/tools/internal/jsonrpc2" - "golang.org/x/tools/internal/jsonrpc2/servertest" - "golang.org/x/tools/internal/testenv" @@ -66494,6 +66421,10 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// -ignore_extra_diags suppresses errors for unmatched diagnostics -// TODO(rfindley): using build constraint expressions for -skip_goos would -// be clearer. +-// -filter_builtins=false disables the filtering of builtins from +-// completion results. +-// -filter_keywords=false disables the filtering of keywords from +-// completion results. -// TODO(rfindley): support flag values containing whitespace. -// - "settings.json": this file is parsed as JSON, and used as the -// session configuration (see gopls/doc/settings.md) @@ -66528,12 +66459,22 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// completion candidate produced at the given location with provided label -// results in the given golden state. -// --// - codeaction(kind, start, end, golden): specifies a codeaction to request --// for the given range. To support multi-line ranges, the range is defined --// to be between start.Start and end.End. The golden directory contains --// changed file content after the code action is applied. +-// - codeaction(start, end, kind, golden, ...titles): specifies a code action +-// to request for the given range. To support multi-line ranges, the range +-// is defined to be between start.Start and end.End. The golden directory +-// contains changed file content after the code action is applied. +-// If titles are provided, they are used to filter the matching code +-// action. +-// +-// TODO(rfindley): consolidate with codeactionedit, via a @loc2 marker that +-// allows binding multi-line locations. -// --// - codeactionerr(kind, start, end, wantError): specifies a codeaction that +-// - codeactionedit(range, kind, golden, ...titles): a shorter form of +-// codeaction. Invokes a code action of the given kind for the given +-// in-line range, and compares the resulting formatted unified *edits* +-// (notably, not the full file content) with the golden directory. +-// +-// - codeactionerr(start, end, kind, wantError): specifies a codeaction that -// fails with an error that matches the expectation. -// -// - codelens(location, title): specifies that a codelens is expected at the @@ -66561,6 +66502,9 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// - def(src, dst location): perform a textDocument/definition request at -// the src location, and check the result points to the dst location. -// +-// - documentLink(golden): asserts that textDocument/documentLink returns +-// links as described by the golden file. +-// -// - foldingrange(golden): perform a textDocument/foldingRange for the -// current document, and compare with the golden content, which is the -// original source annotated with numbered tags delimiting the resulting @@ -66595,6 +66539,11 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// - loc(name, location): specifies the name for a location in the source. These -// locations may be referenced by other markers. -// +-// - preparerename(src, spn, placeholder): asserts that a textDocument/prepareRename +-// request at the src location expands to the spn location, with given +-// placeholder. If placeholder is "", this is treated as a negative +-// assertion and prepareRename should return nil. +-// -// - rename(location, new, golden): specifies a renaming of the -// identifier at the specified location to the new name. -// The golden directory contains the transformed files. @@ -66602,6 +66551,10 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// - renameerr(location, new, wantError): specifies a renaming that -// fails with an error that matches the expectation. -// +-// - signature(location, label, active): specifies that +-// signatureHelp at the given location should match the provided string, with +-// the active parameter (an index) highlighted. +-// -// - suggestedfix(location, regexp, kind, golden): like diag, the location and -// regexp identify an expected diagnostic. This diagnostic must -// to have exactly one associated code action of the specified kind. @@ -66734,35 +66687,22 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// internal/lsp/tests. -// -// Remaining TODO: --// - optimize test execution -// - reorganize regtest packages (and rename to just 'test'?) -// - Rename the files .txtar. -// - Provide some means by which locations in the standard library -// (or builtin.go) can be named, so that, for example, we can we -// can assert that MyError implements the built-in error type. +-// - If possible, improve handling for optional arguments. Rather than have +-// multiple variations of a marker, it would be nice to support a more +-// flexible signature: can codeaction, codeactionedit, codeactionerr, and +-// suggestedfix be consolidated? -// -// Existing marker tests (in ../testdata) to port: -// - CallHierarchy --// - Diagnostics --// - CompletionItems --// - Completions --// - CompletionSnippets --// - DeepCompletions --// - FuzzyCompletions --// - CaseSensitiveCompletions --// - RankCompletions --// - Formats --// - Imports -// - SemanticTokens --// - FunctionExtractions --// - MethodExtractions --// - Renames --// - PrepareRenames +-// - SuggestedFixes -// - InlayHints --// - WorkspaceSymbols --// - Signatures --// - Links --// - AddImport +-// - Renames -// - SelectionRanges -func RunMarkerTests(t *testing.T, dir string) { - // The marker tests must be able to run go/packages.Load. @@ -66774,7 +66714,6 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } - - // Opt: use a shared cache. -- // TODO(rfindley): opt: use a memoize store with no eviction. - cache := cache.New(nil) - - for _, test := range tests { @@ -67084,16 +67023,19 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -var actionMarkerFuncs = map[string]func(marker){ - "acceptcompletion": actionMarkerFunc(acceptCompletionMarker), - "codeaction": actionMarkerFunc(codeActionMarker), +- "codeactionedit": actionMarkerFunc(codeActionEditMarker), - "codeactionerr": actionMarkerFunc(codeActionErrMarker), - "codelenses": actionMarkerFunc(codeLensesMarker), - "complete": actionMarkerFunc(completeMarker), - "def": actionMarkerFunc(defMarker), - "diag": actionMarkerFunc(diagMarker), +- "documentlink": actionMarkerFunc(documentLinkMarker), - "foldingrange": actionMarkerFunc(foldingRangeMarker), - "format": actionMarkerFunc(formatMarker), - "highlight": actionMarkerFunc(highlightMarker), - "hover": actionMarkerFunc(hoverMarker), - "implementation": actionMarkerFunc(implementationMarker), +- "preparerename": actionMarkerFunc(prepareRenameMarker), - "rank": actionMarkerFunc(rankMarker), - "rankl": actionMarkerFunc(ranklMarker), - "refs": actionMarkerFunc(refsMarker), @@ -67133,6 +67075,8 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - writeGoSum []string // comma separated dirs to write go sum for - skipGOOS []string // comma separated GOOS values to skip - ignoreExtraDiags bool +- filterBuiltins bool +- filterKeywords bool -} - -// flagSet returns the flagset used for parsing the special "flags" file in the @@ -67144,6 +67088,8 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - flags.Var((*stringListValue)(&t.writeGoSum), "write_sumfile", "if set, write the sumfile for these directories") - flags.Var((*stringListValue)(&t.skipGOOS), "skip_goos", "if set, skip this test on these GOOS values") - flags.BoolVar(&t.ignoreExtraDiags, "ignore_extra_diags", false, "if set, suppress errors for unmatched diagnostics") +- flags.BoolVar(&t.filterBuiltins, "filter_builtins", true, "if set, filter builtins from completion results") +- flags.BoolVar(&t.filterKeywords, "filter_keywords", true, "if set, filter keywords from completion results") - return flags -} - @@ -67230,7 +67176,7 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// archive. -func loadMarkerTests(dir string) ([]*markerTest, error) { - var tests []*markerTest -- err := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error { +- err := filepath.WalkDir(dir, func(path string, _ fs.DirEntry, err error) error { - if strings.HasSuffix(path, ".txt") { - content, err := os.ReadFile(path) - if err != nil { @@ -67244,7 +67190,7 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } - tests = append(tests, test) - } -- return nil +- return err - }) - return tests, err -} @@ -67275,9 +67221,6 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - - case file.Name == "flags": - test.flags = strings.Fields(string(file.Data)) -- if err := test.flagSet().Parse(test.flags); err != nil { -- return nil, fmt.Errorf("parsing flags: %v", err) -- } - - case file.Name == "settings.json": - if err := json.Unmarshal(file.Data, &test.settings); err != nil { @@ -67342,6 +67285,12 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } - } - +- // Parse flags after loading files, as they may have been set by the "flags" +- // file. +- if err := test.flagSet().Parse(test.flags); err != nil { +- return nil, fmt.Errorf("parsing flags: %v", err) +- } +- - return test, nil -} - @@ -67381,6 +67330,9 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - // ...followed by any new golden files. - var newGoldenFiles []txtar.File - for filename, data := range updatedGolden { +- // TODO(rfindley): it looks like this implicitly removes trailing newlines +- // from golden content. Is there any way to fix that? Perhaps we should +- // just make the diff tolerant of missing newlines? - newGoldenFiles = append(newGoldenFiles, txtar.File{Name: filename, Data: data}) - } - // Sort new golden files lexically. @@ -67599,7 +67551,7 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - if id, ok := arg.(expect.Identifier); ok { - if arg, ok := mark.run.values[id]; ok { - if !reflect.TypeOf(arg).AssignableTo(paramType) { -- return nil, fmt.Errorf("cannot convert %v to %s", arg, paramType) +- return nil, fmt.Errorf("cannot convert %v (%T) to %s", arg, arg, paramType) - } - return arg, nil - } @@ -67613,7 +67565,7 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - case wantErrorType: - return convertWantError(mark, arg) - default: -- return nil, fmt.Errorf("cannot convert %v to %s", arg, paramType) +- return nil, fmt.Errorf("cannot convert %v (%T) to %s", arg, arg, paramType) - } -} - @@ -67784,6 +67736,41 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } -} - +-// checkDiffs computes unified diffs for each changed file, and compares with +-// the diff content stored in the given golden directory. +-func checkDiffs(mark marker, changed map[string][]byte, golden *Golden) { +- diffs := make(map[string]string) +- for name, after := range changed { +- before := mark.run.env.FileContent(name) +- edits := diff.Strings(before, string(after)) +- d, err := diff.ToUnified("before", "after", before, edits, 0) +- if err != nil { +- // Can't happen: edits are consistent. +- log.Fatalf("internal error in diff.ToUnified: %v", err) +- } +- diffs[name] = d +- } +- // Check changed files match expectations. +- for filename, got := range diffs { +- if want, ok := golden.Get(mark.run.env.T, filename, []byte(got)); !ok { +- mark.errorf("%s: unexpected change to file %s; got diff:\n%s", +- mark.note.Name, filename, got) +- +- } else if got != string(want) { +- mark.errorf("%s: wrong diff for %s:\n\ngot:\n%s\n\nwant:\n%s\n", +- mark.note.Name, filename, got, want) +- } +- } +- // Report unmet expectations. +- for filename := range golden.data { +- if _, ok := changed[filename]; !ok { +- want, _ := golden.Get(mark.run.env.T, filename, nil) +- mark.errorf("%s: missing change to file %s; want:\n%s", +- mark.note.Name, filename, want) +- } +- } +-} +- -// ---- marker functions ---- - -// TODO(rfindley): consolidate documentation of these markers. They are already @@ -67858,7 +67845,7 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - got string - all []string // for errors - ) -- items := filterBuiltinsAndKeywords(list.Items) +- items := filterBuiltinsAndKeywords(mark, list.Items) - for _, i := range items { - all = append(all, i.Label) - if i.Label == item.Label { @@ -67883,7 +67870,7 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// results match the expected results. -func completeMarker(mark marker, src protocol.Location, want ...completionItem) { - list := mark.run.env.Completion(src) -- items := filterBuiltinsAndKeywords(list.Items) +- items := filterBuiltinsAndKeywords(mark, list.Items) - var got []completionItem - for i, item := range items { - simplified := completionItem{ @@ -67926,13 +67913,17 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// results. -// -// It over-approximates, and does not detect if builtins are shadowed. --func filterBuiltinsAndKeywords(items []protocol.CompletionItem) []protocol.CompletionItem { +-func filterBuiltinsAndKeywords(mark marker, items []protocol.CompletionItem) []protocol.CompletionItem { - keep := 0 - for _, item := range items { -- if types.Universe.Lookup(item.Label) == nil && token.Lookup(item.Label) == token.IDENT { -- items[keep] = item -- keep++ +- if mark.run.test.filterKeywords && item.Kind == protocol.KeywordCompletion { +- continue +- } +- if mark.run.test.filterBuiltins && types.Universe.Lookup(item.Label) != nil { +- continue - } +- items[keep] = item +- keep++ - } - return items[:keep] -} @@ -68059,15 +68050,7 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } - } - -- want, ok := golden.Get(mark.run.env.T, "", got) -- if !ok { -- mark.errorf("missing golden file @%s", golden.id) -- return -- } -- -- if diff := compare.Bytes(want, got); diff != "" { -- mark.errorf("golden file @%s does not match format results:\n%s", golden.id, diff) -- } +- compareGolden(mark, "format", got, golden) -} - -func highlightMarker(mark marker, src protocol.Location, dsts ...protocol.Location) { @@ -68170,14 +68153,23 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - wantErr.check(mark, err) -} - --func signatureMarker(mark marker, src protocol.Location, want string) { +-func signatureMarker(mark marker, src protocol.Location, label string, active int64) { - got := mark.run.env.SignatureHelp(src) +- if label == "" { +- if got != nil && len(got.Signatures) > 0 { +- mark.errorf("signatureHelp = %v, want 0 signatures", got) +- } +- return +- } - if got == nil || len(got.Signatures) != 1 { - mark.errorf("signatureHelp = %v, want exactly 1 signature", got) - return - } -- if got := got.Signatures[0].Label; got != want { -- mark.errorf("signatureHelp: got %q, want %q", got, want) +- if got := got.Signatures[0].Label; got != label { +- mark.errorf("signatureHelp: got label %q, want %q", got, label) +- } +- if got := int64(got.ActiveParameter); got != active { +- mark.errorf("signatureHelp: got active parameter %d, want %d", got, active) - } -} - @@ -68246,26 +68238,36 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - return nil -} - --func codeActionMarker(mark marker, actionKind string, start, end protocol.Location, golden *Golden) { +-func codeActionMarker(mark marker, start, end protocol.Location, actionKind string, g *Golden, titles ...string) { - // Request the range from start.Start to end.End. - loc := start - loc.Range.End = end.Range.End - - // Apply the fix it suggests. -- changed, err := codeAction(mark.run.env, loc.URI, loc.Range, actionKind, nil) +- changed, err := codeAction(mark.run.env, loc.URI, loc.Range, actionKind, nil, titles) - if err != nil { - mark.errorf("codeAction failed: %v", err) - return - } - - // Check the file state. -- checkChangedFiles(mark, changed, golden) +- checkChangedFiles(mark, changed, g) -} - --func codeActionErrMarker(mark marker, actionKind string, start, end protocol.Location, wantErr wantError) { +-func codeActionEditMarker(mark marker, loc protocol.Location, actionKind string, g *Golden, titles ...string) { +- changed, err := codeAction(mark.run.env, loc.URI, loc.Range, actionKind, nil, titles) +- if err != nil { +- mark.errorf("codeAction failed: %v", err) +- return +- } +- +- checkDiffs(mark, changed, g) +-} +- +-func codeActionErrMarker(mark marker, start, end protocol.Location, actionKind string, wantErr wantError) { - loc := start - loc.Range.End = end.Range.End -- _, err := codeAction(mark.run.env, loc.URI, loc.Range, actionKind, nil) +- _, err := codeAction(mark.run.env, loc.URI, loc.Range, actionKind, nil, nil) - wantErr.check(mark, err) -} - @@ -68289,7 +68291,7 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } - - var want []codeLens -- mark.consumeExtraNotes("codelens", actionMarkerFunc(func(mark marker, loc protocol.Location, title string) { +- mark.consumeExtraNotes("codelens", actionMarkerFunc(func(_ marker, loc protocol.Location, title string) { - want = append(want, codeLens{loc.Range, title}) - })) - @@ -68308,6 +68310,21 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } -} - +-func documentLinkMarker(mark marker, g *Golden) { +- var b bytes.Buffer +- links := mark.run.env.DocumentLink(mark.path()) +- for _, l := range links { +- if l.Target == nil { +- mark.errorf("%s: nil link target", l.Range) +- continue +- } +- loc := protocol.Location{URI: mark.uri(), Range: l.Range} +- fmt.Fprintln(&b, mark.run.fmtLocDetails(loc, false), *l.Target) +- } +- +- compareGolden(mark, "documentLink", b.Bytes(), g) +-} +- -// consumeExtraNotes runs the provided func for each extra note with the given -// name, and deletes all matching notes. -func (mark marker) consumeExtraNotes(name string, f func(marker)) { @@ -68324,7 +68341,7 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// kind, golden) marker. It acts like @diag(location, regexp), to set -// the expectation of a diagnostic, but then it applies the first code -// action of the specified kind suggested by the matched diagnostic. --func suggestedfixMarker(mark marker, loc protocol.Location, re *regexp.Regexp, actionKind string, golden *Golden) { +-func suggestedfixMarker(mark marker, loc protocol.Location, re *regexp.Regexp, golden *Golden) { - loc.Range.End = loc.Range.Start // diagnostics ignore end position. - // Find and remove the matching diagnostic. - diag, ok := removeDiagnostic(mark, loc, re) @@ -68334,14 +68351,14 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } - - // Apply the fix it suggests. -- changed, err := codeAction(mark.run.env, loc.URI, diag.Range, actionKind, &diag) +- changed, err := codeAction(mark.run.env, loc.URI, diag.Range, "quickfix", &diag, nil) - if err != nil { - mark.errorf("suggestedfix failed: %v. (Use @suggestedfixerr for expected errors.)", err) - return - } - - // Check the file state. -- checkChangedFiles(mark, changed, golden) +- checkDiffs(mark, changed, golden) -} - -// codeAction executes a textDocument/codeAction request for the specified @@ -68351,7 +68368,23 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// The resulting map contains resulting file contents after the code action is -// applied. Currently, this function does not support code actions that return -// edits directly; it only supports code action commands. --func codeAction(env *Env, uri protocol.DocumentURI, rng protocol.Range, actionKind string, diag *protocol.Diagnostic) (map[string][]byte, error) { +-func codeAction(env *Env, uri protocol.DocumentURI, rng protocol.Range, actionKind string, diag *protocol.Diagnostic, titles []string) (map[string][]byte, error) { +- changes, err := codeActionChanges(env, uri, rng, actionKind, diag, titles) +- if err != nil { +- return nil, err +- } +- fileChanges := make(map[string][]byte) +- if err := applyDocumentChanges(env, changes, fileChanges); err != nil { +- return nil, fmt.Errorf("applying document changes: %v", err) +- } +- return fileChanges, nil +-} +- +-// codeActionChanges executes a textDocument/codeAction request for the +-// specified location and kind, and captures the resulting document changes. +-// If diag is non-nil, it is used as the code action context. +-// If titles is non-empty, the code action title must be present among the provided titles. +-func codeActionChanges(env *Env, uri protocol.DocumentURI, rng protocol.Range, actionKind string, diag *protocol.Diagnostic, titles []string) ([]protocol.DocumentChanges, error) { - // Request all code actions that apply to the diagnostic. - // (The protocol supports filtering using Context.Only={actionKind} - // but we can give a better error if we don't filter.) @@ -68375,14 +68408,23 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - var candidates []protocol.CodeAction - for _, act := range actions { - if act.Kind == protocol.CodeActionKind(actionKind) { -- candidates = append(candidates, act) +- if len(titles) > 0 { +- for _, f := range titles { +- if act.Title == f { +- candidates = append(candidates, act) +- break +- } +- } +- } else { +- candidates = append(candidates, act) +- } - } - } - if len(candidates) != 1 { - for _, act := range actions { - env.T.Logf("found CodeAction Kind=%s Title=%q", act.Kind, act.Title) - } -- return nil, fmt.Errorf("found %d CodeActions of kind %s for this diagnostic, want 1", len(candidates), actionKind) +- return nil, fmt.Errorf("found %d CodeActions of kind %s matching filters %v for this diagnostic, want 1", len(candidates), actionKind, titles) - } - action := candidates[0] - @@ -68391,20 +68433,19 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - // Spec: - // "If a code action provides an edit and a command, first the edit is - // executed and then the command." -- fileChanges := make(map[string][]byte) - // An action may specify an edit and/or a command, to be - // applied in that order. But since applyDocumentChanges(env, - // action.Edit.DocumentChanges) doesn't compose, for now we -- // assert that all commands used in the @suggestedfix tests -- // return only a command. +- // assert that actions return one or the other. - if action.Edit != nil { - if action.Edit.Changes != nil { - env.T.Errorf("internal error: discarding unexpected CodeAction{Kind=%s, Title=%q}.Edit.Changes", action.Kind, action.Title) - } - if action.Edit.DocumentChanges != nil { -- if err := applyDocumentChanges(env, action.Edit.DocumentChanges, fileChanges); err != nil { -- return nil, fmt.Errorf("applying document changes: %v", err) +- if action.Command != nil { +- env.T.Errorf("internal error: discarding unexpected CodeAction{Kind=%s, Title=%q}.Command", action.Kind, action.Title) - } +- return action.Edit.DocumentChanges, nil - } - } - @@ -68427,15 +68468,12 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - Command: action.Command.Command, - Arguments: action.Command.Arguments, - }); err != nil { -- env.T.Fatalf("error converting command %q to edits: %v", action.Command.Command, err) -- } -- -- if err := applyDocumentChanges(env, env.Awaiter.takeDocumentChanges(), fileChanges); err != nil { -- return nil, fmt.Errorf("applying document changes from command: %v", err) +- return nil, err - } +- return env.Awaiter.takeDocumentChanges(), nil - } - -- return fileChanges, nil +- return nil, nil -} - -// TODO(adonovan): suggestedfixerr @@ -68485,6 +68523,26 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } -} - +-func prepareRenameMarker(mark marker, src, spn protocol.Location, placeholder string) { +- params := &protocol.PrepareRenameParams{ +- TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(src), +- } +- got, err := mark.run.env.Editor.Server.PrepareRename(mark.run.env.Ctx, params) +- if err != nil { +- mark.run.env.T.Fatal(err) +- } +- if placeholder == "" { +- if got != nil { +- mark.errorf("PrepareRename(...) = %v, want nil", got) +- } +- return +- } +- want := &protocol.PrepareRename2Gn{Range: spn.Range, Placeholder: placeholder} +- if diff := cmp.Diff(want, got); diff != "" { +- mark.errorf("mismatching PrepareRename result:\n%s", diff) +- } +-} +- -// symbolMarker implements the @symbol marker. -func symbolMarker(mark marker, golden *Golden) { - // Retrieve information about all symbols in this file. @@ -68595,19 +68653,26 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - fmt.Fprintf(&got, "%s %s %s\n", loc, s.Name, s.Kind) - } - -- want, ok := golden.Get(mark.run.env.T, "", got.Bytes()) +- compareGolden(mark, fmt.Sprintf("Symbol(%q)", query), got.Bytes(), golden) +-} +- +-// compareGolden compares the content of got with that of g.Get(""), reporting +-// errors on any mismatch. +-// +-// TODO(rfindley): use this helper in more places. +-func compareGolden(mark marker, op string, got []byte, g *Golden) { +- want, ok := g.Get(mark.run.env.T, "", got) - if !ok { -- mark.errorf("missing golden file @%s", golden.id) +- mark.errorf("missing golden file @%s", g.id) - return - } -- -- if diff := compare.Bytes(want, got.Bytes()); diff != "" { -- mark.errorf("Symbol(%q) mismatch:\n%s", query, diff) +- if diff := compare.Bytes(want, got); diff != "" { +- mark.errorf("%s mismatch:\n%s", op, diff) - } -} diff -urN a/gopls/internal/lsp/regtest/options.go b/gopls/internal/lsp/regtest/options.go --- a/gopls/internal/lsp/regtest/options.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/regtest/options.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/regtest/options.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,134 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -68745,7 +68810,7 @@ diff -urN a/gopls/internal/lsp/regtest/options.go b/gopls/internal/lsp/regtest/o -} diff -urN a/gopls/internal/lsp/regtest/regtest.go b/gopls/internal/lsp/regtest/regtest.go --- a/gopls/internal/lsp/regtest/regtest.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/regtest/regtest.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/regtest/regtest.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,156 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -68853,7 +68918,7 @@ diff -urN a/gopls/internal/lsp/regtest/regtest.go b/gopls/internal/lsp/regtest/r - } - - if !testenv.HasExec() { -- fmt.Printf("skipping all tests: exec not supported on %s\n", runtime.GOOS) +- fmt.Printf("skipping all tests: exec not supported on %s/%s\n", runtime.GOOS, runtime.GOARCH) - os.Exit(0) - } - testenv.ExitIfSmallMachine() @@ -68905,7 +68970,7 @@ diff -urN a/gopls/internal/lsp/regtest/regtest.go b/gopls/internal/lsp/regtest/r -} diff -urN a/gopls/internal/lsp/regtest/runner.go b/gopls/internal/lsp/regtest/runner.go --- a/gopls/internal/lsp/regtest/runner.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/regtest/runner.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/regtest/runner.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,436 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -69345,8 +69410,8 @@ diff -urN a/gopls/internal/lsp/regtest/runner.go b/gopls/internal/lsp/regtest/ru -} diff -urN a/gopls/internal/lsp/regtest/wrappers.go b/gopls/internal/lsp/regtest/wrappers.go --- a/gopls/internal/lsp/regtest/wrappers.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/regtest/wrappers.go 1970-01-01 08:00:00 -@@ -1,544 +0,0 @@ ++++ b/gopls/internal/lsp/regtest/wrappers.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,556 +0,0 @@ -// Copyright 2020 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. @@ -69463,6 +69528,18 @@ diff -urN a/gopls/internal/lsp/regtest/wrappers.go b/gopls/internal/lsp/regtest/ - } -} - +-// ReadFile returns the file content for name that applies to the current +-// editing session: if the file is open, it returns its buffer content, +-// otherwise it returns on disk content. +-func (e *Env) FileContent(name string) string { +- e.T.Helper() +- text, ok := e.Editor.BufferText(name) +- if ok { +- return text +- } +- return e.ReadWorkspaceFile(name) +-} +- -// RegexpSearch returns the starting position of the first match for re in the -// buffer specified by name, calling t.Fatal on any error. It first searches -// for the position in open buffers, then in workspace files. @@ -69893,7 +69970,7 @@ diff -urN a/gopls/internal/lsp/regtest/wrappers.go b/gopls/internal/lsp/regtest/ -} diff -urN a/gopls/internal/lsp/rename.go b/gopls/internal/lsp/rename.go --- a/gopls/internal/lsp/rename.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/rename.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/rename.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -69983,7 +70060,7 @@ diff -urN a/gopls/internal/lsp/rename.go b/gopls/internal/lsp/rename.go -} diff -urN a/gopls/internal/lsp/reset_golden.sh b/gopls/internal/lsp/reset_golden.sh --- a/gopls/internal/lsp/reset_golden.sh 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/reset_golden.sh 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/reset_golden.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -#!/bin/bash -# @@ -70017,7 +70094,7 @@ diff -urN a/gopls/internal/lsp/reset_golden.sh b/gopls/internal/lsp/reset_golden -go test ./test -golden diff -urN a/gopls/internal/lsp/safetoken/safetoken.go b/gopls/internal/lsp/safetoken/safetoken.go --- a/gopls/internal/lsp/safetoken/safetoken.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/safetoken/safetoken.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/safetoken/safetoken.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,127 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -70148,7 +70225,7 @@ diff -urN a/gopls/internal/lsp/safetoken/safetoken.go b/gopls/internal/lsp/safet -} diff -urN a/gopls/internal/lsp/safetoken/safetoken_test.go b/gopls/internal/lsp/safetoken/safetoken_test.go --- a/gopls/internal/lsp/safetoken/safetoken_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/safetoken/safetoken_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/safetoken/safetoken_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,132 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -70284,7 +70361,7 @@ diff -urN a/gopls/internal/lsp/safetoken/safetoken_test.go b/gopls/internal/lsp/ -} diff -urN a/gopls/internal/lsp/selection_range.go b/gopls/internal/lsp/selection_range.go --- a/gopls/internal/lsp/selection_range.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/selection_range.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/selection_range.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -70357,8 +70434,8 @@ diff -urN a/gopls/internal/lsp/selection_range.go b/gopls/internal/lsp/selection -} diff -urN a/gopls/internal/lsp/semantic.go b/gopls/internal/lsp/semantic.go --- a/gopls/internal/lsp/semantic.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/semantic.go 1970-01-01 08:00:00 -@@ -1,999 +0,0 @@ ++++ b/gopls/internal/lsp/semantic.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,1052 +0,0 @@ -// Copyright 2020 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. @@ -70504,6 +70581,10 @@ diff -urN a/gopls/internal/lsp/semantic.go b/gopls/internal/lsp/semantic.go - } - for _, cg := range f.Comments { - for _, c := range cg.List { +- if strings.HasPrefix(c.Text, "//go:") { +- e.godirective(c) +- continue +- } - if !strings.Contains(c.Text, "\n") { - e.token(c.Pos(), len(c.Text), tokComment, nil) - continue @@ -71358,218 +71439,58 @@ diff -urN a/gopls/internal/lsp/semantic.go b/gopls/internal/lsp/semantic.go - "deprecated", "abstract", "async", "modification", "documentation", "defaultLibrary", - } -) -diff -urN a/gopls/internal/lsp/server.go b/gopls/internal/lsp/server.go ---- a/gopls/internal/lsp/server.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/server.go 1970-01-01 08:00:00 -@@ -1,205 +0,0 @@ --// Copyright 2018 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. -- --//go:generate go run ./helper -d protocol/tsserver.go -o server_gen.go -u . -- --// Package lsp implements LSP for gopls. --package lsp -- --import ( -- "context" -- "fmt" -- "os" -- "sync" -- -- "golang.org/x/tools/gopls/internal/lsp/cache" -- "golang.org/x/tools/gopls/internal/lsp/progress" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/event" -- "golang.org/x/tools/internal/jsonrpc2" --) -- --const concurrentAnalyses = 1 -- --// NewServer creates an LSP server and binds it to handle incoming client --// messages on the supplied stream. --func NewServer(session *cache.Session, client protocol.ClientCloser, options *source.Options) *Server { -- return &Server{ -- diagnostics: map[span.URI]*fileReports{}, -- gcOptimizationDetails: make(map[source.PackageID]struct{}), -- watchedGlobPatterns: nil, // empty -- changedFiles: make(map[span.URI]struct{}), -- session: session, -- client: client, -- diagnosticsSema: make(chan struct{}, concurrentAnalyses), -- progress: progress.NewTracker(client), -- options: options, -- } --} -- --type serverState int -- --const ( -- serverCreated = serverState(iota) -- serverInitializing // set once the server has received "initialize" request -- serverInitialized // set once the server has received "initialized" request -- serverShutDown --) - --func (s serverState) String() string { -- switch s { -- case serverCreated: -- return "created" -- case serverInitializing: -- return "initializing" -- case serverInitialized: -- return "initialized" -- case serverShutDown: -- return "shutDown" +-var godirectives = map[string]struct{}{ +- // https://pkg.go.dev/cmd/compile +- "noescape": {}, +- "uintptrescapes": {}, +- "noinline": {}, +- "norace": {}, +- "nosplit": {}, +- "linkname": {}, +- +- // https://pkg.go.dev/go/build +- "build": {}, +- "binary-only-package": {}, +- "embed": {}, +-} +- +-// Tokenize godirective at the start of the comment c, if any, and the surrounding comment. +-// If there is any failure, emits the entire comment as a tokComment token. +-// Directives are highlighted as-is, even if used incorrectly. Typically there are +-// dedicated analyzers that will warn about misuse. +-func (e *encoded) godirective(c *ast.Comment) { +- // First check if '//go:directive args...' is a valid directive. +- directive, args, _ := strings.Cut(c.Text, " ") +- kind, _ := stringsCutPrefix(directive, "//go:") +- if _, ok := godirectives[kind]; !ok { +- // Unknown go: directive. +- e.token(c.Pos(), len(c.Text), tokComment, nil) +- return - } -- return fmt.Sprintf("(unknown state: %d)", int(s)) --} -- --// Server implements the protocol.Server interface. --type Server struct { -- client protocol.ClientCloser - -- stateMu sync.Mutex -- state serverState -- // notifications generated before serverInitialized -- notifications []*protocol.ShowMessageParams -- -- session *cache.Session +- // Make the 'go:directive' part stand out, the rest is comments. +- e.token(c.Pos(), len("//"), tokComment, nil) - -- tempDir string +- directiveStart := c.Pos() + token.Pos(len("//")) +- e.token(directiveStart, len(directive[len("//"):]), tokNamespace, nil) - -- // changedFiles tracks files for which there has been a textDocument/didChange. -- changedFilesMu sync.Mutex -- changedFiles map[span.URI]struct{} -- -- // folders is only valid between initialize and initialized, and holds the -- // set of folders to build views for when we are ready -- pendingFolders []protocol.WorkspaceFolder -- -- // watchedGlobPatterns is the set of glob patterns that we have requested -- // the client watch on disk. It will be updated as the set of directories -- // that the server should watch changes. -- // The map field may be reassigned but the map is immutable. -- watchedGlobPatternsMu sync.Mutex -- watchedGlobPatterns map[string]struct{} -- watchRegistrationCount int -- -- diagnosticsMu sync.Mutex -- diagnostics map[span.URI]*fileReports -- -- // gcOptimizationDetails describes the packages for which we want -- // optimization details to be included in the diagnostics. The key is the -- // ID of the package. -- gcOptimizationDetailsMu sync.Mutex -- gcOptimizationDetails map[source.PackageID]struct{} -- -- // diagnosticsSema limits the concurrency of diagnostics runs, which can be -- // expensive. -- diagnosticsSema chan struct{} -- -- progress *progress.Tracker -- -- // When the workspace fails to load, we show its status through a progress -- // report with an error message. -- criticalErrorStatusMu sync.Mutex -- criticalErrorStatus *progress.WorkDone -- -- // Track an ongoing CPU profile created with the StartProfile command and -- // terminated with the StopProfile command. -- ongoingProfileMu sync.Mutex -- ongoingProfile *os.File // if non-nil, an ongoing profile is writing to this file -- -- // Track most recently requested options. -- optionsMu sync.Mutex -- options *source.Options --} -- --func (s *Server) workDoneProgressCancel(ctx context.Context, params *protocol.WorkDoneProgressCancelParams) error { -- ctx, done := event.Start(ctx, "lsp.Server.workDoneProgressCancel") -- defer done() -- -- return s.progress.Cancel(params.Token) --} -- --func (s *Server) nonstandardRequest(ctx context.Context, method string, params interface{}) (interface{}, error) { -- ctx, done := event.Start(ctx, "lsp.Server.nonstandardRequest") -- defer done() -- -- switch method { -- case "gopls/diagnoseFiles": -- paramMap := params.(map[string]interface{}) -- // TODO(adonovan): opt: parallelize FileDiagnostics(URI...), either -- // by calling it in multiple goroutines or, better, by making -- // the relevant APIs accept a set of URIs/packages. -- for _, file := range paramMap["files"].([]interface{}) { -- snapshot, fh, ok, release, err := s.beginFileRequest(ctx, protocol.DocumentURI(file.(string)), source.UnknownKind) -- defer release() -- if !ok { -- return nil, err -- } -- -- fileID, diagnostics, err := s.diagnoseFile(ctx, snapshot, fh.URI()) -- if err != nil { -- return nil, err -- } -- if err := s.client.PublishDiagnostics(ctx, &protocol.PublishDiagnosticsParams{ -- URI: protocol.URIFromSpanURI(fh.URI()), -- Diagnostics: toProtocolDiagnostics(diagnostics), -- Version: fileID.Version(), -- }); err != nil { -- return nil, err -- } -- } -- if err := s.client.PublishDiagnostics(ctx, &protocol.PublishDiagnosticsParams{ -- URI: "gopls://diagnostics-done", -- }); err != nil { -- return nil, err -- } -- return struct{}{}, nil +- if len(args) > 0 { +- tailStart := c.Pos() + token.Pos(len(directive)+len(" ")) +- e.token(tailStart, len(args), tokComment, nil) - } -- return nil, notImplemented(method) -} - --// fileDiagnostics reports diagnostics in the specified file, --// as used by the "gopls check" or "gopls fix" commands. --// --// TODO(adonovan): opt: this function is called in a loop from the --// "gopls/diagnoseFiles" nonstandard request handler. It would be more --// efficient to compute the set of packages and TypeCheck and --// Analyze them all at once. Or instead support textDocument/diagnostic --// (golang/go#60122). --func (s *Server) diagnoseFile(ctx context.Context, snapshot source.Snapshot, uri span.URI) (source.FileHandle, []*source.Diagnostic, error) { -- fh, err := snapshot.ReadFile(ctx, uri) -- if err != nil { -- return nil, nil, err -- } -- pkg, _, err := source.NarrowestPackageForFile(ctx, snapshot, uri) -- if err != nil { -- return nil, nil, err -- } -- pkgDiags, err := pkg.DiagnosticsForFile(ctx, snapshot, uri) -- if err != nil { -- return nil, nil, err -- } -- adiags, err := source.Analyze(ctx, snapshot, map[source.PackageID]unit{pkg.Metadata().ID: {}}, nil /* progress tracker */) -- if err != nil { -- return nil, nil, err +-// Go 1.20 strings.CutPrefix. +-func stringsCutPrefix(s, prefix string) (after string, found bool) { +- if !strings.HasPrefix(s, prefix) { +- return s, false - } -- var td, ad []*source.Diagnostic // combine load/parse/type + analysis diagnostics -- source.CombineDiagnostics(pkgDiags, adiags[uri], &td, &ad) -- s.storeDiagnostics(snapshot, uri, typeCheckSource, td, true) -- s.storeDiagnostics(snapshot, uri, analysisSource, ad, true) -- return fh, append(td, ad...), nil --} -- --func notImplemented(method string) error { -- return fmt.Errorf("%w: %q not yet implemented", jsonrpc2.ErrMethodNotFound, method) +- return s[len(prefix):], true -} diff -urN a/gopls/internal/lsp/server_gen.go b/gopls/internal/lsp/server_gen.go --- a/gopls/internal/lsp/server_gen.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/server_gen.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/server_gen.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,309 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -71577,7 +71498,7 @@ diff -urN a/gopls/internal/lsp/server_gen.go b/gopls/internal/lsp/server_gen.go - -package lsp - --// code generated by helper. DO NOT EDIT. +-// Code generated by gopls/internal/lsp/helper. DO NOT EDIT. - -import ( - "context" @@ -71880,9 +71801,218 @@ diff -urN a/gopls/internal/lsp/server_gen.go b/gopls/internal/lsp/server_gen.go -func (s *Server) WorkDoneProgressCancel(ctx context.Context, params *protocol.WorkDoneProgressCancelParams) error { - return s.workDoneProgressCancel(ctx, params) -} +diff -urN a/gopls/internal/lsp/server.go b/gopls/internal/lsp/server.go +--- a/gopls/internal/lsp/server.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/server.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,205 +0,0 @@ +-// Copyright 2018 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. +- +-//go:generate go run ./helper -d protocol/tsserver.go -o server_gen.go -u . +- +-// Package lsp implements LSP for gopls. +-package lsp +- +-import ( +- "context" +- "fmt" +- "os" +- "sync" +- +- "golang.org/x/tools/gopls/internal/lsp/cache" +- "golang.org/x/tools/gopls/internal/lsp/progress" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/jsonrpc2" +-) +- +-const concurrentAnalyses = 1 +- +-// NewServer creates an LSP server and binds it to handle incoming client +-// messages on the supplied stream. +-func NewServer(session *cache.Session, client protocol.ClientCloser, options *source.Options) *Server { +- return &Server{ +- diagnostics: map[span.URI]*fileReports{}, +- gcOptimizationDetails: make(map[source.PackageID]struct{}), +- watchedGlobPatterns: nil, // empty +- changedFiles: make(map[span.URI]struct{}), +- session: session, +- client: client, +- diagnosticsSema: make(chan struct{}, concurrentAnalyses), +- progress: progress.NewTracker(client), +- options: options, +- } +-} +- +-type serverState int +- +-const ( +- serverCreated = serverState(iota) +- serverInitializing // set once the server has received "initialize" request +- serverInitialized // set once the server has received "initialized" request +- serverShutDown +-) +- +-func (s serverState) String() string { +- switch s { +- case serverCreated: +- return "created" +- case serverInitializing: +- return "initializing" +- case serverInitialized: +- return "initialized" +- case serverShutDown: +- return "shutDown" +- } +- return fmt.Sprintf("(unknown state: %d)", int(s)) +-} +- +-// Server implements the protocol.Server interface. +-type Server struct { +- client protocol.ClientCloser +- +- stateMu sync.Mutex +- state serverState +- // notifications generated before serverInitialized +- notifications []*protocol.ShowMessageParams +- +- session *cache.Session +- +- tempDir string +- +- // changedFiles tracks files for which there has been a textDocument/didChange. +- changedFilesMu sync.Mutex +- changedFiles map[span.URI]struct{} +- +- // folders is only valid between initialize and initialized, and holds the +- // set of folders to build views for when we are ready +- pendingFolders []protocol.WorkspaceFolder +- +- // watchedGlobPatterns is the set of glob patterns that we have requested +- // the client watch on disk. It will be updated as the set of directories +- // that the server should watch changes. +- // The map field may be reassigned but the map is immutable. +- watchedGlobPatternsMu sync.Mutex +- watchedGlobPatterns map[string]struct{} +- watchRegistrationCount int +- +- diagnosticsMu sync.Mutex +- diagnostics map[span.URI]*fileReports +- +- // gcOptimizationDetails describes the packages for which we want +- // optimization details to be included in the diagnostics. The key is the +- // ID of the package. +- gcOptimizationDetailsMu sync.Mutex +- gcOptimizationDetails map[source.PackageID]struct{} +- +- // diagnosticsSema limits the concurrency of diagnostics runs, which can be +- // expensive. +- diagnosticsSema chan struct{} +- +- progress *progress.Tracker +- +- // When the workspace fails to load, we show its status through a progress +- // report with an error message. +- criticalErrorStatusMu sync.Mutex +- criticalErrorStatus *progress.WorkDone +- +- // Track an ongoing CPU profile created with the StartProfile command and +- // terminated with the StopProfile command. +- ongoingProfileMu sync.Mutex +- ongoingProfile *os.File // if non-nil, an ongoing profile is writing to this file +- +- // Track most recently requested options. +- optionsMu sync.Mutex +- options *source.Options +-} +- +-func (s *Server) workDoneProgressCancel(ctx context.Context, params *protocol.WorkDoneProgressCancelParams) error { +- ctx, done := event.Start(ctx, "lsp.Server.workDoneProgressCancel") +- defer done() +- +- return s.progress.Cancel(params.Token) +-} +- +-func (s *Server) nonstandardRequest(ctx context.Context, method string, params interface{}) (interface{}, error) { +- ctx, done := event.Start(ctx, "lsp.Server.nonstandardRequest") +- defer done() +- +- switch method { +- case "gopls/diagnoseFiles": +- paramMap := params.(map[string]interface{}) +- // TODO(adonovan): opt: parallelize FileDiagnostics(URI...), either +- // by calling it in multiple goroutines or, better, by making +- // the relevant APIs accept a set of URIs/packages. +- for _, file := range paramMap["files"].([]interface{}) { +- snapshot, fh, ok, release, err := s.beginFileRequest(ctx, protocol.DocumentURI(file.(string)), source.UnknownKind) +- defer release() +- if !ok { +- return nil, err +- } +- +- fileID, diagnostics, err := s.diagnoseFile(ctx, snapshot, fh.URI()) +- if err != nil { +- return nil, err +- } +- if err := s.client.PublishDiagnostics(ctx, &protocol.PublishDiagnosticsParams{ +- URI: protocol.URIFromSpanURI(fh.URI()), +- Diagnostics: toProtocolDiagnostics(diagnostics), +- Version: fileID.Version(), +- }); err != nil { +- return nil, err +- } +- } +- if err := s.client.PublishDiagnostics(ctx, &protocol.PublishDiagnosticsParams{ +- URI: "gopls://diagnostics-done", +- }); err != nil { +- return nil, err +- } +- return struct{}{}, nil +- } +- return nil, notImplemented(method) +-} +- +-// fileDiagnostics reports diagnostics in the specified file, +-// as used by the "gopls check" or "gopls fix" commands. +-// +-// TODO(adonovan): opt: this function is called in a loop from the +-// "gopls/diagnoseFiles" nonstandard request handler. It would be more +-// efficient to compute the set of packages and TypeCheck and +-// Analyze them all at once. Or instead support textDocument/diagnostic +-// (golang/go#60122). +-func (s *Server) diagnoseFile(ctx context.Context, snapshot source.Snapshot, uri span.URI) (source.FileHandle, []*source.Diagnostic, error) { +- fh, err := snapshot.ReadFile(ctx, uri) +- if err != nil { +- return nil, nil, err +- } +- pkg, _, err := source.NarrowestPackageForFile(ctx, snapshot, uri) +- if err != nil { +- return nil, nil, err +- } +- pkgDiags, err := pkg.DiagnosticsForFile(ctx, snapshot, uri) +- if err != nil { +- return nil, nil, err +- } +- adiags, err := source.Analyze(ctx, snapshot, map[source.PackageID]unit{pkg.Metadata().ID: {}}, nil /* progress tracker */) +- if err != nil { +- return nil, nil, err +- } +- var td, ad []*source.Diagnostic // combine load/parse/type + analysis diagnostics +- source.CombineDiagnostics(pkgDiags, adiags[uri], &td, &ad) +- s.storeDiagnostics(snapshot, uri, typeCheckSource, td, true) +- s.storeDiagnostics(snapshot, uri, analysisSource, ad, true) +- return fh, append(td, ad...), nil +-} +- +-func notImplemented(method string) error { +- return fmt.Errorf("%w: %q not yet implemented", jsonrpc2.ErrMethodNotFound, method) +-} diff -urN a/gopls/internal/lsp/signature_help.go b/gopls/internal/lsp/signature_help.go --- a/gopls/internal/lsp/signature_help.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/signature_help.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/signature_help.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -71920,7 +72050,7 @@ diff -urN a/gopls/internal/lsp/signature_help.go b/gopls/internal/lsp/signature_ -} diff -urN a/gopls/internal/lsp/snippet/snippet_builder.go b/gopls/internal/lsp/snippet/snippet_builder.go --- a/gopls/internal/lsp/snippet/snippet_builder.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/snippet/snippet_builder.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/snippet/snippet_builder.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -72035,7 +72165,7 @@ diff -urN a/gopls/internal/lsp/snippet/snippet_builder.go b/gopls/internal/lsp/s -} diff -urN a/gopls/internal/lsp/snippet/snippet_builder_test.go b/gopls/internal/lsp/snippet/snippet_builder_test.go --- a/gopls/internal/lsp/snippet/snippet_builder_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/snippet/snippet_builder_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/snippet/snippet_builder_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -72101,7 +72231,7 @@ diff -urN a/gopls/internal/lsp/snippet/snippet_builder_test.go b/gopls/internal/ -} diff -urN a/gopls/internal/lsp/source/add_import.go b/gopls/internal/lsp/source/add_import.go --- a/gopls/internal/lsp/source/add_import.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/add_import.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/add_import.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -72131,8 +72261,8 @@ diff -urN a/gopls/internal/lsp/source/add_import.go b/gopls/internal/lsp/source/ -} diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/api_json.go --- a/gopls/internal/lsp/source/api_json.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/api_json.go 1970-01-01 08:00:00 -@@ -1,1263 +0,0 @@ ++++ b/gopls/internal/lsp/source/api_json.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,1288 +0,0 @@ -// Code generated by "golang.org/x/tools/gopls/doc/generate"; DO NOT EDIT. - -package source @@ -72473,7 +72603,7 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - { - Name: "\"nilness\"", - Doc: "check for redundant or impossible nil comparisons\n\nThe nilness checker inspects the control-flow graph of each function in\na package and reports nil pointer dereferences, degenerate nil\npointers, and panics with nil values. A degenerate comparison is of the form\nx==nil or x!=nil where x is statically known to be nil or non-nil. These are\noften a mistake, especially in control flow related to errors. Panics with nil\nvalues are checked because they are not detectable by\n\n\tif r := recover(); r != nil {\n\nThis check reports conditions such as:\n\n\tif f == nil { // impossible condition (f is a function)\n\t}\n\nand:\n\n\tp := &v\n\t...\n\tif p != nil { // tautological condition\n\t}\n\nand:\n\n\tif p == nil {\n\t\tprint(*p) // nil dereference\n\t}\n\nand:\n\n\tif p == nil {\n\t\tpanic(p)\n\t}", -- Default: "false", +- Default: "true", - }, - { - Name: "\"printf\"", @@ -72693,6 +72823,24 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - Hierarchy: "ui.diagnostic", - }, - { +- Name: "diagnosticsTrigger", +- Type: "enum", +- Doc: "diagnosticsTrigger controls when to run diagnostics.\n", +- EnumValues: []EnumValue{ +- { +- Value: "\"Edit\"", +- Doc: "`\"Edit\"`: Trigger diagnostics on file edit and save. (default)\n", +- }, +- { +- Value: "\"Save\"", +- Doc: "`\"Save\"`: Trigger diagnostics only on file save. Events like initial workspace load\nor configuration change will still trigger diagnostics.\n", +- }, +- }, +- Default: "\"Edit\"", +- Status: "experimental", +- Hierarchy: "ui.diagnostic", +- }, +- { - Name: "analysisProgressReporting", - Type: "bool", - Doc: "analysisProgressReporting controls whether gopls sends progress\nnotifications when construction of its index of analysis facts is taking a\nlong time. Cancelling these notifications will cancel the indexing task,\nthough it will restart after the next change in the workspace.\n\nWhen a package is opened for the first time and heavyweight analyses such as\nstaticcheck are enabled, it can take a while to construct the index of\nanalysis facts for all its dependencies. The index is cached in the\nfilesystem, so subsequent analysis should be faster.\n", @@ -72869,6 +73017,12 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - ArgDoc: "{\n\t// The fix to apply.\n\t\"Fix\": string,\n\t// The file URI for the document to fix.\n\t\"URI\": string,\n\t// The document range to scan for fixes.\n\t\"Range\": {\n\t\t\"start\": {\n\t\t\t\"line\": uint32,\n\t\t\t\"character\": uint32,\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": uint32,\n\t\t\t\"character\": uint32,\n\t\t},\n\t},\n}", - }, - { +- Command: "gopls.change_signature", +- Title: "performs a \"change signature\" refactoring.", +- Doc: "This command is experimental, currently only supporting parameter removal.\nIts signature will certainly change in the future (pun intended).", +- ArgDoc: "{\n\t\"RemoveParameter\": {\n\t\t\"uri\": string,\n\t\t\"range\": {\n\t\t\t\"start\": { ... },\n\t\t\t\"end\": { ... },\n\t\t},\n\t},\n}", +- }, +- { - Command: "gopls.check_upgrades", - Title: "Check for upgrades", - Doc: "Checks for module upgrades.", @@ -73204,9 +73358,10 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - Default: true, - }, - { -- Name: "nilness", -- Doc: "check for redundant or impossible nil comparisons\n\nThe nilness checker inspects the control-flow graph of each function in\na package and reports nil pointer dereferences, degenerate nil\npointers, and panics with nil values. A degenerate comparison is of the form\nx==nil or x!=nil where x is statically known to be nil or non-nil. These are\noften a mistake, especially in control flow related to errors. Panics with nil\nvalues are checked because they are not detectable by\n\n\tif r := recover(); r != nil {\n\nThis check reports conditions such as:\n\n\tif f == nil { // impossible condition (f is a function)\n\t}\n\nand:\n\n\tp := &v\n\t...\n\tif p != nil { // tautological condition\n\t}\n\nand:\n\n\tif p == nil {\n\t\tprint(*p) // nil dereference\n\t}\n\nand:\n\n\tif p == nil {\n\t\tpanic(p)\n\t}", -- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/nilness", +- Name: "nilness", +- Doc: "check for redundant or impossible nil comparisons\n\nThe nilness checker inspects the control-flow graph of each function in\na package and reports nil pointer dereferences, degenerate nil\npointers, and panics with nil values. A degenerate comparison is of the form\nx==nil or x!=nil where x is statically known to be nil or non-nil. These are\noften a mistake, especially in control flow related to errors. Panics with nil\nvalues are checked because they are not detectable by\n\n\tif r := recover(); r != nil {\n\nThis check reports conditions such as:\n\n\tif f == nil { // impossible condition (f is a function)\n\t}\n\nand:\n\n\tp := &v\n\t...\n\tif p != nil { // tautological condition\n\t}\n\nand:\n\n\tif p == nil {\n\t\tprint(*p) // nil dereference\n\t}\n\nand:\n\n\tif p == nil {\n\t\tpanic(p)\n\t}", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/nilness", +- Default: true, - }, - { - Name: "printf", @@ -73398,7 +73553,7 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap -} diff -urN a/gopls/internal/lsp/source/call_hierarchy.go b/gopls/internal/lsp/source/call_hierarchy.go --- a/gopls/internal/lsp/source/call_hierarchy.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/call_hierarchy.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/call_hierarchy.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,311 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -73711,9 +73866,585 @@ diff -urN a/gopls/internal/lsp/source/call_hierarchy.go b/gopls/internal/lsp/sou - } - return outgoingCallItems, nil -} +diff -urN a/gopls/internal/lsp/source/change_signature.go b/gopls/internal/lsp/source/change_signature.go +--- a/gopls/internal/lsp/source/change_signature.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/change_signature.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,572 +0,0 @@ +-// Copyright 2023 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 source +- +-import ( +- "bytes" +- "context" +- "fmt" +- "go/ast" +- "go/format" +- "go/parser" +- "go/token" +- "go/types" +- "regexp" +- +- "golang.org/x/tools/go/ast/astutil" +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/safetoken" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/imports" +- internalastutil "golang.org/x/tools/internal/astutil" +- "golang.org/x/tools/internal/diff" +- "golang.org/x/tools/internal/refactor/inline" +- "golang.org/x/tools/internal/tokeninternal" +- "golang.org/x/tools/internal/typesinternal" +-) +- +-// RemoveUnusedParameter computes a refactoring to remove the parameter +-// indicated by the given range, which must be contained within an unused +-// parameter name or field. +-// +-// This operation is a work in progress. Remaining TODO: +-// - Handle function assignment correctly. +-// - Improve the extra newlines in output. +-// - Stream type checking via ForEachPackage. +-// - Avoid unnecessary additional type checking. +-func RemoveUnusedParameter(ctx context.Context, fh FileHandle, rng protocol.Range, snapshot Snapshot) ([]protocol.DocumentChanges, error) { +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, fh.URI()) +- if err != nil { +- return nil, err +- } +- if perrors, terrors := pkg.GetParseErrors(), pkg.GetTypeErrors(); len(perrors) > 0 || len(terrors) > 0 { +- var sample string +- if len(perrors) > 0 { +- sample = perrors[0].Error() +- } else { +- sample = terrors[0].Error() +- } +- return nil, fmt.Errorf("can't change signatures for packages with parse or type errors: (e.g. %s)", sample) +- } +- +- info := FindParam(pgf, rng) +- if info.Decl == nil { +- return nil, fmt.Errorf("failed to find declaration") +- } +- if info.Decl.Recv != nil { +- return nil, fmt.Errorf("can't change signature of methods (yet)") +- } +- if info.Field == nil { +- return nil, fmt.Errorf("failed to find field") +- } +- +- // Create the new declaration, which is a copy of the original decl with the +- // unnecessary parameter removed. +- newDecl := internalastutil.CloneNode(info.Decl) +- if info.Name != nil { +- names := remove(newDecl.Type.Params.List[info.FieldIndex].Names, info.NameIndex) +- newDecl.Type.Params.List[info.FieldIndex].Names = names +- } +- if len(newDecl.Type.Params.List[info.FieldIndex].Names) == 0 { +- // Unnamed, or final name was removed: in either case, remove the field. +- newDecl.Type.Params.List = remove(newDecl.Type.Params.List, info.FieldIndex) +- } +- +- // Compute inputs into building a wrapper function around the modified +- // signature. +- var ( +- params = internalastutil.CloneNode(info.Decl.Type.Params) // "_" names will be modified +- args []ast.Expr // arguments to delegate +- variadic = false // whether the signature is variadic +- ) +- { +- allNames := make(map[string]bool) // for renaming blanks +- for _, fld := range params.List { +- for _, n := range fld.Names { +- if n.Name != "_" { +- allNames[n.Name] = true +- } +- } +- } +- blanks := 0 +- for i, fld := range params.List { +- for j, n := range fld.Names { +- if i == info.FieldIndex && j == info.NameIndex { +- continue +- } +- if n.Name == "_" { +- // Create names for blank (_) parameters so the delegating wrapper +- // can refer to them. +- for { +- newName := fmt.Sprintf("blank%d", blanks) +- blanks++ +- if !allNames[newName] { +- n.Name = newName +- break +- } +- } +- } +- args = append(args, &ast.Ident{Name: n.Name}) +- if i == len(params.List)-1 { +- _, variadic = fld.Type.(*ast.Ellipsis) +- } +- } +- } +- } +- +- // Rewrite all referring calls. +- newContent, err := rewriteCalls(ctx, signatureRewrite{ +- snapshot: snapshot, +- pkg: pkg, +- pgf: pgf, +- origDecl: info.Decl, +- newDecl: newDecl, +- params: params, +- callArgs: args, +- variadic: variadic, +- }) +- if err != nil { +- return nil, err +- } +- // Finally, rewrite the original declaration. We do this after inlining all +- // calls, as there may be calls in the same file as the declaration. But none +- // of the inlining should have changed the location of the original +- // declaration. +- { +- idx := findDecl(pgf.File, info.Decl) +- if idx < 0 { +- return nil, bug.Errorf("didn't find original decl") +- } +- +- src, ok := newContent[pgf.URI] +- if !ok { +- src = pgf.Src +- } +- fset := tokeninternal.FileSetFor(pgf.Tok) +- src, err = rewriteSignature(fset, idx, src, newDecl) +- newContent[pgf.URI] = src +- } +- +- // Translate the resulting state into document changes. +- var changes []protocol.DocumentChanges +- for uri, after := range newContent { +- fh, err := snapshot.ReadFile(ctx, uri) +- if err != nil { +- return nil, err +- } +- before, err := fh.Content() +- if err != nil { +- return nil, err +- } +- edits := diff.Bytes(before, after) +- mapper := protocol.NewMapper(uri, before) +- pedits, err := ToProtocolEdits(mapper, edits) +- if err != nil { +- return nil, fmt.Errorf("computing edits for %s: %v", uri, err) +- } +- changes = append(changes, protocol.DocumentChanges{ +- TextDocumentEdit: &protocol.TextDocumentEdit{ +- TextDocument: protocol.OptionalVersionedTextDocumentIdentifier{ +- Version: fh.Version(), +- TextDocumentIdentifier: protocol.TextDocumentIdentifier{URI: protocol.URIFromSpanURI(uri)}, +- }, +- Edits: pedits, +- }, +- }) +- } +- return changes, nil +-} +- +-// rewriteSignature rewrites the signature of the declIdx'th declaration in src +-// to use the signature of newDecl (described by fset). +-// +-// TODO(rfindley): I think this operation could be generalized, for example by +-// using a concept of a 'nodepath' to correlate nodes between two related +-// files. +-// +-// Note that with its current application, rewriteSignature is expected to +-// succeed. Separate bug.Errorf calls are used below (rather than one call at +-// the callsite) in order to have greater precision. +-func rewriteSignature(fset *token.FileSet, declIdx int, src0 []byte, newDecl *ast.FuncDecl) ([]byte, error) { +- // Parse the new file0 content, to locate the original params. +- file0, err := parser.ParseFile(fset, "", src0, parser.ParseComments|parser.SkipObjectResolution) +- if err != nil { +- return nil, bug.Errorf("re-parsing declaring file failed: %v", err) +- } +- decl0, _ := file0.Decls[declIdx].(*ast.FuncDecl) +- // Inlining shouldn't have changed the location of any declarations, but do +- // a sanity check. +- if decl0 == nil || decl0.Name.Name != newDecl.Name.Name { +- return nil, bug.Errorf("inlining affected declaration order: found %v, not func %s", decl0, newDecl.Name.Name) +- } +- opening0, closing0, err := safetoken.Offsets(fset.File(decl0.Pos()), decl0.Type.Params.Opening, decl0.Type.Params.Closing) +- if err != nil { +- return nil, bug.Errorf("can't find params: %v", err) +- } +- +- // Format the modified signature and apply a textual replacement. This +- // minimizes comment disruption. +- formattedType := FormatNode(fset, newDecl.Type) +- expr, err := parser.ParseExprFrom(fset, "", []byte(formattedType), 0) +- if err != nil { +- return nil, bug.Errorf("parsing modified signature: %v", err) +- } +- newType := expr.(*ast.FuncType) +- opening1, closing1, err := safetoken.Offsets(fset.File(newType.Pos()), newType.Params.Opening, newType.Params.Closing) +- if err != nil { +- return nil, bug.Errorf("param offsets: %v", err) +- } +- newParams := formattedType[opening1 : closing1+1] +- +- // Splice. +- var buf bytes.Buffer +- buf.Write(src0[:opening0]) +- buf.WriteString(newParams) +- buf.Write(src0[closing0+1:]) +- newSrc := buf.Bytes() +- if len(file0.Imports) > 0 { +- formatted, err := imports.Process("output", newSrc, nil) +- if err != nil { +- return nil, bug.Errorf("imports.Process failed: %v", err) +- } +- newSrc = formatted +- } +- return newSrc, nil +-} +- +-// ParamInfo records information about a param identified by a position. +-type ParamInfo struct { +- Decl *ast.FuncDecl // enclosing func decl, or nil +- FieldIndex int // index of Field in Decl.Type.Params, or -1 +- Field *ast.Field // enclosing field of Decl, or nil +- NameIndex int // index of Name in Field.Names, or nil +- Name *ast.Ident // indicated name (either enclosing, or Field.Names[0] if len(Field.Names) == 1) +-} +- +-// FindParam finds the parameter information spanned by the given range. +-func FindParam(pgf *ParsedGoFile, rng protocol.Range) ParamInfo { +- info := ParamInfo{FieldIndex: -1, NameIndex: -1} +- start, end, err := pgf.RangePos(rng) +- if err != nil { +- bug.Reportf("(file=%v).RangePos(%v) failed: %v", pgf.URI, rng, err) +- return info +- } +- +- path, _ := astutil.PathEnclosingInterval(pgf.File, start, end) +- var ( +- id *ast.Ident +- field *ast.Field +- decl *ast.FuncDecl +- ) +- // Find the outermost enclosing node of each kind, whether or not they match +- // the semantics described in the docstring. +- for _, n := range path { +- switch n := n.(type) { +- case *ast.Ident: +- id = n +- case *ast.Field: +- field = n +- case *ast.FuncDecl: +- decl = n +- } +- } +- // Check the conditions described in the docstring. +- if decl == nil { +- return info +- } +- info.Decl = decl +- for fi, f := range decl.Type.Params.List { +- if f == field { +- info.FieldIndex = fi +- info.Field = f +- for ni, n := range f.Names { +- if n == id { +- info.NameIndex = ni +- info.Name = n +- break +- } +- } +- if info.Name == nil && len(info.Field.Names) == 1 { +- info.NameIndex = 0 +- info.Name = info.Field.Names[0] +- } +- break +- } +- } +- return info +-} +- +-// signatureRewrite defines a rewritten function signature. +-// +-// See rewriteCalls for more details. +-type signatureRewrite struct { +- snapshot Snapshot +- pkg Package +- pgf *ParsedGoFile +- origDecl, newDecl *ast.FuncDecl +- params *ast.FieldList +- callArgs []ast.Expr +- variadic bool +-} +- +-// rewriteCalls returns the document changes required to rewrite the +-// signature of origDecl to that of newDecl. +-// +-// This is a rather complicated factoring of the rewrite operation, but is able +-// to describe arbitrary rewrites. Specifically, rewriteCalls creates a +-// synthetic copy of pkg, where the original function declaration is changed to +-// be a trivial wrapper around the new declaration. params and callArgs are +-// used to perform this delegation: params must have the same type as origDecl, +-// but may have renamed parameters (such as is required for delegating blank +-// parameters). callArgs are the arguments of the delegated call (i.e. using +-// params). +-// +-// For example, consider removing the unused 'b' parameter below, rewriting +-// +-// func Foo(a, b, c, _ int) int { +-// return a+c +-// } +-// +-// To +-// +-// func Foo(a, c, _ int) int { +-// return a+c +-// } +-// +-// In this case, rewriteCalls is parameterized as follows: +-// - origDecl is the original declaration +-// - newDecl is the new declaration, which is a copy of origDecl less the 'b' +-// parameter. +-// - params is a new parameter list (a, b, c, blank0 int) to be used for the +-// new wrapper. +-// - callArgs is the argument list (a, c, blank0), to be used to call the new +-// delegate. +-// +-// rewriting is expressed this way so that rewriteCalls can own the details +-// of *how* this rewriting is performed. For example, as of writing it names +-// the synthetic delegate G_o_p_l_s_foo, but the caller need not know this. +-// +-// By passing an entirely new declaration, rewriteCalls may be used for +-// signature refactorings that may affect the function body, such as removing +-// or adding return values. +-func rewriteCalls(ctx context.Context, rw signatureRewrite) (map[span.URI][]byte, error) { +- // tag is a unique prefix that is added to the delegated declaration. +- // +- // It must have a ~0% probability of causing collisions with existing names. +- const tag = "G_o_p_l_s_" +- +- var ( +- modifiedSrc []byte +- modifiedFile *ast.File +- modifiedDecl *ast.FuncDecl +- ) +- { +- delegate := internalastutil.CloneNode(rw.newDecl) // clone before modifying +- delegate.Name.Name = tag + delegate.Name.Name +- if obj := rw.pkg.GetTypes().Scope().Lookup(delegate.Name.Name); obj != nil { +- return nil, fmt.Errorf("synthetic name %q conflicts with an existing declaration", delegate.Name.Name) +- } +- +- wrapper := internalastutil.CloneNode(rw.origDecl) +- wrapper.Type.Params = rw.params +- call := &ast.CallExpr{ +- Fun: &ast.Ident{Name: delegate.Name.Name}, +- Args: rw.callArgs, +- } +- if rw.variadic { +- call.Ellipsis = 1 // must not be token.NoPos +- } +- +- var stmt ast.Stmt +- if delegate.Type.Results.NumFields() > 0 { +- stmt = &ast.ReturnStmt{ +- Results: []ast.Expr{call}, +- } +- } else { +- stmt = &ast.ExprStmt{ +- X: call, +- } +- } +- wrapper.Body = &ast.BlockStmt{ +- List: []ast.Stmt{stmt}, +- } +- +- fset := tokeninternal.FileSetFor(rw.pgf.Tok) +- var err error +- modifiedSrc, err = replaceFileDecl(rw.pgf, rw.origDecl, delegate) +- if err != nil { +- return nil, err +- } +- // TODO(rfindley): we can probably get away with one fewer parse operations +- // by returning the modified AST from replaceDecl. Investigate if that is +- // accurate. +- modifiedSrc = append(modifiedSrc, []byte("\n\n"+FormatNode(fset, wrapper))...) +- modifiedFile, err = parser.ParseFile(rw.pkg.FileSet(), rw.pgf.URI.Filename(), modifiedSrc, parser.ParseComments|parser.SkipObjectResolution) +- if err != nil { +- return nil, err +- } +- modifiedDecl = modifiedFile.Decls[len(modifiedFile.Decls)-1].(*ast.FuncDecl) +- } +- +- // Type check pkg again with the modified file, to compute the synthetic +- // callee. +- logf := logger(ctx, "change signature", rw.snapshot.Options().VerboseOutput) +- pkg2, info, err := reTypeCheck(logf, rw.pkg, map[span.URI]*ast.File{rw.pgf.URI: modifiedFile}, false) +- if err != nil { +- return nil, err +- } +- calleeInfo, err := inline.AnalyzeCallee(logf, rw.pkg.FileSet(), pkg2, info, modifiedDecl, modifiedSrc) +- if err != nil { +- return nil, fmt.Errorf("analyzing callee: %v", err) +- } +- +- post := func(got []byte) []byte { return bytes.ReplaceAll(got, []byte(tag), nil) } +- return inlineAllCalls(ctx, logf, rw.snapshot, rw.pkg, rw.pgf, rw.origDecl, calleeInfo, post) +-} +- +-// reTypeCheck re-type checks orig with new file contents defined by fileMask. +-// +-// It expects that any newly added imports are already present in the +-// transitive imports of orig. +-// +-// If expectErrors is true, reTypeCheck allows errors in the new package. +-// TODO(rfindley): perhaps this should be a filter to specify which errors are +-// acceptable. +-func reTypeCheck(logf func(string, ...any), orig Package, fileMask map[span.URI]*ast.File, expectErrors bool) (*types.Package, *types.Info, error) { +- pkg := types.NewPackage(string(orig.Metadata().PkgPath), string(orig.Metadata().Name)) +- info := &types.Info{ +- Types: make(map[ast.Expr]types.TypeAndValue), +- Defs: make(map[*ast.Ident]types.Object), +- Uses: make(map[*ast.Ident]types.Object), +- Implicits: make(map[ast.Node]types.Object), +- Selections: make(map[*ast.SelectorExpr]*types.Selection), +- Scopes: make(map[ast.Node]*types.Scope), +- Instances: make(map[*ast.Ident]types.Instance), +- } +- { +- var files []*ast.File +- for _, pgf := range orig.CompiledGoFiles() { +- if mask, ok := fileMask[pgf.URI]; ok { +- files = append(files, mask) +- } else { +- files = append(files, pgf.File) +- } +- } +- +- // Implement a BFS for imports in the transitive package graph. +- // +- // Note that this only works if any newly added imports are expected to be +- // present among transitive imports. In general we cannot assume this to +- // be the case, but in the special case of removing a parameter it works +- // because any parameter types must be present in export data. +- var importer func(importPath string) (*types.Package, error) +- { +- var ( +- importsByPath = make(map[string]*types.Package) // cached imports +- toSearch = []*types.Package{orig.GetTypes()} // packages to search +- searched = make(map[string]bool) // path -> (false, if present in toSearch; true, if already searched) +- ) +- importer = func(path string) (*types.Package, error) { +- if p, ok := importsByPath[path]; ok { +- return p, nil +- } +- for len(toSearch) > 0 { +- pkg := toSearch[0] +- toSearch = toSearch[1:] +- searched[pkg.Path()] = true +- for _, p := range pkg.Imports() { +- // TODO(rfindley): this is incorrect: p.Path() is a package path, +- // whereas path is an import path. We can fix this by reporting any +- // newly added imports from inlining, or by using the ImporterFrom +- // interface and package metadata. +- // +- // TODO(rfindley): can't the inliner also be wrong here? It's +- // possible that an import path means different things depending on +- // the location. +- importsByPath[p.Path()] = p +- if _, ok := searched[p.Path()]; !ok { +- searched[p.Path()] = false +- toSearch = append(toSearch, p) +- } +- } +- if p, ok := importsByPath[path]; ok { +- return p, nil +- } +- } +- return nil, fmt.Errorf("missing import") +- } +- } +- cfg := &types.Config{ +- Sizes: orig.Metadata().TypesSizes, +- Importer: ImporterFunc(importer), +- } +- +- // Copied from cache/check.go. +- // TODO(rfindley): factor this out and fix goVersionRx. +- // Set Go dialect. +- if module := orig.Metadata().Module; module != nil && module.GoVersion != "" { +- goVersion := "go" + module.GoVersion +- // types.NewChecker panics if GoVersion is invalid. +- // An unparsable mod file should probably stop us +- // before we get here, but double check just in case. +- if goVersionRx.MatchString(goVersion) { +- typesinternal.SetGoVersion(cfg, goVersion) +- } +- } +- if expectErrors { +- cfg.Error = func(err error) { +- logf("re-type checking: expected error: %v", err) +- } +- } +- typesinternal.SetUsesCgo(cfg) +- checker := types.NewChecker(cfg, orig.FileSet(), pkg, info) +- if err := checker.Files(files); err != nil && !expectErrors { +- return nil, nil, fmt.Errorf("type checking rewritten package: %v", err) +- } +- } +- return pkg, info, nil +-} +- +-// TODO(golang/go#63472): this looks wrong with the new Go version syntax. +-var goVersionRx = regexp.MustCompile(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`) +- +-func remove[T any](s []T, i int) []T { +- return append(s[:i], s[i+1:]...) +-} +- +-// replaceFileDecl replaces old with new in the file described by pgf. +-// +-// TODO(rfindley): generalize, and combine with rewriteSignature. +-func replaceFileDecl(pgf *ParsedGoFile, old, new ast.Decl) ([]byte, error) { +- i := findDecl(pgf.File, old) +- if i == -1 { +- return nil, bug.Errorf("didn't find old declaration") +- } +- start, end, err := safetoken.Offsets(pgf.Tok, old.Pos(), old.End()) +- if err != nil { +- return nil, err +- } +- var out bytes.Buffer +- out.Write(pgf.Src[:start]) +- fset := tokeninternal.FileSetFor(pgf.Tok) +- if err := format.Node(&out, fset, new); err != nil { +- return nil, bug.Errorf("formatting new node: %v", err) +- } +- out.Write(pgf.Src[end:]) +- return out.Bytes(), nil +-} +- +-// findDecl finds the index of decl in file.Decls. +-// +-// TODO: use slices.Index when it is available. +-func findDecl(file *ast.File, decl ast.Decl) int { +- for i, d := range file.Decls { +- if d == decl { +- return i +- } +- } +- return -1 +-} diff -urN a/gopls/internal/lsp/source/code_lens.go b/gopls/internal/lsp/source/code_lens.go --- a/gopls/internal/lsp/source/code_lens.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/code_lens.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/code_lens.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,248 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -73759,7 +74490,7 @@ diff -urN a/gopls/internal/lsp/source/code_lens.go b/gopls/internal/lsp/source/c - if err != nil { - return nil, err - } -- fns, err := TestsAndBenchmarks(ctx, snapshot, pkg, pgf) +- fns, err := TestsAndBenchmarks(pkg, pgf) - if err != nil { - return nil, err - } @@ -73805,18 +74536,18 @@ diff -urN a/gopls/internal/lsp/source/code_lens.go b/gopls/internal/lsp/source/c - return codeLens, nil -} - --type testFn struct { +-type TestFn struct { - Name string - Rng protocol.Range -} - --type testFns struct { -- Tests []testFn -- Benchmarks []testFn +-type TestFns struct { +- Tests []TestFn +- Benchmarks []TestFn -} - --func TestsAndBenchmarks(ctx context.Context, snapshot Snapshot, pkg Package, pgf *ParsedGoFile) (testFns, error) { -- var out testFns +-func TestsAndBenchmarks(pkg Package, pgf *ParsedGoFile) (TestFns, error) { +- var out TestFns - - if !strings.HasSuffix(pgf.URI.Filename(), "_test.go") { - return out, nil @@ -73834,11 +74565,11 @@ diff -urN a/gopls/internal/lsp/source/code_lens.go b/gopls/internal/lsp/source/c - } - - if matchTestFunc(fn, pkg, testRe, "T") { -- out.Tests = append(out.Tests, testFn{fn.Name.Name, rng}) +- out.Tests = append(out.Tests, TestFn{fn.Name.Name, rng}) - } - - if matchTestFunc(fn, pkg, benchmarkRe, "B") { -- out.Benchmarks = append(out.Benchmarks, testFn{fn.Name.Name, rng}) +- out.Benchmarks = append(out.Benchmarks, TestFn{fn.Name.Name, rng}) - } - } - @@ -73965,7 +74696,7 @@ diff -urN a/gopls/internal/lsp/source/code_lens.go b/gopls/internal/lsp/source/c -} diff -urN a/gopls/internal/lsp/source/comment.go b/gopls/internal/lsp/source/comment.go --- a/gopls/internal/lsp/source/comment.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/comment.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/comment.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,384 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -74353,7 +75084,7 @@ diff -urN a/gopls/internal/lsp/source/comment.go b/gopls/internal/lsp/source/com -} diff -urN a/gopls/internal/lsp/source/comment_go118_test.go b/gopls/internal/lsp/source/comment_go118_test.go --- a/gopls/internal/lsp/source/comment_go118_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/comment_go118_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/comment_go118_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,371 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -74728,7 +75459,7 @@ diff -urN a/gopls/internal/lsp/source/comment_go118_test.go b/gopls/internal/lsp -} diff -urN a/gopls/internal/lsp/source/comment_go119.go b/gopls/internal/lsp/source/comment_go119.go --- a/gopls/internal/lsp/source/comment_go119.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/comment_go119.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/comment_go119.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -74788,7 +75519,7 @@ diff -urN a/gopls/internal/lsp/source/comment_go119.go b/gopls/internal/lsp/sour -} diff -urN a/gopls/internal/lsp/source/completion/builtin.go b/gopls/internal/lsp/source/completion/builtin.go --- a/gopls/internal/lsp/source/completion/builtin.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/builtin.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/builtin.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -74939,7 +75670,7 @@ diff -urN a/gopls/internal/lsp/source/completion/builtin.go b/gopls/internal/lsp -} diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/lsp/source/completion/completion.go --- a/gopls/internal/lsp/source/completion/completion.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/completion.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/completion.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,3279 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -78222,7 +78953,7 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ -} diff -urN a/gopls/internal/lsp/source/completion/deep_completion.go b/gopls/internal/lsp/source/completion/deep_completion.go --- a/gopls/internal/lsp/source/completion/deep_completion.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/deep_completion.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/deep_completion.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,378 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -78604,7 +79335,7 @@ diff -urN a/gopls/internal/lsp/source/completion/deep_completion.go b/gopls/inte -} diff -urN a/gopls/internal/lsp/source/completion/deep_completion_test.go b/gopls/internal/lsp/source/completion/deep_completion_test.go --- a/gopls/internal/lsp/source/completion/deep_completion_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/deep_completion_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/deep_completion_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -78641,7 +79372,7 @@ diff -urN a/gopls/internal/lsp/source/completion/deep_completion_test.go b/gopls -} diff -urN a/gopls/internal/lsp/source/completion/definition.go b/gopls/internal/lsp/source/completion/definition.go --- a/gopls/internal/lsp/source/completion/definition.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/definition.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/definition.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,160 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -78805,7 +79536,7 @@ diff -urN a/gopls/internal/lsp/source/completion/definition.go b/gopls/internal/ -} diff -urN a/gopls/internal/lsp/source/completion/format.go b/gopls/internal/lsp/source/completion/format.go --- a/gopls/internal/lsp/source/completion/format.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/format.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/format.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,345 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -79154,7 +79885,7 @@ diff -urN a/gopls/internal/lsp/source/completion/format.go b/gopls/internal/lsp/ -} diff -urN a/gopls/internal/lsp/source/completion/fuzz.go b/gopls/internal/lsp/source/completion/fuzz.go --- a/gopls/internal/lsp/source/completion/fuzz.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/fuzz.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/fuzz.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,142 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -79300,7 +80031,7 @@ diff -urN a/gopls/internal/lsp/source/completion/fuzz.go b/gopls/internal/lsp/so -} diff -urN a/gopls/internal/lsp/source/completion/keywords.go b/gopls/internal/lsp/source/completion/keywords.go --- a/gopls/internal/lsp/source/completion/keywords.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/keywords.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/keywords.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,154 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -79458,7 +80189,7 @@ diff -urN a/gopls/internal/lsp/source/completion/keywords.go b/gopls/internal/ls -} diff -urN a/gopls/internal/lsp/source/completion/labels.go b/gopls/internal/lsp/source/completion/labels.go --- a/gopls/internal/lsp/source/completion/labels.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/labels.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/labels.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -79574,7 +80305,7 @@ diff -urN a/gopls/internal/lsp/source/completion/labels.go b/gopls/internal/lsp/ -} diff -urN a/gopls/internal/lsp/source/completion/literal.go b/gopls/internal/lsp/source/completion/literal.go --- a/gopls/internal/lsp/source/completion/literal.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/literal.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/literal.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,592 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -80170,7 +80901,7 @@ diff -urN a/gopls/internal/lsp/source/completion/literal.go b/gopls/internal/lsp -} diff -urN a/gopls/internal/lsp/source/completion/package.go b/gopls/internal/lsp/source/completion/package.go --- a/gopls/internal/lsp/source/completion/package.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/package.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/package.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,351 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -80525,7 +81256,7 @@ diff -urN a/gopls/internal/lsp/source/completion/package.go b/gopls/internal/lsp -} diff -urN a/gopls/internal/lsp/source/completion/package_test.go b/gopls/internal/lsp/source/completion/package_test.go --- a/gopls/internal/lsp/source/completion/package_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/package_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/package_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -80610,7 +81341,7 @@ diff -urN a/gopls/internal/lsp/source/completion/package_test.go b/gopls/interna -} diff -urN a/gopls/internal/lsp/source/completion/postfix_snippets.go b/gopls/internal/lsp/source/completion/postfix_snippets.go --- a/gopls/internal/lsp/source/completion/postfix_snippets.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/postfix_snippets.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/postfix_snippets.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,481 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -81095,7 +81826,7 @@ diff -urN a/gopls/internal/lsp/source/completion/postfix_snippets.go b/gopls/int -} diff -urN a/gopls/internal/lsp/source/completion/printf.go b/gopls/internal/lsp/source/completion/printf.go --- a/gopls/internal/lsp/source/completion/printf.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/printf.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/printf.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,172 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -81271,7 +82002,7 @@ diff -urN a/gopls/internal/lsp/source/completion/printf.go b/gopls/internal/lsp/ -} diff -urN a/gopls/internal/lsp/source/completion/printf_test.go b/gopls/internal/lsp/source/completion/printf_test.go --- a/gopls/internal/lsp/source/completion/printf_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/printf_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/printf_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -81347,7 +82078,7 @@ diff -urN a/gopls/internal/lsp/source/completion/printf_test.go b/gopls/internal -} diff -urN a/gopls/internal/lsp/source/completion/snippet.go b/gopls/internal/lsp/source/completion/snippet.go --- a/gopls/internal/lsp/source/completion/snippet.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/snippet.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/snippet.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -81472,8 +82203,8 @@ diff -urN a/gopls/internal/lsp/source/completion/snippet.go b/gopls/internal/lsp -} diff -urN a/gopls/internal/lsp/source/completion/statements.go b/gopls/internal/lsp/source/completion/statements.go --- a/gopls/internal/lsp/source/completion/statements.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/statements.go 1970-01-01 08:00:00 -@@ -1,361 +0,0 @@ ++++ b/gopls/internal/lsp/source/completion/statements.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,360 +0,0 @@ -// Copyright 2020 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. @@ -81783,9 +82514,8 @@ diff -urN a/gopls/internal/lsp/source/completion/statements.go b/gopls/internal/ - } - - c.items = append(c.items, CompletionItem{ -- Label: label, -- // There doesn't seem to be a more appropriate kind. -- Kind: protocol.KeywordCompletion, +- Label: label, +- Kind: protocol.SnippetCompletion, - Score: highScore, - snippet: &snip, - }) @@ -81837,7 +82567,7 @@ diff -urN a/gopls/internal/lsp/source/completion/statements.go b/gopls/internal/ -} diff -urN a/gopls/internal/lsp/source/completion/util.go b/gopls/internal/lsp/source/completion/util.go --- a/gopls/internal/lsp/source/completion/util.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/util.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/util.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,344 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -82185,7 +82915,7 @@ diff -urN a/gopls/internal/lsp/source/completion/util.go b/gopls/internal/lsp/so -} diff -urN a/gopls/internal/lsp/source/completion/util_test.go b/gopls/internal/lsp/source/completion/util_test.go --- a/gopls/internal/lsp/source/completion/util_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/completion/util_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/completion/util_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -82217,7 +82947,7 @@ diff -urN a/gopls/internal/lsp/source/completion/util_test.go b/gopls/internal/l -} diff -urN a/gopls/internal/lsp/source/definition.go b/gopls/internal/lsp/source/definition.go --- a/gopls/internal/lsp/source/definition.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/definition.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/definition.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,261 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -82281,7 +83011,7 @@ diff -urN a/gopls/internal/lsp/source/definition.go b/gopls/internal/lsp/source/ - } - - // Handle the case where the cursor is in a linkname directive. -- locations, err := LinknameDefinition(ctx, snapshot, fh, position) +- locations, err := LinknameDefinition(ctx, snapshot, pgf.Mapper, position) - if !errors.Is(err, ErrNoLinkname) { - return locations, err - } @@ -82482,7 +83212,7 @@ diff -urN a/gopls/internal/lsp/source/definition.go b/gopls/internal/lsp/source/ -} diff -urN a/gopls/internal/lsp/source/diagnostics.go b/gopls/internal/lsp/source/diagnostics.go --- a/gopls/internal/lsp/source/diagnostics.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/diagnostics.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/diagnostics.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,187 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -82673,7 +83403,7 @@ diff -urN a/gopls/internal/lsp/source/diagnostics.go b/gopls/internal/lsp/source -} diff -urN a/gopls/internal/lsp/source/embeddirective.go b/gopls/internal/lsp/source/embeddirective.go --- a/gopls/internal/lsp/source/embeddirective.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/embeddirective.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/embeddirective.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,195 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -82872,8 +83602,8 @@ diff -urN a/gopls/internal/lsp/source/embeddirective.go b/gopls/internal/lsp/sou -} diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/extract.go --- a/gopls/internal/lsp/source/extract.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/extract.go 1970-01-01 08:00:00 -@@ -1,1352 +0,0 @@ ++++ b/gopls/internal/lsp/source/extract.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,1351 +0,0 @@ -// Copyright 2020 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. @@ -82912,14 +83642,14 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - // TODO: stricter rules for selectorExpr. - case *ast.BasicLit, *ast.CompositeLit, *ast.IndexExpr, *ast.SliceExpr, - *ast.UnaryExpr, *ast.BinaryExpr, *ast.SelectorExpr: -- lhsName, _ := generateAvailableIdentifier(expr.Pos(), file, path, pkg, info, "x", 0) +- lhsName, _ := generateAvailableIdentifier(expr.Pos(), path, pkg, info, "x", 0) - lhsNames = append(lhsNames, lhsName) - case *ast.CallExpr: - tup, ok := info.TypeOf(expr).(*types.Tuple) - if !ok { - // If the call expression only has one return value, we can treat it the - // same as our standard extract variable case. -- lhsName, _ := generateAvailableIdentifier(expr.Pos(), file, path, pkg, info, "x", 0) +- lhsName, _ := generateAvailableIdentifier(expr.Pos(), path, pkg, info, "x", 0) - lhsNames = append(lhsNames, lhsName) - break - } @@ -82927,7 +83657,7 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - for i := 0; i < tup.Len(); i++ { - // Generate a unique variable for each return value. - var lhsName string -- lhsName, idx = generateAvailableIdentifier(expr.Pos(), file, path, pkg, info, "x", idx) +- lhsName, idx = generateAvailableIdentifier(expr.Pos(), path, pkg, info, "x", idx) - lhsNames = append(lhsNames, lhsName) - } - default: @@ -83018,7 +83748,7 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - -// generateAvailableIdentifier adjusts the new function name until there are no collisions in scope. -// Possible collisions include other function and variable names. Returns the next index to check for prefix. --func generateAvailableIdentifier(pos token.Pos, file *ast.File, path []ast.Node, pkg *types.Package, info *types.Info, prefix string, idx int) (string, int) { +-func generateAvailableIdentifier(pos token.Pos, path []ast.Node, pkg *types.Package, info *types.Info, prefix string, idx int) (string, int) { - scopes := CollectScopes(info, path, pos) - scopes = append(scopes, pkg.Scope()) - return generateIdentifier(idx, prefix, func(name string) bool { @@ -83361,8 +84091,7 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - // signature of the extracted function as described above. Adjust all of - // the return statements in the extracted function to reflect this change in - // signature. -- if err := adjustReturnStatements(returnTypes, seenVars, fset, file, -- pkg, extractedBlock); err != nil { +- if err := adjustReturnStatements(returnTypes, seenVars, file, pkg, extractedBlock); err != nil { - return nil, err - } - } @@ -83370,7 +84099,7 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - // statements in the selection. Update the type signature of the extracted - // function and construct the if statement that will be inserted in the enclosing - // function. -- retVars, ifReturn, err = generateReturnInfo(enclosing, pkg, path, file, info, fset, start, hasNonNestedReturn) +- retVars, ifReturn, err = generateReturnInfo(enclosing, pkg, path, file, info, start, hasNonNestedReturn) - if err != nil { - return nil, err - } @@ -83405,7 +84134,7 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - funName = name - } else { - name = "newFunction" -- funName, _ = generateAvailableIdentifier(start, file, path, pkg, info, name, 0) +- funName, _ = generateAvailableIdentifier(start, path, pkg, info, name, 0) - } - extractedFunCall := generateFuncCall(hasNonNestedReturn, hasReturnValues, params, - append(returns, getNames(retVars)...), funName, sym, receiverName) @@ -84030,12 +84759,12 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext -// signature of the extracted function. We prepare names, signatures, and "zero values" that -// represent the new variables. We also use this information to construct the if statement that -// is inserted below the call to the extracted function. --func generateReturnInfo(enclosing *ast.FuncType, pkg *types.Package, path []ast.Node, file *ast.File, info *types.Info, fset *token.FileSet, pos token.Pos, hasNonNestedReturns bool) ([]*returnVariable, *ast.IfStmt, error) { +-func generateReturnInfo(enclosing *ast.FuncType, pkg *types.Package, path []ast.Node, file *ast.File, info *types.Info, pos token.Pos, hasNonNestedReturns bool) ([]*returnVariable, *ast.IfStmt, error) { - var retVars []*returnVariable - var cond *ast.Ident - if !hasNonNestedReturns { - // Generate information for the added bool value. -- name, _ := generateAvailableIdentifier(pos, file, path, pkg, info, "shouldReturn", 0) +- name, _ := generateAvailableIdentifier(pos, path, pkg, info, "shouldReturn", 0) - cond = &ast.Ident{Name: name} - retVars = append(retVars, &returnVariable{ - name: cond, @@ -84057,7 +84786,7 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - return nil, nil, fmt.Errorf("nil AST expression") - } - var name string -- name, idx = generateAvailableIdentifier(pos, file, path, pkg, info, "returnValue", idx) +- name, idx = generateAvailableIdentifier(pos, path, pkg, info, "returnValue", idx) - retVars = append(retVars, &returnVariable{ - name: ast.NewIdent(name), - decl: &ast.Field{Type: expr}, @@ -84081,7 +84810,7 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - -// adjustReturnStatements adds "zero values" of the given types to each return statement -// in the given AST node. --func adjustReturnStatements(returnTypes []*ast.Field, seenVars map[types.Object]ast.Expr, fset *token.FileSet, file *ast.File, pkg *types.Package, extractedBlock *ast.BlockStmt) error { +-func adjustReturnStatements(returnTypes []*ast.Field, seenVars map[types.Object]ast.Expr, file *ast.File, pkg *types.Package, extractedBlock *ast.BlockStmt) error { - var zeroVals []ast.Expr - // Create "zero values" for each type. - for _, returnType := range returnTypes { @@ -84228,7 +84957,7 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext -} diff -urN a/gopls/internal/lsp/source/fix.go b/gopls/internal/lsp/source/fix.go --- a/gopls/internal/lsp/source/fix.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/fix.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/fix.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,195 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -84388,7 +85117,7 @@ diff -urN a/gopls/internal/lsp/source/fix.go b/gopls/internal/lsp/source/fix.go -} - -// addEmbedImport adds a missing embed "embed" import with blank name. --func addEmbedImport(ctx context.Context, snapshot Snapshot, fh FileHandle, rng protocol.Range) (*token.FileSet, *analysis.SuggestedFix, error) { +-func addEmbedImport(ctx context.Context, snapshot Snapshot, fh FileHandle, _ protocol.Range) (*token.FileSet, *analysis.SuggestedFix, error) { - pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, fh.URI()) - if err != nil { - return nil, nil, fmt.Errorf("narrow pkg: %w", err) @@ -84427,7 +85156,7 @@ diff -urN a/gopls/internal/lsp/source/fix.go b/gopls/internal/lsp/source/fix.go -} diff -urN a/gopls/internal/lsp/source/folding_range.go b/gopls/internal/lsp/source/folding_range.go --- a/gopls/internal/lsp/source/folding_range.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/folding_range.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/folding_range.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,194 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -84625,7 +85354,7 @@ diff -urN a/gopls/internal/lsp/source/folding_range.go b/gopls/internal/lsp/sour -} diff -urN a/gopls/internal/lsp/source/format.go b/gopls/internal/lsp/source/format.go --- a/gopls/internal/lsp/source/format.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/format.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/format.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,388 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -85017,7 +85746,7 @@ diff -urN a/gopls/internal/lsp/source/format.go b/gopls/internal/lsp/source/form -} diff -urN a/gopls/internal/lsp/source/format_test.go b/gopls/internal/lsp/source/format_test.go --- a/gopls/internal/lsp/source/format_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/format_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/format_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -85096,7 +85825,7 @@ diff -urN a/gopls/internal/lsp/source/format_test.go b/gopls/internal/lsp/source -} diff -urN a/gopls/internal/lsp/source/gc_annotations.go b/gopls/internal/lsp/source/gc_annotations.go --- a/gopls/internal/lsp/source/gc_annotations.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/gc_annotations.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/gc_annotations.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,221 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -85321,7 +86050,7 @@ diff -urN a/gopls/internal/lsp/source/gc_annotations.go b/gopls/internal/lsp/sou -} diff -urN a/gopls/internal/lsp/source/highlight.go b/gopls/internal/lsp/source/highlight.go --- a/gopls/internal/lsp/source/highlight.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/highlight.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/highlight.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,480 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -85805,7 +86534,7 @@ diff -urN a/gopls/internal/lsp/source/highlight.go b/gopls/internal/lsp/source/h -} diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover.go --- a/gopls/internal/lsp/source/hover.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/hover.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/hover.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,1069 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -85940,7 +86669,7 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - - // Handle linkname directive by overriding what to look for. - var linkedRange *protocol.Range // range referenced by linkname directive, or nil -- if pkgPath, name, offset := parseLinkname(ctx, snapshot, fh, pp); pkgPath != "" && name != "" { +- if pkgPath, name, offset := parseLinkname(pgf.Mapper, pp); pkgPath != "" && name != "" { - // rng covering 2nd linkname argument: pkgPath.name. - rng, err := pgf.PosRange(pgf.Tok.Pos(offset), pgf.Tok.Pos(offset+len(pkgPath)+len(".")+len(name))) - if err != nil { @@ -86878,7 +87607,7 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover -} diff -urN a/gopls/internal/lsp/source/identifier.go b/gopls/internal/lsp/source/identifier.go --- a/gopls/internal/lsp/source/identifier.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/identifier.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/identifier.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,174 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -87056,7 +87785,7 @@ diff -urN a/gopls/internal/lsp/source/identifier.go b/gopls/internal/lsp/source/ -} diff -urN a/gopls/internal/lsp/source/identifier_test.go b/gopls/internal/lsp/source/identifier_test.go --- a/gopls/internal/lsp/source/identifier_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/identifier_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/identifier_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -87163,7 +87892,7 @@ diff -urN a/gopls/internal/lsp/source/identifier_test.go b/gopls/internal/lsp/so -} diff -urN a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/source/implementation.go --- a/gopls/internal/lsp/source/implementation.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/implementation.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/implementation.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -87662,7 +88391,7 @@ diff -urN a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/sou -} diff -urN a/gopls/internal/lsp/source/inlay_hint.go b/gopls/internal/lsp/source/inlay_hint.go --- a/gopls/internal/lsp/source/inlay_hint.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/inlay_hint.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/inlay_hint.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,394 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -87972,7 +88701,7 @@ diff -urN a/gopls/internal/lsp/source/inlay_hint.go b/gopls/internal/lsp/source/ - return hints -} - --func compositeLiteralFields(node ast.Node, m *protocol.Mapper, tf *token.File, info *types.Info, q *types.Qualifier) []protocol.InlayHint { +-func compositeLiteralFields(node ast.Node, m *protocol.Mapper, tf *token.File, info *types.Info, _ *types.Qualifier) []protocol.InlayHint { - compLit, ok := node.(*ast.CompositeLit) - if !ok { - return nil @@ -88058,10 +88787,289 @@ diff -urN a/gopls/internal/lsp/source/inlay_hint.go b/gopls/internal/lsp/source/ - } - return []protocol.InlayHintLabelPart{label} -} +diff -urN a/gopls/internal/lsp/source/inline_all.go b/gopls/internal/lsp/source/inline_all.go +--- a/gopls/internal/lsp/source/inline_all.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/inline_all.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,275 +0,0 @@ +-// Copyright 2023 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 source +- +-import ( +- "context" +- "fmt" +- "go/ast" +- "go/parser" +- "go/types" +- +- "golang.org/x/tools/go/ast/astutil" +- "golang.org/x/tools/go/types/typeutil" +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/refactor/inline" +-) +- +-// inlineAllCalls inlines all calls to the original function declaration +-// described by callee, returning the resulting modified file content. +-// +-// inlining everything is currently an expensive operation: it involves re-type +-// checking every package that contains a potential call, as reported by +-// References. In cases where there are multiple calls per file, inlineAllCalls +-// must type check repeatedly for each additional call. +-// +-// The provided post processing function is applied to the resulting source +-// after each transformation. This is necessary because we are using this +-// function to inline synthetic wrappers for the purpose of signature +-// rewriting. The delegated function has a fake name that doesn't exist in the +-// snapshot, and so we can't re-type check until we replace this fake name. +-// +-// TODO(rfindley): this only works because removing a parameter is a very +-// narrow operation. A better solution would be to allow for ad-hoc snapshots +-// that expose the full machinery of real snapshots: minimal invalidation, +-// batched type checking, etc. Then we could actually rewrite the declaring +-// package in this snapshot (and so 'post' would not be necessary), and could +-// robustly re-type check for the purpose of iterative inlining, even if the +-// inlined code pulls in new imports that weren't present in export data. +-// +-// The code below notes where are assumptions are made that only hold true in +-// the case of parameter removal (annotated with 'Assumption:') +-func inlineAllCalls(ctx context.Context, logf func(string, ...any), snapshot Snapshot, pkg Package, pgf *ParsedGoFile, origDecl *ast.FuncDecl, callee *inline.Callee, post func([]byte) []byte) (map[span.URI][]byte, error) { +- // Collect references. +- var refs []protocol.Location +- { +- funcPos, err := pgf.Mapper.PosPosition(pgf.Tok, origDecl.Name.NamePos) +- if err != nil { +- return nil, err +- } +- fh, err := snapshot.ReadFile(ctx, pgf.URI) +- if err != nil { +- return nil, err +- } +- refs, err = References(ctx, snapshot, fh, funcPos, false) +- if err != nil { +- return nil, fmt.Errorf("finding references to rewrite: %v", err) +- } +- } +- +- // Type-check the narrowest package containing each reference. +- // TODO(rfindley): we should expose forEachPackage in order to operate in +- // parallel and to reduce peak memory for this operation. +- var ( +- pkgForRef = make(map[protocol.Location]PackageID) +- pkgs = make(map[PackageID]Package) +- ) +- { +- needPkgs := make(map[PackageID]struct{}) +- for _, ref := range refs { +- md, err := NarrowestMetadataForFile(ctx, snapshot, ref.URI.SpanURI()) +- if err != nil { +- return nil, fmt.Errorf("finding ref metadata: %v", err) +- } +- pkgForRef[ref] = md.ID +- needPkgs[md.ID] = struct{}{} +- } +- var pkgIDs []PackageID +- for id := range needPkgs { // TODO: use maps.Keys once it is available to us +- pkgIDs = append(pkgIDs, id) +- } +- +- refPkgs, err := snapshot.TypeCheck(ctx, pkgIDs...) +- if err != nil { +- return nil, fmt.Errorf("type checking reference packages: %v", err) +- } +- +- for _, p := range refPkgs { +- pkgs[p.Metadata().ID] = p +- } +- } +- +- // Organize calls by top file declaration. Calls within a single file may +- // affect each other, as the inlining edit may affect the surrounding scope +- // or imports Therefore, when inlining subsequent calls in the same +- // declaration, we must re-type check. +- +- type fileCalls struct { +- pkg Package +- pgf *ParsedGoFile +- calls []*ast.CallExpr +- } +- +- refsByFile := make(map[span.URI]*fileCalls) +- for _, ref := range refs { +- refpkg := pkgs[pkgForRef[ref]] +- pgf, err := refpkg.File(ref.URI.SpanURI()) +- if err != nil { +- return nil, bug.Errorf("finding %s in %s: %v", ref.URI, refpkg.Metadata().ID, err) +- } +- start, end, err := pgf.RangePos(ref.Range) +- if err != nil { +- return nil, bug.Errorf("RangePos(ref): %v", err) +- } +- +- // Look for the surrounding call expression. +- var ( +- name *ast.Ident +- call *ast.CallExpr +- ) +- path, _ := astutil.PathEnclosingInterval(pgf.File, start, end) +- name, _ = path[0].(*ast.Ident) +- if _, ok := path[1].(*ast.SelectorExpr); ok { +- call, _ = path[2].(*ast.CallExpr) +- } else { +- call, _ = path[1].(*ast.CallExpr) +- } +- if name == nil || call == nil { +- // TODO(rfindley): handle this case with eta-abstraction: +- // a reference to the target function f in a non-call position +- // use(f) +- // is replaced by +- // use(func(...) { f(...) }) +- return nil, fmt.Errorf("cannot inline: found non-call function reference %v", ref) +- } +- // Sanity check. +- if obj := refpkg.GetTypesInfo().ObjectOf(name); obj == nil || +- obj.Name() != origDecl.Name.Name || +- obj.Pkg() == nil || +- obj.Pkg().Path() != string(pkg.Metadata().PkgPath) { +- return nil, bug.Errorf("cannot inline: corrupted reference %v", ref) +- } +- +- callInfo, ok := refsByFile[ref.URI.SpanURI()] +- if !ok { +- callInfo = &fileCalls{ +- pkg: refpkg, +- pgf: pgf, +- } +- refsByFile[ref.URI.SpanURI()] = callInfo +- } +- callInfo.calls = append(callInfo.calls, call) +- } +- +- // Inline each call within the same decl in sequence, re-typechecking after +- // each one. If there is only a single call within the decl, we can avoid +- // additional type checking. +- // +- // Assumption: inlining does not affect the package scope, so we can operate +- // on separate files independently. +- result := make(map[span.URI][]byte) +- for uri, callInfo := range refsByFile { +- var ( +- calls = callInfo.calls +- fset = callInfo.pkg.FileSet() +- tpkg = callInfo.pkg.GetTypes() +- tinfo = callInfo.pkg.GetTypesInfo() +- file = callInfo.pgf.File +- content = callInfo.pgf.Src +- ) +- +- // Check for overlapping calls (such as Foo(Foo())). We can't handle these +- // because inlining may change the source order of the inner call with +- // respect to the inlined outer call, and so the heuristic we use to find +- // the next call (counting from top-to-bottom) does not work. +- for i := range calls { +- if i > 0 && calls[i-1].End() > calls[i].Pos() { +- return nil, fmt.Errorf("%s: can't inline overlapping call %s", uri, types.ExprString(calls[i-1])) +- } +- } +- +- currentCall := 0 +- for currentCall < len(calls) { +- caller := &inline.Caller{ +- Fset: fset, +- Types: tpkg, +- Info: tinfo, +- File: file, +- Call: calls[currentCall], +- Content: content, +- } +- var err error +- content, err = inline.Inline(logf, caller, callee) +- if err != nil { +- return nil, fmt.Errorf("inlining failed: %v", err) +- } +- if post != nil { +- content = post(content) +- } +- if len(calls) <= 1 { +- // No need to re-type check, as we've inlined all calls. +- break +- } +- +- // TODO(rfindley): develop a theory of "trivial" inlining, which are +- // inlinings that don't require re-type checking. +- // +- // In principle, if the inlining only involves replacing one call with +- // another, the scope of the caller is unchanged and there is no need to +- // type check again before inlining subsequent calls (edits should not +- // overlap, and should not affect each other semantically). However, it +- // feels sufficiently complicated that, to be safe, this optimization is +- // deferred until later. +- +- file, err = parser.ParseFile(fset, uri.Filename(), content, parser.ParseComments|parser.SkipObjectResolution) +- if err != nil { +- return nil, bug.Errorf("inlined file failed to parse: %v", err) +- } +- +- // After inlining one call with a removed parameter, the package will +- // fail to type check due to "not enough arguments". Therefore, we must +- // allow type errors here. +- // +- // Assumption: the resulting type errors do not affect the correctness of +- // subsequent inlining, because invalid arguments to a call do not affect +- // anything in the surrounding scope. +- // +- // TODO(rfindley): improve this. +- tpkg, tinfo, err = reTypeCheck(logf, callInfo.pkg, map[span.URI]*ast.File{uri: file}, true) +- if err != nil { +- return nil, bug.Errorf("type checking after inlining failed: %v", err) +- } +- +- // Collect calls to the target function in the modified declaration. +- var calls2 []*ast.CallExpr +- ast.Inspect(file, func(n ast.Node) bool { +- if call, ok := n.(*ast.CallExpr); ok { +- fn := typeutil.StaticCallee(tinfo, call) +- if fn != nil && fn.Pkg().Path() == string(pkg.Metadata().PkgPath) && fn.Name() == origDecl.Name.Name { +- calls2 = append(calls2, call) +- } +- } +- return true +- }) +- +- // If the number of calls has increased, this process will never cease. +- // If the number of calls has decreased, assume that inlining removed a +- // call. +- // If the number of calls didn't change, assume that inlining replaced +- // a call, and move on to the next. +- // +- // Assumption: we're inlining a call that has at most one recursive +- // reference (which holds for signature rewrites). +- // +- // TODO(rfindley): this isn't good enough. We should be able to support +- // inlining all existing calls even if they increase calls. How do we +- // correlate the before and after syntax? +- switch { +- case len(calls2) > len(calls): +- return nil, fmt.Errorf("inlining increased calls %d->%d, possible recursive call? content:\n%s", len(calls), len(calls2), content) +- case len(calls2) < len(calls): +- calls = calls2 +- case len(calls2) == len(calls): +- calls = calls2 +- currentCall++ +- } +- } +- +- result[callInfo.pgf.URI] = content +- } +- return result, nil +-} diff -urN a/gopls/internal/lsp/source/inline.go b/gopls/internal/lsp/source/inline.go --- a/gopls/internal/lsp/source/inline.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/inline.go 1970-01-01 08:00:00 -@@ -1,138 +0,0 @@ ++++ b/gopls/internal/lsp/source/inline.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,147 +0,0 @@ -// Copyright 2023 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. @@ -88170,9 +89178,7 @@ diff -urN a/gopls/internal/lsp/source/inline.go b/gopls/internal/lsp/source/inli - - // Users can consult the gopls event log to see - // why a particular inlining strategy was chosen. -- logf := func(format string, args ...any) { -- event.Log(ctx, "inliner: "+fmt.Sprintf(format, args...)) -- } +- logf := logger(ctx, "inliner", snapshot.Options().VerboseOutput) - - callee, err := inline.AnalyzeCallee(logf, calleePkg.FileSet(), calleePkg.GetTypes(), calleePkg.GetTypesInfo(), calleeDecl, calleePGF.Src) - if err != nil { @@ -88200,9 +89206,20 @@ diff -urN a/gopls/internal/lsp/source/inline.go b/gopls/internal/lsp/source/inli - TextEdits: diffToTextEdits(callerPGF.Tok, diff.Bytes(callerPGF.Src, got)), - }, nil -} +- +-// TODO(adonovan): change the inliner to instead accept an io.Writer. +-func logger(ctx context.Context, name string, verbose bool) func(format string, args ...any) { +- if verbose { +- return func(format string, args ...any) { +- event.Log(ctx, name+": "+fmt.Sprintf(format, args...)) +- } +- } else { +- return func(string, ...any) {} +- } +-} diff -urN a/gopls/internal/lsp/source/invertifcondition.go b/gopls/internal/lsp/source/invertifcondition.go --- a/gopls/internal/lsp/source/invertifcondition.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/invertifcondition.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/invertifcondition.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,268 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -88474,7 +89491,7 @@ diff -urN a/gopls/internal/lsp/source/invertifcondition.go b/gopls/internal/lsp/ -} diff -urN a/gopls/internal/lsp/source/known_packages.go b/gopls/internal/lsp/source/known_packages.go --- a/gopls/internal/lsp/source/known_packages.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/known_packages.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/known_packages.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,134 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -88612,8 +89629,8 @@ diff -urN a/gopls/internal/lsp/source/known_packages.go b/gopls/internal/lsp/sou -} diff -urN a/gopls/internal/lsp/source/linkname.go b/gopls/internal/lsp/source/linkname.go --- a/gopls/internal/lsp/source/linkname.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/linkname.go 1970-01-01 08:00:00 -@@ -1,156 +0,0 @@ ++++ b/gopls/internal/lsp/source/linkname.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,143 +0,0 @@ -// Copyright 2023 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. @@ -88637,10 +89654,10 @@ diff -urN a/gopls/internal/lsp/source/linkname.go b/gopls/internal/lsp/source/li -// As such it indicates that other definitions could be worth checking. -var ErrNoLinkname = errors.New("no linkname directive found") - --// LinknameDefinition finds the definition of the linkname directive in fh at pos. +-// LinknameDefinition finds the definition of the linkname directive in m at pos. -// If there is no linkname directive at pos, returns ErrNoLinkname. --func LinknameDefinition(ctx context.Context, snapshot Snapshot, fh FileHandle, from protocol.Position) ([]protocol.Location, error) { -- pkgPath, name, _ := parseLinkname(ctx, snapshot, fh, from) +-func LinknameDefinition(ctx context.Context, snapshot Snapshot, m *protocol.Mapper, from protocol.Position) ([]protocol.Location, error) { +- pkgPath, name, _ := parseLinkname(m, from) - if pkgPath == "" { - return nil, ErrNoLinkname - } @@ -88660,27 +89677,34 @@ diff -urN a/gopls/internal/lsp/source/linkname.go b/gopls/internal/lsp/source/li -// If successful, it returns -// - package path referenced -// - object name referenced --// - byte offset in fh of the start of the link target +-// - byte offset in mapped file of the start of the link target -// of the linkname directives 2nd argument. -// -// If the position is not in the second argument of a go:linkname directive, -// or parsing fails, it returns "", "", 0. --func parseLinkname(ctx context.Context, snapshot Snapshot, fh FileHandle, pos protocol.Position) (pkgPath, name string, targetOffset int) { -- // TODO(adonovan): opt: parsing isn't necessary here. -- // We're only looking for a line comment. -- pgf, err := snapshot.ParseGo(ctx, fh, ParseFull) +-func parseLinkname(m *protocol.Mapper, pos protocol.Position) (pkgPath, name string, targetOffset int) { +- lineStart, err := m.PositionOffset(protocol.Position{Line: pos.Line, Character: 0}) - if err != nil { - return "", "", 0 - } -- -- offset, err := pgf.Mapper.PositionOffset(pos) +- lineEnd, err := m.PositionOffset(protocol.Position{Line: pos.Line + 1, Character: 0}) - if err != nil { - return "", "", 0 - } - +- directive := string(m.Content[lineStart:lineEnd]) +- // (Assumes no leading spaces.) +- if !strings.HasPrefix(directive, "//go:linkname") { +- return "", "", 0 +- } +- // Sometimes source code (typically tests) has another +- // comment after the directive, trim that away. +- if i := strings.LastIndex(directive, "//"); i != 0 { +- directive = strings.TrimSpace(directive[:i]) +- } +- - // Looking for pkgpath in '//go:linkname f pkgpath.g'. - // (We ignore 1-arg linkname directives.) -- directive, end := findLinknameAtOffset(pgf, offset) - parts := strings.Fields(directive) - if len(parts) != 3 { - return "", "", 0 @@ -88688,6 +89712,11 @@ diff -urN a/gopls/internal/lsp/source/linkname.go b/gopls/internal/lsp/source/li - - // Inside 2nd arg [start, end]? - // (Assumes no trailing spaces.) +- offset, err := m.PositionOffset(pos) +- if err != nil { +- return "", "", 0 +- } +- end := lineStart + len(directive) - start := end - len(parts[2]) - if !(start <= offset && offset <= end) { - return "", "", 0 @@ -88703,31 +89732,6 @@ diff -urN a/gopls/internal/lsp/source/linkname.go b/gopls/internal/lsp/source/li - return linkname[:dot], linkname[dot+1:], start -} - --// findLinknameAtOffset returns the first linkname directive on line and its end offset. --// Returns "", 0 if the offset is not in a linkname directive. --func findLinknameAtOffset(pgf *ParsedGoFile, offset int) (string, int) { -- for _, grp := range pgf.File.Comments { -- for _, com := range grp.List { -- if strings.HasPrefix(com.Text, "//go:linkname") { -- p := safetoken.Position(pgf.Tok, com.Pos()) -- -- // Sometimes source code (typically tests) has another -- // comment after the directive, trim that away. -- text := com.Text -- if i := strings.LastIndex(text, "//"); i != 0 { -- text = strings.TrimSpace(text[:i]) -- } -- -- end := p.Offset + len(text) -- if p.Offset <= offset && offset < end { -- return text, end -- } -- } -- } -- } -- return "", 0 --} -- -// findLinkname searches dependencies of packages containing fh for an object -// with linker name matching the given package path and name. -func findLinkname(ctx context.Context, snapshot Snapshot, pkgPath PackagePath, name string) (Package, *ParsedGoFile, token.Pos, error) { @@ -88772,7 +89776,7 @@ diff -urN a/gopls/internal/lsp/source/linkname.go b/gopls/internal/lsp/source/li -} diff -urN a/gopls/internal/lsp/source/methodsets/methodsets.go b/gopls/internal/lsp/source/methodsets/methodsets.go --- a/gopls/internal/lsp/source/methodsets/methodsets.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/methodsets/methodsets.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/methodsets/methodsets.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,490 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -89266,8 +90270,8 @@ diff -urN a/gopls/internal/lsp/source/methodsets/methodsets.go b/gopls/internal/ -} diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/options.go --- a/gopls/internal/lsp/source/options.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/options.go 1970-01-01 08:00:00 -@@ -1,1797 +0,0 @@ ++++ b/gopls/internal/lsp/source/options.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,1830 +0,0 @@ -// 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. @@ -89407,6 +90411,7 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - }, - Vulncheck: ModeVulncheckOff, - DiagnosticsDelay: 1 * time.Second, +- DiagnosticsTrigger: DiagnosticsOnEdit, - AnalysisProgressReporting: true, - }, - InlayHintOptions: InlayHintOptions{}, @@ -89738,6 +90743,9 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - // This option must be set to a valid duration string, for example `"250ms"`. - DiagnosticsDelay time.Duration `status:"advanced"` - +- // DiagnosticsTrigger controls when to run diagnostics. +- DiagnosticsTrigger DiagnosticsTrigger `status:"experimental"` +- - // AnalysisProgressReporting controls whether gopls sends progress - // notifications when construction of its index of analysis facts is taking a - // long time. Cancelling these notifications will cancel the indexing task, @@ -89865,6 +90873,9 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - // LiteralCompletions controls whether literal candidates such as - // "&someStruct{}" are offered. Tests disable this flag to simplify - // their expected values. +- // +- // TODO(rfindley): this is almost unnecessary now. Remove it along with the +- // old marker tests. - LiteralCompletions bool - - // VerboseWorkDoneProgress controls whether the LSP server should send @@ -90077,6 +91088,17 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - // TODO: VulncheckRequire, VulncheckCallgraph -) - +-type DiagnosticsTrigger string +- +-const ( +- // Trigger diagnostics on file edit and save. (default) +- DiagnosticsOnEdit DiagnosticsTrigger = "Edit" +- // Trigger diagnostics only on file save. Events like initial workspace load +- // or configuration change will still trigger diagnostics. +- DiagnosticsOnSave DiagnosticsTrigger = "Save" +- // TODO: support "Manual"? +-) +- -type OptionResults []OptionResult - -type OptionResult struct { @@ -90451,6 +91473,7 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - result.setBool(&o.VerboseWorkDoneProgress) - - case "tempModfile": +- result.softErrorf("gopls setting \"tempModfile\" is deprecated.\nPlease comment on https://go.dev/issue/63537 if this impacts your workflow.") - result.setBool(&o.TempModfile) - - case "showBugReports": @@ -90477,6 +91500,7 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - result.setBool(&o.NoSemanticNumber) - - case "expandWorkspaceToModule": +- result.softErrorf("gopls setting \"expandWorkspaceToModule\" is deprecated.\nPlease comment on https://go.dev/issue/63536 if this impacts your workflow.") - result.setBool(&o.ExpandWorkspaceToModule) - - case "experimentalPostfixCompletions": @@ -90509,6 +91533,14 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - case "diagnosticsDelay": - result.setDuration(&o.DiagnosticsDelay) - +- case "diagnosticsTrigger": +- if s, ok := result.asOneOf( +- string(DiagnosticsOnEdit), +- string(DiagnosticsOnSave), +- ); ok { +- o.DiagnosticsTrigger = DiagnosticsTrigger(s) +- } +- - case "analysisProgressReporting": - result.setBool(&o.AnalysisProgressReporting) - @@ -90626,6 +91658,11 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - r.Error = &SoftError{msg} -} - +-// softErrorf reports a soft error related to the current option. +-func (r *OptionResult) softErrorf(format string, args ...any) { +- r.Error = &SoftError{fmt.Sprintf(format, args...)} +-} +- -// unexpected reports that the current setting is not known to gopls. -func (r *OptionResult) unexpected() { - r.Error = fmt.Errorf("unexpected gopls setting %q", r.Name) @@ -90869,7 +91906,7 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - atomicalign.Analyzer.Name: {Analyzer: atomicalign.Analyzer, Enabled: true}, - deepequalerrors.Analyzer.Name: {Analyzer: deepequalerrors.Analyzer, Enabled: true}, - fieldalignment.Analyzer.Name: {Analyzer: fieldalignment.Analyzer, Enabled: false}, -- nilness.Analyzer.Name: {Analyzer: nilness.Analyzer, Enabled: false}, +- nilness.Analyzer.Name: {Analyzer: nilness.Analyzer, Enabled: true}, - shadow.Analyzer.Name: {Analyzer: shadow.Analyzer, Enabled: false}, - sortslice.Analyzer.Name: {Analyzer: sortslice.Analyzer, Enabled: true}, - testinggoroutine.Analyzer.Name: {Analyzer: testinggoroutine.Analyzer, Enabled: true}, @@ -90958,7 +91995,7 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - -func collectEnums(opt *OptionJSON) string { - var b strings.Builder -- write := func(name, doc string, index, len int) { +- write := func(name, doc string) { - if doc != "" { - unbroken := parBreakRE.ReplaceAllString(doc, "\\\n") - fmt.Fprintf(&b, "* %s\n", strings.TrimSpace(unbroken)) @@ -90968,13 +92005,13 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - } - if len(opt.EnumValues) > 0 && opt.Type == "enum" { - b.WriteString("\nMust be one of:\n\n") -- for i, val := range opt.EnumValues { -- write(val.Value, val.Doc, i, len(opt.EnumValues)) +- for _, val := range opt.EnumValues { +- write(val.Value, val.Doc) - } - } else if len(opt.EnumKeys.Keys) > 0 && shouldShowEnumKeysInSettings(opt.Name) { - b.WriteString("\nCan contain any of:\n\n") -- for i, val := range opt.EnumKeys.Keys { -- write(val.Name, val.Doc, i, len(opt.EnumKeys.Keys)) +- for _, val := range opt.EnumKeys.Keys { +- write(val.Name, val.Doc) - } - } - return b.String() @@ -91067,7 +92104,7 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt -} diff -urN a/gopls/internal/lsp/source/options_test.go b/gopls/internal/lsp/source/options_test.go --- a/gopls/internal/lsp/source/options_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/options_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/options_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,206 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -91275,16 +92312,16 @@ diff -urN a/gopls/internal/lsp/source/options_test.go b/gopls/internal/lsp/sourc - } - } -} -diff -urN a/gopls/internal/lsp/source/origin.go b/gopls/internal/lsp/source/origin.go ---- a/gopls/internal/lsp/source/origin.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/origin.go 1970-01-01 08:00:00 -@@ -1,26 +0,0 @@ +diff -urN a/gopls/internal/lsp/source/origin_119.go b/gopls/internal/lsp/source/origin_119.go +--- a/gopls/internal/lsp/source/origin_119.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/origin_119.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,33 +0,0 @@ -// Copyright 2023 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. - --//go:build !go1.19 --// +build !go1.19 +-//go:build go1.19 +-// +build go1.19 - -package source - @@ -91294,27 +92331,34 @@ diff -urN a/gopls/internal/lsp/source/origin.go b/gopls/internal/lsp/source/orig -// with the same origin as the provided obj (which may be a synthetic object -// created during instantiation). -func containsOrigin(objSet map[types.Object]bool, obj types.Object) bool { -- if obj == nil { -- return objSet[obj] -- } -- // In Go 1.18, we can't use the types.Var.Origin and types.Func.Origin methods. +- objOrigin := origin(obj) - for target := range objSet { -- if target.Pkg() == obj.Pkg() && target.Pos() == obj.Pos() && target.Name() == obj.Name() { +- if origin(target) == objOrigin { - return true - } - } - return false -} -diff -urN a/gopls/internal/lsp/source/origin_119.go b/gopls/internal/lsp/source/origin_119.go ---- a/gopls/internal/lsp/source/origin_119.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/origin_119.go 1970-01-01 08:00:00 -@@ -1,33 +0,0 @@ +- +-func origin(obj types.Object) types.Object { +- switch obj := obj.(type) { +- case *types.Var: +- return obj.Origin() +- case *types.Func: +- return obj.Origin() +- } +- return obj +-} +diff -urN a/gopls/internal/lsp/source/origin.go b/gopls/internal/lsp/source/origin.go +--- a/gopls/internal/lsp/source/origin.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/origin.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,26 +0,0 @@ -// Copyright 2023 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. - --//go:build go1.19 --// +build go1.19 +-//go:build !go1.19 +-// +build !go1.19 - -package source - @@ -91324,27 +92368,20 @@ diff -urN a/gopls/internal/lsp/source/origin_119.go b/gopls/internal/lsp/source/ -// with the same origin as the provided obj (which may be a synthetic object -// created during instantiation). -func containsOrigin(objSet map[types.Object]bool, obj types.Object) bool { -- objOrigin := origin(obj) +- if obj == nil { +- return objSet[obj] +- } +- // In Go 1.18, we can't use the types.Var.Origin and types.Func.Origin methods. - for target := range objSet { -- if origin(target) == objOrigin { +- if target.Pkg() == obj.Pkg() && target.Pos() == obj.Pos() && target.Name() == obj.Name() { - return true - } - } - return false -} -- --func origin(obj types.Object) types.Object { -- switch obj := obj.(type) { -- case *types.Var: -- return obj.Origin() -- case *types.Func: -- return obj.Origin() -- } -- return obj --} diff -urN a/gopls/internal/lsp/source/parsemode_go116.go b/gopls/internal/lsp/source/parsemode_go116.go --- a/gopls/internal/lsp/source/parsemode_go116.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/parsemode_go116.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/parsemode_go116.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -91361,7 +92398,7 @@ diff -urN a/gopls/internal/lsp/source/parsemode_go116.go b/gopls/internal/lsp/so -const SkipObjectResolution parser.Mode = 0 diff -urN a/gopls/internal/lsp/source/parsemode_go117.go b/gopls/internal/lsp/source/parsemode_go117.go --- a/gopls/internal/lsp/source/parsemode_go117.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/parsemode_go117.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/parsemode_go117.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -91377,7 +92414,7 @@ diff -urN a/gopls/internal/lsp/source/parsemode_go117.go b/gopls/internal/lsp/so -const SkipObjectResolution = parser.SkipObjectResolution diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/references.go --- a/gopls/internal/lsp/source/references.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/references.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/references.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,692 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -92071,519 +93108,1444 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ - } - return loc -} -diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rename.go ---- a/gopls/internal/lsp/source/rename.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/rename.go 1970-01-01 08:00:00 -@@ -1,1277 +0,0 @@ +diff -urN a/gopls/internal/lsp/source/rename_check.go b/gopls/internal/lsp/source/rename_check.go +--- a/gopls/internal/lsp/source/rename_check.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/rename_check.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,921 +0,0 @@ -// 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. +-// +-// Taken from golang.org/x/tools/refactor/rename. - -package source - --// TODO(adonovan): --// --// - method of generic concrete type -> arbitrary instances of same --// --// - make satisfy work across packages. +-// This file defines the conflict-checking portion of the rename operation. -// --// - tests, tests, tests: --// - play with renamings in the k8s tree. --// - generics --// - error cases (e.g. conflicts) --// - renaming a symbol declared in the module cache --// (currently proceeds with half of the renaming!) --// - make sure all tests have both a local and a cross-package analogue. --// - look at coverage --// - special cases: embedded fields, interfaces, test variants, --// function-local things with uppercase names; --// packages with type errors (currently 'satisfy' rejects them), --// package with missing imports; +-// The renamer works on a single package of type-checked syntax, and +-// is called in parallel for all necessary packages in the workspace, +-// possibly up to the transitive reverse dependencies of the +-// declaration. Finally the union of all edits and errors is computed. -// --// - measure performance in k8s. +-// Renaming one object may entail renaming of others. For example: -// --// - The original gorename tool assumed well-typedness, but the gopls feature --// does no such check (which actually makes it much more useful). --// Audit to ensure it is safe on ill-typed code. +-// - An embedded field couples a Var (field) and a TypeName. +-// So, renaming either one requires renaming the other. +-// If the initial object is an embedded field, we must add its +-// TypeName (and its enclosing package) to the renaming set; +-// this is easily discovered at the outset. -// --// - Generics support was no doubt buggy before but incrementalization --// may have exacerbated it. If the problem were just about objects, --// defs and uses it would be fairly simple, but type assignability --// comes into play in the 'satisfy' check for method renamings. --// De-instantiating Vector[int] to Vector[T] changes its type. --// We need to come up with a theory for the satisfy check that --// works with generics, and across packages. We currently have no --// simple way to pass types between packages (think: objectpath for --// types), though presumably exportdata could be pressed into service. +-// Conversely, if the initial object is a TypeName, we must observe +-// whether any of its references (from directly importing packages) +-// is coincident with an embedded field Var and, if so, initiate a +-// renaming of it. -// --// - FileID-based de-duplication of edits to different URIs for the same file. +-// - A method of an interface type is coupled to all corresponding +-// methods of types that are assigned to the interface (as +-// discovered by the 'satisfy' pass). As a matter of usability, we +-// require that such renamings be initiated from the interface +-// method, not the concrete method. - -import ( -- "context" -- "errors" - "fmt" - "go/ast" - "go/token" - "go/types" -- "path" - "path/filepath" -- "regexp" -- "sort" -- "strconv" +- "reflect" - "strings" +- "unicode" - -- "golang.org/x/mod/modfile" - "golang.org/x/tools/go/ast/astutil" -- "golang.org/x/tools/go/types/objectpath" -- "golang.org/x/tools/go/types/typeutil" -- "golang.org/x/tools/gopls/internal/bug" -- "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/safetoken" -- "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/diff" -- "golang.org/x/tools/internal/event" -- "golang.org/x/tools/internal/typeparams" - "golang.org/x/tools/refactor/satisfy" -) - --// A renamer holds state of a single call to renameObj, which renames --// an object (or several coupled objects) within a single type-checked --// syntax package. --type renamer struct { -- pkg Package // the syntax package in which the renaming is applied -- objsToUpdate map[types.Object]bool // records progress of calls to check -- hadConflicts bool -- conflicts []string -- from, to string -- satisfyConstraints map[satisfy.Constraint]bool -- msets typeutil.MethodSetCache -- changeMethods bool --} -- --// A PrepareItem holds the result of a "prepare rename" operation: --// the source range and value of a selected identifier. --type PrepareItem struct { -- Range protocol.Range -- Text string --} -- --// PrepareRename searches for a valid renaming at position pp. --// --// The returned usererr is intended to be displayed to the user to explain why --// the prepare fails. Probably we could eliminate the redundancy in returning --// two errors, but for now this is done defensively. --func PrepareRename(ctx context.Context, snapshot Snapshot, f FileHandle, pp protocol.Position) (_ *PrepareItem, usererr, err error) { -- ctx, done := event.Start(ctx, "source.PrepareRename") -- defer done() -- -- // Is the cursor within the package name declaration? -- if pgf, inPackageName, err := parsePackageNameDecl(ctx, snapshot, f, pp); err != nil { -- return nil, err, err -- } else if inPackageName { -- item, err := prepareRenamePackageName(ctx, snapshot, pgf) -- return item, err, err -- } -- -- // Ordinary (non-package) renaming. +-// errorf reports an error (e.g. conflict) and prevents file modification. +-func (r *renamer) errorf(pos token.Pos, format string, args ...interface{}) { +- // Conflict error messages in the old gorename tool (whence this +- // logic originated) contain rich information associated with +- // multiple source lines, such as: - // -- // Type-check the current package, locate the reference at the position, -- // validate the object, and report its name and range. +- // p/a.go:1:2: renaming "x" to "y" here +- // p/b.go:3:4: \t would cause this reference to "y" +- // p/c.go:5:5: \t to become shadowed by this intervening declaration. - // -- // TODO(adonovan): in all cases below, we return usererr=nil, -- // which means we return (nil, nil) at the protocol -- // layer. This seems like a bug, or at best an exploitation of -- // knowledge of VSCode-specific behavior. Can we avoid that? -- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, f.URI()) -- if err != nil { -- return nil, nil, err -- } -- pos, err := pgf.PositionPos(pp) -- if err != nil { -- return nil, nil, err -- } -- targets, node, err := objectsAt(pkg.GetTypesInfo(), pgf.File, pos) -- if err != nil { -- return nil, nil, err -- } -- var obj types.Object -- for obj = range targets { -- break // pick one arbitrarily -- } -- if err := checkRenamable(obj); err != nil { -- return nil, nil, err -- } -- rng, err := pgf.NodeRange(node) -- if err != nil { -- return nil, nil, err -- } -- if _, isImport := node.(*ast.ImportSpec); isImport { -- // We're not really renaming the import path. -- rng.End = rng.Start -- } -- return &PrepareItem{ -- Range: rng, -- Text: obj.Name(), -- }, nil, nil --} +- // Unfortunately LSP provides no means to transmit the +- // structure of this error, so we format the positions briefly +- // using dir/file.go where dir is the base name of the parent +- // directory. - --func prepareRenamePackageName(ctx context.Context, snapshot Snapshot, pgf *ParsedGoFile) (*PrepareItem, error) { -- // Does the client support file renaming? -- fileRenameSupported := false -- for _, op := range snapshot.Options().SupportedResourceOperations { -- if op == protocol.Rename { -- fileRenameSupported = true -- break +- var conflict strings.Builder +- +- // Add prefix of (truncated) position. +- if pos != token.NoPos { +- // TODO(adonovan): skip position of first error if it is +- // on the same line as the renaming itself. +- posn := safetoken.StartPosition(r.pkg.FileSet(), pos).String() +- segments := strings.Split(filepath.ToSlash(posn), "/") +- if n := len(segments); n > 2 { +- segments = segments[n-2:] - } -- } -- if !fileRenameSupported { -- return nil, errors.New("can't rename package: LSP client does not support file renaming") -- } +- posn = strings.Join(segments, "/") +- fmt.Fprintf(&conflict, "%s:", posn) - -- // Check validity of the metadata for the file's containing package. -- meta, err := NarrowestMetadataForFile(ctx, snapshot, pgf.URI) -- if err != nil { -- return nil, err -- } -- if meta.Name == "main" { -- return nil, fmt.Errorf("can't rename package \"main\"") -- } -- if strings.HasSuffix(string(meta.Name), "_test") { -- return nil, fmt.Errorf("can't rename x_test packages") -- } -- if meta.Module == nil { -- return nil, fmt.Errorf("can't rename package: missing module information for package %q", meta.PkgPath) -- } -- if meta.Module.Path == string(meta.PkgPath) { -- return nil, fmt.Errorf("can't rename package: package path %q is the same as module path %q", meta.PkgPath, meta.Module.Path) +- if !strings.HasPrefix(format, "\t") { +- conflict.WriteByte(' ') +- } - } - -- // Return the location of the package declaration. -- rng, err := pgf.NodeRange(pgf.File.Name) -- if err != nil { -- return nil, err -- } -- return &PrepareItem{ -- Range: rng, -- Text: string(meta.Name), -- }, nil +- fmt.Fprintf(&conflict, format, args...) +- r.conflicts = append(r.conflicts, conflict.String()) -} - --func checkRenamable(obj types.Object) error { -- switch obj := obj.(type) { -- case *types.Var: -- if obj.Embedded() { -- return fmt.Errorf("can't rename embedded fields: rename the type directly or name the field") -- } -- case *types.Builtin, *types.Nil: -- return fmt.Errorf("%s is built in and cannot be renamed", obj.Name()) -- } -- if obj.Pkg() == nil || obj.Pkg().Path() == "unsafe" { -- // e.g. error.Error, unsafe.Pointer -- return fmt.Errorf("%s is built in and cannot be renamed", obj.Name()) +-// check performs safety checks of the renaming of the 'from' object to r.to. +-func (r *renamer) check(from types.Object) { +- if r.objsToUpdate[from] { +- return - } -- if obj.Name() == "_" { -- return errors.New("can't rename \"_\"") +- r.objsToUpdate[from] = true +- +- // NB: order of conditions is important. +- if from_, ok := from.(*types.PkgName); ok { +- r.checkInFileBlock(from_) +- } else if from_, ok := from.(*types.Label); ok { +- r.checkLabel(from_) +- } else if isPackageLevel(from) { +- r.checkInPackageBlock(from) +- } else if v, ok := from.(*types.Var); ok && v.IsField() { +- r.checkStructField(v) +- } else if f, ok := from.(*types.Func); ok && recv(f) != nil { +- r.checkMethod(f) +- } else if isLocal(from) { +- r.checkInLexicalScope(from) +- } else { +- r.errorf(from.Pos(), "unexpected %s object %q (please report a bug)\n", +- objectKind(from), from) - } -- return nil -} - --// Rename returns a map of TextEdits for each file modified when renaming a --// given identifier within a package and a boolean value of true for renaming --// package and false otherwise. --func Rename(ctx context.Context, snapshot Snapshot, f FileHandle, pp protocol.Position, newName string) (map[span.URI][]protocol.TextEdit, bool, error) { -- ctx, done := event.Start(ctx, "source.Rename") -- defer done() -- -- if !isValidIdentifier(newName) { -- return nil, false, fmt.Errorf("invalid identifier to rename: %q", newName) +-// checkInFileBlock performs safety checks for renames of objects in the file block, +-// i.e. imported package names. +-func (r *renamer) checkInFileBlock(from *types.PkgName) { +- // Check import name is not "init". +- if r.to == "init" { +- r.errorf(from.Pos(), "%q is not a valid imported package name", r.to) - } - -- // Cursor within package name declaration? -- _, inPackageName, err := parsePackageNameDecl(ctx, snapshot, f, pp) -- if err != nil { -- return nil, false, err +- // Check for conflicts between file and package block. +- if prev := from.Pkg().Scope().Lookup(r.to); prev != nil { +- r.errorf(from.Pos(), "renaming this %s %q to %q would conflict", +- objectKind(from), from.Name(), r.to) +- r.errorf(prev.Pos(), "\twith this package member %s", +- objectKind(prev)) +- return // since checkInPackageBlock would report redundant errors - } - -- var editMap map[span.URI][]diff.Edit -- if inPackageName { -- editMap, err = renamePackageName(ctx, snapshot, f, PackageName(newName)) -- } else { -- editMap, err = renameOrdinary(ctx, snapshot, f, pp, newName) -- } -- if err != nil { -- return nil, false, err +- // Check for conflicts in lexical scope. +- r.checkInLexicalScope(from) +-} +- +-// checkInPackageBlock performs safety checks for renames of +-// func/var/const/type objects in the package block. +-func (r *renamer) checkInPackageBlock(from types.Object) { +- // Check that there are no references to the name from another +- // package if the renaming would make it unexported. +- if typ := r.pkg.GetTypes(); typ != from.Pkg() && ast.IsExported(r.from) && !ast.IsExported(r.to) { +- if id := someUse(r.pkg.GetTypesInfo(), from); id != nil { +- r.checkExport(id, typ, from) +- } - } - -- // Convert edits to protocol form. -- result := make(map[span.URI][]protocol.TextEdit) -- for uri, edits := range editMap { -- // Sort and de-duplicate edits. -- // -- // Overlapping edits may arise in local renamings (due -- // to type switch implicits) and globals ones (due to -- // processing multiple package variants). -- // -- // We assume renaming produces diffs that are all -- // replacements (no adjacent insertions that might -- // become reordered) and that are either identical or -- // non-overlapping. -- diff.SortEdits(edits) -- filtered := edits[:0] -- for i, edit := range edits { -- if i == 0 || edit != filtered[len(filtered)-1] { -- filtered = append(filtered, edit) +- // Check that in the package block, "init" is a function, and never referenced. +- if r.to == "init" { +- kind := objectKind(from) +- if kind == "func" { +- // Reject if intra-package references to it exist. +- for id, obj := range r.pkg.GetTypesInfo().Uses { +- if obj == from { +- r.errorf(from.Pos(), +- "renaming this func %q to %q would make it a package initializer", +- from.Name(), r.to) +- r.errorf(id.Pos(), "\tbut references to it exist") +- break +- } - } +- } else { +- r.errorf(from.Pos(), "you cannot have a %s at package level named %q", +- kind, r.to) - } -- edits = filtered +- } - -- // TODO(adonovan): the logic above handles repeat edits to the -- // same file URI (e.g. as a member of package p and p_test) but -- // is not sufficient to handle file-system level aliasing arising -- // from symbolic or hard links. For that, we should use a -- // robustio-FileID-keyed map. -- // See https://go.dev/cl/457615 for example. -- // This really occurs in practice, e.g. kubernetes has -- // vendor/k8s.io/kubectl -> ../../staging/src/k8s.io/kubectl. -- fh, err := snapshot.ReadFile(ctx, uri) -- if err != nil { -- return nil, false, err -- } -- data, err := fh.Content() -- if err != nil { -- return nil, false, err -- } -- m := protocol.NewMapper(uri, data) -- protocolEdits, err := ToProtocolEdits(m, edits) -- if err != nil { -- return nil, false, err +- // Check for conflicts between package block and all file blocks. +- for _, f := range r.pkg.GetSyntax() { +- fileScope := r.pkg.GetTypesInfo().Scopes[f] +- b, prev := fileScope.LookupParent(r.to, token.NoPos) +- if b == fileScope { +- r.errorf(from.Pos(), "renaming this %s %q to %q would conflict", objectKind(from), from.Name(), r.to) +- var prevPos token.Pos +- if prev != nil { +- prevPos = prev.Pos() +- } +- r.errorf(prevPos, "\twith this %s", objectKind(prev)) +- return // since checkInPackageBlock would report redundant errors - } -- result[uri] = protocolEdits - } - -- return result, inPackageName, nil +- // Check for conflicts in lexical scope. +- r.checkInLexicalScope(from) -} - --// renameOrdinary renames an ordinary (non-package) name throughout the workspace. --func renameOrdinary(ctx context.Context, snapshot Snapshot, f FileHandle, pp protocol.Position, newName string) (map[span.URI][]diff.Edit, error) { -- // Type-check the referring package and locate the object(s). -- // -- // Unlike NarrowestPackageForFile, this operation prefers the -- // widest variant as, for non-exported identifiers, it is the -- // only package we need. (In case you're wondering why -- // 'references' doesn't also want the widest variant: it -- // computes the union across all variants.) -- var targets map[types.Object]ast.Node -- var pkg Package -- { -- metas, err := snapshot.MetadataForFile(ctx, f.URI()) -- if err != nil { -- return nil, err -- } -- RemoveIntermediateTestVariants(&metas) -- if len(metas) == 0 { -- return nil, fmt.Errorf("no package metadata for file %s", f.URI()) -- } -- widest := metas[len(metas)-1] // widest variant may include _test.go files -- pkgs, err := snapshot.TypeCheck(ctx, widest.ID) -- if err != nil { -- return nil, err -- } -- pkg = pkgs[0] -- pgf, err := pkg.File(f.URI()) -- if err != nil { -- return nil, err // "can't happen" -- } -- pos, err := pgf.PositionPos(pp) -- if err != nil { -- return nil, err -- } -- objects, _, err := objectsAt(pkg.GetTypesInfo(), pgf.File, pos) -- if err != nil { -- return nil, err +-// checkInLexicalScope performs safety checks that a renaming does not +-// change the lexical reference structure of the specified package. +-// +-// For objects in lexical scope, there are three kinds of conflicts: +-// same-, sub-, and super-block conflicts. We will illustrate all three +-// using this example: +-// +-// var x int +-// var z int +-// +-// func f(y int) { +-// print(x) +-// print(y) +-// } +-// +-// Renaming x to z encounters a "same-block conflict", because an object +-// with the new name already exists, defined in the same lexical block +-// as the old object. +-// +-// Renaming x to y encounters a "sub-block conflict", because there exists +-// a reference to x from within (what would become) a hole in its scope. +-// The definition of y in an (inner) sub-block would cast a shadow in +-// the scope of the renamed variable. +-// +-// Renaming y to x encounters a "super-block conflict". This is the +-// converse situation: there is an existing definition of the new name +-// (x) in an (enclosing) super-block, and the renaming would create a +-// hole in its scope, within which there exist references to it. The +-// new name shadows the existing definition of x in the super-block. +-// +-// Removing the old name (and all references to it) is always safe, and +-// requires no checks. +-func (r *renamer) checkInLexicalScope(from types.Object) { +- b := from.Parent() // the block defining the 'from' object +- if b != nil { +- toBlock, to := b.LookupParent(r.to, from.Parent().End()) +- if toBlock == b { +- // same-block conflict +- r.errorf(from.Pos(), "renaming this %s %q to %q", +- objectKind(from), from.Name(), r.to) +- r.errorf(to.Pos(), "\tconflicts with %s in same block", +- objectKind(to)) +- return +- } else if toBlock != nil { +- // Check for super-block conflict. +- // The name r.to is defined in a superblock. +- // Is that name referenced from within this block? +- forEachLexicalRef(r.pkg, to, func(id *ast.Ident, block *types.Scope) bool { +- _, obj := block.LookupParent(from.Name(), id.Pos()) +- if obj == from { +- // super-block conflict +- r.errorf(from.Pos(), "renaming this %s %q to %q", +- objectKind(from), from.Name(), r.to) +- r.errorf(id.Pos(), "\twould shadow this reference") +- r.errorf(to.Pos(), "\tto the %s declared here", +- objectKind(to)) +- return false // stop +- } +- return true +- }) - } -- targets = objects -- } -- -- // Pick a representative object arbitrarily. -- // (All share the same name, pos, and kind.) -- var obj types.Object -- for obj = range targets { -- break -- } -- if obj.Name() == newName { -- return nil, fmt.Errorf("old and new names are the same: %s", newName) -- } -- if err := checkRenamable(obj); err != nil { -- return nil, err - } -- -- // Find objectpath, if object is exported ("" otherwise). -- var declObjPath objectpath.Path -- if obj.Exported() { -- // objectpath.For requires the origin of a generic function or type, not an -- // instantiation (a bug?). Unfortunately we can't call Func.Origin as this -- // is not available in go/types@go1.18. So we take a scenic route. -- // -- // Note that unlike Funcs, TypeNames are always canonical (they are "left" -- // of the type parameters, unlike methods). -- switch obj.(type) { // avoid "obj :=" since cases reassign the var -- case *types.TypeName: -- if _, ok := obj.Type().(*typeparams.TypeParam); ok { -- // As with capitalized function parameters below, type parameters are -- // local. -- goto skipObjectPath +- // Check for sub-block conflict. +- // Is there an intervening definition of r.to between +- // the block defining 'from' and some reference to it? +- forEachLexicalRef(r.pkg, from, func(id *ast.Ident, block *types.Scope) bool { +- // Find the block that defines the found reference. +- // It may be an ancestor. +- fromBlock, _ := block.LookupParent(from.Name(), id.Pos()) +- // See what r.to would resolve to in the same scope. +- toBlock, to := block.LookupParent(r.to, id.Pos()) +- if to != nil { +- // sub-block conflict +- if deeper(toBlock, fromBlock) { +- r.errorf(from.Pos(), "renaming this %s %q to %q", +- objectKind(from), from.Name(), r.to) +- r.errorf(id.Pos(), "\twould cause this reference to become shadowed") +- r.errorf(to.Pos(), "\tby this intervening %s definition", +- objectKind(to)) +- return false // stop - } -- case *types.Func: -- obj = funcOrigin(obj.(*types.Func)) -- case *types.Var: -- // TODO(adonovan): do vars need the origin treatment too? (issue #58462) +- } +- return true +- }) - -- // Function parameter and result vars that are (unusually) -- // capitalized are technically exported, even though they -- // cannot be referenced, because they may affect downstream -- // error messages. But we can safely treat them as local. -- // -- // This is not merely an optimization: the renameExported -- // operation gets confused by such vars. It finds them from -- // objectpath, the classifies them as local vars, but as -- // they came from export data they lack syntax and the -- // correct scope tree (issue #61294). -- if !obj.(*types.Var).IsField() && !isPackageLevel(obj) { -- goto skipObjectPath +- // Renaming a type that is used as an embedded field +- // requires renaming the field too. e.g. +- // type T int // if we rename this to U.. +- // var s struct {T} +- // print(s.T) // ...this must change too +- if _, ok := from.(*types.TypeName); ok { +- for id, obj := range r.pkg.GetTypesInfo().Uses { +- if obj == from { +- if field := r.pkg.GetTypesInfo().Defs[id]; field != nil { +- r.check(field) +- } - } - } -- if path, err := objectpath.For(obj); err == nil { -- declObjPath = path -- } -- skipObjectPath: - } +-} - -- // Nonexported? Search locally. -- if declObjPath == "" { -- var objects []types.Object -- for obj := range targets { -- objects = append(objects, obj) -- } -- editMap, _, err := renameObjects(ctx, snapshot, newName, pkg, objects...) -- return editMap, err +-// deeper reports whether block x is lexically deeper than y. +-func deeper(x, y *types.Scope) bool { +- if x == y || x == nil { +- return false +- } else if y == nil { +- return true +- } else { +- return deeper(x.Parent(), y.Parent()) - } +-} - -- // Exported: search globally. -- // -- // For exported package-level var/const/func/type objects, the -- // search scope is just the direct importers. -- // -- // For exported fields and methods, the scope is the -- // transitive rdeps. (The exportedness of the field's struct -- // or method's receiver is irrelevant.) -- transitive := false -- switch obj.(type) { -- case *types.TypeName: -- // Renaming an exported package-level type -- // requires us to inspect all transitive rdeps -- // in the event that the type is embedded. -- // -- // TODO(adonovan): opt: this is conservative -- // but inefficient. Instead, expand the scope -- // of the search only if we actually encounter -- // an embedding of the type, and only then to -- // the rdeps of the embedding package. -- if obj.Parent() == obj.Pkg().Scope() { -- transitive = true -- } +-// forEachLexicalRef calls fn(id, block) for each identifier id in package +-// pkg that is a reference to obj in lexical scope. block is the +-// lexical block enclosing the reference. If fn returns false the +-// iteration is terminated and findLexicalRefs returns false. +-func forEachLexicalRef(pkg Package, obj types.Object, fn func(id *ast.Ident, block *types.Scope) bool) bool { +- ok := true +- var stack []ast.Node - -- case *types.Var: -- if obj.(*types.Var).IsField() { -- transitive = true // field +- var visit func(n ast.Node) bool +- visit = func(n ast.Node) bool { +- if n == nil { +- stack = stack[:len(stack)-1] // pop +- return false +- } +- if !ok { +- return false // bail out - } - -- // TODO(adonovan): opt: process only packages that -- // contain a reference (xrefs) to the target field. +- stack = append(stack, n) // push +- switch n := n.(type) { +- case *ast.Ident: +- if pkg.GetTypesInfo().Uses[n] == obj { +- block := enclosingBlock(pkg.GetTypesInfo(), stack) +- if !fn(n, block) { +- ok = false +- } +- } +- return visit(nil) // pop stack - -- case *types.Func: -- if obj.Type().(*types.Signature).Recv() != nil { -- transitive = true // method -- } +- case *ast.SelectorExpr: +- // don't visit n.Sel +- ast.Inspect(n.X, visit) +- return visit(nil) // pop stack, don't descend - -- // It's tempting to optimize by skipping -- // packages that don't contain a reference to -- // the method in the xrefs index, but we still -- // need to apply the satisfy check to those -- // packages to find assignment statements that -- // might expands the scope of the renaming. +- case *ast.CompositeLit: +- // Handle recursion ourselves for struct literals +- // so we don't visit field identifiers. +- tv, ok := pkg.GetTypesInfo().Types[n] +- if !ok { +- return visit(nil) // pop stack, don't descend +- } +- if _, ok := Deref(tv.Type).Underlying().(*types.Struct); ok { +- if n.Type != nil { +- ast.Inspect(n.Type, visit) +- } +- for _, elt := range n.Elts { +- if kv, ok := elt.(*ast.KeyValueExpr); ok { +- ast.Inspect(kv.Value, visit) +- } else { +- ast.Inspect(elt, visit) +- } +- } +- return visit(nil) // pop stack, don't descend +- } +- } +- return true - } - -- // Type-check all the packages to inspect. -- declURI := span.URIFromPath(pkg.FileSet().File(obj.Pos()).Name()) -- pkgs, err := typeCheckReverseDependencies(ctx, snapshot, declURI, transitive) -- if err != nil { -- return nil, err +- for _, f := range pkg.GetSyntax() { +- ast.Inspect(f, visit) +- if len(stack) != 0 { +- panic(stack) +- } +- if !ok { +- break +- } - } -- -- // Apply the renaming to the (initial) object. -- declPkgPath := PackagePath(obj.Pkg().Path()) -- return renameExported(ctx, snapshot, pkgs, declPkgPath, declObjPath, newName) +- return ok -} - --// funcOrigin is a go1.18-portable implementation of (*types.Func).Origin. --func funcOrigin(fn *types.Func) *types.Func { -- // Method? -- if fn.Type().(*types.Signature).Recv() != nil { -- return typeparams.OriginMethod(fn) +-// enclosingBlock returns the innermost block enclosing the specified +-// AST node, specified in the form of a path from the root of the file, +-// [file...n]. +-func enclosingBlock(info *types.Info, stack []ast.Node) *types.Scope { +- for i := range stack { +- n := stack[len(stack)-1-i] +- // For some reason, go/types always associates a +- // function's scope with its FuncType. +- // TODO(adonovan): feature or a bug? +- switch f := n.(type) { +- case *ast.FuncDecl: +- n = f.Type +- case *ast.FuncLit: +- n = f.Type +- } +- if b := info.Scopes[n]; b != nil { +- return b +- } - } +- panic("no Scope for *ast.File") +-} - -- // Package-level function? -- // (Assume the origin has the same position.) -- gen := fn.Pkg().Scope().Lookup(fn.Name()) -- if gen != nil && gen.Pos() == fn.Pos() { -- return gen.(*types.Func) +-func (r *renamer) checkLabel(label *types.Label) { +- // Check there are no identical labels in the function's label block. +- // (Label blocks don't nest, so this is easy.) +- if prev := label.Parent().Lookup(r.to); prev != nil { +- r.errorf(label.Pos(), "renaming this label %q to %q", label.Name(), prev.Name()) +- r.errorf(prev.Pos(), "\twould conflict with this one") - } -- -- return fn -} - --// typeCheckReverseDependencies returns the type-checked packages for --// the reverse dependencies of all packages variants containing --// file declURI. The packages are in some topological order. --// --// It includes all variants (even intermediate test variants) for the --// purposes of computing reverse dependencies, but discards ITVs for --// the actual renaming work. --// --// (This neglects obscure edge cases where a _test.go file changes the --// selectors used only in an ITV, but life is short. Also sin must be --// punished.) --func typeCheckReverseDependencies(ctx context.Context, snapshot Snapshot, declURI span.URI, transitive bool) ([]Package, error) { -- variants, err := snapshot.MetadataForFile(ctx, declURI) -- if err != nil { -- return nil, err -- } -- // variants must include ITVs for the reverse dependency -- // computation, but they are filtered out before we typecheck. -- allRdeps := make(map[PackageID]*Metadata) -- for _, variant := range variants { -- rdeps, err := snapshot.ReverseDependencies(ctx, variant.ID, transitive) -- if err != nil { -- return nil, err +-// checkStructField checks that the field renaming will not cause +-// conflicts at its declaration, or ambiguity or changes to any selection. +-func (r *renamer) checkStructField(from *types.Var) { +- +- // If this is the declaring package, check that the struct +- // declaration is free of field conflicts, and field/method +- // conflicts. +- // +- // go/types offers no easy way to get from a field (or interface +- // method) to its declaring struct (or interface), so we must +- // ascend the AST. +- if pgf, ok := enclosingFile(r.pkg, from.Pos()); ok { +- path, _ := astutil.PathEnclosingInterval(pgf.File, from.Pos(), from.Pos()) +- // path matches this pattern: +- // [Ident SelectorExpr? StarExpr? Field FieldList StructType ParenExpr* ... File] +- +- // Ascend to FieldList. +- var i int +- for { +- if _, ok := path[i].(*ast.FieldList); ok { +- break +- } +- i++ - } -- allRdeps[variant.ID] = variant // include self -- for id, meta := range rdeps { -- allRdeps[id] = meta +- i++ +- tStruct := path[i].(*ast.StructType) +- i++ +- // Ascend past parens (unlikely). +- for { +- _, ok := path[i].(*ast.ParenExpr) +- if !ok { +- break +- } +- i++ +- } +- if spec, ok := path[i].(*ast.TypeSpec); ok { +- // This struct is also a named type. +- // We must check for direct (non-promoted) field/field +- // and method/field conflicts. +- named := r.pkg.GetTypesInfo().Defs[spec.Name].Type() +- prev, indices, _ := types.LookupFieldOrMethod(named, true, r.pkg.GetTypes(), r.to) +- if len(indices) == 1 { +- r.errorf(from.Pos(), "renaming this field %q to %q", +- from.Name(), r.to) +- r.errorf(prev.Pos(), "\twould conflict with this %s", +- objectKind(prev)) +- return // skip checkSelections to avoid redundant errors +- } +- } else { +- // This struct is not a named type. +- // We need only check for direct (non-promoted) field/field conflicts. +- T := r.pkg.GetTypesInfo().Types[tStruct].Type.Underlying().(*types.Struct) +- for i := 0; i < T.NumFields(); i++ { +- if prev := T.Field(i); prev.Name() == r.to { +- r.errorf(from.Pos(), "renaming this field %q to %q", +- from.Name(), r.to) +- r.errorf(prev.Pos(), "\twould conflict with this field") +- return // skip checkSelections to avoid redundant errors +- } +- } - } - } -- var ids []PackageID -- for id, meta := range allRdeps { -- if meta.IsIntermediateTestVariant() { -- continue +- +- // Renaming an anonymous field requires renaming the type too. e.g. +- // print(s.T) // if we rename T to U, +- // type T int // this and +- // var s struct {T} // this must change too. +- if from.Anonymous() { +- if named, ok := from.Type().(*types.Named); ok { +- r.check(named.Obj()) +- } else if named, ok := Deref(from.Type()).(*types.Named); ok { +- r.check(named.Obj()) - } -- ids = append(ids, id) - } - -- // Sort the packages into some topological order of the -- // (unfiltered) metadata graph. -- SortPostOrder(snapshot, ids) +- // Check integrity of existing (field and method) selections. +- r.checkSelections(from) +-} - -- // Dependencies must be visited first since they can expand +-// checkSelections checks that all uses and selections that resolve to +-// the specified object would continue to do so after the renaming. +-func (r *renamer) checkSelections(from types.Object) { +- pkg := r.pkg +- typ := pkg.GetTypes() +- { +- if id := someUse(pkg.GetTypesInfo(), from); id != nil { +- if !r.checkExport(id, typ, from) { +- return +- } +- } +- +- for syntax, sel := range pkg.GetTypesInfo().Selections { +- // There may be extant selections of only the old +- // name or only the new name, so we must check both. +- // (If neither, the renaming is sound.) +- // +- // In both cases, we wish to compare the lengths +- // of the implicit field path (Selection.Index) +- // to see if the renaming would change it. +- // +- // If a selection that resolves to 'from', when renamed, +- // would yield a path of the same or shorter length, +- // this indicates ambiguity or a changed referent, +- // analogous to same- or sub-block lexical conflict. +- // +- // If a selection using the name 'to' would +- // yield a path of the same or shorter length, +- // this indicates ambiguity or shadowing, +- // analogous to same- or super-block lexical conflict. +- +- // TODO(adonovan): fix: derive from Types[syntax.X].Mode +- // TODO(adonovan): test with pointer, value, addressable value. +- isAddressable := true +- +- if sel.Obj() == from { +- if obj, indices, _ := types.LookupFieldOrMethod(sel.Recv(), isAddressable, from.Pkg(), r.to); obj != nil { +- // Renaming this existing selection of +- // 'from' may block access to an existing +- // type member named 'to'. +- delta := len(indices) - len(sel.Index()) +- if delta > 0 { +- continue // no ambiguity +- } +- r.selectionConflict(from, delta, syntax, obj) +- return +- } +- } else if sel.Obj().Name() == r.to { +- if obj, indices, _ := types.LookupFieldOrMethod(sel.Recv(), isAddressable, from.Pkg(), from.Name()); obj == from { +- // Renaming 'from' may cause this existing +- // selection of the name 'to' to change +- // its meaning. +- delta := len(indices) - len(sel.Index()) +- if delta > 0 { +- continue // no ambiguity +- } +- r.selectionConflict(from, -delta, syntax, sel.Obj()) +- return +- } +- } +- } +- } +-} +- +-func (r *renamer) selectionConflict(from types.Object, delta int, syntax *ast.SelectorExpr, obj types.Object) { +- r.errorf(from.Pos(), "renaming this %s %q to %q", +- objectKind(from), from.Name(), r.to) +- +- switch { +- case delta < 0: +- // analogous to sub-block conflict +- r.errorf(syntax.Sel.Pos(), +- "\twould change the referent of this selection") +- r.errorf(obj.Pos(), "\tof this %s", objectKind(obj)) +- case delta == 0: +- // analogous to same-block conflict +- r.errorf(syntax.Sel.Pos(), +- "\twould make this reference ambiguous") +- r.errorf(obj.Pos(), "\twith this %s", objectKind(obj)) +- case delta > 0: +- // analogous to super-block conflict +- r.errorf(syntax.Sel.Pos(), +- "\twould shadow this selection") +- r.errorf(obj.Pos(), "\tof the %s declared here", +- objectKind(obj)) +- } +-} +- +-// checkMethod performs safety checks for renaming a method. +-// There are three hazards: +-// - declaration conflicts +-// - selection ambiguity/changes +-// - entailed renamings of assignable concrete/interface types. +-// +-// We reject renamings initiated at concrete methods if it would +-// change the assignability relation. For renamings of abstract +-// methods, we rename all methods transitively coupled to it via +-// assignability. +-func (r *renamer) checkMethod(from *types.Func) { +- // e.g. error.Error +- if from.Pkg() == nil { +- r.errorf(from.Pos(), "you cannot rename built-in method %s", from) +- return +- } +- +- // ASSIGNABILITY: We reject renamings of concrete methods that +- // would break a 'satisfy' constraint; but renamings of abstract +- // methods are allowed to proceed, and we rename affected +- // concrete and abstract methods as necessary. It is the +- // initial method that determines the policy. +- +- // Check for conflict at point of declaration. +- // Check to ensure preservation of assignability requirements. +- R := recv(from).Type() +- if types.IsInterface(R) { +- // Abstract method +- +- // declaration +- prev, _, _ := types.LookupFieldOrMethod(R, false, from.Pkg(), r.to) +- if prev != nil { +- r.errorf(from.Pos(), "renaming this interface method %q to %q", +- from.Name(), r.to) +- r.errorf(prev.Pos(), "\twould conflict with this method") +- return +- } +- +- // Check all interfaces that embed this one for +- // declaration conflicts too. +- { +- // Start with named interface types (better errors) +- for _, obj := range r.pkg.GetTypesInfo().Defs { +- if obj, ok := obj.(*types.TypeName); ok && types.IsInterface(obj.Type()) { +- f, _, _ := types.LookupFieldOrMethod( +- obj.Type(), false, from.Pkg(), from.Name()) +- if f == nil { +- continue +- } +- t, _, _ := types.LookupFieldOrMethod( +- obj.Type(), false, from.Pkg(), r.to) +- if t == nil { +- continue +- } +- r.errorf(from.Pos(), "renaming this interface method %q to %q", +- from.Name(), r.to) +- r.errorf(t.Pos(), "\twould conflict with this method") +- r.errorf(obj.Pos(), "\tin named interface type %q", obj.Name()) +- } +- } +- +- // Now look at all literal interface types (includes named ones again). +- for e, tv := range r.pkg.GetTypesInfo().Types { +- if e, ok := e.(*ast.InterfaceType); ok { +- _ = e +- _ = tv.Type.(*types.Interface) +- // TODO(adonovan): implement same check as above. +- } +- } +- } +- +- // assignability +- // +- // Find the set of concrete or abstract methods directly +- // coupled to abstract method 'from' by some +- // satisfy.Constraint, and rename them too. +- for key := range r.satisfy() { +- // key = (lhs, rhs) where lhs is always an interface. +- +- lsel := r.msets.MethodSet(key.LHS).Lookup(from.Pkg(), from.Name()) +- if lsel == nil { +- continue +- } +- rmethods := r.msets.MethodSet(key.RHS) +- rsel := rmethods.Lookup(from.Pkg(), from.Name()) +- if rsel == nil { +- continue +- } +- +- // If both sides have a method of this name, +- // and one of them is m, the other must be coupled. +- var coupled *types.Func +- switch from { +- case lsel.Obj(): +- coupled = rsel.Obj().(*types.Func) +- case rsel.Obj(): +- coupled = lsel.Obj().(*types.Func) +- default: +- continue +- } +- +- // We must treat concrete-to-interface +- // constraints like an implicit selection C.f of +- // each interface method I.f, and check that the +- // renaming leaves the selection unchanged and +- // unambiguous. +- // +- // Fun fact: the implicit selection of C.f +- // type I interface{f()} +- // type C struct{I} +- // func (C) g() +- // var _ I = C{} // here +- // yields abstract method I.f. This can make error +- // messages less than obvious. +- // +- if !types.IsInterface(key.RHS) { +- // The logic below was derived from checkSelections. +- +- rtosel := rmethods.Lookup(from.Pkg(), r.to) +- if rtosel != nil { +- rto := rtosel.Obj().(*types.Func) +- delta := len(rsel.Index()) - len(rtosel.Index()) +- if delta < 0 { +- continue // no ambiguity +- } +- +- // TODO(adonovan): record the constraint's position. +- keyPos := token.NoPos +- +- r.errorf(from.Pos(), "renaming this method %q to %q", +- from.Name(), r.to) +- if delta == 0 { +- // analogous to same-block conflict +- r.errorf(keyPos, "\twould make the %s method of %s invoked via interface %s ambiguous", +- r.to, key.RHS, key.LHS) +- r.errorf(rto.Pos(), "\twith (%s).%s", +- recv(rto).Type(), r.to) +- } else { +- // analogous to super-block conflict +- r.errorf(keyPos, "\twould change the %s method of %s invoked via interface %s", +- r.to, key.RHS, key.LHS) +- r.errorf(coupled.Pos(), "\tfrom (%s).%s", +- recv(coupled).Type(), r.to) +- r.errorf(rto.Pos(), "\tto (%s).%s", +- recv(rto).Type(), r.to) +- } +- return // one error is enough +- } +- } +- +- if !r.changeMethods { +- // This should be unreachable. +- r.errorf(from.Pos(), "internal error: during renaming of abstract method %s", from) +- r.errorf(coupled.Pos(), "\tchangedMethods=false, coupled method=%s", coupled) +- r.errorf(from.Pos(), "\tPlease file a bug report") +- return +- } +- +- // Rename the coupled method to preserve assignability. +- r.check(coupled) +- } +- } else { +- // Concrete method +- +- // declaration +- prev, indices, _ := types.LookupFieldOrMethod(R, true, from.Pkg(), r.to) +- if prev != nil && len(indices) == 1 { +- r.errorf(from.Pos(), "renaming this method %q to %q", +- from.Name(), r.to) +- r.errorf(prev.Pos(), "\twould conflict with this %s", +- objectKind(prev)) +- return +- } +- +- // assignability +- // +- // Find the set of abstract methods coupled to concrete +- // method 'from' by some satisfy.Constraint, and rename +- // them too. +- // +- // Coupling may be indirect, e.g. I.f <-> C.f via type D. +- // +- // type I interface {f()} +- // type C int +- // type (C) f() +- // type D struct{C} +- // var _ I = D{} +- // +- for key := range r.satisfy() { +- // key = (lhs, rhs) where lhs is always an interface. +- if types.IsInterface(key.RHS) { +- continue +- } +- rsel := r.msets.MethodSet(key.RHS).Lookup(from.Pkg(), from.Name()) +- if rsel == nil || rsel.Obj() != from { +- continue // rhs does not have the method +- } +- lsel := r.msets.MethodSet(key.LHS).Lookup(from.Pkg(), from.Name()) +- if lsel == nil { +- continue +- } +- imeth := lsel.Obj().(*types.Func) +- +- // imeth is the abstract method (e.g. I.f) +- // and key.RHS is the concrete coupling type (e.g. D). +- if !r.changeMethods { +- r.errorf(from.Pos(), "renaming this method %q to %q", +- from.Name(), r.to) +- var pos token.Pos +- var iface string +- +- I := recv(imeth).Type() +- if named, ok := I.(*types.Named); ok { +- pos = named.Obj().Pos() +- iface = "interface " + named.Obj().Name() +- } else { +- pos = from.Pos() +- iface = I.String() +- } +- r.errorf(pos, "\twould make %s no longer assignable to %s", +- key.RHS, iface) +- r.errorf(imeth.Pos(), "\t(rename %s.%s if you intend to change both types)", +- I, from.Name()) +- return // one error is enough +- } +- +- // Rename the coupled interface method to preserve assignability. +- r.check(imeth) +- } +- } +- +- // Check integrity of existing (field and method) selections. +- // We skip this if there were errors above, to avoid redundant errors. +- r.checkSelections(from) +-} +- +-func (r *renamer) checkExport(id *ast.Ident, pkg *types.Package, from types.Object) bool { +- // Reject cross-package references if r.to is unexported. +- // (Such references may be qualified identifiers or field/method +- // selections.) +- if !ast.IsExported(r.to) && pkg != from.Pkg() { +- r.errorf(from.Pos(), +- "renaming %q to %q would make it unexported", +- from.Name(), r.to) +- r.errorf(id.Pos(), "\tbreaking references from packages such as %q", +- pkg.Path()) +- return false +- } +- return true +-} +- +-// satisfy returns the set of interface satisfaction constraints. +-func (r *renamer) satisfy() map[satisfy.Constraint]bool { +- if r.satisfyConstraints == nil { +- // Compute on demand: it's expensive. +- var f satisfy.Finder +- pkg := r.pkg +- { +- // From satisfy.Finder documentation: +- // +- // The package must be free of type errors, and +- // info.{Defs,Uses,Selections,Types} must have been populated by the +- // type-checker. +- // +- // Only proceed if all packages have no errors. +- if len(pkg.GetParseErrors()) > 0 || len(pkg.GetTypeErrors()) > 0 { +- r.errorf(token.NoPos, // we don't have a position for this error. +- "renaming %q to %q not possible because %q has errors", +- r.from, r.to, pkg.Metadata().PkgPath) +- return nil +- } +- f.Find(pkg.GetTypesInfo(), pkg.GetSyntax()) +- } +- r.satisfyConstraints = f.Result +- } +- return r.satisfyConstraints +-} +- +-// -- helpers ---------------------------------------------------------- +- +-// recv returns the method's receiver. +-func recv(meth *types.Func) *types.Var { +- return meth.Type().(*types.Signature).Recv() +-} +- +-// someUse returns an arbitrary use of obj within info. +-func someUse(info *types.Info, obj types.Object) *ast.Ident { +- for id, o := range info.Uses { +- if o == obj { +- return id +- } +- } +- return nil +-} +- +-func objectKind(obj types.Object) string { +- if obj == nil { +- return "nil object" +- } +- switch obj := obj.(type) { +- case *types.PkgName: +- return "imported package name" +- case *types.TypeName: +- return "type" +- case *types.Var: +- if obj.IsField() { +- return "field" +- } +- case *types.Func: +- if obj.Type().(*types.Signature).Recv() != nil { +- return "method" +- } +- } +- // label, func, var, const +- return strings.ToLower(strings.TrimPrefix(reflect.TypeOf(obj).String(), "*types.")) +-} +- +-// NB: for renamings, blank is not considered valid. +-func isValidIdentifier(id string) bool { +- if id == "" || id == "_" { +- return false +- } +- for i, r := range id { +- if !isLetter(r) && (i == 0 || !isDigit(r)) { +- return false +- } +- } +- return token.Lookup(id) == token.IDENT +-} +- +-// isLocal reports whether obj is local to some function. +-// Precondition: not a struct field or interface method. +-func isLocal(obj types.Object) bool { +- // [... 5=stmt 4=func 3=file 2=pkg 1=universe] +- var depth int +- for scope := obj.Parent(); scope != nil; scope = scope.Parent() { +- depth++ +- } +- return depth >= 4 +-} +- +-func isPackageLevel(obj types.Object) bool { +- if obj == nil { +- return false +- } +- return obj.Pkg().Scope().Lookup(obj.Name()) == obj +-} +- +-// -- Plundered from go/scanner: --------------------------------------- +- +-func isLetter(ch rune) bool { +- return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= 0x80 && unicode.IsLetter(ch) +-} +- +-func isDigit(ch rune) bool { +- return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch) +-} +diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rename.go +--- a/gopls/internal/lsp/source/rename.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/rename.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,1277 +0,0 @@ +-// 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 source +- +-// TODO(adonovan): +-// +-// - method of generic concrete type -> arbitrary instances of same +-// +-// - make satisfy work across packages. +-// +-// - tests, tests, tests: +-// - play with renamings in the k8s tree. +-// - generics +-// - error cases (e.g. conflicts) +-// - renaming a symbol declared in the module cache +-// (currently proceeds with half of the renaming!) +-// - make sure all tests have both a local and a cross-package analogue. +-// - look at coverage +-// - special cases: embedded fields, interfaces, test variants, +-// function-local things with uppercase names; +-// packages with type errors (currently 'satisfy' rejects them), +-// package with missing imports; +-// +-// - measure performance in k8s. +-// +-// - The original gorename tool assumed well-typedness, but the gopls feature +-// does no such check (which actually makes it much more useful). +-// Audit to ensure it is safe on ill-typed code. +-// +-// - Generics support was no doubt buggy before but incrementalization +-// may have exacerbated it. If the problem were just about objects, +-// defs and uses it would be fairly simple, but type assignability +-// comes into play in the 'satisfy' check for method renamings. +-// De-instantiating Vector[int] to Vector[T] changes its type. +-// We need to come up with a theory for the satisfy check that +-// works with generics, and across packages. We currently have no +-// simple way to pass types between packages (think: objectpath for +-// types), though presumably exportdata could be pressed into service. +-// +-// - FileID-based de-duplication of edits to different URIs for the same file. +- +-import ( +- "context" +- "errors" +- "fmt" +- "go/ast" +- "go/token" +- "go/types" +- "path" +- "path/filepath" +- "regexp" +- "sort" +- "strconv" +- "strings" +- +- "golang.org/x/mod/modfile" +- "golang.org/x/tools/go/ast/astutil" +- "golang.org/x/tools/go/types/objectpath" +- "golang.org/x/tools/go/types/typeutil" +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/safetoken" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/diff" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/typeparams" +- "golang.org/x/tools/refactor/satisfy" +-) +- +-// A renamer holds state of a single call to renameObj, which renames +-// an object (or several coupled objects) within a single type-checked +-// syntax package. +-type renamer struct { +- pkg Package // the syntax package in which the renaming is applied +- objsToUpdate map[types.Object]bool // records progress of calls to check +- hadConflicts bool +- conflicts []string +- from, to string +- satisfyConstraints map[satisfy.Constraint]bool +- msets typeutil.MethodSetCache +- changeMethods bool +-} +- +-// A PrepareItem holds the result of a "prepare rename" operation: +-// the source range and value of a selected identifier. +-type PrepareItem struct { +- Range protocol.Range +- Text string +-} +- +-// PrepareRename searches for a valid renaming at position pp. +-// +-// The returned usererr is intended to be displayed to the user to explain why +-// the prepare fails. Probably we could eliminate the redundancy in returning +-// two errors, but for now this is done defensively. +-func PrepareRename(ctx context.Context, snapshot Snapshot, f FileHandle, pp protocol.Position) (_ *PrepareItem, usererr, err error) { +- ctx, done := event.Start(ctx, "source.PrepareRename") +- defer done() +- +- // Is the cursor within the package name declaration? +- if pgf, inPackageName, err := parsePackageNameDecl(ctx, snapshot, f, pp); err != nil { +- return nil, err, err +- } else if inPackageName { +- item, err := prepareRenamePackageName(ctx, snapshot, pgf) +- return item, err, err +- } +- +- // Ordinary (non-package) renaming. +- // +- // Type-check the current package, locate the reference at the position, +- // validate the object, and report its name and range. +- // +- // TODO(adonovan): in all cases below, we return usererr=nil, +- // which means we return (nil, nil) at the protocol +- // layer. This seems like a bug, or at best an exploitation of +- // knowledge of VSCode-specific behavior. Can we avoid that? +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, f.URI()) +- if err != nil { +- return nil, nil, err +- } +- pos, err := pgf.PositionPos(pp) +- if err != nil { +- return nil, nil, err +- } +- targets, node, err := objectsAt(pkg.GetTypesInfo(), pgf.File, pos) +- if err != nil { +- return nil, nil, err +- } +- var obj types.Object +- for obj = range targets { +- break // pick one arbitrarily +- } +- if err := checkRenamable(obj); err != nil { +- return nil, nil, err +- } +- rng, err := pgf.NodeRange(node) +- if err != nil { +- return nil, nil, err +- } +- if _, isImport := node.(*ast.ImportSpec); isImport { +- // We're not really renaming the import path. +- rng.End = rng.Start +- } +- return &PrepareItem{ +- Range: rng, +- Text: obj.Name(), +- }, nil, nil +-} +- +-func prepareRenamePackageName(ctx context.Context, snapshot Snapshot, pgf *ParsedGoFile) (*PrepareItem, error) { +- // Does the client support file renaming? +- fileRenameSupported := false +- for _, op := range snapshot.Options().SupportedResourceOperations { +- if op == protocol.Rename { +- fileRenameSupported = true +- break +- } +- } +- if !fileRenameSupported { +- return nil, errors.New("can't rename package: LSP client does not support file renaming") +- } +- +- // Check validity of the metadata for the file's containing package. +- meta, err := NarrowestMetadataForFile(ctx, snapshot, pgf.URI) +- if err != nil { +- return nil, err +- } +- if meta.Name == "main" { +- return nil, fmt.Errorf("can't rename package \"main\"") +- } +- if strings.HasSuffix(string(meta.Name), "_test") { +- return nil, fmt.Errorf("can't rename x_test packages") +- } +- if meta.Module == nil { +- return nil, fmt.Errorf("can't rename package: missing module information for package %q", meta.PkgPath) +- } +- if meta.Module.Path == string(meta.PkgPath) { +- return nil, fmt.Errorf("can't rename package: package path %q is the same as module path %q", meta.PkgPath, meta.Module.Path) +- } +- +- // Return the location of the package declaration. +- rng, err := pgf.NodeRange(pgf.File.Name) +- if err != nil { +- return nil, err +- } +- return &PrepareItem{ +- Range: rng, +- Text: string(meta.Name), +- }, nil +-} +- +-func checkRenamable(obj types.Object) error { +- switch obj := obj.(type) { +- case *types.Var: +- if obj.Embedded() { +- return fmt.Errorf("can't rename embedded fields: rename the type directly or name the field") +- } +- case *types.Builtin, *types.Nil: +- return fmt.Errorf("%s is built in and cannot be renamed", obj.Name()) +- } +- if obj.Pkg() == nil || obj.Pkg().Path() == "unsafe" { +- // e.g. error.Error, unsafe.Pointer +- return fmt.Errorf("%s is built in and cannot be renamed", obj.Name()) +- } +- if obj.Name() == "_" { +- return errors.New("can't rename \"_\"") +- } +- return nil +-} +- +-// Rename returns a map of TextEdits for each file modified when renaming a +-// given identifier within a package and a boolean value of true for renaming +-// package and false otherwise. +-func Rename(ctx context.Context, snapshot Snapshot, f FileHandle, pp protocol.Position, newName string) (map[span.URI][]protocol.TextEdit, bool, error) { +- ctx, done := event.Start(ctx, "source.Rename") +- defer done() +- +- if !isValidIdentifier(newName) { +- return nil, false, fmt.Errorf("invalid identifier to rename: %q", newName) +- } +- +- // Cursor within package name declaration? +- _, inPackageName, err := parsePackageNameDecl(ctx, snapshot, f, pp) +- if err != nil { +- return nil, false, err +- } +- +- var editMap map[span.URI][]diff.Edit +- if inPackageName { +- editMap, err = renamePackageName(ctx, snapshot, f, PackageName(newName)) +- } else { +- editMap, err = renameOrdinary(ctx, snapshot, f, pp, newName) +- } +- if err != nil { +- return nil, false, err +- } +- +- // Convert edits to protocol form. +- result := make(map[span.URI][]protocol.TextEdit) +- for uri, edits := range editMap { +- // Sort and de-duplicate edits. +- // +- // Overlapping edits may arise in local renamings (due +- // to type switch implicits) and globals ones (due to +- // processing multiple package variants). +- // +- // We assume renaming produces diffs that are all +- // replacements (no adjacent insertions that might +- // become reordered) and that are either identical or +- // non-overlapping. +- diff.SortEdits(edits) +- filtered := edits[:0] +- for i, edit := range edits { +- if i == 0 || edit != filtered[len(filtered)-1] { +- filtered = append(filtered, edit) +- } +- } +- edits = filtered +- +- // TODO(adonovan): the logic above handles repeat edits to the +- // same file URI (e.g. as a member of package p and p_test) but +- // is not sufficient to handle file-system level aliasing arising +- // from symbolic or hard links. For that, we should use a +- // robustio-FileID-keyed map. +- // See https://go.dev/cl/457615 for example. +- // This really occurs in practice, e.g. kubernetes has +- // vendor/k8s.io/kubectl -> ../../staging/src/k8s.io/kubectl. +- fh, err := snapshot.ReadFile(ctx, uri) +- if err != nil { +- return nil, false, err +- } +- data, err := fh.Content() +- if err != nil { +- return nil, false, err +- } +- m := protocol.NewMapper(uri, data) +- protocolEdits, err := ToProtocolEdits(m, edits) +- if err != nil { +- return nil, false, err +- } +- result[uri] = protocolEdits +- } +- +- return result, inPackageName, nil +-} +- +-// renameOrdinary renames an ordinary (non-package) name throughout the workspace. +-func renameOrdinary(ctx context.Context, snapshot Snapshot, f FileHandle, pp protocol.Position, newName string) (map[span.URI][]diff.Edit, error) { +- // Type-check the referring package and locate the object(s). +- // +- // Unlike NarrowestPackageForFile, this operation prefers the +- // widest variant as, for non-exported identifiers, it is the +- // only package we need. (In case you're wondering why +- // 'references' doesn't also want the widest variant: it +- // computes the union across all variants.) +- var targets map[types.Object]ast.Node +- var pkg Package +- { +- metas, err := snapshot.MetadataForFile(ctx, f.URI()) +- if err != nil { +- return nil, err +- } +- RemoveIntermediateTestVariants(&metas) +- if len(metas) == 0 { +- return nil, fmt.Errorf("no package metadata for file %s", f.URI()) +- } +- widest := metas[len(metas)-1] // widest variant may include _test.go files +- pkgs, err := snapshot.TypeCheck(ctx, widest.ID) +- if err != nil { +- return nil, err +- } +- pkg = pkgs[0] +- pgf, err := pkg.File(f.URI()) +- if err != nil { +- return nil, err // "can't happen" +- } +- pos, err := pgf.PositionPos(pp) +- if err != nil { +- return nil, err +- } +- objects, _, err := objectsAt(pkg.GetTypesInfo(), pgf.File, pos) +- if err != nil { +- return nil, err +- } +- targets = objects +- } +- +- // Pick a representative object arbitrarily. +- // (All share the same name, pos, and kind.) +- var obj types.Object +- for obj = range targets { +- break +- } +- if obj.Name() == newName { +- return nil, fmt.Errorf("old and new names are the same: %s", newName) +- } +- if err := checkRenamable(obj); err != nil { +- return nil, err +- } +- +- // Find objectpath, if object is exported ("" otherwise). +- var declObjPath objectpath.Path +- if obj.Exported() { +- // objectpath.For requires the origin of a generic function or type, not an +- // instantiation (a bug?). Unfortunately we can't call Func.Origin as this +- // is not available in go/types@go1.18. So we take a scenic route. +- // +- // Note that unlike Funcs, TypeNames are always canonical (they are "left" +- // of the type parameters, unlike methods). +- switch obj.(type) { // avoid "obj :=" since cases reassign the var +- case *types.TypeName: +- if _, ok := obj.Type().(*typeparams.TypeParam); ok { +- // As with capitalized function parameters below, type parameters are +- // local. +- goto skipObjectPath +- } +- case *types.Func: +- obj = funcOrigin(obj.(*types.Func)) +- case *types.Var: +- // TODO(adonovan): do vars need the origin treatment too? (issue #58462) +- +- // Function parameter and result vars that are (unusually) +- // capitalized are technically exported, even though they +- // cannot be referenced, because they may affect downstream +- // error messages. But we can safely treat them as local. +- // +- // This is not merely an optimization: the renameExported +- // operation gets confused by such vars. It finds them from +- // objectpath, the classifies them as local vars, but as +- // they came from export data they lack syntax and the +- // correct scope tree (issue #61294). +- if !obj.(*types.Var).IsField() && !isPackageLevel(obj) { +- goto skipObjectPath +- } +- } +- if path, err := objectpath.For(obj); err == nil { +- declObjPath = path +- } +- skipObjectPath: +- } +- +- // Nonexported? Search locally. +- if declObjPath == "" { +- var objects []types.Object +- for obj := range targets { +- objects = append(objects, obj) +- } +- editMap, _, err := renameObjects(newName, pkg, objects...) +- return editMap, err +- } +- +- // Exported: search globally. +- // +- // For exported package-level var/const/func/type objects, the +- // search scope is just the direct importers. +- // +- // For exported fields and methods, the scope is the +- // transitive rdeps. (The exportedness of the field's struct +- // or method's receiver is irrelevant.) +- transitive := false +- switch obj.(type) { +- case *types.TypeName: +- // Renaming an exported package-level type +- // requires us to inspect all transitive rdeps +- // in the event that the type is embedded. +- // +- // TODO(adonovan): opt: this is conservative +- // but inefficient. Instead, expand the scope +- // of the search only if we actually encounter +- // an embedding of the type, and only then to +- // the rdeps of the embedding package. +- if obj.Parent() == obj.Pkg().Scope() { +- transitive = true +- } +- +- case *types.Var: +- if obj.(*types.Var).IsField() { +- transitive = true // field +- } +- +- // TODO(adonovan): opt: process only packages that +- // contain a reference (xrefs) to the target field. +- +- case *types.Func: +- if obj.Type().(*types.Signature).Recv() != nil { +- transitive = true // method +- } +- +- // It's tempting to optimize by skipping +- // packages that don't contain a reference to +- // the method in the xrefs index, but we still +- // need to apply the satisfy check to those +- // packages to find assignment statements that +- // might expands the scope of the renaming. +- } +- +- // Type-check all the packages to inspect. +- declURI := span.URIFromPath(pkg.FileSet().File(obj.Pos()).Name()) +- pkgs, err := typeCheckReverseDependencies(ctx, snapshot, declURI, transitive) +- if err != nil { +- return nil, err +- } +- +- // Apply the renaming to the (initial) object. +- declPkgPath := PackagePath(obj.Pkg().Path()) +- return renameExported(pkgs, declPkgPath, declObjPath, newName) +-} +- +-// funcOrigin is a go1.18-portable implementation of (*types.Func).Origin. +-func funcOrigin(fn *types.Func) *types.Func { +- // Method? +- if fn.Type().(*types.Signature).Recv() != nil { +- return typeparams.OriginMethod(fn) +- } +- +- // Package-level function? +- // (Assume the origin has the same position.) +- gen := fn.Pkg().Scope().Lookup(fn.Name()) +- if gen != nil && gen.Pos() == fn.Pos() { +- return gen.(*types.Func) +- } +- +- return fn +-} +- +-// typeCheckReverseDependencies returns the type-checked packages for +-// the reverse dependencies of all packages variants containing +-// file declURI. The packages are in some topological order. +-// +-// It includes all variants (even intermediate test variants) for the +-// purposes of computing reverse dependencies, but discards ITVs for +-// the actual renaming work. +-// +-// (This neglects obscure edge cases where a _test.go file changes the +-// selectors used only in an ITV, but life is short. Also sin must be +-// punished.) +-func typeCheckReverseDependencies(ctx context.Context, snapshot Snapshot, declURI span.URI, transitive bool) ([]Package, error) { +- variants, err := snapshot.MetadataForFile(ctx, declURI) +- if err != nil { +- return nil, err +- } +- // variants must include ITVs for the reverse dependency +- // computation, but they are filtered out before we typecheck. +- allRdeps := make(map[PackageID]*Metadata) +- for _, variant := range variants { +- rdeps, err := snapshot.ReverseDependencies(ctx, variant.ID, transitive) +- if err != nil { +- return nil, err +- } +- allRdeps[variant.ID] = variant // include self +- for id, meta := range rdeps { +- allRdeps[id] = meta +- } +- } +- var ids []PackageID +- for id, meta := range allRdeps { +- if meta.IsIntermediateTestVariant() { +- continue +- } +- ids = append(ids, id) +- } +- +- // Sort the packages into some topological order of the +- // (unfiltered) metadata graph. +- SortPostOrder(snapshot, ids) +- +- // Dependencies must be visited first since they can expand - // the search set. Ideally we would process the (filtered) set - // of packages in the parallel postorder of the snapshot's - // (unfiltered) metadata graph, but this is quite tricky @@ -92626,7 +94588,7 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena -// within the specified packages, along with any other objects that -// must be renamed as a consequence. The slice of packages must be -// topologically ordered. --func renameExported(ctx context.Context, snapshot Snapshot, pkgs []Package, declPkgPath PackagePath, declObjPath objectpath.Path, newName string) (map[span.URI][]diff.Edit, error) { +-func renameExported(pkgs []Package, declPkgPath PackagePath, declObjPath objectpath.Path, newName string) (map[span.URI][]diff.Edit, error) { - - // A target is a name for an object that is stable across types.Packages. - type target struct { @@ -92682,7 +94644,7 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - } - - // Apply the renaming. -- editMap, moreObjects, err := renameObjects(ctx, snapshot, newName, pkg, objects...) +- editMap, moreObjects, err := renameObjects(newName, pkg, objects...) - if err != nil { - return nil, err - } @@ -93047,7 +95009,7 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - // become shadowed by an intervening declaration that - // uses the new name. - // It returns the edits if no conflict was detected. -- editMap, _, err := renameObjects(ctx, snapshot, localName, pkg, pkgname) +- editMap, _, err := renameObjects(localName, pkg, pkgname) - if err != nil { - return err - } @@ -93081,7 +95043,7 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena -// consequence of the requested renamings. -// -// It returns an error if the renaming would cause a conflict. --func renameObjects(ctx context.Context, snapshot Snapshot, newName string, pkg Package, targets ...types.Object) (map[span.URI][]diff.Edit, map[types.Object]bool, error) { +-func renameObjects(newName string, pkg Package, targets ...types.Object) (map[span.URI][]diff.Edit, map[types.Object]bool, error) { - r := renamer{ - pkg: pkg, - objsToUpdate: make(map[types.Object]bool), @@ -93352,957 +95314,33 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - } - return diff.Edit{Start: startOffset, End: endOffset, New: new}, nil -} -diff -urN a/gopls/internal/lsp/source/rename_check.go b/gopls/internal/lsp/source/rename_check.go ---- a/gopls/internal/lsp/source/rename_check.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/rename_check.go 1970-01-01 08:00:00 -@@ -1,921 +0,0 @@ --// Copyright 2019 The Go Authors. All rights reserved. +diff -urN a/gopls/internal/lsp/source/signature_help.go b/gopls/internal/lsp/source/signature_help.go +--- a/gopls/internal/lsp/source/signature_help.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/signature_help.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,198 +0,0 @@ +-// Copyright 2018 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. --// --// Taken from golang.org/x/tools/refactor/rename. - -package source - --// This file defines the conflict-checking portion of the rename operation. --// --// The renamer works on a single package of type-checked syntax, and --// is called in parallel for all necessary packages in the workspace, --// possibly up to the transitive reverse dependencies of the --// declaration. Finally the union of all edits and errors is computed. --// --// Renaming one object may entail renaming of others. For example: --// --// - An embedded field couples a Var (field) and a TypeName. --// So, renaming either one requires renaming the other. --// If the initial object is an embedded field, we must add its --// TypeName (and its enclosing package) to the renaming set; --// this is easily discovered at the outset. --// --// Conversely, if the initial object is a TypeName, we must observe --// whether any of its references (from directly importing packages) --// is coincident with an embedded field Var and, if so, initiate a --// renaming of it. --// --// - A method of an interface type is coupled to all corresponding --// methods of types that are assigned to the interface (as --// discovered by the 'satisfy' pass). As a matter of usability, we --// require that such renamings be initiated from the interface --// method, not the concrete method. -- -import ( +- "context" - "fmt" - "go/ast" - "go/token" - "go/types" -- "path/filepath" -- "reflect" - "strings" -- "unicode" - - "golang.org/x/tools/go/ast/astutil" -- "golang.org/x/tools/gopls/internal/lsp/safetoken" -- "golang.org/x/tools/refactor/satisfy" +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/internal/event" -) - --// errorf reports an error (e.g. conflict) and prevents file modification. --func (r *renamer) errorf(pos token.Pos, format string, args ...interface{}) { -- // Conflict error messages in the old gorename tool (whence this -- // logic originated) contain rich information associated with -- // multiple source lines, such as: -- // -- // p/a.go:1:2: renaming "x" to "y" here -- // p/b.go:3:4: \t would cause this reference to "y" -- // p/c.go:5:5: \t to become shadowed by this intervening declaration. -- // -- // Unfortunately LSP provides no means to transmit the -- // structure of this error, so we format the positions briefly -- // using dir/file.go where dir is the base name of the parent -- // directory. -- -- var conflict strings.Builder -- -- // Add prefix of (truncated) position. -- if pos != token.NoPos { -- // TODO(adonovan): skip position of first error if it is -- // on the same line as the renaming itself. -- posn := safetoken.StartPosition(r.pkg.FileSet(), pos).String() -- segments := strings.Split(filepath.ToSlash(posn), "/") -- if n := len(segments); n > 2 { -- segments = segments[n-2:] -- } -- posn = strings.Join(segments, "/") -- fmt.Fprintf(&conflict, "%s:", posn) -- -- if !strings.HasPrefix(format, "\t") { -- conflict.WriteByte(' ') -- } -- } -- -- fmt.Fprintf(&conflict, format, args...) -- r.conflicts = append(r.conflicts, conflict.String()) --} -- --// check performs safety checks of the renaming of the 'from' object to r.to. --func (r *renamer) check(from types.Object) { -- if r.objsToUpdate[from] { -- return -- } -- r.objsToUpdate[from] = true -- -- // NB: order of conditions is important. -- if from_, ok := from.(*types.PkgName); ok { -- r.checkInFileBlock(from_) -- } else if from_, ok := from.(*types.Label); ok { -- r.checkLabel(from_) -- } else if isPackageLevel(from) { -- r.checkInPackageBlock(from) -- } else if v, ok := from.(*types.Var); ok && v.IsField() { -- r.checkStructField(v) -- } else if f, ok := from.(*types.Func); ok && recv(f) != nil { -- r.checkMethod(f) -- } else if isLocal(from) { -- r.checkInLexicalScope(from) -- } else { -- r.errorf(from.Pos(), "unexpected %s object %q (please report a bug)\n", -- objectKind(from), from) -- } --} -- --// checkInFileBlock performs safety checks for renames of objects in the file block, --// i.e. imported package names. --func (r *renamer) checkInFileBlock(from *types.PkgName) { -- // Check import name is not "init". -- if r.to == "init" { -- r.errorf(from.Pos(), "%q is not a valid imported package name", r.to) -- } -- -- // Check for conflicts between file and package block. -- if prev := from.Pkg().Scope().Lookup(r.to); prev != nil { -- r.errorf(from.Pos(), "renaming this %s %q to %q would conflict", -- objectKind(from), from.Name(), r.to) -- r.errorf(prev.Pos(), "\twith this package member %s", -- objectKind(prev)) -- return // since checkInPackageBlock would report redundant errors -- } -- -- // Check for conflicts in lexical scope. -- r.checkInLexicalScope(from) --} -- --// checkInPackageBlock performs safety checks for renames of --// func/var/const/type objects in the package block. --func (r *renamer) checkInPackageBlock(from types.Object) { -- // Check that there are no references to the name from another -- // package if the renaming would make it unexported. -- if typ := r.pkg.GetTypes(); typ != from.Pkg() && ast.IsExported(r.from) && !ast.IsExported(r.to) { -- if id := someUse(r.pkg.GetTypesInfo(), from); id != nil { -- r.checkExport(id, typ, from) -- } -- } -- -- // Check that in the package block, "init" is a function, and never referenced. -- if r.to == "init" { -- kind := objectKind(from) -- if kind == "func" { -- // Reject if intra-package references to it exist. -- for id, obj := range r.pkg.GetTypesInfo().Uses { -- if obj == from { -- r.errorf(from.Pos(), -- "renaming this func %q to %q would make it a package initializer", -- from.Name(), r.to) -- r.errorf(id.Pos(), "\tbut references to it exist") -- break -- } -- } -- } else { -- r.errorf(from.Pos(), "you cannot have a %s at package level named %q", -- kind, r.to) -- } -- } -- -- // Check for conflicts between package block and all file blocks. -- for _, f := range r.pkg.GetSyntax() { -- fileScope := r.pkg.GetTypesInfo().Scopes[f] -- b, prev := fileScope.LookupParent(r.to, token.NoPos) -- if b == fileScope { -- r.errorf(from.Pos(), "renaming this %s %q to %q would conflict", objectKind(from), from.Name(), r.to) -- var prevPos token.Pos -- if prev != nil { -- prevPos = prev.Pos() -- } -- r.errorf(prevPos, "\twith this %s", objectKind(prev)) -- return // since checkInPackageBlock would report redundant errors -- } -- } -- -- // Check for conflicts in lexical scope. -- r.checkInLexicalScope(from) --} -- --// checkInLexicalScope performs safety checks that a renaming does not --// change the lexical reference structure of the specified package. --// --// For objects in lexical scope, there are three kinds of conflicts: --// same-, sub-, and super-block conflicts. We will illustrate all three --// using this example: --// --// var x int --// var z int --// --// func f(y int) { --// print(x) --// print(y) --// } --// --// Renaming x to z encounters a "same-block conflict", because an object --// with the new name already exists, defined in the same lexical block --// as the old object. --// --// Renaming x to y encounters a "sub-block conflict", because there exists --// a reference to x from within (what would become) a hole in its scope. --// The definition of y in an (inner) sub-block would cast a shadow in --// the scope of the renamed variable. --// --// Renaming y to x encounters a "super-block conflict". This is the --// converse situation: there is an existing definition of the new name --// (x) in an (enclosing) super-block, and the renaming would create a --// hole in its scope, within which there exist references to it. The --// new name shadows the existing definition of x in the super-block. --// --// Removing the old name (and all references to it) is always safe, and --// requires no checks. --func (r *renamer) checkInLexicalScope(from types.Object) { -- b := from.Parent() // the block defining the 'from' object -- if b != nil { -- toBlock, to := b.LookupParent(r.to, from.Parent().End()) -- if toBlock == b { -- // same-block conflict -- r.errorf(from.Pos(), "renaming this %s %q to %q", -- objectKind(from), from.Name(), r.to) -- r.errorf(to.Pos(), "\tconflicts with %s in same block", -- objectKind(to)) -- return -- } else if toBlock != nil { -- // Check for super-block conflict. -- // The name r.to is defined in a superblock. -- // Is that name referenced from within this block? -- forEachLexicalRef(r.pkg, to, func(id *ast.Ident, block *types.Scope) bool { -- _, obj := block.LookupParent(from.Name(), id.Pos()) -- if obj == from { -- // super-block conflict -- r.errorf(from.Pos(), "renaming this %s %q to %q", -- objectKind(from), from.Name(), r.to) -- r.errorf(id.Pos(), "\twould shadow this reference") -- r.errorf(to.Pos(), "\tto the %s declared here", -- objectKind(to)) -- return false // stop -- } -- return true -- }) -- } -- } -- // Check for sub-block conflict. -- // Is there an intervening definition of r.to between -- // the block defining 'from' and some reference to it? -- forEachLexicalRef(r.pkg, from, func(id *ast.Ident, block *types.Scope) bool { -- // Find the block that defines the found reference. -- // It may be an ancestor. -- fromBlock, _ := block.LookupParent(from.Name(), id.Pos()) -- // See what r.to would resolve to in the same scope. -- toBlock, to := block.LookupParent(r.to, id.Pos()) -- if to != nil { -- // sub-block conflict -- if deeper(toBlock, fromBlock) { -- r.errorf(from.Pos(), "renaming this %s %q to %q", -- objectKind(from), from.Name(), r.to) -- r.errorf(id.Pos(), "\twould cause this reference to become shadowed") -- r.errorf(to.Pos(), "\tby this intervening %s definition", -- objectKind(to)) -- return false // stop -- } -- } -- return true -- }) -- -- // Renaming a type that is used as an embedded field -- // requires renaming the field too. e.g. -- // type T int // if we rename this to U.. -- // var s struct {T} -- // print(s.T) // ...this must change too -- if _, ok := from.(*types.TypeName); ok { -- for id, obj := range r.pkg.GetTypesInfo().Uses { -- if obj == from { -- if field := r.pkg.GetTypesInfo().Defs[id]; field != nil { -- r.check(field) -- } -- } -- } -- } --} -- --// deeper reports whether block x is lexically deeper than y. --func deeper(x, y *types.Scope) bool { -- if x == y || x == nil { -- return false -- } else if y == nil { -- return true -- } else { -- return deeper(x.Parent(), y.Parent()) -- } --} -- --// forEachLexicalRef calls fn(id, block) for each identifier id in package --// pkg that is a reference to obj in lexical scope. block is the --// lexical block enclosing the reference. If fn returns false the --// iteration is terminated and findLexicalRefs returns false. --func forEachLexicalRef(pkg Package, obj types.Object, fn func(id *ast.Ident, block *types.Scope) bool) bool { -- ok := true -- var stack []ast.Node -- -- var visit func(n ast.Node) bool -- visit = func(n ast.Node) bool { -- if n == nil { -- stack = stack[:len(stack)-1] // pop -- return false -- } -- if !ok { -- return false // bail out -- } -- -- stack = append(stack, n) // push -- switch n := n.(type) { -- case *ast.Ident: -- if pkg.GetTypesInfo().Uses[n] == obj { -- block := enclosingBlock(pkg.GetTypesInfo(), stack) -- if !fn(n, block) { -- ok = false -- } -- } -- return visit(nil) // pop stack -- -- case *ast.SelectorExpr: -- // don't visit n.Sel -- ast.Inspect(n.X, visit) -- return visit(nil) // pop stack, don't descend -- -- case *ast.CompositeLit: -- // Handle recursion ourselves for struct literals -- // so we don't visit field identifiers. -- tv, ok := pkg.GetTypesInfo().Types[n] -- if !ok { -- return visit(nil) // pop stack, don't descend -- } -- if _, ok := Deref(tv.Type).Underlying().(*types.Struct); ok { -- if n.Type != nil { -- ast.Inspect(n.Type, visit) -- } -- for _, elt := range n.Elts { -- if kv, ok := elt.(*ast.KeyValueExpr); ok { -- ast.Inspect(kv.Value, visit) -- } else { -- ast.Inspect(elt, visit) -- } -- } -- return visit(nil) // pop stack, don't descend -- } -- } -- return true -- } -- -- for _, f := range pkg.GetSyntax() { -- ast.Inspect(f, visit) -- if len(stack) != 0 { -- panic(stack) -- } -- if !ok { -- break -- } -- } -- return ok --} -- --// enclosingBlock returns the innermost block enclosing the specified --// AST node, specified in the form of a path from the root of the file, --// [file...n]. --func enclosingBlock(info *types.Info, stack []ast.Node) *types.Scope { -- for i := range stack { -- n := stack[len(stack)-1-i] -- // For some reason, go/types always associates a -- // function's scope with its FuncType. -- // TODO(adonovan): feature or a bug? -- switch f := n.(type) { -- case *ast.FuncDecl: -- n = f.Type -- case *ast.FuncLit: -- n = f.Type -- } -- if b := info.Scopes[n]; b != nil { -- return b -- } -- } -- panic("no Scope for *ast.File") --} -- --func (r *renamer) checkLabel(label *types.Label) { -- // Check there are no identical labels in the function's label block. -- // (Label blocks don't nest, so this is easy.) -- if prev := label.Parent().Lookup(r.to); prev != nil { -- r.errorf(label.Pos(), "renaming this label %q to %q", label.Name(), prev.Name()) -- r.errorf(prev.Pos(), "\twould conflict with this one") -- } --} -- --// checkStructField checks that the field renaming will not cause --// conflicts at its declaration, or ambiguity or changes to any selection. --func (r *renamer) checkStructField(from *types.Var) { -- -- // If this is the declaring package, check that the struct -- // declaration is free of field conflicts, and field/method -- // conflicts. -- // -- // go/types offers no easy way to get from a field (or interface -- // method) to its declaring struct (or interface), so we must -- // ascend the AST. -- if pgf, ok := enclosingFile(r.pkg, from.Pos()); ok { -- path, _ := astutil.PathEnclosingInterval(pgf.File, from.Pos(), from.Pos()) -- // path matches this pattern: -- // [Ident SelectorExpr? StarExpr? Field FieldList StructType ParenExpr* ... File] -- -- // Ascend to FieldList. -- var i int -- for { -- if _, ok := path[i].(*ast.FieldList); ok { -- break -- } -- i++ -- } -- i++ -- tStruct := path[i].(*ast.StructType) -- i++ -- // Ascend past parens (unlikely). -- for { -- _, ok := path[i].(*ast.ParenExpr) -- if !ok { -- break -- } -- i++ -- } -- if spec, ok := path[i].(*ast.TypeSpec); ok { -- // This struct is also a named type. -- // We must check for direct (non-promoted) field/field -- // and method/field conflicts. -- named := r.pkg.GetTypesInfo().Defs[spec.Name].Type() -- prev, indices, _ := types.LookupFieldOrMethod(named, true, r.pkg.GetTypes(), r.to) -- if len(indices) == 1 { -- r.errorf(from.Pos(), "renaming this field %q to %q", -- from.Name(), r.to) -- r.errorf(prev.Pos(), "\twould conflict with this %s", -- objectKind(prev)) -- return // skip checkSelections to avoid redundant errors -- } -- } else { -- // This struct is not a named type. -- // We need only check for direct (non-promoted) field/field conflicts. -- T := r.pkg.GetTypesInfo().Types[tStruct].Type.Underlying().(*types.Struct) -- for i := 0; i < T.NumFields(); i++ { -- if prev := T.Field(i); prev.Name() == r.to { -- r.errorf(from.Pos(), "renaming this field %q to %q", -- from.Name(), r.to) -- r.errorf(prev.Pos(), "\twould conflict with this field") -- return // skip checkSelections to avoid redundant errors -- } -- } -- } -- } -- -- // Renaming an anonymous field requires renaming the type too. e.g. -- // print(s.T) // if we rename T to U, -- // type T int // this and -- // var s struct {T} // this must change too. -- if from.Anonymous() { -- if named, ok := from.Type().(*types.Named); ok { -- r.check(named.Obj()) -- } else if named, ok := Deref(from.Type()).(*types.Named); ok { -- r.check(named.Obj()) -- } -- } -- -- // Check integrity of existing (field and method) selections. -- r.checkSelections(from) --} -- --// checkSelections checks that all uses and selections that resolve to --// the specified object would continue to do so after the renaming. --func (r *renamer) checkSelections(from types.Object) { -- pkg := r.pkg -- typ := pkg.GetTypes() -- { -- if id := someUse(pkg.GetTypesInfo(), from); id != nil { -- if !r.checkExport(id, typ, from) { -- return -- } -- } -- -- for syntax, sel := range pkg.GetTypesInfo().Selections { -- // There may be extant selections of only the old -- // name or only the new name, so we must check both. -- // (If neither, the renaming is sound.) -- // -- // In both cases, we wish to compare the lengths -- // of the implicit field path (Selection.Index) -- // to see if the renaming would change it. -- // -- // If a selection that resolves to 'from', when renamed, -- // would yield a path of the same or shorter length, -- // this indicates ambiguity or a changed referent, -- // analogous to same- or sub-block lexical conflict. -- // -- // If a selection using the name 'to' would -- // yield a path of the same or shorter length, -- // this indicates ambiguity or shadowing, -- // analogous to same- or super-block lexical conflict. -- -- // TODO(adonovan): fix: derive from Types[syntax.X].Mode -- // TODO(adonovan): test with pointer, value, addressable value. -- isAddressable := true -- -- if sel.Obj() == from { -- if obj, indices, _ := types.LookupFieldOrMethod(sel.Recv(), isAddressable, from.Pkg(), r.to); obj != nil { -- // Renaming this existing selection of -- // 'from' may block access to an existing -- // type member named 'to'. -- delta := len(indices) - len(sel.Index()) -- if delta > 0 { -- continue // no ambiguity -- } -- r.selectionConflict(from, delta, syntax, obj) -- return -- } -- } else if sel.Obj().Name() == r.to { -- if obj, indices, _ := types.LookupFieldOrMethod(sel.Recv(), isAddressable, from.Pkg(), from.Name()); obj == from { -- // Renaming 'from' may cause this existing -- // selection of the name 'to' to change -- // its meaning. -- delta := len(indices) - len(sel.Index()) -- if delta > 0 { -- continue // no ambiguity -- } -- r.selectionConflict(from, -delta, syntax, sel.Obj()) -- return -- } -- } -- } -- } --} -- --func (r *renamer) selectionConflict(from types.Object, delta int, syntax *ast.SelectorExpr, obj types.Object) { -- r.errorf(from.Pos(), "renaming this %s %q to %q", -- objectKind(from), from.Name(), r.to) -- -- switch { -- case delta < 0: -- // analogous to sub-block conflict -- r.errorf(syntax.Sel.Pos(), -- "\twould change the referent of this selection") -- r.errorf(obj.Pos(), "\tof this %s", objectKind(obj)) -- case delta == 0: -- // analogous to same-block conflict -- r.errorf(syntax.Sel.Pos(), -- "\twould make this reference ambiguous") -- r.errorf(obj.Pos(), "\twith this %s", objectKind(obj)) -- case delta > 0: -- // analogous to super-block conflict -- r.errorf(syntax.Sel.Pos(), -- "\twould shadow this selection") -- r.errorf(obj.Pos(), "\tof the %s declared here", -- objectKind(obj)) -- } --} -- --// checkMethod performs safety checks for renaming a method. --// There are three hazards: --// - declaration conflicts --// - selection ambiguity/changes --// - entailed renamings of assignable concrete/interface types. --// --// We reject renamings initiated at concrete methods if it would --// change the assignability relation. For renamings of abstract --// methods, we rename all methods transitively coupled to it via --// assignability. --func (r *renamer) checkMethod(from *types.Func) { -- // e.g. error.Error -- if from.Pkg() == nil { -- r.errorf(from.Pos(), "you cannot rename built-in method %s", from) -- return -- } -- -- // ASSIGNABILITY: We reject renamings of concrete methods that -- // would break a 'satisfy' constraint; but renamings of abstract -- // methods are allowed to proceed, and we rename affected -- // concrete and abstract methods as necessary. It is the -- // initial method that determines the policy. -- -- // Check for conflict at point of declaration. -- // Check to ensure preservation of assignability requirements. -- R := recv(from).Type() -- if types.IsInterface(R) { -- // Abstract method -- -- // declaration -- prev, _, _ := types.LookupFieldOrMethod(R, false, from.Pkg(), r.to) -- if prev != nil { -- r.errorf(from.Pos(), "renaming this interface method %q to %q", -- from.Name(), r.to) -- r.errorf(prev.Pos(), "\twould conflict with this method") -- return -- } -- -- // Check all interfaces that embed this one for -- // declaration conflicts too. -- { -- // Start with named interface types (better errors) -- for _, obj := range r.pkg.GetTypesInfo().Defs { -- if obj, ok := obj.(*types.TypeName); ok && types.IsInterface(obj.Type()) { -- f, _, _ := types.LookupFieldOrMethod( -- obj.Type(), false, from.Pkg(), from.Name()) -- if f == nil { -- continue -- } -- t, _, _ := types.LookupFieldOrMethod( -- obj.Type(), false, from.Pkg(), r.to) -- if t == nil { -- continue -- } -- r.errorf(from.Pos(), "renaming this interface method %q to %q", -- from.Name(), r.to) -- r.errorf(t.Pos(), "\twould conflict with this method") -- r.errorf(obj.Pos(), "\tin named interface type %q", obj.Name()) -- } -- } -- -- // Now look at all literal interface types (includes named ones again). -- for e, tv := range r.pkg.GetTypesInfo().Types { -- if e, ok := e.(*ast.InterfaceType); ok { -- _ = e -- _ = tv.Type.(*types.Interface) -- // TODO(adonovan): implement same check as above. -- } -- } -- } -- -- // assignability -- // -- // Find the set of concrete or abstract methods directly -- // coupled to abstract method 'from' by some -- // satisfy.Constraint, and rename them too. -- for key := range r.satisfy() { -- // key = (lhs, rhs) where lhs is always an interface. -- -- lsel := r.msets.MethodSet(key.LHS).Lookup(from.Pkg(), from.Name()) -- if lsel == nil { -- continue -- } -- rmethods := r.msets.MethodSet(key.RHS) -- rsel := rmethods.Lookup(from.Pkg(), from.Name()) -- if rsel == nil { -- continue -- } -- -- // If both sides have a method of this name, -- // and one of them is m, the other must be coupled. -- var coupled *types.Func -- switch from { -- case lsel.Obj(): -- coupled = rsel.Obj().(*types.Func) -- case rsel.Obj(): -- coupled = lsel.Obj().(*types.Func) -- default: -- continue -- } -- -- // We must treat concrete-to-interface -- // constraints like an implicit selection C.f of -- // each interface method I.f, and check that the -- // renaming leaves the selection unchanged and -- // unambiguous. -- // -- // Fun fact: the implicit selection of C.f -- // type I interface{f()} -- // type C struct{I} -- // func (C) g() -- // var _ I = C{} // here -- // yields abstract method I.f. This can make error -- // messages less than obvious. -- // -- if !types.IsInterface(key.RHS) { -- // The logic below was derived from checkSelections. -- -- rtosel := rmethods.Lookup(from.Pkg(), r.to) -- if rtosel != nil { -- rto := rtosel.Obj().(*types.Func) -- delta := len(rsel.Index()) - len(rtosel.Index()) -- if delta < 0 { -- continue // no ambiguity -- } -- -- // TODO(adonovan): record the constraint's position. -- keyPos := token.NoPos -- -- r.errorf(from.Pos(), "renaming this method %q to %q", -- from.Name(), r.to) -- if delta == 0 { -- // analogous to same-block conflict -- r.errorf(keyPos, "\twould make the %s method of %s invoked via interface %s ambiguous", -- r.to, key.RHS, key.LHS) -- r.errorf(rto.Pos(), "\twith (%s).%s", -- recv(rto).Type(), r.to) -- } else { -- // analogous to super-block conflict -- r.errorf(keyPos, "\twould change the %s method of %s invoked via interface %s", -- r.to, key.RHS, key.LHS) -- r.errorf(coupled.Pos(), "\tfrom (%s).%s", -- recv(coupled).Type(), r.to) -- r.errorf(rto.Pos(), "\tto (%s).%s", -- recv(rto).Type(), r.to) -- } -- return // one error is enough -- } -- } -- -- if !r.changeMethods { -- // This should be unreachable. -- r.errorf(from.Pos(), "internal error: during renaming of abstract method %s", from) -- r.errorf(coupled.Pos(), "\tchangedMethods=false, coupled method=%s", coupled) -- r.errorf(from.Pos(), "\tPlease file a bug report") -- return -- } -- -- // Rename the coupled method to preserve assignability. -- r.check(coupled) -- } -- } else { -- // Concrete method -- -- // declaration -- prev, indices, _ := types.LookupFieldOrMethod(R, true, from.Pkg(), r.to) -- if prev != nil && len(indices) == 1 { -- r.errorf(from.Pos(), "renaming this method %q to %q", -- from.Name(), r.to) -- r.errorf(prev.Pos(), "\twould conflict with this %s", -- objectKind(prev)) -- return -- } -- -- // assignability -- // -- // Find the set of abstract methods coupled to concrete -- // method 'from' by some satisfy.Constraint, and rename -- // them too. -- // -- // Coupling may be indirect, e.g. I.f <-> C.f via type D. -- // -- // type I interface {f()} -- // type C int -- // type (C) f() -- // type D struct{C} -- // var _ I = D{} -- // -- for key := range r.satisfy() { -- // key = (lhs, rhs) where lhs is always an interface. -- if types.IsInterface(key.RHS) { -- continue -- } -- rsel := r.msets.MethodSet(key.RHS).Lookup(from.Pkg(), from.Name()) -- if rsel == nil || rsel.Obj() != from { -- continue // rhs does not have the method -- } -- lsel := r.msets.MethodSet(key.LHS).Lookup(from.Pkg(), from.Name()) -- if lsel == nil { -- continue -- } -- imeth := lsel.Obj().(*types.Func) -- -- // imeth is the abstract method (e.g. I.f) -- // and key.RHS is the concrete coupling type (e.g. D). -- if !r.changeMethods { -- r.errorf(from.Pos(), "renaming this method %q to %q", -- from.Name(), r.to) -- var pos token.Pos -- var iface string -- -- I := recv(imeth).Type() -- if named, ok := I.(*types.Named); ok { -- pos = named.Obj().Pos() -- iface = "interface " + named.Obj().Name() -- } else { -- pos = from.Pos() -- iface = I.String() -- } -- r.errorf(pos, "\twould make %s no longer assignable to %s", -- key.RHS, iface) -- r.errorf(imeth.Pos(), "\t(rename %s.%s if you intend to change both types)", -- I, from.Name()) -- return // one error is enough -- } -- -- // Rename the coupled interface method to preserve assignability. -- r.check(imeth) -- } -- } -- -- // Check integrity of existing (field and method) selections. -- // We skip this if there were errors above, to avoid redundant errors. -- r.checkSelections(from) --} -- --func (r *renamer) checkExport(id *ast.Ident, pkg *types.Package, from types.Object) bool { -- // Reject cross-package references if r.to is unexported. -- // (Such references may be qualified identifiers or field/method -- // selections.) -- if !ast.IsExported(r.to) && pkg != from.Pkg() { -- r.errorf(from.Pos(), -- "renaming %q to %q would make it unexported", -- from.Name(), r.to) -- r.errorf(id.Pos(), "\tbreaking references from packages such as %q", -- pkg.Path()) -- return false -- } -- return true --} -- --// satisfy returns the set of interface satisfaction constraints. --func (r *renamer) satisfy() map[satisfy.Constraint]bool { -- if r.satisfyConstraints == nil { -- // Compute on demand: it's expensive. -- var f satisfy.Finder -- pkg := r.pkg -- { -- // From satisfy.Finder documentation: -- // -- // The package must be free of type errors, and -- // info.{Defs,Uses,Selections,Types} must have been populated by the -- // type-checker. -- // -- // Only proceed if all packages have no errors. -- if len(pkg.GetParseErrors()) > 0 || len(pkg.GetTypeErrors()) > 0 { -- r.errorf(token.NoPos, // we don't have a position for this error. -- "renaming %q to %q not possible because %q has errors", -- r.from, r.to, pkg.Metadata().PkgPath) -- return nil -- } -- f.Find(pkg.GetTypesInfo(), pkg.GetSyntax()) -- } -- r.satisfyConstraints = f.Result -- } -- return r.satisfyConstraints --} -- --// -- helpers ---------------------------------------------------------- -- --// recv returns the method's receiver. --func recv(meth *types.Func) *types.Var { -- return meth.Type().(*types.Signature).Recv() --} -- --// someUse returns an arbitrary use of obj within info. --func someUse(info *types.Info, obj types.Object) *ast.Ident { -- for id, o := range info.Uses { -- if o == obj { -- return id -- } -- } -- return nil --} -- --func objectKind(obj types.Object) string { -- if obj == nil { -- return "nil object" -- } -- switch obj := obj.(type) { -- case *types.PkgName: -- return "imported package name" -- case *types.TypeName: -- return "type" -- case *types.Var: -- if obj.IsField() { -- return "field" -- } -- case *types.Func: -- if obj.Type().(*types.Signature).Recv() != nil { -- return "method" -- } -- } -- // label, func, var, const -- return strings.ToLower(strings.TrimPrefix(reflect.TypeOf(obj).String(), "*types.")) --} -- --// NB: for renamings, blank is not considered valid. --func isValidIdentifier(id string) bool { -- if id == "" || id == "_" { -- return false -- } -- for i, r := range id { -- if !isLetter(r) && (i == 0 || !isDigit(r)) { -- return false -- } -- } -- return token.Lookup(id) == token.IDENT --} -- --// isLocal reports whether obj is local to some function. --// Precondition: not a struct field or interface method. --func isLocal(obj types.Object) bool { -- // [... 5=stmt 4=func 3=file 2=pkg 1=universe] -- var depth int -- for scope := obj.Parent(); scope != nil; scope = scope.Parent() { -- depth++ -- } -- return depth >= 4 --} -- --func isPackageLevel(obj types.Object) bool { -- if obj == nil { -- return false -- } -- return obj.Pkg().Scope().Lookup(obj.Name()) == obj --} -- --// -- Plundered from go/scanner: --------------------------------------- -- --func isLetter(ch rune) bool { -- return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= 0x80 && unicode.IsLetter(ch) --} -- --func isDigit(ch rune) bool { -- return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch) --} -diff -urN a/gopls/internal/lsp/source/signature_help.go b/gopls/internal/lsp/source/signature_help.go ---- a/gopls/internal/lsp/source/signature_help.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/signature_help.go 1970-01-01 08:00:00 -@@ -1,185 +0,0 @@ --// Copyright 2018 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 source -- --import ( -- "context" -- "fmt" -- "go/ast" -- "go/token" -- "go/types" -- "strings" -- -- "golang.org/x/tools/go/ast/astutil" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/internal/event" --) -- --func SignatureHelp(ctx context.Context, snapshot Snapshot, fh FileHandle, position protocol.Position) (*protocol.SignatureInformation, int, error) { -- ctx, done := event.Start(ctx, "source.SignatureHelp") -- defer done() +-func SignatureHelp(ctx context.Context, snapshot Snapshot, fh FileHandle, position protocol.Position) (*protocol.SignatureInformation, int, error) { +- ctx, done := event.Start(ctx, "source.SignatureHelp") +- defer done() - - // We need full type-checking here, as we must type-check function bodies in - // order to provide signature help at the requested position. @@ -94357,9 +95395,22 @@ diff -urN a/gopls/internal/lsp/source/signature_help.go b/gopls/internal/lsp/sou - obj = pkg.GetTypesInfo().ObjectOf(t.Sel) - } - -- // Handle builtin functions separately. -- if obj, ok := obj.(*types.Builtin); ok { -- return builtinSignature(ctx, snapshot, callExpr, obj.Name(), pos) +- // Built-in? +- if obj != nil && !obj.Pos().IsValid() { +- // built-in function? +- if obj, ok := obj.(*types.Builtin); ok { +- return builtinSignature(ctx, snapshot, callExpr, obj.Name(), pos) +- } +- +- // error.Error? +- if fn, ok := obj.(*types.Func); ok && fn.Name() == "Error" { +- return &protocol.SignatureInformation{ +- Label: "Error()", +- Documentation: stringToSigInfoDocumentation("Error returns the error message.", snapshot.Options()), +- }, 0, nil +- } +- +- return nil, 0, bug.Errorf("call to unexpected built-in %v (%T)", obj, obj) - } - - // Get the type information for the function being called. @@ -94420,7 +95471,6 @@ diff -urN a/gopls/internal/lsp/source/signature_help.go b/gopls/internal/lsp/sou - Documentation: stringToSigInfoDocumentation(sig.doc, snapshot.Options()), - Parameters: paramInfo, - }, activeParam, nil -- -} - -func activeParameter(callExpr *ast.CallExpr, numParams int, variadic bool, pos token.Pos) (activeParam int) { @@ -94468,7 +95518,7 @@ diff -urN a/gopls/internal/lsp/source/signature_help.go b/gopls/internal/lsp/sou -} diff -urN a/gopls/internal/lsp/source/stub.go b/gopls/internal/lsp/source/stub.go --- a/gopls/internal/lsp/source/stub.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/stub.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/stub.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,250 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -94722,7 +95772,7 @@ diff -urN a/gopls/internal/lsp/source/stub.go b/gopls/internal/lsp/source/stub.g -} diff -urN a/gopls/internal/lsp/source/symbols.go b/gopls/internal/lsp/source/symbols.go --- a/gopls/internal/lsp/source/symbols.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/symbols.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/symbols.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,227 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -94953,7 +96003,7 @@ diff -urN a/gopls/internal/lsp/source/symbols.go b/gopls/internal/lsp/source/sym -} diff -urN a/gopls/internal/lsp/source/type_definition.go b/gopls/internal/lsp/source/type_definition.go --- a/gopls/internal/lsp/source/type_definition.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/type_definition.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/type_definition.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -95014,7 +96064,7 @@ diff -urN a/gopls/internal/lsp/source/type_definition.go b/gopls/internal/lsp/so -} diff -urN a/gopls/internal/lsp/source/typerefs/doc.go b/gopls/internal/lsp/source/typerefs/doc.go --- a/gopls/internal/lsp/source/typerefs/doc.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/typerefs/doc.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/typerefs/doc.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,151 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -95169,7 +96219,7 @@ diff -urN a/gopls/internal/lsp/source/typerefs/doc.go b/gopls/internal/lsp/sourc -package typerefs diff -urN a/gopls/internal/lsp/source/typerefs/packageset.go b/gopls/internal/lsp/source/typerefs/packageset.go --- a/gopls/internal/lsp/source/typerefs/packageset.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/typerefs/packageset.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/typerefs/packageset.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,148 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -95321,7 +96371,7 @@ diff -urN a/gopls/internal/lsp/source/typerefs/packageset.go b/gopls/internal/ls -} diff -urN a/gopls/internal/lsp/source/typerefs/pkggraph_test.go b/gopls/internal/lsp/source/typerefs/pkggraph_test.go --- a/gopls/internal/lsp/source/typerefs/pkggraph_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/typerefs/pkggraph_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/typerefs/pkggraph_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,243 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -95568,7 +96618,7 @@ diff -urN a/gopls/internal/lsp/source/typerefs/pkggraph_test.go b/gopls/internal -} diff -urN a/gopls/internal/lsp/source/typerefs/pkgrefs_test.go b/gopls/internal/lsp/source/typerefs/pkgrefs_test.go --- a/gopls/internal/lsp/source/typerefs/pkgrefs_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/typerefs/pkgrefs_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/typerefs/pkgrefs_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,407 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -95979,7 +97029,7 @@ diff -urN a/gopls/internal/lsp/source/typerefs/pkgrefs_test.go b/gopls/internal/ -} diff -urN a/gopls/internal/lsp/source/typerefs/refs.go b/gopls/internal/lsp/source/typerefs/refs.go --- a/gopls/internal/lsp/source/typerefs/refs.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/typerefs/refs.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/typerefs/refs.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,832 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -96815,7 +97865,7 @@ diff -urN a/gopls/internal/lsp/source/typerefs/refs.go b/gopls/internal/lsp/sour -} diff -urN a/gopls/internal/lsp/source/typerefs/refs_test.go b/gopls/internal/lsp/source/typerefs/refs_test.go --- a/gopls/internal/lsp/source/typerefs/refs_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/typerefs/refs_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/typerefs/refs_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,558 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -97377,8 +98427,8 @@ diff -urN a/gopls/internal/lsp/source/typerefs/refs_test.go b/gopls/internal/lsp -} diff -urN a/gopls/internal/lsp/source/types_format.go b/gopls/internal/lsp/source/types_format.go --- a/gopls/internal/lsp/source/types_format.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/types_format.go 1970-01-01 08:00:00 -@@ -1,520 +0,0 @@ ++++ b/gopls/internal/lsp/source/types_format.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,524 +0,0 @@ -// Copyright 2020 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. @@ -97693,7 +98743,11 @@ diff -urN a/gopls/internal/lsp/source/types_format.go b/gopls/internal/lsp/sourc - return types.TypeString(obj.Type(), qf), nil // in generic function - } - if decl.Recv != nil && len(decl.Recv.List) > 0 { -- if x, _, _, _ := typeparams.UnpackIndexExpr(decl.Recv.List[0].Type); x != nil { +- rtype := decl.Recv.List[0].Type +- if e, ok := rtype.(*ast.StarExpr); ok { +- rtype = e.X +- } +- if x, _, _, _ := typeparams.UnpackIndexExpr(rtype); x != nil { - return types.TypeString(obj.Type(), qf), nil // in method of generic type - } - } @@ -97901,8 +98955,8 @@ diff -urN a/gopls/internal/lsp/source/types_format.go b/gopls/internal/lsp/sourc -} diff -urN a/gopls/internal/lsp/source/util.go b/gopls/internal/lsp/source/util.go --- a/gopls/internal/lsp/source/util.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/util.go 1970-01-01 08:00:00 -@@ -1,533 +0,0 @@ ++++ b/gopls/internal/lsp/source/util.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,541 +0,0 @@ -// 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. @@ -98024,6 +99078,8 @@ diff -urN a/gopls/internal/lsp/source/util.go b/gopls/internal/lsp/source/util.g -func FormatNode(fset *token.FileSet, n ast.Node) string { - var buf strings.Builder - if err := printer.Fprint(&buf, fset, n); err != nil { +- // TODO(rfindley): we should use bug.Reportf here. +- // We encounter this during completion.resolveInvalid. - return "" - } - return buf.String() @@ -98436,10 +99492,16 @@ diff -urN a/gopls/internal/lsp/source/util.go b/gopls/internal/lsp/source/util.g - } - return nil -} +- +-// An importFunc is an implementation of the single-method +-// types.Importer interface based on a function value. +-type ImporterFunc func(path string) (*types.Package, error) +- +-func (f ImporterFunc) Import(path string) (*types.Package, error) { return f(path) } diff -urN a/gopls/internal/lsp/source/view.go b/gopls/internal/lsp/source/view.go --- a/gopls/internal/lsp/source/view.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/view.go 1970-01-01 08:00:00 -@@ -1,1036 +0,0 @@ ++++ b/gopls/internal/lsp/source/view.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,1060 +0,0 @@ -// Copyright 2018 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. @@ -98726,24 +99788,44 @@ diff -urN a/gopls/internal/lsp/source/view.go b/gopls/internal/lsp/source/view.g - return []label.Label{tag.Snapshot.Of(snapshot.SequenceID()), tag.Directory.Of(snapshot.View().Folder())} -} - --// NarrowestPackageForFile is a convenience function that selects the --// narrowest non-ITV package to which this file belongs, type-checks --// it in the requested mode (full or workspace), and returns it, along --// with the parse tree of that file. +-// NarrowestPackageForFile is a convenience function that selects the narrowest +-// non-ITV package to which this file belongs, type-checks it in the requested +-// mode (full or workspace), and returns it, along with the parse tree of that +-// file. -// --// The "narrowest" package is the one with the fewest number of files --// that includes the given file. This solves the problem of test --// variants, as the test will have more files than the non-test package. --// (Historically the preference was a parameter but widest was almost --// never needed.) +-// The "narrowest" package is the one with the fewest number of files that +-// includes the given file. This solves the problem of test variants, as the +-// test will have more files than the non-test package. -// --// An intermediate test variant (ITV) package has identical source --// to a regular package but resolves imports differently. --// gopls should never need to type-check them. +-// An intermediate test variant (ITV) package has identical source to a regular +-// package but resolves imports differently. gopls should never need to +-// type-check them. -// --// Type-checking is expensive. Call snapshot.ParseGo if all you need --// is a parse tree, or snapshot.MetadataForFile if you only need metadata. +-// Type-checking is expensive. Call snapshot.ParseGo if all you need is a parse +-// tree, or snapshot.MetadataForFile if you only need metadata. -func NarrowestPackageForFile(ctx context.Context, snapshot Snapshot, uri span.URI) (Package, *ParsedGoFile, error) { +- return selectPackageForFile(ctx, snapshot, uri, func(metas []*Metadata) *Metadata { return metas[0] }) +-} +- +-// WidestPackageForFile is a convenience function that selects the widest +-// non-ITV package to which this file belongs, type-checks it in the requested +-// mode (full or workspace), and returns it, along with the parse tree of that +-// file. +-// +-// The "widest" package is the one with the most number of files that includes +-// the given file. Which is the test variant if one exists. +-// +-// An intermediate test variant (ITV) package has identical source to a regular +-// package but resolves imports differently. gopls should never need to +-// type-check them. +-// +-// Type-checking is expensive. Call snapshot.ParseGo if all you need is a parse +-// tree, or snapshot.MetadataForFile if you only need metadata. +-func WidestPackageForFile(ctx context.Context, snapshot Snapshot, uri span.URI) (Package, *ParsedGoFile, error) { +- return selectPackageForFile(ctx, snapshot, uri, func(metas []*Metadata) *Metadata { return metas[len(metas)-1] }) +-} +- +-func selectPackageForFile(ctx context.Context, snapshot Snapshot, uri span.URI, selector func([]*Metadata) *Metadata) (Package, *ParsedGoFile, error) { - metas, err := snapshot.MetadataForFile(ctx, uri) - if err != nil { - return nil, nil, err @@ -98752,8 +99834,8 @@ diff -urN a/gopls/internal/lsp/source/view.go b/gopls/internal/lsp/source/view.g - if len(metas) == 0 { - return nil, nil, fmt.Errorf("no package metadata for file %s", uri) - } -- narrowest := metas[0] -- pkgs, err := snapshot.TypeCheck(ctx, narrowest.ID) +- md := selector(metas) +- pkgs, err := snapshot.TypeCheck(ctx, md.ID) - if err != nil { - return nil, nil, err - } @@ -98794,9 +99876,16 @@ diff -urN a/gopls/internal/lsp/source/view.go b/gopls/internal/lsp/source/view.g - return m&AllowNetwork != 0 -} - --// View represents a single workspace. --// This is the level at which we maintain configuration like working directory --// and build tags. +-// View represents a single build context for a workspace. +-// +-// A unique build is determined by the workspace folder along with a Go +-// environment (GOOS, GOARCH, GOWORK, etc). +-// +-// Additionally, the View holds a pointer to the current state of that build +-// (the Snapshot). +-// +-// TODO(rfindley): move all other state such as module upgrades into the +-// Snapshot. -type View interface { - // ID returns a globally unique identifier for this view. - ID() string @@ -99153,7 +100242,6 @@ diff -urN a/gopls/internal/lsp/source/view.go b/gopls/internal/lsp/source/view.g - Save - Create - Delete -- InvalidateMetadata -) - -func (a FileAction) String() string { @@ -99170,8 +100258,6 @@ diff -urN a/gopls/internal/lsp/source/view.go b/gopls/internal/lsp/source/view.g - return "Create" - case Delete: - return "Delete" -- case InvalidateMetadata: -- return "InvalidateMetadata" - default: - return "Unknown" - } @@ -99478,7 +100564,7 @@ diff -urN a/gopls/internal/lsp/source/view.go b/gopls/internal/lsp/source/view.g -} diff -urN a/gopls/internal/lsp/source/workspace_symbol.go b/gopls/internal/lsp/source/workspace_symbol.go --- a/gopls/internal/lsp/source/workspace_symbol.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/workspace_symbol.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/workspace_symbol.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,611 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -100093,7 +101179,7 @@ diff -urN a/gopls/internal/lsp/source/workspace_symbol.go b/gopls/internal/lsp/s -} diff -urN a/gopls/internal/lsp/source/workspace_symbol_test.go b/gopls/internal/lsp/source/workspace_symbol_test.go --- a/gopls/internal/lsp/source/workspace_symbol_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/workspace_symbol_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/workspace_symbol_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,136 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -100233,7 +101319,7 @@ diff -urN a/gopls/internal/lsp/source/workspace_symbol_test.go b/gopls/internal/ -} diff -urN a/gopls/internal/lsp/source/xrefs/xrefs.go b/gopls/internal/lsp/source/xrefs/xrefs.go --- a/gopls/internal/lsp/source/xrefs/xrefs.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/xrefs/xrefs.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/source/xrefs/xrefs.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,193 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -100430,7 +101516,7 @@ diff -urN a/gopls/internal/lsp/source/xrefs/xrefs.go b/gopls/internal/lsp/source -} diff -urN a/gopls/internal/lsp/symbols.go b/gopls/internal/lsp/symbols.go --- a/gopls/internal/lsp/symbols.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/symbols.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/symbols.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -100494,7 +101580,7 @@ diff -urN a/gopls/internal/lsp/symbols.go b/gopls/internal/lsp/symbols.go -} diff -urN a/gopls/internal/lsp/template/completion.go b/gopls/internal/lsp/template/completion.go --- a/gopls/internal/lsp/template/completion.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/template/completion.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/template/completion.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,287 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -100785,7 +101871,7 @@ diff -urN a/gopls/internal/lsp/template/completion.go b/gopls/internal/lsp/templ -} diff -urN a/gopls/internal/lsp/template/completion_test.go b/gopls/internal/lsp/template/completion_test.go --- a/gopls/internal/lsp/template/completion_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/template/completion_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/template/completion_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,102 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -100891,7 +101977,7 @@ diff -urN a/gopls/internal/lsp/template/completion_test.go b/gopls/internal/lsp/ -} diff -urN a/gopls/internal/lsp/template/highlight.go b/gopls/internal/lsp/template/highlight.go --- a/gopls/internal/lsp/template/highlight.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/template/highlight.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/template/highlight.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -100991,7 +102077,7 @@ diff -urN a/gopls/internal/lsp/template/highlight.go b/gopls/internal/lsp/templa -} diff -urN a/gopls/internal/lsp/template/implementations.go b/gopls/internal/lsp/template/implementations.go --- a/gopls/internal/lsp/template/implementations.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/template/implementations.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/template/implementations.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,189 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -101184,7 +102270,7 @@ diff -urN a/gopls/internal/lsp/template/implementations.go b/gopls/internal/lsp/ -// still need to do rename, etc diff -urN a/gopls/internal/lsp/template/parse.go b/gopls/internal/lsp/template/parse.go --- a/gopls/internal/lsp/template/parse.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/template/parse.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/template/parse.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,508 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -101696,7 +102782,7 @@ diff -urN a/gopls/internal/lsp/template/parse.go b/gopls/internal/lsp/template/p -} diff -urN a/gopls/internal/lsp/template/parse_test.go b/gopls/internal/lsp/template/parse_test.go --- a/gopls/internal/lsp/template/parse_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/template/parse_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/template/parse_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,238 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -101938,7 +103024,7 @@ diff -urN a/gopls/internal/lsp/template/parse_test.go b/gopls/internal/lsp/templ -} diff -urN a/gopls/internal/lsp/template/symbols.go b/gopls/internal/lsp/template/symbols.go --- a/gopls/internal/lsp/template/symbols.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/template/symbols.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/template/symbols.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,230 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -102170,14 +103256,9 @@ diff -urN a/gopls/internal/lsp/template/symbols.go b/gopls/internal/lsp/template - } - return ans, nil -} -diff -urN a/gopls/internal/lsp/testdata/%percent/perc%ent.go b/gopls/internal/lsp/testdata/%percent/perc%ent.go ---- a/gopls/internal/lsp/testdata/%percent/perc%ent.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/%percent/perc%ent.go 1970-01-01 08:00:00 -@@ -1 +0,0 @@ --package percent diff -urN a/gopls/internal/lsp/testdata/addimport/addimport.go.golden b/gopls/internal/lsp/testdata/addimport/addimport.go.golden --- a/gopls/internal/lsp/testdata/addimport/addimport.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/addimport/addimport.go.golden 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/testdata/addimport/addimport.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ --- addimport -- -package addimport //@addimport("", "bytes") @@ -102188,351 +103269,14 @@ diff -urN a/gopls/internal/lsp/testdata/addimport/addimport.go.golden b/gopls/in - diff -urN a/gopls/internal/lsp/testdata/addimport/addimport.go.in b/gopls/internal/lsp/testdata/addimport/addimport.go.in --- a/gopls/internal/lsp/testdata/addimport/addimport.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/addimport/addimport.go.in 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/testdata/addimport/addimport.go.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -package addimport //@addimport("", "bytes") - -func main() {} -diff -urN a/gopls/internal/lsp/testdata/address/address.go b/gopls/internal/lsp/testdata/address/address.go ---- a/gopls/internal/lsp/testdata/address/address.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/address/address.go 1970-01-01 08:00:00 -@@ -1,78 +0,0 @@ --package address -- --func wantsPtr(*int) {} --func wantsVariadicPtr(...*int) {} -- --func wantsVariadic(...int) {} -- --type foo struct{ c int } //@item(addrFieldC, "c", "int", "field") -- --func _() { -- var ( -- a string //@item(addrA, "a", "string", "var") -- b int //@item(addrB, "b", "int", "var") -- ) -- -- wantsPtr() //@rank(")", addrB, addrA),snippet(")", addrB, "&b", "&b") -- wantsPtr(&b) //@snippet(")", addrB, "b", "b") -- -- wantsVariadicPtr() //@rank(")", addrB, addrA),snippet(")", addrB, "&b", "&b") -- -- var s foo -- s.c //@item(addrDeepC, "s.c", "int", "field") -- wantsPtr() //@snippet(")", addrDeepC, "&s.c", "&s.c") -- wantsPtr(s) //@snippet(")", addrDeepC, "&s.c", "&s.c") -- wantsPtr(&s) //@snippet(")", addrDeepC, "s.c", "s.c") -- -- // don't add "&" in item (it gets added as an additional edit) -- wantsPtr(&s.c) //@snippet(")", addrFieldC, "c", "c") -- -- // check dereferencing as well -- var c *int //@item(addrCPtr, "c", "*int", "var") -- var _ int = _ //@rank("_ //", addrCPtr, addrA),snippet("_ //", addrCPtr, "*c", "*c") -- -- wantsVariadic() //@rank(")", addrCPtr, addrA),snippet(")", addrCPtr, "*c", "*c") -- -- var d **int //@item(addrDPtr, "d", "**int", "var") -- var _ int = _ //@rank("_ //", addrDPtr, addrA),snippet("_ //", addrDPtr, "**d", "**d") -- -- type namedPtr *int -- var np namedPtr //@item(addrNamedPtr, "np", "namedPtr", "var") -- -- var _ int = _ //@rank("_ //", addrNamedPtr, addrA) -- -- // don't get tripped up by recursive pointer type -- type dontMessUp *dontMessUp -- var dmu *dontMessUp //@item(addrDMU, "dmu", "*dontMessUp", "var") -- -- var _ int = dmu //@complete(" //", addrDMU) --} -- --func (f foo) ptr() *foo { return &f } -- --func _() { -- getFoo := func() foo { return foo{} } -- -- // not addressable -- getFoo().c //@item(addrGetFooC, "getFoo().c", "int", "field") -- -- // addressable -- getFoo().ptr().c //@item(addrGetFooPtrC, "getFoo().ptr().c", "int", "field") -- -- wantsPtr() //@rank(addrGetFooPtrC, addrGetFooC),snippet(")", addrGetFooPtrC, "&getFoo().ptr().c", "&getFoo().ptr().c") -- wantsPtr(&g) //@rank(addrGetFooPtrC, addrGetFooC),snippet(")", addrGetFooPtrC, "getFoo().ptr().c", "getFoo().ptr().c") --} -- --type nested struct { -- f foo --} -- --func _() { -- getNested := func() nested { return nested{} } -- -- getNested().f.c //@item(addrNestedC, "getNested().f.c", "int", "field") -- getNested().f.ptr().c //@item(addrNestedPtrC, "getNested().f.ptr().c", "int", "field") -- -- // addrNestedC is not addressable, so rank lower -- wantsPtr(getNestedfc) //@fuzzy(")", addrNestedPtrC, addrNestedC) --} -diff -urN a/gopls/internal/lsp/testdata/anon/anon.go.in b/gopls/internal/lsp/testdata/anon/anon.go.in ---- a/gopls/internal/lsp/testdata/anon/anon.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/anon/anon.go.in 1970-01-01 08:00:00 -@@ -1,23 +0,0 @@ --package anon -- --func _() { -- for _, _ := range []struct { -- i, j int //@item(anonI, "i", "int", "field"),item(anonJ, "j", "int", "field") -- }{ -- { -- i: 1, -- //@complete("", anonJ) -- }, -- { -- //@complete("", anonI, anonJ) -- }, -- } { -- continue -- } -- -- s := struct{ f int }{ } //@item(anonF, "f", "int", "field"),item(structS, "s", "struct{...}", "var"),complete(" }", anonF) -- -- _ = map[struct{ x int }]int{ //@item(anonX, "x", "int", "field") -- struct{ x int }{ }: 1, //@complete(" }", anonX, structS) -- } --} -diff -urN a/gopls/internal/lsp/testdata/append/append.go b/gopls/internal/lsp/testdata/append/append.go ---- a/gopls/internal/lsp/testdata/append/append.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/append/append.go 1970-01-01 08:00:00 -@@ -1,38 +0,0 @@ --package append -- --func foo([]string) {} --func bar(...string) {} -- --func _() { -- var ( -- aInt []int //@item(appendInt, "aInt", "[]int", "var") -- aStrings []string //@item(appendStrings, "aStrings", "[]string", "var") -- aString string //@item(appendString, "aString", "string", "var") -- ) -- -- append(aStrings, a) //@rank(")", appendString, appendInt) -- var _ interface{} = append(aStrings, a) //@rank(")", appendString, appendInt) -- var _ []string = append(oops, a) //@rank(")", appendString, appendInt) -- -- foo(append()) //@rank("))", appendStrings, appendInt),rank("))", appendStrings, appendString) -- foo(append([]string{}, a)) //@rank("))", appendStrings, appendInt),rank("))", appendString, appendInt),snippet("))", appendStrings, "aStrings...", "aStrings...") -- foo(append([]string{}, "", a)) //@rank("))", appendString, appendInt),rank("))", appendString, appendStrings) -- -- // Don't add "..." to append() argument. -- bar(append()) //@snippet("))", appendStrings, "aStrings", "aStrings") -- -- type baz struct{} -- baz{} //@item(appendBazLiteral, "baz{}", "", "var") -- var bazzes []baz //@item(appendBazzes, "bazzes", "[]baz", "var") -- var bazzy baz //@item(appendBazzy, "bazzy", "baz", "var") -- bazzes = append(bazzes, ba) //@rank(")", appendBazzy, appendBazLiteral, appendBazzes) -- -- var b struct{ b []baz } -- b.b //@item(appendNestedBaz, "b.b", "[]baz", "field") -- b.b = append(b.b, b) //@rank(")", appendBazzy, appendBazLiteral, appendNestedBaz) -- -- var aStringsPtr *[]string //@item(appendStringsPtr, "aStringsPtr", "*[]string", "var") -- foo(append([]string{}, a)) //@snippet("))", appendStringsPtr, "*aStringsPtr...", "*aStringsPtr...") -- -- foo(append([]string{}, *a)) //@snippet("))", appendStringsPtr, "aStringsPtr...", "aStringsPtr...") --} -diff -urN a/gopls/internal/lsp/testdata/append/append2.go.in b/gopls/internal/lsp/testdata/append/append2.go.in ---- a/gopls/internal/lsp/testdata/append/append2.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/append/append2.go.in 1970-01-01 08:00:00 -@@ -1,5 +0,0 @@ --package append -- --func _() { -- _ = append(a, struct) //@complete(")") --} -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/assign/assign.go.in b/gopls/internal/lsp/testdata/assign/assign.go.in ---- a/gopls/internal/lsp/testdata/assign/assign.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/assign/assign.go.in 1970-01-01 08:00:00 -@@ -1,26 +0,0 @@ --package assign -- --import "golang.org/lsptests/assign/internal/secret" -- --func _() { -- secret.Hello() -- var ( -- myInt int //@item(assignInt, "myInt", "int", "var") -- myStr string //@item(assignStr, "myStr", "string", "var") -- ) -- -- var _ string = my //@rank(" //", assignStr, assignInt) -- var _ string = //@rank(" //", assignStr, assignInt) --} -- --func _() { -- var a string = a //@complete(" //") --} -- --func _() { -- fooBar := fooBa //@complete(" //"),item(assignFooBar, "fooBar", "", "var") -- abc, fooBar := 123, fooBa //@complete(" //", assignFooBar) -- { -- fooBar := fooBa //@complete(" //", assignFooBar) -- } --} -diff -urN a/gopls/internal/lsp/testdata/assign/internal/secret/secret.go b/gopls/internal/lsp/testdata/assign/internal/secret/secret.go ---- a/gopls/internal/lsp/testdata/assign/internal/secret/secret.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/assign/internal/secret/secret.go 1970-01-01 08:00:00 -@@ -1,3 +0,0 @@ --package secret -- --func Hello() {} -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/basiclit/basiclit.go b/gopls/internal/lsp/testdata/basiclit/basiclit.go ---- a/gopls/internal/lsp/testdata/basiclit/basiclit.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/basiclit/basiclit.go 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ --package basiclit -- --func _() { -- var a int // something for lexical completions -- -- _ = "hello." //@complete(".") -- -- _ = 1 //@complete(" //") -- -- _ = 1. //@complete(".") -- -- _ = 'a' //@complete("' ") --} -diff -urN a/gopls/internal/lsp/testdata/builtins/builtin_args.go b/gopls/internal/lsp/testdata/builtins/builtin_args.go ---- a/gopls/internal/lsp/testdata/builtins/builtin_args.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/builtins/builtin_args.go 1970-01-01 08:00:00 -@@ -1,62 +0,0 @@ --package builtins -- --func _() { -- var ( -- aSlice []int //@item(builtinSlice, "aSlice", "[]int", "var") -- aMap map[string]int //@item(builtinMap, "aMap", "map[string]int", "var") -- aString string //@item(builtinString, "aString", "string", "var") -- aArray [0]int //@item(builtinArray, "aArray", "[0]int", "var") -- aArrayPtr *[0]int //@item(builtinArrayPtr, "aArrayPtr", "*[0]int", "var") -- aChan chan int //@item(builtinChan, "aChan", "chan int", "var") -- aPtr *int //@item(builtinPtr, "aPtr", "*int", "var") -- aInt int //@item(builtinInt, "aInt", "int", "var") -- ) -- -- type ( -- aSliceType []int //@item(builtinSliceType, "aSliceType", "[]int", "type") -- aChanType chan int //@item(builtinChanType, "aChanType", "chan int", "type") -- aMapType map[string]int //@item(builtinMapType, "aMapType", "map[string]int", "type") -- ) -- -- close() //@rank(")", builtinChan, builtinSlice) -- -- append() //@rank(")", builtinSlice, builtinChan) -- -- var _ []byte = append([]byte(nil), ""...) //@rank(") //") -- -- copy() //@rank(")", builtinSlice, builtinChan) -- copy(aSlice, aS) //@rank(")", builtinSlice, builtinString) -- copy(aS, aSlice) //@rank(",", builtinSlice, builtinString) -- -- delete() //@rank(")", builtinMap, builtinChan) -- delete(aMap, aS) //@rank(")", builtinString, builtinSlice) -- -- aMapFunc := func() map[int]int { //@item(builtinMapFunc, "aMapFunc", "func() map[int]int", "var") -- return nil -- } -- delete() //@rank(")", builtinMapFunc, builtinSlice) -- -- len() //@rank(")", builtinSlice, builtinInt),rank(")", builtinMap, builtinInt),rank(")", builtinString, builtinInt),rank(")", builtinArray, builtinInt),rank(")", builtinArrayPtr, builtinPtr),rank(")", builtinChan, builtinInt) -- -- cap() //@rank(")", builtinSlice, builtinMap),rank(")", builtinArray, builtinString),rank(")", builtinArrayPtr, builtinPtr),rank(")", builtinChan, builtinInt) -- -- make() //@rank(")", builtinMapType, int),rank(")", builtinChanType, int),rank(")", builtinSliceType, int),rank(")", builtinMapType, int) -- make(aSliceType, a) //@rank(")", builtinInt, builtinSlice) -- -- type myInt int -- var mi myInt //@item(builtinMyInt, "mi", "myInt", "var") -- make(aSliceType, m) //@snippet(")", builtinMyInt, "mi", "mi") -- -- var _ []int = make() //@rank(")", builtinSliceType, builtinMapType) -- -- type myStruct struct{} //@item(builtinStructType, "myStruct", "struct{...}", "struct") -- var _ *myStruct = new() //@rank(")", builtinStructType, int) -- -- for k := range a { //@rank(" {", builtinSlice, builtinInt),rank(" {", builtinString, builtinInt),rank(" {", builtinChan, builtinInt),rank(" {", builtinArray, builtinInt),rank(" {", builtinArrayPtr, builtinInt),rank(" {", builtinMap, builtinInt), -- } -- -- for k, v := range a { //@rank(" {", builtinSlice, builtinChan) -- } -- -- <-a //@rank(" //", builtinChan, builtinInt) --} -diff -urN a/gopls/internal/lsp/testdata/builtins/builtin_types.go b/gopls/internal/lsp/testdata/builtins/builtin_types.go ---- a/gopls/internal/lsp/testdata/builtins/builtin_types.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/builtins/builtin_types.go 1970-01-01 08:00:00 -@@ -1,11 +0,0 @@ --package builtins -- --func _() { -- var _ []bool //@item(builtinBoolSliceType, "[]bool", "[]bool", "type") -- -- var _ []bool = make() //@rank(")", builtinBoolSliceType, int) -- -- var _ []bool = make([], 0) //@rank(",", bool, int) -- -- var _ [][]bool = make([][], 0) //@rank(",", bool, int) --} -diff -urN a/gopls/internal/lsp/testdata/builtins/builtins.go b/gopls/internal/lsp/testdata/builtins/builtins.go ---- a/gopls/internal/lsp/testdata/builtins/builtins.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/builtins/builtins.go 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ --package builtins -- --// Definitions of builtin completion items that are still used in tests. -- --/* bool */ //@item(bool, "bool", "", "type") --/* complex(r float64, i float64) */ //@item(complex, "complex", "func(r float64, i float64) complex128", "func") --/* float32 */ //@item(float32, "float32", "", "type") --/* float64 */ //@item(float64, "float64", "", "type") --/* imag(c complex128) float64 */ //@item(imag, "imag", "func(c complex128) float64", "func") --/* int */ //@item(int, "int", "", "type") --/* iota */ //@item(iota, "iota", "", "const") --/* string */ //@item(string, "string", "", "type") --/* true */ //@item(_true, "true", "", "const") -diff -urN a/gopls/internal/lsp/testdata/builtins/constants.go b/gopls/internal/lsp/testdata/builtins/constants.go ---- a/gopls/internal/lsp/testdata/builtins/constants.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/builtins/constants.go 1970-01-01 08:00:00 -@@ -1,19 +0,0 @@ --package builtins -- --func _() { -- const ( -- foo = iota //@complete(" //", iota) -- ) -- -- iota //@complete(" //") -- -- var iota int //@item(iotaVar, "iota", "int", "var") -- -- iota //@complete(" //", iotaVar) --} -- --func _() { -- var twoRedUpEnd bool //@item(TRUEVar, "twoRedUpEnd", "bool", "var") -- -- var _ bool = true //@rank(" //", _true, TRUEVar) --} diff -urN a/gopls/internal/lsp/testdata/callhierarchy/callhierarchy.go b/gopls/internal/lsp/testdata/callhierarchy/callhierarchy.go --- a/gopls/internal/lsp/testdata/callhierarchy/callhierarchy.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/callhierarchy/callhierarchy.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/testdata/callhierarchy/callhierarchy.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -102606,7 +103350,7 @@ diff -urN a/gopls/internal/lsp/testdata/callhierarchy/callhierarchy.go b/gopls/i -} diff -urN a/gopls/internal/lsp/testdata/callhierarchy/incoming/incoming.go b/gopls/internal/lsp/testdata/callhierarchy/incoming/incoming.go --- a/gopls/internal/lsp/testdata/callhierarchy/incoming/incoming.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/callhierarchy/incoming/incoming.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/testdata/callhierarchy/incoming/incoming.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -102622,7 +103366,7 @@ diff -urN a/gopls/internal/lsp/testdata/callhierarchy/incoming/incoming.go b/gop -} diff -urN a/gopls/internal/lsp/testdata/callhierarchy/outgoing/outgoing.go b/gopls/internal/lsp/testdata/callhierarchy/outgoing/outgoing.go --- a/gopls/internal/lsp/testdata/callhierarchy/outgoing/outgoing.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/callhierarchy/outgoing/outgoing.go 1970-01-01 08:00:00 ++++ b/gopls/internal/lsp/testdata/callhierarchy/outgoing/outgoing.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -102633,12512 +103377,9902 @@ diff -urN a/gopls/internal/lsp/testdata/callhierarchy/outgoing/outgoing.go b/gop -// B is exported to test outgoing calls across packages -func B() { //@mark(outgoingB, "B") -} -diff -urN a/gopls/internal/lsp/testdata/casesensitive/casesensitive.go b/gopls/internal/lsp/testdata/casesensitive/casesensitive.go ---- a/gopls/internal/lsp/testdata/casesensitive/casesensitive.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/casesensitive/casesensitive.go 1970-01-01 08:00:00 -@@ -1,16 +0,0 @@ --// Copyright 2019 The Go Authors. All rights reserved. +diff -urN a/gopls/internal/lsp/testdata/embeddirective/embed.txt b/gopls/internal/lsp/testdata/embeddirective/embed.txt +--- a/gopls/internal/lsp/testdata/embeddirective/embed.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/embeddirective/embed.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1 +0,0 @@ +-text +diff -urN a/gopls/internal/lsp/testdata/embeddirective/fix_import.go b/gopls/internal/lsp/testdata/embeddirective/fix_import.go +--- a/gopls/internal/lsp/testdata/embeddirective/fix_import.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/embeddirective/fix_import.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +-// Copyright 2023 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 casesensitive -- --func _() { -- var lower int //@item(lower, "lower", "int", "var") -- var Upper int //@item(upper, "Upper", "int", "var") -- -- l //@casesensitive(" //", lower) -- U //@casesensitive(" //", upper) +-package embeddirective - -- L //@casesensitive(" //") -- u //@casesensitive(" //") --} -diff -urN a/gopls/internal/lsp/testdata/cast/cast.go.in b/gopls/internal/lsp/testdata/cast/cast.go.in ---- a/gopls/internal/lsp/testdata/cast/cast.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/cast/cast.go.in 1970-01-01 08:00:00 -@@ -1,11 +0,0 @@ --package cast +-import ( +- "io" +- "os" +-) - --func _() { -- foo := struct{x int}{x: 1} //@item(x_field, "x", "int", "field") -- _ = float64(foo.x) //@complete("x", x_field) --} +-//go:embed embed.txt //@suggestedfix("//go:embed", "quickfix", "") +-var t string - --func _() { -- foo := struct{x int}{x: 1} -- _ = float64(foo. //@complete(" /", x_field) +-func unused() { +- _ = os.Stdin +- _ = io.EOF -} -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/channel/channel.go b/gopls/internal/lsp/testdata/channel/channel.go ---- a/gopls/internal/lsp/testdata/channel/channel.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/channel/channel.go 1970-01-01 08:00:00 -@@ -1,25 +0,0 @@ --package channel +diff -urN a/gopls/internal/lsp/testdata/embeddirective/fix_import.go.golden b/gopls/internal/lsp/testdata/embeddirective/fix_import.go.golden +--- a/gopls/internal/lsp/testdata/embeddirective/fix_import.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/embeddirective/fix_import.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,21 +0,0 @@ +--- suggestedfix_fix_import_12_1 -- +-// Copyright 2023 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. - --func _() { -- var ( -- aa = "123" //@item(channelAA, "aa", "string", "var") -- ab = 123 //@item(channelAB, "ab", "int", "var") -- ) +-package embeddirective - -- { -- type myChan chan int -- var mc myChan -- mc <- a //@complete(" //", channelAB, channelAA) -- } +-import ( +- _ "embed" +- "io" +- "os" +-) - -- { -- var ac chan int //@item(channelAC, "ac", "chan int", "var") -- a <- a //@complete(" <-", channelAC, channelAA, channelAB) -- } +-//go:embed embed.txt //@suggestedfix("//go:embed", "quickfix", "") +-var t string - -- { -- var foo chan int //@item(channelFoo, "foo", "chan int", "var") -- wantsInt := func(int) {} //@item(channelWantsInt, "wantsInt", "func(int)", "var") -- wantsInt(<-) //@rank(")", channelFoo, channelAB) -- } +-func unused() { +- _ = os.Stdin +- _ = io.EOF -} -diff -urN a/gopls/internal/lsp/testdata/comment_completion/comment_completion.go.in b/gopls/internal/lsp/testdata/comment_completion/comment_completion.go.in ---- a/gopls/internal/lsp/testdata/comment_completion/comment_completion.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/comment_completion/comment_completion.go.in 1970-01-01 08:00:00 -@@ -1,70 +0,0 @@ --package comment_completion -- --var p bool - --//@complete(re"$") -- --func _() { -- var a int +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go b/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go +--- a/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,27 +0,0 @@ +-package inlayHint //@inlayHint("package") - -- switch a { -- case 1: -- //@complete(re"$") -- _ = a -- } +-import "fmt" - -- var b chan int -- select { -- case <-b: -- //@complete(re"$") -- _ = b +-func fieldNames() { +- for _, c := range []struct { +- in, want string +- }{ +- struct{ in, want string }{"Hello, world", "dlrow ,olleH"}, +- {"Hello, 世界", "界世 ,olleH"}, +- {"", ""}, +- } { +- fmt.Println(c.in == c.want) - } -- -- var ( -- //@complete(re"$") -- _ = a -- ) --} -- --// //@complete(" ", variableC) --var C string //@item(variableC, "C", "string", "var") //@complete(" ", variableC) -- --// //@complete(" ", constant) --const Constant = "example" //@item(constant, "Constant", "string", "const") //@complete(" ", constant) -- --// //@complete(" ", structType, fieldB, fieldA) --type StructType struct { //@item(structType, "StructType", "struct{...}", "struct") //@complete(" ", structType, fieldA, fieldB) -- // //@complete(" ", fieldA, structType, fieldB) -- A string //@item(fieldA, "A", "string", "field") //@complete(" ", fieldA, structType, fieldB) -- b int //@item(fieldB, "b", "int", "field") //@complete(" ", fieldB, structType, fieldA) --} -- --// //@complete(" ", method, structRecv, paramX, resultY, fieldB, fieldA) --func (structType *StructType) Method(X int) (Y int) { //@item(structRecv, "structType", "*StructType", "var"),item(method, "Method", "func(X int) (Y int)", "method"),item(paramX, "X", "int", "var"),item(resultY, "Y", "int", "var") -- // //@complete(" ", method, structRecv, paramX, resultY, fieldB, fieldA) -- return --} -- --// //@complete(" ", newType) --type NewType string //@item(newType, "NewType", "string", "type") //@complete(" ", newType) -- --// //@complete(" ", testInterface, testA, testB) --type TestInterface interface { //@item(testInterface, "TestInterface", "interface{...}", "interface") -- // //@complete(" ", testA, testInterface, testB) -- TestA(L string) (M int) //@item(testA, "TestA", "func(L string) (M int)", "method"),item(paramL, "L", "var", "string"),item(resM, "M", "var", "int") //@complete(" ", testA, testInterface, testB) -- TestB(N int) bool //@item(testB, "TestB", "func(N int) bool", "method"),item(paramN, "N", "var", "int") //@complete(" ", testB, testInterface, testA) --} -- --// //@complete(" ", function) --func Function() int { //@item(function, "Function", "func() int", "func") //@complete(" ", function) -- // //@complete(" ", function) -- return 0 --} -- --// This tests multiline block comments and completion with prefix --// Lorem Ipsum Multili//@complete("Multi", multiline) --// Lorem ipsum dolor sit ametom --func Multiline() int { //@item(multiline, "Multiline", "func() int", "func") -- // //@complete(" ", multiline) -- return 0 --} -diff -urN a/gopls/internal/lsp/testdata/complit/complit.go.in b/gopls/internal/lsp/testdata/complit/complit.go.in ---- a/gopls/internal/lsp/testdata/complit/complit.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/complit/complit.go.in 1970-01-01 08:00:00 -@@ -1,90 +0,0 @@ --package complit -- --// general completions -- --type position struct { //@item(structPosition, "position", "struct{...}", "struct") -- X, Y int //@item(fieldX, "X", "int", "field"),item(fieldY, "Y", "int", "field") -} - --func _() { -- _ = position{ -- //@complete("", fieldX, fieldY, structPosition) -- } -- _ = position{ -- X: 1, -- //@complete("", fieldY) -- } -- _ = position{ -- //@complete("", fieldX) -- Y: 1, -- } -- _ = []*position{ -- { -- //@complete("", fieldX, fieldY, structPosition) -- }, +-func fieldNamesPointers() { +- for _, c := range []*struct { +- in, want string +- }{ +- &struct{ in, want string }{"Hello, world", "dlrow ,olleH"}, +- {"Hello, 世界", "界世 ,olleH"}, +- {"", ""}, +- } { +- fmt.Println(c.in == c.want) - } -} +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go.golden b/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go.golden +--- a/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,29 +0,0 @@ +--- inlayHint -- +-package inlayHint //@inlayHint("package") - --func _() { -- var ( -- aa string //@item(aaVar, "aa", "string", "var") -- ab int //@item(abVar, "ab", "int", "var") -- ) -- -- _ = map[int]int{ -- a: a, //@complete(":", abVar, aaVar),complete(",", abVar, aaVar) -- } +-import "fmt" - -- _ = map[int]int{ -- //@complete("", abVar, aaVar, structPosition) +-func fieldNames() { +- for _< int>, c< struct{in string; want string}> := range []struct { +- in, want string +- }{ +- struct{ in, want string }{"Hello, world", "dlrow ,olleH"}, +- {"Hello, 世界", "界世 ,olleH"}, +- {"", ""}, +- } { +- fmt.Println(c.in == c.want) - } +-} - -- _ = []string{a: ""} //@complete(":", abVar, aaVar) -- _ = [1]string{a: ""} //@complete(":", abVar, aaVar) -- -- _ = position{X: a} //@complete("}", abVar, aaVar) -- _ = position{a} //@complete("}", abVar, aaVar) -- _ = position{a, } //@complete("}", abVar, aaVar, structPosition) -- -- _ = []int{a} //@complete("}", abVar, aaVar) -- _ = [1]int{a} //@complete("}", abVar, aaVar) -- -- type myStruct struct { -- AA int //@item(fieldAA, "AA", "int", "field") -- AB string //@item(fieldAB, "AB", "string", "field") +-func fieldNamesPointers() { +- for _< int>, c< *struct{in string; want string}> := range []*struct { +- in, want string +- }{ +- &struct{ in, want string }{"Hello, world", "dlrow ,olleH"}, +- <&struct{in string; want string}>{"Hello, 世界", "界世 ,olleH"}, +- <&struct{in string; want string}>{"", ""}, +- } { +- fmt.Println(c.in == c.want) - } +-} - -- _ = myStruct{ -- AB: a, //@complete(",", aaVar, abVar) -- } +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/constant_values.go b/gopls/internal/lsp/testdata/inlay_hint/constant_values.go +--- a/gopls/internal/lsp/testdata/inlay_hint/constant_values.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/constant_values.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,45 +0,0 @@ +-package inlayHint //@inlayHint("package") - -- var s myStruct +-const True = true - -- _ = map[int]string{1: "" + s.A} //@complete("}", fieldAB, fieldAA) -- _ = map[int]string{1: (func(i int) string { return "" })(s.A)} //@complete(")}", fieldAA, fieldAB) -- _ = map[int]string{1: func() string { s.A }} //@complete(" }", fieldAA, fieldAB) +-type Kind int - -- _ = position{s.A} //@complete("}", fieldAA, fieldAB) +-const ( +- KindNone Kind = iota +- KindPrint +- KindPrintf +- KindErrorf +-) - -- var X int //@item(varX, "X", "int", "var") -- _ = position{X} //@complete("}", fieldX, varX) --} +-const ( +- u = iota * 4 +- v float64 = iota * 42 +- w = iota * 42 +-) - --func _() { -- type foo struct{} //@item(complitFoo, "foo", "struct{...}", "struct") +-const ( +- a, b = 1, 2 +- c, d +- e, f = 5 * 5, "hello" + "world" +- g, h +- i, j = true, f +-) - -- var _ *foo = &fo{} //@snippet("{", complitFoo, "foo", "foo") -- var _ *foo = fo{} //@snippet("{", complitFoo, "&foo", "&foo") +-// No hint +-const ( +- Int = 3 +- Float = 3.14 +- Bool = true +- Rune = '3' +- Complex = 2.7i +- String = "Hello, world!" +-) - -- struct { a, b *foo }{ -- a: &fo{}, //@rank("{", complitFoo) -- b: fo{}, //@snippet("{", complitFoo, "&foo", "&foo") -- } --} +-var ( +- varInt = 3 +- varFloat = 3.14 +- varBool = true +- varRune = '3' + '4' +- varComplex = 2.7i +- varString = "Hello, world!" +-) +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/constant_values.go.golden b/gopls/internal/lsp/testdata/inlay_hint/constant_values.go.golden +--- a/gopls/internal/lsp/testdata/inlay_hint/constant_values.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/constant_values.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,47 +0,0 @@ +--- inlayHint -- +-package inlayHint //@inlayHint("package") - --func _() { -- _ := position{ -- X: 1, //@complete("X", fieldX),complete(" 1", structPosition) -- Y: , //@complete(":", fieldY),complete(" ,", structPosition) -- } --} -diff -urN a/gopls/internal/lsp/testdata/constant/constant.go b/gopls/internal/lsp/testdata/constant/constant.go ---- a/gopls/internal/lsp/testdata/constant/constant.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/constant/constant.go 1970-01-01 08:00:00 -@@ -1,14 +0,0 @@ --package constant +-const True = true - --const x = 1 //@item(constX, "x", "int", "const") +-type Kind int - -const ( -- a int = iota << 2 //@item(constA, "a", "int", "const") -- b //@item(constB, "b", "int", "const") -- c //@item(constC, "c", "int", "const") +- KindNone Kind = iota< = 0> +- KindPrint< = 1> +- KindPrintf< = 2> +- KindErrorf< = 3> -) - --func _() { -- const y = "hi" //@item(constY, "y", "string", "const") -- //@complete("", constY, constA, constB, constC, constX) --} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_for.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_for.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_for.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_for.go 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --package danglingstmt +-const ( +- u = iota * 4< = 0> +- v float64 = iota * 42< = 42> +- w = iota * 42< = 84> +-) - --func _() { -- for bar //@rank(" //", danglingBar) --} +-const ( +- a, b = 1, 2 +- c, d< = 1, 2> +- e, f = 5 * 5, "hello" + "world"< = 25, "helloworld"> +- g, h< = 25, "helloworld"> +- i, j = true, f< = true, "helloworld"> +-) - --func bar() bool { //@item(danglingBar, "bar", "func() bool", "func") -- return true --} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init.go 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --package danglingstmt +-// No hint +-const ( +- Int = 3 +- Float = 3.14 +- Bool = true +- Rune = '3' +- Complex = 2.7i +- String = "Hello, world!" +-) - --func _() { -- for i := bar //@rank(" //", danglingBar2) --} +-var ( +- varInt = 3 +- varFloat = 3.14 +- varBool = true +- varRune = '3' + '4' +- varComplex = 2.7i +- varString = "Hello, world!" +-) - --func bar2() int { //@item(danglingBar2, "bar2", "func() int", "func") -- return 0 --} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond.go 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --package danglingstmt +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go b/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go +--- a/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,50 +0,0 @@ +-package inlayHint //@inlayHint("package") - --func _() { -- for i := bar3(); i > bar //@rank(" //", danglingBar3) --} +-import "fmt" - --func bar3() int { //@item(danglingBar3, "bar3", "func() int", "func") -- return 0 +-func hello(name string) string { +- return "Hello " + name -} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond_post.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond_post.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond_post.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond_post.go 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --package danglingstmt - --func _() { -- for i := bar4(); i > bar4(); i += bar //@rank(" //", danglingBar4) +-func helloWorld() string { +- return hello("World") -} - --func bar4() int { //@item(danglingBar4, "bar4", "func() int", "func") -- return 0 --} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_if.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_if.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_if.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_if.go 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --package danglingstmt +-type foo struct{} - --func _() { -- if foo //@rank(" //", danglingFoo) +-func (*foo) bar(baz string, qux int) int { +- if baz != "" { +- return qux + 1 +- } +- return qux -} - --func foo() bool { //@item(danglingFoo, "foo", "func() bool", "func") -- return true +-func kase(foo int, bar bool, baz ...string) { +- fmt.Println(foo, bar, baz) -} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_eof.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_eof.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_eof.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_eof.go 1970-01-01 08:00:00 -@@ -1,8 +0,0 @@ --package danglingstmt - --func bar5() bool { //@item(danglingBar5, "bar5", "func() bool", "func") -- return true +-func kipp(foo string, bar, baz string) { +- fmt.Println(foo, bar, baz) -} - --func _() { -- if b //@rank(" //", danglingBar5) -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init.go 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --package danglingstmt -- --func _() { -- if i := foo //@rank(" //", danglingFoo2) +-func plex(foo, bar string, baz string) { +- fmt.Println(foo, bar, baz) -} - --func foo2() bool { //@item(danglingFoo2, "foo2", "func() bool", "func") -- return true +-func tars(foo string, bar, baz string) { +- fmt.Println(foo, bar, baz) -} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init_cond.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init_cond.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init_cond.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init_cond.go 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --package danglingstmt - --func _() { -- if i := 123; foo //@rank(" //", danglingFoo3) --} +-func foobar() { +- var x foo +- x.bar("", 1) +- kase(0, true, "c", "d", "e") +- kipp("a", "b", "c") +- plex("a", "b", "c") +- tars("a", "b", "c") +- foo, bar, baz := "a", "b", "c" +- kipp(foo, bar, baz) +- plex("a", bar, baz) +- tars(foo+foo, (bar), "c") - --func foo3() bool { //@item(danglingFoo3, "foo3", "func() bool", "func") -- return true -} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_multiline_if.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_multiline_if.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_multiline_if.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_multiline_if.go 1970-01-01 08:00:00 -@@ -1,10 +0,0 @@ --package danglingstmt +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go.golden b/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go.golden +--- a/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,52 +0,0 @@ +--- inlayHint -- +-package inlayHint //@inlayHint("package") - --func walrus() bool { //@item(danglingWalrus, "walrus", "func() bool", "func") -- return true --} +-import "fmt" - --func _() { -- if true && -- walrus //@complete(" //", danglingWalrus) +-func hello(name string) string { +- return "Hello " + name -} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_1.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_1.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_1.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_1.go 1970-01-01 08:00:00 -@@ -1,7 +0,0 @@ --package danglingstmt - --func _() { -- x. //@rank(" //", danglingI) +-func helloWorld() string { +- return hello("World") -} - --var x struct { i int } //@item(danglingI, "i", "int", "field") -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_2.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_2.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_2.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_2.go 1970-01-01 08:00:00 -@@ -1,10 +0,0 @@ --package danglingstmt -- --// TODO: re-enable this test, which was broken when the foo package was removed. --// (we can replicate the relevant definitions in the new marker test) --// import "golang.org/lsptests/foo" +-type foo struct{} - --func _() { -- foo. // rank(" //", Foo) -- var _ = []string{foo.} // rank("}", Foo) +-func (*foo) bar(baz string, qux int) int { +- if baz != "" { +- return qux + 1 +- } +- return qux -} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init.go 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --package danglingstmt - --func _() { -- switch i := baz //@rank(" //", danglingBaz) +-func kase(foo int, bar bool, baz ...string) { +- fmt.Println(foo, bar, baz) -} - --func baz() int { //@item(danglingBaz, "baz", "func() int", "func") -- return 0 +-func kipp(foo string, bar, baz string) { +- fmt.Println(foo, bar, baz) -} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init_tag.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init_tag.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init_tag.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init_tag.go 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --package danglingstmt - --func _() { -- switch i := 0; baz //@rank(" //", danglingBaz2) +-func plex(foo, bar string, baz string) { +- fmt.Println(foo, bar, baz) -} - --func baz2() int { //@item(danglingBaz2, "baz2", "func() int", "func") -- return 0 +-func tars(foo string, bar, baz string) { +- fmt.Println(foo, bar, baz) -} -diff -urN a/gopls/internal/lsp/testdata/deep/deep.go b/gopls/internal/lsp/testdata/deep/deep.go ---- a/gopls/internal/lsp/testdata/deep/deep.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/deep/deep.go 1970-01-01 08:00:00 -@@ -1,142 +0,0 @@ --package deep - --import "context" +-func foobar() { +- var x foo +- x.bar("", 1) +- kase(0, true, "c", "d", "e") +- kipp("a", "b", "c") +- plex("a", "b", "c") +- tars("a", "b", "c") +- foo< string>, bar< string>, baz< string> := "a", "b", "c" +- kipp(foo, bar, baz) +- plex("a", bar, baz) +- tars(foo+foo, (bar), "c") - --type deepA struct { -- b deepB //@item(deepBField, "b", "deepB", "field") -} - --type deepB struct { --} +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/type_params.go b/gopls/internal/lsp/testdata/inlay_hint/type_params.go +--- a/gopls/internal/lsp/testdata/inlay_hint/type_params.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/type_params.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,45 +0,0 @@ +-//go:build go1.18 +-// +build go1.18 - --func wantsDeepB(deepB) {} +-package inlayHint //@inlayHint("package") - --func _() { -- var a deepA //@item(deepAVar, "a", "deepA", "var") -- a.b //@item(deepABField, "a.b", "deepB", "field") -- wantsDeepB(a) //@deep(")", deepABField, deepAVar) +-func main() { +- ints := map[string]int64{ +- "first": 34, +- "second": 12, +- } - -- deepA{a} //@snippet("}", deepABField, "a.b", "a.b") --} +- floats := map[string]float64{ +- "first": 35.98, +- "second": 26.99, +- } - --func wantsContext(context.Context) {} +- SumIntsOrFloats[string, int64](ints) +- SumIntsOrFloats[string, float64](floats) - --func _() { -- context.Background() //@item(ctxBackground, "context.Background", "func() context.Context", "func", "Background returns a non-nil, empty Context.") -- context.TODO() //@item(ctxTODO, "context.TODO", "func() context.Context", "func", "TODO returns a non-nil, empty Context.") +- SumIntsOrFloats(ints) +- SumIntsOrFloats(floats) - -- wantsContext(c) //@rank(")", ctxBackground),rank(")", ctxTODO) +- SumNumbers(ints) +- SumNumbers(floats) -} - --func _() { -- var cork struct{ err error } -- cork.err //@item(deepCorkErr, "cork.err", "error", "field") -- context //@item(deepContextPkg, "context", "\"context\"", "package") -- var _ error = co //@rank(" //", deepCorkErr, deepContextPkg) +-type Number interface { +- int64 | float64 -} - --func _() { -- // deepCircle is circular. -- type deepCircle struct { -- *deepCircle +-func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V { +- var s V +- for _, v := range m { +- s += v - } -- var circle deepCircle //@item(deepCircle, "circle", "deepCircle", "var") -- circle.deepCircle //@item(deepCircleField, "circle.deepCircle", "*deepCircle", "field") -- var _ deepCircle = circ //@deep(" //", deepCircle, deepCircleField),snippet(" //", deepCircleField, "*circle.deepCircle", "*circle.deepCircle") +- return s -} - --func _() { -- type deepEmbedC struct { -- } -- type deepEmbedB struct { -- deepEmbedC -- } -- type deepEmbedA struct { -- deepEmbedB +-func SumNumbers[K comparable, V Number](m map[K]V) V { +- var s V +- for _, v := range m { +- s += v - } -- -- wantsC := func(deepEmbedC) {} -- -- var a deepEmbedA //@item(deepEmbedA, "a", "deepEmbedA", "var") -- a.deepEmbedB //@item(deepEmbedB, "a.deepEmbedB", "deepEmbedB", "field") -- a.deepEmbedC //@item(deepEmbedC, "a.deepEmbedC", "deepEmbedC", "field") -- wantsC(a) //@deep(")", deepEmbedC, deepEmbedA, deepEmbedB) +- return s -} +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/type_params.go.golden b/gopls/internal/lsp/testdata/inlay_hint/type_params.go.golden +--- a/gopls/internal/lsp/testdata/inlay_hint/type_params.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/type_params.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,47 +0,0 @@ +--- inlayHint -- +-//go:build go1.18 +-// +build go1.18 - --func _() { -- type nested struct { -- a int -- n *nested //@item(deepNestedField, "n", "*nested", "field") -- } +-package inlayHint //@inlayHint("package") - -- nested{ -- a: 123, //@deep(" //", deepNestedField) +-func main() { +- ints< map[string]int64> := map[string]int64{ +- "first": 34, +- "second": 12, - } --} - --func _() { -- var a struct { -- b struct { -- c int -- } -- d int +- floats< map[string]float64> := map[string]float64{ +- "first": 35.98, +- "second": 26.99, - } - -- a.d //@item(deepAD, "a.d", "int", "field") -- a.b.c //@item(deepABC, "a.b.c", "int", "field") -- a.b //@item(deepAB, "a.b", "struct{...}", "field") -- a //@item(deepA, "a", "struct{...}", "var") +- SumIntsOrFloats[string, int64](ints) +- SumIntsOrFloats[string, float64](floats) - -- // "a.d" should be ranked above the deeper "a.b.c" -- var i int -- i = a //@deep(" //", deepAD, deepABC, deepA, deepAB) +- SumIntsOrFloats<[string, int64]>(ints) +- SumIntsOrFloats<[string, float64]>(floats) +- +- SumNumbers<[string, int64]>(ints) +- SumNumbers<[string, float64]>(floats) -} - --type foo struct { -- b bar +-type Number interface { +- int64 | float64 -} - --func (f foo) bar() bar { -- return f.b +-func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V { +- var s V +- for _< K>, v< V> := range m { +- s += v +- } +- return s -} - --func (f foo) barPtr() *bar { -- return &f.b +-func SumNumbers[K comparable, V Number](m map[K]V) V { +- var s V +- for _< K>, v< V> := range m { +- s += v +- } +- return s -} - --type bar struct{} +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/variable_types.go b/gopls/internal/lsp/testdata/inlay_hint/variable_types.go +--- a/gopls/internal/lsp/testdata/inlay_hint/variable_types.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/variable_types.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,20 +0,0 @@ +-package inlayHint //@inlayHint("package") - --func (b bar) valueReceiver() int { -- return 0 +-func assignTypes() { +- i, j := 0, len([]string{})-1 +- println(i, j) -} - --func (b *bar) ptrReceiver() int { -- return 0 +-func rangeTypes() { +- for k, v := range []string{} { +- println(k, v) +- } -} - --func _() { -- var ( -- i int -- f foo -- ) +-func funcLitType() { +- myFunc := func(a string) string { return "" } +-} - -- f.bar().valueReceiver //@item(deepBarValue, "f.bar().valueReceiver", "func() int", "method") -- f.barPtr().ptrReceiver //@item(deepBarPtrPtr, "f.barPtr().ptrReceiver", "func() int", "method") -- f.barPtr().valueReceiver //@item(deepBarPtrValue, "f.barPtr().valueReceiver", "func() int", "method") +-func compositeLitType() { +- foo := map[string]interface{}{"": ""} +-} +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/variable_types.go.golden b/gopls/internal/lsp/testdata/inlay_hint/variable_types.go.golden +--- a/gopls/internal/lsp/testdata/inlay_hint/variable_types.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/variable_types.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,22 +0,0 @@ +--- inlayHint -- +-package inlayHint //@inlayHint("package") - -- i = fbar //@fuzzy(" //", deepBarValue, deepBarPtrPtr, deepBarPtrValue) +-func assignTypes() { +- i< int>, j< int> := 0, len([]string{})-1 +- println(i, j) -} - --func (b baz) Thing() struct{ val int } { -- return b.thing +-func rangeTypes() { +- for k< int>, v< string> := range []string{} { +- println(k, v) +- } -} - --type baz struct { -- thing struct{ val int } +-func funcLitType() { +- myFunc< func(a string) string> := func(a string) string { return "" } -} - --func (b baz) _() { -- b.Thing().val //@item(deepBazMethVal, "b.Thing().val", "int", "field") -- b.thing.val //@item(deepBazFieldVal, "b.thing.val", "int", "field") -- var _ int = bval //@rank(" //", deepBazFieldVal, deepBazMethVal) +-func compositeLitType() { +- foo< map[string]interface{}> := map[string]interface{}{"": ""} -} -diff -urN a/gopls/internal/lsp/testdata/embeddirective/embed.txt b/gopls/internal/lsp/testdata/embeddirective/embed.txt ---- a/gopls/internal/lsp/testdata/embeddirective/embed.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/embeddirective/embed.txt 1970-01-01 08:00:00 -@@ -1 +0,0 @@ --text -diff -urN a/gopls/internal/lsp/testdata/embeddirective/fix_import.go b/gopls/internal/lsp/testdata/embeddirective/fix_import.go ---- a/gopls/internal/lsp/testdata/embeddirective/fix_import.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/embeddirective/fix_import.go 1970-01-01 08:00:00 -@@ -1,18 +0,0 @@ --// Copyright 2023 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 embeddirective +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go b/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go +--- a/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +-package invertifcondition - -import ( -- "io" +- "fmt" - "os" -) - --//go:embed embed.txt //@suggestedfix("//go:embed", "quickfix", "") --var t string -- --func unused() { -- _ = os.Stdin -- _ = io.EOF +-func BooleanFn() { +- if os.IsPathSeparator('X') { //@suggestedfix("if os.IsPathSeparator('X')", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } -} -diff -urN a/gopls/internal/lsp/testdata/embeddirective/fix_import.go.golden b/gopls/internal/lsp/testdata/embeddirective/fix_import.go.golden ---- a/gopls/internal/lsp/testdata/embeddirective/fix_import.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/embeddirective/fix_import.go.golden 1970-01-01 08:00:00 -@@ -1,21 +0,0 @@ ---- suggestedfix_fix_import_12_1 -- --// Copyright 2023 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 embeddirective +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go.golden b/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +--- suggestedfix_boolean_fn_9_2 -- +-package invertifcondition - -import ( -- _ "embed" -- "io" +- "fmt" - "os" -) - --//go:embed embed.txt //@suggestedfix("//go:embed", "quickfix", "") --var t string -- --func unused() { -- _ = os.Stdin -- _ = io.EOF +-func BooleanFn() { +- if !os.IsPathSeparator('X') { +- fmt.Println("B") +- } else { //@suggestedfix("if os.IsPathSeparator('X')", "refactor.rewrite", "") +- fmt.Println("A") +- } -} - -diff -urN a/gopls/internal/lsp/testdata/errors/errors.go b/gopls/internal/lsp/testdata/errors/errors.go ---- a/gopls/internal/lsp/testdata/errors/errors.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/errors/errors.go 1970-01-01 08:00:00 -@@ -1,10 +0,0 @@ --package errors +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/boolean.go b/gopls/internal/lsp/testdata/invertifcondition/boolean.go +--- a/gopls/internal/lsp/testdata/invertifcondition/boolean.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/boolean.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +-package invertifcondition - -import ( -- "golang.org/lsptests/types" +- "fmt" -) - --func _() { -- bob.Bob() //@complete(".") -- types.b //@complete(" //", Bob_interface) +-func Boolean() { +- b := true +- if b { //@suggestedfix("if b", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go b/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go ---- a/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go 1970-01-01 08:00:00 -@@ -1,24 +0,0 @@ --package extract +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/boolean.go.golden b/gopls/internal/lsp/testdata/invertifcondition/boolean.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/boolean.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/boolean.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +--- suggestedfix_boolean_9_2 -- +-package invertifcondition - --type A struct { -- x int -- y int --} +-import ( +- "fmt" +-) - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func Boolean() { +- b := true +- if !b { +- fmt.Println("B") +- } else { //@suggestedfix("if b", "refactor.rewrite", "") +- fmt.Println("A") +- } -} - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go b/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go +--- a/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +-package invertifcondition - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +-import ( +- "fmt" +-) - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-func DontRemoveParens() { +- a := false +- b := true +- if !(a || +- b) { //@suggestedfix("b", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go.golden b/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go.golden 1970-01-01 08:00:00 -@@ -1,364 +0,0 @@ ---- functionextraction_extract_basic_13_2 -- --package extract +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go.golden b/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +--- suggestedfix_dont_remove_parens_11_3 -- +-package invertifcondition - --type A struct { -- x int -- y int --} +-import ( +- "fmt" +-) - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func DontRemoveParens() { +- a := false +- b := true +- if (a || +- b) { +- fmt.Println("B") +- } else { //@suggestedfix("b", "refactor.rewrite", "") +- fmt.Println("A") +- } -} - --func (a *A) AddP() int { -- sum := newFunction(a) //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/else_if.go b/gopls/internal/lsp/testdata/invertifcondition/else_if.go +--- a/gopls/internal/lsp/testdata/invertifcondition/else_if.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/else_if.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,22 +0,0 @@ +-package invertifcondition - --func newFunction(a *A) int { -- sum := a.x + a.y -- return sum --} +-import ( +- "fmt" +- "os" +-) - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +-func ElseIf() { +- // No inversion expected when there's not else clause +- if len(os.Args) > 2 { +- fmt.Println("A") +- } - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +- // No inversion expected for else-if, that would become unreadable +- if len(os.Args) > 2 { +- fmt.Println("A") +- } else if os.Args[0] == "X" { //@suggestedfix(re"if os.Args.0. == .X.", "refactor.rewrite", "") +- fmt.Println("B") +- } else { +- fmt.Println("C") +- } -} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/else_if.go.golden b/gopls/internal/lsp/testdata/invertifcondition/else_if.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/else_if.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/else_if.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,24 +0,0 @@ +--- suggestedfix_else_if_17_9 -- +-package invertifcondition - ---- functionextraction_extract_basic_14_2 -- --package extract -- --type A struct { -- x int -- y int --} +-import ( +- "fmt" +- "os" +-) - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +-func ElseIf() { +- // No inversion expected when there's not else clause +- if len(os.Args) > 2 { +- fmt.Println("A") +- } - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return newFunction(sum) //@extractmethod("return", "sum"),extractfunc("return", "sum") +- // No inversion expected for else-if, that would become unreadable +- if len(os.Args) > 2 { +- fmt.Println("A") +- } else if os.Args[0] != "X" { +- fmt.Println("C") +- } else { //@suggestedfix(re"if os.Args.0. == .X.", "refactor.rewrite", "") +- fmt.Println("B") +- } -} - --func newFunction(sum int) int { -- return sum --} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/greater_than.go b/gopls/internal/lsp/testdata/invertifcondition/greater_than.go +--- a/gopls/internal/lsp/testdata/invertifcondition/greater_than.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/greater_than.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +-package invertifcondition - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +-import ( +- "fmt" +- "os" +-) - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-func GreaterThan() { +- if len(os.Args) > 2 { //@suggestedfix("i", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } -} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/greater_than.go.golden b/gopls/internal/lsp/testdata/invertifcondition/greater_than.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/greater_than.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/greater_than.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +--- suggestedfix_greater_than_9_2 -- +-package invertifcondition - ---- functionextraction_extract_basic_18_2 -- --package extract +-import ( +- "fmt" +- "os" +-) - --type A struct { -- x int -- y int +-func GreaterThan() { +- if len(os.Args) <= 2 { +- fmt.Println("B") +- } else { //@suggestedfix("i", "refactor.rewrite", "") +- fmt.Println("A") +- } -} - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go b/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go +--- a/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +-package invertifcondition - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +-import ( +- "fmt" +-) - --func (a A) XLessThanY() bool { -- return newFunction(a) //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func NotBoolean() { +- b := true +- if !b { //@suggestedfix("if !b", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } -} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go.golden b/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +--- suggestedfix_not_boolean_9_2 -- +-package invertifcondition - --func newFunction(a A) bool { -- return a.x < a.y --} +-import ( +- "fmt" +-) - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-func NotBoolean() { +- b := true +- if b { +- fmt.Println("B") +- } else { //@suggestedfix("if !b", "refactor.rewrite", "") +- fmt.Println("A") +- } -} - ---- functionextraction_extract_basic_22_2 -- --package extract -- --type A struct { -- x int -- y int --} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/remove_else.go b/gopls/internal/lsp/testdata/invertifcondition/remove_else.go +--- a/gopls/internal/lsp/testdata/invertifcondition/remove_else.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/remove_else.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +-package invertifcondition - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +-import ( +- "fmt" +-) - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +-func RemoveElse() { +- if true { //@suggestedfix("if true", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- return +- } - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +- fmt.Println("C") -} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/remove_else.go.golden b/gopls/internal/lsp/testdata/invertifcondition/remove_else.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/remove_else.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/remove_else.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,19 +0,0 @@ +--- suggestedfix_remove_else_8_2 -- +-package invertifcondition - --func (a A) Add() int { -- sum := newFunction(a) //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +-import ( +- "fmt" +-) - --func newFunction(a A) int { -- sum := a.x + a.y -- return sum --} +-func RemoveElse() { +- if false { +- fmt.Println("B") +- return +- } - ---- functionextraction_extract_basic_23_2 -- --package extract +- //@suggestedfix("if true", "refactor.rewrite", "") +- fmt.Println("A") - --type A struct { -- x int -- y int +- fmt.Println("C") -} - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go b/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go +--- a/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +-package invertifcondition - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +-import ( +- "fmt" +-) - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func RemoveParens() { +- b := true +- if !(b) { //@suggestedfix("if", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } -} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go.golden b/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +--- suggestedfix_remove_parens_9_2 -- +-package invertifcondition - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return newFunction(sum) //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +-import ( +- "fmt" +-) - --func newFunction(sum int) int { -- return sum +-func RemoveParens() { +- b := true +- if b { +- fmt.Println("B") +- } else { //@suggestedfix("if", "refactor.rewrite", "") +- fmt.Println("A") +- } -} - ---- functionextraction_extract_basic_9_2 -- --package extract -- --type A struct { -- x int -- y int --} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go b/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go +--- a/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package invertifcondition - --func (a *A) XLessThanYP() bool { -- return newFunction(a) //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +-import ( +- "fmt" +-) - --func newFunction(a *A) bool { -- return a.x < a.y +-func SemicolonAnd() { +- if n, err := fmt.Println("x"); err != nil && n > 0 { //@suggestedfix("f", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } -} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go.golden b/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +--- suggestedfix_semicolon_and_8_3 -- +-package invertifcondition - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +-import ( +- "fmt" +-) - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func SemicolonAnd() { +- if n, err := fmt.Println("x"); err == nil || n <= 0 { +- fmt.Println("B") +- } else { //@suggestedfix("f", "refactor.rewrite", "") +- fmt.Println("A") +- } -} - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon.go b/gopls/internal/lsp/testdata/invertifcondition/semicolon.go +--- a/gopls/internal/lsp/testdata/invertifcondition/semicolon.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package invertifcondition - ---- methodextraction_extract_basic_13_2 -- --package extract +-import ( +- "fmt" +-) - --type A struct { -- x int -- y int +-func Semicolon() { +- if _, err := fmt.Println("x"); err != nil { //@suggestedfix("if", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } -} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon.go.golden b/gopls/internal/lsp/testdata/invertifcondition/semicolon.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/semicolon.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +--- suggestedfix_semicolon_8_2 -- +-package invertifcondition - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +-import ( +- "fmt" +-) - --func (a *A) AddP() int { -- sum := a.newMethod() //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-func Semicolon() { +- if _, err := fmt.Println("x"); err == nil { +- fmt.Println("B") +- } else { //@suggestedfix("if", "refactor.rewrite", "") +- fmt.Println("A") +- } -} - --func (a *A) newMethod() int { -- sum := a.x + a.y -- return sum --} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go b/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go +--- a/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package invertifcondition - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +-import ( +- "fmt" +-) - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-func SemicolonOr() { +- if n, err := fmt.Println("x"); err != nil || n < 5 { //@suggestedfix(re"if n, err := fmt.Println..x..; err != nil .. n < 5", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } -} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go.golden b/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +--- suggestedfix_semicolon_or_8_2 -- +-package invertifcondition - ---- methodextraction_extract_basic_14_2 -- --package extract -- --type A struct { -- x int -- y int --} +-import ( +- "fmt" +-) - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func SemicolonOr() { +- if n, err := fmt.Println("x"); err == nil && n >= 5 { +- fmt.Println("B") +- } else { //@suggestedfix(re"if n, err := fmt.Println..x..; err != nil .. n < 5", "refactor.rewrite", "") +- fmt.Println("A") +- } -} - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return a.newMethod(sum) //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/channels.go b/gopls/internal/lsp/testdata/missingfunction/channels.go +--- a/gopls/internal/lsp/testdata/missingfunction/channels.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/channels.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package missingfunction - --func (*A) newMethod(sum int) int { -- return sum +-func channels(s string) { +- undefinedChannels(c()) //@suggestedfix("undefinedChannels", "quickfix", "") -} - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func c() (<-chan string, chan string) { +- return make(<-chan string), make(chan string) -} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/channels.go.golden b/gopls/internal/lsp/testdata/missingfunction/channels.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/channels.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/channels.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +--- suggestedfix_channels_4_2 -- +-package missingfunction - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-func channels(s string) { +- undefinedChannels(c()) //@suggestedfix("undefinedChannels", "quickfix", "") -} - ---- methodextraction_extract_basic_18_2 -- --package extract -- --type A struct { -- x int -- y int +-func undefinedChannels(ch1 <-chan string, ch2 chan string) { +- panic("unimplemented") -} - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func c() (<-chan string, chan string) { +- return make(<-chan string), make(chan string) -} - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go b/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go +--- a/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,6 +0,0 @@ +-package missingfunction - --func (a A) XLessThanY() bool { -- return a.newMethod() //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func consecutiveParams() { +- var s string +- undefinedConsecutiveParams(s, s) //@suggestedfix("undefinedConsecutiveParams", "quickfix", "") -} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go.golden b/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +--- suggestedfix_consecutive_params_5_2 -- +-package missingfunction - --func (a A) newMethod() bool { -- return a.x < a.y +-func consecutiveParams() { +- var s string +- undefinedConsecutiveParams(s, s) //@suggestedfix("undefinedConsecutiveParams", "quickfix", "") -} - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-func undefinedConsecutiveParams(s1, s2 string) { +- panic("unimplemented") -} - ---- methodextraction_extract_basic_22_2 -- --package extract +diff -urN a/gopls/internal/lsp/testdata/missingfunction/error_param.go b/gopls/internal/lsp/testdata/missingfunction/error_param.go +--- a/gopls/internal/lsp/testdata/missingfunction/error_param.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/error_param.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,6 +0,0 @@ +-package missingfunction - --type A struct { -- x int -- y int +-func errorParam() { +- var err error +- undefinedErrorParam(err) //@suggestedfix("undefinedErrorParam", "quickfix", "") -} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/error_param.go.golden b/gopls/internal/lsp/testdata/missingfunction/error_param.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/error_param.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/error_param.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +--- suggestedfix_error_param_5_2 -- +-package missingfunction - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func errorParam() { +- var err error +- undefinedErrorParam(err) //@suggestedfix("undefinedErrorParam", "quickfix", "") -} - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-func undefinedErrorParam(err error) { +- panic("unimplemented") -} - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/literals.go b/gopls/internal/lsp/testdata/missingfunction/literals.go +--- a/gopls/internal/lsp/testdata/missingfunction/literals.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/literals.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package missingfunction - --func (a A) Add() int { -- sum := a.newMethod() //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +-type T struct{} - --func (a A) newMethod() int { -- sum := a.x + a.y -- return sum +-func literals() { +- undefinedLiterals("hey compiler", T{}, &T{}) //@suggestedfix("undefinedLiterals", "quickfix", "") -} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/literals.go.golden b/gopls/internal/lsp/testdata/missingfunction/literals.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/literals.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/literals.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +--- suggestedfix_literals_6_2 -- +-package missingfunction - ---- methodextraction_extract_basic_23_2 -- --package extract -- --type A struct { -- x int -- y int --} +-type T struct{} - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func literals() { +- undefinedLiterals("hey compiler", T{}, &T{}) //@suggestedfix("undefinedLiterals", "quickfix", "") -} - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-func undefinedLiterals(s string, t1 T, t2 *T) { +- panic("unimplemented") -} - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/operation.go b/gopls/internal/lsp/testdata/missingfunction/operation.go +--- a/gopls/internal/lsp/testdata/missingfunction/operation.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/operation.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package missingfunction - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return a.newMethod(sum) //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +-import "time" - --func (A) newMethod(sum int) int { -- return sum +-func operation() { +- undefinedOperation(10 * time.Second) //@suggestedfix("undefinedOperation", "quickfix", "") -} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/operation.go.golden b/gopls/internal/lsp/testdata/missingfunction/operation.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/operation.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/operation.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +--- suggestedfix_operation_6_2 -- +-package missingfunction - ---- methodextraction_extract_basic_9_2 -- --package extract +-import "time" - --type A struct { -- x int -- y int +-func operation() { +- undefinedOperation(10 * time.Second) //@suggestedfix("undefinedOperation", "quickfix", "") -} - --func (a *A) XLessThanYP() bool { -- return a.newMethod() //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func undefinedOperation(duration time.Duration) { +- panic("unimplemented") -} - --func (a *A) newMethod() bool { -- return a.x < a.y --} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/selector.go b/gopls/internal/lsp/testdata/missingfunction/selector.go +--- a/gopls/internal/lsp/testdata/missingfunction/selector.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/selector.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,6 +0,0 @@ +-package missingfunction - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-func selector() { +- m := map[int]bool{} +- undefinedSelector(m[1]) //@suggestedfix("undefinedSelector", "quickfix", "") -} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/selector.go.golden b/gopls/internal/lsp/testdata/missingfunction/selector.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/selector.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/selector.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +--- suggestedfix_selector_5_2 -- +-package missingfunction - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func selector() { +- m := map[int]bool{} +- undefinedSelector(m[1]) //@suggestedfix("undefinedSelector", "quickfix", "") -} - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-func undefinedSelector(b bool) { +- panic("unimplemented") -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_method/extract_context.go b/gopls/internal/lsp/testdata/extract/extract_method/extract_context.go ---- a/gopls/internal/lsp/testdata/extract/extract_method/extract_context.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_method/extract_context.go 1970-01-01 08:00:00 -@@ -1,20 +0,0 @@ --package extract -- --import "context" +diff -urN a/gopls/internal/lsp/testdata/missingfunction/slice.go b/gopls/internal/lsp/testdata/missingfunction/slice.go +--- a/gopls/internal/lsp/testdata/missingfunction/slice.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/slice.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,5 +0,0 @@ +-package missingfunction - --type B struct { -- x int -- y int +-func slice() { +- undefinedSlice([]int{1, 2}) //@suggestedfix("undefinedSlice", "quickfix", "") -} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/slice.go.golden b/gopls/internal/lsp/testdata/missingfunction/slice.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/slice.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/slice.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +--- suggestedfix_slice_4_2 -- +-package missingfunction - --func (b *B) AddP(ctx context.Context) (int, error) { -- sum := b.x + b.y -- return sum, ctx.Err() //@extractmethod("return", "ctx.Err()"),extractfunc("return", "ctx.Err()") +-func slice() { +- undefinedSlice([]int{1, 2}) //@suggestedfix("undefinedSlice", "quickfix", "") -} - --func (b *B) LongList(ctx context.Context) (int, error) { -- p1 := 1 -- p2 := 1 -- p3 := 1 -- return p1 + p2 + p3, ctx.Err() //@extractmethod("return", "ctx.Err()"),extractfunc("return", "ctx.Err()") +-func undefinedSlice(i []int) { +- panic("unimplemented") -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_method/extract_context.go.golden b/gopls/internal/lsp/testdata/extract/extract_method/extract_context.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_method/extract_context.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_method/extract_context.go.golden 1970-01-01 08:00:00 -@@ -1,52 +0,0 @@ ---- methodextraction_extract_context_12_2 -- --package extract - --import "context" +diff -urN a/gopls/internal/lsp/testdata/missingfunction/tuple.go b/gopls/internal/lsp/testdata/missingfunction/tuple.go +--- a/gopls/internal/lsp/testdata/missingfunction/tuple.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/tuple.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package missingfunction - --type B struct { -- x int -- y int +-func tuple() { +- undefinedTuple(b()) //@suggestedfix("undefinedTuple", "quickfix", "") -} - --func (b *B) AddP(ctx context.Context) (int, error) { -- sum := b.x + b.y -- return b.newMethod(ctx, sum) //@extractmethod("return", "ctx.Err()"),extractfunc("return", "ctx.Err()") +-func b() (string, error) { +- return "", nil -} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/tuple.go.golden b/gopls/internal/lsp/testdata/missingfunction/tuple.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/tuple.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/tuple.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +--- suggestedfix_tuple_4_2 -- +-package missingfunction - --func (*B) newMethod(ctx context.Context, sum int) (int, error) { -- return sum, ctx.Err() +-func tuple() { +- undefinedTuple(b()) //@suggestedfix("undefinedTuple", "quickfix", "") -} - --func (b *B) LongList(ctx context.Context) (int, error) { -- p1 := 1 -- p2 := 1 -- p3 := 1 -- return p1 + p2 + p3, ctx.Err() //@extractmethod("return", "ctx.Err()"),extractfunc("return", "ctx.Err()") +-func undefinedTuple(s string, err error) { +- panic("unimplemented") -} - ---- methodextraction_extract_context_19_2 -- --package extract +-func b() (string, error) { +- return "", nil +-} - --import "context" +diff -urN a/gopls/internal/lsp/testdata/missingfunction/unique_params.go b/gopls/internal/lsp/testdata/missingfunction/unique_params.go +--- a/gopls/internal/lsp/testdata/missingfunction/unique_params.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/unique_params.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package missingfunction - --type B struct { -- x int -- y int +-func uniqueArguments() { +- var s string +- var i int +- undefinedUniqueArguments(s, i, s) //@suggestedfix("undefinedUniqueArguments", "quickfix", "") -} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/unique_params.go.golden b/gopls/internal/lsp/testdata/missingfunction/unique_params.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/unique_params.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/unique_params.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +--- suggestedfix_unique_params_6_2 -- +-package missingfunction - --func (b *B) AddP(ctx context.Context) (int, error) { -- sum := b.x + b.y -- return sum, ctx.Err() //@extractmethod("return", "ctx.Err()"),extractfunc("return", "ctx.Err()") +-func uniqueArguments() { +- var s string +- var i int +- undefinedUniqueArguments(s, i, s) //@suggestedfix("undefinedUniqueArguments", "quickfix", "") -} - --func (b *B) LongList(ctx context.Context) (int, error) { -- p1 := 1 -- p2 := 1 -- p3 := 1 -- return b.newMethod(ctx, p1, p2, p3) //@extractmethod("return", "ctx.Err()"),extractfunc("return", "ctx.Err()") +-func undefinedUniqueArguments(s1 string, i int, s2 string) { +- panic("unimplemented") -} - --func (*B) newMethod(ctx context.Context, p1 int, p2 int, p3 int) (int, error) { -- return p1 + p2 + p3, ctx.Err() --} +diff -urN a/gopls/internal/lsp/testdata/nested_complit/nested_complit.go.in b/gopls/internal/lsp/testdata/nested_complit/nested_complit.go.in +--- a/gopls/internal/lsp/testdata/nested_complit/nested_complit.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/nested_complit/nested_complit.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +-package nested_complit - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go b/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go ---- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go 1970-01-01 08:00:00 -@@ -1,6 +0,0 @@ --package extract +-type ncFoo struct {} //@item(structNCFoo, "ncFoo", "struct{...}", "struct") - --func _() { -- var _ = 1 + 2 //@suggestedfix("1", "refactor.extract", "") -- var _ = 3 + 4 //@suggestedfix("3 + 4", "refactor.extract", "") +-type ncBar struct { //@item(structNCBar, "ncBar", "struct{...}", "struct") +- baz []ncFoo -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go.golden b/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go.golden 1970-01-01 08:00:00 -@@ -1,18 +0,0 @@ ---- suggestedfix_extract_basic_lit_4_10 -- --package extract - -func _() { -- x := 1 -- var _ = x + 2 //@suggestedfix("1", "refactor.extract", "") -- var _ = 3 + 4 //@suggestedfix("3 + 4", "refactor.extract", "") +- []ncFoo{} //@item(litNCFoo, "[]ncFoo{}", "", "var") +- _ := ncBar{ +- // disabled - see issue #54822 +- baz: [] // complete(" //", structNCFoo, structNCBar) +- } -} +diff -urN a/gopls/internal/lsp/testdata/%percent/perc%ent.go b/gopls/internal/lsp/testdata/%percent/perc%ent.go +--- a/gopls/internal/lsp/testdata/%percent/perc%ent.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/%percent/perc%ent.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1 +0,0 @@ +-package percent +diff -urN a/gopls/internal/lsp/testdata/rename/a/random.go.golden b/gopls/internal/lsp/testdata/rename/a/random.go.golden +--- a/gopls/internal/lsp/testdata/rename/a/random.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/a/random.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,616 +0,0 @@ +--- GetSum-rename -- +-package a - ---- suggestedfix_extract_basic_lit_5_10 -- --package extract +-import ( +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +-) - --func _() { -- var _ = 1 + 2 //@suggestedfix("1", "refactor.extract", "") -- x := 3 + 4 -- var _ = x //@suggestedfix("3 + 4", "refactor.extract", "") +-func Random() int { +- y := 6 + 7 +- return y -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go b/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go ---- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --package extract -- --import "strconv" -- --func _() { -- x0 := append([]int{}, 1) //@suggestedfix("append([]int{}, 1)", "refactor.extract", "") -- str := "1" -- b, err := strconv.Atoi(str) //@suggestedfix("strconv.Atoi(str)", "refactor.extract", "") +-func Random2(y int) int { //@rename("y", "z") +- return y -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go.golden b/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go.golden 1970-01-01 08:00:00 -@@ -1,24 +0,0 @@ ---- suggestedfix_extract_func_call_6_8 -- --package extract - --import "strconv" -- --func _() { -- x := append([]int{}, 1) -- x0 := x //@suggestedfix("append([]int{}, 1)", "refactor.extract", "") -- str := "1" -- b, err := strconv.Atoi(str) //@suggestedfix("strconv.Atoi(str)", "refactor.extract", "") +-type Pos struct { +- x, y int -} - ---- suggestedfix_extract_func_call_8_12 -- --package extract -- --import "strconv" -- --func _() { -- x0 := append([]int{}, 1) //@suggestedfix("append([]int{}, 1)", "refactor.extract", "") -- str := "1" -- x, x1 := strconv.Atoi(str) -- b, err := x, x1 //@suggestedfix("strconv.Atoi(str)", "refactor.extract", "") +-func (p *Pos) GetSum() int { +- return p.x + p.y //@rename("x", "myX") -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go b/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go ---- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ --package extract -- --import "go/ast" -- -func _() { -- x0 := 0 -- if true { -- y := ast.CompositeLit{} //@suggestedfix("ast.CompositeLit{}", "refactor.extract", "") -- } -- if true { -- x1 := !false //@suggestedfix("!false", "refactor.extract", "") -- } +- var p Pos //@rename("p", "pos") +- _ = p.GetSum() //@rename("Sum", "GetSum") -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go.golden b/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go.golden 1970-01-01 08:00:00 -@@ -1,32 +0,0 @@ ---- suggestedfix_extract_scope_11_9 -- --package extract - --import "go/ast" +-func sw() { +- var x interface{} - --func _() { -- x0 := 0 -- if true { -- y := ast.CompositeLit{} //@suggestedfix("ast.CompositeLit{}", "refactor.extract", "") -- } -- if true { -- x := !false -- x1 := x //@suggestedfix("!false", "refactor.extract", "") +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") - } -} - ---- suggestedfix_extract_scope_8_8 -- --package extract +--- f2name-rename -- +-package a - --import "go/ast" +-import ( +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2name "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +-) - --func _() { -- x0 := 0 -- if true { -- x := ast.CompositeLit{} -- y := x //@suggestedfix("ast.CompositeLit{}", "refactor.extract", "") -- } -- if true { -- x1 := !false //@suggestedfix("!false", "refactor.extract", "") -- } +-func Random() int { +- y := 6 + 7 +- return y -} - -diff -urN a/gopls/internal/lsp/testdata/fieldlist/field_list.go b/gopls/internal/lsp/testdata/fieldlist/field_list.go ---- a/gopls/internal/lsp/testdata/fieldlist/field_list.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fieldlist/field_list.go 1970-01-01 08:00:00 -@@ -1,27 +0,0 @@ --package fieldlist -- --var myInt int //@item(flVar, "myInt", "int", "var") --type myType int //@item(flType, "myType", "int", "type") -- --func (my) _() {} //@complete(") _", flType) --func (my my) _() {} //@complete(" my)"),complete(") _", flType) -- --func (myType) _() {} //@complete(") {", flType) -- --func (myType) _(my my) {} //@complete(" my)"),complete(") {", flType) +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - --func (myType) _() my {} //@complete(" {", flType) +-type Pos struct { +- x, y int +-} - --func (myType) _() (my my) {} //@complete(" my"),complete(") {", flType) +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - -func _() { -- var _ struct { -- //@complete("", flType) -- m my //@complete(" my"),complete(" //", flType) -- } +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") +-} - -- var _ interface { -- //@complete("", flType) -- m() my //@complete("("),complete(" //", flType) +-func sw() { +- var x interface{} +- +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2name.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") - } -} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/a.go b/gopls/internal/lsp/testdata/fillstruct/a.go ---- a/gopls/internal/lsp/testdata/fillstruct/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/a.go 1970-01-01 08:00:00 -@@ -1,27 +0,0 @@ --package fillstruct +- +--- f2y-rename -- +-package a - -import ( -- "golang.org/lsptests/fillstruct/data" +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2y "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") -) - --type basicStruct struct { -- foo int +-func Random() int { +- y := 6 + 7 +- return y -} - --var _ = basicStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - --type twoArgStruct struct { -- foo int -- bar string +-type Pos struct { +- x, y int -} - --var _ = twoArgStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - --type nestedStruct struct { -- bar string -- basic basicStruct +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - --var _ = nestedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func sw() { +- var x interface{} - --var _ = data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") -diff -urN a/gopls/internal/lsp/testdata/fillstruct/a.go.golden b/gopls/internal/lsp/testdata/fillstruct/a.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/a.go.golden 1970-01-01 08:00:00 -@@ -1,126 +0,0 @@ ---- suggestedfix_a_11_21 -- --package fillstruct +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2y.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } +-} +- +--- fmt2-rename -- +-package a - -import ( -- "golang.org/lsptests/fillstruct/data" +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- fmt2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") -) - --type basicStruct struct { -- foo int +-func Random() int { +- y := 6 + 7 +- return y -} - --var _ = basicStruct{ -- foo: 0, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - --type twoArgStruct struct { -- foo int -- bar string +-type Pos struct { +- x, y int -} - --var _ = twoArgStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - --type nestedStruct struct { -- bar string -- basic basicStruct +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - --var _ = nestedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func sw() { +- var x interface{} - --var _ = data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- fmt2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } +-} - ---- suggestedfix_a_18_22 -- --package fillstruct +--- fmty-rename -- +-package a - -import ( -- "golang.org/lsptests/fillstruct/data" +- lg "log" +- fmty "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") -) - --type basicStruct struct { -- foo int +-func Random() int { +- y := 6 + 7 +- return y -} - --var _ = basicStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - --type twoArgStruct struct { -- foo int -- bar string +-type Pos struct { +- x, y int -} - --var _ = twoArgStruct{ -- foo: 0, -- bar: "", --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - --type nestedStruct struct { -- bar string -- basic basicStruct +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - --var _ = nestedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func sw() { +- var x interface{} - --var _ = data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmty.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } +-} - ---- suggestedfix_a_25_22 -- --package fillstruct +--- format-rename -- +-package a - -import ( -- "golang.org/lsptests/fillstruct/data" +- lg "log" +- format "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") -) - --type basicStruct struct { -- foo int +-func Random() int { +- y := 6 + 7 +- return y -} - --var _ = basicStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - --type twoArgStruct struct { -- foo int -- bar string +-type Pos struct { +- x, y int -} - --var _ = twoArgStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - --type nestedStruct struct { -- bar string -- basic basicStruct +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - --var _ = nestedStruct{ -- bar: "", -- basic: basicStruct{}, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func sw() { +- var x interface{} - --var _ = data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- format.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } +-} - ---- suggestedfix_a_27_16 -- --package fillstruct +--- log-rename -- +-package a - -import ( -- "golang.org/lsptests/fillstruct/data" +- "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") -) - --type basicStruct struct { -- foo int +-func Random() int { +- y := 6 + 7 +- return y -} - --var _ = basicStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type twoArgStruct struct { -- foo int -- bar string +-func Random2(y int) int { //@rename("y", "z") +- return y -} - --var _ = twoArgStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type nestedStruct struct { -- bar string -- basic basicStruct +-type Pos struct { +- x, y int -} - --var _ = nestedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --var _ = data.B{ -- ExportedInt: 0, --} //@suggestedfix("}", "refactor.rewrite", "Fill") -- -diff -urN a/gopls/internal/lsp/testdata/fillstruct/a2.go b/gopls/internal/lsp/testdata/fillstruct/a2.go ---- a/gopls/internal/lsp/testdata/fillstruct/a2.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/a2.go 1970-01-01 08:00:00 -@@ -1,29 +0,0 @@ --package fillstruct -- --type typedStruct struct { -- m map[string]int -- s []int -- c chan int -- c1 <-chan int -- a [2]string +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") -} - --var _ = typedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type funStruct struct { -- fn func(i int) int +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - --var _ = funStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func sw() { +- var x interface{} - --type funStructCompex struct { -- fn func(i int, s string) (string, int) +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- log.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } -} - --var _ = funStructCompex{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type funStructEmpty struct { -- fn func() --} +--- myX-rename -- +-package a - --var _ = funStructEmpty{} //@suggestedfix("}", "refactor.rewrite", "Fill") -diff -urN a/gopls/internal/lsp/testdata/fillstruct/a2.go.golden b/gopls/internal/lsp/testdata/fillstruct/a2.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/a2.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/a2.go.golden 1970-01-01 08:00:00 -@@ -1,139 +0,0 @@ ---- suggestedfix_a2_11_21 -- --package fillstruct +-import ( +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +-) - --type typedStruct struct { -- m map[string]int -- s []int -- c chan int -- c1 <-chan int -- a [2]string +-func Random() int { +- y := 6 + 7 +- return y -} - --var _ = typedStruct{ -- m: map[string]int{}, -- s: []int{}, -- c: make(chan int), -- c1: make(<-chan int), -- a: [2]string{}, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - --type funStruct struct { -- fn func(i int) int +-type Pos struct { +- myX, y int -} - --var _ = funStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (p *Pos) Sum() int { +- return p.myX + p.y //@rename("x", "myX") +-} - --type funStructCompex struct { -- fn func(i int, s string) (string, int) +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - --var _ = funStructCompex{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func sw() { +- var x interface{} - --type funStructEmpty struct { -- fn func() +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } -} - --var _ = funStructEmpty{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- pos-rename -- +-package a - ---- suggestedfix_a2_17_19 -- --package fillstruct +-import ( +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +-) - --type typedStruct struct { -- m map[string]int -- s []int -- c chan int -- c1 <-chan int -- a [2]string +-func Random() int { +- y := 6 + 7 +- return y -} - --var _ = typedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - --type funStruct struct { -- fn func(i int) int +-type Pos struct { +- x, y int -} - --var _ = funStruct{ -- fn: func(i int) int { -- }, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - --type funStructCompex struct { -- fn func(i int, s string) (string, int) +-func _() { +- var pos Pos //@rename("p", "pos") +- _ = pos.Sum() //@rename("Sum", "GetSum") -} - --var _ = funStructCompex{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func sw() { +- var x interface{} - --type funStructEmpty struct { -- fn func() +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } -} - --var _ = funStructEmpty{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- y0-rename -- +-package a - ---- suggestedfix_a2_23_25 -- --package fillstruct +-import ( +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +-) - --type typedStruct struct { -- m map[string]int -- s []int -- c chan int -- c1 <-chan int -- a [2]string +-func Random() int { +- y := 6 + 7 +- return y -} - --var _ = typedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - --type funStruct struct { -- fn func(i int) int +-type Pos struct { +- x, y int -} - --var _ = funStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - --type funStructCompex struct { -- fn func(i int, s string) (string, int) +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - --var _ = funStructCompex{ -- fn: func(i int, s string) (string, int) { -- }, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func sw() { +- var x interface{} - --type funStructEmpty struct { -- fn func() +- switch y0 := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y0) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y0) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y0) //@rename("y", "y3"),rename("f2","fmt2") +- } -} - --var _ = funStructEmpty{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- y1-rename -- +-package a - ---- suggestedfix_a2_29_24 -- --package fillstruct +-import ( +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +-) - --type typedStruct struct { -- m map[string]int -- s []int -- c chan int -- c1 <-chan int -- a [2]string +-func Random() int { +- y := 6 + 7 +- return y -} - --var _ = typedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - --type funStruct struct { -- fn func(i int) int +-type Pos struct { +- x, y int -} - --var _ = funStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - --type funStructCompex struct { -- fn func(i int, s string) (string, int) +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - --var _ = funStructCompex{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func sw() { +- var x interface{} - --type funStructEmpty struct { -- fn func() +- switch y1 := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y1) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y1) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y1) //@rename("y", "y3"),rename("f2","fmt2") +- } -} - --var _ = funStructEmpty{ -- fn: func() { -- }, --} //@suggestedfix("}", "refactor.rewrite", "Fill") -- -diff -urN a/gopls/internal/lsp/testdata/fillstruct/a3.go b/gopls/internal/lsp/testdata/fillstruct/a3.go ---- a/gopls/internal/lsp/testdata/fillstruct/a3.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/a3.go 1970-01-01 08:00:00 -@@ -1,42 +0,0 @@ --package fillstruct +--- y2-rename -- +-package a - -import ( -- "go/ast" -- "go/token" +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") -) - --type Foo struct { -- A int +-func Random() int { +- y := 6 + 7 +- return y -} - --type Bar struct { -- X *Foo -- Y *Foo +-func Random2(y int) int { //@rename("y", "z") +- return y -} - --var _ = Bar{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type importedStruct struct { -- m map[*ast.CompositeLit]ast.Field -- s []ast.BadExpr -- a [3]token.Token -- c chan ast.EmptyStmt -- fn func(ast_decl ast.DeclStmt) ast.Ellipsis -- st ast.CompositeLit +-type Pos struct { +- x, y int -} - --var _ = importedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - --type pointerBuiltinStruct struct { -- b *bool -- s *string -- i *int +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - --var _ = pointerBuiltinStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func sw() { +- var x interface{} - --var _ = []ast.BasicLit{ -- {}, //@suggestedfix("}", "refactor.rewrite", "Fill") +- switch y2 := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y2) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y2) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y2) //@rename("y", "y3"),rename("f2","fmt2") +- } -} - --var _ = []ast.BasicLit{{}} //@suggestedfix("}", "refactor.rewrite", "Fill") -diff -urN a/gopls/internal/lsp/testdata/fillstruct/a3.go.golden b/gopls/internal/lsp/testdata/fillstruct/a3.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/a3.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/a3.go.golden 1970-01-01 08:00:00 -@@ -1,243 +0,0 @@ ---- suggestedfix_a3_17_13 -- --package fillstruct +--- y3-rename -- +-package a - -import ( -- "go/ast" -- "go/token" +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") -) - --type Foo struct { -- A int +-func Random() int { +- y := 6 + 7 +- return y -} - --type Bar struct { -- X *Foo -- Y *Foo +-func Random2(y int) int { //@rename("y", "z") +- return y -} - --var _ = Bar{ -- X: &Foo{}, -- Y: &Foo{}, --} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type importedStruct struct { -- m map[*ast.CompositeLit]ast.Field -- s []ast.BadExpr -- a [3]token.Token -- c chan ast.EmptyStmt -- fn func(ast_decl ast.DeclStmt) ast.Ellipsis -- st ast.CompositeLit +-type Pos struct { +- x, y int -} - --var _ = importedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - --type pointerBuiltinStruct struct { -- b *bool -- s *string -- i *int +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - --var _ = pointerBuiltinStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func sw() { +- var x interface{} - --var _ = []ast.BasicLit{ -- {}, //@suggestedfix("}", "refactor.rewrite", "Fill") +- switch y3 := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y3) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y3) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y3) //@rename("y", "y3"),rename("f2","fmt2") +- } -} - --var _ = []ast.BasicLit{{}} //@suggestedfix("}", "refactor.rewrite", "Fill") -- ---- suggestedfix_a3_28_24 -- --package fillstruct +--- z-rename -- +-package a - -import ( -- "go/ast" -- "go/token" +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") -) - --type Foo struct { -- A int +-func Random() int { +- y := 6 + 7 +- return y -} - --type Bar struct { -- X *Foo -- Y *Foo +-func Random2(z int) int { //@rename("y", "z") +- return z -} - --var _ = Bar{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type importedStruct struct { -- m map[*ast.CompositeLit]ast.Field -- s []ast.BadExpr -- a [3]token.Token -- c chan ast.EmptyStmt -- fn func(ast_decl ast.DeclStmt) ast.Ellipsis -- st ast.CompositeLit +-type Pos struct { +- x, y int -} - --var _ = importedStruct{ -- m: map[*ast.CompositeLit]ast.Field{}, -- s: []ast.BadExpr{}, -- a: [3]token.Token{}, -- c: make(chan ast.EmptyStmt), -- fn: func(ast_decl ast.DeclStmt) ast.Ellipsis { -- }, -- st: ast.CompositeLit{}, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - --type pointerBuiltinStruct struct { -- b *bool -- s *string -- i *int +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - --var _ = pointerBuiltinStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func sw() { +- var x interface{} - --var _ = []ast.BasicLit{ -- {}, //@suggestedfix("}", "refactor.rewrite", "Fill") +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } -} - --var _ = []ast.BasicLit{{}} //@suggestedfix("}", "refactor.rewrite", "Fill") -- ---- suggestedfix_a3_36_30 -- --package fillstruct +diff -urN a/gopls/internal/lsp/testdata/rename/a/random.go.in b/gopls/internal/lsp/testdata/rename/a/random.go.in +--- a/gopls/internal/lsp/testdata/rename/a/random.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/a/random.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,42 +0,0 @@ +-package a - -import ( -- "go/ast" -- "go/token" +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") -) - --type Foo struct { -- A int +-func Random() int { +- y := 6 + 7 +- return y -} - --type Bar struct { -- X *Foo -- Y *Foo +-func Random2(y int) int { //@rename("y", "z") +- return y -} - --var _ = Bar{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type importedStruct struct { -- m map[*ast.CompositeLit]ast.Field -- s []ast.BadExpr -- a [3]token.Token -- c chan ast.EmptyStmt -- fn func(ast_decl ast.DeclStmt) ast.Ellipsis -- st ast.CompositeLit +-type Pos struct { +- x, y int -} - --var _ = importedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - --type pointerBuiltinStruct struct { -- b *bool -- s *string -- i *int +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - --var _ = pointerBuiltinStruct{ -- b: new(bool), -- s: new(string), -- i: new(int), --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func sw() { +- var x interface{} - --var _ = []ast.BasicLit{ -- {}, //@suggestedfix("}", "refactor.rewrite", "Fill") +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } -} +diff -urN a/gopls/internal/lsp/testdata/rename/b/b.go b/gopls/internal/lsp/testdata/rename/b/b.go +--- a/gopls/internal/lsp/testdata/rename/b/b.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/b/b.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,20 +0,0 @@ +-package b - --var _ = []ast.BasicLit{{}} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var c int //@rename("int", "uint") - ---- suggestedfix_a3_39_3 -- --package fillstruct +-func _() { +- a := 1 //@rename("a", "error") +- a = 2 +- _ = a +-} - --import ( -- "go/ast" -- "go/token" +-var ( +- // Hello there. +- // Foo does the thing. +- Foo int //@rename("Foo", "Bob") -) - --type Foo struct { -- A int --} -- --type Bar struct { -- X *Foo -- Y *Foo --} +-/* +-Hello description +-*/ +-func Hello() {} //@rename("Hello", "Goodbye") +diff -urN a/gopls/internal/lsp/testdata/rename/b/b.go.golden b/gopls/internal/lsp/testdata/rename/b/b.go.golden +--- a/gopls/internal/lsp/testdata/rename/b/b.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/b/b.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,78 +0,0 @@ +--- Bob-rename -- +-package b - --var _ = Bar{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var c int //@rename("int", "uint") - --type importedStruct struct { -- m map[*ast.CompositeLit]ast.Field -- s []ast.BadExpr -- a [3]token.Token -- c chan ast.EmptyStmt -- fn func(ast_decl ast.DeclStmt) ast.Ellipsis -- st ast.CompositeLit +-func _() { +- a := 1 //@rename("a", "error") +- a = 2 +- _ = a -} - --var _ = importedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type pointerBuiltinStruct struct { -- b *bool -- s *string -- i *int --} +-var ( +- // Hello there. +- // Bob does the thing. +- Bob int //@rename("Foo", "Bob") +-) - --var _ = pointerBuiltinStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-/* +-Hello description +-*/ +-func Hello() {} //@rename("Hello", "Goodbye") - --var _ = []ast.BasicLit{ -- { -- ValuePos: 0, -- Kind: 0, -- Value: "", -- }, //@suggestedfix("}", "refactor.rewrite", "Fill") --} +--- Goodbye-rename -- +-b.go: +-package b - --var _ = []ast.BasicLit{{}} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var c int //@rename("int", "uint") - ---- suggestedfix_a3_42_25 -- --package fillstruct +-func _() { +- a := 1 //@rename("a", "error") +- a = 2 +- _ = a +-} - --import ( -- "go/ast" -- "go/token" +-var ( +- // Hello there. +- // Foo does the thing. +- Foo int //@rename("Foo", "Bob") -) - --type Foo struct { -- A int --} +-/* +-Goodbye description +-*/ +-func Goodbye() {} //@rename("Hello", "Goodbye") - --type Bar struct { -- X *Foo -- Y *Foo --} +-c.go: +-package c - --var _ = Bar{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import "golang.org/lsptests/rename/b" - --type importedStruct struct { -- m map[*ast.CompositeLit]ast.Field -- s []ast.BadExpr -- a [3]token.Token -- c chan ast.EmptyStmt -- fn func(ast_decl ast.DeclStmt) ast.Ellipsis -- st ast.CompositeLit +-func _() { +- b.Goodbye() //@rename("Hello", "Goodbye") -} - --var _ = importedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type pointerBuiltinStruct struct { -- b *bool -- s *string -- i *int --} +--- error-rename -- +-package b - --var _ = pointerBuiltinStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var c int //@rename("int", "uint") - --var _ = []ast.BasicLit{ -- {}, //@suggestedfix("}", "refactor.rewrite", "Fill") +-func _() { +- error := 1 //@rename("a", "error") +- error = 2 +- _ = error -} - --var _ = []ast.BasicLit{{ -- ValuePos: 0, -- Kind: 0, -- Value: "", --}} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var ( +- // Hello there. +- // Foo does the thing. +- Foo int //@rename("Foo", "Bob") +-) - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/a4.go b/gopls/internal/lsp/testdata/fillstruct/a4.go ---- a/gopls/internal/lsp/testdata/fillstruct/a4.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/a4.go 1970-01-01 08:00:00 -@@ -1,39 +0,0 @@ --package fillstruct +-/* +-Hello description +-*/ +-func Hello() {} //@rename("Hello", "Goodbye") - --import "go/ast" +--- uint-rename -- +-int is built in and cannot be renamed +diff -urN a/gopls/internal/lsp/testdata/rename/bad/bad.go.golden b/gopls/internal/lsp/testdata/rename/bad/bad.go.golden +--- a/gopls/internal/lsp/testdata/rename/bad/bad.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/bad/bad.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,2 +0,0 @@ +--- rFunc-rename -- +-renaming "sFunc" to "rFunc" not possible because "golang.org/lsptests/rename/bad" has errors +diff -urN a/gopls/internal/lsp/testdata/rename/bad/bad.go.in b/gopls/internal/lsp/testdata/rename/bad/bad.go.in +--- a/gopls/internal/lsp/testdata/rename/bad/bad.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/bad/bad.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package bad - --type iStruct struct { -- X int +-type myStruct struct { -} - --type sStruct struct { -- str string +-func (s *myStruct) sFunc() bool { //@rename("sFunc", "rFunc") +- return s.Bad -} +diff -urN a/gopls/internal/lsp/testdata/rename/bad/bad_test.go.in b/gopls/internal/lsp/testdata/rename/bad/bad_test.go.in +--- a/gopls/internal/lsp/testdata/rename/bad/bad_test.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/bad/bad_test.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1 +0,0 @@ +-package bad +\ No newline at end of file +diff -urN a/gopls/internal/lsp/testdata/rename/c/c2.go b/gopls/internal/lsp/testdata/rename/c/c2.go +--- a/gopls/internal/lsp/testdata/rename/c/c2.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/c/c2.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,4 +0,0 @@ +-package c - --type multiFill struct { -- num int -- strin string -- arr []int --} +-//go:embed Static/* +-var Static embed.FS //@rename("Static", "static") +\ No newline at end of file +diff -urN a/gopls/internal/lsp/testdata/rename/c/c2.go.golden b/gopls/internal/lsp/testdata/rename/c/c2.go.golden +--- a/gopls/internal/lsp/testdata/rename/c/c2.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/c/c2.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,5 +0,0 @@ +--- static-rename -- +-package c - --type assignStruct struct { -- n ast.Node --} +-//go:embed Static/* +-var static embed.FS //@rename("Static", "static") +diff -urN a/gopls/internal/lsp/testdata/rename/c/c.go b/gopls/internal/lsp/testdata/rename/c/c.go +--- a/gopls/internal/lsp/testdata/rename/c/c.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/c/c.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package c - --func fill() { -- var x int -- var _ = iStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import "golang.org/lsptests/rename/b" - -- var s string -- var _ = sStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func _() { +- b.Hello() //@rename("Hello", "Goodbye") +-} +diff -urN a/gopls/internal/lsp/testdata/rename/c/c.go.golden b/gopls/internal/lsp/testdata/rename/c/c.go.golden +--- a/gopls/internal/lsp/testdata/rename/c/c.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/c/c.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,32 +0,0 @@ +--- Goodbye-rename -- +-b.go: +-package b - -- var n int -- _ = []int{} -- if true { -- arr := []int{1, 2} -- } -- var _ = multiFill{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var c int //@rename("int", "uint") - -- var node *ast.CompositeLit -- var _ = assignStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func _() { +- a := 1 //@rename("a", "error") +- a = 2 +- _ = a -} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/a4.go.golden b/gopls/internal/lsp/testdata/fillstruct/a4.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/a4.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/a4.go.golden 1970-01-01 08:00:00 -@@ -1,174 +0,0 @@ ---- suggestedfix_a4_25_18 -- --package fillstruct - --import "go/ast" +-var ( +- // Hello there. +- // Foo does the thing. +- Foo int //@rename("Foo", "Bob") +-) - --type iStruct struct { -- X int --} +-/* +-Goodbye description +-*/ +-func Goodbye() {} //@rename("Hello", "Goodbye") - --type sStruct struct { -- str string --} +-c.go: +-package c - --type multiFill struct { -- num int -- strin string -- arr []int --} +-import "golang.org/lsptests/rename/b" - --type assignStruct struct { -- n ast.Node +-func _() { +- b.Goodbye() //@rename("Hello", "Goodbye") -} - --func fill() { -- var x int -- var _ = iStruct{ -- X: x, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") +diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go b/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go +--- a/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package another - -- var s string -- var _ = sStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-type ( +- I interface{ F() } +- C struct{ I } +-) - -- var n int -- _ = []int{} -- if true { -- arr := []int{1, 2} -- } -- var _ = multiFill{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (C) g() - -- var node *ast.CompositeLit -- var _ = assignStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func _() { +- var x I = C{} +- x.F() //@rename("F", "G") -} +diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go.golden b/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go.golden +--- a/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +--- G-rename -- +-package another - ---- suggestedfix_a4_28_18 -- --package fillstruct +-type ( +- I interface{ G() } +- C struct{ I } +-) - --import "go/ast" +-func (C) g() - --type iStruct struct { -- X int +-func _() { +- var x I = C{} +- x.G() //@rename("F", "G") -} - --type sStruct struct { -- str string --} +diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go b/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go +--- a/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package crosspkg - --type multiFill struct { -- num int -- strin string -- arr []int --} +-func Foo() { //@rename("Foo", "Dolphin") - --type assignStruct struct { -- n ast.Node -} - --func fill() { -- var x int -- var _ = iStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- -- var s string -- var _ = sStruct{ -- str: s, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") +-var Bar int //@rename("Bar", "Tomato") +diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden b/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden +--- a/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,40 +0,0 @@ +--- Dolphin-rename -- +-crosspkg.go: +-package crosspkg - -- var n int -- _ = []int{} -- if true { -- arr := []int{1, 2} -- } -- var _ = multiFill{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func Dolphin() { //@rename("Foo", "Dolphin") - -- var node *ast.CompositeLit -- var _ = assignStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -} - ---- suggestedfix_a4_35_20 -- --package fillstruct +-var Bar int //@rename("Bar", "Tomato") - --import "go/ast" +-other.go: +-package other - --type iStruct struct { -- X int --} +-import "golang.org/lsptests/rename/crosspkg" - --type sStruct struct { -- str string +-func Other() { +- crosspkg.Bar +- crosspkg.Dolphin() //@rename("Foo", "Flamingo") -} - --type multiFill struct { -- num int -- strin string -- arr []int --} +--- Tomato-rename -- +-crosspkg.go: +-package crosspkg +- +-func Foo() { //@rename("Foo", "Dolphin") - --type assignStruct struct { -- n ast.Node -} - --func fill() { -- var x int -- var _ = iStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var Tomato int //@rename("Bar", "Tomato") - -- var s string -- var _ = sStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-other.go: +-package other - -- var n int -- _ = []int{} -- if true { -- arr := []int{1, 2} -- } -- var _ = multiFill{ -- num: n, -- strin: s, -- arr: []int{}, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") +-import "golang.org/lsptests/rename/crosspkg" - -- var node *ast.CompositeLit -- var _ = assignStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func Other() { +- crosspkg.Tomato +- crosspkg.Foo() //@rename("Foo", "Flamingo") -} - ---- suggestedfix_a4_38_23 -- --package fillstruct -- --import "go/ast" +diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go b/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go +--- a/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package other - --type iStruct struct { -- X int --} +-import "golang.org/lsptests/rename/crosspkg" - --type sStruct struct { -- str string +-func Other() { +- crosspkg.Bar +- crosspkg.Foo() //@rename("Foo", "Flamingo") -} +diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go.golden b/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go.golden +--- a/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,20 +0,0 @@ +--- Flamingo-rename -- +-crosspkg.go: +-package crosspkg - --type multiFill struct { -- num int -- strin string -- arr []int --} +-func Flamingo() { //@rename("Foo", "Dolphin") - --type assignStruct struct { -- n ast.Node -} - --func fill() { -- var x int -- var _ = iStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var Bar int //@rename("Bar", "Tomato") - -- var s string -- var _ = sStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-other.go: +-package other - -- var n int -- _ = []int{} -- if true { -- arr := []int{1, 2} -- } -- var _ = multiFill{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import "golang.org/lsptests/rename/crosspkg" - -- var node *ast.CompositeLit -- var _ = assignStruct{ -- n: node, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") +-func Other() { +- crosspkg.Bar +- crosspkg.Flamingo() //@rename("Foo", "Flamingo") -} - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/data/a.go b/gopls/internal/lsp/testdata/fillstruct/data/a.go ---- a/gopls/internal/lsp/testdata/fillstruct/data/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/data/a.go 1970-01-01 08:00:00 -@@ -1,6 +0,0 @@ --package data -- --type B struct { -- ExportedInt int -- unexportedInt int --} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct.go ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct.go 1970-01-01 08:00:00 -@@ -1,26 +0,0 @@ --package fillstruct +diff -urN a/gopls/internal/lsp/testdata/rename/generics/embedded.go b/gopls/internal/lsp/testdata/rename/generics/embedded.go +--- a/gopls/internal/lsp/testdata/rename/generics/embedded.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/generics/embedded.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,10 +0,0 @@ +-//go:build go1.18 +-// +build go1.18 - --type StructA struct { -- unexportedIntField int -- ExportedIntField int -- MapA map[int]string -- Array []int -- StructB --} +-package generics - --type StructA2 struct { -- B *StructB --} +-type foo[P any] int //@rename("foo","bar") - --type StructA3 struct { -- B StructB --} +-var x struct{ foo[int] } - --func fill() { -- a := StructA{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- b := StructA2{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- c := StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- if true { -- _ = StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- } --} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct.go.golden 1970-01-01 08:00:00 -@@ -1,124 +0,0 @@ ---- suggestedfix_fill_struct_20_15 -- --package fillstruct +-var _ = x.foo +diff -urN a/gopls/internal/lsp/testdata/rename/generics/embedded.go.golden b/gopls/internal/lsp/testdata/rename/generics/embedded.go.golden +--- a/gopls/internal/lsp/testdata/rename/generics/embedded.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/generics/embedded.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +--- bar-rename -- +-//go:build go1.18 +-// +build go1.18 - --type StructA struct { -- unexportedIntField int -- ExportedIntField int -- MapA map[int]string -- Array []int -- StructB --} +-package generics - --type StructA2 struct { -- B *StructB --} +-type bar[P any] int //@rename("foo","bar") - --type StructA3 struct { -- B StructB --} +-var x struct{ bar[int] } - --func fill() { -- a := StructA{ -- unexportedIntField: 0, -- ExportedIntField: 0, -- MapA: map[int]string{}, -- Array: []int{}, -- StructB: StructB{}, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- b := StructA2{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- c := StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- if true { -- _ = StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- } --} +-var _ = x.bar - ---- suggestedfix_fill_struct_21_16 -- --package fillstruct +diff -urN a/gopls/internal/lsp/testdata/rename/generics/generics.go b/gopls/internal/lsp/testdata/rename/generics/generics.go +--- a/gopls/internal/lsp/testdata/rename/generics/generics.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/generics/generics.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,25 +0,0 @@ +-//go:build go1.18 +-// +build go1.18 - --type StructA struct { -- unexportedIntField int -- ExportedIntField int -- MapA map[int]string -- Array []int -- StructB --} +-package generics - --type StructA2 struct { -- B *StructB +-type G[P any] struct { +- F int -} - --type StructA3 struct { -- B StructB --} +-func (G[_]) M() {} - --func fill() { -- a := StructA{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- b := StructA2{ -- B: &StructB{}, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- c := StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- if true { -- _ = StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- } +-func F[P any](P) { +- var p P //@rename("P", "Q") +- _ = p -} - ---- suggestedfix_fill_struct_22_16 -- --package fillstruct +-func _() { +- var x G[int] //@rename("G", "H") +- _ = x.F //@rename("F", "K") +- x.M() //@rename("M", "N") - --type StructA struct { -- unexportedIntField int -- ExportedIntField int -- MapA map[int]string -- Array []int -- StructB +- var y G[string] +- _ = y.F +- y.M() -} +diff -urN a/gopls/internal/lsp/testdata/rename/generics/generics.go.golden b/gopls/internal/lsp/testdata/rename/generics/generics.go.golden +--- a/gopls/internal/lsp/testdata/rename/generics/generics.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/generics/generics.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,108 +0,0 @@ +--- H-rename -- +-//go:build go1.18 +-// +build go1.18 - --type StructA2 struct { -- B *StructB --} +-package generics - --type StructA3 struct { -- B StructB +-type H[P any] struct { +- F int -} - --func fill() { -- a := StructA{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- b := StructA2{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- c := StructA3{ -- B: StructB{}, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- if true { -- _ = StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- } +-func (H[_]) M() {} +- +-func F[P any](P) { +- var p P //@rename("P", "Q") +- _ = p -} - ---- suggestedfix_fill_struct_24_16 -- --package fillstruct +-func _() { +- var x H[int] //@rename("G", "H") +- _ = x.F //@rename("F", "K") +- x.M() //@rename("M", "N") - --type StructA struct { -- unexportedIntField int -- ExportedIntField int -- MapA map[int]string -- Array []int -- StructB +- var y H[string] +- _ = y.F +- y.M() -} - --type StructA2 struct { -- B *StructB --} +--- K-rename -- +-//go:build go1.18 +-// +build go1.18 - --type StructA3 struct { -- B StructB --} +-package generics - --func fill() { -- a := StructA{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- b := StructA2{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- c := StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- if true { -- _ = StructA3{ -- B: StructB{}, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- } +-type G[P any] struct { +- K int -} - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go 1970-01-01 08:00:00 -@@ -1,14 +0,0 @@ --package fillstruct +-func (G[_]) M() {} - --type StructAnon struct { -- a struct{} -- b map[string]interface{} -- c map[string]struct { -- d int -- e bool -- } +-func F[P any](P) { +- var p P //@rename("P", "Q") +- _ = p -} - --func fill() { -- _ := StructAnon{} //@suggestedfix("}", "refactor.rewrite", "Fill") --} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go.golden 1970-01-01 08:00:00 -@@ -1,20 +0,0 @@ ---- suggestedfix_fill_struct_anon_13_18 -- --package fillstruct +-func _() { +- var x G[int] //@rename("G", "H") +- _ = x.K //@rename("F", "K") +- x.M() //@rename("M", "N") - --type StructAnon struct { -- a struct{} -- b map[string]interface{} -- c map[string]struct { -- d int -- e bool -- } +- var y G[string] +- _ = y.K +- y.M() -} - --func fill() { -- _ := StructAnon{ -- a: struct{}{}, -- b: map[string]interface{}{}, -- c: map[string]struct{d int; e bool}{}, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") --} +--- N-rename -- +-//go:build go1.18 +-// +build go1.18 - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go 1970-01-01 08:00:00 -@@ -1,15 +0,0 @@ --package fillstruct +-package generics - --type StructB struct { -- StructC +-type G[P any] struct { +- F int -} - --type StructC struct { -- unexportedInt int --} +-func (G[_]) N() {} - --func nested() { -- c := StructB{ -- StructC: StructC{}, //@suggestedfix("}", "refactor.rewrite", "Fill") -- } +-func F[P any](P) { +- var p P //@rename("P", "Q") +- _ = p -} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go.golden 1970-01-01 08:00:00 -@@ -1,19 +0,0 @@ ---- suggestedfix_fill_struct_nested_13_20 -- --package fillstruct - --type StructB struct { -- StructC --} +-func _() { +- var x G[int] //@rename("G", "H") +- _ = x.F //@rename("F", "K") +- x.N() //@rename("M", "N") - --type StructC struct { -- unexportedInt int +- var y G[string] +- _ = y.F +- y.N() -} - --func nested() { -- c := StructB{ -- StructC: StructC{ -- unexportedInt: 0, -- }, //@suggestedfix("}", "refactor.rewrite", "Fill") -- } --} +--- Q-rename -- +-//go:build go1.18 +-// +build go1.18 - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go 1970-01-01 08:00:00 -@@ -1,12 +0,0 @@ --package fillstruct +-package generics - --import ( -- h2 "net/http" +-type G[P any] struct { +- F int +-} - -- "golang.org/lsptests/fillstruct/data" --) +-func (G[_]) M() {} - --func unexported() { -- a := data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- _ = h2.Client{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func F[Q any](Q) { +- var p Q //@rename("P", "Q") +- _ = p -} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go.golden 1970-01-01 08:00:00 -@@ -1,36 +0,0 @@ ---- suggestedfix_fill_struct_package_10_14 -- --package fillstruct -- --import ( -- h2 "net/http" - -- "golang.org/lsptests/fillstruct/data" --) +-func _() { +- var x G[int] //@rename("G", "H") +- _ = x.F //@rename("F", "K") +- x.M() //@rename("M", "N") - --func unexported() { -- a := data.B{ -- ExportedInt: 0, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- _ = h2.Client{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- var y G[string] +- _ = y.F +- y.M() -} - ---- suggestedfix_fill_struct_package_11_16 -- --package fillstruct +diff -urN a/gopls/internal/lsp/testdata/rename/generics/unions.go b/gopls/internal/lsp/testdata/rename/generics/unions.go +--- a/gopls/internal/lsp/testdata/rename/generics/unions.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/generics/unions.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,10 +0,0 @@ +-//go:build go1.18 +-// +build go1.18 - --import ( -- h2 "net/http" +-package generics - -- "golang.org/lsptests/fillstruct/data" --) +-type T string //@rename("T", "R") - --func unexported() { -- a := data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- _ = h2.Client{ -- Transport: nil, -- CheckRedirect: func(req *h2.Request, via []*h2.Request) error { -- }, -- Jar: nil, -- Timeout: 0, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") +-type C interface { +- T | ~int //@rename("T", "S") -} -- -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go 1970-01-01 08:00:00 +diff -urN a/gopls/internal/lsp/testdata/rename/generics/unions.go.golden b/gopls/internal/lsp/testdata/rename/generics/unions.go.golden +--- a/gopls/internal/lsp/testdata/rename/generics/unions.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/generics/unions.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ --package fillstruct -- --type StructPartialA struct { -- PrefilledInt int -- UnfilledInt int -- StructPartialB --} +--- R-rename -- +-//go:build go1.18 +-// +build go1.18 - --type StructPartialB struct { -- PrefilledInt int -- UnfilledInt int --} +-package generics - --func fill() { -- a := StructPartialA{ -- PrefilledInt: 5, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- b := StructPartialB{ -- /* this comment should disappear */ -- PrefilledInt: 7, // This comment should be blown away. -- /* As should -- this one */ -- } //@suggestedfix("}", "refactor.rewrite", "Fill") --} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go.golden 1970-01-01 08:00:00 -@@ -1,52 +0,0 @@ ---- suggestedfix_fill_struct_partial_17_2 -- --package fillstruct +-type R string //@rename("T", "R") - --type StructPartialA struct { -- PrefilledInt int -- UnfilledInt int -- StructPartialB +-type C interface { +- R | ~int //@rename("T", "S") -} - --type StructPartialB struct { -- PrefilledInt int -- UnfilledInt int --} +--- S-rename -- +-//go:build go1.18 +-// +build go1.18 - --func fill() { -- a := StructPartialA{ -- PrefilledInt: 5, -- UnfilledInt: 0, -- StructPartialB: StructPartialB{}, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- b := StructPartialB{ -- /* this comment should disappear */ -- PrefilledInt: 7, // This comment should be blown away. -- /* As should -- this one */ -- } //@suggestedfix("}", "refactor.rewrite", "Fill") --} +-package generics - ---- suggestedfix_fill_struct_partial_23_2 -- --package fillstruct +-type S string //@rename("T", "R") - --type StructPartialA struct { -- PrefilledInt int -- UnfilledInt int -- StructPartialB +-type C interface { +- S | ~int //@rename("T", "S") -} - --type StructPartialB struct { -- PrefilledInt int -- UnfilledInt int --} +diff -urN a/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.golden b/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.golden +--- a/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,10 +0,0 @@ +--- bar-rename -- +-package issue39614 - --func fill() { -- a := StructPartialA{ -- PrefilledInt: 5, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- b := StructPartialB{ -- PrefilledInt: 7, -- UnfilledInt: 0, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") +-func fn() { +- var bar bool //@rename("foo","bar") +- make(map[string]bool +- if true { +- } -} - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --package fillstruct +diff -urN a/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.in b/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.in +--- a/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package issue39614 - --type StructD struct { -- ExportedIntField int +-func fn() { +- var foo bool //@rename("foo","bar") +- make(map[string]bool +- if true { +- } -} +diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/1.go b/gopls/internal/lsp/testdata/rename/issue42134/1.go +--- a/gopls/internal/lsp/testdata/rename/issue42134/1.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue42134/1.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package issue42134 - --func spaces() { -- d := StructD{} //@suggestedfix("}", "refactor.rewrite", "Fill") --} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go.golden 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ ---- suggestedfix_fill_struct_spaces_8_15 -- --package fillstruct +-func _() { +- // foo computes things. +- foo := func() {} - --type StructD struct { -- ExportedIntField int +- foo() //@rename("foo", "bar") -} +diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/1.go.golden b/gopls/internal/lsp/testdata/rename/issue42134/1.go.golden +--- a/gopls/internal/lsp/testdata/rename/issue42134/1.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue42134/1.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,10 +0,0 @@ +--- bar-rename -- +-package issue42134 - --func spaces() { -- d := StructD{ -- ExportedIntField: 0, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") +-func _() { +- // bar computes things. +- bar := func() {} +- +- bar() //@rename("foo", "bar") -} - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go 1970-01-01 08:00:00 +diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/2.go b/gopls/internal/lsp/testdata/rename/issue42134/2.go +--- a/gopls/internal/lsp/testdata/rename/issue42134/2.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue42134/2.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ --package fillstruct -- --import "unsafe" +-package issue42134 - --type unsafeStruct struct { -- x int -- p unsafe.Pointer --} +-import "fmt" - --func fill() { -- _ := unsafeStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func _() { +- // minNumber is a min number. +- // Second line. +- minNumber := min(1, 2) +- fmt.Println(minNumber) //@rename("minNumber", "res") -} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go.golden 1970-01-01 08:00:00 -@@ -1,17 +0,0 @@ ---- suggestedfix_fill_struct_unsafe_11_20 -- --package fillstruct - --import "unsafe" +-func min(a, b int) int { return a } +diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/2.go.golden b/gopls/internal/lsp/testdata/rename/issue42134/2.go.golden +--- a/gopls/internal/lsp/testdata/rename/issue42134/2.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue42134/2.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +--- res-rename -- +-package issue42134 - --type unsafeStruct struct { -- x int -- p unsafe.Pointer --} +-import "fmt" - --func fill() { -- _ := unsafeStruct{ -- x: 0, -- p: nil, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") +-func _() { +- // res is a min number. +- // Second line. +- res := min(1, 2) +- fmt.Println(res) //@rename("minNumber", "res") -} - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/typeparams.go b/gopls/internal/lsp/testdata/fillstruct/typeparams.go ---- a/gopls/internal/lsp/testdata/fillstruct/typeparams.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/typeparams.go 1970-01-01 08:00:00 -@@ -1,37 +0,0 @@ --//go:build go1.18 --// +build go1.18 -- --package fillstruct -- --type emptyStructWithTypeParams[A any] struct{} +-func min(a, b int) int { return a } - --var _ = emptyStructWithTypeParams[int]{} // no suggested fix +diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/3.go b/gopls/internal/lsp/testdata/rename/issue42134/3.go +--- a/gopls/internal/lsp/testdata/rename/issue42134/3.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue42134/3.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package issue42134 - --type basicStructWithTypeParams[T any] struct { -- foo T +-func _() { +- /* +- tests contains test cases +- */ +- tests := []struct { //@rename("tests", "testCases") +- in, out string +- }{} +- _ = tests -} +diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/3.go.golden b/gopls/internal/lsp/testdata/rename/issue42134/3.go.golden +--- a/gopls/internal/lsp/testdata/rename/issue42134/3.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue42134/3.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +--- testCases-rename -- +-package issue42134 - --var _ = basicStructWithTypeParams[int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type twoArgStructWithTypeParams[F, B any] struct { -- foo F -- bar B +-func _() { +- /* +- testCases contains test cases +- */ +- testCases := []struct { //@rename("tests", "testCases") +- in, out string +- }{} +- _ = testCases -} - --var _ = twoArgStructWithTypeParams[string, int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/4.go b/gopls/internal/lsp/testdata/rename/issue42134/4.go +--- a/gopls/internal/lsp/testdata/rename/issue42134/4.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue42134/4.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package issue42134 - --var _ = twoArgStructWithTypeParams[int, string]{ -- bar: "bar", --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func _() { +- // a is equal to 5. Comment must stay the same - --type nestedStructWithTypeParams struct { -- bar string -- basic basicStructWithTypeParams[int] +- a := 5 +- _ = a //@rename("a", "b") -} +diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/4.go.golden b/gopls/internal/lsp/testdata/rename/issue42134/4.go.golden +--- a/gopls/internal/lsp/testdata/rename/issue42134/4.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue42134/4.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,10 +0,0 @@ +--- b-rename -- +-package issue42134 - --var _ = nestedStructWithTypeParams{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func _() { +- // a is equal to 5. Comment must stay the same - --func _[T any]() { -- type S struct{ t T } -- _ = S{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- b := 5 +- _ = b //@rename("a", "b") -} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/typeparams.go.golden b/gopls/internal/lsp/testdata/fillstruct/typeparams.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/typeparams.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/typeparams.go.golden 1970-01-01 08:00:00 -@@ -1,206 +0,0 @@ ---- suggestedfix_typeparams_14_40 -- --//go:build go1.18 --// +build go1.18 -- --package fillstruct - --type emptyStructWithTypeParams[A any] struct{} -- --var _ = emptyStructWithTypeParams[int]{} // no suggested fix +diff -urN a/gopls/internal/lsp/testdata/rename/shadow/shadow.go b/gopls/internal/lsp/testdata/rename/shadow/shadow.go +--- a/gopls/internal/lsp/testdata/rename/shadow/shadow.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/shadow/shadow.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,20 +0,0 @@ +-package shadow - --type basicStructWithTypeParams[T any] struct { -- foo T +-func _() { +- a := true +- b, c, _ := A(), B(), D() //@rename("A", "a"),rename("B", "b"),rename("b", "c"),rename("D", "d") +- d := false +- _, _, _, _ = a, b, c, d -} - --var _ = basicStructWithTypeParams[int]{ -- foo: 0, --} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type twoArgStructWithTypeParams[F, B any] struct { -- foo F -- bar B +-func A() int { +- return 0 -} - --var _ = twoArgStructWithTypeParams[string, int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func B() int { +- return 0 +-} - --var _ = twoArgStructWithTypeParams[int, string]{ -- bar: "bar", --} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type nestedStructWithTypeParams struct { -- bar string -- basic basicStructWithTypeParams[int] +-func D() int { +- return 0 -} +diff -urN a/gopls/internal/lsp/testdata/rename/shadow/shadow.go.golden b/gopls/internal/lsp/testdata/rename/shadow/shadow.go.golden +--- a/gopls/internal/lsp/testdata/rename/shadow/shadow.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/shadow/shadow.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,51 +0,0 @@ +--- a-rename -- +-shadow/shadow.go:10:6: renaming this func "A" to "a" +-shadow/shadow.go:5:13: would cause this reference to become shadowed +-shadow/shadow.go:4:2: by this intervening var definition +--- b-rename -- +-package shadow - --var _ = nestedStructWithTypeParams{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func _() { +- a := true +- b, c, _ := A(), b(), D() //@rename("A", "a"),rename("B", "b"),rename("b", "c"),rename("D", "d") +- d := false +- _, _, _, _ = a, b, c, d +-} - --func _[T any]() { -- type S struct{ t T } -- _ = S{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func A() int { +- return 0 -} - ---- suggestedfix_typeparams_21_49 -- --//go:build go1.18 --// +build go1.18 +-func b() int { +- return 0 +-} - --package fillstruct +-func D() int { +- return 0 +-} - --type emptyStructWithTypeParams[A any] struct{} +--- c-rename -- +-shadow/shadow.go:5:2: renaming this var "b" to "c" +-shadow/shadow.go:5:5: conflicts with var in same block +--- d-rename -- +-package shadow - --var _ = emptyStructWithTypeParams[int]{} // no suggested fix +-func _() { +- a := true +- b, c, _ := A(), B(), d() //@rename("A", "a"),rename("B", "b"),rename("b", "c"),rename("D", "d") +- d := false +- _, _, _, _ = a, b, c, d +-} - --type basicStructWithTypeParams[T any] struct { -- foo T +-func A() int { +- return 0 -} - --var _ = basicStructWithTypeParams[int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func B() int { +- return 0 +-} - --type twoArgStructWithTypeParams[F, B any] struct { -- foo F -- bar B +-func d() int { +- return 0 -} - --var _ = twoArgStructWithTypeParams[string, int]{ -- foo: "", -- bar: 0, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +diff -urN a/gopls/internal/lsp/testdata/rename/testy/testy.go b/gopls/internal/lsp/testdata/rename/testy/testy.go +--- a/gopls/internal/lsp/testdata/rename/testy/testy.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/testy/testy.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package testy - --var _ = twoArgStructWithTypeParams[int, string]{ -- bar: "bar", --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-type tt int //@rename("tt", "testyType") - --type nestedStructWithTypeParams struct { -- bar string -- basic basicStructWithTypeParams[int] +-func a() { +- foo := 42 //@rename("foo", "bar") -} +diff -urN a/gopls/internal/lsp/testdata/rename/testy/testy.go.golden b/gopls/internal/lsp/testdata/rename/testy/testy.go.golden +--- a/gopls/internal/lsp/testdata/rename/testy/testy.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/testy/testy.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +--- bar-rename -- +-package testy - --var _ = nestedStructWithTypeParams{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-type tt int //@rename("tt", "testyType") - --func _[T any]() { -- type S struct{ t T } -- _ = S{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func a() { +- bar := 42 //@rename("foo", "bar") -} - ---- suggestedfix_typeparams_25_1 -- --//go:build go1.18 --// +build go1.18 +--- testyType-rename -- +-package testy - --package fillstruct +-type testyType int //@rename("tt", "testyType") - --type emptyStructWithTypeParams[A any] struct{} +-func a() { +- foo := 42 //@rename("foo", "bar") +-} - --var _ = emptyStructWithTypeParams[int]{} // no suggested fix +diff -urN a/gopls/internal/lsp/testdata/rename/testy/testy_test.go b/gopls/internal/lsp/testdata/rename/testy/testy_test.go +--- a/gopls/internal/lsp/testdata/rename/testy/testy_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/testy/testy_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package testy - --type basicStructWithTypeParams[T any] struct { -- foo T +-import "testing" +- +-func TestSomething(t *testing.T) { +- var x int //@rename("x", "testyX") +- a() //@rename("a", "b") -} +diff -urN a/gopls/internal/lsp/testdata/rename/testy/testy_test.go.golden b/gopls/internal/lsp/testdata/rename/testy/testy_test.go.golden +--- a/gopls/internal/lsp/testdata/rename/testy/testy_test.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/testy/testy_test.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,30 +0,0 @@ +--- b-rename -- +-testy.go: +-package testy - --var _ = basicStructWithTypeParams[int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-type tt int //@rename("tt", "testyType") - --type twoArgStructWithTypeParams[F, B any] struct { -- foo F -- bar B +-func b() { +- foo := 42 //@rename("foo", "bar") -} - --var _ = twoArgStructWithTypeParams[string, int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-testy_test.go: +-package testy - --var _ = twoArgStructWithTypeParams[int, string]{ -- foo: 0, -- bar: "bar", --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import "testing" - --type nestedStructWithTypeParams struct { -- bar string -- basic basicStructWithTypeParams[int] +-func TestSomething(t *testing.T) { +- var x int //@rename("x", "testyX") +- b() //@rename("a", "b") -} - --var _ = nestedStructWithTypeParams{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- testyX-rename -- +-package testy +- +-import "testing" - --func _[T any]() { -- type S struct{ t T } -- _ = S{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func TestSomething(t *testing.T) { +- var testyX int //@rename("x", "testyX") +- a() //@rename("a", "b") -} - ---- suggestedfix_typeparams_32_36 -- --//go:build go1.18 --// +build go1.18 +diff -urN a/gopls/internal/lsp/testdata/selectionrange/foo.go b/gopls/internal/lsp/testdata/selectionrange/foo.go +--- a/gopls/internal/lsp/testdata/selectionrange/foo.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/selectionrange/foo.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package foo - --package fillstruct +-import "time" - --type emptyStructWithTypeParams[A any] struct{} +-func Bar(x, y int, t time.Time) int { +- zs := []int{1, 2, 3} //@selectionrange("1") - --var _ = emptyStructWithTypeParams[int]{} // no suggested fix +- for _, z := range zs { +- x = x + z + y + zs[1] //@selectionrange("1") +- } - --type basicStructWithTypeParams[T any] struct { -- foo T +- return x + y //@selectionrange("+") -} +diff -urN a/gopls/internal/lsp/testdata/selectionrange/foo.go.golden b/gopls/internal/lsp/testdata/selectionrange/foo.go.golden +--- a/gopls/internal/lsp/testdata/selectionrange/foo.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/selectionrange/foo.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,29 +0,0 @@ +--- selectionrange_foo_12_11 -- +-Ranges 0: +- 11:8-11:13 "x + y" +- 11:1-11:13 "return x + y" +- 4:36-12:1 "{\\n\tzs := []int{...ionrange(\"+\")\\n}" +- 4:0-12:1 "func Bar(x, y i...ionrange(\"+\")\\n}" +- 0:0-12:1 "package foo\\n\\nim...ionrange(\"+\")\\n}" - --var _ = basicStructWithTypeParams[int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- selectionrange_foo_6_14 -- +-Ranges 0: +- 5:13-5:14 "1" +- 5:7-5:21 "[]int{1, 2, 3}" +- 5:1-5:21 "zs := []int{1, 2, 3}" +- 4:36-12:1 "{\\n\tzs := []int{...ionrange(\"+\")\\n}" +- 4:0-12:1 "func Bar(x, y i...ionrange(\"+\")\\n}" +- 0:0-12:1 "package foo\\n\\nim...ionrange(\"+\")\\n}" - --type twoArgStructWithTypeParams[F, B any] struct { -- foo F -- bar B --} +--- selectionrange_foo_9_22 -- +-Ranges 0: +- 8:21-8:22 "1" +- 8:18-8:23 "zs[1]" +- 8:6-8:23 "x + z + y + zs[1]" +- 8:2-8:23 "x = x + z + y + zs[1]" +- 7:22-9:2 "{\\n\t\tx = x + z +...onrange(\"1\")\\n\t}" +- 7:1-9:2 "for _, z := ran...onrange(\"1\")\\n\t}" +- 4:36-12:1 "{\\n\tzs := []int{...ionrange(\"+\")\\n}" +- 4:0-12:1 "func Bar(x, y i...ionrange(\"+\")\\n}" +- 0:0-12:1 "package foo\\n\\nim...ionrange(\"+\")\\n}" - --var _ = twoArgStructWithTypeParams[string, int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +diff -urN a/gopls/internal/lsp/testdata/semantic/a.go b/gopls/internal/lsp/testdata/semantic/a.go +--- a/gopls/internal/lsp/testdata/semantic/a.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/semantic/a.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,81 +0,0 @@ +-package semantictokens //@ semantic("") - --var _ = twoArgStructWithTypeParams[int, string]{ -- bar: "bar", --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import ( +- _ "encoding/utf8" +- utf "encoding/utf8" +- "fmt" //@ semantic("fmt") +- . "fmt" +- "unicode/utf8" +-) - --type nestedStructWithTypeParams struct { -- bar string -- basic basicStructWithTypeParams[int] +-var ( +- a = fmt.Print +- b []string = []string{"foo"} +- c1 chan int +- c2 <-chan int +- c3 = make([]chan<- int) +- b = A{X: 23} +- m map[bool][3]*float64 +-) +- +-const ( +- xx F = iota +- yy = xx + 3 +- zz = "" +- ww = "not " + zz +-) +- +-type A struct { +- X int `foof` +-} +-type B interface { +- A +- sad(int) bool -} - --var _ = nestedStructWithTypeParams{ -- bar: "", -- basic: basicStructWithTypeParams{}, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-type F int - --func _[T any]() { -- type S struct{ t T } -- _ = S{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (a *A) f() bool { +- var z string +- x := "foo" +- a(x) +- y := "bar" + x +- switch z { +- case "xx": +- default: +- } +- select { +- case z := <-c3[0]: +- default: +- } +- for k, v := range m { +- return (!k) && v[0] == nil +- } +- c2 <- A.X +- w := b[4:] +- j := len(x) +- j-- +- q := []interface{}{j, 23i, &y} +- g(q...) +- return true -} - ---- suggestedfix_typeparams_36_8 -- --//go:build go1.18 --// +build go1.18 +-func g(vv ...interface{}) { +- ff := func() {} +- defer ff() +- go utf.RuneCount("") +- go utf8.RuneCount(vv.(string)) +- if true { +- } else { +- } +-Never: +- for i := 0; i < 10; { +- break Never +- } +- _, ok := vv[0].(A) +- if !ok { +- switch x := vv[0].(type) { +- } +- goto Never +- } +-} +diff -urN a/gopls/internal/lsp/testdata/semantic/a.go.golden b/gopls/internal/lsp/testdata/semantic/a.go.golden +--- a/gopls/internal/lsp/testdata/semantic/a.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/semantic/a.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,83 +0,0 @@ +--- semantic -- +-/*⇒7,keyword,[]*/package /*⇒14,namespace,[]*/semantictokens /*⇒16,comment,[]*///@ semantic("") - --package fillstruct +-/*⇒6,keyword,[]*/import ( +- _ "encoding/utf8" +- /*⇒3,namespace,[]*/utf "encoding/utf8" +- "fmt"/*⇐3,namespace,[]*/ /*⇒19,comment,[]*///@ semantic("fmt") +- . "fmt" +- "unicode/utf8"/*⇐4,namespace,[]*/ +-) - --type emptyStructWithTypeParams[A any] struct{} +-/*⇒3,keyword,[]*/var ( +- /*⇒1,variable,[definition]*/a = /*⇒3,namespace,[]*/fmt./*⇒5,function,[]*/Print +- /*⇒1,variable,[definition]*/b []/*⇒6,type,[defaultLibrary]*/string = []/*⇒6,type,[defaultLibrary]*/string{/*⇒5,string,[]*/"foo"} +- /*⇒2,variable,[definition]*/c1 /*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int +- /*⇒2,variable,[definition]*/c2 /*⇒2,operator,[]*/<-/*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int +- /*⇒2,variable,[definition]*/c3 = /*⇒4,function,[defaultLibrary]*/make([]/*⇒4,keyword,[]*/chan/*⇒2,operator,[]*/<- /*⇒3,type,[defaultLibrary]*/int) +- /*⇒1,variable,[definition]*/b = /*⇒1,type,[]*/A{/*⇒1,variable,[]*/X: /*⇒2,number,[]*/23} +- /*⇒1,variable,[definition]*/m /*⇒3,keyword,[]*/map[/*⇒4,type,[defaultLibrary]*/bool][/*⇒1,number,[]*/3]/*⇒1,operator,[]*/*/*⇒7,type,[defaultLibrary]*/float64 +-) - --var _ = emptyStructWithTypeParams[int]{} // no suggested fix +-/*⇒5,keyword,[]*/const ( +- /*⇒2,variable,[definition readonly]*/xx /*⇒1,type,[]*/F = /*⇒4,variable,[readonly]*/iota +- /*⇒2,variable,[definition readonly]*/yy = /*⇒2,variable,[readonly]*/xx /*⇒1,operator,[]*/+ /*⇒1,number,[]*/3 +- /*⇒2,variable,[definition readonly]*/zz = /*⇒2,string,[]*/"" +- /*⇒2,variable,[definition readonly]*/ww = /*⇒6,string,[]*/"not " /*⇒1,operator,[]*/+ /*⇒2,variable,[readonly]*/zz +-) - --type basicStructWithTypeParams[T any] struct { -- foo T +-/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/A /*⇒6,keyword,[]*/struct { +- /*⇒1,variable,[definition]*/X /*⇒3,type,[defaultLibrary]*/int /*⇒6,string,[]*/`foof` +-} +-/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/B /*⇒9,keyword,[]*/interface { +- /*⇒1,type,[]*/A +- /*⇒3,method,[definition]*/sad(/*⇒3,type,[defaultLibrary]*/int) /*⇒4,type,[defaultLibrary]*/bool -} - --var _ = basicStructWithTypeParams[int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/F /*⇒3,type,[defaultLibrary]*/int - --type twoArgStructWithTypeParams[F, B any] struct { -- foo F -- bar B +-/*⇒4,keyword,[]*/func (/*⇒1,variable,[]*/a /*⇒1,operator,[]*/*/*⇒1,type,[]*/A) /*⇒1,method,[definition]*/f() /*⇒4,type,[defaultLibrary]*/bool { +- /*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/z /*⇒6,type,[defaultLibrary]*/string +- /*⇒1,variable,[definition]*/x /*⇒2,operator,[]*/:= /*⇒5,string,[]*/"foo" +- /*⇒1,variable,[]*/a(/*⇒1,variable,[]*/x) +- /*⇒1,variable,[definition]*/y /*⇒2,operator,[]*/:= /*⇒5,string,[]*/"bar" /*⇒1,operator,[]*/+ /*⇒1,variable,[]*/x +- /*⇒6,keyword,[]*/switch /*⇒1,variable,[]*/z { +- /*⇒4,keyword,[]*/case /*⇒4,string,[]*/"xx": +- /*⇒7,keyword,[]*/default: +- } +- /*⇒6,keyword,[]*/select { +- /*⇒4,keyword,[]*/case /*⇒1,variable,[definition]*/z /*⇒2,operator,[]*/:= /*⇒2,operator,[]*/<-/*⇒2,variable,[]*/c3[/*⇒1,number,[]*/0]: +- /*⇒7,keyword,[]*/default: +- } +- /*⇒3,keyword,[]*/for /*⇒1,variable,[definition]*/k, /*⇒1,variable,[definition]*/v := /*⇒5,keyword,[]*/range /*⇒1,variable,[]*/m { +- /*⇒6,keyword,[]*/return (/*⇒1,operator,[]*/!/*⇒1,variable,[]*/k) /*⇒2,operator,[]*/&& /*⇒1,variable,[]*/v[/*⇒1,number,[]*/0] /*⇒2,operator,[]*/== /*⇒3,variable,[readonly defaultLibrary]*/nil +- } +- /*⇒2,variable,[]*/c2 /*⇒2,operator,[]*/<- /*⇒1,type,[]*/A./*⇒1,variable,[]*/X +- /*⇒1,variable,[definition]*/w /*⇒2,operator,[]*/:= /*⇒1,variable,[]*/b[/*⇒1,number,[]*/4:] +- /*⇒1,variable,[definition]*/j /*⇒2,operator,[]*/:= /*⇒3,function,[defaultLibrary]*/len(/*⇒1,variable,[]*/x) +- /*⇒1,variable,[]*/j/*⇒2,operator,[]*/-- +- /*⇒1,variable,[definition]*/q /*⇒2,operator,[]*/:= []/*⇒9,keyword,[]*/interface{}{/*⇒1,variable,[]*/j, /*⇒3,number,[]*/23i, /*⇒1,operator,[]*/&/*⇒1,variable,[]*/y} +- /*⇒1,function,[]*/g(/*⇒1,variable,[]*/q/*⇒3,operator,[]*/...) +- /*⇒6,keyword,[]*/return /*⇒4,variable,[readonly]*/true -} - --var _ = twoArgStructWithTypeParams[string, int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-/*⇒4,keyword,[]*/func /*⇒1,function,[definition]*/g(/*⇒2,parameter,[definition]*/vv /*⇒3,operator,[]*/.../*⇒9,keyword,[]*/interface{}) { +- /*⇒2,variable,[definition]*/ff /*⇒2,operator,[]*/:= /*⇒4,keyword,[]*/func() {} +- /*⇒5,keyword,[]*/defer /*⇒2,function,[]*/ff() +- /*⇒2,keyword,[]*/go /*⇒3,namespace,[]*/utf./*⇒9,function,[]*/RuneCount(/*⇒2,string,[]*/"") +- /*⇒2,keyword,[]*/go /*⇒4,namespace,[]*/utf8./*⇒9,function,[]*/RuneCount(/*⇒2,parameter,[]*/vv.(/*⇒6,type,[]*/string)) +- /*⇒2,keyword,[]*/if /*⇒4,variable,[readonly]*/true { +- } /*⇒4,keyword,[]*/else { +- } +-/*⇒5,parameter,[definition]*/Never: +- /*⇒3,keyword,[]*/for /*⇒1,variable,[definition]*/i /*⇒2,operator,[]*/:= /*⇒1,number,[]*/0; /*⇒1,variable,[]*/i /*⇒1,operator,[]*/< /*⇒2,number,[]*/10; { +- /*⇒5,keyword,[]*/break Never +- } +- _, /*⇒2,variable,[definition]*/ok /*⇒2,operator,[]*/:= /*⇒2,parameter,[]*/vv[/*⇒1,number,[]*/0].(/*⇒1,type,[]*/A) +- /*⇒2,keyword,[]*/if /*⇒1,operator,[]*/!/*⇒2,variable,[]*/ok { +- /*⇒6,keyword,[]*/switch /*⇒1,variable,[definition]*/x /*⇒2,operator,[]*/:= /*⇒2,parameter,[]*/vv[/*⇒1,number,[]*/0].(/*⇒4,keyword,[]*/type) { +- } +- /*⇒4,keyword,[]*/goto Never +- } +-} - --var _ = twoArgStructWithTypeParams[int, string]{ -- bar: "bar", --} //@suggestedfix("}", "refactor.rewrite", "Fill") +diff -urN a/gopls/internal/lsp/testdata/semantic/b.go b/gopls/internal/lsp/testdata/semantic/b.go +--- a/gopls/internal/lsp/testdata/semantic/b.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/semantic/b.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,38 +0,0 @@ +-package semantictokens //@ semantic("") - --type nestedStructWithTypeParams struct { -- bar string -- basic basicStructWithTypeParams[int] +-func f(x ...interface{}) { -} - --var _ = nestedStructWithTypeParams{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --func _[T any]() { -- type S struct{ t T } -- _ = S{ -- t: *new(T), -- } //@suggestedfix("}", "refactor.rewrite", "Fill") +-func weirⰀd() { /*😀*/ // comment +- const ( +- snil = nil +- nil = true +- true = false +- false = snil +- cmd = `foof` +- double = iota +- iota = copy +- four = (len(cmd)/2 < 5) +- five = four +- ) +- f(cmd, nil, double, iota) -} - -diff -urN a/gopls/internal/lsp/testdata/func_rank/func_rank.go.in b/gopls/internal/lsp/testdata/func_rank/func_rank.go.in ---- a/gopls/internal/lsp/testdata/func_rank/func_rank.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/func_rank/func_rank.go.in 1970-01-01 08:00:00 -@@ -1,70 +0,0 @@ --package func_rank +-/* - --import "net/http" +-multiline */ /* +-multiline +-*/ +-type AA int +-type BB struct { +- AA +-} +-type CC struct { +- AA int +-} +-type D func(aa AA) (BB error) +-type E func(AA) BB - --var stringAVar = "var" //@item(stringAVar, "stringAVar", "string", "var") --func stringBFunc() string { return "str" } //@item(stringBFunc, "stringBFunc", "func() string", "func") --type stringer struct{} //@item(stringer, "stringer", "struct{...}", "struct") +-var a chan<- chan int +-var b chan<- <-chan int +-var c <-chan <-chan int +diff -urN a/gopls/internal/lsp/testdata/semantic/b.go.golden b/gopls/internal/lsp/testdata/semantic/b.go.golden +--- a/gopls/internal/lsp/testdata/semantic/b.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/semantic/b.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,40 +0,0 @@ +--- semantic -- +-/*⇒7,keyword,[]*/package /*⇒14,namespace,[]*/semantictokens /*⇒16,comment,[]*///@ semantic("") - --func _() stringer //@complete("tr", stringer) +-/*⇒4,keyword,[]*/func /*⇒1,function,[definition]*/f(/*⇒1,parameter,[definition]*/x /*⇒3,operator,[]*/.../*⇒9,keyword,[]*/interface{}) { +-} - --func _(val stringer) {} //@complete("tr", stringer) +-/*⇒4,keyword,[]*/func /*⇒6,function,[definition]*/weirⰀd() { /*⇒5,comment,[]*//*😀*/ /*⇒10,comment,[]*/// comment +- /*⇒5,keyword,[]*/const ( +- /*⇒4,variable,[definition readonly]*/snil = /*⇒3,variable,[readonly defaultLibrary]*/nil +- /*⇒3,variable,[definition readonly]*/nil = /*⇒4,variable,[readonly]*/true +- /*⇒4,variable,[definition readonly]*/true = /*⇒5,variable,[readonly]*/false +- /*⇒5,variable,[definition readonly]*/false = /*⇒4,variable,[readonly]*/snil +- /*⇒3,variable,[definition readonly]*/cmd = /*⇒6,string,[]*/`foof` +- /*⇒6,variable,[definition readonly]*/double = /*⇒4,variable,[readonly]*/iota +- /*⇒4,variable,[definition readonly]*/iota = /*⇒4,function,[defaultLibrary]*/copy +- /*⇒4,variable,[definition readonly]*/four = (/*⇒3,function,[defaultLibrary]*/len(/*⇒3,variable,[readonly]*/cmd)/*⇒1,operator,[]*// /*⇒1,number,[]*/2 /*⇒1,operator,[]*/< /*⇒1,number,[]*/5) +- /*⇒4,variable,[definition readonly]*/five = /*⇒4,variable,[readonly]*/four +- ) +- /*⇒1,function,[]*/f(/*⇒3,variable,[readonly]*/cmd, /*⇒3,variable,[readonly]*/nil, /*⇒6,variable,[readonly]*/double, /*⇒4,variable,[readonly]*/iota) +-} - --func (stringer) _() {} //@complete("tr", stringer) +-/*⇒2,comment,[]*//* +-/*⇒0,comment,[]*/ +-/*⇒12,comment,[]*/multiline */ /*⇒2,comment,[]*//* +-/*⇒9,comment,[]*/multiline +-/*⇒2,comment,[]*/*/ +-/*⇒4,keyword,[]*/type /*⇒2,type,[definition]*/AA /*⇒3,type,[defaultLibrary]*/int +-/*⇒4,keyword,[]*/type /*⇒2,type,[definition]*/BB /*⇒6,keyword,[]*/struct { +- /*⇒2,type,[]*/AA +-} +-/*⇒4,keyword,[]*/type /*⇒2,type,[definition]*/CC /*⇒6,keyword,[]*/struct { +- /*⇒2,variable,[definition]*/AA /*⇒3,type,[defaultLibrary]*/int +-} +-/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/D /*⇒4,keyword,[]*/func(/*⇒2,parameter,[definition]*/aa /*⇒2,type,[]*/AA) (/*⇒2,parameter,[definition]*/BB /*⇒5,type,[]*/error) +-/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/E /*⇒4,keyword,[]*/func(/*⇒2,type,[]*/AA) /*⇒2,type,[]*/BB - --func _() { -- var s struct { -- AA int //@item(rankAA, "AA", "int", "field") -- AB string //@item(rankAB, "AB", "string", "field") -- AC int //@item(rankAC, "AC", "int", "field") -- } -- fnStr := func(string) {} -- fnStr(s.A) //@complete(")", rankAB, rankAA, rankAC) -- fnStr("" + s.A) //@complete(")", rankAB, rankAA, rankAC) +-/*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/a /*⇒4,keyword,[]*/chan/*⇒2,operator,[]*/<- /*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int +-/*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/b /*⇒4,keyword,[]*/chan/*⇒2,operator,[]*/<- /*⇒2,operator,[]*/<-/*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int +-/*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/c /*⇒2,operator,[]*/<-/*⇒4,keyword,[]*/chan /*⇒2,operator,[]*/<-/*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int - -- fnInt := func(int) {} -- fnInt(-s.A) //@complete(")", rankAA, rankAC, rankAB) +diff -urN a/gopls/internal/lsp/testdata/semantic/README.md b/gopls/internal/lsp/testdata/semantic/README.md +--- a/gopls/internal/lsp/testdata/semantic/README.md 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/semantic/README.md 1970-01-01 00:00:00.000000000 +0000 +@@ -1,2 +0,0 @@ +-The golden files are the output of `gopls semtok `, with `-- semantic --` +-inserted as the first line (the spaces are mandatory) and an extra newline at the end. +diff -urN a/gopls/internal/lsp/testdata/semantic/semantic_test.go b/gopls/internal/lsp/testdata/semantic/semantic_test.go +--- a/gopls/internal/lsp/testdata/semantic/semantic_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/semantic/semantic_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package semantictokens - -- // no expected type -- fnInt(func() int { s.A }) //@complete(" }", rankAA, rankAB, rankAC) -- fnInt(s.A()) //@complete("()", rankAA, rankAC, rankAB) -- fnInt([]int{}[s.A]) //@complete("])", rankAA, rankAC, rankAB) -- fnInt([]int{}[:s.A]) //@complete("])", rankAA, rankAC, rankAB) +-import ( +- "os" +- "testing" +-) - -- fnInt(s.A.(int)) //@complete(".(", rankAA, rankAC, rankAB) +-func TestSemanticTokens(t *testing.T) { +- a, _ := os.Getwd() +- // climb up to find internal/lsp +- // find all the .go files - -- fnPtr := func(*string) {} -- fnPtr(&s.A) //@complete(")", rankAB, rankAA, rankAC) +-} +diff -urN a/gopls/internal/lsp/testdata/stub/other/other.go b/gopls/internal/lsp/testdata/stub/other/other.go +--- a/gopls/internal/lsp/testdata/stub/other/other.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/other/other.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,10 +0,0 @@ +-package other - -- var aaPtr *string //@item(rankAAPtr, "aaPtr", "*string", "var") -- var abPtr *int //@item(rankABPtr, "abPtr", "*int", "var") -- fnInt(*a) //@complete(")", rankABPtr, rankAAPtr) +-import ( +- "bytes" +- renamed_context "context" +-) - -- _ = func() string { -- return s.A //@complete(" //", rankAB, rankAA, rankAC) -- } +-type Interface interface { +- Get(renamed_context.Context) *bytes.Buffer -} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_add_selector.go b/gopls/internal/lsp/testdata/stub/stub_add_selector.go +--- a/gopls/internal/lsp/testdata/stub/stub_add_selector.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_add_selector.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +-package stub - --type foo struct { -- fooPrivateField int //@item(rankFooPrivField, "fooPrivateField", "int", "field") -- FooPublicField int //@item(rankFooPubField, "FooPublicField", "int", "field") --} +-import "io" - --func (foo) fooPrivateMethod() int { //@item(rankFooPrivMeth, "fooPrivateMethod", "func() int", "method") -- return 0 --} +-// This file tests that if an interface +-// method references a type from its own package +-// then our implementation must add the import/package selector +-// in the concrete method if the concrete type is outside of the interface +-// package +-var _ io.ReaderFrom = &readerFrom{} //@suggestedfix("&readerFrom", "quickfix", "") - --func (foo) FooPublicMethod() int { //@item(rankFooPubMeth, "FooPublicMethod", "func() int", "method") -- return 0 --} +-type readerFrom struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_add_selector.go.golden b/gopls/internal/lsp/testdata/stub/stub_add_selector.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_add_selector.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_add_selector.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,19 +0,0 @@ +--- suggestedfix_stub_add_selector_10_23 -- +-package stub - --func _() { -- var _ int = foo{}. //@rank(" //", rankFooPrivField, rankFooPubField),rank(" //", rankFooPrivMeth, rankFooPubMeth),rank(" //", rankFooPrivField, rankFooPrivMeth) --} +-import "io" - --func _() { -- HandleFunc //@item(httpHandleFunc, "HandleFunc", "func(pattern string, handler func(http.ResponseWriter, *http.Request))", "func") -- HandlerFunc //@item(httpHandlerFunc, "HandlerFunc", "func(http.ResponseWriter, *http.Request)", "type") +-// This file tests that if an interface +-// method references a type from its own package +-// then our implementation must add the import/package selector +-// in the concrete method if the concrete type is outside of the interface +-// package +-var _ io.ReaderFrom = &readerFrom{} //@suggestedfix("&readerFrom", "quickfix", "") - -- http.HandleFunc //@rank(" //", httpHandleFunc, httpHandlerFunc) +-type readerFrom struct{} +- +-// ReadFrom implements io.ReaderFrom. +-func (*readerFrom) ReadFrom(r io.Reader) (n int64, err error) { +- panic("unimplemented") -} -diff -urN a/gopls/internal/lsp/testdata/funcsig/func_sig.go b/gopls/internal/lsp/testdata/funcsig/func_sig.go ---- a/gopls/internal/lsp/testdata/funcsig/func_sig.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/funcsig/func_sig.go 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --package funcsig - --type someType int //@item(sigSomeType, "someType", "int", "type") +diff -urN a/gopls/internal/lsp/testdata/stub/stub_assign.go b/gopls/internal/lsp/testdata/stub/stub_assign.go +--- a/gopls/internal/lsp/testdata/stub/stub_assign.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_assign.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,10 +0,0 @@ +-package stub - --// Don't complete "foo" in signature. --func (foo someType) _() { //@item(sigFoo, "foo", "someType", "var"),complete(") {", sigSomeType) +-import "io" - -- //@complete("", sigFoo, sigSomeType) +-func main() { +- var br io.ByteWriter +- br = &byteWriter{} //@suggestedfix("&", "quickfix", "") -} -diff -urN a/gopls/internal/lsp/testdata/funcvalue/func_value.go b/gopls/internal/lsp/testdata/funcvalue/func_value.go ---- a/gopls/internal/lsp/testdata/funcvalue/func_value.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/funcvalue/func_value.go 1970-01-01 08:00:00 -@@ -1,27 +0,0 @@ --package funcvalue - --func fooFunc() int { //@item(fvFooFunc, "fooFunc", "func() int", "func") -- return 0 --} +-type byteWriter struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_assign.go.golden b/gopls/internal/lsp/testdata/stub/stub_assign.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_assign.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_assign.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,17 +0,0 @@ +--- suggestedfix_stub_assign_7_7 -- +-package stub - --var _ = fooFunc() //@item(fvFooFuncCall, "fooFunc", "func() int", "func") +-import "io" - --var fooVar = func() int { //@item(fvFooVar, "fooVar", "func() int", "var") -- return 0 +-func main() { +- var br io.ByteWriter +- br = &byteWriter{} //@suggestedfix("&", "quickfix", "") -} - --var _ = fooVar() //@item(fvFooVarCall, "fooVar", "func() int", "var") -- --type myFunc func() int +-type byteWriter struct{} - --var fooType myFunc = fooVar //@item(fvFooType, "fooType", "myFunc", "var") +-// WriteByte implements io.ByteWriter. +-func (*byteWriter) WriteByte(c byte) error { +- panic("unimplemented") +-} - --var _ = fooType() //@item(fvFooTypeCall, "fooType", "func() int", "var") +diff -urN a/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go b/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go +--- a/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package stub - --func _() { -- var f func() int -- f = foo //@complete(" //", fvFooFunc, fvFooType, fvFooVar) +-import "io" - +-func main() { +- var br io.ByteWriter - var i int -- i = foo //@complete(" //", fvFooFuncCall, fvFooTypeCall, fvFooVarCall) +- i, br = 1, &multiByteWriter{} //@suggestedfix("&", "quickfix", "") -} -diff -urN a/gopls/internal/lsp/testdata/fuzzymatch/fuzzymatch.go b/gopls/internal/lsp/testdata/fuzzymatch/fuzzymatch.go ---- a/gopls/internal/lsp/testdata/fuzzymatch/fuzzymatch.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fuzzymatch/fuzzymatch.go 1970-01-01 08:00:00 -@@ -1,48 +0,0 @@ --// 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 fuzzy +-type multiByteWriter struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go.golden b/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +--- suggestedfix_stub_assign_multivars_8_13 -- +-package stub - --func _() { -- var a struct { -- fabar int -- fooBar string -- } +-import "io" - -- a.fabar //@item(fuzzFabarField, "a.fabar", "int", "field") -- a.fooBar //@item(fuzzFooBarField, "a.fooBar", "string", "field") +-func main() { +- var br io.ByteWriter +- var i int +- i, br = 1, &multiByteWriter{} //@suggestedfix("&", "quickfix", "") +-} - -- afa //@fuzzy(" //", fuzzFabarField, fuzzFooBarField) -- afb //@fuzzy(" //", fuzzFooBarField, fuzzFabarField) +-type multiByteWriter struct{} - -- fab //@fuzzy(" //", fuzzFabarField) +-// WriteByte implements io.ByteWriter. +-func (*multiByteWriter) WriteByte(c byte) error { +- panic("unimplemented") +-} - -- var myString string -- myString = af //@fuzzy(" //", fuzzFooBarField, fuzzFabarField) +diff -urN a/gopls/internal/lsp/testdata/stub/stub_call_expr.go b/gopls/internal/lsp/testdata/stub/stub_call_expr.go +--- a/gopls/internal/lsp/testdata/stub/stub_call_expr.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_call_expr.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package stub - -- var b struct { -- c struct { -- d struct { -- e struct { -- abc string -- } -- abc float32 -- } -- abc bool -- } -- abc int +-func main() { +- check(&callExpr{}) //@suggestedfix("&", "quickfix", "") +-} +- +-func check(err error) { +- if err != nil { +- panic(err) - } +-} - -- b.abc //@item(fuzzABCInt, "b.abc", "int", "field") -- b.c.abc //@item(fuzzABCbool, "b.c.abc", "bool", "field") -- b.c.d.abc //@item(fuzzABCfloat, "b.c.d.abc", "float32", "field") -- b.c.d.e.abc //@item(fuzzABCstring, "b.c.d.e.abc", "string", "field") +-type callExpr struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_call_expr.go.golden b/gopls/internal/lsp/testdata/stub/stub_call_expr.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_call_expr.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_call_expr.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,20 +0,0 @@ +--- suggestedfix_stub_call_expr_4_8 -- +-package stub - -- // in depth order by default -- abc //@fuzzy(" //", fuzzABCInt, fuzzABCbool, fuzzABCfloat) +-func main() { +- check(&callExpr{}) //@suggestedfix("&", "quickfix", "") +-} - -- // deep candidate that matches expected type should still ranked first -- var s string -- s = abc //@fuzzy(" //", fuzzABCstring, fuzzABCInt, fuzzABCbool) +-func check(err error) { +- if err != nil { +- panic(err) +- } -} -diff -urN a/gopls/internal/lsp/testdata/good/good0.go b/gopls/internal/lsp/testdata/good/good0.go ---- a/gopls/internal/lsp/testdata/good/good0.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/good/good0.go 1970-01-01 08:00:00 -@@ -1,6 +0,0 @@ --package good - --func stuff() { //@item(good_stuff, "stuff", "func()", "func"),prepare("stu", "stuff", "stuff") -- x := 5 -- random2(x) //@prepare("dom", "random2", "random2") +-type callExpr struct{} +- +-// Error implements error. +-func (*callExpr) Error() string { +- panic("unimplemented") -} -diff -urN a/gopls/internal/lsp/testdata/good/good1.go b/gopls/internal/lsp/testdata/good/good1.go ---- a/gopls/internal/lsp/testdata/good/good1.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/good/good1.go 1970-01-01 08:00:00 -@@ -1,21 +0,0 @@ --package good +- +diff -urN a/gopls/internal/lsp/testdata/stub/stub_embedded.go b/gopls/internal/lsp/testdata/stub/stub_embedded.go +--- a/gopls/internal/lsp/testdata/stub/stub_embedded.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_embedded.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +-package stub - -import ( -- "golang.org/lsptests/types" //@item(types_import, "types", "\"golang.org/lsptests/types\"", "package") +- "io" +- "sort" -) - --func random() int { //@item(good_random, "random", "func() int", "func") -- _ = "random() int" //@prepare("random", "", "") -- y := 6 + 7 //@prepare("7", "", "") -- return y //@prepare("return", "","") --} +-var _ embeddedInterface = (*embeddedConcrete)(nil) //@suggestedfix("(", "quickfix", "") - --func random2(y int) int { //@item(good_random2, "random2", "func(y int) int", "func"),item(good_y_param, "y", "int", "var") -- //@complete("", good_y_param, types_import, good_random, good_random2, good_stuff) -- var b types.Bob = &types.X{} //@prepare("ypes","types", "types") -- if _, ok := b.(*types.X); ok { //@complete("X", X_struct, Y_struct, Bob_interface, CoolAlias) -- _ = 0 // suppress "empty branch" diagnostic -- } +-type embeddedConcrete struct{} - -- return y +-type embeddedInterface interface { +- sort.Interface +- io.Reader -} -diff -urN a/gopls/internal/lsp/testdata/importedcomplit/imported_complit.go.in b/gopls/internal/lsp/testdata/importedcomplit/imported_complit.go.in ---- a/gopls/internal/lsp/testdata/importedcomplit/imported_complit.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/importedcomplit/imported_complit.go.in 1970-01-01 08:00:00 -@@ -1,54 +0,0 @@ --package importedcomplit +diff -urN a/gopls/internal/lsp/testdata/stub/stub_embedded.go.golden b/gopls/internal/lsp/testdata/stub/stub_embedded.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_embedded.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_embedded.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,37 +0,0 @@ +--- suggestedfix_stub_embedded_8_27 -- +-package stub - -import ( -- // TODO(rfindley): re-enable after moving to new framework -- // "golang.org/lsptests/foo" -- -- // import completions (separate blocks to avoid comment alignment) -- "crypto/elli" //@complete("\" //", cryptoImport) +- "io" +- "sort" +-) - -- "fm" //@complete("\" //", fmtImport) +-var _ embeddedInterface = (*embeddedConcrete)(nil) //@suggestedfix("(", "quickfix", "") - -- "go/pars" //@complete("\" //", parserImport) +-type embeddedConcrete struct{} - -- namedParser "go/pars" //@complete("\" //", parserImport) +-// Len implements embeddedInterface. +-func (*embeddedConcrete) Len() int { +- panic("unimplemented") +-} - -- "golang.org/lspte" //@complete("\" //", lsptestsImport) +-// Less implements embeddedInterface. +-func (*embeddedConcrete) Less(i int, j int) bool { +- panic("unimplemented") +-} - -- "golang.org/lsptests/sign" //@complete("\" //", signatureImport) +-// Read implements embeddedInterface. +-func (*embeddedConcrete) Read(p []byte) (n int, err error) { +- panic("unimplemented") +-} - -- "golang.org/lsptests/sign" //@complete("ests", lsptestsImport) +-// Swap implements embeddedInterface. +-func (*embeddedConcrete) Swap(i int, j int) { +- panic("unimplemented") +-} - -- "golang.org/lsptests/signa" //@complete("na\" //", signatureImport) --) +-type embeddedInterface interface { +- sort.Interface +- io.Reader +-} - --func _() { -- var V int //@item(icVVar, "V", "int", "var") +diff -urN a/gopls/internal/lsp/testdata/stub/stub_err.go b/gopls/internal/lsp/testdata/stub/stub_err.go +--- a/gopls/internal/lsp/testdata/stub/stub_err.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_err.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package stub - -- // TODO(rfindley): re-enable after moving to new framework -- // _ = foo.StructFoo{V} // complete("}", Value, icVVar) +-func main() { +- var br error = &customErr{} //@suggestedfix("&", "quickfix", "") -} - --func _() { -- var ( -- aa string //@item(icAAVar, "aa", "string", "var") -- ab int //@item(icABVar, "ab", "int", "var") -- ) +-type customErr struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_err.go.golden b/gopls/internal/lsp/testdata/stub/stub_err.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_err.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_err.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +--- suggestedfix_stub_err_4_17 -- +-package stub - -- // TODO(rfindley): re-enable after moving to new framework -- // _ = foo.StructFoo{a} // complete("}", abVar, aaVar) +-func main() { +- var br error = &customErr{} //@suggestedfix("&", "quickfix", "") +-} - -- var s struct { -- AA string //@item(icFieldAA, "AA", "string", "field") -- AB int //@item(icFieldAB, "AB", "int", "field") -- } +-type customErr struct{} - -- // TODO(rfindley): re-enable after moving to new framework -- //_ = foo.StructFoo{s.} // complete("}", icFieldAB, icFieldAA) +-// Error implements error. +-func (*customErr) Error() string { +- panic("unimplemented") -} - --/* "fmt" */ //@item(fmtImport, "fmt", "\"fmt\"", "package") --/* "go/parser" */ //@item(parserImport, "parser", "\"go/parser\"", "package") --/* "golang.org/lsptests/signature" */ //@item(signatureImport, "signature", "\"golang.org/lsptests/signature\"", "package") --/* "golang.org/lsptests/" */ //@item(lsptestsImport, "lsptests/", "\"golang.org/lsptests/\"", "package") --/* "crypto/elliptic" */ //@item(cryptoImport, "elliptic", "\"crypto/elliptic\"", "package") -diff -urN a/gopls/internal/lsp/testdata/index/index.go b/gopls/internal/lsp/testdata/index/index.go ---- a/gopls/internal/lsp/testdata/index/index.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/index/index.go 1970-01-01 08:00:00 -@@ -1,25 +0,0 @@ --package index +diff -urN a/gopls/internal/lsp/testdata/stub/stub_function_return.go b/gopls/internal/lsp/testdata/stub/stub_function_return.go +--- a/gopls/internal/lsp/testdata/stub/stub_function_return.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_function_return.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package stub - --func _() { -- var ( -- aa = "123" //@item(indexAA, "aa", "string", "var") -- ab = 123 //@item(indexAB, "ab", "int", "var") -- ) +-import ( +- "io" +-) - -- var foo [1]int -- foo[a] //@complete("]", indexAB, indexAA) -- foo[:a] //@complete("]", indexAB, indexAA) -- a[:a] //@complete("[", indexAA, indexAB) -- a[a] //@complete("[", indexAA, indexAB) +-func newCloser() io.Closer { +- return closer{} //@suggestedfix("c", "quickfix", "") +-} - -- var bar map[string]int -- bar[a] //@complete("]", indexAA, indexAB) +-type closer struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_function_return.go.golden b/gopls/internal/lsp/testdata/stub/stub_function_return.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_function_return.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_function_return.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +--- suggestedfix_stub_function_return_8_9 -- +-package stub - -- type myMap map[string]int -- var baz myMap -- baz[a] //@complete("]", indexAA, indexAB) +-import ( +- "io" +-) - -- type myInt int -- var mi myInt //@item(indexMyInt, "mi", "myInt", "var") -- foo[m] //@snippet("]", indexMyInt, "mi", "mi") +-func newCloser() io.Closer { +- return closer{} //@suggestedfix("c", "quickfix", "") -} -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go b/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go ---- a/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go 1970-01-01 08:00:00 -@@ -1,27 +0,0 @@ --package inlayHint //@inlayHint("package") - --import "fmt" +-type closer struct{} - --func fieldNames() { -- for _, c := range []struct { -- in, want string -- }{ -- struct{ in, want string }{"Hello, world", "dlrow ,olleH"}, -- {"Hello, 世界", "界世 ,olleH"}, -- {"", ""}, -- } { -- fmt.Println(c.in == c.want) -- } +-// Close implements io.Closer. +-func (closer) Close() error { +- panic("unimplemented") -} - --func fieldNamesPointers() { -- for _, c := range []*struct { -- in, want string -- }{ -- &struct{ in, want string }{"Hello, world", "dlrow ,olleH"}, -- {"Hello, 世界", "界世 ,olleH"}, -- {"", ""}, -- } { -- fmt.Println(c.in == c.want) -- } +diff -urN a/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go b/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go +--- a/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +-//go:build go1.18 +-// +build go1.18 +- +-package stub +- +-import "io" +- +-// This file tests that that the stub method generator accounts for concrete +-// types that have type parameters defined. +-var _ io.ReaderFrom = &genReader[string, int]{} //@suggestedfix("&genReader", "quickfix", "Implement io.ReaderFrom") +- +-type genReader[T, Y any] struct { +- T T +- Y Y -} -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go.golden b/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go.golden ---- a/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go.golden 1970-01-01 08:00:00 -@@ -1,29 +0,0 @@ ---- inlayHint -- --package inlayHint //@inlayHint("package") +diff -urN a/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go.golden b/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,22 +0,0 @@ +--- suggestedfix_stub_generic_receiver_10_23 -- +-//go:build go1.18 +-// +build go1.18 - --import "fmt" +-package stub - --func fieldNames() { -- for _< int>, c< struct{in string; want string}> := range []struct { -- in, want string -- }{ -- struct{ in, want string }{"Hello, world", "dlrow ,olleH"}, -- {"Hello, 世界", "界世 ,olleH"}, -- {"", ""}, -- } { -- fmt.Println(c.in == c.want) -- } +-import "io" +- +-// This file tests that that the stub method generator accounts for concrete +-// types that have type parameters defined. +-var _ io.ReaderFrom = &genReader[string, int]{} //@suggestedfix("&genReader", "quickfix", "Implement io.ReaderFrom") +- +-type genReader[T, Y any] struct { +- T T +- Y Y -} - --func fieldNamesPointers() { -- for _< int>, c< *struct{in string; want string}> := range []*struct { -- in, want string -- }{ -- &struct{ in, want string }{"Hello, world", "dlrow ,olleH"}, -- <&struct{in string; want string}>{"Hello, 世界", "界世 ,olleH"}, -- <&struct{in string; want string}>{"", ""}, -- } { -- fmt.Println(c.in == c.want) -- } +-// ReadFrom implements io.ReaderFrom. +-func (*genReader[T, Y]) ReadFrom(r io.Reader) (n int64, err error) { +- panic("unimplemented") -} - -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/constant_values.go b/gopls/internal/lsp/testdata/inlay_hint/constant_values.go ---- a/gopls/internal/lsp/testdata/inlay_hint/constant_values.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/constant_values.go 1970-01-01 08:00:00 -@@ -1,45 +0,0 @@ --package inlayHint //@inlayHint("package") +diff -urN a/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go b/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go +--- a/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +-package stub - --const True = true +-import ( +- "compress/zlib" +- . "io" +- _ "io" +-) - --type Kind int +-// This file tests that dot-imports and underscore imports +-// are properly ignored and that a new import is added to +-// reference method types - --const ( -- KindNone Kind = iota -- KindPrint -- KindPrintf -- KindErrorf +-var ( +- _ Reader +- _ zlib.Resetter = (*ignoredResetter)(nil) //@suggestedfix("(", "quickfix", "") -) - --const ( -- u = iota * 4 -- v float64 = iota * 42 -- w = iota * 42 --) +-type ignoredResetter struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go.golden b/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,25 +0,0 @@ +--- suggestedfix_stub_ignored_imports_15_20 -- +-package stub - --const ( -- a, b = 1, 2 -- c, d -- e, f = 5 * 5, "hello" + "world" -- g, h -- i, j = true, f +-import ( +- "compress/zlib" +- . "io" +- _ "io" -) - --// No hint --const ( -- Int = 3 -- Float = 3.14 -- Bool = true -- Rune = '3' -- Complex = 2.7i -- String = "Hello, world!" --) +-// This file tests that dot-imports and underscore imports +-// are properly ignored and that a new import is added to +-// reference method types - -var ( -- varInt = 3 -- varFloat = 3.14 -- varBool = true -- varRune = '3' + '4' -- varComplex = 2.7i -- varString = "Hello, world!" +- _ Reader +- _ zlib.Resetter = (*ignoredResetter)(nil) //@suggestedfix("(", "quickfix", "") -) -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/constant_values.go.golden b/gopls/internal/lsp/testdata/inlay_hint/constant_values.go.golden ---- a/gopls/internal/lsp/testdata/inlay_hint/constant_values.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/constant_values.go.golden 1970-01-01 08:00:00 -@@ -1,47 +0,0 @@ ---- inlayHint -- --package inlayHint //@inlayHint("package") - --const True = true +-type ignoredResetter struct{} - --type Kind int +-// Reset implements zlib.Resetter. +-func (*ignoredResetter) Reset(r Reader, dict []byte) error { +- panic("unimplemented") +-} - --const ( -- KindNone Kind = iota< = 0> -- KindPrint< = 1> -- KindPrintf< = 2> -- KindErrorf< = 3> --) +diff -urN a/gopls/internal/lsp/testdata/stub/stub_issue2606.go b/gopls/internal/lsp/testdata/stub/stub_issue2606.go +--- a/gopls/internal/lsp/testdata/stub/stub_issue2606.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_issue2606.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package stub - --const ( -- u = iota * 4< = 0> -- v float64 = iota * 42< = 42> -- w = iota * 42< = 84> --) +-type I interface{ error } - --const ( -- a, b = 1, 2 -- c, d< = 1, 2> -- e, f = 5 * 5, "hello" + "world"< = 25, "helloworld"> -- g, h< = 25, "helloworld"> -- i, j = true, f< = true, "helloworld"> --) +-type C int - --// No hint --const ( -- Int = 3 -- Float = 3.14 -- Bool = true -- Rune = '3' -- Complex = 2.7i -- String = "Hello, world!" --) -- --var ( -- varInt = 3 -- varFloat = 3.14 -- varBool = true -- varRune = '3' + '4' -- varComplex = 2.7i -- varString = "Hello, world!" --) -- -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go b/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go ---- a/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go 1970-01-01 08:00:00 -@@ -1,50 +0,0 @@ --package inlayHint //@inlayHint("package") -- --import "fmt" -- --func hello(name string) string { -- return "Hello " + name --} +-var _ I = C(0) //@suggestedfix("C", "quickfix", "") +diff -urN a/gopls/internal/lsp/testdata/stub/stub_issue2606.go.golden b/gopls/internal/lsp/testdata/stub/stub_issue2606.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_issue2606.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_issue2606.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +--- suggestedfix_stub_issue2606_7_11 -- +-package stub - --func helloWorld() string { -- return hello("World") --} +-type I interface{ error } - --type foo struct{} +-type C int - --func (*foo) bar(baz string, qux int) int { -- if baz != "" { -- return qux + 1 -- } -- return qux +-// Error implements I. +-func (C) Error() string { +- panic("unimplemented") -} - --func kase(foo int, bar bool, baz ...string) { -- fmt.Println(foo, bar, baz) --} +-var _ I = C(0) //@suggestedfix("C", "quickfix", "") - --func kipp(foo string, bar, baz string) { -- fmt.Println(foo, bar, baz) --} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_multi_var.go b/gopls/internal/lsp/testdata/stub/stub_multi_var.go +--- a/gopls/internal/lsp/testdata/stub/stub_multi_var.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_multi_var.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package stub - --func plex(foo, bar string, baz string) { -- fmt.Println(foo, bar, baz) --} +-import "io" - --func tars(foo string, bar, baz string) { -- fmt.Println(foo, bar, baz) --} +-// This test ensures that a variable declaration that +-// has multiple values on the same line can still be +-// analyzed correctly to target the interface implementation +-// diagnostic. +-var one, two, three io.Reader = nil, &multiVar{}, nil //@suggestedfix("&", "quickfix", "") - --func foobar() { -- var x foo -- x.bar("", 1) -- kase(0, true, "c", "d", "e") -- kipp("a", "b", "c") -- plex("a", "b", "c") -- tars("a", "b", "c") -- foo, bar, baz := "a", "b", "c" -- kipp(foo, bar, baz) -- plex("a", bar, baz) -- tars(foo+foo, (bar), "c") +-type multiVar struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_multi_var.go.golden b/gopls/internal/lsp/testdata/stub/stub_multi_var.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_multi_var.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_multi_var.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +--- suggestedfix_stub_multi_var_9_38 -- +-package stub - --} -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go.golden b/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go.golden ---- a/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go.golden 1970-01-01 08:00:00 -@@ -1,52 +0,0 @@ ---- inlayHint -- --package inlayHint //@inlayHint("package") +-import "io" - --import "fmt" +-// This test ensures that a variable declaration that +-// has multiple values on the same line can still be +-// analyzed correctly to target the interface implementation +-// diagnostic. +-var one, two, three io.Reader = nil, &multiVar{}, nil //@suggestedfix("&", "quickfix", "") - --func hello(name string) string { -- return "Hello " + name --} +-type multiVar struct{} - --func helloWorld() string { -- return hello("World") +-// Read implements io.Reader. +-func (*multiVar) Read(p []byte) (n int, err error) { +- panic("unimplemented") -} - --type foo struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_pointer.go b/gopls/internal/lsp/testdata/stub/stub_pointer.go +--- a/gopls/internal/lsp/testdata/stub/stub_pointer.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_pointer.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package stub - --func (*foo) bar(baz string, qux int) int { -- if baz != "" { -- return qux + 1 -- } -- return qux --} +-import "io" - --func kase(foo int, bar bool, baz ...string) { -- fmt.Println(foo, bar, baz) +-func getReaderFrom() io.ReaderFrom { +- return &pointerImpl{} //@suggestedfix("&", "quickfix", "") -} - --func kipp(foo string, bar, baz string) { -- fmt.Println(foo, bar, baz) --} +-type pointerImpl struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_pointer.go.golden b/gopls/internal/lsp/testdata/stub/stub_pointer.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_pointer.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_pointer.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +--- suggestedfix_stub_pointer_6_9 -- +-package stub - --func plex(foo, bar string, baz string) { -- fmt.Println(foo, bar, baz) --} +-import "io" - --func tars(foo string, bar, baz string) { -- fmt.Println(foo, bar, baz) +-func getReaderFrom() io.ReaderFrom { +- return &pointerImpl{} //@suggestedfix("&", "quickfix", "") -} - --func foobar() { -- var x foo -- x.bar("", 1) -- kase(0, true, "c", "d", "e") -- kipp("a", "b", "c") -- plex("a", "b", "c") -- tars("a", "b", "c") -- foo< string>, bar< string>, baz< string> := "a", "b", "c" -- kipp(foo, bar, baz) -- plex("a", bar, baz) -- tars(foo+foo, (bar), "c") +-type pointerImpl struct{} - +-// ReadFrom implements io.ReaderFrom. +-func (*pointerImpl) ReadFrom(r io.Reader) (n int64, err error) { +- panic("unimplemented") -} - -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/type_params.go b/gopls/internal/lsp/testdata/inlay_hint/type_params.go ---- a/gopls/internal/lsp/testdata/inlay_hint/type_params.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/type_params.go 1970-01-01 08:00:00 -@@ -1,45 +0,0 @@ --//go:build go1.18 --// +build go1.18 +diff -urN a/gopls/internal/lsp/testdata/stub/stub_renamed_import.go b/gopls/internal/lsp/testdata/stub/stub_renamed_import.go +--- a/gopls/internal/lsp/testdata/stub/stub_renamed_import.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_renamed_import.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package stub - --package inlayHint //@inlayHint("package") +-import ( +- "compress/zlib" +- myio "io" +-) - --func main() { -- ints := map[string]int64{ -- "first": 34, -- "second": 12, -- } +-var _ zlib.Resetter = &myIO{} //@suggestedfix("&", "quickfix", "") +-var _ myio.Reader - -- floats := map[string]float64{ -- "first": 35.98, -- "second": 26.99, -- } +-type myIO struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_renamed_import.go.golden b/gopls/internal/lsp/testdata/stub/stub_renamed_import.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_renamed_import.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_renamed_import.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +--- suggestedfix_stub_renamed_import_8_23 -- +-package stub - -- SumIntsOrFloats[string, int64](ints) -- SumIntsOrFloats[string, float64](floats) +-import ( +- "compress/zlib" +- myio "io" +-) - -- SumIntsOrFloats(ints) -- SumIntsOrFloats(floats) +-var _ zlib.Resetter = &myIO{} //@suggestedfix("&", "quickfix", "") +-var _ myio.Reader - -- SumNumbers(ints) -- SumNumbers(floats) --} +-type myIO struct{} - --type Number interface { -- int64 | float64 +-// Reset implements zlib.Resetter. +-func (*myIO) Reset(r myio.Reader, dict []byte) error { +- panic("unimplemented") -} - --func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V { -- var s V -- for _, v := range m { -- s += v -- } -- return s --} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go b/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go +--- a/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package stub - --func SumNumbers[K comparable, V Number](m map[K]V) V { -- var s V -- for _, v := range m { -- s += v -- } -- return s --} -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/type_params.go.golden b/gopls/internal/lsp/testdata/inlay_hint/type_params.go.golden ---- a/gopls/internal/lsp/testdata/inlay_hint/type_params.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/type_params.go.golden 1970-01-01 08:00:00 -@@ -1,47 +0,0 @@ ---- inlayHint -- --//go:build go1.18 --// +build go1.18 +-import ( +- "golang.org/lsptests/stub/other" +-) - --package inlayHint //@inlayHint("package") +-// This file tests that if an interface +-// method references an import from its own package +-// that the concrete type does not yet import, and that import happens +-// to be renamed, then we prefer the renaming of the interface. +-var _ other.Interface = &otherInterfaceImpl{} //@suggestedfix("&otherInterfaceImpl", "quickfix", "") - --func main() { -- ints< map[string]int64> := map[string]int64{ -- "first": 34, -- "second": 12, -- } +-type otherInterfaceImpl struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go.golden b/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,22 +0,0 @@ +--- suggestedfix_stub_renamed_import_iface_11_25 -- +-package stub - -- floats< map[string]float64> := map[string]float64{ -- "first": 35.98, -- "second": 26.99, -- } +-import ( +- "bytes" +- "context" +- "golang.org/lsptests/stub/other" +-) - -- SumIntsOrFloats[string, int64](ints) -- SumIntsOrFloats[string, float64](floats) +-// This file tests that if an interface +-// method references an import from its own package +-// that the concrete type does not yet import, and that import happens +-// to be renamed, then we prefer the renaming of the interface. +-var _ other.Interface = &otherInterfaceImpl{} //@suggestedfix("&otherInterfaceImpl", "quickfix", "") - -- SumIntsOrFloats<[string, int64]>(ints) -- SumIntsOrFloats<[string, float64]>(floats) +-type otherInterfaceImpl struct{} - -- SumNumbers<[string, int64]>(ints) -- SumNumbers<[string, float64]>(floats) +-// Get implements other.Interface. +-func (*otherInterfaceImpl) Get(context.Context) *bytes.Buffer { +- panic("unimplemented") -} - --type Number interface { -- int64 | float64 --} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_stdlib.go b/gopls/internal/lsp/testdata/stub/stub_stdlib.go +--- a/gopls/internal/lsp/testdata/stub/stub_stdlib.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_stdlib.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package stub - --func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V { -- var s V -- for _< K>, v< V> := range m { -- s += v -- } -- return s --} +-import ( +- "io" +-) - --func SumNumbers[K comparable, V Number](m map[K]V) V { -- var s V -- for _< K>, v< V> := range m { -- s += v -- } -- return s --} +-var _ io.Writer = writer{} //@suggestedfix("w", "quickfix", "") - -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/variable_types.go b/gopls/internal/lsp/testdata/inlay_hint/variable_types.go ---- a/gopls/internal/lsp/testdata/inlay_hint/variable_types.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/variable_types.go 1970-01-01 08:00:00 -@@ -1,20 +0,0 @@ --package inlayHint //@inlayHint("package") +-type writer struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_stdlib.go.golden b/gopls/internal/lsp/testdata/stub/stub_stdlib.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_stdlib.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_stdlib.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +--- suggestedfix_stub_stdlib_7_19 -- +-package stub - --func assignTypes() { -- i, j := 0, len([]string{})-1 -- println(i, j) --} +-import ( +- "io" +-) - --func rangeTypes() { -- for k, v := range []string{} { -- println(k, v) -- } --} +-var _ io.Writer = writer{} //@suggestedfix("w", "quickfix", "") - --func funcLitType() { -- myFunc := func(a string) string { return "" } --} +-type writer struct{} - --func compositeLitType() { -- foo := map[string]interface{}{"": ""} +-// Write implements io.Writer. +-func (writer) Write(p []byte) (n int, err error) { +- panic("unimplemented") -} -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/variable_types.go.golden b/gopls/internal/lsp/testdata/inlay_hint/variable_types.go.golden ---- a/gopls/internal/lsp/testdata/inlay_hint/variable_types.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/variable_types.go.golden 1970-01-01 08:00:00 -@@ -1,22 +0,0 @@ ---- inlayHint -- --package inlayHint //@inlayHint("package") - --func assignTypes() { -- i< int>, j< int> := 0, len([]string{})-1 -- println(i, j) --} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go b/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go +--- a/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,27 +0,0 @@ +-package stub - --func rangeTypes() { -- for k< int>, v< string> := range []string{} { -- println(k, v) -- } --} +-// Regression test for Issue #56825: file corrupted by insertion of +-// methods after TypeSpec in a parenthesized TypeDecl. - --func funcLitType() { -- myFunc< func(a string) string> := func(a string) string { return "" } --} +-import "io" - --func compositeLitType() { -- foo< map[string]interface{}> := map[string]interface{}{"": ""} +-func newReadCloser() io.ReadCloser { +- return rdcloser{} //@suggestedfix("rd", "quickfix", "") -} - -diff -urN a/gopls/internal/lsp/testdata/interfacerank/interface_rank.go b/gopls/internal/lsp/testdata/interfacerank/interface_rank.go ---- a/gopls/internal/lsp/testdata/interfacerank/interface_rank.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/interfacerank/interface_rank.go 1970-01-01 08:00:00 -@@ -1,23 +0,0 @@ --package interfacerank +-type ( +- A int +- rdcloser struct{} +- B int +-) - --type foo interface { -- foo() +-func _() { +- // Local types can't be stubbed as there's nowhere to put the methods. +- // The suggestedfix assertion can't express this yet. TODO(adonovan): support it. +- type local struct{} +- var _ io.ReadCloser = local{} // want error: `local type "local" cannot be stubbed` -} - --type fooImpl int +-type ( +- C int +-) +diff -urN a/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go.golden b/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,39 +0,0 @@ +--- suggestedfix_stub_typedecl_group_9_9 -- +-package stub - --func (*fooImpl) foo() {} +-// Regression test for Issue #56825: file corrupted by insertion of +-// methods after TypeSpec in a parenthesized TypeDecl. - --func wantsFoo(foo) {} +-import "io" - --func _() { -- var ( -- aa string //@item(irAA, "aa", "string", "var") -- ab *fooImpl //@item(irAB, "ab", "*fooImpl", "var") -- ) +-func newReadCloser() io.ReadCloser { +- return rdcloser{} //@suggestedfix("rd", "quickfix", "") +-} - -- wantsFoo(a) //@complete(")", irAB, irAA) +-type ( +- A int +- rdcloser struct{} +- B int +-) - -- var ac fooImpl //@item(irAC, "ac", "fooImpl", "var") -- wantsFoo(&a) //@complete(")", irAC, irAA, irAB) +-// Close implements io.ReadCloser. +-func (rdcloser) Close() error { +- panic("unimplemented") -} -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/boolean.go b/gopls/internal/lsp/testdata/invertifcondition/boolean.go ---- a/gopls/internal/lsp/testdata/invertifcondition/boolean.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/boolean.go 1970-01-01 08:00:00 -@@ -1,14 +0,0 @@ --package invertifcondition - --import ( -- "fmt" --) +-// Read implements io.ReadCloser. +-func (rdcloser) Read(p []byte) (n int, err error) { +- panic("unimplemented") +-} - --func Boolean() { -- b := true -- if b { //@suggestedfix("if b", "refactor.rewrite", "") -- fmt.Println("A") -- } else { -- fmt.Println("B") -- } +-func _() { +- // Local types can't be stubbed as there's nowhere to put the methods. +- // The suggestedfix assertion can't express this yet. TODO(adonovan): support it. +- type local struct{} +- var _ io.ReadCloser = local{} // want error: `local type "local" cannot be stubbed` -} -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/boolean.go.golden b/gopls/internal/lsp/testdata/invertifcondition/boolean.go.golden ---- a/gopls/internal/lsp/testdata/invertifcondition/boolean.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/boolean.go.golden 1970-01-01 08:00:00 -@@ -1,16 +0,0 @@ ---- suggestedfix_boolean_9_2 -- --package invertifcondition - --import ( -- "fmt" +-type ( +- C int -) - --func Boolean() { -- b := true -- if !b { -- fmt.Println("B") -- } else { //@suggestedfix("if b", "refactor.rewrite", "") -- fmt.Println("A") -- } --} +diff -urN a/gopls/internal/lsp/testdata/summary.txt.golden b/gopls/internal/lsp/testdata/summary.txt.golden +--- a/gopls/internal/lsp/testdata/summary.txt.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/summary.txt.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +--- summary -- +-CallHierarchyCount = 2 +-SemanticTokenCount = 3 +-SuggestedFixCount = 39 +-InlayHintsCount = 5 +-RenamesCount = 45 +-SelectionRangesCount = 3 - -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go b/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go ---- a/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go 1970-01-01 08:00:00 +diff -urN a/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go b/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go +--- a/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,5 +0,0 @@ +-package typeerrors +- +-func x() { return nil } //@suggestedfix("nil", "quickfix", "") +- +-func y() { return nil, "hello" } //@suggestedfix("nil", "quickfix", "") +diff -urN a/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go.golden b/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go.golden +--- a/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ --package invertifcondition +--- suggestedfix_noresultvalues_3_19 -- +-package typeerrors - --import ( -- "fmt" -- "os" --) +-func x() { return } //@suggestedfix("nil", "quickfix", "") - --func BooleanFn() { -- if os.IsPathSeparator('X') { //@suggestedfix("if os.IsPathSeparator('X')", "refactor.rewrite", "") -- fmt.Println("A") -- } else { -- fmt.Println("B") -- } --} -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go.golden b/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go.golden ---- a/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go.golden 1970-01-01 08:00:00 -@@ -1,16 +0,0 @@ ---- suggestedfix_boolean_fn_9_2 -- --package invertifcondition +-func y() { return nil, "hello" } //@suggestedfix("nil", "quickfix", "") - --import ( -- "fmt" -- "os" --) +--- suggestedfix_noresultvalues_5_19 -- +-package typeerrors - --func BooleanFn() { -- if !os.IsPathSeparator('X') { -- fmt.Println("B") -- } else { //@suggestedfix("if os.IsPathSeparator('X')", "refactor.rewrite", "") -- fmt.Println("A") -- } --} +-func x() { return nil } //@suggestedfix("nil", "quickfix", "") - -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go b/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go ---- a/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go 1970-01-01 08:00:00 -@@ -1,16 +0,0 @@ --package invertifcondition +-func y() { return } //@suggestedfix("nil", "quickfix", "") - --import ( -- "fmt" --) +diff -urN a/gopls/internal/lsp/tests/compare/text.go b/gopls/internal/lsp/tests/compare/text.go +--- a/gopls/internal/lsp/tests/compare/text.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/compare/text.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,49 +0,0 @@ +-// Copyright 2022 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. - --func DontRemoveParens() { -- a := false -- b := true -- if !(a || -- b) { //@suggestedfix("b", "refactor.rewrite", "") -- fmt.Println("A") -- } else { -- fmt.Println("B") -- } --} -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go.golden b/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go.golden ---- a/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go.golden 1970-01-01 08:00:00 -@@ -1,18 +0,0 @@ ---- suggestedfix_dont_remove_parens_11_3 -- --package invertifcondition +-package compare - -import ( -- "fmt" +- "bytes" +- +- "golang.org/x/tools/internal/diff" -) - --func DontRemoveParens() { -- a := false -- b := true -- if (a || -- b) { -- fmt.Println("B") -- } else { //@suggestedfix("b", "refactor.rewrite", "") -- fmt.Println("A") -- } +-// Text returns a formatted unified diff of the edits to go from want to +-// got, returning "" if and only if want == got. +-// +-// This function is intended for use in testing, and panics if any error occurs +-// while computing the diff. It is not sufficiently tested for production use. +-func Text(want, got string) string { +- return NamedText("want", "got", want, got) -} - -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/else_if.go b/gopls/internal/lsp/testdata/invertifcondition/else_if.go ---- a/gopls/internal/lsp/testdata/invertifcondition/else_if.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/else_if.go 1970-01-01 08:00:00 -@@ -1,22 +0,0 @@ --package invertifcondition +-// NamedText is like text, but allows passing custom names of the 'want' and +-// 'got' content. +-func NamedText(wantName, gotName, want, got string) string { +- if want == got { +- return "" +- } - --import ( -- "fmt" -- "os" --) +- // Add newlines to avoid verbose newline messages ("No newline at end of file"). +- unified := diff.Unified(wantName, gotName, want+"\n", got+"\n") - --func ElseIf() { -- // No inversion expected when there's not else clause -- if len(os.Args) > 2 { -- fmt.Println("A") +- // Defensively assert that we get an actual diff, so that we guarantee the +- // invariant that we return "" if and only if want == got. +- // +- // This is probably unnecessary, but convenient. +- if unified == "" { +- panic("empty diff for non-identical input") - } - -- // No inversion expected for else-if, that would become unreadable -- if len(os.Args) > 2 { -- fmt.Println("A") -- } else if os.Args[0] == "X" { //@suggestedfix(re"if os.Args.0. == .X.", "refactor.rewrite", "") -- fmt.Println("B") -- } else { -- fmt.Println("C") +- return unified +-} +- +-// Bytes is like Text but using byte slices. +-func Bytes(want, got []byte) string { +- if bytes.Equal(want, got) { +- return "" // common case - } +- return Text(string(want), string(got)) -} -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/else_if.go.golden b/gopls/internal/lsp/testdata/invertifcondition/else_if.go.golden ---- a/gopls/internal/lsp/testdata/invertifcondition/else_if.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/else_if.go.golden 1970-01-01 08:00:00 -@@ -1,24 +0,0 @@ ---- suggestedfix_else_if_17_9 -- --package invertifcondition +diff -urN a/gopls/internal/lsp/tests/compare/text_test.go b/gopls/internal/lsp/tests/compare/text_test.go +--- a/gopls/internal/lsp/tests/compare/text_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/compare/text_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,28 +0,0 @@ +-// Copyright 2022 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 compare_test - -import ( -- "fmt" -- "os" +- "testing" +- +- "golang.org/x/tools/gopls/internal/lsp/tests/compare" -) - --func ElseIf() { -- // No inversion expected when there's not else clause -- if len(os.Args) > 2 { -- fmt.Println("A") +-func TestText(t *testing.T) { +- tests := []struct { +- got, want, wantDiff string +- }{ +- {"", "", ""}, +- {"equal", "equal", ""}, +- {"a", "b", "--- want\n+++ got\n@@ -1 +1 @@\n-b\n+a\n"}, +- {"a\nd\nc\n", "a\nb\nc\n", "--- want\n+++ got\n@@ -1,4 +1,4 @@\n a\n-b\n+d\n c\n \n"}, - } - -- // No inversion expected for else-if, that would become unreadable -- if len(os.Args) > 2 { -- fmt.Println("A") -- } else if os.Args[0] != "X" { -- fmt.Println("C") -- } else { //@suggestedfix(re"if os.Args.0. == .X.", "refactor.rewrite", "") -- fmt.Println("B") +- for _, test := range tests { +- if gotDiff := compare.Text(test.want, test.got); gotDiff != test.wantDiff { +- t.Errorf("compare.Text(%q, %q) =\n%q, want\n%q", test.want, test.got, gotDiff, test.wantDiff) +- } - } -} +diff -urN a/gopls/internal/lsp/tests/markdown_go118.go b/gopls/internal/lsp/tests/markdown_go118.go +--- a/gopls/internal/lsp/tests/markdown_go118.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/markdown_go118.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,69 +0,0 @@ +-// Copyright 2022 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. - -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/greater_than.go b/gopls/internal/lsp/testdata/invertifcondition/greater_than.go ---- a/gopls/internal/lsp/testdata/invertifcondition/greater_than.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/greater_than.go 1970-01-01 08:00:00 -@@ -1,14 +0,0 @@ --package invertifcondition +-//go:build !go1.19 +-// +build !go1.19 +- +-package tests - -import ( -- "fmt" -- "os" +- "regexp" +- "strings" +- +- "golang.org/x/tools/gopls/internal/lsp/tests/compare" -) - --func GreaterThan() { -- if len(os.Args) > 2 { //@suggestedfix("i", "refactor.rewrite", "") -- fmt.Println("A") -- } else { -- fmt.Println("B") -- } +-// DiffMarkdown compares two markdown strings produced by parsing go doc +-// comments. +-// +-// For go1.19 and later, markdown conversion is done using go/doc/comment. +-// Compared to the newer version, the older version has extra escapes, and +-// treats code blocks slightly differently. +-func DiffMarkdown(want, got string) string { +- want = normalizeMarkdown(want) +- got = normalizeMarkdown(got) +- return compare.Text(want, got) -} -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/greater_than.go.golden b/gopls/internal/lsp/testdata/invertifcondition/greater_than.go.golden ---- a/gopls/internal/lsp/testdata/invertifcondition/greater_than.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/greater_than.go.golden 1970-01-01 08:00:00 -@@ -1,16 +0,0 @@ ---- suggestedfix_greater_than_9_2 -- --package invertifcondition - --import ( -- "fmt" -- "os" --) +-// normalizeMarkdown normalizes whitespace and escaping of the input string, to +-// eliminate differences between the Go 1.18 and Go 1.19 generated markdown for +-// doc comments. Note that it does not normalize to either the 1.18 or 1.19 +-// formatting: it simplifies both so that they may be compared. +-// +-// This function may need to be adjusted as we encounter more differences in +-// the generated text. +-// +-// TODO(rfindley): this function doesn't correctly handle the case of +-// multi-line docstrings. +-func normalizeMarkdown(input string) string { +- input = strings.TrimSpace(input) - --func GreaterThan() { -- if len(os.Args) <= 2 { -- fmt.Println("B") -- } else { //@suggestedfix("i", "refactor.rewrite", "") -- fmt.Println("A") -- } +- // For simplicity, eliminate blank lines. +- input = regexp.MustCompile("\n+").ReplaceAllString(input, "\n") +- +- // Replace common escaped characters with their unescaped version. +- // +- // This list may not be exhaustive: it was just sufficient to make tests +- // pass. +- input = strings.NewReplacer( +- `\\`, ``, +- `\@`, `@`, +- `\(`, `(`, +- `\)`, `)`, +- `\{`, `{`, +- `\}`, `}`, +- `\"`, `"`, +- `\.`, `.`, +- `\-`, `-`, +- `\'`, `'`, +- `\+`, `+`, +- `\~`, `~`, +- `\=`, `=`, +- `\:`, `:`, +- `\?`, `?`, +- `\n\n\n`, `\n\n`, // Note that these are *escaped* newlines. +- ).Replace(input) +- +- return input -} +diff -urN a/gopls/internal/lsp/tests/markdown_go119.go b/gopls/internal/lsp/tests/markdown_go119.go +--- a/gopls/internal/lsp/tests/markdown_go119.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/markdown_go119.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,22 +0,0 @@ +-// Copyright 2022 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. - -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go b/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go ---- a/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go 1970-01-01 08:00:00 -@@ -1,14 +0,0 @@ --package invertifcondition +-//go:build go1.19 +-// +build go1.19 +- +-package tests - -import ( -- "fmt" +- "golang.org/x/tools/gopls/internal/lsp/tests/compare" -) - --func NotBoolean() { -- b := true -- if !b { //@suggestedfix("if !b", "refactor.rewrite", "") -- fmt.Println("A") -- } else { -- fmt.Println("B") -- } +-// DiffMarkdown compares two markdown strings produced by parsing go doc +-// comments. +-// +-// For go1.19 and later, markdown conversion is done using go/doc/comment. +-// Compared to the newer version, the older version has extra escapes, and +-// treats code blocks slightly differently. +-func DiffMarkdown(want, got string) string { +- return compare.Text(want, got) -} -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go.golden b/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go.golden ---- a/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go.golden 1970-01-01 08:00:00 -@@ -1,16 +0,0 @@ ---- suggestedfix_not_boolean_9_2 -- --package invertifcondition +diff -urN a/gopls/internal/lsp/tests/README.md b/gopls/internal/lsp/tests/README.md +--- a/gopls/internal/lsp/tests/README.md 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/README.md 1970-01-01 00:00:00.000000000 +0000 +@@ -1,66 +0,0 @@ +-# Testing - --import ( -- "fmt" --) +-LSP has "marker tests" defined in `internal/lsp/testdata`, as well as +-traditional tests. - --func NotBoolean() { -- b := true -- if b { -- fmt.Println("B") -- } else { //@suggestedfix("if !b", "refactor.rewrite", "") -- fmt.Println("A") -- } --} +-## Marker tests - -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/remove_else.go b/gopls/internal/lsp/testdata/invertifcondition/remove_else.go ---- a/gopls/internal/lsp/testdata/invertifcondition/remove_else.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/remove_else.go 1970-01-01 08:00:00 -@@ -1,16 +0,0 @@ --package invertifcondition +-Marker tests have a standard input file, like +-`internal/lsp/testdata/foo/bar.go`, and some may have a corresponding golden +-file, like `internal/lsp/testdata/foo/bar.go.golden`. The former is the "input" +-and the latter is the expected output. - --import ( -- "fmt" --) +-Each input file contains annotations like +-`//@suggestedfix("}", "refactor.rewrite", "Fill anonymous struct")`. These annotations are interpreted by +-test runners to perform certain actions. The expected output after those actions +-is encoded in the golden file. - --func RemoveElse() { -- if true { //@suggestedfix("if true", "refactor.rewrite", "") -- fmt.Println("A") -- } else { -- fmt.Println("B") -- return -- } +-When tests are run, each annotation results in a new subtest, which is encoded +-in the golden file with a heading like, - -- fmt.Println("C") --} -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/remove_else.go.golden b/gopls/internal/lsp/testdata/invertifcondition/remove_else.go.golden ---- a/gopls/internal/lsp/testdata/invertifcondition/remove_else.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/remove_else.go.golden 1970-01-01 08:00:00 -@@ -1,19 +0,0 @@ ---- suggestedfix_remove_else_8_2 -- --package invertifcondition +-```bash +--- suggestedfix_bar_11_21 -- +-// expected contents go here +--- suggestedfix_bar_13_20 -- +-// expected contents go here +-``` - --import ( -- "fmt" --) +-The format of these headings vary: they are defined by the +-[`Golden`](https://pkg.go.dev/golang.org/x/tools/gopls/internal/lsp/tests#Data.Golden) +-function for each annotation. In the case above, the format is: annotation +-name, file name, annotation line location, annotation character location. - --func RemoveElse() { -- if false { -- fmt.Println("B") -- return -- } +-So, if `internal/lsp/testdata/foo/bar.go` has three `suggestedfix` annotations, +-the golden file should have three headers with `suggestedfix_bar_xx_yy` +-headings. - -- //@suggestedfix("if true", "refactor.rewrite", "") -- fmt.Println("A") +-To see a list of all available annotations, see the exported "expectations" in +-[tests.go](https://github.com/golang/tools/blob/299f270db45902e93469b1152fafed034bb3f033/internal/lsp/tests/tests.go#L418-L447). - -- fmt.Println("C") --} +-To run marker tests, - -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go b/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go ---- a/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go 1970-01-01 08:00:00 -@@ -1,14 +0,0 @@ --package invertifcondition +-```bash +-cd /path/to/tools - --import ( -- "fmt" --) +-# The marker tests are located in "internal/lsp", "internal/lsp/cmd, and +-# "internal/lsp/source". +-go test ./internal/lsp/... +-``` - --func RemoveParens() { -- b := true -- if !(b) { //@suggestedfix("if", "refactor.rewrite", "") -- fmt.Println("A") -- } else { -- fmt.Println("B") -- } --} -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go.golden b/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go.golden ---- a/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go.golden 1970-01-01 08:00:00 -@@ -1,16 +0,0 @@ ---- suggestedfix_remove_parens_9_2 -- --package invertifcondition +-There are quite a lot of marker tests, so to run one individually, pass the test +-path and heading into a -run argument: - --import ( -- "fmt" --) +-```bash +-cd /path/to/tools +-go test ./internal/lsp/... -v -run TestLSP/Modules/SuggestedFix/bar_11_21 +-``` - --func RemoveParens() { -- b := true -- if b { -- fmt.Println("B") -- } else { //@suggestedfix("if", "refactor.rewrite", "") -- fmt.Println("A") -- } --} +-## Resetting marker tests - -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon.go b/gopls/internal/lsp/testdata/invertifcondition/semicolon.go ---- a/gopls/internal/lsp/testdata/invertifcondition/semicolon.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon.go 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ --package invertifcondition +-Sometimes, a change is made to lsp that requires a change to multiple golden +-files. When this happens, you can run, - --import ( -- "fmt" --) +-```bash +-cd /path/to/tools +-./internal/lsp/reset_golden.sh +-``` +diff -urN a/gopls/internal/lsp/tests/tests.go b/gopls/internal/lsp/tests/tests.go +--- a/gopls/internal/lsp/tests/tests.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/tests.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,645 +0,0 @@ +-// 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. - --func Semicolon() { -- if _, err := fmt.Println("x"); err != nil { //@suggestedfix("if", "refactor.rewrite", "") -- fmt.Println("A") -- } else { -- fmt.Println("B") -- } --} -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon.go.golden b/gopls/internal/lsp/testdata/invertifcondition/semicolon.go.golden ---- a/gopls/internal/lsp/testdata/invertifcondition/semicolon.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon.go.golden 1970-01-01 08:00:00 -@@ -1,15 +0,0 @@ ---- suggestedfix_semicolon_8_2 -- --package invertifcondition +-// Package tests exports functionality to be used across a variety of gopls tests. +-package tests - -import ( +- "bytes" +- "context" +- "flag" - "fmt" --) +- "go/ast" +- "go/token" +- "io" +- "os" +- "path/filepath" +- "sort" +- "strings" +- "sync" +- "testing" +- "time" - --func Semicolon() { -- if _, err := fmt.Println("x"); err == nil { -- fmt.Println("B") -- } else { //@suggestedfix("if", "refactor.rewrite", "") -- fmt.Println("A") -- } --} +- "golang.org/x/tools/go/packages" +- "golang.org/x/tools/go/packages/packagestest" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/lsp/tests/compare" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/typeparams" +- "golang.org/x/tools/txtar" +-) - -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go b/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go ---- a/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ --package invertifcondition +-const ( +- overlayFileSuffix = ".overlay" +- goldenFileSuffix = ".golden" +- inFileSuffix = ".in" +- summaryFile = "summary.txt" - --import ( -- "fmt" +- // The module path containing the testdata packages. +- // +- // Warning: the length of this module path matters, as we have bumped up +- // against command-line limitations on windows (golang/go#54800). +- testModule = "golang.org/lsptests" -) - --func SemicolonAnd() { -- if n, err := fmt.Println("x"); err != nil && n > 0 { //@suggestedfix("f", "refactor.rewrite", "") -- fmt.Println("A") -- } else { -- fmt.Println("B") -- } --} -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go.golden b/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go.golden ---- a/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go.golden 1970-01-01 08:00:00 -@@ -1,15 +0,0 @@ ---- suggestedfix_semicolon_and_8_3 -- --package invertifcondition +-var UpdateGolden = flag.Bool("golden", false, "Update golden files") - --import ( -- "fmt" --) +-// These type names apparently avoid the need to repeat the +-// type in the field name and the make() expression. +-type CallHierarchy = map[span.Span]*CallHierarchyResult +-type SemanticTokens = []span.Span +-type SuggestedFixes = map[span.Span][]SuggestedFix +-type Renames = map[span.Span]string +-type InlayHints = []span.Span +-type AddImport = map[span.URI]string +-type SelectionRanges = []span.Span - --func SemicolonAnd() { -- if n, err := fmt.Println("x"); err == nil || n <= 0 { -- fmt.Println("B") -- } else { //@suggestedfix("f", "refactor.rewrite", "") -- fmt.Println("A") -- } --} +-type Data struct { +- Config packages.Config +- Exported *packagestest.Exported +- CallHierarchy CallHierarchy +- SemanticTokens SemanticTokens +- SuggestedFixes SuggestedFixes +- Renames Renames +- InlayHints InlayHints +- AddImport AddImport +- SelectionRanges SelectionRanges - -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go b/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go ---- a/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ --package invertifcondition +- fragments map[string]string +- dir string +- golden map[string]*Golden +- mode string - --import ( -- "fmt" --) +- ModfileFlagAvailable bool - --func SemicolonOr() { -- if n, err := fmt.Println("x"); err != nil || n < 5 { //@suggestedfix(re"if n, err := fmt.Println..x..; err != nil .. n < 5", "refactor.rewrite", "") -- fmt.Println("A") -- } else { -- fmt.Println("B") -- } +- mappersMu sync.Mutex +- mappers map[span.URI]*protocol.Mapper -} -diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go.golden b/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go.golden ---- a/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go.golden 1970-01-01 08:00:00 -@@ -1,15 +0,0 @@ ---- suggestedfix_semicolon_or_8_2 -- --package invertifcondition -- --import ( -- "fmt" --) - --func SemicolonOr() { -- if n, err := fmt.Println("x"); err == nil && n >= 5 { -- fmt.Println("B") -- } else { //@suggestedfix(re"if n, err := fmt.Println..x..; err != nil .. n < 5", "refactor.rewrite", "") -- fmt.Println("A") -- } +-// The Tests interface abstracts the LSP-based implementation of the marker +-// test operators appearing in files beneath ../testdata/. +-// +-// TODO(adonovan): reduce duplication; see https://github.com/golang/go/issues/54845. +-// There is only one implementation (*runner in ../lsp_test.go), so +-// we can abolish the interface now. +-type Tests interface { +- CallHierarchy(*testing.T, span.Span, *CallHierarchyResult) +- SemanticTokens(*testing.T, span.Span) +- SuggestedFix(*testing.T, span.Span, []SuggestedFix, int) +- InlayHints(*testing.T, span.Span) +- Rename(*testing.T, span.Span, string) +- AddImport(*testing.T, span.URI, string) +- SelectionRanges(*testing.T, span.Span) -} - -diff -urN a/gopls/internal/lsp/testdata/issues/issue56505.go b/gopls/internal/lsp/testdata/issues/issue56505.go ---- a/gopls/internal/lsp/testdata/issues/issue56505.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/issues/issue56505.go 1970-01-01 08:00:00 -@@ -1,8 +0,0 @@ --package issues -- --// Test for golang/go#56505: completion on variables of type *error should not --// panic. --func _() { -- var e *error -- e.x //@complete(" //") +-type Completion struct { +- CompletionItems []token.Pos -} -diff -urN a/gopls/internal/lsp/testdata/keywords/accidental_keywords.go.in b/gopls/internal/lsp/testdata/keywords/accidental_keywords.go.in ---- a/gopls/internal/lsp/testdata/keywords/accidental_keywords.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/keywords/accidental_keywords.go.in 1970-01-01 08:00:00 -@@ -1,31 +0,0 @@ --package keywords - --// non-matching candidate - shouldn't show up as completion --var apple = "apple" +-type CompletionSnippet struct { +- CompletionItem token.Pos +- PlainSnippet string +- PlaceholderSnippet string +-} - --func _() { -- foo.bar() // insert some extra statements to exercise our AST surgery -- variance := 123 //@item(kwVariance, "variance", "int", "var") -- foo.bar() -- println(var) //@complete(")", kwVariance) +-type CallHierarchyResult struct { +- IncomingCalls, OutgoingCalls []protocol.CallHierarchyItem -} - --func _() { -- foo.bar() -- var s struct { variance int } //@item(kwVarianceField, "variance", "int", "field") -- foo.bar() -- s.var //@complete(" //", kwVarianceField) +-type Link struct { +- Src span.Span +- Target string +- NotePosition token.Position -} - --func _() { -- channel := 123 //@item(kwChannel, "channel", "int", "var") -- chan //@complete(" //", kwChannel) -- foo.bar() +-type SuggestedFix struct { +- ActionKind, Title string -} - --func _() { -- foo.bar() -- var typeName string //@item(kwTypeName, "typeName", "string", "var") -- foo.bar() -- type //@complete(" //", kwTypeName) +-type Golden struct { +- Filename string +- Archive *txtar.Archive +- Modified bool -} -diff -urN a/gopls/internal/lsp/testdata/keywords/empty_select.go b/gopls/internal/lsp/testdata/keywords/empty_select.go ---- a/gopls/internal/lsp/testdata/keywords/empty_select.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/keywords/empty_select.go 1970-01-01 08:00:00 -@@ -1,7 +0,0 @@ --package keywords - --func _() { -- select { -- c //@complete(" //", case) -- } +-func Context(t testing.TB) context.Context { +- return context.Background() -} -diff -urN a/gopls/internal/lsp/testdata/keywords/empty_switch.go b/gopls/internal/lsp/testdata/keywords/empty_switch.go ---- a/gopls/internal/lsp/testdata/keywords/empty_switch.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/keywords/empty_switch.go 1970-01-01 08:00:00 -@@ -1,11 +0,0 @@ --package keywords - --func _() { -- switch { -- //@complete("", case, default) +-func DefaultOptions(o *source.Options) { +- o.SupportedCodeActions = map[source.FileKind]map[protocol.CodeActionKind]bool{ +- source.Go: { +- protocol.SourceOrganizeImports: true, +- protocol.QuickFix: true, +- protocol.RefactorRewrite: true, +- protocol.RefactorInline: true, +- protocol.RefactorExtract: true, +- protocol.SourceFixAll: true, +- }, +- source.Mod: { +- protocol.SourceOrganizeImports: true, +- }, +- source.Sum: {}, +- source.Work: {}, +- source.Tmpl: {}, - } +- o.InsertTextFormat = protocol.SnippetTextFormat +- o.CompletionBudget = time.Minute +- o.HierarchicalDocumentSymbolSupport = true +- o.SemanticTokens = true +- o.InternalOptions.NewDiff = "new" - -- switch test.(type) { -- d //@complete(" //", default) +- // Enable all inlay hints. +- if o.Hints == nil { +- o.Hints = make(map[string]bool) +- } +- for name := range source.AllInlayHints { +- o.Hints[name] = true - } -} -diff -urN a/gopls/internal/lsp/testdata/keywords/keywords.go b/gopls/internal/lsp/testdata/keywords/keywords.go ---- a/gopls/internal/lsp/testdata/keywords/keywords.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/keywords/keywords.go 1970-01-01 08:00:00 -@@ -1,100 +0,0 @@ --package keywords -- --//@rank("", type),rank("", func),rank("", var),rank("", const),rank("", import) -- --func _() { -- var test int //@rank(" //", int, interface) -- var tChan chan int -- var _ m //@complete(" //", map) -- var _ f //@complete(" //", func) -- var _ c //@complete(" //", chan) -- -- var _ str //@rank(" //", string, struct) - -- type _ int //@rank(" //", interface, int) +-func RunTests(t *testing.T, dataDir string, includeMultiModule bool, f func(*testing.T, *Data)) { +- t.Helper() +- modes := []string{"Modules", "GOPATH"} +- if includeMultiModule { +- modes = append(modes, "MultiModule") +- } +- for _, mode := range modes { +- t.Run(mode, func(t *testing.T) { +- datum := load(t, mode, dataDir) +- t.Helper() +- f(t, datum) +- }) +- } +-} - -- type _ str //@rank(" //", struct, string) +-func load(t testing.TB, mode string, dir string) *Data { +- datum := &Data{ +- CallHierarchy: make(CallHierarchy), +- Renames: make(Renames), +- SuggestedFixes: make(SuggestedFixes), +- AddImport: make(AddImport), - -- switch test { -- case 1: // TODO: trying to complete case here will break because the parser won't return *ast.Ident -- b //@complete(" //", break) -- case 2: -- f //@complete(" //", fallthrough, for) -- r //@complete(" //", return) -- d //@complete(" //", default, defer) -- c //@complete(" //", case, const) +- dir: dir, +- fragments: map[string]string{}, +- golden: map[string]*Golden{}, +- mode: mode, +- mappers: map[span.URI]*protocol.Mapper{}, - } - -- switch test.(type) { -- case fo: //@complete(":") -- case int: -- b //@complete(" //", break) -- case int32: -- f //@complete(" //", for) -- d //@complete(" //", default, defer) -- r //@complete(" //", return) -- c //@complete(" //", case, const) +- if !*UpdateGolden { +- summary := filepath.Join(filepath.FromSlash(dir), summaryFile+goldenFileSuffix) +- if _, err := os.Stat(summary); os.IsNotExist(err) { +- t.Fatalf("could not find golden file summary.txt in %#v", dir) +- } +- archive, err := txtar.ParseFile(summary) +- if err != nil { +- t.Fatalf("could not read golden file %v/%v: %v", dir, summary, err) +- } +- datum.golden[summaryFile] = &Golden{ +- Filename: summary, +- Archive: archive, +- } - } - -- select { -- case <-tChan: -- b //@complete(" //", break) -- c //@complete(" //", case, const) +- files := packagestest.MustCopyFileTree(dir) +- // Prune test cases that exercise generics. +- if !typeparams.Enabled { +- for name := range files { +- if strings.Contains(name, "_generics") { +- delete(files, name) +- } +- } - } -- -- for index := 0; index < test; index++ { -- c //@complete(" //", const, continue) -- b //@complete(" //", break) +- overlays := map[string][]byte{} +- for fragment, operation := range files { +- if trimmed := strings.TrimSuffix(fragment, goldenFileSuffix); trimmed != fragment { +- delete(files, fragment) +- goldFile := filepath.Join(dir, fragment) +- archive, err := txtar.ParseFile(goldFile) +- if err != nil { +- t.Fatalf("could not read golden file %v: %v", fragment, err) +- } +- datum.golden[trimmed] = &Golden{ +- Filename: goldFile, +- Archive: archive, +- } +- } else if trimmed := strings.TrimSuffix(fragment, inFileSuffix); trimmed != fragment { +- delete(files, fragment) +- files[trimmed] = operation +- } else if index := strings.Index(fragment, overlayFileSuffix); index >= 0 { +- delete(files, fragment) +- partial := fragment[:index] + fragment[index+len(overlayFileSuffix):] +- contents, err := os.ReadFile(filepath.Join(dir, fragment)) +- if err != nil { +- t.Fatal(err) +- } +- overlays[partial] = contents +- } - } - -- for range []int{} { -- c //@complete(" //", const, continue) -- b //@complete(" //", break) +- modules := []packagestest.Module{ +- { +- Name: testModule, +- Files: files, +- Overlay: overlays, +- }, - } +- switch mode { +- case "Modules": +- datum.Exported = packagestest.Export(t, packagestest.Modules, modules) +- case "GOPATH": +- datum.Exported = packagestest.Export(t, packagestest.GOPATH, modules) +- case "MultiModule": +- files := map[string]interface{}{} +- for k, v := range modules[0].Files { +- files[filepath.Join("testmodule", k)] = v +- } +- modules[0].Files = files - -- // Test function level keywords -- -- //Using 2 characters to test because map output order is random -- sw //@complete(" //", switch) -- se //@complete(" //", select) -- -- f //@complete(" //", for) -- d //@complete(" //", defer) -- g //@rank(" //", go),rank(" //", goto) -- r //@complete(" //", return) -- i //@complete(" //", if) -- e //@complete(" //", else) -- v //@complete(" //", var) -- c //@complete(" //", const) +- overlays := map[string][]byte{} +- for k, v := range modules[0].Overlay { +- overlays[filepath.Join("testmodule", k)] = v +- } +- modules[0].Overlay = overlays - -- for i := r //@complete(" //", range) --} +- golden := map[string]*Golden{} +- for k, v := range datum.golden { +- if k == summaryFile { +- golden[k] = v +- } else { +- golden[filepath.Join("testmodule", k)] = v +- } +- } +- datum.golden = golden - --/* package */ //@item(package, "package", "", "keyword") --/* import */ //@item(import, "import", "", "keyword") --/* func */ //@item(func, "func", "", "keyword") --/* type */ //@item(type, "type", "", "keyword") --/* var */ //@item(var, "var", "", "keyword") --/* const */ //@item(const, "const", "", "keyword") --/* break */ //@item(break, "break", "", "keyword") --/* default */ //@item(default, "default", "", "keyword") --/* case */ //@item(case, "case", "", "keyword") --/* defer */ //@item(defer, "defer", "", "keyword") --/* go */ //@item(go, "go", "", "keyword") --/* for */ //@item(for, "for", "", "keyword") --/* if */ //@item(if, "if", "", "keyword") --/* else */ //@item(else, "else", "", "keyword") --/* switch */ //@item(switch, "switch", "", "keyword") --/* select */ //@item(select, "select", "", "keyword") --/* fallthrough */ //@item(fallthrough, "fallthrough", "", "keyword") --/* continue */ //@item(continue, "continue", "", "keyword") --/* return */ //@item(return, "return", "", "keyword") --/* var */ //@item(var, "var", "", "keyword") --/* const */ //@item(const, "const", "", "keyword") --/* goto */ //@item(goto, "goto", "", "keyword") --/* struct */ //@item(struct, "struct", "", "keyword") --/* interface */ //@item(interface, "interface", "", "keyword") --/* map */ //@item(map, "map", "", "keyword") --/* func */ //@item(func, "func", "", "keyword") --/* chan */ //@item(chan, "chan", "", "keyword") --/* range */ //@item(range, "range", "", "keyword") -diff -urN a/gopls/internal/lsp/testdata/labels/labels.go b/gopls/internal/lsp/testdata/labels/labels.go ---- a/gopls/internal/lsp/testdata/labels/labels.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/labels/labels.go 1970-01-01 08:00:00 -@@ -1,49 +0,0 @@ --package labels +- datum.Exported = packagestest.Export(t, packagestest.Modules, modules) +- default: +- panic("unknown mode " + mode) +- } - --func _() { -- goto F //@complete(" //", label1, label5) +- for _, m := range modules { +- for fragment := range m.Files { +- filename := datum.Exported.File(m.Name, fragment) +- datum.fragments[filename] = fragment +- } +- } - --Foo1: //@item(label1, "Foo1", "label", "const") -- for a, b := range []int{} { -- Foo2: //@item(label2, "Foo2", "label", "const") -- switch { -- case true: -- break F //@complete(" //", label2, label1) +- // Turn off go/packages debug logging. +- datum.Exported.Config.Logf = nil +- datum.Config.Logf = nil - -- continue F //@complete(" //", label1) +- // Merge the exported.Config with the view.Config. +- datum.Config = *datum.Exported.Config +- datum.Config.Fset = token.NewFileSet() +- datum.Config.Context = Context(nil) +- datum.Config.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) { +- panic("ParseFile should not be called") +- } - -- { -- FooUnjumpable: -- } +- // Do a first pass to collect special markers for completion and workspace symbols. +- if err := datum.Exported.Expect(map[string]interface{}{ +- "item": func(name string, r packagestest.Range, _ []string) { +- datum.Exported.Mark(name, r) +- }, +- "symbol": func(name string, r packagestest.Range, _ []string) { +- datum.Exported.Mark(name, r) +- }, +- }); err != nil { +- t.Fatal(err) +- } - -- goto F //@complete(" //", label1, label2, label4, label5) +- // Collect any data that needs to be used by subsequent tests. +- if err := datum.Exported.Expect(map[string]interface{}{ +- "semantic": datum.collectSemanticTokens, +- "inlayHint": datum.collectInlayHints, +- "rename": datum.collectRenames, +- "suggestedfix": datum.collectSuggestedFixes, +- "incomingcalls": datum.collectIncomingCalls, +- "outgoingcalls": datum.collectOutgoingCalls, +- "addimport": datum.collectAddImports, +- "selectionrange": datum.collectSelectionRanges, +- }); err != nil { +- t.Fatal(err) +- } - -- func() { -- goto F //@complete(" //", label3) +- if mode == "MultiModule" { +- if err := moveFile(filepath.Join(datum.Config.Dir, "go.mod"), filepath.Join(datum.Config.Dir, "testmodule/go.mod")); err != nil { +- t.Fatal(err) +- } +- } - -- break F //@complete(" //") +- return datum +-} - -- continue F //@complete(" //") +-// moveFile moves the file at oldpath to newpath, by renaming if possible +-// or copying otherwise. +-func moveFile(oldpath, newpath string) (err error) { +- renameErr := os.Rename(oldpath, newpath) +- if renameErr == nil { +- return nil +- } - -- Foo3: //@item(label3, "Foo3", "label", "const") -- }() +- src, err := os.Open(oldpath) +- if err != nil { +- return err +- } +- defer func() { +- src.Close() +- if err == nil { +- err = os.Remove(oldpath) - } +- }() - -- Foo4: //@item(label4, "Foo4", "label", "const") -- switch interface{}(a).(type) { -- case int: -- break F //@complete(" //", label4, label1) -- } +- perm := os.ModePerm +- fi, err := src.Stat() +- if err == nil { +- perm = fi.Mode().Perm() - } - -- break F //@complete(" //") -- -- continue F //@complete(" //") -- --Foo5: //@item(label5, "Foo5", "label", "const") -- for { -- break F //@complete(" //", label5) +- dst, err := os.OpenFile(newpath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm) +- if err != nil { +- return err - } - -- return +- _, err = io.Copy(dst, src) +- if closeErr := dst.Close(); err == nil { +- err = closeErr +- } +- return err -} -diff -urN a/gopls/internal/lsp/testdata/links/links.go b/gopls/internal/lsp/testdata/links/links.go ---- a/gopls/internal/lsp/testdata/links/links.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/links/links.go 1970-01-01 08:00:00 -@@ -1,26 +0,0 @@ --package links -- --import ( -- "fmt" //@link(`fmt`,"https://pkg.go.dev/fmt") - -- "golang.org/lsptests/foo" //@link(`golang.org/lsptests/foo`,`https://pkg.go.dev/golang.org/lsptests/foo`) +-func Run(t *testing.T, tests Tests, data *Data) { +- t.Helper() +- checkData(t, data) - -- _ "database/sql" //@link(`database/sql`, `https://pkg.go.dev/database/sql`) --) +- t.Run("CallHierarchy", func(t *testing.T) { +- t.Helper() +- for spn, callHierarchyResult := range data.CallHierarchy { +- t.Run(SpanName(spn), func(t *testing.T) { +- t.Helper() +- tests.CallHierarchy(t, spn, callHierarchyResult) +- }) +- } +- }) - --var ( -- _ fmt.Formatter -- _ foo.StructFoo -- _ errors.Formatter --) +- t.Run("SemanticTokens", func(t *testing.T) { +- t.Helper() +- for _, spn := range data.SemanticTokens { +- t.Run(uriName(spn.URI()), func(t *testing.T) { +- t.Helper() +- tests.SemanticTokens(t, spn) +- }) +- } +- }) - --// Foo function --func Foo() string { -- /*https://example.com/comment */ //@link("https://example.com/comment","https://example.com/comment") +- t.Run("SuggestedFix", func(t *testing.T) { +- t.Helper() +- for spn, actionKinds := range data.SuggestedFixes { +- // Check if we should skip this spn if the -modfile flag is not available. +- if shouldSkip(data, spn.URI()) { +- continue +- } +- t.Run(SpanName(spn), func(t *testing.T) { +- t.Helper() +- tests.SuggestedFix(t, spn, actionKinds, 1) +- }) +- } +- }) - -- url := "https://example.com/string_literal" //@link("https://example.com/string_literal","https://example.com/string_literal") -- return url +- t.Run("InlayHints", func(t *testing.T) { +- t.Helper() +- for _, src := range data.InlayHints { +- t.Run(SpanName(src), func(t *testing.T) { +- t.Helper() +- tests.InlayHints(t, src) +- }) +- } +- }) - -- // TODO(golang/go#1234): Link the relevant issue. //@link("golang/go#1234", "https://github.com/golang/go/issues/1234") -- // TODO(microsoft/vscode-go#12): Another issue. //@link("microsoft/vscode-go#12", "https://github.com/microsoft/vscode-go/issues/12") --} -diff -urN a/gopls/internal/lsp/testdata/maps/maps.go.in b/gopls/internal/lsp/testdata/maps/maps.go.in ---- a/gopls/internal/lsp/testdata/maps/maps.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/maps/maps.go.in 1970-01-01 08:00:00 -@@ -1,18 +0,0 @@ --package maps +- t.Run("Renames", func(t *testing.T) { +- t.Helper() +- for spn, newText := range data.Renames { +- t.Run(uriName(spn.URI())+"_"+newText, func(t *testing.T) { +- t.Helper() +- tests.Rename(t, spn, newText) +- }) +- } +- }) - --func _() { -- var aVar int //@item(mapVar, "aVar", "int", "var") +- t.Run("AddImport", func(t *testing.T) { +- t.Helper() +- for uri, exp := range data.AddImport { +- t.Run(uriName(uri), func(t *testing.T) { +- tests.AddImport(t, uri, exp) +- }) +- } +- }) - -- // not comparabale -- type aSlice []int //@item(mapSliceType, "aSlice", "[]int", "type") +- t.Run("SelectionRanges", func(t *testing.T) { +- t.Helper() +- for _, span := range data.SelectionRanges { +- t.Run(SpanName(span), func(t *testing.T) { +- tests.SelectionRanges(t, span) +- }) +- } +- }) - -- *aSlice //@item(mapSliceTypePtr, "*aSlice", "[]int", "type") +- if *UpdateGolden { +- for _, golden := range data.golden { +- if !golden.Modified { +- continue +- } +- sort.Slice(golden.Archive.Files, func(i, j int) bool { +- return golden.Archive.Files[i].Name < golden.Archive.Files[j].Name +- }) +- if err := os.WriteFile(golden.Filename, txtar.Format(golden.Archive), 0666); err != nil { +- t.Fatal(err) +- } +- } +- } +-} - -- // comparable -- type aStruct struct{} //@item(mapStructType, "aStruct", "struct{...}", "struct") +-func checkData(t *testing.T, data *Data) { +- buf := &bytes.Buffer{} - -- map[]a{} //@complete("]", mapSliceType, mapStructType),snippet("]", mapSliceType, "*aSlice", "*aSlice") +- fmt.Fprintf(buf, "CallHierarchyCount = %v\n", len(data.CallHierarchy)) +- fmt.Fprintf(buf, "SemanticTokenCount = %v\n", len(data.SemanticTokens)) +- fmt.Fprintf(buf, "SuggestedFixCount = %v\n", len(data.SuggestedFixes)) +- fmt.Fprintf(buf, "InlayHintsCount = %v\n", len(data.InlayHints)) +- fmt.Fprintf(buf, "RenamesCount = %v\n", len(data.Renames)) +- fmt.Fprintf(buf, "SelectionRangesCount = %v\n", len(data.SelectionRanges)) - -- map[a]a{} //@complete("]", mapSliceType, mapStructType) -- map[a]a{} //@complete("{", mapSliceType, mapStructType) +- want := string(data.Golden(t, "summary", summaryFile, func() ([]byte, error) { +- return buf.Bytes(), nil +- })) +- got := buf.String() +- if want != got { +- // These counters change when assertions are added or removed. +- // They act as an independent safety net to ensure that the +- // tests didn't spuriously pass because they did no work. +- t.Errorf("test summary does not match:\n%s\n(Run with -golden to update golden file; also, there may be one per Go version.)", compare.Text(want, got)) +- } -} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/channels.go b/gopls/internal/lsp/testdata/missingfunction/channels.go ---- a/gopls/internal/lsp/testdata/missingfunction/channels.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/channels.go 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --package missingfunction - --func channels(s string) { -- undefinedChannels(c()) //@suggestedfix("undefinedChannels", "quickfix", "") --} +-func (data *Data) Mapper(uri span.URI) (*protocol.Mapper, error) { +- data.mappersMu.Lock() +- defer data.mappersMu.Unlock() - --func c() (<-chan string, chan string) { -- return make(<-chan string), make(chan string) +- if _, ok := data.mappers[uri]; !ok { +- content, err := data.Exported.FileContents(uri.Filename()) +- if err != nil { +- return nil, err +- } +- data.mappers[uri] = protocol.NewMapper(uri, content) +- } +- return data.mappers[uri], nil -} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/channels.go.golden b/gopls/internal/lsp/testdata/missingfunction/channels.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/channels.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/channels.go.golden 1970-01-01 08:00:00 -@@ -1,15 +0,0 @@ ---- suggestedfix_channels_4_2 -- --package missingfunction - --func channels(s string) { -- undefinedChannels(c()) //@suggestedfix("undefinedChannels", "quickfix", "") --} +-func (data *Data) Golden(t *testing.T, tag, target string, update func() ([]byte, error)) []byte { +- t.Helper() +- fragment, found := data.fragments[target] +- if !found { +- if filepath.IsAbs(target) { +- t.Fatalf("invalid golden file fragment %v", target) +- } +- fragment = target +- } +- golden := data.golden[fragment] +- if golden == nil { +- if !*UpdateGolden { +- t.Fatalf("could not find golden file %v: %v", fragment, tag) +- } +- golden = &Golden{ +- Filename: filepath.Join(data.dir, fragment+goldenFileSuffix), +- Archive: &txtar.Archive{}, +- Modified: true, +- } +- data.golden[fragment] = golden +- } +- var file *txtar.File +- for i := range golden.Archive.Files { +- f := &golden.Archive.Files[i] +- if f.Name == tag { +- file = f +- break +- } +- } +- if *UpdateGolden { +- if file == nil { +- golden.Archive.Files = append(golden.Archive.Files, txtar.File{ +- Name: tag, +- }) +- file = &golden.Archive.Files[len(golden.Archive.Files)-1] +- } +- contents, err := update() +- if err != nil { +- t.Fatalf("could not update golden file %v: %v", fragment, err) +- } +- file.Data = append(contents, '\n') // add trailing \n for txtar +- golden.Modified = true - --func undefinedChannels(ch1 <-chan string, ch2 chan string) { -- panic("unimplemented") +- } +- if file == nil { +- t.Fatalf("could not find golden contents %v: %v", fragment, tag) +- } +- if len(file.Data) == 0 { +- return file.Data +- } +- return file.Data[:len(file.Data)-1] // drop the trailing \n -} - --func c() (<-chan string, chan string) { -- return make(<-chan string), make(chan string) +-func (data *Data) collectAddImports(spn span.Span, imp string) { +- data.AddImport[spn.URI()] = imp -} - -diff -urN a/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go b/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go ---- a/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go 1970-01-01 08:00:00 -@@ -1,6 +0,0 @@ --package missingfunction -- --func consecutiveParams() { -- var s string -- undefinedConsecutiveParams(s, s) //@suggestedfix("undefinedConsecutiveParams", "quickfix", "") +-func (data *Data) collectSemanticTokens(spn span.Span) { +- data.SemanticTokens = append(data.SemanticTokens, spn) -} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go.golden b/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go.golden 1970-01-01 08:00:00 -@@ -1,12 +0,0 @@ ---- suggestedfix_consecutive_params_5_2 -- --package missingfunction - --func consecutiveParams() { -- var s string -- undefinedConsecutiveParams(s, s) //@suggestedfix("undefinedConsecutiveParams", "quickfix", "") +-func (data *Data) collectSuggestedFixes(spn span.Span, actionKind, fix string) { +- data.SuggestedFixes[spn] = append(data.SuggestedFixes[spn], SuggestedFix{actionKind, fix}) -} - --func undefinedConsecutiveParams(s1, s2 string) { -- panic("unimplemented") +-func (data *Data) collectSelectionRanges(spn span.Span) { +- data.SelectionRanges = append(data.SelectionRanges, spn) -} - -diff -urN a/gopls/internal/lsp/testdata/missingfunction/error_param.go b/gopls/internal/lsp/testdata/missingfunction/error_param.go ---- a/gopls/internal/lsp/testdata/missingfunction/error_param.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/error_param.go 1970-01-01 08:00:00 -@@ -1,6 +0,0 @@ --package missingfunction -- --func errorParam() { -- var err error -- undefinedErrorParam(err) //@suggestedfix("undefinedErrorParam", "quickfix", "") +-func (data *Data) collectIncomingCalls(src span.Span, calls []span.Span) { +- for _, call := range calls { +- rng := data.mustRange(call) +- // we're only comparing protocol.range +- if data.CallHierarchy[src] != nil { +- data.CallHierarchy[src].IncomingCalls = append(data.CallHierarchy[src].IncomingCalls, +- protocol.CallHierarchyItem{ +- URI: protocol.DocumentURI(call.URI()), +- Range: rng, +- }) +- } else { +- data.CallHierarchy[src] = &CallHierarchyResult{ +- IncomingCalls: []protocol.CallHierarchyItem{ +- {URI: protocol.DocumentURI(call.URI()), Range: rng}, +- }, +- } +- } +- } -} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/error_param.go.golden b/gopls/internal/lsp/testdata/missingfunction/error_param.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/error_param.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/error_param.go.golden 1970-01-01 08:00:00 -@@ -1,12 +0,0 @@ ---- suggestedfix_error_param_5_2 -- --package missingfunction - --func errorParam() { -- var err error -- undefinedErrorParam(err) //@suggestedfix("undefinedErrorParam", "quickfix", "") +-func (data *Data) collectOutgoingCalls(src span.Span, calls []span.Span) { +- if data.CallHierarchy[src] == nil { +- data.CallHierarchy[src] = &CallHierarchyResult{} +- } +- for _, call := range calls { +- // we're only comparing protocol.range +- data.CallHierarchy[src].OutgoingCalls = append(data.CallHierarchy[src].OutgoingCalls, +- protocol.CallHierarchyItem{ +- URI: protocol.DocumentURI(call.URI()), +- Range: data.mustRange(call), +- }) +- } -} - --func undefinedErrorParam(err error) { -- panic("unimplemented") +-func (data *Data) collectInlayHints(src span.Span) { +- data.InlayHints = append(data.InlayHints, src) -} - -diff -urN a/gopls/internal/lsp/testdata/missingfunction/literals.go b/gopls/internal/lsp/testdata/missingfunction/literals.go ---- a/gopls/internal/lsp/testdata/missingfunction/literals.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/literals.go 1970-01-01 08:00:00 -@@ -1,7 +0,0 @@ --package missingfunction -- --type T struct{} +-func (data *Data) collectRenames(src span.Span, newText string) { +- data.Renames[src] = newText +-} - --func literals() { -- undefinedLiterals("hey compiler", T{}, &T{}) //@suggestedfix("undefinedLiterals", "quickfix", "") +-// mustRange converts spn into a protocol.Range, panicking on any error. +-func (data *Data) mustRange(spn span.Span) protocol.Range { +- m, err := data.Mapper(spn.URI()) +- rng, err := m.SpanRange(spn) +- if err != nil { +- panic(fmt.Sprintf("converting span %s to range: %v", spn, err)) +- } +- return rng -} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/literals.go.golden b/gopls/internal/lsp/testdata/missingfunction/literals.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/literals.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/literals.go.golden 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ ---- suggestedfix_literals_6_2 -- --package missingfunction - --type T struct{} +-func uriName(uri span.URI) string { +- return filepath.Base(strings.TrimSuffix(uri.Filename(), ".go")) +-} - --func literals() { -- undefinedLiterals("hey compiler", T{}, &T{}) //@suggestedfix("undefinedLiterals", "quickfix", "") +-// TODO(golang/go#54845): improve the formatting here to match standard +-// line:column position formatting. +-func SpanName(spn span.Span) string { +- return fmt.Sprintf("%v_%v_%v", uriName(spn.URI()), spn.Start().Line(), spn.Start().Column()) -} - --func undefinedLiterals(s string, t1 T, t2 *T) { -- panic("unimplemented") +-func shouldSkip(data *Data, uri span.URI) bool { +- if data.ModfileFlagAvailable { +- return false +- } +- // If the -modfile flag is not available, then we do not want to run +- // any tests on the go.mod file. +- if strings.HasSuffix(uri.Filename(), ".mod") { +- return true +- } +- // If the -modfile flag is not available, then we do not want to test any +- // uri that contains "go mod tidy". +- m, err := data.Mapper(uri) +- return err == nil && strings.Contains(string(m.Content), ", \"go mod tidy\",") -} +diff -urN a/gopls/internal/lsp/tests/util.go b/gopls/internal/lsp/tests/util.go +--- a/gopls/internal/lsp/tests/util.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/util.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,33 +0,0 @@ +-// Copyright 2020 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. - -diff -urN a/gopls/internal/lsp/testdata/missingfunction/operation.go b/gopls/internal/lsp/testdata/missingfunction/operation.go ---- a/gopls/internal/lsp/testdata/missingfunction/operation.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/operation.go 1970-01-01 08:00:00 -@@ -1,7 +0,0 @@ --package missingfunction +-package tests - --import "time" +-import ( +- "fmt" - --func operation() { -- undefinedOperation(10 * time.Second) //@suggestedfix("undefinedOperation", "quickfix", "") --} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/operation.go.golden b/gopls/internal/lsp/testdata/missingfunction/operation.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/operation.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/operation.go.golden 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ ---- suggestedfix_operation_6_2 -- --package missingfunction +- "golang.org/x/tools/gopls/internal/lsp/protocol" +-) - --import "time" +-// DiffCallHierarchyItems returns the diff between expected and actual call locations for incoming/outgoing call hierarchies +-func DiffCallHierarchyItems(gotCalls []protocol.CallHierarchyItem, expectedCalls []protocol.CallHierarchyItem) string { +- expected := make(map[protocol.Location]bool) +- for _, call := range expectedCalls { +- expected[protocol.Location{URI: call.URI, Range: call.Range}] = true +- } - --func operation() { -- undefinedOperation(10 * time.Second) //@suggestedfix("undefinedOperation", "quickfix", "") +- got := make(map[protocol.Location]bool) +- for _, call := range gotCalls { +- got[protocol.Location{URI: call.URI, Range: call.Range}] = true +- } +- if len(got) != len(expected) { +- return fmt.Sprintf("expected %d calls but got %d", len(expected), len(got)) +- } +- for spn := range got { +- if !expected[spn] { +- return fmt.Sprintf("incorrect calls, expected locations %v but got locations %v", expected, got) +- } +- } +- return "" -} +diff -urN a/gopls/internal/lsp/text_synchronization.go b/gopls/internal/lsp/text_synchronization.go +--- a/gopls/internal/lsp/text_synchronization.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/text_synchronization.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,367 +0,0 @@ +-// 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. - --func undefinedOperation(duration time.Duration) { -- panic("unimplemented") --} +-package lsp - -diff -urN a/gopls/internal/lsp/testdata/missingfunction/selector.go b/gopls/internal/lsp/testdata/missingfunction/selector.go ---- a/gopls/internal/lsp/testdata/missingfunction/selector.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/selector.go 1970-01-01 08:00:00 -@@ -1,6 +0,0 @@ --package missingfunction +-import ( +- "bytes" +- "context" +- "errors" +- "fmt" +- "path/filepath" +- "sync" - --func selector() { -- m := map[int]bool{} -- undefinedSelector(m[1]) //@suggestedfix("undefinedSelector", "quickfix", "") --} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/selector.go.golden b/gopls/internal/lsp/testdata/missingfunction/selector.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/selector.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/selector.go.golden 1970-01-01 08:00:00 -@@ -1,12 +0,0 @@ ---- suggestedfix_selector_5_2 -- --package missingfunction +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/event/tag" +- "golang.org/x/tools/internal/jsonrpc2" +-) - --func selector() { -- m := map[int]bool{} -- undefinedSelector(m[1]) //@suggestedfix("undefinedSelector", "quickfix", "") --} +-// ModificationSource identifies the origin of a change. +-type ModificationSource int - --func undefinedSelector(b bool) { -- panic("unimplemented") --} +-const ( +- // FromDidOpen is from a didOpen notification. +- FromDidOpen = ModificationSource(iota) - -diff -urN a/gopls/internal/lsp/testdata/missingfunction/slice.go b/gopls/internal/lsp/testdata/missingfunction/slice.go ---- a/gopls/internal/lsp/testdata/missingfunction/slice.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/slice.go 1970-01-01 08:00:00 -@@ -1,5 +0,0 @@ --package missingfunction +- // FromDidChange is from a didChange notification. +- FromDidChange - --func slice() { -- undefinedSlice([]int{1, 2}) //@suggestedfix("undefinedSlice", "quickfix", "") --} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/slice.go.golden b/gopls/internal/lsp/testdata/missingfunction/slice.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/slice.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/slice.go.golden 1970-01-01 08:00:00 -@@ -1,11 +0,0 @@ ---- suggestedfix_slice_4_2 -- --package missingfunction +- // FromDidChangeWatchedFiles is from didChangeWatchedFiles notification. +- FromDidChangeWatchedFiles - --func slice() { -- undefinedSlice([]int{1, 2}) //@suggestedfix("undefinedSlice", "quickfix", "") --} +- // FromDidSave is from a didSave notification. +- FromDidSave - --func undefinedSlice(i []int) { -- panic("unimplemented") --} +- // FromDidClose is from a didClose notification. +- FromDidClose - -diff -urN a/gopls/internal/lsp/testdata/missingfunction/tuple.go b/gopls/internal/lsp/testdata/missingfunction/tuple.go ---- a/gopls/internal/lsp/testdata/missingfunction/tuple.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/tuple.go 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --package missingfunction +- // FromDidChangeConfiguration is from a didChangeConfiguration notification. +- FromDidChangeConfiguration - --func tuple() { -- undefinedTuple(b()) //@suggestedfix("undefinedTuple", "quickfix", "") --} +- // FromRegenerateCgo refers to file modifications caused by regenerating +- // the cgo sources for the workspace. +- FromRegenerateCgo - --func b() (string, error) { -- return "", nil --} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/tuple.go.golden b/gopls/internal/lsp/testdata/missingfunction/tuple.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/tuple.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/tuple.go.golden 1970-01-01 08:00:00 -@@ -1,15 +0,0 @@ ---- suggestedfix_tuple_4_2 -- --package missingfunction +- // FromInitialWorkspaceLoad refers to the loading of all packages in the +- // workspace when the view is first created. +- FromInitialWorkspaceLoad +-) - --func tuple() { -- undefinedTuple(b()) //@suggestedfix("undefinedTuple", "quickfix", "") +-func (m ModificationSource) String() string { +- switch m { +- case FromDidOpen: +- return "opened files" +- case FromDidChange: +- return "changed files" +- case FromDidChangeWatchedFiles: +- return "files changed on disk" +- case FromDidSave: +- return "saved files" +- case FromDidClose: +- return "close files" +- case FromRegenerateCgo: +- return "regenerate cgo" +- case FromInitialWorkspaceLoad: +- return "initial workspace load" +- default: +- return "unknown file modification" +- } -} - --func undefinedTuple(s string, err error) { -- panic("unimplemented") --} +-func (s *Server) didOpen(ctx context.Context, params *protocol.DidOpenTextDocumentParams) error { +- ctx, done := event.Start(ctx, "lsp.Server.didOpen", tag.URI.Of(params.TextDocument.URI)) +- defer done() - --func b() (string, error) { -- return "", nil +- uri := params.TextDocument.URI.SpanURI() +- if !uri.IsFile() { +- return nil +- } +- // There may not be any matching view in the current session. If that's +- // the case, try creating a new view based on the opened file path. +- // +- // TODO(rstambler): This seems like it would continuously add new +- // views, but it won't because ViewOf only returns an error when there +- // are no views in the session. I don't know if that logic should go +- // here, or if we can continue to rely on that implementation detail. +- // +- // TODO(golang/go#57979): this will be generalized to a different view calculation. +- if _, err := s.session.ViewOf(uri); err != nil { +- dir := filepath.Dir(uri.Filename()) +- if err := s.addFolders(ctx, []protocol.WorkspaceFolder{{ +- URI: string(protocol.URIFromPath(dir)), +- Name: filepath.Base(dir), +- }}); err != nil { +- return err +- } +- } +- return s.didModifyFiles(ctx, []source.FileModification{{ +- URI: uri, +- Action: source.Open, +- Version: params.TextDocument.Version, +- Text: []byte(params.TextDocument.Text), +- LanguageID: params.TextDocument.LanguageID, +- }}, FromDidOpen) -} - -diff -urN a/gopls/internal/lsp/testdata/missingfunction/unique_params.go b/gopls/internal/lsp/testdata/missingfunction/unique_params.go ---- a/gopls/internal/lsp/testdata/missingfunction/unique_params.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/unique_params.go 1970-01-01 08:00:00 -@@ -1,7 +0,0 @@ --package missingfunction -- --func uniqueArguments() { -- var s string -- var i int -- undefinedUniqueArguments(s, i, s) //@suggestedfix("undefinedUniqueArguments", "quickfix", "") --} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/unique_params.go.golden b/gopls/internal/lsp/testdata/missingfunction/unique_params.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/unique_params.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/unique_params.go.golden 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ ---- suggestedfix_unique_params_6_2 -- --package missingfunction +-func (s *Server) didChange(ctx context.Context, params *protocol.DidChangeTextDocumentParams) error { +- ctx, done := event.Start(ctx, "lsp.Server.didChange", tag.URI.Of(params.TextDocument.URI)) +- defer done() - --func uniqueArguments() { -- var s string -- var i int -- undefinedUniqueArguments(s, i, s) //@suggestedfix("undefinedUniqueArguments", "quickfix", "") --} +- uri := params.TextDocument.URI.SpanURI() +- if !uri.IsFile() { +- return nil +- } - --func undefinedUniqueArguments(s1 string, i int, s2 string) { -- panic("unimplemented") +- text, err := s.changedText(ctx, uri, params.ContentChanges) +- if err != nil { +- return err +- } +- c := source.FileModification{ +- URI: uri, +- Action: source.Change, +- Version: params.TextDocument.Version, +- Text: text, +- } +- if err := s.didModifyFiles(ctx, []source.FileModification{c}, FromDidChange); err != nil { +- return err +- } +- return s.warnAboutModifyingGeneratedFiles(ctx, uri) -} - -diff -urN a/gopls/internal/lsp/testdata/multireturn/multi_return.go.in b/gopls/internal/lsp/testdata/multireturn/multi_return.go.in ---- a/gopls/internal/lsp/testdata/multireturn/multi_return.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/multireturn/multi_return.go.in 1970-01-01 08:00:00 -@@ -1,48 +0,0 @@ --package multireturn +-// warnAboutModifyingGeneratedFiles shows a warning if a user tries to edit a +-// generated file for the first time. +-func (s *Server) warnAboutModifyingGeneratedFiles(ctx context.Context, uri span.URI) error { +- s.changedFilesMu.Lock() +- _, ok := s.changedFiles[uri] +- if !ok { +- s.changedFiles[uri] = struct{}{} +- } +- s.changedFilesMu.Unlock() - --func f0() {} //@item(multiF0, "f0", "func()", "func") +- // This file has already been edited before. +- if ok { +- return nil +- } - --func f1(int) int { return 0 } //@item(multiF1, "f1", "func(int) int", "func") +- // Ideally, we should be able to specify that a generated file should +- // be opened as read-only. Tell the user that they should not be +- // editing a generated file. +- view, err := s.session.ViewOf(uri) +- if err != nil { +- return err +- } +- snapshot, release, err := view.Snapshot() +- if err != nil { +- return err +- } +- isGenerated := source.IsGenerated(ctx, snapshot, uri) +- release() - --func f2(int, int) (int, int) { return 0, 0 } //@item(multiF2, "f2", "func(int, int) (int, int)", "func") +- if !isGenerated { +- return nil +- } +- return s.client.ShowMessage(ctx, &protocol.ShowMessageParams{ +- Message: fmt.Sprintf("Do not edit this file! %s is a generated file.", uri.Filename()), +- Type: protocol.Warning, +- }) +-} - --func f2Str(string, string) (string, string) { return "", "" } //@item(multiF2Str, "f2Str", "func(string, string) (string, string)", "func") +-func (s *Server) didChangeWatchedFiles(ctx context.Context, params *protocol.DidChangeWatchedFilesParams) error { +- ctx, done := event.Start(ctx, "lsp.Server.didChangeWatchedFiles") +- defer done() - --func f3(int, int, int) (int, int, int) { return 0, 0, 0 } //@item(multiF3, "f3", "func(int, int, int) (int, int, int)", "func") -- --func _() { -- _ := f //@rank(" //", multiF1, multiF2) -- -- _, _ := f //@rank(" //", multiF2, multiF0),rank(" //", multiF1, multiF0) -- -- _, _ := _, f //@rank(" //", multiF1, multiF2),rank(" //", multiF1, multiF0) -- -- _, _ := f, abc //@rank(", abc", multiF1, multiF2) -- -- f1() //@rank(")", multiF1, multiF0) -- f1(f) //@rank(")", multiF1, multiF2) -- f2(f) //@rank(")", multiF2, multiF3),rank(")", multiF1, multiF3) -- f2(1, f) //@rank(")", multiF1, multiF2),rank(")", multiF1, multiF0) -- f2(1, ) //@rank(")", multiF1, multiF2),rank(")", multiF1, multiF0) -- f2Str() //@rank(")", multiF2Str, multiF2) -- -- var i int -- i, _ := f //@rank(" //", multiF2, multiF2Str) -- -- var s string -- _, s := f //@rank(" //", multiF2Str, multiF2) -- -- banana, s = f //@rank(" //", multiF2, multiF3) -- -- var variadic func(int, ...int) -- variadic() //@rank(")", multiF1, multiF0),rank(")", multiF2, multiF0),rank(")", multiF3, multiF0) +- var modifications []source.FileModification +- for _, change := range params.Changes { +- uri := change.URI.SpanURI() +- if !uri.IsFile() { +- continue +- } +- action := changeTypeToFileAction(change.Type) +- modifications = append(modifications, source.FileModification{ +- URI: uri, +- Action: action, +- OnDisk: true, +- }) +- } +- return s.didModifyFiles(ctx, modifications, FromDidChangeWatchedFiles) -} - --func _() { -- var baz func(...interface{}) -- -- var otterNap func() (int, int) //@item(multiTwo, "otterNap", "func() (int, int)", "var") -- var one int //@item(multiOne, "one", "int", "var") +-func (s *Server) didSave(ctx context.Context, params *protocol.DidSaveTextDocumentParams) error { +- ctx, done := event.Start(ctx, "lsp.Server.didSave", tag.URI.Of(params.TextDocument.URI)) +- defer done() - -- baz(on) //@rank(")", multiOne, multiTwo) +- uri := params.TextDocument.URI.SpanURI() +- if !uri.IsFile() { +- return nil +- } +- c := source.FileModification{ +- URI: uri, +- Action: source.Save, +- } +- if params.Text != nil { +- c.Text = []byte(*params.Text) +- } +- return s.didModifyFiles(ctx, []source.FileModification{c}, FromDidSave) -} -diff -urN a/gopls/internal/lsp/testdata/nested_complit/nested_complit.go.in b/gopls/internal/lsp/testdata/nested_complit/nested_complit.go.in ---- a/gopls/internal/lsp/testdata/nested_complit/nested_complit.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/nested_complit/nested_complit.go.in 1970-01-01 08:00:00 -@@ -1,15 +0,0 @@ --package nested_complit -- --type ncFoo struct {} //@item(structNCFoo, "ncFoo", "struct{...}", "struct") - --type ncBar struct { //@item(structNCBar, "ncBar", "struct{...}", "struct") -- baz []ncFoo --} +-func (s *Server) didClose(ctx context.Context, params *protocol.DidCloseTextDocumentParams) error { +- ctx, done := event.Start(ctx, "lsp.Server.didClose", tag.URI.Of(params.TextDocument.URI)) +- defer done() - --func _() { -- []ncFoo{} //@item(litNCFoo, "[]ncFoo{}", "", "var") -- _ := ncBar{ -- // disabled - see issue #54822 -- baz: [] // complete(" //", structNCFoo, structNCBar) +- uri := params.TextDocument.URI.SpanURI() +- if !uri.IsFile() { +- return nil - } +- return s.didModifyFiles(ctx, []source.FileModification{ +- { +- URI: uri, +- Action: source.Close, +- Version: -1, +- Text: nil, +- }, +- }, FromDidClose) -} -diff -urN a/gopls/internal/lsp/testdata/printf/printf.go b/gopls/internal/lsp/testdata/printf/printf.go ---- a/gopls/internal/lsp/testdata/printf/printf.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/printf/printf.go 1970-01-01 08:00:00 -@@ -1,33 +0,0 @@ --package printf -- --import "fmt" - --func myPrintf(string, ...interface{}) {} +-func (s *Server) didModifyFiles(ctx context.Context, modifications []source.FileModification, cause ModificationSource) error { +- // wg guards two conditions: +- // 1. didModifyFiles is complete +- // 2. the goroutine diagnosing changes on behalf of didModifyFiles is +- // complete, if it was started +- // +- // Both conditions must be satisfied for the purpose of testing: we don't +- // want to observe the completion of change processing until we have received +- // all diagnostics as well as all server->client notifications done on behalf +- // of this function. +- var wg sync.WaitGroup +- wg.Add(1) +- defer wg.Done() - --func _() { -- var ( -- aInt int //@item(printfInt, "aInt", "int", "var") -- aFloat float64 //@item(printfFloat, "aFloat", "float64", "var") -- aString string //@item(printfString, "aString", "string", "var") -- aBytes []byte //@item(printfBytes, "aBytes", "[]byte", "var") -- aStringer fmt.Stringer //@item(printfStringer, "aStringer", "fmt.Stringer", "var") -- aError error //@item(printfError, "aError", "error", "var") -- aBool bool //@item(printfBool, "aBool", "bool", "var") -- ) +- if s.Options().VerboseWorkDoneProgress { +- work := s.progress.Start(ctx, DiagnosticWorkTitle(cause), "Calculating file diagnostics...", nil, nil) +- go func() { +- wg.Wait() +- work.End(ctx, "Done.") +- }() +- } - -- myPrintf("%d", a) //@rank(")", printfInt, printfFloat) -- myPrintf("%s", a) //@rank(")", printfString, printfInt),rank(")", printfBytes, printfInt),rank(")", printfStringer, printfInt),rank(")", printfError, printfInt) -- myPrintf("%w", a) //@rank(")", printfError, printfInt) -- myPrintf("%x %[1]b", a) //@rank(")", printfInt, printfString) +- onDisk := cause == FromDidChangeWatchedFiles - -- fmt.Printf("%t", a) //@rank(")", printfBool, printfInt) +- s.stateMu.Lock() +- if s.state >= serverShutDown { +- // This state check does not prevent races below, and exists only to +- // produce a better error message. The actual race to the cache should be +- // guarded by Session.viewMu. +- s.stateMu.Unlock() +- return errors.New("server is shut down") +- } +- s.stateMu.Unlock() - -- fmt.Fprintf(nil, "%f", a) //@rank(")", printfFloat, printfInt) +- // If the set of changes included directories, expand those directories +- // to their files. +- modifications = s.session.ExpandModificationsToDirectories(ctx, modifications) - -- fmt.Sprintf("%[2]q %[1]*.[3]*[4]f", -- a, //@rank(",", printfInt, printfFloat) -- a, //@rank(",", printfString, printfFloat) -- a, //@rank(",", printfInt, printfFloat) -- a, //@rank(",", printfFloat, printfInt) -- ) --} -diff -urN a/gopls/internal/lsp/testdata/rank/assign_rank.go.in b/gopls/internal/lsp/testdata/rank/assign_rank.go.in ---- a/gopls/internal/lsp/testdata/rank/assign_rank.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rank/assign_rank.go.in 1970-01-01 08:00:00 -@@ -1,19 +0,0 @@ --package rank +- // Build a lookup map for file modifications, so that we can later join +- // with the snapshot file associations. +- modMap := make(map[span.URI]source.FileModification) +- for _, mod := range modifications { +- modMap[mod.URI] = mod +- } - --var ( -- apple int = 3 //@item(apple, "apple", "int", "var") -- pear string = "hello" //@item(pear, "pear", "string", "var") --) +- snapshots, release, err := s.session.DidModifyFiles(ctx, modifications) +- if err != nil { +- return err +- } - --func _() { -- orange := 1 //@item(orange, "orange", "int", "var") -- grape := "hello" //@item(grape, "grape", "string", "var") -- orange, grape = 2, "hello" //@complete(" \"", grape, pear, orange, apple) --} +- // golang/go#50267: diagnostics should be re-sent after an open or close. For +- // some clients, it may be helpful to re-send after each change. +- for snapshot, uris := range snapshots { +- for _, uri := range uris { +- mod := modMap[uri] +- if snapshot.Options().ChattyDiagnostics || mod.Action == source.Open || mod.Action == source.Close { +- s.mustPublishDiagnostics(uri) +- } +- } +- } - --func _() { -- var pineapple int //@item(pineapple, "pineapple", "int", "var") -- pineapple = 1 //@complete(" 1", pineapple, apple, pear) +- wg.Add(1) +- go func() { +- s.diagnoseSnapshots(snapshots, onDisk, cause) +- release() +- wg.Done() +- }() - -- y := //@complete(" /", pineapple, apple, pear) +- // After any file modifications, we need to update our watched files, +- // in case something changed. Compute the new set of directories to watch, +- // and if it differs from the current set, send updated registrations. +- return s.updateWatchedDirectories(ctx) -} -diff -urN a/gopls/internal/lsp/testdata/rank/binexpr_rank.go.in b/gopls/internal/lsp/testdata/rank/binexpr_rank.go.in ---- a/gopls/internal/lsp/testdata/rank/binexpr_rank.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rank/binexpr_rank.go.in 1970-01-01 08:00:00 -@@ -1,8 +0,0 @@ --package rank -- --func _() { -- _ = 5 + ; //@complete(" ;", apple, pear) -- y := + 5; //@complete(" +", apple, pear) - -- if 6 == {} //@complete(" {", apple, pear) +-// DiagnosticWorkTitle returns the title of the diagnostic work resulting from a +-// file change originating from the given cause. +-func DiagnosticWorkTitle(cause ModificationSource) string { +- return fmt.Sprintf("diagnosing %v", cause) -} -diff -urN a/gopls/internal/lsp/testdata/rank/boolexpr_rank.go b/gopls/internal/lsp/testdata/rank/boolexpr_rank.go ---- a/gopls/internal/lsp/testdata/rank/boolexpr_rank.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rank/boolexpr_rank.go 1970-01-01 08:00:00 -@@ -1,11 +0,0 @@ --package rank - --func _() { -- someRandomBoolFunc := func() bool { //@item(boolExprFunc, "someRandomBoolFunc", "func() bool", "var") -- return true +-func (s *Server) changedText(ctx context.Context, uri span.URI, changes []protocol.TextDocumentContentChangeEvent) ([]byte, error) { +- if len(changes) == 0 { +- return nil, fmt.Errorf("%w: no content changes provided", jsonrpc2.ErrInternal) - } - -- var foo, bar int //@item(boolExprBar, "bar", "int", "var") -- if foo == 123 && b { //@rank(" {", boolExprBar, boolExprFunc) +- // Check if the client sent the full content of the file. +- // We accept a full content change even if the server expected incremental changes. +- if len(changes) == 1 && changes[0].Range == nil && changes[0].RangeLength == 0 { +- return []byte(changes[0].Text), nil - } +- return s.applyIncrementalChanges(ctx, uri, changes) -} -diff -urN a/gopls/internal/lsp/testdata/rank/convert_rank.go.in b/gopls/internal/lsp/testdata/rank/convert_rank.go.in ---- a/gopls/internal/lsp/testdata/rank/convert_rank.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rank/convert_rank.go.in 1970-01-01 08:00:00 -@@ -1,54 +0,0 @@ --package rank - --import "time" +-func (s *Server) applyIncrementalChanges(ctx context.Context, uri span.URI, changes []protocol.TextDocumentContentChangeEvent) ([]byte, error) { +- fh, err := s.session.ReadFile(ctx, uri) +- if err != nil { +- return nil, err +- } +- content, err := fh.Content() +- if err != nil { +- return nil, fmt.Errorf("%w: file not found (%v)", jsonrpc2.ErrInternal, err) +- } +- for _, change := range changes { +- // TODO(adonovan): refactor to use diff.Apply, which is robust w.r.t. +- // out-of-order or overlapping changes---and much more efficient. - --func _() { -- type strList []string -- wantsStrList := func(strList) {} +- // Make sure to update mapper along with the content. +- m := protocol.NewMapper(uri, content) +- if change.Range == nil { +- return nil, fmt.Errorf("%w: unexpected nil range for change", jsonrpc2.ErrInternal) +- } +- spn, err := m.RangeSpan(*change.Range) +- if err != nil { +- return nil, err +- } +- start, end := spn.Start().Offset(), spn.End().Offset() +- if end < start { +- return nil, fmt.Errorf("%w: invalid range for content change", jsonrpc2.ErrInternal) +- } +- var buf bytes.Buffer +- buf.Write(content[:start]) +- buf.WriteString(change.Text) +- buf.Write(content[end:]) +- content = buf.Bytes() +- } +- return content, nil +-} - -- var ( -- convA string //@item(convertA, "convA", "string", "var") -- convB []string //@item(convertB, "convB", "[]string", "var") -- ) -- wantsStrList(strList(conv)) //@complete("))", convertB, convertA) +-func changeTypeToFileAction(ct protocol.FileChangeType) source.FileAction { +- switch ct { +- case protocol.Changed: +- return source.Change +- case protocol.Created: +- return source.Create +- case protocol.Deleted: +- return source.Delete +- } +- return source.UnknownFileAction -} +diff -urN a/gopls/internal/lsp/work/completion.go b/gopls/internal/lsp/work/completion.go +--- a/gopls/internal/lsp/work/completion.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/work/completion.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,154 +0,0 @@ +-// Copyright 2022 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. - --func _() { -- type myInt int +-package work - -- const ( -- convC = "hi" //@item(convertC, "convC", "string", "const") -- convD = 123 //@item(convertD, "convD", "int", "const") -- convE int = 123 //@item(convertE, "convE", "int", "const") -- convF string = "there" //@item(convertF, "convF", "string", "const") -- convG myInt = 123 //@item(convertG, "convG", "myInt", "const") -- ) +-import ( +- "context" +- "errors" +- "fmt" +- "os" +- "path/filepath" +- "sort" +- "strings" - -- var foo int -- foo = conv //@rank(" //", convertE, convertD) +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/event" +-) - -- var mi myInt -- mi = conv //@rank(" //", convertG, convertD, convertE) -- mi + conv //@rank(" //", convertG, convertD, convertE) +-func Completion(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, position protocol.Position) (*protocol.CompletionList, error) { +- ctx, done := event.Start(ctx, "work.Completion") +- defer done() - -- 1 + conv //@rank(" //", convertD, convertC),rank(" //", convertE, convertC),rank(" //", convertG, convertC) +- // Get the position of the cursor. +- pw, err := snapshot.ParseWork(ctx, fh) +- if err != nil { +- return nil, fmt.Errorf("getting go.work file handle: %w", err) +- } +- cursor, err := pw.Mapper.PositionOffset(position) +- if err != nil { +- return nil, fmt.Errorf("computing cursor offset: %w", err) +- } - -- type myString string -- var ms myString -- ms = conv //@rank(" //", convertC, convertF) +- // Find the use statement the user is in. +- use, pathStart, _ := usePath(pw, cursor) +- if use == nil { +- return &protocol.CompletionList{}, nil +- } +- completingFrom := use.Path[:cursor-pathStart] - -- type myUint uint32 -- var mu myUint -- mu = conv //@rank(" //", convertD, convertE) +- // We're going to find the completions of the user input +- // (completingFrom) by doing a walk on the innermost directory +- // of the given path, and comparing the found paths to make sure +- // that they match the component of the path after the +- // innermost directory. +- // +- // We'll maintain two paths when doing this: pathPrefixSlash +- // is essentially the path the user typed in, and pathPrefixAbs +- // is the path made absolute from the go.work directory. - -- // don't downrank constants when assigning to interface{} -- var _ interface{} = c //@rank(" //", convertD, complex) +- pathPrefixSlash := completingFrom +- pathPrefixAbs := filepath.FromSlash(pathPrefixSlash) +- if !filepath.IsAbs(pathPrefixAbs) { +- pathPrefixAbs = filepath.Join(filepath.Dir(pw.URI.Filename()), pathPrefixAbs) +- } - -- var _ time.Duration = conv //@rank(" //", convertD, convertE),snippet(" //", convertE, "time.Duration(convE)", "time.Duration(convE)") +- // pathPrefixDir is the directory that will be walked to find matches. +- // If pathPrefixSlash is not explicitly a directory boundary (is either equivalent to "." or +- // ends in a separator) we need to examine its parent directory to find sibling files that +- // match. +- depthBound := 5 +- pathPrefixDir, pathPrefixBase := pathPrefixAbs, "" +- pathPrefixSlashDir := pathPrefixSlash +- if filepath.Clean(pathPrefixSlash) != "." && !strings.HasSuffix(pathPrefixSlash, "/") { +- depthBound++ +- pathPrefixDir, pathPrefixBase = filepath.Split(pathPrefixAbs) +- pathPrefixSlashDir = dirNonClean(pathPrefixSlash) +- } - -- var convP myInt //@item(convertP, "convP", "myInt", "var") -- var _ *int = conv //@snippet(" //", convertP, "(*int)(&convP)", "(*int)(&convP)") +- var completions []string +- // Stop traversing deeper once we've hit 10k files to try to stay generally under 100ms. +- const numSeenBound = 10000 +- var numSeen int +- stopWalking := errors.New("hit numSeenBound") +- err = filepath.Walk(pathPrefixDir, func(wpath string, info os.FileInfo, err error) error { +- if numSeen > numSeenBound { +- // Stop traversing if we hit bound. +- return stopWalking +- } +- numSeen++ - -- var ff float64 //@item(convertFloat, "ff", "float64", "var") -- f == convD //@snippet(" =", convertFloat, "ff", "ff") --} -diff -urN a/gopls/internal/lsp/testdata/rank/struct/struct_rank.go b/gopls/internal/lsp/testdata/rank/struct/struct_rank.go ---- a/gopls/internal/lsp/testdata/rank/struct/struct_rank.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rank/struct/struct_rank.go 1970-01-01 08:00:00 -@@ -1,11 +0,0 @@ --package struct_rank +- // rel is the path relative to pathPrefixDir. +- // Make sure that it has pathPrefixBase as a prefix +- // otherwise it won't match the beginning of the +- // base component of the path the user typed in. +- rel := strings.TrimPrefix(wpath[len(pathPrefixDir):], string(filepath.Separator)) +- if info.IsDir() && wpath != pathPrefixDir && !strings.HasPrefix(rel, pathPrefixBase) { +- return filepath.SkipDir +- } - --type foo struct { -- c int //@item(c_rank, "c", "int", "field") -- b int //@item(b_rank, "b", "int", "field") -- a int //@item(a_rank, "a", "int", "field") --} +- // Check for a match (a module directory). +- if filepath.Base(rel) == "go.mod" { +- relDir := strings.TrimSuffix(dirNonClean(rel), string(os.PathSeparator)) +- completionPath := join(pathPrefixSlashDir, filepath.ToSlash(relDir)) - --func f() { -- foo := foo{} //@rank("}", c_rank, b_rank, a_rank) --} -diff -urN a/gopls/internal/lsp/testdata/rank/switch_rank.go.in b/gopls/internal/lsp/testdata/rank/switch_rank.go.in ---- a/gopls/internal/lsp/testdata/rank/switch_rank.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rank/switch_rank.go.in 1970-01-01 08:00:00 -@@ -1,29 +0,0 @@ --package rank +- if !strings.HasPrefix(completionPath, completingFrom) { +- return nil +- } +- if strings.HasSuffix(completionPath, "/") { +- // Don't suggest paths that end in "/". This happens +- // when the input is a path that ends in "/" and +- // the completion is empty. +- return nil +- } +- completion := completionPath[len(completingFrom):] +- if completingFrom == "" && !strings.HasPrefix(completion, "./") { +- // Bias towards "./" prefixes. +- completion = join(".", completion) +- } - --import "time" +- completions = append(completions, completion) +- } - --func _() { -- switch pear { -- case _: //@rank("_", pear, apple) +- if depth := strings.Count(rel, string(filepath.Separator)); depth >= depthBound { +- return filepath.SkipDir +- } +- return nil +- }) +- if err != nil && !errors.Is(err, stopWalking) { +- return nil, fmt.Errorf("walking to find completions: %w", err) - } - -- time.Monday //@item(timeMonday, "time.Monday", "time.Weekday", "const"),item(monday ,"Monday", "time.Weekday", "const") -- time.Friday //@item(timeFriday, "time.Friday", "time.Weekday", "const"),item(friday ,"Friday", "time.Weekday", "const") -- -- now := time.Now() -- now.Weekday //@item(nowWeekday, "now.Weekday", "func() time.Weekday", "method") -- -- then := time.Now() -- then.Weekday //@item(thenWeekday, "then.Weekday", "func() time.Weekday", "method") -- -- switch time.Weekday(0) { -- case time.Monday, time.Tuesday: -- case time.Wednesday, time.Thursday: -- case time.Saturday, time.Sunday: -- case t: //@rank(":", timeFriday, timeMonday) -- case time.: //@rank(":", friday, monday) +- sort.Strings(completions) - -- case now.Weekday(): -- case week: //@rank(":", thenWeekday, nowWeekday) +- items := []protocol.CompletionItem{} // must be a slice +- for _, c := range completions { +- items = append(items, protocol.CompletionItem{ +- Label: c, +- InsertText: c, +- }) - } +- return &protocol.CompletionList{Items: items}, nil -} -diff -urN a/gopls/internal/lsp/testdata/rank/type_assert_rank.go.in b/gopls/internal/lsp/testdata/rank/type_assert_rank.go.in ---- a/gopls/internal/lsp/testdata/rank/type_assert_rank.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rank/type_assert_rank.go.in 1970-01-01 08:00:00 -@@ -1,8 +0,0 @@ --package rank - --func _() { -- type flower int //@item(flower, "flower", "int", "type") -- var fig string //@item(fig, "fig", "string", "var") +-// dirNonClean is filepath.Dir, without the Clean at the end. +-func dirNonClean(path string) string { +- vol := filepath.VolumeName(path) +- i := len(path) - 1 +- for i >= len(vol) && !os.IsPathSeparator(path[i]) { +- i-- +- } +- return path[len(vol) : i+1] +-} - -- _ = interface{}(nil).(f) //@complete(") //", flower) +-func join(a, b string) string { +- if a == "" { +- return b +- } +- if b == "" { +- return a +- } +- return strings.TrimSuffix(a, "/") + "/" + b -} -diff -urN a/gopls/internal/lsp/testdata/rank/type_switch_rank.go.in b/gopls/internal/lsp/testdata/rank/type_switch_rank.go.in ---- a/gopls/internal/lsp/testdata/rank/type_switch_rank.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rank/type_switch_rank.go.in 1970-01-01 08:00:00 -@@ -1,31 +0,0 @@ --package rank +diff -urN a/gopls/internal/lsp/work/diagnostics.go b/gopls/internal/lsp/work/diagnostics.go +--- a/gopls/internal/lsp/work/diagnostics.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/work/diagnostics.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,92 +0,0 @@ +-// Copyright 2022 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 work - -import ( +- "context" - "fmt" -- "go/ast" +- "os" +- "path/filepath" +- +- "golang.org/x/mod/modfile" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/event" -) - --func _() { -- type basket int //@item(basket, "basket", "int", "type") -- var banana string //@item(banana, "banana", "string", "var") +-func Diagnostics(ctx context.Context, snapshot source.Snapshot) (map[span.URI][]*source.Diagnostic, error) { +- ctx, done := event.Start(ctx, "work.Diagnostics", source.SnapshotLabels(snapshot)...) +- defer done() - -- switch interface{}(pear).(type) { -- case b: //@complete(":", basket) -- b //@complete(" //", banana, basket) +- reports := map[span.URI][]*source.Diagnostic{} +- uri := snapshot.WorkFile() +- if uri == "" { +- return nil, nil +- } +- fh, err := snapshot.ReadFile(ctx, uri) +- if err != nil { +- return nil, err +- } +- reports[fh.URI()] = []*source.Diagnostic{} +- diagnostics, err := DiagnosticsForWork(ctx, snapshot, fh) +- if err != nil { +- return nil, err +- } +- for _, d := range diagnostics { +- fh, err := snapshot.ReadFile(ctx, d.URI) +- if err != nil { +- return nil, err +- } +- reports[fh.URI()] = append(reports[fh.URI()], d) - } - -- Ident //@item(astIdent, "Ident", "struct{...}", "struct") -- IfStmt //@item(astIfStmt, "IfStmt", "struct{...}", "struct") +- return reports, nil +-} - -- switch ast.Node(nil).(type) { -- case *ast.Ident: -- case *ast.I: //@rank(":", astIfStmt, astIdent) +-func DiagnosticsForWork(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) ([]*source.Diagnostic, error) { +- pw, err := snapshot.ParseWork(ctx, fh) +- if err != nil { +- if pw == nil || len(pw.ParseErrors) == 0 { +- return nil, err +- } +- return pw.ParseErrors, nil - } - -- Stringer //@item(fmtStringer, "Stringer", "interface{...}", "interface") -- GoStringer //@item(fmtGoStringer, "GoStringer", "interface{...}", "interface") +- // Add diagnostic if a directory does not contain a module. +- var diagnostics []*source.Diagnostic +- for _, use := range pw.File.Use { +- rng, err := pw.Mapper.OffsetRange(use.Syntax.Start.Byte, use.Syntax.End.Byte) +- if err != nil { +- return nil, err +- } - -- switch interface{}(nil).(type) { -- case fmt.Stringer: //@rank(":", fmtStringer, fmtGoStringer) +- modfh, err := snapshot.ReadFile(ctx, modFileURI(pw, use)) +- if err != nil { +- return nil, err +- } +- if _, err := modfh.Content(); err != nil && os.IsNotExist(err) { +- diagnostics = append(diagnostics, &source.Diagnostic{ +- URI: fh.URI(), +- Range: rng, +- Severity: protocol.SeverityError, +- Source: source.WorkFileError, +- Message: fmt.Sprintf("directory %v does not contain a module", use.Path), +- }) +- } - } +- return diagnostics, nil -} -diff -urN a/gopls/internal/lsp/testdata/rename/a/random.go.golden b/gopls/internal/lsp/testdata/rename/a/random.go.golden ---- a/gopls/internal/lsp/testdata/rename/a/random.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/a/random.go.golden 1970-01-01 08:00:00 -@@ -1,616 +0,0 @@ ---- GetSum-rename -- --package a - --import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +-func modFileURI(pw *source.ParsedWorkFile, use *modfile.Use) span.URI { +- workdir := filepath.Dir(pw.URI.Filename()) - --func Random() int { -- y := 6 + 7 -- return y --} +- modroot := filepath.FromSlash(use.Path) +- if !filepath.IsAbs(modroot) { +- modroot = filepath.Join(workdir, modroot) +- } - --func Random2(y int) int { //@rename("y", "z") -- return y +- return span.URIFromPath(filepath.Join(modroot, "go.mod")) -} +diff -urN a/gopls/internal/lsp/work/format.go b/gopls/internal/lsp/work/format.go +--- a/gopls/internal/lsp/work/format.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/work/format.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,28 +0,0 @@ +-// Copyright 2022 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. - --type Pos struct { -- x, y int --} +-package work - --func (p *Pos) GetSum() int { -- return p.x + p.y //@rename("x", "myX") --} +-import ( +- "context" - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.GetSum() //@rename("Sum", "GetSum") --} +- "golang.org/x/mod/modfile" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/event" +-) - --func sw() { -- var x interface{} +-func Format(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) ([]protocol.TextEdit, error) { +- ctx, done := event.Start(ctx, "work.Format") +- defer done() - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- pw, err := snapshot.ParseWork(ctx, fh) +- if err != nil { +- return nil, err - } +- formatted := modfile.Format(pw.File.Syntax) +- // Calculate the edits to be made due to the change. +- diffs := snapshot.Options().ComputeEdits(string(pw.Mapper.Content), string(formatted)) +- return source.ToProtocolEdits(pw.Mapper, diffs) -} +diff -urN a/gopls/internal/lsp/work/hover.go b/gopls/internal/lsp/work/hover.go +--- a/gopls/internal/lsp/work/hover.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/work/hover.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,92 +0,0 @@ +-// Copyright 2022 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. - ---- f2name-rename -- --package a +-package work - -import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2name "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +- "bytes" +- "context" +- "fmt" +- +- "golang.org/x/mod/modfile" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/event" -) - --func Random() int { -- y := 6 + 7 -- return y --} +-func Hover(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, position protocol.Position) (*protocol.Hover, error) { +- // We only provide hover information for the view's go.work file. +- if fh.URI() != snapshot.WorkFile() { +- return nil, nil +- } - --func Random2(y int) int { //@rename("y", "z") -- return y --} +- ctx, done := event.Start(ctx, "work.Hover") +- defer done() - --type Pos struct { -- x, y int --} +- // Get the position of the cursor. +- pw, err := snapshot.ParseWork(ctx, fh) +- if err != nil { +- return nil, fmt.Errorf("getting go.work file handle: %w", err) +- } +- offset, err := pw.Mapper.PositionOffset(position) +- if err != nil { +- return nil, fmt.Errorf("computing cursor offset: %w", err) +- } - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") --} +- // Confirm that the cursor is inside a use statement, and then find +- // the position of the use statement's directory path. +- use, pathStart, pathEnd := usePath(pw, offset) - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} +- // The cursor position is not on a use statement. +- if use == nil { +- return nil, nil +- } - --func sw() { -- var x interface{} +- // Get the mod file denoted by the use. +- modfh, err := snapshot.ReadFile(ctx, modFileURI(pw, use)) +- if err != nil { +- return nil, fmt.Errorf("getting modfile handle: %w", err) +- } +- pm, err := snapshot.ParseMod(ctx, modfh) +- if err != nil { +- return nil, fmt.Errorf("getting modfile handle: %w", err) +- } +- if pm.File.Module == nil { +- return nil, fmt.Errorf("modfile has no module declaration") +- } +- mod := pm.File.Module.Mod - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2name.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- // Get the range to highlight for the hover. +- rng, err := pw.Mapper.OffsetRange(pathStart, pathEnd) +- if err != nil { +- return nil, err - } +- options := snapshot.Options() +- return &protocol.Hover{ +- Contents: protocol.MarkupContent{ +- Kind: options.PreferredContentFormat, +- Value: mod.Path, +- }, +- Range: rng, +- }, nil -} - ---- f2y-rename -- --package a +-func usePath(pw *source.ParsedWorkFile, offset int) (use *modfile.Use, pathStart, pathEnd int) { +- for _, u := range pw.File.Use { +- path := []byte(u.Path) +- s, e := u.Syntax.Start.Byte, u.Syntax.End.Byte +- i := bytes.Index(pw.Mapper.Content[s:e], path) +- if i == -1 { +- // This should not happen. +- continue +- } +- // Shift the start position to the location of the +- // module directory within the use statement. +- pathStart, pathEnd = s+i, s+i+len(path) +- if pathStart <= offset && offset <= pathEnd { +- return u, pathStart, pathEnd +- } +- } +- return nil, 0, 0 +-} +diff -urN a/gopls/internal/lsp/workspace.go b/gopls/internal/lsp/workspace.go +--- a/gopls/internal/lsp/workspace.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/workspace.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,106 +0,0 @@ +-// 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 lsp - -import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2y "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +- "context" +- "fmt" +- "sync" - --func Random() int { -- y := 6 + 7 -- return y --} +- "golang.org/x/tools/gopls/internal/lsp/cache" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/event" +-) - --func Random2(y int) int { //@rename("y", "z") -- return y +-func (s *Server) didChangeWorkspaceFolders(ctx context.Context, params *protocol.DidChangeWorkspaceFoldersParams) error { +- event := params.Event +- for _, folder := range event.Removed { +- view := s.session.ViewByName(folder.Name) +- if view != nil { +- s.session.RemoveView(view) +- } else { +- return fmt.Errorf("view %s for %v not found", folder.Name, folder.URI) +- } +- } +- return s.addFolders(ctx, event.Added) -} - --type Pos struct { -- x, y int +-// addView returns a Snapshot and a release function that must be +-// called when it is no longer needed. +-func (s *Server) addView(ctx context.Context, name string, uri span.URI) (source.Snapshot, func(), error) { +- s.stateMu.Lock() +- state := s.state +- s.stateMu.Unlock() +- if state < serverInitialized { +- return nil, nil, fmt.Errorf("addView called before server initialized") +- } +- options, err := s.fetchFolderOptions(ctx, uri) +- if err != nil { +- return nil, nil, err +- } +- folder := &cache.Folder{ +- Dir: uri, +- Name: name, +- Options: options, +- } +- _, snapshot, release, err := s.session.NewView(ctx, folder) +- return snapshot, release, err -} - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") --} +-func (s *Server) didChangeConfiguration(ctx context.Context, _ *protocol.DidChangeConfigurationParams) error { +- ctx, done := event.Start(ctx, "lsp.Server.didChangeConfiguration") +- defer done() - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} +- // Apply any changes to the session-level settings. +- options, err := s.fetchFolderOptions(ctx, "") +- if err != nil { +- return err +- } +- s.SetOptions(options) - --func sw() { -- var x interface{} +- // Collect options for all workspace folders. +- seen := make(map[span.URI]bool) +- for _, view := range s.session.Views() { +- if seen[view.Folder()] { +- continue +- } +- seen[view.Folder()] = true +- options, err := s.fetchFolderOptions(ctx, view.Folder()) +- if err != nil { +- return err +- } +- s.session.SetFolderOptions(ctx, view.Folder(), options) +- } - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2y.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- var wg sync.WaitGroup +- for _, view := range s.session.Views() { +- view := view +- wg.Add(1) +- go func() { +- defer wg.Done() +- snapshot, release, err := view.Snapshot() +- if err != nil { +- return // view is shut down; no need to diagnose +- } +- defer release() +- s.diagnoseSnapshot(snapshot, nil, false, 0) +- }() - } --} - ---- fmt2-rename -- --package a +- if s.Options().VerboseWorkDoneProgress { +- work := s.progress.Start(ctx, DiagnosticWorkTitle(FromDidChangeConfiguration), "Calculating diagnostics...", nil, nil) +- go func() { +- wg.Wait() +- work.End(ctx, "Done.") +- }() +- } - --import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- fmt2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +- // An options change may have affected the detected Go version. +- s.checkViewGoVersions() - --func Random() int { -- y := 6 + 7 -- return y +- return nil -} +diff -urN a/gopls/internal/lsp/workspace_symbol.go b/gopls/internal/lsp/workspace_symbol.go +--- a/gopls/internal/lsp/workspace_symbol.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/workspace_symbol.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,38 +0,0 @@ +-// Copyright 2020 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. - --func Random2(y int) int { //@rename("y", "z") -- return y --} +-package lsp - --type Pos struct { -- x, y int --} +-import ( +- "context" - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") --} +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/telemetry" +- "golang.org/x/tools/internal/event" +-) - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} +-func (s *Server) symbol(ctx context.Context, params *protocol.WorkspaceSymbolParams) (_ []protocol.SymbolInformation, rerr error) { +- recordLatency := telemetry.StartLatencyTimer("symbol") +- defer func() { +- recordLatency(ctx, rerr) +- }() - --func sw() { -- var x interface{} +- ctx, done := event.Start(ctx, "lsp.Server.symbol") +- defer done() - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- fmt2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- views := s.session.Views() +- matcher := s.Options().SymbolMatcher +- style := s.Options().SymbolStyle +- // TODO(rfindley): it looks wrong that we need to pass views here. +- // +- // Evidence: +- // - this is the only place we convert views to []source.View +- // - workspace symbols is the only place where we call source.View.Snapshot +- var sourceViews []source.View +- for _, v := range views { +- sourceViews = append(sourceViews, v) - } +- return source.WorkspaceSymbols(ctx, matcher, style, sourceViews, params.Query) -} +diff -urN a/gopls/internal/regtest/bench/bench_test.go b/gopls/internal/regtest/bench/bench_test.go +--- a/gopls/internal/regtest/bench/bench_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/bench_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,351 +0,0 @@ +-// Copyright 2020 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. - ---- fmty-rename -- --package a +-package bench - -import ( -- lg "log" -- fmty "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +- "bytes" +- "compress/gzip" +- "context" +- "flag" +- "fmt" +- "io" +- "log" +- "os" +- "os/exec" +- "path/filepath" +- "strings" +- "sync" +- "testing" +- "time" - --func Random() int { -- y := 6 + 7 -- return y --} +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/hooks" +- "golang.org/x/tools/gopls/internal/lsp/cmd" +- "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp/fake" +- "golang.org/x/tools/gopls/internal/lsp/regtest" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/fakenet" +- "golang.org/x/tools/internal/jsonrpc2" +- "golang.org/x/tools/internal/jsonrpc2/servertest" +- "golang.org/x/tools/internal/pprof" +- "golang.org/x/tools/internal/tool" +-) - --func Random2(y int) int { //@rename("y", "z") -- return y --} +-var ( +- goplsPath = flag.String("gopls_path", "", "if set, use this gopls for testing; incompatible with -gopls_commit") - --type Pos struct { -- x, y int --} +- installGoplsOnce sync.Once // guards installing gopls at -gopls_commit +- goplsCommit = flag.String("gopls_commit", "", "if set, install and use gopls at this commit for testing; incompatible with -gopls_path") - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") --} +- cpuProfile = flag.String("gopls_cpuprofile", "", "if set, the cpu profile file suffix; see \"Profiling\" in the package doc") +- memProfile = flag.String("gopls_memprofile", "", "if set, the mem profile file suffix; see \"Profiling\" in the package doc") +- allocProfile = flag.String("gopls_allocprofile", "", "if set, the alloc profile file suffix; see \"Profiling\" in the package doc") +- trace = flag.String("gopls_trace", "", "if set, the trace file suffix; see \"Profiling\" in the package doc") - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} +- // If non-empty, tempDir is a temporary working dir that was created by this +- // test suite. +- makeTempDirOnce sync.Once // guards creation of the temp dir +- tempDir string +-) - --func sw() { -- var x interface{} +-// if runAsGopls is "true", run the gopls command instead of the testing.M. +-const runAsGopls = "_GOPLS_BENCH_RUN_AS_GOPLS" - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmty.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +-func TestMain(m *testing.M) { +- bug.PanicOnBugs = true +- if os.Getenv(runAsGopls) == "true" { +- tool.Main(context.Background(), cmd.New("gopls", "", nil, hooks.Options), os.Args[1:]) +- os.Exit(0) +- } +- event.SetExporter(nil) // don't log to stderr +- code := m.Run() +- if err := cleanup(); err != nil { +- fmt.Fprintf(os.Stderr, "cleaning up after benchmarks: %v\n", err) +- if code == 0 { +- code = 1 +- } - } +- os.Exit(code) -} - ---- format-rename -- --package a -- --import ( -- lg "log" -- format "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) -- --func Random() int { -- y := 6 + 7 -- return y --} -- --func Random2(y int) int { //@rename("y", "z") -- return y +-// getTempDir returns the temporary directory to use for benchmark files, +-// creating it if necessary. +-func getTempDir() string { +- makeTempDirOnce.Do(func() { +- var err error +- tempDir, err = os.MkdirTemp("", "gopls-bench") +- if err != nil { +- log.Fatal(err) +- } +- }) +- return tempDir -} - --type Pos struct { -- x, y int --} +-// shallowClone performs a shallow clone of repo into dir at the given +-// 'commitish' ref (any commit reference understood by git). +-// +-// The directory dir must not already exist. +-func shallowClone(dir, repo, commitish string) error { +- if err := os.Mkdir(dir, 0750); err != nil { +- return fmt.Errorf("creating dir for %s: %v", repo, err) +- } - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") --} +- // Set a timeout for git fetch. If this proves flaky, it can be removed. +- ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) +- defer cancel() - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") +- // Use a shallow fetch to download just the relevant commit. +- shInit := fmt.Sprintf("git init && git fetch --depth=1 %q %q && git checkout FETCH_HEAD", repo, commitish) +- initCmd := exec.CommandContext(ctx, "/bin/sh", "-c", shInit) +- initCmd.Dir = dir +- if output, err := initCmd.CombinedOutput(); err != nil { +- return fmt.Errorf("checking out %s: %v\n%s", repo, err, output) +- } +- return nil -} - --func sw() { -- var x interface{} -- -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- format.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +-// connectEditor connects a fake editor session in the given dir, using the +-// given editor config. +-func connectEditor(dir string, config fake.EditorConfig, ts servertest.Connector) (*fake.Sandbox, *fake.Editor, *regtest.Awaiter, error) { +- s, err := fake.NewSandbox(&fake.SandboxConfig{ +- Workdir: dir, +- GOPROXY: "https://proxy.golang.org", +- }) +- if err != nil { +- return nil, nil, nil, err - } --} - ---- log-rename -- --package a +- a := regtest.NewAwaiter(s.Workdir) +- const skipApplyEdits = false +- editor, err := fake.NewEditor(s, config).Connect(context.Background(), ts, a.Hooks(), skipApplyEdits) +- if err != nil { +- return nil, nil, nil, err +- } - --import ( -- "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +- return s, editor, a, nil +-} - --func Random() int { -- y := 6 + 7 -- return y +-// newGoplsConnector returns a connector that connects to a new gopls process, +-// executed with the provided arguments. +-func newGoplsConnector(args []string) (servertest.Connector, error) { +- if *goplsPath != "" && *goplsCommit != "" { +- panic("can't set both -gopls_path and -gopls_commit") +- } +- var ( +- goplsPath = *goplsPath +- env []string +- ) +- if *goplsCommit != "" { +- goplsPath = getInstalledGopls() +- } +- if goplsPath == "" { +- var err error +- goplsPath, err = os.Executable() +- if err != nil { +- return nil, err +- } +- env = []string{fmt.Sprintf("%s=true", runAsGopls)} +- } +- return &SidecarServer{ +- goplsPath: goplsPath, +- env: env, +- args: args, +- }, nil -} - --func Random2(y int) int { //@rename("y", "z") -- return y +-// profileArgs returns additional command-line arguments to use when invoking +-// gopls, to enable the user-requested profiles. +-// +-// If wantCPU is set, CPU profiling is enabled as well. Some tests may want to +-// instrument profiling around specific critical sections of the benchmark, +-// rather than the entire process. +-// +-// TODO(rfindley): like CPU, all of these would be better served by a custom +-// command. Very rarely do we care about memory usage as the process exits: we +-// care about specific points in time during the benchmark. mem and alloc +-// should be snapshotted, and tracing should be bracketed around critical +-// sections. +-func profileArgs(name string, wantCPU bool) []string { +- var args []string +- if wantCPU && *cpuProfile != "" { +- args = append(args, fmt.Sprintf("-profile.cpu=%s", qualifiedName(name, *cpuProfile))) +- } +- if *memProfile != "" { +- args = append(args, fmt.Sprintf("-profile.mem=%s", qualifiedName(name, *memProfile))) +- } +- if *allocProfile != "" { +- args = append(args, fmt.Sprintf("-profile.alloc=%s", qualifiedName(name, *allocProfile))) +- } +- if *trace != "" { +- args = append(args, fmt.Sprintf("-profile.trace=%s", qualifiedName(name, *trace))) +- } +- return args -} - --type Pos struct { -- x, y int +-func qualifiedName(args ...string) string { +- return strings.Join(args, ".") -} - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") +-// getInstalledGopls builds gopls at the given -gopls_commit, returning the +-// path to the gopls binary. +-func getInstalledGopls() string { +- if *goplsCommit == "" { +- panic("must provide -gopls_commit") +- } +- toolsDir := filepath.Join(getTempDir(), "gopls_build") +- goplsPath := filepath.Join(toolsDir, "gopls", "gopls") +- +- installGoplsOnce.Do(func() { +- log.Printf("installing gopls: checking out x/tools@%s into %s\n", *goplsCommit, toolsDir) +- if err := shallowClone(toolsDir, "https://go.googlesource.com/tools", *goplsCommit); err != nil { +- log.Fatal(err) +- } +- +- log.Println("installing gopls: building...") +- bld := exec.Command("go", "build", ".") +- bld.Dir = filepath.Join(toolsDir, "gopls") +- if output, err := bld.CombinedOutput(); err != nil { +- log.Fatalf("building gopls: %v\n%s", err, output) +- } +- +- // Confirm that the resulting path now exists. +- if _, err := os.Stat(goplsPath); err != nil { +- log.Fatalf("os.Stat(%s): %v", goplsPath, err) +- } +- }) +- return goplsPath -} - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") +-// A SidecarServer starts (and connects to) a separate gopls process at the +-// given path. +-type SidecarServer struct { +- goplsPath string +- env []string // additional environment bindings +- args []string // command-line arguments -} - --func sw() { -- var x interface{} +-// Connect creates new io.Pipes and binds them to the underlying StreamServer. +-// +-// It implements the servertest.Connector interface. +-func (s *SidecarServer) Connect(ctx context.Context) jsonrpc2.Conn { +- // Note: don't use CommandContext here, as we want gopls to exit gracefully +- // in order to write out profile data. +- // +- // We close the connection on context cancelation below. +- cmd := exec.Command(s.goplsPath, s.args...) - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- log.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- stdin, err := cmd.StdinPipe() +- if err != nil { +- log.Fatal(err) +- } +- stdout, err := cmd.StdoutPipe() +- if err != nil { +- log.Fatal(err) +- } +- cmd.Stderr = os.Stderr +- cmd.Env = append(os.Environ(), s.env...) +- if err := cmd.Start(); err != nil { +- log.Fatalf("starting gopls: %v", err) - } --} -- ---- myX-rename -- --package a - --import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +- go func() { +- // If we don't log.Fatal here, benchmarks may hang indefinitely if gopls +- // exits abnormally. +- // +- // TODO(rfindley): ideally we would shut down the connection gracefully, +- // but that doesn't currently work. +- if err := cmd.Wait(); err != nil { +- log.Fatalf("gopls invocation failed with error: %v", err) +- } +- }() - --func Random() int { -- y := 6 + 7 -- return y --} +- clientStream := jsonrpc2.NewHeaderStream(fakenet.NewConn("stdio", stdout, stdin)) +- clientConn := jsonrpc2.NewConn(clientStream) - --func Random2(y int) int { //@rename("y", "z") -- return y --} +- go func() { +- select { +- case <-ctx.Done(): +- clientConn.Close() +- clientStream.Close() +- case <-clientConn.Done(): +- } +- }() - --type Pos struct { -- myX, y int +- return clientConn -} - --func (p *Pos) Sum() int { -- return p.myX + p.y //@rename("x", "myX") +-// startProfileIfSupported checks to see if the remote gopls instance supports +-// the start/stop profiling commands. If so, it starts profiling and returns a +-// function that stops profiling and records the total CPU seconds sampled in the +-// cpu_seconds benchmark metric. +-// +-// If the remote gopls instance does not support profiling commands, this +-// function returns nil. +-// +-// If the supplied userSuffix is non-empty, the profile is written to +-// ., and not deleted when the benchmark exits. Otherwise, +-// the profile is written to a temp file that is deleted after the cpu_seconds +-// metric has been computed. +-func startProfileIfSupported(b *testing.B, env *regtest.Env, name string) func() { +- if !env.Editor.HasCommand(command.StartProfile.ID()) { +- return nil +- } +- b.StopTimer() +- stopProfile := env.StartProfile() +- b.StartTimer() +- return func() { +- b.StopTimer() +- profFile := stopProfile() +- totalCPU, err := totalCPUForProfile(profFile) +- if err != nil { +- b.Fatalf("reading profile: %v", err) +- } +- b.ReportMetric(totalCPU.Seconds()/float64(b.N), "cpu_seconds/op") +- if *cpuProfile == "" { +- // The user didn't request profiles, so delete it to clean up. +- if err := os.Remove(profFile); err != nil { +- b.Errorf("removing profile file: %v", err) +- } +- } else { +- // NOTE: if this proves unreliable (due to e.g. EXDEV), we can fall back +- // on Read+Write+Remove. +- name := qualifiedName(name, *cpuProfile) +- if err := os.Rename(profFile, name); err != nil { +- b.Fatalf("renaming profile file: %v", err) +- } +- } +- } -} - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") +-// totalCPUForProfile reads the pprof profile with the given file name, parses, +-// and aggregates the total CPU sampled during the profile. +-func totalCPUForProfile(filename string) (time.Duration, error) { +- protoGz, err := os.ReadFile(filename) +- if err != nil { +- return 0, err +- } +- rd, err := gzip.NewReader(bytes.NewReader(protoGz)) +- if err != nil { +- return 0, fmt.Errorf("creating gzip reader for %s: %v", filename, err) +- } +- data, err := io.ReadAll(rd) +- if err != nil { +- return 0, fmt.Errorf("reading %s: %v", filename, err) +- } +- return pprof.TotalTime(data) -} - --func sw() { -- var x interface{} -- -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") -- } +-// closeBuffer stops the benchmark timer and closes the buffer with the given +-// name. +-// +-// It may be used to clean up files opened in the shared environment during +-// benchmarking. +-func closeBuffer(b *testing.B, env *regtest.Env, name string) { +- b.StopTimer() +- env.CloseBuffer(name) +- env.AfterChange() +- b.StartTimer() -} +diff -urN a/gopls/internal/regtest/bench/codeaction_test.go b/gopls/internal/regtest/bench/codeaction_test.go +--- a/gopls/internal/regtest/bench/codeaction_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/codeaction_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,69 +0,0 @@ +-// Copyright 2023 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. - ---- pos-rename -- --package a +-package bench - -import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +- "fmt" +- "sync/atomic" +- "testing" +- +- "golang.org/x/tools/gopls/internal/lsp/protocol" -) - --func Random() int { -- y := 6 + 7 -- return y --} +-func BenchmarkCodeAction(b *testing.B) { +- for _, test := range didChangeTests { +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- defer closeBuffer(b, env, test.file) +- env.AfterChange() - --func Random2(y int) int { //@rename("y", "z") -- return y --} +- env.CodeAction(test.file, nil) // pre-warm - --type Pos struct { -- x, y int --} +- b.ResetTimer() - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") --} +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "hover")); stopAndRecord != nil { +- defer stopAndRecord() +- } - --func _() { -- var pos Pos //@rename("p", "pos") -- _ = pos.Sum() //@rename("Sum", "GetSum") +- for i := 0; i < b.N; i++ { +- env.CodeAction(test.file, nil) +- } +- }) +- } -} - --func sw() { -- var x interface{} +-func BenchmarkCodeActionFollowingEdit(b *testing.B) { +- for _, test := range didChangeTests { +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- defer closeBuffer(b, env, test.file) +- env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"}) +- env.AfterChange() - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- env.CodeAction(test.file, nil) // pre-warm +- +- b.ResetTimer() +- +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "hover")); stopAndRecord != nil { +- defer stopAndRecord() +- } +- +- for i := 0; i < b.N; i++ { +- edits := atomic.AddInt64(&editID, 1) +- env.EditBuffer(test.file, protocol.TextEdit{ +- Range: protocol.Range{ +- Start: protocol.Position{Line: 0, Character: 0}, +- End: protocol.Position{Line: 1, Character: 0}, +- }, +- // Increment the placeholder text, to ensure cache misses. +- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), +- }) +- env.CodeAction(test.file, nil) +- } +- }) - } -} +diff -urN a/gopls/internal/regtest/bench/completion_test.go b/gopls/internal/regtest/bench/completion_test.go +--- a/gopls/internal/regtest/bench/completion_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/completion_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,290 +0,0 @@ +-// Copyright 2020 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. - ---- y0-rename -- --package a +-package bench - -import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +- "flag" +- "fmt" +- "sync/atomic" +- "testing" +- +- "golang.org/x/tools/gopls/internal/lsp/fake" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" -) - --func Random() int { -- y := 6 + 7 -- return y --} +-// TODO(rfindley): update these completion tests to run on multiple repos. - --func Random2(y int) int { //@rename("y", "z") -- return y --} +-type completionBenchOptions struct { +- file, locationRegexp string - --type Pos struct { -- x, y int +- // Hooks to run edits before initial completion +- setup func(*Env) // run before the benchmark starts +- beforeCompletion func(*Env) // run before each completion -} - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") --} +-func benchmarkCompletion(options completionBenchOptions, b *testing.B) { +- repo := getRepo(b, "tools") +- _ = repo.sharedEnv(b) // ensure cache is warm +- env := repo.newEnv(b, fake.EditorConfig{}, "completion", false) +- defer env.Close() - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} +- // Run edits required for this completion. +- if options.setup != nil { +- options.setup(env) +- } - --func sw() { -- var x interface{} +- // Run a completion to make sure the system is warm. +- loc := env.RegexpSearch(options.file, options.locationRegexp) +- completions := env.Completion(loc) - -- switch y0 := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y0) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y0) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y0) //@rename("y", "y3"),rename("f2","fmt2") +- if testing.Verbose() { +- fmt.Println("Results:") +- for i := 0; i < len(completions.Items); i++ { +- fmt.Printf("\t%d. %v\n", i, completions.Items[i]) +- } - } --} -- ---- y1-rename -- --package a - --import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +- b.Run("tools", func(b *testing.B) { +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName("tools", "completion")); stopAndRecord != nil { +- defer stopAndRecord() +- } - --func Random() int { -- y := 6 + 7 -- return y +- for i := 0; i < b.N; i++ { +- if options.beforeCompletion != nil { +- options.beforeCompletion(env) +- } +- env.Completion(loc) +- } +- }) -} - --func Random2(y int) int { //@rename("y", "z") -- return y +-// endRangeInBuffer returns the position for last character in the buffer for +-// the given file. +-func endRangeInBuffer(env *Env, name string) protocol.Range { +- buffer := env.BufferText(name) +- m := protocol.NewMapper("", []byte(buffer)) +- rng, err := m.OffsetRange(len(buffer), len(buffer)) +- if err != nil { +- env.T.Fatal(err) +- } +- return rng -} - --type Pos struct { -- x, y int --} +-// Benchmark struct completion in tools codebase. +-func BenchmarkStructCompletion(b *testing.B) { +- file := "internal/lsp/cache/session.go" - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") --} +- setup := func(env *Env) { +- env.OpenFile(file) +- env.EditBuffer(file, protocol.TextEdit{ +- Range: endRangeInBuffer(env, file), +- NewText: "\nvar testVariable map[string]bool = Session{}.\n", +- }) +- } - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") +- benchmarkCompletion(completionBenchOptions{ +- file: file, +- locationRegexp: `var testVariable map\[string\]bool = Session{}(\.)`, +- setup: setup, +- }, b) -} - --func sw() { -- var x interface{} -- -- switch y1 := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y1) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y1) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y1) //@rename("y", "y3"),rename("f2","fmt2") -- } +-// Benchmark import completion in tools codebase. +-func BenchmarkImportCompletion(b *testing.B) { +- const file = "internal/lsp/source/completion/completion.go" +- benchmarkCompletion(completionBenchOptions{ +- file: file, +- locationRegexp: `go\/()`, +- setup: func(env *Env) { env.OpenFile(file) }, +- }, b) -} - ---- y2-rename -- --package a -- --import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +-// Benchmark slice completion in tools codebase. +-func BenchmarkSliceCompletion(b *testing.B) { +- file := "internal/lsp/cache/session.go" - --func Random() int { -- y := 6 + 7 -- return y --} +- setup := func(env *Env) { +- env.OpenFile(file) +- env.EditBuffer(file, protocol.TextEdit{ +- Range: endRangeInBuffer(env, file), +- NewText: "\nvar testVariable []byte = \n", +- }) +- } - --func Random2(y int) int { //@rename("y", "z") -- return y +- benchmarkCompletion(completionBenchOptions{ +- file: file, +- locationRegexp: `var testVariable \[\]byte (=)`, +- setup: setup, +- }, b) -} - --type Pos struct { -- x, y int +-// Benchmark deep completion in function call in tools codebase. +-func BenchmarkFuncDeepCompletion(b *testing.B) { +- file := "internal/lsp/source/completion/completion.go" +- fileContent := ` +-func (c *completer) _() { +- c.inference.kindMatches(c.) -} +-` +- setup := func(env *Env) { +- env.OpenFile(file) +- originalBuffer := env.BufferText(file) +- env.EditBuffer(file, protocol.TextEdit{ +- Range: endRangeInBuffer(env, file), +- // TODO(rfindley): this is a bug: it should just be fileContent. +- NewText: originalBuffer + fileContent, +- }) +- } - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") +- benchmarkCompletion(completionBenchOptions{ +- file: file, +- locationRegexp: `func \(c \*completer\) _\(\) {\n\tc\.inference\.kindMatches\((c)`, +- setup: setup, +- }, b) -} - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") +-type completionFollowingEditTest struct { +- repo string +- name string +- file string // repo-relative file to create +- content string // file content +- locationRegexp string // regexp for completion -} - --func sw() { -- var x interface{} +-var completionFollowingEditTests = []completionFollowingEditTest{ +- { +- "tools", +- "selector", +- "internal/lsp/source/completion/completion2.go", +- ` +-package completion - -- switch y2 := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y2) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y2) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y2) //@rename("y", "y3"),rename("f2","fmt2") -- } +-func (c *completer) _() { +- c.inference.kindMatches(c.) -} +-`, +- `func \(c \*completer\) _\(\) {\n\tc\.inference\.kindMatches\((c)`, +- }, +- { +- "kubernetes", +- "selector", +- "pkg/kubelet/kubelet2.go", +- ` +-package kubelet - ---- y3-rename -- --package a -- --import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) -- --func Random() int { -- y := 6 + 7 -- return y +-func (kl *Kubelet) _() { +- kl. -} +-`, +- `kl\.()`, +- }, +- { +- "kubernetes", +- "identifier", +- "pkg/kubelet/kubelet2.go", +- ` +-package kubelet - --func Random2(y int) int { //@rename("y", "z") -- return y +-func (kl *Kubelet) _() { +- k // here -} +-`, +- `k() // here`, +- }, +- { +- "oracle", +- "selector", +- "dataintegration/pivot2.go", +- ` +-package dataintegration - --type Pos struct { -- x, y int +-func (p *Pivot) _() { +- p. -} -- --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") +-`, +- `p\.()`, +- }, -} - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") +-// Benchmark completion following an arbitrary edit. +-// +-// Edits force type-checked packages to be invalidated, so we want to measure +-// how long it takes before completion results are available. +-func BenchmarkCompletionFollowingEdit(b *testing.B) { +- for _, test := range completionFollowingEditTests { +- b.Run(fmt.Sprintf("%s_%s", test.repo, test.name), func(b *testing.B) { +- for _, completeUnimported := range []bool{true, false} { +- b.Run(fmt.Sprintf("completeUnimported=%v", completeUnimported), func(b *testing.B) { +- for _, budget := range []string{"0s", "100ms"} { +- b.Run(fmt.Sprintf("budget=%s", budget), func(b *testing.B) { +- runCompletionFollowingEdit(b, test, completeUnimported, budget) +- }) +- } +- }) +- } +- }) +- } -} - --func sw() { -- var x interface{} +-var gomodcache = flag.String("gomodcache", "", "optional GOMODCACHE for unimported completion benchmarks") - -- switch y3 := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y3) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y3) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y3) //@rename("y", "y3"),rename("f2","fmt2") +-func runCompletionFollowingEdit(b *testing.B, test completionFollowingEditTest, completeUnimported bool, budget string) { +- repo := getRepo(b, test.repo) +- sharedEnv := repo.sharedEnv(b) // ensure cache is warm +- envvars := map[string]string{ +- "GOPATH": sharedEnv.Sandbox.GOPATH(), // use the warm cache - } --} -- ---- z-rename -- --package a - --import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +- if *gomodcache != "" { +- envvars["GOMODCACHE"] = *gomodcache +- } - --func Random() int { -- y := 6 + 7 -- return y --} +- env := repo.newEnv(b, fake.EditorConfig{ +- Env: envvars, +- Settings: map[string]interface{}{ +- "completeUnimported": completeUnimported, +- "completionBudget": budget, +- }, +- }, "completionFollowingEdit", false) +- defer env.Close() - --func Random2(z int) int { //@rename("y", "z") -- return z --} +- env.CreateBuffer(test.file, "// __REGTEST_PLACEHOLDER_0__\n"+test.content) +- editPlaceholder := func() { +- edits := atomic.AddInt64(&editID, 1) +- env.EditBuffer(test.file, protocol.TextEdit{ +- Range: protocol.Range{ +- Start: protocol.Position{Line: 0, Character: 0}, +- End: protocol.Position{Line: 1, Character: 0}, +- }, +- // Increment the placeholder text, to ensure cache misses. +- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), +- }) +- } +- env.AfterChange() - --type Pos struct { -- x, y int --} +- // Run a completion to make sure the system is warm. +- loc := env.RegexpSearch(test.file, test.locationRegexp) +- completions := env.Completion(loc) - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") --} +- if testing.Verbose() { +- fmt.Println("Results:") +- for i, item := range completions.Items { +- fmt.Printf("\t%d. %v\n", i, item) +- } +- } - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} +- b.ResetTimer() - --func sw() { -- var x interface{} +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "completionFollowingEdit")); stopAndRecord != nil { +- defer stopAndRecord() +- } - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- for i := 0; i < b.N; i++ { +- editPlaceholder() +- loc := env.RegexpSearch(test.file, test.locationRegexp) +- env.Completion(loc) - } -} +diff -urN a/gopls/internal/regtest/bench/definition_test.go b/gopls/internal/regtest/bench/definition_test.go +--- a/gopls/internal/regtest/bench/definition_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/definition_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,46 +0,0 @@ +-// Copyright 2023 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. - -diff -urN a/gopls/internal/lsp/testdata/rename/a/random.go.in b/gopls/internal/lsp/testdata/rename/a/random.go.in ---- a/gopls/internal/lsp/testdata/rename/a/random.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/a/random.go.in 1970-01-01 08:00:00 -@@ -1,42 +0,0 @@ --package a +-package bench - -import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +- "testing" -) - --func Random() int { -- y := 6 + 7 -- return y --} -- --func Random2(y int) int { //@rename("y", "z") -- return y --} -- --type Pos struct { -- x, y int --} +-func BenchmarkDefinition(b *testing.B) { +- tests := []struct { +- repo string +- file string +- regexp string +- }{ +- {"istio", "pkg/config/model.go", `gogotypes\.(MarshalAny)`}, +- {"google-cloud-go", "httpreplay/httpreplay.go", `proxy\.(ForRecording)`}, +- {"kubernetes", "pkg/controller/lookup_cache.go", `hashutil\.(DeepHashObject)`}, +- {"kuma", "api/generic/insights.go", `proto\.(Message)`}, +- {"pkgsite", "internal/log/log.go", `derrors\.(Wrap)`}, +- {"starlark", "starlark/eval.go", "prog.compiled.(Encode)"}, +- {"tools", "internal/lsp/cache/check.go", `(snapshot)\) buildKey`}, +- } - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") --} +- for _, test := range tests { +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- defer closeBuffer(b, env, test.file) - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} +- loc := env.RegexpSearch(test.file, test.regexp) +- env.Await(env.DoneWithOpen()) +- env.GoToDefinition(loc) // pre-warm the query, and open the target file +- b.ResetTimer() - --func sw() { -- var x interface{} +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "definition")); stopAndRecord != nil { +- defer stopAndRecord() +- } - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- for i := 0; i < b.N; i++ { +- env.GoToDefinition(loc) // pre-warm the query +- } +- }) - } -} -diff -urN a/gopls/internal/lsp/testdata/rename/b/b.go b/gopls/internal/lsp/testdata/rename/b/b.go ---- a/gopls/internal/lsp/testdata/rename/b/b.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/b/b.go 1970-01-01 08:00:00 -@@ -1,20 +0,0 @@ --package b +diff -urN a/gopls/internal/regtest/bench/didchange_test.go b/gopls/internal/regtest/bench/didchange_test.go +--- a/gopls/internal/regtest/bench/didchange_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/didchange_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,142 +0,0 @@ +-// Copyright 2022 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. - --var c int //@rename("int", "uint") +-package bench - --func _() { -- a := 1 //@rename("a", "error") -- a = 2 -- _ = a --} +-import ( +- "fmt" +- "sync/atomic" +- "testing" +- "time" - --var ( -- // Hello there. -- // Foo does the thing. -- Foo int //@rename("Foo", "Bob") +- "golang.org/x/tools/gopls/internal/lsp/fake" +- "golang.org/x/tools/gopls/internal/lsp/protocol" -) - --/* --Hello description --*/ --func Hello() {} //@rename("Hello", "Goodbye") -diff -urN a/gopls/internal/lsp/testdata/rename/b/b.go.golden b/gopls/internal/lsp/testdata/rename/b/b.go.golden ---- a/gopls/internal/lsp/testdata/rename/b/b.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/b/b.go.golden 1970-01-01 08:00:00 -@@ -1,78 +0,0 @@ ---- Bob-rename -- --package b -- --var c int //@rename("int", "uint") +-// Use a global edit counter as bench function may execute multiple times, and +-// we want to avoid cache hits. Use time.Now to also avoid cache hits from the +-// shared file cache. +-var editID int64 = time.Now().UnixNano() - --func _() { -- a := 1 //@rename("a", "error") -- a = 2 -- _ = a +-type changeTest struct { +- repo string +- file string +- canSave bool -} - --var ( -- // Hello there. -- // Bob does the thing. -- Bob int //@rename("Foo", "Bob") --) -- --/* --Hello description --*/ --func Hello() {} //@rename("Hello", "Goodbye") -- ---- Goodbye-rename -- --b.go: --package b -- --var c int //@rename("int", "uint") -- --func _() { -- a := 1 //@rename("a", "error") -- a = 2 -- _ = a +-var didChangeTests = []changeTest{ +- {"google-cloud-go", "internal/annotate.go", true}, +- {"istio", "pkg/fuzz/util.go", true}, +- {"kubernetes", "pkg/controller/lookup_cache.go", true}, +- {"kuma", "api/generic/insights.go", true}, +- {"oracle", "dataintegration/data_type.go", false}, // diagnoseSave fails because this package is generated +- {"pkgsite", "internal/frontend/server.go", true}, +- {"starlark", "starlark/eval.go", true}, +- {"tools", "internal/lsp/cache/snapshot.go", true}, -} - --var ( -- // Hello there. -- // Foo does the thing. -- Foo int //@rename("Foo", "Bob") --) -- --/* --Goodbye description --*/ --func Goodbye() {} //@rename("Hello", "Goodbye") +-// BenchmarkDidChange benchmarks modifications of a single file by making +-// synthetic modifications in a comment. It controls pacing by waiting for the +-// server to actually start processing the didChange notification before +-// proceeding. Notably it does not wait for diagnostics to complete. +-func BenchmarkDidChange(b *testing.B) { +- for _, test := range didChangeTests { +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- defer closeBuffer(b, env, test.file) - --c.go: --package c +- // Insert the text we'll be modifying at the top of the file. +- env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"}) +- env.AfterChange() +- b.ResetTimer() - --import "golang.org/lsptests/rename/b" +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "didchange")); stopAndRecord != nil { +- defer stopAndRecord() +- } - --func _() { -- b.Goodbye() //@rename("Hello", "Goodbye") +- for i := 0; i < b.N; i++ { +- edits := atomic.AddInt64(&editID, 1) +- env.EditBuffer(test.file, protocol.TextEdit{ +- Range: protocol.Range{ +- Start: protocol.Position{Line: 0, Character: 0}, +- End: protocol.Position{Line: 1, Character: 0}, +- }, +- // Increment the placeholder text, to ensure cache misses. +- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), +- }) +- env.Await(env.StartedChange()) +- } +- }) +- } -} - ---- error-rename -- --package b +-func BenchmarkDiagnoseChange(b *testing.B) { +- for _, test := range didChangeTests { +- runChangeDiagnosticsBenchmark(b, test, false, "diagnoseChange") +- } +-} - --var c int //@rename("int", "uint") -- --func _() { -- error := 1 //@rename("a", "error") -- error = 2 -- _ = error --} -- --var ( -- // Hello there. -- // Foo does the thing. -- Foo int //@rename("Foo", "Bob") --) -- --/* --Hello description --*/ --func Hello() {} //@rename("Hello", "Goodbye") -- ---- uint-rename -- --int is built in and cannot be renamed -diff -urN a/gopls/internal/lsp/testdata/rename/bad/bad.go.golden b/gopls/internal/lsp/testdata/rename/bad/bad.go.golden ---- a/gopls/internal/lsp/testdata/rename/bad/bad.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/bad/bad.go.golden 1970-01-01 08:00:00 -@@ -1,2 +0,0 @@ ---- rFunc-rename -- --renaming "sFunc" to "rFunc" not possible because "golang.org/lsptests/rename/bad" has errors -diff -urN a/gopls/internal/lsp/testdata/rename/bad/bad.go.in b/gopls/internal/lsp/testdata/rename/bad/bad.go.in ---- a/gopls/internal/lsp/testdata/rename/bad/bad.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/bad/bad.go.in 1970-01-01 08:00:00 -@@ -1,8 +0,0 @@ --package bad -- --type myStruct struct { --} -- --func (s *myStruct) sFunc() bool { //@rename("sFunc", "rFunc") -- return s.Bad +-// TODO(rfindley): add a benchmark for with a metadata-affecting change, when +-// this matters. +-func BenchmarkDiagnoseSave(b *testing.B) { +- for _, test := range didChangeTests { +- runChangeDiagnosticsBenchmark(b, test, true, "diagnoseSave") +- } -} -diff -urN a/gopls/internal/lsp/testdata/rename/bad/bad_test.go.in b/gopls/internal/lsp/testdata/rename/bad/bad_test.go.in ---- a/gopls/internal/lsp/testdata/rename/bad/bad_test.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/bad/bad_test.go.in 1970-01-01 08:00:00 -@@ -1 +0,0 @@ --package bad -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/rename/c/c.go b/gopls/internal/lsp/testdata/rename/c/c.go ---- a/gopls/internal/lsp/testdata/rename/c/c.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/c/c.go 1970-01-01 08:00:00 -@@ -1,7 +0,0 @@ --package c - --import "golang.org/lsptests/rename/b" +-// runChangeDiagnosticsBenchmark runs a benchmark to edit the test file and +-// await the resulting diagnostics pass. If save is set, the file is also saved. +-func runChangeDiagnosticsBenchmark(b *testing.B, test changeTest, save bool, operation string) { +- b.Run(test.repo, func(b *testing.B) { +- if !test.canSave { +- b.Skipf("skipping as %s cannot be saved", test.file) +- } +- sharedEnv := getRepo(b, test.repo).sharedEnv(b) +- config := fake.EditorConfig{ +- Env: map[string]string{ +- "GOPATH": sharedEnv.Sandbox.GOPATH(), +- }, +- Settings: map[string]interface{}{ +- "diagnosticsDelay": "0s", +- }, +- } +- // Use a new env to avoid the diagnostic delay: we want to measure how +- // long it takes to produce the diagnostics. +- env := getRepo(b, test.repo).newEnv(b, config, operation, false) +- defer env.Close() +- env.OpenFile(test.file) +- // Insert the text we'll be modifying at the top of the file. +- env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"}) +- if save { +- env.SaveBuffer(test.file) +- } +- env.AfterChange() +- b.ResetTimer() - --func _() { -- b.Hello() //@rename("Hello", "Goodbye") +- // We must use an extra subtest layer here, so that we only set up the +- // shared env once (otherwise we pay additional overhead and the profiling +- // flags don't work). +- b.Run("diagnose", func(b *testing.B) { +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, operation)); stopAndRecord != nil { +- defer stopAndRecord() +- } +- for i := 0; i < b.N; i++ { +- edits := atomic.AddInt64(&editID, 1) +- env.EditBuffer(test.file, protocol.TextEdit{ +- Range: protocol.Range{ +- Start: protocol.Position{Line: 0, Character: 0}, +- End: protocol.Position{Line: 1, Character: 0}, +- }, +- // Increment the placeholder text, to ensure cache misses. +- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), +- }) +- if save { +- env.SaveBuffer(test.file) +- } +- env.AfterChange() +- } +- }) +- }) -} -diff -urN a/gopls/internal/lsp/testdata/rename/c/c.go.golden b/gopls/internal/lsp/testdata/rename/c/c.go.golden ---- a/gopls/internal/lsp/testdata/rename/c/c.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/c/c.go.golden 1970-01-01 08:00:00 -@@ -1,32 +0,0 @@ ---- Goodbye-rename -- --b.go: --package b +diff -urN a/gopls/internal/regtest/bench/doc.go b/gopls/internal/regtest/bench/doc.go +--- a/gopls/internal/regtest/bench/doc.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/doc.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,40 +0,0 @@ +-// Copyright 2023 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. - --var c int //@rename("int", "uint") +-// The bench package implements benchmarks for various LSP operations. +-// +-// Benchmarks check out specific commits of popular and/or exemplary +-// repositories, and script an external gopls process via a fake text editor. +-// By default, benchmarks run the test executable as gopls (using a special +-// "gopls mode" environment variable). A different gopls binary may be used by +-// setting the -gopls_path or -gopls_commit flags. +-// +-// This package is a work in progress. +-// +-// # Profiling +-// +-// Benchmark functions run gopls in a separate process, which means the normal +-// test flags for profiling aren't useful. Instead the -gopls_cpuprofile, +-// -gopls_memprofile, -gopls_allocprofile, and -gopls_trace flags may be used +-// to pass through profiling to the gopls subproces. +-// +-// Each of these flags sets a suffix for the respective gopls profile, which is +-// named according to the schema ... For example, +-// setting -gopls_cpuprofile=cpu will result in profiles named tools.iwl.cpu, +-// tools.rename.cpu, etc. In some cases, these profiles are for the entire +-// gopls subprocess (as in the initial workspace load), whereas in others they +-// span only the critical section of the benchmark. It is up to each benchmark +-// to implement profiling as appropriate. +-// +-// # Integration with perf.golang.org +-// +-// Benchmarks that run with -short are automatically tracked by +-// perf.golang.org, at +-// https://perf.golang.org/dashboard/?benchmark=all&repository=tools&branch=release-branch.go1.20 +-// +-// # TODO +-// - add more benchmarks, and more repositories +-// - fix the perf dashboard to not require the branch= parameter +-// - improve this documentation +-package bench +diff -urN a/gopls/internal/regtest/bench/hover_test.go b/gopls/internal/regtest/bench/hover_test.go +--- a/gopls/internal/regtest/bench/hover_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/hover_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,47 +0,0 @@ +-// Copyright 2023 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. - --func _() { -- a := 1 //@rename("a", "error") -- a = 2 -- _ = a --} +-package bench - --var ( -- // Hello there. -- // Foo does the thing. -- Foo int //@rename("Foo", "Bob") +-import ( +- "testing" -) - --/* --Goodbye description --*/ --func Goodbye() {} //@rename("Hello", "Goodbye") +-func BenchmarkHover(b *testing.B) { +- tests := []struct { +- repo string +- file string +- regexp string +- }{ +- {"google-cloud-go", "httpreplay/httpreplay.go", `proxy\.(ForRecording)`}, +- {"istio", "pkg/config/model.go", `gogotypes\.(MarshalAny)`}, +- {"kubernetes", "pkg/apis/core/types.go", "type (Pod)"}, +- {"kuma", "api/generic/insights.go", `proto\.(Message)`}, +- {"pkgsite", "internal/log/log.go", `derrors\.(Wrap)`}, +- {"starlark", "starlark/eval.go", "prog.compiled.(Encode)"}, +- {"tools", "internal/lsp/cache/check.go", `(snapshot)\) buildKey`}, +- } - --c.go: --package c +- for _, test := range tests { +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- defer closeBuffer(b, env, test.file) - --import "golang.org/lsptests/rename/b" +- loc := env.RegexpSearch(test.file, test.regexp) +- env.AfterChange() - --func _() { -- b.Goodbye() //@rename("Hello", "Goodbye") --} +- env.Hover(loc) // pre-warm the query +- b.ResetTimer() - -diff -urN a/gopls/internal/lsp/testdata/rename/c/c2.go b/gopls/internal/lsp/testdata/rename/c/c2.go ---- a/gopls/internal/lsp/testdata/rename/c/c2.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/c/c2.go 1970-01-01 08:00:00 -@@ -1,4 +0,0 @@ --package c +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "hover")); stopAndRecord != nil { +- defer stopAndRecord() +- } - --//go:embed Static/* --var Static embed.FS //@rename("Static", "static") -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/rename/c/c2.go.golden b/gopls/internal/lsp/testdata/rename/c/c2.go.golden ---- a/gopls/internal/lsp/testdata/rename/c/c2.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/c/c2.go.golden 1970-01-01 08:00:00 -@@ -1,5 +0,0 @@ ---- static-rename -- --package c +- for i := 0; i < b.N; i++ { +- env.Hover(loc) // pre-warm the query +- } +- }) +- } +-} +diff -urN a/gopls/internal/regtest/bench/implementations_test.go b/gopls/internal/regtest/bench/implementations_test.go +--- a/gopls/internal/regtest/bench/implementations_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/implementations_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,44 +0,0 @@ +-// Copyright 2023 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. - --//go:embed Static/* --var static embed.FS //@rename("Static", "static") -diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go b/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go ---- a/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ --package another +-package bench - --type ( -- I interface{ F() } -- C struct{ I } --) +-import "testing" - --func (C) g() +-func BenchmarkImplementations(b *testing.B) { +- tests := []struct { +- repo string +- file string +- regexp string +- }{ +- {"google-cloud-go", "httpreplay/httpreplay.go", `type (Recorder)`}, +- {"istio", "pkg/config/mesh/watcher.go", `type (Watcher)`}, +- {"kubernetes", "pkg/controller/lookup_cache.go", `objectWithMeta`}, +- {"kuma", "api/generic/insights.go", `type (Insight)`}, +- {"pkgsite", "internal/datasource.go", `type (DataSource)`}, +- {"starlark", "syntax/syntax.go", `type (Expr)`}, +- {"tools", "internal/lsp/source/view.go", `type (Snapshot)`}, +- } - --func _() { -- var x I = C{} -- x.F() //@rename("F", "G") --} -diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go.golden b/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go.golden ---- a/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go.golden 1970-01-01 08:00:00 -@@ -1,15 +0,0 @@ ---- G-rename -- --package another +- for _, test := range tests { +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- defer closeBuffer(b, env, test.file) - --type ( -- I interface{ G() } -- C struct{ I } --) +- loc := env.RegexpSearch(test.file, test.regexp) +- env.AfterChange() +- env.Implementations(loc) // pre-warm the query +- b.ResetTimer() - --func (C) g() +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "implementations")); stopAndRecord != nil { +- defer stopAndRecord() +- } - --func _() { -- var x I = C{} -- x.G() //@rename("F", "G") +- for i := 0; i < b.N; i++ { +- env.Implementations(loc) +- } +- }) +- } -} +diff -urN a/gopls/internal/regtest/bench/iwl_test.go b/gopls/internal/regtest/bench/iwl_test.go +--- a/gopls/internal/regtest/bench/iwl_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/iwl_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,76 +0,0 @@ +-// Copyright 2022 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. - -diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go b/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go ---- a/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go 1970-01-01 08:00:00 -@@ -1,7 +0,0 @@ --package crosspkg +-package bench - --func Foo() { //@rename("Foo", "Dolphin") +-import ( +- "testing" - --} +- "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp/fake" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) - --var Bar int //@rename("Bar", "Tomato") -diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden b/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden ---- a/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden 1970-01-01 08:00:00 -@@ -1,40 +0,0 @@ ---- Dolphin-rename -- --crosspkg.go: --package crosspkg +-// BenchmarkInitialWorkspaceLoad benchmarks the initial workspace load time for +-// a new editing session. +-func BenchmarkInitialWorkspaceLoad(b *testing.B) { +- tests := []struct { +- repo string +- file string +- }{ +- {"google-cloud-go", "httpreplay/httpreplay.go"}, +- {"istio", "pkg/fuzz/util.go"}, +- {"kubernetes", "pkg/controller/lookup_cache.go"}, +- {"kuma", "api/generic/insights.go"}, +- {"oracle", "dataintegration/data_type.go"}, +- {"pkgsite", "internal/frontend/server.go"}, +- {"starlark", "starlark/eval.go"}, +- {"tools", "internal/lsp/cache/snapshot.go"}, +- {"hashiform", "internal/provider/provider.go"}, +- } - --func Dolphin() { //@rename("Foo", "Dolphin") +- for _, test := range tests { +- b.Run(test.repo, func(b *testing.B) { +- repo := getRepo(b, test.repo) +- // get the (initialized) shared env to ensure the cache is warm. +- // Reuse its GOPATH so that we get cache hits for things in the module +- // cache. +- sharedEnv := repo.sharedEnv(b) +- b.ResetTimer() - +- for i := 0; i < b.N; i++ { +- doIWL(b, sharedEnv.Sandbox.GOPATH(), repo, test.file) +- } +- }) +- } -} - --var Bar int //@rename("Bar", "Tomato") +-func doIWL(b *testing.B, gopath string, repo *repo, file string) { +- // Exclude the time to set up the env from the benchmark time, as this may +- // involve installing gopls and/or checking out the repo dir. +- b.StopTimer() +- config := fake.EditorConfig{Env: map[string]string{"GOPATH": gopath}} +- env := repo.newEnv(b, config, "iwl", true) +- defer env.Close() +- b.StartTimer() - --other.go: --package other +- // Note: in the future, we may need to open a file in order to cause gopls to +- // start loading the workspace. - --import "golang.org/lsptests/rename/crosspkg" +- env.Await(InitialWorkspaceLoad) - --func Other() { -- crosspkg.Bar -- crosspkg.Dolphin() //@rename("Foo", "Flamingo") +- if env.Editor.HasCommand(command.MemStats.ID()) { +- b.StopTimer() +- params := &protocol.ExecuteCommandParams{ +- Command: command.MemStats.ID(), +- } +- var memstats command.MemStatsResult +- env.ExecuteCommand(params, &memstats) +- b.ReportMetric(float64(memstats.HeapAlloc), "alloc_bytes") +- b.ReportMetric(float64(memstats.HeapInUse), "in_use_bytes") +- b.ReportMetric(float64(memstats.TotalAlloc), "total_alloc_bytes") +- b.StartTimer() +- } -} +diff -urN a/gopls/internal/regtest/bench/references_test.go b/gopls/internal/regtest/bench/references_test.go +--- a/gopls/internal/regtest/bench/references_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/references_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,44 +0,0 @@ +-// Copyright 2023 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. - ---- Tomato-rename -- --crosspkg.go: --package crosspkg +-package bench - --func Foo() { //@rename("Foo", "Dolphin") +-import "testing" - --} +-func BenchmarkReferences(b *testing.B) { +- tests := []struct { +- repo string +- file string +- regexp string +- }{ +- {"google-cloud-go", "httpreplay/httpreplay.go", `func (NewRecorder)`}, +- {"istio", "pkg/config/model.go", "type (Meta)"}, +- {"kubernetes", "pkg/controller/lookup_cache.go", "type (objectWithMeta)"}, // TODO: choose an exported identifier +- {"kuma", "pkg/events/interfaces.go", "type (Event)"}, +- {"pkgsite", "internal/log/log.go", "func (Infof)"}, +- {"starlark", "syntax/syntax.go", "type (Ident)"}, +- {"tools", "internal/lsp/source/view.go", "type (Snapshot)"}, +- } - --var Tomato int //@rename("Bar", "Tomato") +- for _, test := range tests { +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- defer closeBuffer(b, env, test.file) - --other.go: --package other +- loc := env.RegexpSearch(test.file, test.regexp) +- env.AfterChange() +- env.References(loc) // pre-warm the query +- b.ResetTimer() - --import "golang.org/lsptests/rename/crosspkg" +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "references")); stopAndRecord != nil { +- defer stopAndRecord() +- } - --func Other() { -- crosspkg.Tomato -- crosspkg.Foo() //@rename("Foo", "Flamingo") +- for i := 0; i < b.N; i++ { +- env.References(loc) +- } +- }) +- } -} +diff -urN a/gopls/internal/regtest/bench/reload_test.go b/gopls/internal/regtest/bench/reload_test.go +--- a/gopls/internal/regtest/bench/reload_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/reload_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,52 +0,0 @@ +-// Copyright 2023 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 bench - -diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go b/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go ---- a/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go 1970-01-01 08:00:00 -@@ -1,8 +0,0 @@ --package other -- --import "golang.org/lsptests/rename/crosspkg" -- --func Other() { -- crosspkg.Bar -- crosspkg.Foo() //@rename("Foo", "Flamingo") --} -diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go.golden b/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go.golden ---- a/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go.golden 1970-01-01 08:00:00 -@@ -1,20 +0,0 @@ ---- Flamingo-rename -- --crosspkg.go: --package crosspkg +-import ( +- "testing" - --func Flamingo() { //@rename("Foo", "Dolphin") +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) - --} +-// BenchmarkReload benchmarks reloading a file metadata after a change to an import. +-// +-// This ensures we are able to diagnose a changed file without reloading all +-// invalidated packages. See also golang/go#61344 +-func BenchmarkReload(b *testing.B) { +- // TODO(rfindley): add more tests, make this test table-driven +- const ( +- repo = "kubernetes" +- // pkg/util/hash is transitively imported by a large number of packages. +- // We should not need to reload those packages to get a diagnostic. +- file = "pkg/util/hash/hash.go" +- ) +- b.Run(repo, func(b *testing.B) { +- env := getRepo(b, repo).sharedEnv(b) - --var Bar int //@rename("Bar", "Tomato") +- env.OpenFile(file) +- defer closeBuffer(b, env, file) - --other.go: --package other +- env.AfterChange() - --import "golang.org/lsptests/rename/crosspkg" +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(repo, "reload")); stopAndRecord != nil { +- defer stopAndRecord() +- } - --func Other() { -- crosspkg.Bar -- crosspkg.Flamingo() //@rename("Foo", "Flamingo") +- b.ResetTimer() +- for i := 0; i < b.N; i++ { +- // Change the "hash" import. This may result in cache hits, but that's +- // OK: the goal is to ensure that we don't reload more than just the +- // current package. +- env.RegexpReplace(file, `"hash"`, `"hashx"`) +- // Note: don't use env.AfterChange() here: we only want to await the +- // first diagnostic. +- // +- // Awaiting a full diagnosis would await diagnosing everything, which +- // would require reloading everything. +- env.Await(Diagnostics(ForFile(file))) +- env.RegexpReplace(file, `"hashx"`, `"hash"`) +- env.Await(NoDiagnostics(ForFile(file))) +- } +- }) -} +diff -urN a/gopls/internal/regtest/bench/rename_test.go b/gopls/internal/regtest/bench/rename_test.go +--- a/gopls/internal/regtest/bench/rename_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/rename_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,49 +0,0 @@ +-// Copyright 2023 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. - -diff -urN a/gopls/internal/lsp/testdata/rename/generics/embedded.go b/gopls/internal/lsp/testdata/rename/generics/embedded.go ---- a/gopls/internal/lsp/testdata/rename/generics/embedded.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/generics/embedded.go 1970-01-01 08:00:00 -@@ -1,10 +0,0 @@ --//go:build go1.18 --// +build go1.18 -- --package generics -- --type foo[P any] int //@rename("foo","bar") +-package bench - --var x struct{ foo[int] } +-import ( +- "fmt" +- "testing" +-) - --var _ = x.foo -diff -urN a/gopls/internal/lsp/testdata/rename/generics/embedded.go.golden b/gopls/internal/lsp/testdata/rename/generics/embedded.go.golden ---- a/gopls/internal/lsp/testdata/rename/generics/embedded.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/generics/embedded.go.golden 1970-01-01 08:00:00 -@@ -1,12 +0,0 @@ ---- bar-rename -- --//go:build go1.18 --// +build go1.18 +-func BenchmarkRename(b *testing.B) { +- tests := []struct { +- repo string +- file string +- regexp string +- baseName string +- }{ +- {"google-cloud-go", "httpreplay/httpreplay.go", `func (NewRecorder)`, "NewRecorder"}, +- {"istio", "pkg/config/model.go", `(Namespace) string`, "Namespace"}, +- {"kubernetes", "pkg/controller/lookup_cache.go", `hashutil\.(DeepHashObject)`, "DeepHashObject"}, +- {"kuma", "pkg/events/interfaces.go", `Delete`, "Delete"}, +- {"pkgsite", "internal/log/log.go", `func (Infof)`, "Infof"}, +- {"starlark", "starlark/eval.go", `Program\) (Filename)`, "Filename"}, +- {"tools", "internal/lsp/cache/snapshot.go", `meta \*(metadataGraph)`, "metadataGraph"}, +- } - --package generics +- for _, test := range tests { +- names := 0 // bench function may execute multiple times +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- loc := env.RegexpSearch(test.file, test.regexp) +- env.Await(env.DoneWithOpen()) +- env.Rename(loc, test.baseName+"X") // pre-warm the query +- b.ResetTimer() - --type bar[P any] int //@rename("foo","bar") +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "rename")); stopAndRecord != nil { +- defer stopAndRecord() +- } - --var x struct{ bar[int] } +- for i := 0; i < b.N; i++ { +- names++ +- newName := fmt.Sprintf("%s%d", test.baseName, names) +- env.Rename(loc, newName) +- } +- }) +- } +-} +diff -urN a/gopls/internal/regtest/bench/repo_test.go b/gopls/internal/regtest/bench/repo_test.go +--- a/gopls/internal/regtest/bench/repo_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/repo_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,290 +0,0 @@ +-// Copyright 2023 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. - --var _ = x.bar +-package bench - -diff -urN a/gopls/internal/lsp/testdata/rename/generics/generics.go b/gopls/internal/lsp/testdata/rename/generics/generics.go ---- a/gopls/internal/lsp/testdata/rename/generics/generics.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/generics/generics.go 1970-01-01 08:00:00 -@@ -1,25 +0,0 @@ --//go:build go1.18 --// +build go1.18 +-import ( +- "bytes" +- "context" +- "errors" +- "flag" +- "fmt" +- "log" +- "os" +- "path/filepath" +- "sync" +- "testing" +- "time" - --package generics +- "golang.org/x/tools/gopls/internal/lsp/fake" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) - --type G[P any] struct { -- F int --} +-// repos holds shared repositories for use in benchmarks. +-// +-// These repos were selected to represent a variety of different types of +-// codebases. +-var repos = map[string]*repo{ +- // google-cloud-go has 145 workspace modules (!), and is quite large. +- "google-cloud-go": { +- name: "google-cloud-go", +- url: "https://github.com/googleapis/google-cloud-go.git", +- commit: "07da765765218debf83148cc7ed8a36d6e8921d5", +- inDir: flag.String("cloud_go_dir", "", "if set, reuse this directory as google-cloud-go@07da7657"), +- }, - --func (G[_]) M() {} +- // Used by x/benchmarks; large. +- "istio": { +- name: "istio", +- url: "https://github.com/istio/istio", +- commit: "1.17.0", +- inDir: flag.String("istio_dir", "", "if set, reuse this directory as istio@v1.17.0"), +- }, - --func F[P any](P) { -- var p P //@rename("P", "Q") -- _ = p --} +- // Kubernetes is a large repo with many dependencies, and in the past has +- // been about as large a repo as gopls could handle. +- "kubernetes": { +- name: "kubernetes", +- url: "https://github.com/kubernetes/kubernetes", +- commit: "v1.24.0", +- short: true, +- inDir: flag.String("kubernetes_dir", "", "if set, reuse this directory as kubernetes@v1.24.0"), +- }, - --func _() { -- var x G[int] //@rename("G", "H") -- _ = x.F //@rename("F", "K") -- x.M() //@rename("M", "N") +- // A large, industrial application. +- "kuma": { +- name: "kuma", +- url: "https://github.com/kumahq/kuma", +- commit: "2.1.1", +- inDir: flag.String("kuma_dir", "", "if set, reuse this directory as kuma@v2.1.1"), +- }, - -- var y G[string] -- _ = y.F -- y.M() --} -diff -urN a/gopls/internal/lsp/testdata/rename/generics/generics.go.golden b/gopls/internal/lsp/testdata/rename/generics/generics.go.golden ---- a/gopls/internal/lsp/testdata/rename/generics/generics.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/generics/generics.go.golden 1970-01-01 08:00:00 -@@ -1,108 +0,0 @@ ---- H-rename -- --//go:build go1.18 --// +build go1.18 +- // A repo containing a very large package (./dataintegration). +- "oracle": { +- name: "oracle", +- url: "https://github.com/oracle/oci-go-sdk.git", +- commit: "v65.43.0", +- short: true, +- inDir: flag.String("oracle_dir", "", "if set, reuse this directory as oracle/oci-go-sdk@v65.43.0"), +- }, - --package generics +- // x/pkgsite is familiar and represents a common use case (a webserver). It +- // also has a number of static non-go files and template files. +- "pkgsite": { +- name: "pkgsite", +- url: "https://go.googlesource.com/pkgsite", +- commit: "81f6f8d4175ad0bf6feaa03543cc433f8b04b19b", +- short: true, +- inDir: flag.String("pkgsite_dir", "", "if set, reuse this directory as pkgsite@81f6f8d4"), +- }, - --type H[P any] struct { -- F int --} +- // A tiny self-contained project. +- "starlark": { +- name: "starlark", +- url: "https://github.com/google/starlark-go", +- commit: "3f75dec8e4039385901a30981e3703470d77e027", +- short: true, +- inDir: flag.String("starlark_dir", "", "if set, reuse this directory as starlark@3f75dec8"), +- }, - --func (H[_]) M() {} +- // The current repository, which is medium-small and has very few dependencies. +- "tools": { +- name: "tools", +- url: "https://go.googlesource.com/tools", +- commit: "gopls/v0.9.0", +- short: true, +- inDir: flag.String("tools_dir", "", "if set, reuse this directory as x/tools@v0.9.0"), +- }, - --func F[P any](P) { -- var p P //@rename("P", "Q") -- _ = p +- // A repo of similar size to kubernetes, but with substantially more +- // complex types that led to a serious performance regression (issue #60621). +- "hashiform": { +- name: "hashiform", +- url: "https://github.com/hashicorp/terraform-provider-aws", +- commit: "ac55de2b1950972d93feaa250d7505d9ed829c7c", +- inDir: flag.String("hashiform_dir", "", "if set, reuse this directory as hashiform@ac55de2"), +- }, -} - --func _() { -- var x H[int] //@rename("G", "H") -- _ = x.F //@rename("F", "K") -- x.M() //@rename("M", "N") -- -- var y H[string] -- _ = y.F -- y.M() +-// getRepo gets the requested repo, and skips the test if -short is set and +-// repo is not configured as a short repo. +-func getRepo(tb testing.TB, name string) *repo { +- tb.Helper() +- repo := repos[name] +- if repo == nil { +- tb.Fatalf("repo %s does not exist", name) +- } +- if !repo.short && testing.Short() { +- tb.Skipf("large repo %s does not run with -short", repo.name) +- } +- return repo -} - ---- K-rename -- --//go:build go1.18 --// +build go1.18 -- --package generics -- --type G[P any] struct { -- K int --} +-// A repo represents a working directory for a repository checked out at a +-// specific commit. +-// +-// Repos are used for sharing state across benchmarks that operate on the same +-// codebase. +-type repo struct { +- // static configuration +- name string // must be unique, used for subdirectory +- url string // repo url +- commit string // full commit hash or tag +- short bool // whether this repo runs with -short +- inDir *string // if set, use this dir as url@commit, and don't delete - --func (G[_]) M() {} +- dirOnce sync.Once +- dir string // directory contaning source code checked out to url@commit - --func F[P any](P) { -- var p P //@rename("P", "Q") -- _ = p +- // shared editor state +- editorOnce sync.Once +- editor *fake.Editor +- sandbox *fake.Sandbox +- awaiter *Awaiter -} - --func _() { -- var x G[int] //@rename("G", "H") -- _ = x.K //@rename("F", "K") -- x.M() //@rename("M", "N") -- -- var y G[string] -- _ = y.K -- y.M() +-// reusableDir return a reusable directory for benchmarking, or "". +-// +-// If the user specifies a directory, the test will create and populate it +-// on the first run an re-use it on subsequent runs. Otherwise it will +-// create, populate, and delete a temporary directory. +-func (r *repo) reusableDir() string { +- if r.inDir == nil { +- return "" +- } +- return *r.inDir -} - ---- N-rename -- --//go:build go1.18 --// +build go1.18 -- --package generics +-// getDir returns directory containing repo source code, creating it if +-// necessary. It is safe for concurrent use. +-func (r *repo) getDir() string { +- r.dirOnce.Do(func() { +- if r.dir = r.reusableDir(); r.dir == "" { +- r.dir = filepath.Join(getTempDir(), r.name) +- } - --type G[P any] struct { -- F int +- _, err := os.Stat(r.dir) +- switch { +- case os.IsNotExist(err): +- log.Printf("cloning %s@%s into %s", r.url, r.commit, r.dir) +- if err := shallowClone(r.dir, r.url, r.commit); err != nil { +- log.Fatal(err) +- } +- case err != nil: +- log.Fatal(err) +- default: +- log.Printf("reusing %s as %s@%s", r.dir, r.url, r.commit) +- } +- }) +- return r.dir -} - --func (G[_]) N() {} +-// sharedEnv returns a shared benchmark environment. It is safe for concurrent +-// use. +-// +-// Every call to sharedEnv uses the same editor and sandbox, as a means to +-// avoid reinitializing the editor for large repos. Calling repo.Close cleans +-// up the shared environment. +-// +-// Repos in the package-local Repos var are closed at the end of the test main +-// function. +-func (r *repo) sharedEnv(tb testing.TB) *Env { +- r.editorOnce.Do(func() { +- dir := r.getDir() - --func F[P any](P) { -- var p P //@rename("P", "Q") -- _ = p --} +- start := time.Now() +- log.Printf("starting initial workspace load for %s", r.name) +- ts, err := newGoplsConnector(profileArgs(r.name, false)) +- if err != nil { +- log.Fatal(err) +- } +- r.sandbox, r.editor, r.awaiter, err = connectEditor(dir, fake.EditorConfig{}, ts) +- if err != nil { +- log.Fatalf("connecting editor: %v", err) +- } - --func _() { -- var x G[int] //@rename("G", "H") -- _ = x.F //@rename("F", "K") -- x.N() //@rename("M", "N") +- if err := r.awaiter.Await(context.Background(), InitialWorkspaceLoad); err != nil { +- log.Fatal(err) +- } +- log.Printf("initial workspace load (cold) for %s took %v", r.name, time.Since(start)) +- }) - -- var y G[string] -- _ = y.F -- y.N() +- return &Env{ +- T: tb, +- Ctx: context.Background(), +- Editor: r.editor, +- Sandbox: r.sandbox, +- Awaiter: r.awaiter, +- } -} - ---- Q-rename -- --//go:build go1.18 --// +build go1.18 -- --package generics -- --type G[P any] struct { -- F int --} +-// newEnv returns a new Env connected to a new gopls process communicating +-// over stdin/stdout. It is safe for concurrent use. +-// +-// It is the caller's responsibility to call Close on the resulting Env when it +-// is no longer needed. +-func (r *repo) newEnv(tb testing.TB, config fake.EditorConfig, forOperation string, cpuProfile bool) *Env { +- dir := r.getDir() - --func (G[_]) M() {} +- args := profileArgs(qualifiedName(r.name, forOperation), cpuProfile) +- ts, err := newGoplsConnector(args) +- if err != nil { +- tb.Fatal(err) +- } +- sandbox, editor, awaiter, err := connectEditor(dir, config, ts) +- if err != nil { +- log.Fatalf("connecting editor: %v", err) +- } - --func F[Q any](Q) { -- var p Q //@rename("P", "Q") -- _ = p +- return &Env{ +- T: tb, +- Ctx: context.Background(), +- Editor: editor, +- Sandbox: sandbox, +- Awaiter: awaiter, +- } -} - --func _() { -- var x G[int] //@rename("G", "H") -- _ = x.F //@rename("F", "K") -- x.M() //@rename("M", "N") -- -- var y G[string] -- _ = y.F -- y.M() +-// Close cleans up shared state referenced by the repo. +-func (r *repo) Close() error { +- var errBuf bytes.Buffer +- if r.editor != nil { +- if err := r.editor.Close(context.Background()); err != nil { +- fmt.Fprintf(&errBuf, "closing editor: %v", err) +- } +- } +- if r.sandbox != nil { +- if err := r.sandbox.Close(); err != nil { +- fmt.Fprintf(&errBuf, "closing sandbox: %v", err) +- } +- } +- if r.dir != "" && r.reusableDir() == "" { +- if err := os.RemoveAll(r.dir); err != nil { +- fmt.Fprintf(&errBuf, "cleaning dir: %v", err) +- } +- } +- if errBuf.Len() > 0 { +- return errors.New(errBuf.String()) +- } +- return nil -} - -diff -urN a/gopls/internal/lsp/testdata/rename/generics/unions.go b/gopls/internal/lsp/testdata/rename/generics/unions.go ---- a/gopls/internal/lsp/testdata/rename/generics/unions.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/generics/unions.go 1970-01-01 08:00:00 -@@ -1,10 +0,0 @@ --//go:build go1.18 --// +build go1.18 -- --package generics -- --type T string //@rename("T", "R") -- --type C interface { -- T | ~int //@rename("T", "S") +-// cleanup cleans up state that is shared across benchmark functions. +-func cleanup() error { +- var errBuf bytes.Buffer +- for _, repo := range repos { +- if err := repo.Close(); err != nil { +- fmt.Fprintf(&errBuf, "closing %q: %v", repo.name, err) +- } +- } +- if tempDir != "" { +- if err := os.RemoveAll(tempDir); err != nil { +- fmt.Fprintf(&errBuf, "cleaning tempDir: %v", err) +- } +- } +- if errBuf.Len() > 0 { +- return errors.New(errBuf.String()) +- } +- return nil -} -diff -urN a/gopls/internal/lsp/testdata/rename/generics/unions.go.golden b/gopls/internal/lsp/testdata/rename/generics/unions.go.golden ---- a/gopls/internal/lsp/testdata/rename/generics/unions.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/generics/unions.go.golden 1970-01-01 08:00:00 -@@ -1,24 +0,0 @@ ---- R-rename -- --//go:build go1.18 --// +build go1.18 +diff -urN a/gopls/internal/regtest/bench/stress_test.go b/gopls/internal/regtest/bench/stress_test.go +--- a/gopls/internal/regtest/bench/stress_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/stress_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,94 +0,0 @@ +-// Copyright 2020 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 generics +-package bench - --type R string //@rename("T", "R") +-import ( +- "context" +- "flag" +- "fmt" +- "testing" +- "time" - --type C interface { -- R | ~int //@rename("T", "S") --} +- "golang.org/x/tools/gopls/internal/hooks" +- "golang.org/x/tools/gopls/internal/lsp/cache" +- "golang.org/x/tools/gopls/internal/lsp/fake" +- "golang.org/x/tools/gopls/internal/lsp/lsprpc" +- "golang.org/x/tools/internal/jsonrpc2" +- "golang.org/x/tools/internal/jsonrpc2/servertest" +-) - ---- S-rename -- --//go:build go1.18 --// +build go1.18 +-// github.com/pilosa/pilosa is a repository that has historically caused +-// significant memory problems for Gopls. We use it for a simple stress test +-// that types arbitrarily in a file with lots of dependents. - --package generics +-var pilosaPath = flag.String("pilosa_path", "", "Path to a directory containing "+ +- "github.com/pilosa/pilosa, for stress testing. Do not set this unless you "+ +- "know what you're doing!") - --type S string //@rename("T", "R") +-func TestPilosaStress(t *testing.T) { +- // TODO(rfindley): revisit this test and make it is hermetic: it should check +- // out pilosa into a directory. +- // +- // Note: This stress test has not been run recently, and may no longer +- // function properly. +- if *pilosaPath == "" { +- t.Skip("-pilosa_path not configured") +- } - --type C interface { -- S | ~int //@rename("T", "S") --} +- sandbox, err := fake.NewSandbox(&fake.SandboxConfig{ +- Workdir: *pilosaPath, +- GOPROXY: "https://proxy.golang.org", +- }) +- if err != nil { +- t.Fatal(err) +- } - -diff -urN a/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.golden b/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.golden ---- a/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.golden 1970-01-01 08:00:00 -@@ -1,10 +0,0 @@ ---- bar-rename -- --package issue39614 +- server := lsprpc.NewStreamServer(cache.New(nil), false, hooks.Options) +- ts := servertest.NewPipeServer(server, jsonrpc2.NewRawStream) +- ctx := context.Background() - --func fn() { -- var bar bool //@rename("foo","bar") -- make(map[string]bool -- if true { +- const skipApplyEdits = false +- editor, err := fake.NewEditor(sandbox, fake.EditorConfig{}).Connect(ctx, ts, fake.ClientHooks{}, skipApplyEdits) +- if err != nil { +- t.Fatal(err) - } --} - -diff -urN a/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.in b/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.in ---- a/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.in 1970-01-01 08:00:00 -@@ -1,8 +0,0 @@ --package issue39614 +- files := []string{ +- "cmd.go", +- "internal/private.pb.go", +- "roaring/roaring.go", +- "roaring/roaring_internal_test.go", +- "server/handler_test.go", +- } +- for _, file := range files { +- if err := editor.OpenFile(ctx, file); err != nil { +- t.Fatal(err) +- } +- } +- ctx, cancel := context.WithTimeout(ctx, 10*time.Minute) +- defer cancel() - --func fn() { -- var foo bool //@rename("foo","bar") -- make(map[string]bool -- if true { +- i := 1 +- // MagicNumber is an identifier that occurs in roaring.go. Just change it +- // arbitrarily. +- if err := editor.RegexpReplace(ctx, "roaring/roaring.go", "MagicNumber", fmt.Sprintf("MagicNumber%d", 1)); err != nil { +- t.Fatal(err) +- } +- for { +- select { +- case <-ctx.Done(): +- return +- default: +- } +- if err := editor.RegexpReplace(ctx, "roaring/roaring.go", fmt.Sprintf("MagicNumber%d", i), fmt.Sprintf("MagicNumber%d", i+1)); err != nil { +- t.Fatal(err) +- } +- // Simulate (very fast) typing. +- // +- // Typing 80 wpm ~150ms per keystroke. +- time.Sleep(150 * time.Millisecond) +- i++ - } -} -diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/1.go b/gopls/internal/lsp/testdata/rename/issue42134/1.go ---- a/gopls/internal/lsp/testdata/rename/issue42134/1.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue42134/1.go 1970-01-01 08:00:00 -@@ -1,8 +0,0 @@ --package issue42134 +diff -urN a/gopls/internal/regtest/bench/typing_test.go b/gopls/internal/regtest/bench/typing_test.go +--- a/gopls/internal/regtest/bench/typing_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/typing_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,63 +0,0 @@ +-// Copyright 2023 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. - --func _() { -- // foo computes things. -- foo := func() {} +-package bench - -- foo() //@rename("foo", "bar") --} -diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/1.go.golden b/gopls/internal/lsp/testdata/rename/issue42134/1.go.golden ---- a/gopls/internal/lsp/testdata/rename/issue42134/1.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue42134/1.go.golden 1970-01-01 08:00:00 -@@ -1,10 +0,0 @@ ---- bar-rename -- --package issue42134 +-import ( +- "fmt" +- "sync/atomic" +- "testing" +- "time" - --func _() { -- // bar computes things. -- bar := func() {} +- "golang.org/x/tools/gopls/internal/lsp/protocol" +-) - -- bar() //@rename("foo", "bar") --} +-// BenchmarkTyping simulates typing steadily in a single file at different +-// paces. +-// +-// The key metric for this benchmark is not latency, but cpu_seconds per +-// operation. +-func BenchmarkTyping(b *testing.B) { +- for _, test := range didChangeTests { +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- defer closeBuffer(b, env, test.file) - -diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/2.go b/gopls/internal/lsp/testdata/rename/issue42134/2.go ---- a/gopls/internal/lsp/testdata/rename/issue42134/2.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue42134/2.go 1970-01-01 08:00:00 -@@ -1,12 +0,0 @@ --package issue42134 +- // Insert the text we'll be modifying at the top of the file. +- env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"}) +- env.AfterChange() - --import "fmt" +- delays := []time.Duration{ +- 10 * time.Millisecond, // automated changes +- 50 * time.Millisecond, // very fast mashing, or fast key sequences +- 150 * time.Millisecond, // avg interval for 80wpm typing. +- } - --func _() { -- // minNumber is a min number. -- // Second line. -- minNumber := min(1, 2) -- fmt.Println(minNumber) //@rename("minNumber", "res") +- for _, delay := range delays { +- b.Run(delay.String(), func(b *testing.B) { +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "typing")); stopAndRecord != nil { +- defer stopAndRecord() +- } +- ticker := time.NewTicker(delay) +- for i := 0; i < b.N; i++ { +- edits := atomic.AddInt64(&editID, 1) +- env.EditBuffer(test.file, protocol.TextEdit{ +- Range: protocol.Range{ +- Start: protocol.Position{Line: 0, Character: 0}, +- End: protocol.Position{Line: 1, Character: 0}, +- }, +- // Increment the placeholder text, to ensure cache misses. +- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), +- }) +- <-ticker.C +- } +- b.StopTimer() +- ticker.Stop() +- env.AfterChange() // wait for all change processing to complete +- }) +- } +- }) +- } -} +diff -urN a/gopls/internal/regtest/bench/workspace_symbols_test.go b/gopls/internal/regtest/bench/workspace_symbols_test.go +--- a/gopls/internal/regtest/bench/workspace_symbols_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/workspace_symbols_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,41 +0,0 @@ +-// Copyright 2022 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. - --func min(a, b int) int { return a } -diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/2.go.golden b/gopls/internal/lsp/testdata/rename/issue42134/2.go.golden ---- a/gopls/internal/lsp/testdata/rename/issue42134/2.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue42134/2.go.golden 1970-01-01 08:00:00 -@@ -1,14 +0,0 @@ ---- res-rename -- --package issue42134 +-package bench - --import "fmt" +-import ( +- "flag" +- "fmt" +- "testing" +-) - --func _() { -- // res is a min number. -- // Second line. -- res := min(1, 2) -- fmt.Println(res) //@rename("minNumber", "res") --} +-var symbolQuery = flag.String("symbol_query", "test", "symbol query to use in benchmark") - --func min(a, b int) int { return a } +-// BenchmarkWorkspaceSymbols benchmarks the time to execute a workspace symbols +-// request (controlled by the -symbol_query flag). +-func BenchmarkWorkspaceSymbols(b *testing.B) { +- for name := range repos { +- b.Run(name, func(b *testing.B) { +- env := getRepo(b, name).sharedEnv(b) +- symbols := env.Symbol(*symbolQuery) // warm the cache - -diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/3.go b/gopls/internal/lsp/testdata/rename/issue42134/3.go ---- a/gopls/internal/lsp/testdata/rename/issue42134/3.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue42134/3.go 1970-01-01 08:00:00 -@@ -1,11 +0,0 @@ --package issue42134 +- if testing.Verbose() { +- fmt.Println("Results:") +- for i, symbol := range symbols { +- fmt.Printf("\t%d. %s (%s)\n", i, symbol.Name, symbol.ContainerName) +- } +- } - --func _() { -- /* -- tests contains test cases -- */ -- tests := []struct { //@rename("tests", "testCases") -- in, out string -- }{} -- _ = tests --} -diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/3.go.golden b/gopls/internal/lsp/testdata/rename/issue42134/3.go.golden ---- a/gopls/internal/lsp/testdata/rename/issue42134/3.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue42134/3.go.golden 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ ---- testCases-rename -- --package issue42134 +- b.ResetTimer() - --func _() { -- /* -- testCases contains test cases -- */ -- testCases := []struct { //@rename("tests", "testCases") -- in, out string -- }{} -- _ = testCases +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(name, "workspaceSymbols")); stopAndRecord != nil { +- defer stopAndRecord() +- } +- +- for i := 0; i < b.N; i++ { +- env.Symbol(*symbolQuery) +- } +- }) +- } -} +diff -urN a/gopls/internal/regtest/codelens/codelens_test.go b/gopls/internal/regtest/codelens/codelens_test.go +--- a/gopls/internal/regtest/codelens/codelens_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/codelens/codelens_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,352 +0,0 @@ +-// Copyright 2020 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. - -diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/4.go b/gopls/internal/lsp/testdata/rename/issue42134/4.go ---- a/gopls/internal/lsp/testdata/rename/issue42134/4.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue42134/4.go 1970-01-01 08:00:00 -@@ -1,8 +0,0 @@ --package issue42134 +-package codelens - --func _() { -- // a is equal to 5. Comment must stay the same +-import ( +- "fmt" +- "testing" - -- a := 5 -- _ = a //@rename("a", "b") --} -diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/4.go.golden b/gopls/internal/lsp/testdata/rename/issue42134/4.go.golden ---- a/gopls/internal/lsp/testdata/rename/issue42134/4.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue42134/4.go.golden 1970-01-01 08:00:00 -@@ -1,10 +0,0 @@ ---- b-rename -- --package issue42134 +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/hooks" +- "golang.org/x/tools/gopls/internal/lsp" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +- "golang.org/x/tools/gopls/internal/lsp/tests/compare" - --func _() { -- // a is equal to 5. Comment must stay the same +- "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/internal/testenv" +-) - -- b := 5 -- _ = b //@rename("a", "b") +-func TestMain(m *testing.M) { +- bug.PanicOnBugs = true +- Main(m, hooks.Options) -} - -diff -urN a/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.golden b/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.golden ---- a/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.golden 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ ---- bar-rename -- --package issue43616 +-func TestDisablingCodeLens(t *testing.T) { +- const workspace = ` +--- go.mod -- +-module codelens.test +- +-go 1.12 +--- lib.go -- +-package lib - --type bar int //@rename("foo","bar"),prepare("oo","foo","foo") +-type Number int - --var x struct{ bar } //@rename("foo","baz") +-const ( +- Zero Number = iota +- One +- Two +-) - --var _ = x.bar //@rename("foo","quux") +-//` + `go:generate stringer -type=Number +-` +- tests := []struct { +- label string +- enabled map[string]bool +- wantCodeLens bool +- }{ +- { +- label: "default", +- wantCodeLens: true, +- }, +- { +- label: "generate disabled", +- enabled: map[string]bool{string(command.Generate): false}, +- wantCodeLens: false, +- }, +- } +- for _, test := range tests { +- t.Run(test.label, func(t *testing.T) { +- WithOptions( +- Settings{"codelenses": test.enabled}, +- ).Run(t, workspace, func(t *testing.T, env *Env) { +- env.OpenFile("lib.go") +- lens := env.CodeLens("lib.go") +- if gotCodeLens := len(lens) > 0; gotCodeLens != test.wantCodeLens { +- t.Errorf("got codeLens: %t, want %t", gotCodeLens, test.wantCodeLens) +- } +- }) +- }) +- } +-} - ---- baz-rename -- --can't rename embedded fields: rename the type directly or name the field ---- quux-rename -- --can't rename embedded fields: rename the type directly or name the field -diff -urN a/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.in b/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.in ---- a/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.in 1970-01-01 08:00:00 -@@ -1,7 +0,0 @@ --package issue43616 +-// This test confirms the full functionality of the code lenses for updating +-// dependencies in a go.mod file. It checks for the code lens that suggests +-// an update and then executes the command associated with that code lens. A +-// regression test for golang/go#39446. It also checks that these code lenses +-// only affect the diagnostics and contents of the containing go.mod file. +-func TestUpgradeCodelens(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) // uses go.work - --type foo int //@rename("foo","bar"),prepare("oo","foo","foo") +- const proxyWithLatest = ` +--- golang.org/x/hello@v1.3.3/go.mod -- +-module golang.org/x/hello - --var x struct{ foo } //@rename("foo","baz") +-go 1.12 +--- golang.org/x/hello@v1.3.3/hi/hi.go -- +-package hi - --var _ = x.foo //@rename("foo","quux") -diff -urN a/gopls/internal/lsp/testdata/rename/shadow/shadow.go b/gopls/internal/lsp/testdata/rename/shadow/shadow.go ---- a/gopls/internal/lsp/testdata/rename/shadow/shadow.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/shadow/shadow.go 1970-01-01 08:00:00 -@@ -1,20 +0,0 @@ --package shadow +-var Goodbye error +--- golang.org/x/hello@v1.2.3/go.mod -- +-module golang.org/x/hello - --func _() { -- a := true -- b, c, _ := A(), B(), D() //@rename("A", "a"),rename("B", "b"),rename("b", "c"),rename("D", "d") -- d := false -- _, _, _, _ = a, b, c, d --} +-go 1.12 +--- golang.org/x/hello@v1.2.3/hi/hi.go -- +-package hi - --func A() int { -- return 0 --} +-var Goodbye error +-` - --func B() int { -- return 0 --} +- const shouldUpdateDep = ` +--- go.work -- +-go 1.18 - --func D() int { -- return 0 --} -diff -urN a/gopls/internal/lsp/testdata/rename/shadow/shadow.go.golden b/gopls/internal/lsp/testdata/rename/shadow/shadow.go.golden ---- a/gopls/internal/lsp/testdata/rename/shadow/shadow.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/shadow/shadow.go.golden 1970-01-01 08:00:00 -@@ -1,51 +0,0 @@ ---- a-rename -- --shadow/shadow.go:10:6: renaming this func "A" to "a" --shadow/shadow.go:5:13: would cause this reference to become shadowed --shadow/shadow.go:4:2: by this intervening var definition ---- b-rename -- --package shadow +-use ( +- ./a +- ./b +-) +--- a/go.mod -- +-module mod.com/a - --func _() { -- a := true -- b, c, _ := A(), b(), D() //@rename("A", "a"),rename("B", "b"),rename("b", "c"),rename("D", "d") -- d := false -- _, _, _, _ = a, b, c, d --} +-go 1.14 - --func A() int { -- return 0 --} +-require golang.org/x/hello v1.2.3 +--- a/go.sum -- +-golang.org/x/hello v1.2.3 h1:7Wesfkx/uBd+eFgPrq0irYj/1XfmbvLV8jZ/W7C2Dwg= +-golang.org/x/hello v1.2.3/go.mod h1:OgtlzsxVMUUdsdQCIDYgaauCTH47B8T8vofouNJfzgY= +--- a/main.go -- +-package main - --func b() int { -- return 0 --} +-import "golang.org/x/hello/hi" - --func D() int { -- return 0 +-func main() { +- _ = hi.Goodbye -} +--- b/go.mod -- +-module mod.com/b - ---- c-rename -- --shadow/shadow.go:5:2: renaming this var "b" to "c" --shadow/shadow.go:5:5: conflicts with var in same block ---- d-rename -- --package shadow +-go 1.14 - --func _() { -- a := true -- b, c, _ := A(), B(), d() //@rename("A", "a"),rename("B", "b"),rename("b", "c"),rename("D", "d") -- d := false -- _, _, _, _ = a, b, c, d --} +-require golang.org/x/hello v1.2.3 +--- b/go.sum -- +-golang.org/x/hello v1.2.3 h1:7Wesfkx/uBd+eFgPrq0irYj/1XfmbvLV8jZ/W7C2Dwg= +-golang.org/x/hello v1.2.3/go.mod h1:OgtlzsxVMUUdsdQCIDYgaauCTH47B8T8vofouNJfzgY= +--- b/main.go -- +-package main - --func A() int { -- return 0 --} +-import ( +- "golang.org/x/hello/hi" +-) - --func B() int { -- return 0 +-func main() { +- _ = hi.Goodbye -} +-` - --func d() int { -- return 0 --} +- const wantGoModA = `module mod.com/a - -diff -urN a/gopls/internal/lsp/testdata/rename/testy/testy.go b/gopls/internal/lsp/testdata/rename/testy/testy.go ---- a/gopls/internal/lsp/testdata/rename/testy/testy.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/testy/testy.go 1970-01-01 08:00:00 -@@ -1,7 +0,0 @@ --package testy +-go 1.14 - --type tt int //@rename("tt", "testyType") +-require golang.org/x/hello v1.3.3 +-` +- // Applying the diagnostics or running the codelenses for a/go.mod +- // should not change the contents of b/go.mod +- const wantGoModB = `module mod.com/b - --func a() { -- foo := 42 //@rename("foo", "bar") --} -diff -urN a/gopls/internal/lsp/testdata/rename/testy/testy.go.golden b/gopls/internal/lsp/testdata/rename/testy/testy.go.golden ---- a/gopls/internal/lsp/testdata/rename/testy/testy.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/testy/testy.go.golden 1970-01-01 08:00:00 -@@ -1,18 +0,0 @@ ---- bar-rename -- --package testy +-go 1.14 - --type tt int //@rename("tt", "testyType") +-require golang.org/x/hello v1.2.3 +-` - --func a() { -- bar := 42 //@rename("foo", "bar") --} +- for _, commandTitle := range []string{ +- "Upgrade transitive dependencies", +- "Upgrade direct dependencies", +- } { +- t.Run(commandTitle, func(t *testing.T) { +- WithOptions( +- ProxyFiles(proxyWithLatest), +- ).Run(t, shouldUpdateDep, func(t *testing.T, env *Env) { +- env.OpenFile("a/go.mod") +- env.OpenFile("b/go.mod") +- var lens protocol.CodeLens +- var found bool +- for _, l := range env.CodeLens("a/go.mod") { +- if l.Command.Title == commandTitle { +- lens = l +- found = true +- } +- } +- if !found { +- t.Fatalf("found no command with the title %s", commandTitle) +- } +- if _, err := env.Editor.ExecuteCommand(env.Ctx, &protocol.ExecuteCommandParams{ +- Command: lens.Command.Command, +- Arguments: lens.Command.Arguments, +- }); err != nil { +- t.Fatal(err) +- } +- env.AfterChange() +- if got := env.BufferText("a/go.mod"); got != wantGoModA { +- t.Fatalf("a/go.mod upgrade failed:\n%s", compare.Text(wantGoModA, got)) +- } +- if got := env.BufferText("b/go.mod"); got != wantGoModB { +- t.Fatalf("b/go.mod changed unexpectedly:\n%s", compare.Text(wantGoModB, got)) +- } +- }) +- }) +- } +- for _, vendoring := range []bool{false, true} { +- t.Run(fmt.Sprintf("Upgrade individual dependency vendoring=%v", vendoring), func(t *testing.T) { +- WithOptions( +- ProxyFiles(proxyWithLatest), +- ).Run(t, shouldUpdateDep, func(t *testing.T, env *Env) { +- if vendoring { +- env.RunGoCommandInDirWithEnv("a", []string{"GOWORK=off"}, "mod", "vendor") +- } +- env.AfterChange() +- env.OpenFile("a/go.mod") +- env.OpenFile("b/go.mod") - ---- testyType-rename -- --package testy +- // Await the diagnostics resulting from opening the modfiles, because +- // otherwise they may cause races when running asynchronously to the +- // explicit re-diagnosing below. +- // +- // TODO(golang/go#58750): there is still a race here, inherent to +- // accessing state on the View; we should create a new snapshot when +- // the view diagnostics change. +- env.AfterChange() - --type testyType int //@rename("tt", "testyType") +- env.ExecuteCodeLensCommand("a/go.mod", command.CheckUpgrades, nil) +- d := &protocol.PublishDiagnosticsParams{} +- env.OnceMet( +- Diagnostics(env.AtRegexp("a/go.mod", `require`), WithMessage("can be upgraded")), +- ReadDiagnostics("a/go.mod", d), +- // We do not want there to be a diagnostic for b/go.mod, +- // but there may be some subtlety in timing here, where this +- // should always succeed, but may not actually test the correct +- // behavior. +- NoDiagnostics(env.AtRegexp("b/go.mod", `require`)), +- ) +- // Check for upgrades in b/go.mod and then clear them. +- env.ExecuteCodeLensCommand("b/go.mod", command.CheckUpgrades, nil) +- env.Await(Diagnostics(env.AtRegexp("b/go.mod", `require`), WithMessage("can be upgraded"))) +- env.ExecuteCodeLensCommand("b/go.mod", command.ResetGoModDiagnostics, nil) +- env.Await(NoDiagnostics(ForFile("b/go.mod"))) - --func a() { -- foo := 42 //@rename("foo", "bar") +- // Apply the diagnostics to a/go.mod. +- env.ApplyQuickFixes("a/go.mod", d.Diagnostics) +- env.AfterChange() +- if got := env.BufferText("a/go.mod"); got != wantGoModA { +- t.Fatalf("a/go.mod upgrade failed:\n%s", compare.Text(wantGoModA, got)) +- } +- if got := env.BufferText("b/go.mod"); got != wantGoModB { +- t.Fatalf("b/go.mod changed unexpectedly:\n%s", compare.Text(wantGoModB, got)) +- } +- }) +- }) +- } -} - -diff -urN a/gopls/internal/lsp/testdata/rename/testy/testy_test.go b/gopls/internal/lsp/testdata/rename/testy/testy_test.go ---- a/gopls/internal/lsp/testdata/rename/testy/testy_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/testy/testy_test.go 1970-01-01 08:00:00 -@@ -1,8 +0,0 @@ --package testy -- --import "testing" +-func TestUnusedDependenciesCodelens(t *testing.T) { +- const proxy = ` +--- golang.org/x/hello@v1.0.0/go.mod -- +-module golang.org/x/hello - --func TestSomething(t *testing.T) { -- var x int //@rename("x", "testyX") -- a() //@rename("a", "b") --} -diff -urN a/gopls/internal/lsp/testdata/rename/testy/testy_test.go.golden b/gopls/internal/lsp/testdata/rename/testy/testy_test.go.golden ---- a/gopls/internal/lsp/testdata/rename/testy/testy_test.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/testy/testy_test.go.golden 1970-01-01 08:00:00 -@@ -1,30 +0,0 @@ ---- b-rename -- --testy.go: --package testy +-go 1.14 +--- golang.org/x/hello@v1.0.0/hi/hi.go -- +-package hi - --type tt int //@rename("tt", "testyType") +-var Goodbye error +--- golang.org/x/unused@v1.0.0/go.mod -- +-module golang.org/x/unused - --func b() { -- foo := 42 //@rename("foo", "bar") --} +-go 1.14 +--- golang.org/x/unused@v1.0.0/nouse/nouse.go -- +-package nouse - --testy_test.go: --package testy +-var NotUsed error +-` - --import "testing" +- const shouldRemoveDep = ` +--- go.mod -- +-module mod.com - --func TestSomething(t *testing.T) { -- var x int //@rename("x", "testyX") -- b() //@rename("a", "b") --} +-go 1.14 - ---- testyX-rename -- --package testy +-require golang.org/x/hello v1.0.0 +-require golang.org/x/unused v1.0.0 +--- go.sum -- +-golang.org/x/hello v1.0.0 h1:qbzE1/qT0/zojAMd/JcPsO2Vb9K4Bkeyq0vB2JGMmsw= +-golang.org/x/hello v1.0.0/go.mod h1:WW7ER2MRNXWA6c8/4bDIek4Hc/+DofTrMaQQitGXcco= +-golang.org/x/unused v1.0.0 h1:LecSbCn5P3vTcxubungSt1Pn4D/WocCaiWOPDC0y0rw= +-golang.org/x/unused v1.0.0/go.mod h1:ihoW8SgWzugwwj0N2SfLfPZCxTB1QOVfhMfB5PWTQ8U= +--- main.go -- +-package main - --import "testing" +-import "golang.org/x/hello/hi" - --func TestSomething(t *testing.T) { -- var testyX int //@rename("x", "testyX") -- a() //@rename("a", "b") +-func main() { +- _ = hi.Goodbye -} +-` +- WithOptions(ProxyFiles(proxy)).Run(t, shouldRemoveDep, func(t *testing.T, env *Env) { +- env.OpenFile("go.mod") +- env.ExecuteCodeLensCommand("go.mod", command.Tidy, nil) +- env.Await(env.DoneWithChangeWatchedFiles()) +- got := env.BufferText("go.mod") +- const wantGoMod = `module mod.com - -diff -urN a/gopls/internal/lsp/testdata/selectionrange/foo.go b/gopls/internal/lsp/testdata/selectionrange/foo.go ---- a/gopls/internal/lsp/testdata/selectionrange/foo.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/selectionrange/foo.go 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ --package foo +-go 1.14 - --import "time" +-require golang.org/x/hello v1.0.0 +-` +- if got != wantGoMod { +- t.Fatalf("go.mod tidy failed:\n%s", compare.Text(wantGoMod, got)) +- } +- }) +-} - --func Bar(x, y int, t time.Time) int { -- zs := []int{1, 2, 3} //@selectionrange("1") +-func TestRegenerateCgo(t *testing.T) { +- testenv.NeedsTool(t, "cgo") +- const workspace = ` +--- go.mod -- +-module example.com - -- for _, z := range zs { -- x = x + z + y + zs[1] //@selectionrange("1") -- } +-go 1.12 +--- cgo.go -- +-package x - -- return x + y //@selectionrange("+") +-/* +-int fortythree() { return 42; } +-*/ +-import "C" +- +-func Foo() { +- print(C.fortytwo()) -} -diff -urN a/gopls/internal/lsp/testdata/selectionrange/foo.go.golden b/gopls/internal/lsp/testdata/selectionrange/foo.go.golden ---- a/gopls/internal/lsp/testdata/selectionrange/foo.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/selectionrange/foo.go.golden 1970-01-01 08:00:00 -@@ -1,29 +0,0 @@ ---- selectionrange_foo_12_11 -- --Ranges 0: -- 11:8-11:13 "x + y" -- 11:1-11:13 "return x + y" -- 4:36-12:1 "{\\n\tzs := []int{...ionrange(\"+\")\\n}" -- 4:0-12:1 "func Bar(x, y i...ionrange(\"+\")\\n}" -- 0:0-12:1 "package foo\\n\\nim...ionrange(\"+\")\\n}" +-` +- Run(t, workspace, func(t *testing.T, env *Env) { +- // Open the file. We have a nonexistant symbol that will break cgo processing. +- env.OpenFile("cgo.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("cgo.go", ``), WithMessage("go list failed to return CompiledGoFiles")), +- ) - ---- selectionrange_foo_6_14 -- --Ranges 0: -- 5:13-5:14 "1" -- 5:7-5:21 "[]int{1, 2, 3}" -- 5:1-5:21 "zs := []int{1, 2, 3}" -- 4:36-12:1 "{\\n\tzs := []int{...ionrange(\"+\")\\n}" -- 4:0-12:1 "func Bar(x, y i...ionrange(\"+\")\\n}" -- 0:0-12:1 "package foo\\n\\nim...ionrange(\"+\")\\n}" +- // Fix the C function name. We haven't regenerated cgo, so nothing should be fixed. +- env.RegexpReplace("cgo.go", `int fortythree`, "int fortytwo") +- env.SaveBuffer("cgo.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("cgo.go", ``), WithMessage("go list failed to return CompiledGoFiles")), +- ) - ---- selectionrange_foo_9_22 -- --Ranges 0: -- 8:21-8:22 "1" -- 8:18-8:23 "zs[1]" -- 8:6-8:23 "x + z + y + zs[1]" -- 8:2-8:23 "x = x + z + y + zs[1]" -- 7:22-9:2 "{\\n\t\tx = x + z +...onrange(\"1\")\\n\t}" -- 7:1-9:2 "for _, z := ran...onrange(\"1\")\\n\t}" -- 4:36-12:1 "{\\n\tzs := []int{...ionrange(\"+\")\\n}" -- 4:0-12:1 "func Bar(x, y i...ionrange(\"+\")\\n}" -- 0:0-12:1 "package foo\\n\\nim...ionrange(\"+\")\\n}" +- // Regenerate cgo, fixing the diagnostic. +- env.ExecuteCodeLensCommand("cgo.go", command.RegenerateCgo, nil) +- env.OnceMet( +- CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromRegenerateCgo), 1, true), +- NoDiagnostics(ForFile("cgo.go")), +- ) +- }) +-} +diff -urN a/gopls/internal/regtest/codelens/gcdetails_test.go b/gopls/internal/regtest/codelens/gcdetails_test.go +--- a/gopls/internal/regtest/codelens/gcdetails_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/codelens/gcdetails_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,127 +0,0 @@ +-// Copyright 2020 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. - -diff -urN a/gopls/internal/lsp/testdata/semantic/README.md b/gopls/internal/lsp/testdata/semantic/README.md ---- a/gopls/internal/lsp/testdata/semantic/README.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/semantic/README.md 1970-01-01 08:00:00 -@@ -1,2 +0,0 @@ --The golden files are the output of `gopls semtok `, with `-- semantic --` --inserted as the first line (the spaces are mandatory) and an extra newline at the end. -diff -urN a/gopls/internal/lsp/testdata/semantic/a.go b/gopls/internal/lsp/testdata/semantic/a.go ---- a/gopls/internal/lsp/testdata/semantic/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/semantic/a.go 1970-01-01 08:00:00 -@@ -1,81 +0,0 @@ --package semantictokens //@ semantic("") +-package codelens - -import ( -- _ "encoding/utf8" -- utf "encoding/utf8" -- "fmt" //@ semantic("fmt") -- . "fmt" -- "unicode/utf8" --) +- "runtime" +- "strings" +- "testing" - --var ( -- a = fmt.Print -- b []string = []string{"foo"} -- c1 chan int -- c2 <-chan int -- c3 = make([]chan<- int) -- b = A{X: 23} -- m map[bool][3]*float64 +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp/fake" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" -) - --const ( -- xx F = iota -- yy = xx + 3 -- zz = "" -- ww = "not " + zz --) +-func TestGCDetails_Toggle(t *testing.T) { +- if runtime.GOOS == "android" { +- t.Skipf("the gc details code lens doesn't work on Android") +- } - --type A struct { -- X int `foof` --} --type B interface { -- A -- sad(int) bool --} +- const mod = ` +--- go.mod -- +-module mod.com - --type F int +-go 1.15 +--- main.go -- +-package main - --func (a *A) f() bool { -- var z string -- x := "foo" -- a(x) -- y := "bar" + x -- switch z { -- case "xx": -- default: -- } -- select { -- case z := <-c3[0]: -- default: -- } -- for k, v := range m { -- return (!k) && v[0] == nil -- } -- c2 <- A.X -- w := b[4:] -- j := len(x) -- j-- -- q := []interface{}{j, 23i, &y} -- g(q...) -- return true --} +-import "fmt" - --func g(vv ...interface{}) { -- ff := func() {} -- defer ff() -- go utf.RuneCount("") -- go utf8.RuneCount(vv.(string)) -- if true { -- } else { -- } --Never: -- for i := 0; i < 10; { -- break Never -- } -- _, ok := vv[0].(A) -- if !ok { -- switch x := vv[0].(type) { -- } -- goto Never -- } +-func main() { +- fmt.Println(42) -} -diff -urN a/gopls/internal/lsp/testdata/semantic/a.go.golden b/gopls/internal/lsp/testdata/semantic/a.go.golden ---- a/gopls/internal/lsp/testdata/semantic/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/semantic/a.go.golden 1970-01-01 08:00:00 -@@ -1,83 +0,0 @@ ---- semantic -- --/*⇒7,keyword,[]*/package /*⇒14,namespace,[]*/semantictokens /*⇒16,comment,[]*///@ semantic("") -- --/*⇒6,keyword,[]*/import ( -- _ "encoding/utf8" -- /*⇒3,namespace,[]*/utf "encoding/utf8" -- "fmt"/*⇐3,namespace,[]*/ /*⇒19,comment,[]*///@ semantic("fmt") -- . "fmt" -- "unicode/utf8"/*⇐4,namespace,[]*/ --) +-` +- WithOptions( +- Settings{ +- "codelenses": map[string]bool{ +- "gc_details": true, +- }, +- }, +- ).Run(t, mod, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.ExecuteCodeLensCommand("main.go", command.GCDetails, nil) +- d := &protocol.PublishDiagnosticsParams{} +- env.OnceMet( +- Diagnostics(AtPosition("main.go", 5, 13)), +- ReadDiagnostics("main.go", d), +- ) +- // Confirm that the diagnostics come from the gc details code lens. +- var found bool +- for _, d := range d.Diagnostics { +- if d.Severity != protocol.SeverityInformation { +- t.Fatalf("unexpected diagnostic severity %v, wanted Information", d.Severity) +- } +- if strings.Contains(d.Message, "42 escapes") { +- found = true +- } +- } +- if !found { +- t.Fatalf(`expected to find diagnostic with message "escape(42 escapes to heap)", found none`) +- } - --/*⇒3,keyword,[]*/var ( -- /*⇒1,variable,[definition]*/a = /*⇒3,namespace,[]*/fmt./*⇒5,function,[]*/Print -- /*⇒1,variable,[definition]*/b []/*⇒6,type,[defaultLibrary]*/string = []/*⇒6,type,[defaultLibrary]*/string{/*⇒5,string,[]*/"foo"} -- /*⇒2,variable,[definition]*/c1 /*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int -- /*⇒2,variable,[definition]*/c2 /*⇒2,operator,[]*/<-/*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int -- /*⇒2,variable,[definition]*/c3 = /*⇒4,function,[defaultLibrary]*/make([]/*⇒4,keyword,[]*/chan/*⇒2,operator,[]*/<- /*⇒3,type,[defaultLibrary]*/int) -- /*⇒1,variable,[definition]*/b = /*⇒1,type,[]*/A{/*⇒1,variable,[]*/X: /*⇒2,number,[]*/23} -- /*⇒1,variable,[definition]*/m /*⇒3,keyword,[]*/map[/*⇒4,type,[defaultLibrary]*/bool][/*⇒1,number,[]*/3]/*⇒1,operator,[]*/*/*⇒7,type,[defaultLibrary]*/float64 --) +- // Editing a buffer should cause gc_details diagnostics to disappear, since +- // they only apply to saved buffers. +- env.EditBuffer("main.go", fake.NewEdit(0, 0, 0, 0, "\n\n")) +- env.AfterChange(NoDiagnostics(ForFile("main.go"))) - --/*⇒5,keyword,[]*/const ( -- /*⇒2,variable,[definition readonly]*/xx /*⇒1,type,[]*/F = /*⇒4,variable,[readonly]*/iota -- /*⇒2,variable,[definition readonly]*/yy = /*⇒2,variable,[readonly]*/xx /*⇒1,operator,[]*/+ /*⇒1,number,[]*/3 -- /*⇒2,variable,[definition readonly]*/zz = /*⇒2,string,[]*/"" -- /*⇒2,variable,[definition readonly]*/ww = /*⇒6,string,[]*/"not " /*⇒1,operator,[]*/+ /*⇒2,variable,[readonly]*/zz --) +- // Saving a buffer should re-format back to the original state, and +- // re-enable the gc_details diagnostics. +- env.SaveBuffer("main.go") +- env.AfterChange(Diagnostics(AtPosition("main.go", 5, 13))) - --/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/A /*⇒6,keyword,[]*/struct { -- /*⇒1,variable,[definition]*/X /*⇒3,type,[defaultLibrary]*/int /*⇒6,string,[]*/`foof` --} --/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/B /*⇒9,keyword,[]*/interface { -- /*⇒1,type,[]*/A -- /*⇒3,method,[definition]*/sad(/*⇒3,type,[defaultLibrary]*/int) /*⇒4,type,[defaultLibrary]*/bool +- // Toggle the GC details code lens again so now it should be off. +- env.ExecuteCodeLensCommand("main.go", command.GCDetails, nil) +- env.Await(NoDiagnostics(ForFile("main.go"))) +- }) -} - --/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/F /*⇒3,type,[defaultLibrary]*/int +-// Test for the crasher in golang/go#54199 +-func TestGCDetails_NewFile(t *testing.T) { +- bug.PanicOnBugs = false +- const src = ` +--- go.mod -- +-module mod.test - --/*⇒4,keyword,[]*/func (/*⇒1,variable,[]*/a /*⇒1,operator,[]*/*/*⇒1,type,[]*/A) /*⇒1,method,[definition]*/f() /*⇒4,type,[defaultLibrary]*/bool { -- /*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/z /*⇒6,type,[defaultLibrary]*/string -- /*⇒1,variable,[definition]*/x /*⇒2,operator,[]*/:= /*⇒5,string,[]*/"foo" -- /*⇒1,variable,[]*/a(/*⇒1,variable,[]*/x) -- /*⇒1,variable,[definition]*/y /*⇒2,operator,[]*/:= /*⇒5,string,[]*/"bar" /*⇒1,operator,[]*/+ /*⇒1,variable,[]*/x -- /*⇒6,keyword,[]*/switch /*⇒1,variable,[]*/z { -- /*⇒4,keyword,[]*/case /*⇒4,string,[]*/"xx": -- /*⇒7,keyword,[]*/default: -- } -- /*⇒6,keyword,[]*/select { -- /*⇒4,keyword,[]*/case /*⇒1,variable,[definition]*/z /*⇒2,operator,[]*/:= /*⇒2,operator,[]*/<-/*⇒2,variable,[]*/c3[/*⇒1,number,[]*/0]: -- /*⇒7,keyword,[]*/default: -- } -- /*⇒3,keyword,[]*/for /*⇒1,variable,[definition]*/k, /*⇒1,variable,[definition]*/v := /*⇒5,keyword,[]*/range /*⇒1,variable,[]*/m { -- /*⇒6,keyword,[]*/return (/*⇒1,operator,[]*/!/*⇒1,variable,[]*/k) /*⇒2,operator,[]*/&& /*⇒1,variable,[]*/v[/*⇒1,number,[]*/0] /*⇒2,operator,[]*/== /*⇒3,variable,[readonly defaultLibrary]*/nil -- } -- /*⇒2,variable,[]*/c2 /*⇒2,operator,[]*/<- /*⇒1,type,[]*/A./*⇒1,variable,[]*/X -- /*⇒1,variable,[definition]*/w /*⇒2,operator,[]*/:= /*⇒1,variable,[]*/b[/*⇒1,number,[]*/4:] -- /*⇒1,variable,[definition]*/j /*⇒2,operator,[]*/:= /*⇒3,function,[defaultLibrary]*/len(/*⇒1,variable,[]*/x) -- /*⇒1,variable,[]*/j/*⇒2,operator,[]*/-- -- /*⇒1,variable,[definition]*/q /*⇒2,operator,[]*/:= []/*⇒9,keyword,[]*/interface{}{/*⇒1,variable,[]*/j, /*⇒3,number,[]*/23i, /*⇒1,operator,[]*/&/*⇒1,variable,[]*/y} -- /*⇒1,function,[]*/g(/*⇒1,variable,[]*/q/*⇒3,operator,[]*/...) -- /*⇒6,keyword,[]*/return /*⇒4,variable,[readonly]*/true --} +-go 1.12 +-` - --/*⇒4,keyword,[]*/func /*⇒1,function,[definition]*/g(/*⇒2,parameter,[definition]*/vv /*⇒3,operator,[]*/.../*⇒9,keyword,[]*/interface{}) { -- /*⇒2,variable,[definition]*/ff /*⇒2,operator,[]*/:= /*⇒4,keyword,[]*/func() {} -- /*⇒5,keyword,[]*/defer /*⇒2,function,[]*/ff() -- /*⇒2,keyword,[]*/go /*⇒3,namespace,[]*/utf./*⇒9,function,[]*/RuneCount(/*⇒2,string,[]*/"") -- /*⇒2,keyword,[]*/go /*⇒4,namespace,[]*/utf8./*⇒9,function,[]*/RuneCount(/*⇒2,parameter,[]*/vv.(/*⇒6,type,[]*/string)) -- /*⇒2,keyword,[]*/if /*⇒4,variable,[readonly]*/true { -- } /*⇒4,keyword,[]*/else { -- } --/*⇒5,parameter,[definition]*/Never: -- /*⇒3,keyword,[]*/for /*⇒1,variable,[definition]*/i /*⇒2,operator,[]*/:= /*⇒1,number,[]*/0; /*⇒1,variable,[]*/i /*⇒1,operator,[]*/< /*⇒2,number,[]*/10; { -- /*⇒5,keyword,[]*/break Never -- } -- _, /*⇒2,variable,[definition]*/ok /*⇒2,operator,[]*/:= /*⇒2,parameter,[]*/vv[/*⇒1,number,[]*/0].(/*⇒1,type,[]*/A) -- /*⇒2,keyword,[]*/if /*⇒1,operator,[]*/!/*⇒2,variable,[]*/ok { -- /*⇒6,keyword,[]*/switch /*⇒1,variable,[definition]*/x /*⇒2,operator,[]*/:= /*⇒2,parameter,[]*/vv[/*⇒1,number,[]*/0].(/*⇒4,keyword,[]*/type) { +- WithOptions( +- Settings{ +- "codelenses": map[string]bool{ +- "gc_details": true, +- }, +- }, +- ).Run(t, src, func(t *testing.T, env *Env) { +- env.CreateBuffer("p_test.go", "") +- +- const gcDetailsCommand = "gopls." + string(command.GCDetails) +- +- hasGCDetails := func() bool { +- lenses := env.CodeLens("p_test.go") // should not crash +- for _, lens := range lenses { +- if lens.Command.Command == gcDetailsCommand { +- return true +- } +- } +- return false - } -- /*⇒4,keyword,[]*/goto Never -- } --} - -diff -urN a/gopls/internal/lsp/testdata/semantic/b.go b/gopls/internal/lsp/testdata/semantic/b.go ---- a/gopls/internal/lsp/testdata/semantic/b.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/semantic/b.go 1970-01-01 08:00:00 -@@ -1,38 +0,0 @@ --package semantictokens //@ semantic("") +- // With an empty file, we shouldn't get the gc_details codelens because +- // there is nowhere to position it (it needs a package name). +- if hasGCDetails() { +- t.Errorf("got the gc_details codelens for an empty file") +- } - --func f(x ...interface{}) { --} +- // Edit to provide a package name. +- env.EditBuffer("p_test.go", fake.NewEdit(0, 0, 0, 0, "package p")) - --func weirⰀd() { /*😀*/ // comment -- const ( -- snil = nil -- nil = true -- true = false -- false = snil -- cmd = `foof` -- double = iota -- iota = copy -- four = (len(cmd)/2 < 5) -- five = four -- ) -- f(cmd, nil, double, iota) +- // Now we should get the gc_details codelens. +- if !hasGCDetails() { +- t.Errorf("didn't get the gc_details codelens for a valid non-empty Go file") +- } +- }) -} +diff -urN a/gopls/internal/regtest/completion/completion18_test.go b/gopls/internal/regtest/completion/completion18_test.go +--- a/gopls/internal/regtest/completion/completion18_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/completion/completion18_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,124 +0,0 @@ +-// Copyright 2021 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. - --/* +-//go:build go1.18 +-// +build go1.18 - --multiline */ /* --multiline --*/ --type AA int --type BB struct { -- AA --} --type CC struct { -- AA int --} --type D func(aa AA) (BB error) --type E func(AA) BB +-package completion - --var a chan<- chan int --var b chan<- <-chan int --var c <-chan <-chan int -diff -urN a/gopls/internal/lsp/testdata/semantic/b.go.golden b/gopls/internal/lsp/testdata/semantic/b.go.golden ---- a/gopls/internal/lsp/testdata/semantic/b.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/semantic/b.go.golden 1970-01-01 08:00:00 -@@ -1,40 +0,0 @@ ---- semantic -- --/*⇒7,keyword,[]*/package /*⇒14,namespace,[]*/semantictokens /*⇒16,comment,[]*///@ semantic("") +-import ( +- "testing" - --/*⇒4,keyword,[]*/func /*⇒1,function,[definition]*/f(/*⇒1,parameter,[definition]*/x /*⇒3,operator,[]*/.../*⇒9,keyword,[]*/interface{}) { --} +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) - --/*⇒4,keyword,[]*/func /*⇒6,function,[definition]*/weirⰀd() { /*⇒5,comment,[]*//*😀*/ /*⇒10,comment,[]*/// comment -- /*⇒5,keyword,[]*/const ( -- /*⇒4,variable,[definition readonly]*/snil = /*⇒3,variable,[readonly defaultLibrary]*/nil -- /*⇒3,variable,[definition readonly]*/nil = /*⇒4,variable,[readonly]*/true -- /*⇒4,variable,[definition readonly]*/true = /*⇒5,variable,[readonly]*/false -- /*⇒5,variable,[definition readonly]*/false = /*⇒4,variable,[readonly]*/snil -- /*⇒3,variable,[definition readonly]*/cmd = /*⇒6,string,[]*/`foof` -- /*⇒6,variable,[definition readonly]*/double = /*⇒4,variable,[readonly]*/iota -- /*⇒4,variable,[definition readonly]*/iota = /*⇒4,function,[defaultLibrary]*/copy -- /*⇒4,variable,[definition readonly]*/four = (/*⇒3,function,[defaultLibrary]*/len(/*⇒3,variable,[readonly]*/cmd)/*⇒1,operator,[]*// /*⇒1,number,[]*/2 /*⇒1,operator,[]*/< /*⇒1,number,[]*/5) -- /*⇒4,variable,[definition readonly]*/five = /*⇒4,variable,[readonly]*/four -- ) -- /*⇒1,function,[]*/f(/*⇒3,variable,[readonly]*/cmd, /*⇒3,variable,[readonly]*/nil, /*⇒6,variable,[readonly]*/double, /*⇒4,variable,[readonly]*/iota) --} +-// test generic receivers +-func TestGenericReceiver(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - --/*⇒2,comment,[]*//* --/*⇒0,comment,[]*/ --/*⇒12,comment,[]*/multiline */ /*⇒2,comment,[]*//* --/*⇒9,comment,[]*/multiline --/*⇒2,comment,[]*/*/ --/*⇒4,keyword,[]*/type /*⇒2,type,[definition]*/AA /*⇒3,type,[defaultLibrary]*/int --/*⇒4,keyword,[]*/type /*⇒2,type,[definition]*/BB /*⇒6,keyword,[]*/struct { -- /*⇒2,type,[]*/AA --} --/*⇒4,keyword,[]*/type /*⇒2,type,[definition]*/CC /*⇒6,keyword,[]*/struct { -- /*⇒2,variable,[definition]*/AA /*⇒3,type,[defaultLibrary]*/int --} --/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/D /*⇒4,keyword,[]*/func(/*⇒2,parameter,[definition]*/aa /*⇒2,type,[]*/AA) (/*⇒2,parameter,[definition]*/BB /*⇒5,type,[]*/error) --/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/E /*⇒4,keyword,[]*/func(/*⇒2,type,[]*/AA) /*⇒2,type,[]*/BB -- --/*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/a /*⇒4,keyword,[]*/chan/*⇒2,operator,[]*/<- /*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int --/*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/b /*⇒4,keyword,[]*/chan/*⇒2,operator,[]*/<- /*⇒2,operator,[]*/<-/*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int --/*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/c /*⇒2,operator,[]*/<-/*⇒4,keyword,[]*/chan /*⇒2,operator,[]*/<-/*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int -- -diff -urN a/gopls/internal/lsp/testdata/semantic/semantic_test.go b/gopls/internal/lsp/testdata/semantic/semantic_test.go ---- a/gopls/internal/lsp/testdata/semantic/semantic_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/semantic/semantic_test.go 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ --package semantictokens -- --import ( -- "os" -- "testing" --) -- --func TestSemanticTokens(t *testing.T) { -- a, _ := os.Getwd() -- // climb up to find internal/lsp -- // find all the .go files +-go 1.18 +--- main.go -- +-package main +-type SyncMap[K any, V comparable] struct {} +-func (s *SyncMap[K,V]) f() {} +-type XX[T any] struct {} +-type UU[T any] struct {} +-func (s SyncMap[XX,string]) g(v UU) {} +-` - +- tests := []struct { +- pat string +- want []string +- }{ +- {"s .Syn", []string{"SyncMap[K, V]"}}, +- {"Map.X", []string{}}, // This is probably wrong, Maybe "XX"? +- {"v U", []string{"UU", "uint", "uint16", "uint32", "uint64", "uint8", "uintptr"}}, // not U[T] +- } +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.Await(env.DoneWithOpen()) +- for _, tst := range tests { +- loc := env.RegexpSearch("main.go", tst.pat) +- loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte(tst.pat))) +- completions := env.Completion(loc) +- result := compareCompletionLabels(tst.want, completions.Items) +- if result != "" { +- t.Errorf("%s: wanted %v", result, tst.want) +- for i, g := range completions.Items { +- t.Errorf("got %d %s %s", i, g.Label, g.Detail) +- } +- } +- } +- }) -} -diff -urN a/gopls/internal/lsp/testdata/signature/signature.go b/gopls/internal/lsp/testdata/signature/signature.go ---- a/gopls/internal/lsp/testdata/signature/signature.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/signature/signature.go 1970-01-01 08:00:00 -@@ -1,85 +0,0 @@ --// Package signature has tests for signature help. --package signature -- --import ( -- "bytes" -- "encoding/json" -- "math/big" --) +-func TestFuzzFunc(t *testing.T) { +- // use the example from the package documentation +- modfile := ` +--- go.mod -- +-module mod.com - --func Foo(a string, b int) (c bool) { -- return +-go 1.18 +-` +- part0 := `package foo +-import "testing" +-func FuzzNone(f *testing.F) { +- f.Add(12) // better not find this f.Add -} -- --func Bar(float64, ...byte) { +-func FuzzHex(f *testing.F) { +- for _, seed := range [][]byte{{}, {0}, {9}, {0xa}, {0xf}, {1, 2, 3, 4}} { +- f.Ad` +- part1 := `d(seed) +- } +- f.F` +- part2 := `uzz(func(t *testing.T, in []byte) { +- enc := hex.EncodeToString(in) +- out, err := hex.DecodeString(enc) +- if err != nil { +- f.Failed() +- } +- if !bytes.Equal(in, out) { +- t.Fatalf("%v: round trip: %v, %s", in, out, f.Name()) +- } +- }) -} +-` +- data := modfile + `-- a_test.go -- +-` + part0 + ` +--- b_test.go -- +-` + part0 + part1 + ` +--- c_test.go -- +-` + part0 + part1 + part2 - --type myStruct struct{} -- --func (*myStruct) foo(e *json.Decoder) (*big.Int, error) { -- return nil, nil +- tests := []struct { +- file string +- pat string +- offset uint32 // UTF16 length from the beginning of pat to what the user just typed +- want []string +- }{ +- {"a_test.go", "f.Ad", 3, []string{"Add"}}, +- {"c_test.go", " f.F", 4, []string{"Failed"}}, +- {"c_test.go", "f.N", 3, []string{"Name"}}, +- {"b_test.go", "f.F", 3, []string{"Fuzz(func(t *testing.T, a []byte)", "Fail", "FailNow", +- "Failed", "Fatal", "Fatalf"}}, +- } +- Run(t, data, func(t *testing.T, env *Env) { +- for _, test := range tests { +- env.OpenFile(test.file) +- env.Await(env.DoneWithOpen()) +- loc := env.RegexpSearch(test.file, test.pat) +- loc.Range.Start.Character += test.offset // character user just typed? will type? +- completions := env.Completion(loc) +- result := compareCompletionLabels(test.want, completions.Items) +- if result != "" { +- t.Errorf("pat %q %q", test.pat, result) +- for i, it := range completions.Items { +- t.Errorf("%d got %q %q", i, it.Label, it.Detail) +- } +- } +- } +- }) -} +diff -urN a/gopls/internal/regtest/completion/completion_test.go b/gopls/internal/regtest/completion/completion_test.go +--- a/gopls/internal/regtest/completion/completion_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/completion/completion_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,1005 +0,0 @@ +-// Copyright 2020 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. - --type MyType struct{} -- --type MyFunc func(foo int) string -- --type Alias = int --type OtherAlias = int --type StringAlias = string -- --func AliasSlice(a []*Alias) (b Alias) { return 0 } --func AliasMap(a map[*Alias]StringAlias) (b, c map[*Alias]StringAlias) { return nil, nil } --func OtherAliasMap(a, b map[Alias]OtherAlias) map[Alias]OtherAlias { return nil } -- --func Qux() { -- Foo("foo", 123) //@signature("(", "Foo(a string, b int) (c bool)", 0) -- Foo("foo", 123) //@signature("123", "Foo(a string, b int) (c bool)", 1) -- Foo("foo", 123) //@signature(",", "Foo(a string, b int) (c bool)", 0) -- Foo("foo", 123) //@signature(" 1", "Foo(a string, b int) (c bool)", 1) -- Foo("foo", 123) //@signature(")", "Foo(a string, b int) (c bool)", 1) -- -- Bar(13.37, 0x13) //@signature("13.37", "Bar(float64, ...byte)", 0) -- Bar(13.37, 0x37) //@signature("0x37", "Bar(float64, ...byte)", 1) -- Bar(13.37, 1, 2, 3, 4) //@signature("4", "Bar(float64, ...byte)", 1) -- -- fn := func(hi, there string) func(i int) rune { -- return func(int) rune { return 0 } -- } +-package completion - -- fn("hi", "there") //@signature("hi", "", 0) -- fn("hi", "there") //@signature(",", "fn(hi string, there string) func(i int) rune", 0) -- fn("hi", "there")(1) //@signature("1", "func(i int) rune", 0) +-import ( +- "fmt" +- "sort" +- "strings" +- "testing" +- "time" - -- fnPtr := &fn -- (*fnPtr)("hi", "there") //@signature(",", "func(hi string, there string) func(i int) rune", 0) +- "github.com/google/go-cmp/cmp" +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/hooks" +- "golang.org/x/tools/gopls/internal/lsp/fake" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +- "golang.org/x/tools/internal/testenv" +-) - -- var fnIntf interface{} = Foo -- fnIntf.(func(string, int) bool)("hi", 123) //@signature("123", "func(string, int) bool", 1) +-func TestMain(m *testing.M) { +- bug.PanicOnBugs = true +- Main(m, hooks.Options) +-} - -- (&bytes.Buffer{}).Next(2) //@signature("2", "Next(n int) []byte", 0) +-const proxy = ` +--- example.com@v1.2.3/go.mod -- +-module example.com - -- myFunc := MyFunc(func(n int) string { return "" }) -- myFunc(123) //@signature("123", "myFunc(foo int) string", 0) +-go 1.12 +--- example.com@v1.2.3/blah/blah.go -- +-package blah - -- var ms myStruct -- ms.foo(nil) //@signature("nil", "foo(e *json.Decoder) (*big.Int, error)", 0) +-const Name = "Blah" +--- random.org@v1.2.3/go.mod -- +-module random.org - -- _ = make([]int, 1, 2) //@signature("2", "make(t Type, size ...int) Type", 1) +-go 1.12 +--- random.org@v1.2.3/blah/blah.go -- +-package hello - -- Foo(myFunc(123), 456) //@signature("myFunc", "Foo(a string, b int) (c bool)", 0) -- Foo(myFunc(123), 456) //@signature("123", "myFunc(foo int) string", 0) +-const Name = "Hello" +-` - -- panic("oops!") //@signature(")", "panic(v interface{})", 0) -- println("hello", "world") //@signature(",", "println(args ...Type)", 0) +-func TestPackageCompletion(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - -- Hello(func() { -- //@signature("//", "", 0) -- }) +-go 1.12 +--- fruits/apple.go -- +-package apple - -- AliasSlice() //@signature(")", "AliasSlice(a []*Alias) (b Alias)", 0) -- AliasMap() //@signature(")", "AliasMap(a map[*Alias]StringAlias) (b map[*Alias]StringAlias, c map[*Alias]StringAlias)", 0) -- OtherAliasMap() //@signature(")", "OtherAliasMap(a map[Alias]OtherAlias, b map[Alias]OtherAlias) map[Alias]OtherAlias", 0) +-fun apple() int { +- return 0 -} - --func Hello(func()) {} -diff -urN a/gopls/internal/lsp/testdata/signature/signature.go.golden b/gopls/internal/lsp/testdata/signature/signature.go.golden ---- a/gopls/internal/lsp/testdata/signature/signature.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/signature/signature.go.golden 1970-01-01 08:00:00 -@@ -1,53 +0,0 @@ ---- AliasMap(a map[*Alias]StringAlias) (b map[*Alias]StringAlias, c map[*Alias]StringAlias)-signature -- --AliasMap(a map[*Alias]StringAlias) (b map[*Alias]StringAlias, c map[*Alias]StringAlias) -- ---- AliasSlice(a []*Alias) (b Alias)-signature -- --AliasSlice(a []*Alias) (b Alias) +--- fruits/testfile.go -- +-// this is a comment - ---- Bar(float64, ...byte)-signature -- --Bar(float64, ...byte) +-/* +- this is a multiline comment +-*/ - ---- Foo(a string, b int) (c bool)-signature -- --Foo(a string, b int) (c bool) +-import "fmt" - ---- Next(n int) []byte-signature -- --Next(n int) []byte +-func test() {} - --Next returns a slice containing the next n bytes from the buffer, advancing the buffer as if the bytes had been returned by Read. +--- fruits/testfile2.go -- +-package - ---- OtherAliasMap(a map[Alias]OtherAlias, b map[Alias]OtherAlias) map[Alias]OtherAlias-signature -- --OtherAliasMap(a map[Alias]OtherAlias, b map[Alias]OtherAlias) map[Alias]OtherAlias +--- fruits/testfile3.go -- +-pac +--- 123f_r.u~its-123/testfile.go -- +-package - ---- fn(hi string, there string) func(i int) rune-signature -- --fn(hi string, there string) func(i int) rune +--- .invalid-dir@-name/testfile.go -- +-package +-` +- var ( +- testfile4 = "" +- testfile5 = "/*a comment*/ " +- testfile6 = "/*a comment*/\n" +- ) +- for _, tc := range []struct { +- name string +- filename string +- content *string +- triggerRegexp string +- want []string +- editRegexp string +- }{ +- { +- name: "package completion at valid position", +- filename: "fruits/testfile.go", +- triggerRegexp: "\n()", +- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, +- editRegexp: "\n()", +- }, +- { +- name: "package completion in a comment", +- filename: "fruits/testfile.go", +- triggerRegexp: "th(i)s", +- want: nil, +- }, +- { +- name: "package completion in a multiline comment", +- filename: "fruits/testfile.go", +- triggerRegexp: `\/\*\n()`, +- want: nil, +- }, +- { +- name: "package completion at invalid position", +- filename: "fruits/testfile.go", +- triggerRegexp: "import \"fmt\"\n()", +- want: nil, +- }, +- { +- name: "package completion after keyword 'package'", +- filename: "fruits/testfile2.go", +- triggerRegexp: "package()", +- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, +- editRegexp: "package\n", +- }, +- { +- name: "package completion with 'pac' prefix", +- filename: "fruits/testfile3.go", +- triggerRegexp: "pac()", +- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, +- editRegexp: "pac", +- }, +- { +- name: "package completion for empty file", +- filename: "fruits/testfile4.go", +- triggerRegexp: "^$", +- content: &testfile4, +- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, +- editRegexp: "^$", +- }, +- { +- name: "package completion without terminal newline", +- filename: "fruits/testfile5.go", +- triggerRegexp: `\*\/ ()`, +- content: &testfile5, +- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, +- editRegexp: `\*\/ ()`, +- }, +- { +- name: "package completion on terminal newline", +- filename: "fruits/testfile6.go", +- triggerRegexp: `\*\/\n()`, +- content: &testfile6, +- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, +- editRegexp: `\*\/\n()`, +- }, +- // Issue golang/go#44680 +- { +- name: "package completion for dir name with punctuation", +- filename: "123f_r.u~its-123/testfile.go", +- triggerRegexp: "package()", +- want: []string{"package fruits123", "package fruits123_test", "package main"}, +- editRegexp: "package\n", +- }, +- { +- name: "package completion for invalid dir name", +- filename: ".invalid-dir@-name/testfile.go", +- triggerRegexp: "package()", +- want: []string{"package main"}, +- editRegexp: "package\n", +- }, +- } { +- t.Run(tc.name, func(t *testing.T) { +- Run(t, files, func(t *testing.T, env *Env) { +- if tc.content != nil { +- env.WriteWorkspaceFile(tc.filename, *tc.content) +- env.Await(env.DoneWithChangeWatchedFiles()) +- } +- env.OpenFile(tc.filename) +- completions := env.Completion(env.RegexpSearch(tc.filename, tc.triggerRegexp)) - ---- foo(e *json.Decoder) (*big.Int, error)-signature -- --foo(e *json.Decoder) (*big.Int, error) +- // Check that the completion item suggestions are in the range +- // of the file. {Start,End}.Line are zero-based. +- lineCount := len(strings.Split(env.BufferText(tc.filename), "\n")) +- for _, item := range completions.Items { +- if start := int(item.TextEdit.Range.Start.Line); start > lineCount { +- t.Fatalf("unexpected text edit range start line number: got %d, want <= %d", start, lineCount) +- } +- if end := int(item.TextEdit.Range.End.Line); end > lineCount { +- t.Fatalf("unexpected text edit range end line number: got %d, want <= %d", end, lineCount) +- } +- } - ---- func(hi string, there string) func(i int) rune-signature -- --func(hi string, there string) func(i int) rune +- if tc.want != nil { +- expectedLoc := env.RegexpSearch(tc.filename, tc.editRegexp) +- for _, item := range completions.Items { +- gotRng := item.TextEdit.Range +- if expectedLoc.Range != gotRng { +- t.Errorf("unexpected completion range for completion item %s: got %v, want %v", +- item.Label, gotRng, expectedLoc.Range) +- } +- } +- } - ---- func(i int) rune-signature -- --func(i int) rune +- diff := compareCompletionLabels(tc.want, completions.Items) +- if diff != "" { +- t.Error(diff) +- } +- }) +- }) +- } +-} - ---- func(string, int) bool-signature -- --func(string, int) bool +-func TestPackageNameCompletion(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - ---- make(t Type, size ...int) Type-signature -- --make(t Type, size ...int) Type +-go 1.12 +--- math/add.go -- +-package ma +-` - --The make built-in function allocates and initializes an object of type slice, map, or chan (only). +- want := []string{"ma", "ma_test", "main", "math", "math_test"} +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("math/add.go") +- completions := env.Completion(env.RegexpSearch("math/add.go", "package ma()")) - ---- myFunc(foo int) string-signature -- --myFunc(foo int) string +- diff := compareCompletionLabels(want, completions.Items) +- if diff != "" { +- t.Fatal(diff) +- } +- }) +-} - ---- panic(v interface{})-signature -- --panic(v any) +-// TODO(rfindley): audit/clean up call sites for this helper, to ensure +-// consistent test errors. +-func compareCompletionLabels(want []string, gotItems []protocol.CompletionItem) string { +- var got []string +- for _, item := range gotItems { +- got = append(got, item.Label) +- if item.Label != item.InsertText && item.TextEdit == nil { +- // Label should be the same as InsertText, if InsertText is to be used +- return fmt.Sprintf("label not the same as InsertText %#v", item) +- } +- } - --The panic built-in function stops normal execution of the current goroutine. +- if len(got) == 0 && len(want) == 0 { +- return "" // treat nil and the empty slice as equivalent +- } - ---- println(args ...Type)-signature -- --println(args ...Type) +- if diff := cmp.Diff(want, got); diff != "" { +- return fmt.Sprintf("completion item mismatch (-want +got):\n%s", diff) +- } +- return "" +-} - --The println built-in function formats its arguments in an implementation-specific way and writes the result to standard error. +-func TestUnimportedCompletion(t *testing.T) { +- const mod = ` +--- go.mod -- +-module mod.com - -diff -urN a/gopls/internal/lsp/testdata/signature/signature2.go.golden b/gopls/internal/lsp/testdata/signature/signature2.go.golden ---- a/gopls/internal/lsp/testdata/signature/signature2.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/signature/signature2.go.golden 1970-01-01 08:00:00 -@@ -1,3 +0,0 @@ ---- Foo(a string, b int) (c bool)-signature -- --Foo(a string, b int) (c bool) +-go 1.14 - -diff -urN a/gopls/internal/lsp/testdata/signature/signature2.go.in b/gopls/internal/lsp/testdata/signature/signature2.go.in ---- a/gopls/internal/lsp/testdata/signature/signature2.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/signature/signature2.go.in 1970-01-01 08:00:00 -@@ -1,5 +0,0 @@ --package signature +-require example.com v1.2.3 +--- go.sum -- +-example.com v1.2.3 h1:ihBTGWGjTU3V4ZJ9OmHITkU9WQ4lGdQkMjgyLFk0FaY= +-example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo= +--- main.go -- +-package main - --func _() { -- Foo(//@signature("//", "Foo(a string, b int) (c bool)", 0) +-func main() { +- _ = blah -} -diff -urN a/gopls/internal/lsp/testdata/signature/signature3.go.golden b/gopls/internal/lsp/testdata/signature/signature3.go.golden ---- a/gopls/internal/lsp/testdata/signature/signature3.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/signature/signature3.go.golden 1970-01-01 08:00:00 -@@ -1,3 +0,0 @@ ---- Foo(a string, b int) (c bool)-signature -- --Foo(a string, b int) (c bool) +--- main2.go -- +-package main - -diff -urN a/gopls/internal/lsp/testdata/signature/signature3.go.in b/gopls/internal/lsp/testdata/signature/signature3.go.in ---- a/gopls/internal/lsp/testdata/signature/signature3.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/signature/signature3.go.in 1970-01-01 08:00:00 -@@ -1,5 +0,0 @@ --package signature +-import "example.com/blah" - -func _() { -- Foo("hello",//@signature("//", "Foo(a string, b int) (c bool)", 1) +- _ = blah.Hello -} -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/signature/signature_test.go b/gopls/internal/lsp/testdata/signature/signature_test.go ---- a/gopls/internal/lsp/testdata/signature/signature_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/signature/signature_test.go 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ --package signature_test +-` +- WithOptions( +- ProxyFiles(proxy), +- ).Run(t, mod, func(t *testing.T, env *Env) { +- // Make sure the dependency is in the module cache and accessible for +- // unimported completions, and then remove it before proceeding. +- env.RemoveWorkspaceFile("main2.go") +- env.RunGoCommand("mod", "tidy") +- env.Await(env.DoneWithChangeWatchedFiles()) - --import ( -- "testing" +- // Trigger unimported completions for the example.com/blah package. +- env.OpenFile("main.go") +- env.Await(env.DoneWithOpen()) +- loc := env.RegexpSearch("main.go", "ah") +- completions := env.Completion(loc) +- if len(completions.Items) == 0 { +- t.Fatalf("no completion items") +- } +- env.AcceptCompletion(loc, completions.Items[0]) // adds blah import to main.go +- env.Await(env.DoneWithChange()) - -- sig "golang.org/lsptests/signature" --) +- // Trigger completions once again for the blah.<> selector. +- env.RegexpReplace("main.go", "_ = blah", "_ = blah.") +- env.Await(env.DoneWithChange()) +- loc = env.RegexpSearch("main.go", "\n}") +- completions = env.Completion(loc) +- if len(completions.Items) != 1 { +- t.Fatalf("expected 1 completion item, got %v", len(completions.Items)) +- } +- item := completions.Items[0] +- if item.Label != "Name" { +- t.Fatalf("expected completion item blah.Name, got %v", item.Label) +- } +- env.AcceptCompletion(loc, item) - --func TestSignature(t *testing.T) { -- sig.AliasSlice() //@signature(")", "AliasSlice(a []*sig.Alias) (b sig.Alias)", 0) -- sig.AliasMap() //@signature(")", "AliasMap(a map[*sig.Alias]sig.StringAlias) (b map[*sig.Alias]sig.StringAlias, c map[*sig.Alias]sig.StringAlias)", 0) -- sig.OtherAliasMap() //@signature(")", "OtherAliasMap(a map[sig.Alias]sig.OtherAlias, b map[sig.Alias]sig.OtherAlias) map[sig.Alias]sig.OtherAlias", 0) +- // Await the diagnostics to add example.com/blah to the go.mod file. +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", `"example.com/blah"`)), +- ) +- }) -} -diff -urN a/gopls/internal/lsp/testdata/signature/signature_test.go.golden b/gopls/internal/lsp/testdata/signature/signature_test.go.golden ---- a/gopls/internal/lsp/testdata/signature/signature_test.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/signature/signature_test.go.golden 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ ---- AliasMap(a map[*sig.Alias]sig.StringAlias) (b map[*sig.Alias]sig.StringAlias, c map[*sig.Alias]sig.StringAlias)-signature -- --AliasMap(a map[*sig.Alias]sig.StringAlias) (b map[*sig.Alias]sig.StringAlias, c map[*sig.Alias]sig.StringAlias) -- ---- AliasSlice(a []*sig.Alias) (b sig.Alias)-signature -- --AliasSlice(a []*sig.Alias) (b sig.Alias) - ---- OtherAliasMap(a map[sig.Alias]sig.OtherAlias, b map[sig.Alias]sig.OtherAlias) map[sig.Alias]sig.OtherAlias-signature -- --OtherAliasMap(a map[sig.Alias]sig.OtherAlias, b map[sig.Alias]sig.OtherAlias) map[sig.Alias]sig.OtherAlias -- -diff -urN a/gopls/internal/lsp/testdata/snippets/func_snippets118.go.in b/gopls/internal/lsp/testdata/snippets/func_snippets118.go.in ---- a/gopls/internal/lsp/testdata/snippets/func_snippets118.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/snippets/func_snippets118.go.in 1970-01-01 08:00:00 -@@ -1,19 +0,0 @@ --// +build go1.18 --//go:build go1.18 +-// Test that completions still work with an undownloaded module, golang/go#43333. +-func TestUndownloadedModule(t *testing.T) { +- // mod.com depends on example.com, but only in a file that's hidden by a +- // build tag, so the IWL won't download example.com. That will cause errors +- // in the go list -m call performed by the imports package. +- const files = ` +--- go.mod -- +-module mod.com - --package snippets +-go 1.14 - --type SyncMap[K comparable, V any] struct{} +-require example.com v1.2.3 +--- go.sum -- +-example.com v1.2.3 h1:ihBTGWGjTU3V4ZJ9OmHITkU9WQ4lGdQkMjgyLFk0FaY= +-example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo= +--- useblah.go -- +-// +build hidden - --func NewSyncMap[K comparable, V any]() (result *SyncMap[K, V]) { //@item(NewSyncMap, "NewSyncMap", "", "") -- return --} +-package pkg +-import "example.com/blah" +-var _ = blah.Name +--- mainmod/mainmod.go -- +-package mainmod - --func Identity[P ~int](p P) P { //@item(Identity, "Identity", "", "") -- return p +-const Name = "mainmod" +-` +- WithOptions(ProxyFiles(proxy)).Run(t, files, func(t *testing.T, env *Env) { +- env.CreateBuffer("import.go", "package pkg\nvar _ = mainmod.Name\n") +- env.SaveBuffer("import.go") +- content := env.ReadWorkspaceFile("import.go") +- if !strings.Contains(content, `import "mod.com/mainmod`) { +- t.Errorf("expected import of mod.com/mainmod in %q", content) +- } +- }) -} - --func _() { -- _ = NewSyncM //@snippet(" //", NewSyncMap, "NewSyncMap[${1:}]()", "NewSyncMap[${1:K comparable}, ${2:V any}]()") -- _ = Identi //@snippet(" //", Identity, "Identity[${1:}](${2:})", "Identity[${1:P ~int}](${2:p P})") --} -diff -urN a/gopls/internal/lsp/testdata/snippets/literal.go b/gopls/internal/lsp/testdata/snippets/literal.go ---- a/gopls/internal/lsp/testdata/snippets/literal.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/snippets/literal.go 1970-01-01 08:00:00 -@@ -1,22 +0,0 @@ --package snippets +-// Test that we can doctor the source code enough so the file is +-// parseable and completion works as expected. +-func TestSourceFixup(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - --import ( -- "golang.org/lsptests/signature" -- t "golang.org/lsptests/types" --) +-go 1.12 +--- foo.go -- +-package foo - --type structy struct { -- x signature.MyType +-func _() { +- var s S +- if s. -} - --func X(_ map[signature.Alias]t.CoolAlias) (map[signature.Alias]t.CoolAlias) { -- return nil +-type S struct { +- i int -} +-` - --func _() { -- X() //@signature(")", "X(_ map[signature.Alias]t.CoolAlias) map[signature.Alias]t.CoolAlias", 0) -- _ = signature.MyType{} //@item(literalMyType, "signature.MyType{}", "", "var") -- s := structy{ -- x: //@snippet(" //", literalMyType, "signature.MyType{\\}", "signature.MyType{\\}") -- } +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("foo.go") +- completions := env.Completion(env.RegexpSearch("foo.go", `if s\.()`)) +- diff := compareCompletionLabels([]string{"i"}, completions.Items) +- if diff != "" { +- t.Fatal(diff) +- } +- }) -} -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/snippets/literal.go.golden b/gopls/internal/lsp/testdata/snippets/literal.go.golden ---- a/gopls/internal/lsp/testdata/snippets/literal.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/snippets/literal.go.golden 1970-01-01 08:00:00 -@@ -1,3 +0,0 @@ ---- X(_ map[signature.Alias]t.CoolAlias) map[signature.Alias]t.CoolAlias-signature -- --X(_ map[signature.Alias]t.CoolAlias) map[signature.Alias]t.CoolAlias - -diff -urN a/gopls/internal/lsp/testdata/snippets/postfix.go b/gopls/internal/lsp/testdata/snippets/postfix.go ---- a/gopls/internal/lsp/testdata/snippets/postfix.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/snippets/postfix.go 1970-01-01 08:00:00 -@@ -1,43 +0,0 @@ --package snippets +-func TestCompletion_Issue45510(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - --// These tests check that postfix completions do and do not show up in --// certain cases. Tests for the postfix completion contents are under --// regtest. +-go 1.12 +--- main.go -- +-package main - -func _() { -- /* append! */ //@item(postfixAppend, "append!", "append and re-assign slice", "snippet") -- var foo []int -- foo.append //@rank(" //", postfixAppend) -- -- []int{}.append //@complete(" //") +- type a *a +- var aaaa1, aaaa2 a +- var _ a = aaaa - -- []int{}.last //@complete(" //") +- type b a +- var bbbb1, bbbb2 b +- var _ b = bbbb +-} - -- /* copy! */ //@item(postfixCopy, "copy!", "duplicate slice", "snippet") +-type ( +- c *d +- d *e +- e **c +-) - -- foo.copy //@rank(" //", postfixCopy) +-func _() { +- var ( +- xxxxc c +- xxxxd d +- xxxxe e +- ) - -- var s struct{ i []int } -- s.i.copy //@rank(" //", postfixCopy) +- var _ c = xxxx +- var _ d = xxxx +- var _ e = xxxx +-} +-` - -- var _ []int = s.i.copy //@complete(" //") +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") - -- var blah func() []int -- blah().append //@complete(" //") +- tests := []struct { +- re string +- want []string +- }{ +- {`var _ a = aaaa()`, []string{"aaaa1", "aaaa2"}}, +- {`var _ b = bbbb()`, []string{"bbbb1", "bbbb2"}}, +- {`var _ c = xxxx()`, []string{"xxxxc", "xxxxd", "xxxxe"}}, +- {`var _ d = xxxx()`, []string{"xxxxc", "xxxxd", "xxxxe"}}, +- {`var _ e = xxxx()`, []string{"xxxxc", "xxxxd", "xxxxe"}}, +- } +- for _, tt := range tests { +- completions := env.Completion(env.RegexpSearch("main.go", tt.re)) +- diff := compareCompletionLabels(tt.want, completions.Items) +- if diff != "" { +- t.Errorf("%s: %s", tt.re, diff) +- } +- } +- }) -} - --func _() { -- /* append! */ //@item(postfixAppend, "append!", "append and re-assign slice", "snippet") -- /* last! */ //@item(postfixLast, "last!", "s[len(s)-1]", "snippet") -- /* print! */ //@item(postfixPrint, "print!", "print to stdout", "snippet") -- /* range! */ //@item(postfixRange, "range!", "range over slice", "snippet") -- /* reverse! */ //@item(postfixReverse, "reverse!", "reverse slice", "snippet") -- /* sort! */ //@item(postfixSort, "sort!", "sort.Slice()", "snippet") -- /* var! */ //@item(postfixVar, "var!", "assign to variable", "snippet") -- /* ifnotnil! */ //@item(postfixIfNotNil, "ifnotnil!", "if expr != nil", "snippet") +-func TestCompletionDeprecation(t *testing.T) { +- const files = ` +--- go.mod -- +-module test.com - -- var foo []int -- foo. //@complete(" //", postfixAppend, postfixCopy, postfixIfNotNil, postfixLast, postfixPrint, postfixRange, postfixReverse, postfixSort, postfixVar) +-go 1.16 +--- prog.go -- +-package waste +-// Deprecated, use newFoof +-func fooFunc() bool { +- return false +-} - -- foo = nil +-// Deprecated +-const badPi = 3.14 +- +-func doit() { +- if fooF +- panic() +- x := badP +-} +-` +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("prog.go") +- loc := env.RegexpSearch("prog.go", "if fooF") +- loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte("if fooF"))) +- completions := env.Completion(loc) +- diff := compareCompletionLabels([]string{"fooFunc"}, completions.Items) +- if diff != "" { +- t.Error(diff) +- } +- if completions.Items[0].Tags == nil { +- t.Errorf("expected Tags to show deprecation %#v", completions.Items[0].Tags) +- } +- loc = env.RegexpSearch("prog.go", "= badP") +- loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte("= badP"))) +- completions = env.Completion(loc) +- diff = compareCompletionLabels([]string{"badPi"}, completions.Items) +- if diff != "" { +- t.Error(diff) +- } +- if completions.Items[0].Tags == nil { +- t.Errorf("expected Tags to show deprecation %#v", completions.Items[0].Tags) +- } +- }) -} -diff -urN a/gopls/internal/lsp/testdata/snippets/snippets.go.golden b/gopls/internal/lsp/testdata/snippets/snippets.go.golden ---- a/gopls/internal/lsp/testdata/snippets/snippets.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/snippets/snippets.go.golden 1970-01-01 08:00:00 -@@ -1,3 +0,0 @@ ---- baz(at AliasType, b bool)-signature -- --baz(at AliasType, b bool) - -diff -urN a/gopls/internal/lsp/testdata/snippets/snippets.go.in b/gopls/internal/lsp/testdata/snippets/snippets.go.in ---- a/gopls/internal/lsp/testdata/snippets/snippets.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/snippets/snippets.go.in 1970-01-01 08:00:00 -@@ -1,64 +0,0 @@ --package snippets +-func TestUnimportedCompletion_VSCodeIssue1489(t *testing.T) { +- const src = ` +--- go.mod -- +-module mod.com - --// Pre-set this marker, as we don't have a "source" for it in this package. --/* Error() */ //@item(Error, "Error", "func() string", "method") +-go 1.14 - --type AliasType = int //@item(sigAliasType, "AliasType", "AliasType", "type") +--- main.go -- +-package main - --func foo(i int, b bool) {} //@item(snipFoo, "foo", "func(i int, b bool)", "func") --func bar(fn func()) func() {} //@item(snipBar, "bar", "func(fn func())", "func") --func baz(at AliasType, b bool) {} //@item(snipBaz, "baz", "func(at AliasType, b bool)", "func") +-import "fmt" - --type Foo struct { -- Bar int //@item(snipFieldBar, "Bar", "int", "field") -- Func func(at AliasType) error //@item(snipFieldFunc, "Func", "func(at AliasType) error", "field") +-func main() { +- fmt.Println("a") +- math.Sqr +-} +-` +- WithOptions( +- WindowsLineEndings(), +- Settings{"ui.completion.usePlaceholders": true}, +- ).Run(t, src, func(t *testing.T, env *Env) { +- // Trigger unimported completions for the mod.com package. +- env.OpenFile("main.go") +- env.Await(env.DoneWithOpen()) +- loc := env.RegexpSearch("main.go", "Sqr()") +- completions := env.Completion(loc) +- if len(completions.Items) == 0 { +- t.Fatalf("no completion items") +- } +- env.AcceptCompletion(loc, completions.Items[0]) +- env.Await(env.DoneWithChange()) +- got := env.BufferText("main.go") +- want := "package main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"math\"\r\n)\r\n\r\nfunc main() {\r\n\tfmt.Println(\"a\")\r\n\tmath.Sqrt(${1:x float64})\r\n}\r\n" +- if diff := cmp.Diff(want, got); diff != "" { +- t.Errorf("unimported completion (-want +got):\n%s", diff) +- } +- }) -} - --func (Foo) Baz() func() {} //@item(snipMethodBaz, "Baz", "func() func()", "method") --func (Foo) BazBar() func() {} //@item(snipMethodBazBar, "BazBar", "func() func()", "method") --func (Foo) BazBaz(at AliasType) func() {} //@item(snipMethodBazBaz, "BazBaz", "func(at AliasType) func()", "method") +-func TestUnimportedCompletionHasPlaceholders60269(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) // uses type params - --func _() { -- f //@snippet(" //", snipFoo, "foo(${1:})", "foo(${1:i int}, ${2:b bool})") +- // We can't express this as a marker test because it doesn't support AcceptCompletion. +- const src = ` +--- go.mod -- +-module example.com +-go 1.12 - -- bar //@snippet(" //", snipBar, "bar(${1:})", "bar(${1:fn func()})") +--- a/a.go -- +-package a - -- baz //@snippet(" //", snipBaz, "baz(${1:})", "baz(${1:at AliasType}, ${2:b bool})") -- baz() //@signature("(", "baz(at AliasType, b bool)", 0) +-var _ = b.F - -- bar(nil) //@snippet("(", snipBar, "bar", "bar") -- bar(ba) //@snippet(")", snipBar, "bar(${1:})", "bar(${1:fn func()})") -- var f Foo -- bar(f.Ba) //@snippet(")", snipMethodBaz, "Baz()", "Baz()") -- (bar)(nil) //@snippet(")", snipBar, "bar(${1:})", "bar(${1:fn func()})") -- (f.Ba)() //@snippet(")", snipMethodBaz, "Baz()", "Baz()") +--- b/b.go -- +-package b - -- Foo{ -- B //@snippet(" //", snipFieldBar, "Bar: ${1:},", "Bar: ${1:int},") -- } +-func F0(a, b int, c float64) {} +-func F1(int, chan *string) {} +-func F2[K, V any](map[K]V, chan V) {} // missing type parameters was issue #60959 +-func F3[K comparable, V any](map[K]V, chan V) {} +-` +- WithOptions( +- WindowsLineEndings(), +- Settings{"ui.completion.usePlaceholders": true}, +- ).Run(t, src, func(t *testing.T, env *Env) { +- env.OpenFile("a/a.go") +- env.Await(env.DoneWithOpen()) - -- Foo{ -- F //@snippet(" //", snipFieldFunc, "Func: ${1:},", "Func: ${1:func(at AliasType) error},") -- } +- // The table lists the expected completions of b.F as they appear in Items. +- const common = "package a\r\n\r\nimport \"example.com/b\"\r\n\r\nvar _ = " +- for i, want := range []string{ +- common + "b.F0(${1:a int}, ${2:b int}, ${3:c float64})\r\n", +- common + "b.F1(${1:_ int}, ${2:_ chan *string})\r\n", +- common + "b.F2[${1:K any}, ${2:V any}](${3:_ map[K]V}, ${4:_ chan V})\r\n", +- common + "b.F3[${1:K comparable}, ${2:V any}](${3:_ map[K]V}, ${4:_ chan V})\r\n", +- } { +- loc := env.RegexpSearch("a/a.go", "b.F()") +- completions := env.Completion(loc) +- if len(completions.Items) == 0 { +- t.Fatalf("no completion items") +- } +- saved := env.BufferText("a/a.go") +- env.AcceptCompletion(loc, completions.Items[i]) +- env.Await(env.DoneWithChange()) +- got := env.BufferText("a/a.go") +- if diff := cmp.Diff(want, got); diff != "" { +- t.Errorf("%d: unimported completion (-want +got):\n%s", i, diff) +- } +- env.SetBufferContent("a/a.go", saved) // restore +- } +- }) +-} - -- Foo{B} //@snippet("}", snipFieldBar, "Bar: ${1:}", "Bar: ${1:int}") -- Foo{} //@snippet("}", snipFieldBar, "Bar: ${1:}", "Bar: ${1:int}") +-func TestPackageMemberCompletionAfterSyntaxError(t *testing.T) { +- // This test documents the current broken behavior due to golang/go#58833. +- const src = ` +--- go.mod -- +-module mod.com - -- Foo{Foo{}.B} //@snippet("} ", snipFieldBar, "Bar", "Bar") +-go 1.14 - -- var err error -- err.Error() //@snippet("E", Error, "Error()", "Error()") -- f.Baz() //@snippet("B", snipMethodBaz, "Baz()", "Baz()") +--- main.go -- +-package main - -- f.Baz() //@snippet("(", snipMethodBazBar, "BazBar", "BazBar") +-import "math" - -- f.Baz() //@snippet("B", snipMethodBazBaz, "BazBaz(${1:})", "BazBaz(${1:at AliasType})") +-func main() { +- math.Sqrt(,0) +- math.Ldex -} -- --func _() { -- type bar struct { -- a int -- b float64 //@item(snipBarB, "b", "float64", "field") -- } -- bar{b} //@snippet("}", snipBarB, "b: ${1:}", "b: ${1:float64}") +-` +- Run(t, src, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.Await(env.DoneWithOpen()) +- loc := env.RegexpSearch("main.go", "Ldex()") +- completions := env.Completion(loc) +- if len(completions.Items) == 0 { +- t.Fatalf("no completion items") +- } +- env.AcceptCompletion(loc, completions.Items[0]) +- env.Await(env.DoneWithChange()) +- got := env.BufferText("main.go") +- // The completion of math.Ldex after the syntax error on the +- // previous line is not "math.Ldexp" but "math.Ldexmath.Abs". +- // (In VSCode, "Abs" wrongly appears in the completion menu.) +- // This is a consequence of poor error recovery in the parser +- // causing "math.Ldex" to become a BadExpr. +- want := "package main\n\nimport \"math\"\n\nfunc main() {\n\tmath.Sqrt(,0)\n\tmath.Ldexmath.Abs(${1:})\n}\n" +- if diff := cmp.Diff(want, got); diff != "" { +- t.Errorf("unimported completion (-want +got):\n%s", diff) +- } +- }) -} -diff -urN a/gopls/internal/lsp/testdata/statements/append.go b/gopls/internal/lsp/testdata/statements/append.go ---- a/gopls/internal/lsp/testdata/statements/append.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/statements/append.go 1970-01-01 08:00:00 -@@ -1,42 +0,0 @@ --package statements - --func _() { -- type mySlice []int +-func TestCompleteAllFields(t *testing.T) { +- // This test verifies that completion results always include all struct fields. +- // See golang/go#53992. - -- var ( -- abc []int //@item(stmtABC, "abc", "[]int", "var") -- abcdef mySlice //@item(stmtABCDEF, "abcdef", "mySlice", "var") -- ) +- const src = ` +--- go.mod -- +-module mod.com - -- /* abcdef = append(abcdef, ) */ //@item(stmtABCDEFAssignAppend, "abcdef = append(abcdef, )", "", "func") +-go 1.18 - -- // don't offer "abc = append(abc, )" because "abc" isn't necessarily -- // better than "abcdef". -- abc //@complete(" //", stmtABC, stmtABCDEF) +--- p/p.go -- +-package p - -- abcdef //@complete(" //", stmtABCDEF, stmtABCDEFAssignAppend) +-import ( +- "fmt" - -- /* append(abc, ) */ //@item(stmtABCAppend, "append(abc, )", "", "func") +- . "net/http" +- . "runtime" +- . "go/types" +- . "go/parser" +- . "go/ast" +-) - -- abc = app //@snippet(" //", stmtABCAppend, "append(abc, ${1:})", "append(abc, ${1:})") +-type S struct { +- a, b, c, d, e, f, g, h, i, j, k, l, m int +- n, o, p, q, r, s, t, u, v, w, x, y, z int -} - -func _() { -- var s struct{ xyz []int } -- -- /* xyz = append(s.xyz, ) */ //@item(stmtXYZAppend, "xyz = append(s.xyz, )", "", "func") +- var s S +- fmt.Println(s.) +-} +-` - -- s.x //@snippet(" //", stmtXYZAppend, "xyz = append(s.xyz, ${1:})", "xyz = append(s.xyz, ${1:})") +- WithOptions(Settings{ +- "completionBudget": "1ns", // must be non-zero as 0 => infinity +- }).Run(t, src, func(t *testing.T, env *Env) { +- wantFields := make(map[string]bool) +- for c := 'a'; c <= 'z'; c++ { +- wantFields[string(c)] = true +- } - -- /* s.xyz = append(s.xyz, ) */ //@item(stmtDeepXYZAppend, "s.xyz = append(s.xyz, )", "", "func") +- env.OpenFile("p/p.go") +- // Make an arbitrary edit to ensure we're not hitting the cache. +- env.EditBuffer("p/p.go", fake.NewEdit(0, 0, 0, 0, fmt.Sprintf("// current time: %v\n", time.Now()))) +- loc := env.RegexpSearch("p/p.go", `s\.()`) +- completions := env.Completion(loc) +- gotFields := make(map[string]bool) +- for _, item := range completions.Items { +- if item.Kind == protocol.FieldCompletion { +- gotFields[item.Label] = true +- } +- } - -- sx //@snippet(" //", stmtDeepXYZAppend, "s.xyz = append(s.xyz, ${1:})", "s.xyz = append(s.xyz, ${1:})") +- if diff := cmp.Diff(wantFields, gotFields); diff != "" { +- t.Errorf("Completion(...) returned mismatching fields (-want +got):\n%s", diff) +- } +- }) -} - --func _() { -- var foo [][]int -- -- /* append(foo[0], ) */ //@item(stmtFooAppend, "append(foo[0], )", "", "func") +-func TestDefinition(t *testing.T) { +- testenv.NeedsGo1Point(t, 17) // in go1.16, The FieldList in func x is not empty +- files := ` +--- go.mod -- +-module mod.com - -- foo[0] = app //@complete(" //"),snippet(" //", stmtFooAppend, "append(foo[0], ${1:})", "append(foo[0], ${1:})") +-go 1.18 +--- a_test.go -- +-package foo +-` +- tests := []struct { +- line string // the sole line in the buffer after the package statement +- pat string // the pattern to search for +- want []string // expected completions +- }{ +- {"func T", "T", []string{"TestXxx(t *testing.T)", "TestMain(m *testing.M)"}}, +- {"func T()", "T", []string{"TestMain", "Test"}}, +- {"func TestM", "TestM", []string{"TestMain(m *testing.M)", "TestM(t *testing.T)"}}, +- {"func TestM()", "TestM", []string{"TestMain"}}, +- {"func TestMi", "TestMi", []string{"TestMi(t *testing.T)"}}, +- {"func TestMi()", "TestMi", nil}, +- {"func TestG", "TestG", []string{"TestG(t *testing.T)"}}, +- {"func TestG(", "TestG", nil}, +- {"func Ben", "B", []string{"BenchmarkXxx(b *testing.B)"}}, +- {"func Ben(", "Ben", []string{"Benchmark"}}, +- {"func BenchmarkFoo", "BenchmarkFoo", []string{"BenchmarkFoo(b *testing.B)"}}, +- {"func BenchmarkFoo(", "BenchmarkFoo", nil}, +- {"func Fuz", "F", []string{"FuzzXxx(f *testing.F)"}}, +- {"func Fuz(", "Fuz", []string{"Fuzz"}}, +- {"func Testx", "Testx", nil}, +- {"func TestMe(t *testing.T)", "TestMe", nil}, +- {"func Te(t *testing.T)", "Te", []string{"TestMain", "Test"}}, +- } +- fname := "a_test.go" +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile(fname) +- env.Await(env.DoneWithOpen()) +- for _, test := range tests { +- env.SetBufferContent(fname, "package foo\n"+test.line) +- loc := env.RegexpSearch(fname, test.pat) +- loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte(test.pat))) +- completions := env.Completion(loc) +- if diff := compareCompletionLabels(test.want, completions.Items); diff != "" { +- t.Error(diff) +- } +- } +- }) -} -diff -urN a/gopls/internal/lsp/testdata/statements/if_err_check_return.go b/gopls/internal/lsp/testdata/statements/if_err_check_return.go ---- a/gopls/internal/lsp/testdata/statements/if_err_check_return.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/statements/if_err_check_return.go 1970-01-01 08:00:00 -@@ -1,27 +0,0 @@ --package statements -- --import ( -- "bytes" -- "io" -- "os" --) - --func one() (int, float32, io.Writer, *int, []int, bytes.Buffer, error) { -- /* if err != nil { return err } */ //@item(stmtOneIfErrReturn, "if err != nil { return err }", "", "") -- /* err != nil { return err } */ //@item(stmtOneErrReturn, "err != nil { return err }", "", "") +-// Test that completing a definition replaces source text when applied, golang/go#56852. +-// Note: With go <= 1.16 the completions does not add parameters and fails these tests. +-func TestDefinitionReplaceRange(t *testing.T) { +- testenv.NeedsGo1Point(t, 17) - -- _, err := os.Open("foo") -- //@snippet("", stmtOneIfErrReturn, "", "if err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") +- const mod = ` +--- go.mod -- +-module mod.com - -- _, err = os.Open("foo") -- i //@snippet(" //", stmtOneIfErrReturn, "", "if err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") +-go 1.17 +-` - -- _, err = os.Open("foo") -- if er //@snippet(" //", stmtOneErrReturn, "", "err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") +- tests := []struct { +- name string +- before, after string +- }{ +- { +- name: "func TestMa", +- before: ` +-package foo_test - -- _, err = os.Open("foo") -- if //@snippet(" //", stmtOneIfErrReturn, "", "if err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") +-func TestMa +-`, +- after: ` +-package foo_test - -- _, err = os.Open("foo") -- if //@snippet("//", stmtOneIfErrReturn, "", "if err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") --} -diff -urN a/gopls/internal/lsp/testdata/statements/if_err_check_return_2.go b/gopls/internal/lsp/testdata/statements/if_err_check_return_2.go ---- a/gopls/internal/lsp/testdata/statements/if_err_check_return_2.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/statements/if_err_check_return_2.go 1970-01-01 08:00:00 -@@ -1,12 +0,0 @@ --package statements +-func TestMain(m *testing.M) +-`, +- }, +- { +- name: "func TestSome", +- before: ` +-package foo_test - --import "os" +-func TestSome +-`, +- after: ` +-package foo_test - --func two() error { -- var s struct{ err error } +-func TestSome(t *testing.T) +-`, +- }, +- { +- name: "func Bench", +- before: ` +-package foo_test - -- /* if s.err != nil { return s.err } */ //@item(stmtTwoIfErrReturn, "if s.err != nil { return s.err }", "", "") +-func Bench +-`, +- // Note: Snippet with escaped }. +- after: ` +-package foo_test - -- _, s.err = os.Open("foo") -- //@snippet("", stmtTwoIfErrReturn, "", "if s.err != nil {\n\treturn ${1:s.err}\n\\}") --} -diff -urN a/gopls/internal/lsp/testdata/statements/if_err_check_test.go b/gopls/internal/lsp/testdata/statements/if_err_check_test.go ---- a/gopls/internal/lsp/testdata/statements/if_err_check_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/statements/if_err_check_test.go 1970-01-01 08:00:00 -@@ -1,20 +0,0 @@ --package statements -- --import ( -- "os" -- "testing" --) -- --func TestErr(t *testing.T) { -- /* if err != nil { t.Fatal(err) } */ //@item(stmtOneIfErrTFatal, "if err != nil { t.Fatal(err) }", "", "") -- -- _, err := os.Open("foo") -- //@snippet("", stmtOneIfErrTFatal, "", "if err != nil {\n\tt.Fatal(err)\n\\}") --} +-func Benchmark${1:Xxx}(b *testing.B) { +- $0 +-\} +-`, +- }, +- } - --func BenchmarkErr(b *testing.B) { -- /* if err != nil { b.Fatal(err) } */ //@item(stmtOneIfErrBFatal, "if err != nil { b.Fatal(err) }", "", "") +- Run(t, mod, func(t *testing.T, env *Env) { +- env.CreateBuffer("foo_test.go", "") - -- _, err := os.Open("foo") -- //@snippet("", stmtOneIfErrBFatal, "", "if err != nil {\n\tb.Fatal(err)\n\\}") --} -diff -urN a/gopls/internal/lsp/testdata/stub/other/other.go b/gopls/internal/lsp/testdata/stub/other/other.go ---- a/gopls/internal/lsp/testdata/stub/other/other.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/other/other.go 1970-01-01 08:00:00 -@@ -1,10 +0,0 @@ --package other +- for _, tst := range tests { +- tst.before = strings.Trim(tst.before, "\n") +- tst.after = strings.Trim(tst.after, "\n") +- env.SetBufferContent("foo_test.go", tst.before) - --import ( -- "bytes" -- renamed_context "context" --) +- loc := env.RegexpSearch("foo_test.go", tst.name) +- loc.Range.Start.Character = uint32(protocol.UTF16Len([]byte(tst.name))) +- completions := env.Completion(loc) +- if len(completions.Items) == 0 { +- t.Fatalf("no completion items") +- } - --type Interface interface { -- Get(renamed_context.Context) *bytes.Buffer +- env.AcceptCompletion(loc, completions.Items[0]) +- env.Await(env.DoneWithChange()) +- if buf := env.BufferText("foo_test.go"); buf != tst.after { +- t.Errorf("%s:incorrect completion: got %q, want %q", tst.name, buf, tst.after) +- } +- } +- }) -} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_add_selector.go b/gopls/internal/lsp/testdata/stub/stub_add_selector.go ---- a/gopls/internal/lsp/testdata/stub/stub_add_selector.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_add_selector.go 1970-01-01 08:00:00 -@@ -1,12 +0,0 @@ --package stub -- --import "io" -- --// This file tests that if an interface --// method references a type from its own package --// then our implementation must add the import/package selector --// in the concrete method if the concrete type is outside of the interface --// package --var _ io.ReaderFrom = &readerFrom{} //@suggestedfix("&readerFrom", "quickfix", "") -- --type readerFrom struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_add_selector.go.golden b/gopls/internal/lsp/testdata/stub/stub_add_selector.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_add_selector.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_add_selector.go.golden 1970-01-01 08:00:00 -@@ -1,19 +0,0 @@ ---- suggestedfix_stub_add_selector_10_23 -- --package stub - --import "io" +-func TestGoWorkCompletion(t *testing.T) { +- const files = ` +--- go.work -- +-go 1.18 - --// This file tests that if an interface --// method references a type from its own package --// then our implementation must add the import/package selector --// in the concrete method if the concrete type is outside of the interface --// package --var _ io.ReaderFrom = &readerFrom{} //@suggestedfix("&readerFrom", "quickfix", "") +-use ./a +-use ./a/ba +-use ./a/b/ +-use ./dir/foo +-use ./dir/foobar/ +--- a/go.mod -- +--- go.mod -- +--- a/bar/go.mod -- +--- a/b/c/d/e/f/go.mod -- +--- dir/bar -- +--- dir/foobar/go.mod -- +-` - --type readerFrom struct{} +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("go.work") - --// ReadFrom implements io.ReaderFrom. --func (*readerFrom) ReadFrom(r io.Reader) (n int64, err error) { -- panic("unimplemented") +- tests := []struct { +- re string +- want []string +- }{ +- {`use ()\.`, []string{".", "./a", "./a/bar", "./dir/foobar"}}, +- {`use \.()`, []string{"", "/a", "/a/bar", "/dir/foobar"}}, +- {`use \./()`, []string{"a", "a/bar", "dir/foobar"}}, +- {`use ./a()`, []string{"", "/b/c/d/e/f", "/bar"}}, +- {`use ./a/b()`, []string{"/c/d/e/f", "ar"}}, +- {`use ./a/b/()`, []string{`c/d/e/f`}}, +- {`use ./a/ba()`, []string{"r"}}, +- {`use ./dir/foo()`, []string{"bar"}}, +- {`use ./dir/foobar/()`, []string{}}, +- } +- for _, tt := range tests { +- completions := env.Completion(env.RegexpSearch("go.work", tt.re)) +- diff := compareCompletionLabels(tt.want, completions.Items) +- if diff != "" { +- t.Errorf("%s: %s", tt.re, diff) +- } +- } +- }) -} - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_assign.go b/gopls/internal/lsp/testdata/stub/stub_assign.go ---- a/gopls/internal/lsp/testdata/stub/stub_assign.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_assign.go 1970-01-01 08:00:00 -@@ -1,10 +0,0 @@ --package stub +-func TestBuiltinCompletion(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - --import "io" +-go 1.18 +--- a.go -- +-package a - --func main() { -- var br io.ByteWriter -- br = &byteWriter{} //@suggestedfix("&", "quickfix", "") +-func _() { +- // here -} +-` - --type byteWriter struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_assign.go.golden b/gopls/internal/lsp/testdata/stub/stub_assign.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_assign.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_assign.go.golden 1970-01-01 08:00:00 -@@ -1,17 +0,0 @@ ---- suggestedfix_stub_assign_7_7 -- --package stub +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("a.go") +- result := env.Completion(env.RegexpSearch("a.go", `// here`)) +- builtins := []string{ +- "any", "append", "bool", "byte", "cap", "close", +- "comparable", "complex", "complex128", "complex64", "copy", "delete", +- "error", "false", "float32", "float64", "imag", "int", "int16", "int32", +- "int64", "int8", "len", "make", "new", "panic", "print", "println", "real", +- "recover", "rune", "string", "true", "uint", "uint16", "uint32", "uint64", +- "uint8", "uintptr", "nil", +- } +- if testenv.Go1Point() >= 21 { +- builtins = append(builtins, "clear", "max", "min") +- } +- sort.Strings(builtins) +- var got []string - --import "io" +- for _, item := range result.Items { +- // TODO(rfindley): for flexibility, ignore zero while it is being +- // implemented. Remove this if/when zero lands. +- if item.Label != "zero" { +- got = append(got, item.Label) +- } +- } +- sort.Strings(got) - --func main() { -- var br io.ByteWriter -- br = &byteWriter{} //@suggestedfix("&", "quickfix", "") +- if diff := cmp.Diff(builtins, got); diff != "" { +- t.Errorf("Completion: unexpected mismatch (-want +got):\n%s", diff) +- } +- }) -} - --type byteWriter struct{} -- --// WriteByte implements io.ByteWriter. --func (*byteWriter) WriteByte(c byte) error { -- panic("unimplemented") --} +-func TestOverlayCompletion(t *testing.T) { +- const files = ` +--- go.mod -- +-module foo.test - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go b/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go ---- a/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go 1970-01-01 08:00:00 -@@ -1,11 +0,0 @@ --package stub +-go 1.18 - --import "io" +--- foo/foo.go -- +-package foo - --func main() { -- var br io.ByteWriter -- var i int -- i, br = 1, &multiByteWriter{} //@suggestedfix("&", "quickfix", "") --} +-type Foo struct{} +-` - --type multiByteWriter struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go.golden b/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go.golden 1970-01-01 08:00:00 -@@ -1,18 +0,0 @@ ---- suggestedfix_stub_assign_multivars_8_13 -- --package stub +- Run(t, files, func(t *testing.T, env *Env) { +- env.CreateBuffer("nodisk/nodisk.go", ` +-package nodisk - --import "io" +-import ( +- "foo.test/foo" +-) - --func main() { -- var br io.ByteWriter -- var i int -- i, br = 1, &multiByteWriter{} //@suggestedfix("&", "quickfix", "") +-func _() { +- foo.Foo() +-} +-`) +- list := env.Completion(env.RegexpSearch("nodisk/nodisk.go", "foo.(Foo)")) +- want := []string{"Foo"} +- var got []string +- for _, item := range list.Items { +- got = append(got, item.Label) +- } +- if diff := cmp.Diff(want, got); diff != "" { +- t.Errorf("Completion: unexpected mismatch (-want +got):\n%s", diff) +- } +- }) -} - --type multiByteWriter struct{} +-// Fix for golang/go#60062: unimported completion included "golang.org/toolchain" results. +-func TestToolchainCompletions(t *testing.T) { +- const files = ` +--- go.mod -- +-module foo.test/foo - --// WriteByte implements io.ByteWriter. --func (*multiByteWriter) WriteByte(c byte) error { -- panic("unimplemented") --} +-go 1.21 - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_call_expr.go b/gopls/internal/lsp/testdata/stub/stub_call_expr.go ---- a/gopls/internal/lsp/testdata/stub/stub_call_expr.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_call_expr.go 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ --package stub +--- foo.go -- +-package foo - --func main() { -- check(&callExpr{}) //@suggestedfix("&", "quickfix", "") +-func _() { +- os.Open -} - --func check(err error) { -- if err != nil { -- panic(err) -- } +-func _() { +- strings -} +-` - --type callExpr struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_call_expr.go.golden b/gopls/internal/lsp/testdata/stub/stub_call_expr.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_call_expr.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_call_expr.go.golden 1970-01-01 08:00:00 -@@ -1,20 +0,0 @@ ---- suggestedfix_stub_call_expr_4_8 -- --package stub +- const proxy = ` +--- golang.org/toolchain@v0.0.1-go1.21.1.linux-amd64/go.mod -- +-module golang.org/toolchain +--- golang.org/toolchain@v0.0.1-go1.21.1.linux-amd64/src/os/os.go -- +-package os - --func main() { -- check(&callExpr{}) //@suggestedfix("&", "quickfix", "") --} +-func Open() {} +--- golang.org/toolchain@v0.0.1-go1.21.1.linux-amd64/src/strings/strings.go -- +-package strings - --func check(err error) { -- if err != nil { -- panic(err) -- } --} +-func Join() {} +-` - --type callExpr struct{} +- WithOptions( +- ProxyFiles(proxy), +- ).Run(t, files, func(t *testing.T, env *Env) { +- env.RunGoCommand("mod", "download", "golang.org/toolchain@v0.0.1-go1.21.1.linux-amd64") +- env.OpenFile("foo.go") - --// Error implements error. --func (*callExpr) Error() string { -- panic("unimplemented") +- for _, pattern := range []string{"os.Open()", "string()"} { +- loc := env.RegexpSearch("foo.go", pattern) +- res := env.Completion(loc) +- for _, item := range res.Items { +- if strings.Contains(item.Detail, "golang.org/toolchain") { +- t.Errorf("Completion(...) returned toolchain item %#v", item) +- } +- } +- } +- }) -} +diff -urN a/gopls/internal/regtest/completion/postfix_snippet_test.go b/gopls/internal/regtest/completion/postfix_snippet_test.go +--- a/gopls/internal/regtest/completion/postfix_snippet_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/completion/postfix_snippet_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,590 +0,0 @@ +-// Copyright 2021 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. - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_embedded.go b/gopls/internal/lsp/testdata/stub/stub_embedded.go ---- a/gopls/internal/lsp/testdata/stub/stub_embedded.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_embedded.go 1970-01-01 08:00:00 -@@ -1,15 +0,0 @@ --package stub +-package completion - -import ( -- "io" -- "sort" --) -- --var _ embeddedInterface = (*embeddedConcrete)(nil) //@suggestedfix("(", "quickfix", "") -- --type embeddedConcrete struct{} -- --type embeddedInterface interface { -- sort.Interface -- io.Reader --} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_embedded.go.golden b/gopls/internal/lsp/testdata/stub/stub_embedded.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_embedded.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_embedded.go.golden 1970-01-01 08:00:00 -@@ -1,37 +0,0 @@ ---- suggestedfix_stub_embedded_8_27 -- --package stub +- "strings" +- "testing" - --import ( -- "io" -- "sort" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" -) - --var _ embeddedInterface = (*embeddedConcrete)(nil) //@suggestedfix("(", "quickfix", "") +-func TestPostfixSnippetCompletion(t *testing.T) { +- const mod = ` +--- go.mod -- +-module mod.com - --type embeddedConcrete struct{} +-go 1.12 +-` - --// Len implements embeddedInterface. --func (*embeddedConcrete) Len() int { -- panic("unimplemented") --} +- cases := []struct { +- name string +- before, after string +- }{ +- { +- name: "sort", +- before: ` +-package foo - --// Less implements embeddedInterface. --func (*embeddedConcrete) Less(i int, j int) bool { -- panic("unimplemented") +-func _() { +- var foo []int +- foo.sort -} +-`, +- after: ` +-package foo - --// Read implements embeddedInterface. --func (*embeddedConcrete) Read(p []byte) (n int, err error) { -- panic("unimplemented") --} +-import "sort" - --// Swap implements embeddedInterface. --func (*embeddedConcrete) Swap(i int, j int) { -- panic("unimplemented") +-func _() { +- var foo []int +- sort.Slice(foo, func(i, j int) bool { +- $0 +-}) -} +-`, +- }, +- { +- name: "sort_renamed_sort_package", +- before: ` +-package foo - --type embeddedInterface interface { -- sort.Interface -- io.Reader --} +-import blahsort "sort" - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_err.go b/gopls/internal/lsp/testdata/stub/stub_err.go ---- a/gopls/internal/lsp/testdata/stub/stub_err.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_err.go 1970-01-01 08:00:00 -@@ -1,7 +0,0 @@ --package stub +-var j int - --func main() { -- var br error = &customErr{} //@suggestedfix("&", "quickfix", "") +-func _() { +- var foo []int +- foo.sort -} +-`, +- after: ` +-package foo - --type customErr struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_err.go.golden b/gopls/internal/lsp/testdata/stub/stub_err.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_err.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_err.go.golden 1970-01-01 08:00:00 -@@ -1,14 +0,0 @@ ---- suggestedfix_stub_err_4_17 -- --package stub -- --func main() { -- var br error = &customErr{} //@suggestedfix("&", "quickfix", "") --} +-import blahsort "sort" - --type customErr struct{} +-var j int - --// Error implements error. --func (*customErr) Error() string { -- panic("unimplemented") +-func _() { +- var foo []int +- blahsort.Slice(foo, func(i, j2 int) bool { +- $0 +-}) -} +-`, +- }, +- { +- name: "last", +- before: ` +-package foo - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_function_return.go b/gopls/internal/lsp/testdata/stub/stub_function_return.go ---- a/gopls/internal/lsp/testdata/stub/stub_function_return.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_function_return.go 1970-01-01 08:00:00 -@@ -1,11 +0,0 @@ --package stub -- --import ( -- "io" --) -- --func newCloser() io.Closer { -- return closer{} //@suggestedfix("c", "quickfix", "") +-func _() { +- var s struct { i []int } +- s.i.last -} +-`, +- after: ` +-package foo - --type closer struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_function_return.go.golden b/gopls/internal/lsp/testdata/stub/stub_function_return.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_function_return.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_function_return.go.golden 1970-01-01 08:00:00 -@@ -1,18 +0,0 @@ ---- suggestedfix_stub_function_return_8_9 -- --package stub -- --import ( -- "io" --) -- --func newCloser() io.Closer { -- return closer{} //@suggestedfix("c", "quickfix", "") +-func _() { +- var s struct { i []int } +- s.i[len(s.i)-1] -} +-`, +- }, +- { +- name: "reverse", +- before: ` +-package foo - --type closer struct{} -- --// Close implements io.Closer. --func (closer) Close() error { -- panic("unimplemented") +-func _() { +- var foo []int +- foo.reverse -} +-`, +- after: ` +-package foo - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go b/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go ---- a/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go 1970-01-01 08:00:00 -@@ -1,15 +0,0 @@ --//go:build go1.18 --// +build go1.18 -- --package stub -- --import "io" -- --// This file tests that that the stub method generator accounts for concrete --// types that have type parameters defined. --var _ io.ReaderFrom = &genReader[string, int]{} //@suggestedfix("&genReader", "quickfix", "Implement io.ReaderFrom") -- --type genReader[T, Y any] struct { -- T T -- Y Y +-func _() { +- var foo []int +- for i, j := 0, len(foo)-1; i < j; i, j = i+1, j-1 { +- foo[i], foo[j] = foo[j], foo[i] -} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go.golden b/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go.golden 1970-01-01 08:00:00 -@@ -1,22 +0,0 @@ ---- suggestedfix_stub_generic_receiver_10_23 -- --//go:build go1.18 --// +build go1.18 -- --package stub - --import "io" -- --// This file tests that that the stub method generator accounts for concrete --// types that have type parameters defined. --var _ io.ReaderFrom = &genReader[string, int]{} //@suggestedfix("&genReader", "quickfix", "Implement io.ReaderFrom") -- --type genReader[T, Y any] struct { -- T T -- Y Y -} +-`, +- }, +- { +- name: "slice_range", +- before: ` +-package foo - --// ReadFrom implements io.ReaderFrom. --func (*genReader[T, Y]) ReadFrom(r io.Reader) (n int64, err error) { -- panic("unimplemented") +-func _() { +- type myThing struct{} +- var foo []myThing +- foo.range -} +-`, +- after: ` +-package foo - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go b/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go ---- a/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go 1970-01-01 08:00:00 -@@ -1,18 +0,0 @@ --package stub -- --import ( -- "compress/zlib" -- . "io" -- _ "io" --) -- --// This file tests that dot-imports and underscore imports --// are properly ignored and that a new import is added to --// reference method types -- --var ( -- _ Reader -- _ zlib.Resetter = (*ignoredResetter)(nil) //@suggestedfix("(", "quickfix", "") --) -- --type ignoredResetter struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go.golden b/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go.golden 1970-01-01 08:00:00 -@@ -1,25 +0,0 @@ ---- suggestedfix_stub_ignored_imports_15_20 -- --package stub -- --import ( -- "compress/zlib" -- . "io" -- _ "io" --) -- --// This file tests that dot-imports and underscore imports --// are properly ignored and that a new import is added to --// reference method types -- --var ( -- _ Reader -- _ zlib.Resetter = (*ignoredResetter)(nil) //@suggestedfix("(", "quickfix", "") --) -- --type ignoredResetter struct{} -- --// Reset implements zlib.Resetter. --func (*ignoredResetter) Reset(r Reader, dict []byte) error { -- panic("unimplemented") +-func _() { +- type myThing struct{} +- var foo []myThing +- for i, mt := range foo { +- $0 -} +-} +-`, +- }, +- { +- name: "append_stmt", +- before: ` +-package foo - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_issue2606.go b/gopls/internal/lsp/testdata/stub/stub_issue2606.go ---- a/gopls/internal/lsp/testdata/stub/stub_issue2606.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_issue2606.go 1970-01-01 08:00:00 -@@ -1,7 +0,0 @@ --package stub -- --type I interface{ error } -- --type C int -- --var _ I = C(0) //@suggestedfix("C", "quickfix", "") -diff -urN a/gopls/internal/lsp/testdata/stub/stub_issue2606.go.golden b/gopls/internal/lsp/testdata/stub/stub_issue2606.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_issue2606.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_issue2606.go.golden 1970-01-01 08:00:00 -@@ -1,14 +0,0 @@ ---- suggestedfix_stub_issue2606_7_11 -- --package stub +-func _() { +- var foo []int +- foo.append +-} +-`, +- after: ` +-package foo - --type I interface{ error } +-func _() { +- var foo []int +- foo = append(foo, $0) +-} +-`, +- }, +- { +- name: "append_expr", +- before: ` +-package foo - --type C int +-func _() { +- var foo []int +- var _ []int = foo.append +-} +-`, +- after: ` +-package foo - --// Error implements I. --func (C) Error() string { -- panic("unimplemented") +-func _() { +- var foo []int +- var _ []int = append(foo, $0) -} +-`, +- }, +- { +- name: "slice_copy", +- before: ` +-package foo - --var _ I = C(0) //@suggestedfix("C", "quickfix", "") +-func _() { +- var foo []int +- foo.copy +-} +-`, +- after: ` +-package foo - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_multi_var.go b/gopls/internal/lsp/testdata/stub/stub_multi_var.go ---- a/gopls/internal/lsp/testdata/stub/stub_multi_var.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_multi_var.go 1970-01-01 08:00:00 -@@ -1,11 +0,0 @@ --package stub +-func _() { +- var foo []int +- fooCopy := make([]int, len(foo)) +-copy(fooCopy, foo) - --import "io" +-} +-`, +- }, +- { +- name: "map_range", +- before: ` +-package foo - --// This test ensures that a variable declaration that --// has multiple values on the same line can still be --// analyzed correctly to target the interface implementation --// diagnostic. --var one, two, three io.Reader = nil, &multiVar{}, nil //@suggestedfix("&", "quickfix", "") +-func _() { +- var foo map[string]int +- foo.range +-} +-`, +- after: ` +-package foo - --type multiVar struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_multi_var.go.golden b/gopls/internal/lsp/testdata/stub/stub_multi_var.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_multi_var.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_multi_var.go.golden 1970-01-01 08:00:00 -@@ -1,18 +0,0 @@ ---- suggestedfix_stub_multi_var_9_38 -- --package stub +-func _() { +- var foo map[string]int +- for k, v := range foo { +- $0 +-} +-} +-`, +- }, +- { +- name: "map_clear", +- before: ` +-package foo - --import "io" +-func _() { +- var foo map[string]int +- foo.clear +-} +-`, +- after: ` +-package foo - --// This test ensures that a variable declaration that --// has multiple values on the same line can still be --// analyzed correctly to target the interface implementation --// diagnostic. --var one, two, three io.Reader = nil, &multiVar{}, nil //@suggestedfix("&", "quickfix", "") +-func _() { +- var foo map[string]int +- for k := range foo { +- delete(foo, k) +-} - --type multiVar struct{} +-} +-`, +- }, +- { +- name: "map_keys", +- before: ` +-package foo - --// Read implements io.Reader. --func (*multiVar) Read(p []byte) (n int, err error) { -- panic("unimplemented") +-func _() { +- var foo map[string]int +- foo.keys -} +-`, +- after: ` +-package foo - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_pointer.go b/gopls/internal/lsp/testdata/stub/stub_pointer.go ---- a/gopls/internal/lsp/testdata/stub/stub_pointer.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_pointer.go 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --package stub +-func _() { +- var foo map[string]int +- keys := make([]string, 0, len(foo)) +-for k := range foo { +- keys = append(keys, k) +-} - --import "io" +-} +-`, +- }, +- { +- name: "channel_range", +- before: ` +-package foo - --func getReaderFrom() io.ReaderFrom { -- return &pointerImpl{} //@suggestedfix("&", "quickfix", "") +-func _() { +- foo := make(chan int) +- foo.range -} +-`, +- after: ` +-package foo - --type pointerImpl struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_pointer.go.golden b/gopls/internal/lsp/testdata/stub/stub_pointer.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_pointer.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_pointer.go.golden 1970-01-01 08:00:00 -@@ -1,16 +0,0 @@ ---- suggestedfix_stub_pointer_6_9 -- --package stub +-func _() { +- foo := make(chan int) +- for e := range foo { +- $0 +-} +-} +-`, +- }, +- { +- name: "var", +- before: ` +-package foo - --import "io" +-func foo() (int, error) { return 0, nil } - --func getReaderFrom() io.ReaderFrom { -- return &pointerImpl{} //@suggestedfix("&", "quickfix", "") +-func _() { +- foo().var -} +-`, +- after: ` +-package foo - --type pointerImpl struct{} +-func foo() (int, error) { return 0, nil } - --// ReadFrom implements io.ReaderFrom. --func (*pointerImpl) ReadFrom(r io.Reader) (n int64, err error) { -- panic("unimplemented") +-func _() { +- i, err := foo() -} +-`, +- }, +- { +- name: "var_single_value", +- before: ` +-package foo - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_renamed_import.go b/gopls/internal/lsp/testdata/stub/stub_renamed_import.go ---- a/gopls/internal/lsp/testdata/stub/stub_renamed_import.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_renamed_import.go 1970-01-01 08:00:00 -@@ -1,11 +0,0 @@ --package stub +-func foo() error { return nil } - --import ( -- "compress/zlib" -- myio "io" --) +-func _() { +- foo().var +-} +-`, +- after: ` +-package foo - --var _ zlib.Resetter = &myIO{} //@suggestedfix("&", "quickfix", "") --var _ myio.Reader +-func foo() error { return nil } - --type myIO struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_renamed_import.go.golden b/gopls/internal/lsp/testdata/stub/stub_renamed_import.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_renamed_import.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_renamed_import.go.golden 1970-01-01 08:00:00 -@@ -1,18 +0,0 @@ ---- suggestedfix_stub_renamed_import_8_23 -- --package stub +-func _() { +- err := foo() +-} +-`, +- }, +- { +- name: "var_same_type", +- before: ` +-package foo - --import ( -- "compress/zlib" -- myio "io" --) +-func foo() (int, int) { return 0, 0 } - --var _ zlib.Resetter = &myIO{} //@suggestedfix("&", "quickfix", "") --var _ myio.Reader +-func _() { +- foo().var +-} +-`, +- after: ` +-package foo - --type myIO struct{} +-func foo() (int, int) { return 0, 0 } - --// Reset implements zlib.Resetter. --func (*myIO) Reset(r myio.Reader, dict []byte) error { -- panic("unimplemented") +-func _() { +- i, i2 := foo() -} +-`, +- }, +- { +- name: "print_scalar", +- before: ` +-package foo - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go b/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go ---- a/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ --package stub +-func _() { +- var foo int +- foo.print +-} +-`, +- after: ` +-package foo - --import ( -- "golang.org/lsptests/stub/other" --) +-import "fmt" - --// This file tests that if an interface --// method references an import from its own package --// that the concrete type does not yet import, and that import happens --// to be renamed, then we prefer the renaming of the interface. --var _ other.Interface = &otherInterfaceImpl{} //@suggestedfix("&otherInterfaceImpl", "quickfix", "") +-func _() { +- var foo int +- fmt.Printf("foo: %v\n", foo) +-} +-`, +- }, +- { +- name: "print_multi", +- before: ` +-package foo - --type otherInterfaceImpl struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go.golden b/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go.golden 1970-01-01 08:00:00 -@@ -1,22 +0,0 @@ ---- suggestedfix_stub_renamed_import_iface_11_25 -- --package stub +-func foo() (int, error) { return 0, nil } - --import ( -- "bytes" -- "context" -- "golang.org/lsptests/stub/other" --) +-func _() { +- foo().print +-} +-`, +- after: ` +-package foo - --// This file tests that if an interface --// method references an import from its own package --// that the concrete type does not yet import, and that import happens --// to be renamed, then we prefer the renaming of the interface. --var _ other.Interface = &otherInterfaceImpl{} //@suggestedfix("&otherInterfaceImpl", "quickfix", "") +-import "fmt" - --type otherInterfaceImpl struct{} +-func foo() (int, error) { return 0, nil } - --// Get implements other.Interface. --func (*otherInterfaceImpl) Get(context.Context) *bytes.Buffer { -- panic("unimplemented") +-func _() { +- fmt.Println(foo()) -} +-`, +- }, +- { +- name: "string split", +- before: ` +-package foo - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_stdlib.go b/gopls/internal/lsp/testdata/stub/stub_stdlib.go ---- a/gopls/internal/lsp/testdata/stub/stub_stdlib.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_stdlib.go 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --package stub -- --import ( -- "io" --) +-func foo() []string { +- x := "test" +- return x.split +-}`, +- after: ` +-package foo - --var _ io.Writer = writer{} //@suggestedfix("w", "quickfix", "") +-import "strings" - --type writer struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_stdlib.go.golden b/gopls/internal/lsp/testdata/stub/stub_stdlib.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_stdlib.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_stdlib.go.golden 1970-01-01 08:00:00 -@@ -1,16 +0,0 @@ ---- suggestedfix_stub_stdlib_7_19 -- --package stub +-func foo() []string { +- x := "test" +- return strings.Split(x, "$0") +-}`, +- }, +- { +- name: "string slice join", +- before: ` +-package foo - --import ( -- "io" --) +-func foo() string { +- x := []string{"a", "test"} +- return x.join +-}`, +- after: ` +-package foo - --var _ io.Writer = writer{} //@suggestedfix("w", "quickfix", "") +-import "strings" - --type writer struct{} +-func foo() string { +- x := []string{"a", "test"} +- return strings.Join(x, "$0") +-}`, +- }, +- { +- name: "if not nil interface", +- before: ` +-package foo - --// Write implements io.Writer. --func (writer) Write(p []byte) (n int, err error) { -- panic("unimplemented") +-func _() { +- var foo error +- foo.ifnotnil -} +-`, +- after: ` +-package foo - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go b/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go ---- a/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go 1970-01-01 08:00:00 -@@ -1,27 +0,0 @@ --package stub -- --// Regression test for Issue #56825: file corrupted by insertion of --// methods after TypeSpec in a parenthesized TypeDecl. -- --import "io" -- --func newReadCloser() io.ReadCloser { -- return rdcloser{} //@suggestedfix("rd", "quickfix", "") +-func _() { +- var foo error +- if foo != nil { +- $0 -} -- --type ( -- A int -- rdcloser struct{} -- B int --) +-} +-`, +- }, +- { +- name: "if not nil pointer", +- before: ` +-package foo - -func _() { -- // Local types can't be stubbed as there's nowhere to put the methods. -- // The suggestedfix assertion can't express this yet. TODO(adonovan): support it. -- type local struct{} -- var _ io.ReadCloser = local{} // want error: `local type "local" cannot be stubbed` --} -- --type ( -- C int --) -diff -urN a/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go.golden b/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go.golden 1970-01-01 08:00:00 -@@ -1,39 +0,0 @@ ---- suggestedfix_stub_typedecl_group_9_9 -- --package stub -- --// Regression test for Issue #56825: file corrupted by insertion of --// methods after TypeSpec in a parenthesized TypeDecl. -- --import "io" -- --func newReadCloser() io.ReadCloser { -- return rdcloser{} //@suggestedfix("rd", "quickfix", "") --} -- --type ( -- A int -- rdcloser struct{} -- B int --) -- --// Close implements io.ReadCloser. --func (rdcloser) Close() error { -- panic("unimplemented") --} -- --// Read implements io.ReadCloser. --func (rdcloser) Read(p []byte) (n int, err error) { -- panic("unimplemented") --} -- --func _() { -- // Local types can't be stubbed as there's nowhere to put the methods. -- // The suggestedfix assertion can't express this yet. TODO(adonovan): support it. -- type local struct{} -- var _ io.ReadCloser = local{} // want error: `local type "local" cannot be stubbed` --} -- --type ( -- C int --) -- -diff -urN a/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go b/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go ---- a/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go 1970-01-01 08:00:00 -@@ -1,11 +0,0 @@ --package suggestedfix -- --import ( -- "log" --) -- --func goodbye() { -- s := "hiiiiiii" -- s = s //@suggestedfix("s = s", "quickfix", "") -- log.Print(s) --} -diff -urN a/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go.golden b/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go.golden ---- a/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go.golden 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ ---- suggestedfix_has_suggested_fix_9_2 -- --package suggestedfix -- --import ( -- "log" --) -- --func goodbye() { -- s := "hiiiiiii" -- //@suggestedfix("s = s", "quickfix", "") -- log.Print(s) --} -- -diff -urN a/gopls/internal/lsp/testdata/summary.txt.golden b/gopls/internal/lsp/testdata/summary.txt.golden ---- a/gopls/internal/lsp/testdata/summary.txt.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/summary.txt.golden 1970-01-01 08:00:00 -@@ -1,18 +0,0 @@ ---- summary -- --CallHierarchyCount = 2 --CompletionsCount = 194 --CompletionSnippetCount = 74 --DeepCompletionsCount = 5 --FuzzyCompletionsCount = 8 --RankedCompletionsCount = 166 --CaseSensitiveCompletionsCount = 4 --SemanticTokenCount = 3 --SuggestedFixCount = 80 --MethodExtractionCount = 8 --InlayHintsCount = 5 --RenamesCount = 48 --PrepareRenamesCount = 7 --SignaturesCount = 32 --LinksCount = 7 --SelectionRangesCount = 3 -- -diff -urN a/gopls/internal/lsp/testdata/typeassert/type_assert.go b/gopls/internal/lsp/testdata/typeassert/type_assert.go ---- a/gopls/internal/lsp/testdata/typeassert/type_assert.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/typeassert/type_assert.go 1970-01-01 08:00:00 -@@ -1,24 +0,0 @@ --package typeassert -- --type abc interface { //@item(abcIntf, "abc", "interface{...}", "interface") -- abc() --} -- --type abcImpl struct{} //@item(abcImpl, "abcImpl", "struct{...}", "struct") --func (abcImpl) abc() -- --type abcPtrImpl struct{} //@item(abcPtrImpl, "abcPtrImpl", "struct{...}", "struct") --func (*abcPtrImpl) abc() -- --type abcNotImpl struct{} //@item(abcNotImpl, "abcNotImpl", "struct{...}", "struct") -- --func _() { -- var a abc -- switch a.(type) { -- case ab: //@complete(":", abcImpl, abcPtrImpl, abcIntf, abcNotImpl) -- case *ab: //@complete(":", abcImpl, abcPtrImpl, abcIntf, abcNotImpl) -- } -- -- a.(ab) //@complete(")", abcImpl, abcPtrImpl, abcIntf, abcNotImpl) -- a.(*ab) //@complete(")", abcImpl, abcPtrImpl, abcIntf, abcNotImpl) --} -diff -urN a/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go b/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go ---- a/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go 1970-01-01 08:00:00 -@@ -1,5 +0,0 @@ --package typeerrors -- --func x() { return nil } //@suggestedfix("nil", "quickfix", "") -- --func y() { return nil, "hello" } //@suggestedfix("nil", "quickfix", "") -diff -urN a/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go.golden b/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go.golden ---- a/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go.golden 1970-01-01 08:00:00 -@@ -1,14 +0,0 @@ ---- suggestedfix_noresultvalues_3_19 -- --package typeerrors -- --func x() { return } //@suggestedfix("nil", "quickfix", "") -- --func y() { return nil, "hello" } //@suggestedfix("nil", "quickfix", "") -- ---- suggestedfix_noresultvalues_5_19 -- --package typeerrors -- --func x() { return nil } //@suggestedfix("nil", "quickfix", "") -- --func y() { return } //@suggestedfix("nil", "quickfix", "") -- -diff -urN a/gopls/internal/lsp/testdata/typemods/type_mods.go b/gopls/internal/lsp/testdata/typemods/type_mods.go ---- a/gopls/internal/lsp/testdata/typemods/type_mods.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/typemods/type_mods.go 1970-01-01 08:00:00 -@@ -1,21 +0,0 @@ --package typemods -- --func fooFunc() func() int { //@item(modFooFunc, "fooFunc", "func() func() int", "func") -- return func() int { -- return 0 -- } --} -- --func fooPtr() *int { //@item(modFooPtr, "fooPtr", "func() *int", "func") -- return nil --} -- --func _() { -- var _ int = foo //@snippet(" //", modFooFunc, "fooFunc()()", "fooFunc()()"),snippet(" //", modFooPtr, "*fooPtr()", "*fooPtr()") --} -- --func _() { -- var m map[int][]chan int //@item(modMapChanPtr, "m", "map[int]chan *int", "var") -- -- var _ int = m //@snippet(" //", modMapChanPtr, "<-m[${1:}][${2:}]", "<-m[${1:}][${2:}]") --} -diff -urN a/gopls/internal/lsp/testdata/typeparams/type_params.go b/gopls/internal/lsp/testdata/typeparams/type_params.go ---- a/gopls/internal/lsp/testdata/typeparams/type_params.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/typeparams/type_params.go 1970-01-01 08:00:00 -@@ -1,61 +0,0 @@ --//go:build go1.18 --// +build go1.18 -- --package typeparams -- --func one[a int | string]() {} --func two[a int | string, b float64 | int]() {} -- --func _() { -- one[]() //@rank("]", string, float64) -- two[]() //@rank("]", int, float64) -- two[int, f]() //@rank("]", float64, float32) --} -- --func slices[a []int | []float64]() {} //@item(tpInts, "[]int", "[]int", "type"),item(tpFloats, "[]float64", "[]float64", "type") -- --func _() { -- slices[]() //@rank("]", tpInts),rank("]", tpFloats) --} -- --type s[a int | string] struct{} -- --func _() { -- s[]{} //@rank("]", int, float64) --} -- --func takesGeneric[a int | string](s[a]) { -- "s[a]{}" //@item(tpInScopeLit, "s[a]{}", "", "var") -- takesGeneric() //@rank(")", tpInScopeLit),snippet(")", tpInScopeLit, "s[a]{\\}", "s[a]{\\}") --} -- --func _() { -- s[int]{} //@item(tpInstLit, "s[int]{}", "", "var") -- takesGeneric[int]() //@rank(")", tpInstLit),snippet(")", tpInstLit, "s[int]{\\}", "s[int]{\\}") -- -- "s[...]{}" //@item(tpUninstLit, "s[...]{}", "", "var") -- takesGeneric() //@rank(")", tpUninstLit),snippet(")", tpUninstLit, "s[${1:}]{\\}", "s[${1:a}]{\\}") --} -- --func returnTP[A int | float64](a A) A { //@item(returnTP, "returnTP", "something", "func") -- return a --} -- --func _() { -- // disabled - see issue #54822 -- var _ int = returnTP // snippet(" //", returnTP, "returnTP[${1:}](${2:})", "returnTP[${1:A int|float64}](${2:a A})") -- -- var aa int //@item(tpInt, "aa", "int", "var") -- var ab float64 //@item(tpFloat, "ab", "float64", "var") -- returnTP[int](a) //@rank(")", tpInt, tpFloat) --} -- --func takesFunc[T any](func(T) T) { -- var _ func(t T) T = f //@snippet(" //", tpLitFunc, "func(t T) T {$0\\}", "func(t T) T {$0\\}") --} -- --func _() { -- _ = "func(...) {}" //@item(tpLitFunc, "func(...) {}", "", "var") -- takesFunc() //@snippet(")", tpLitFunc, "func(${1:}) ${2:} {$0\\}", "func(${1:t} ${2:T}) ${3:T} {$0\\}") -- takesFunc[int]() //@snippet(")", tpLitFunc, "func(i int) int {$0\\}", "func(${1:i} int) int {$0\\}") --} -diff -urN a/gopls/internal/lsp/testdata/types/types.go b/gopls/internal/lsp/testdata/types/types.go ---- a/gopls/internal/lsp/testdata/types/types.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/types/types.go 1970-01-01 08:00:00 -@@ -1,18 +0,0 @@ --package types -- --type CoolAlias = int //@item(CoolAlias, "CoolAlias", "int", "type") -- --type X struct { //@item(X_struct, "X", "struct{...}", "struct") -- x int --} -- --type Y struct { //@item(Y_struct, "Y", "struct{...}", "struct") -- y int --} -- --type Bob interface { //@item(Bob_interface, "Bob", "interface{...}", "interface") -- Bobby() --} -- --func (*X) Bobby() {} --func (*Y) Bobby() {} -diff -urN a/gopls/internal/lsp/testdata/unresolved/unresolved.go.in b/gopls/internal/lsp/testdata/unresolved/unresolved.go.in ---- a/gopls/internal/lsp/testdata/unresolved/unresolved.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/unresolved/unresolved.go.in 1970-01-01 08:00:00 -@@ -1,6 +0,0 @@ --package unresolved -- --func foo(interface{}) { -- // don't crash on fake "resolved" type -- foo(func(i, j f //@complete(" //") --} -diff -urN a/gopls/internal/lsp/testdata/unsafe/unsafe.go b/gopls/internal/lsp/testdata/unsafe/unsafe.go ---- a/gopls/internal/lsp/testdata/unsafe/unsafe.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/unsafe/unsafe.go 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ --package unsafe -- --import ( -- "unsafe" --) -- --// Pre-set this marker, as we don't have a "source" for it in this package. --/* unsafe.Sizeof */ //@item(Sizeof, "Sizeof", "invalid type", "text") -- --func _() { -- x := struct{}{} -- _ = unsafe.Sizeof(x) //@complete("z", Sizeof) --} -diff -urN a/gopls/internal/lsp/testdata/variadic/variadic.go.in b/gopls/internal/lsp/testdata/variadic/variadic.go.in ---- a/gopls/internal/lsp/testdata/variadic/variadic.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/variadic/variadic.go.in 1970-01-01 08:00:00 -@@ -1,38 +0,0 @@ --package variadic -- --func foo(i int, strs ...string) {} -- --func bar() []string { //@item(vFunc, "bar", "func() []string", "func") -- return nil +- var foo *int +- foo.ifnotnil -} +-`, +- after: ` +-package foo - -func _() { -- var ( -- i int //@item(vInt, "i", "int", "var") -- s string //@item(vStr, "s", "string", "var") -- ss []string //@item(vStrSlice, "ss", "[]string", "var") -- v interface{} //@item(vIntf, "v", "interface{}", "var") -- ) -- -- foo() //@rank(")", vInt, vStr),rank(")", vInt, vStrSlice) -- foo(123, ) //@rank(")", vStr, vInt),rank(")", vStrSlice, vInt) -- foo(123, "", ) //@rank(")", vStr, vInt),rank(")", vStr, vStrSlice) -- foo(123, s, "") //@rank(", \"", vStr, vStrSlice) -- -- // snippet will add the "..." for you -- foo(123, ) //@snippet(")", vStrSlice, "ss...", "ss..."),snippet(")", vFunc, "bar()...", "bar()..."),snippet(")", vStr, "s", "s") -- -- // don't add "..." for interface{} -- foo(123, ) //@snippet(")", vIntf, "v", "v") +- var foo *int +- if foo != nil { +- $0 -} -- --func qux(...func()) {} --func f() {} //@item(vVarArg, "f", "func()", "func") -- --func _() { -- qux(f) //@snippet(")", vVarArg, "f", "f") -} +-`, +- }, +- { +- name: "if not nil slice", +- before: ` +-package foo - -func _() { -- foo(0, []string{}...) //@complete(")") --} -diff -urN a/gopls/internal/lsp/testdata/variadic/variadic_intf.go b/gopls/internal/lsp/testdata/variadic/variadic_intf.go ---- a/gopls/internal/lsp/testdata/variadic/variadic_intf.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/variadic/variadic_intf.go 1970-01-01 08:00:00 -@@ -1,21 +0,0 @@ --package variadic -- --type baz interface { -- baz() +- var foo []int +- foo.ifnotnil -} -- --func wantsBaz(...baz) {} -- --type bazImpl int -- --func (bazImpl) baz() {} +-`, +- after: ` +-package foo - -func _() { -- var ( -- impls []bazImpl //@item(vImplSlice, "impls", "[]bazImpl", "var") -- impl bazImpl //@item(vImpl, "impl", "bazImpl", "var") -- bazes []baz //@item(vIntfSlice, "bazes", "[]baz", "var") -- ) -- -- wantsBaz() //@rank(")", vImpl, vImplSlice),rank(")", vIntfSlice, vImplSlice) --} -diff -urN a/gopls/internal/lsp/tests/README.md b/gopls/internal/lsp/tests/README.md ---- a/gopls/internal/lsp/tests/README.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/README.md 1970-01-01 08:00:00 -@@ -1,66 +0,0 @@ --# Testing -- --LSP has "marker tests" defined in `internal/lsp/testdata`, as well as --traditional tests. -- --## Marker tests -- --Marker tests have a standard input file, like --`internal/lsp/testdata/foo/bar.go`, and some may have a corresponding golden --file, like `internal/lsp/testdata/foo/bar.go.golden`. The former is the "input" --and the latter is the expected output. -- --Each input file contains annotations like --`//@suggestedfix("}", "refactor.rewrite", "Fill anonymous struct")`. These annotations are interpreted by --test runners to perform certain actions. The expected output after those actions --is encoded in the golden file. -- --When tests are run, each annotation results in a new subtest, which is encoded --in the golden file with a heading like, -- --```bash ---- suggestedfix_bar_11_21 -- --// expected contents go here ---- suggestedfix_bar_13_20 -- --// expected contents go here --``` -- --The format of these headings vary: they are defined by the --[`Golden`](https://pkg.go.dev/golang.org/x/tools/gopls/internal/lsp/tests#Data.Golden) --function for each annotation. In the case above, the format is: annotation --name, file name, annotation line location, annotation character location. -- --So, if `internal/lsp/testdata/foo/bar.go` has three `suggestedfix` annotations, --the golden file should have three headers with `suggestedfix_bar_xx_yy` --headings. -- --To see a list of all available annotations, see the exported "expectations" in --[tests.go](https://github.com/golang/tools/blob/299f270db45902e93469b1152fafed034bb3f033/internal/lsp/tests/tests.go#L418-L447). -- --To run marker tests, -- --```bash --cd /path/to/tools -- --# The marker tests are located in "internal/lsp", "internal/lsp/cmd, and --# "internal/lsp/source". --go test ./internal/lsp/... --``` -- --There are quite a lot of marker tests, so to run one individually, pass the test --path and heading into a -run argument: -- --```bash --cd /path/to/tools --go test ./internal/lsp/... -v -run TestLSP/Modules/SuggestedFix/bar_11_21 --``` -- --## Resetting marker tests -- --Sometimes, a change is made to lsp that requires a change to multiple golden --files. When this happens, you can run, -- --```bash --cd /path/to/tools --./internal/lsp/reset_golden.sh --``` -diff -urN a/gopls/internal/lsp/tests/compare/text.go b/gopls/internal/lsp/tests/compare/text.go ---- a/gopls/internal/lsp/tests/compare/text.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/compare/text.go 1970-01-01 08:00:00 -@@ -1,49 +0,0 @@ --// Copyright 2022 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 compare -- --import ( -- "bytes" -- -- "golang.org/x/tools/internal/diff" --) -- --// Text returns a formatted unified diff of the edits to go from want to --// got, returning "" if and only if want == got. --// --// This function is intended for use in testing, and panics if any error occurs --// while computing the diff. It is not sufficiently tested for production use. --func Text(want, got string) string { -- return NamedText("want", "got", want, got) --} -- --// NamedText is like text, but allows passing custom names of the 'want' and --// 'got' content. --func NamedText(wantName, gotName, want, got string) string { -- if want == got { -- return "" -- } -- -- // Add newlines to avoid verbose newline messages ("No newline at end of file"). -- unified := diff.Unified(wantName, gotName, want+"\n", got+"\n") -- -- // Defensively assert that we get an actual diff, so that we guarantee the -- // invariant that we return "" if and only if want == got. -- // -- // This is probably unnecessary, but convenient. -- if unified == "" { -- panic("empty diff for non-identical input") -- } -- -- return unified --} -- --// Bytes is like Text but using byte slices. --func Bytes(want, got []byte) string { -- if bytes.Equal(want, got) { -- return "" // common case -- } -- return Text(string(want), string(got)) --} -diff -urN a/gopls/internal/lsp/tests/compare/text_test.go b/gopls/internal/lsp/tests/compare/text_test.go ---- a/gopls/internal/lsp/tests/compare/text_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/compare/text_test.go 1970-01-01 08:00:00 -@@ -1,28 +0,0 @@ --// Copyright 2022 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 compare_test -- --import ( -- "testing" -- -- "golang.org/x/tools/gopls/internal/lsp/tests/compare" --) -- --func TestText(t *testing.T) { -- tests := []struct { -- got, want, wantDiff string -- }{ -- {"", "", ""}, -- {"equal", "equal", ""}, -- {"a", "b", "--- want\n+++ got\n@@ -1 +1 @@\n-b\n+a\n"}, -- {"a\nd\nc\n", "a\nb\nc\n", "--- want\n+++ got\n@@ -1,4 +1,4 @@\n a\n-b\n+d\n c\n \n"}, -- } -- -- for _, test := range tests { -- if gotDiff := compare.Text(test.want, test.got); gotDiff != test.wantDiff { -- t.Errorf("compare.Text(%q, %q) =\n%q, want\n%q", test.want, test.got, gotDiff, test.wantDiff) -- } -- } --} -diff -urN a/gopls/internal/lsp/tests/markdown_go118.go b/gopls/internal/lsp/tests/markdown_go118.go ---- a/gopls/internal/lsp/tests/markdown_go118.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/markdown_go118.go 1970-01-01 08:00:00 -@@ -1,69 +0,0 @@ --// Copyright 2022 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. -- --//go:build !go1.19 --// +build !go1.19 -- --package tests -- --import ( -- "regexp" -- "strings" -- -- "golang.org/x/tools/gopls/internal/lsp/tests/compare" --) -- --// DiffMarkdown compares two markdown strings produced by parsing go doc --// comments. --// --// For go1.19 and later, markdown conversion is done using go/doc/comment. --// Compared to the newer version, the older version has extra escapes, and --// treats code blocks slightly differently. --func DiffMarkdown(want, got string) string { -- want = normalizeMarkdown(want) -- got = normalizeMarkdown(got) -- return compare.Text(want, got) --} -- --// normalizeMarkdown normalizes whitespace and escaping of the input string, to --// eliminate differences between the Go 1.18 and Go 1.19 generated markdown for --// doc comments. Note that it does not normalize to either the 1.18 or 1.19 --// formatting: it simplifies both so that they may be compared. --// --// This function may need to be adjusted as we encounter more differences in --// the generated text. --// --// TODO(rfindley): this function doesn't correctly handle the case of --// multi-line docstrings. --func normalizeMarkdown(input string) string { -- input = strings.TrimSpace(input) -- -- // For simplicity, eliminate blank lines. -- input = regexp.MustCompile("\n+").ReplaceAllString(input, "\n") -- -- // Replace common escaped characters with their unescaped version. -- // -- // This list may not be exhaustive: it was just sufficient to make tests -- // pass. -- input = strings.NewReplacer( -- `\\`, ``, -- `\@`, `@`, -- `\(`, `(`, -- `\)`, `)`, -- `\{`, `{`, -- `\}`, `}`, -- `\"`, `"`, -- `\.`, `.`, -- `\-`, `-`, -- `\'`, `'`, -- `\+`, `+`, -- `\~`, `~`, -- `\=`, `=`, -- `\:`, `:`, -- `\?`, `?`, -- `\n\n\n`, `\n\n`, // Note that these are *escaped* newlines. -- ).Replace(input) -- -- return input --} -diff -urN a/gopls/internal/lsp/tests/markdown_go119.go b/gopls/internal/lsp/tests/markdown_go119.go ---- a/gopls/internal/lsp/tests/markdown_go119.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/markdown_go119.go 1970-01-01 08:00:00 -@@ -1,22 +0,0 @@ --// Copyright 2022 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. -- --//go:build go1.19 --// +build go1.19 -- --package tests -- --import ( -- "golang.org/x/tools/gopls/internal/lsp/tests/compare" --) -- --// DiffMarkdown compares two markdown strings produced by parsing go doc --// comments. --// --// For go1.19 and later, markdown conversion is done using go/doc/comment. --// Compared to the newer version, the older version has extra escapes, and --// treats code blocks slightly differently. --func DiffMarkdown(want, got string) string { -- return compare.Text(want, got) --} -diff -urN a/gopls/internal/lsp/tests/tests.go b/gopls/internal/lsp/tests/tests.go ---- a/gopls/internal/lsp/tests/tests.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/tests.go 1970-01-01 08:00:00 -@@ -1,956 +0,0 @@ --// 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 tests exports functionality to be used across a variety of gopls tests. --package tests -- --import ( -- "bytes" -- "context" -- "flag" -- "fmt" -- "go/ast" -- "go/token" -- "io" -- "os" -- "path/filepath" -- "regexp" -- "sort" -- "strconv" -- "strings" -- "sync" -- "testing" -- "time" -- -- "golang.org/x/tools/go/expect" -- "golang.org/x/tools/go/packages" -- "golang.org/x/tools/go/packages/packagestest" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/safetoken" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/lsp/source/completion" -- "golang.org/x/tools/gopls/internal/lsp/tests/compare" -- "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/testenv" -- "golang.org/x/tools/internal/typeparams" -- "golang.org/x/tools/txtar" --) -- --const ( -- overlayFileSuffix = ".overlay" -- goldenFileSuffix = ".golden" -- inFileSuffix = ".in" -- summaryFile = "summary.txt" -- -- // The module path containing the testdata packages. -- // -- // Warning: the length of this module path matters, as we have bumped up -- // against command-line limitations on windows (golang/go#54800). -- testModule = "golang.org/lsptests" --) -- --var UpdateGolden = flag.Bool("golden", false, "Update golden files") -- --// These type names apparently avoid the need to repeat the --// type in the field name and the make() expression. --type CallHierarchy = map[span.Span]*CallHierarchyResult --type CompletionItems = map[token.Pos]*completion.CompletionItem --type Completions = map[span.Span][]Completion --type CompletionSnippets = map[span.Span][]CompletionSnippet --type DeepCompletions = map[span.Span][]Completion --type FuzzyCompletions = map[span.Span][]Completion --type CaseSensitiveCompletions = map[span.Span][]Completion --type RankCompletions = map[span.Span][]Completion --type SemanticTokens = []span.Span --type SuggestedFixes = map[span.Span][]SuggestedFix --type MethodExtractions = map[span.Span]span.Span --type Renames = map[span.Span]string --type PrepareRenames = map[span.Span]*source.PrepareItem --type InlayHints = []span.Span --type Signatures = map[span.Span]*protocol.SignatureHelp --type Links = map[span.URI][]Link --type AddImport = map[span.URI]string --type SelectionRanges = []span.Span -- --type Data struct { -- Config packages.Config -- Exported *packagestest.Exported -- CallHierarchy CallHierarchy -- CompletionItems CompletionItems -- Completions Completions -- CompletionSnippets CompletionSnippets -- DeepCompletions DeepCompletions -- FuzzyCompletions FuzzyCompletions -- CaseSensitiveCompletions CaseSensitiveCompletions -- RankCompletions RankCompletions -- SemanticTokens SemanticTokens -- SuggestedFixes SuggestedFixes -- MethodExtractions MethodExtractions -- Renames Renames -- InlayHints InlayHints -- PrepareRenames PrepareRenames -- Signatures Signatures -- Links Links -- AddImport AddImport -- SelectionRanges SelectionRanges -- -- fragments map[string]string -- dir string -- golden map[string]*Golden -- mode string -- -- ModfileFlagAvailable bool -- -- mappersMu sync.Mutex -- mappers map[span.URI]*protocol.Mapper --} -- --// The Tests interface abstracts the LSP-based implementation of the marker --// test operators appearing in files beneath ../testdata/. --// --// TODO(adonovan): reduce duplication; see https://github.com/golang/go/issues/54845. --// There is only one implementation (*runner in ../lsp_test.go), so --// we can abolish the interface now. --type Tests interface { -- CallHierarchy(*testing.T, span.Span, *CallHierarchyResult) -- Completion(*testing.T, span.Span, Completion, CompletionItems) -- CompletionSnippet(*testing.T, span.Span, CompletionSnippet, bool, CompletionItems) -- DeepCompletion(*testing.T, span.Span, Completion, CompletionItems) -- FuzzyCompletion(*testing.T, span.Span, Completion, CompletionItems) -- CaseSensitiveCompletion(*testing.T, span.Span, Completion, CompletionItems) -- RankCompletion(*testing.T, span.Span, Completion, CompletionItems) -- SemanticTokens(*testing.T, span.Span) -- SuggestedFix(*testing.T, span.Span, []SuggestedFix, int) -- MethodExtraction(*testing.T, span.Span, span.Span) -- InlayHints(*testing.T, span.Span) -- Rename(*testing.T, span.Span, string) -- PrepareRename(*testing.T, span.Span, *source.PrepareItem) -- SignatureHelp(*testing.T, span.Span, *protocol.SignatureHelp) -- Link(*testing.T, span.URI, []Link) -- AddImport(*testing.T, span.URI, string) -- SelectionRanges(*testing.T, span.Span) --} -- --type CompletionTestType int -- --const ( -- // Default runs the standard completion tests. -- CompletionDefault = CompletionTestType(iota) -- -- // Deep tests deep completion. -- CompletionDeep -- -- // Fuzzy tests deep completion and fuzzy matching. -- CompletionFuzzy -- -- // CaseSensitive tests case sensitive completion. -- CompletionCaseSensitive -- -- // CompletionRank candidates in test must be valid and in the right relative order. -- CompletionRank --) -- --type Completion struct { -- CompletionItems []token.Pos --} -- --type CompletionSnippet struct { -- CompletionItem token.Pos -- PlainSnippet string -- PlaceholderSnippet string --} -- --type CallHierarchyResult struct { -- IncomingCalls, OutgoingCalls []protocol.CallHierarchyItem --} -- --type Link struct { -- Src span.Span -- Target string -- NotePosition token.Position --} -- --type SuggestedFix struct { -- ActionKind, Title string --} -- --type Golden struct { -- Filename string -- Archive *txtar.Archive -- Modified bool +- var foo []int +- if foo != nil { +- $0 -} -- --func Context(t testing.TB) context.Context { -- return context.Background() -} -- --func DefaultOptions(o *source.Options) { -- o.SupportedCodeActions = map[source.FileKind]map[protocol.CodeActionKind]bool{ -- source.Go: { -- protocol.SourceOrganizeImports: true, -- protocol.QuickFix: true, -- protocol.RefactorRewrite: true, -- protocol.RefactorInline: true, -- protocol.RefactorExtract: true, -- protocol.SourceFixAll: true, -- }, -- source.Mod: { -- protocol.SourceOrganizeImports: true, +-`, - }, -- source.Sum: {}, -- source.Work: {}, -- source.Tmpl: {}, -- } -- o.InsertTextFormat = protocol.SnippetTextFormat -- o.CompletionBudget = time.Minute -- o.HierarchicalDocumentSymbolSupport = true -- o.SemanticTokens = true -- o.InternalOptions.NewDiff = "new" -- -- // Enable all inlay hints. -- if o.Hints == nil { -- o.Hints = make(map[string]bool) -- } -- for name := range source.AllInlayHints { -- o.Hints[name] = true -- } --} -- --func RunTests(t *testing.T, dataDir string, includeMultiModule bool, f func(*testing.T, *Data)) { -- t.Helper() -- modes := []string{"Modules", "GOPATH"} -- if includeMultiModule { -- modes = append(modes, "MultiModule") -- } -- for _, mode := range modes { -- t.Run(mode, func(t *testing.T) { -- datum := load(t, mode, dataDir) -- t.Helper() -- f(t, datum) -- }) -- } --} -- --func load(t testing.TB, mode string, dir string) *Data { -- datum := &Data{ -- CallHierarchy: make(CallHierarchy), -- CompletionItems: make(CompletionItems), -- Completions: make(Completions), -- CompletionSnippets: make(CompletionSnippets), -- DeepCompletions: make(DeepCompletions), -- FuzzyCompletions: make(FuzzyCompletions), -- RankCompletions: make(RankCompletions), -- CaseSensitiveCompletions: make(CaseSensitiveCompletions), -- Renames: make(Renames), -- PrepareRenames: make(PrepareRenames), -- SuggestedFixes: make(SuggestedFixes), -- MethodExtractions: make(MethodExtractions), -- Signatures: make(Signatures), -- Links: make(Links), -- AddImport: make(AddImport), -- -- dir: dir, -- fragments: map[string]string{}, -- golden: map[string]*Golden{}, -- mode: mode, -- mappers: map[span.URI]*protocol.Mapper{}, -- } -- -- if !*UpdateGolden { -- summary := filepath.Join(filepath.FromSlash(dir), summaryFile+goldenFileSuffix) -- if _, err := os.Stat(summary); os.IsNotExist(err) { -- t.Fatalf("could not find golden file summary.txt in %#v", dir) -- } -- archive, err := txtar.ParseFile(summary) -- if err != nil { -- t.Fatalf("could not read golden file %v/%v: %v", dir, summary, err) -- } -- datum.golden[summaryFile] = &Golden{ -- Filename: summary, -- Archive: archive, -- } -- } -- -- files := packagestest.MustCopyFileTree(dir) -- // Prune test cases that exercise generics. -- if !typeparams.Enabled { -- for name := range files { -- if strings.Contains(name, "_generics") { -- delete(files, name) -- } -- } -- } -- overlays := map[string][]byte{} -- for fragment, operation := range files { -- if trimmed := strings.TrimSuffix(fragment, goldenFileSuffix); trimmed != fragment { -- delete(files, fragment) -- goldFile := filepath.Join(dir, fragment) -- archive, err := txtar.ParseFile(goldFile) -- if err != nil { -- t.Fatalf("could not read golden file %v: %v", fragment, err) -- } -- datum.golden[trimmed] = &Golden{ -- Filename: goldFile, -- Archive: archive, -- } -- } else if trimmed := strings.TrimSuffix(fragment, inFileSuffix); trimmed != fragment { -- delete(files, fragment) -- files[trimmed] = operation -- } else if index := strings.Index(fragment, overlayFileSuffix); index >= 0 { -- delete(files, fragment) -- partial := fragment[:index] + fragment[index+len(overlayFileSuffix):] -- contents, err := os.ReadFile(filepath.Join(dir, fragment)) -- if err != nil { -- t.Fatal(err) -- } -- overlays[partial] = contents -- } -- } -- -- modules := []packagestest.Module{ - { -- Name: testModule, -- Files: files, -- Overlay: overlays, -- }, -- } -- switch mode { -- case "Modules": -- datum.Exported = packagestest.Export(t, packagestest.Modules, modules) -- case "GOPATH": -- datum.Exported = packagestest.Export(t, packagestest.GOPATH, modules) -- case "MultiModule": -- files := map[string]interface{}{} -- for k, v := range modules[0].Files { -- files[filepath.Join("testmodule", k)] = v -- } -- modules[0].Files = files -- -- overlays := map[string][]byte{} -- for k, v := range modules[0].Overlay { -- overlays[filepath.Join("testmodule", k)] = v -- } -- modules[0].Overlay = overlays -- -- golden := map[string]*Golden{} -- for k, v := range datum.golden { -- if k == summaryFile { -- golden[k] = v -- } else { -- golden[filepath.Join("testmodule", k)] = v -- } -- } -- datum.golden = golden -- -- datum.Exported = packagestest.Export(t, packagestest.Modules, modules) -- default: -- panic("unknown mode " + mode) -- } -- -- for _, m := range modules { -- for fragment := range m.Files { -- filename := datum.Exported.File(m.Name, fragment) -- datum.fragments[filename] = fragment -- } -- } -- -- // Turn off go/packages debug logging. -- datum.Exported.Config.Logf = nil -- datum.Config.Logf = nil -- -- // Merge the exported.Config with the view.Config. -- datum.Config = *datum.Exported.Config -- datum.Config.Fset = token.NewFileSet() -- datum.Config.Context = Context(nil) -- datum.Config.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) { -- panic("ParseFile should not be called") -- } -- -- // Do a first pass to collect special markers for completion and workspace symbols. -- if err := datum.Exported.Expect(map[string]interface{}{ -- "item": func(name string, r packagestest.Range, _ []string) { -- datum.Exported.Mark(name, r) -- }, -- "symbol": func(name string, r packagestest.Range, _ []string) { -- datum.Exported.Mark(name, r) -- }, -- }); err != nil { -- t.Fatal(err) -- } -- -- // Collect any data that needs to be used by subsequent tests. -- if err := datum.Exported.Expect(map[string]interface{}{ -- "item": datum.collectCompletionItems, -- "complete": datum.collectCompletions(CompletionDefault), -- "deep": datum.collectCompletions(CompletionDeep), -- "fuzzy": datum.collectCompletions(CompletionFuzzy), -- "casesensitive": datum.collectCompletions(CompletionCaseSensitive), -- "rank": datum.collectCompletions(CompletionRank), -- "snippet": datum.collectCompletionSnippets, -- "semantic": datum.collectSemanticTokens, -- "inlayHint": datum.collectInlayHints, -- "rename": datum.collectRenames, -- "prepare": datum.collectPrepareRenames, -- "signature": datum.collectSignatures, -- "link": datum.collectLinks, -- "suggestedfix": datum.collectSuggestedFixes, -- "extractmethod": datum.collectMethodExtractions, -- "incomingcalls": datum.collectIncomingCalls, -- "outgoingcalls": datum.collectOutgoingCalls, -- "addimport": datum.collectAddImports, -- "selectionrange": datum.collectSelectionRanges, -- }); err != nil { -- t.Fatal(err) -- } -- -- if mode == "MultiModule" { -- if err := moveFile(filepath.Join(datum.Config.Dir, "go.mod"), filepath.Join(datum.Config.Dir, "testmodule/go.mod")); err != nil { -- t.Fatal(err) -- } -- } -- -- return datum --} -- --// moveFile moves the file at oldpath to newpath, by renaming if possible --// or copying otherwise. --func moveFile(oldpath, newpath string) (err error) { -- renameErr := os.Rename(oldpath, newpath) -- if renameErr == nil { -- return nil -- } -- -- src, err := os.Open(oldpath) -- if err != nil { -- return err -- } -- defer func() { -- src.Close() -- if err == nil { -- err = os.Remove(oldpath) -- } -- }() -- -- perm := os.ModePerm -- fi, err := src.Stat() -- if err == nil { -- perm = fi.Mode().Perm() -- } -- -- dst, err := os.OpenFile(newpath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm) -- if err != nil { -- return err -- } +- name: "if not nil map", +- before: ` +-package foo - -- _, err = io.Copy(dst, src) -- if closeErr := dst.Close(); err == nil { -- err = closeErr -- } -- return err --} -- --func Run(t *testing.T, tests Tests, data *Data) { -- t.Helper() -- checkData(t, data) -- -- eachCompletion := func(t *testing.T, cases map[span.Span][]Completion, test func(*testing.T, span.Span, Completion, CompletionItems)) { -- t.Helper() -- -- for src, exp := range cases { -- for i, e := range exp { -- t.Run(SpanName(src)+"_"+strconv.Itoa(i), func(t *testing.T) { -- t.Helper() -- if strings.Contains(t.Name(), "cgo") { -- testenv.NeedsTool(t, "cgo") -- } -- test(t, src, e, data.CompletionItems) -- }) -- } -- -- } -- } -- -- t.Run("CallHierarchy", func(t *testing.T) { -- t.Helper() -- for spn, callHierarchyResult := range data.CallHierarchy { -- t.Run(SpanName(spn), func(t *testing.T) { -- t.Helper() -- tests.CallHierarchy(t, spn, callHierarchyResult) -- }) -- } -- }) -- -- t.Run("Completion", func(t *testing.T) { -- t.Helper() -- eachCompletion(t, data.Completions, tests.Completion) -- }) -- -- t.Run("CompletionSnippets", func(t *testing.T) { -- t.Helper() -- for _, placeholders := range []bool{true, false} { -- for src, expecteds := range data.CompletionSnippets { -- for i, expected := range expecteds { -- name := SpanName(src) + "_" + strconv.Itoa(i+1) -- if placeholders { -- name += "_placeholders" -- } -- -- t.Run(name, func(t *testing.T) { -- t.Helper() -- tests.CompletionSnippet(t, src, expected, placeholders, data.CompletionItems) -- }) -- } -- } -- } -- }) -- -- t.Run("DeepCompletion", func(t *testing.T) { -- t.Helper() -- eachCompletion(t, data.DeepCompletions, tests.DeepCompletion) -- }) -- -- t.Run("FuzzyCompletion", func(t *testing.T) { -- t.Helper() -- eachCompletion(t, data.FuzzyCompletions, tests.FuzzyCompletion) -- }) -- -- t.Run("CaseSensitiveCompletion", func(t *testing.T) { -- t.Helper() -- eachCompletion(t, data.CaseSensitiveCompletions, tests.CaseSensitiveCompletion) -- }) -- -- t.Run("RankCompletions", func(t *testing.T) { -- t.Helper() -- eachCompletion(t, data.RankCompletions, tests.RankCompletion) -- }) -- -- t.Run("SemanticTokens", func(t *testing.T) { -- t.Helper() -- for _, spn := range data.SemanticTokens { -- t.Run(uriName(spn.URI()), func(t *testing.T) { -- t.Helper() -- tests.SemanticTokens(t, spn) -- }) -- } -- }) -- -- t.Run("SuggestedFix", func(t *testing.T) { -- t.Helper() -- for spn, actionKinds := range data.SuggestedFixes { -- // Check if we should skip this spn if the -modfile flag is not available. -- if shouldSkip(data, spn.URI()) { -- continue -- } -- t.Run(SpanName(spn), func(t *testing.T) { -- t.Helper() -- tests.SuggestedFix(t, spn, actionKinds, 1) -- }) -- } -- }) -- -- t.Run("MethodExtraction", func(t *testing.T) { -- t.Helper() -- for start, end := range data.MethodExtractions { -- // Check if we should skip this spn if the -modfile flag is not available. -- if shouldSkip(data, start.URI()) { -- continue -- } -- t.Run(SpanName(start), func(t *testing.T) { -- t.Helper() -- tests.MethodExtraction(t, start, end) -- }) -- } -- }) -- -- t.Run("InlayHints", func(t *testing.T) { -- t.Helper() -- for _, src := range data.InlayHints { -- t.Run(SpanName(src), func(t *testing.T) { -- t.Helper() -- tests.InlayHints(t, src) -- }) -- } -- }) -- -- t.Run("Renames", func(t *testing.T) { -- t.Helper() -- for spn, newText := range data.Renames { -- t.Run(uriName(spn.URI())+"_"+newText, func(t *testing.T) { -- t.Helper() -- tests.Rename(t, spn, newText) -- }) -- } -- }) -- -- t.Run("PrepareRenames", func(t *testing.T) { -- t.Helper() -- for src, want := range data.PrepareRenames { -- t.Run(SpanName(src), func(t *testing.T) { -- t.Helper() -- tests.PrepareRename(t, src, want) -- }) -- } -- }) -- -- t.Run("SignatureHelp", func(t *testing.T) { -- t.Helper() -- for spn, expectedSignature := range data.Signatures { -- t.Run(SpanName(spn), func(t *testing.T) { -- t.Helper() -- tests.SignatureHelp(t, spn, expectedSignature) -- }) -- } -- }) -- -- t.Run("Link", func(t *testing.T) { -- t.Helper() -- for uri, wantLinks := range data.Links { -- // If we are testing GOPATH, then we do not want links with the versions -- // attached (pkg.go.dev/repoa/moda@v1.1.0/pkg), unless the file is a -- // go.mod, then we can skip it altogether. -- if data.Exported.Exporter == packagestest.GOPATH { -- if strings.HasSuffix(uri.Filename(), ".mod") { -- continue -- } -- re := regexp.MustCompile(`@v\d+\.\d+\.[\w-]+`) -- for i, link := range wantLinks { -- wantLinks[i].Target = re.ReplaceAllString(link.Target, "") -- } -- } -- t.Run(uriName(uri), func(t *testing.T) { -- t.Helper() -- tests.Link(t, uri, wantLinks) -- }) -- } -- }) -- -- t.Run("AddImport", func(t *testing.T) { -- t.Helper() -- for uri, exp := range data.AddImport { -- t.Run(uriName(uri), func(t *testing.T) { -- tests.AddImport(t, uri, exp) -- }) -- } -- }) -- -- t.Run("SelectionRanges", func(t *testing.T) { -- t.Helper() -- for _, span := range data.SelectionRanges { -- t.Run(SpanName(span), func(t *testing.T) { -- tests.SelectionRanges(t, span) -- }) -- } -- }) -- -- if *UpdateGolden { -- for _, golden := range data.golden { -- if !golden.Modified { -- continue -- } -- sort.Slice(golden.Archive.Files, func(i, j int) bool { -- return golden.Archive.Files[i].Name < golden.Archive.Files[j].Name -- }) -- if err := os.WriteFile(golden.Filename, txtar.Format(golden.Archive), 0666); err != nil { -- t.Fatal(err) -- } -- } -- } --} -- --func checkData(t *testing.T, data *Data) { -- buf := &bytes.Buffer{} -- linksCount := 0 -- for _, want := range data.Links { -- linksCount += len(want) -- } -- -- snippetCount := 0 -- for _, want := range data.CompletionSnippets { -- snippetCount += len(want) -- } -- -- countCompletions := func(c map[span.Span][]Completion) (count int) { -- for _, want := range c { -- count += len(want) -- } -- return count -- } -- -- fmt.Fprintf(buf, "CallHierarchyCount = %v\n", len(data.CallHierarchy)) -- fmt.Fprintf(buf, "CompletionsCount = %v\n", countCompletions(data.Completions)) -- fmt.Fprintf(buf, "CompletionSnippetCount = %v\n", snippetCount) -- fmt.Fprintf(buf, "DeepCompletionsCount = %v\n", countCompletions(data.DeepCompletions)) -- fmt.Fprintf(buf, "FuzzyCompletionsCount = %v\n", countCompletions(data.FuzzyCompletions)) -- fmt.Fprintf(buf, "RankedCompletionsCount = %v\n", countCompletions(data.RankCompletions)) -- fmt.Fprintf(buf, "CaseSensitiveCompletionsCount = %v\n", countCompletions(data.CaseSensitiveCompletions)) -- fmt.Fprintf(buf, "SemanticTokenCount = %v\n", len(data.SemanticTokens)) -- fmt.Fprintf(buf, "SuggestedFixCount = %v\n", len(data.SuggestedFixes)) -- fmt.Fprintf(buf, "MethodExtractionCount = %v\n", len(data.MethodExtractions)) -- fmt.Fprintf(buf, "InlayHintsCount = %v\n", len(data.InlayHints)) -- fmt.Fprintf(buf, "RenamesCount = %v\n", len(data.Renames)) -- fmt.Fprintf(buf, "PrepareRenamesCount = %v\n", len(data.PrepareRenames)) -- fmt.Fprintf(buf, "SignaturesCount = %v\n", len(data.Signatures)) -- fmt.Fprintf(buf, "LinksCount = %v\n", linksCount) -- fmt.Fprintf(buf, "SelectionRangesCount = %v\n", len(data.SelectionRanges)) -- -- want := string(data.Golden(t, "summary", summaryFile, func() ([]byte, error) { -- return buf.Bytes(), nil -- })) -- got := buf.String() -- if want != got { -- // These counters change when assertions are added or removed. -- // They act as an independent safety net to ensure that the -- // tests didn't spuriously pass because they did no work. -- t.Errorf("test summary does not match:\n%s\n(Run with -golden to update golden file; also, there may be one per Go version.)", compare.Text(want, got)) -- } --} -- --func (data *Data) Mapper(uri span.URI) (*protocol.Mapper, error) { -- data.mappersMu.Lock() -- defer data.mappersMu.Unlock() -- -- if _, ok := data.mappers[uri]; !ok { -- content, err := data.Exported.FileContents(uri.Filename()) -- if err != nil { -- return nil, err -- } -- data.mappers[uri] = protocol.NewMapper(uri, content) -- } -- return data.mappers[uri], nil --} -- --func (data *Data) Golden(t *testing.T, tag, target string, update func() ([]byte, error)) []byte { -- t.Helper() -- fragment, found := data.fragments[target] -- if !found { -- if filepath.IsAbs(target) { -- t.Fatalf("invalid golden file fragment %v", target) -- } -- fragment = target -- } -- golden := data.golden[fragment] -- if golden == nil { -- if !*UpdateGolden { -- t.Fatalf("could not find golden file %v: %v", fragment, tag) -- } -- golden = &Golden{ -- Filename: filepath.Join(data.dir, fragment+goldenFileSuffix), -- Archive: &txtar.Archive{}, -- Modified: true, -- } -- data.golden[fragment] = golden -- } -- var file *txtar.File -- for i := range golden.Archive.Files { -- f := &golden.Archive.Files[i] -- if f.Name == tag { -- file = f -- break -- } -- } -- if *UpdateGolden { -- if file == nil { -- golden.Archive.Files = append(golden.Archive.Files, txtar.File{ -- Name: tag, -- }) -- file = &golden.Archive.Files[len(golden.Archive.Files)-1] -- } -- contents, err := update() -- if err != nil { -- t.Fatalf("could not update golden file %v: %v", fragment, err) -- } -- file.Data = append(contents, '\n') // add trailing \n for txtar -- golden.Modified = true -- -- } -- if file == nil { -- t.Fatalf("could not find golden contents %v: %v", fragment, tag) -- } -- if len(file.Data) == 0 { -- return file.Data -- } -- return file.Data[:len(file.Data)-1] // drop the trailing \n --} -- --func (data *Data) collectCompletions(typ CompletionTestType) func(span.Span, []token.Pos) { -- result := func(m map[span.Span][]Completion, src span.Span, expected []token.Pos) { -- m[src] = append(m[src], Completion{ -- CompletionItems: expected, -- }) -- } -- switch typ { -- case CompletionDeep: -- return func(src span.Span, expected []token.Pos) { -- result(data.DeepCompletions, src, expected) -- } -- case CompletionFuzzy: -- return func(src span.Span, expected []token.Pos) { -- result(data.FuzzyCompletions, src, expected) -- } -- case CompletionRank: -- return func(src span.Span, expected []token.Pos) { -- result(data.RankCompletions, src, expected) -- } -- case CompletionCaseSensitive: -- return func(src span.Span, expected []token.Pos) { -- result(data.CaseSensitiveCompletions, src, expected) -- } -- default: -- return func(src span.Span, expected []token.Pos) { -- result(data.Completions, src, expected) -- } -- } --} -- --func (data *Data) collectCompletionItems(pos token.Pos, label, detail, kind string, args []string) { -- var documentation string -- if len(args) > 3 { -- documentation = args[3] -- } -- data.CompletionItems[pos] = &completion.CompletionItem{ -- Label: label, -- Detail: detail, -- Kind: protocol.ParseCompletionItemKind(kind), -- Documentation: documentation, -- } --} -- --func (data *Data) collectAddImports(spn span.Span, imp string) { -- data.AddImport[spn.URI()] = imp --} -- --func (data *Data) collectSemanticTokens(spn span.Span) { -- data.SemanticTokens = append(data.SemanticTokens, spn) --} -- --func (data *Data) collectSuggestedFixes(spn span.Span, actionKind, fix string) { -- data.SuggestedFixes[spn] = append(data.SuggestedFixes[spn], SuggestedFix{actionKind, fix}) --} -- --func (data *Data) collectMethodExtractions(start span.Span, end span.Span) { -- if _, ok := data.MethodExtractions[start]; !ok { -- data.MethodExtractions[start] = end -- } --} -- --func (data *Data) collectSelectionRanges(spn span.Span) { -- data.SelectionRanges = append(data.SelectionRanges, spn) --} -- --func (data *Data) collectIncomingCalls(src span.Span, calls []span.Span) { -- for _, call := range calls { -- rng := data.mustRange(call) -- // we're only comparing protocol.range -- if data.CallHierarchy[src] != nil { -- data.CallHierarchy[src].IncomingCalls = append(data.CallHierarchy[src].IncomingCalls, -- protocol.CallHierarchyItem{ -- URI: protocol.DocumentURI(call.URI()), -- Range: rng, -- }) -- } else { -- data.CallHierarchy[src] = &CallHierarchyResult{ -- IncomingCalls: []protocol.CallHierarchyItem{ -- {URI: protocol.DocumentURI(call.URI()), Range: rng}, -- }, -- } -- } -- } --} -- --func (data *Data) collectOutgoingCalls(src span.Span, calls []span.Span) { -- if data.CallHierarchy[src] == nil { -- data.CallHierarchy[src] = &CallHierarchyResult{} -- } -- for _, call := range calls { -- // we're only comparing protocol.range -- data.CallHierarchy[src].OutgoingCalls = append(data.CallHierarchy[src].OutgoingCalls, -- protocol.CallHierarchyItem{ -- URI: protocol.DocumentURI(call.URI()), -- Range: data.mustRange(call), -- }) -- } --} -- --func (data *Data) collectInlayHints(src span.Span) { -- data.InlayHints = append(data.InlayHints, src) --} -- --func (data *Data) collectRenames(src span.Span, newText string) { -- data.Renames[src] = newText --} -- --func (data *Data) collectPrepareRenames(src, spn span.Span, placeholder string) { -- data.PrepareRenames[src] = &source.PrepareItem{ -- Range: data.mustRange(spn), -- Text: placeholder, -- } --} -- --// mustRange converts spn into a protocol.Range, panicking on any error. --func (data *Data) mustRange(spn span.Span) protocol.Range { -- m, err := data.Mapper(spn.URI()) -- rng, err := m.SpanRange(spn) -- if err != nil { -- panic(fmt.Sprintf("converting span %s to range: %v", spn, err)) -- } -- return rng --} -- --func (data *Data) collectSignatures(spn span.Span, signature string, activeParam int64) { -- data.Signatures[spn] = &protocol.SignatureHelp{ -- Signatures: []protocol.SignatureInformation{ -- { -- Label: signature, -- }, -- }, -- ActiveParameter: uint32(activeParam), -- } -- // Hardcode special case to test the lack of a signature. -- if signature == "" && activeParam == 0 { -- data.Signatures[spn] = nil -- } --} -- --func (data *Data) collectCompletionSnippets(spn span.Span, item token.Pos, plain, placeholder string) { -- data.CompletionSnippets[spn] = append(data.CompletionSnippets[spn], CompletionSnippet{ -- CompletionItem: item, -- PlainSnippet: plain, -- PlaceholderSnippet: placeholder, -- }) --} -- --func (data *Data) collectLinks(spn span.Span, link string, note *expect.Note, fset *token.FileSet) { -- position := safetoken.StartPosition(fset, note.Pos) -- uri := spn.URI() -- data.Links[uri] = append(data.Links[uri], Link{ -- Src: spn, -- Target: link, -- NotePosition: position, -- }) --} -- --func uriName(uri span.URI) string { -- return filepath.Base(strings.TrimSuffix(uri.Filename(), ".go")) --} -- --// TODO(golang/go#54845): improve the formatting here to match standard --// line:column position formatting. --func SpanName(spn span.Span) string { -- return fmt.Sprintf("%v_%v_%v", uriName(spn.URI()), spn.Start().Line(), spn.Start().Column()) --} -- --func shouldSkip(data *Data, uri span.URI) bool { -- if data.ModfileFlagAvailable { -- return false -- } -- // If the -modfile flag is not available, then we do not want to run -- // any tests on the go.mod file. -- if strings.HasSuffix(uri.Filename(), ".mod") { -- return true -- } -- // If the -modfile flag is not available, then we do not want to test any -- // uri that contains "go mod tidy". -- m, err := data.Mapper(uri) -- return err == nil && strings.Contains(string(m.Content), ", \"go mod tidy\",") --} -diff -urN a/gopls/internal/lsp/tests/util.go b/gopls/internal/lsp/tests/util.go ---- a/gopls/internal/lsp/tests/util.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/util.go 1970-01-01 08:00:00 -@@ -1,311 +0,0 @@ --// Copyright 2020 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 tests -- --import ( -- "bytes" -- "fmt" -- "go/token" -- "sort" -- "strconv" -- "strings" -- -- "github.com/google/go-cmp/cmp" -- "github.com/google/go-cmp/cmp/cmpopts" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source/completion" -- "golang.org/x/tools/gopls/internal/lsp/tests/compare" -- "golang.org/x/tools/gopls/internal/span" --) -- --var builtins = map[string]bool{ -- "append": true, -- "cap": true, -- "close": true, -- "complex": true, -- "copy": true, -- "delete": true, -- "error": true, -- "false": true, -- "imag": true, -- "iota": true, -- "len": true, -- "make": true, -- "new": true, -- "nil": true, -- "panic": true, -- "print": true, -- "println": true, -- "real": true, -- "recover": true, -- "true": true, --} -- --// DiffLinks takes the links we got and checks if they are located within the source or a Note. --// If the link is within a Note, the link is removed. --// Returns an diff comment if there are differences and empty string if no diffs. --func DiffLinks(mapper *protocol.Mapper, wantLinks []Link, gotLinks []protocol.DocumentLink) string { -- var notePositions []token.Position -- links := make(map[span.Span]string, len(wantLinks)) -- for _, link := range wantLinks { -- links[link.Src] = link.Target -- notePositions = append(notePositions, link.NotePosition) -- } -- -- var msg strings.Builder -- for _, link := range gotLinks { -- spn, err := mapper.RangeSpan(link.Range) -- if err != nil { -- return fmt.Sprintf("%v", err) -- } -- linkInNote := false -- for _, notePosition := range notePositions { -- // Drop the links found inside expectation notes arguments as this links are not collected by expect package. -- if notePosition.Line == spn.Start().Line() && -- notePosition.Column <= spn.Start().Column() { -- delete(links, spn) -- linkInNote = true -- } -- } -- if linkInNote { -- continue -- } -- -- if target, ok := links[spn]; ok { -- delete(links, spn) -- if target != *link.Target { -- fmt.Fprintf(&msg, "%s: want link with target %q, got %q\n", spn, target, *link.Target) -- } -- } else { -- fmt.Fprintf(&msg, "%s: got unexpected link with target %q\n", spn, *link.Target) -- } -- } -- for spn, target := range links { -- fmt.Fprintf(&msg, "%s: expected link with target %q is missing\n", spn, target) -- } -- return msg.String() --} -- --// inRange reports whether p is contained within [r.Start, r.End), or if p == --// r.Start == r.End (special handling for the case where the range is a single --// point). --func inRange(p protocol.Position, r protocol.Range) bool { -- if protocol.IsPoint(r) { -- return protocol.ComparePosition(r.Start, p) == 0 -- } -- if protocol.ComparePosition(r.Start, p) <= 0 && protocol.ComparePosition(p, r.End) < 0 { -- return true -- } -- return false --} -- --func DiffSignatures(spn span.Span, want, got *protocol.SignatureHelp) string { -- decorate := func(f string, args ...interface{}) string { -- return fmt.Sprintf("invalid signature at %s: %s", spn, fmt.Sprintf(f, args...)) -- } -- if len(got.Signatures) != 1 { -- return decorate("wanted 1 signature, got %d", len(got.Signatures)) -- } -- if got.ActiveSignature != 0 { -- return decorate("wanted active signature of 0, got %d", int(got.ActiveSignature)) -- } -- if want.ActiveParameter != got.ActiveParameter { -- return decorate("wanted active parameter of %d, got %d", want.ActiveParameter, int(got.ActiveParameter)) -- } -- g := got.Signatures[0] -- w := want.Signatures[0] -- if diff := compare.Text(NormalizeAny(w.Label), NormalizeAny(g.Label)); diff != "" { -- return decorate("mismatched labels:\n%s", diff) -- } -- var paramParts []string -- for _, p := range g.Parameters { -- paramParts = append(paramParts, p.Label) -- } -- paramsStr := strings.Join(paramParts, ", ") -- if !strings.Contains(g.Label, paramsStr) { -- return decorate("expected signature %q to contain params %q", g.Label, paramsStr) -- } -- return "" --} -- --// NormalizeAny replaces occurrences of interface{} in input with any. --// --// In Go 1.18, standard library functions were changed to use the 'any' --// alias in place of interface{}, which affects their type string. --func NormalizeAny(input string) string { -- return strings.ReplaceAll(input, "interface{}", "any") --} -- --// DiffCallHierarchyItems returns the diff between expected and actual call locations for incoming/outgoing call hierarchies --func DiffCallHierarchyItems(gotCalls []protocol.CallHierarchyItem, expectedCalls []protocol.CallHierarchyItem) string { -- expected := make(map[protocol.Location]bool) -- for _, call := range expectedCalls { -- expected[protocol.Location{URI: call.URI, Range: call.Range}] = true -- } -- -- got := make(map[protocol.Location]bool) -- for _, call := range gotCalls { -- got[protocol.Location{URI: call.URI, Range: call.Range}] = true -- } -- if len(got) != len(expected) { -- return fmt.Sprintf("expected %d calls but got %d", len(expected), len(got)) -- } -- for spn := range got { -- if !expected[spn] { -- return fmt.Sprintf("incorrect calls, expected locations %v but got locations %v", expected, got) -- } -- } -- return "" --} -- --func FilterBuiltins(src span.Span, items []protocol.CompletionItem) []protocol.CompletionItem { -- var ( -- got []protocol.CompletionItem -- wantBuiltins = strings.Contains(string(src.URI()), "builtins") -- wantKeywords = strings.Contains(string(src.URI()), "keywords") -- ) -- for _, item := range items { -- if !wantBuiltins && isBuiltin(item.Label, item.Detail, item.Kind) { -- continue -- } -- -- if !wantKeywords && token.Lookup(item.Label).IsKeyword() { -- continue -- } -- -- got = append(got, item) -- } -- return got --} -- --func isBuiltin(label, detail string, kind protocol.CompletionItemKind) bool { -- if detail == "" && kind == protocol.ClassCompletion { -- return true -- } -- // Remaining builtin constants, variables, interfaces, and functions. -- trimmed := label -- if i := strings.Index(trimmed, "("); i >= 0 { -- trimmed = trimmed[:i] -- } -- return builtins[trimmed] --} -- --func CheckCompletionOrder(want, got []protocol.CompletionItem, strictScores bool) string { -- var ( -- matchedIdxs []int -- lastGotIdx int -- lastGotSort float64 -- inOrder = true -- errorMsg = "completions out of order" -- ) -- for _, w := range want { -- var found bool -- for i, g := range got { -- if w.Label == g.Label && NormalizeAny(w.Detail) == NormalizeAny(g.Detail) && w.Kind == g.Kind { -- matchedIdxs = append(matchedIdxs, i) -- found = true -- -- if i < lastGotIdx { -- inOrder = false -- } -- lastGotIdx = i -- -- sort, _ := strconv.ParseFloat(g.SortText, 64) -- if strictScores && len(matchedIdxs) > 1 && sort <= lastGotSort { -- inOrder = false -- errorMsg = "candidate scores not strictly decreasing" -- } -- lastGotSort = sort -- -- break -- } -- } -- if !found { -- return summarizeCompletionItems(-1, []protocol.CompletionItem{w}, got, "didn't find expected completion") -- } -- } -- -- sort.Ints(matchedIdxs) -- matched := make([]protocol.CompletionItem, 0, len(matchedIdxs)) -- for _, idx := range matchedIdxs { -- matched = append(matched, got[idx]) -- } -- -- if !inOrder { -- return summarizeCompletionItems(-1, want, matched, errorMsg) -- } -- -- return "" --} -- --func DiffSnippets(want string, got *protocol.CompletionItem) string { -- if want == "" { -- if got != nil { -- x := got.TextEdit -- return fmt.Sprintf("expected no snippet but got %s", x.NewText) -- } -- } else { -- if got == nil { -- return fmt.Sprintf("couldn't find completion matching %q", want) -- } -- x := got.TextEdit -- if want != x.NewText { -- return fmt.Sprintf("expected snippet %q, got %q", want, x.NewText) -- } -- } -- return "" --} -- --func FindItem(list []protocol.CompletionItem, want completion.CompletionItem) *protocol.CompletionItem { -- for _, item := range list { -- if item.Label == want.Label { -- return &item -- } -- } -- return nil --} -- --// DiffCompletionItems prints the diff between expected and actual completion --// test results. --// --// The diff will be formatted using '-' and '+' for want and got, respectively. --func DiffCompletionItems(want, got []protocol.CompletionItem) string { -- // Many fields are not set in the "want" slice. -- irrelevantFields := []string{ -- "AdditionalTextEdits", -- "Documentation", -- "TextEdit", -- "SortText", -- "Preselect", -- "FilterText", -- "InsertText", -- "InsertTextFormat", -- } -- ignore := cmpopts.IgnoreFields(protocol.CompletionItem{}, irrelevantFields...) -- normalizeAny := cmpopts.AcyclicTransformer("NormalizeAny", func(item protocol.CompletionItem) protocol.CompletionItem { -- item.Detail = NormalizeAny(item.Detail) -- return item -- }) -- return cmp.Diff(want, got, ignore, normalizeAny) --} -- --func summarizeCompletionItems(i int, want, got []protocol.CompletionItem, reason string, args ...interface{}) string { -- msg := &bytes.Buffer{} -- fmt.Fprint(msg, "completion failed") -- if i >= 0 { -- fmt.Fprintf(msg, " at %d", i) -- } -- fmt.Fprint(msg, " because of ") -- fmt.Fprintf(msg, reason, args...) -- fmt.Fprint(msg, ":\nexpected:\n") -- for _, d := range want { -- fmt.Fprintf(msg, " %v\n", d) -- } -- fmt.Fprintf(msg, "got:\n") -- for _, d := range got { -- fmt.Fprintf(msg, " %v\n", d) -- } -- return msg.String() --} -diff -urN a/gopls/internal/lsp/tests/util_go118.go b/gopls/internal/lsp/tests/util_go118.go ---- a/gopls/internal/lsp/tests/util_go118.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/util_go118.go 1970-01-01 08:00:00 -@@ -1,13 +0,0 @@ --// Copyright 2023 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. -- --//go:build go1.18 --// +build go1.18 -- --package tests -- --func init() { -- builtins["any"] = true -- builtins["comparable"] = true --} -diff -urN a/gopls/internal/lsp/tests/util_go121.go b/gopls/internal/lsp/tests/util_go121.go ---- a/gopls/internal/lsp/tests/util_go121.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/util_go121.go 1970-01-01 08:00:00 -@@ -1,14 +0,0 @@ --// Copyright 2023 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. -- --//go:build go1.21 --// +build go1.21 -- --package tests -- --func init() { -- builtins["clear"] = true -- builtins["max"] = true -- builtins["min"] = true --} -diff -urN a/gopls/internal/lsp/tests/util_go122.go b/gopls/internal/lsp/tests/util_go122.go ---- a/gopls/internal/lsp/tests/util_go122.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/util_go122.go 1970-01-01 08:00:00 -@@ -1,12 +0,0 @@ --// Copyright 2023 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. -- --//go:build go1.22 --// +build go1.22 -- --package tests -- --func init() { -- builtins["zero"] = true --} -diff -urN a/gopls/internal/lsp/text_synchronization.go b/gopls/internal/lsp/text_synchronization.go ---- a/gopls/internal/lsp/text_synchronization.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/text_synchronization.go 1970-01-01 08:00:00 -@@ -1,367 +0,0 @@ --// 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 lsp -- --import ( -- "bytes" -- "context" -- "errors" -- "fmt" -- "path/filepath" -- "sync" -- -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/event" -- "golang.org/x/tools/internal/event/tag" -- "golang.org/x/tools/internal/jsonrpc2" --) -- --// ModificationSource identifies the origin of a change. --type ModificationSource int -- --const ( -- // FromDidOpen is from a didOpen notification. -- FromDidOpen = ModificationSource(iota) -- -- // FromDidChange is from a didChange notification. -- FromDidChange -- -- // FromDidChangeWatchedFiles is from didChangeWatchedFiles notification. -- FromDidChangeWatchedFiles -- -- // FromDidSave is from a didSave notification. -- FromDidSave -- -- // FromDidClose is from a didClose notification. -- FromDidClose -- -- // FromDidChangeConfiguration is from a didChangeConfiguration notification. -- FromDidChangeConfiguration -- -- // FromRegenerateCgo refers to file modifications caused by regenerating -- // the cgo sources for the workspace. -- FromRegenerateCgo -- -- // FromInitialWorkspaceLoad refers to the loading of all packages in the -- // workspace when the view is first created. -- FromInitialWorkspaceLoad --) -- --func (m ModificationSource) String() string { -- switch m { -- case FromDidOpen: -- return "opened files" -- case FromDidChange: -- return "changed files" -- case FromDidChangeWatchedFiles: -- return "files changed on disk" -- case FromDidSave: -- return "saved files" -- case FromDidClose: -- return "close files" -- case FromRegenerateCgo: -- return "regenerate cgo" -- case FromInitialWorkspaceLoad: -- return "initial workspace load" -- default: -- return "unknown file modification" -- } --} -- --func (s *Server) didOpen(ctx context.Context, params *protocol.DidOpenTextDocumentParams) error { -- ctx, done := event.Start(ctx, "lsp.Server.didOpen", tag.URI.Of(params.TextDocument.URI)) -- defer done() -- -- uri := params.TextDocument.URI.SpanURI() -- if !uri.IsFile() { -- return nil -- } -- // There may not be any matching view in the current session. If that's -- // the case, try creating a new view based on the opened file path. -- // -- // TODO(rstambler): This seems like it would continuously add new -- // views, but it won't because ViewOf only returns an error when there -- // are no views in the session. I don't know if that logic should go -- // here, or if we can continue to rely on that implementation detail. -- // -- // TODO(golang/go#57979): this will be generalized to a different view calculation. -- if _, err := s.session.ViewOf(uri); err != nil { -- dir := filepath.Dir(uri.Filename()) -- if err := s.addFolders(ctx, []protocol.WorkspaceFolder{{ -- URI: string(protocol.URIFromPath(dir)), -- Name: filepath.Base(dir), -- }}); err != nil { -- return err -- } -- } -- return s.didModifyFiles(ctx, []source.FileModification{{ -- URI: uri, -- Action: source.Open, -- Version: params.TextDocument.Version, -- Text: []byte(params.TextDocument.Text), -- LanguageID: params.TextDocument.LanguageID, -- }}, FromDidOpen) --} -- --func (s *Server) didChange(ctx context.Context, params *protocol.DidChangeTextDocumentParams) error { -- ctx, done := event.Start(ctx, "lsp.Server.didChange", tag.URI.Of(params.TextDocument.URI)) -- defer done() -- -- uri := params.TextDocument.URI.SpanURI() -- if !uri.IsFile() { -- return nil -- } -- -- text, err := s.changedText(ctx, uri, params.ContentChanges) -- if err != nil { -- return err -- } -- c := source.FileModification{ -- URI: uri, -- Action: source.Change, -- Version: params.TextDocument.Version, -- Text: text, -- } -- if err := s.didModifyFiles(ctx, []source.FileModification{c}, FromDidChange); err != nil { -- return err -- } -- return s.warnAboutModifyingGeneratedFiles(ctx, uri) --} -- --// warnAboutModifyingGeneratedFiles shows a warning if a user tries to edit a --// generated file for the first time. --func (s *Server) warnAboutModifyingGeneratedFiles(ctx context.Context, uri span.URI) error { -- s.changedFilesMu.Lock() -- _, ok := s.changedFiles[uri] -- if !ok { -- s.changedFiles[uri] = struct{}{} -- } -- s.changedFilesMu.Unlock() -- -- // This file has already been edited before. -- if ok { -- return nil -- } -- -- // Ideally, we should be able to specify that a generated file should -- // be opened as read-only. Tell the user that they should not be -- // editing a generated file. -- view, err := s.session.ViewOf(uri) -- if err != nil { -- return err -- } -- snapshot, release, err := view.Snapshot() -- if err != nil { -- return err -- } -- isGenerated := source.IsGenerated(ctx, snapshot, uri) -- release() -- -- if !isGenerated { -- return nil -- } -- return s.client.ShowMessage(ctx, &protocol.ShowMessageParams{ -- Message: fmt.Sprintf("Do not edit this file! %s is a generated file.", uri.Filename()), -- Type: protocol.Warning, -- }) --} -- --func (s *Server) didChangeWatchedFiles(ctx context.Context, params *protocol.DidChangeWatchedFilesParams) error { -- ctx, done := event.Start(ctx, "lsp.Server.didChangeWatchedFiles") -- defer done() -- -- var modifications []source.FileModification -- for _, change := range params.Changes { -- uri := change.URI.SpanURI() -- if !uri.IsFile() { -- continue -- } -- action := changeTypeToFileAction(change.Type) -- modifications = append(modifications, source.FileModification{ -- URI: uri, -- Action: action, -- OnDisk: true, -- }) -- } -- return s.didModifyFiles(ctx, modifications, FromDidChangeWatchedFiles) --} -- --func (s *Server) didSave(ctx context.Context, params *protocol.DidSaveTextDocumentParams) error { -- ctx, done := event.Start(ctx, "lsp.Server.didSave", tag.URI.Of(params.TextDocument.URI)) -- defer done() -- -- uri := params.TextDocument.URI.SpanURI() -- if !uri.IsFile() { -- return nil -- } -- c := source.FileModification{ -- URI: uri, -- Action: source.Save, -- } -- if params.Text != nil { -- c.Text = []byte(*params.Text) -- } -- return s.didModifyFiles(ctx, []source.FileModification{c}, FromDidSave) --} -- --func (s *Server) didClose(ctx context.Context, params *protocol.DidCloseTextDocumentParams) error { -- ctx, done := event.Start(ctx, "lsp.Server.didClose", tag.URI.Of(params.TextDocument.URI)) -- defer done() -- -- uri := params.TextDocument.URI.SpanURI() -- if !uri.IsFile() { -- return nil -- } -- return s.didModifyFiles(ctx, []source.FileModification{ -- { -- URI: uri, -- Action: source.Close, -- Version: -1, -- Text: nil, -- }, -- }, FromDidClose) --} -- --func (s *Server) didModifyFiles(ctx context.Context, modifications []source.FileModification, cause ModificationSource) error { -- // wg guards two conditions: -- // 1. didModifyFiles is complete -- // 2. the goroutine diagnosing changes on behalf of didModifyFiles is -- // complete, if it was started -- // -- // Both conditions must be satisfied for the purpose of testing: we don't -- // want to observe the completion of change processing until we have received -- // all diagnostics as well as all server->client notifications done on behalf -- // of this function. -- var wg sync.WaitGroup -- wg.Add(1) -- defer wg.Done() -- -- if s.Options().VerboseWorkDoneProgress { -- work := s.progress.Start(ctx, DiagnosticWorkTitle(cause), "Calculating file diagnostics...", nil, nil) -- go func() { -- wg.Wait() -- work.End(ctx, "Done.") -- }() -- } -- -- onDisk := cause == FromDidChangeWatchedFiles -- -- s.stateMu.Lock() -- if s.state >= serverShutDown { -- // This state check does not prevent races below, and exists only to -- // produce a better error message. The actual race to the cache should be -- // guarded by Session.viewMu. -- s.stateMu.Unlock() -- return errors.New("server is shut down") -- } -- s.stateMu.Unlock() -- -- // If the set of changes included directories, expand those directories -- // to their files. -- modifications = s.session.ExpandModificationsToDirectories(ctx, modifications) -- -- // Build a lookup map for file modifications, so that we can later join -- // with the snapshot file associations. -- modMap := make(map[span.URI]source.FileModification) -- for _, mod := range modifications { -- modMap[mod.URI] = mod -- } -- -- snapshots, release, err := s.session.DidModifyFiles(ctx, modifications) -- if err != nil { -- return err -- } -- -- // golang/go#50267: diagnostics should be re-sent after an open or close. For -- // some clients, it may be helpful to re-send after each change. -- for snapshot, uris := range snapshots { -- for _, uri := range uris { -- mod := modMap[uri] -- if snapshot.Options().ChattyDiagnostics || mod.Action == source.Open || mod.Action == source.Close { -- s.mustPublishDiagnostics(uri) -- } -- } -- } -- -- wg.Add(1) -- go func() { -- s.diagnoseSnapshots(snapshots, onDisk) -- release() -- wg.Done() -- }() -- -- // After any file modifications, we need to update our watched files, -- // in case something changed. Compute the new set of directories to watch, -- // and if it differs from the current set, send updated registrations. -- return s.updateWatchedDirectories(ctx) --} -- --// DiagnosticWorkTitle returns the title of the diagnostic work resulting from a --// file change originating from the given cause. --func DiagnosticWorkTitle(cause ModificationSource) string { -- return fmt.Sprintf("diagnosing %v", cause) --} -- --func (s *Server) changedText(ctx context.Context, uri span.URI, changes []protocol.TextDocumentContentChangeEvent) ([]byte, error) { -- if len(changes) == 0 { -- return nil, fmt.Errorf("%w: no content changes provided", jsonrpc2.ErrInternal) -- } -- -- // Check if the client sent the full content of the file. -- // We accept a full content change even if the server expected incremental changes. -- if len(changes) == 1 && changes[0].Range == nil && changes[0].RangeLength == 0 { -- return []byte(changes[0].Text), nil -- } -- return s.applyIncrementalChanges(ctx, uri, changes) --} -- --func (s *Server) applyIncrementalChanges(ctx context.Context, uri span.URI, changes []protocol.TextDocumentContentChangeEvent) ([]byte, error) { -- fh, err := s.session.ReadFile(ctx, uri) -- if err != nil { -- return nil, err -- } -- content, err := fh.Content() -- if err != nil { -- return nil, fmt.Errorf("%w: file not found (%v)", jsonrpc2.ErrInternal, err) -- } -- for _, change := range changes { -- // TODO(adonovan): refactor to use diff.Apply, which is robust w.r.t. -- // out-of-order or overlapping changes---and much more efficient. -- -- // Make sure to update mapper along with the content. -- m := protocol.NewMapper(uri, content) -- if change.Range == nil { -- return nil, fmt.Errorf("%w: unexpected nil range for change", jsonrpc2.ErrInternal) -- } -- spn, err := m.RangeSpan(*change.Range) -- if err != nil { -- return nil, err -- } -- start, end := spn.Start().Offset(), spn.End().Offset() -- if end < start { -- return nil, fmt.Errorf("%w: invalid range for content change", jsonrpc2.ErrInternal) -- } -- var buf bytes.Buffer -- buf.Write(content[:start]) -- buf.WriteString(change.Text) -- buf.Write(content[end:]) -- content = buf.Bytes() -- } -- return content, nil --} -- --func changeTypeToFileAction(ct protocol.FileChangeType) source.FileAction { -- switch ct { -- case protocol.Changed: -- return source.Change -- case protocol.Created: -- return source.Create -- case protocol.Deleted: -- return source.Delete -- } -- return source.UnknownFileAction --} -diff -urN a/gopls/internal/lsp/work/completion.go b/gopls/internal/lsp/work/completion.go ---- a/gopls/internal/lsp/work/completion.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/work/completion.go 1970-01-01 08:00:00 -@@ -1,154 +0,0 @@ --// Copyright 2022 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 work -- --import ( -- "context" -- "errors" -- "fmt" -- "os" -- "path/filepath" -- "sort" -- "strings" -- -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/internal/event" --) -- --func Completion(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, position protocol.Position) (*protocol.CompletionList, error) { -- ctx, done := event.Start(ctx, "work.Completion") -- defer done() -- -- // Get the position of the cursor. -- pw, err := snapshot.ParseWork(ctx, fh) -- if err != nil { -- return nil, fmt.Errorf("getting go.work file handle: %w", err) -- } -- cursor, err := pw.Mapper.PositionOffset(position) -- if err != nil { -- return nil, fmt.Errorf("computing cursor offset: %w", err) -- } -- -- // Find the use statement the user is in. -- use, pathStart, _ := usePath(pw, cursor) -- if use == nil { -- return &protocol.CompletionList{}, nil -- } -- completingFrom := use.Path[:cursor-pathStart] -- -- // We're going to find the completions of the user input -- // (completingFrom) by doing a walk on the innermost directory -- // of the given path, and comparing the found paths to make sure -- // that they match the component of the path after the -- // innermost directory. -- // -- // We'll maintain two paths when doing this: pathPrefixSlash -- // is essentially the path the user typed in, and pathPrefixAbs -- // is the path made absolute from the go.work directory. -- -- pathPrefixSlash := completingFrom -- pathPrefixAbs := filepath.FromSlash(pathPrefixSlash) -- if !filepath.IsAbs(pathPrefixAbs) { -- pathPrefixAbs = filepath.Join(filepath.Dir(pw.URI.Filename()), pathPrefixAbs) -- } -- -- // pathPrefixDir is the directory that will be walked to find matches. -- // If pathPrefixSlash is not explicitly a directory boundary (is either equivalent to "." or -- // ends in a separator) we need to examine its parent directory to find sibling files that -- // match. -- depthBound := 5 -- pathPrefixDir, pathPrefixBase := pathPrefixAbs, "" -- pathPrefixSlashDir := pathPrefixSlash -- if filepath.Clean(pathPrefixSlash) != "." && !strings.HasSuffix(pathPrefixSlash, "/") { -- depthBound++ -- pathPrefixDir, pathPrefixBase = filepath.Split(pathPrefixAbs) -- pathPrefixSlashDir = dirNonClean(pathPrefixSlash) -- } -- -- var completions []string -- // Stop traversing deeper once we've hit 10k files to try to stay generally under 100ms. -- const numSeenBound = 10000 -- var numSeen int -- stopWalking := errors.New("hit numSeenBound") -- err = filepath.Walk(pathPrefixDir, func(wpath string, info os.FileInfo, err error) error { -- if numSeen > numSeenBound { -- // Stop traversing if we hit bound. -- return stopWalking -- } -- numSeen++ -- -- // rel is the path relative to pathPrefixDir. -- // Make sure that it has pathPrefixBase as a prefix -- // otherwise it won't match the beginning of the -- // base component of the path the user typed in. -- rel := strings.TrimPrefix(wpath[len(pathPrefixDir):], string(filepath.Separator)) -- if info.IsDir() && wpath != pathPrefixDir && !strings.HasPrefix(rel, pathPrefixBase) { -- return filepath.SkipDir -- } -- -- // Check for a match (a module directory). -- if filepath.Base(rel) == "go.mod" { -- relDir := strings.TrimSuffix(dirNonClean(rel), string(os.PathSeparator)) -- completionPath := join(pathPrefixSlashDir, filepath.ToSlash(relDir)) -- -- if !strings.HasPrefix(completionPath, completingFrom) { -- return nil -- } -- if strings.HasSuffix(completionPath, "/") { -- // Don't suggest paths that end in "/". This happens -- // when the input is a path that ends in "/" and -- // the completion is empty. -- return nil -- } -- completion := completionPath[len(completingFrom):] -- if completingFrom == "" && !strings.HasPrefix(completion, "./") { -- // Bias towards "./" prefixes. -- completion = join(".", completion) -- } -- -- completions = append(completions, completion) -- } -- -- if depth := strings.Count(rel, string(filepath.Separator)); depth >= depthBound { -- return filepath.SkipDir -- } -- return nil -- }) -- if err != nil && !errors.Is(err, stopWalking) { -- return nil, fmt.Errorf("walking to find completions: %w", err) -- } -- -- sort.Strings(completions) -- -- items := []protocol.CompletionItem{} // must be a slice -- for _, c := range completions { -- items = append(items, protocol.CompletionItem{ -- Label: c, -- InsertText: c, -- }) -- } -- return &protocol.CompletionList{Items: items}, nil --} -- --// dirNonClean is filepath.Dir, without the Clean at the end. --func dirNonClean(path string) string { -- vol := filepath.VolumeName(path) -- i := len(path) - 1 -- for i >= len(vol) && !os.IsPathSeparator(path[i]) { -- i-- -- } -- return path[len(vol) : i+1] --} -- --func join(a, b string) string { -- if a == "" { -- return b -- } -- if b == "" { -- return a -- } -- return strings.TrimSuffix(a, "/") + "/" + b --} -diff -urN a/gopls/internal/lsp/work/diagnostics.go b/gopls/internal/lsp/work/diagnostics.go ---- a/gopls/internal/lsp/work/diagnostics.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/work/diagnostics.go 1970-01-01 08:00:00 -@@ -1,92 +0,0 @@ --// Copyright 2022 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 work -- --import ( -- "context" -- "fmt" -- "os" -- "path/filepath" -- -- "golang.org/x/mod/modfile" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/event" --) -- --func Diagnostics(ctx context.Context, snapshot source.Snapshot) (map[span.URI][]*source.Diagnostic, error) { -- ctx, done := event.Start(ctx, "work.Diagnostics", source.SnapshotLabels(snapshot)...) -- defer done() -- -- reports := map[span.URI][]*source.Diagnostic{} -- uri := snapshot.WorkFile() -- if uri == "" { -- return nil, nil -- } -- fh, err := snapshot.ReadFile(ctx, uri) -- if err != nil { -- return nil, err -- } -- reports[fh.URI()] = []*source.Diagnostic{} -- diagnostics, err := DiagnosticsForWork(ctx, snapshot, fh) -- if err != nil { -- return nil, err -- } -- for _, d := range diagnostics { -- fh, err := snapshot.ReadFile(ctx, d.URI) -- if err != nil { -- return nil, err -- } -- reports[fh.URI()] = append(reports[fh.URI()], d) -- } -- -- return reports, nil --} -- --func DiagnosticsForWork(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) ([]*source.Diagnostic, error) { -- pw, err := snapshot.ParseWork(ctx, fh) -- if err != nil { -- if pw == nil || len(pw.ParseErrors) == 0 { -- return nil, err -- } -- return pw.ParseErrors, nil -- } -- -- // Add diagnostic if a directory does not contain a module. -- var diagnostics []*source.Diagnostic -- for _, use := range pw.File.Use { -- rng, err := pw.Mapper.OffsetRange(use.Syntax.Start.Byte, use.Syntax.End.Byte) -- if err != nil { -- return nil, err -- } -- -- modfh, err := snapshot.ReadFile(ctx, modFileURI(pw, use)) -- if err != nil { -- return nil, err -- } -- if _, err := modfh.Content(); err != nil && os.IsNotExist(err) { -- diagnostics = append(diagnostics, &source.Diagnostic{ -- URI: fh.URI(), -- Range: rng, -- Severity: protocol.SeverityError, -- Source: source.WorkFileError, -- Message: fmt.Sprintf("directory %v does not contain a module", use.Path), -- }) -- } -- } -- return diagnostics, nil --} -- --func modFileURI(pw *source.ParsedWorkFile, use *modfile.Use) span.URI { -- workdir := filepath.Dir(pw.URI.Filename()) -- -- modroot := filepath.FromSlash(use.Path) -- if !filepath.IsAbs(modroot) { -- modroot = filepath.Join(workdir, modroot) -- } -- -- return span.URIFromPath(filepath.Join(modroot, "go.mod")) --} -diff -urN a/gopls/internal/lsp/work/format.go b/gopls/internal/lsp/work/format.go ---- a/gopls/internal/lsp/work/format.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/work/format.go 1970-01-01 08:00:00 -@@ -1,28 +0,0 @@ --// Copyright 2022 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 work -- --import ( -- "context" -- -- "golang.org/x/mod/modfile" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/internal/event" --) -- --func Format(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) ([]protocol.TextEdit, error) { -- ctx, done := event.Start(ctx, "work.Format") -- defer done() -- -- pw, err := snapshot.ParseWork(ctx, fh) -- if err != nil { -- return nil, err -- } -- formatted := modfile.Format(pw.File.Syntax) -- // Calculate the edits to be made due to the change. -- diffs := snapshot.Options().ComputeEdits(string(pw.Mapper.Content), string(formatted)) -- return source.ToProtocolEdits(pw.Mapper, diffs) --} -diff -urN a/gopls/internal/lsp/work/hover.go b/gopls/internal/lsp/work/hover.go ---- a/gopls/internal/lsp/work/hover.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/work/hover.go 1970-01-01 08:00:00 -@@ -1,92 +0,0 @@ --// Copyright 2022 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 work -- --import ( -- "bytes" -- "context" -- "fmt" -- -- "golang.org/x/mod/modfile" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/internal/event" --) -- --func Hover(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, position protocol.Position) (*protocol.Hover, error) { -- // We only provide hover information for the view's go.work file. -- if fh.URI() != snapshot.WorkFile() { -- return nil, nil -- } -- -- ctx, done := event.Start(ctx, "work.Hover") -- defer done() -- -- // Get the position of the cursor. -- pw, err := snapshot.ParseWork(ctx, fh) -- if err != nil { -- return nil, fmt.Errorf("getting go.work file handle: %w", err) -- } -- offset, err := pw.Mapper.PositionOffset(position) -- if err != nil { -- return nil, fmt.Errorf("computing cursor offset: %w", err) -- } -- -- // Confirm that the cursor is inside a use statement, and then find -- // the position of the use statement's directory path. -- use, pathStart, pathEnd := usePath(pw, offset) -- -- // The cursor position is not on a use statement. -- if use == nil { -- return nil, nil -- } -- -- // Get the mod file denoted by the use. -- modfh, err := snapshot.ReadFile(ctx, modFileURI(pw, use)) -- if err != nil { -- return nil, fmt.Errorf("getting modfile handle: %w", err) -- } -- pm, err := snapshot.ParseMod(ctx, modfh) -- if err != nil { -- return nil, fmt.Errorf("getting modfile handle: %w", err) -- } -- if pm.File.Module == nil { -- return nil, fmt.Errorf("modfile has no module declaration") -- } -- mod := pm.File.Module.Mod -- -- // Get the range to highlight for the hover. -- rng, err := pw.Mapper.OffsetRange(pathStart, pathEnd) -- if err != nil { -- return nil, err -- } -- options := snapshot.Options() -- return &protocol.Hover{ -- Contents: protocol.MarkupContent{ -- Kind: options.PreferredContentFormat, -- Value: mod.Path, -- }, -- Range: rng, -- }, nil --} -- --func usePath(pw *source.ParsedWorkFile, offset int) (use *modfile.Use, pathStart, pathEnd int) { -- for _, u := range pw.File.Use { -- path := []byte(u.Path) -- s, e := u.Syntax.Start.Byte, u.Syntax.End.Byte -- i := bytes.Index(pw.Mapper.Content[s:e], path) -- if i == -1 { -- // This should not happen. -- continue -- } -- // Shift the start position to the location of the -- // module directory within the use statement. -- pathStart, pathEnd = s+i, s+i+len(path) -- if pathStart <= offset && offset <= pathEnd { -- return u, pathStart, pathEnd -- } -- } -- return nil, 0, 0 --} -diff -urN a/gopls/internal/lsp/workspace.go b/gopls/internal/lsp/workspace.go ---- a/gopls/internal/lsp/workspace.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/workspace.go 1970-01-01 08:00:00 -@@ -1,100 +0,0 @@ --// 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 lsp -- --import ( -- "context" -- "fmt" -- "sync" -- -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/event" --) -- --func (s *Server) didChangeWorkspaceFolders(ctx context.Context, params *protocol.DidChangeWorkspaceFoldersParams) error { -- event := params.Event -- for _, folder := range event.Removed { -- view := s.session.ViewByName(folder.Name) -- if view != nil { -- s.session.RemoveView(view) -- } else { -- return fmt.Errorf("view %s for %v not found", folder.Name, folder.URI) -- } -- } -- return s.addFolders(ctx, event.Added) --} -- --// addView returns a Snapshot and a release function that must be --// called when it is no longer needed. --func (s *Server) addView(ctx context.Context, name string, uri span.URI) (source.Snapshot, func(), error) { -- s.stateMu.Lock() -- state := s.state -- s.stateMu.Unlock() -- if state < serverInitialized { -- return nil, nil, fmt.Errorf("addView called before server initialized") -- } -- options, err := s.fetchFolderOptions(ctx, uri) -- if err != nil { -- return nil, nil, err -- } -- _, snapshot, release, err := s.session.NewView(ctx, name, uri, options) -- return snapshot, release, err --} -- --func (s *Server) didChangeConfiguration(ctx context.Context, _ *protocol.DidChangeConfigurationParams) error { -- ctx, done := event.Start(ctx, "lsp.Server.didChangeConfiguration") -- defer done() -- -- // Apply any changes to the session-level settings. -- options, err := s.fetchFolderOptions(ctx, "") -- if err != nil { -- return err -- } -- s.SetOptions(options) -- -- // Collect options for all workspace folders. -- seen := make(map[span.URI]bool) -- for _, view := range s.session.Views() { -- if seen[view.Folder()] { -- continue -- } -- seen[view.Folder()] = true -- options, err := s.fetchFolderOptions(ctx, view.Folder()) -- if err != nil { -- return err -- } -- s.session.SetFolderOptions(ctx, view.Folder(), options) -- } -- -- var wg sync.WaitGroup -- for _, view := range s.session.Views() { -- view := view -- wg.Add(1) -- go func() { -- defer wg.Done() -- snapshot, release, err := view.Snapshot() -- if err != nil { -- return // view is shut down; no need to diagnose -- } -- defer release() -- s.diagnoseSnapshot(snapshot, nil, false, 0) -- }() -- } -- -- if s.Options().VerboseWorkDoneProgress { -- work := s.progress.Start(ctx, DiagnosticWorkTitle(FromDidChangeConfiguration), "Calculating diagnostics...", nil, nil) -- go func() { -- wg.Wait() -- work.End(ctx, "Done.") -- }() -- } -- -- // An options change may have affected the detected Go version. -- s.checkViewGoVersions() -- -- return nil --} -diff -urN a/gopls/internal/lsp/workspace_symbol.go b/gopls/internal/lsp/workspace_symbol.go ---- a/gopls/internal/lsp/workspace_symbol.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/workspace_symbol.go 1970-01-01 08:00:00 -@@ -1,38 +0,0 @@ --// Copyright 2020 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 lsp -- --import ( -- "context" -- -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/telemetry" -- "golang.org/x/tools/internal/event" --) -- --func (s *Server) symbol(ctx context.Context, params *protocol.WorkspaceSymbolParams) (_ []protocol.SymbolInformation, rerr error) { -- recordLatency := telemetry.StartLatencyTimer("symbol") -- defer func() { -- recordLatency(ctx, rerr) -- }() -- -- ctx, done := event.Start(ctx, "lsp.Server.symbol") -- defer done() -- -- views := s.session.Views() -- matcher := s.Options().SymbolMatcher -- style := s.Options().SymbolStyle -- // TODO(rfindley): it looks wrong that we need to pass views here. -- // -- // Evidence: -- // - this is the only place we convert views to []source.View -- // - workspace symbols is the only place where we call source.View.Snapshot -- var sourceViews []source.View -- for _, v := range views { -- sourceViews = append(sourceViews, v) -- } -- return source.WorkspaceSymbols(ctx, matcher, style, sourceViews, params.Query) --} -diff -urN a/gopls/internal/regtest/bench/bench_test.go b/gopls/internal/regtest/bench/bench_test.go ---- a/gopls/internal/regtest/bench/bench_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/bench_test.go 1970-01-01 08:00:00 -@@ -1,351 +0,0 @@ --// Copyright 2020 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 bench -- --import ( -- "bytes" -- "compress/gzip" -- "context" -- "flag" -- "fmt" -- "io" -- "log" -- "os" -- "os/exec" -- "path/filepath" -- "strings" -- "sync" -- "testing" -- "time" -- -- "golang.org/x/tools/gopls/internal/bug" -- "golang.org/x/tools/gopls/internal/hooks" -- "golang.org/x/tools/gopls/internal/lsp/cmd" -- "golang.org/x/tools/gopls/internal/lsp/command" -- "golang.org/x/tools/gopls/internal/lsp/fake" -- "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/internal/event" -- "golang.org/x/tools/internal/fakenet" -- "golang.org/x/tools/internal/jsonrpc2" -- "golang.org/x/tools/internal/jsonrpc2/servertest" -- "golang.org/x/tools/internal/pprof" -- "golang.org/x/tools/internal/tool" --) -- --var ( -- goplsPath = flag.String("gopls_path", "", "if set, use this gopls for testing; incompatible with -gopls_commit") -- -- installGoplsOnce sync.Once // guards installing gopls at -gopls_commit -- goplsCommit = flag.String("gopls_commit", "", "if set, install and use gopls at this commit for testing; incompatible with -gopls_path") -- -- cpuProfile = flag.String("gopls_cpuprofile", "", "if set, the cpu profile file suffix; see \"Profiling\" in the package doc") -- memProfile = flag.String("gopls_memprofile", "", "if set, the mem profile file suffix; see \"Profiling\" in the package doc") -- allocProfile = flag.String("gopls_allocprofile", "", "if set, the alloc profile file suffix; see \"Profiling\" in the package doc") -- trace = flag.String("gopls_trace", "", "if set, the trace file suffix; see \"Profiling\" in the package doc") -- -- // If non-empty, tempDir is a temporary working dir that was created by this -- // test suite. -- makeTempDirOnce sync.Once // guards creation of the temp dir -- tempDir string --) -- --// if runAsGopls is "true", run the gopls command instead of the testing.M. --const runAsGopls = "_GOPLS_BENCH_RUN_AS_GOPLS" -- --func TestMain(m *testing.M) { -- bug.PanicOnBugs = true -- if os.Getenv(runAsGopls) == "true" { -- tool.Main(context.Background(), cmd.New("gopls", "", nil, hooks.Options), os.Args[1:]) -- os.Exit(0) -- } -- event.SetExporter(nil) // don't log to stderr -- code := m.Run() -- if err := cleanup(); err != nil { -- fmt.Fprintf(os.Stderr, "cleaning up after benchmarks: %v\n", err) -- if code == 0 { -- code = 1 -- } -- } -- os.Exit(code) --} -- --// getTempDir returns the temporary directory to use for benchmark files, --// creating it if necessary. --func getTempDir() string { -- makeTempDirOnce.Do(func() { -- var err error -- tempDir, err = os.MkdirTemp("", "gopls-bench") -- if err != nil { -- log.Fatal(err) -- } -- }) -- return tempDir --} -- --// shallowClone performs a shallow clone of repo into dir at the given --// 'commitish' ref (any commit reference understood by git). --// --// The directory dir must not already exist. --func shallowClone(dir, repo, commitish string) error { -- if err := os.Mkdir(dir, 0750); err != nil { -- return fmt.Errorf("creating dir for %s: %v", repo, err) -- } -- -- // Set a timeout for git fetch. If this proves flaky, it can be removed. -- ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) -- defer cancel() -- -- // Use a shallow fetch to download just the relevant commit. -- shInit := fmt.Sprintf("git init && git fetch --depth=1 %q %q && git checkout FETCH_HEAD", repo, commitish) -- initCmd := exec.CommandContext(ctx, "/bin/sh", "-c", shInit) -- initCmd.Dir = dir -- if output, err := initCmd.CombinedOutput(); err != nil { -- return fmt.Errorf("checking out %s: %v\n%s", repo, err, output) -- } -- return nil --} -- --// connectEditor connects a fake editor session in the given dir, using the --// given editor config. --func connectEditor(dir string, config fake.EditorConfig, ts servertest.Connector) (*fake.Sandbox, *fake.Editor, *regtest.Awaiter, error) { -- s, err := fake.NewSandbox(&fake.SandboxConfig{ -- Workdir: dir, -- GOPROXY: "https://proxy.golang.org", -- }) -- if err != nil { -- return nil, nil, nil, err -- } -- -- a := regtest.NewAwaiter(s.Workdir) -- const skipApplyEdits = false -- editor, err := fake.NewEditor(s, config).Connect(context.Background(), ts, a.Hooks(), skipApplyEdits) -- if err != nil { -- return nil, nil, nil, err -- } -- -- return s, editor, a, nil --} -- --// newGoplsConnector returns a connector that connects to a new gopls process, --// executed with the provided arguments. --func newGoplsConnector(args []string) (servertest.Connector, error) { -- if *goplsPath != "" && *goplsCommit != "" { -- panic("can't set both -gopls_path and -gopls_commit") -- } -- var ( -- goplsPath = *goplsPath -- env []string -- ) -- if *goplsCommit != "" { -- goplsPath = getInstalledGopls() -- } -- if goplsPath == "" { -- var err error -- goplsPath, err = os.Executable() -- if err != nil { -- return nil, err -- } -- env = []string{fmt.Sprintf("%s=true", runAsGopls)} -- } -- return &SidecarServer{ -- goplsPath: goplsPath, -- env: env, -- args: args, -- }, nil --} -- --// profileArgs returns additional command-line arguments to use when invoking --// gopls, to enable the user-requested profiles. --// --// If wantCPU is set, CPU profiling is enabled as well. Some tests may want to --// instrument profiling around specific critical sections of the benchmark, --// rather than the entire process. --// --// TODO(rfindley): like CPU, all of these would be better served by a custom --// command. Very rarely do we care about memory usage as the process exits: we --// care about specific points in time during the benchmark. mem and alloc --// should be snapshotted, and tracing should be bracketed around critical --// sections. --func profileArgs(name string, wantCPU bool) []string { -- var args []string -- if wantCPU && *cpuProfile != "" { -- args = append(args, fmt.Sprintf("-profile.cpu=%s", qualifiedName(name, *cpuProfile))) -- } -- if *memProfile != "" { -- args = append(args, fmt.Sprintf("-profile.mem=%s", qualifiedName(name, *memProfile))) -- } -- if *allocProfile != "" { -- args = append(args, fmt.Sprintf("-profile.alloc=%s", qualifiedName(name, *allocProfile))) -- } -- if *trace != "" { -- args = append(args, fmt.Sprintf("-profile.trace=%s", qualifiedName(name, *trace))) -- } -- return args --} -- --func qualifiedName(args ...string) string { -- return strings.Join(args, ".") --} -- --// getInstalledGopls builds gopls at the given -gopls_commit, returning the --// path to the gopls binary. --func getInstalledGopls() string { -- if *goplsCommit == "" { -- panic("must provide -gopls_commit") -- } -- toolsDir := filepath.Join(getTempDir(), "gopls_build") -- goplsPath := filepath.Join(toolsDir, "gopls", "gopls") -- -- installGoplsOnce.Do(func() { -- log.Printf("installing gopls: checking out x/tools@%s into %s\n", *goplsCommit, toolsDir) -- if err := shallowClone(toolsDir, "https://go.googlesource.com/tools", *goplsCommit); err != nil { -- log.Fatal(err) -- } -- -- log.Println("installing gopls: building...") -- bld := exec.Command("go", "build", ".") -- bld.Dir = filepath.Join(toolsDir, "gopls") -- if output, err := bld.CombinedOutput(); err != nil { -- log.Fatalf("building gopls: %v\n%s", err, output) -- } -- -- // Confirm that the resulting path now exists. -- if _, err := os.Stat(goplsPath); err != nil { -- log.Fatalf("os.Stat(%s): %v", goplsPath, err) -- } -- }) -- return goplsPath --} -- --// A SidecarServer starts (and connects to) a separate gopls process at the --// given path. --type SidecarServer struct { -- goplsPath string -- env []string // additional environment bindings -- args []string // command-line arguments --} -- --// Connect creates new io.Pipes and binds them to the underlying StreamServer. --// --// It implements the servertest.Connector interface. --func (s *SidecarServer) Connect(ctx context.Context) jsonrpc2.Conn { -- // Note: don't use CommandContext here, as we want gopls to exit gracefully -- // in order to write out profile data. -- // -- // We close the connection on context cancelation below. -- cmd := exec.Command(s.goplsPath, s.args...) -- -- stdin, err := cmd.StdinPipe() -- if err != nil { -- log.Fatal(err) -- } -- stdout, err := cmd.StdoutPipe() -- if err != nil { -- log.Fatal(err) -- } -- cmd.Stderr = os.Stderr -- cmd.Env = append(os.Environ(), s.env...) -- if err := cmd.Start(); err != nil { -- log.Fatalf("starting gopls: %v", err) -- } -- -- go func() { -- // If we don't log.Fatal here, benchmarks may hang indefinitely if gopls -- // exits abnormally. -- // -- // TODO(rfindley): ideally we would shut down the connection gracefully, -- // but that doesn't currently work. -- if err := cmd.Wait(); err != nil { -- log.Fatalf("gopls invocation failed with error: %v", err) -- } -- }() -- -- clientStream := jsonrpc2.NewHeaderStream(fakenet.NewConn("stdio", stdout, stdin)) -- clientConn := jsonrpc2.NewConn(clientStream) -- -- go func() { -- select { -- case <-ctx.Done(): -- clientConn.Close() -- clientStream.Close() -- case <-clientConn.Done(): -- } -- }() -- -- return clientConn --} -- --// startProfileIfSupported checks to see if the remote gopls instance supports --// the start/stop profiling commands. If so, it starts profiling and returns a --// function that stops profiling and records the total CPU seconds sampled in the --// cpu_seconds benchmark metric. --// --// If the remote gopls instance does not support profiling commands, this --// function returns nil. --// --// If the supplied userSuffix is non-empty, the profile is written to --// ., and not deleted when the benchmark exits. Otherwise, --// the profile is written to a temp file that is deleted after the cpu_seconds --// metric has been computed. --func startProfileIfSupported(b *testing.B, env *regtest.Env, name string) func() { -- if !env.Editor.HasCommand(command.StartProfile.ID()) { -- return nil -- } -- b.StopTimer() -- stopProfile := env.StartProfile() -- b.StartTimer() -- return func() { -- b.StopTimer() -- profFile := stopProfile() -- totalCPU, err := totalCPUForProfile(profFile) -- if err != nil { -- b.Fatalf("reading profile: %v", err) -- } -- b.ReportMetric(totalCPU.Seconds()/float64(b.N), "cpu_seconds/op") -- if *cpuProfile == "" { -- // The user didn't request profiles, so delete it to clean up. -- if err := os.Remove(profFile); err != nil { -- b.Errorf("removing profile file: %v", err) -- } -- } else { -- // NOTE: if this proves unreliable (due to e.g. EXDEV), we can fall back -- // on Read+Write+Remove. -- name := qualifiedName(name, *cpuProfile) -- if err := os.Rename(profFile, name); err != nil { -- b.Fatalf("renaming profile file: %v", err) -- } -- } -- } --} -- --// totalCPUForProfile reads the pprof profile with the given file name, parses, --// and aggregates the total CPU sampled during the profile. --func totalCPUForProfile(filename string) (time.Duration, error) { -- protoGz, err := os.ReadFile(filename) -- if err != nil { -- return 0, err -- } -- rd, err := gzip.NewReader(bytes.NewReader(protoGz)) -- if err != nil { -- return 0, fmt.Errorf("creating gzip reader for %s: %v", filename, err) -- } -- data, err := io.ReadAll(rd) -- if err != nil { -- return 0, fmt.Errorf("reading %s: %v", filename, err) -- } -- return pprof.TotalTime(data) --} -- --// closeBuffer stops the benchmark timer and closes the buffer with the given --// name. --// --// It may be used to clean up files opened in the shared environment during --// benchmarking. --func closeBuffer(b *testing.B, env *regtest.Env, name string) { -- b.StopTimer() -- env.CloseBuffer(name) -- env.AfterChange() -- b.StartTimer() --} -diff -urN a/gopls/internal/regtest/bench/codeaction_test.go b/gopls/internal/regtest/bench/codeaction_test.go ---- a/gopls/internal/regtest/bench/codeaction_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/codeaction_test.go 1970-01-01 08:00:00 -@@ -1,69 +0,0 @@ --// Copyright 2023 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 bench -- --import ( -- "fmt" -- "sync/atomic" -- "testing" -- -- "golang.org/x/tools/gopls/internal/lsp/protocol" --) -- --func BenchmarkCodeAction(b *testing.B) { -- for _, test := range didChangeTests { -- b.Run(test.repo, func(b *testing.B) { -- env := getRepo(b, test.repo).sharedEnv(b) -- env.OpenFile(test.file) -- defer closeBuffer(b, env, test.file) -- env.AfterChange() -- -- env.CodeAction(test.file, nil) // pre-warm -- -- b.ResetTimer() -- -- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "hover")); stopAndRecord != nil { -- defer stopAndRecord() -- } -- -- for i := 0; i < b.N; i++ { -- env.CodeAction(test.file, nil) -- } -- }) -- } --} -- --func BenchmarkCodeActionFollowingEdit(b *testing.B) { -- for _, test := range didChangeTests { -- b.Run(test.repo, func(b *testing.B) { -- env := getRepo(b, test.repo).sharedEnv(b) -- env.OpenFile(test.file) -- defer closeBuffer(b, env, test.file) -- env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"}) -- env.AfterChange() -- -- env.CodeAction(test.file, nil) // pre-warm -- -- b.ResetTimer() -- -- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "hover")); stopAndRecord != nil { -- defer stopAndRecord() -- } -- -- for i := 0; i < b.N; i++ { -- edits := atomic.AddInt64(&editID, 1) -- env.EditBuffer(test.file, protocol.TextEdit{ -- Range: protocol.Range{ -- Start: protocol.Position{Line: 0, Character: 0}, -- End: protocol.Position{Line: 1, Character: 0}, -- }, -- // Increment the placeholder text, to ensure cache misses. -- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), -- }) -- env.CodeAction(test.file, nil) -- } -- }) -- } --} -diff -urN a/gopls/internal/regtest/bench/completion_test.go b/gopls/internal/regtest/bench/completion_test.go ---- a/gopls/internal/regtest/bench/completion_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/completion_test.go 1970-01-01 08:00:00 -@@ -1,290 +0,0 @@ --// Copyright 2020 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 bench -- --import ( -- "flag" -- "fmt" -- "sync/atomic" -- "testing" -- -- "golang.org/x/tools/gopls/internal/lsp/fake" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" --) -- --// TODO(rfindley): update these completion tests to run on multiple repos. -- --type completionBenchOptions struct { -- file, locationRegexp string -- -- // Hooks to run edits before initial completion -- setup func(*Env) // run before the benchmark starts -- beforeCompletion func(*Env) // run before each completion --} -- --func benchmarkCompletion(options completionBenchOptions, b *testing.B) { -- repo := getRepo(b, "tools") -- _ = repo.sharedEnv(b) // ensure cache is warm -- env := repo.newEnv(b, fake.EditorConfig{}, "completion", false) -- defer env.Close() -- -- // Run edits required for this completion. -- if options.setup != nil { -- options.setup(env) -- } -- -- // Run a completion to make sure the system is warm. -- loc := env.RegexpSearch(options.file, options.locationRegexp) -- completions := env.Completion(loc) -- -- if testing.Verbose() { -- fmt.Println("Results:") -- for i := 0; i < len(completions.Items); i++ { -- fmt.Printf("\t%d. %v\n", i, completions.Items[i]) -- } -- } -- -- b.Run("tools", func(b *testing.B) { -- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName("tools", "completion")); stopAndRecord != nil { -- defer stopAndRecord() -- } -- -- for i := 0; i < b.N; i++ { -- if options.beforeCompletion != nil { -- options.beforeCompletion(env) -- } -- env.Completion(loc) -- } -- }) --} -- --// endRangeInBuffer returns the position for last character in the buffer for --// the given file. --func endRangeInBuffer(env *Env, name string) protocol.Range { -- buffer := env.BufferText(name) -- m := protocol.NewMapper("", []byte(buffer)) -- rng, err := m.OffsetRange(len(buffer), len(buffer)) -- if err != nil { -- env.T.Fatal(err) -- } -- return rng --} -- --// Benchmark struct completion in tools codebase. --func BenchmarkStructCompletion(b *testing.B) { -- file := "internal/lsp/cache/session.go" -- -- setup := func(env *Env) { -- env.OpenFile(file) -- env.EditBuffer(file, protocol.TextEdit{ -- Range: endRangeInBuffer(env, file), -- NewText: "\nvar testVariable map[string]bool = Session{}.\n", -- }) -- } -- -- benchmarkCompletion(completionBenchOptions{ -- file: file, -- locationRegexp: `var testVariable map\[string\]bool = Session{}(\.)`, -- setup: setup, -- }, b) --} -- --// Benchmark import completion in tools codebase. --func BenchmarkImportCompletion(b *testing.B) { -- const file = "internal/lsp/source/completion/completion.go" -- benchmarkCompletion(completionBenchOptions{ -- file: file, -- locationRegexp: `go\/()`, -- setup: func(env *Env) { env.OpenFile(file) }, -- }, b) --} -- --// Benchmark slice completion in tools codebase. --func BenchmarkSliceCompletion(b *testing.B) { -- file := "internal/lsp/cache/session.go" -- -- setup := func(env *Env) { -- env.OpenFile(file) -- env.EditBuffer(file, protocol.TextEdit{ -- Range: endRangeInBuffer(env, file), -- NewText: "\nvar testVariable []byte = \n", -- }) -- } -- -- benchmarkCompletion(completionBenchOptions{ -- file: file, -- locationRegexp: `var testVariable \[\]byte (=)`, -- setup: setup, -- }, b) --} -- --// Benchmark deep completion in function call in tools codebase. --func BenchmarkFuncDeepCompletion(b *testing.B) { -- file := "internal/lsp/source/completion/completion.go" -- fileContent := ` --func (c *completer) _() { -- c.inference.kindMatches(c.) --} --` -- setup := func(env *Env) { -- env.OpenFile(file) -- originalBuffer := env.BufferText(file) -- env.EditBuffer(file, protocol.TextEdit{ -- Range: endRangeInBuffer(env, file), -- // TODO(rfindley): this is a bug: it should just be fileContent. -- NewText: originalBuffer + fileContent, -- }) -- } -- -- benchmarkCompletion(completionBenchOptions{ -- file: file, -- locationRegexp: `func \(c \*completer\) _\(\) {\n\tc\.inference\.kindMatches\((c)`, -- setup: setup, -- }, b) --} -- --type completionFollowingEditTest struct { -- repo string -- name string -- file string // repo-relative file to create -- content string // file content -- locationRegexp string // regexp for completion --} -- --var completionFollowingEditTests = []completionFollowingEditTest{ -- { -- "tools", -- "selector", -- "internal/lsp/source/completion/completion2.go", -- ` --package completion -- --func (c *completer) _() { -- c.inference.kindMatches(c.) --} --`, -- `func \(c \*completer\) _\(\) {\n\tc\.inference\.kindMatches\((c)`, -- }, -- { -- "kubernetes", -- "selector", -- "pkg/kubelet/kubelet2.go", -- ` --package kubelet -- --func (kl *Kubelet) _() { -- kl. --} --`, -- `kl\.()`, -- }, -- { -- "kubernetes", -- "identifier", -- "pkg/kubelet/kubelet2.go", -- ` --package kubelet -- --func (kl *Kubelet) _() { -- k // here --} --`, -- `k() // here`, -- }, -- { -- "oracle", -- "selector", -- "dataintegration/pivot2.go", -- ` --package dataintegration -- --func (p *Pivot) _() { -- p. +-func _() { +- var foo map[string]any +- foo.ifnotnil -} -`, -- `p\.()`, -- }, --} -- --// Benchmark completion following an arbitrary edit. --// --// Edits force type-checked packages to be invalidated, so we want to measure --// how long it takes before completion results are available. --func BenchmarkCompletionFollowingEdit(b *testing.B) { -- for _, test := range completionFollowingEditTests { -- b.Run(fmt.Sprintf("%s_%s", test.repo, test.name), func(b *testing.B) { -- for _, completeUnimported := range []bool{true, false} { -- b.Run(fmt.Sprintf("completeUnimported=%v", completeUnimported), func(b *testing.B) { -- for _, budget := range []string{"0s", "100ms"} { -- b.Run(fmt.Sprintf("budget=%s", budget), func(b *testing.B) { -- runCompletionFollowingEdit(b, test, completeUnimported, budget) -- }) -- } -- }) -- } -- }) -- } --} -- --var gomodcache = flag.String("gomodcache", "", "optional GOMODCACHE for unimported completion benchmarks") -- --func runCompletionFollowingEdit(b *testing.B, test completionFollowingEditTest, completeUnimported bool, budget string) { -- repo := getRepo(b, test.repo) -- sharedEnv := repo.sharedEnv(b) // ensure cache is warm -- envvars := map[string]string{ -- "GOPATH": sharedEnv.Sandbox.GOPATH(), // use the warm cache -- } -- -- if *gomodcache != "" { -- envvars["GOMODCACHE"] = *gomodcache -- } -- -- env := repo.newEnv(b, fake.EditorConfig{ -- Env: envvars, -- Settings: map[string]interface{}{ -- "completeUnimported": completeUnimported, -- "completionBudget": budget, -- }, -- }, "completionFollowingEdit", false) -- defer env.Close() -- -- env.CreateBuffer(test.file, "// __REGTEST_PLACEHOLDER_0__\n"+test.content) -- editPlaceholder := func() { -- edits := atomic.AddInt64(&editID, 1) -- env.EditBuffer(test.file, protocol.TextEdit{ -- Range: protocol.Range{ -- Start: protocol.Position{Line: 0, Character: 0}, -- End: protocol.Position{Line: 1, Character: 0}, -- }, -- // Increment the placeholder text, to ensure cache misses. -- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), -- }) -- } -- env.AfterChange() -- -- // Run a completion to make sure the system is warm. -- loc := env.RegexpSearch(test.file, test.locationRegexp) -- completions := env.Completion(loc) -- -- if testing.Verbose() { -- fmt.Println("Results:") -- for i, item := range completions.Items { -- fmt.Printf("\t%d. %v\n", i, item) -- } -- } -- -- b.ResetTimer() -- -- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "completionFollowingEdit")); stopAndRecord != nil { -- defer stopAndRecord() -- } -- -- for i := 0; i < b.N; i++ { -- editPlaceholder() -- loc := env.RegexpSearch(test.file, test.locationRegexp) -- env.Completion(loc) -- } --} -diff -urN a/gopls/internal/regtest/bench/definition_test.go b/gopls/internal/regtest/bench/definition_test.go ---- a/gopls/internal/regtest/bench/definition_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/definition_test.go 1970-01-01 08:00:00 -@@ -1,46 +0,0 @@ --// Copyright 2023 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 bench -- --import ( -- "testing" --) -- --func BenchmarkDefinition(b *testing.B) { -- tests := []struct { -- repo string -- file string -- regexp string -- }{ -- {"istio", "pkg/config/model.go", `gogotypes\.(MarshalAny)`}, -- {"google-cloud-go", "httpreplay/httpreplay.go", `proxy\.(ForRecording)`}, -- {"kubernetes", "pkg/controller/lookup_cache.go", `hashutil\.(DeepHashObject)`}, -- {"kuma", "api/generic/insights.go", `proto\.(Message)`}, -- {"pkgsite", "internal/log/log.go", `derrors\.(Wrap)`}, -- {"starlark", "starlark/eval.go", "prog.compiled.(Encode)"}, -- {"tools", "internal/lsp/cache/check.go", `(snapshot)\) buildKey`}, -- } -- -- for _, test := range tests { -- b.Run(test.repo, func(b *testing.B) { -- env := getRepo(b, test.repo).sharedEnv(b) -- env.OpenFile(test.file) -- defer closeBuffer(b, env, test.file) -- -- loc := env.RegexpSearch(test.file, test.regexp) -- env.Await(env.DoneWithOpen()) -- env.GoToDefinition(loc) // pre-warm the query, and open the target file -- b.ResetTimer() -- -- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "definition")); stopAndRecord != nil { -- defer stopAndRecord() -- } -- -- for i := 0; i < b.N; i++ { -- env.GoToDefinition(loc) // pre-warm the query -- } -- }) -- } --} -diff -urN a/gopls/internal/regtest/bench/didchange_test.go b/gopls/internal/regtest/bench/didchange_test.go ---- a/gopls/internal/regtest/bench/didchange_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/didchange_test.go 1970-01-01 08:00:00 -@@ -1,142 +0,0 @@ --// Copyright 2022 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 bench -- --import ( -- "fmt" -- "sync/atomic" -- "testing" -- "time" -- -- "golang.org/x/tools/gopls/internal/lsp/fake" -- "golang.org/x/tools/gopls/internal/lsp/protocol" --) -- --// Use a global edit counter as bench function may execute multiple times, and --// we want to avoid cache hits. Use time.Now to also avoid cache hits from the --// shared file cache. --var editID int64 = time.Now().UnixNano() -- --type changeTest struct { -- repo string -- file string -- canSave bool --} -- --var didChangeTests = []changeTest{ -- {"google-cloud-go", "internal/annotate.go", true}, -- {"istio", "pkg/fuzz/util.go", true}, -- {"kubernetes", "pkg/controller/lookup_cache.go", true}, -- {"kuma", "api/generic/insights.go", true}, -- {"oracle", "dataintegration/data_type.go", false}, // diagnoseSave fails because this package is generated -- {"pkgsite", "internal/frontend/server.go", true}, -- {"starlark", "starlark/eval.go", true}, -- {"tools", "internal/lsp/cache/snapshot.go", true}, --} -- --// BenchmarkDidChange benchmarks modifications of a single file by making --// synthetic modifications in a comment. It controls pacing by waiting for the --// server to actually start processing the didChange notification before --// proceeding. Notably it does not wait for diagnostics to complete. --func BenchmarkDidChange(b *testing.B) { -- for _, test := range didChangeTests { -- b.Run(test.repo, func(b *testing.B) { -- env := getRepo(b, test.repo).sharedEnv(b) -- env.OpenFile(test.file) -- defer closeBuffer(b, env, test.file) -- -- // Insert the text we'll be modifying at the top of the file. -- env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"}) -- env.AfterChange() -- b.ResetTimer() -- -- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "didchange")); stopAndRecord != nil { -- defer stopAndRecord() -- } -- -- for i := 0; i < b.N; i++ { -- edits := atomic.AddInt64(&editID, 1) -- env.EditBuffer(test.file, protocol.TextEdit{ -- Range: protocol.Range{ -- Start: protocol.Position{Line: 0, Character: 0}, -- End: protocol.Position{Line: 1, Character: 0}, -- }, -- // Increment the placeholder text, to ensure cache misses. -- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), -- }) -- env.Await(env.StartedChange()) -- } -- }) -- } --} -- --func BenchmarkDiagnoseChange(b *testing.B) { -- for _, test := range didChangeTests { -- runChangeDiagnosticsBenchmark(b, test, false, "diagnoseChange") -- } --} -- --// TODO(rfindley): add a benchmark for with a metadata-affecting change, when --// this matters. --func BenchmarkDiagnoseSave(b *testing.B) { -- for _, test := range didChangeTests { -- runChangeDiagnosticsBenchmark(b, test, true, "diagnoseSave") -- } --} -- --// runChangeDiagnosticsBenchmark runs a benchmark to edit the test file and --// await the resulting diagnostics pass. If save is set, the file is also saved. --func runChangeDiagnosticsBenchmark(b *testing.B, test changeTest, save bool, operation string) { -- b.Run(test.repo, func(b *testing.B) { -- if !test.canSave { -- b.Skipf("skipping as %s cannot be saved", test.file) -- } -- sharedEnv := getRepo(b, test.repo).sharedEnv(b) -- config := fake.EditorConfig{ -- Env: map[string]string{ -- "GOPATH": sharedEnv.Sandbox.GOPATH(), -- }, -- Settings: map[string]interface{}{ -- "diagnosticsDelay": "0s", -- }, -- } -- // Use a new env to avoid the diagnostic delay: we want to measure how -- // long it takes to produce the diagnostics. -- env := getRepo(b, test.repo).newEnv(b, config, operation, false) -- defer env.Close() -- env.OpenFile(test.file) -- // Insert the text we'll be modifying at the top of the file. -- env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"}) -- if save { -- env.SaveBuffer(test.file) -- } -- env.AfterChange() -- b.ResetTimer() -- -- // We must use an extra subtest layer here, so that we only set up the -- // shared env once (otherwise we pay additional overhead and the profiling -- // flags don't work). -- b.Run("diagnose", func(b *testing.B) { -- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, operation)); stopAndRecord != nil { -- defer stopAndRecord() -- } -- for i := 0; i < b.N; i++ { -- edits := atomic.AddInt64(&editID, 1) -- env.EditBuffer(test.file, protocol.TextEdit{ -- Range: protocol.Range{ -- Start: protocol.Position{Line: 0, Character: 0}, -- End: protocol.Position{Line: 1, Character: 0}, -- }, -- // Increment the placeholder text, to ensure cache misses. -- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), -- }) -- if save { -- env.SaveBuffer(test.file) -- } -- env.AfterChange() -- } -- }) -- }) --} -diff -urN a/gopls/internal/regtest/bench/doc.go b/gopls/internal/regtest/bench/doc.go ---- a/gopls/internal/regtest/bench/doc.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/doc.go 1970-01-01 08:00:00 -@@ -1,40 +0,0 @@ --// Copyright 2023 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. -- --// The bench package implements benchmarks for various LSP operations. --// --// Benchmarks check out specific commits of popular and/or exemplary --// repositories, and script an external gopls process via a fake text editor. --// By default, benchmarks run the test executable as gopls (using a special --// "gopls mode" environment variable). A different gopls binary may be used by --// setting the -gopls_path or -gopls_commit flags. --// --// This package is a work in progress. --// --// # Profiling --// --// Benchmark functions run gopls in a separate process, which means the normal --// test flags for profiling aren't useful. Instead the -gopls_cpuprofile, --// -gopls_memprofile, -gopls_allocprofile, and -gopls_trace flags may be used --// to pass through profiling to the gopls subproces. --// --// Each of these flags sets a suffix for the respective gopls profile, which is --// named according to the schema ... For example, --// setting -gopls_cpuprofile=cpu will result in profiles named tools.iwl.cpu, --// tools.rename.cpu, etc. In some cases, these profiles are for the entire --// gopls subprocess (as in the initial workspace load), whereas in others they --// span only the critical section of the benchmark. It is up to each benchmark --// to implement profiling as appropriate. --// --// # Integration with perf.golang.org --// --// Benchmarks that run with -short are automatically tracked by --// perf.golang.org, at --// https://perf.golang.org/dashboard/?benchmark=all&repository=tools&branch=release-branch.go1.20 --// --// # TODO --// - add more benchmarks, and more repositories --// - fix the perf dashboard to not require the branch= parameter --// - improve this documentation --package bench -diff -urN a/gopls/internal/regtest/bench/hover_test.go b/gopls/internal/regtest/bench/hover_test.go ---- a/gopls/internal/regtest/bench/hover_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/hover_test.go 1970-01-01 08:00:00 -@@ -1,47 +0,0 @@ --// Copyright 2023 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 bench -- --import ( -- "testing" --) -- --func BenchmarkHover(b *testing.B) { -- tests := []struct { -- repo string -- file string -- regexp string -- }{ -- {"google-cloud-go", "httpreplay/httpreplay.go", `proxy\.(ForRecording)`}, -- {"istio", "pkg/config/model.go", `gogotypes\.(MarshalAny)`}, -- {"kubernetes", "pkg/apis/core/types.go", "type (Pod)"}, -- {"kuma", "api/generic/insights.go", `proto\.(Message)`}, -- {"pkgsite", "internal/log/log.go", `derrors\.(Wrap)`}, -- {"starlark", "starlark/eval.go", "prog.compiled.(Encode)"}, -- {"tools", "internal/lsp/cache/check.go", `(snapshot)\) buildKey`}, -- } -- -- for _, test := range tests { -- b.Run(test.repo, func(b *testing.B) { -- env := getRepo(b, test.repo).sharedEnv(b) -- env.OpenFile(test.file) -- defer closeBuffer(b, env, test.file) -- -- loc := env.RegexpSearch(test.file, test.regexp) -- env.AfterChange() -- -- env.Hover(loc) // pre-warm the query -- b.ResetTimer() -- -- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "hover")); stopAndRecord != nil { -- defer stopAndRecord() -- } -- -- for i := 0; i < b.N; i++ { -- env.Hover(loc) // pre-warm the query -- } -- }) -- } --} -diff -urN a/gopls/internal/regtest/bench/implementations_test.go b/gopls/internal/regtest/bench/implementations_test.go ---- a/gopls/internal/regtest/bench/implementations_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/implementations_test.go 1970-01-01 08:00:00 -@@ -1,44 +0,0 @@ --// Copyright 2023 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 bench -- --import "testing" -- --func BenchmarkImplementations(b *testing.B) { -- tests := []struct { -- repo string -- file string -- regexp string -- }{ -- {"google-cloud-go", "httpreplay/httpreplay.go", `type (Recorder)`}, -- {"istio", "pkg/config/mesh/watcher.go", `type (Watcher)`}, -- {"kubernetes", "pkg/controller/lookup_cache.go", `objectWithMeta`}, -- {"kuma", "api/generic/insights.go", `type (Insight)`}, -- {"pkgsite", "internal/datasource.go", `type (DataSource)`}, -- {"starlark", "syntax/syntax.go", `type (Expr)`}, -- {"tools", "internal/lsp/source/view.go", `type (Snapshot)`}, -- } -- -- for _, test := range tests { -- b.Run(test.repo, func(b *testing.B) { -- env := getRepo(b, test.repo).sharedEnv(b) -- env.OpenFile(test.file) -- defer closeBuffer(b, env, test.file) -- -- loc := env.RegexpSearch(test.file, test.regexp) -- env.AfterChange() -- env.Implementations(loc) // pre-warm the query -- b.ResetTimer() -- -- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "implementations")); stopAndRecord != nil { -- defer stopAndRecord() -- } -- -- for i := 0; i < b.N; i++ { -- env.Implementations(loc) -- } -- }) -- } --} -diff -urN a/gopls/internal/regtest/bench/iwl_test.go b/gopls/internal/regtest/bench/iwl_test.go ---- a/gopls/internal/regtest/bench/iwl_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/iwl_test.go 1970-01-01 08:00:00 -@@ -1,76 +0,0 @@ --// Copyright 2022 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 bench -- --import ( -- "testing" -- -- "golang.org/x/tools/gopls/internal/lsp/command" -- "golang.org/x/tools/gopls/internal/lsp/fake" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" --) -- --// BenchmarkInitialWorkspaceLoad benchmarks the initial workspace load time for --// a new editing session. --func BenchmarkInitialWorkspaceLoad(b *testing.B) { -- tests := []struct { -- repo string -- file string -- }{ -- {"google-cloud-go", "httpreplay/httpreplay.go"}, -- {"istio", "pkg/fuzz/util.go"}, -- {"kubernetes", "pkg/controller/lookup_cache.go"}, -- {"kuma", "api/generic/insights.go"}, -- {"oracle", "dataintegration/data_type.go"}, -- {"pkgsite", "internal/frontend/server.go"}, -- {"starlark", "starlark/eval.go"}, -- {"tools", "internal/lsp/cache/snapshot.go"}, -- {"hashiform", "internal/provider/provider.go"}, -- } -- -- for _, test := range tests { -- b.Run(test.repo, func(b *testing.B) { -- repo := getRepo(b, test.repo) -- // get the (initialized) shared env to ensure the cache is warm. -- // Reuse its GOPATH so that we get cache hits for things in the module -- // cache. -- sharedEnv := repo.sharedEnv(b) -- b.ResetTimer() -- -- for i := 0; i < b.N; i++ { -- doIWL(b, sharedEnv.Sandbox.GOPATH(), repo, test.file) -- } -- }) -- } --} -- --func doIWL(b *testing.B, gopath string, repo *repo, file string) { -- // Exclude the time to set up the env from the benchmark time, as this may -- // involve installing gopls and/or checking out the repo dir. -- b.StopTimer() -- config := fake.EditorConfig{Env: map[string]string{"GOPATH": gopath}} -- env := repo.newEnv(b, config, "iwl", true) -- defer env.Close() -- b.StartTimer() -- -- // Note: in the future, we may need to open a file in order to cause gopls to -- // start loading the workspace. -- -- env.Await(InitialWorkspaceLoad) -- -- if env.Editor.HasCommand(command.MemStats.ID()) { -- b.StopTimer() -- params := &protocol.ExecuteCommandParams{ -- Command: command.MemStats.ID(), -- } -- var memstats command.MemStatsResult -- env.ExecuteCommand(params, &memstats) -- b.ReportMetric(float64(memstats.HeapAlloc), "alloc_bytes") -- b.ReportMetric(float64(memstats.HeapInUse), "in_use_bytes") -- b.ReportMetric(float64(memstats.TotalAlloc), "total_alloc_bytes") -- b.StartTimer() -- } --} -diff -urN a/gopls/internal/regtest/bench/references_test.go b/gopls/internal/regtest/bench/references_test.go ---- a/gopls/internal/regtest/bench/references_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/references_test.go 1970-01-01 08:00:00 -@@ -1,44 +0,0 @@ --// Copyright 2023 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 bench -- --import "testing" -- --func BenchmarkReferences(b *testing.B) { -- tests := []struct { -- repo string -- file string -- regexp string -- }{ -- {"google-cloud-go", "httpreplay/httpreplay.go", `func (NewRecorder)`}, -- {"istio", "pkg/config/model.go", "type (Meta)"}, -- {"kubernetes", "pkg/controller/lookup_cache.go", "type (objectWithMeta)"}, // TODO: choose an exported identifier -- {"kuma", "pkg/events/interfaces.go", "type (Event)"}, -- {"pkgsite", "internal/log/log.go", "func (Infof)"}, -- {"starlark", "syntax/syntax.go", "type (Ident)"}, -- {"tools", "internal/lsp/source/view.go", "type (Snapshot)"}, -- } -- -- for _, test := range tests { -- b.Run(test.repo, func(b *testing.B) { -- env := getRepo(b, test.repo).sharedEnv(b) -- env.OpenFile(test.file) -- defer closeBuffer(b, env, test.file) -- -- loc := env.RegexpSearch(test.file, test.regexp) -- env.AfterChange() -- env.References(loc) // pre-warm the query -- b.ResetTimer() -- -- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "references")); stopAndRecord != nil { -- defer stopAndRecord() -- } -- -- for i := 0; i < b.N; i++ { -- env.References(loc) -- } -- }) -- } --} -diff -urN a/gopls/internal/regtest/bench/reload_test.go b/gopls/internal/regtest/bench/reload_test.go ---- a/gopls/internal/regtest/bench/reload_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/reload_test.go 1970-01-01 08:00:00 -@@ -1,52 +0,0 @@ --// Copyright 2023 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 bench -- --import ( -- "testing" -- -- . "golang.org/x/tools/gopls/internal/lsp/regtest" --) -- --// BenchmarkReload benchmarks reloading a file metadata after a change to an import. --// --// This ensures we are able to diagnose a changed file without reloading all --// invalidated packages. See also golang/go#61344 --func BenchmarkReload(b *testing.B) { -- // TODO(rfindley): add more tests, make this test table-driven -- const ( -- repo = "kubernetes" -- // pkg/util/hash is transitively imported by a large number of packages. -- // We should not need to reload those packages to get a diagnostic. -- file = "pkg/util/hash/hash.go" -- ) -- b.Run(repo, func(b *testing.B) { -- env := getRepo(b, repo).sharedEnv(b) +- after: ` +-package foo - -- env.OpenFile(file) -- defer closeBuffer(b, env, file) +-func _() { +- var foo map[string]any +- if foo != nil { +- $0 +-} +-} +-`, +- }, +- { +- name: "if not nil channel", +- before: ` +-package foo - -- env.AfterChange() +-func _() { +- var foo chan int +- foo.ifnotnil +-} +-`, +- after: ` +-package foo - -- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(repo, "reload")); stopAndRecord != nil { -- defer stopAndRecord() -- } +-func _() { +- var foo chan int +- if foo != nil { +- $0 +-} +-} +-`, +- }, +- { +- name: "if not nil function", +- before: ` +-package foo - -- b.ResetTimer() -- for i := 0; i < b.N; i++ { -- // Change the "hash" import. This may result in cache hits, but that's -- // OK: the goal is to ensure that we don't reload more than just the -- // current package. -- env.RegexpReplace(file, `"hash"`, `"hashx"`) -- // Note: don't use env.AfterChange() here: we only want to await the -- // first diagnostic. -- // -- // Awaiting a full diagnosis would await diagnosing everything, which -- // would require reloading everything. -- env.Await(Diagnostics(ForFile(file))) -- env.RegexpReplace(file, `"hashx"`, `"hash"`) -- env.Await(NoDiagnostics(ForFile(file))) -- } -- }) +-func _() { +- var foo func() +- foo.ifnotnil -} -diff -urN a/gopls/internal/regtest/bench/rename_test.go b/gopls/internal/regtest/bench/rename_test.go ---- a/gopls/internal/regtest/bench/rename_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/rename_test.go 1970-01-01 08:00:00 -@@ -1,49 +0,0 @@ --// Copyright 2023 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. +-`, +- after: ` +-package foo - --package bench +-func _() { +- var foo func() +- if foo != nil { +- $0 +-} +-} +-`, +- }, +- } - --import ( -- "fmt" -- "testing" --) +- r := WithOptions( +- Settings{ +- "experimentalPostfixCompletions": true, +- }, +- ) +- r.Run(t, mod, func(t *testing.T, env *Env) { +- env.CreateBuffer("foo.go", "") - --func BenchmarkRename(b *testing.B) { -- tests := []struct { -- repo string -- file string -- regexp string -- baseName string -- }{ -- {"google-cloud-go", "httpreplay/httpreplay.go", `func (NewRecorder)`, "NewRecorder"}, -- {"istio", "pkg/config/model.go", `(Namespace) string`, "Namespace"}, -- {"kubernetes", "pkg/controller/lookup_cache.go", `hashutil\.(DeepHashObject)`, "DeepHashObject"}, -- {"kuma", "pkg/events/interfaces.go", `Delete`, "Delete"}, -- {"pkgsite", "internal/log/log.go", `func (Infof)`, "Infof"}, -- {"starlark", "starlark/eval.go", `Program\) (Filename)`, "Filename"}, -- {"tools", "internal/lsp/cache/snapshot.go", `meta \*(metadataGraph)`, "metadataGraph"}, -- } +- for _, c := range cases { +- t.Run(c.name, func(t *testing.T) { +- c.before = strings.Trim(c.before, "\n") +- c.after = strings.Trim(c.after, "\n") - -- for _, test := range tests { -- names := 0 // bench function may execute multiple times -- b.Run(test.repo, func(b *testing.B) { -- env := getRepo(b, test.repo).sharedEnv(b) -- env.OpenFile(test.file) -- loc := env.RegexpSearch(test.file, test.regexp) -- env.Await(env.DoneWithOpen()) -- env.Rename(loc, test.baseName+"X") // pre-warm the query -- b.ResetTimer() +- env.SetBufferContent("foo.go", c.before) - -- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "rename")); stopAndRecord != nil { -- defer stopAndRecord() -- } +- loc := env.RegexpSearch("foo.go", "\n}") +- completions := env.Completion(loc) +- if len(completions.Items) != 1 { +- t.Fatalf("expected one completion, got %v", completions.Items) +- } - -- for i := 0; i < b.N; i++ { -- names++ -- newName := fmt.Sprintf("%s%d", test.baseName, names) -- env.Rename(loc, newName) -- } -- }) -- } +- env.AcceptCompletion(loc, completions.Items[0]) +- +- if buf := env.BufferText("foo.go"); buf != c.after { +- t.Errorf("\nGOT:\n%s\nEXPECTED:\n%s", buf, c.after) +- } +- }) +- } +- }) -} -diff -urN a/gopls/internal/regtest/bench/repo_test.go b/gopls/internal/regtest/bench/repo_test.go ---- a/gopls/internal/regtest/bench/repo_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/repo_test.go 1970-01-01 08:00:00 -@@ -1,290 +0,0 @@ --// Copyright 2023 The Go Authors. All rights reserved. +diff -urN a/gopls/internal/regtest/debug/debug_test.go b/gopls/internal/regtest/debug/debug_test.go +--- a/gopls/internal/regtest/debug/debug_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/debug/debug_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,101 +0,0 @@ +-// Copyright 2022 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 bench +-package debug - -import ( -- "bytes" - "context" -- "errors" -- "flag" -- "fmt" -- "log" -- "os" -- "path/filepath" -- "sync" +- "encoding/json" +- "io" +- "net/http" +- "strings" - "testing" -- "time" - -- "golang.org/x/tools/gopls/internal/lsp/fake" +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/hooks" +- "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp/protocol" - . "golang.org/x/tools/gopls/internal/lsp/regtest" -) - --// repos holds shared repositories for use in benchmarks. --// --// These repos were selected to represent a variety of different types of --// codebases. --var repos = map[string]*repo{ -- // google-cloud-go has 145 workspace modules (!), and is quite large. -- "google-cloud-go": { -- name: "google-cloud-go", -- url: "https://github.com/googleapis/google-cloud-go.git", -- commit: "07da765765218debf83148cc7ed8a36d6e8921d5", -- inDir: flag.String("cloud_go_dir", "", "if set, reuse this directory as google-cloud-go@07da7657"), -- }, -- -- // Used by x/benchmarks; large. -- "istio": { -- name: "istio", -- url: "https://github.com/istio/istio", -- commit: "1.17.0", -- inDir: flag.String("istio_dir", "", "if set, reuse this directory as istio@v1.17.0"), -- }, -- -- // Kubernetes is a large repo with many dependencies, and in the past has -- // been about as large a repo as gopls could handle. -- "kubernetes": { -- name: "kubernetes", -- url: "https://github.com/kubernetes/kubernetes", -- commit: "v1.24.0", -- short: true, -- inDir: flag.String("kubernetes_dir", "", "if set, reuse this directory as kubernetes@v1.24.0"), -- }, -- -- // A large, industrial application. -- "kuma": { -- name: "kuma", -- url: "https://github.com/kumahq/kuma", -- commit: "2.1.1", -- inDir: flag.String("kuma_dir", "", "if set, reuse this directory as kuma@v2.1.1"), -- }, -- -- // A repo containing a very large package (./dataintegration). -- "oracle": { -- name: "oracle", -- url: "https://github.com/oracle/oci-go-sdk.git", -- commit: "v65.43.0", -- short: true, -- inDir: flag.String("oracle_dir", "", "if set, reuse this directory as oracle/oci-go-sdk@v65.43.0"), -- }, -- -- // x/pkgsite is familiar and represents a common use case (a webserver). It -- // also has a number of static non-go files and template files. -- "pkgsite": { -- name: "pkgsite", -- url: "https://go.googlesource.com/pkgsite", -- commit: "81f6f8d4175ad0bf6feaa03543cc433f8b04b19b", -- short: true, -- inDir: flag.String("pkgsite_dir", "", "if set, reuse this directory as pkgsite@81f6f8d4"), -- }, -- -- // A tiny self-contained project. -- "starlark": { -- name: "starlark", -- url: "https://github.com/google/starlark-go", -- commit: "3f75dec8e4039385901a30981e3703470d77e027", -- short: true, -- inDir: flag.String("starlark_dir", "", "if set, reuse this directory as starlark@3f75dec8"), -- }, -- -- // The current repository, which is medium-small and has very few dependencies. -- "tools": { -- name: "tools", -- url: "https://go.googlesource.com/tools", -- commit: "gopls/v0.9.0", -- short: true, -- inDir: flag.String("tools_dir", "", "if set, reuse this directory as x/tools@v0.9.0"), -- }, -- -- // A repo of similar size to kubernetes, but with substantially more -- // complex types that led to a serious performance regression (issue #60621). -- "hashiform": { -- name: "hashiform", -- url: "https://github.com/hashicorp/terraform-provider-aws", -- commit: "ac55de2b1950972d93feaa250d7505d9ed829c7c", -- inDir: flag.String("hashiform_dir", "", "if set, reuse this directory as hashiform@ac55de2"), -- }, --} -- --// getRepo gets the requested repo, and skips the test if -short is set and --// repo is not configured as a short repo. --func getRepo(tb testing.TB, name string) *repo { -- tb.Helper() -- repo := repos[name] -- if repo == nil { -- tb.Fatalf("repo %s does not exist", name) -- } -- if !repo.short && testing.Short() { -- tb.Skipf("large repo %s does not run with -short", repo.name) -- } -- return repo --} -- --// A repo represents a working directory for a repository checked out at a --// specific commit. --// --// Repos are used for sharing state across benchmarks that operate on the same --// codebase. --type repo struct { -- // static configuration -- name string // must be unique, used for subdirectory -- url string // repo url -- commit string // full commit hash or tag -- short bool // whether this repo runs with -short -- inDir *string // if set, use this dir as url@commit, and don't delete -- -- dirOnce sync.Once -- dir string // directory contaning source code checked out to url@commit -- -- // shared editor state -- editorOnce sync.Once -- editor *fake.Editor -- sandbox *fake.Sandbox -- awaiter *Awaiter +-func TestMain(m *testing.M) { +- Main(m, hooks.Options) -} - --// reusableDir return a reusable directory for benchmarking, or "". --// --// If the user specifies a directory, the test will create and populate it --// on the first run an re-use it on subsequent runs. Otherwise it will --// create, populate, and delete a temporary directory. --func (r *repo) reusableDir() string { -- if r.inDir == nil { -- return "" -- } -- return *r.inDir +-func TestBugNotification(t *testing.T) { +- // Verify that a properly configured session gets notified of a bug on the +- // server. +- WithOptions( +- Modes(Default), // must be in-process to receive the bug report below +- Settings{"showBugReports": true}, +- ).Run(t, "", func(t *testing.T, env *Env) { +- const desc = "got a bug" +- bug.Report(desc) +- env.Await(ShownMessage(desc)) +- }) -} - --// getDir returns directory containing repo source code, creating it if --// necessary. It is safe for concurrent use. --func (r *repo) getDir() string { -- r.dirOnce.Do(func() { -- if r.dir = r.reusableDir(); r.dir == "" { -- r.dir = filepath.Join(getTempDir(), r.name) -- } -- -- _, err := os.Stat(r.dir) -- switch { -- case os.IsNotExist(err): -- log.Printf("cloning %s@%s into %s", r.url, r.commit, r.dir) -- if err := shallowClone(r.dir, r.url, r.commit); err != nil { -- log.Fatal(err) -- } -- case err != nil: -- log.Fatal(err) -- default: -- log.Printf("reusing %s as %s@%s", r.dir, r.url, r.commit) +-// TestStartDebugging executes a gopls.start_debugging command to +-// start the internal web server. +-func TestStartDebugging(t *testing.T) { +- WithOptions( +- Modes(Default|Experimental), // doesn't work in Forwarded mode +- ).Run(t, "", func(t *testing.T, env *Env) { +- // Start a debugging server. +- res, err := startDebugging(env.Ctx, env.Editor.Server, &command.DebuggingArgs{ +- Addr: "", // any free port +- }) +- if err != nil { +- t.Fatalf("startDebugging: %v", err) - } -- }) -- return r.dir --} - --// sharedEnv returns a shared benchmark environment. It is safe for concurrent --// use. --// --// Every call to sharedEnv uses the same editor and sandbox, as a means to --// avoid reinitializing the editor for large repos. Calling repo.Close cleans --// up the shared environment. --// --// Repos in the package-local Repos var are closed at the end of the test main --// function. --func (r *repo) sharedEnv(tb testing.TB) *Env { -- r.editorOnce.Do(func() { -- dir := r.getDir() +- // Assert that the server requested that the +- // client show the debug page in a browser. +- debugURL := res.URLs[0] +- env.Await(ShownDocument(debugURL)) - -- start := time.Now() -- log.Printf("starting initial workspace load for %s", r.name) -- ts, err := newGoplsConnector(profileArgs(r.name, false)) +- // Send a request to the debug server and ensure it responds. +- resp, err := http.Get(debugURL) - if err != nil { -- log.Fatal(err) +- t.Fatal(err) - } -- r.sandbox, r.editor, r.awaiter, err = connectEditor(dir, fake.EditorConfig{}, ts) +- defer resp.Body.Close() +- data, err := io.ReadAll(resp.Body) - if err != nil { -- log.Fatalf("connecting editor: %v", err) +- t.Fatalf("reading HTTP response body: %v", err) - } -- -- if err := r.awaiter.Await(context.Background(), InitialWorkspaceLoad); err != nil { -- log.Fatal(err) +- const want = "GoPls" +- if !strings.Contains(string(data), want) { +- t.Errorf("GET %s response does not contain %q: <<%s>>", debugURL, want, data) - } -- log.Printf("initial workspace load (cold) for %s took %v", r.name, time.Since(start)) - }) -- -- return &Env{ -- T: tb, -- Ctx: context.Background(), -- Editor: r.editor, -- Sandbox: r.sandbox, -- Awaiter: r.awaiter, -- } -} - --// newEnv returns a new Env connected to a new gopls process communicating --// over stdin/stdout. It is safe for concurrent use. --// --// It is the caller's responsibility to call Close on the resulting Env when it --// is no longer needed. --func (r *repo) newEnv(tb testing.TB, config fake.EditorConfig, forOperation string, cpuProfile bool) *Env { -- dir := r.getDir() -- -- args := profileArgs(qualifiedName(r.name, forOperation), cpuProfile) -- ts, err := newGoplsConnector(args) +-// startDebugging starts a debugging server. +-// TODO(adonovan): move into command package? +-func startDebugging(ctx context.Context, server protocol.Server, args *command.DebuggingArgs) (*command.DebuggingResult, error) { +- rawArgs, err := command.MarshalArgs(args) - if err != nil { -- tb.Fatal(err) +- return nil, err - } -- sandbox, editor, awaiter, err := connectEditor(dir, config, ts) +- res0, err := server.ExecuteCommand(ctx, &protocol.ExecuteCommandParams{ +- Command: command.StartDebugging.ID(), +- Arguments: rawArgs, +- }) - if err != nil { -- log.Fatalf("connecting editor: %v", err) -- } -- -- return &Env{ -- T: tb, -- Ctx: context.Background(), -- Editor: editor, -- Sandbox: sandbox, -- Awaiter: awaiter, -- } --} -- --// Close cleans up shared state referenced by the repo. --func (r *repo) Close() error { -- var errBuf bytes.Buffer -- if r.editor != nil { -- if err := r.editor.Close(context.Background()); err != nil { -- fmt.Fprintf(&errBuf, "closing editor: %v", err) -- } -- } -- if r.sandbox != nil { -- if err := r.sandbox.Close(); err != nil { -- fmt.Fprintf(&errBuf, "closing sandbox: %v", err) -- } -- } -- if r.dir != "" && r.reusableDir() == "" { -- if err := os.RemoveAll(r.dir); err != nil { -- fmt.Fprintf(&errBuf, "cleaning dir: %v", err) -- } -- } -- if errBuf.Len() > 0 { -- return errors.New(errBuf.String()) -- } -- return nil --} -- --// cleanup cleans up state that is shared across benchmark functions. --func cleanup() error { -- var errBuf bytes.Buffer -- for _, repo := range repos { -- if err := repo.Close(); err != nil { -- fmt.Fprintf(&errBuf, "closing %q: %v", repo.name, err) -- } +- return nil, err - } -- if tempDir != "" { -- if err := os.RemoveAll(tempDir); err != nil { -- fmt.Fprintf(&errBuf, "cleaning tempDir: %v", err) -- } +- // res0 is the result of a schemaless (map[string]any) JSON decoding. +- // Re-encode and decode into the correct Go struct type. +- // TODO(adonovan): fix (*serverDispatcher).ExecuteCommand. +- data, err := json.Marshal(res0) +- if err != nil { +- return nil, err - } -- if errBuf.Len() > 0 { -- return errors.New(errBuf.String()) +- var res *command.DebuggingResult +- if err := json.Unmarshal(data, &res); err != nil { +- return nil, err - } -- return nil +- return res, nil -} -diff -urN a/gopls/internal/regtest/bench/stress_test.go b/gopls/internal/regtest/bench/stress_test.go ---- a/gopls/internal/regtest/bench/stress_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/stress_test.go 1970-01-01 08:00:00 -@@ -1,94 +0,0 @@ --// Copyright 2020 The Go Authors. All rights reserved. +diff -urN a/gopls/internal/regtest/diagnostics/analysis_test.go b/gopls/internal/regtest/diagnostics/analysis_test.go +--- a/gopls/internal/regtest/diagnostics/analysis_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/diagnostics/analysis_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,127 +0,0 @@ +-// Copyright 2022 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 bench +-package diagnostics - -import ( -- "context" -- "flag" - "fmt" - "testing" -- "time" - -- "golang.org/x/tools/gopls/internal/hooks" - "golang.org/x/tools/gopls/internal/lsp/cache" -- "golang.org/x/tools/gopls/internal/lsp/fake" -- "golang.org/x/tools/gopls/internal/lsp/lsprpc" -- "golang.org/x/tools/internal/jsonrpc2" -- "golang.org/x/tools/internal/jsonrpc2/servertest" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" -) - --// github.com/pilosa/pilosa is a repository that has historically caused --// significant memory problems for Gopls. We use it for a simple stress test --// that types arbitrarily in a file with lots of dependents. +-// Test for the timeformat analyzer, following golang/vscode-go#2406. +-// +-// This test checks that applying the suggested fix from the analyzer resolves +-// the diagnostic warning. +-func TestTimeFormatAnalyzer(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - --var pilosaPath = flag.String("pilosa_path", "", "Path to a directory containing "+ -- "github.com/pilosa/pilosa, for stress testing. Do not set this unless you "+ -- "know what you're doing!") +-go 1.18 +--- main.go -- +-package main - --func TestPilosaStress(t *testing.T) { -- // TODO(rfindley): revisit this test and make it is hermetic: it should check -- // out pilosa into a directory. -- // -- // Note: This stress test has not been run recently, and may no longer -- // function properly. -- if *pilosaPath == "" { -- t.Skip("-pilosa_path not configured") -- } +-import ( +- "fmt" +- "time" +-) - -- sandbox, err := fake.NewSandbox(&fake.SandboxConfig{ -- Workdir: *pilosaPath, -- GOPROXY: "https://proxy.golang.org", +-func main() { +- now := time.Now() +- fmt.Println(now.Format("2006-02-01")) +-}` +- +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- +- var d protocol.PublishDiagnosticsParams +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", "2006-02-01")), +- ReadDiagnostics("main.go", &d), +- ) +- +- env.ApplyQuickFixes("main.go", d.Diagnostics) +- env.AfterChange(NoDiagnostics(ForFile("main.go"))) - }) -- if err != nil { -- t.Fatal(err) -- } +-} - -- server := lsprpc.NewStreamServer(cache.New(nil), false, hooks.Options) -- ts := servertest.NewPipeServer(server, jsonrpc2.NewRawStream) -- ctx := context.Background() +-func TestAnalysisProgressReporting(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - -- const skipApplyEdits = false -- editor, err := fake.NewEditor(sandbox, fake.EditorConfig{}).Connect(ctx, ts, fake.ClientHooks{}, skipApplyEdits) -- if err != nil { -- t.Fatal(err) -- } +-go 1.18 - -- files := []string{ -- "cmd.go", -- "internal/private.pb.go", -- "roaring/roaring.go", -- "roaring/roaring_internal_test.go", -- "server/handler_test.go", -- } -- for _, file := range files { -- if err := editor.OpenFile(ctx, file); err != nil { -- t.Fatal(err) -- } -- } -- ctx, cancel := context.WithTimeout(ctx, 10*time.Minute) -- defer cancel() +--- main.go -- +-package main - -- i := 1 -- // MagicNumber is an identifier that occurs in roaring.go. Just change it -- // arbitrarily. -- if err := editor.RegexpReplace(ctx, "roaring/roaring.go", "MagicNumber", fmt.Sprintf("MagicNumber%d", 1)); err != nil { -- t.Fatal(err) +-func main() { +-}` +- +- tests := []struct { +- setting bool +- want Expectation +- }{ +- {true, CompletedWork(cache.AnalysisProgressTitle, 1, true)}, +- {false, Not(CompletedWork(cache.AnalysisProgressTitle, 1, true))}, - } -- for { -- select { -- case <-ctx.Done(): -- return -- default: -- } -- if err := editor.RegexpReplace(ctx, "roaring/roaring.go", fmt.Sprintf("MagicNumber%d", i), fmt.Sprintf("MagicNumber%d", i+1)); err != nil { -- t.Fatal(err) -- } -- // Simulate (very fast) typing. -- // -- // Typing 80 wpm ~150ms per keystroke. -- time.Sleep(150 * time.Millisecond) -- i++ +- +- for _, test := range tests { +- t.Run(fmt.Sprint(test.setting), func(t *testing.T) { +- WithOptions( +- Settings{ +- "reportAnalysisProgressAfter": "0s", +- "analysisProgressReporting": test.setting, +- }, +- ).Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.AfterChange(test.want) +- }) +- }) - } -} -diff -urN a/gopls/internal/regtest/bench/typing_test.go b/gopls/internal/regtest/bench/typing_test.go ---- a/gopls/internal/regtest/bench/typing_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/typing_test.go 1970-01-01 08:00:00 -@@ -1,63 +0,0 @@ --// Copyright 2023 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 bench +-// Test the embed directive analyzer. +-// +-// There is a fix for missing imports, but it should not trigger for other +-// kinds of issues reported by the analayzer, here the variable +-// declaration following the embed directive is wrong. +-func TestNoSuggestedFixesForEmbedDirectiveDeclaration(t *testing.T) { +- const generated = ` +--- go.mod -- +-module mod.com - --import ( -- "fmt" -- "sync/atomic" -- "testing" -- "time" +-go 1.20 - -- "golang.org/x/tools/gopls/internal/lsp/protocol" --) +--- foo.txt -- +-FOO - --// BenchmarkTyping simulates typing steadily in a single file at different --// paces. --// --// The key metric for this benchmark is not latency, but cpu_seconds per --// operation. --func BenchmarkTyping(b *testing.B) { -- for _, test := range didChangeTests { -- b.Run(test.repo, func(b *testing.B) { -- env := getRepo(b, test.repo).sharedEnv(b) -- env.OpenFile(test.file) -- defer closeBuffer(b, env, test.file) +--- main.go -- +-package main - -- // Insert the text we'll be modifying at the top of the file. -- env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"}) -- env.AfterChange() +-import _ "embed" - -- delays := []time.Duration{ -- 10 * time.Millisecond, // automated changes -- 50 * time.Millisecond, // very fast mashing, or fast key sequences -- 150 * time.Millisecond, // avg interval for 80wpm typing. -- } +-//go:embed foo.txt +-var foo, bar string - -- for _, delay := range delays { -- b.Run(delay.String(), func(b *testing.B) { -- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "typing")); stopAndRecord != nil { -- defer stopAndRecord() -- } -- ticker := time.NewTicker(delay) -- for i := 0; i < b.N; i++ { -- edits := atomic.AddInt64(&editID, 1) -- env.EditBuffer(test.file, protocol.TextEdit{ -- Range: protocol.Range{ -- Start: protocol.Position{Line: 0, Character: 0}, -- End: protocol.Position{Line: 1, Character: 0}, -- }, -- // Increment the placeholder text, to ensure cache misses. -- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), -- }) -- <-ticker.C -- } -- b.StopTimer() -- ticker.Stop() -- env.AfterChange() // wait for all change processing to complete -- }) -- } -- }) -- } +-func main() { +- _ = foo -} -diff -urN a/gopls/internal/regtest/bench/workspace_symbols_test.go b/gopls/internal/regtest/bench/workspace_symbols_test.go ---- a/gopls/internal/regtest/bench/workspace_symbols_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/workspace_symbols_test.go 1970-01-01 08:00:00 -@@ -1,41 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. +-` +- Run(t, generated, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- var d protocol.PublishDiagnosticsParams +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", "//go:embed")), +- ReadDiagnostics("main.go", &d), +- ) +- if fixes := env.GetQuickFixes("main.go", d.Diagnostics); len(fixes) != 0 { +- t.Errorf("got quick fixes %v, wanted none", fixes) +- } +- }) +-} +diff -urN a/gopls/internal/regtest/diagnostics/builtin_test.go b/gopls/internal/regtest/diagnostics/builtin_test.go +--- a/gopls/internal/regtest/diagnostics/builtin_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/diagnostics/builtin_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,35 +0,0 @@ +-// Copyright 2021 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 bench +-package diagnostics - -import ( -- "flag" -- "fmt" +- "strings" - "testing" --) -- --var symbolQuery = flag.String("symbol_query", "test", "symbol query to use in benchmark") - --// BenchmarkWorkspaceSymbols benchmarks the time to execute a workspace symbols --// request (controlled by the -symbol_query flag). --func BenchmarkWorkspaceSymbols(b *testing.B) { -- for name := range repos { -- b.Run(name, func(b *testing.B) { -- env := getRepo(b, name).sharedEnv(b) -- symbols := env.Symbol(*symbolQuery) // warm the cache -- -- if testing.Verbose() { -- fmt.Println("Results:") -- for i, symbol := range symbols { -- fmt.Printf("\t%d. %s (%s)\n", i, symbol.Name, symbol.ContainerName) -- } -- } +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) - -- b.ResetTimer() +-func TestIssue44866(t *testing.T) { +- src := ` +--- go.mod -- +-module mod.com - -- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(name, "workspaceSymbols")); stopAndRecord != nil { -- defer stopAndRecord() -- } +-go 1.12 +--- a.go -- +-package a - -- for i := 0; i < b.N; i++ { -- env.Symbol(*symbolQuery) -- } -- }) -- } +-const ( +- c = iota +-) +-` +- Run(t, src, func(t *testing.T, env *Env) { +- env.OpenFile("a.go") +- loc := env.GoToDefinition(env.RegexpSearch("a.go", "iota")) +- if !strings.HasSuffix(string(loc.URI), "builtin.go") { +- t.Fatalf("jumped to %q, want builtin.go", loc.URI) +- } +- env.AfterChange(NoDiagnostics(ForFile("builtin.go"))) +- }) -} -diff -urN a/gopls/internal/regtest/codelens/codelens_test.go b/gopls/internal/regtest/codelens/codelens_test.go ---- a/gopls/internal/regtest/codelens/codelens_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/codelens/codelens_test.go 1970-01-01 08:00:00 -@@ -1,348 +0,0 @@ +diff -urN a/gopls/internal/regtest/diagnostics/diagnostics_test.go b/gopls/internal/regtest/diagnostics/diagnostics_test.go +--- a/gopls/internal/regtest/diagnostics/diagnostics_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/diagnostics/diagnostics_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,2155 +0,0 @@ -// Copyright 2020 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 codelens +-package diagnostics - -import ( +- "context" - "fmt" +- "os/exec" - "testing" - - "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/hooks" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/gopls/internal/lsp/tests/compare" -- -- "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp" +- "golang.org/x/tools/gopls/internal/lsp/fake" - "golang.org/x/tools/gopls/internal/lsp/protocol" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" - "golang.org/x/tools/internal/testenv" -) - @@ -115147,2300 +113281,2214 @@ diff -urN a/gopls/internal/regtest/codelens/codelens_test.go b/gopls/internal/re - Main(m, hooks.Options) -} - --func TestDisablingCodeLens(t *testing.T) { -- const workspace = ` +-// Use mod.com for all go.mod files due to golang/go#35230. +-const exampleProgram = ` --- go.mod -- --module codelens.test +-module mod.com - -go 1.12 ---- lib.go -- --package lib +--- main.go -- +-package main - --type Number int +-import "fmt" - --const ( -- Zero Number = iota -- One -- Two --) +-func main() { +- fmt.Println("Hello World.") +-}` - --//` + `go:generate stringer -type=Number +-func TestDiagnosticErrorInEditedFile(t *testing.T) { +- // This test is very basic: start with a clean Go program, make an error, and +- // get a diagnostic for that error. However, it also demonstrates how to +- // combine Expectations to await more complex state in the editor. +- Run(t, exampleProgram, func(t *testing.T, env *Env) { +- // Deleting the 'n' at the end of Println should generate a single error +- // diagnostic. +- env.OpenFile("main.go") +- env.RegexpReplace("main.go", "Printl(n)", "") +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", "Printl")), +- // Assert that this test has sent no error logs to the client. This is not +- // strictly necessary for testing this regression, but is included here +- // as an example of using the NoErrorLogs() expectation. Feel free to +- // delete. +- NoErrorLogs(), +- ) +- }) +-} +- +-func TestMissingImportDiagsClearOnFirstFile(t *testing.T) { +- const onlyMod = ` +--- go.mod -- +-module mod.com +- +-go 1.12 -` -- tests := []struct { -- label string -- enabled map[string]bool -- wantCodeLens bool -- }{ -- { -- label: "default", -- wantCodeLens: true, -- }, -- { -- label: "generate disabled", -- enabled: map[string]bool{string(command.Generate): false}, -- wantCodeLens: false, -- }, -- } -- for _, test := range tests { -- t.Run(test.label, func(t *testing.T) { -- WithOptions( -- Settings{"codelenses": test.enabled}, -- ).Run(t, workspace, func(t *testing.T, env *Env) { -- env.OpenFile("lib.go") -- lens := env.CodeLens("lib.go") -- if gotCodeLens := len(lens) > 0; gotCodeLens != test.wantCodeLens { -- t.Errorf("got codeLens: %t, want %t", gotCodeLens, test.wantCodeLens) -- } -- }) -- }) -- } +- Run(t, onlyMod, func(t *testing.T, env *Env) { +- env.CreateBuffer("main.go", `package main +- +-func m() { +- log.Println() +-} +-`) +- env.AfterChange(Diagnostics(env.AtRegexp("main.go", "log"))) +- env.SaveBuffer("main.go") +- env.AfterChange(NoDiagnostics(ForFile("main.go"))) +- }) -} - --// This test confirms the full functionality of the code lenses for updating --// dependencies in a go.mod file. It checks for the code lens that suggests --// an update and then executes the command associated with that code lens. A --// regression test for golang/go#39446. It also checks that these code lenses --// only affect the diagnostics and contents of the containing go.mod file. --func TestUpgradeCodelens(t *testing.T) { -- testenv.NeedsGo1Point(t, 18) // uses go.work +-func TestDiagnosticErrorInNewFile(t *testing.T) { +- const brokenFile = `package main - -- const proxyWithLatest = ` ---- golang.org/x/hello@v1.3.3/go.mod -- --module golang.org/x/hello +-const Foo = "abc +-` +- Run(t, brokenFile, func(t *testing.T, env *Env) { +- env.CreateBuffer("broken.go", brokenFile) +- env.AfterChange(Diagnostics(env.AtRegexp("broken.go", "\"abc"))) +- }) +-} +- +-// badPackage contains a duplicate definition of the 'a' const. +-const badPackage = ` +--- go.mod -- +-module mod.com - -go 1.12 ---- golang.org/x/hello@v1.3.3/hi/hi.go -- --package hi +--- a.go -- +-package consts - --var Goodbye error ---- golang.org/x/hello@v1.2.3/go.mod -- --module golang.org/x/hello +-const a = 1 +--- b.go -- +-package consts +- +-const a = 2 +-` +- +-func TestDiagnosticClearingOnEdit(t *testing.T) { +- Run(t, badPackage, func(t *testing.T, env *Env) { +- env.OpenFile("b.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("a.go", "a = 1")), +- Diagnostics(env.AtRegexp("b.go", "a = 2")), +- ) +- +- // Fix the error by editing the const name in b.go to `b`. +- env.RegexpReplace("b.go", "(a) = 2", "b") +- env.AfterChange( +- NoDiagnostics(ForFile("a.go")), +- NoDiagnostics(ForFile("b.go")), +- ) +- }) +-} +- +-func TestDiagnosticClearingOnDelete_Issue37049(t *testing.T) { +- Run(t, badPackage, func(t *testing.T, env *Env) { +- env.OpenFile("a.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("a.go", "a = 1")), +- Diagnostics(env.AtRegexp("b.go", "a = 2")), +- ) +- env.RemoveWorkspaceFile("b.go") +- +- env.AfterChange( +- NoDiagnostics(ForFile("a.go")), +- NoDiagnostics(ForFile("b.go")), +- ) +- }) +-} +- +-func TestDiagnosticClearingOnClose(t *testing.T) { +- Run(t, badPackage, func(t *testing.T, env *Env) { +- env.CreateBuffer("c.go", `package consts +- +-const a = 3`) +- env.AfterChange( +- Diagnostics(env.AtRegexp("a.go", "a = 1")), +- Diagnostics(env.AtRegexp("b.go", "a = 2")), +- Diagnostics(env.AtRegexp("c.go", "a = 3")), +- ) +- env.CloseBuffer("c.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("a.go", "a = 1")), +- Diagnostics(env.AtRegexp("b.go", "a = 2")), +- NoDiagnostics(ForFile("c.go")), +- ) +- }) +-} +- +-// Tests golang/go#37978. +-func TestIssue37978(t *testing.T) { +- Run(t, exampleProgram, func(t *testing.T, env *Env) { +- // Create a new workspace-level directory and empty file. +- env.CreateBuffer("c/c.go", "") +- +- // Write the file contents with a missing import. +- env.EditBuffer("c/c.go", protocol.TextEdit{ +- NewText: `package c +- +-const a = http.MethodGet +-`, +- }) +- env.AfterChange( +- Diagnostics(env.AtRegexp("c/c.go", "http.MethodGet")), +- ) +- // Save file, which will organize imports, adding the expected import. +- // Expect the diagnostics to clear. +- env.SaveBuffer("c/c.go") +- env.AfterChange( +- NoDiagnostics(ForFile("c/c.go")), +- ) +- }) +-} +- +-// Tests golang/go#38878: good a.go, bad a_test.go, remove a_test.go but its errors remain +-// If the file is open in the editor, this is working as intended +-// If the file is not open in the editor, the errors go away +-const test38878 = ` +--- go.mod -- +-module foo - -go 1.12 ---- golang.org/x/hello@v1.2.3/hi/hi.go -- --package hi +--- a.go -- +-package x - --var Goodbye error --` +-// import "fmt" - -- const shouldUpdateDep = ` ---- go.work -- --go 1.18 +-func f() {} - --use ( -- ./a -- ./b --) ---- a/go.mod -- --module mod.com/a +--- a_test.go -- +-package x - --go 1.14 +-import "testing" - --require golang.org/x/hello v1.2.3 ---- a/go.sum -- --golang.org/x/hello v1.2.3 h1:7Wesfkx/uBd+eFgPrq0irYj/1XfmbvLV8jZ/W7C2Dwg= --golang.org/x/hello v1.2.3/go.mod h1:OgtlzsxVMUUdsdQCIDYgaauCTH47B8T8vofouNJfzgY= ---- a/main.go -- --package main +-func TestA(t *testing.T) { +- f(3) +-} +-` - --import "golang.org/x/hello/hi" +-// Tests golang/go#38878: deleting a test file should clear its errors, and +-// not break the workspace. +-func TestDeleteTestVariant(t *testing.T) { +- Run(t, test38878, func(t *testing.T, env *Env) { +- env.AfterChange(Diagnostics(env.AtRegexp("a_test.go", `f\((3)\)`))) +- env.RemoveWorkspaceFile("a_test.go") +- env.AfterChange(NoDiagnostics(ForFile("a_test.go"))) - --func main() { -- _ = hi.Goodbye +- // Make sure the test variant has been removed from the workspace by +- // triggering a metadata load. +- env.OpenFile("a.go") +- env.RegexpReplace("a.go", `// import`, "import") +- env.AfterChange(Diagnostics(env.AtRegexp("a.go", `"fmt"`))) +- }) -} ---- b/go.mod -- --module mod.com/b - --go 1.14 +-// Tests golang/go#38878: deleting a test file on disk while it's still open +-// should not clear its errors. +-func TestDeleteTestVariant_DiskOnly(t *testing.T) { +- Run(t, test38878, func(t *testing.T, env *Env) { +- env.OpenFile("a_test.go") +- env.AfterChange(Diagnostics(AtPosition("a_test.go", 5, 3))) +- env.Sandbox.Workdir.RemoveFile(context.Background(), "a_test.go") +- env.AfterChange(Diagnostics(AtPosition("a_test.go", 5, 3))) +- }) +-} - --require golang.org/x/hello v1.2.3 ---- b/go.sum -- --golang.org/x/hello v1.2.3 h1:7Wesfkx/uBd+eFgPrq0irYj/1XfmbvLV8jZ/W7C2Dwg= --golang.org/x/hello v1.2.3/go.mod h1:OgtlzsxVMUUdsdQCIDYgaauCTH47B8T8vofouNJfzgY= ---- b/main.go -- +-// TestNoMod confirms that gopls continues to work when a user adds a go.mod +-// file to their workspace. +-func TestNoMod(t *testing.T) { +- const noMod = ` +--- main.go -- -package main - --import ( -- "golang.org/x/hello/hi" --) +-import "mod.com/bob" - -func main() { -- _ = hi.Goodbye +- bob.Hello() -} --` -- -- const wantGoModA = `module mod.com/a -- --go 1.14 +--- bob/bob.go -- +-package bob - --require golang.org/x/hello v1.3.3 +-func Hello() { +- var x int +-} -` -- // Applying the diagnostics or running the codelenses for a/go.mod -- // should not change the contents of b/go.mod -- const wantGoModB = `module mod.com/b - --go 1.14 +- t.Run("manual", func(t *testing.T) { +- Run(t, noMod, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `"mod.com/bob"`)), +- ) +- env.CreateBuffer("go.mod", `module mod.com - --require golang.org/x/hello v1.2.3 --` +- go 1.12 +-`) +- env.SaveBuffer("go.mod") +- var d protocol.PublishDiagnosticsParams +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- Diagnostics(env.AtRegexp("bob/bob.go", "x")), +- ReadDiagnostics("bob/bob.go", &d), +- ) +- if len(d.Diagnostics) != 1 { +- t.Fatalf("expected 1 diagnostic, got %v", len(d.Diagnostics)) +- } +- }) +- }) +- t.Run("initialized", func(t *testing.T) { +- Run(t, noMod, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `"mod.com/bob"`)), +- ) +- env.RunGoCommand("mod", "init", "mod.com") +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- Diagnostics(env.AtRegexp("bob/bob.go", "x")), +- ) +- }) +- }) - -- for _, commandTitle := range []string{ -- "Upgrade transitive dependencies", -- "Upgrade direct dependencies", -- } { -- t.Run(commandTitle, func(t *testing.T) { -- WithOptions( -- ProxyFiles(proxyWithLatest), -- ).Run(t, shouldUpdateDep, func(t *testing.T, env *Env) { -- env.OpenFile("a/go.mod") -- env.OpenFile("b/go.mod") -- var lens protocol.CodeLens -- var found bool -- for _, l := range env.CodeLens("a/go.mod") { -- if l.Command.Title == commandTitle { -- lens = l -- found = true -- } -- } -- if !found { -- t.Fatalf("found no command with the title %s", commandTitle) -- } -- if _, err := env.Editor.ExecuteCommand(env.Ctx, &protocol.ExecuteCommandParams{ -- Command: lens.Command.Command, -- Arguments: lens.Command.Arguments, -- }); err != nil { -- t.Fatal(err) -- } -- env.AfterChange() -- if got := env.BufferText("a/go.mod"); got != wantGoModA { -- t.Fatalf("a/go.mod upgrade failed:\n%s", compare.Text(wantGoModA, got)) -- } -- if got := env.BufferText("b/go.mod"); got != wantGoModB { -- t.Fatalf("b/go.mod changed unexpectedly:\n%s", compare.Text(wantGoModB, got)) -- } -- }) +- t.Run("without workspace module", func(t *testing.T) { +- WithOptions( +- Modes(Default), +- ).Run(t, noMod, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `"mod.com/bob"`)), +- ) +- if err := env.Sandbox.RunGoCommand(env.Ctx, "", "mod", []string{"init", "mod.com"}, nil, true); err != nil { +- t.Fatal(err) +- } +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- Diagnostics(env.AtRegexp("bob/bob.go", "x")), +- ) - }) -- } -- for _, vendoring := range []bool{false, true} { -- t.Run(fmt.Sprintf("Upgrade individual dependency vendoring=%v", vendoring), func(t *testing.T) { -- WithOptions( -- ProxyFiles(proxyWithLatest), -- ).Run(t, shouldUpdateDep, func(t *testing.T, env *Env) { -- if vendoring { -- env.RunGoCommandInDirWithEnv("a", []string{"GOWORK=off"}, "mod", "vendor") -- } -- env.AfterChange() -- env.OpenFile("a/go.mod") -- env.OpenFile("b/go.mod") +- }) +-} - -- // Await the diagnostics resulting from opening the modfiles, because -- // otherwise they may cause races when running asynchronously to the -- // explicit re-diagnosing below. -- // -- // TODO(golang/go#58750): there is still a race here, inherent to -- // accessing state on the View; we should create a new snapshot when -- // the view diagnostics change. -- env.AfterChange() +-// Tests golang/go#38267. +-func TestIssue38267(t *testing.T) { +- const testPackage = ` +--- go.mod -- +-module mod.com - -- env.ExecuteCodeLensCommand("a/go.mod", command.CheckUpgrades, nil) -- d := &protocol.PublishDiagnosticsParams{} -- env.OnceMet( -- Diagnostics(env.AtRegexp("a/go.mod", `require`), WithMessage("can be upgraded")), -- ReadDiagnostics("a/go.mod", d), -- // We do not want there to be a diagnostic for b/go.mod, -- // but there may be some subtlety in timing here, where this -- // should always succeed, but may not actually test the correct -- // behavior. -- NoDiagnostics(env.AtRegexp("b/go.mod", `require`)), -- ) -- // Check for upgrades in b/go.mod and then clear them. -- env.ExecuteCodeLensCommand("b/go.mod", command.CheckUpgrades, nil) -- env.Await(Diagnostics(env.AtRegexp("b/go.mod", `require`), WithMessage("can be upgraded"))) -- env.ExecuteCodeLensCommand("b/go.mod", command.ResetGoModDiagnostics, nil) -- env.Await(NoDiagnostics(ForFile("b/go.mod"))) +-go 1.12 +--- lib.go -- +-package lib - -- // Apply the diagnostics to a/go.mod. -- env.ApplyQuickFixes("a/go.mod", d.Diagnostics) -- env.AfterChange() -- if got := env.BufferText("a/go.mod"); got != wantGoModA { -- t.Fatalf("a/go.mod upgrade failed:\n%s", compare.Text(wantGoModA, got)) -- } -- if got := env.BufferText("b/go.mod"); got != wantGoModB { -- t.Fatalf("b/go.mod changed unexpectedly:\n%s", compare.Text(wantGoModB, got)) -- } -- }) -- }) -- } +-func Hello(x string) { +- _ = x -} +--- lib_test.go -- +-package lib - --func TestUnusedDependenciesCodelens(t *testing.T) { -- const proxy = ` ---- golang.org/x/hello@v1.0.0/go.mod -- --module golang.org/x/hello +-import "testing" - --go 1.14 ---- golang.org/x/hello@v1.0.0/hi/hi.go -- --package hi +-type testStruct struct{ +- name string +-} - --var Goodbye error ---- golang.org/x/unused@v1.0.0/go.mod -- --module golang.org/x/unused +-func TestHello(t *testing.T) { +- testStructs := []*testStruct{ +- &testStruct{"hello"}, +- &testStruct{"goodbye"}, +- } +- for y := range testStructs { +- _ = y +- } +-} +-` - --go 1.14 ---- golang.org/x/unused@v1.0.0/nouse/nouse.go -- --package nouse +- Run(t, testPackage, func(t *testing.T, env *Env) { +- env.OpenFile("lib_test.go") +- env.AfterChange( +- Diagnostics(AtPosition("lib_test.go", 10, 2)), +- Diagnostics(AtPosition("lib_test.go", 11, 2)), +- ) +- env.OpenFile("lib.go") +- env.RegexpReplace("lib.go", "_ = x", "var y int") +- env.AfterChange( +- Diagnostics(env.AtRegexp("lib.go", "y int")), +- NoDiagnostics(ForFile("lib_test.go")), +- ) +- }) +-} - --var NotUsed error +-// Tests golang/go#38328. +-func TestPackageChange_Issue38328(t *testing.T) { +- const packageChange = ` +--- go.mod -- +-module fake +- +-go 1.12 +--- a.go -- +-package foo +-func main() {} -` +- Run(t, packageChange, func(t *testing.T, env *Env) { +- env.OpenFile("a.go") +- env.RegexpReplace("a.go", "foo", "foox") +- env.AfterChange( +- NoDiagnostics(ForFile("a.go")), +- ) +- }) +-} - -- const shouldRemoveDep = ` +-const testPackageWithRequire = ` --- go.mod -- -module mod.com - --go 1.14 +-go 1.12 - --require golang.org/x/hello v1.0.0 --require golang.org/x/unused v1.0.0 +-require foo.test v1.2.3 --- go.sum -- --golang.org/x/hello v1.0.0 h1:qbzE1/qT0/zojAMd/JcPsO2Vb9K4Bkeyq0vB2JGMmsw= --golang.org/x/hello v1.0.0/go.mod h1:WW7ER2MRNXWA6c8/4bDIek4Hc/+DofTrMaQQitGXcco= --golang.org/x/unused v1.0.0 h1:LecSbCn5P3vTcxubungSt1Pn4D/WocCaiWOPDC0y0rw= --golang.org/x/unused v1.0.0/go.mod h1:ihoW8SgWzugwwj0N2SfLfPZCxTB1QOVfhMfB5PWTQ8U= ---- main.go -- --package main +-foo.test v1.2.3 h1:TMA+lyd1ck0TqjSFpNe4T6cf/K6TYkoHwOOcMBMjaEw= +-foo.test v1.2.3/go.mod h1:Ij3kyLIe5lzjycjh13NL8I2gX0quZuTdW0MnmlwGBL4= +--- print.go -- +-package lib - --import "golang.org/x/hello/hi" +-import ( +- "fmt" - --func main() { -- _ = hi.Goodbye +- "foo.test/bar" +-) +- +-func PrintAnswer() { +- fmt.Printf("answer: %s", bar.Answer) -} -` -- WithOptions(ProxyFiles(proxy)).Run(t, shouldRemoveDep, func(t *testing.T, env *Env) { -- env.OpenFile("go.mod") -- env.ExecuteCodeLensCommand("go.mod", command.Tidy, nil) -- env.Await(env.DoneWithChangeWatchedFiles()) -- got := env.BufferText("go.mod") -- const wantGoMod = `module mod.com - --go 1.14 +-const testPackageWithRequireProxy = ` +--- foo.test@v1.2.3/go.mod -- +-module foo.test - --require golang.org/x/hello v1.0.0 +-go 1.12 +--- foo.test@v1.2.3/bar/const.go -- +-package bar +- +-const Answer = 42 -` -- if got != wantGoMod { -- t.Fatalf("go.mod tidy failed:\n%s", compare.Text(wantGoMod, got)) -- } +- +-func TestResolveDiagnosticWithDownload(t *testing.T) { +- WithOptions( +- ProxyFiles(testPackageWithRequireProxy), +- ).Run(t, testPackageWithRequire, func(t *testing.T, env *Env) { +- env.OpenFile("print.go") +- // Check that gopackages correctly loaded this dependency. We should get a +- // diagnostic for the wrong formatting type. +- env.AfterChange( +- Diagnostics( +- env.AtRegexp("print.go", "fmt.Printf"), +- WithMessage("wrong type int"), +- ), +- ) - }) -} - --func TestRegenerateCgo(t *testing.T) { -- testenv.NeedsTool(t, "cgo") -- const workspace = ` ---- go.mod -- --module example.com -- --go 1.12 ---- cgo.go -- --package x +-func TestMissingDependency(t *testing.T) { +- Run(t, testPackageWithRequire, func(t *testing.T, env *Env) { +- env.OpenFile("print.go") +- env.Await( +- // Log messages are asynchronous to other events on the LSP stream, so we +- // can't use OnceMet or AfterChange here. +- LogMatching(protocol.Error, "initial workspace load failed", 1, false), +- ) +- }) +-} - --/* --int fortythree() { return 42; } --*/ --import "C" +-// Tests golang/go#36951. +-func TestAdHocPackages_Issue36951(t *testing.T) { +- const adHoc = ` +--- b/b.go -- +-package b - --func Foo() { -- print(C.fortytwo()) +-func Hello() { +- var x int -} -` -- Run(t, workspace, func(t *testing.T, env *Env) { -- // Open the file. We have a nonexistant symbol that will break cgo processing. -- env.OpenFile("cgo.go") +- Run(t, adHoc, func(t *testing.T, env *Env) { +- env.OpenFile("b/b.go") - env.AfterChange( -- Diagnostics(env.AtRegexp("cgo.go", ``), WithMessage("go list failed to return CompiledGoFiles")), +- Diagnostics(env.AtRegexp("b/b.go", "x")), - ) +- }) +-} - -- // Fix the C function name. We haven't regenerated cgo, so nothing should be fixed. -- env.RegexpReplace("cgo.go", `int fortythree`, "int fortytwo") -- env.SaveBuffer("cgo.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("cgo.go", ``), WithMessage("go list failed to return CompiledGoFiles")), -- ) +-// Tests golang/go#37984: GOPATH should be read from the go command. +-func TestNoGOPATH_Issue37984(t *testing.T) { +- const files = ` +--- main.go -- +-package main - -- // Regenerate cgo, fixing the diagnostic. -- env.ExecuteCodeLensCommand("cgo.go", command.RegenerateCgo, nil) -- env.Await(NoDiagnostics(ForFile("cgo.go"))) +-func _() { +- fmt.Println("Hello World") +-} +-` +- WithOptions( +- EnvVars{ +- "GOPATH": "", +- "GO111MODULE": "off", +- }, +- ).Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.AfterChange(Diagnostics(env.AtRegexp("main.go", "fmt"))) +- env.SaveBuffer("main.go") +- env.AfterChange(NoDiagnostics(ForFile("main.go"))) - }) -} -diff -urN a/gopls/internal/regtest/codelens/gcdetails_test.go b/gopls/internal/regtest/codelens/gcdetails_test.go ---- a/gopls/internal/regtest/codelens/gcdetails_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/codelens/gcdetails_test.go 1970-01-01 08:00:00 -@@ -1,127 +0,0 @@ --// Copyright 2020 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 codelens +-// Tests golang/go#38669. +-func TestEqualInEnv_Issue38669(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - --import ( -- "runtime" -- "strings" -- "testing" +-go 1.12 +--- main.go -- +-package main - -- "golang.org/x/tools/gopls/internal/bug" -- "golang.org/x/tools/gopls/internal/lsp/command" -- "golang.org/x/tools/gopls/internal/lsp/fake" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" --) +-var _ = x.X +--- x/x.go -- +-package x - --func TestGCDetails_Toggle(t *testing.T) { -- if runtime.GOOS == "android" { -- t.Skipf("the gc details code lens doesn't work on Android") -- } +-var X = 0 +-` +- WithOptions( +- EnvVars{"GOFLAGS": "-tags=foo"}, +- ).Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.OrganizeImports("main.go") +- env.AfterChange(NoDiagnostics(ForFile("main.go"))) +- }) +-} - -- const mod = ` +-// Tests golang/go#38467. +-func TestNoSuggestedFixesForGeneratedFiles_Issue38467(t *testing.T) { +- const generated = ` --- go.mod -- -module mod.com - --go 1.15 +-go 1.12 --- main.go -- -package main - --import "fmt" +-// Code generated by generator.go. DO NOT EDIT. - --func main() { -- fmt.Println(42) +-func _() { +- for i, _ := range []string{} { +- _ = i +- } -} -` -- WithOptions( -- Settings{ -- "codelenses": map[string]bool{ -- "gc_details": true, -- }, -- }, -- ).Run(t, mod, func(t *testing.T, env *Env) { +- Run(t, generated, func(t *testing.T, env *Env) { - env.OpenFile("main.go") -- env.ExecuteCodeLensCommand("main.go", command.GCDetails, nil) -- d := &protocol.PublishDiagnosticsParams{} -- env.OnceMet( -- Diagnostics(AtPosition("main.go", 5, 13)), -- ReadDiagnostics("main.go", d), +- var d protocol.PublishDiagnosticsParams +- env.AfterChange( +- Diagnostics(AtPosition("main.go", 5, 8)), +- ReadDiagnostics("main.go", &d), - ) -- // Confirm that the diagnostics come from the gc details code lens. -- var found bool -- for _, d := range d.Diagnostics { -- if d.Severity != protocol.SeverityInformation { -- t.Fatalf("unexpected diagnostic severity %v, wanted Information", d.Severity) -- } -- if strings.Contains(d.Message, "42 escapes") { -- found = true -- } -- } -- if !found { -- t.Fatalf(`expected to find diagnostic with message "escape(42 escapes to heap)", found none`) +- if fixes := env.GetQuickFixes("main.go", d.Diagnostics); len(fixes) != 0 { +- t.Errorf("got quick fixes %v, wanted none", fixes) - } +- }) +-} - -- // Editing a buffer should cause gc_details diagnostics to disappear, since -- // they only apply to saved buffers. -- env.EditBuffer("main.go", fake.NewEdit(0, 0, 0, 0, "\n\n")) -- env.AfterChange(NoDiagnostics(ForFile("main.go"))) +-// Expect a module/GOPATH error if there is an error in the file at startup. +-// Tests golang/go#37279. +-func TestBrokenWorkspace_OutsideModule(t *testing.T) { +- const noModule = ` +--- a.go -- +-package foo - -- // Saving a buffer should re-format back to the original state, and -- // re-enable the gc_details diagnostics. -- env.SaveBuffer("main.go") -- env.AfterChange(Diagnostics(AtPosition("main.go", 5, 13))) +-import "mod.com/hello" - -- // Toggle the GC details code lens again so now it should be off. -- env.ExecuteCodeLensCommand("main.go", command.GCDetails, nil) -- env.Await(NoDiagnostics(ForFile("main.go"))) +-func f() { +- hello.Goodbye() +-} +-` +- Run(t, noModule, func(t *testing.T, env *Env) { +- env.OpenFile("a.go") +- env.AfterChange( +- // Expect the adHocPackagesWarning. +- OutstandingWork(lsp.WorkspaceLoadFailure, "outside of a module"), +- ) +- // Deleting the import dismisses the warning. +- env.RegexpReplace("a.go", `import "mod.com/hello"`, "") +- env.AfterChange( +- NoOutstandingWork(IgnoreTelemetryPromptWork), +- ) - }) -} - --// Test for the crasher in golang/go#54199 --func TestGCDetails_NewFile(t *testing.T) { -- bug.PanicOnBugs = false -- const src = ` ---- go.mod -- --module mod.test -- --go 1.12 +-func TestNonGoFolder(t *testing.T) { +- const files = ` +--- hello.txt -- +-hi mom -` +- for _, go111module := range []string{"on", "off", ""} { +- t.Run(fmt.Sprintf("GO111MODULE_%v", go111module), func(t *testing.T) { +- WithOptions( +- EnvVars{"GO111MODULE": go111module}, +- ).Run(t, files, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- NoOutstandingWork(IgnoreTelemetryPromptWork), +- ) +- }) +- }) +- } +-} - -- WithOptions( -- Settings{ -- "codelenses": map[string]bool{ -- "gc_details": true, -- }, -- }, -- ).Run(t, src, func(t *testing.T, env *Env) { -- env.CreateBuffer("p_test.go", "") -- -- const gcDetailsCommand = "gopls." + string(command.GCDetails) +-// Tests the repro case from golang/go#38602. Diagnostics are now handled properly, +-// which blocks type checking. +-func TestConflictingMainPackageErrors(t *testing.T) { +- const collision = ` +--- x/x.go -- +-package x - -- hasGCDetails := func() bool { -- lenses := env.CodeLens("p_test.go") // should not crash -- for _, lens := range lenses { -- if lens.Command.Command == gcDetailsCommand { -- return true -- } -- } -- return false -- } +-import "x/hello" - -- // With an empty file, we shouldn't get the gc_details codelens because -- // there is nowhere to position it (it needs a package name). -- if hasGCDetails() { -- t.Errorf("got the gc_details codelens for an empty file") -- } +-func Hello() { +- hello.HiThere() +-} +--- x/main.go -- +-package main - -- // Edit to provide a package name. -- env.EditBuffer("p_test.go", fake.NewEdit(0, 0, 0, 0, "package p")) +-func main() { +- fmt.Println("") +-} +-` +- WithOptions( +- InGOPATH(), +- EnvVars{"GO111MODULE": "off"}, +- ).Run(t, collision, func(t *testing.T, env *Env) { +- env.OpenFile("x/x.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("x/x.go", `^`), WithMessage("found packages main (main.go) and x (x.go)")), +- Diagnostics(env.AtRegexp("x/main.go", `^`), WithMessage("found packages main (main.go) and x (x.go)")), +- ) - -- // Now we should get the gc_details codelens. -- if !hasGCDetails() { -- t.Errorf("didn't get the gc_details codelens for a valid non-empty Go file") +- // We don't recover cleanly from the errors without good overlay support. +- if testenv.Go1Point() >= 16 { +- env.RegexpReplace("x/x.go", `package x`, `package main`) +- env.AfterChange( +- Diagnostics(env.AtRegexp("x/main.go", `fmt`)), +- ) - } - }) -} -diff -urN a/gopls/internal/regtest/completion/completion18_test.go b/gopls/internal/regtest/completion/completion18_test.go ---- a/gopls/internal/regtest/completion/completion18_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/completion/completion18_test.go 1970-01-01 08:00:00 -@@ -1,124 +0,0 @@ --// Copyright 2021 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. -- --//go:build go1.18 --// +build go1.18 - --package completion +-const ardanLabsProxy = ` +--- github.com/ardanlabs/conf@v1.2.3/go.mod -- +-module github.com/ardanlabs/conf - --import ( -- "testing" +-go 1.12 +--- github.com/ardanlabs/conf@v1.2.3/conf.go -- +-package conf - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" --) +-var ErrHelpWanted error +-` - --// test generic receivers --func TestGenericReceiver(t *testing.T) { -- const files = ` +-// Test for golang/go#38211. +-func Test_Issue38211(t *testing.T) { +- const ardanLabs = ` --- go.mod -- -module mod.com - --go 1.18 +-go 1.14 --- main.go -- -package main --type SyncMap[K any, V comparable] struct {} --func (s *SyncMap[K,V]) f() {} --type XX[T any] struct {} --type UU[T any] struct {} --func (s SyncMap[XX,string]) g(v UU) {} --` - -- tests := []struct { -- pat string -- want []string -- }{ -- {"s .Syn", []string{"SyncMap[K, V]"}}, -- {"Map.X", []string{}}, // This is probably wrong, Maybe "XX"? -- {"v U", []string{"UU", "uint", "uint16", "uint32", "uint64", "uint8", "uintptr"}}, // not U[T] -- } -- Run(t, files, func(t *testing.T, env *Env) { +-import "github.com/ardanlabs/conf" +- +-func main() { +- _ = conf.ErrHelpWanted +-} +-` +- WithOptions( +- ProxyFiles(ardanLabsProxy), +- ).Run(t, ardanLabs, func(t *testing.T, env *Env) { +- // Expect a diagnostic with a suggested fix to add +- // "github.com/ardanlabs/conf" to the go.mod file. +- env.OpenFile("go.mod") - env.OpenFile("main.go") -- env.Await(env.DoneWithOpen()) -- for _, tst := range tests { -- loc := env.RegexpSearch("main.go", tst.pat) -- loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte(tst.pat))) -- completions := env.Completion(loc) -- result := compareCompletionLabels(tst.want, completions.Items) -- if result != "" { -- t.Errorf("%s: wanted %v", result, tst.want) -- for i, g := range completions.Items { -- t.Errorf("got %d %s %s", i, g.Label, g.Detail) -- } -- } -- } +- var d protocol.PublishDiagnosticsParams +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", `"github.com/ardanlabs/conf"`)), +- ReadDiagnostics("main.go", &d), +- ) +- env.ApplyQuickFixes("main.go", d.Diagnostics) +- env.SaveBuffer("go.mod") +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- ) +- // Comment out the line that depends on conf and expect a +- // diagnostic and a fix to remove the import. +- env.RegexpReplace("main.go", "_ = conf.ErrHelpWanted", "//_ = conf.ErrHelpWanted") +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", `"github.com/ardanlabs/conf"`)), +- ) +- env.SaveBuffer("main.go") +- // Expect a diagnostic and fix to remove the dependency in the go.mod. +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- Diagnostics(env.AtRegexp("go.mod", "require github.com/ardanlabs/conf"), WithMessage("not used in this module")), +- ReadDiagnostics("go.mod", &d), +- ) +- env.ApplyQuickFixes("go.mod", d.Diagnostics) +- env.SaveBuffer("go.mod") +- env.AfterChange( +- NoDiagnostics(ForFile("go.mod")), +- ) +- // Uncomment the lines and expect a new diagnostic for the import. +- env.RegexpReplace("main.go", "//_ = conf.ErrHelpWanted", "_ = conf.ErrHelpWanted") +- env.SaveBuffer("main.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", `"github.com/ardanlabs/conf"`)), +- ) - }) -} --func TestFuzzFunc(t *testing.T) { -- // use the example from the package documentation -- modfile := ` +- +-// Test for golang/go#38207. +-func TestNewModule_Issue38207(t *testing.T) { +- const emptyFile = ` --- go.mod -- -module mod.com - --go 1.18 --` -- part0 := `package foo --import "testing" --func FuzzNone(f *testing.F) { -- f.Add(12) // better not find this f.Add --} --func FuzzHex(f *testing.F) { -- for _, seed := range [][]byte{{}, {0}, {9}, {0xa}, {0xf}, {1, 2, 3, 4}} { -- f.Ad` -- part1 := `d(seed) -- } -- f.F` -- part2 := `uzz(func(t *testing.T, in []byte) { -- enc := hex.EncodeToString(in) -- out, err := hex.DecodeString(enc) -- if err != nil { -- f.Failed() -- } -- if !bytes.Equal(in, out) { -- t.Fatalf("%v: round trip: %v, %s", in, out, f.Name()) -- } -- }) --} +-go 1.12 +--- main.go -- -` -- data := modfile + `-- a_test.go -- --` + part0 + ` ---- b_test.go -- --` + part0 + part1 + ` ---- c_test.go -- --` + part0 + part1 + part2 +- WithOptions( +- ProxyFiles(ardanLabsProxy), +- ).Run(t, emptyFile, func(t *testing.T, env *Env) { +- env.CreateBuffer("main.go", `package main - -- tests := []struct { -- file string -- pat string -- offset uint32 // UTF16 length from the beginning of pat to what the user just typed -- want []string -- }{ -- {"a_test.go", "f.Ad", 3, []string{"Add"}}, -- {"c_test.go", " f.F", 4, []string{"Failed"}}, -- {"c_test.go", "f.N", 3, []string{"Name"}}, -- {"b_test.go", "f.F", 3, []string{"Fuzz(func(t *testing.T, a []byte)", "Fail", "FailNow", -- "Failed", "Fatal", "Fatalf"}}, -- } -- Run(t, data, func(t *testing.T, env *Env) { -- for _, test := range tests { -- env.OpenFile(test.file) -- env.Await(env.DoneWithOpen()) -- loc := env.RegexpSearch(test.file, test.pat) -- loc.Range.Start.Character += test.offset // character user just typed? will type? -- completions := env.Completion(loc) -- result := compareCompletionLabels(test.want, completions.Items) -- if result != "" { -- t.Errorf("pat %q %q", test.pat, result) -- for i, it := range completions.Items { -- t.Errorf("%d got %q %q", i, it.Label, it.Detail) -- } -- } -- } +-import "github.com/ardanlabs/conf" +- +-func main() { +- _ = conf.ErrHelpWanted +-} +-`) +- env.SaveBuffer("main.go") +- var d protocol.PublishDiagnosticsParams +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", `"github.com/ardanlabs/conf"`), WithMessage("no required module")), +- ReadDiagnostics("main.go", &d), +- ) +- env.ApplyQuickFixes("main.go", d.Diagnostics) +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- ) - }) -} -diff -urN a/gopls/internal/regtest/completion/completion_test.go b/gopls/internal/regtest/completion/completion_test.go ---- a/gopls/internal/regtest/completion/completion_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/completion/completion_test.go 1970-01-01 08:00:00 -@@ -1,1005 +0,0 @@ --// Copyright 2020 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 completion +-// Test for golang/go#36960. +-func TestNewFileBadImports_Issue36960(t *testing.T) { +- const simplePackage = ` +--- go.mod -- +-module mod.com - --import ( -- "fmt" -- "sort" -- "strings" -- "testing" -- "time" +-go 1.14 +--- a/a1.go -- +-package a - -- "github.com/google/go-cmp/cmp" -- "golang.org/x/tools/gopls/internal/bug" -- "golang.org/x/tools/gopls/internal/hooks" -- "golang.org/x/tools/gopls/internal/lsp/fake" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/internal/testenv" --) +-import "fmt" - --func TestMain(m *testing.M) { -- bug.PanicOnBugs = true -- Main(m, hooks.Options) +-func _() { +- fmt.Println("hi") -} -- --const proxy = ` ---- example.com@v1.2.3/go.mod -- --module example.com -- --go 1.12 ---- example.com@v1.2.3/blah/blah.go -- --package blah -- --const Name = "Blah" ---- random.org@v1.2.3/go.mod -- --module random.org -- --go 1.12 ---- random.org@v1.2.3/blah/blah.go -- --package hello -- --const Name = "Hello" -` +- Run(t, simplePackage, func(t *testing.T, env *Env) { +- env.OpenFile("a/a1.go") +- env.CreateBuffer("a/a2.go", ``) +- env.SaveBufferWithoutActions("a/a2.go") +- env.AfterChange( +- NoDiagnostics(ForFile("a/a1.go")), +- ) +- env.EditBuffer("a/a2.go", fake.NewEdit(0, 0, 0, 0, `package a`)) +- env.AfterChange( +- NoDiagnostics(ForFile("a/a1.go")), +- ) +- }) +-} - --func TestPackageCompletion(t *testing.T) { -- const files = ` +-// This test tries to replicate the workflow of a user creating a new x test. +-// It also tests golang/go#39315. +-func TestManuallyCreatingXTest(t *testing.T) { +- // Create a package that already has a test variant (in-package test). +- const testVariant = ` --- go.mod -- -module mod.com - --go 1.12 ---- fruits/apple.go -- --package apple +-go 1.15 +--- hello/hello.go -- +-package hello - --fun apple() int { -- return 0 +-func Hello() { +- var x int -} +--- hello/hello_test.go -- +-package hello - ---- fruits/testfile.go -- --// this is a comment -- --/* -- this is a multiline comment --*/ -- --import "fmt" -- --func test() {} -- ---- fruits/testfile2.go -- --package -- ---- fruits/testfile3.go -- --pac ---- 123f_r.u~its-123/testfile.go -- --package +-import "testing" - ---- .invalid-dir@-name/testfile.go -- --package +-func TestHello(t *testing.T) { +- var x int +- Hello() +-} -` -- var ( -- testfile4 = "" -- testfile5 = "/*a comment*/ " -- testfile6 = "/*a comment*/\n" -- ) -- for _, tc := range []struct { -- name string -- filename string -- content *string -- triggerRegexp string -- want []string -- editRegexp string -- }{ -- { -- name: "package completion at valid position", -- filename: "fruits/testfile.go", -- triggerRegexp: "\n()", -- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, -- editRegexp: "\n()", -- }, -- { -- name: "package completion in a comment", -- filename: "fruits/testfile.go", -- triggerRegexp: "th(i)s", -- want: nil, -- }, -- { -- name: "package completion in a multiline comment", -- filename: "fruits/testfile.go", -- triggerRegexp: `\/\*\n()`, -- want: nil, -- }, -- { -- name: "package completion at invalid position", -- filename: "fruits/testfile.go", -- triggerRegexp: "import \"fmt\"\n()", -- want: nil, -- }, -- { -- name: "package completion after keyword 'package'", -- filename: "fruits/testfile2.go", -- triggerRegexp: "package()", -- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, -- editRegexp: "package\n", -- }, -- { -- name: "package completion with 'pac' prefix", -- filename: "fruits/testfile3.go", -- triggerRegexp: "pac()", -- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, -- editRegexp: "pac", -- }, -- { -- name: "package completion for empty file", -- filename: "fruits/testfile4.go", -- triggerRegexp: "^$", -- content: &testfile4, -- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, -- editRegexp: "^$", -- }, -- { -- name: "package completion without terminal newline", -- filename: "fruits/testfile5.go", -- triggerRegexp: `\*\/ ()`, -- content: &testfile5, -- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, -- editRegexp: `\*\/ ()`, -- }, -- { -- name: "package completion on terminal newline", -- filename: "fruits/testfile6.go", -- triggerRegexp: `\*\/\n()`, -- content: &testfile6, -- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, -- editRegexp: `\*\/\n()`, -- }, -- // Issue golang/go#44680 -- { -- name: "package completion for dir name with punctuation", -- filename: "123f_r.u~its-123/testfile.go", -- triggerRegexp: "package()", -- want: []string{"package fruits123", "package fruits123_test", "package main"}, -- editRegexp: "package\n", -- }, -- { -- name: "package completion for invalid dir name", -- filename: ".invalid-dir@-name/testfile.go", -- triggerRegexp: "package()", -- want: []string{"package main"}, -- editRegexp: "package\n", -- }, -- } { -- t.Run(tc.name, func(t *testing.T) { -- Run(t, files, func(t *testing.T, env *Env) { -- if tc.content != nil { -- env.WriteWorkspaceFile(tc.filename, *tc.content) -- env.Await(env.DoneWithChangeWatchedFiles()) -- } -- env.OpenFile(tc.filename) -- completions := env.Completion(env.RegexpSearch(tc.filename, tc.triggerRegexp)) +- Run(t, testVariant, func(t *testing.T, env *Env) { +- // Open the file, triggering the workspace load. +- // There are errors in the code to ensure all is working as expected. +- env.OpenFile("hello/hello.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("hello/hello.go", "x")), +- Diagnostics(env.AtRegexp("hello/hello_test.go", "x")), +- ) - -- // Check that the completion item suggestions are in the range -- // of the file. {Start,End}.Line are zero-based. -- lineCount := len(strings.Split(env.BufferText(tc.filename), "\n")) -- for _, item := range completions.Items { -- if start := int(item.TextEdit.Range.Start.Line); start > lineCount { -- t.Fatalf("unexpected text edit range start line number: got %d, want <= %d", start, lineCount) -- } -- if end := int(item.TextEdit.Range.End.Line); end > lineCount { -- t.Fatalf("unexpected text edit range end line number: got %d, want <= %d", end, lineCount) -- } -- } +- // Create an empty file with the intention of making it an x test. +- // This resembles a typical flow in an editor like VS Code, in which +- // a user would create an empty file and add content, saving +- // intermittently. +- // TODO(rstambler): There might be more edge cases here, as file +- // content can be added incrementally. +- env.CreateBuffer("hello/hello_x_test.go", ``) +- +- // Save the empty file (no actions since formatting will fail). +- env.SaveBufferWithoutActions("hello/hello_x_test.go") - -- if tc.want != nil { -- expectedLoc := env.RegexpSearch(tc.filename, tc.editRegexp) -- for _, item := range completions.Items { -- gotRng := item.TextEdit.Range -- if expectedLoc.Range != gotRng { -- t.Errorf("unexpected completion range for completion item %s: got %v, want %v", -- item.Label, gotRng, expectedLoc.Range) -- } -- } -- } +- // Add the content. The missing import is for the package under test. +- env.EditBuffer("hello/hello_x_test.go", fake.NewEdit(0, 0, 0, 0, `package hello_test - -- diff := compareCompletionLabels(tc.want, completions.Items) -- if diff != "" { -- t.Error(diff) -- } -- }) -- }) -- } +-import ( +- "testing" +-) +- +-func TestHello(t *testing.T) { +- hello.Hello() +-} +-`)) +- // Expect a diagnostic for the missing import. Save, which should +- // trigger import organization. The diagnostic should clear. +- env.AfterChange( +- Diagnostics(env.AtRegexp("hello/hello_x_test.go", "hello.Hello")), +- ) +- env.SaveBuffer("hello/hello_x_test.go") +- env.AfterChange( +- NoDiagnostics(ForFile("hello/hello_x_test.go")), +- ) +- }) -} - --func TestPackageNameCompletion(t *testing.T) { -- const files = ` +-// Reproduce golang/go#40690. +-func TestCreateOnlyXTest(t *testing.T) { +- const mod = ` --- go.mod -- -module mod.com - -go 1.12 ---- math/add.go -- --package ma +--- foo/foo.go -- +-package foo +--- foo/bar_test.go -- -` +- Run(t, mod, func(t *testing.T, env *Env) { +- env.OpenFile("foo/bar_test.go") +- env.EditBuffer("foo/bar_test.go", fake.NewEdit(0, 0, 0, 0, "package foo")) +- env.Await(env.DoneWithChange()) +- env.RegexpReplace("foo/bar_test.go", "package foo", `package foo_test - -- want := []string{"ma", "ma_test", "main", "math", "math_test"} -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("math/add.go") -- completions := env.Completion(env.RegexpSearch("math/add.go", "package ma()")) +-import "testing" - -- diff := compareCompletionLabels(want, completions.Items) -- if diff != "" { -- t.Fatal(diff) -- } +-func TestX(t *testing.T) { +- var x int +-} +-`) +- env.AfterChange( +- Diagnostics(env.AtRegexp("foo/bar_test.go", "x")), +- ) - }) -} - --// TODO(rfindley): audit/clean up call sites for this helper, to ensure --// consistent test errors. --func compareCompletionLabels(want []string, gotItems []protocol.CompletionItem) string { -- var got []string -- for _, item := range gotItems { -- got = append(got, item.Label) -- if item.Label != item.InsertText && item.TextEdit == nil { -- // Label should be the same as InsertText, if InsertText is to be used -- return fmt.Sprintf("label not the same as InsertText %#v", item) -- } -- } +-func TestChangePackageName(t *testing.T) { +- const mod = ` +--- go.mod -- +-module mod.com - -- if len(got) == 0 && len(want) == 0 { -- return "" // treat nil and the empty slice as equivalent -- } +-go 1.12 +--- foo/foo.go -- +-package foo +--- foo/bar_test.go -- +-package foo_ +-` +- Run(t, mod, func(t *testing.T, env *Env) { +- env.OpenFile("foo/bar_test.go") +- env.AfterChange() +- env.RegexpReplace("foo/bar_test.go", "package foo_", "package foo_test") +- env.AfterChange( +- NoDiagnostics(ForFile("foo/bar_test.go")), +- NoDiagnostics(ForFile("foo/foo.go")), +- ) +- }) +-} - -- if diff := cmp.Diff(want, got); diff != "" { -- return fmt.Sprintf("completion item mismatch (-want +got):\n%s", diff) -- } -- return "" +-func TestIgnoredFiles(t *testing.T) { +- const ws = ` +--- go.mod -- +-module mod.com +- +-go 1.12 +--- _foo/x.go -- +-package x +- +-var _ = foo.Bar +-` +- Run(t, ws, func(t *testing.T, env *Env) { +- env.OpenFile("_foo/x.go") +- env.AfterChange( +- NoDiagnostics(ForFile("_foo/x.go")), +- ) +- }) -} - --func TestUnimportedCompletion(t *testing.T) { -- const mod = ` +-// Partially reproduces golang/go#38977, moving a file between packages. +-// It also gets hit by some go command bug fixed in 1.15, but we don't +-// care about that so much here. +-func TestDeletePackage(t *testing.T) { +- const ws = ` --- go.mod -- -module mod.com - --go 1.14 +-go 1.15 +--- a/a.go -- +-package a - --require example.com v1.2.3 ---- go.sum -- --example.com v1.2.3 h1:ihBTGWGjTU3V4ZJ9OmHITkU9WQ4lGdQkMjgyLFk0FaY= --example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo= ---- main.go -- --package main +-const A = 1 - --func main() { -- _ = blah --} ---- main2.go -- --package main +--- b/b.go -- +-package b - --import "example.com/blah" +-import "mod.com/a" - --func _() { -- _ = blah.Hello +-const B = a.A +- +--- c/c.go -- +-package c +- +-import "mod.com/a" +- +-const C = a.A +-` +- Run(t, ws, func(t *testing.T, env *Env) { +- env.OpenFile("b/b.go") +- env.Await(env.DoneWithOpen()) +- // Delete c/c.go, the only file in package c. +- env.RemoveWorkspaceFile("c/c.go") +- +- // We should still get diagnostics for files that exist. +- env.RegexpReplace("b/b.go", `a.A`, "a.Nonexistant") +- env.AfterChange( +- Diagnostics(env.AtRegexp("b/b.go", `Nonexistant`)), +- ) +- }) -} +- +-// This is a copy of the scenario_default/quickfix_empty_files.txt test from +-// govim. Reproduces golang/go#39646. +-func TestQuickFixEmptyFiles(t *testing.T) { +- const mod = ` +--- go.mod -- +-module mod.com +- +-go 1.12 -` -- WithOptions( -- ProxyFiles(proxy), -- ).Run(t, mod, func(t *testing.T, env *Env) { -- // Make sure the dependency is in the module cache and accessible for -- // unimported completions, and then remove it before proceeding. -- env.RemoveWorkspaceFile("main2.go") -- env.RunGoCommand("mod", "tidy") +- // To fully recreate the govim tests, we create files by inserting +- // a newline, adding to the file, and then deleting the newline. +- // Wait for each event to process to avoid cancellations and force +- // package loads. +- writeGoVim := func(env *Env, name, content string) { +- env.WriteWorkspaceFile(name, "") - env.Await(env.DoneWithChangeWatchedFiles()) - -- // Trigger unimported completions for the example.com/blah package. -- env.OpenFile("main.go") +- env.CreateBuffer(name, "\n") - env.Await(env.DoneWithOpen()) -- loc := env.RegexpSearch("main.go", "ah") -- completions := env.Completion(loc) -- if len(completions.Items) == 0 { -- t.Fatalf("no completion items") -- } -- env.AcceptCompletion(loc, completions.Items[0]) // adds blah import to main.go +- +- env.EditBuffer(name, fake.NewEdit(1, 0, 1, 0, content)) - env.Await(env.DoneWithChange()) - -- // Trigger completions once again for the blah.<> selector. -- env.RegexpReplace("main.go", "_ = blah", "_ = blah.") +- env.EditBuffer(name, fake.NewEdit(0, 0, 1, 0, "")) - env.Await(env.DoneWithChange()) -- loc = env.RegexpSearch("main.go", "\n}") -- completions = env.Completion(loc) -- if len(completions.Items) != 1 { -- t.Fatalf("expected 1 completion item, got %v", len(completions.Items)) -- } -- item := completions.Items[0] -- if item.Label != "Name" { -- t.Fatalf("expected completion item blah.Name, got %v", item.Label) -- } -- env.AcceptCompletion(loc, item) +- } - -- // Await the diagnostics to add example.com/blah to the go.mod file. -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", `"example.com/blah"`)), -- ) +- const p = `package p; func DoIt(s string) {};` +- const main = `package main +- +-import "mod.com/p" +- +-func main() { +- p.DoIt(5) +-} +-` +- // A simple version of the test that reproduces most of the problems it +- // exposes. +- t.Run("short", func(t *testing.T) { +- Run(t, mod, func(t *testing.T, env *Env) { +- writeGoVim(env, "p/p.go", p) +- writeGoVim(env, "main.go", main) +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", "5")), +- ) +- }) +- }) +- +- // A full version that replicates the whole flow of the test. +- t.Run("full", func(t *testing.T) { +- Run(t, mod, func(t *testing.T, env *Env) { +- writeGoVim(env, "p/p.go", p) +- writeGoVim(env, "main.go", main) +- writeGoVim(env, "p/p_test.go", `package p +- +-import "testing" +- +-func TestDoIt(t *testing.T) { +- DoIt(5) +-} +-`) +- writeGoVim(env, "p/x_test.go", `package p_test +- +-import ( +- "testing" +- +- "mod.com/p" +-) +- +-func TestDoIt(t *testing.T) { +- p.DoIt(5) +-} +-`) +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", "5")), +- Diagnostics(env.AtRegexp("p/p_test.go", "5")), +- Diagnostics(env.AtRegexp("p/x_test.go", "5")), +- ) +- env.RegexpReplace("p/p.go", "s string", "i int") +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- NoDiagnostics(ForFile("p/p_test.go")), +- NoDiagnostics(ForFile("p/x_test.go")), +- ) +- }) - }) -} - --// Test that completions still work with an undownloaded module, golang/go#43333. --func TestUndownloadedModule(t *testing.T) { -- // mod.com depends on example.com, but only in a file that's hidden by a -- // build tag, so the IWL won't download example.com. That will cause errors -- // in the go list -m call performed by the imports package. -- const files = ` +-func TestSingleFile(t *testing.T) { +- const mod = ` --- go.mod -- -module mod.com - --go 1.14 -- --require example.com v1.2.3 ---- go.sum -- --example.com v1.2.3 h1:ihBTGWGjTU3V4ZJ9OmHITkU9WQ4lGdQkMjgyLFk0FaY= --example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo= ---- useblah.go -- --// +build hidden -- --package pkg --import "example.com/blah" --var _ = blah.Name ---- mainmod/mainmod.go -- --package mainmod +-go 1.13 +--- a/a.go -- +-package a - --const Name = "mainmod" +-func _() { +- var x int +-} -` -- WithOptions(ProxyFiles(proxy)).Run(t, files, func(t *testing.T, env *Env) { -- env.CreateBuffer("import.go", "package pkg\nvar _ = mainmod.Name\n") -- env.SaveBuffer("import.go") -- content := env.ReadWorkspaceFile("import.go") -- if !strings.Contains(content, `import "mod.com/mainmod`) { -- t.Errorf("expected import of mod.com/mainmod in %q", content) -- } +- WithOptions( +- // Empty workspace folders. +- WorkspaceFolders(), +- ).Run(t, mod, func(t *testing.T, env *Env) { +- env.OpenFile("a/a.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("a/a.go", "x")), +- ) - }) -} - --// Test that we can doctor the source code enough so the file is --// parseable and completion works as expected. --func TestSourceFixup(t *testing.T) { -- const files = ` +-// Reproduces the case described in +-// https://github.com/golang/go/issues/39296#issuecomment-652058883. +-func TestPkgm(t *testing.T) { +- const basic = ` --- go.mod -- -module mod.com - --go 1.12 ---- foo.go -- +-go 1.15 +--- foo/foo.go -- -package foo - --func _() { -- var s S -- if s. --} +-import "fmt" - --type S struct { -- i int +-func Foo() { +- fmt.Println("") -} -` +- Run(t, basic, func(t *testing.T, env *Env) { +- env.WriteWorkspaceFile("foo/foo_test.go", `package main - -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("foo.go") -- completions := env.Completion(env.RegexpSearch("foo.go", `if s\.()`)) -- diff := compareCompletionLabels([]string{"i"}, completions.Items) -- if diff != "" { -- t.Fatal(diff) -- } +-func main() { +- +-}`) +- env.OpenFile("foo/foo_test.go") +- env.RegexpReplace("foo/foo_test.go", `package main`, `package foo`) +- env.AfterChange(NoDiagnostics(ForFile("foo/foo.go"))) - }) -} - --func TestCompletion_Issue45510(t *testing.T) { -- const files = ` +-func TestClosingBuffer(t *testing.T) { +- const basic = ` --- go.mod -- -module mod.com - --go 1.12 +-go 1.14 --- main.go -- -package main - --func _() { -- type a *a -- var aaaa1, aaaa2 a -- var _ a = aaaa -- -- type b a -- var bbbb1, bbbb2 b -- var _ b = bbbb +-func main() {} +-` +- Run(t, basic, func(t *testing.T, env *Env) { +- env.Editor.CreateBuffer(env.Ctx, "foo.go", `package main`) +- env.AfterChange() +- env.CloseBuffer("foo.go") +- env.AfterChange(NoLogMatching(protocol.Info, "packages=0")) +- }) -} - --type ( -- c *d -- d *e -- e **c --) +-// Reproduces golang/go#38424. +-func TestCutAndPaste(t *testing.T) { +- const basic = ` +--- go.mod -- +-module mod.com - --func _() { -- var ( -- xxxxc c -- xxxxd d -- xxxxe e -- ) +-go 1.14 +--- main2.go -- +-package main +-` +- Run(t, basic, func(t *testing.T, env *Env) { +- env.CreateBuffer("main.go", "") +- env.Await(env.DoneWithOpen()) - -- var _ c = xxxx -- var _ d = xxxx -- var _ e = xxxx +- env.SaveBufferWithoutActions("main.go") +- env.Await(env.DoneWithSave(), env.DoneWithChangeWatchedFiles()) +- +- env.EditBuffer("main.go", fake.NewEdit(0, 0, 0, 0, `package main +- +-func main() { -} --` +-`)) +- env.Await(env.DoneWithChange()) - -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") +- env.SaveBuffer("main.go") +- env.Await(env.DoneWithSave(), env.DoneWithChangeWatchedFiles()) - -- tests := []struct { -- re string -- want []string -- }{ -- {`var _ a = aaaa()`, []string{"aaaa1", "aaaa2"}}, -- {`var _ b = bbbb()`, []string{"bbbb1", "bbbb2"}}, -- {`var _ c = xxxx()`, []string{"xxxxc", "xxxxd", "xxxxe"}}, -- {`var _ d = xxxx()`, []string{"xxxxc", "xxxxd", "xxxxe"}}, -- {`var _ e = xxxx()`, []string{"xxxxc", "xxxxd", "xxxxe"}}, -- } -- for _, tt := range tests { -- completions := env.Completion(env.RegexpSearch("main.go", tt.re)) -- diff := compareCompletionLabels(tt.want, completions.Items) -- if diff != "" { -- t.Errorf("%s: %s", tt.re, diff) -- } -- } +- env.EditBuffer("main.go", fake.NewEdit(0, 0, 4, 0, "")) +- env.Await(env.DoneWithChange()) +- +- env.EditBuffer("main.go", fake.NewEdit(0, 0, 0, 0, `package main +- +-func main() { +- var x int +-} +-`)) +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", "x")), +- ) - }) -} - --func TestCompletionDeprecation(t *testing.T) { -- const files = ` +-// Reproduces golang/go#39763. +-func TestInvalidPackageName(t *testing.T) { +- const pkgDefault = ` --- go.mod -- --module test.com -- --go 1.16 ---- prog.go -- --package waste --// Deprecated, use newFoof --func fooFunc() bool { -- return false --} +-module mod.com - --// Deprecated --const badPi = 3.14 +-go 1.12 +--- main.go -- +-package default - --func doit() { -- if fooF -- panic() -- x := badP --} +-func main() {} -` -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("prog.go") -- loc := env.RegexpSearch("prog.go", "if fooF") -- loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte("if fooF"))) -- completions := env.Completion(loc) -- diff := compareCompletionLabels([]string{"fooFunc"}, completions.Items) -- if diff != "" { -- t.Error(diff) -- } -- if completions.Items[0].Tags == nil { -- t.Errorf("expected Tags to show deprecation %#v", completions.Items[0].Tags) -- } -- loc = env.RegexpSearch("prog.go", "= badP") -- loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte("= badP"))) -- completions = env.Completion(loc) -- diff = compareCompletionLabels([]string{"badPi"}, completions.Items) -- if diff != "" { -- t.Error(diff) -- } -- if completions.Items[0].Tags == nil { -- t.Errorf("expected Tags to show deprecation %#v", completions.Items[0].Tags) -- } +- Run(t, pkgDefault, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.AfterChange( +- Diagnostics( +- env.AtRegexp("main.go", "default"), +- WithMessage("expected 'IDENT'"), +- ), +- ) - }) -} - --func TestUnimportedCompletion_VSCodeIssue1489(t *testing.T) { -- const src = ` +-// This tests the functionality of the "limitWorkspaceScope" +-func TestLimitWorkspaceScope(t *testing.T) { +- const mod = ` --- go.mod -- -module mod.com - --go 1.14 +-go 1.12 +--- a/main.go -- +-package main - +-func main() {} --- main.go -- -package main - --import "fmt" -- -func main() { -- fmt.Println("a") -- math.Sqr +- var x int -} -` - WithOptions( -- WindowsLineEndings(), -- Settings{"ui.completion.usePlaceholders": true}, -- ).Run(t, src, func(t *testing.T, env *Env) { -- // Trigger unimported completions for the mod.com package. -- env.OpenFile("main.go") -- env.Await(env.DoneWithOpen()) -- loc := env.RegexpSearch("main.go", "Sqr()") -- completions := env.Completion(loc) -- if len(completions.Items) == 0 { -- t.Fatalf("no completion items") -- } -- env.AcceptCompletion(loc, completions.Items[0]) -- env.Await(env.DoneWithChange()) -- got := env.BufferText("main.go") -- want := "package main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"math\"\r\n)\r\n\r\nfunc main() {\r\n\tfmt.Println(\"a\")\r\n\tmath.Sqrt(${1:x float64})\r\n}\r\n" -- if diff := cmp.Diff(want, got); diff != "" { -- t.Errorf("unimported completion (-want +got):\n%s", diff) -- } +- WorkspaceFolders("a"), +- ).Run(t, mod, func(t *testing.T, env *Env) { +- env.OpenFile("a/main.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", "x")), +- ) +- }) +- WithOptions( +- WorkspaceFolders("a"), +- Settings{"expandWorkspaceToModule": false}, +- ).Run(t, mod, func(t *testing.T, env *Env) { +- env.OpenFile("a/main.go") +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- ) - }) -} - --func TestUnimportedCompletionHasPlaceholders60269(t *testing.T) { -- testenv.NeedsGo1Point(t, 18) // uses type params -- -- // We can't express this as a marker test because it doesn't support AcceptCompletion. -- const src = ` +-func TestSimplifyCompositeLitDiagnostic(t *testing.T) { +- const files = ` --- go.mod -- --module example.com --go 1.12 +-module mod.com - ---- a/a.go -- --package a +-go 1.12 +--- main.go -- +-package main - --var _ = b.F +-import "fmt" - ---- b/b.go -- --package b +-type t struct { +- msg string +-} - --func F0(a, b int, c float64) {} --func F1(int, chan *string) {} --func F2[K, V any](map[K]V, chan V) {} // missing type parameters was issue #60959 --func F3[K comparable, V any](map[K]V, chan V) {} +-func main() { +- x := []t{t{"msg"}} +- fmt.Println(x) +-} -` -- WithOptions( -- WindowsLineEndings(), -- Settings{"ui.completion.usePlaceholders": true}, -- ).Run(t, src, func(t *testing.T, env *Env) { -- env.OpenFile("a/a.go") -- env.Await(env.DoneWithOpen()) - -- // The table lists the expected completions of b.F as they appear in Items. -- const common = "package a\r\n\r\nimport \"example.com/b\"\r\n\r\nvar _ = " -- for i, want := range []string{ -- common + "b.F0(${1:a int}, ${2:b int}, ${3:c float64})\r\n", -- common + "b.F1(${1:_ int}, ${2:_ chan *string})\r\n", -- common + "b.F2[${1:K any}, ${2:V any}](${3:_ map[K]V}, ${4:_ chan V})\r\n", -- common + "b.F3[${1:K comparable}, ${2:V any}](${3:_ map[K]V}, ${4:_ chan V})\r\n", -- } { -- loc := env.RegexpSearch("a/a.go", "b.F()") -- completions := env.Completion(loc) -- if len(completions.Items) == 0 { -- t.Fatalf("no completion items") -- } -- saved := env.BufferText("a/a.go") -- env.AcceptCompletion(loc, completions.Items[i]) -- env.Await(env.DoneWithChange()) -- got := env.BufferText("a/a.go") -- if diff := cmp.Diff(want, got); diff != "" { -- t.Errorf("%d: unimported completion (-want +got):\n%s", i, diff) -- } -- env.SetBufferContent("a/a.go", saved) // restore +- WithOptions( +- Settings{"staticcheck": true}, +- ).Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- var d protocol.PublishDiagnosticsParams +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", `t{"msg"}`), WithMessage("redundant type")), +- ReadDiagnostics("main.go", &d), +- ) +- if tags := d.Diagnostics[0].Tags; len(tags) == 0 || tags[0] != protocol.Unnecessary { +- t.Errorf("wanted Unnecessary tag on diagnostic, got %v", tags) - } +- env.ApplyQuickFixes("main.go", d.Diagnostics) +- env.AfterChange(NoDiagnostics(ForFile("main.go"))) - }) -} - --func TestPackageMemberCompletionAfterSyntaxError(t *testing.T) { -- // This test documents the current broken behavior due to golang/go#58833. -- const src = ` +-// Test some secondary diagnostics +-func TestSecondaryDiagnostics(t *testing.T) { +- const dir = ` --- go.mod -- -module mod.com - --go 1.14 -- +-go 1.12 --- main.go -- -package main -- --import "math" -- -func main() { -- math.Sqrt(,0) -- math.Ldex +- panic("not here") -} +--- other.go -- +-package main +-func main() {} -` -- Run(t, src, func(t *testing.T, env *Env) { +- Run(t, dir, func(t *testing.T, env *Env) { - env.OpenFile("main.go") -- env.Await(env.DoneWithOpen()) -- loc := env.RegexpSearch("main.go", "Ldex()") -- completions := env.Completion(loc) -- if len(completions.Items) == 0 { -- t.Fatalf("no completion items") +- env.OpenFile("other.go") +- var mainDiags, otherDiags protocol.PublishDiagnosticsParams +- env.AfterChange( +- ReadDiagnostics("main.go", &mainDiags), +- ReadDiagnostics("other.go", &otherDiags), +- ) +- if len(mainDiags.Diagnostics) != 1 { +- t.Fatalf("main.go, got %d diagnostics, expected 1", len(mainDiags.Diagnostics)) - } -- env.AcceptCompletion(loc, completions.Items[0]) -- env.Await(env.DoneWithChange()) -- got := env.BufferText("main.go") -- // The completion of math.Ldex after the syntax error on the -- // previous line is not "math.Ldexp" but "math.Ldexmath.Abs". -- // (In VSCode, "Abs" wrongly appears in the completion menu.) -- // This is a consequence of poor error recovery in the parser -- // causing "math.Ldex" to become a BadExpr. -- want := "package main\n\nimport \"math\"\n\nfunc main() {\n\tmath.Sqrt(,0)\n\tmath.Ldexmath.Abs(${1:})\n}\n" -- if diff := cmp.Diff(want, got); diff != "" { -- t.Errorf("unimported completion (-want +got):\n%s", diff) +- keep := mainDiags.Diagnostics[0] +- if len(otherDiags.Diagnostics) != 1 { +- t.Fatalf("other.go: got %d diagnostics, expected 1", len(otherDiags.Diagnostics)) +- } +- if len(otherDiags.Diagnostics[0].RelatedInformation) != 1 { +- t.Fatalf("got %d RelatedInformations, expected 1", len(otherDiags.Diagnostics[0].RelatedInformation)) +- } +- // check that the RelatedInformation matches the error from main.go +- c := otherDiags.Diagnostics[0].RelatedInformation[0] +- if c.Location.Range != keep.Range { +- t.Errorf("locations don't match. Got %v expected %v", c.Location.Range, keep.Range) - } - }) -} - --func TestCompleteAllFields(t *testing.T) { -- // This test verifies that completion results always include all struct fields. -- // See golang/go#53992. -- -- const src = ` +-func TestOrphanedFiles(t *testing.T) { +- const files = ` --- go.mod -- -module mod.com - --go 1.18 -- ---- p/p.go -- --package p -- --import ( -- "fmt" -- -- . "net/http" -- . "runtime" -- . "go/types" -- . "go/parser" -- . "go/ast" --) +-go 1.12 +--- a/a.go -- +-package a - --type S struct { -- a, b, c, d, e, f, g, h, i, j, k, l, m int -- n, o, p, q, r, s, t, u, v, w, x, y, z int +-func main() { +- var x int -} +--- a/a_exclude.go -- +-// +build exclude +- +-package a - -func _() { -- var s S -- fmt.Println(s.) +- var x int -} -` +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("a/a.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("a/a.go", "x")), +- ) +- env.OpenFile("a/a_exclude.go") - -- WithOptions(Settings{ -- "completionBudget": "1ns", // must be non-zero as 0 => infinity -- }).Run(t, src, func(t *testing.T, env *Env) { -- wantFields := make(map[string]bool) -- for c := 'a'; c <= 'z'; c++ { -- wantFields[string(c)] = true -- } +- loadOnce := LogMatching(protocol.Info, "query=.*file=.*a_exclude.go", 1, false) - -- env.OpenFile("p/p.go") -- // Make an arbitrary edit to ensure we're not hitting the cache. -- env.EditBuffer("p/p.go", fake.NewEdit(0, 0, 0, 0, fmt.Sprintf("// current time: %v\n", time.Now()))) -- loc := env.RegexpSearch("p/p.go", `s\.()`) -- completions := env.Completion(loc) -- gotFields := make(map[string]bool) -- for _, item := range completions.Items { -- if item.Kind == protocol.FieldCompletion { -- gotFields[item.Label] = true -- } -- } +- // can't use OnceMet or AfterChange as logs are async +- env.Await(loadOnce) +- // ...but ensure that the change has been fully processed before editing. +- // Otherwise, there may be a race where the snapshot is cloned before all +- // state changes resulting from the load have been processed +- // (golang/go#61521). +- env.AfterChange() - -- if diff := cmp.Diff(wantFields, gotFields); diff != "" { -- t.Errorf("Completion(...) returned mismatching fields (-want +got):\n%s", diff) -- } +- // Check that orphaned files are not reloaded, by making a change in +- // a.go file and confirming that the workspace diagnosis did not reload +- // a_exclude.go. +- // +- // This is racy (but fails open) because logs are asynchronous to other LSP +- // operations. There's a chance gopls _did_ log, and we just haven't seen +- // it yet. +- env.RegexpReplace("a/a.go", "package a", "package a // arbitrary comment") +- env.AfterChange(loadOnce) - }) -} - --func TestDefinition(t *testing.T) { -- testenv.NeedsGo1Point(t, 17) // in go1.16, The FieldList in func x is not empty -- files := ` +-func TestEnableAllExperiments(t *testing.T) { +- // Before the oldest supported Go version, gopls sends a warning to upgrade +- // Go, which fails the expectation below. +- testenv.NeedsGo1Point(t, lsp.OldestSupportedGoVersion()) +- +- const mod = ` --- go.mod -- -module mod.com - --go 1.18 ---- a_test.go -- --package foo +-go 1.12 +--- main.go -- +-package main +- +-import "bytes" +- +-func b(c bytes.Buffer) { +- _ = 1 +-} -` -- tests := []struct { -- line string // the sole line in the buffer after the package statement -- pat string // the pattern to search for -- want []string // expected completions -- }{ -- {"func T", "T", []string{"TestXxx(t *testing.T)", "TestMain(m *testing.M)"}}, -- {"func T()", "T", []string{"TestMain", "Test"}}, -- {"func TestM", "TestM", []string{"TestMain(m *testing.M)", "TestM(t *testing.T)"}}, -- {"func TestM()", "TestM", []string{"TestMain"}}, -- {"func TestMi", "TestMi", []string{"TestMi(t *testing.T)"}}, -- {"func TestMi()", "TestMi", nil}, -- {"func TestG", "TestG", []string{"TestG(t *testing.T)"}}, -- {"func TestG(", "TestG", nil}, -- {"func Ben", "B", []string{"BenchmarkXxx(b *testing.B)"}}, -- {"func Ben(", "Ben", []string{"Benchmark"}}, -- {"func BenchmarkFoo", "BenchmarkFoo", []string{"BenchmarkFoo(b *testing.B)"}}, -- {"func BenchmarkFoo(", "BenchmarkFoo", nil}, -- {"func Fuz", "F", []string{"FuzzXxx(f *testing.F)"}}, -- {"func Fuz(", "Fuz", []string{"Fuzz"}}, -- {"func Testx", "Testx", nil}, -- {"func TestMe(t *testing.T)", "TestMe", nil}, -- {"func Te(t *testing.T)", "Te", []string{"TestMain", "Test"}}, -- } -- fname := "a_test.go" -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile(fname) -- env.Await(env.DoneWithOpen()) -- for _, test := range tests { -- env.SetBufferContent(fname, "package foo\n"+test.line) -- loc := env.RegexpSearch(fname, test.pat) -- loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte(test.pat))) -- completions := env.Completion(loc) -- if diff := compareCompletionLabels(test.want, completions.Items); diff != "" { -- t.Error(diff) -- } -- } +- WithOptions( +- Settings{"allExperiments": true}, +- ).Run(t, mod, func(t *testing.T, env *Env) { +- // Confirm that the setting doesn't cause any warnings. +- env.OnceMet( +- InitialWorkspaceLoad, +- NoShownMessage(""), // empty substring to match any message +- ) - }) -} - --// Test that completing a definition replaces source text when applied, golang/go#56852. --// Note: With go <= 1.16 the completions does not add parameters and fails these tests. --func TestDefinitionReplaceRange(t *testing.T) { +-func TestSwig(t *testing.T) { +- // This is fixed in Go 1.17, but not earlier. - testenv.NeedsGo1Point(t, 17) - +- if _, err := exec.LookPath("swig"); err != nil { +- t.Skip("skipping test: swig not available") +- } +- if _, err := exec.LookPath("g++"); err != nil { +- t.Skip("skipping test: g++ not available") +- } +- - const mod = ` --- go.mod -- -module mod.com - --go 1.17 --` -- -- tests := []struct { -- name string -- before, after string -- }{ -- { -- name: "func TestMa", -- before: ` --package foo_test +-go 1.12 +--- pkg/simple/export_swig.go -- +-package simple - --func TestMa --`, -- after: ` --package foo_test +-func ExportSimple(x, y int) int { +- return Gcd(x, y) +-} +--- pkg/simple/simple.swigcxx -- +-%module simple - --func TestMain(m *testing.M) --`, -- }, -- { -- name: "func TestSome", -- before: ` --package foo_test +-%inline %{ +-extern int gcd(int x, int y) +-{ +- int g; +- g = y; +- while (x > 0) { +- g = x; +- x = y % x; +- y = g; +- } +- return g; +-} +-%} +--- main.go -- +-package a - --func TestSome --`, -- after: ` --package foo_test +-func main() { +- var x int +-} +-` +- Run(t, mod, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- NoDiagnostics(WithMessage("illegal character U+0023 '#'")), +- ) +- }) +-} - --func TestSome(t *testing.T) --`, -- }, -- { -- name: "func Bench", -- before: ` --package foo_test +-// When foo_test.go is opened, gopls will object to the borked package name. +-// This test asserts that when the package name is fixed, gopls will soon after +-// have no more complaints about it. +-// https://github.com/golang/go/issues/41061 +-func TestRenamePackage(t *testing.T) { +- const proxy = ` +--- example.com@v1.2.3/go.mod -- +-module example.com - --func Bench --`, -- // Note: Snippet with escaped }. -- after: ` --package foo_test +-go 1.12 +--- example.com@v1.2.3/blah/blah.go -- +-package blah - --func Benchmark${1:Xxx}(b *testing.B) { -- $0 --\} --`, -- }, -- } +-const Name = "Blah" +--- random.org@v1.2.3/go.mod -- +-module random.org - -- Run(t, mod, func(t *testing.T, env *Env) { -- env.CreateBuffer("foo_test.go", "") +-go 1.12 +--- random.org@v1.2.3/blah/blah.go -- +-package hello - -- for _, tst := range tests { -- tst.before = strings.Trim(tst.before, "\n") -- tst.after = strings.Trim(tst.after, "\n") -- env.SetBufferContent("foo_test.go", tst.before) +-const Name = "Hello" +-` - -- loc := env.RegexpSearch("foo_test.go", tst.name) -- loc.Range.Start.Character = uint32(protocol.UTF16Len([]byte(tst.name))) -- completions := env.Completion(loc) -- if len(completions.Items) == 0 { -- t.Fatalf("no completion items") -- } +- const contents = ` +--- go.mod -- +-module mod.com - -- env.AcceptCompletion(loc, completions.Items[0]) -- env.Await(env.DoneWithChange()) -- if buf := env.BufferText("foo_test.go"); buf != tst.after { -- t.Errorf("%s:incorrect completion: got %q, want %q", tst.name, buf, tst.after) -- } -- } -- }) --} +-go 1.12 +--- main.go -- +-package main - --func TestGoWorkCompletion(t *testing.T) { -- const files = ` ---- go.work -- --go 1.18 +-import "example.com/blah" - --use ./a --use ./a/ba --use ./a/b/ --use ./dir/foo --use ./dir/foobar/ ---- a/go.mod -- ---- go.mod -- ---- a/bar/go.mod -- ---- a/b/c/d/e/f/go.mod -- ---- dir/bar -- ---- dir/foobar/go.mod -- +-func main() { +- blah.Hello() +-} +--- bob.go -- +-package main +--- foo/foo.go -- +-package foo +--- foo/foo_test.go -- +-package foo_ -` - -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("go.work") -- -- tests := []struct { -- re string -- want []string -- }{ -- {`use ()\.`, []string{".", "./a", "./a/bar", "./dir/foobar"}}, -- {`use \.()`, []string{"", "/a", "/a/bar", "/dir/foobar"}}, -- {`use \./()`, []string{"a", "a/bar", "dir/foobar"}}, -- {`use ./a()`, []string{"", "/b/c/d/e/f", "/bar"}}, -- {`use ./a/b()`, []string{"/c/d/e/f", "ar"}}, -- {`use ./a/b/()`, []string{`c/d/e/f`}}, -- {`use ./a/ba()`, []string{"r"}}, -- {`use ./dir/foo()`, []string{"bar"}}, -- {`use ./dir/foobar/()`, []string{}}, -- } -- for _, tt := range tests { -- completions := env.Completion(env.RegexpSearch("go.work", tt.re)) -- diff := compareCompletionLabels(tt.want, completions.Items) -- if diff != "" { -- t.Errorf("%s: %s", tt.re, diff) -- } -- } +- WithOptions( +- ProxyFiles(proxy), +- InGOPATH(), +- EnvVars{"GO111MODULE": "off"}, +- ).Run(t, contents, func(t *testing.T, env *Env) { +- // Simulate typing character by character. +- env.OpenFile("foo/foo_test.go") +- env.Await(env.DoneWithOpen()) +- env.RegexpReplace("foo/foo_test.go", "_", "_t") +- env.Await(env.DoneWithChange()) +- env.RegexpReplace("foo/foo_test.go", "_t", "_test") +- env.AfterChange( +- NoDiagnostics(ForFile("foo/foo_test.go")), +- NoOutstandingWork(IgnoreTelemetryPromptWork), +- ) - }) -} - --func TestBuiltinCompletion(t *testing.T) { -- const files = ` +-// TestProgressBarErrors confirms that critical workspace load errors are shown +-// and updated via progress reports. +-func TestProgressBarErrors(t *testing.T) { +- const pkg = ` --- go.mod -- --module mod.com +-modul mod.com - --go 1.18 ---- a.go -- --package a +-go 1.12 +--- main.go -- +-package main +-` +- Run(t, pkg, func(t *testing.T, env *Env) { +- env.OpenFile("go.mod") +- env.AfterChange( +- OutstandingWork(lsp.WorkspaceLoadFailure, "unknown directive"), +- ) +- env.EditBuffer("go.mod", fake.NewEdit(0, 0, 3, 0, `module mod.com - --func _() { -- // here +-go 1.hello +-`)) +- // As of golang/go#42529, go.mod changes do not reload the workspace until +- // they are saved. +- env.SaveBufferWithoutActions("go.mod") +- env.AfterChange( +- OutstandingWork(lsp.WorkspaceLoadFailure, "invalid go version"), +- ) +- env.RegexpReplace("go.mod", "go 1.hello", "go 1.12") +- env.SaveBufferWithoutActions("go.mod") +- env.AfterChange( +- NoOutstandingWork(IgnoreTelemetryPromptWork), +- ) +- }) -} --` - -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("a.go") -- result := env.Completion(env.RegexpSearch("a.go", `// here`)) -- builtins := []string{ -- "any", "append", "bool", "byte", "cap", "close", -- "comparable", "complex", "complex128", "complex64", "copy", "delete", -- "error", "false", "float32", "float64", "imag", "int", "int16", "int32", -- "int64", "int8", "len", "make", "new", "panic", "print", "println", "real", -- "recover", "rune", "string", "true", "uint", "uint16", "uint32", "uint64", -- "uint8", "uintptr", "nil", -- } -- if testenv.Go1Point() >= 21 { -- builtins = append(builtins, "clear", "max", "min") -- } -- sort.Strings(builtins) -- var got []string +-func TestDeleteDirectory(t *testing.T) { +- const mod = ` +--- bob/bob.go -- +-package bob - -- for _, item := range result.Items { -- // TODO(rfindley): for flexibility, ignore zero while it is being -- // implemented. Remove this if/when zero lands. -- if item.Label != "zero" { -- got = append(got, item.Label) -- } -- } -- sort.Strings(got) +-func Hello() { +- var x int +-} +--- go.mod -- +-module mod.com +--- cmd/main.go -- +-package main - -- if diff := cmp.Diff(builtins, got); diff != "" { -- t.Errorf("Completion: unexpected mismatch (-want +got):\n%s", diff) -- } +-import "mod.com/bob" +- +-func main() { +- bob.Hello() +-} +-` +- WithOptions( +- Settings{ +- // Now that we don't watch subdirs by default (except for VS Code), +- // we must explicitly ask gopls to requests subdir watch patterns. +- "subdirWatchPatterns": "on", +- }, +- ).Run(t, mod, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- FileWatchMatching("bob"), +- ) +- env.RemoveWorkspaceFile("bob") +- env.AfterChange( +- Diagnostics(env.AtRegexp("cmd/main.go", `"mod.com/bob"`)), +- NoDiagnostics(ForFile("bob/bob.go")), +- NoFileWatchMatching("bob"), +- ) - }) -} - --func TestOverlayCompletion(t *testing.T) { -- const files = ` +-// Confirms that circular imports are tested and reported. +-func TestCircularImports(t *testing.T) { +- const mod = ` --- go.mod -- --module foo.test +-module mod.com - --go 1.18 +-go 1.12 +--- self/self.go -- +-package self - ---- foo/foo.go -- --package foo +-import _ "mod.com/self" +-func Hello() {} +--- double/a/a.go -- +-package a - --type Foo struct{} --` +-import _ "mod.com/double/b" +--- double/b/b.go -- +-package b - -- Run(t, files, func(t *testing.T, env *Env) { -- env.CreateBuffer("nodisk/nodisk.go", ` --package nodisk +-import _ "mod.com/double/a" +--- triple/a/a.go -- +-package a - --import ( -- "foo.test/foo" --) +-import _ "mod.com/triple/b" +--- triple/b/b.go -- +-package b - --func _() { -- foo.Foo() --} --`) -- list := env.Completion(env.RegexpSearch("nodisk/nodisk.go", "foo.(Foo)")) -- want := []string{"Foo"} -- var got []string -- for _, item := range list.Items { -- got = append(got, item.Label) -- } -- if diff := cmp.Diff(want, got); diff != "" { -- t.Errorf("Completion: unexpected mismatch (-want +got):\n%s", diff) -- } +-import _ "mod.com/triple/c" +--- triple/c/c.go -- +-package c +- +-import _ "mod.com/triple/a" +-` +- Run(t, mod, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("self/self.go", `_ "mod.com/self"`), WithMessage("import cycle not allowed")), +- Diagnostics(env.AtRegexp("double/a/a.go", `_ "mod.com/double/b"`), WithMessage("import cycle not allowed")), +- Diagnostics(env.AtRegexp("triple/a/a.go", `_ "mod.com/triple/b"`), WithMessage("import cycle not allowed")), +- ) - }) -} - --// Fix for golang/go#60062: unimported completion included "golang.org/toolchain" results. --func TestToolchainCompletions(t *testing.T) { -- const files = ` +-// Tests golang/go#46667: deleting a problematic import path should resolve +-// import cycle errors. +-func TestResolveImportCycle(t *testing.T) { +- const mod = ` --- go.mod -- --module foo.test/foo +-module mod.test - --go 1.21 +-go 1.16 +--- a/a.go -- +-package a - ---- foo.go -- --package foo +-import "mod.test/b" - --func _() { -- os.Open --} +-const A = b.A +-const B = 2 +--- b/b.go -- +-package b - --func _() { -- strings +-import "mod.test/a" +- +-const A = 1 +-const B = a.B +- ` +- Run(t, mod, func(t *testing.T, env *Env) { +- env.OpenFile("a/a.go") +- env.OpenFile("b/b.go") +- env.AfterChange( +- // The Go command sometimes tells us about only one of the import cycle +- // errors below. For robustness of this test, succeed if we get either. +- // +- // TODO(golang/go#52904): we should get *both* of these errors. +- AnyOf( +- Diagnostics(env.AtRegexp("a/a.go", `"mod.test/b"`), WithMessage("import cycle")), +- Diagnostics(env.AtRegexp("b/b.go", `"mod.test/a"`), WithMessage("import cycle")), +- ), +- ) +- env.RegexpReplace("b/b.go", `const B = a\.B`, "") +- env.SaveBuffer("b/b.go") +- env.AfterChange( +- NoDiagnostics(ForFile("a/a.go")), +- NoDiagnostics(ForFile("b/b.go")), +- ) +- }) -} --` - -- const proxy = ` ---- golang.org/toolchain@v0.0.1-go1.21.1.linux-amd64/go.mod -- --module golang.org/toolchain ---- golang.org/toolchain@v0.0.1-go1.21.1.linux-amd64/src/os/os.go -- --package os +-func TestBadImport(t *testing.T) { +- const mod = ` +--- go.mod -- +-module mod.com - --func Open() {} ---- golang.org/toolchain@v0.0.1-go1.21.1.linux-amd64/src/strings/strings.go -- --package strings +-go 1.12 +--- main.go -- +-package main - --func Join() {} +-import ( +- _ "nosuchpkg" +-) -` -- -- WithOptions( -- ProxyFiles(proxy), -- ).Run(t, files, func(t *testing.T, env *Env) { -- env.RunGoCommand("mod", "download", "golang.org/toolchain@v0.0.1-go1.21.1.linux-amd64") -- env.OpenFile("foo.go") -- -- for _, pattern := range []string{"os.Open()", "string()"} { -- loc := env.RegexpSearch("foo.go", pattern) -- res := env.Completion(loc) -- for _, item := range res.Items { -- if strings.Contains(item.Detail, "golang.org/toolchain") { -- t.Errorf("Completion(...) returned toolchain item %#v", item) -- } -- } -- } +- t.Run("module", func(t *testing.T) { +- Run(t, mod, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `"nosuchpkg"`), WithMessage(`could not import nosuchpkg (no required module provides package "nosuchpkg"`)), +- ) +- }) +- }) +- t.Run("GOPATH", func(t *testing.T) { +- WithOptions( +- InGOPATH(), +- EnvVars{"GO111MODULE": "off"}, +- Modes(Default), +- ).Run(t, mod, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `"nosuchpkg"`), WithMessage(`cannot find package "nosuchpkg"`)), +- ) +- }) - }) -} -diff -urN a/gopls/internal/regtest/completion/postfix_snippet_test.go b/gopls/internal/regtest/completion/postfix_snippet_test.go ---- a/gopls/internal/regtest/completion/postfix_snippet_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/completion/postfix_snippet_test.go 1970-01-01 08:00:00 -@@ -1,590 +0,0 @@ --// Copyright 2021 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 completion +-func TestNestedModules(t *testing.T) { +- const proxy = ` +--- nested.com@v1.0.0/go.mod -- +-module nested.com - --import ( -- "strings" -- "testing" +-go 1.12 +--- nested.com@v1.0.0/hello/hello.go -- +-package hello - -- . "golang.org/x/tools/gopls/internal/lsp/regtest" --) +-func Hello() {} +-` - --func TestPostfixSnippetCompletion(t *testing.T) { -- const mod = ` +- const nested = ` --- go.mod -- -module mod.com - -go 1.12 --` - -- cases := []struct { -- name string -- before, after string -- }{ -- { -- name: "sort", -- before: ` --package foo +-require nested.com v1.0.0 +--- go.sum -- +-nested.com v1.0.0 h1:I6spLE4CgFqMdBPc+wTV2asDO2QJ3tU0YAT+jkLeN1I= +-nested.com v1.0.0/go.mod h1:ly53UzXQgVjSlV7wicdBB4p8BxfytuGT1Xcyv0ReJfI= +--- main.go -- +-package main - --func _() { -- var foo []int -- foo.sort +-import "nested.com/hello" +- +-func main() { +- hello.Hello() -} --`, -- after: ` --package foo +--- nested/go.mod -- +-module nested.com - --import "sort" +--- nested/hello/hello.go -- +-package hello - --func _() { -- var foo []int -- sort.Slice(foo, func(i, j int) bool { -- $0 --}) +-func Hello() { +- helloHelper() -} --`, -- }, -- { -- name: "sort_renamed_sort_package", -- before: ` --package foo +--- nested/hello/hello_helper.go -- +-package hello - --import blahsort "sort" +-func helloHelper() {} +-` +- WithOptions( +- ProxyFiles(proxy), +- Modes(Default), +- ).Run(t, nested, func(t *testing.T, env *Env) { +- // Expect a diagnostic in a nested module. +- env.OpenFile("nested/hello/hello.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("nested/hello/hello.go", "helloHelper")), +- Diagnostics(env.AtRegexp("nested/hello/hello.go", "package (hello)"), WithMessage("not included in your workspace")), +- ) +- }) +-} - --var j int +-func TestAdHocPackagesReloading(t *testing.T) { +- const nomod = ` +--- main.go -- +-package main - --func _() { -- var foo []int -- foo.sort +-func main() {} +-` +- Run(t, nomod, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.RegexpReplace("main.go", "{}", "{ var x int; }") // simulate typing +- env.AfterChange(NoLogMatching(protocol.Info, "packages=1")) +- }) -} --`, -- after: ` --package foo -- --import blahsort "sort" - --var j int +-func TestBuildTagChange(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - --func _() { -- var foo []int -- blahsort.Slice(foo, func(i, j2 int) bool { -- $0 --}) --} --`, -- }, -- { -- name: "last", -- before: ` --package foo +-go 1.12 +--- foo.go -- +-// decoy comment +-// +build hidden +-// decoy comment - --func _() { -- var s struct { i []int } -- s.i.last --} --`, -- after: ` -package foo -- --func _() { -- var s struct { i []int } -- s.i[len(s.i)-1] --} --`, -- }, -- { -- name: "reverse", -- before: ` +-var Foo = 1 +--- bar.go -- -package foo +-var Bar = Foo +-` - --func _() { -- var foo []int -- foo.reverse --} --`, -- after: ` --package foo +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("foo.go") +- env.AfterChange(Diagnostics(env.AtRegexp("bar.go", `Foo`))) +- env.RegexpReplace("foo.go", `\+build`, "") +- env.AfterChange(NoDiagnostics(ForFile("bar.go"))) +- }) - --func _() { -- var foo []int -- for i, j := 0, len(foo)-1; i < j; i, j = i+1, j-1 { -- foo[i], foo[j] = foo[j], foo[i] -} - --} --`, -- }, -- { -- name: "slice_range", -- before: ` --package foo +-func TestIssue44736(t *testing.T) { +- const files = ` +- -- go.mod -- +-module blah.com - --func _() { -- type myThing struct{} -- var foo []myThing -- foo.range --} --`, -- after: ` --package foo +-go 1.16 +--- main.go -- +-package main - --func _() { -- type myThing struct{} -- var foo []myThing -- for i, mt := range foo { -- $0 --} --} --`, -- }, -- { -- name: "append_stmt", -- before: ` --package foo +-import "fmt" - --func _() { -- var foo []int -- foo.append +-func main() { +- asdf +- fmt.Printf("This is a test %v") +- fdas -} --`, -- after: ` --package foo +--- other.go -- +-package main - --func _() { -- var foo []int -- foo = append(foo, $0) +-` +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.OpenFile("other.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", "asdf")), +- Diagnostics(env.AtRegexp("main.go", "fdas")), +- ) +- env.SetBufferContent("other.go", "package main\n\nasdf") +- // The new diagnostic in other.go should not suppress diagnostics in main.go. +- env.AfterChange( +- Diagnostics(env.AtRegexp("other.go", "asdf"), WithMessage("expected declaration")), +- Diagnostics(env.AtRegexp("main.go", "asdf")), +- ) +- }) -} --`, -- }, -- { -- name: "append_expr", -- before: ` --package foo - --func _() { -- var foo []int -- var _ []int = foo.append --} --`, -- after: ` --package foo +-func TestInitialization(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - --func _() { -- var foo []int -- var _ []int = append(foo, $0) +-go 1.16 +--- main.go -- +-package main +-` +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("go.mod") +- env.Await(env.DoneWithOpen()) +- env.RegexpReplace("go.mod", "module", "modul") +- env.SaveBufferWithoutActions("go.mod") +- env.AfterChange( +- NoLogMatching(protocol.Error, "initial workspace load failed"), +- ) +- }) -} --`, -- }, -- { -- name: "slice_copy", -- before: ` --package foo - --func _() { -- var foo []int -- foo.copy --} --`, -- after: ` --package foo +-// This test confirms that the view does not reinitialize when a go.mod file is +-// opened. +-func TestNoReinitialize(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - --func _() { -- var foo []int -- fooCopy := make([]int, len(foo)) --copy(fooCopy, foo) +-go 1.12 +--- main.go -- +-package main - +-func main() {} +-` +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("go.mod") +- env.Await( +- // Check that we have only loaded "<dir>/..." once. +- // Log messages are asynchronous to other events on the LSP stream, so we +- // can't use OnceMet or AfterChange here. +- LogMatching(protocol.Info, `.*query=.*\.\.\..*`, 1, false), +- ) +- }) -} --`, -- }, -- { -- name: "map_range", -- before: ` --package foo - --func _() { -- var foo map[string]int -- foo.range --} --`, -- after: ` --package foo +-func TestLangVersion(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) // Requires types.Config.GoVersion, new in 1.18. +- const files = ` +--- go.mod -- +-module mod.com - --func _() { -- var foo map[string]int -- for k, v := range foo { -- $0 --} --} --`, -- }, -- { -- name: "map_clear", -- before: ` --package foo +-go 1.12 +--- main.go -- +-package main - --func _() { -- var foo map[string]int -- foo.clear +-const C = 0b10 +-` +- Run(t, files, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `0b10`), WithMessage("go1.13 or later")), +- ) +- env.WriteWorkspaceFile("go.mod", "module mod.com \n\ngo 1.13\n") +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- ) +- }) -} --`, -- after: ` --package foo - --func _() { -- var foo map[string]int -- for k := range foo { -- delete(foo, k) --} +-func TestNoQuickFixForUndeclaredConstraint(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) +- const files = ` +--- go.mod -- +-module mod.com - --} --`, -- }, -- { -- name: "map_keys", -- before: ` --package foo +-go 1.18 +--- main.go -- +-package main - --func _() { -- var foo map[string]int -- foo.keys +-func F[T C](_ T) { -} --`, -- after: ` --package foo +-` - --func _() { -- var foo map[string]int -- keys := make([]string, 0, len(foo)) --for k := range foo { -- keys = append(keys, k) +- Run(t, files, func(t *testing.T, env *Env) { +- var d protocol.PublishDiagnosticsParams +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `C`)), +- ReadDiagnostics("main.go", &d), +- ) +- if fixes := env.GetQuickFixes("main.go", d.Diagnostics); len(fixes) != 0 { +- t.Errorf("got quick fixes %v, wanted none", fixes) +- } +- }) -} - --} --`, -- }, -- { -- name: "channel_range", -- before: ` --package foo +-func TestEditGoDirective(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) +- const files = ` +--- go.mod -- +-module mod.com - --func _() { -- foo := make(chan int) -- foo.range --} --`, -- after: ` --package foo +-go 1.16 +--- main.go -- +-package main - --func _() { -- foo := make(chan int) -- for e := range foo { -- $0 --} +-func F[T any](_ T) { -} --`, -- }, -- { -- name: "var", -- before: ` --package foo -- --func foo() (int, error) { return 0, nil } +-` +- Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file. +- var d protocol.PublishDiagnosticsParams +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `T any`), WithMessage("type parameter")), +- ReadDiagnostics("main.go", &d), +- ) - --func _() { -- foo().var +- env.ApplyQuickFixes("main.go", d.Diagnostics) +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- ) +- }) -} --`, -- after: ` --package foo - --func foo() (int, error) { return 0, nil } +-func TestEditGoDirectiveWorkspace(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) +- const files = ` +--- go.mod -- +-module mod.com - --func _() { -- i, err := foo() --} --`, -- }, -- { -- name: "var_single_value", -- before: ` --package foo +-go 1.16 +--- go.work -- +-go 1.18 - --func foo() error { return nil } +-use . +--- main.go -- +-package main - --func _() { -- foo().var +-func F[T any](_ T) { -} --`, -- after: ` --package foo -- --func foo() error { return nil } +-` +- Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file. +- var d protocol.PublishDiagnosticsParams - --func _() { -- err := foo() --} --`, -- }, -- { -- name: "var_same_type", -- before: ` --package foo +- // We should have a diagnostic because generics are not supported at 1.16. +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `T any`), WithMessage("type parameter")), +- ReadDiagnostics("main.go", &d), +- ) - --func foo() (int, int) { return 0, 0 } +- // This diagnostic should have a quick fix to edit the go version. +- env.ApplyQuickFixes("main.go", d.Diagnostics) - --func _() { -- foo().var +- // Once the edit is applied, the problematic diagnostics should be +- // resolved. +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- ) +- }) -} --`, -- after: ` --package foo - --func foo() (int, int) { return 0, 0 } +-// This test demonstrates that analysis facts are correctly propagated +-// across packages. +-func TestInterpackageAnalysis(t *testing.T) { +- const src = ` +--- go.mod -- +-module example.com +--- a/a.go -- +-package a - --func _() { -- i, i2 := foo() --} --`, -- }, -- { -- name: "print_scalar", -- before: ` --package foo +-import "example.com/b" - -func _() { -- var foo int -- foo.print +- new(b.B).Printf("%d", "s") // printf error -} --`, -- after: ` --package foo - --import "fmt" +--- b/b.go -- +-package b - --func _() { -- var foo int -- fmt.Printf("foo: %v\n", foo) --} --`, -- }, -- { -- name: "print_multi", -- before: ` --package foo +-import "example.com/c" - --func foo() (int, error) { return 0, nil } +-type B struct{} - --func _() { -- foo().print +-func (B) Printf(format string, args ...interface{}) { +- c.MyPrintf(format, args...) -} --`, -- after: ` --package foo - --import "fmt" +--- c/c.go -- +-package c - --func foo() (int, error) { return 0, nil } +-import "fmt" - --func _() { -- fmt.Println(foo()) +-func MyPrintf(format string, args ...interface{}) { +- fmt.Printf(format, args...) +-} +-` +- Run(t, src, func(t *testing.T, env *Env) { +- env.OpenFile("a/a.go") +- env.AfterChange( +- Diagnostics( +- env.AtRegexp("a/a.go", "new.*Printf"), +- WithMessage("format %d has arg \"s\" of wrong type string"), +- ), +- ) +- }) -} --`, -- }, -- { -- name: "string split", -- before: ` --package foo -- --func foo() []string { -- x := "test" -- return x.split --}`, -- after: ` --package foo -- --import "strings" -- --func foo() []string { -- x := "test" -- return strings.Split(x, "$0") --}`, -- }, -- { -- name: "string slice join", -- before: ` --package foo -- --func foo() string { -- x := []string{"a", "test"} -- return x.join --}`, -- after: ` --package foo - --import "strings" +-// This test ensures that only Analyzers with RunDespiteErrors=true +-// are invoked on a package that would not compile, even if the errors +-// are distant and localized. +-func TestErrorsThatPreventAnalysis(t *testing.T) { +- const src = ` +--- go.mod -- +-module example.com +--- a/a.go -- +-package a - --func foo() string { -- x := []string{"a", "test"} -- return strings.Join(x, "$0") --}`, -- }, -- { -- name: "if not nil interface", -- before: ` --package foo +-import "fmt" +-import "sync" +-import _ "example.com/b" - -func _() { -- var foo error -- foo.ifnotnil --} --`, -- after: ` --package foo +- // The copylocks analyzer (RunDespiteErrors, FactTypes={}) does run. +- var mu sync.Mutex +- mu2 := mu // copylocks error, reported +- _ = &mu2 - --func _() { -- var foo error -- if foo != nil { -- $0 --} --} --`, -- }, -- { -- name: "if not nil pointer", -- before: ` --package foo +- // The printf analyzer (!RunDespiteErrors, FactTypes!={}) does not run: +- // (c, printf) failed because of type error in c +- // (b, printf) and (a, printf) do not run because of failed prerequisites. +- fmt.Printf("%d", "s") // printf error, unreported - --func _() { -- var foo *int -- foo.ifnotnil +- // The bools analyzer (!RunDespiteErrors, FactTypes={}) does not run: +- var cond bool +- _ = cond != true && cond != true // bools error, unreported -} --`, -- after: ` --package foo - --func _() { -- var foo *int -- if foo != nil { -- $0 --} --} --`, -- }, -- { -- name: "if not nil slice", -- before: ` --package foo +--- b/b.go -- +-package b - --func _() { -- var foo []int -- foo.ifnotnil --} --`, -- after: ` --package foo +-import _ "example.com/c" - --func _() { -- var foo []int -- if foo != nil { -- $0 --} --} --`, -- }, -- { -- name: "if not nil map", -- before: ` --package foo +--- c/c.go -- +-package c - --func _() { -- var foo map[string]any -- foo.ifnotnil --} --`, -- after: ` --package foo +-var _ = 1 / "" // type error - --func _() { -- var foo map[string]any -- if foo != nil { -- $0 --} --} --`, -- }, -- { -- name: "if not nil channel", -- before: ` --package foo +-` +- Run(t, src, func(t *testing.T, env *Env) { +- var diags protocol.PublishDiagnosticsParams +- env.OpenFile("a/a.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("a/a.go", "mu2 := (mu)"), WithMessage("assignment copies lock value")), +- ReadDiagnostics("a/a.go", &diags)) - --func _() { -- var foo chan int -- foo.ifnotnil +- // Assert that there were no other diagnostics. +- // In particular: +- // - "fmt.Printf" does not trigger a [printf] finding; +- // - "cond != true" does not trigger a [bools] finding. +- // +- // We use this check in preference to NoDiagnosticAtRegexp +- // as it is robust in case of minor mistakes in the position +- // regexp, and because it reports unexpected diagnostics. +- if got, want := len(diags.Diagnostics), 1; got != want { +- t.Errorf("got %d diagnostics in a/a.go, want %d:", got, want) +- for i, diag := range diags.Diagnostics { +- t.Logf("Diagnostics[%d] = %+v", i, diag) +- } +- } +- }) -} --`, -- after: ` --package foo - --func _() { -- var foo chan int -- if foo != nil { -- $0 --} --} --`, -- }, -- { -- name: "if not nil function", -- before: ` --package foo +-// This test demonstrates the deprecated symbol analyzer +-// produces deprecation notices with expected severity and tags. +-func TestDeprecatedAnalysis(t *testing.T) { +- const src = ` +--- go.mod -- +-module example.com +--- a/a.go -- +-package a +- +-import "example.com/b" - -func _() { -- var foo func() -- foo.ifnotnil +- new(b.B).Obsolete() // deprecated -} --`, -- after: ` --package foo - --func _() { -- var foo func() -- if foo != nil { -- $0 +--- b/b.go -- +-package b +- +-type B struct{} +- +-// Deprecated: use New instead. +-func (B) Obsolete() {} +- +-func (B) New() {} +-` +- Run(t, src, func(t *testing.T, env *Env) { +- env.OpenFile("a/a.go") +- env.AfterChange( +- Diagnostics( +- env.AtRegexp("a/a.go", "new.*Obsolete"), +- WithMessage("use New instead."), +- WithSeverityTags("deprecated", protocol.SeverityHint, []protocol.DiagnosticTag{protocol.Deprecated}), +- ), +- ) +- }) -} +- +-func TestDiagnosticsOnlyOnSaveFile(t *testing.T) { +- const onlyMod = ` +--- go.mod -- +-module mod.com +- +-go 1.12 +--- main.go -- +-package main +- +-func main() { +- Foo() -} --`, -- }, -- } +--- foo.go -- +-package main - -- r := WithOptions( +-func Foo() {} +-` +- WithOptions( - Settings{ -- "experimentalPostfixCompletions": true, +- "diagnosticsTrigger": "Save", - }, -- ) -- r.Run(t, mod, func(t *testing.T, env *Env) { -- env.CreateBuffer("foo.go", "") -- -- for _, c := range cases { -- t.Run(c.name, func(t *testing.T) { -- c.before = strings.Trim(c.before, "\n") -- c.after = strings.Trim(c.after, "\n") -- -- env.SetBufferContent("foo.go", c.before) +- ).Run(t, onlyMod, func(t *testing.T, env *Env) { +- env.OpenFile("foo.go") +- env.RegexpReplace("foo.go", "(Foo)", "Bar") // Makes reference to Foo undefined/undeclared. +- env.AfterChange(NoDiagnostics()) // No diagnostics update until file save. - -- loc := env.RegexpSearch("foo.go", "\n}") -- completions := env.Completion(loc) -- if len(completions.Items) != 1 { -- t.Fatalf("expected one completion, got %v", completions.Items) -- } +- env.SaveBuffer("foo.go") +- // Compiler's error message about undeclared names vary depending on the version, +- // but must be explicit about the problematic name. +- env.AfterChange(Diagnostics(env.AtRegexp("main.go", "Foo"), WithMessage("Foo"))) - -- env.AcceptCompletion(loc, completions.Items[0]) +- env.OpenFile("main.go") +- env.RegexpReplace("main.go", "(Foo)", "Bar") +- // No diagnostics update until file save. That results in outdated diagnostic. +- env.AfterChange(Diagnostics(env.AtRegexp("main.go", "Bar"), WithMessage("Foo"))) - -- if buf := env.BufferText("foo.go"); buf != c.after { -- t.Errorf("\nGOT:\n%s\nEXPECTED:\n%s", buf, c.after) -- } -- }) -- } +- env.SaveBuffer("main.go") +- env.AfterChange(NoDiagnostics()) - }) -} -diff -urN a/gopls/internal/regtest/debug/debug_test.go b/gopls/internal/regtest/debug/debug_test.go ---- a/gopls/internal/regtest/debug/debug_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/debug/debug_test.go 1970-01-01 08:00:00 -@@ -1,101 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. +diff -urN a/gopls/internal/regtest/diagnostics/golist_test.go b/gopls/internal/regtest/diagnostics/golist_test.go +--- a/gopls/internal/regtest/diagnostics/golist_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/diagnostics/golist_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,71 +0,0 @@ +-// Copyright 2023 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 debug +-package diagnostics - -import ( -- "context" -- "encoding/json" -- "io" -- "net/http" -- "strings" - "testing" - -- "golang.org/x/tools/gopls/internal/bug" -- "golang.org/x/tools/gopls/internal/hooks" -- "golang.org/x/tools/gopls/internal/lsp/command" -- "golang.org/x/tools/gopls/internal/lsp/protocol" - . "golang.org/x/tools/gopls/internal/lsp/regtest" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/testenv" -) - --func TestMain(m *testing.M) { -- Main(m, hooks.Options) --} +-func TestGoListErrors(t *testing.T) { +- testenv.NeedsTool(t, "cgo") - --func TestBugNotification(t *testing.T) { -- // Verify that a properly configured session gets notified of a bug on the -- // server. -- WithOptions( -- Modes(Default), // must be in-process to receive the bug report below -- Settings{"showBugReports": true}, -- ).Run(t, "", func(t *testing.T, env *Env) { -- const desc = "got a bug" -- bug.Report(desc) -- env.Await(ShownMessage(desc)) -- }) --} +- const src = ` +--- go.mod -- +-module a.com - --// TestStartDebugging executes a gopls.start_debugging command to --// start the internal web server. --func TestStartDebugging(t *testing.T) { -- WithOptions( -- Modes(Default|Experimental), // doesn't work in Forwarded mode -- ).Run(t, "", func(t *testing.T, env *Env) { -- // Start a debugging server. -- res, err := startDebugging(env.Ctx, env.Editor.Server, &command.DebuggingArgs{ -- Addr: "", // any free port -- }) -- if err != nil { -- t.Fatalf("startDebugging: %v", err) -- } +-go 1.18 +--- a/a.go -- +-package a - -- // Assert that the server requested that the -- // client show the debug page in a browser. -- debugURL := res.URLs[0] -- env.Await(ShownDocument(debugURL)) +-import +--- c/c.go -- +-package c - -- // Send a request to the debug server and ensure it responds. -- resp, err := http.Get(debugURL) -- if err != nil { -- t.Fatal(err) -- } -- defer resp.Body.Close() -- data, err := io.ReadAll(resp.Body) -- if err != nil { -- t.Fatalf("reading HTTP response body: %v", err) -- } -- const want = "<title>GoPls" -- if !strings.Contains(string(data), want) { -- t.Errorf("GET %s response does not contain %q: <<%s>>", debugURL, want, data) -- } -- }) +-/* +-int fortythree() { return 42; } +-*/ +-import "C" +- +-func Foo() { +- print(C.fortytwo()) -} +--- p/p.go -- +-package p - --// startDebugging starts a debugging server. --// TODO(adonovan): move into command package? --func startDebugging(ctx context.Context, server protocol.Server, args *command.DebuggingArgs) (*command.DebuggingResult, error) { -- rawArgs, err := command.MarshalArgs(args) -- if err != nil { -- return nil, err -- } -- res0, err := server.ExecuteCommand(ctx, &protocol.ExecuteCommandParams{ -- Command: command.StartDebugging.ID(), -- Arguments: rawArgs, +-import "a.com/q" +- +-const P = q.Q + 1 +--- q/q.go -- +-package q +- +-import "a.com/p" +- +-const Q = p.P + 1 +-` +- +- Run(t, src, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics( +- env.AtRegexp("a/a.go", "import\n()"), +- FromSource(string(source.ParseError)), +- ), +- Diagnostics( +- AtPosition("c/c.go", 0, 0), +- FromSource(string(source.ListError)), +- WithMessage("may indicate failure to perform cgo processing"), +- ), +- Diagnostics( +- env.AtRegexp("p/p.go", `"a.com/q"`), +- FromSource(string(source.ListError)), +- WithMessage("import cycle not allowed"), +- ), +- ) - }) -- if err != nil { -- return nil, err -- } -- // res0 is the result of a schemaless (map[string]any) JSON decoding. -- // Re-encode and decode into the correct Go struct type. -- // TODO(adonovan): fix (*serverDispatcher).ExecuteCommand. -- data, err := json.Marshal(res0) -- if err != nil { -- return nil, err -- } -- var res *command.DebuggingResult -- if err := json.Unmarshal(data, &res); err != nil { -- return nil, err -- } -- return res, nil -} -diff -urN a/gopls/internal/regtest/diagnostics/analysis_test.go b/gopls/internal/regtest/diagnostics/analysis_test.go ---- a/gopls/internal/regtest/diagnostics/analysis_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/diagnostics/analysis_test.go 1970-01-01 08:00:00 -@@ -1,127 +0,0 @@ +diff -urN a/gopls/internal/regtest/diagnostics/invalidation_test.go b/gopls/internal/regtest/diagnostics/invalidation_test.go +--- a/gopls/internal/regtest/diagnostics/invalidation_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/diagnostics/invalidation_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,111 +0,0 @@ -// Copyright 2022 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. @@ -117451,127 +115499,111 @@ diff -urN a/gopls/internal/regtest/diagnostics/analysis_test.go b/gopls/internal - "fmt" - "testing" - -- "golang.org/x/tools/gopls/internal/lsp/cache" - "golang.org/x/tools/gopls/internal/lsp/protocol" - . "golang.org/x/tools/gopls/internal/lsp/regtest" -) - --// Test for the timeformat analyzer, following golang/vscode-go#2406. --// --// This test checks that applying the suggested fix from the analyzer resolves --// the diagnostic warning. --func TestTimeFormatAnalyzer(t *testing.T) { +-// Test for golang/go#50267: diagnostics should be re-sent after a file is +-// opened. +-func TestDiagnosticsAreResentAfterCloseOrOpen(t *testing.T) { - const files = ` --- go.mod -- -module mod.com - --go 1.18 +-go 1.16 --- main.go -- -package main - --import ( -- "fmt" -- "time" --) -- --func main() { -- now := time.Now() -- fmt.Println(now.Format("2006-02-01")) --}` -- -- Run(t, files, func(t *testing.T, env *Env) { +-func _() { +- x := 2 +-} +-` +- Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file. - env.OpenFile("main.go") -- -- var d protocol.PublishDiagnosticsParams +- var afterOpen protocol.PublishDiagnosticsParams - env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", "2006-02-01")), -- ReadDiagnostics("main.go", &d), +- ReadDiagnostics("main.go", &afterOpen), - ) -- -- env.ApplyQuickFixes("main.go", d.Diagnostics) -- env.AfterChange(NoDiagnostics(ForFile("main.go"))) +- env.CloseBuffer("main.go") +- var afterClose protocol.PublishDiagnosticsParams +- env.AfterChange( +- ReadDiagnostics("main.go", &afterClose), +- ) +- if afterOpen.Version == afterClose.Version { +- t.Errorf("publishDiagnostics: got the same version after closing (%d) as after opening", afterOpen.Version) +- } +- env.OpenFile("main.go") +- var afterReopen protocol.PublishDiagnosticsParams +- env.AfterChange( +- ReadDiagnostics("main.go", &afterReopen), +- ) +- if afterReopen.Version == afterClose.Version { +- t.Errorf("pubslishDiagnostics: got the same version after reopening (%d) as after closing", afterClose.Version) +- } - }) -} - --func TestAnalysisProgressReporting(t *testing.T) { +-// Test for the "chattyDiagnostics" setting: we should get re-published +-// diagnostics after every file change, even if diagnostics did not change. +-func TestChattyDiagnostics(t *testing.T) { - const files = ` --- go.mod -- -module mod.com - --go 1.18 -- +-go 1.16 --- main.go -- -package main - --func main() { --}` -- -- tests := []struct { -- setting bool -- want Expectation -- }{ -- {true, CompletedWork(cache.AnalysisProgressTitle, 1, true)}, -- {false, Not(CompletedWork(cache.AnalysisProgressTitle, 1, true))}, -- } -- -- for _, test := range tests { -- t.Run(fmt.Sprint(test.setting), func(t *testing.T) { -- WithOptions( -- Settings{ -- "reportAnalysisProgressAfter": "0s", -- "analysisProgressReporting": test.setting, -- }, -- ).Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- env.AfterChange(test.want) -- }) -- }) -- } +-func _() { +- x := 2 -} - --// Test the embed directive analyzer. --// --// There is a fix for missing imports, but it should not trigger for other --// kinds of issues reported by the analayzer, here the variable --// declaration following the embed directive is wrong. --func TestNoSuggestedFixesForEmbedDirectiveDeclaration(t *testing.T) { -- const generated = ` ---- go.mod -- --module mod.com -- --go 1.20 -- ---- foo.txt -- --FOO -- ---- main.go -- --package main -- --import _ "embed" +-// Irrelevant comment #0 +-` - --//go:embed foo.txt --var foo, bar string +- WithOptions( +- Settings{ +- "chattyDiagnostics": true, +- }, +- ).Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file. - --func main() { -- _ = foo --} --` -- Run(t, generated, func(t *testing.T, env *Env) { - env.OpenFile("main.go") - var d protocol.PublishDiagnosticsParams - env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", "//go:embed")), - ReadDiagnostics("main.go", &d), - ) -- if fixes := env.GetQuickFixes("main.go", d.Diagnostics); len(fixes) != 0 { -- t.Errorf("got quick fixes %v, wanted none", fixes) +- +- if len(d.Diagnostics) != 1 { +- t.Fatalf("len(Diagnostics) = %d, want 1", len(d.Diagnostics)) +- } +- msg := d.Diagnostics[0].Message +- +- for i := 0; i < 5; i++ { +- before := d.Version +- env.RegexpReplace("main.go", "Irrelevant comment #.", fmt.Sprintf("Irrelevant comment #%d", i)) +- env.AfterChange( +- ReadDiagnostics("main.go", &d), +- ) +- +- if d.Version == before { +- t.Errorf("after change, got version %d, want new version", d.Version) +- } +- +- // As a sanity check, make sure we have the same diagnostic. +- if len(d.Diagnostics) != 1 { +- t.Fatalf("len(Diagnostics) = %d, want 1", len(d.Diagnostics)) +- } +- newMsg := d.Diagnostics[0].Message +- if newMsg != msg { +- t.Errorf("after change, got message %q, want %q", newMsg, msg) +- } - } - }) -} -diff -urN a/gopls/internal/regtest/diagnostics/builtin_test.go b/gopls/internal/regtest/diagnostics/builtin_test.go ---- a/gopls/internal/regtest/diagnostics/builtin_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/diagnostics/builtin_test.go 1970-01-01 08:00:00 -@@ -1,35 +0,0 @@ +diff -urN a/gopls/internal/regtest/diagnostics/undeclared_test.go b/gopls/internal/regtest/diagnostics/undeclared_test.go +--- a/gopls/internal/regtest/diagnostics/undeclared_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/diagnostics/undeclared_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,73 +0,0 @@ -// Copyright 2021 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. @@ -117579,57 +115611,88 @@ diff -urN a/gopls/internal/regtest/diagnostics/builtin_test.go b/gopls/internal/ -package diagnostics - -import ( -- "strings" - "testing" - +- "golang.org/x/tools/gopls/internal/lsp/protocol" - . "golang.org/x/tools/gopls/internal/lsp/regtest" -) - --func TestIssue44866(t *testing.T) { +-func TestUndeclaredDiagnostics(t *testing.T) { - src := ` --- go.mod -- -module mod.com - -go 1.12 ---- a.go -- +--- a/a.go -- -package a - --const ( -- c = iota --) +-func _() int { +- return x +-} +--- b/b.go -- +-package b +- +-func _() int { +- var y int +- y = y +- return y +-} -` - Run(t, src, func(t *testing.T, env *Env) { -- env.OpenFile("a.go") -- loc := env.GoToDefinition(env.RegexpSearch("a.go", "iota")) -- if !strings.HasSuffix(string(loc.URI), "builtin.go") { -- t.Fatalf("jumped to %q, want builtin.go", loc.URI) +- isUnnecessary := func(diag protocol.Diagnostic) bool { +- for _, tag := range diag.Tags { +- if tag == protocol.Unnecessary { +- return true +- } +- } +- return false +- } +- +- // 'x' is undeclared, but still necessary. +- env.OpenFile("a/a.go") +- var adiags protocol.PublishDiagnosticsParams +- env.AfterChange( +- Diagnostics(env.AtRegexp("a/a.go", "x")), +- ReadDiagnostics("a/a.go", &adiags), +- ) +- if got := len(adiags.Diagnostics); got != 1 { +- t.Errorf("len(Diagnostics) = %d, want 1", got) +- } +- if diag := adiags.Diagnostics[0]; isUnnecessary(diag) { +- t.Errorf("%v tagged unnecessary, want necessary", diag) +- } +- +- // 'y = y' is pointless, and should be detected as unnecessary. +- env.OpenFile("b/b.go") +- var bdiags protocol.PublishDiagnosticsParams +- env.AfterChange( +- Diagnostics(env.AtRegexp("b/b.go", "y = y")), +- ReadDiagnostics("b/b.go", &bdiags), +- ) +- if got := len(bdiags.Diagnostics); got != 1 { +- t.Errorf("len(Diagnostics) = %d, want 1", got) +- } +- if diag := bdiags.Diagnostics[0]; !isUnnecessary(diag) { +- t.Errorf("%v tagged necessary, want unnecessary", diag) - } -- env.AfterChange(NoDiagnostics(ForFile("builtin.go"))) - }) -} -diff -urN a/gopls/internal/regtest/diagnostics/diagnostics_test.go b/gopls/internal/regtest/diagnostics/diagnostics_test.go ---- a/gopls/internal/regtest/diagnostics/diagnostics_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/diagnostics/diagnostics_test.go 1970-01-01 08:00:00 -@@ -1,2114 +0,0 @@ --// Copyright 2020 The Go Authors. All rights reserved. +diff -urN a/gopls/internal/regtest/inlayhints/inlayhints_test.go b/gopls/internal/regtest/inlayhints/inlayhints_test.go +--- a/gopls/internal/regtest/inlayhints/inlayhints_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/inlayhints/inlayhints_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,69 +0,0 @@ +-// Copyright 2022 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 diagnostics +-package inlayhint - -import ( -- "context" -- "fmt" -- "os/exec" - "testing" - - "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/hooks" -- "golang.org/x/tools/gopls/internal/lsp" -- "golang.org/x/tools/gopls/internal/lsp/fake" -- "golang.org/x/tools/gopls/internal/lsp/protocol" - . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/internal/testenv" +- "golang.org/x/tools/gopls/internal/lsp/source" -) - -func TestMain(m *testing.M) { @@ -117637,3472 +115700,3682 @@ diff -urN a/gopls/internal/regtest/diagnostics/diagnostics_test.go b/gopls/inter - Main(m, hooks.Options) -} - --// Use mod.com for all go.mod files due to golang/go#35230. --const exampleProgram = ` +-func TestEnablingInlayHints(t *testing.T) { +- const workspace = ` --- go.mod -- --module mod.com -- +-module inlayHint.test -go 1.12 ---- main.go -- --package main +--- lib.go -- +-package lib +-type Number int +-const ( +- Zero Number = iota +- One +- Two +-) +-` +- tests := []struct { +- label string +- enabled map[string]bool +- wantInlayHint bool +- }{ +- { +- label: "default", +- wantInlayHint: false, +- }, +- { +- label: "enable const", +- enabled: map[string]bool{source.ConstantValues: true}, +- wantInlayHint: true, +- }, +- { +- label: "enable parameter names", +- enabled: map[string]bool{source.ParameterNames: true}, +- wantInlayHint: false, +- }, +- } +- for _, test := range tests { +- t.Run(test.label, func(t *testing.T) { +- WithOptions( +- Settings{ +- "hints": test.enabled, +- }, +- ).Run(t, workspace, func(t *testing.T, env *Env) { +- env.OpenFile("lib.go") +- lens := env.InlayHints("lib.go") +- if gotInlayHint := len(lens) > 0; gotInlayHint != test.wantInlayHint { +- t.Errorf("got inlayHint: %t, want %t", gotInlayHint, test.wantInlayHint) +- } +- }) +- }) +- } +-} +diff -urN a/gopls/internal/regtest/marker/marker_test.go b/gopls/internal/regtest/marker/marker_test.go +--- a/gopls/internal/regtest/marker/marker_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/marker_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,30 +0,0 @@ +-// Copyright 2023 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. - --import "fmt" +-package marker - --func main() { -- fmt.Println("Hello World.") --}` +-import ( +- "os" +- "testing" - --func TestDiagnosticErrorInEditedFile(t *testing.T) { -- // This test is very basic: start with a clean Go program, make an error, and -- // get a diagnostic for that error. However, it also demonstrates how to -- // combine Expectations to await more complex state in the editor. -- Run(t, exampleProgram, func(t *testing.T, env *Env) { -- // Deleting the 'n' at the end of Println should generate a single error -- // diagnostic. -- env.OpenFile("main.go") -- env.RegexpReplace("main.go", "Printl(n)", "") -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", "Printl")), -- // Assert that this test has sent no error logs to the client. This is not -- // strictly necessary for testing this regression, but is included here -- // as an example of using the NoErrorLogs() expectation. Feel free to -- // delete. -- NoErrorLogs(), -- ) -- }) +- "golang.org/x/tools/gopls/internal/bug" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +- "golang.org/x/tools/internal/testenv" +-) +- +-func TestMain(m *testing.M) { +- bug.PanicOnBugs = true +- testenv.ExitIfSmallMachine() +- os.Exit(m.Run()) -} - --func TestMissingImportDiagsClearOnFirstFile(t *testing.T) { -- const onlyMod = ` ---- go.mod -- --module mod.com +-// Note: we use a separate package for the marker tests so that we can easily +-// compare their performance to the existing marker tests in ./internal/lsp. - --go 1.12 --` -- Run(t, onlyMod, func(t *testing.T, env *Env) { -- env.CreateBuffer("main.go", `package main +-// TestMarkers runs the marker tests from the testdata directory. +-// +-// See RunMarkerTests for details on how marker tests work. +-func TestMarkers(t *testing.T) { +- RunMarkerTests(t, "testdata") +-} +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/extract_method.txt b/gopls/internal/regtest/marker/testdata/codeaction/extract_method.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/extract_method.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/extract_method.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,244 +0,0 @@ +-This test exercises function and method extraction. - --func m() { -- log.Println() +--- flags -- +--ignore_extra_diags +- +--- basic.go -- +-package extract +- +-//@codeactionedit(A_XLessThanYP, "refactor.extract", meth1, "Extract method") +-//@codeactionedit(A_XLessThanYP, "refactor.extract", func1, "Extract function") +-//@codeactionedit(A_AddP1, "refactor.extract", meth2, "Extract method") +-//@codeactionedit(A_AddP1, "refactor.extract", func2, "Extract function") +-//@codeactionedit(A_AddP2, "refactor.extract", meth3, "Extract method") +-//@codeactionedit(A_AddP2, "refactor.extract", func3, "Extract function") +-//@codeactionedit(A_XLessThanY, "refactor.extract", meth4, "Extract method") +-//@codeactionedit(A_XLessThanY, "refactor.extract", func4, "Extract function") +-//@codeactionedit(A_Add1, "refactor.extract", meth5, "Extract method") +-//@codeactionedit(A_Add1, "refactor.extract", func5, "Extract function") +-//@codeactionedit(A_Add2, "refactor.extract", meth6, "Extract method") +-//@codeactionedit(A_Add2, "refactor.extract", func6, "Extract function") +- +-type A struct { +- x int +- y int -} --`) -- env.AfterChange(Diagnostics(env.AtRegexp("main.go", "log"))) -- env.SaveBuffer("main.go") -- env.AfterChange(NoDiagnostics(ForFile("main.go"))) -- }) +- +-func (a *A) XLessThanYP() bool { +- return a.x < a.y //@loc(A_XLessThanYP, re`return.*a\.y`) -} - --func TestDiagnosticErrorInNewFile(t *testing.T) { -- const brokenFile = `package main +-func (a *A) AddP() int { +- sum := a.x + a.y //@loc(A_AddP1, re`sum.*a\.y`) +- return sum //@loc(A_AddP2, re`return.*sum`) +-} - --const Foo = "abc --` -- Run(t, brokenFile, func(t *testing.T, env *Env) { -- env.CreateBuffer("broken.go", brokenFile) -- env.AfterChange(Diagnostics(env.AtRegexp("broken.go", "\"abc"))) -- }) +-func (a A) XLessThanY() bool { +- return a.x < a.y //@loc(A_XLessThanY, re`return.*a\.y`) -} - --// badPackage contains a duplicate definition of the 'a' const. --const badPackage = ` +-func (a A) Add() int { +- sum := a.x + a.y //@loc(A_Add1, re`sum.*a\.y`) +- return sum //@loc(A_Add2, re`return.*sum`) +-} +- +--- @func1/basic.go -- +---- before +-+++ after +-@@ -22 +22,5 @@ +-- return a.x < a.y //@loc(A_XLessThanYP, re`return.*a\.y`) +-+ return newFunction(a) //@loc(A_XLessThanYP, re`return.*a\.y`) +-+} +-+ +-+func newFunction(a *A) bool { +-+ return a.x < a.y +--- @func2/basic.go -- +---- before +-+++ after +-@@ -26,2 +26,7 @@ +-- sum := a.x + a.y //@loc(A_AddP1, re`sum.*a\.y`) +-+ sum := newFunction(a) //@loc(A_AddP1, re`sum.*a\.y`) +-- return sum //@loc(A_AddP2, re`return.*sum`) +-+ return sum //@loc(A_AddP2, re`return.*sum`) +-+} +-+ +-+func newFunction(a *A) int { +-+ sum := a.x + a.y +-+ return sum +--- @func3/basic.go -- +---- before +-+++ after +-@@ -27 +27,5 @@ +-- return sum //@loc(A_AddP2, re`return.*sum`) +-+ return newFunction(sum) //@loc(A_AddP2, re`return.*sum`) +-+} +-+ +-+func newFunction(sum int) int { +-+ return sum +--- @func4/basic.go -- +---- before +-+++ after +-@@ -31 +31,5 @@ +-- return a.x < a.y //@loc(A_XLessThanY, re`return.*a\.y`) +-+ return newFunction(a) //@loc(A_XLessThanY, re`return.*a\.y`) +-+} +-+ +-+func newFunction(a A) bool { +-+ return a.x < a.y +--- @func5/basic.go -- +---- before +-+++ after +-@@ -35 +35 @@ +-- sum := a.x + a.y //@loc(A_Add1, re`sum.*a\.y`) +-+ sum := newFunction(a) //@loc(A_Add1, re`sum.*a\.y`) +-@@ -39 +39,5 @@ +-+func newFunction(a A) int { +-+ sum := a.x + a.y +-+ return sum +-+} +-+ +--- @func6/basic.go -- +---- before +-+++ after +-@@ -36 +36 @@ +-- return sum //@loc(A_Add2, re`return.*sum`) +-+ return newFunction(sum) //@loc(A_Add2, re`return.*sum`) +-@@ -39 +39,4 @@ +-+func newFunction(sum int) int { +-+ return sum +-+} +-+ +--- @meth1/basic.go -- +---- before +-+++ after +-@@ -22 +22,5 @@ +-- return a.x < a.y //@loc(A_XLessThanYP, re`return.*a\.y`) +-+ return a.newMethod() //@loc(A_XLessThanYP, re`return.*a\.y`) +-+} +-+ +-+func (a *A) newMethod() bool { +-+ return a.x < a.y +--- @meth2/basic.go -- +---- before +-+++ after +-@@ -26,2 +26,7 @@ +-- sum := a.x + a.y //@loc(A_AddP1, re`sum.*a\.y`) +-+ sum := a.newMethod() //@loc(A_AddP1, re`sum.*a\.y`) +-- return sum //@loc(A_AddP2, re`return.*sum`) +-+ return sum //@loc(A_AddP2, re`return.*sum`) +-+} +-+ +-+func (a *A) newMethod() int { +-+ sum := a.x + a.y +-+ return sum +--- @meth3/basic.go -- +---- before +-+++ after +-@@ -27 +27,5 @@ +-- return sum //@loc(A_AddP2, re`return.*sum`) +-+ return a.newMethod(sum) //@loc(A_AddP2, re`return.*sum`) +-+} +-+ +-+func (*A) newMethod(sum int) int { +-+ return sum +--- @meth4/basic.go -- +---- before +-+++ after +-@@ -31 +31,5 @@ +-- return a.x < a.y //@loc(A_XLessThanY, re`return.*a\.y`) +-+ return a.newMethod() //@loc(A_XLessThanY, re`return.*a\.y`) +-+} +-+ +-+func (a A) newMethod() bool { +-+ return a.x < a.y +--- @meth5/basic.go -- +---- before +-+++ after +-@@ -35 +35 @@ +-- sum := a.x + a.y //@loc(A_Add1, re`sum.*a\.y`) +-+ sum := a.newMethod() //@loc(A_Add1, re`sum.*a\.y`) +-@@ -39 +39,5 @@ +-+func (a A) newMethod() int { +-+ sum := a.x + a.y +-+ return sum +-+} +-+ +--- @meth6/basic.go -- +---- before +-+++ after +-@@ -36 +36 @@ +-- return sum //@loc(A_Add2, re`return.*sum`) +-+ return a.newMethod(sum) //@loc(A_Add2, re`return.*sum`) +-@@ -39 +39,4 @@ +-+func (A) newMethod(sum int) int { +-+ return sum +-+} +-+ +--- context.go -- +-package extract +- +-import "context" +- +-//@codeactionedit(B_AddP, "refactor.extract", contextMeth1, "Extract method") +-//@codeactionedit(B_AddP, "refactor.extract", contextFunc1, "Extract function") +-//@codeactionedit(B_LongList, "refactor.extract", contextMeth2, "Extract method") +-//@codeactionedit(B_LongList, "refactor.extract", contextFunc2, "Extract function") +- +-type B struct { +- x int +- y int +-} +- +-func (b *B) AddP(ctx context.Context) (int, error) { +- sum := b.x + b.y +- return sum, ctx.Err() //@loc(B_AddP, re`return.*ctx\.Err\(\)`) +-} +- +-func (b *B) LongList(ctx context.Context) (int, error) { +- p1 := 1 +- p2 := 1 +- p3 := 1 +- return p1 + p2 + p3, ctx.Err() //@loc(B_LongList, re`return.*ctx\.Err\(\)`) +-} +--- @contextMeth1/context.go -- +---- before +-+++ after +-@@ -17 +17,5 @@ +-- return sum, ctx.Err() //@loc(B_AddP, re`return.*ctx\.Err\(\)`) +-+ return b.newMethod(ctx, sum) //@loc(B_AddP, re`return.*ctx\.Err\(\)`) +-+} +-+ +-+func (*B) newMethod(ctx context.Context, sum int) (int, error) { +-+ return sum, ctx.Err() +--- @contextMeth2/context.go -- +---- before +-+++ after +-@@ -24 +24 @@ +-- return p1 + p2 + p3, ctx.Err() //@loc(B_LongList, re`return.*ctx\.Err\(\)`) +-+ return b.newMethod(ctx, p1, p2, p3) //@loc(B_LongList, re`return.*ctx\.Err\(\)`) +-@@ -26 +26,4 @@ +-+ +-+func (*B) newMethod(ctx context.Context, p1 int, p2 int, p3 int) (int, error) { +-+ return p1 + p2 + p3, ctx.Err() +-+} +--- @contextFunc2/context.go -- +---- before +-+++ after +-@@ -24 +24 @@ +-- return p1 + p2 + p3, ctx.Err() //@loc(B_LongList, re`return.*ctx\.Err\(\)`) +-+ return newFunction(ctx, p1, p2, p3) //@loc(B_LongList, re`return.*ctx\.Err\(\)`) +-@@ -26 +26,4 @@ +-+ +-+func newFunction(ctx context.Context, p1 int, p2 int, p3 int) (int, error) { +-+ return p1 + p2 + p3, ctx.Err() +-+} +--- @contextFunc1/context.go -- +---- before +-+++ after +-@@ -17 +17,5 @@ +-- return sum, ctx.Err() //@loc(B_AddP, re`return.*ctx\.Err\(\)`) +-+ return newFunction(ctx, sum) //@loc(B_AddP, re`return.*ctx\.Err\(\)`) +-+} +-+ +-+func newFunction(ctx context.Context, sum int) (int, error) { +-+ return sum, ctx.Err() +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/extract_variable.txt b/gopls/internal/regtest/marker/testdata/codeaction/extract_variable.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/extract_variable.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/extract_variable.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,83 +0,0 @@ +-This test checks the behavior of the 'extract variable' code action. +- +--- flags -- +--ignore_extra_diags +- +--- basic_lit.go -- +-package extract +- +-func _() { +- var _ = 1 + 2 //@codeactionedit("1", "refactor.extract", basic_lit1) +- var _ = 3 + 4 //@codeactionedit("3 + 4", "refactor.extract", basic_lit2) +-} +- +--- @basic_lit1/basic_lit.go -- +---- before +-+++ after +-@@ -3,2 +3,3 @@ +--func _() { +-+func _() { +-+ x := 1 +-- var _ = 1 + 2 //@codeactionedit("1", "refactor.extract", basic_lit1) +-+ var _ = x + 2 //@codeactionedit("1", "refactor.extract", basic_lit1) +--- @basic_lit2/basic_lit.go -- +---- before +-+++ after +-@@ -5 +5,2 @@ +-- var _ = 3 + 4 //@codeactionedit("3 + 4", "refactor.extract", basic_lit2) +-+ x := 3 + 4 +-+ var _ = x //@codeactionedit("3 + 4", "refactor.extract", basic_lit2) +--- func_call.go -- +-package extract +- +-import "strconv" +- +-func _() { +- x0 := append([]int{}, 1) //@codeactionedit("append([]int{}, 1)", "refactor.extract", func_call1) +- str := "1" +- b, err := strconv.Atoi(str) //@codeactionedit("strconv.Atoi(str)", "refactor.extract", func_call2) +-} +- +--- @func_call1/func_call.go -- +---- before +-+++ after +-@@ -6 +6,2 @@ +-- x0 := append([]int{}, 1) //@codeactionedit("append([]int{}, 1)", "refactor.extract", func_call1) +-+ x := append([]int{}, 1) +-+ x0 := x //@codeactionedit("append([]int{}, 1)", "refactor.extract", func_call1) +--- @func_call2/func_call.go -- +---- before +-+++ after +-@@ -8 +8,2 @@ +-- b, err := strconv.Atoi(str) //@codeactionedit("strconv.Atoi(str)", "refactor.extract", func_call2) +-+ x, x1 := strconv.Atoi(str) +-+ b, err := x, x1 //@codeactionedit("strconv.Atoi(str)", "refactor.extract", func_call2) +--- scope.go -- +-package extract +- +-import "go/ast" +- +-func _() { +- x0 := 0 +- if true { +- y := ast.CompositeLit{} //@codeactionedit("ast.CompositeLit{}", "refactor.extract", scope1) +- } +- if true { +- x1 := !false //@codeactionedit("!false", "refactor.extract", scope2) +- } +-} +- +--- @scope1/scope.go -- +---- before +-+++ after +-@@ -8 +8,2 @@ +-- y := ast.CompositeLit{} //@codeactionedit("ast.CompositeLit{}", "refactor.extract", scope1) +-+ x := ast.CompositeLit{} +-+ y := x //@codeactionedit("ast.CompositeLit{}", "refactor.extract", scope1) +--- @scope2/scope.go -- +---- before +-+++ after +-@@ -11 +11,2 @@ +-- x1 := !false //@codeactionedit("!false", "refactor.extract", scope2) +-+ x := !false +-+ x1 := x //@codeactionedit("!false", "refactor.extract", scope2) +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/fill_struct.txt b/gopls/internal/regtest/marker/testdata/codeaction/fill_struct.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/fill_struct.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/fill_struct.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,630 +0,0 @@ +-This test checks the behavior of the 'fill struct' code action. +- +--- flags -- +--ignore_extra_diags +- --- go.mod -- --module mod.com +-module golang.org/lsptests/fillstruct +- +-go 1.18 +- +--- data/data.go -- +-package data +- +-type B struct { +- ExportedInt int +- unexportedInt int +-} - --go 1.12 --- a.go -- --package consts +-package fillstruct - --const a = 1 ---- b.go -- --package consts +-import ( +- "golang.org/lsptests/fillstruct/data" +-) - --const a = 2 --` +-type basicStruct struct { +- foo int +-} - --func TestDiagnosticClearingOnEdit(t *testing.T) { -- Run(t, badPackage, func(t *testing.T, env *Env) { -- env.OpenFile("b.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("a.go", "a = 1")), -- Diagnostics(env.AtRegexp("b.go", "a = 2")), -- ) +-var _ = basicStruct{} //@codeactionedit("}", "refactor.rewrite", a1) - -- // Fix the error by editing the const name in b.go to `b`. -- env.RegexpReplace("b.go", "(a) = 2", "b") -- env.AfterChange( -- NoDiagnostics(ForFile("a.go")), -- NoDiagnostics(ForFile("b.go")), -- ) -- }) +-type twoArgStruct struct { +- foo int +- bar string -} - --func TestDiagnosticClearingOnDelete_Issue37049(t *testing.T) { -- Run(t, badPackage, func(t *testing.T, env *Env) { -- env.OpenFile("a.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("a.go", "a = 1")), -- Diagnostics(env.AtRegexp("b.go", "a = 2")), -- ) -- env.RemoveWorkspaceFile("b.go") +-var _ = twoArgStruct{} //@codeactionedit("}", "refactor.rewrite", a2) - -- env.AfterChange( -- NoDiagnostics(ForFile("a.go")), -- NoDiagnostics(ForFile("b.go")), -- ) -- }) +-type nestedStruct struct { +- bar string +- basic basicStruct -} - --func TestDiagnosticClearingOnClose(t *testing.T) { -- Run(t, badPackage, func(t *testing.T, env *Env) { -- env.CreateBuffer("c.go", `package consts +-var _ = nestedStruct{} //@codeactionedit("}", "refactor.rewrite", a3) +- +-var _ = data.B{} //@codeactionedit("}", "refactor.rewrite", a4) +--- @a1/a.go -- +---- before +-+++ after +-@@ -11 +11,3 @@ +--var _ = basicStruct{} //@codeactionedit("}", "refactor.rewrite", a1) +-+var _ = basicStruct{ +-+ foo: 0, +-+} //@codeactionedit("}", "refactor.rewrite", a1) +--- @a2/a.go -- +---- before +-+++ after +-@@ -18 +18,4 @@ +--var _ = twoArgStruct{} //@codeactionedit("}", "refactor.rewrite", a2) +-+var _ = twoArgStruct{ +-+ foo: 0, +-+ bar: "", +-+} //@codeactionedit("}", "refactor.rewrite", a2) +--- @a3/a.go -- +---- before +-+++ after +-@@ -25 +25,4 @@ +--var _ = nestedStruct{} //@codeactionedit("}", "refactor.rewrite", a3) +-+var _ = nestedStruct{ +-+ bar: "", +-+ basic: basicStruct{}, +-+} //@codeactionedit("}", "refactor.rewrite", a3) +--- @a4/a.go -- +---- before +-+++ after +-@@ -27 +27,3 @@ +--var _ = data.B{} //@codeactionedit("}", "refactor.rewrite", a4) +-+var _ = data.B{ +-+ ExportedInt: 0, +-+} //@codeactionedit("}", "refactor.rewrite", a4) +--- a2.go -- +-package fillstruct - --const a = 3`) -- env.AfterChange( -- Diagnostics(env.AtRegexp("a.go", "a = 1")), -- Diagnostics(env.AtRegexp("b.go", "a = 2")), -- Diagnostics(env.AtRegexp("c.go", "a = 3")), -- ) -- env.CloseBuffer("c.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("a.go", "a = 1")), -- Diagnostics(env.AtRegexp("b.go", "a = 2")), -- NoDiagnostics(ForFile("c.go")), -- ) -- }) +-type typedStruct struct { +- m map[string]int +- s []int +- c chan int +- c1 <-chan int +- a [2]string -} - --// Tests golang/go#37978. --func TestIssue37978(t *testing.T) { -- Run(t, exampleProgram, func(t *testing.T, env *Env) { -- // Create a new workspace-level directory and empty file. -- env.CreateBuffer("c/c.go", "") +-var _ = typedStruct{} //@codeactionedit("}", "refactor.rewrite", a21) - -- // Write the file contents with a missing import. -- env.EditBuffer("c/c.go", protocol.TextEdit{ -- NewText: `package c +-type funStruct struct { +- fn func(i int) int +-} - --const a = http.MethodGet --`, -- }) -- env.AfterChange( -- Diagnostics(env.AtRegexp("c/c.go", "http.MethodGet")), -- ) -- // Save file, which will organize imports, adding the expected import. -- // Expect the diagnostics to clear. -- env.SaveBuffer("c/c.go") -- env.AfterChange( -- NoDiagnostics(ForFile("c/c.go")), -- ) -- }) +-var _ = funStruct{} //@codeactionedit("}", "refactor.rewrite", a22) +- +-type funStructCompex struct { +- fn func(i int, s string) (string, int) -} - --// Tests golang/go#38878: good a.go, bad a_test.go, remove a_test.go but its errors remain --// If the file is open in the editor, this is working as intended --// If the file is not open in the editor, the errors go away --const test38878 = ` ---- go.mod -- --module foo +-var _ = funStructCompex{} //@codeactionedit("}", "refactor.rewrite", a23) - --go 1.12 ---- a.go -- --package x +-type funStructEmpty struct { +- fn func() +-} - --// import "fmt" +-var _ = funStructEmpty{} //@codeactionedit("}", "refactor.rewrite", a24) +- +--- @a21/a2.go -- +---- before +-+++ after +-@@ -11 +11,7 @@ +--var _ = typedStruct{} //@codeactionedit("}", "refactor.rewrite", a21) +-+var _ = typedStruct{ +-+ m: map[string]int{}, +-+ s: []int{}, +-+ c: make(chan int), +-+ c1: make(<-chan int), +-+ a: [2]string{}, +-+} //@codeactionedit("}", "refactor.rewrite", a21) +--- @a22/a2.go -- +---- before +-+++ after +-@@ -17 +17,4 @@ +--var _ = funStruct{} //@codeactionedit("}", "refactor.rewrite", a22) +-+var _ = funStruct{ +-+ fn: func(i int) int { +-+ }, +-+} //@codeactionedit("}", "refactor.rewrite", a22) +--- @a23/a2.go -- +---- before +-+++ after +-@@ -23 +23,4 @@ +--var _ = funStructCompex{} //@codeactionedit("}", "refactor.rewrite", a23) +-+var _ = funStructCompex{ +-+ fn: func(i int, s string) (string, int) { +-+ }, +-+} //@codeactionedit("}", "refactor.rewrite", a23) +--- @a24/a2.go -- +---- before +-+++ after +-@@ -29 +29,4 @@ +--var _ = funStructEmpty{} //@codeactionedit("}", "refactor.rewrite", a24) +-+var _ = funStructEmpty{ +-+ fn: func() { +-+ }, +-+} //@codeactionedit("}", "refactor.rewrite", a24) +--- a3.go -- +-package fillstruct - --func f() {} +-import ( +- "go/ast" +- "go/token" +-) - ---- a_test.go -- --package x +-type Foo struct { +- A int +-} - --import "testing" +-type Bar struct { +- X *Foo +- Y *Foo +-} - --func TestA(t *testing.T) { -- f(3) +-var _ = Bar{} //@codeactionedit("}", "refactor.rewrite", a31) +- +-type importedStruct struct { +- m map[*ast.CompositeLit]ast.Field +- s []ast.BadExpr +- a [3]token.Token +- c chan ast.EmptyStmt +- fn func(ast_decl ast.DeclStmt) ast.Ellipsis +- st ast.CompositeLit -} --` - --// Tests golang/go#38878: deleting a test file should clear its errors, and --// not break the workspace. --func TestDeleteTestVariant(t *testing.T) { -- Run(t, test38878, func(t *testing.T, env *Env) { -- env.AfterChange(Diagnostics(env.AtRegexp("a_test.go", `f\((3)\)`))) -- env.RemoveWorkspaceFile("a_test.go") -- env.AfterChange(NoDiagnostics(ForFile("a_test.go"))) +-var _ = importedStruct{} //@codeactionedit("}", "refactor.rewrite", a32) - -- // Make sure the test variant has been removed from the workspace by -- // triggering a metadata load. -- env.OpenFile("a.go") -- env.RegexpReplace("a.go", `// import`, "import") -- env.AfterChange(Diagnostics(env.AtRegexp("a.go", `"fmt"`))) -- }) +-type pointerBuiltinStruct struct { +- b *bool +- s *string +- i *int -} - --// Tests golang/go#38878: deleting a test file on disk while it's still open --// should not clear its errors. --func TestDeleteTestVariant_DiskOnly(t *testing.T) { -- Run(t, test38878, func(t *testing.T, env *Env) { -- env.OpenFile("a_test.go") -- env.AfterChange(Diagnostics(AtPosition("a_test.go", 5, 3))) -- env.Sandbox.Workdir.RemoveFile(context.Background(), "a_test.go") -- env.AfterChange(Diagnostics(AtPosition("a_test.go", 5, 3))) -- }) +-var _ = pointerBuiltinStruct{} //@codeactionedit("}", "refactor.rewrite", a33) +- +-var _ = []ast.BasicLit{ +- {}, //@codeactionedit("}", "refactor.rewrite", a34) +-} +- +-var _ = []ast.BasicLit{{}} //@codeactionedit("}", "refactor.rewrite", a35) +--- @a31/a3.go -- +---- before +-+++ after +-@@ -17 +17,4 @@ +--var _ = Bar{} //@codeactionedit("}", "refactor.rewrite", a31) +-+var _ = Bar{ +-+ X: &Foo{}, +-+ Y: &Foo{}, +-+} //@codeactionedit("}", "refactor.rewrite", a31) +--- @a32/a3.go -- +---- before +-+++ after +-@@ -28 +28,9 @@ +--var _ = importedStruct{} //@codeactionedit("}", "refactor.rewrite", a32) +-+var _ = importedStruct{ +-+ m: map[*ast.CompositeLit]ast.Field{}, +-+ s: []ast.BadExpr{}, +-+ a: [3]token.Token{}, +-+ c: make(chan ast.EmptyStmt), +-+ fn: func(ast_decl ast.DeclStmt) ast.Ellipsis { +-+ }, +-+ st: ast.CompositeLit{}, +-+} //@codeactionedit("}", "refactor.rewrite", a32) +--- @a33/a3.go -- +---- before +-+++ after +-@@ -36 +36,5 @@ +--var _ = pointerBuiltinStruct{} //@codeactionedit("}", "refactor.rewrite", a33) +-+var _ = pointerBuiltinStruct{ +-+ b: new(bool), +-+ s: new(string), +-+ i: new(int), +-+} //@codeactionedit("}", "refactor.rewrite", a33) +--- @a34/a3.go -- +---- before +-+++ after +-@@ -39 +39,5 @@ +-- {}, //@codeactionedit("}", "refactor.rewrite", a34) +-+ { +-+ ValuePos: 0, +-+ Kind: 0, +-+ Value: "", +-+ }, //@codeactionedit("}", "refactor.rewrite", a34) +--- @a35/a3.go -- +---- before +-+++ after +-@@ -42 +42,5 @@ +--var _ = []ast.BasicLit{{}} //@codeactionedit("}", "refactor.rewrite", a35) +-+var _ = []ast.BasicLit{{ +-+ ValuePos: 0, +-+ Kind: 0, +-+ Value: "", +-+}} //@codeactionedit("}", "refactor.rewrite", a35) +--- a4.go -- +-package fillstruct +- +-import "go/ast" +- +-type iStruct struct { +- X int +-} +- +-type sStruct struct { +- str string +-} +- +-type multiFill struct { +- num int +- strin string +- arr []int +-} +- +-type assignStruct struct { +- n ast.Node +-} +- +-func fill() { +- var x int +- var _ = iStruct{} //@codeactionedit("}", "refactor.rewrite", a41) +- +- var s string +- var _ = sStruct{} //@codeactionedit("}", "refactor.rewrite", a42) +- +- var n int +- _ = []int{} +- if true { +- arr := []int{1, 2} +- } +- var _ = multiFill{} //@codeactionedit("}", "refactor.rewrite", a43) +- +- var node *ast.CompositeLit +- var _ = assignStruct{} //@codeactionedit("}", "refactor.rewrite", a45) +-} +- +--- @a41/a4.go -- +---- before +-+++ after +-@@ -25 +25,3 @@ +-- var _ = iStruct{} //@codeactionedit("}", "refactor.rewrite", a41) +-+ var _ = iStruct{ +-+ X: x, +-+ } //@codeactionedit("}", "refactor.rewrite", a41) +--- @a42/a4.go -- +---- before +-+++ after +-@@ -28 +28,3 @@ +-- var _ = sStruct{} //@codeactionedit("}", "refactor.rewrite", a42) +-+ var _ = sStruct{ +-+ str: s, +-+ } //@codeactionedit("}", "refactor.rewrite", a42) +--- @a43/a4.go -- +---- before +-+++ after +-@@ -35 +35,5 @@ +-- var _ = multiFill{} //@codeactionedit("}", "refactor.rewrite", a43) +-+ var _ = multiFill{ +-+ num: n, +-+ strin: s, +-+ arr: []int{}, +-+ } //@codeactionedit("}", "refactor.rewrite", a43) +--- @a45/a4.go -- +---- before +-+++ after +-@@ -38 +38,3 @@ +-- var _ = assignStruct{} //@codeactionedit("}", "refactor.rewrite", a45) +-+ var _ = assignStruct{ +-+ n: node, +-+ } //@codeactionedit("}", "refactor.rewrite", a45) +--- fill_struct.go -- +-package fillstruct +- +-type StructA struct { +- unexportedIntField int +- ExportedIntField int +- MapA map[int]string +- Array []int +- StructB +-} +- +-type StructA2 struct { +- B *StructB +-} +- +-type StructA3 struct { +- B StructB +-} +- +-func fill() { +- a := StructA{} //@codeactionedit("}", "refactor.rewrite", fill_struct1) +- b := StructA2{} //@codeactionedit("}", "refactor.rewrite", fill_struct2) +- c := StructA3{} //@codeactionedit("}", "refactor.rewrite", fill_struct3) +- if true { +- _ = StructA3{} //@codeactionedit("}", "refactor.rewrite", fill_struct4) +- } +-} +- +--- @fill_struct1/fill_struct.go -- +---- before +-+++ after +-@@ -20 +20,7 @@ +-- a := StructA{} //@codeactionedit("}", "refactor.rewrite", fill_struct1) +-+ a := StructA{ +-+ unexportedIntField: 0, +-+ ExportedIntField: 0, +-+ MapA: map[int]string{}, +-+ Array: []int{}, +-+ StructB: StructB{}, +-+ } //@codeactionedit("}", "refactor.rewrite", fill_struct1) +--- @fill_struct2/fill_struct.go -- +---- before +-+++ after +-@@ -21 +21,3 @@ +-- b := StructA2{} //@codeactionedit("}", "refactor.rewrite", fill_struct2) +-+ b := StructA2{ +-+ B: &StructB{}, +-+ } //@codeactionedit("}", "refactor.rewrite", fill_struct2) +--- @fill_struct3/fill_struct.go -- +---- before +-+++ after +-@@ -22 +22,3 @@ +-- c := StructA3{} //@codeactionedit("}", "refactor.rewrite", fill_struct3) +-+ c := StructA3{ +-+ B: StructB{}, +-+ } //@codeactionedit("}", "refactor.rewrite", fill_struct3) +--- @fill_struct4/fill_struct.go -- +---- before +-+++ after +-@@ -24 +24,3 @@ +-- _ = StructA3{} //@codeactionedit("}", "refactor.rewrite", fill_struct4) +-+ _ = StructA3{ +-+ B: StructB{}, +-+ } //@codeactionedit("}", "refactor.rewrite", fill_struct4) +--- fill_struct_anon.go -- +-package fillstruct +- +-type StructAnon struct { +- a struct{} +- b map[string]interface{} +- c map[string]struct { +- d int +- e bool +- } +-} +- +-func fill() { +- _ := StructAnon{} //@codeactionedit("}", "refactor.rewrite", fill_struct_anon) +-} +--- @fill_struct_anon/fill_struct_anon.go -- +---- before +-+++ after +-@@ -13 +13,5 @@ +-- _ := StructAnon{} //@codeactionedit("}", "refactor.rewrite", fill_struct_anon) +-+ _ := StructAnon{ +-+ a: struct{}{}, +-+ b: map[string]interface{}{}, +-+ c: map[string]struct{d int; e bool}{}, +-+ } //@codeactionedit("}", "refactor.rewrite", fill_struct_anon) +--- fill_struct_nested.go -- +-package fillstruct +- +-type StructB struct { +- StructC +-} +- +-type StructC struct { +- unexportedInt int +-} +- +-func nested() { +- c := StructB{ +- StructC: StructC{}, //@codeactionedit("}", "refactor.rewrite", fill_nested) +- } +-} +- +--- @fill_nested/fill_struct_nested.go -- +---- before +-+++ after +-@@ -13 +13,3 @@ +-- StructC: StructC{}, //@codeactionedit("}", "refactor.rewrite", fill_nested) +-+ StructC: StructC{ +-+ unexportedInt: 0, +-+ }, //@codeactionedit("}", "refactor.rewrite", fill_nested) +--- fill_struct_package.go -- +-package fillstruct +- +-import ( +- h2 "net/http" +- +- "golang.org/lsptests/fillstruct/data" +-) +- +-func unexported() { +- a := data.B{} //@codeactionedit("}", "refactor.rewrite", fill_struct_package1) +- _ = h2.Client{} //@codeactionedit("}", "refactor.rewrite", fill_struct_package2) +-} +--- @fill_struct_package1/fill_struct_package.go -- +---- before +-+++ after +-@@ -10 +10,3 @@ +-- a := data.B{} //@codeactionedit("}", "refactor.rewrite", fill_struct_package1) +-+ a := data.B{ +-+ ExportedInt: 0, +-+ } //@codeactionedit("}", "refactor.rewrite", fill_struct_package1) +--- @fill_struct_package2/fill_struct_package.go -- +---- before +-+++ after +-@@ -11 +11,7 @@ +-- _ = h2.Client{} //@codeactionedit("}", "refactor.rewrite", fill_struct_package2) +-+ _ = h2.Client{ +-+ Transport: nil, +-+ CheckRedirect: func(req *h2.Request, via []*h2.Request) error { +-+ }, +-+ Jar: nil, +-+ Timeout: 0, +-+ } //@codeactionedit("}", "refactor.rewrite", fill_struct_package2) +--- fill_struct_partial.go -- +-package fillstruct +- +-type StructPartialA struct { +- PrefilledInt int +- UnfilledInt int +- StructPartialB +-} +- +-type StructPartialB struct { +- PrefilledInt int +- UnfilledInt int +-} +- +-func fill() { +- a := StructPartialA{ +- PrefilledInt: 5, +- } //@codeactionedit("}", "refactor.rewrite", fill_struct_partial1) +- b := StructPartialB{ +- /* this comment should disappear */ +- PrefilledInt: 7, // This comment should be blown away. +- /* As should +- this one */ +- } //@codeactionedit("}", "refactor.rewrite", fill_struct_partial2) +-} +- +--- @fill_struct_partial1/fill_struct_partial.go -- +---- before +-+++ after +-@@ -16 +16,3 @@ +-- PrefilledInt: 5, +-+ PrefilledInt: 5, +-+ UnfilledInt: 0, +-+ StructPartialB: StructPartialB{}, +--- @fill_struct_partial2/fill_struct_partial.go -- +---- before +-+++ after +-@@ -19,4 +19,2 @@ +-- /* this comment should disappear */ +-+ PrefilledInt: 7, +-- PrefilledInt: 7, // This comment should be blown away. +-- /* As should +-- this one */ +-+ UnfilledInt: 0, +--- fill_struct_spaces.go -- +-package fillstruct +- +-type StructD struct { +- ExportedIntField int +-} +- +-func spaces() { +- d := StructD{} //@codeactionedit("}", "refactor.rewrite", fill_struct_spaces) +-} +- +--- @fill_struct_spaces/fill_struct_spaces.go -- +---- before +-+++ after +-@@ -8 +8,3 @@ +-- d := StructD{} //@codeactionedit("}", "refactor.rewrite", fill_struct_spaces) +-+ d := StructD{ +-+ ExportedIntField: 0, +-+ } //@codeactionedit("}", "refactor.rewrite", fill_struct_spaces) +--- fill_struct_unsafe.go -- +-package fillstruct +- +-import "unsafe" +- +-type unsafeStruct struct { +- x int +- p unsafe.Pointer +-} +- +-func fill() { +- _ := unsafeStruct{} //@codeactionedit("}", "refactor.rewrite", fill_struct_unsafe) +-} +- +--- @fill_struct_unsafe/fill_struct_unsafe.go -- +---- before +-+++ after +-@@ -11 +11,4 @@ +-- _ := unsafeStruct{} //@codeactionedit("}", "refactor.rewrite", fill_struct_unsafe) +-+ _ := unsafeStruct{ +-+ x: 0, +-+ p: nil, +-+ } //@codeactionedit("}", "refactor.rewrite", fill_struct_unsafe) +--- typeparams.go -- +-package fillstruct +- +-type emptyStructWithTypeParams[A any] struct{} +- +-var _ = emptyStructWithTypeParams[int]{} // no suggested fix +- +-type basicStructWithTypeParams[T any] struct { +- foo T +-} +- +-var _ = basicStructWithTypeParams[int]{} //@codeactionedit("}", "refactor.rewrite", typeparams1) +- +-type twoArgStructWithTypeParams[F, B any] struct { +- foo F +- bar B +-} +- +-var _ = twoArgStructWithTypeParams[string, int]{} //@codeactionedit("}", "refactor.rewrite", typeparams2) +- +-var _ = twoArgStructWithTypeParams[int, string]{ +- bar: "bar", +-} //@codeactionedit("}", "refactor.rewrite", typeparams3) +- +-type nestedStructWithTypeParams struct { +- bar string +- basic basicStructWithTypeParams[int] +-} +- +-var _ = nestedStructWithTypeParams{} //@codeactionedit("}", "refactor.rewrite", typeparams4) +- +-func _[T any]() { +- type S struct{ t T } +- _ = S{} //@codeactionedit("}", "refactor.rewrite", typeparams5) +-} +--- @typeparams1/typeparams.go -- +---- before +-+++ after +-@@ -11 +11,3 @@ +--var _ = basicStructWithTypeParams[int]{} //@codeactionedit("}", "refactor.rewrite", typeparams1) +-+var _ = basicStructWithTypeParams[int]{ +-+ foo: 0, +-+} //@codeactionedit("}", "refactor.rewrite", typeparams1) +--- @typeparams2/typeparams.go -- +---- before +-+++ after +-@@ -18 +18,4 @@ +--var _ = twoArgStructWithTypeParams[string, int]{} //@codeactionedit("}", "refactor.rewrite", typeparams2) +-+var _ = twoArgStructWithTypeParams[string, int]{ +-+ foo: "", +-+ bar: 0, +-+} //@codeactionedit("}", "refactor.rewrite", typeparams2) +--- @typeparams3/typeparams.go -- +---- before +-+++ after +-@@ -20 +20,2 @@ +--var _ = twoArgStructWithTypeParams[int, string]{ +-+var _ = twoArgStructWithTypeParams[int, string]{ +-+ foo: 0, +--- @typeparams4/typeparams.go -- +---- before +-+++ after +-@@ -29 +29,4 @@ +--var _ = nestedStructWithTypeParams{} //@codeactionedit("}", "refactor.rewrite", typeparams4) +-+var _ = nestedStructWithTypeParams{ +-+ bar: "", +-+ basic: basicStructWithTypeParams{}, +-+} //@codeactionedit("}", "refactor.rewrite", typeparams4) +--- @typeparams5/typeparams.go -- +---- before +-+++ after +-@@ -33 +33,3 @@ +-- _ = S{} //@codeactionedit("}", "refactor.rewrite", typeparams5) +-+ _ = S{ +-+ t: *new(T), +-+ } //@codeactionedit("}", "refactor.rewrite", typeparams5) +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/functionextraction_issue44813.txt b/gopls/internal/regtest/marker/testdata/codeaction/functionextraction_issue44813.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/functionextraction_issue44813.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/functionextraction_issue44813.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,42 +0,0 @@ +-This test verifies the fix for golang/go#44813: extraction failure when there +-are blank identifiers. +- +--- go.mod -- +-module mod.test/extract +- +-go 1.18 +- +--- p.go -- +-package extract +- +-import "fmt" +- +-func main() { +- x := []rune{} //@codeaction("x", end, "refactor.extract", ext) +- s := "HELLO" +- for _, c := range s { +- x = append(x, c) +- } //@loc(end, "}") +- fmt.Printf("%x\n", x) -} - --// TestNoMod confirms that gopls continues to work when a user adds a go.mod --// file to their workspace. --func TestNoMod(t *testing.T) { -- const noMod = ` ---- main.go -- --package main +--- @ext/p.go -- +-package extract - --import "mod.com/bob" +-import "fmt" - -func main() { -- bob.Hello() +- //@codeaction("x", end, "refactor.extract", ext) +- x := newFunction() //@loc(end, "}") +- fmt.Printf("%x\n", x) -} ---- bob/bob.go -- --package bob - --func Hello() { -- var x int +-func newFunction() []rune { +- x := []rune{} +- s := "HELLO" +- for _, c := range s { +- x = append(x, c) +- } +- return x -} --` - -- t.Run("manual", func(t *testing.T) { -- Run(t, noMod, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `"mod.com/bob"`)), -- ) -- env.CreateBuffer("go.mod", `module mod.com +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/functionextraction.txt b/gopls/internal/regtest/marker/testdata/codeaction/functionextraction.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/functionextraction.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/functionextraction.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,583 +0,0 @@ +-This test verifies various behaviors of function extraction. - -- go 1.12 --`) -- env.SaveBuffer("go.mod") -- var d protocol.PublishDiagnosticsParams -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- Diagnostics(env.AtRegexp("bob/bob.go", "x")), -- ReadDiagnostics("bob/bob.go", &d), -- ) -- if len(d.Diagnostics) != 1 { -- t.Fatalf("expected 1 diagnostic, got %v", len(d.Diagnostics)) -- } -- }) -- }) -- t.Run("initialized", func(t *testing.T) { -- Run(t, noMod, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `"mod.com/bob"`)), -- ) -- env.RunGoCommand("mod", "init", "mod.com") -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- Diagnostics(env.AtRegexp("bob/bob.go", "x")), -- ) -- }) -- }) +--- go.mod -- +-module mod.test/extract - -- t.Run("without workspace module", func(t *testing.T) { -- WithOptions( -- Modes(Default), -- ).Run(t, noMod, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `"mod.com/bob"`)), -- ) -- if err := env.Sandbox.RunGoCommand(env.Ctx, "", "mod", []string{"init", "mod.com"}, nil, true); err != nil { -- t.Fatal(err) -- } -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- Diagnostics(env.AtRegexp("bob/bob.go", "x")), -- ) -- }) -- }) +-go 1.18 +- +--- basic.go -- +-package extract +- +-func _() { //@codeaction("{", closeBracket, "refactor.extract", outer) +- a := 1 //@codeaction("a", end, "refactor.extract", inner) +- _ = a + 4 //@loc(end, "4") +-} //@loc(closeBracket, "}") +- +--- @inner/basic.go -- +-package extract +- +-func _() { //@codeaction("{", closeBracket, "refactor.extract", outer) +- //@codeaction("a", end, "refactor.extract", inner) +- newFunction() //@loc(end, "4") -} - --// Tests golang/go#38267. --func TestIssue38267(t *testing.T) { -- const testPackage = ` ---- go.mod -- --module mod.com +-func newFunction() { +- a := 1 +- _ = a + 4 +-} //@loc(closeBracket, "}") - --go 1.12 ---- lib.go -- --package lib +--- @outer/basic.go -- +-package extract - --func Hello(x string) { -- _ = x +-func _() { //@codeaction("{", closeBracket, "refactor.extract", outer) +- //@codeaction("a", end, "refactor.extract", inner) +- newFunction() //@loc(end, "4") -} ---- lib_test.go -- --package lib - --import "testing" +-func newFunction() { +- a := 1 +- _ = a + 4 +-} //@loc(closeBracket, "}") - --type testStruct struct{ -- name string +--- return.go -- +-package extract +- +-func _() bool { +- x := 1 +- if x == 0 { //@codeaction("if", ifend, "refactor.extract", return) +- return true +- } //@loc(ifend, "}") +- return false -} - --func TestHello(t *testing.T) { -- testStructs := []*testStruct{ -- &testStruct{"hello"}, -- &testStruct{"goodbye"}, -- } -- for y := range testStructs { -- _ = y -- } +--- @return/return.go -- +-package extract +- +-func _() bool { +- x := 1 +- //@codeaction("if", ifend, "refactor.extract", return) +- shouldReturn, returnValue := newFunction(x) +- if shouldReturn { +- return returnValue +- } //@loc(ifend, "}") +- return false -} --` - -- Run(t, testPackage, func(t *testing.T, env *Env) { -- env.OpenFile("lib_test.go") -- env.AfterChange( -- Diagnostics(AtPosition("lib_test.go", 10, 2)), -- Diagnostics(AtPosition("lib_test.go", 11, 2)), -- ) -- env.OpenFile("lib.go") -- env.RegexpReplace("lib.go", "_ = x", "var y int") -- env.AfterChange( -- Diagnostics(env.AtRegexp("lib.go", "y int")), -- NoDiagnostics(ForFile("lib_test.go")), -- ) -- }) +-func newFunction(x int) (bool, bool) { +- if x == 0 { +- return true, true +- } +- return false, false -} - --// Tests golang/go#38328. --func TestPackageChange_Issue38328(t *testing.T) { -- const packageChange = ` ---- go.mod -- --module fake +--- return_nonnested.go -- +-package extract - --go 1.12 ---- a.go -- --package foo --func main() {} --` -- Run(t, packageChange, func(t *testing.T, env *Env) { -- env.OpenFile("a.go") -- env.RegexpReplace("a.go", "foo", "foox") -- env.AfterChange( -- NoDiagnostics(ForFile("a.go")), -- ) -- }) +-func _() bool { +- x := 1 //@codeaction("x", rnnEnd, "refactor.extract", rnn) +- if x == 0 { +- return true +- } +- return false //@loc(rnnEnd, "false") -} - --const testPackageWithRequire = ` ---- go.mod -- --module mod.com +--- @rnn/return_nonnested.go -- +-package extract - --go 1.12 +-func _() bool { +- //@codeaction("x", rnnEnd, "refactor.extract", rnn) +- return newFunction() //@loc(rnnEnd, "false") +-} - --require foo.test v1.2.3 ---- go.sum -- --foo.test v1.2.3 h1:TMA+lyd1ck0TqjSFpNe4T6cf/K6TYkoHwOOcMBMjaEw= --foo.test v1.2.3/go.mod h1:Ij3kyLIe5lzjycjh13NL8I2gX0quZuTdW0MnmlwGBL4= ---- print.go -- --package lib +-func newFunction() bool { +- x := 1 +- if x == 0 { +- return true +- } +- return false +-} - --import ( -- "fmt" +--- return_complex.go -- +-package extract - -- "foo.test/bar" --) +-import "fmt" - --func PrintAnswer() { -- fmt.Printf("answer: %s", bar.Answer) +-func _() (int, string, error) { +- x := 1 +- y := "hello" +- z := "bye" //@codeaction("z", rcEnd, "refactor.extract", rc) +- if y == z { +- return x, y, fmt.Errorf("same") +- } else if false { +- z = "hi" +- return x, z, nil +- } //@loc(rcEnd, "}") +- return x, z, nil -} --` - --const testPackageWithRequireProxy = ` ---- foo.test@v1.2.3/go.mod -- --module foo.test +--- @rc/return_complex.go -- +-package extract - --go 1.12 ---- foo.test@v1.2.3/bar/const.go -- --package bar +-import "fmt" - --const Answer = 42 --` +-func _() (int, string, error) { +- x := 1 +- y := "hello" +- //@codeaction("z", rcEnd, "refactor.extract", rc) +- z, shouldReturn, returnValue, returnValue1, returnValue2 := newFunction(y, x) +- if shouldReturn { +- return returnValue, returnValue1, returnValue2 +- } //@loc(rcEnd, "}") +- return x, z, nil +-} - --func TestResolveDiagnosticWithDownload(t *testing.T) { -- WithOptions( -- ProxyFiles(testPackageWithRequireProxy), -- ).Run(t, testPackageWithRequire, func(t *testing.T, env *Env) { -- env.OpenFile("print.go") -- // Check that gopackages correctly loaded this dependency. We should get a -- // diagnostic for the wrong formatting type. -- env.AfterChange( -- Diagnostics( -- env.AtRegexp("print.go", "fmt.Printf"), -- WithMessage("wrong type int"), -- ), -- ) -- }) +-func newFunction(y string, x int) (string, bool, int, string, error) { +- z := "bye" +- if y == z { +- return "", true, x, y, fmt.Errorf("same") +- } else if false { +- z = "hi" +- return "", true, x, z, nil +- } +- return z, false, 0, "", nil -} - --func TestMissingDependency(t *testing.T) { -- Run(t, testPackageWithRequire, func(t *testing.T, env *Env) { -- env.OpenFile("print.go") -- env.Await( -- // Log messages are asynchronous to other events on the LSP stream, so we -- // can't use OnceMet or AfterChange here. -- LogMatching(protocol.Error, "initial workspace load failed", 1, false), -- ) -- }) +--- return_complex_nonnested.go -- +-package extract +- +-import "fmt" +- +-func _() (int, string, error) { +- x := 1 +- y := "hello" +- z := "bye" //@codeaction("z", rcnnEnd, "refactor.extract", rcnn) +- if y == z { +- return x, y, fmt.Errorf("same") +- } else if false { +- z = "hi" +- return x, z, nil +- } +- return x, z, nil //@loc(rcnnEnd, "nil") -} - --// Tests golang/go#36951. --func TestAdHocPackages_Issue36951(t *testing.T) { -- const adHoc = ` ---- b/b.go -- --package b +--- @rcnn/return_complex_nonnested.go -- +-package extract - --func Hello() { -- var x int +-import "fmt" +- +-func _() (int, string, error) { +- x := 1 +- y := "hello" +- //@codeaction("z", rcnnEnd, "refactor.extract", rcnn) +- return newFunction(y, x) //@loc(rcnnEnd, "nil") -} --` -- Run(t, adHoc, func(t *testing.T, env *Env) { -- env.OpenFile("b/b.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("b/b.go", "x")), -- ) -- }) +- +-func newFunction(y string, x int) (int, string, error) { +- z := "bye" +- if y == z { +- return x, y, fmt.Errorf("same") +- } else if false { +- z = "hi" +- return x, z, nil +- } +- return x, z, nil -} - --// Tests golang/go#37984: GOPATH should be read from the go command. --func TestNoGOPATH_Issue37984(t *testing.T) { -- const files = ` ---- main.go -- --package main +--- return_func_lit.go -- +-package extract +- +-import "go/ast" - -func _() { -- fmt.Println("Hello World") --} --` -- WithOptions( -- EnvVars{ -- "GOPATH": "", -- "GO111MODULE": "off", -- }, -- ).Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- env.AfterChange(Diagnostics(env.AtRegexp("main.go", "fmt"))) -- env.SaveBuffer("main.go") -- env.AfterChange(NoDiagnostics(ForFile("main.go"))) +- ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool { +- if n == nil { //@codeaction("if", rflEnd, "refactor.extract", rfl) +- return true +- } //@loc(rflEnd, "}") +- return false - }) -} - --// Tests golang/go#38669. --func TestEqualInEnv_Issue38669(t *testing.T) { -- const files = ` ---- go.mod -- --module mod.com -- --go 1.12 ---- main.go -- --package main +--- @rfl/return_func_lit.go -- +-package extract - --var _ = x.X ---- x/x.go -- --package x +-import "go/ast" - --var X = 0 --` -- WithOptions( -- EnvVars{"GOFLAGS": "-tags=foo"}, -- ).Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- env.OrganizeImports("main.go") -- env.AfterChange(NoDiagnostics(ForFile("main.go"))) +-func _() { +- ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool { +- //@codeaction("if", rflEnd, "refactor.extract", rfl) +- shouldReturn, returnValue := newFunction(n) +- if shouldReturn { +- return returnValue +- } //@loc(rflEnd, "}") +- return false - }) -} - --// Tests golang/go#38467. --func TestNoSuggestedFixesForGeneratedFiles_Issue38467(t *testing.T) { -- const generated = ` ---- go.mod -- --module mod.com +-func newFunction(n ast.Node) (bool, bool) { +- if n == nil { +- return true, true +- } +- return false, false +-} - --go 1.12 ---- main.go -- --package main +--- return_func_lit_nonnested.go -- +-package extract - --// Code generated by generator.go. DO NOT EDIT. +-import "go/ast" - -func _() { -- for i, _ := range []string{} { -- _ = i -- } --} --` -- Run(t, generated, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- var d protocol.PublishDiagnosticsParams -- env.AfterChange( -- Diagnostics(AtPosition("main.go", 5, 8)), -- ReadDiagnostics("main.go", &d), -- ) -- if fixes := env.GetQuickFixes("main.go", d.Diagnostics); len(fixes) != 0 { -- t.Errorf("got quick fixes %v, wanted none", fixes) +- ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool { +- if n == nil { //@codeaction("if", rflnnEnd, "refactor.extract", rflnn) +- return true - } +- return false //@loc(rflnnEnd, "false") - }) -} - --// Expect a module/GOPATH error if there is an error in the file at startup. --// Tests golang/go#37279. --func TestBrokenWorkspace_OutsideModule(t *testing.T) { -- const noModule = ` ---- a.go -- --package foo +--- @rflnn/return_func_lit_nonnested.go -- +-package extract - --import "mod.com/hello" +-import "go/ast" - --func f() { -- hello.Goodbye() --} --` -- Run(t, noModule, func(t *testing.T, env *Env) { -- env.OpenFile("a.go") -- env.AfterChange( -- // Expect the adHocPackagesWarning. -- OutstandingWork(lsp.WorkspaceLoadFailure, "outside of a module"), -- ) -- // Deleting the import dismisses the warning. -- env.RegexpReplace("a.go", `import "mod.com/hello"`, "") -- env.AfterChange( -- NoOutstandingWork(IgnoreTelemetryPromptWork), -- ) +-func _() { +- ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool { +- //@codeaction("if", rflnnEnd, "refactor.extract", rflnn) +- return newFunction(n) //@loc(rflnnEnd, "false") - }) -} - --func TestNonGoFolder(t *testing.T) { -- const files = ` ---- hello.txt -- --hi mom --` -- for _, go111module := range []string{"on", "off", ""} { -- t.Run(fmt.Sprintf("GO111MODULE_%v", go111module), func(t *testing.T) { -- WithOptions( -- EnvVars{"GO111MODULE": go111module}, -- ).Run(t, files, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- NoOutstandingWork(IgnoreTelemetryPromptWork), -- ) -- }) -- }) +-func newFunction(n ast.Node) bool { +- if n == nil { +- return true - } +- return false -} - --// Tests the repro case from golang/go#38602. Diagnostics are now handled properly, --// which blocks type checking. --func TestConflictingMainPackageErrors(t *testing.T) { -- const collision = ` ---- x/x.go -- --package x -- --import "x/hello" +--- return_init.go -- +-package extract - --func Hello() { -- hello.HiThere() +-func _() string { +- x := 1 +- if x == 0 { //@codeaction("if", riEnd, "refactor.extract", ri) +- x = 3 +- return "a" +- } //@loc(riEnd, "}") +- x = 2 +- return "b" -} ---- x/main.go -- --package main - --func main() { -- fmt.Println("") +--- @ri/return_init.go -- +-package extract +- +-func _() string { +- x := 1 +- //@codeaction("if", riEnd, "refactor.extract", ri) +- shouldReturn, returnValue := newFunction(x) +- if shouldReturn { +- return returnValue +- } //@loc(riEnd, "}") +- x = 2 +- return "b" -} --` -- WithOptions( -- InGOPATH(), -- EnvVars{"GO111MODULE": "off"}, -- ).Run(t, collision, func(t *testing.T, env *Env) { -- env.OpenFile("x/x.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("x/x.go", `^`), WithMessage("found packages main (main.go) and x (x.go)")), -- Diagnostics(env.AtRegexp("x/main.go", `^`), WithMessage("found packages main (main.go) and x (x.go)")), -- ) - -- // We don't recover cleanly from the errors without good overlay support. -- if testenv.Go1Point() >= 16 { -- env.RegexpReplace("x/x.go", `package x`, `package main`) -- env.AfterChange( -- Diagnostics(env.AtRegexp("x/main.go", `fmt`)), -- ) -- } -- }) +-func newFunction(x int) (bool, string) { +- if x == 0 { +- x = 3 +- return true, "a" +- } +- return false, "" -} - --const ardanLabsProxy = ` ---- github.com/ardanlabs/conf@v1.2.3/go.mod -- --module github.com/ardanlabs/conf +--- return_init_nonnested.go -- +-package extract - --go 1.12 ---- github.com/ardanlabs/conf@v1.2.3/conf.go -- --package conf +-func _() string { +- x := 1 +- if x == 0 { //@codeaction("if", rinnEnd, "refactor.extract", rinn) +- x = 3 +- return "a" +- } +- x = 2 +- return "b" //@loc(rinnEnd, "\"b\"") +-} - --var ErrHelpWanted error --` +--- @rinn/return_init_nonnested.go -- +-package extract - --// Test for golang/go#38211. --func Test_Issue38211(t *testing.T) { -- const ardanLabs = ` ---- go.mod -- --module mod.com +-func _() string { +- x := 1 +- //@codeaction("if", rinnEnd, "refactor.extract", rinn) +- return newFunction(x) //@loc(rinnEnd, "\"b\"") +-} - --go 1.14 ---- main.go -- --package main +-func newFunction(x int) string { +- if x == 0 { +- x = 3 +- return "a" +- } +- x = 2 +- return "b" +-} - --import "github.com/ardanlabs/conf" +--- args_returns.go -- +-package extract - --func main() { -- _ = conf.ErrHelpWanted +-func _() { +- a := 1 +- a = 5 //@codeaction("a", araend, "refactor.extract", ara) +- a = a + 2 //@loc(araend, "2") +- +- b := a * 2 //@codeaction("b", arbend, "refactor.extract", arb) +- _ = b + 4 //@loc(arbend, "4") -} --` -- WithOptions( -- ProxyFiles(ardanLabsProxy), -- ).Run(t, ardanLabs, func(t *testing.T, env *Env) { -- // Expect a diagnostic with a suggested fix to add -- // "github.com/ardanlabs/conf" to the go.mod file. -- env.OpenFile("go.mod") -- env.OpenFile("main.go") -- var d protocol.PublishDiagnosticsParams -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", `"github.com/ardanlabs/conf"`)), -- ReadDiagnostics("main.go", &d), -- ) -- env.ApplyQuickFixes("main.go", d.Diagnostics) -- env.SaveBuffer("go.mod") -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- ) -- // Comment out the line that depends on conf and expect a -- // diagnostic and a fix to remove the import. -- env.RegexpReplace("main.go", "_ = conf.ErrHelpWanted", "//_ = conf.ErrHelpWanted") -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", `"github.com/ardanlabs/conf"`)), -- ) -- env.SaveBuffer("main.go") -- // Expect a diagnostic and fix to remove the dependency in the go.mod. -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- Diagnostics(env.AtRegexp("go.mod", "require github.com/ardanlabs/conf"), WithMessage("not used in this module")), -- ReadDiagnostics("go.mod", &d), -- ) -- env.ApplyQuickFixes("go.mod", d.Diagnostics) -- env.SaveBuffer("go.mod") -- env.AfterChange( -- NoDiagnostics(ForFile("go.mod")), -- ) -- // Uncomment the lines and expect a new diagnostic for the import. -- env.RegexpReplace("main.go", "//_ = conf.ErrHelpWanted", "_ = conf.ErrHelpWanted") -- env.SaveBuffer("main.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", `"github.com/ardanlabs/conf"`)), -- ) -- }) +- +--- @ara/args_returns.go -- +-package extract +- +-func _() { +- a := 1 +- //@codeaction("a", araend, "refactor.extract", ara) +- a = newFunction(a) //@loc(araend, "2") +- +- b := a * 2 //@codeaction("b", arbend, "refactor.extract", arb) +- _ = b + 4 //@loc(arbend, "4") -} - --// Test for golang/go#38207. --func TestNewModule_Issue38207(t *testing.T) { -- const emptyFile = ` ---- go.mod -- --module mod.com +-func newFunction(a int) int { +- a = 5 +- a = a + 2 +- return a +-} - --go 1.12 ---- main.go -- --` -- WithOptions( -- ProxyFiles(ardanLabsProxy), -- ).Run(t, emptyFile, func(t *testing.T, env *Env) { -- env.CreateBuffer("main.go", `package main +--- @arb/args_returns.go -- +-package extract - --import "github.com/ardanlabs/conf" +-func _() { +- a := 1 +- a = 5 //@codeaction("a", araend, "refactor.extract", ara) +- a = a + 2 //@loc(araend, "2") - --func main() { -- _ = conf.ErrHelpWanted +- //@codeaction("b", arbend, "refactor.extract", arb) +- newFunction(a) //@loc(arbend, "4") -} --`) -- env.SaveBuffer("main.go") -- var d protocol.PublishDiagnosticsParams -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", `"github.com/ardanlabs/conf"`), WithMessage("no required module")), -- ReadDiagnostics("main.go", &d), -- ) -- env.ApplyQuickFixes("main.go", d.Diagnostics) -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- ) -- }) +- +-func newFunction(a int) { +- b := a * 2 +- _ = b + 4 -} - --// Test for golang/go#36960. --func TestNewFileBadImports_Issue36960(t *testing.T) { -- const simplePackage = ` ---- go.mod -- --module mod.com +--- scope.go -- +-package extract - --go 1.14 ---- a/a1.go -- --package a +-func _() { +- newFunction := 1 +- a := newFunction //@codeaction("a", "newFunction", "refactor.extract", scope) +- _ = a // avoid diagnostic +-} - --import "fmt" +-func newFunction1() int { +- return 1 +-} +- +--- @scope/scope.go -- +-package extract - -func _() { -- fmt.Println("hi") +- newFunction := 1 +- a := newFunction2(newFunction) //@codeaction("a", "newFunction", "refactor.extract", scope) +- _ = a // avoid diagnostic -} --` -- Run(t, simplePackage, func(t *testing.T, env *Env) { -- env.OpenFile("a/a1.go") -- env.CreateBuffer("a/a2.go", ``) -- env.SaveBufferWithoutActions("a/a2.go") -- env.AfterChange( -- NoDiagnostics(ForFile("a/a1.go")), -- ) -- env.EditBuffer("a/a2.go", fake.NewEdit(0, 0, 0, 0, `package a`)) -- env.AfterChange( -- NoDiagnostics(ForFile("a/a1.go")), -- ) -- }) +- +-func newFunction2(newFunction int) int { +- a := newFunction +- return a -} - --// This test tries to replicate the workflow of a user creating a new x test. --// It also tests golang/go#39315. --func TestManuallyCreatingXTest(t *testing.T) { -- // Create a package that already has a test variant (in-package test). -- const testVariant = ` ---- go.mod -- --module mod.com +-func newFunction1() int { +- return 1 +-} - --go 1.15 ---- hello/hello.go -- --package hello +--- smart_initialization.go -- +-package extract - --func Hello() { -- var x int +-func _() { +- var a []int +- a = append(a, 2) //@codeaction("a", siEnd, "refactor.extract", si) +- b := 4 //@loc(siEnd, "4") +- a = append(a, b) -} ---- hello/hello_test.go -- --package hello - --import "testing" +--- @si/smart_initialization.go -- +-package extract - --func TestHello(t *testing.T) { -- var x int -- Hello() +-func _() { +- var a []int +- //@codeaction("a", siEnd, "refactor.extract", si) +- a, b := newFunction(a) //@loc(siEnd, "4") +- a = append(a, b) -} --` -- Run(t, testVariant, func(t *testing.T, env *Env) { -- // Open the file, triggering the workspace load. -- // There are errors in the code to ensure all is working as expected. -- env.OpenFile("hello/hello.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("hello/hello.go", "x")), -- Diagnostics(env.AtRegexp("hello/hello_test.go", "x")), -- ) - -- // Create an empty file with the intention of making it an x test. -- // This resembles a typical flow in an editor like VS Code, in which -- // a user would create an empty file and add content, saving -- // intermittently. -- // TODO(rstambler): There might be more edge cases here, as file -- // content can be added incrementally. -- env.CreateBuffer("hello/hello_x_test.go", ``) +-func newFunction(a []int) ([]int, int) { +- a = append(a, 2) +- b := 4 +- return a, b +-} - -- // Save the empty file (no actions since formatting will fail). -- env.SaveBufferWithoutActions("hello/hello_x_test.go") +--- smart_return.go -- +-package extract - -- // Add the content. The missing import is for the package under test. -- env.EditBuffer("hello/hello_x_test.go", fake.NewEdit(0, 0, 0, 0, `package hello_test +-func _() { +- var b []int +- var a int +- a = 2 //@codeaction("a", srEnd, "refactor.extract", sr) +- b = []int{} +- b = append(b, a) //@loc(srEnd, ")") +- b[0] = 1 +-} - --import ( -- "testing" --) +--- @sr/smart_return.go -- +-package extract - --func TestHello(t *testing.T) { -- hello.Hello() +-func _() { +- var b []int +- var a int +- //@codeaction("a", srEnd, "refactor.extract", sr) +- b = newFunction(a, b) //@loc(srEnd, ")") +- b[0] = 1 -} --`)) -- // Expect a diagnostic for the missing import. Save, which should -- // trigger import organization. The diagnostic should clear. -- env.AfterChange( -- Diagnostics(env.AtRegexp("hello/hello_x_test.go", "hello.Hello")), -- ) -- env.SaveBuffer("hello/hello_x_test.go") -- env.AfterChange( -- NoDiagnostics(ForFile("hello/hello_x_test.go")), -- ) -- }) +- +-func newFunction(a int, b []int) []int { +- a = 2 +- b = []int{} +- b = append(b, a) +- return b -} - --// Reproduce golang/go#40690. --func TestCreateOnlyXTest(t *testing.T) { -- const mod = ` ---- go.mod -- --module mod.com +--- unnecessary_param.go -- +-package extract - --go 1.12 ---- foo/foo.go -- --package foo ---- foo/bar_test.go -- --` -- Run(t, mod, func(t *testing.T, env *Env) { -- env.OpenFile("foo/bar_test.go") -- env.EditBuffer("foo/bar_test.go", fake.NewEdit(0, 0, 0, 0, "package foo")) -- env.Await(env.DoneWithChange()) -- env.RegexpReplace("foo/bar_test.go", "package foo", `package foo_test +-func _() { +- var b []int +- a := 2 //@codeaction("a", upEnd, "refactor.extract", up) +- b = []int{} +- b = append(b, a) //@loc(upEnd, ")") +- b[0] = 1 +- if a == 2 { +- return +- } +-} - --import "testing" +--- @up/unnecessary_param.go -- +-package extract - --func TestX(t *testing.T) { -- var x int +-func _() { +- var b []int +- //@codeaction("a", upEnd, "refactor.extract", up) +- a, b := newFunction(b) //@loc(upEnd, ")") +- b[0] = 1 +- if a == 2 { +- return +- } -} --`) -- env.AfterChange( -- Diagnostics(env.AtRegexp("foo/bar_test.go", "x")), -- ) -- }) +- +-func newFunction(b []int) (int, []int) { +- a := 2 +- b = []int{} +- b = append(b, a) +- return a, b -} - --func TestChangePackageName(t *testing.T) { -- const mod = ` ---- go.mod -- --module mod.com +--- comment.go -- +-package extract - --go 1.12 ---- foo/foo.go -- --package foo ---- foo/bar_test.go -- --package foo_ --` -- Run(t, mod, func(t *testing.T, env *Env) { -- env.OpenFile("foo/bar_test.go") -- env.AfterChange() -- env.RegexpReplace("foo/bar_test.go", "package foo_", "package foo_test") -- env.AfterChange( -- NoDiagnostics(ForFile("foo/bar_test.go")), -- NoDiagnostics(ForFile("foo/foo.go")), -- ) -- }) +-func _() { +- a := /* comment in the middle of a line */ 1 //@codeaction("a", commentEnd, "refactor.extract", comment1) +- // Comment on its own line //@codeaction("Comment", commentEnd, "refactor.extract", comment2) +- _ = a + 4 //@loc(commentEnd, "4"),codeaction("_", lastComment, "refactor.extract", comment3) +- // Comment right after 3 + 4 +- +- // Comment after with space //@loc(lastComment, "Comment") -} - --func TestIgnoredFiles(t *testing.T) { -- const ws = ` ---- go.mod -- --module mod.com +--- @comment1/comment.go -- +-package extract - --go 1.12 ---- _foo/x.go -- --package x +-func _() { +- /* comment in the middle of a line */ +- //@codeaction("a", commentEnd, "refactor.extract", comment1) +- // Comment on its own line //@codeaction("Comment", commentEnd, "refactor.extract", comment2) +- newFunction() //@loc(commentEnd, "4"),codeaction("_", lastComment, "refactor.extract", comment3) +- // Comment right after 3 + 4 - --var _ = foo.Bar --` -- Run(t, ws, func(t *testing.T, env *Env) { -- env.OpenFile("_foo/x.go") -- env.AfterChange( -- NoDiagnostics(ForFile("_foo/x.go")), -- ) -- }) +- // Comment after with space //@loc(lastComment, "Comment") -} - --// Partially reproduces golang/go#38977, moving a file between packages. --// It also gets hit by some go command bug fixed in 1.15, but we don't --// care about that so much here. --func TestDeletePackage(t *testing.T) { -- const ws = ` ---- go.mod -- --module mod.com +-func newFunction() { +- a := 1 - --go 1.15 ---- a/a.go -- --package a +- _ = a + 4 +-} - --const A = 1 +--- @comment2/comment.go -- +-package extract - ---- b/b.go -- --package b +-func _() { +- a := /* comment in the middle of a line */ 1 //@codeaction("a", commentEnd, "refactor.extract", comment1) +- // Comment on its own line //@codeaction("Comment", commentEnd, "refactor.extract", comment2) +- newFunction(a) //@loc(commentEnd, "4"),codeaction("_", lastComment, "refactor.extract", comment3) +- // Comment right after 3 + 4 - --import "mod.com/a" +- // Comment after with space //@loc(lastComment, "Comment") +-} - --const B = a.A +-func newFunction(a int) { +- _ = a + 4 +-} - ---- c/c.go -- --package c +--- @comment3/comment.go -- +-package extract - --import "mod.com/a" +-func _() { +- a := /* comment in the middle of a line */ 1 //@codeaction("a", commentEnd, "refactor.extract", comment1) +- // Comment on its own line //@codeaction("Comment", commentEnd, "refactor.extract", comment2) +- newFunction(a) //@loc(commentEnd, "4"),codeaction("_", lastComment, "refactor.extract", comment3) +- // Comment right after 3 + 4 - --const C = a.A --` -- Run(t, ws, func(t *testing.T, env *Env) { -- env.OpenFile("b/b.go") -- env.Await(env.DoneWithOpen()) -- // Delete c/c.go, the only file in package c. -- env.RemoveWorkspaceFile("c/c.go") +- // Comment after with space //@loc(lastComment, "Comment") +-} - -- // We should still get diagnostics for files that exist. -- env.RegexpReplace("b/b.go", `a.A`, "a.Nonexistant") -- env.AfterChange( -- Diagnostics(env.AtRegexp("b/b.go", `Nonexistant`)), -- ) -- }) +-func newFunction(a int) { +- _ = a + 4 -} - --// This is a copy of the scenario_default/quickfix_empty_files.txt test from --// govim. Reproduces golang/go#39646. --func TestQuickFixEmptyFiles(t *testing.T) { -- const mod = ` +--- redefine.go -- +-package extract +- +-import "strconv" +- +-func _() { +- i, err := strconv.Atoi("1") +- u, err := strconv.Atoi("2") //@codeaction("u", ")", "refactor.extract", redefine) +- if i == u || err == nil { +- return +- } +-} +- +--- @redefine/redefine.go -- +-package extract +- +-import "strconv" +- +-func _() { +- i, err := strconv.Atoi("1") +- u, err := newFunction() //@codeaction("u", ")", "refactor.extract", redefine) +- if i == u || err == nil { +- return +- } +-} +- +-func newFunction() (int, error) { +- u, err := strconv.Atoi("2") +- return u, err +-} +- +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/imports.txt b/gopls/internal/regtest/marker/testdata/codeaction/imports.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/imports.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/imports.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,175 +0,0 @@ +-This test verifies the behavior of the 'source.organizeImports' code action. +- --- go.mod -- --module mod.com +-module mod.test/imports - --go 1.12 --` -- // To fully recreate the govim tests, we create files by inserting -- // a newline, adding to the file, and then deleting the newline. -- // Wait for each event to process to avoid cancellations and force -- // package loads. -- writeGoVim := func(env *Env, name, content string) { -- env.WriteWorkspaceFile(name, "") -- env.Await(env.DoneWithChangeWatchedFiles()) +-go 1.18 - -- env.CreateBuffer(name, "\n") -- env.Await(env.DoneWithOpen()) +--- add.go -- +-package imports //@codeaction("imports", "", "source.organizeImports", add) +- +-import ( +- "fmt" +-) +- +-func _() { +- fmt.Println("") +- bytes.NewBuffer(nil) //@diag("bytes", re"(undeclared|undefined)") +-} +- +--- @add/add.go -- +-package imports //@codeaction("imports", "", "source.organizeImports", add) - -- env.EditBuffer(name, fake.NewEdit(1, 0, 1, 0, content)) -- env.Await(env.DoneWithChange()) +-import ( +- "bytes" +- "fmt" +-) - -- env.EditBuffer(name, fake.NewEdit(0, 0, 1, 0, "")) -- env.Await(env.DoneWithChange()) -- } +-func _() { +- fmt.Println("") +- bytes.NewBuffer(nil) //@diag("bytes", re"(undeclared|undefined)") +-} - -- const p = `package p; func DoIt(s string) {};` -- const main = `package main +--- good.go -- +-package imports //@codeactionerr("imports", "", "source.organizeImports", re"found 0 CodeActions") - --import "mod.com/p" +-import "fmt" - --func main() { -- p.DoIt(5) +-func _() { +-fmt.Println("") -} --` -- // A simple version of the test that reproduces most of the problems it -- // exposes. -- t.Run("short", func(t *testing.T) { -- Run(t, mod, func(t *testing.T, env *Env) { -- writeGoVim(env, "p/p.go", p) -- writeGoVim(env, "main.go", main) -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", "5")), -- ) -- }) -- }) - -- // A full version that replicates the whole flow of the test. -- t.Run("full", func(t *testing.T) { -- Run(t, mod, func(t *testing.T, env *Env) { -- writeGoVim(env, "p/p.go", p) -- writeGoVim(env, "main.go", main) -- writeGoVim(env, "p/p_test.go", `package p +--- issue35458.go -- - --import "testing" - --func TestDoIt(t *testing.T) { -- DoIt(5) --} --`) -- writeGoVim(env, "p/x_test.go", `package p_test - --import ( -- "testing" - -- "mod.com/p" --) - --func TestDoIt(t *testing.T) { -- p.DoIt(5) --} --`) -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", "5")), -- Diagnostics(env.AtRegexp("p/p_test.go", "5")), -- Diagnostics(env.AtRegexp("p/x_test.go", "5")), -- ) -- env.RegexpReplace("p/p.go", "s string", "i int") -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- NoDiagnostics(ForFile("p/p_test.go")), -- NoDiagnostics(ForFile("p/x_test.go")), -- ) -- }) -- }) --} +-// package doc +-package imports //@codeaction("imports", "", "source.organizeImports", issue35458) +- +- +- - --func TestSingleFile(t *testing.T) { -- const mod = ` ---- go.mod -- --module mod.com - --go 1.13 ---- a/a.go -- --package a - -func _() { -- var x int --} --` -- WithOptions( -- // Empty workspace folders. -- WorkspaceFolders(), -- ).Run(t, mod, func(t *testing.T, env *Env) { -- env.OpenFile("a/a.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("a/a.go", "x")), -- ) -- }) +- println("Hello, world!") -} - --// Reproduces the case described in --// https://github.com/golang/go/issues/39296#issuecomment-652058883. --func TestPkgm(t *testing.T) { -- const basic = ` ---- go.mod -- --module mod.com - --go 1.15 ---- foo/foo.go -- --package foo - --import "fmt" - --func Foo() { -- fmt.Println("") --} --` -- Run(t, basic, func(t *testing.T, env *Env) { -- env.WriteWorkspaceFile("foo/foo_test.go", `package main - --func main() { - --}`) -- env.OpenFile("foo/foo_test.go") -- env.RegexpReplace("foo/foo_test.go", `package main`, `package foo`) -- env.AfterChange(NoDiagnostics(ForFile("foo/foo.go"))) -- }) --} - --func TestClosingBuffer(t *testing.T) { -- const basic = ` ---- go.mod -- --module mod.com - --go 1.14 ---- main.go -- --package main +--- @issue35458/issue35458.go -- +-// package doc +-package imports //@codeaction("imports", "", "source.organizeImports", issue35458) - --func main() {} --` -- Run(t, basic, func(t *testing.T, env *Env) { -- env.Editor.CreateBuffer(env.Ctx, "foo.go", `package main`) -- env.AfterChange() -- env.CloseBuffer("foo.go") -- env.AfterChange(NoLogMatching(protocol.Info, "packages=0")) -- }) --} - --// Reproduces golang/go#38424. --func TestCutAndPaste(t *testing.T) { -- const basic = ` ---- go.mod -- --module mod.com - --go 1.14 ---- main2.go -- --package main --` -- Run(t, basic, func(t *testing.T, env *Env) { -- env.CreateBuffer("main.go", "") -- env.Await(env.DoneWithOpen()) - -- env.SaveBufferWithoutActions("main.go") -- env.Await(env.DoneWithSave(), env.DoneWithChangeWatchedFiles()) - -- env.EditBuffer("main.go", fake.NewEdit(0, 0, 0, 0, `package main - --func main() { +-func _() { +- println("Hello, world!") -} --`)) -- env.Await(env.DoneWithChange()) - -- env.SaveBuffer("main.go") -- env.Await(env.DoneWithSave(), env.DoneWithChangeWatchedFiles()) - -- env.EditBuffer("main.go", fake.NewEdit(0, 0, 4, 0, "")) -- env.Await(env.DoneWithChange()) - -- env.EditBuffer("main.go", fake.NewEdit(0, 0, 0, 0, `package main - --func main() { -- var x int --} --`)) -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", "x")), -- ) -- }) --} - --// Reproduces golang/go#39763. --func TestInvalidPackageName(t *testing.T) { -- const pkgDefault = ` ---- go.mod -- --module mod.com - --go 1.12 ---- main.go -- --package default - --func main() {} --` -- Run(t, pkgDefault, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- env.AfterChange( -- Diagnostics( -- env.AtRegexp("main.go", "default"), -- WithMessage("expected 'IDENT'"), -- ), -- ) -- }) --} - --// This tests the functionality of the "limitWorkspaceScope" --func TestLimitWorkspaceScope(t *testing.T) { -- const mod = ` ---- go.mod -- --module mod.com +--- multi.go -- +-package imports //@codeaction("imports", "", "source.organizeImports", multi) - --go 1.12 ---- a/main.go -- --package main +-import "fmt" - --func main() {} ---- main.go -- --package main +-import "bytes" //@diag("\"bytes\"", re"not used") - --func main() { -- var x int --} --` -- WithOptions( -- WorkspaceFolders("a"), -- ).Run(t, mod, func(t *testing.T, env *Env) { -- env.OpenFile("a/main.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", "x")), -- ) -- }) -- WithOptions( -- WorkspaceFolders("a"), -- Settings{"expandWorkspaceToModule": false}, -- ).Run(t, mod, func(t *testing.T, env *Env) { -- env.OpenFile("a/main.go") -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- ) -- }) +-func _() { +- fmt.Println("") -} - --func TestSimplifyCompositeLitDiagnostic(t *testing.T) { -- const files = ` ---- go.mod -- --module mod.com -- --go 1.12 ---- main.go -- --package main +--- @multi/multi.go -- +-package imports //@codeaction("imports", "", "source.organizeImports", multi) - -import "fmt" - --type t struct { -- msg string --} +-//@diag("\"bytes\"", re"not used") - --func main() { -- x := []t{t{"msg"}} -- fmt.Println(x) +-func _() { +- fmt.Println("") -} --` - -- WithOptions( -- Settings{"staticcheck": true}, -- ).Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- var d protocol.PublishDiagnosticsParams -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", `t{"msg"}`), WithMessage("redundant type")), -- ReadDiagnostics("main.go", &d), -- ) -- if tags := d.Diagnostics[0].Tags; len(tags) == 0 || tags[0] != protocol.Unnecessary { -- t.Errorf("wanted Unnecessary tag on diagnostic, got %v", tags) -- } -- env.ApplyQuickFixes("main.go", d.Diagnostics) -- env.AfterChange(NoDiagnostics(ForFile("main.go"))) -- }) +--- needs.go -- +-package imports //@codeaction("package", "", "source.organizeImports", needs) +- +-func goodbye() { +- fmt.Printf("HI") //@diag("fmt", re"(undeclared|undefined)") +- log.Printf("byeeeee") //@diag("log", re"(undeclared|undefined)") -} - --// Test some secondary diagnostics --func TestSecondaryDiagnostics(t *testing.T) { -- const dir = ` ---- go.mod -- --module mod.com +--- @needs/needs.go -- +-package imports //@codeaction("package", "", "source.organizeImports", needs) - --go 1.12 ---- main.go -- --package main --func main() { -- panic("not here") +-import ( +- "fmt" +- "log" +-) +- +-func goodbye() { +- fmt.Printf("HI") //@diag("fmt", re"(undeclared|undefined)") +- log.Printf("byeeeee") //@diag("log", re"(undeclared|undefined)") -} ---- other.go -- --package main --func main() {} --` -- Run(t, dir, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- env.OpenFile("other.go") -- var mainDiags, otherDiags protocol.PublishDiagnosticsParams -- env.AfterChange( -- ReadDiagnostics("main.go", &mainDiags), -- ReadDiagnostics("other.go", &otherDiags), -- ) -- if len(mainDiags.Diagnostics) != 1 { -- t.Fatalf("main.go, got %d diagnostics, expected 1", len(mainDiags.Diagnostics)) -- } -- keep := mainDiags.Diagnostics[0] -- if len(otherDiags.Diagnostics) != 1 { -- t.Fatalf("other.go: got %d diagnostics, expected 1", len(otherDiags.Diagnostics)) -- } -- if len(otherDiags.Diagnostics[0].RelatedInformation) != 1 { -- t.Fatalf("got %d RelatedInformations, expected 1", len(otherDiags.Diagnostics[0].RelatedInformation)) -- } -- // check that the RelatedInformation matches the error from main.go -- c := otherDiags.Diagnostics[0].RelatedInformation[0] -- if c.Location.Range != keep.Range { -- t.Errorf("locations don't match. Got %v expected %v", c.Location.Range, keep.Range) -- } -- }) +- +--- remove.go -- +-package imports //@codeaction("package", "", "source.organizeImports", remove) +- +-import ( +- "bytes" //@diag("\"bytes\"", re"not used") +- "fmt" +-) +- +-func _() { +- fmt.Println("") -} - --func TestOrphanedFiles(t *testing.T) { -- const files = ` ---- go.mod -- --module mod.com +--- @remove/remove.go -- +-package imports //@codeaction("package", "", "source.organizeImports", remove) - --go 1.12 ---- a/a.go -- --package a +-import ( +- "fmt" +-) - --func main() { -- var x int +-func _() { +- fmt.Println("") -} ---- a/a_exclude.go -- --// +build exclude - --package a +--- removeall.go -- +-package imports //@codeaction("package", "", "source.organizeImports", removeall) +- +-import ( +- "bytes" //@diag("\"bytes\"", re"not used") +- "fmt" //@diag("\"fmt\"", re"not used") +- +-) - -func _() { -- var x int -} --` -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("a/a.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("a/a.go", "x")), -- ) -- env.OpenFile("a/a_exclude.go") - -- loadOnce := LogMatching(protocol.Info, "query=.*file=.*a_exclude.go", 1, false) +--- @removeall/removeall.go -- +-package imports //@codeaction("package", "", "source.organizeImports", removeall) - -- // can't use OnceMet or AfterChange as logs are async -- env.Await(loadOnce) -- // ...but ensure that the change has been fully processed before editing. -- // Otherwise, there may be a race where the snapshot is cloned before all -- // state changes resulting from the load have been processed -- // (golang/go#61521). -- env.AfterChange() +-//@diag("\"fmt\"", re"not used") - -- // Check that orphaned files are not reloaded, by making a change in -- // a.go file and confirming that the workspace diagnosis did not reload -- // a_exclude.go. -- // -- // This is racy (but fails open) because logs are asynchronous to other LSP -- // operations. There's a chance gopls _did_ log, and we just haven't seen -- // it yet. -- env.RegexpReplace("a/a.go", "package a", "package a // arbitrary comment") -- env.AfterChange(loadOnce) -- }) +-func _() { -} - --func TestEnableAllExperiments(t *testing.T) { -- // Before the oldest supported Go version, gopls sends a warning to upgrade -- // Go, which fails the expectation below. -- testenv.NeedsGo1Point(t, lsp.OldestSupportedGoVersion()) +--- twolines.go -- +-package imports +-func main() {} //@codeactionerr("main", "", "source.organizeImports", re"found 0") +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/infertypeargs.txt b/gopls/internal/regtest/marker/testdata/codeaction/infertypeargs.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/infertypeargs.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/infertypeargs.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,38 +0,0 @@ +-This test verifies the infertypeargs refactoring. +- +--- flags -- +--min_go=go1.18 - -- const mod = ` --- go.mod -- --module mod.com +-module mod.test/infertypeargs - --go 1.12 ---- main.go -- --package main +-go 1.18 - --import "bytes" +--- p.go -- +-package infertypeargs - --func b(c bytes.Buffer) { -- _ = 1 +-func app[S interface{ ~[]E }, E interface{}](s S, e E) S { +- return append(s, e) -} --` -- WithOptions( -- Settings{"allExperiments": true}, -- ).Run(t, mod, func(t *testing.T, env *Env) { -- // Confirm that the setting doesn't cause any warnings. -- env.OnceMet( -- InitialWorkspaceLoad, -- NoShownMessage(""), // empty substring to match any message -- ) -- }) +- +-func _() { +- _ = app[[]int] +- _ = app[[]int, int] +- _ = app[[]int]([]int{}, 0) //@codeaction("app", ")", "refactor.rewrite", infer) +- _ = app([]int{}, 0) -} - --func TestSwig(t *testing.T) { -- // This is fixed in Go 1.17, but not earlier. -- testenv.NeedsGo1Point(t, 17) +--- @infer/p.go -- +-package infertypeargs - -- if _, err := exec.LookPath("swig"); err != nil { -- t.Skip("skipping test: swig not available") -- } -- if _, err := exec.LookPath("g++"); err != nil { -- t.Skip("skipping test: g++ not available") -- } +-func app[S interface{ ~[]E }, E interface{}](s S, e E) S { +- return append(s, e) +-} - -- const mod = ` ---- go.mod -- --module mod.com +-func _() { +- _ = app[[]int] +- _ = app[[]int, int] +- _ = app([]int{}, 0) //@codeaction("app", ")", "refactor.rewrite", infer) +- _ = app([]int{}, 0) +-} - --go 1.12 ---- pkg/simple/export_swig.go -- --package simple +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/inline.txt b/gopls/internal/regtest/marker/testdata/codeaction/inline.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/inline.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/inline.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,23 +0,0 @@ +-This is a minimal test of the refactor.inline code action. - --func ExportSimple(x, y int) int { -- return Gcd(x, y) --} ---- pkg/simple/simple.swigcxx -- --%module simple +--- go.mod -- +-module testdata/codeaction +-go 1.18 - --%inline %{ --extern int gcd(int x, int y) --{ -- int g; -- g = y; -- while (x > 0) { -- g = x; -- x = y % x; -- y = g; -- } -- return g; --} --%} ---- main.go -- +--- a/a.go -- -package a - --func main() { -- var x int --} --` -- Run(t, mod, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- NoDiagnostics(WithMessage("illegal character U+0023 '#'")), -- ) -- }) +-func _() { +- println(add(1, 2)) //@codeaction("add", ")", "refactor.inline", inline) -} - --// When foo_test.go is opened, gopls will object to the borked package name. --// This test asserts that when the package name is fixed, gopls will soon after --// have no more complaints about it. --// https://github.com/golang/go/issues/41061 --func TestRenamePackage(t *testing.T) { -- const proxy = ` ---- example.com@v1.2.3/go.mod -- --module example.com +-func add(x, y int) int { return x + y } - --go 1.12 ---- example.com@v1.2.3/blah/blah.go -- --package blah +--- @inline/a/a.go -- +-package a - --const Name = "Blah" ---- random.org@v1.2.3/go.mod -- --module random.org +-func _() { +- println(1 + 2) //@codeaction("add", ")", "refactor.inline", inline) +-} - --go 1.12 ---- random.org@v1.2.3/blah/blah.go -- --package hello +-func add(x, y int) int { return x + y } +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/removeparam_formatting.txt b/gopls/internal/regtest/marker/testdata/codeaction/removeparam_formatting.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/removeparam_formatting.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/removeparam_formatting.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,55 +0,0 @@ +-This test exercises behavior of change signature refactoring with respect to +-comments. - --const Name = "Hello" --` +-Currently, inline comments around arguments or parameters are dropped, which is +-probably acceptable. Fixing this is likely intractible without fixing comment +-representation in the AST. - -- const contents = ` --- go.mod -- --module mod.com +-module unused.mod - --go 1.12 ---- main.go -- --package main +-go 1.18 - --import "example.com/blah" +--- a/a.go -- +-package a - --func main() { -- blah.Hello() +-// A doc comment. +-func A(x /* used parameter */, unused int /* unused parameter */ ) int { //@codeaction("unused", "unused", "refactor.rewrite", a) +- // about to return +- return x // returning +- // just returned -} ---- bob.go -- --package main ---- foo/foo.go -- --package foo ---- foo/foo_test.go -- --package foo_ --` - -- WithOptions( -- ProxyFiles(proxy), -- InGOPATH(), -- EnvVars{"GO111MODULE": "off"}, -- ).Run(t, contents, func(t *testing.T, env *Env) { -- // Simulate typing character by character. -- env.OpenFile("foo/foo_test.go") -- env.Await(env.DoneWithOpen()) -- env.RegexpReplace("foo/foo_test.go", "_", "_t") -- env.Await(env.DoneWithChange()) -- env.RegexpReplace("foo/foo_test.go", "_t", "_test") -- env.AfterChange( -- NoDiagnostics(ForFile("foo/foo_test.go")), -- NoOutstandingWork(IgnoreTelemetryPromptWork), -- ) -- }) +-// This function makes calls. +-func _() { +- // about to call +- A(one() /* used arg */, 2 /* unused arg */) // calling +- // just called -} - --// TestProgressBarErrors confirms that critical workspace load errors are shown --// and updated via progress reports. --func TestProgressBarErrors(t *testing.T) { -- const pkg = ` ---- go.mod -- --modul mod.com -- --go 1.12 ---- main.go -- --package main --` -- Run(t, pkg, func(t *testing.T, env *Env) { -- env.OpenFile("go.mod") -- env.AfterChange( -- OutstandingWork(lsp.WorkspaceLoadFailure, "unknown directive"), -- ) -- env.EditBuffer("go.mod", fake.NewEdit(0, 0, 3, 0, `module mod.com -- --go 1.hello --`)) -- // As of golang/go#42529, go.mod changes do not reload the workspace until -- // they are saved. -- env.SaveBufferWithoutActions("go.mod") -- env.AfterChange( -- OutstandingWork(lsp.WorkspaceLoadFailure, "invalid go version"), -- ) -- env.RegexpReplace("go.mod", "go 1.hello", "go 1.12") -- env.SaveBufferWithoutActions("go.mod") -- env.AfterChange( -- NoOutstandingWork(IgnoreTelemetryPromptWork), -- ) -- }) +-func one() int { +- // I should be unaffected! +- return 1 -} - --func TestDeleteDirectory(t *testing.T) { -- const mod = ` ---- bob/bob.go -- --package bob +--- @a/a/a.go -- +-package a - --func Hello() { -- var x int +-// A doc comment. +-func A(x int) int { //@codeaction("unused", "unused", "refactor.rewrite", a) +- // about to return +- return x // returning +- // just returned -} ---- go.mod -- --module mod.com ---- cmd/main.go -- --package main -- --import "mod.com/bob" - --func main() { -- bob.Hello() --} --` -- WithOptions( -- Settings{ -- // Now that we don't watch subdirs by default (except for VS Code), -- // we must explicitly ask gopls to requests subdir watch patterns. -- "subdirWatchPatterns": "on", -- }, -- ).Run(t, mod, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- FileWatchMatching("bob"), -- ) -- env.RemoveWorkspaceFile("bob") -- env.AfterChange( -- Diagnostics(env.AtRegexp("cmd/main.go", `"mod.com/bob"`)), -- NoDiagnostics(ForFile("bob/bob.go")), -- NoFileWatchMatching("bob"), -- ) -- }) +-// This function makes calls. +-func _() { +- // about to call +- A(one()) // calling +- // just called -} - --// Confirms that circular imports are tested and reported. --func TestCircularImports(t *testing.T) { -- const mod = ` ---- go.mod -- --module mod.com +-func one() int { +- // I should be unaffected! +- return 1 +-} +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/removeparam_funcvalue.txt b/gopls/internal/regtest/marker/testdata/codeaction/removeparam_funcvalue.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/removeparam_funcvalue.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/removeparam_funcvalue.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,19 +0,0 @@ +-This test exercises change signature refactoring handling of function values. - --go 1.12 ---- self/self.go -- --package self +-TODO(rfindley): use a literalization strategy to allow these references. - --import _ "mod.com/self" --func Hello() {} ---- double/a/a.go -- --package a +--- go.mod -- +-module unused.mod - --import _ "mod.com/double/b" ---- double/b/b.go -- --package b +-go 1.18 - --import _ "mod.com/double/a" ---- triple/a/a.go -- +--- a/a.go -- -package a - --import _ "mod.com/triple/b" ---- triple/b/b.go -- --package b -- --import _ "mod.com/triple/c" ---- triple/c/c.go -- --package c +-func A(x, unused int) int { //@codeactionerr("unused", "unused", "refactor.rewrite", re"non-call function reference") +- return x +-} - --import _ "mod.com/triple/a" --` -- Run(t, mod, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("self/self.go", `_ "mod.com/self"`), WithMessage("import cycle not allowed")), -- Diagnostics(env.AtRegexp("double/a/a.go", `_ "mod.com/double/b"`), WithMessage("import cycle not allowed")), -- Diagnostics(env.AtRegexp("triple/a/a.go", `_ "mod.com/triple/b"`), WithMessage("import cycle not allowed")), -- ) -- }) +-func _() { +- _ = A -} +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/removeparam_imports.txt b/gopls/internal/regtest/marker/testdata/codeaction/removeparam_imports.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/removeparam_imports.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/removeparam_imports.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,160 +0,0 @@ +-This test checks the behavior of removing a parameter with respect to various +-import scenarios. - --// Tests golang/go#46667: deleting a problematic import path should resolve --// import cycle errors. --func TestResolveImportCycle(t *testing.T) { -- const mod = ` --- go.mod -- -module mod.test - --go 1.16 ---- a/a.go -- --package a +-go 1.21 - --import "mod.test/b" - --const A = b.A --const B = 2 ---- b/b.go -- --package b +--- a/a1.go -- +-package a - --import "mod.test/a" +-import "mod.test/b" - --const A = 1 --const B = a.B -- ` -- Run(t, mod, func(t *testing.T, env *Env) { -- env.OpenFile("a/a.go") -- env.OpenFile("b/b.go") -- env.AfterChange( -- // The Go command sometimes tells us about only one of the import cycle -- // errors below. For robustness of this test, succeed if we get either. -- // -- // TODO(golang/go#52904): we should get *both* of these errors. -- AnyOf( -- Diagnostics(env.AtRegexp("a/a.go", `"mod.test/b"`), WithMessage("import cycle")), -- Diagnostics(env.AtRegexp("b/b.go", `"mod.test/a"`), WithMessage("import cycle")), -- ), -- ) -- env.RegexpReplace("b/b.go", `const B = a\.B`, "") -- env.SaveBuffer("b/b.go") -- env.AfterChange( -- NoDiagnostics(ForFile("a/a.go")), -- NoDiagnostics(ForFile("b/b.go")), -- ) -- }) +-func _() { +- b.B(<-b.Chan, <-b.Chan) -} - --func TestBadImport(t *testing.T) { -- const mod = ` ---- go.mod -- --module mod.com +--- a/a2.go -- +-package a - --go 1.12 ---- main.go -- --package main +-import "mod.test/b" - --import ( -- _ "nosuchpkg" --) --` -- t.Run("module", func(t *testing.T) { -- Run(t, mod, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `"nosuchpkg"`), WithMessage(`could not import nosuchpkg (no required module provides package "nosuchpkg"`)), -- ) -- }) -- }) -- t.Run("GOPATH", func(t *testing.T) { -- WithOptions( -- InGOPATH(), -- EnvVars{"GO111MODULE": "off"}, -- Modes(Default), -- ).Run(t, mod, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `"nosuchpkg"`), WithMessage(`cannot find package "nosuchpkg"`)), -- ) -- }) -- }) +-func _() { +- b.B(<-b.Chan, <-b.Chan) +- b.B(<-b.Chan, <-b.Chan) -} - --func TestNestedModules(t *testing.T) { -- const proxy = ` ---- nested.com@v1.0.0/go.mod -- --module nested.com -- --go 1.12 ---- nested.com@v1.0.0/hello/hello.go -- --package hello +--- a/a3.go -- +-package a - --func Hello() {} --` +-import "mod.test/b" - -- const nested = ` ---- go.mod -- --module mod.com +-func _() { +- b.B(<-b.Chan, <-b.Chan) +-} - --go 1.12 +-func _() { +- b.B(<-b.Chan, <-b.Chan) +-} - --require nested.com v1.0.0 ---- go.sum -- --nested.com v1.0.0 h1:I6spLE4CgFqMdBPc+wTV2asDO2QJ3tU0YAT+jkLeN1I= --nested.com v1.0.0/go.mod h1:ly53UzXQgVjSlV7wicdBB4p8BxfytuGT1Xcyv0ReJfI= ---- main.go -- --package main +--- a/a4.go -- +-package a - --import "nested.com/hello" +-// TODO(rfindley/adonovan): inlining here adds an additional import of +-// mod.test/b. Can we do better? +-import ( +- . "mod.test/b" +-) - --func main() { -- hello.Hello() +-func _() { +- B(<-Chan, <-Chan) -} ---- nested/go.mod -- --module nested.com -- ---- nested/hello/hello.go -- --package hello - --func Hello() { -- helloHelper() --} ---- nested/hello/hello_helper.go -- --package hello +--- b/b.go -- +-package b - --func helloHelper() {} --` -- WithOptions( -- ProxyFiles(proxy), -- Modes(Default), -- ).Run(t, nested, func(t *testing.T, env *Env) { -- // Expect a diagnostic in a nested module. -- env.OpenFile("nested/hello/hello.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("nested/hello/hello.go", "helloHelper")), -- Diagnostics(env.AtRegexp("nested/hello/hello.go", "package (hello)"), WithMessage("not included in your workspace")), -- ) -- }) --} +-import "mod.test/c" - --func TestAdHocPackagesReloading(t *testing.T) { -- const nomod = ` ---- main.go -- --package main +-var Chan chan c.C - --func main() {} --` -- Run(t, nomod, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- env.RegexpReplace("main.go", "{}", "{ var x int; }") // simulate typing -- env.AfterChange(NoLogMatching(protocol.Info, "packages=1")) -- }) +-func B(x, y c.C) { //@codeaction("x", "x", "refactor.rewrite", b) -} - --func TestBuildTagChange(t *testing.T) { -- const files = ` ---- go.mod -- --module mod.com +--- c/c.go -- +-package c - --go 1.12 ---- foo.go -- --// decoy comment --// +build hidden --// decoy comment +-type C int - --package foo --var Foo = 1 ---- bar.go -- --package foo --var Bar = Foo --` +--- d/d.go -- +-package d - -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("foo.go") -- env.AfterChange(Diagnostics(env.AtRegexp("bar.go", `Foo`))) -- env.RegexpReplace("foo.go", `\+build`, "") -- env.AfterChange(NoDiagnostics(ForFile("bar.go"))) -- }) +-// Removing the parameter should remove this import. +-import "mod.test/c" - +-func D(x c.C) { //@codeaction("x", "x", "refactor.rewrite", d) -} - --func TestIssue44736(t *testing.T) { -- const files = ` -- -- go.mod -- --module blah.com +-func _() { +- D(1) +-} - --go 1.16 ---- main.go -- --package main +--- @b/a/a1.go -- +-package a - --import "fmt" +-import ( +- "mod.test/b" +- "mod.test/c" +-) - --func main() { -- asdf -- fmt.Printf("This is a test %v") -- fdas +-func _() { +- var _ c.C = <-b.Chan +- b.B(<-b.Chan) -} ---- other.go -- --package main +--- @b/a/a2.go -- +-package a - --` -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- env.OpenFile("other.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", "asdf")), -- Diagnostics(env.AtRegexp("main.go", "fdas")), -- ) -- env.SetBufferContent("other.go", "package main\n\nasdf") -- // The new diagnostic in other.go should not suppress diagnostics in main.go. -- env.AfterChange( -- Diagnostics(env.AtRegexp("other.go", "asdf"), WithMessage("expected declaration")), -- Diagnostics(env.AtRegexp("main.go", "asdf")), -- ) -- }) +-import ( +- "mod.test/b" +- "mod.test/c" +-) +- +-func _() { +- var _ c.C = <-b.Chan +- b.B(<-b.Chan) +- var _ c.C = <-b.Chan +- b.B(<-b.Chan) -} +--- @b/a/a3.go -- +-package a - --func TestInitialization(t *testing.T) { -- const files = ` ---- go.mod -- --module mod.com +-import ( +- "mod.test/b" +- "mod.test/c" +-) - --go 1.16 ---- main.go -- --package main --` -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("go.mod") -- env.Await(env.DoneWithOpen()) -- env.RegexpReplace("go.mod", "module", "modul") -- env.SaveBufferWithoutActions("go.mod") -- env.AfterChange( -- NoLogMatching(protocol.Error, "initial workspace load failed"), -- ) -- }) +-func _() { +- var _ c.C = <-b.Chan +- b.B(<-b.Chan) -} - --// This test confirms that the view does not reinitialize when a go.mod file is --// opened. --func TestNoReinitialize(t *testing.T) { -- const files = ` ---- go.mod -- --module mod.com +-func _() { +- var _ c.C = <-b.Chan +- b.B(<-b.Chan) +-} +--- @b/a/a4.go -- +-package a - --go 1.12 ---- main.go -- --package main +-// TODO(rfindley/adonovan): inlining here adds an additional import of +-// mod.test/b. Can we do better? +-import ( +- "mod.test/b" +- . "mod.test/b" +- "mod.test/c" +-) - --func main() {} --` -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("go.mod") -- env.Await( -- // Check that we have only loaded "<dir>/..." once. -- // Log messages are asynchronous to other events on the LSP stream, so we -- // can't use OnceMet or AfterChange here. -- LogMatching(protocol.Info, `.*query=.*\.\.\..*`, 1, false), -- ) -- }) +-func _() { +- var _ c.C = <-Chan +- b.B(<-Chan) -} +--- @b/b/b.go -- +-package b - --func TestLangVersion(t *testing.T) { -- testenv.NeedsGo1Point(t, 18) // Requires types.Config.GoVersion, new in 1.18. -- const files = ` ---- go.mod -- --module mod.com +-import "mod.test/c" - --go 1.12 ---- main.go -- --package main +-var Chan chan c.C - --const C = 0b10 --` -- Run(t, files, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `0b10`), WithMessage("go1.13 or later")), -- ) -- env.WriteWorkspaceFile("go.mod", "module mod.com \n\ngo 1.13\n") -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- ) -- }) +-func B(y c.C) { //@codeaction("x", "x", "refactor.rewrite", b) -} +--- @d/d/d.go -- +-package d - --func TestNoQuickFixForUndeclaredConstraint(t *testing.T) { -- testenv.NeedsGo1Point(t, 18) -- const files = ` ---- go.mod -- --module mod.com -- --go 1.18 ---- main.go -- --package main +-// Removing the parameter should remove this import. - --func F[T C](_ T) { +-func D() { //@codeaction("x", "x", "refactor.rewrite", d) -} --` - -- Run(t, files, func(t *testing.T, env *Env) { -- var d protocol.PublishDiagnosticsParams -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `C`)), -- ReadDiagnostics("main.go", &d), -- ) -- if fixes := env.GetQuickFixes("main.go", d.Diagnostics); len(fixes) != 0 { -- t.Errorf("got quick fixes %v, wanted none", fixes) -- } -- }) +-func _() { +- D() -} +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/removeparam.txt b/gopls/internal/regtest/marker/testdata/codeaction/removeparam.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/removeparam.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/removeparam.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,246 +0,0 @@ +-This test exercises the refactoring to remove unused parameters. - --func TestEditGoDirective(t *testing.T) { -- testenv.NeedsGo1Point(t, 18) -- const files = ` --- go.mod -- --module mod.com +-module unused.mod - --go 1.16 ---- main.go -- --package main +-go 1.18 - --func F[T any](_ T) { --} --` -- Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file. -- var d protocol.PublishDiagnosticsParams -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `T any`), WithMessage("type parameter")), -- ReadDiagnostics("main.go", &d), -- ) +--- a/a.go -- +-package a - -- env.ApplyQuickFixes("main.go", d.Diagnostics) -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- ) -- }) +-func A(x, unused int) int { //@codeaction("unused", "unused", "refactor.rewrite", a) +- return x -} - --func TestEditGoDirectiveWorkspace(t *testing.T) { -- testenv.NeedsGo1Point(t, 18) -- const files = ` ---- go.mod -- --module mod.com +--- @a/a/a.go -- +-package a - --go 1.16 ---- go.work -- --go 1.18 +-func A(x int) int { //@codeaction("unused", "unused", "refactor.rewrite", a) +- return x +-} - --use . ---- main.go -- --package main +--- a/a2.go -- +-package a - --func F[T any](_ T) { +-func _() { +- A(1, 2) -} --` -- Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file. -- var d protocol.PublishDiagnosticsParams -- -- // We should have a diagnostic because generics are not supported at 1.16. -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `T any`), WithMessage("type parameter")), -- ReadDiagnostics("main.go", &d), -- ) - -- // This diagnostic should have a quick fix to edit the go version. -- env.ApplyQuickFixes("main.go", d.Diagnostics) +--- a/a_test.go -- +-package a - -- // Once the edit is applied, the problematic diagnostics should be -- // resolved. -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- ) -- }) +-func _() { +- A(1, 2) -} - --// This test demonstrates that analysis facts are correctly propagated --// across packages. --func TestInterpackageAnalysis(t *testing.T) { -- const src = ` ---- go.mod -- --module example.com ---- a/a.go -- --package a +--- a/a_x_test.go -- +-package a_test - --import "example.com/b" +-import "unused.mod/a" - -func _() { -- new(b.B).Printf("%d", "s") // printf error +- a.A(1, 2) -} - --- b/b.go -- -package b - --import "example.com/c" +-import "unused.mod/a" - --type B struct{} +-func f() int { +- return 1 +-} - --func (B) Printf(format string, args ...interface{}) { -- c.MyPrintf(format, args...) +-func g() int { +- return 2 -} - ---- c/c.go -- --package c +-func _() { +- a.A(f(), 1) +-} - --import "fmt" +--- @a/a/a2.go -- +-package a - --func MyPrintf(format string, args ...interface{}) { -- fmt.Printf(format, args...) +-func _() { +- A(1) -} --` -- Run(t, src, func(t *testing.T, env *Env) { -- env.OpenFile("a/a.go") -- env.AfterChange( -- Diagnostics( -- env.AtRegexp("a/a.go", "new.*Printf"), -- WithMessage("format %d has arg \"s\" of wrong type string"), -- ), -- ) -- }) +--- @a/a/a_test.go -- +-package a +- +-func _() { +- A(1) -} +--- @a/a/a_x_test.go -- +-package a_test - --// This test ensures that only Analyzers with RunDespiteErrors=true --// are invoked on a package that would not compile, even if the errors --// are distant and localized. --func TestErrorsThatPreventAnalysis(t *testing.T) { -- const src = ` ---- go.mod -- --module example.com ---- a/a.go -- --package a +-import "unused.mod/a" - --import "fmt" --import "sync" --import _ "example.com/b" +-func _() { +- a.A(1) +-} +--- @a/b/b.go -- +-package b +- +-import "unused.mod/a" +- +-func f() int { +- return 1 +-} +- +-func g() int { +- return 2 +-} - -func _() { -- // The copylocks analyzer (RunDespiteErrors, FactTypes={}) does run. -- var mu sync.Mutex -- mu2 := mu // copylocks error, reported -- _ = &mu2 +- a.A(f()) +-} +--- field/field.go -- +-package field - -- // The printf analyzer (!RunDespiteErrors, FactTypes!={}) does not run: -- // (c, printf) failed because of type error in c -- // (b, printf) and (a, printf) do not run because of failed prerequisites. -- fmt.Printf("%d", "s") // printf error, unreported +-func Field(x int, field int) { //@codeaction("int", "int", "refactor.rewrite", field) +-} - -- // The bools analyzer (!RunDespiteErrors, FactTypes={}) does not run: -- var cond bool -- _ = cond != true && cond != true // bools error, unreported +-func _() { +- Field(1, 2) -} +--- @field/field/field.go -- +-package field - ---- b/b.go -- --package b +-func Field(field int) { //@codeaction("int", "int", "refactor.rewrite", field) +-} - --import _ "example.com/c" +-func _() { +- Field(2) +-} +--- ellipsis/ellipsis.go -- +-package ellipsis - ---- c/c.go -- --package c +-func Ellipsis(...any) { //@codeaction("any", "any", "refactor.rewrite", ellipsis) +-} - --var _ = 1 / "" // type error +-func _() { +- // TODO(rfindley): investigate the broken formatting resulting from these inlinings. +- Ellipsis() +- Ellipsis(1) +- Ellipsis(1, 2) +- Ellipsis(1, f(), g()) +- Ellipsis(h()) +- Ellipsis(i()...) +-} - --` -- Run(t, src, func(t *testing.T, env *Env) { -- var diags protocol.PublishDiagnosticsParams -- env.OpenFile("a/a.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("a/a.go", "mu2 := (mu)"), WithMessage("assignment copies lock value")), -- ReadDiagnostics("a/a.go", &diags)) +-func f() int +-func g() int +-func h() (int, int) +-func i() []any - -- // Assert that there were no other diagnostics. -- // In particular: -- // - "fmt.Printf" does not trigger a [printf] finding; -- // - "cond != true" does not trigger a [bools] finding. -- // -- // We use this check in preference to NoDiagnosticAtRegexp -- // as it is robust in case of minor mistakes in the position -- // regexp, and because it reports unexpected diagnostics. -- if got, want := len(diags.Diagnostics), 1; got != want { -- t.Errorf("got %d diagnostics in a/a.go, want %d:", got, want) -- for i, diag := range diags.Diagnostics { -- t.Logf("Diagnostics[%d] = %+v", i, diag) -- } -- } -- }) +--- @ellipsis/ellipsis/ellipsis.go -- +-package ellipsis +- +-func Ellipsis() { //@codeaction("any", "any", "refactor.rewrite", ellipsis) -} - --// This test demonstrates the deprecated symbol analyzer --// produces deprecation notices with expected severity and tags. --func TestDeprecatedAnalysis(t *testing.T) { -- const src = ` ---- go.mod -- --module example.com ---- a/a.go -- --package a +-func _() { +- // TODO(rfindley): investigate the broken formatting resulting from these inlinings. +- Ellipsis() +- Ellipsis() +- Ellipsis() +- var _ []any = []any{1, f(), g()} +- Ellipsis() +- func(_ ...any) { +- Ellipsis() +- }(h()) +- var _ []any = i() +- Ellipsis() +-} - --import "example.com/b" +-func f() int +-func g() int +-func h() (int, int) +-func i() []any +--- ellipsis2/ellipsis2.go -- +-package ellipsis2 +- +-func Ellipsis2(_, _ int, rest ...int) { //@codeaction("_", "_", "refactor.rewrite", ellipsis2) +-} - -func _() { -- new(b.B).Obsolete() // deprecated +- Ellipsis2(1,2,3) +- Ellipsis2(h()) +- Ellipsis2(1,2, []int{3, 4}...) -} - ---- b/b.go -- --package b +-func h() (int, int) - --type B struct{} +--- @ellipsis2/ellipsis2/ellipsis2.go -- +-package ellipsis2 - --// Deprecated: use New instead. --func (B) Obsolete() {} +-func Ellipsis2(_ int, rest ...int) { //@codeaction("_", "_", "refactor.rewrite", ellipsis2) +-} - --func (B) New() {} --` -- Run(t, src, func(t *testing.T, env *Env) { -- env.OpenFile("a/a.go") -- env.AfterChange( -- Diagnostics( -- env.AtRegexp("a/a.go", "new.*Obsolete"), -- WithMessage("use New instead."), -- WithSeverityTags("deprecated", protocol.SeverityHint, []protocol.DiagnosticTag{protocol.Deprecated}), -- ), -- ) -- }) +-func _() { +- Ellipsis2(2, []int{3}...) +- func(_, blank0 int, rest ...int) { +- Ellipsis2(blank0, rest...) +- }(h()) +- Ellipsis2(2, []int{3, 4}...) -} -diff -urN a/gopls/internal/regtest/diagnostics/golist_test.go b/gopls/internal/regtest/diagnostics/golist_test.go ---- a/gopls/internal/regtest/diagnostics/golist_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/diagnostics/golist_test.go 1970-01-01 08:00:00 -@@ -1,71 +0,0 @@ --// Copyright 2023 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 diagnostics +-func h() (int, int) +--- overlapping/overlapping.go -- +-package overlapping - --import ( -- "testing" +-func Overlapping(i int) int { //@codeactionerr(re"(i) int", re"(i) int", "refactor.rewrite", re"overlapping") +- return 0 +-} - -- . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/internal/testenv" --) +-func _() { +- x := Overlapping(Overlapping(0)) +- _ = x +-} - --func TestGoListErrors(t *testing.T) { -- testenv.NeedsTool(t, "cgo") +--- effects/effects.go -- +-package effects - -- const src = ` ---- go.mod -- --module a.com +-func effects(x, y int) int { //@codeaction("y", "y", "refactor.rewrite", effects) +- return x +-} - --go 1.18 ---- a/a.go -- --package a +-func f() int +-func g() int - --import ---- c/c.go -- --package c +-func _() { +- effects(f(), g()) +- effects(f(), g()) +-} +--- @effects/effects/effects.go -- +-package effects - --/* --int fortythree() { return 42; } --*/ --import "C" +-func effects(x int) int { //@codeaction("y", "y", "refactor.rewrite", effects) +- return x +-} - --func Foo() { -- print(C.fortytwo()) +-func f() int +-func g() int +- +-func _() { +- var x, _ int = f(), g() +- effects(x) +- { +- var x, _ int = f(), g() +- effects(x) +- } -} ---- p/p.go -- --package p +--- recursive/recursive.go -- +-package recursive - --import "a.com/q" +-func Recursive(x int) int { //@codeaction("x", "x", "refactor.rewrite", recursive) +- return Recursive(1) +-} - --const P = q.Q + 1 ---- q/q.go -- --package q +--- @recursive/recursive/recursive.go -- +-package recursive - --import "a.com/p" +-func Recursive() int { //@codeaction("x", "x", "refactor.rewrite", recursive) +- return Recursive() +-} +diff -urN a/gopls/internal/regtest/marker/testdata/codelens/generate.txt b/gopls/internal/regtest/marker/testdata/codelens/generate.txt +--- a/gopls/internal/regtest/marker/testdata/codelens/generate.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codelens/generate.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-This test exercises the "generate" codelens. - --const Q = p.P + 1 --` +--- generate.go -- +-//@codelenses() - -- Run(t, src, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics( -- env.AtRegexp("a/a.go", "import\n()"), -- FromSource(string(source.ParseError)), -- ), -- Diagnostics( -- AtPosition("c/c.go", 0, 0), -- FromSource(string(source.ListError)), -- WithMessage("may indicate failure to perform cgo processing"), -- ), -- Diagnostics( -- env.AtRegexp("p/p.go", `"a.com/q"`), -- FromSource(string(source.ListError)), -- WithMessage("import cycle not allowed"), -- ), -- ) -- }) +-package generate +- +-//go:generate echo Hi //@ codelens("//go:generate", "run go generate"), codelens("//go:generate", "run go generate ./...") +-//go:generate echo I shall have no CodeLens +diff -urN a/gopls/internal/regtest/marker/testdata/codelens/test.txt b/gopls/internal/regtest/marker/testdata/codelens/test.txt +--- a/gopls/internal/regtest/marker/testdata/codelens/test.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codelens/test.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,31 +0,0 @@ +-This file tests codelenses for test functions. +- +-TODO: for some reason these code lens have zero width. Does that affect their +-utility/visibility in various LSP clients? +- +--- settings.json -- +-{ +- "codelenses": { +- "test": true +- } -} -diff -urN a/gopls/internal/regtest/diagnostics/invalidation_test.go b/gopls/internal/regtest/diagnostics/invalidation_test.go ---- a/gopls/internal/regtest/diagnostics/invalidation_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/diagnostics/invalidation_test.go 1970-01-01 08:00:00 -@@ -1,111 +0,0 @@ --// Copyright 2022 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 diagnostics +--- p_test.go -- +-//@codelenses() - --import ( -- "fmt" -- "testing" +-package codelens //@codelens(re"()package codelens", "run file benchmarks") - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" --) +-import "testing" - --// Test for golang/go#50267: diagnostics should be re-sent after a file is --// opened. --func TestDiagnosticsAreResentAfterCloseOrOpen(t *testing.T) { -- const files = ` ---- go.mod -- --module mod.com +-func TestMain(m *testing.M) {} // no code lens for TestMain - --go 1.16 ---- main.go -- --package main +-func TestFuncWithCodeLens(t *testing.T) { //@codelens(re"()func", "run test") +-} - --func _() { -- x := 2 +-func thisShouldNotHaveACodeLens(t *testing.T) { -} --` -- Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file. -- env.OpenFile("main.go") -- var afterOpen protocol.PublishDiagnosticsParams -- env.AfterChange( -- ReadDiagnostics("main.go", &afterOpen), -- ) -- env.CloseBuffer("main.go") -- var afterClose protocol.PublishDiagnosticsParams -- env.AfterChange( -- ReadDiagnostics("main.go", &afterClose), -- ) -- if afterOpen.Version == afterClose.Version { -- t.Errorf("publishDiagnostics: got the same version after closing (%d) as after opening", afterOpen.Version) -- } -- env.OpenFile("main.go") -- var afterReopen protocol.PublishDiagnosticsParams -- env.AfterChange( -- ReadDiagnostics("main.go", &afterReopen), -- ) -- if afterReopen.Version == afterClose.Version { -- t.Errorf("pubslishDiagnostics: got the same version after reopening (%d) as after closing", afterClose.Version) -- } -- }) +- +-func BenchmarkFuncWithCodeLens(b *testing.B) { //@codelens(re"()func", "run benchmark") -} - --// Test for the "chattyDiagnostics" setting: we should get re-published --// diagnostics after every file change, even if diagnostics did not change. --func TestChattyDiagnostics(t *testing.T) { -- const files = ` +-func helper() {} // expect no code lens +diff -urN a/gopls/internal/regtest/marker/testdata/completion/address.txt b/gopls/internal/regtest/marker/testdata/completion/address.txt +--- a/gopls/internal/regtest/marker/testdata/completion/address.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/address.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,92 +0,0 @@ +-This test exercises the reference and dereference completion modifiers. +- +-TODO: remove the need to set "literalCompletions" here, as this is one of the +-few places this setting is needed. +- +--- flags -- +--ignore_extra_diags +- --- go.mod -- --module mod.com +-module golang.org/lsptests - --go 1.16 ---- main.go -- --package main +-go 1.18 +- +--- address/address.go -- +-package address +- +-func wantsPtr(*int) {} +-func wantsVariadicPtr(...*int) {} +- +-func wantsVariadic(...int) {} +- +-type foo struct{ c int } //@item(addrFieldC, "c", "int", "field") - -func _() { -- x := 2 --} +- var ( +- a string //@item(addrA, "a", "string", "var") +- b int //@item(addrB, "b", "int", "var") +- ) - --// Irrelevant comment #0 --` +- wantsPtr() //@rank(")", addrB, addrA),snippet(")", addrB, "&b") +- wantsPtr(&b) //@snippet(")", addrB, "b") - -- WithOptions( -- Settings{ -- "chattyDiagnostics": true, -- }, -- ).Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file. +- wantsVariadicPtr() //@rank(")", addrB, addrA),snippet(")", addrB, "&b") - -- env.OpenFile("main.go") -- var d protocol.PublishDiagnosticsParams -- env.AfterChange( -- ReadDiagnostics("main.go", &d), -- ) +- var s foo +- s.c //@item(addrDeepC, "s.c", "int", "field") +- wantsPtr() //@snippet(")", addrDeepC, "&s.c") +- wantsPtr(s) //@snippet(")", addrDeepC, "&s.c") +- wantsPtr(&s) //@snippet(")", addrDeepC, "s.c") - -- if len(d.Diagnostics) != 1 { -- t.Fatalf("len(Diagnostics) = %d, want 1", len(d.Diagnostics)) -- } -- msg := d.Diagnostics[0].Message +- // don't add "&" in item (it gets added as an additional edit) +- wantsPtr(&s.c) //@snippet(")", addrFieldC, "c") - -- for i := 0; i < 5; i++ { -- before := d.Version -- env.RegexpReplace("main.go", "Irrelevant comment #.", fmt.Sprintf("Irrelevant comment #%d", i)) -- env.AfterChange( -- ReadDiagnostics("main.go", &d), -- ) +- // check dereferencing as well +- var c *int //@item(addrCPtr, "c", "*int", "var") +- var _ int = _ //@rank("_ //", addrCPtr, addrA),snippet("_ //", addrCPtr, "*c") - -- if d.Version == before { -- t.Errorf("after change, got version %d, want new version", d.Version) -- } +- wantsVariadic() //@rank(")", addrCPtr, addrA),snippet(")", addrCPtr, "*c") - -- // As a sanity check, make sure we have the same diagnostic. -- if len(d.Diagnostics) != 1 { -- t.Fatalf("len(Diagnostics) = %d, want 1", len(d.Diagnostics)) -- } -- newMsg := d.Diagnostics[0].Message -- if newMsg != msg { -- t.Errorf("after change, got message %q, want %q", newMsg, msg) -- } -- } -- }) --} -diff -urN a/gopls/internal/regtest/diagnostics/undeclared_test.go b/gopls/internal/regtest/diagnostics/undeclared_test.go ---- a/gopls/internal/regtest/diagnostics/undeclared_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/diagnostics/undeclared_test.go 1970-01-01 08:00:00 -@@ -1,73 +0,0 @@ --// Copyright 2021 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. +- var d **int //@item(addrDPtr, "d", "**int", "var") +- var _ int = _ //@rank("_ //", addrDPtr, addrA),snippet("_ //", addrDPtr, "**d") - --package diagnostics +- type namedPtr *int +- var np namedPtr //@item(addrNamedPtr, "np", "namedPtr", "var") - --import ( -- "testing" +- var _ int = _ //@rank("_ //", addrNamedPtr, addrA) - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" --) +- // don't get tripped up by recursive pointer type +- type dontMessUp *dontMessUp //@item(dontMessUp, "dontMessUp", "*dontMessUp", "type") +- var dmu *dontMessUp //@item(addrDMU, "dmu", "*dontMessUp", "var") - --func TestUndeclaredDiagnostics(t *testing.T) { -- src := ` ---- go.mod -- --module mod.com +- var _ int = dmu //@complete(" //", addrDMU, dontMessUp) +-} - --go 1.12 ---- a/a.go -- --package a +-func (f foo) ptr() *foo { return &f } - --func _() int { -- return x +-func _() { +- getFoo := func() foo { return foo{} } +- +- // not addressable +- getFoo().c //@item(addrGetFooC, "getFoo().c", "int", "field") +- +- // addressable +- getFoo().ptr().c //@item(addrGetFooPtrC, "getFoo().ptr().c", "int", "field") +- +- wantsPtr() //@snippet(")", addrGetFooPtrC, "&getFoo().ptr().c") +- wantsPtr(&g) //@snippet(")", addrGetFooPtrC, "getFoo().ptr().c") -} ---- b/b.go -- --package b - --func _() int { -- var y int -- y = y -- return y +-type nested struct { +- f foo -} --` -- Run(t, src, func(t *testing.T, env *Env) { -- isUnnecessary := func(diag protocol.Diagnostic) bool { -- for _, tag := range diag.Tags { -- if tag == protocol.Unnecessary { -- return true -- } -- } -- return false -- } - -- // 'x' is undeclared, but still necessary. -- env.OpenFile("a/a.go") -- var adiags protocol.PublishDiagnosticsParams -- env.AfterChange( -- Diagnostics(env.AtRegexp("a/a.go", "x")), -- ReadDiagnostics("a/a.go", &adiags), -- ) -- if got := len(adiags.Diagnostics); got != 1 { -- t.Errorf("len(Diagnostics) = %d, want 1", got) -- } -- if diag := adiags.Diagnostics[0]; isUnnecessary(diag) { -- t.Errorf("%v tagged unnecessary, want necessary", diag) -- } +-func _() { +- getNested := func() nested { return nested{} } - -- // 'y = y' is pointless, and should be detected as unnecessary. -- env.OpenFile("b/b.go") -- var bdiags protocol.PublishDiagnosticsParams -- env.AfterChange( -- Diagnostics(env.AtRegexp("b/b.go", "y = y")), -- ReadDiagnostics("b/b.go", &bdiags), -- ) -- if got := len(bdiags.Diagnostics); got != 1 { -- t.Errorf("len(Diagnostics) = %d, want 1", got) -- } -- if diag := bdiags.Diagnostics[0]; !isUnnecessary(diag) { -- t.Errorf("%v tagged necessary, want unnecessary", diag) -- } -- }) --} -diff -urN a/gopls/internal/regtest/inlayhints/inlayhints_test.go b/gopls/internal/regtest/inlayhints/inlayhints_test.go ---- a/gopls/internal/regtest/inlayhints/inlayhints_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/inlayhints/inlayhints_test.go 1970-01-01 08:00:00 -@@ -1,69 +0,0 @@ --// Copyright 2022 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 inlayhint +- getNested().f.c //@item(addrNestedC, "getNested().f.c", "int", "field") +- getNested().f.ptr().c //@item(addrNestedPtrC, "getNested().f.ptr().c", "int", "field") - --import ( -- "testing" +- // addrNestedC is not addressable, so rank lower +- wantsPtr(getNestedfc) //@complete(")", addrNestedPtrC, addrNestedC) +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/anon.txt b/gopls/internal/regtest/marker/testdata/completion/anon.txt +--- a/gopls/internal/regtest/marker/testdata/completion/anon.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/anon.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,37 +0,0 @@ +-This test checks completion related to anonymous structs. - -- "golang.org/x/tools/gopls/internal/bug" -- "golang.org/x/tools/gopls/internal/hooks" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/gopls/internal/lsp/source" --) +--- flags -- +--ignore_extra_diags - --func TestMain(m *testing.M) { -- bug.PanicOnBugs = true -- Main(m, hooks.Options) +--- settings.json -- +-{ +- "deepCompletion": false -} - --func TestEnablingInlayHints(t *testing.T) { -- const workspace = ` ---- go.mod -- --module inlayHint.test --go 1.12 ---- lib.go -- --package lib --type Number int --const ( -- Zero Number = iota -- One -- Two --) --` -- tests := []struct { -- label string -- enabled map[string]bool -- wantInlayHint bool +--- anon.go -- +-package anon +- +-// Literal completion results. +-/* int() */ //@item(int, "int()", "int", "var") +- +-func _() { +- for _, _ := range []struct { +- i, j int //@item(anonI, "i", "int", "field"),item(anonJ, "j", "int", "field") - }{ - { -- label: "default", -- wantInlayHint: false, -- }, -- { -- label: "enable const", -- enabled: map[string]bool{source.ConstantValues: true}, -- wantInlayHint: true, +- i: 1, +- //@complete("", anonJ) - }, - { -- label: "enable parameter names", -- enabled: map[string]bool{source.ParameterNames: true}, -- wantInlayHint: false, +- //@complete("", anonI, anonJ, int) - }, +- } { +- continue - } -- for _, test := range tests { -- t.Run(test.label, func(t *testing.T) { -- WithOptions( -- Settings{ -- "hints": test.enabled, -- }, -- ).Run(t, workspace, func(t *testing.T, env *Env) { -- env.OpenFile("lib.go") -- lens := env.InlayHints("lib.go") -- if gotInlayHint := len(lens) > 0; gotInlayHint != test.wantInlayHint { -- t.Errorf("got inlayHint: %t, want %t", gotInlayHint, test.wantInlayHint) -- } -- }) -- }) -- } --} -diff -urN a/gopls/internal/regtest/marker/marker_test.go b/gopls/internal/regtest/marker/marker_test.go ---- a/gopls/internal/regtest/marker/marker_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/marker_test.go 1970-01-01 08:00:00 -@@ -1,30 +0,0 @@ --// Copyright 2023 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 marker -- --import ( -- "os" -- "testing" - -- "golang.org/x/tools/gopls/internal/bug" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/internal/testenv" --) +- s := struct{ f int }{ } //@item(anonF, "f", "int", "field"),item(structS, "s", "struct{...}", "var"),complete(" }", anonF, int) - --func TestMain(m *testing.M) { -- bug.PanicOnBugs = true -- testenv.ExitIfSmallMachine() -- os.Exit(m.Run()) +- _ = map[struct{ x int }]int{ //@item(anonX, "x", "int", "field") +- struct{ x int }{ }: 1, //@complete(" }", anonX, int, structS) +- } -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/append.txt b/gopls/internal/regtest/marker/testdata/completion/append.txt +--- a/gopls/internal/regtest/marker/testdata/completion/append.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/append.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,56 +0,0 @@ +-This test checks behavior of completion within append expressions. - --// Note: we use a separate package for the marker tests so that we can easily --// compare their performance to the existing marker tests in ./internal/lsp. -- --// TestMarkers runs the marker tests from the testdata directory. --// --// See RunMarkerTests for details on how marker tests work. --func TestMarkers(t *testing.T) { -- RunMarkerTests(t, "testdata") --} -diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/functionextraction.txt b/gopls/internal/regtest/marker/testdata/codeaction/functionextraction.txt ---- a/gopls/internal/regtest/marker/testdata/codeaction/functionextraction.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/codeaction/functionextraction.txt 1970-01-01 08:00:00 -@@ -1,583 +0,0 @@ --This test verifies various behaviors of function extraction. +--- flags -- +--ignore_extra_diags - --- go.mod -- --module mod.test/extract +-module golang.org/lsptests/append - -go 1.18 - ---- basic.go -- --package extract +--- append.go -- +-package append - --func _() { //@codeaction("refactor.extract", "{", closeBracket, outer) -- a := 1 //@codeaction("refactor.extract", "a", end, inner) -- _ = a + 4 //@loc(end, "4") --} //@loc(closeBracket, "}") +-func foo([]string) {} +-func bar(...string) {} - ---- @inner/basic.go -- --package extract +-func _() { +- var ( +- aInt []int //@item(appendInt, "aInt", "[]int", "var") +- aStrings []string //@item(appendStrings, "aStrings", "[]string", "var") +- aString string //@item(appendString, "aString", "string", "var") +- ) - --func _() { //@codeaction("refactor.extract", "{", closeBracket, outer) -- //@codeaction("refactor.extract", "a", end, inner) -- newFunction() //@loc(end, "4") --} +- append(aStrings, a) //@rank(")", appendString, appendInt) +- var _ interface{} = append(aStrings, a) //@rank(")", appendString, appendInt) +- var _ []string = append(oops, a) //@rank(")", appendString, appendInt) - --func newFunction() { -- a := 1 -- _ = a + 4 --} //@loc(closeBracket, "}") +- foo(append()) //@rank("))", appendStrings, appendInt),rank("))", appendStrings, appendString) +- foo(append([]string{}, a)) //@rank("))", appendStrings, appendInt),rank("))", appendString, appendInt),snippet("))", appendStrings, "aStrings...") +- foo(append([]string{}, "", a)) //@rank("))", appendString, appendInt),rank("))", appendString, appendStrings) - ---- @outer/basic.go -- --package extract +- // Don't add "..." to append() argument. +- bar(append()) //@snippet("))", appendStrings, "aStrings") - --func _() { //@codeaction("refactor.extract", "{", closeBracket, outer) -- //@codeaction("refactor.extract", "a", end, inner) -- newFunction() //@loc(end, "4") --} +- type baz struct{} +- baz{} //@item(appendBazLiteral, "baz{}", "", "var") +- var bazzes []baz //@item(appendBazzes, "bazzes", "[]baz", "var") +- var bazzy baz //@item(appendBazzy, "bazzy", "baz", "var") +- bazzes = append(bazzes, ba) //@rank(")", appendBazzy, appendBazLiteral, appendBazzes) - --func newFunction() { -- a := 1 -- _ = a + 4 --} //@loc(closeBracket, "}") +- var b struct{ b []baz } +- b.b //@item(appendNestedBaz, "b.b", "[]baz", "field") +- b.b = append(b.b, b) //@rank(")", appendBazzy, appendBazLiteral, appendNestedBaz) - ---- return.go -- --package extract +- var aStringsPtr *[]string //@item(appendStringsPtr, "aStringsPtr", "*[]string", "var") +- foo(append([]string{}, a)) //@snippet("))", appendStringsPtr, "*aStringsPtr...") - --func _() bool { -- x := 1 -- if x == 0 { //@codeaction("refactor.extract", "if", ifend, return) -- return true -- } //@loc(ifend, "}") -- return false +- foo(append([]string{}, *a)) //@snippet("))", appendStringsPtr, "aStringsPtr...") -} - ---- @return/return.go -- --package extract +--- append2.go -- +-package append - --func _() bool { -- x := 1 -- //@codeaction("refactor.extract", "if", ifend, return) -- shouldReturn, returnValue := newFunction(x) -- if shouldReturn { -- return returnValue -- } //@loc(ifend, "}") -- return false +-func _() { +- _ = append(a, struct) //@complete(")") -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/assign.txt b/gopls/internal/regtest/marker/testdata/completion/assign.txt +--- a/gopls/internal/regtest/marker/testdata/completion/assign.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/assign.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,47 +0,0 @@ +-This test checks that completion considers assignability when ranking results. - --func newFunction(x int) (bool, bool) { -- if x == 0 { -- return true, true -- } -- return false, false --} +--- flags -- +--ignore_extra_diags - ---- return_nonnested.go -- --package extract +--- go.mod -- +-module golang.org/lsptests/assign - --func _() bool { -- x := 1 //@codeaction("refactor.extract", "x", rnnEnd, rnn) -- if x == 0 { -- return true -- } -- return false //@loc(rnnEnd, "false") +-go 1.18 +- +--- settings.json -- +-{ +- "completeUnimported": false -} - ---- @rnn/return_nonnested.go -- --package extract +--- assign.go -- +-package assign - --func _() bool { -- //@codeaction("refactor.extract", "x", rnnEnd, rnn) -- return newFunction() //@loc(rnnEnd, "false") +-import "golang.org/lsptests/assign/internal/secret" +- +-func _() { +- secret.Hello() +- var ( +- myInt int //@item(assignInt, "myInt", "int", "var") +- myStr string //@item(assignStr, "myStr", "string", "var") +- ) +- +- var _ string = my //@rank(" //", assignStr, assignInt) +- var _ string = //@rank(" //", assignStr, assignInt) -} - --func newFunction() bool { -- x := 1 -- if x == 0 { -- return true +-func _() { +- var a string = a //@complete(" //") +-} +- +-func _() { +- fooBar := fooBa //@complete(" //"),item(assignFooBar, "fooBar", "", "var") +- abc, fooBar := 123, fooBa //@complete(" //", assignFooBar) +- { +- fooBar := fooBa //@complete(" //", assignFooBar) - } -- return false -} - ---- return_complex.go -- --package extract +--- internal/secret/secret.go -- +-package secret - --import "fmt" +-func Hello() {} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/bad.txt b/gopls/internal/regtest/marker/testdata/completion/bad.txt +--- a/gopls/internal/regtest/marker/testdata/completion/bad.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/bad.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,68 +0,0 @@ +-This test exercises completion in the presence of type errors. - --func _() (int, string, error) { -- x := 1 -- y := "hello" -- z := "bye" //@codeaction("refactor.extract", "z", rcEnd, rc) -- if y == z { -- return x, y, fmt.Errorf("same") -- } else if false { -- z = "hi" -- return x, z, nil -- } //@loc(rcEnd, "}") -- return x, z, nil +-Note: this test was ported from the old marker tests, which did not enable +-unimported completion. Enabling it causes matches in e.g. crypto/rand. +- +--- settings.json -- +-{ +- "completeUnimported": false -} - ---- @rc/return_complex.go -- --package extract +--- go.mod -- +-module bad.test - --import "fmt" +-go 1.18 - --func _() (int, string, error) { -- x := 1 -- y := "hello" -- //@codeaction("refactor.extract", "z", rcEnd, rc) -- z, shouldReturn, returnValue, returnValue1, returnValue2 := newFunction(y, x) -- if shouldReturn { -- return returnValue, returnValue1, returnValue2 -- } //@loc(rcEnd, "}") -- return x, z, nil --} +--- bad/bad0.go -- +-package bad - --func newFunction(y string, x int) (string, bool, int, string, error) { -- z := "bye" -- if y == z { -- return "", true, x, y, fmt.Errorf("same") -- } else if false { -- z = "hi" -- return "", true, x, z, nil -- } -- return z, false, 0, "", nil +-func stuff() { //@item(stuff, "stuff", "func()", "func") +- x := "heeeeyyyy" +- random2(x) //@diag("x", re"cannot use x \\(variable of type string\\) as int value in argument to random2") +- random2(1) //@complete("dom", random, random2, random3) +- y := 3 //@diag("y", re"y declared (and|but) not used") -} - ---- return_complex_nonnested.go -- --package extract -- --import "fmt" +-type bob struct { //@item(bob, "bob", "struct{...}", "struct") +- x int +-} - --func _() (int, string, error) { -- x := 1 -- y := "hello" -- z := "bye" //@codeaction("refactor.extract", "z", rcnnEnd, rcnn) -- if y == z { -- return x, y, fmt.Errorf("same") -- } else if false { -- z = "hi" -- return x, z, nil +-func _() { +- var q int +- _ = &bob{ +- f: q, //@diag("f: q", re"unknown field f in struct literal") - } -- return x, z, nil //@loc(rcnnEnd, "nil") -} - ---- @rcnn/return_complex_nonnested.go -- --package extract +--- bad/bad1.go -- +-package bad - --import "fmt" +-// See #36637 +-type stateFunc func() stateFunc //@item(stateFunc, "stateFunc", "func() stateFunc", "type") - --func _() (int, string, error) { -- x := 1 -- y := "hello" -- //@codeaction("refactor.extract", "z", rcnnEnd, rcnn) -- return newFunction(y, x) //@loc(rcnnEnd, "nil") --} +-var a unknown //@item(global_a, "a", "unknown", "var"),diag("unknown", re"(undeclared name|undefined): unknown") - --func newFunction(y string, x int) (int, string, error) { -- z := "bye" -- if y == z { -- return x, y, fmt.Errorf("same") -- } else if false { -- z = "hi" -- return x, z, nil -- } -- return x, z, nil +-func random() int { //@item(random, "random", "func() int", "func") +- //@complete("", global_a, bob, random, random2, random3, stateFunc, stuff) +- return 0 -} - ---- return_func_lit.go -- --package extract +-func random2(y int) int { //@item(random2, "random2", "func(y int) int", "func"),item(bad_y_param, "y", "int", "var") +- x := 6 //@item(x, "x", "int", "var"),diag("x", re"x declared (and|but) not used") +- var q blah //@item(q, "q", "blah", "var"),diag("q", re"q declared (and|but) not used"),diag("blah", re"(undeclared name|undefined): blah") +- var t **blob //@item(t, "t", "**blob", "var"),diag("t", re"t declared (and|but) not used"),diag("blob", re"(undeclared name|undefined): blob") +- //@complete("", q, t, x, bad_y_param, global_a, bob, random, random2, random3, stateFunc, stuff) - --import "go/ast" +- return y +-} - --func _() { -- ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool { -- if n == nil { //@codeaction("refactor.extract", "if", rflEnd, rfl) -- return true -- } //@loc(rflEnd, "}") -- return false -- }) +-func random3(y ...int) { //@item(random3, "random3", "func(y ...int)", "func"),item(y_variadic_param, "y", "[]int", "var") +- //@complete("", y_variadic_param, global_a, bob, random, random2, random3, stateFunc, stuff) +- +- var ch chan (favType1) //@item(ch, "ch", "chan (favType1)", "var"),diag("ch", re"ch declared (and|but) not used"),diag("favType1", re"(undeclared name|undefined): favType1") +- var m map[keyType]int //@item(m, "m", "map[keyType]int", "var"),diag("m", re"m declared (and|but) not used"),diag("keyType", re"(undeclared name|undefined): keyType") +- var arr []favType2 //@item(arr, "arr", "[]favType2", "var"),diag("arr", re"arr declared (and|but) not used"),diag("favType2", re"(undeclared name|undefined): favType2") +- var fn1 func() badResult //@item(fn1, "fn1", "func() badResult", "var"),diag("fn1", re"fn1 declared (and|but) not used"),diag("badResult", re"(undeclared name|undefined): badResult") +- var fn2 func(badParam) //@item(fn2, "fn2", "func(badParam)", "var"),diag("fn2", re"fn2 declared (and|but) not used"),diag("badParam", re"(undeclared name|undefined): badParam") +- //@complete("", arr, ch, fn1, fn2, m, y_variadic_param, global_a, bob, random, random2, random3, stateFunc, stuff) -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/basic_lit.txt b/gopls/internal/regtest/marker/testdata/completion/basic_lit.txt +--- a/gopls/internal/regtest/marker/testdata/completion/basic_lit.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/basic_lit.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,19 +0,0 @@ +-This test checks completion related to basic literals. - ---- @rfl/return_func_lit.go -- --package extract +--- flags -- +--ignore_extra_diags - --import "go/ast" +--- basiclit.go -- +-package basiclit - -func _() { -- ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool { -- //@codeaction("refactor.extract", "if", rflEnd, rfl) -- shouldReturn, returnValue := newFunction(n) -- if shouldReturn { -- return returnValue -- } //@loc(rflEnd, "}") -- return false -- }) --} +- var a int // something for lexical completions - --func newFunction(n ast.Node) (bool, bool) { -- if n == nil { -- return true, true -- } -- return false, false --} +- _ = "hello." //@complete(".") - ---- return_func_lit_nonnested.go -- --package extract +- _ = 1 //@complete(" //") - --import "go/ast" +- _ = 1. //@complete(".") - --func _() { -- ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool { -- if n == nil { //@codeaction("refactor.extract", "if", rflnnEnd, rflnn) -- return true -- } -- return false //@loc(rflnnEnd, "false") -- }) +- _ = 'a' //@complete("' ") -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/builtins.txt b/gopls/internal/regtest/marker/testdata/completion/builtins.txt +--- a/gopls/internal/regtest/marker/testdata/completion/builtins.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/builtins.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,118 +0,0 @@ +-This test checks completion of Go builtins. - ---- @rflnn/return_func_lit_nonnested.go -- --package extract +--- flags -- +--ignore_extra_diags +--filter_builtins=false - --import "go/ast" +--- builtin_args.go -- +-package builtins - -func _() { -- ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool { -- //@codeaction("refactor.extract", "if", rflnnEnd, rflnn) -- return newFunction(n) //@loc(rflnnEnd, "false") -- }) --} +- var ( +- aSlice []int //@item(builtinSlice, "aSlice", "[]int", "var") +- aMap map[string]int //@item(builtinMap, "aMap", "map[string]int", "var") +- aString string //@item(builtinString, "aString", "string", "var") +- aArray [0]int //@item(builtinArray, "aArray", "[0]int", "var") +- aArrayPtr *[0]int //@item(builtinArrayPtr, "aArrayPtr", "*[0]int", "var") +- aChan chan int //@item(builtinChan, "aChan", "chan int", "var") +- aPtr *int //@item(builtinPtr, "aPtr", "*int", "var") +- aInt int //@item(builtinInt, "aInt", "int", "var") +- ) - --func newFunction(n ast.Node) bool { -- if n == nil { -- return true -- } -- return false --} +- type ( +- aSliceType []int //@item(builtinSliceType, "aSliceType", "[]int", "type") +- aChanType chan int //@item(builtinChanType, "aChanType", "chan int", "type") +- aMapType map[string]int //@item(builtinMapType, "aMapType", "map[string]int", "type") +- ) - ---- return_init.go -- --package extract +- close() //@rank(")", builtinChan, builtinSlice) - --func _() string { -- x := 1 -- if x == 0 { //@codeaction("refactor.extract", "if", riEnd, ri) -- x = 3 -- return "a" -- } //@loc(riEnd, "}") -- x = 2 -- return "b" --} +- append() //@rank(")", builtinSlice, builtinChan) - ---- @ri/return_init.go -- --package extract +- var _ []byte = append([]byte(nil), ""...) //@rank(") //") - --func _() string { -- x := 1 -- //@codeaction("refactor.extract", "if", riEnd, ri) -- shouldReturn, returnValue := newFunction(x) -- if shouldReturn { -- return returnValue -- } //@loc(riEnd, "}") -- x = 2 -- return "b" --} +- copy() //@rank(")", builtinSlice, builtinChan) +- copy(aSlice, aS) //@rank(")", builtinSlice, builtinString) +- copy(aS, aSlice) //@rank(",", builtinSlice, builtinString) - --func newFunction(x int) (bool, string) { -- if x == 0 { -- x = 3 -- return true, "a" +- delete() //@rank(")", builtinMap, builtinChan) +- delete(aMap, aS) //@rank(")", builtinString, builtinSlice) +- +- aMapFunc := func() map[int]int { //@item(builtinMapFunc, "aMapFunc", "func() map[int]int", "var") +- return nil - } -- return false, "" --} +- delete() //@rank(")", builtinMapFunc, builtinSlice) - ---- return_init_nonnested.go -- --package extract +- len() //@rank(")", builtinSlice, builtinInt),rank(")", builtinMap, builtinInt),rank(")", builtinString, builtinInt),rank(")", builtinArray, builtinInt),rank(")", builtinArrayPtr, builtinPtr),rank(")", builtinChan, builtinInt) - --func _() string { -- x := 1 -- if x == 0 { //@codeaction("refactor.extract", "if", rinnEnd, rinn) -- x = 3 -- return "a" -- } -- x = 2 -- return "b" //@loc(rinnEnd, "\"b\"") --} +- cap() //@rank(")", builtinSlice, builtinMap),rank(")", builtinArray, builtinString),rank(")", builtinArrayPtr, builtinPtr),rank(")", builtinChan, builtinInt) - ---- @rinn/return_init_nonnested.go -- --package extract +- make() //@rank(")", builtinMapType, int),rank(")", builtinChanType, int),rank(")", builtinSliceType, int),rank(")", builtinMapType, int) +- make(aSliceType, a) //@rank(")", builtinInt, builtinSlice) - --func _() string { -- x := 1 -- //@codeaction("refactor.extract", "if", rinnEnd, rinn) -- return newFunction(x) //@loc(rinnEnd, "\"b\"") --} +- type myInt int +- var mi myInt //@item(builtinMyInt, "mi", "myInt", "var") +- make(aSliceType, m) //@snippet(")", builtinMyInt, "mi") - --func newFunction(x int) string { -- if x == 0 { -- x = 3 -- return "a" -- } -- x = 2 -- return "b" --} +- var _ []int = make() //@rank(")", builtinSliceType, builtinMapType) - ---- args_returns.go -- --package extract +- type myStruct struct{} //@item(builtinStructType, "myStruct", "struct{...}", "struct") +- var _ *myStruct = new() //@rank(")", builtinStructType, int) - --func _() { -- a := 1 -- a = 5 //@codeaction("refactor.extract", "a", araend, ara) -- a = a + 2 //@loc(araend, "2") +- for k := range a { //@rank(" {", builtinSlice, builtinInt),rank(" {", builtinString, builtinInt),rank(" {", builtinChan, builtinInt),rank(" {", builtinArray, builtinInt),rank(" {", builtinArrayPtr, builtinInt),rank(" {", builtinMap, builtinInt), +- } - -- b := a * 2 //@codeaction("refactor.extract", "b", arbend, arb) -- _ = b + 4 //@loc(arbend, "4") +- for k, v := range a { //@rank(" {", builtinSlice, builtinChan) +- } +- +- <-a //@rank(" //", builtinChan, builtinInt) -} - ---- @ara/args_returns.go -- --package extract +--- builtin_types.go -- +-package builtins - -func _() { -- a := 1 -- //@codeaction("refactor.extract", "a", araend, ara) -- a = newFunction(a) //@loc(araend, "2") +- var _ []bool //@item(builtinBoolSliceType, "[]bool", "[]bool", "type") - -- b := a * 2 //@codeaction("refactor.extract", "b", arbend, arb) -- _ = b + 4 //@loc(arbend, "4") --} +- var _ []bool = make() //@rank(")", builtinBoolSliceType, int) - --func newFunction(a int) int { -- a = 5 -- a = a + 2 -- return a --} +- var _ []bool = make([], 0) //@rank(",", bool, int) - ---- @arb/args_returns.go -- --package extract +- var _ [][]bool = make([][], 0) //@rank(",", bool, int) +-} - --func _() { -- a := 1 -- a = 5 //@codeaction("refactor.extract", "a", araend, ara) -- a = a + 2 //@loc(araend, "2") +--- builtins.go -- +-package builtins - -- //@codeaction("refactor.extract", "b", arbend, arb) -- newFunction(a) //@loc(arbend, "4") --} +-// Definitions of builtin completion items that are still used in tests. - --func newFunction(a int) { -- b := a * 2 -- _ = b + 4 --} +-/* bool */ //@item(bool, "bool", "", "type") +-/* complex(r float64, i float64) */ //@item(complex, "complex", "func(r float64, i float64) complex128", "func") +-/* float32 */ //@item(float32, "float32", "", "type") +-/* float64 */ //@item(float64, "float64", "", "type") +-/* imag(c complex128) float64 */ //@item(imag, "imag", "func(c complex128) float64", "func") +-/* int */ //@item(int, "int", "", "type") +-/* iota */ //@item(iota, "iota", "", "const") +-/* string */ //@item(string, "string", "", "type") +-/* true */ //@item(_true, "true", "", "const") - ---- scope.go -- --package extract +--- constants.go -- +-package builtins - -func _() { -- newFunction := 1 -- a := newFunction //@codeaction("refactor.extract", "a", "newFunction", scope) -- _ = a // avoid diagnostic --} +- const ( +- foo = iota //@complete(" //", iota) +- ) - --func newFunction1() int { -- return 1 --} +- iota //@complete(" //") +- +- var iota int //@item(iotaVar, "iota", "int", "var") - ---- @scope/scope.go -- --package extract +- iota //@complete(" //", iotaVar) +-} - -func _() { -- newFunction := 1 -- a := newFunction2(newFunction) //@codeaction("refactor.extract", "a", "newFunction", scope) -- _ = a // avoid diagnostic --} +- var twoRedUpEnd bool //@item(TRUEVar, "twoRedUpEnd", "bool", "var") - --func newFunction2(newFunction int) int { -- a := newFunction -- return a +- var _ bool = true //@rank(" //", _true, TRUEVar) -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/casesensitive.txt b/gopls/internal/regtest/marker/testdata/completion/casesensitive.txt +--- a/gopls/internal/regtest/marker/testdata/completion/casesensitive.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/casesensitive.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,24 +0,0 @@ +-This test exercises the caseSensitive completion matcher. - --func newFunction1() int { -- return 1 +--- flags -- +--ignore_extra_diags +- +--- settings.json -- +-{ +- "completeUnimported": false, +- "matcher": "caseSensitive" -} - ---- smart_initialization.go -- --package extract +--- casesensitive.go -- +-package casesensitive - -func _() { -- var a []int -- a = append(a, 2) //@codeaction("refactor.extract", "a", siEnd, si) -- b := 4 //@loc(siEnd, "4") -- a = append(a, b) --} +- var lower int //@item(lower, "lower", "int", "var") +- var Upper int //@item(upper, "Upper", "int", "var") - ---- @si/smart_initialization.go -- --package extract +- l //@complete(" //", lower) +- U //@complete(" //", upper) - --func _() { -- var a []int -- //@codeaction("refactor.extract", "a", siEnd, si) -- a, b := newFunction(a) //@loc(siEnd, "4") -- a = append(a, b) +- L //@complete(" //") +- u //@complete(" //") -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/cast.txt b/gopls/internal/regtest/marker/testdata/completion/cast.txt +--- a/gopls/internal/regtest/marker/testdata/completion/cast.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/cast.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,17 +0,0 @@ +-This test checks completion related to casts. - --func newFunction(a []int) ([]int, int) { -- a = append(a, 2) -- b := 4 -- return a, b --} +--- flags -- +--ignore_extra_diags - ---- smart_return.go -- --package extract +--- cast.go -- +-package cast - -func _() { -- var b []int -- var a int -- a = 2 //@codeaction("refactor.extract", "a", srEnd, sr) -- b = []int{} -- b = append(b, a) //@loc(srEnd, ")") -- b[0] = 1 +- foo := struct{x int}{x: 1} //@item(x_field, "x", "int", "field") +- _ = float64(foo.x) //@complete("x", x_field) -} - ---- @sr/smart_return.go -- --package extract -- -func _() { -- var b []int -- var a int -- //@codeaction("refactor.extract", "a", srEnd, sr) -- b = newFunction(a, b) //@loc(srEnd, ")") -- b[0] = 1 +- foo := struct{x int}{x: 1} +- _ = float64(foo. //@complete(" /", x_field) -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/channel.txt b/gopls/internal/regtest/marker/testdata/completion/channel.txt +--- a/gopls/internal/regtest/marker/testdata/completion/channel.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/channel.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,36 +0,0 @@ +-This test checks completion related to channels. - --func newFunction(a int, b []int) []int { -- a = 2 -- b = []int{} -- b = append(b, a) -- return b +--- flags -- +--ignore_extra_diags +- +--- settings.json -- +-{ +- "completeUnimported": false -} - ---- unnecessary_param.go -- --package extract +--- channel.go -- +-package channel - -func _() { -- var b []int -- a := 2 //@codeaction("refactor.extract", "a", upEnd, up) -- b = []int{} -- b = append(b, a) //@loc(upEnd, ")") -- b[0] = 1 -- if a == 2 { -- return +- var ( +- aa = "123" //@item(channelAA, "aa", "string", "var") +- ab = 123 //@item(channelAB, "ab", "int", "var") +- ) +- +- { +- type myChan chan int +- var mc myChan +- mc <- a //@complete(" //", channelAB, channelAA) - } --} - ---- @up/unnecessary_param.go -- --package extract +- { +- var ac chan int //@item(channelAC, "ac", "chan int", "var") +- a <- a //@complete(" <-", channelAC, channelAA, channelAB) +- } - --func _() { -- var b []int -- //@codeaction("refactor.extract", "a", upEnd, up) -- a, b := newFunction(b) //@loc(upEnd, ")") -- b[0] = 1 -- if a == 2 { -- return +- { +- var foo chan int //@item(channelFoo, "foo", "chan int", "var") +- wantsInt := func(int) {} //@item(channelWantsInt, "wantsInt", "func(int)", "var") +- wantsInt(<-) //@rank(")", channelFoo, channelAB) - } -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/comment.txt b/gopls/internal/regtest/marker/testdata/completion/comment.txt +--- a/gopls/internal/regtest/marker/testdata/completion/comment.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/comment.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,81 +0,0 @@ +-This test checks behavior of completion within comments. - --func newFunction(b []int) (int, []int) { -- a := 2 -- b = []int{} -- b = append(b, a) -- return a, b --} +--- flags -- +--ignore_extra_diags - ---- comment.go -- --package extract +--- go.mod -- +-module golang.org/lsptests/comment - --func _() { -- a := /* comment in the middle of a line */ 1 //@codeaction("refactor.extract", "a", commentEnd, comment1) -- // Comment on its own line //@codeaction("refactor.extract", "Comment", commentEnd, comment2) -- _ = a + 4 //@loc(commentEnd, "4"),codeaction("refactor.extract", "_", lastComment, comment3) -- // Comment right after 3 + 4 +-go 1.18 - -- // Comment after with space //@loc(lastComment, "Comment") --} +--- p.go -- +-package comment_completion - ---- @comment1/comment.go -- --package extract +-var p bool +- +-//@complete(re"$") - -func _() { -- /* comment in the middle of a line */ -- //@codeaction("refactor.extract", "a", commentEnd, comment1) -- // Comment on its own line //@codeaction("refactor.extract", "Comment", commentEnd, comment2) -- newFunction() //@loc(commentEnd, "4"),codeaction("refactor.extract", "_", lastComment, comment3) -- // Comment right after 3 + 4 +- var a int - -- // Comment after with space //@loc(lastComment, "Comment") --} +- switch a { +- case 1: +- //@complete(re"$") +- _ = a +- } - --func newFunction() { -- a := 1 +- var b chan int +- select { +- case <-b: +- //@complete(re"$") +- _ = b +- } - -- _ = a + 4 +- var ( +- //@complete(re"$") +- _ = a +- ) -} - ---- @comment2/comment.go -- --package extract +-// //@complete(" ", variableC) +-var C string //@item(variableC, "C", "string", "var") //@complete(" ", variableC) - --func _() { -- a := /* comment in the middle of a line */ 1 //@codeaction("refactor.extract", "a", commentEnd, comment1) -- // Comment on its own line //@codeaction("refactor.extract", "Comment", commentEnd, comment2) -- newFunction(a) //@loc(commentEnd, "4"),codeaction("refactor.extract", "_", lastComment, comment3) -- // Comment right after 3 + 4 +-// //@complete(" ", constant) +-const Constant = "example" //@item(constant, "Constant", "string", "const") //@complete(" ", constant) - -- // Comment after with space //@loc(lastComment, "Comment") +-// //@complete(" ", structType, fieldB, fieldA) +-type StructType struct { //@item(structType, "StructType", "struct{...}", "struct") //@complete(" ", structType, fieldA, fieldB) +- // //@complete(" ", fieldA, structType, fieldB) +- A string //@item(fieldA, "A", "string", "field") //@complete(" ", fieldA, structType, fieldB) +- b int //@item(fieldB, "b", "int", "field") //@complete(" ", fieldB, structType, fieldA) -} - --func newFunction(a int) { -- _ = a + 4 +-// //@complete(" ", method, structRecv, paramX, resultY, fieldB, fieldA) +-func (structType *StructType) Method(X int) (Y int) { //@item(structRecv, "structType", "*StructType", "var"),item(method, "Method", "func(X int) (Y int)", "method"),item(paramX, "X", "int", "var"),item(resultY, "Y", "int", "var") +- // //@complete(" ", method, structRecv, paramX, resultY, fieldB, fieldA) +- return -} - ---- @comment3/comment.go -- --package extract +-// //@complete(" ", newType) +-type NewType string //@item(newType, "NewType", "string", "type") //@complete(" ", newType) - --func _() { -- a := /* comment in the middle of a line */ 1 //@codeaction("refactor.extract", "a", commentEnd, comment1) -- // Comment on its own line //@codeaction("refactor.extract", "Comment", commentEnd, comment2) -- newFunction(a) //@loc(commentEnd, "4"),codeaction("refactor.extract", "_", lastComment, comment3) -- // Comment right after 3 + 4 +-// //@complete(" ", testInterface, testA, testB) +-type TestInterface interface { //@item(testInterface, "TestInterface", "interface{...}", "interface") +- // //@complete(" ", testA, testInterface, testB) +- TestA(L string) (M int) //@item(testA, "TestA", "func(L string) (M int)", "method"),item(paramL, "L", "var", "string"),item(resM, "M", "var", "int") //@complete(" ", testA, testInterface, testB) +- TestB(N int) bool //@item(testB, "TestB", "func(N int) bool", "method"),item(paramN, "N", "var", "int") //@complete(" ", testB, testInterface, testA) +-} - -- // Comment after with space //@loc(lastComment, "Comment") +-// //@complete(" ", function) +-func Function() int { //@item(function, "Function", "func() int", "func") //@complete(" ", function) +- // //@complete(" ", function) +- return 0 -} - --func newFunction(a int) { -- _ = a + 4 +-// This tests multiline block comments and completion with prefix +-// Lorem Ipsum Multili//@complete("Multi", multiline) +-// Lorem ipsum dolor sit ametom +-func Multiline() int { //@item(multiline, "Multiline", "func() int", "func") +- // //@complete(" ", multiline) +- return 0 -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/complit.txt b/gopls/internal/regtest/marker/testdata/completion/complit.txt +--- a/gopls/internal/regtest/marker/testdata/completion/complit.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/complit.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,104 +0,0 @@ +-This test checks completion related to composite literals. - ---- redefine.go -- --package extract +--- flags -- +--ignore_extra_diags - --import "strconv" +--- settings.json -- +-{ +- "completeUnimported": false +-} +- +--- complit.go -- +-package complit +- +-// Literal completion results. +-/* int() */ //@item(int, "int()", "int", "var") +- +-// general completions +- +-type position struct { //@item(structPosition, "position", "struct{...}", "struct") +- X, Y int //@item(fieldX, "X", "int", "field"),item(fieldY, "Y", "int", "field") +-} - -func _() { -- i, err := strconv.Atoi("1") -- u, err := strconv.Atoi("2") //@codeaction("refactor.extract", "u", ")", redefine) -- if i == u || err == nil { -- return +- _ = position{ +- //@complete("", fieldX, fieldY, int, structPosition) +- } +- _ = position{ +- X: 1, +- //@complete("", fieldY) +- } +- _ = position{ +- //@complete("", fieldX) +- Y: 1, +- } +- _ = []*position{ +- { +- //@complete("", fieldX, fieldY, int, structPosition) +- }, - } -} - ---- @redefine/redefine.go -- --package extract +-func _() { +- var ( +- aa string //@item(aaVar, "aa", "string", "var") +- ab int //@item(abVar, "ab", "int", "var") +- ) - --import "strconv" +- _ = map[int]int{ +- a: a, //@complete(":", abVar, aaVar),complete(",", abVar, aaVar) +- } - --func _() { -- i, err := strconv.Atoi("1") -- u, err := newFunction() //@codeaction("refactor.extract", "u", ")", redefine) -- if i == u || err == nil { -- return +- _ = map[int]int{ +- //@complete("", abVar, int, aaVar, structPosition) - } --} - --func newFunction() (int, error) { -- u, err := strconv.Atoi("2") -- return u, err --} +- _ = []string{a: ""} //@complete(":", abVar, aaVar) +- _ = [1]string{a: ""} //@complete(":", abVar, aaVar) - -diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/functionextraction_issue44813.txt b/gopls/internal/regtest/marker/testdata/codeaction/functionextraction_issue44813.txt ---- a/gopls/internal/regtest/marker/testdata/codeaction/functionextraction_issue44813.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/codeaction/functionextraction_issue44813.txt 1970-01-01 08:00:00 -@@ -1,42 +0,0 @@ --This test verifies the fix for golang/go#44813: extraction failure when there --are blank identifiers. +- _ = position{X: a} //@complete("}", abVar, aaVar) +- _ = position{a} //@complete("}", abVar, aaVar) +- _ = position{a, } //@complete("}", abVar, int, aaVar, structPosition) - ---- go.mod -- --module mod.test/extract +- _ = []int{a} //@complete("}", abVar, aaVar) +- _ = [1]int{a} //@complete("}", abVar, aaVar) - --go 1.18 +- type myStruct struct { +- AA int //@item(fieldAA, "AA", "int", "field") +- AB string //@item(fieldAB, "AB", "string", "field") +- } - ---- p.go -- --package extract +- _ = myStruct{ +- AB: a, //@complete(",", aaVar, abVar) +- } - --import "fmt" +- var s myStruct - --func main() { -- x := []rune{} //@codeaction("refactor.extract", "x", end, ext) -- s := "HELLO" -- for _, c := range s { -- x = append(x, c) -- } //@loc(end, "}") -- fmt.Printf("%x\n", x) +- _ = map[int]string{1: "" + s.A} //@complete("}", fieldAB, fieldAA) +- _ = map[int]string{1: (func(i int) string { return "" })(s.A)} //@complete(")}", fieldAA, fieldAB) +- _ = map[int]string{1: func() string { s.A }} //@complete(" }", fieldAA, fieldAB) +- +- _ = position{s.A} //@complete("}", fieldAA, fieldAB) +- +- var X int //@item(varX, "X", "int", "var") +- _ = position{X} //@complete("}", fieldX, varX) -} - ---- @ext/p.go -- --package extract +-func _() { +- type foo struct{} //@item(complitFoo, "foo", "struct{...}", "struct") - --import "fmt" +- var _ *foo = &fo{} //@snippet("{", complitFoo, "foo") +- var _ *foo = fo{} //@snippet("{", complitFoo, "&foo") - --func main() { -- //@codeaction("refactor.extract", "x", end, ext) -- x := newFunction() //@loc(end, "}") -- fmt.Printf("%x\n", x) +- struct { a, b *foo }{ +- a: &fo{}, //@rank("{", complitFoo) +- b: fo{}, //@snippet("{", complitFoo, "&foo") +- } -} - --func newFunction() []rune { -- x := []rune{} -- s := "HELLO" -- for _, c := range s { -- x = append(x, c) +-func _() { +- _ := position{ +- X: 1, //@complete("X", fieldX),complete(" 1", int, structPosition) +- Y: , //@complete(":", fieldY),complete(" ,", int, structPosition) - } -- return x -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/constant.txt b/gopls/internal/regtest/marker/testdata/completion/constant.txt +--- a/gopls/internal/regtest/marker/testdata/completion/constant.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/constant.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,20 +0,0 @@ +-This test checks completion related to constants. - -diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/imports.txt b/gopls/internal/regtest/marker/testdata/codeaction/imports.txt ---- a/gopls/internal/regtest/marker/testdata/codeaction/imports.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/codeaction/imports.txt 1970-01-01 08:00:00 -@@ -1,175 +0,0 @@ --This test verifies the behavior of the 'source.organizeImports' code action. -- ---- go.mod -- --module mod.test/imports +--- flags -- +--ignore_extra_diags - --go 1.18 +--- constant.go -- +-package constant - ---- add.go -- --package imports //@codeaction("source.organizeImports", "imports", "", add) +-const x = 1 //@item(constX, "x", "int", "const") - --import ( -- "fmt" +-const ( +- a int = iota << 2 //@item(constA, "a", "int", "const") +- b //@item(constB, "b", "int", "const") +- c //@item(constC, "c", "int", "const") -) - -func _() { -- fmt.Println("") -- bytes.NewBuffer(nil) //@diag("bytes", re"(undeclared|undefined)") +- const y = "hi" //@item(constY, "y", "string", "const") +- //@complete("", constY, constA, constB, constC, constX) -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/danglingstmt.txt b/gopls/internal/regtest/marker/testdata/completion/danglingstmt.txt +--- a/gopls/internal/regtest/marker/testdata/completion/danglingstmt.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/danglingstmt.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,158 +0,0 @@ +-This test checks that completion works as expected in the presence of +-incomplete statements that may affect parser recovery. - ---- @add/add.go -- --package imports //@codeaction("source.organizeImports", "imports", "", add) +--- flags -- +--ignore_extra_diags - --import ( -- "bytes" -- "fmt" --) +--- go.mod -- +-module golang.org/lsptests/dangling - --func _() { -- fmt.Println("") -- bytes.NewBuffer(nil) //@diag("bytes", re"(undeclared|undefined)") --} +-go 1.18 - ---- good.go -- --package imports //@codeactionerr("source.organizeImports", "imports", "", re"found 0 CodeActions") +--- settings.json -- +-{ +- "completeUnimported": false, +- "deepCompletion": false +-} - --import "fmt" +--- dangling_for.go -- +-package danglingstmt - -func _() { --fmt.Println("") +- for bar //@rank(" //", danglingBar) -} - ---- issue35458.go -- +-func bar() bool { //@item(danglingBar, "bar", "func() bool", "func") +- return true +-} - +--- dangling_for_init.go -- +-package danglingstmt - +-func _() { +- for i := bar //@rank(" //", danglingBar2) +-} - +-func bar2() int { //@item(danglingBar2, "bar2", "func() int", "func") +- return 0 +-} - +--- dangling_for_init_cond.go -- +-package danglingstmt - --// package doc --package imports //@codeaction("source.organizeImports", "imports", "", issue35458) +-func _() { +- for i := bar3(); i > bar //@rank(" //", danglingBar3) +-} - +-func bar3() int { //@item(danglingBar3, "bar3", "func() int", "func") +- return 0 +-} - +--- dangling_for_init_cond_post.go -- +-package danglingstmt - +-func _() { +- for i := bar4(); i > bar4(); i += bar //@rank(" //", danglingBar4) +-} - +-func bar4() int { //@item(danglingBar4, "bar4", "func() int", "func") +- return 0 +-} - +--- dangling_if.go -- +-package danglingstmt - -func _() { -- println("Hello, world!") +- if foo //@rank(" //", danglingFoo) -} - +-func foo() bool { //@item(danglingFoo, "foo", "func() bool", "func") +- return true +-} - +--- dangling_if_eof.go -- +-package danglingstmt - +-func bar5() bool { //@item(danglingBar5, "bar5", "func() bool", "func") +- return true +-} - +-func _() { +- if b //@rank(" //", danglingBar5) - +--- dangling_if_init.go -- +-package danglingstmt - +-func _() { +- if i := foo //@rank(" //", danglingFoo2) +-} - +-func foo2() bool { //@item(danglingFoo2, "foo2", "func() bool", "func") +- return true +-} - ---- @issue35458/issue35458.go -- --// package doc --package imports //@codeaction("source.organizeImports", "imports", "", issue35458) -- +--- dangling_if_init_cond.go -- +-package danglingstmt - +-func _() { +- if i := 123; foo //@rank(" //", danglingFoo3) +-} - +-func foo3() bool { //@item(danglingFoo3, "foo3", "func() bool", "func") +- return true +-} - +--- dangling_multiline_if.go -- +-package danglingstmt - +-func walrus() bool { //@item(danglingWalrus, "walrus", "func() bool", "func") +- return true +-} - -func _() { -- println("Hello, world!") +- if true && +- walrus //@complete(" //", danglingWalrus) -} - +--- dangling_selector_1.go -- +-package danglingstmt - +-func _() { +- x. //@rank(" //", danglingI) +-} - +-var x struct { i int } //@item(danglingI, "i", "int", "field") - +--- dangling_selector_2.go -- +-package danglingstmt - +-// TODO: re-enable this test, which was broken when the foo package was removed. +-// (we can replicate the relevant definitions in the new marker test) +-// import "golang.org/lsptests/foo" - +-func _() { +- foo. // rank(" //", Foo) +- var _ = []string{foo.} // rank("}", Foo) +-} - -- ---- multi.go -- --package imports //@codeaction("source.organizeImports", "imports", "", multi) -- --import "fmt" -- --import "bytes" //@diag("\"bytes\"", re"not used") +--- dangling_switch_init.go -- +-package danglingstmt - -func _() { -- fmt.Println("") +- switch i := baz //@rank(" //", danglingBaz) -} - ---- @multi/multi.go -- --package imports //@codeaction("source.organizeImports", "imports", "", multi) -- --import "fmt" +-func baz() int { //@item(danglingBaz, "baz", "func() int", "func") +- return 0 +-} - --//@diag("\"bytes\"", re"not used") +--- dangling_switch_init_tag.go -- +-package danglingstmt - -func _() { -- fmt.Println("") +- switch i := 0; baz //@rank(" //", danglingBaz2) -} - ---- needs.go -- --package imports //@codeaction("source.organizeImports", "package", "", needs) -- --func goodbye() { -- fmt.Printf("HI") //@diag("fmt", re"(undeclared|undefined)") -- log.Printf("byeeeee") //@diag("log", re"(undeclared|undefined)") +-func baz2() int { //@item(danglingBaz2, "baz2", "func() int", "func") +- return 0 -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/deep2.txt b/gopls/internal/regtest/marker/testdata/completion/deep2.txt +--- a/gopls/internal/regtest/marker/testdata/completion/deep2.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/deep2.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,65 +0,0 @@ +-This test exercises deep completion. - ---- @needs/needs.go -- --package imports //@codeaction("source.organizeImports", "package", "", needs) +-It was originally bundled with deep.go, but is split into a separate test as +-the new marker tests do not permit mutating server options for individual +-marks. - --import ( -- "fmt" -- "log" --) +--- flags -- +--ignore_extra_diags - --func goodbye() { -- fmt.Printf("HI") //@diag("fmt", re"(undeclared|undefined)") -- log.Printf("byeeeee") //@diag("log", re"(undeclared|undefined)") --} +--- go.mod -- +-module golang.org/lsptests - ---- remove.go -- --package imports //@codeaction("source.organizeImports", "package", "", remove) +-go 1.18 - --import ( -- "bytes" //@diag("\"bytes\"", re"not used") -- "fmt" --) +--- deep/deep2.go -- +-package deep - --func _() { -- fmt.Println("") +-type foo struct { +- b bar -} - ---- @remove/remove.go -- --package imports //@codeaction("source.organizeImports", "package", "", remove) -- --import ( -- "fmt" --) +-func (f foo) bar() bar { +- return f.b +-} - --func _() { -- fmt.Println("") +-func (f foo) barPtr() *bar { +- return &f.b -} - ---- removeall.go -- --package imports //@codeaction("source.organizeImports", "package", "", removeall) +-type bar struct{} - --import ( -- "bytes" //@diag("\"bytes\"", re"not used") -- "fmt" //@diag("\"fmt\"", re"not used") +-func (b bar) valueReceiver() int { +- return 0 +-} - --) +-func (b *bar) ptrReceiver() int { +- return 0 +-} - -func _() { +- var ( +- i int +- f foo +- ) +- +- f.bar().valueReceiver //@item(deepBarValue, "f.bar().valueReceiver", "func() int", "method") +- f.barPtr().ptrReceiver //@item(deepBarPtrPtr, "f.barPtr().ptrReceiver", "func() int", "method") +- f.barPtr().valueReceiver //@item(deepBarPtrValue, "f.barPtr().valueReceiver", "func() int", "method") +- +- i = fbar //@complete(" //", deepBarValue, deepBarPtrPtr, deepBarPtrValue) -} - ---- @removeall/removeall.go -- --package imports //@codeaction("source.organizeImports", "package", "", removeall) +-func (b baz) Thing() struct{ val int } { +- return b.thing +-} - --//@diag("\"fmt\"", re"not used") +-type baz struct { +- thing struct{ val int } +-} - --func _() { +-func (b baz) _() { +- b.Thing().val //@item(deepBazMethVal, "b.Thing().val", "int", "field") +- b.thing.val //@item(deepBazFieldVal, "b.thing.val", "int", "field") +- var _ int = bval //@rank(" //", deepBazFieldVal, deepBazMethVal) -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/deep.txt b/gopls/internal/regtest/marker/testdata/completion/deep.txt +--- a/gopls/internal/regtest/marker/testdata/completion/deep.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/deep.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,110 +0,0 @@ +-This test exercises deep completion. - ---- twolines.go -- --package imports --func main() {} //@codeactionerr("source.organizeImports", "main", "", re"found 0") -diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/infertypeargs.txt b/gopls/internal/regtest/marker/testdata/codeaction/infertypeargs.txt ---- a/gopls/internal/regtest/marker/testdata/codeaction/infertypeargs.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/codeaction/infertypeargs.txt 1970-01-01 08:00:00 -@@ -1,38 +0,0 @@ --This test verifies the infertypeargs refactoring. +--- settings.json -- +-{ +- "completeUnimported": false, +- "matcher": "caseInsensitive" +-} - --- flags -- ---min_go=go1.18 +--ignore_extra_diags - --- go.mod -- --module mod.test/infertypeargs +-module golang.org/lsptests - -go 1.18 - ---- p.go -- --package infertypeargs +--- deep/deep.go -- +-package deep - --func app[S interface{ ~[]E }, E interface{}](s S, e E) S { -- return append(s, e) --} +-import "context" - --func _() { -- _ = app[[]int] -- _ = app[[]int, int] -- _ = app[[]int]([]int{}, 0) //@codeaction("refactor.rewrite", "app", ")", infer) -- _ = app([]int{}, 0) +-type deepA struct { +- b deepB //@item(deepBField, "b", "deepB", "field") -} - ---- @infer/p.go -- --package infertypeargs -- --func app[S interface{ ~[]E }, E interface{}](s S, e E) S { -- return append(s, e) +-type deepB struct { -} - +-func wantsDeepB(deepB) {} +- -func _() { -- _ = app[[]int] -- _ = app[[]int, int] -- _ = app([]int{}, 0) //@codeaction("refactor.rewrite", "app", ")", infer) -- _ = app([]int{}, 0) +- var a deepA //@item(deepAVar, "a", "deepA", "var") +- a.b //@item(deepABField, "a.b", "deepB", "field") +- wantsDeepB(a) //@complete(")", deepABField, deepAVar) +- +- deepA{a} //@snippet("}", deepABField, "a.b") -} - -diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/inline.txt b/gopls/internal/regtest/marker/testdata/codeaction/inline.txt ---- a/gopls/internal/regtest/marker/testdata/codeaction/inline.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/codeaction/inline.txt 1970-01-01 08:00:00 -@@ -1,23 +0,0 @@ --This is a minimal test of the refactor.inline code action. +-func wantsContext(context.Context) {} - ---- go.mod -- --module testdata/codeaction --go 1.18 +-func _() { +- context.Background() //@item(ctxBackground, "context.Background", "func() context.Context", "func", "Background returns a non-nil, empty Context.") +- context.TODO() //@item(ctxTODO, "context.TODO", "func() context.Context", "func", "TODO returns a non-nil, empty Context.") - ---- a/a.go -- --package a +- wantsContext(c) //@rank(")", ctxBackground),rank(")", ctxTODO) +-} - -func _() { -- println(add(1, 2)) //@codeaction("refactor.inline", "add", ")", inline) +- var cork struct{ err error } +- cork.err //@item(deepCorkErr, "cork.err", "error", "field") +- context //@item(deepContextPkg, "context", "\"context\"", "package") +- var _ error = co // rank(" //", deepCorkErr, deepContextPkg) -} - --func add(x, y int) int { return x + y } -- ---- @inline/a/a.go -- --package a -- -func _() { -- println(1 + 2) //@codeaction("refactor.inline", "add", ")", inline) +- // deepCircle is circular. +- type deepCircle struct { +- *deepCircle +- } +- var circle deepCircle //@item(deepCircle, "circle", "deepCircle", "var") +- circle.deepCircle //@item(deepCircleField, "circle.deepCircle", "*deepCircle", "field") +- var _ deepCircle = circ //@complete(" //", deepCircle, deepCircleField),snippet(" //", deepCircleField, "*circle.deepCircle") -} - --func add(x, y int) int { return x + y } -diff -urN a/gopls/internal/regtest/marker/testdata/codelens/generate.txt b/gopls/internal/regtest/marker/testdata/codelens/generate.txt ---- a/gopls/internal/regtest/marker/testdata/codelens/generate.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/codelens/generate.txt 1970-01-01 08:00:00 -@@ -1,9 +0,0 @@ --This test exercises the "generate" codelens. -- ---- generate.go -- --//@codelenses() +-func _() { +- type deepEmbedC struct { +- } +- type deepEmbedB struct { +- deepEmbedC +- } +- type deepEmbedA struct { +- deepEmbedB +- } - --package generate +- wantsC := func(deepEmbedC) {} - --//go:generate echo Hi //@ codelens("//go:generate", "run go generate"), codelens("//go:generate", "run go generate ./...") --//go:generate echo I shall have no CodeLens -diff -urN a/gopls/internal/regtest/marker/testdata/codelens/test.txt b/gopls/internal/regtest/marker/testdata/codelens/test.txt ---- a/gopls/internal/regtest/marker/testdata/codelens/test.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/codelens/test.txt 1970-01-01 08:00:00 -@@ -1,31 +0,0 @@ --This file tests codelenses for test functions. +- var a deepEmbedA //@item(deepEmbedA, "a", "deepEmbedA", "var") +- a.deepEmbedB //@item(deepEmbedB, "a.deepEmbedB", "deepEmbedB", "field") +- a.deepEmbedC //@item(deepEmbedC, "a.deepEmbedC", "deepEmbedC", "field") +- wantsC(a) //@complete(")", deepEmbedC, deepEmbedA, deepEmbedB) +-} - --TODO: for some reason these code lens have zero width. Does that affect their --utility/visibility in various LSP clients? +-func _() { +- type nested struct { +- a int +- n *nested //@item(deepNestedField, "n", "*nested", "field") +- } - ---- settings.json -- --{ -- "codelenses": { -- "test": true +- nested{ +- a: 123, //@complete(" //", deepNestedField) - } -} - ---- p_test.go -- --//@codelenses() -- --package codelens //@codelens(re"()package codelens", "run file benchmarks") -- --import "testing" -- --func TestMain(m *testing.M) {} // no code lens for TestMain -- --func TestFuncWithCodeLens(t *testing.T) { //@codelens(re"()func", "run test") --} +-func _() { +- var a struct { +- b struct { +- c int +- } +- d int +- } - --func thisShouldNotHaveACodeLens(t *testing.T) { --} +- a.d //@item(deepAD, "a.d", "int", "field") +- a.b.c //@item(deepABC, "a.b.c", "int", "field") +- a.b //@item(deepAB, "a.b", "struct{...}", "field") +- a //@item(deepA, "a", "struct{...}", "var") - --func BenchmarkFuncWithCodeLens(b *testing.B) { //@codelens(re"()func", "run benchmark") +- // "a.d" should be ranked above the deeper "a.b.c" +- var i int +- i = a //@complete(" //", deepAD, deepABC, deepA, deepAB) -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/errors.txt b/gopls/internal/regtest/marker/testdata/completion/errors.txt +--- a/gopls/internal/regtest/marker/testdata/completion/errors.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/errors.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,33 +0,0 @@ +-This test checks completion related to errors. - --func helper() {} // expect no code lens -diff -urN a/gopls/internal/regtest/marker/testdata/completion/bad.txt b/gopls/internal/regtest/marker/testdata/completion/bad.txt ---- a/gopls/internal/regtest/marker/testdata/completion/bad.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/completion/bad.txt 1970-01-01 08:00:00 -@@ -1,68 +0,0 @@ --This test exercises completion in the presence of type errors. -- --Note: this test was ported from the old marker tests, which did not enable --unimported completion. Enabling it causes matches in e.g. crypto/rand. +--- flags -- +--ignore_extra_diags - --- settings.json -- -{ -- "completeUnimported": false +- "deepCompletion": false -} - --- go.mod -- --module bad.test +-module golang.org/lsptests - -go 1.18 - ---- bad/bad0.go -- --package bad +--- errors.go -- +-package errors - --func stuff() { //@item(stuff, "stuff", "func()", "func") -- x := "heeeeyyyy" -- random2(x) //@diag("x", re"cannot use x \\(variable of type string\\) as int value in argument to random2") -- random2(1) //@complete("dom", random, random2, random3) -- y := 3 //@diag("y", re"y declared (and|but) not used") +-import ( +- "golang.org/lsptests/types" +-) +- +-func _() { +- bob.Bob() //@complete(".") +- types.b //@complete(" //", Bob_interface) -} - --type bob struct { //@item(bob, "bob", "struct{...}", "struct") -- x int +--- types/types.go -- +-package types +- +-type Bob interface { //@item(Bob_interface, "Bob", "interface{...}", "interface") +- Bobby() -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/field_list.txt b/gopls/internal/regtest/marker/testdata/completion/field_list.txt +--- a/gopls/internal/regtest/marker/testdata/completion/field_list.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/field_list.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,38 +0,0 @@ +-This test checks completion related to field lists. - --func _() { -- var q int -- _ = &bob{ -- f: q, //@diag("f: q", re"unknown field f in struct literal") -- } +--- flags -- +--ignore_extra_diags +- +--- settings.json -- +-{ +- "completeUnimported": false -} - ---- bad/bad1.go -- --package bad +--- field_list.go -- +-package fieldlist - --// See #36637 --type stateFunc func() stateFunc //@item(stateFunc, "stateFunc", "func() stateFunc", "type") +-var myInt int //@item(flVar, "myInt", "int", "var") +-type myType int //@item(flType, "myType", "int", "type") - --var a unknown //@item(global_a, "a", "unknown", "var"),diag("unknown", re"(undeclared name|undefined): unknown") +-func (my) _() {} //@complete(") _", flType) +-func (my my) _() {} //@complete(" my)"),complete(") _", flType) - --func random() int { //@item(random, "random", "func() int", "func") -- //@complete("", global_a, bob, random, random2, random3, stateFunc, stuff) -- return 0 --} +-func (myType) _() {} //@complete(") {", flType) - --func random2(y int) int { //@item(random2, "random2", "func(y int) int", "func"),item(bad_y_param, "y", "int", "var") -- x := 6 //@item(x, "x", "int", "var"),diag("x", re"x declared (and|but) not used") -- var q blah //@item(q, "q", "blah", "var"),diag("q", re"q declared (and|but) not used"),diag("blah", re"(undeclared name|undefined): blah") -- var t **blob //@item(t, "t", "**blob", "var"),diag("t", re"t declared (and|but) not used"),diag("blob", re"(undeclared name|undefined): blob") -- //@complete("", q, t, x, bad_y_param, global_a, bob, random, random2, random3, stateFunc, stuff) +-func (myType) _(my my) {} //@complete(" my)"),complete(") {", flType) - -- return y --} +-func (myType) _() my {} //@complete(" {", flType) - --func random3(y ...int) { //@item(random3, "random3", "func(y ...int)", "func"),item(y_variadic_param, "y", "[]int", "var") -- //@complete("", y_variadic_param, global_a, bob, random, random2, random3, stateFunc, stuff) +-func (myType) _() (my my) {} //@complete(" my"),complete(") {", flType) - -- var ch chan (favType1) //@item(ch, "ch", "chan (favType1)", "var"),diag("ch", re"ch declared (and|but) not used"),diag("favType1", re"(undeclared name|undefined): favType1") -- var m map[keyType]int //@item(m, "m", "map[keyType]int", "var"),diag("m", re"m declared (and|but) not used"),diag("keyType", re"(undeclared name|undefined): keyType") -- var arr []favType2 //@item(arr, "arr", "[]favType2", "var"),diag("arr", re"arr declared (and|but) not used"),diag("favType2", re"(undeclared name|undefined): favType2") -- var fn1 func() badResult //@item(fn1, "fn1", "func() badResult", "var"),diag("fn1", re"fn1 declared (and|but) not used"),diag("badResult", re"(undeclared name|undefined): badResult") -- var fn2 func(badParam) //@item(fn2, "fn2", "func(badParam)", "var"),diag("fn2", re"fn2 declared (and|but) not used"),diag("badParam", re"(undeclared name|undefined): badParam") -- //@complete("", arr, ch, fn1, fn2, m, y_variadic_param, global_a, bob, random, random2, random3, stateFunc, stuff) +-func _() { +- var _ struct { +- //@complete("", flType) +- m my //@complete(" my"),complete(" //", flType) +- } +- +- var _ interface { +- //@complete("", flType) +- m() my //@complete("("),complete(" //", flType) +- } -} diff -urN a/gopls/internal/regtest/marker/testdata/completion/foobarbaz.txt b/gopls/internal/regtest/marker/testdata/completion/foobarbaz.txt --- a/gopls/internal/regtest/marker/testdata/completion/foobarbaz.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/completion/foobarbaz.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/completion/foobarbaz.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,541 +0,0 @@ -This test ports some arbitrary tests from the old marker framework, that were -*mostly* about completion. @@ -121573,81 +119846,416 @@ diff -urN a/gopls/internal/regtest/marker/testdata/completion/foobarbaz.txt b/go - var multiNamedReturn func() (b bool, i int) - multiNamedReturn = f //@snippet(" //", litFunc, "func() (b bool, i int) {$0\\}") - -- var duplicateParams func(myImpl, int, myImpl) -- duplicateParams = f //@snippet(" //", litFunc, "func(mi1 myImpl, i int, mi2 myImpl) {$0\\}") +- var duplicateParams func(myImpl, int, myImpl) +- duplicateParams = f //@snippet(" //", litFunc, "func(mi1 myImpl, i int, mi2 myImpl) {$0\\}") +- +- type aliasImpl = myImpl +- var aliasParams func(aliasImpl) aliasImpl +- aliasParams = f //@snippet(" //", litFunc, "func(ai aliasImpl) aliasImpl {$0\\}") +- +- const two = 2 +- var builtinTypes func([]int, [two]bool, map[string]string, struct{ i int }, interface{ foo() }, <-chan int) +- builtinTypes = f //@snippet(" //", litFunc, "func(i1 []int, b [two]bool, m map[string]string, s struct{ i int \\}, i2 interface{ foo() \\}, c <-chan int) {$0\\}") +- +- var _ func(ast.Node) = f //@snippet(" //", litFunc, "func(n ast.Node) {$0\\}") +- var _ func(error) = f //@snippet(" //", litFunc, "func(err error) {$0\\}") +- var _ func(context.Context) = f //@snippet(" //", litFunc, "func(ctx context.Context) {$0\\}") +- +- type context struct {} +- var _ func(context) = f //@snippet(" //", litFunc, "func(ctx context) {$0\\}") +-} +- +-func _() { +- float64() //@item(litFloat64, "float64()", "float64", "var") +- +- // don't complete to "&float64()" +- var _ *float64 = float64 //@complete(" //") +- +- var f float64 +- f = fl //@complete(" //", litFloat64),snippet(" //", litFloat64, "float64($0)") +- +- type myInt int +- myInt() //@item(litMyInt, "myInt()", "", "var") +- +- var mi myInt +- mi = my //@snippet(" //", litMyInt, "myInt($0)") +-} +- +-func _() { +- type ptrStruct struct { +- p *ptrStruct +- } +- +- ptrStruct{} //@item(litPtrStruct, "ptrStruct{}", "", "var") +- +- ptrStruct{ +- p: &ptrSt, //@rank(",", litPtrStruct) +- } +- +- &ptrStruct{} //@item(litPtrStructPtr, "&ptrStruct{}", "", "var") +- +- &ptrStruct{ +- p: ptrSt, //@rank(",", litPtrStructPtr) +- } +-} +- +-func _() { +- f := func(...[]int) {} +- f() //@snippet(")", litIntSlice, "[]int{$0\\}") +-} +- +- +-func _() { +- // don't complete to "untyped int()" +- []int{}[untyped] //@complete("] //") +-} +- +-type Tree[T any] struct{} +- +-func (tree Tree[T]) Do(f func(s T)) {} +- +-func _() { +- var t Tree[string] +- t.Do(fun) //@complete(")", litFunc), snippet(")", litFunc, "func(s string) {$0\\}") +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/func_rank.txt b/gopls/internal/regtest/marker/testdata/completion/func_rank.txt +--- a/gopls/internal/regtest/marker/testdata/completion/func_rank.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/func_rank.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,83 +0,0 @@ +-This test checks various ranking of completion results within function call +-context. +- +--- flags -- +--ignore_extra_diags +- +--- settings.json -- +-{ +- "completeUnimported": false, +- "deepCompletion": false +-} +- +--- func_rank.go -- +-package func_rank +- +-import "net/http" +- +-var stringAVar = "var" //@item(stringAVar, "stringAVar", "string", "var") +-func stringBFunc() string { return "str" } //@item(stringBFunc, "stringBFunc", "func() string", "func") +-type stringer struct{} //@item(stringer, "stringer", "struct{...}", "struct") +- +-func _() stringer //@complete("tr", stringer) +- +-func _(val stringer) {} //@complete("tr", stringer) +- +-func (stringer) _() {} //@complete("tr", stringer) +- +-func _() { +- var s struct { +- AA int //@item(rankAA, "AA", "int", "field") +- AB string //@item(rankAB, "AB", "string", "field") +- AC int //@item(rankAC, "AC", "int", "field") +- } +- fnStr := func(string) {} +- fnStr(s.A) //@complete(")", rankAB, rankAA, rankAC) +- fnStr("" + s.A) //@complete(")", rankAB, rankAA, rankAC) +- +- fnInt := func(int) {} +- fnInt(-s.A) //@complete(")", rankAA, rankAC, rankAB) +- +- // no expected type +- fnInt(func() int { s.A }) //@complete(" }", rankAA, rankAB, rankAC) +- fnInt(s.A()) //@complete("()", rankAA, rankAC, rankAB) +- fnInt([]int{}[s.A]) //@complete("])", rankAA, rankAC, rankAB) +- fnInt([]int{}[:s.A]) //@complete("])", rankAA, rankAC, rankAB) +- +- fnInt(s.A.(int)) //@complete(".(", rankAA, rankAC, rankAB) +- +- fnPtr := func(*string) {} +- fnPtr(&s.A) //@complete(")", rankAB, rankAA, rankAC) +- +- var aaPtr *string //@item(rankAAPtr, "aaPtr", "*string", "var") +- var abPtr *int //@item(rankABPtr, "abPtr", "*int", "var") +- fnInt(*a) //@complete(")", rankABPtr, rankAAPtr, stringAVar) +- +- _ = func() string { +- return s.A //@complete(" //", rankAB, rankAA, rankAC) +- } +-} +- +-type foo struct { +- fooPrivateField int //@item(rankFooPrivField, "fooPrivateField", "int", "field") +- FooPublicField int //@item(rankFooPubField, "FooPublicField", "int", "field") +-} +- +-func (foo) fooPrivateMethod() int { //@item(rankFooPrivMeth, "fooPrivateMethod", "func() int", "method") +- return 0 +-} +- +-func (foo) FooPublicMethod() int { //@item(rankFooPubMeth, "FooPublicMethod", "func() int", "method") +- return 0 +-} +- +-func _() { +- var _ int = foo{}. //@rank(" //", rankFooPrivField, rankFooPubField),rank(" //", rankFooPrivMeth, rankFooPubMeth),rank(" //", rankFooPrivField, rankFooPrivMeth) +-} +- +-func _() { +- HandleFunc //@item(httpHandleFunc, "HandleFunc", "func(pattern string, handler func(http.ResponseWriter, *http.Request))", "func") +- HandlerFunc //@item(httpHandlerFunc, "HandlerFunc", "func(http.ResponseWriter, *http.Request)", "type") +- +- http.HandleFunc //@rank(" //", httpHandleFunc, httpHandlerFunc) +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/func_sig.txt b/gopls/internal/regtest/marker/testdata/completion/func_sig.txt +--- a/gopls/internal/regtest/marker/testdata/completion/func_sig.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/func_sig.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +-This test checks completion related to function signatures. +- +--- flags -- +--ignore_extra_diags +- +--- func_sig.go -- +-package funcsig +- +-type someType int //@item(sigSomeType, "someType", "int", "type") +- +-// Don't complete "foo" in signature. +-func (foo someType) _() { //@item(sigFoo, "foo", "someType", "var"),complete(") {", sigSomeType) +- +- //@complete("", sigFoo, sigSomeType) +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/func_snippets.txt b/gopls/internal/regtest/marker/testdata/completion/func_snippets.txt +--- a/gopls/internal/regtest/marker/testdata/completion/func_snippets.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/func_snippets.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,32 +0,0 @@ +-This test exercises function snippets using generics. +- +--- flags -- +--ignore_extra_diags +- +--- settings.json -- +-{ +- "usePlaceholders": true +-} +- +--- go.mod -- +-module golang.org/lsptests/snippets +- +-go 1.18 +- +--- funcsnippets.go -- +-package snippets +- +-type SyncMap[K comparable, V any] struct{} +- +-func NewSyncMap[K comparable, V any]() (result *SyncMap[K, V]) { //@item(NewSyncMap, "NewSyncMap", "", "") +- return +-} +- +-func Identity[P ~int](p P) P { //@item(Identity, "Identity", "", "") +- return p +-} +- +-func _() { +- _ = NewSyncM //@snippet(" //", NewSyncMap, "NewSyncMap[${1:K comparable}, ${2:V any}]()") +- _ = Identi //@snippet(" //", Identity, "Identity[${1:P ~int}](${2:p P})") +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/func_value.txt b/gopls/internal/regtest/marker/testdata/completion/func_value.txt +--- a/gopls/internal/regtest/marker/testdata/completion/func_value.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/func_value.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,33 +0,0 @@ +-This test checks completion related to function values. +- +--- flags -- +--ignore_extra_diags +- +--- func_value.go -- +-package funcvalue +- +-func fooFunc() int { //@item(fvFooFunc, "fooFunc", "func() int", "func") +- return 0 +-} +- +-var _ = fooFunc() //@item(fvFooFuncCall, "fooFunc", "func() int", "func") +- +-var fooVar = func() int { //@item(fvFooVar, "fooVar", "func() int", "var") +- return 0 +-} +- +-var _ = fooVar() //@item(fvFooVarCall, "fooVar", "func() int", "var") +- +-type myFunc func() int +- +-var fooType myFunc = fooVar //@item(fvFooType, "fooType", "myFunc", "var") +- +-var _ = fooType() //@item(fvFooTypeCall, "fooType", "func() int", "var") +- +-func _() { +- var f func() int +- f = foo //@complete(" //", fvFooFunc, fvFooType, fvFooVar) +- +- var i int +- i = foo //@complete(" //", fvFooFuncCall, fvFooTypeCall, fvFooVarCall) +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/fuzzy.txt b/gopls/internal/regtest/marker/testdata/completion/fuzzy.txt +--- a/gopls/internal/regtest/marker/testdata/completion/fuzzy.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/fuzzy.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,55 +0,0 @@ +-This test exercises fuzzy completion matching. +- +--- flags -- +--ignore_extra_diags +- +--- go.mod -- +-module golang.org/lsptests +- +-go 1.18 +- +--- fuzzy/fuzzy.go -- +-package fuzzy +- +-func _() { +- var a struct { +- fabar int +- fooBar string +- } +- +- a.fabar //@item(fuzzFabarField, "a.fabar", "int", "field") +- a.fooBar //@item(fuzzFooBarField, "a.fooBar", "string", "field") +- +- afa //@complete(" //", fuzzFabarField, fuzzFooBarField) +- afb //@complete(" //", fuzzFooBarField, fuzzFabarField) +- +- fab //@complete(" //", fuzzFabarField) +- +- var myString string +- myString = af //@complete(" //", fuzzFooBarField, fuzzFabarField) +- +- var b struct { +- c struct { +- d struct { +- e struct { +- abc string +- } +- abc float32 +- } +- abc bool +- } +- abc int +- } +- +- b.abc //@item(fuzzABCInt, "b.abc", "int", "field") +- b.c.abc //@item(fuzzABCbool, "b.c.abc", "bool", "field") +- b.c.d.abc //@item(fuzzABCfloat, "b.c.d.abc", "float32", "field") +- b.c.d.e.abc //@item(fuzzABCstring, "b.c.d.e.abc", "string", "field") - -- type aliasImpl = myImpl -- var aliasParams func(aliasImpl) aliasImpl -- aliasParams = f //@snippet(" //", litFunc, "func(ai aliasImpl) aliasImpl {$0\\}") +- // in depth order by default +- abc //@complete(" //", fuzzABCInt, fuzzABCbool, fuzzABCfloat) - -- const two = 2 -- var builtinTypes func([]int, [two]bool, map[string]string, struct{ i int }, interface{ foo() }, <-chan int) -- builtinTypes = f //@snippet(" //", litFunc, "func(i1 []int, b [two]bool, m map[string]string, s struct{ i int \\}, i2 interface{ foo() \\}, c <-chan int) {$0\\}") +- // deep candidate that matches expected type should still ranked first +- var s string +- s = abc //@complete(" //", fuzzABCstring, fuzzABCInt, fuzzABCbool) +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/index.txt b/gopls/internal/regtest/marker/testdata/completion/index.txt +--- a/gopls/internal/regtest/marker/testdata/completion/index.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/index.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,36 +0,0 @@ +-This test checks completion related to index expressions. - -- var _ func(ast.Node) = f //@snippet(" //", litFunc, "func(n ast.Node) {$0\\}") -- var _ func(error) = f //@snippet(" //", litFunc, "func(err error) {$0\\}") -- var _ func(context.Context) = f //@snippet(" //", litFunc, "func(ctx context.Context) {$0\\}") +--- flags -- +--ignore_extra_diags - -- type context struct {} -- var _ func(context) = f //@snippet(" //", litFunc, "func(ctx context) {$0\\}") +--- settings.json -- +-{ +- "completeUnimported": false -} - +--- index.go -- +-package index +- -func _() { -- float64() //@item(litFloat64, "float64()", "float64", "var") +- var ( +- aa = "123" //@item(indexAA, "aa", "string", "var") +- ab = 123 //@item(indexAB, "ab", "int", "var") +- ) - -- // don't complete to "&float64()" -- var _ *float64 = float64 //@complete(" //") +- var foo [1]int +- foo[a] //@complete("]", indexAB, indexAA) +- foo[:a] //@complete("]", indexAB, indexAA) +- a[:a] //@complete("[", indexAA, indexAB) +- a[a] //@complete("[", indexAA, indexAB) - -- var f float64 -- f = fl //@complete(" //", litFloat64),snippet(" //", litFloat64, "float64($0)") +- var bar map[string]int +- bar[a] //@complete("]", indexAA, indexAB) - -- type myInt int -- myInt() //@item(litMyInt, "myInt()", "", "var") +- type myMap map[string]int +- var baz myMap +- baz[a] //@complete("]", indexAA, indexAB) - -- var mi myInt -- mi = my //@snippet(" //", litMyInt, "myInt($0)") +- type myInt int +- var mi myInt //@item(indexMyInt, "mi", "myInt", "var") +- foo[m] //@snippet("]", indexMyInt, "mi") -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/interfacerank.txt b/gopls/internal/regtest/marker/testdata/completion/interfacerank.txt +--- a/gopls/internal/regtest/marker/testdata/completion/interfacerank.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/interfacerank.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,36 +0,0 @@ +-This test checks that completion ranking accounts for interface assignability. - --func _() { -- type ptrStruct struct { -- p *ptrStruct -- } +--- flags -- +--ignore_extra_diags - -- ptrStruct{} //@item(litPtrStruct, "ptrStruct{}", "", "var") +--- settings.json -- +-{ +- "completeUnimported": false, +- "deepCompletion": false +-} - -- ptrStruct{ -- p: &ptrSt, //@rank(",", litPtrStruct) -- } +--- p.go -- - -- &ptrStruct{} //@item(litPtrStructPtr, "&ptrStruct{}", "", "var") +-package interfacerank - -- &ptrStruct{ -- p: ptrSt, //@rank(",", litPtrStructPtr) -- } +-type foo interface { +- foo() -} - --func _() { -- f := func(...[]int) {} -- f() //@snippet(")", litIntSlice, "[]int{$0\\}") --} +-type fooImpl int +- +-func (*fooImpl) foo() {} - +-func wantsFoo(foo) {} - -func _() { -- // don't complete to "untyped int()" -- []int{}[untyped] //@complete("] //") +- var ( +- aa string //@item(irAA, "aa", "string", "var") +- ab *fooImpl //@item(irAB, "ab", "*fooImpl", "var") +- ) +- +- wantsFoo(a) //@complete(")", irAB, irAA) +- +- var ac fooImpl //@item(irAC, "ac", "fooImpl", "var") +- wantsFoo(&a) //@complete(")", irAC, irAA, irAB) -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/issue56505.txt b/gopls/internal/regtest/marker/testdata/completion/issue56505.txt +--- a/gopls/internal/regtest/marker/testdata/completion/issue56505.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/issue56505.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-Test for golang/go#56505: completion on variables of type *error should not +-panic. - --type Tree[T any] struct{} +--- flags -- +--ignore_extra_diags - --func (tree Tree[T]) Do(f func(s T)) {} +--- issue.go -- +-package issues - -func _() { -- var t Tree[string] -- t.Do(fun) //@complete(")", litFunc), snippet(")", litFunc, "func(s string) {$0\\}") +- var e *error +- e.x //@complete(" //") -} diff -urN a/gopls/internal/regtest/marker/testdata/completion/issue59096.txt b/gopls/internal/regtest/marker/testdata/completion/issue59096.txt --- a/gopls/internal/regtest/marker/testdata/completion/issue59096.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/completion/issue59096.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/completion/issue59096.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -This test exercises the panic in golang/go#59096: completing at a syntactic -type-assert expression was panicking because gopls was translating it into @@ -121671,7 +120279,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/completion/issue59096.txt b/g -const B = 0 diff -urN a/gopls/internal/regtest/marker/testdata/completion/issue60545.txt b/gopls/internal/regtest/marker/testdata/completion/issue60545.txt --- a/gopls/internal/regtest/marker/testdata/completion/issue60545.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/completion/issue60545.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/completion/issue60545.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -This test checks that unimported completion is case-insensitive. - @@ -121703,7 +120311,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/completion/issue60545.txt b/g -} diff -urN a/gopls/internal/regtest/marker/testdata/completion/issue62141.txt b/gopls/internal/regtest/marker/testdata/completion/issue62141.txt --- a/gopls/internal/regtest/marker/testdata/completion/issue62141.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/completion/issue62141.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/completion/issue62141.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -This test checks that we don't suggest completion to an untyped conversion such -as "untyped float(abcdef)". @@ -121746,7 +120354,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/completion/issue62141.txt b/g - diff -urN a/gopls/internal/regtest/marker/testdata/completion/issue62560.txt b/gopls/internal/regtest/marker/testdata/completion/issue62560.txt --- a/gopls/internal/regtest/marker/testdata/completion/issue62560.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/completion/issue62560.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/completion/issue62560.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -This test verifies that completion of package members in unimported packages -reflects their fuzzy score, even when those members are present in the @@ -121769,7 +120377,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/completion/issue62560.txt b/g -import _ "encoding/json" diff -urN a/gopls/internal/regtest/marker/testdata/completion/issue62676.txt b/gopls/internal/regtest/marker/testdata/completion/issue62676.txt --- a/gopls/internal/regtest/marker/testdata/completion/issue62676.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/completion/issue62676.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/completion/issue62676.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ -This test verifies that unimported completion respects the usePlaceholders setting. - @@ -121834,9 +120442,238 @@ diff -urN a/gopls/internal/regtest/marker/testdata/completion/issue62676.txt b/g - errors.New //@acceptcompletion(re"New()", "New", new) -} - +diff -urN a/gopls/internal/regtest/marker/testdata/completion/keywords.txt b/gopls/internal/regtest/marker/testdata/completion/keywords.txt +--- a/gopls/internal/regtest/marker/testdata/completion/keywords.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/keywords.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,166 +0,0 @@ +-This test checks completion of Go keywords. +- +--- flags -- +--ignore_extra_diags +--filter_keywords=false +- +--- settings.json -- +-{ +- "completeUnimported": false, +- "matcher": "caseInsensitive", +- "experimentalPostfixCompletions": false +-} +- +--- keywords.go -- +-package keywords +- +-//@rank("", type),rank("", func),rank("", var),rank("", const),rank("", import) +- +-func _() { +- var test int //@rank(" //", int, interface) +- var tChan chan int +- var _ m //@complete(" //", map) +- var _ f //@complete(" //", func) +- var _ c //@complete(" //", chan) +- +- var _ str //@rank(" //", string, struct) +- +- type _ int //@rank(" //", interface, int) +- +- type _ str //@rank(" //", struct, string) +- +- switch test { +- case 1: // TODO: trying to complete case here will break because the parser won't return *ast.Ident +- b //@complete(" //", break) +- case 2: +- f //@complete(" //", fallthrough, for) +- r //@complete(" //", return) +- d //@complete(" //", default, defer) +- c //@complete(" //", case, const) +- } +- +- switch test.(type) { +- case fo: //@complete(":") +- case int: +- b //@complete(" //", break) +- case int32: +- f //@complete(" //", for) +- d //@complete(" //", default, defer) +- r //@complete(" //", return) +- c //@complete(" //", case, const) +- } +- +- select { +- case <-tChan: +- b //@complete(" //", break) +- c //@complete(" //", case, const) +- } +- +- for index := 0; index < test; index++ { +- c //@complete(" //", const, continue) +- b //@complete(" //", break) +- } +- +- for range []int{} { +- c //@complete(" //", const, continue) +- b //@complete(" //", break) +- } +- +- // Test function level keywords +- +- //Using 2 characters to test because map output order is random +- sw //@complete(" //", switch) +- se //@complete(" //", select) +- +- f //@complete(" //", for) +- d //@complete(" //", defer) +- g //@rank(" //", go),rank(" //", goto) +- r //@complete(" //", return) +- i //@complete(" //", if) +- e //@complete(" //", else) +- v //@complete(" //", var) +- c //@complete(" //", const) +- +- for i := r //@complete(" //", range) +-} +- +-/* package */ //@item(package, "package", "", "keyword") +-/* import */ //@item(import, "import", "", "keyword") +-/* func */ //@item(func, "func", "", "keyword") +-/* type */ //@item(type, "type", "", "keyword") +-/* var */ //@item(var, "var", "", "keyword") +-/* const */ //@item(const, "const", "", "keyword") +-/* break */ //@item(break, "break", "", "keyword") +-/* default */ //@item(default, "default", "", "keyword") +-/* case */ //@item(case, "case", "", "keyword") +-/* defer */ //@item(defer, "defer", "", "keyword") +-/* go */ //@item(go, "go", "", "keyword") +-/* for */ //@item(for, "for", "", "keyword") +-/* if */ //@item(if, "if", "", "keyword") +-/* else */ //@item(else, "else", "", "keyword") +-/* switch */ //@item(switch, "switch", "", "keyword") +-/* select */ //@item(select, "select", "", "keyword") +-/* fallthrough */ //@item(fallthrough, "fallthrough", "", "keyword") +-/* continue */ //@item(continue, "continue", "", "keyword") +-/* return */ //@item(return, "return", "", "keyword") +-/* goto */ //@item(goto, "goto", "", "keyword") +-/* struct */ //@item(struct, "struct", "", "keyword") +-/* interface */ //@item(interface, "interface", "", "keyword") +-/* map */ //@item(map, "map", "", "keyword") +-/* chan */ //@item(chan, "chan", "", "keyword") +-/* range */ //@item(range, "range", "", "keyword") +-/* string */ //@item(string, "string", "", "type") +-/* int */ //@item(int, "int", "", "type") +- +--- accidental_keywords.go -- +-package keywords +- +-// non-matching candidate - shouldn't show up as completion +-var apple = "apple" +- +-func _() { +- foo.bar() // insert some extra statements to exercise our AST surgery +- variance := 123 //@item(kwVariance, "variance", "int", "var") +- foo.bar() +- println(var) //@complete(")", kwVariance) +-} +- +-func _() { +- foo.bar() +- var s struct { variance int } //@item(kwVarianceField, "variance", "int", "field") +- foo.bar() +- s.var //@complete(" //", kwVarianceField) +-} +- +-func _() { +- channel := 123 //@item(kwChannel, "channel", "int", "var") +- chan //@complete(" //", kwChannel) +- foo.bar() +-} +- +-func _() { +- foo.bar() +- var typeName string //@item(kwTypeName, "typeName", "string", "var") +- foo.bar() +- type //@complete(" //", kwTypeName) +-} +--- empty_select.go -- +-package keywords +- +-func _() { +- select { +- c //@complete(" //", case) +- } +-} +--- empty_switch.go -- +-package keywords +- +-func _() { +- switch { +- //@complete("", case, default) +- } +- +- switch test.(type) { +- d //@complete(" //", default) +- } +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/labels.txt b/gopls/internal/regtest/marker/testdata/completion/labels.txt +--- a/gopls/internal/regtest/marker/testdata/completion/labels.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/labels.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,55 +0,0 @@ +-This test checks completion of labels. +- +--- flags -- +--ignore_extra_diags +- +--- labels.go -- +-package labels +- +-func _() { +- goto F //@complete(" //", label1, label5) +- +-Foo1: //@item(label1, "Foo1", "label", "const") +- for a, b := range []int{} { +- Foo2: //@item(label2, "Foo2", "label", "const") +- switch { +- case true: +- break F //@complete(" //", label2, label1) +- +- continue F //@complete(" //", label1) +- +- { +- FooUnjumpable: +- } +- +- goto F //@complete(" //", label1, label2, label4, label5) +- +- func() { +- goto F //@complete(" //", label3) +- +- break F //@complete(" //") +- +- continue F //@complete(" //") +- +- Foo3: //@item(label3, "Foo3", "label", "const") +- }() +- } +- +- Foo4: //@item(label4, "Foo4", "label", "const") +- switch interface{}(a).(type) { +- case int: +- break F //@complete(" //", label4, label1) +- } +- } +- +- break F //@complete(" //") +- +- continue F //@complete(" //") +- +-Foo5: //@item(label5, "Foo5", "label", "const") +- for { +- break F //@complete(" //", label5) +- } +- +- return +-} diff -urN a/gopls/internal/regtest/marker/testdata/completion/lit.txt b/gopls/internal/regtest/marker/testdata/completion/lit.txt --- a/gopls/internal/regtest/marker/testdata/completion/lit.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/completion/lit.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/completion/lit.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ - --- flags -- @@ -121887,10 +120724,736 @@ diff -urN a/gopls/internal/regtest/marker/testdata/completion/lit.txt b/gopls/in - http.Handle("", http.HandlerFunc()) //@snippet("))", litFunc, "func(w http.ResponseWriter, r *http.Request) {$0\\}") - http.Handle("", h) //@snippet(")", handlerFunc, "http.HandlerFunc($0)") -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/maps.txt b/gopls/internal/regtest/marker/testdata/completion/maps.txt +--- a/gopls/internal/regtest/marker/testdata/completion/maps.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/maps.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,29 +0,0 @@ +-This test checks completion of map keys and values. +- +--- flags -- +--ignore_extra_diags +- +--- settings.json -- +-{ +- "completeUnimported": false +-} +- +--- maps.go -- +-package maps +- +-func _() { +- var aVar int //@item(mapVar, "aVar", "int", "var") +- +- // not comparabale +- type aSlice []int //@item(mapSliceType, "aSlice", "[]int", "type") +- +- *aSlice //@item(mapSliceTypePtr, "*aSlice", "[]int", "type") +- +- // comparable +- type aStruct struct{} //@item(mapStructType, "aStruct", "struct{...}", "struct") +- +- map[]a{} //@complete("]", mapSliceType, mapStructType),snippet("]", mapSliceType, "*aSlice") +- +- map[a]a{} //@complete("]", mapSliceType, mapStructType) +- map[a]a{} //@complete("{", mapSliceType, mapStructType) +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/multi_return.txt b/gopls/internal/regtest/marker/testdata/completion/multi_return.txt +--- a/gopls/internal/regtest/marker/testdata/completion/multi_return.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/multi_return.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,55 +0,0 @@ +-This test checks various ranking of completion results related to functions +-with multiple return values. +- +--- flags -- +--ignore_extra_diags +- +--- multireturn.go -- +-package multireturn +- +-func f0() {} //@item(multiF0, "f0", "func()", "func") +- +-func f1(int) int { return 0 } //@item(multiF1, "f1", "func(int) int", "func") +- +-func f2(int, int) (int, int) { return 0, 0 } //@item(multiF2, "f2", "func(int, int) (int, int)", "func") +- +-func f2Str(string, string) (string, string) { return "", "" } //@item(multiF2Str, "f2Str", "func(string, string) (string, string)", "func") +- +-func f3(int, int, int) (int, int, int) { return 0, 0, 0 } //@item(multiF3, "f3", "func(int, int, int) (int, int, int)", "func") +- +-func _() { +- _ := f //@rank(" //", multiF1, multiF2) +- +- _, _ := f //@rank(" //", multiF2, multiF0),rank(" //", multiF1, multiF0) +- +- _, _ := _, f //@rank(" //", multiF1, multiF2),rank(" //", multiF1, multiF0) +- +- _, _ := f, abc //@rank(", abc", multiF1, multiF2) +- +- f1() //@rank(")", multiF1, multiF0) +- f1(f) //@rank(")", multiF1, multiF2) +- f2(f) //@rank(")", multiF2, multiF3),rank(")", multiF1, multiF3) +- f2(1, f) //@rank(")", multiF1, multiF2),rank(")", multiF1, multiF0) +- f2(1, ) //@rank(")", multiF1, multiF2),rank(")", multiF1, multiF0) +- f2Str() //@rank(")", multiF2Str, multiF2) +- +- var i int +- i, _ := f //@rank(" //", multiF2, multiF2Str) +- +- var s string +- _, s := f //@rank(" //", multiF2Str, multiF2) +- +- banana, s = f //@rank(" //", multiF2, multiF3) +- +- var variadic func(int, ...int) +- variadic() //@rank(")", multiF1, multiF0),rank(")", multiF2, multiF0),rank(")", multiF3, multiF0) +-} +- +-func _() { +- var baz func(...interface{}) +- +- var otterNap func() (int, int) //@item(multiTwo, "otterNap", "func() (int, int)", "var") +- var one int //@item(multiOne, "one", "int", "var") +- +- baz(on) //@rank(")", multiOne, multiTwo) +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/nested_complit.txt b/gopls/internal/regtest/marker/testdata/completion/nested_complit.txt +--- a/gopls/internal/regtest/marker/testdata/completion/nested_complit.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/nested_complit.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,23 +0,0 @@ +-This test checks completion of nested composite literals; +- +-TODO(rfindley): investigate an un-skip the disabled test below. +- +--- flags -- +--ignore_extra_diags +- +--- nested_complit.go -- +-package nested_complit +- +-type ncFoo struct {} //@item(structNCFoo, "ncFoo", "struct{...}", "struct") +- +-type ncBar struct { //@item(structNCBar, "ncBar", "struct{...}", "struct") +- baz []ncFoo +-} +- +-func _() { +- []ncFoo{} //@item(litNCFoo, "[]ncFoo{}", "", "var") +- _ := ncBar{ +- // disabled - see issue #54822 +- baz: [] // complete(" //", structNCFoo, structNCBar) +- } +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/postfix.txt b/gopls/internal/regtest/marker/testdata/completion/postfix.txt +--- a/gopls/internal/regtest/marker/testdata/completion/postfix.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/postfix.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,51 +0,0 @@ +-These tests check that postfix completions do and do not show up in certain +-cases. Tests for the postfix completion contents are implemented as ad-hoc +-regtests. +- +--- flags -- +--ignore_extra_diags +- +--- go.mod -- +-module golang.org/lsptests/snippets +- +-go 1.18 +- +--- postfix.go -- +-package snippets +- +-func _() { +- var foo []int +- foo.append //@rank(" //", postfixAppend) +- +- []int{}.append //@complete(" //") +- +- []int{}.last //@complete(" //") +- +- /* copy! */ //@item(postfixCopy, "copy!", "duplicate slice", "snippet") +- +- foo.copy //@rank(" //", postfixCopy) +- +- var s struct{ i []int } +- s.i.copy //@rank(" //", postfixCopy) +- +- var _ []int = s.i.copy //@complete(" //") +- +- var blah func() []int +- blah().append //@complete(" //") +-} +- +-func _() { +- /* append! */ //@item(postfixAppend, "append!", "append and re-assign slice", "snippet") +- /* last! */ //@item(postfixLast, "last!", "s[len(s)-1]", "snippet") +- /* print! */ //@item(postfixPrint, "print!", "print to stdout", "snippet") +- /* range! */ //@item(postfixRange, "range!", "range over slice", "snippet") +- /* reverse! */ //@item(postfixReverse, "reverse!", "reverse slice", "snippet") +- /* sort! */ //@item(postfixSort, "sort!", "sort.Slice()", "snippet") +- /* var! */ //@item(postfixVar, "var!", "assign to variable", "snippet") +- /* ifnotnil! */ //@item(postfixIfNotNil, "ifnotnil!", "if expr != nil", "snippet") +- +- var foo []int +- foo. //@complete(" //", postfixAppend, postfixCopy, postfixIfNotNil, postfixLast, postfixPrint, postfixRange, postfixReverse, postfixSort, postfixVar) +- +- foo = nil +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/printf.txt b/gopls/internal/regtest/marker/testdata/completion/printf.txt +--- a/gopls/internal/regtest/marker/testdata/completion/printf.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/printf.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,39 +0,0 @@ +-This test checks various ranking of completion results related to printf. +- +--- flags -- +--ignore_extra_diags +- +--- printf.go -- +-package printf +- +-import "fmt" +- +-func myPrintf(string, ...interface{}) {} +- +-func _() { +- var ( +- aInt int //@item(printfInt, "aInt", "int", "var") +- aFloat float64 //@item(printfFloat, "aFloat", "float64", "var") +- aString string //@item(printfString, "aString", "string", "var") +- aBytes []byte //@item(printfBytes, "aBytes", "[]byte", "var") +- aStringer fmt.Stringer //@item(printfStringer, "aStringer", "fmt.Stringer", "var") +- aError error //@item(printfError, "aError", "error", "var") +- aBool bool //@item(printfBool, "aBool", "bool", "var") +- ) +- +- myPrintf("%d", a) //@rank(")", printfInt, printfFloat) +- myPrintf("%s", a) //@rank(")", printfString, printfInt),rank(")", printfBytes, printfInt),rank(")", printfStringer, printfInt),rank(")", printfError, printfInt) +- myPrintf("%w", a) //@rank(")", printfError, printfInt) +- myPrintf("%x %[1]b", a) //@rank(")", printfInt, printfString) +- +- fmt.Printf("%t", a) //@rank(")", printfBool, printfInt) +- +- fmt.Fprintf(nil, "%f", a) //@rank(")", printfFloat, printfInt) +- +- fmt.Sprintf("%[2]q %[1]*.[3]*[4]f", +- a, //@rank(",", printfInt, printfFloat) +- a, //@rank(",", printfString, printfFloat) +- a, //@rank(",", printfInt, printfFloat) +- a, //@rank(",", printfFloat, printfInt) +- ) +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/rank.txt b/gopls/internal/regtest/marker/testdata/completion/rank.txt +--- a/gopls/internal/regtest/marker/testdata/completion/rank.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/rank.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,212 +0,0 @@ +-This test checks various ranking of completion results. +- +--- flags -- +--ignore_extra_diags +- +--- settings.json -- +-{ +- "completeUnimported": false, +- "deepCompletion": false +-} +- +--- go.mod -- +-module golang.org/lsptests/rank +- +-go 1.18 +- +--- struct/struct_rank.go -- +-package struct_rank +- +-type foo struct { +- c int //@item(c_rank, "c", "int", "field") +- b int //@item(b_rank, "b", "int", "field") +- a int //@item(a_rank, "a", "int", "field") +-} +- +-func f() { +- foo := foo{} //@rank("}", c_rank, b_rank, a_rank) +-} +- +--- assign_rank.go -- +-package rank +- +-// Literal completion results. +-/* int() */ //@item(int, "int()", "int", "var") +-/* string() */ //@item(string, "string()", "string", "var") +- +-var ( +- apple int = 3 //@item(apple, "apple", "int", "var") +- pear string = "hello" //@item(pear, "pear", "string", "var") +-) +- +-func _() { +- orange := 1 //@item(orange, "orange", "int", "var") +- grape := "hello" //@item(grape, "grape", "string", "var") +- orange, grape = 2, "hello" //@complete(" \"", grape, pear, string, orange, apple) +-} +- +-func _() { +- var pineapple int //@item(pineapple, "pineapple", "int", "var") +- pineapple = 1 //@complete(" 1", pineapple, apple, int, pear) +- +- y := //@complete(" /", pineapple, apple, pear) +-} +- +--- binexpr_rank.go -- +-package rank +- +-func _() { +- _ = 5 + ; //@complete(" ;", apple, pear) +- y := + 5; //@complete(" +", apple, pear) +- +- if 6 == {} //@complete(" {", apple, pear) +-} +- +--- boolexpr_rank.go -- +-package rank +- +-func _() { +- someRandomBoolFunc := func() bool { //@item(boolExprFunc, "someRandomBoolFunc", "func() bool", "var") +- return true +- } +- +- var foo, bar int //@item(boolExprBar, "bar", "int", "var") +- if foo == 123 && b { //@rank(" {", boolExprBar, boolExprFunc) +- } +-} +- +--- convert_rank.go -- +-package rank +- +-import "time" +- +-// Copied from the old builtins.go, which has been ported to the new marker tests. +-/* complex(r float64, i float64) */ //@item(complex, "complex", "func(r float64, i float64) complex128", "func") +- +-func _() { +- type strList []string +- wantsStrList := func(strList) {} +- +- var ( +- convA string //@item(convertA, "convA", "string", "var") +- convB []string //@item(convertB, "convB", "[]string", "var") +- ) +- wantsStrList(strList(conv)) //@complete("))", convertB, convertA) +-} +- +-func _() { +- type myInt int +- +- const ( +- convC = "hi" //@item(convertC, "convC", "string", "const") +- convD = 123 //@item(convertD, "convD", "int", "const") +- convE int = 123 //@item(convertE, "convE", "int", "const") +- convF string = "there" //@item(convertF, "convF", "string", "const") +- convG myInt = 123 //@item(convertG, "convG", "myInt", "const") +- ) +- +- var foo int +- foo = conv //@rank(" //", convertE, convertD) +- +- var mi myInt +- mi = conv //@rank(" //", convertG, convertD, convertE) +- mi + conv //@rank(" //", convertG, convertD, convertE) +- +- 1 + conv //@rank(" //", convertD, convertC),rank(" //", convertE, convertC),rank(" //", convertG, convertC) +- +- type myString string +- var ms myString +- ms = conv //@rank(" //", convertC, convertF) +- +- type myUint uint32 +- var mu myUint +- mu = conv //@rank(" //", convertD, convertE) +- +- // don't downrank constants when assigning to interface{} +- var _ interface{} = c //@rank(" //", convertD, complex) +- +- var _ time.Duration = conv //@rank(" //", convertD, convertE),snippet(" //", convertE, "time.Duration(convE)") +- +- var convP myInt //@item(convertP, "convP", "myInt", "var") +- var _ *int = conv //@snippet(" //", convertP, "(*int)(&convP)") +- +- var ff float64 //@item(convertFloat, "ff", "float64", "var") +- f == convD //@snippet(" =", convertFloat, "ff") +-} +- +--- switch_rank.go -- +-package rank +- +-import "time" +- +-func _() { +- switch pear { +- case _: //@rank("_", pear, apple) +- } +- +- time.Monday //@item(timeMonday, "time.Monday", "time.Weekday", "const"),item(monday ,"Monday", "time.Weekday", "const") +- time.Friday //@item(timeFriday, "time.Friday", "time.Weekday", "const"),item(friday ,"Friday", "time.Weekday", "const") +- +- now := time.Now() +- now.Weekday //@item(nowWeekday, "now.Weekday", "func() time.Weekday", "method") +- +- then := time.Now() +- then.Weekday //@item(thenWeekday, "then.Weekday", "func() time.Weekday", "method") +- +- switch time.Weekday(0) { +- case time.Monday, time.Tuesday: +- case time.Wednesday, time.Thursday: +- case time.Saturday, time.Sunday: +- // TODO: these tests were disabled because they require deep completion +- // (which would break other tests) +- case t: // rank(":", timeFriday, timeMonday) +- case time.: //@rank(":", friday, monday) +- +- case now.Weekday(): +- case week: // rank(":", thenWeekday, nowWeekday) +- } +-} +- +--- type_assert_rank.go -- +-package rank +- +-func _() { +- type flower int //@item(flower, "flower", "int", "type") +- var fig string //@item(fig, "fig", "string", "var") +- +- _ = interface{}(nil).(f) //@complete(") //", flower) +-} +- +--- type_switch_rank.go -- +-package rank +- +-import ( +- "fmt" +- "go/ast" +-) +- +-func _() { +- type basket int //@item(basket, "basket", "int", "type") +- var banana string //@item(banana, "banana", "string", "var") +- +- switch interface{}(pear).(type) { +- case b: //@complete(":", basket) +- b //@complete(" //", banana, basket) +- } +- +- Ident //@item(astIdent, "Ident", "struct{...}", "struct") +- IfStmt //@item(astIfStmt, "IfStmt", "struct{...}", "struct") +- +- switch ast.Node(nil).(type) { +- case *ast.Ident: +- case *ast.I: //@rank(":", astIfStmt, astIdent) +- } +- +- Stringer //@item(fmtStringer, "Stringer", "interface{...}", "interface") +- GoStringer //@item(fmtGoStringer, "GoStringer", "interface{...}", "interface") +- +- switch interface{}(nil).(type) { +- case fmt.Stringer: //@rank(":", fmtStringer, fmtGoStringer) +- } +-} +- +diff -urN a/gopls/internal/regtest/marker/testdata/completion/snippet_placeholder.txt b/gopls/internal/regtest/marker/testdata/completion/snippet_placeholder.txt +--- a/gopls/internal/regtest/marker/testdata/completion/snippet_placeholder.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/snippet_placeholder.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,83 +0,0 @@ +-This test checks basic completion snippet support, using placeholders. +- +-Unlike the old marker tests, the new marker tests assume static configuration +-(as defined by settings.json), and therefore there is duplication between this +-test and snippet.txt. This is a price we pay so that we don't have to mutate +-the server during testing. +- +--- flags -- +--ignore_extra_diags +- +--- settings.json -- +-{ +- "usePlaceholders": true +-} +- +--- go.mod -- +-module golang.org/lsptests/snippet +- +--- snippet.go -- +-package snippets +- +-// Pre-set this marker, as we don't have a "source" for it in this package. +-/* Error() */ //@item(Error, "Error", "func() string", "method") +- +-type AliasType = int //@item(sigAliasType, "AliasType", "AliasType", "type") +- +-func foo(i int, b bool) {} //@item(snipFoo, "foo", "func(i int, b bool)", "func") +-func bar(fn func()) func() {} //@item(snipBar, "bar", "func(fn func())", "func") +-func baz(at AliasType, b bool) {} //@item(snipBaz, "baz", "func(at AliasType, b bool)", "func") +- +-type Foo struct { +- Bar int //@item(snipFieldBar, "Bar", "int", "field") +- Func func(at AliasType) error //@item(snipFieldFunc, "Func", "func(at AliasType) error", "field") +-} +- +-func (Foo) Baz() func() {} //@item(snipMethodBaz, "Baz", "func() func()", "method") +-func (Foo) BazBar() func() {} //@item(snipMethodBazBar, "BazBar", "func() func()", "method") +-func (Foo) BazBaz(at AliasType) func() {} //@item(snipMethodBazBaz, "BazBaz", "func(at AliasType) func()", "method") +- +-func _() { +- f //@snippet(" //", snipFoo, "foo(${1:i int}, ${2:b bool})") +- +- bar //@snippet(" //", snipBar, "bar(${1:fn func()})") +- +- baz //@snippet(" //", snipBaz, "baz(${1:at AliasType}, ${2:b bool})") +- baz() //@signature("(", "baz(at AliasType, b bool)", 0) +- +- bar(nil) //@snippet("(", snipBar, "bar") +- bar(ba) //@snippet(")", snipBar, "bar(${1:fn func()})") +- var f Foo +- bar(f.Ba) //@snippet(")", snipMethodBaz, "Baz()") +- (bar)(nil) //@snippet(")", snipBar, "bar(${1:fn func()})") +- (f.Ba)() //@snippet(")", snipMethodBaz, "Baz()") +- +- Foo{ +- B //@snippet(" //", snipFieldBar, "Bar: ${1:int},") +- } +- +- Foo{ +- F //@snippet(" //", snipFieldFunc, "Func: ${1:func(at AliasType) error},") +- } +- +- Foo{B} //@snippet("}", snipFieldBar, "Bar: ${1:int}") +- Foo{} //@snippet("}", snipFieldBar, "Bar: ${1:int}") +- +- Foo{Foo{}.B} //@snippet("} ", snipFieldBar, "Bar") +- +- var err error +- err.Error() //@snippet("E", Error, "Error()") +- f.Baz() //@snippet("B", snipMethodBaz, "Baz()") +- +- f.Baz() //@snippet("(", snipMethodBazBar, "BazBar") +- +- f.Baz() //@snippet("B", snipMethodBazBaz, "BazBaz(${1:at AliasType})") +-} +- +-func _() { +- type bar struct { +- a int +- b float64 //@item(snipBarB, "b", "field") +- } +- bar{b} //@snippet("}", snipBarB, "b: ${1:float64}") +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/snippet.txt b/gopls/internal/regtest/marker/testdata/completion/snippet.txt +--- a/gopls/internal/regtest/marker/testdata/completion/snippet.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/snippet.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,77 +0,0 @@ +-This test checks basic completion snippet support. +- +--- flags -- +--ignore_extra_diags +- +--- go.mod -- +-module golang.org/lsptests/snippet +- +--- snippet.go -- +-package snippets +- +-// Pre-set this marker, as we don't have a "source" for it in this package. +-// The comment is used to create a synthetic completion item. +-// +-// TODO(rfindley): allow completion markers to refer to ad-hoc items inline, +-// without this trick. +-/* Error() */ //@item(Error, "Error", "func() string", "method") +- +-type AliasType = int //@item(sigAliasType, "AliasType", "AliasType", "type") +- +-func foo(i int, b bool) {} //@item(snipFoo, "foo", "func(i int, b bool)", "func") +-func bar(fn func()) func() {} //@item(snipBar, "bar", "func(fn func())", "func") +-func baz(at AliasType, b bool) {} //@item(snipBaz, "baz", "func(at AliasType, b bool)", "func") +- +-type Foo struct { +- Bar int //@item(snipFieldBar, "Bar", "int", "field") +- Func func(at AliasType) error //@item(snipFieldFunc, "Func", "func(at AliasType) error", "field") +-} +- +-func (Foo) Baz() func() {} //@item(snipMethodBaz, "Baz", "func() func()", "method") +-func (Foo) BazBar() func() {} //@item(snipMethodBazBar, "BazBar", "func() func()", "method") +-func (Foo) BazBaz(at AliasType) func() {} //@item(snipMethodBazBaz, "BazBaz", "func(at AliasType) func()", "method") +- +-func _() { +- f //@snippet(" //", snipFoo, "foo(${1:})") +- +- bar //@snippet(" //", snipBar, "bar(${1:})") +- +- baz //@snippet(" //", snipBaz, "baz(${1:})") +- baz() //@signature("(", "baz(at AliasType, b bool)", 0) +- +- bar(nil) //@snippet("(", snipBar, "bar") +- bar(ba) //@snippet(")", snipBar, "bar(${1:})") +- var f Foo +- bar(f.Ba) //@snippet(")", snipMethodBaz, "Baz()") +- (bar)(nil) //@snippet(")", snipBar, "bar(${1:})") +- (f.Ba)() //@snippet(")", snipMethodBaz, "Baz()") +- +- Foo{ +- B //@snippet(" //", snipFieldBar, "Bar: ${1:},") +- } +- +- Foo{ +- F //@snippet(" //", snipFieldFunc, "Func: ${1:},") +- } +- +- Foo{B} //@snippet("}", snipFieldBar, "Bar: ${1:}") +- Foo{} //@snippet("}", snipFieldBar, "Bar: ${1:}") +- +- Foo{Foo{}.B} //@snippet("} ", snipFieldBar, "Bar") +- +- var err error +- err.Error() //@snippet("E", Error, "Error()") +- f.Baz() //@snippet("B", snipMethodBaz, "Baz()") +- +- f.Baz() //@snippet("(", snipMethodBazBar, "BazBar") +- +- f.Baz() //@snippet("B", snipMethodBazBaz, "BazBaz(${1:})") +-} +- +-func _() { +- type bar struct { +- a int +- b float64 //@item(snipBarB, "b", "float64") +- } +- bar{b} //@snippet("}", snipBarB, "b: ${1:}") +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/statements.txt b/gopls/internal/regtest/marker/testdata/completion/statements.txt +--- a/gopls/internal/regtest/marker/testdata/completion/statements.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/statements.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,121 +0,0 @@ +-This test exercises completion around various statements. +- +--- flags -- +--ignore_extra_diags +- +--- settings.json -- +-{ +- "usePlaceholders": true +-} +- +--- go.mod -- +-module golang.org/lsptests/statements +- +--- append.go -- +-package statements +- +-func _() { +- type mySlice []int +- +- var ( +- abc []int //@item(stmtABC, "abc", "[]int", "var") +- abcdef mySlice //@item(stmtABCDEF, "abcdef", "mySlice", "var") +- ) +- +- /* abcdef = append(abcdef, ) */ //@item(stmtABCDEFAssignAppend, "abcdef = append(abcdef, )", "", "func") +- +- // don't offer "abc = append(abc, )" because "abc" isn't necessarily +- // better than "abcdef". +- abc //@complete(" //", stmtABC, stmtABCDEF) +- +- abcdef //@complete(" //", stmtABCDEF, stmtABCDEFAssignAppend) +- +- /* append(abc, ) */ //@item(stmtABCAppend, "append(abc, )", "", "func") +- +- abc = app //@snippet(" //", stmtABCAppend, "append(abc, ${1:})") +-} +- +-func _() { +- var s struct{ xyz []int } +- +- /* xyz = append(s.xyz, ) */ //@item(stmtXYZAppend, "xyz = append(s.xyz, )", "", "func") +- +- s.x //@snippet(" //", stmtXYZAppend, "xyz = append(s.xyz, ${1:})") +- +- /* s.xyz = append(s.xyz, ) */ //@item(stmtDeepXYZAppend, "s.xyz = append(s.xyz, )", "", "func") +- +- sx //@snippet(" //", stmtDeepXYZAppend, "s.xyz = append(s.xyz, ${1:})") +-} +- +-func _() { +- var foo [][]int +- +- /* append(foo[0], ) */ //@item(stmtFooAppend, "append(foo[0], )", "", "func") +- +- foo[0] = app //@complete(" //", stmtFooAppend),snippet(" //", stmtFooAppend, "append(foo[0], ${1:})") +-} +- +--- if_err_check_return.go -- +-package statements +- +-import ( +- "bytes" +- "io" +- "os" +-) +- +-func one() (int, float32, io.Writer, *int, []int, bytes.Buffer, error) { +- /* if err != nil { return err } */ //@item(stmtOneIfErrReturn, "if err != nil { return err }", "", "") +- /* err != nil { return err } */ //@item(stmtOneErrReturn, "err != nil { return err }", "", "") +- +- _, err := os.Open("foo") +- //@snippet("", stmtOneIfErrReturn, "if err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") +- +- _, err = os.Open("foo") +- i //@snippet(" //", stmtOneIfErrReturn, "if err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") +- +- _, err = os.Open("foo") +- if er //@snippet(" //", stmtOneErrReturn, "err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") +- +- _, err = os.Open("foo") +- if //@snippet(" //", stmtOneIfErrReturn, "if err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") +- +- _, err = os.Open("foo") +- if //@snippet("//", stmtOneIfErrReturn, "if err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") +-} +- +--- if_err_check_return2.go -- +-package statements +- +-import "os" +- +-func two() error { +- var s struct{ err error } +- +- /* if s.err != nil { return s.err } */ //@item(stmtTwoIfErrReturn, "if s.err != nil { return s.err }", "", "") +- +- _, s.err = os.Open("foo") +- //@snippet("", stmtTwoIfErrReturn, "if s.err != nil {\n\treturn ${1:s.err}\n\\}") +-} +- +--- if_err_check_test.go -- +-package statements +- +-import ( +- "os" +- "testing" +-) +- +-func TestErr(t *testing.T) { +- /* if err != nil { t.Fatal(err) } */ //@item(stmtOneIfErrTFatal, "if err != nil { t.Fatal(err) }", "", "") +- +- _, err := os.Open("foo") +- //@snippet("", stmtOneIfErrTFatal, "if err != nil {\n\tt.Fatal(err)\n\\}") +-} +- +-func BenchmarkErr(b *testing.B) { +- /* if err != nil { b.Fatal(err) } */ //@item(stmtOneIfErrBFatal, "if err != nil { b.Fatal(err) }", "", "") +- +- _, err := os.Open("foo") +- //@snippet("", stmtOneIfErrBFatal, "if err != nil {\n\tb.Fatal(err)\n\\}") +-} diff -urN a/gopls/internal/regtest/marker/testdata/completion/testy.txt b/gopls/internal/regtest/marker/testdata/completion/testy.txt --- a/gopls/internal/regtest/marker/testdata/completion/testy.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/completion/testy.txt 1970-01-01 08:00:00 -@@ -1,57 +0,0 @@ ++++ b/gopls/internal/regtest/marker/testdata/completion/testy.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,61 +0,0 @@ - --- flags -- --ignore_extra_diags @@ -121945,12 +121508,156 @@ diff -urN a/gopls/internal/regtest/marker/testdata/completion/testy.txt b/gopls/ -} - -func _() { -- _ = snippets.X(nil) //@signature("nil", "X(_ map[sig.Alias]types.CoolAlias) map[sig.Alias]types.CoolAlias") +- _ = snippets.X(nil) //@signature("nil", "X(_ map[sig.Alias]types.CoolAlias) map[sig.Alias]types.CoolAlias", 0) - var _ sig.Alias -} +- +-func issue63578(err error) { +- err.Error() //@signature(")", "Error()", 0) +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/type_assert.txt b/gopls/internal/regtest/marker/testdata/completion/type_assert.txt +--- a/gopls/internal/regtest/marker/testdata/completion/type_assert.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/type_assert.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,30 +0,0 @@ +-This test checks completion related to type assertions. +- +--- flags -- +--ignore_extra_diags +- +--- type_assert.go -- +-package typeassert +- +-type abc interface { //@item(abcIntf, "abc", "interface{...}", "interface") +- abc() +-} +- +-type abcImpl struct{} //@item(abcImpl, "abcImpl", "struct{...}", "struct") +-func (abcImpl) abc() +- +-type abcPtrImpl struct{} //@item(abcPtrImpl, "abcPtrImpl", "struct{...}", "struct") +-func (*abcPtrImpl) abc() +- +-type abcNotImpl struct{} //@item(abcNotImpl, "abcNotImpl", "struct{...}", "struct") +- +-func _() { +- var a abc +- switch a.(type) { +- case ab: //@complete(":", abcImpl, abcPtrImpl, abcIntf, abcNotImpl) +- case *ab: //@complete(":", abcImpl, abcPtrImpl, abcIntf, abcNotImpl) +- } +- +- a.(ab) //@complete(")", abcImpl, abcPtrImpl, abcIntf, abcNotImpl) +- a.(*ab) //@complete(")", abcImpl, abcPtrImpl, abcIntf, abcNotImpl) +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/type_mods.txt b/gopls/internal/regtest/marker/testdata/completion/type_mods.txt +--- a/gopls/internal/regtest/marker/testdata/completion/type_mods.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/type_mods.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,27 +0,0 @@ +-This test check completion snippets with type modifiers. +- +--- flags -- +--ignore_extra_diags +- +--- typemods.go -- +-package typemods +- +-func fooFunc() func() int { //@item(modFooFunc, "fooFunc", "func() func() int", "func") +- return func() int { +- return 0 +- } +-} +- +-func fooPtr() *int { //@item(modFooPtr, "fooPtr", "func() *int", "func") +- return nil +-} +- +-func _() { +- var _ int = foo //@snippet(" //", modFooFunc, "fooFunc()()"),snippet(" //", modFooPtr, "*fooPtr()") +-} +- +-func _() { +- var m map[int][]chan int //@item(modMapChanPtr, "m", "map[int]chan *int", "var") +- +- var _ int = m //@snippet(" //", modMapChanPtr, "<-m[${1:}][${2:}]") +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/type_params.txt b/gopls/internal/regtest/marker/testdata/completion/type_params.txt +--- a/gopls/internal/regtest/marker/testdata/completion/type_params.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/type_params.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,71 +0,0 @@ +-This test checks various ranking of completion results related to type +-parameters. +- +--- flags -- +--ignore_extra_diags +- +--- type_params.go -- +-package typeparams +- +-// Copied from the old builtins.go, which has been ported to the new marker tests. +-/* string */ //@item(string, "string", "", "type") +-/* float32 */ //@item(float32, "float32", "", "type") +-/* float64 */ //@item(float64, "float64", "", "type") +-/* int */ //@item(int, "int", "", "type") +- +-func one[a int | string]() {} +-func two[a int | string, b float64 | int]() {} +- +-func _() { +- one[]() //@rank("]", string, float64) +- two[]() //@rank("]", int, float64) +- two[int, f]() //@rank("]", float64, float32) +-} +- +-func slices[a []int | []float64]() {} //@item(tpInts, "[]int", "[]int", "type"),item(tpFloats, "[]float64", "[]float64", "type") +- +-func _() { +- slices[]() //@rank("]", tpInts),rank("]", tpFloats) +-} +- +-type s[a int | string] struct{} +- +-func _() { +- s[]{} //@rank("]", int, float64) +-} +- +-func takesGeneric[a int | string](s[a]) { +- "s[a]{}" //@item(tpInScopeLit, "s[a]{}", "", "var") +- takesGeneric() //@rank(")", tpInScopeLit),snippet(")", tpInScopeLit, "s[a]{\\}") +-} +- +-func _() { +- s[int]{} //@item(tpInstLit, "s[int]{}", "", "var") +- takesGeneric[int]() //@rank(")", tpInstLit),snippet(")", tpInstLit, "s[int]{\\}") +- +- "s[...]{}" //@item(tpUninstLit, "s[...]{}", "", "var") +- takesGeneric() //@rank(")", tpUninstLit),snippet(")", tpUninstLit, "s[${1:}]{\\}") +-} +- +-func returnTP[A int | float64](a A) A { //@item(returnTP, "returnTP", "something", "func") +- return a +-} +- +-func _() { +- // disabled - see issue #54822 +- var _ int = returnTP // snippet(" //", returnTP, "returnTP[${1:}](${2:})") +- +- var aa int //@item(tpInt, "aa", "int", "var") +- var ab float64 //@item(tpFloat, "ab", "float64", "var") +- returnTP[int](a) //@rank(")", tpInt, tpFloat) +-} +- +-func takesFunc[T any](func(T) T) { +- var _ func(t T) T = f //@snippet(" //", tpLitFunc, "func(t T) T {$0\\}") +-} +- +-func _() { +- _ = "func(...) {}" //@item(tpLitFunc, "func(...) {}", "", "var") +- takesFunc() //@snippet(")", tpLitFunc, "func(${1:}) ${2:} {$0\\}") +- takesFunc[int]() //@snippet(")", tpLitFunc, "func(i int) int {$0\\}") +-} diff -urN a/gopls/internal/regtest/marker/testdata/completion/unimported.txt b/gopls/internal/regtest/marker/testdata/completion/unimported.txt --- a/gopls/internal/regtest/marker/testdata/completion/unimported.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/completion/unimported.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/completion/unimported.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ - --- flags -- @@ -122040,9 +121747,128 @@ diff -urN a/gopls/internal/regtest/marker/testdata/completion/unimported.txt b/g -func TestSomething(t *testing.T) { - _ = unimported.TestExport //@complete("TestExport", testexport) -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/unresolved.txt b/gopls/internal/regtest/marker/testdata/completion/unresolved.txt +--- a/gopls/internal/regtest/marker/testdata/completion/unresolved.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/unresolved.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +-This test verifies gopls does not crash on fake "resolved" types. +- +--- flags -- +--ignore_extra_diags +- +--- settings.json -- +-{ +- "completeUnimported": false +-} +- +--- unresolved.go -- +-package unresolved +- +-func foo(interface{}) { +- foo(func(i, j f //@complete(" //") +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/unsafe.txt b/gopls/internal/regtest/marker/testdata/completion/unsafe.txt +--- a/gopls/internal/regtest/marker/testdata/completion/unsafe.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/unsafe.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,24 +0,0 @@ +-This test checks completion of symbols in the 'unsafe' package. +- +--- flags -- +--ignore_extra_diags +- +--- settings.json -- +-{ +- "matcher": "caseinsensitive" +-} +- +--- unsafe.go -- +-package unsafe +- +-import ( +- "unsafe" +-) +- +-// Pre-set this marker, as we don't have a "source" for it in this package. +-/* unsafe.Sizeof */ //@item(Sizeof, "Sizeof", "invalid type", "text") +- +-func _() { +- x := struct{}{} +- _ = unsafe.Sizeof(x) //@complete("z", Sizeof) +-} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/variadic.txt b/gopls/internal/regtest/marker/testdata/completion/variadic.txt +--- a/gopls/internal/regtest/marker/testdata/completion/variadic.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/variadic.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,67 +0,0 @@ +-This test checks completion related to variadic functions. +- +--- flags -- +--ignore_extra_diags +- +--- variadic.go -- +-package variadic +- +-func foo(i int, strs ...string) {} +- +-func bar() []string { //@item(vFunc, "bar", "func() []string", "func") +- return nil +-} +- +-func _() { +- var ( +- i int //@item(vInt, "i", "int", "var") +- s string //@item(vStr, "s", "string", "var") +- ss []string //@item(vStrSlice, "ss", "[]string", "var") +- v interface{} //@item(vIntf, "v", "interface{}", "var") +- ) +- +- foo() //@rank(")", vInt, vStr),rank(")", vInt, vStrSlice) +- foo(123, ) //@rank(")", vStr, vInt),rank(")", vStrSlice, vInt) +- foo(123, "", ) //@rank(")", vStr, vInt),rank(")", vStr, vStrSlice) +- foo(123, s, "") //@rank(", \"", vStr, vStrSlice) +- +- // snippet will add the "..." for you +- foo(123, ) //@snippet(")", vStrSlice, "ss..."),snippet(")", vFunc, "bar()..."),snippet(")", vStr, "s") +- +- // don't add "..." for interface{} +- foo(123, ) //@snippet(")", vIntf, "v") +-} +- +-func qux(...func()) {} +-func f() {} //@item(vVarArg, "f", "func()", "func") +- +-func _() { +- qux(f) //@snippet(")", vVarArg, "f") +-} +- +-func _() { +- foo(0, []string{}...) //@complete(")") +-} +- +--- variadic_intf.go -- +-package variadic +- +-type baz interface { +- baz() +-} +- +-func wantsBaz(...baz) {} +- +-type bazImpl int +- +-func (bazImpl) baz() {} +- +-func _() { +- var ( +- impls []bazImpl //@item(vImplSlice, "impls", "[]bazImpl", "var") +- impl bazImpl //@item(vImpl, "impl", "bazImpl", "var") +- bazes []baz //@item(vIntfSlice, "bazes", "[]baz", "var") +- ) +- +- wantsBaz() //@rank(")", vImpl, vImplSlice),rank(")", vIntfSlice, vImplSlice) +-} diff -urN a/gopls/internal/regtest/marker/testdata/definition/cgo.txt b/gopls/internal/regtest/marker/testdata/definition/cgo.txt --- a/gopls/internal/regtest/marker/testdata/definition/cgo.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/definition/cgo.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/definition/cgo.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -This test is ported from the old marker tests. -It tests hover and definition for cgo declarations. @@ -122108,7 +121934,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/definition/cgo.txt b/gopls/in -[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/cgo.test/cgo#Example) diff -urN a/gopls/internal/regtest/marker/testdata/definition/embed.txt b/gopls/internal/regtest/marker/testdata/definition/embed.txt --- a/gopls/internal/regtest/marker/testdata/definition/embed.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/definition/embed.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/definition/embed.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,254 +0,0 @@ -This test checks definition and hover operations over embedded fields and methods. - @@ -122366,7 +122192,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/definition/embed.txt b/gopls/ -@loc(aAlias, "aAlias") diff -urN a/gopls/internal/regtest/marker/testdata/definition/import.txt b/gopls/internal/regtest/marker/testdata/definition/import.txt --- a/gopls/internal/regtest/marker/testdata/definition/import.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/definition/import.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/definition/import.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -This test checks definition and hover over imports. --- go.mod -- @@ -122422,7 +122248,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/definition/import.txt b/gopls -[`myFoo` on pkg.go.dev](https://pkg.go.dev/mod.com/foo) diff -urN a/gopls/internal/regtest/marker/testdata/definition/misc.txt b/gopls/internal/regtest/marker/testdata/definition/misc.txt --- a/gopls/internal/regtest/marker/testdata/definition/misc.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/definition/misc.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/definition/misc.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,230 +0,0 @@ -This test exercises miscellaneous definition and hover requests. --- go.mod -- @@ -122656,7 +122482,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/definition/misc.txt b/gopls/i -z is a variable too. diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/addgowork.txt b/gopls/internal/regtest/marker/testdata/diagnostics/addgowork.txt --- a/gopls/internal/regtest/marker/testdata/diagnostics/addgowork.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/diagnostics/addgowork.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/addgowork.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -This test demonstrates diagnostics for adding a go.work file. - @@ -122710,10 +122536,10 @@ diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/addgowork.txt b/g -const C = "b" diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/analyzers.txt b/gopls/internal/regtest/marker/testdata/diagnostics/analyzers.txt --- a/gopls/internal/regtest/marker/testdata/diagnostics/analyzers.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/diagnostics/analyzers.txt 1970-01-01 08:00:00 -@@ -1,51 +0,0 @@ ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/analyzers.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,57 +0,0 @@ -Test of warning diagnostics from various analyzers: --copylocks, printf, slog, tests, and timeformat. +-copylocks, printf, slog, tests, timeformat, and nilness. - --- go.mod -- -module example.com @@ -122763,9 +122589,15 @@ diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/analyzers.txt b/g - fmt.Println(now.Format("2006-02-01")) //@diag("2006-02-01", re"2006-02-01 should be 2006-01-02") -} - +-// nilness +-func _(ptr *int) { +- if ptr == nil { +- _ = *ptr //@diag("*ptr", re"nil dereference in load") +- } +-} diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/excludedfile.txt b/gopls/internal/regtest/marker/testdata/diagnostics/excludedfile.txt --- a/gopls/internal/regtest/marker/testdata/diagnostics/excludedfile.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/diagnostics/excludedfile.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/excludedfile.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -This test demonstrates diagnostics for various forms of file exclusion. - @@ -122807,7 +122639,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/excludedfile.txt - diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/generated.txt b/gopls/internal/regtest/marker/testdata/diagnostics/generated.txt --- a/gopls/internal/regtest/marker/testdata/diagnostics/generated.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/diagnostics/generated.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/generated.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -Test of "undeclared" diagnostic in generated code. - @@ -122832,7 +122664,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/generated.txt b/g -} diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/issue56943.txt b/gopls/internal/regtest/marker/testdata/diagnostics/issue56943.txt --- a/gopls/internal/regtest/marker/testdata/diagnostics/issue56943.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/diagnostics/issue56943.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/issue56943.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -This test verifies that we produce diagnostics related to mismatching -unexported interface methods in non-workspace packages. @@ -122858,7 +122690,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/issue56943.txt b/ -func (node) End() token.Pos { return 0 } diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/issue59005.txt b/gopls/internal/regtest/marker/testdata/diagnostics/issue59005.txt --- a/gopls/internal/regtest/marker/testdata/diagnostics/issue59005.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/diagnostics/issue59005.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/issue59005.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -This test verifies that we don't drop type checking errors on the floor when we -fail to compute positions for their related errors. @@ -122882,7 +122714,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/issue59005.txt b/ -const C = 2 diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/issue60544.txt b/gopls/internal/regtest/marker/testdata/diagnostics/issue60544.txt --- a/gopls/internal/regtest/marker/testdata/diagnostics/issue60544.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/diagnostics/issue60544.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/issue60544.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -This test exercises a crash due to treatment of "comparable" in methodset -calculation (golang/go#60544). @@ -122899,7 +122731,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/issue60544.txt b/ -func (X) test(x comparable) {} //@diag("comparable", re"outside a type constraint") diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/issue60605.txt b/gopls/internal/regtest/marker/testdata/diagnostics/issue60605.txt --- a/gopls/internal/regtest/marker/testdata/diagnostics/issue60605.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/diagnostics/issue60605.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/issue60605.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -This test verifies that we can export constants with unknown kind. -Previously, the exporter would panic while attempting to convert such constants @@ -122915,7 +122747,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/issue60605.txt b/ -const EPSILON float64 = 1e- //@diag(re"1e-()", re"exponent has no digits") diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/parseerr.txt b/gopls/internal/regtest/marker/testdata/diagnostics/parseerr.txt --- a/gopls/internal/regtest/marker/testdata/diagnostics/parseerr.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/diagnostics/parseerr.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/parseerr.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ - -This test exercises diagnostics produced for syntax errors. @@ -122946,7 +122778,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/parseerr.txt b/go -} diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/rundespiteerrors.txt b/gopls/internal/regtest/marker/testdata/diagnostics/rundespiteerrors.txt --- a/gopls/internal/regtest/marker/testdata/diagnostics/rundespiteerrors.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/diagnostics/rundespiteerrors.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/rundespiteerrors.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -This test verifies that analyzers without RunDespiteErrors are not -executed on a package containing type errors (see issue #54762). @@ -122977,8 +122809,8 @@ diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/rundespiteerrors. -} diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/typeerr.txt b/gopls/internal/regtest/marker/testdata/diagnostics/typeerr.txt --- a/gopls/internal/regtest/marker/testdata/diagnostics/typeerr.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/diagnostics/typeerr.txt 1970-01-01 08:00:00 -@@ -1,33 +0,0 @@ ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/typeerr.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,30 +0,0 @@ - -This test exercises diagnostics produced for type errors -in the absence of syntax errors. @@ -123000,21 +122832,18 @@ diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/typeerr.txt b/gop -func f(x int) { - append("") //@diag(re`""`, re"a slice") - -- x := 123 //@diag(re"x := 123", re"no new variables"), suggestedfix(re"():", re"no new variables", "quickfix", fix) +- x := 123 //@diag(re"x := 123", re"no new variables"), suggestedfix(re"():", re"no new variables", fix) -} - --- @fix/typeerr.go -- --package a -- --func f(x int) { -- append("") //@diag(re`""`, re"a slice") -- -- x = 123 //@diag(re"x := 123", re"no new variables"), suggestedfix(re"():", re"no new variables", "quickfix", fix) --} -- +---- before +-+++ after +-@@ -6 +6 @@ +-- x := 123 //@diag(re"x := 123", re"no new variables"), suggestedfix(re"():", re"no new variables", fix) +-+ x = 123 //@diag(re"x := 123", re"no new variables"), suggestedfix(re"():", re"no new variables", fix) diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/useinternal.txt b/gopls/internal/regtest/marker/testdata/diagnostics/useinternal.txt --- a/gopls/internal/regtest/marker/testdata/diagnostics/useinternal.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/diagnostics/useinternal.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/useinternal.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -This test checks a diagnostic for invalid use of internal packages. - @@ -123039,7 +122868,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/useinternal.txt b -import _ "bad.test/assign/internal/secret" //@diag("\"bad.test/assign/internal/secret\"", re"could not import bad.test/assign/internal/secret \\(invalid use of internal package \"bad.test/assign/internal/secret\"\\)"),diag("_", re"use of internal package bad.test/assign/internal/secret not allowed") diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/usemodule.txt b/gopls/internal/regtest/marker/testdata/diagnostics/usemodule.txt --- a/gopls/internal/regtest/marker/testdata/diagnostics/usemodule.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/diagnostics/usemodule.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/usemodule.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -This test demonstrates diagnostics for a module that is missing from the -go.work file. @@ -123094,7 +122923,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/usemodule.txt b/g -const C = "b" diff -urN a/gopls/internal/regtest/marker/testdata/fixedbugs/issue59318.txt b/gopls/internal/regtest/marker/testdata/fixedbugs/issue59318.txt --- a/gopls/internal/regtest/marker/testdata/fixedbugs/issue59318.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/fixedbugs/issue59318.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/fixedbugs/issue59318.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -This test verifies that we can load multiple orphaned files as -command-line-arguments packages. @@ -123120,7 +122949,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/fixedbugs/issue59318.txt b/go -go 1.18 diff -urN a/gopls/internal/regtest/marker/testdata/fixedbugs/issue59944.txt b/gopls/internal/regtest/marker/testdata/fixedbugs/issue59944.txt --- a/gopls/internal/regtest/marker/testdata/fixedbugs/issue59944.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/fixedbugs/issue59944.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/fixedbugs/issue59944.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -This test verifies that gopls does not panic when encountering the go/types -bug described in golang/go#59944: the Bindingf function is not included in @@ -123155,167 +122984,9 @@ diff -urN a/gopls/internal/regtest/marker/testdata/fixedbugs/issue59944.txt b/go -func (l *Layout) Bindingf(format string, args ...interface{}) { - fmt.Printf(format, args...) -} -diff -urN a/gopls/internal/regtest/marker/testdata/foldingrange/a.txt b/gopls/internal/regtest/marker/testdata/foldingrange/a.txt ---- a/gopls/internal/regtest/marker/testdata/foldingrange/a.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/foldingrange/a.txt 1970-01-01 08:00:00 -@@ -1,154 +0,0 @@ --This test checks basic behavior of textDocument/foldingRange. -- ---- a.go -- --package folding //@foldingrange(raw) -- --import ( -- "fmt" -- _ "log" --) -- --import _ "os" -- --// bar is a function. --// With a multiline doc comment. --func bar() string { -- /* This is a single line comment */ -- switch { -- case true: -- if true { -- fmt.Println("true") -- } else { -- fmt.Println("false") -- } -- case false: -- fmt.Println("false") -- default: -- fmt.Println("default") -- } -- /* This is a multiline -- block -- comment */ -- -- /* This is a multiline -- block -- comment */ -- // Followed by another comment. -- _ = []int{ -- 1, -- 2, -- 3, -- } -- _ = [2]string{"d", -- "e", -- } -- _ = map[string]int{ -- "a": 1, -- "b": 2, -- "c": 3, -- } -- type T struct { -- f string -- g int -- h string -- } -- _ = T{ -- f: "j", -- g: 4, -- h: "i", -- } -- x, y := make(chan bool), make(chan bool) -- select { -- case val := <-x: -- if val { -- fmt.Println("true from x") -- } else { -- fmt.Println("false from x") -- } -- case <-y: -- fmt.Println("y") -- default: -- fmt.Println("default") -- } -- // This is a multiline comment -- // that is not a doc comment. -- return ` --this string --is not indented` --} ---- @raw -- --package folding //@foldingrange(raw) -- --import (<0 kind="imports"> -- "fmt" -- _ "log" --</0>) -- --import _ "os" -- --// bar is a function.<1 kind="comment"> --// With a multiline doc comment.</1> --func bar(<2 kind=""></2>) string {<3 kind=""> -- /* This is a single line comment */ -- switch {<4 kind=""> -- case true:<5 kind=""> -- if true {<6 kind=""> -- fmt.Println(<7 kind="">"true"</7>) -- </6>} else {<8 kind=""> -- fmt.Println(<9 kind="">"false"</9>) -- </8>}</5> -- case false:<10 kind=""> -- fmt.Println(<11 kind="">"false"</11>)</10> -- default:<12 kind=""> -- fmt.Println(<13 kind="">"default"</13>)</12> -- </4>} -- /* This is a multiline<14 kind="comment"> -- block -- comment */</14> -- -- /* This is a multiline<15 kind="comment"> -- block -- comment */ -- // Followed by another comment.</15> -- _ = []int{<16 kind=""> -- 1, -- 2, -- 3, -- </16>} -- _ = [2]string{<17 kind="">"d", -- "e", -- </17>} -- _ = map[string]int{<18 kind=""> -- "a": 1, -- "b": 2, -- "c": 3, -- </18>} -- type T struct {<19 kind=""> -- f string -- g int -- h string -- </19>} -- _ = T{<20 kind=""> -- f: "j", -- g: 4, -- h: "i", -- </20>} -- x, y := make(<21 kind="">chan bool</21>), make(<22 kind="">chan bool</22>) -- select {<23 kind=""> -- case val := <-x:<24 kind=""> -- if val {<25 kind=""> -- fmt.Println(<26 kind="">"true from x"</26>) -- </25>} else {<27 kind=""> -- fmt.Println(<28 kind="">"false from x"</28>) -- </27>}</24> -- case <-y:<29 kind=""> -- fmt.Println(<30 kind="">"y"</30>)</29> -- default:<31 kind=""> -- fmt.Println(<32 kind="">"default"</32>)</31> -- </23>} -- // This is a multiline comment<33 kind="comment"> -- // that is not a doc comment.</33> -- return <34 kind="">` --this string --is not indented`</34> --</3>} diff -urN a/gopls/internal/regtest/marker/testdata/foldingrange/a_lineonly.txt b/gopls/internal/regtest/marker/testdata/foldingrange/a_lineonly.txt --- a/gopls/internal/regtest/marker/testdata/foldingrange/a_lineonly.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/foldingrange/a_lineonly.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/foldingrange/a_lineonly.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,163 +0,0 @@ -This test checks basic behavior of the textDocument/foldingRange, when the -editor only supports line folding. @@ -123480,9 +123151,167 @@ diff -urN a/gopls/internal/regtest/marker/testdata/foldingrange/a_lineonly.txt b -this string -is not indented`</2></22> -} +diff -urN a/gopls/internal/regtest/marker/testdata/foldingrange/a.txt b/gopls/internal/regtest/marker/testdata/foldingrange/a.txt +--- a/gopls/internal/regtest/marker/testdata/foldingrange/a.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/foldingrange/a.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,154 +0,0 @@ +-This test checks basic behavior of textDocument/foldingRange. +- +--- a.go -- +-package folding //@foldingrange(raw) +- +-import ( +- "fmt" +- _ "log" +-) +- +-import _ "os" +- +-// bar is a function. +-// With a multiline doc comment. +-func bar() string { +- /* This is a single line comment */ +- switch { +- case true: +- if true { +- fmt.Println("true") +- } else { +- fmt.Println("false") +- } +- case false: +- fmt.Println("false") +- default: +- fmt.Println("default") +- } +- /* This is a multiline +- block +- comment */ +- +- /* This is a multiline +- block +- comment */ +- // Followed by another comment. +- _ = []int{ +- 1, +- 2, +- 3, +- } +- _ = [2]string{"d", +- "e", +- } +- _ = map[string]int{ +- "a": 1, +- "b": 2, +- "c": 3, +- } +- type T struct { +- f string +- g int +- h string +- } +- _ = T{ +- f: "j", +- g: 4, +- h: "i", +- } +- x, y := make(chan bool), make(chan bool) +- select { +- case val := <-x: +- if val { +- fmt.Println("true from x") +- } else { +- fmt.Println("false from x") +- } +- case <-y: +- fmt.Println("y") +- default: +- fmt.Println("default") +- } +- // This is a multiline comment +- // that is not a doc comment. +- return ` +-this string +-is not indented` +-} +--- @raw -- +-package folding //@foldingrange(raw) +- +-import (<0 kind="imports"> +- "fmt" +- _ "log" +-</0>) +- +-import _ "os" +- +-// bar is a function.<1 kind="comment"> +-// With a multiline doc comment.</1> +-func bar(<2 kind=""></2>) string {<3 kind=""> +- /* This is a single line comment */ +- switch {<4 kind=""> +- case true:<5 kind=""> +- if true {<6 kind=""> +- fmt.Println(<7 kind="">"true"</7>) +- </6>} else {<8 kind=""> +- fmt.Println(<9 kind="">"false"</9>) +- </8>}</5> +- case false:<10 kind=""> +- fmt.Println(<11 kind="">"false"</11>)</10> +- default:<12 kind=""> +- fmt.Println(<13 kind="">"default"</13>)</12> +- </4>} +- /* This is a multiline<14 kind="comment"> +- block +- comment */</14> +- +- /* This is a multiline<15 kind="comment"> +- block +- comment */ +- // Followed by another comment.</15> +- _ = []int{<16 kind=""> +- 1, +- 2, +- 3, +- </16>} +- _ = [2]string{<17 kind="">"d", +- "e", +- </17>} +- _ = map[string]int{<18 kind=""> +- "a": 1, +- "b": 2, +- "c": 3, +- </18>} +- type T struct {<19 kind=""> +- f string +- g int +- h string +- </19>} +- _ = T{<20 kind=""> +- f: "j", +- g: 4, +- h: "i", +- </20>} +- x, y := make(<21 kind="">chan bool</21>), make(<22 kind="">chan bool</22>) +- select {<23 kind=""> +- case val := <-x:<24 kind=""> +- if val {<25 kind=""> +- fmt.Println(<26 kind="">"true from x"</26>) +- </25>} else {<27 kind=""> +- fmt.Println(<28 kind="">"false from x"</28>) +- </27>}</24> +- case <-y:<29 kind=""> +- fmt.Println(<30 kind="">"y"</30>)</29> +- default:<31 kind=""> +- fmt.Println(<32 kind="">"default"</32>)</31> +- </23>} +- // This is a multiline comment<33 kind="comment"> +- // that is not a doc comment.</33> +- return <34 kind="">` +-this string +-is not indented`</34> +-</3>} diff -urN a/gopls/internal/regtest/marker/testdata/foldingrange/bad.txt b/gopls/internal/regtest/marker/testdata/foldingrange/bad.txt --- a/gopls/internal/regtest/marker/testdata/foldingrange/bad.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/foldingrange/bad.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/foldingrange/bad.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -This test verifies behavior of textDocument/foldingRange in the presence of -unformatted syntax. @@ -123527,7 +123356,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/foldingrange/bad.txt b/gopls/ -</3>} diff -urN a/gopls/internal/regtest/marker/testdata/format/format.txt b/gopls/internal/regtest/marker/testdata/format/format.txt --- a/gopls/internal/regtest/marker/testdata/format/format.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/format/format.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/format/format.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -This test checks basic behavior of textDocument/formatting requests. - @@ -123611,7 +123440,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/format/format.txt b/gopls/int -package format //@format(oneline) diff -urN a/gopls/internal/regtest/marker/testdata/format/issue59554.txt b/gopls/internal/regtest/marker/testdata/format/issue59554.txt --- a/gopls/internal/regtest/marker/testdata/format/issue59554.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/format/issue59554.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/format/issue59554.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -Test case for golang/go#59554: data corruption on formatting due to line -directives. @@ -123648,7 +123477,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/format/issue59554.txt b/gopls -} diff -urN a/gopls/internal/regtest/marker/testdata/format/noparse.txt b/gopls/internal/regtest/marker/testdata/format/noparse.txt --- a/gopls/internal/regtest/marker/testdata/format/noparse.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/format/noparse.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/format/noparse.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -This test checks that formatting does not run on code that has parse errors. - @@ -123679,7 +123508,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/format/noparse.txt b/gopls/in -7:5: missing condition in if statement diff -urN a/gopls/internal/regtest/marker/testdata/highlight/highlight.txt b/gopls/internal/regtest/marker/testdata/highlight/highlight.txt --- a/gopls/internal/regtest/marker/testdata/highlight/highlight.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/highlight/highlight.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/highlight/highlight.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,158 +0,0 @@ -This test checks basic functionality of the textDocument/highlight request. - @@ -123841,7 +123670,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/highlight/highlight.txt b/gop -} diff -urN a/gopls/internal/regtest/marker/testdata/highlight/issue60435.txt b/gopls/internal/regtest/marker/testdata/highlight/issue60435.txt --- a/gopls/internal/regtest/marker/testdata/highlight/issue60435.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/highlight/issue60435.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/highlight/issue60435.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -This is a regression test for issue 60435: -Highlighting "net/http" shouldn't have any effect @@ -123860,7 +123689,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/highlight/issue60435.txt b/go -var _ = http.NewRequest //@loc(here, "http"), highlight(here, here, httpImp) diff -urN a/gopls/internal/regtest/marker/testdata/hover/basiclit.txt b/gopls/internal/regtest/marker/testdata/hover/basiclit.txt --- a/gopls/internal/regtest/marker/testdata/hover/basiclit.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/basiclit.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/hover/basiclit.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -This test checks gopls behavior when hovering over basic literals. --- basiclit.go -- @@ -123945,7 +123774,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/hover/basiclit.txt b/gopls/in -127754, '🌊', U+1F30A, WATER WAVE diff -urN a/gopls/internal/regtest/marker/testdata/hover/const.txt b/gopls/internal/regtest/marker/testdata/hover/const.txt --- a/gopls/internal/regtest/marker/testdata/hover/const.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/const.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/hover/const.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ -This test checks hovering over constants. - @@ -124106,7 +123935,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/hover/const.txt b/gopls/inter -[`math.Log2E` on pkg.go.dev](https://pkg.go.dev/math#Log2E) diff -urN a/gopls/internal/regtest/marker/testdata/hover/generics.txt b/gopls/internal/regtest/marker/testdata/hover/generics.txt --- a/gopls/internal/regtest/marker/testdata/hover/generics.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/generics.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/hover/generics.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -This file contains tests for hovering over generic Go code. - @@ -124186,7 +124015,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/hover/generics.txt b/gopls/in -``` diff -urN a/gopls/internal/regtest/marker/testdata/hover/godef.txt b/gopls/internal/regtest/marker/testdata/hover/godef.txt --- a/gopls/internal/regtest/marker/testdata/hover/godef.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/godef.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/hover/godef.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,406 +0,0 @@ -This test was ported from 'godef' in the old marker tests. -It tests various hover and definition requests. @@ -124596,7 +124425,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/hover/godef.txt b/gopls/inter -func _() {} //@diag("_", re"expected") diff -urN a/gopls/internal/regtest/marker/testdata/hover/goprivate.txt b/gopls/internal/regtest/marker/testdata/hover/goprivate.txt --- a/gopls/internal/regtest/marker/testdata/hover/goprivate.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/goprivate.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/hover/goprivate.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -This test checks that links in hover obey GOPRIVATE. --- env -- @@ -124627,7 +124456,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/hover/goprivate.txt b/gopls/i -T should not be linked, as it is private. diff -urN a/gopls/internal/regtest/marker/testdata/hover/hover.txt b/gopls/internal/regtest/marker/testdata/hover/hover.txt --- a/gopls/internal/regtest/marker/testdata/hover/hover.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/hover.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/hover/hover.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -This test demonstrates some features of the new marker test runner. --- a.go -- @@ -124658,133 +124487,9 @@ diff -urN a/gopls/internal/regtest/marker/testdata/hover/hover.txt b/gopls/inter -```go -var x int -``` -diff -urN a/gopls/internal/regtest/marker/testdata/hover/linkable.txt b/gopls/internal/regtest/marker/testdata/hover/linkable.txt ---- a/gopls/internal/regtest/marker/testdata/hover/linkable.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/linkable.txt 1970-01-01 08:00:00 -@@ -1,120 +0,0 @@ --This test checks that we correctly determine pkgsite links for various --identifiers. -- --We should only produce links that work, meaning the object is reachable via the --package's public API. ---- go.mod -- --module mod.com -- --go 1.18 ---- p.go -- --package p -- --type E struct { -- Embed int --} -- --// T is in the package scope, and so should be linkable. --type T struct{ //@hover("T", "T", T) -- // Only exported fields should be linkable -- -- f int //@hover("f", "f", f) -- F int //@hover("F", "F", F) -- -- E -- -- // TODO(rfindley): is the link here correct? It ignores N. -- N struct { -- // Nested fields should also be linkable. -- Nested int //@hover("Nested", "Nested", Nested) -- } --} --// M is an exported method, and so should be linkable. --func (T) M() {} -- --// m is not exported, and so should not be linkable. --func (T) m() {} -- --func _() { -- var t T -- -- // Embedded fields should be linkable. -- _ = t.Embed //@hover("Embed", "Embed", Embed) -- -- // Local variables should not be linkable, even if they are capitalized. -- var X int //@hover("X", "X", X) -- _ = X -- -- // Local types should not be linkable, even if they are capitalized. -- type Local struct { //@hover("Local", "Local", Local) -- E -- } -- -- // But the embedded field should still be linkable. -- var l Local -- _ = l.Embed //@hover("Embed", "Embed", Embed) --} ---- @Embed/hover.md -- --```go --field Embed int --``` -- --[`(p.E).Embed` on pkg.go.dev](https://pkg.go.dev/mod.com#E.Embed) ---- @F/hover.md -- --```go --field F int --``` -- --@hover("F", "F", F) -- -- --[`(p.T).F` on pkg.go.dev](https://pkg.go.dev/mod.com#T.F) ---- @Local/hover.md -- --```go --type Local struct { -- E --} --``` -- --Local types should not be linkable, even if they are capitalized. ---- @Nested/hover.md -- --```go --field Nested int --``` -- --Nested fields should also be linkable. ---- @T/hover.md -- --```go --type T struct { -- f int //@hover("f", "f", f) -- F int //@hover("F", "F", F) -- -- E -- -- // TODO(rfindley): is the link here correct? It ignores N. -- N struct { -- // Nested fields should also be linkable. -- Nested int //@hover("Nested", "Nested", Nested) -- } --} -- --func (T).M() --func (T).m() --``` -- --T is in the package scope, and so should be linkable. -- -- --[`p.T` on pkg.go.dev](https://pkg.go.dev/mod.com#T) ---- @X/hover.md -- --```go --var X int --``` -- --Local variables should not be linkable, even if they are capitalized. ---- @f/hover.md -- --```go --field f int --``` -- --@hover("f", "f", f) diff -urN a/gopls/internal/regtest/marker/testdata/hover/linkable_generics.txt b/gopls/internal/regtest/marker/testdata/hover/linkable_generics.txt --- a/gopls/internal/regtest/marker/testdata/hover/linkable_generics.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/linkable_generics.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/hover/linkable_generics.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,145 +0,0 @@ -This file contains tests for documentation links to generic code in hover. - @@ -124931,9 +124636,133 @@ diff -urN a/gopls/internal/regtest/marker/testdata/hover/linkable_generics.txt b - - -[`generic.GT` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GT) +diff -urN a/gopls/internal/regtest/marker/testdata/hover/linkable.txt b/gopls/internal/regtest/marker/testdata/hover/linkable.txt +--- a/gopls/internal/regtest/marker/testdata/hover/linkable.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/hover/linkable.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,120 +0,0 @@ +-This test checks that we correctly determine pkgsite links for various +-identifiers. +- +-We should only produce links that work, meaning the object is reachable via the +-package's public API. +--- go.mod -- +-module mod.com +- +-go 1.18 +--- p.go -- +-package p +- +-type E struct { +- Embed int +-} +- +-// T is in the package scope, and so should be linkable. +-type T struct{ //@hover("T", "T", T) +- // Only exported fields should be linkable +- +- f int //@hover("f", "f", f) +- F int //@hover("F", "F", F) +- +- E +- +- // TODO(rfindley): is the link here correct? It ignores N. +- N struct { +- // Nested fields should also be linkable. +- Nested int //@hover("Nested", "Nested", Nested) +- } +-} +-// M is an exported method, and so should be linkable. +-func (T) M() {} +- +-// m is not exported, and so should not be linkable. +-func (T) m() {} +- +-func _() { +- var t T +- +- // Embedded fields should be linkable. +- _ = t.Embed //@hover("Embed", "Embed", Embed) +- +- // Local variables should not be linkable, even if they are capitalized. +- var X int //@hover("X", "X", X) +- _ = X +- +- // Local types should not be linkable, even if they are capitalized. +- type Local struct { //@hover("Local", "Local", Local) +- E +- } +- +- // But the embedded field should still be linkable. +- var l Local +- _ = l.Embed //@hover("Embed", "Embed", Embed) +-} +--- @Embed/hover.md -- +-```go +-field Embed int +-``` +- +-[`(p.E).Embed` on pkg.go.dev](https://pkg.go.dev/mod.com#E.Embed) +--- @F/hover.md -- +-```go +-field F int +-``` +- +-@hover("F", "F", F) +- +- +-[`(p.T).F` on pkg.go.dev](https://pkg.go.dev/mod.com#T.F) +--- @Local/hover.md -- +-```go +-type Local struct { +- E +-} +-``` +- +-Local types should not be linkable, even if they are capitalized. +--- @Nested/hover.md -- +-```go +-field Nested int +-``` +- +-Nested fields should also be linkable. +--- @T/hover.md -- +-```go +-type T struct { +- f int //@hover("f", "f", f) +- F int //@hover("F", "F", F) +- +- E +- +- // TODO(rfindley): is the link here correct? It ignores N. +- N struct { +- // Nested fields should also be linkable. +- Nested int //@hover("Nested", "Nested", Nested) +- } +-} +- +-func (T).M() +-func (T).m() +-``` +- +-T is in the package scope, and so should be linkable. +- +- +-[`p.T` on pkg.go.dev](https://pkg.go.dev/mod.com#T) +--- @X/hover.md -- +-```go +-var X int +-``` +- +-Local variables should not be linkable, even if they are capitalized. +--- @f/hover.md -- +-```go +-field f int +-``` +- +-@hover("f", "f", f) diff -urN a/gopls/internal/regtest/marker/testdata/hover/linkname.txt b/gopls/internal/regtest/marker/testdata/hover/linkname.txt --- a/gopls/internal/regtest/marker/testdata/hover/linkname.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/linkname.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/hover/linkname.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -This test check hover on the 2nd argument in go:linkname directives. --- go.mod -- @@ -124966,7 +124795,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/hover/linkname.txt b/gopls/in -bar does foo. diff -urN a/gopls/internal/regtest/marker/testdata/hover/std.txt b/gopls/internal/regtest/marker/testdata/hover/std.txt --- a/gopls/internal/regtest/marker/testdata/hover/std.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/std.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/hover/std.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -This test checks hover results for built-in or standard library symbols. - @@ -125050,7 +124879,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/hover/std.txt b/gopls/interna -[`string` on pkg.go.dev](https://pkg.go.dev/builtin#string) diff -urN a/gopls/internal/regtest/marker/testdata/implementation/basic.txt b/gopls/internal/regtest/marker/testdata/implementation/basic.txt --- a/gopls/internal/regtest/marker/testdata/implementation/basic.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/implementation/basic.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/implementation/basic.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -Basic test of implementation query. - @@ -125127,7 +124956,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/implementation/basic.txt b/go -} diff -urN a/gopls/internal/regtest/marker/testdata/implementation/generics.txt b/gopls/internal/regtest/marker/testdata/implementation/generics.txt --- a/gopls/internal/regtest/marker/testdata/implementation/generics.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/implementation/generics.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/implementation/generics.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -Test of 'implementation' query on generic types. - @@ -125165,7 +124994,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/implementation/generics.txt b -func (GC[V]) F(int, string, V) {} //@loc(GCF, "F"),implementation("F", GenIfaceF) diff -urN a/gopls/internal/regtest/marker/testdata/implementation/issue43655.txt b/gopls/internal/regtest/marker/testdata/implementation/issue43655.txt --- a/gopls/internal/regtest/marker/testdata/implementation/issue43655.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/implementation/issue43655.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/implementation/issue43655.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -This test verifies that we fine implementations of the built-in error interface. - @@ -125189,156 +125018,60 @@ diff -urN a/gopls/internal/regtest/marker/testdata/implementation/issue43655.txt - var a errA - _ = a.Error //@implementation("Error", errBError) -} -diff -urN a/gopls/internal/regtest/marker/testdata/quickfix/undeclared.txt b/gopls/internal/regtest/marker/testdata/quickfix/undeclared.txt ---- a/gopls/internal/regtest/marker/testdata/quickfix/undeclared.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/quickfix/undeclared.txt 1970-01-01 08:00:00 -@@ -1,62 +0,0 @@ --Tests of suggested fixes for "undeclared name" diagnostics, --which are of ("compiler", "error") type. +diff -urN a/gopls/internal/regtest/marker/testdata/links/links.txt b/gopls/internal/regtest/marker/testdata/links/links.txt +--- a/gopls/internal/regtest/marker/testdata/links/links.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/links/links.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,47 +0,0 @@ +-This test verifies behavior of textDocument/documentLink. - --- go.mod -- --module example.com --go 1.12 -- ---- a.go -- --package p -- --func a() { -- z, _ := 1+y, 11 //@suggestedfix("y", re"(undeclared name|undefined): y", "quickfix", a) -- _ = z --} -- ---- @a/a.go -- --package p -- --func a() { -- y := -- z, _ := 1+y, 11 //@suggestedfix("y", re"(undeclared name|undefined): y", "quickfix", a) -- _ = z --} -- ---- b.go -- --package p -- --func b() { -- if 100 < 90 { -- } else if 100 > n+2 { //@suggestedfix("n", re"(undeclared name|undefined): n", "quickfix", b) -- } --} -- ---- @b/b.go -- --package p -- --func b() { -- n := -- if 100 < 90 { -- } else if 100 > n+2 { //@suggestedfix("n", re"(undeclared name|undefined): n", "quickfix", b) -- } --} -- ---- c.go -- --package p -- --func c() { -- for i < 200 { //@suggestedfix("i", re"(undeclared name|undefined): i", "quickfix", c) -- } -- r() //@diag("r", re"(undeclared name|undefined): r") --} -- ---- @c/c.go -- --package p -- --func c() { -- i := -- for i < 200 { //@suggestedfix("i", re"(undeclared name|undefined): i", "quickfix", c) -- } -- r() //@diag("r", re"(undeclared name|undefined): r") --} -- -diff -urN a/gopls/internal/regtest/marker/testdata/quickfix/unusedrequire.txt b/gopls/internal/regtest/marker/testdata/quickfix/unusedrequire.txt ---- a/gopls/internal/regtest/marker/testdata/quickfix/unusedrequire.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/quickfix/unusedrequire.txt 1970-01-01 08:00:00 -@@ -1,24 +0,0 @@ --This test checks the suggested fix to remove unused require statements from --go.mod files. -- ---- flags -- ---write_sumfile=a -- ---- proxy/example.com@v1.0.0/x.go -- --package pkg --const X = 1 -- ---- a/go.mod -- --module mod.com -- --go 1.14 -- --require example.com v1.0.0 //@suggestedfix("require", re"not used", "quickfix", a) -- ---- @a/a/go.mod -- --module mod.com +-module golang.org/lsptests - --go 1.14 ---- a/main.go -- --package main --func main() {} -diff -urN a/gopls/internal/regtest/marker/testdata/quickfix/unusedrequire_gowork.txt b/gopls/internal/regtest/marker/testdata/quickfix/unusedrequire_gowork.txt ---- a/gopls/internal/regtest/marker/testdata/quickfix/unusedrequire_gowork.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/quickfix/unusedrequire_gowork.txt 1970-01-01 08:00:00 -@@ -1,49 +0,0 @@ --This test checks the suggested fix to remove unused require statements from --go.mod files, when a go.work file is used. +-go 1.18 +--- foo/foo.go -- +-package foo - --Note that unlike unusedrequire.txt, we need not write go.sum files when --a go.work file is used. +-type StructFoo struct {} - ---- flags -- ---min_go=go1.18 +--- links/links.go -- +-package links //@documentlink(links) - ---- proxy/example.com@v1.0.0/x.go -- --package pkg --const X = 1 +-import ( +- "fmt" - ---- go.work -- --go 1.21 +- "golang.org/lsptests/foo" - --use ( -- ./a -- ./b +- _ "database/sql" -) ---- a/go.mod -- --module mod.com/a -- --go 1.14 -- --require example.com v1.0.0 //@suggestedfix("require", re"not used", "quickfix", a) -- ---- @a/a/go.mod -- --module mod.com/a - --go 1.14 ---- a/main.go -- --package main --func main() {} -- ---- b/go.mod -- --module mod.com/b +-var ( +- _ fmt.Formatter +- _ foo.StructFoo +- _ errors.Formatter //@diag("errors", re"(undeclared|undefined)") +-) - --go 1.14 +-// Foo function +-func Foo() string { +- /*https://example.com/comment */ - --require example.com v1.0.0 //@suggestedfix("require", re"not used", "quickfix", b) +- url := "https://example.com/string_literal" +- return url - ---- @b/b/go.mod -- --module mod.com/b +- // TODO(golang/go#1234): Link the relevant issue. +- // TODO(microsoft/vscode-go#12): Another issue. +-} - --go 1.14 ---- b/main.go -- --package main --func main() {} +--- @links -- +-links/links.go:4:3-6 https://pkg.go.dev/fmt +-links/links.go:6:3-26 https://pkg.go.dev/golang.org/lsptests/foo +-links/links.go:8:5-17 https://pkg.go.dev/database/sql +-links/links.go:21:10-44 https://example.com/string_literal +-links/links.go:19:4-31 https://example.com/comment +-links/links.go:24:10-24 https://github.com/golang/go/issues/1234 +-links/links.go:25:10-32 https://github.com/microsoft/vscode-go/issues/12 diff -urN a/gopls/internal/regtest/marker/testdata/references/crosspackage.txt b/gopls/internal/regtest/marker/testdata/references/crosspackage.txt --- a/gopls/internal/regtest/marker/testdata/references/crosspackage.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/references/crosspackage.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/references/crosspackage.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -Test of basic cross-package references. - @@ -125379,7 +125112,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/references/crosspackage.txt b -} diff -urN a/gopls/internal/regtest/marker/testdata/references/imports.txt b/gopls/internal/regtest/marker/testdata/references/imports.txt --- a/gopls/internal/regtest/marker/testdata/references/imports.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/references/imports.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/references/imports.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -Test of references to local package names (imports). - @@ -125400,7 +125133,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/references/imports.txt b/gopl -} diff -urN a/gopls/internal/regtest/marker/testdata/references/interfaces.txt b/gopls/internal/regtest/marker/testdata/references/interfaces.txt --- a/gopls/internal/regtest/marker/testdata/references/interfaces.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/references/interfaces.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/references/interfaces.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -Test of references applied to concrete and interface types that are -related by assignability. The result includes references to both. @@ -125446,7 +125179,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/references/interfaces.txt b/g -} diff -urN a/gopls/internal/regtest/marker/testdata/references/intrapackage.txt b/gopls/internal/regtest/marker/testdata/references/intrapackage.txt --- a/gopls/internal/regtest/marker/testdata/references/intrapackage.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/references/intrapackage.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/references/intrapackage.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -Basic test of references within a single package. - @@ -125486,7 +125219,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/references/intrapackage.txt b -} diff -urN a/gopls/internal/regtest/marker/testdata/references/issue58506.txt b/gopls/internal/regtest/marker/testdata/references/issue58506.txt --- a/gopls/internal/regtest/marker/testdata/references/issue58506.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/references/issue58506.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/references/issue58506.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -Regression test for 'references' bug golang/go#58506. - @@ -125546,7 +125279,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/references/issue58506.txt b/g -var _ interface{} = b.B.F //@loc(refd, "F") diff -urN a/gopls/internal/regtest/marker/testdata/references/issue59851.txt b/gopls/internal/regtest/marker/testdata/references/issue59851.txt --- a/gopls/internal/regtest/marker/testdata/references/issue59851.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/references/issue59851.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/references/issue59851.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -Regression test for 'references' bug golang/go#59851. - @@ -125579,7 +125312,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/references/issue59851.txt b/g -var _ = Iface(nil).Method //@loc(ireftest, "Method") diff -urN a/gopls/internal/regtest/marker/testdata/references/issue60369.txt b/gopls/internal/regtest/marker/testdata/references/issue60369.txt --- a/gopls/internal/regtest/marker/testdata/references/issue60369.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/references/issue60369.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/references/issue60369.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -Regression test for 'references' bug golang/go#60369: a references -query on the embedded type name T in struct{p.T} instead reports all @@ -125612,7 +125345,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/references/issue60369.txt b/g -const c = a.C //@loc(aref3, "a") diff -urN a/gopls/internal/regtest/marker/testdata/references/issue60622.txt b/gopls/internal/regtest/marker/testdata/references/issue60622.txt --- a/gopls/internal/regtest/marker/testdata/references/issue60622.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/references/issue60622.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/references/issue60622.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -Regression test for 'references' bug golang/go#60622: -references to methods of generics were missing. @@ -125641,8 +125374,8 @@ diff -urN a/gopls/internal/regtest/marker/testdata/references/issue60622.txt b/g -} diff -urN a/gopls/internal/regtest/marker/testdata/references/issue60676.txt b/gopls/internal/regtest/marker/testdata/references/issue60676.txt --- a/gopls/internal/regtest/marker/testdata/references/issue60676.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/references/issue60676.txt 1970-01-01 08:00:00 -@@ -1,69 +0,0 @@ ++++ b/gopls/internal/regtest/marker/testdata/references/issue60676.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,70 +0,0 @@ -This test verifies that even after importing from export data, the references -algorithm is able to find all references to struct fields or methods that are -shared by types from multiple packages. See golang/go#60676. @@ -125707,14 +125440,15 @@ diff -urN a/gopls/internal/regtest/marker/testdata/references/issue60676.txt b/g - } - x.G = "hi" //@refs("G", GDef, "G") - _ = x.E //@refs("E", EDef, "E") +-} - -- var y b.BI +-func _(y b.BI) { - _ = y.M //@refs("M", MDef, "M") - _ = y.N //@refs("N", NDef, "N") -} diff -urN a/gopls/internal/regtest/marker/testdata/references/issue61618.txt b/gopls/internal/regtest/marker/testdata/references/issue61618.txt --- a/gopls/internal/regtest/marker/testdata/references/issue61618.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/references/issue61618.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/references/issue61618.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -Regression test for 'references' bug golang/go#61618: -references to instantiated fields were missing. @@ -125757,7 +125491,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/references/issue61618.txt b/g -} diff -urN a/gopls/internal/regtest/marker/testdata/references/shadow.txt b/gopls/internal/regtest/marker/testdata/references/shadow.txt --- a/gopls/internal/regtest/marker/testdata/references/shadow.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/references/shadow.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/references/shadow.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -Test of references in the presence of shadowing. - @@ -125778,7 +125512,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/references/shadow.txt b/gopls -} diff -urN a/gopls/internal/regtest/marker/testdata/references/test.txt b/gopls/internal/regtest/marker/testdata/references/test.txt --- a/gopls/internal/regtest/marker/testdata/references/test.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/references/test.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/references/test.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -Test of references between the extra files of a test variant -and the regular package. @@ -125811,7 +125545,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/references/test.txt b/gopls/i -func (u) g() {} //@loc(gdef2, "g") diff -urN a/gopls/internal/regtest/marker/testdata/references/typeswitch.txt b/gopls/internal/regtest/marker/testdata/references/typeswitch.txt --- a/gopls/internal/regtest/marker/testdata/references/typeswitch.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/references/typeswitch.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/references/typeswitch.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -Tests of reference to implicit type switch vars, which are -a special case in go/types.Info{Def,Use,Implicits}. @@ -125833,7 +125567,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/references/typeswitch.txt b/g -} diff -urN a/gopls/internal/regtest/marker/testdata/rename/basic.txt b/gopls/internal/regtest/marker/testdata/rename/basic.txt --- a/gopls/internal/regtest/marker/testdata/rename/basic.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/rename/basic.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/rename/basic.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -This test performs basic coverage of 'rename' within a single package. - @@ -125875,7 +125609,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/rename/basic.txt b/gopls/inte - diff -urN a/gopls/internal/regtest/marker/testdata/rename/conflict.txt b/gopls/internal/regtest/marker/testdata/rename/conflict.txt --- a/gopls/internal/regtest/marker/testdata/rename/conflict.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/rename/conflict.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/rename/conflict.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -This test exercises some renaming conflict scenarios -and ensures that the errors are informative. @@ -125938,7 +125672,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/rename/conflict.txt b/gopls/i -pkgname2/p1.go:2:5: with this package member var diff -urN a/gopls/internal/regtest/marker/testdata/rename/embed.txt b/gopls/internal/regtest/marker/testdata/rename/embed.txt --- a/gopls/internal/regtest/marker/testdata/rename/embed.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/rename/embed.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/rename/embed.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -This test exercises renaming of types used as embedded fields. - @@ -125978,7 +125712,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/rename/embed.txt b/gopls/inte - diff -urN a/gopls/internal/regtest/marker/testdata/rename/generics.txt b/gopls/internal/regtest/marker/testdata/rename/generics.txt --- a/gopls/internal/regtest/marker/testdata/rename/generics.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/rename/generics.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/rename/generics.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,240 +0,0 @@ -This test exercises various renaming features on generic code. - @@ -126220,9 +125954,32 @@ diff -urN a/gopls/internal/regtest/marker/testdata/rename/generics.txt b/gopls/i - x = x.Do(x) -} - +diff -urN a/gopls/internal/regtest/marker/testdata/rename/issue43616.txt b/gopls/internal/regtest/marker/testdata/rename/issue43616.txt +--- a/gopls/internal/regtest/marker/testdata/rename/issue43616.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/rename/issue43616.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,19 +0,0 @@ +-This test verifies the fix for golang/go#43616: renaming mishandles embedded +-fields. +- +--- p.go -- +-package issue43616 +- +-type foo int //@rename("foo", "bar", fooToBar),preparerename("oo","foo","foo") +- +-var x struct{ foo } //@renameerr("foo", "baz", "rename the type directly") +- +-var _ = x.foo //@renameerr("foo", "quux", "rename the type directly") +--- @fooToBar/p.go -- +-package issue43616 +- +-type bar int //@rename("foo", "bar", fooToBar),preparerename("oo","foo","foo") +- +-var x struct{ bar } //@renameerr("foo", "baz", "rename the type directly") +- +-var _ = x.bar //@renameerr("foo", "quux", "rename the type directly") diff -urN a/gopls/internal/regtest/marker/testdata/rename/issue60789.txt b/gopls/internal/regtest/marker/testdata/rename/issue60789.txt --- a/gopls/internal/regtest/marker/testdata/rename/issue60789.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/rename/issue60789.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/rename/issue60789.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ - -This test renames an exported method of an unexported type, @@ -126262,7 +126019,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/rename/issue60789.txt b/gopls - diff -urN a/gopls/internal/regtest/marker/testdata/rename/issue61294.txt b/gopls/internal/regtest/marker/testdata/rename/issue61294.txt --- a/gopls/internal/regtest/marker/testdata/rename/issue61294.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/rename/issue61294.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/rename/issue61294.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ - -This test renames a parameter var whose name is the same as a @@ -126295,7 +126052,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/rename/issue61294.txt b/gopls - diff -urN a/gopls/internal/regtest/marker/testdata/rename/issue61640.txt b/gopls/internal/regtest/marker/testdata/rename/issue61640.txt --- a/gopls/internal/regtest/marker/testdata/rename/issue61640.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/rename/issue61640.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/rename/issue61640.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -This test verifies that gopls can rename instantiated fields. - @@ -126346,7 +126103,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/rename/issue61640.txt b/gopls -} diff -urN a/gopls/internal/regtest/marker/testdata/rename/issue61813.txt b/gopls/internal/regtest/marker/testdata/rename/issue61813.txt --- a/gopls/internal/regtest/marker/testdata/rename/issue61813.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/rename/issue61813.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/rename/issue61813.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -This test exercises the panic reported in golang/go#61813. - @@ -126368,7 +126125,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/rename/issue61813.txt b/gopls -var x = []*P{{}} diff -urN a/gopls/internal/regtest/marker/testdata/rename/methods.txt b/gopls/internal/regtest/marker/testdata/rename/methods.txt --- a/gopls/internal/regtest/marker/testdata/rename/methods.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/rename/methods.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/rename/methods.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -This test exercises renaming of interface methods. - @@ -126437,9 +126194,75 @@ diff -urN a/gopls/internal/regtest/marker/testdata/rename/methods.txt b/gopls/in -c/c.go:5:10: renaming this method "F" to "G" -b/b.go:6:6: would make example.com/c.C no longer assignable to interface B -b/b.go:6:20: (rename example.com/b.B.F if you intend to change both types) +diff -urN a/gopls/internal/regtest/marker/testdata/rename/prepare.txt b/gopls/internal/regtest/marker/testdata/rename/prepare.txt +--- a/gopls/internal/regtest/marker/testdata/rename/prepare.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/rename/prepare.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,62 +0,0 @@ +-This test verifies the behavior of textDocument/prepareRename. +- +--- settings.json -- +-{ +- "deepCompletion": false +-} +- +--- go.mod -- +-module golang.org/lsptests +- +-go 1.18 +--- types/types.go -- +-package types +- +-type CoolAlias = int //@item(CoolAlias, "CoolAlias", "int", "type") +- +-type X struct { //@item(X_struct, "X", "struct{...}", "struct") +- x int +-} +- +-type Y struct { //@item(Y_struct, "Y", "struct{...}", "struct") +- y int +-} +- +- +-type Bob interface { //@item(Bob_interface, "Bob", "interface{...}", "interface") +- Bobby() +-} +- +-func (*X) Bobby() {} +-func (*Y) Bobby() {} +- +--- good/good0.go -- +-package good +- +-func stuff() { //@item(good_stuff, "stuff", "func()", "func"),preparerename("stu", "stuff", "stuff") +- x := 5 +- random2(x) //@preparerename("dom", "random2", "random2") +-} +- +--- good/good1.go -- +-package good +- +-import ( +- "golang.org/lsptests/types" //@item(types_import, "types", "\"golang.org/lsptests/types\"", "package") +-) +- +-func random() int { //@item(good_random, "random", "func() int", "func") +- _ = "random() int" //@preparerename("random", "", "") +- y := 6 + 7 //@preparerename("7", "", "") +- return y //@preparerename("return", "","") +-} +- +-func random2(y int) int { //@item(good_random2, "random2", "func(y int) int", "func"),item(good_y_param, "y", "int", "var") +- //@complete("", good_y_param, types_import, good_random, good_random2, good_stuff) +- var b types.Bob = &types.X{} //@preparerename("ypes","types", "types") +- if _, ok := b.(*types.X); ok { //@complete("X", X_struct, Y_struct, Bob_interface, CoolAlias) +- _ = 0 // suppress "empty branch" diagnostic +- } +- +- return y +-} diff -urN a/gopls/internal/regtest/marker/testdata/rename/typeswitch.txt b/gopls/internal/regtest/marker/testdata/rename/typeswitch.txt --- a/gopls/internal/regtest/marker/testdata/rename/typeswitch.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/rename/typeswitch.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/rename/typeswitch.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -This test covers the special case of renaming a type switch var. - @@ -126469,7 +126292,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/rename/typeswitch.txt b/gopls - diff -urN a/gopls/internal/regtest/marker/testdata/rename/unexported.txt b/gopls/internal/regtest/marker/testdata/rename/unexported.txt --- a/gopls/internal/regtest/marker/testdata/rename/unexported.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/rename/unexported.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/rename/unexported.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ - -This test attempts to rename a.S.X to x, which would make it @@ -126496,10 +126319,245 @@ diff -urN a/gopls/internal/regtest/marker/testdata/rename/unexported.txt b/gopls --- @oops -- -a/a.go:3:15: renaming "X" to "x" would make it unexported -a/a_test.go:5:13: breaking references from packages such as "example.com/a_test" +diff -urN a/gopls/internal/regtest/marker/testdata/signature/generic.txt b/gopls/internal/regtest/marker/testdata/signature/generic.txt +--- a/gopls/internal/regtest/marker/testdata/signature/generic.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/signature/generic.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,21 +0,0 @@ +-This test checks signature help on generic signatures. +- +--- g.go -- +-package g +- +-type M[K comparable, V any] map[K]V +- +-// golang/go#61189: signatureHelp must handle pointer receivers. +-func (m *M[K, V]) Get(k K) V { +- return (*m)[k] +-} +- +-func Get[K comparable, V any](m M[K, V], k K) V { +- return m[k] +-} +- +-func _() { +- var m M[int, string] +- _ = m.Get(0) //@signature("(", "Get(k int) string", 0) +- _ = Get(m, 0) //@signature("0", "Get(m M[int, string], k int) string", 1) +-} +diff -urN a/gopls/internal/regtest/marker/testdata/signature/signature.txt b/gopls/internal/regtest/marker/testdata/signature/signature.txt +--- a/gopls/internal/regtest/marker/testdata/signature/signature.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/signature/signature.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,206 +0,0 @@ +-This test exercises basic tests for signature help. +- +--- flags -- +--ignore_extra_diags +- +--- go.mod -- +-module golang.org/lsptests +- +-go 1.18 +- +--- signature/signature.go -- +-// Package signature has tests for signature help. +-package signature +- +-import ( +- "bytes" +- "encoding/json" +- "math/big" +-) +- +-func Foo(a string, b int) (c bool) { +- return +-} +- +-func Bar(float64, ...byte) { +-} +- +-type myStruct struct{} +- +-func (*myStruct) foo(e *json.Decoder) (*big.Int, error) { +- return nil, nil +-} +- +-type MyType struct{} +- +-type MyFunc func(foo int) string +- +-type Alias = int +-type OtherAlias = int +-type StringAlias = string +- +-func AliasSlice(a []*Alias) (b Alias) { return 0 } +-func AliasMap(a map[*Alias]StringAlias) (b, c map[*Alias]StringAlias) { return nil, nil } +-func OtherAliasMap(a, b map[Alias]OtherAlias) map[Alias]OtherAlias { return nil } +- +-func Qux() { +- Foo("foo", 123) //@signature("(", "Foo(a string, b int) (c bool)", 0) +- Foo("foo", 123) //@signature("123", "Foo(a string, b int) (c bool)", 1) +- Foo("foo", 123) //@signature(",", "Foo(a string, b int) (c bool)", 0) +- Foo("foo", 123) //@signature(" 1", "Foo(a string, b int) (c bool)", 1) +- Foo("foo", 123) //@signature(")", "Foo(a string, b int) (c bool)", 1) +- +- Bar(13.37, 0x13) //@signature("13.37", "Bar(float64, ...byte)", 0) +- Bar(13.37, 0x37) //@signature("0x37", "Bar(float64, ...byte)", 1) +- Bar(13.37, 1, 2, 3, 4) //@signature("4", "Bar(float64, ...byte)", 1) +- +- fn := func(hi, there string) func(i int) rune { +- return func(int) rune { return 0 } +- } +- +- fn("hi", "there") //@signature("hi", "", 0) +- fn("hi", "there") //@signature(",", "fn(hi string, there string) func(i int) rune", 0) +- fn("hi", "there")(1) //@signature("1", "func(i int) rune", 0) +- +- fnPtr := &fn +- (*fnPtr)("hi", "there") //@signature(",", "func(hi string, there string) func(i int) rune", 0) +- +- var fnIntf interface{} = Foo +- fnIntf.(func(string, int) bool)("hi", 123) //@signature("123", "func(string, int) bool", 1) +- +- (&bytes.Buffer{}).Next(2) //@signature("2", "Next(n int) []byte", 0) +- +- myFunc := MyFunc(func(n int) string { return "" }) +- myFunc(123) //@signature("123", "myFunc(foo int) string", 0) +- +- var ms myStruct +- ms.foo(nil) //@signature("nil", "foo(e *json.Decoder) (*big.Int, error)", 0) +- +- _ = make([]int, 1, 2) //@signature("2", "make(t Type, size ...int) Type", 1) +- +- Foo(myFunc(123), 456) //@signature("myFunc", "Foo(a string, b int) (c bool)", 0) +- Foo(myFunc(123), 456) //@signature("123", "myFunc(foo int) string", 0) +- +- panic("oops!") //@signature(")", "panic(v any)", 0) +- println("hello", "world") //@signature(",", "println(args ...Type)", 0) +- +- Hello(func() { +- //@signature("//", "", 0) +- }) +- +- AliasSlice() //@signature(")", "AliasSlice(a []*Alias) (b Alias)", 0) +- AliasMap() //@signature(")", "AliasMap(a map[*Alias]StringAlias) (b map[*Alias]StringAlias, c map[*Alias]StringAlias)", 0) +- OtherAliasMap() //@signature(")", "OtherAliasMap(a map[Alias]OtherAlias, b map[Alias]OtherAlias) map[Alias]OtherAlias", 0) +-} +- +-func Hello(func()) {} +- +--- signature/signature2.go -- +-package signature +- +-func _() { +- Foo(//@signature("//", "Foo(a string, b int) (c bool)", 0) +-} +- +--- signature/signature3.go -- +-package signature +- +-func _() { +- Foo("hello",//@signature("//", "Foo(a string, b int) (c bool)", 1) +-} +- +--- signature/signature_test.go -- +-package signature_test +- +-import ( +- "testing" +- +- sig "golang.org/lsptests/signature" +-) +- +-func TestSignature(t *testing.T) { +- sig.AliasSlice() //@signature(")", "AliasSlice(a []*sig.Alias) (b sig.Alias)", 0) +- sig.AliasMap() //@signature(")", "AliasMap(a map[*sig.Alias]sig.StringAlias) (b map[*sig.Alias]sig.StringAlias, c map[*sig.Alias]sig.StringAlias)", 0) +- sig.OtherAliasMap() //@signature(")", "OtherAliasMap(a map[sig.Alias]sig.OtherAlias, b map[sig.Alias]sig.OtherAlias) map[sig.Alias]sig.OtherAlias", 0) +-} +- +--- snippets/snippets.go -- +-package snippets +- +-import ( +- "golang.org/lsptests/signature" +-) +- +-type CoolAlias = int //@item(CoolAlias, "CoolAlias", "int", "type") +- +-type structy struct { +- x signature.MyType +-} +- +-func X(_ map[signature.Alias]CoolAlias) (map[signature.Alias]CoolAlias) { +- return nil +-} +- +-func _() { +- X() //@signature(")", "X(_ map[signature.Alias]CoolAlias) map[signature.Alias]CoolAlias", 0) +- _ = signature.MyType{} //@item(literalMyType, "signature.MyType{}", "", "var") +- s := structy{ +- x: //@snippet(" //", literalMyType, "signature.MyType{\\}") +- } +-} +- +--- importedcomplit/importedcomplit.go -- +-package importedcomplit +- +-import ( +- // TODO(rfindley): re-enable after moving to new framework +- // "golang.org/lsptests/foo" +- +- // import completions (separate blocks to avoid comment alignment) +- "crypto/elli" //@complete("\" //", cryptoImport) +- +- "fm" //@complete("\" //", fmtImport) +- +- "go/pars" //@complete("\" //", parserImport) +- +- namedParser "go/pars" //@complete("\" //", parserImport) +- +- "golang.org/lspte" //@complete("\" //", lsptestsImport) +- +- "golang.org/lsptests/sign" //@complete("\" //", signatureImport) +- +- "golang.org/lsptests/sign" //@complete("ests", lsptestsImport) +- +- "golang.org/lsptests/signa" //@complete("na\" //", signatureImport) +-) +- +-func _() { +- var V int //@item(icVVar, "V", "int", "var") +- +- // TODO(rfindley): re-enable after moving to new framework +- // _ = foo.StructFoo{V} // complete("}", Value, icVVar) +-} +- +-func _() { +- var ( +- aa string //@item(icAAVar, "aa", "string", "var") +- ab int //@item(icABVar, "ab", "int", "var") +- ) +- +- // TODO(rfindley): re-enable after moving to new framework +- // _ = foo.StructFoo{a} // complete("}", abVar, aaVar) +- +- var s struct { +- AA string //@item(icFieldAA, "AA", "string", "field") +- AB int //@item(icFieldAB, "AB", "int", "field") +- } +- +- // TODO(rfindley): re-enable after moving to new framework +- //_ = foo.StructFoo{s.} // complete("}", icFieldAB, icFieldAA) +-} +- +-/* "fmt" */ //@item(fmtImport, "fmt", "\"fmt\"", "package") +-/* "go/parser" */ //@item(parserImport, "parser", "\"go/parser\"", "package") +-/* "golang.org/lsptests/signature" */ //@item(signatureImport, "signature", "\"golang.org/lsptests/signature\"", "package") +-/* "golang.org/lsptests/" */ //@item(lsptestsImport, "lsptests/", "\"golang.org/lsptests/\"", "package") +-/* "crypto/elliptic" */ //@item(cryptoImport, "elliptic", "\"crypto/elliptic\"", "package") diff -urN a/gopls/internal/regtest/marker/testdata/stubmethods/basic.txt b/gopls/internal/regtest/marker/testdata/stubmethods/basic.txt --- a/gopls/internal/regtest/marker/testdata/stubmethods/basic.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/stubmethods/basic.txt 1970-01-01 08:00:00 -@@ -1,24 +0,0 @@ ++++ b/gopls/internal/regtest/marker/testdata/stubmethods/basic.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,23 +0,0 @@ -This test exercises basic 'stub methods' functionality. - --- go.mod -- @@ -126511,23 +126569,22 @@ diff -urN a/gopls/internal/regtest/marker/testdata/stubmethods/basic.txt b/gopls - -type C int - --var _ error = C(0) //@suggestedfix(re"C.0.", re"missing method Error", "quickfix", stub) -- +-var _ error = C(0) //@suggestedfix(re"C.0.", re"missing method Error", stub) --- @stub/a/a.go -- --package a -- --type C int -- --// Error implements error. --func (C) Error() string { -- panic("unimplemented") --} -- --var _ error = C(0) //@suggestedfix(re"C.0.", re"missing method Error", "quickfix", stub) +---- before +-+++ after +-@@ -3 +3,6 @@ +--type C int +-+type C int +-+ +-+// Error implements error. +-+func (C) Error() string { +-+ panic("unimplemented") +-+} diff -urN a/gopls/internal/regtest/marker/testdata/stubmethods/issue61693.txt b/gopls/internal/regtest/marker/testdata/stubmethods/issue61693.txt --- a/gopls/internal/regtest/marker/testdata/stubmethods/issue61693.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/stubmethods/issue61693.txt 1970-01-01 08:00:00 -@@ -1,35 +0,0 @@ ++++ b/gopls/internal/regtest/marker/testdata/stubmethods/issue61693.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,30 +0,0 @@ -This test exercises stub methods functionality with variadic parameters. - -In golang/go#61693 stubmethods was panicking in this case. @@ -126545,28 +126602,23 @@ diff -urN a/gopls/internal/regtest/marker/testdata/stubmethods/issue61693.txt b/ - -func _() { - var x error -- F(x, C(0)) //@suggestedfix(re"C.0.", re"missing method Error", "quickfix", stub) +- F(x, C(0)) //@suggestedfix(re"C.0.", re"missing method Error", stub) -} --- @stub/main.go -- --package main -- --type C int -- --// Error implements error. --func (C) Error() string { -- panic("unimplemented") --} -- --func F(err ...error) {} -- --func _() { -- var x error -- F(x, C(0)) //@suggestedfix(re"C.0.", re"missing method Error", "quickfix", stub) --} +---- before +-+++ after +-@@ -3 +3,6 @@ +--type C int +-+type C int +-+ +-+// Error implements error. +-+func (C) Error() string { +-+ panic("unimplemented") +-+} diff -urN a/gopls/internal/regtest/marker/testdata/stubmethods/issue61830.txt b/gopls/internal/regtest/marker/testdata/stubmethods/issue61830.txt --- a/gopls/internal/regtest/marker/testdata/stubmethods/issue61830.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/stubmethods/issue61830.txt 1970-01-01 08:00:00 -@@ -1,36 +0,0 @@ ++++ b/gopls/internal/regtest/marker/testdata/stubmethods/issue61830.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,28 +0,0 @@ -This test verifies that method stubbing qualifies types relative to the current -package. - @@ -126583,29 +126635,194 @@ diff -urN a/gopls/internal/regtest/marker/testdata/stubmethods/issue61830.txt b/ - -type A struct{} - --var _ I = &A{} //@suggestedfix(re"&A..", re"missing method M", "quickfix", stub) +-var _ I = &A{} //@suggestedfix(re"&A..", re"missing method M", stub) --- @stub/p.go -- +---- before +-+++ after +-@@ -11 +11,6 @@ +--type A struct{} +-+type A struct{} +-+ +-+// M implements I. +-+func (*A) M(io.Reader, B) { +-+ panic("unimplemented") +-+} +diff -urN a/gopls/internal/regtest/marker/testdata/suggestedfix/self_assignment.txt b/gopls/internal/regtest/marker/testdata/suggestedfix/self_assignment.txt +--- a/gopls/internal/regtest/marker/testdata/suggestedfix/self_assignment.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/suggestedfix/self_assignment.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,21 +0,0 @@ +-Test of the suggested fix to remove unnecessary assignments. +- +--- a.go -- +-package suggestedfix +- +-import ( +- "log" +-) +- +-func goodbye() { +- s := "hiiiiiii" +- s = s //@suggestedfix("s = s", re"self-assignment", fix) +- log.Print(s) +-} +- +--- @fix/a.go -- +---- before +-+++ after +-@@ -9 +9 @@ +-- s = s //@suggestedfix("s = s", re"self-assignment", fix) +-+ //@suggestedfix("s = s", re"self-assignment", fix) +diff -urN a/gopls/internal/regtest/marker/testdata/suggestedfix/undeclared.txt b/gopls/internal/regtest/marker/testdata/suggestedfix/undeclared.txt +--- a/gopls/internal/regtest/marker/testdata/suggestedfix/undeclared.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/suggestedfix/undeclared.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,54 +0,0 @@ +-Tests of suggested fixes for "undeclared name" diagnostics, +-which are of ("compiler", "error") type. +- +--- go.mod -- +-module example.com +-go 1.12 +- +--- a.go -- -package p - --import "io" +-func a() { +- z, _ := 1+y, 11 //@suggestedfix("y", re"(undeclared name|undefined): y", a) +- _ = z +-} - --type B struct{} +--- @a/a.go -- +---- before +-+++ after +-@@ -3 +3,2 @@ +--func a() { +-+func a() { +-+ y := +--- b.go -- +-package p - --type I interface { -- M(io.Reader, B) +-func b() { +- if 100 < 90 { +- } else if 100 > n+2 { //@suggestedfix("n", re"(undeclared name|undefined): n", b) +- } -} - --type A struct{} +--- @b/b.go -- +---- before +-+++ after +-@@ -3 +3,2 @@ +--func b() { +-+func b() { +-+ n := +--- c.go -- +-package p - --// M implements I. --func (*A) M(io.Reader, B) { -- panic("unimplemented") +-func c() { +- for i < 200 { //@suggestedfix("i", re"(undeclared name|undefined): i", c) +- } +- r() //@diag("r", re"(undeclared name|undefined): r") -} - --var _ I = &A{} //@suggestedfix(re"&A..", re"missing method M", "quickfix", stub) +--- @c/c.go -- +---- before +-+++ after +-@@ -3 +3,2 @@ +--func c() { +-+func c() { +-+ i := +diff -urN a/gopls/internal/regtest/marker/testdata/suggestedfix/unusedrequire_gowork.txt b/gopls/internal/regtest/marker/testdata/suggestedfix/unusedrequire_gowork.txt +--- a/gopls/internal/regtest/marker/testdata/suggestedfix/unusedrequire_gowork.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/suggestedfix/unusedrequire_gowork.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,55 +0,0 @@ +-This test checks the suggested fix to remove unused require statements from +-go.mod files, when a go.work file is used. +- +-Note that unlike unusedrequire.txt, we need not write go.sum files when +-a go.work file is used. +- +--- flags -- +--min_go=go1.18 +- +--- proxy/example.com@v1.0.0/x.go -- +-package pkg +-const X = 1 +- +--- go.work -- +-go 1.21 +- +-use ( +- ./a +- ./b +-) +--- a/go.mod -- +-module mod.com/a +- +-go 1.14 +- +-require example.com v1.0.0 //@suggestedfix("require", re"not used", a) +- +--- @a/a/go.mod -- +---- before +-+++ after +-@@ -4,3 +4 @@ +-- +--require example.com v1.0.0 //@suggestedfix("require", re"not used", a) +-- +--- a/main.go -- +-package main +-func main() {} +- +--- b/go.mod -- +-module mod.com/b +- +-go 1.14 +- +-require example.com v1.0.0 //@suggestedfix("require", re"not used", b) +- +--- @b/b/go.mod -- +---- before +-+++ after +-@@ -4,3 +4 @@ +-- +--require example.com v1.0.0 //@suggestedfix("require", re"not used", b) +-- +--- b/main.go -- +-package main +-func main() {} +diff -urN a/gopls/internal/regtest/marker/testdata/suggestedfix/unusedrequire.txt b/gopls/internal/regtest/marker/testdata/suggestedfix/unusedrequire.txt +--- a/gopls/internal/regtest/marker/testdata/suggestedfix/unusedrequire.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/suggestedfix/unusedrequire.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,27 +0,0 @@ +-This test checks the suggested fix to remove unused require statements from +-go.mod files. +- +--- flags -- +--write_sumfile=a +- +--- proxy/example.com@v1.0.0/x.go -- +-package pkg +-const X = 1 +- +--- a/go.mod -- +-module mod.com +- +-go 1.14 +- +-require example.com v1.0.0 //@suggestedfix("require", re"not used", a) +- +--- @a/a/go.mod -- +---- before +-+++ after +-@@ -4,3 +4 @@ +-- +--require example.com v1.0.0 //@suggestedfix("require", re"not used", a) +-- +--- a/main.go -- +-package main +-func main() {} diff -urN a/gopls/internal/regtest/marker/testdata/symbol/basic.txt b/gopls/internal/regtest/marker/testdata/symbol/basic.txt --- a/gopls/internal/regtest/marker/testdata/symbol/basic.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/symbol/basic.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/symbol/basic.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,114 +0,0 @@ -Basic tests of textDocument/documentSymbols. - @@ -126723,7 +126940,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/symbol/basic.txt b/gopls/inte -y "" diff -urN a/gopls/internal/regtest/marker/testdata/symbol/generic.txt b/gopls/internal/regtest/marker/testdata/symbol/generic.txt --- a/gopls/internal/regtest/marker/testdata/symbol/generic.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/symbol/generic.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/symbol/generic.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -Basic tests of textDocument/documentSymbols with generics. - @@ -126756,7 +126973,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/symbol/generic.txt b/gopls/in -T.F "P" diff -urN a/gopls/internal/regtest/marker/testdata/typedef/typedef.txt b/gopls/internal/regtest/marker/testdata/typedef/typedef.txt --- a/gopls/internal/regtest/marker/testdata/typedef/typedef.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/typedef/typedef.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/typedef/typedef.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -This test exercises the textDocument/typeDefinition action. - @@ -126828,7 +127045,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/typedef/typedef.txt b/gopls/i -} diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/allscope.txt b/gopls/internal/regtest/marker/testdata/workspacesymbol/allscope.txt --- a/gopls/internal/regtest/marker/testdata/workspacesymbol/allscope.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/allscope.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/allscope.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -This test verifies behavior when "symbolScope" is set to "all". - @@ -126862,7 +127079,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/allscope.txt -<unknown> fmt.Println Function diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/caseinsensitive.txt b/gopls/internal/regtest/marker/testdata/workspacesymbol/caseinsensitive.txt --- a/gopls/internal/regtest/marker/testdata/workspacesymbol/caseinsensitive.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/caseinsensitive.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/caseinsensitive.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -This file contains test for symbol matches using the caseinsensitive matcher. - @@ -126892,7 +127109,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/caseinsensiti -p.go:7:5-26 randomgopherVariableB Variable diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/casesensitive.txt b/gopls/internal/regtest/marker/testdata/workspacesymbol/casesensitive.txt --- a/gopls/internal/regtest/marker/testdata/workspacesymbol/casesensitive.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/casesensitive.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/casesensitive.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,116 +0,0 @@ -This file contains tests for symbol matches using the casesensitive matcher. - @@ -127012,7 +127229,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/casesensitive -main.go:45:2-10 main.embed.myStruct Field diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/issue44806.txt b/gopls/internal/regtest/marker/testdata/workspacesymbol/issue44806.txt --- a/gopls/internal/regtest/marker/testdata/workspacesymbol/issue44806.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/issue44806.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/issue44806.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -This test verifies the fix for the crash encountered in golang/go#44806. - @@ -127043,7 +127260,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/issue44806.tx -symbol.go:5:6-7 symbol.T Struct diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/workspacesymbol.txt b/gopls/internal/regtest/marker/testdata/workspacesymbol/workspacesymbol.txt --- a/gopls/internal/regtest/marker/testdata/workspacesymbol/workspacesymbol.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/workspacesymbol.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/workspacesymbol.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -This test contains tests for basic functionality of the workspace/symbol -request. @@ -127119,7 +127336,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/workspacesymb -b/b.go:6:2-5 RandomGopherStructB.Bar Field diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/wsscope.txt b/gopls/internal/regtest/marker/testdata/workspacesymbol/wsscope.txt --- a/gopls/internal/regtest/marker/testdata/workspacesymbol/wsscope.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/wsscope.txt 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/wsscope.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -This test verifies behavior when "symbolScope" is set to "workspace". - @@ -127152,7 +127369,7 @@ diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/wsscope.txt b -fmt/fmt.go:5:6-13 mod.test/symbols/fmt.Println Function diff -urN a/gopls/internal/regtest/misc/call_hierarchy_test.go b/gopls/internal/regtest/misc/call_hierarchy_test.go --- a/gopls/internal/regtest/misc/call_hierarchy_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/call_hierarchy_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/call_hierarchy_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -127191,8 +127408,8 @@ diff -urN a/gopls/internal/regtest/misc/call_hierarchy_test.go b/gopls/internal/ -} diff -urN a/gopls/internal/regtest/misc/configuration_test.go b/gopls/internal/regtest/misc/configuration_test.go --- a/gopls/internal/regtest/misc/configuration_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/configuration_test.go 1970-01-01 08:00:00 -@@ -1,153 +0,0 @@ ++++ b/gopls/internal/regtest/misc/configuration_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,157 +0,0 @@ -// Copyright 2020 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. @@ -127336,6 +127553,8 @@ diff -urN a/gopls/internal/regtest/misc/configuration_test.go b/gopls/internal/r - "experimentalUseInvalidMetadata": true, - "experimentalWatchedFileDelay": "1s", - "experimentalWorkspaceModule": true, +- "tempModfile": true, +- "expandWorkspaceToModule": false, - }, - ).Run(t, "", func(t *testing.T, env *Env) { - env.OnceMet( @@ -127343,12 +127562,14 @@ diff -urN a/gopls/internal/regtest/misc/configuration_test.go b/gopls/internal/r - ShownMessage("experimentalWorkspaceModule"), - ShownMessage("experimentalUseInvalidMetadata"), - ShownMessage("experimentalWatchedFileDelay"), +- ShownMessage("https://go.dev/issue/63537"), // issue to remove tempModfile +- ShownMessage("https://go.dev/issue/63536"), // issue to remove expandWorkspaceToModule - ) - }) -} diff -urN a/gopls/internal/regtest/misc/debugserver_test.go b/gopls/internal/regtest/misc/debugserver_test.go --- a/gopls/internal/regtest/misc/debugserver_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/debugserver_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/debugserver_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -127398,7 +127619,7 @@ diff -urN a/gopls/internal/regtest/misc/debugserver_test.go b/gopls/internal/reg -} diff -urN a/gopls/internal/regtest/misc/definition_test.go b/gopls/internal/regtest/misc/definition_test.go --- a/gopls/internal/regtest/misc/definition_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/definition_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/definition_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,571 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -127973,7 +128194,7 @@ diff -urN a/gopls/internal/regtest/misc/definition_test.go b/gopls/internal/regt -} diff -urN a/gopls/internal/regtest/misc/embed_test.go b/gopls/internal/regtest/misc/embed_test.go --- a/gopls/internal/regtest/misc/embed_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/embed_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/embed_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -128017,7 +128238,7 @@ diff -urN a/gopls/internal/regtest/misc/embed_test.go b/gopls/internal/regtest/m -} diff -urN a/gopls/internal/regtest/misc/extract_test.go b/gopls/internal/regtest/misc/extract_test.go --- a/gopls/internal/regtest/misc/extract_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/extract_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/extract_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -128086,7 +128307,7 @@ diff -urN a/gopls/internal/regtest/misc/extract_test.go b/gopls/internal/regtest -} diff -urN a/gopls/internal/regtest/misc/failures_test.go b/gopls/internal/regtest/misc/failures_test.go --- a/gopls/internal/regtest/misc/failures_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/failures_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/failures_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -128172,8 +128393,8 @@ diff -urN a/gopls/internal/regtest/misc/failures_test.go b/gopls/internal/regtes -} diff -urN a/gopls/internal/regtest/misc/fix_test.go b/gopls/internal/regtest/misc/fix_test.go --- a/gopls/internal/regtest/misc/fix_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/fix_test.go 1970-01-01 08:00:00 -@@ -1,103 +0,0 @@ ++++ b/gopls/internal/regtest/misc/fix_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,136 +0,0 @@ -// Copyright 2020 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. @@ -128277,9 +128498,42 @@ diff -urN a/gopls/internal/regtest/misc/fix_test.go b/gopls/internal/regtest/mis - env.AfterChange(NoDiagnostics(ForFile("main.go"))) - }) -} +- +-func TestUnusedParameter_Issue63755(t *testing.T) { +- // This test verifies the fix for #63755, where codeActions panicked on parameters +- // of functions with no function body. +- +- // We should not detect parameters as unused for external functions. +- +- const files = ` +--- go.mod -- +-module unused.mod +- +-go 1.18 +- +--- external.go -- +-package external +- +-func External(z int) //@codeaction("refactor.rewrite", "z", "z", recursive) +- +-func _() { +- External(1) +-} +- ` +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("external.go") +- actions, err := env.Editor.CodeAction(env.Ctx, env.RegexpSearch("external.go", "z"), nil) +- if err != nil { +- t.Fatal(err) +- } +- if len(actions) > 0 { +- t.Errorf("CodeAction(): got %d code actions, want 0", len(actions)) +- } +- }) +-} diff -urN a/gopls/internal/regtest/misc/formatting_test.go b/gopls/internal/regtest/misc/formatting_test.go --- a/gopls/internal/regtest/misc/formatting_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/formatting_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/formatting_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,395 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -128678,7 +128932,7 @@ diff -urN a/gopls/internal/regtest/misc/formatting_test.go b/gopls/internal/regt -} diff -urN a/gopls/internal/regtest/misc/generate_test.go b/gopls/internal/regtest/misc/generate_test.go --- a/gopls/internal/regtest/misc/generate_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/generate_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/generate_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,71 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -128753,7 +129007,7 @@ diff -urN a/gopls/internal/regtest/misc/generate_test.go b/gopls/internal/regtes -} diff -urN a/gopls/internal/regtest/misc/highlight_test.go b/gopls/internal/regtest/misc/highlight_test.go --- a/gopls/internal/regtest/misc/highlight_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/highlight_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/highlight_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -128910,7 +129164,7 @@ diff -urN a/gopls/internal/regtest/misc/highlight_test.go b/gopls/internal/regte -} diff -urN a/gopls/internal/regtest/misc/hover_test.go b/gopls/internal/regtest/misc/hover_test.go --- a/gopls/internal/regtest/misc/hover_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/hover_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/hover_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,493 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -129405,146 +129659,9 @@ diff -urN a/gopls/internal/regtest/misc/hover_test.go b/gopls/internal/regtest/m - } - }) -} -diff -urN a/gopls/internal/regtest/misc/import_test.go b/gopls/internal/regtest/misc/import_test.go ---- a/gopls/internal/regtest/misc/import_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/import_test.go 1970-01-01 08:00:00 -@@ -1,133 +0,0 @@ --// Copyright 2021 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 misc -- --import ( -- "testing" -- -- "github.com/google/go-cmp/cmp" -- "golang.org/x/tools/gopls/internal/lsp/command" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/gopls/internal/lsp/tests/compare" --) -- --func TestAddImport(t *testing.T) { -- const before = `package main -- --import "fmt" -- --func main() { -- fmt.Println("hello world") --} --` -- -- const want = `package main -- --import ( -- "bytes" -- "fmt" --) -- --func main() { -- fmt.Println("hello world") --} --` -- -- Run(t, "", func(t *testing.T, env *Env) { -- env.CreateBuffer("main.go", before) -- cmd, err := command.NewAddImportCommand("Add Import", command.AddImportArgs{ -- URI: env.Sandbox.Workdir.URI("main.go"), -- ImportPath: "bytes", -- }) -- if err != nil { -- t.Fatal(err) -- } -- env.ExecuteCommand(&protocol.ExecuteCommandParams{ -- Command: "gopls.add_import", -- Arguments: cmd.Arguments, -- }, nil) -- got := env.BufferText("main.go") -- if got != want { -- t.Fatalf("gopls.add_import failed\n%s", compare.Text(want, got)) -- } -- }) --} -- --func TestListImports(t *testing.T) { -- const files = ` ---- go.mod -- --module mod.com -- --go 1.12 ---- foo.go -- --package foo --const C = 1 ---- import_strings_test.go -- --package foo --import ( -- x "strings" -- "testing" --) -- --func TestFoo(t *testing.T) {} ---- import_testing_test.go -- --package foo -- --import "testing" -- --func TestFoo2(t *testing.T) {} --` -- tests := []struct { -- filename string -- want command.ListImportsResult -- }{ -- { -- filename: "import_strings_test.go", -- want: command.ListImportsResult{ -- Imports: []command.FileImport{ -- {Name: "x", Path: "strings"}, -- {Path: "testing"}, -- }, -- PackageImports: []command.PackageImport{ -- {Path: "strings"}, -- {Path: "testing"}, -- }, -- }, -- }, -- { -- filename: "import_testing_test.go", -- want: command.ListImportsResult{ -- Imports: []command.FileImport{ -- {Path: "testing"}, -- }, -- PackageImports: []command.PackageImport{ -- {Path: "strings"}, -- {Path: "testing"}, -- }, -- }, -- }, -- } -- -- Run(t, files, func(t *testing.T, env *Env) { -- for _, tt := range tests { -- cmd, err := command.NewListImportsCommand("List Imports", command.URIArg{ -- URI: env.Sandbox.Workdir.URI(tt.filename), -- }) -- if err != nil { -- t.Fatal(err) -- } -- var result command.ListImportsResult -- env.ExecuteCommand(&protocol.ExecuteCommandParams{ -- Command: command.ListImports.ID(), -- Arguments: cmd.Arguments, -- }, &result) -- if diff := cmp.Diff(tt.want, result); diff != "" { -- t.Errorf("unexpected list imports result for %q (-want +got):\n%s", tt.filename, diff) -- } -- } -- -- }) --} diff -urN a/gopls/internal/regtest/misc/imports_test.go b/gopls/internal/regtest/misc/imports_test.go --- a/gopls/internal/regtest/misc/imports_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/imports_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/imports_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,286 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -129832,9 +129949,146 @@ diff -urN a/gopls/internal/regtest/misc/imports_test.go b/gopls/internal/regtest - env.AfterChange(NoDiagnostics(ForFile("caller/caller.go"))) - }) -} +diff -urN a/gopls/internal/regtest/misc/import_test.go b/gopls/internal/regtest/misc/import_test.go +--- a/gopls/internal/regtest/misc/import_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/misc/import_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,133 +0,0 @@ +-// Copyright 2021 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 misc +- +-import ( +- "testing" +- +- "github.com/google/go-cmp/cmp" +- "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +- "golang.org/x/tools/gopls/internal/lsp/tests/compare" +-) +- +-func TestAddImport(t *testing.T) { +- const before = `package main +- +-import "fmt" +- +-func main() { +- fmt.Println("hello world") +-} +-` +- +- const want = `package main +- +-import ( +- "bytes" +- "fmt" +-) +- +-func main() { +- fmt.Println("hello world") +-} +-` +- +- Run(t, "", func(t *testing.T, env *Env) { +- env.CreateBuffer("main.go", before) +- cmd, err := command.NewAddImportCommand("Add Import", command.AddImportArgs{ +- URI: env.Sandbox.Workdir.URI("main.go"), +- ImportPath: "bytes", +- }) +- if err != nil { +- t.Fatal(err) +- } +- env.ExecuteCommand(&protocol.ExecuteCommandParams{ +- Command: "gopls.add_import", +- Arguments: cmd.Arguments, +- }, nil) +- got := env.BufferText("main.go") +- if got != want { +- t.Fatalf("gopls.add_import failed\n%s", compare.Text(want, got)) +- } +- }) +-} +- +-func TestListImports(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com +- +-go 1.12 +--- foo.go -- +-package foo +-const C = 1 +--- import_strings_test.go -- +-package foo +-import ( +- x "strings" +- "testing" +-) +- +-func TestFoo(t *testing.T) {} +--- import_testing_test.go -- +-package foo +- +-import "testing" +- +-func TestFoo2(t *testing.T) {} +-` +- tests := []struct { +- filename string +- want command.ListImportsResult +- }{ +- { +- filename: "import_strings_test.go", +- want: command.ListImportsResult{ +- Imports: []command.FileImport{ +- {Name: "x", Path: "strings"}, +- {Path: "testing"}, +- }, +- PackageImports: []command.PackageImport{ +- {Path: "strings"}, +- {Path: "testing"}, +- }, +- }, +- }, +- { +- filename: "import_testing_test.go", +- want: command.ListImportsResult{ +- Imports: []command.FileImport{ +- {Path: "testing"}, +- }, +- PackageImports: []command.PackageImport{ +- {Path: "strings"}, +- {Path: "testing"}, +- }, +- }, +- }, +- } +- +- Run(t, files, func(t *testing.T, env *Env) { +- for _, tt := range tests { +- cmd, err := command.NewListImportsCommand("List Imports", command.URIArg{ +- URI: env.Sandbox.Workdir.URI(tt.filename), +- }) +- if err != nil { +- t.Fatal(err) +- } +- var result command.ListImportsResult +- env.ExecuteCommand(&protocol.ExecuteCommandParams{ +- Command: command.ListImports.ID(), +- Arguments: cmd.Arguments, +- }, &result) +- if diff := cmp.Diff(tt.want, result); diff != "" { +- t.Errorf("unexpected list imports result for %q (-want +got):\n%s", tt.filename, diff) +- } +- } +- +- }) +-} diff -urN a/gopls/internal/regtest/misc/link_test.go b/gopls/internal/regtest/misc/link_test.go --- a/gopls/internal/regtest/misc/link_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/link_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/link_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -129934,7 +130188,7 @@ diff -urN a/gopls/internal/regtest/misc/link_test.go b/gopls/internal/regtest/mi -} diff -urN a/gopls/internal/regtest/misc/misc_test.go b/gopls/internal/regtest/misc/misc_test.go --- a/gopls/internal/regtest/misc/misc_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/misc_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/misc_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -129956,7 +130210,7 @@ diff -urN a/gopls/internal/regtest/misc/misc_test.go b/gopls/internal/regtest/mi -} diff -urN a/gopls/internal/regtest/misc/multiple_adhoc_test.go b/gopls/internal/regtest/misc/multiple_adhoc_test.go --- a/gopls/internal/regtest/misc/multiple_adhoc_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/multiple_adhoc_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/multiple_adhoc_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -130004,7 +130258,7 @@ diff -urN a/gopls/internal/regtest/misc/multiple_adhoc_test.go b/gopls/internal/ -} diff -urN a/gopls/internal/regtest/misc/prompt_test.go b/gopls/internal/regtest/misc/prompt_test.go --- a/gopls/internal/regtest/misc/prompt_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/prompt_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/prompt_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,231 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -130239,7 +130493,7 @@ diff -urN a/gopls/internal/regtest/misc/prompt_test.go b/gopls/internal/regtest/ -} diff -urN a/gopls/internal/regtest/misc/references_test.go b/gopls/internal/regtest/misc/references_test.go --- a/gopls/internal/regtest/misc/references_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/references_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/references_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,581 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -130824,7 +131078,7 @@ diff -urN a/gopls/internal/regtest/misc/references_test.go b/gopls/internal/regt -} diff -urN a/gopls/internal/regtest/misc/rename_test.go b/gopls/internal/regtest/misc/rename_test.go --- a/gopls/internal/regtest/misc/rename_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/rename_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/rename_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,935 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -131763,7 +132017,7 @@ diff -urN a/gopls/internal/regtest/misc/rename_test.go b/gopls/internal/regtest/ -} diff -urN a/gopls/internal/regtest/misc/semantictokens_test.go b/gopls/internal/regtest/misc/semantictokens_test.go --- a/gopls/internal/regtest/misc/semantictokens_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/semantictokens_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/semantictokens_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,204 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -131772,11 +132026,10 @@ diff -urN a/gopls/internal/regtest/misc/semantictokens_test.go b/gopls/internal/ -package misc - -import ( -- "strings" - "testing" - - "github.com/google/go-cmp/cmp" -- "golang.org/x/tools/gopls/internal/lsp" +- "golang.org/x/tools/gopls/internal/lsp/fake" - "golang.org/x/tools/gopls/internal/lsp/protocol" - . "golang.org/x/tools/gopls/internal/lsp/regtest" - "golang.org/x/tools/internal/typeparams" @@ -131815,31 +132068,30 @@ diff -urN a/gopls/internal/regtest/misc/semantictokens_test.go b/gopls/internal/ -// fix bug involving type parameters and regular parameters -// (golang/vscode-go#2527) -func TestSemantic_2527(t *testing.T) { -- if !typeparams.Enabled { -- t.Skip("type parameters are needed for this test") -- } - // these are the expected types of identifiers in text order -- want := []result{ -- {"package", "keyword", ""}, -- {"foo", "namespace", ""}, -- {"func", "keyword", ""}, -- {"Add", "function", "definition deprecated"}, -- {"T", "typeParameter", "definition"}, -- {"int", "type", "defaultLibrary"}, -- {"target", "parameter", "definition"}, -- {"T", "typeParameter", ""}, -- {"l", "parameter", "definition"}, -- {"T", "typeParameter", ""}, -- {"T", "typeParameter", ""}, -- {"return", "keyword", ""}, -- {"append", "function", "defaultLibrary"}, -- {"l", "parameter", ""}, -- {"target", "parameter", ""}, -- {"for", "keyword", ""}, -- {"range", "keyword", ""}, -- {"l", "parameter", ""}, -- {"return", "keyword", ""}, -- {"nil", "variable", "readonly defaultLibrary"}, +- want := []fake.SemanticToken{ +- {Token: "package", TokenType: "keyword"}, +- {Token: "foo", TokenType: "namespace"}, +- {Token: "// Deprecated (for testing)", TokenType: "comment"}, +- {Token: "func", TokenType: "keyword"}, +- {Token: "Add", TokenType: "function", Mod: "definition deprecated"}, +- {Token: "T", TokenType: "typeParameter", Mod: "definition"}, +- {Token: "int", TokenType: "type", Mod: "defaultLibrary"}, +- {Token: "target", TokenType: "parameter", Mod: "definition"}, +- {Token: "T", TokenType: "typeParameter"}, +- {Token: "l", TokenType: "parameter", Mod: "definition"}, +- {Token: "T", TokenType: "typeParameter"}, +- {Token: "T", TokenType: "typeParameter"}, +- {Token: "return", TokenType: "keyword"}, +- {Token: "append", TokenType: "function", Mod: "defaultLibrary"}, +- {Token: "l", TokenType: "parameter"}, +- {Token: "target", TokenType: "parameter"}, +- {Token: "for", TokenType: "keyword"}, +- {Token: "range", TokenType: "keyword"}, +- {Token: "l", TokenType: "parameter"}, +- {Token: "// test coverage", TokenType: "comment"}, +- {Token: "return", TokenType: "keyword"}, +- {Token: "nil", TokenType: "variable", Mod: "readonly defaultLibrary"}, - } - src := ` --- go.mod -- @@ -131863,16 +132115,10 @@ diff -urN a/gopls/internal/regtest/misc/semantictokens_test.go b/gopls/internal/ - env.AfterChange( - Diagnostics(env.AtRegexp("main.go", "for range")), - ) -- p := &protocol.SemanticTokensParams{ -- TextDocument: protocol.TextDocumentIdentifier{ -- URI: env.Sandbox.Workdir.URI("main.go"), -- }, -- } -- v, err := env.Editor.Server.SemanticTokensFull(env.Ctx, p) +- seen, err := env.Editor.SemanticTokens(env.Ctx, "main.go") - if err != nil { - t.Fatal(err) - } -- seen := interpret(v.Data, env.BufferText("main.go")) - if x := cmp.Diff(want, seen); x != "" { - t.Errorf("Semantic tokens do not match (-want +got):\n%s", x) - } @@ -131909,16 +132155,10 @@ diff -urN a/gopls/internal/regtest/misc/semantictokens_test.go b/gopls/internal/ - Settings{"semanticTokens": true}, - ).Run(t, src, func(t *testing.T, env *Env) { - env.OpenFile("main.go") -- p := &protocol.SemanticTokensParams{ -- TextDocument: protocol.TextDocumentIdentifier{ -- URI: env.Sandbox.Workdir.URI("main.go"), -- }, -- } -- v, err := env.Editor.Server.SemanticTokensFull(env.Ctx, p) +- seen, err := env.Editor.SemanticTokens(env.Ctx, "main.go") - if err != nil { - t.Fatal(err) - } -- seen := interpret(v.Data, env.BufferText("main.go")) - for i, s := range seen { - if (s.Token == "K" || s.Token == "V") && s.TokenType != "typeParameter" { - t.Errorf("%d: expected K and V to be type parameters, but got %v", i, s) @@ -131927,51 +132167,65 @@ diff -urN a/gopls/internal/regtest/misc/semantictokens_test.go b/gopls/internal/ - }) -} - --type result struct { -- Token string -- TokenType string -- Mod string --} +-func TestSemanticGoDirectives(t *testing.T) { +- src := ` +--- go.mod -- +-module example.com - --// human-readable version of the semantic tokens --// comment, string, number are elided --// (and in the future, maybe elide other things, like operators) --func interpret(x []uint32, contents string) []result { -- lines := strings.Split(contents, "\n") -- ans := []result{} -- line, col := 1, 1 -- for i := 0; i < len(x); i += 5 { -- line += int(x[i]) -- col += int(x[i+1]) -- if x[i] != 0 { // new line -- col = int(x[i+1]) + 1 // 1-based column numbers -- } -- sz := x[i+2] -- t := semanticTypes[x[i+3]] -- if t == "comment" || t == "string" || t == "number" { -- continue +-go 1.19 +--- main.go -- +-package foo +- +-//go:linkname now time.Now +-func now() +- +-//go:noinline +-func foo() {} +- +-// Mentioning go:noinline should not tokenize. +- +-//go:notadirective +-func bar() {} +-` +- want := []fake.SemanticToken{ +- {Token: "package", TokenType: "keyword"}, +- {Token: "foo", TokenType: "namespace"}, +- +- {Token: "//", TokenType: "comment"}, +- {Token: "go:linkname", TokenType: "namespace"}, +- {Token: "now time.Now", TokenType: "comment"}, +- {Token: "func", TokenType: "keyword"}, +- {Token: "now", TokenType: "function", Mod: "definition"}, +- +- {Token: "//", TokenType: "comment"}, +- {Token: "go:noinline", TokenType: "namespace"}, +- {Token: "func", TokenType: "keyword"}, +- {Token: "foo", TokenType: "function", Mod: "definition"}, +- +- {Token: "// Mentioning go:noinline should not tokenize.", TokenType: "comment"}, +- +- {Token: "//go:notadirective", TokenType: "comment"}, +- {Token: "func", TokenType: "keyword"}, +- {Token: "bar", TokenType: "function", Mod: "definition"}, +- } +- +- WithOptions( +- Modes(Default), +- Settings{"semanticTokens": true}, +- ).Run(t, src, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- seen, err := env.Editor.SemanticTokens(env.Ctx, "main.go") +- if err != nil { +- t.Fatal(err) - } -- l := x[i+4] -- var mods []string -- for i, mod := range semanticModifiers { -- if l&(1<<i) != 0 { -- mods = append(mods, mod) -- } +- if x := cmp.Diff(want, seen); x != "" { +- t.Errorf("Semantic tokens do not match (-want +got):\n%s", x) - } -- // col is a utf-8 offset -- tok := lines[line-1][col-1 : col-1+int(sz)] -- ans = append(ans, result{tok, t, strings.Join(mods, " ")}) -- } -- return ans +- }) -} -- --var ( -- semanticTypes = lsp.SemanticTypes() -- semanticModifiers = lsp.SemanticModifiers() --) diff -urN a/gopls/internal/regtest/misc/settings_test.go b/gopls/internal/regtest/misc/settings_test.go --- a/gopls/internal/regtest/misc/settings_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/settings_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/settings_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -132007,7 +132261,7 @@ diff -urN a/gopls/internal/regtest/misc/settings_test.go b/gopls/internal/regtes -} diff -urN a/gopls/internal/regtest/misc/shared_test.go b/gopls/internal/regtest/misc/shared_test.go --- a/gopls/internal/regtest/misc/shared_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/shared_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/shared_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -132083,7 +132337,7 @@ diff -urN a/gopls/internal/regtest/misc/shared_test.go b/gopls/internal/regtest/ -} diff -urN a/gopls/internal/regtest/misc/signature_help_test.go b/gopls/internal/regtest/misc/signature_help_test.go --- a/gopls/internal/regtest/misc/signature_help_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/signature_help_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/signature_help_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -132156,7 +132410,7 @@ diff -urN a/gopls/internal/regtest/misc/signature_help_test.go b/gopls/internal/ -} diff -urN a/gopls/internal/regtest/misc/staticcheck_test.go b/gopls/internal/regtest/misc/staticcheck_test.go --- a/gopls/internal/regtest/misc/staticcheck_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/staticcheck_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/staticcheck_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,110 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -132270,7 +132524,7 @@ diff -urN a/gopls/internal/regtest/misc/staticcheck_test.go b/gopls/internal/reg -} diff -urN a/gopls/internal/regtest/misc/vendor_test.go b/gopls/internal/regtest/misc/vendor_test.go --- a/gopls/internal/regtest/misc/vendor_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/vendor_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/vendor_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -132377,7 +132631,7 @@ diff -urN a/gopls/internal/regtest/misc/vendor_test.go b/gopls/internal/regtest/ -} diff -urN a/gopls/internal/regtest/misc/vuln_test.go b/gopls/internal/regtest/misc/vuln_test.go --- a/gopls/internal/regtest/misc/vuln_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/vuln_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/vuln_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,952 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -133333,7 +133587,7 @@ diff -urN a/gopls/internal/regtest/misc/vuln_test.go b/gopls/internal/regtest/mi -} diff -urN a/gopls/internal/regtest/misc/workspace_symbol_test.go b/gopls/internal/regtest/misc/workspace_symbol_test.go --- a/gopls/internal/regtest/misc/workspace_symbol_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/workspace_symbol_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/misc/workspace_symbol_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,114 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -133451,7 +133705,7 @@ diff -urN a/gopls/internal/regtest/misc/workspace_symbol_test.go b/gopls/interna -} diff -urN a/gopls/internal/regtest/modfile/modfile_test.go b/gopls/internal/regtest/modfile/modfile_test.go --- a/gopls/internal/regtest/modfile/modfile_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/modfile/modfile_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/modfile/modfile_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,1222 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -134677,7 +134931,7 @@ diff -urN a/gopls/internal/regtest/modfile/modfile_test.go b/gopls/internal/regt -} diff -urN a/gopls/internal/regtest/modfile/tempmodfile_test.go b/gopls/internal/regtest/modfile/tempmodfile_test.go --- a/gopls/internal/regtest/modfile/tempmodfile_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/modfile/tempmodfile_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/modfile/tempmodfile_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -134722,7 +134976,7 @@ diff -urN a/gopls/internal/regtest/modfile/tempmodfile_test.go b/gopls/internal/ -} diff -urN a/gopls/internal/regtest/template/template_test.go b/gopls/internal/regtest/template/template_test.go --- a/gopls/internal/regtest/template/template_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/template/template_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/template/template_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,231 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -134957,7 +135211,7 @@ diff -urN a/gopls/internal/regtest/template/template_test.go b/gopls/internal/re -// Hover needs tests diff -urN a/gopls/internal/regtest/watch/setting_test.go b/gopls/internal/regtest/watch/setting_test.go --- a/gopls/internal/regtest/watch/setting_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/watch/setting_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/watch/setting_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -135046,7 +135300,7 @@ diff -urN a/gopls/internal/regtest/watch/setting_test.go b/gopls/internal/regtes -} diff -urN a/gopls/internal/regtest/watch/watch_test.go b/gopls/internal/regtest/watch/watch_test.go --- a/gopls/internal/regtest/watch/watch_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/watch/watch_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/watch/watch_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,704 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -135754,7 +136008,7 @@ diff -urN a/gopls/internal/regtest/watch/watch_test.go b/gopls/internal/regtest/ -} diff -urN a/gopls/internal/regtest/workspace/adhoc_test.go b/gopls/internal/regtest/workspace/adhoc_test.go --- a/gopls/internal/regtest/workspace/adhoc_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/workspace/adhoc_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/workspace/adhoc_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -135800,7 +136054,7 @@ diff -urN a/gopls/internal/regtest/workspace/adhoc_test.go b/gopls/internal/regt -} diff -urN a/gopls/internal/regtest/workspace/broken_test.go b/gopls/internal/regtest/workspace/broken_test.go --- a/gopls/internal/regtest/workspace/broken_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/workspace/broken_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/workspace/broken_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,263 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -136067,7 +136321,7 @@ diff -urN a/gopls/internal/regtest/workspace/broken_test.go b/gopls/internal/reg -} diff -urN a/gopls/internal/regtest/workspace/directoryfilters_test.go b/gopls/internal/regtest/workspace/directoryfilters_test.go --- a/gopls/internal/regtest/workspace/directoryfilters_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/workspace/directoryfilters_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/workspace/directoryfilters_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,259 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -136330,7 +136584,7 @@ diff -urN a/gopls/internal/regtest/workspace/directoryfilters_test.go b/gopls/in -} diff -urN a/gopls/internal/regtest/workspace/fromenv_test.go b/gopls/internal/regtest/workspace/fromenv_test.go --- a/gopls/internal/regtest/workspace/fromenv_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/workspace/fromenv_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/workspace/fromenv_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,79 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -136413,7 +136667,7 @@ diff -urN a/gopls/internal/regtest/workspace/fromenv_test.go b/gopls/internal/re -} diff -urN a/gopls/internal/regtest/workspace/metadata_test.go b/gopls/internal/regtest/workspace/metadata_test.go --- a/gopls/internal/regtest/workspace/metadata_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/workspace/metadata_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/workspace/metadata_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,245 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -136662,7 +136916,7 @@ diff -urN a/gopls/internal/regtest/workspace/metadata_test.go b/gopls/internal/r -} diff -urN a/gopls/internal/regtest/workspace/misspelling_test.go b/gopls/internal/regtest/workspace/misspelling_test.go --- a/gopls/internal/regtest/workspace/misspelling_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/workspace/misspelling_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/workspace/misspelling_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -136746,7 +137000,7 @@ diff -urN a/gopls/internal/regtest/workspace/misspelling_test.go b/gopls/interna -} diff -urN a/gopls/internal/regtest/workspace/quickfix_test.go b/gopls/internal/regtest/workspace/quickfix_test.go --- a/gopls/internal/regtest/workspace/quickfix_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/workspace/quickfix_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/workspace/quickfix_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,342 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -137092,7 +137346,7 @@ diff -urN a/gopls/internal/regtest/workspace/quickfix_test.go b/gopls/internal/r -} diff -urN a/gopls/internal/regtest/workspace/standalone_test.go b/gopls/internal/regtest/workspace/standalone_test.go --- a/gopls/internal/regtest/workspace/standalone_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/workspace/standalone_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/workspace/standalone_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,206 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -137302,7 +137556,7 @@ diff -urN a/gopls/internal/regtest/workspace/standalone_test.go b/gopls/internal -} diff -urN a/gopls/internal/regtest/workspace/workspace_test.go b/gopls/internal/regtest/workspace/workspace_test.go --- a/gopls/internal/regtest/workspace/workspace_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/workspace/workspace_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/regtest/workspace/workspace_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,1258 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -138564,7 +138818,7 @@ diff -urN a/gopls/internal/regtest/workspace/workspace_test.go b/gopls/internal/ -} diff -urN a/gopls/internal/span/parse.go b/gopls/internal/span/parse.go --- a/gopls/internal/span/parse.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/span/parse.go 1970-01-01 08:00:00 ++++ b/gopls/internal/span/parse.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,114 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -138682,7 +138936,7 @@ diff -urN a/gopls/internal/span/parse.go b/gopls/internal/span/parse.go -} diff -urN a/gopls/internal/span/span.go b/gopls/internal/span/span.go --- a/gopls/internal/span/span.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/span/span.go 1970-01-01 08:00:00 ++++ b/gopls/internal/span/span.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,249 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -138935,7 +139189,7 @@ diff -urN a/gopls/internal/span/span.go b/gopls/internal/span/span.go -} diff -urN a/gopls/internal/span/span_test.go b/gopls/internal/span/span_test.go --- a/gopls/internal/span/span_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/span/span_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/span/span_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -138996,7 +139250,7 @@ diff -urN a/gopls/internal/span/span_test.go b/gopls/internal/span/span_test.go -} diff -urN a/gopls/internal/span/uri.go b/gopls/internal/span/uri.go --- a/gopls/internal/span/uri.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/span/uri.go 1970-01-01 08:00:00 ++++ b/gopls/internal/span/uri.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,177 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -139177,7 +139431,7 @@ diff -urN a/gopls/internal/span/uri.go b/gopls/internal/span/uri.go -} diff -urN a/gopls/internal/span/uri_test.go b/gopls/internal/span/uri_test.go --- a/gopls/internal/span/uri_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/span/uri_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/span/uri_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -139298,7 +139552,7 @@ diff -urN a/gopls/internal/span/uri_test.go b/gopls/internal/span/uri_test.go -} diff -urN a/gopls/internal/span/uri_windows_test.go b/gopls/internal/span/uri_windows_test.go --- a/gopls/internal/span/uri_windows_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/span/uri_windows_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/span/uri_windows_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -139414,7 +139668,7 @@ diff -urN a/gopls/internal/span/uri_windows_test.go b/gopls/internal/span/uri_wi -} diff -urN a/gopls/internal/telemetry/latency.go b/gopls/internal/telemetry/latency.go --- a/gopls/internal/telemetry/latency.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/telemetry/latency.go 1970-01-01 08:00:00 ++++ b/gopls/internal/telemetry/latency.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,102 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -139520,7 +139774,7 @@ diff -urN a/gopls/internal/telemetry/latency.go b/gopls/internal/telemetry/laten -} diff -urN a/gopls/internal/telemetry/telemetry.go b/gopls/internal/telemetry/telemetry.go --- a/gopls/internal/telemetry/telemetry.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/telemetry/telemetry.go 1970-01-01 08:00:00 ++++ b/gopls/internal/telemetry/telemetry.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -139617,7 +139871,7 @@ diff -urN a/gopls/internal/telemetry/telemetry.go b/gopls/internal/telemetry/tel -} diff -urN a/gopls/internal/telemetry/telemetry_go118.go b/gopls/internal/telemetry/telemetry_go118.go --- a/gopls/internal/telemetry/telemetry_go118.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/telemetry/telemetry_go118.go 1970-01-01 08:00:00 ++++ b/gopls/internal/telemetry/telemetry_go118.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -139651,7 +139905,7 @@ diff -urN a/gopls/internal/telemetry/telemetry_go118.go b/gopls/internal/telemet -} diff -urN a/gopls/internal/telemetry/telemetry_test.go b/gopls/internal/telemetry/telemetry_test.go --- a/gopls/internal/telemetry/telemetry_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/telemetry/telemetry_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/telemetry/telemetry_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,215 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -139870,7 +140124,7 @@ diff -urN a/gopls/internal/telemetry/telemetry_test.go b/gopls/internal/telemetr -} diff -urN a/gopls/internal/vulncheck/copier.go b/gopls/internal/vulncheck/copier.go --- a/gopls/internal/vulncheck/copier.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/copier.go 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/copier.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,142 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -140016,7 +140270,7 @@ diff -urN a/gopls/internal/vulncheck/copier.go b/gopls/internal/vulncheck/copier -} diff -urN a/gopls/internal/vulncheck/govulncheck/govulncheck.go b/gopls/internal/vulncheck/govulncheck/govulncheck.go --- a/gopls/internal/vulncheck/govulncheck/govulncheck.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/govulncheck/govulncheck.go 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/govulncheck/govulncheck.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,160 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -140180,7 +140434,7 @@ diff -urN a/gopls/internal/vulncheck/govulncheck/govulncheck.go b/gopls/internal -func (l ScanLevel) WantSymbols() bool { return l == scanLevelSymbol } diff -urN a/gopls/internal/vulncheck/govulncheck/handler.go b/gopls/internal/vulncheck/govulncheck/handler.go --- a/gopls/internal/vulncheck/govulncheck/handler.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/govulncheck/handler.go 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/govulncheck/handler.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -140245,7 +140499,7 @@ diff -urN a/gopls/internal/vulncheck/govulncheck/handler.go b/gopls/internal/vul -} diff -urN a/gopls/internal/vulncheck/govulncheck/jsonhandler.go b/gopls/internal/vulncheck/govulncheck/jsonhandler.go --- a/gopls/internal/vulncheck/govulncheck/jsonhandler.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/govulncheck/jsonhandler.go 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/govulncheck/jsonhandler.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -140295,7 +140549,7 @@ diff -urN a/gopls/internal/vulncheck/govulncheck/jsonhandler.go b/gopls/internal -} diff -urN a/gopls/internal/vulncheck/osv/osv.go b/gopls/internal/vulncheck/osv/osv.go --- a/gopls/internal/vulncheck/osv/osv.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/osv/osv.go 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/osv/osv.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,240 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -140539,7 +140793,7 @@ diff -urN a/gopls/internal/vulncheck/osv/osv.go b/gopls/internal/vulncheck/osv/o -} diff -urN a/gopls/internal/vulncheck/scan/command.go b/gopls/internal/vulncheck/scan/command.go --- a/gopls/internal/vulncheck/scan/command.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/scan/command.go 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/scan/command.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,476 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -141019,7 +141273,7 @@ diff -urN a/gopls/internal/vulncheck/scan/command.go b/gopls/internal/vulncheck/ -} diff -urN a/gopls/internal/vulncheck/scan/util.go b/gopls/internal/vulncheck/scan/util.go --- a/gopls/internal/vulncheck/scan/util.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/scan/util.go 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/scan/util.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -141059,7 +141313,7 @@ diff -urN a/gopls/internal/vulncheck/scan/util.go b/gopls/internal/vulncheck/sca -} diff -urN a/gopls/internal/vulncheck/semver/semver.go b/gopls/internal/vulncheck/semver/semver.go --- a/gopls/internal/vulncheck/semver/semver.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/semver/semver.go 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/semver/semver.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -141122,7 +141376,7 @@ diff -urN a/gopls/internal/vulncheck/semver/semver.go b/gopls/internal/vulncheck -) diff -urN a/gopls/internal/vulncheck/semver/semver_test.go b/gopls/internal/vulncheck/semver/semver_test.go --- a/gopls/internal/vulncheck/semver/semver_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/semver/semver_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/semver/semver_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -141154,7 +141408,7 @@ diff -urN a/gopls/internal/vulncheck/semver/semver_test.go b/gopls/internal/vuln -} diff -urN a/gopls/internal/vulncheck/types.go b/gopls/internal/vulncheck/types.go --- a/gopls/internal/vulncheck/types.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/types.go 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/types.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -141205,8 +141459,8 @@ diff -urN a/gopls/internal/vulncheck/types.go b/gopls/internal/vulncheck/types.g -) diff -urN a/gopls/internal/vulncheck/vulntest/db.go b/gopls/internal/vulncheck/vulntest/db.go --- a/gopls/internal/vulncheck/vulntest/db.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/vulntest/db.go 1970-01-01 08:00:00 -@@ -1,243 +0,0 @@ ++++ b/gopls/internal/vulncheck/vulntest/db.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,236 +0,0 @@ -// Copyright 2022 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. @@ -141329,13 +141583,6 @@ diff -urN a/gopls/internal/vulncheck/vulntest/db.go b/gopls/internal/vulncheck/v - return entries, nil -} - --func writeVulns(outPath string, vulns []osv.Entry, indent bool) error { -- if err := os.MkdirAll(filepath.Dir(outPath), 0755); err != nil { -- return fmt.Errorf("failed to create directory %q: %s", filepath.Dir(outPath), err) -- } -- return writeJSON(outPath+".json", vulns, indent) --} -- -func writeEntriesByID(idDir string, entries []osv.Entry, indent bool) error { - // Write a directory containing entries by ID. - if err := os.MkdirAll(idDir, 0755); err != nil { @@ -141452,7 +141699,7 @@ diff -urN a/gopls/internal/vulncheck/vulntest/db.go b/gopls/internal/vulncheck/v -} diff -urN a/gopls/internal/vulncheck/vulntest/db_test.go b/gopls/internal/vulncheck/vulntest/db_test.go --- a/gopls/internal/vulncheck/vulntest/db_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/vulntest/db_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/vulntest/db_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,79 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -141535,7 +141782,7 @@ diff -urN a/gopls/internal/vulncheck/vulntest/db_test.go b/gopls/internal/vulnch -} diff -urN a/gopls/internal/vulncheck/vulntest/report.go b/gopls/internal/vulncheck/vulntest/report.go --- a/gopls/internal/vulncheck/vulntest/report.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/vulntest/report.go 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/vulntest/report.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,179 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -141718,7 +141965,7 @@ diff -urN a/gopls/internal/vulncheck/vulntest/report.go b/gopls/internal/vulnche -} diff -urN a/gopls/internal/vulncheck/vulntest/report_test.go b/gopls/internal/vulncheck/vulntest/report_test.go --- a/gopls/internal/vulncheck/vulntest/report_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/vulntest/report_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/vulntest/report_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -141773,7 +142020,7 @@ diff -urN a/gopls/internal/vulncheck/vulntest/report_test.go b/gopls/internal/vu -} diff -urN a/gopls/internal/vulncheck/vulntest/stdlib.go b/gopls/internal/vulncheck/vulntest/stdlib.go --- a/gopls/internal/vulncheck/vulntest/stdlib.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/vulntest/stdlib.go 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/vulntest/stdlib.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -141803,7 +142050,7 @@ diff -urN a/gopls/internal/vulncheck/vulntest/stdlib.go b/gopls/internal/vulnche -} diff -urN a/gopls/internal/vulncheck/vulntest/stdlib_test.go b/gopls/internal/vulncheck/vulntest/stdlib_test.go --- a/gopls/internal/vulncheck/vulntest/stdlib_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/vulntest/stdlib_test.go 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/vulntest/stdlib_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -141834,7 +142081,7 @@ diff -urN a/gopls/internal/vulncheck/vulntest/stdlib_test.go b/gopls/internal/vu -} diff -urN a/gopls/internal/vulncheck/vulntest/testdata/GO-2020-0001.json b/gopls/internal/vulncheck/vulntest/testdata/GO-2020-0001.json --- a/gopls/internal/vulncheck/vulntest/testdata/GO-2020-0001.json 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/vulntest/testdata/GO-2020-0001.json 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/vulntest/testdata/GO-2020-0001.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -{ - "id": "GO-2020-0001", @@ -141889,7 +142136,7 @@ diff -urN a/gopls/internal/vulncheck/vulntest/testdata/GO-2020-0001.json b/gopls \ No newline at end of file diff -urN a/gopls/internal/vulncheck/vulntest/testdata/report.yaml b/gopls/internal/vulncheck/vulntest/testdata/report.yaml --- a/gopls/internal/vulncheck/vulntest/testdata/report.yaml 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/vulncheck/vulntest/testdata/report.yaml 1970-01-01 08:00:00 ++++ b/gopls/internal/vulncheck/vulntest/testdata/report.yaml 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -modules: - - module: github.com/gin-gonic/gin @@ -141908,7 +142155,7 @@ diff -urN a/gopls/internal/vulncheck/vulntest/testdata/report.yaml b/gopls/inter - - fix: https://github.com/gin-gonic/gin/commit/abcdefg diff -urN a/gopls/main.go b/gopls/main.go --- a/gopls/main.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/main.go 1970-01-01 08:00:00 ++++ b/gopls/main.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -141940,9 +142187,145 @@ diff -urN a/gopls/main.go b/gopls/main.go - ctx := context.Background() - tool.Main(ctx, cmd.New("gopls", "", nil, hooks.Options), os.Args[1:]) -} +diff -urN a/gopls/README.md b/gopls/README.md +--- a/gopls/README.md 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/README.md 1970-01-01 00:00:00.000000000 +0000 +@@ -1,132 +0,0 @@ +-# `gopls`, the Go language server +- +-[![PkgGoDev](https://pkg.go.dev/badge/golang.org/x/tools/gopls)](https://pkg.go.dev/golang.org/x/tools/gopls) +- +-`gopls` (pronounced "Go please") is the official Go [language server] developed +-by the Go team. It provides IDE features to any [LSP]-compatible editor. +- +-<!--TODO(rfindley): Add gifs here.--> +- +-You should not need to interact with `gopls` directly--it will be automatically +-integrated into your editor. The specific features and settings vary slightly +-by editor, so we recommend that you proceed to the +-[documentation for your editor](#editors) below. +- +-## Editors +- +-To get started with `gopls`, install an LSP plugin in your editor of choice. +- +-* [VS Code](https://github.com/golang/vscode-go/blob/master/README.md) +-* [Vim / Neovim](doc/vim.md) +-* [Emacs](doc/emacs.md) +-* [Atom](https://github.com/MordFustang21/ide-gopls) +-* [Sublime Text](doc/subl.md) +-* [Acme](https://github.com/fhs/acme-lsp) +-* [Lapce](https://github.com/lapce-community/lapce-go) +- +-If you use `gopls` with an editor that is not on this list, please send us a CL +-[updating this documentation](doc/contributing.md). +- +-## Installation +- +-For the most part, you should not need to install or update `gopls`. Your +-editor should handle that step for you. +- +-If you do want to get the latest stable version of `gopls`, run the following +-command: +- +-```sh +-go install golang.org/x/tools/gopls@latest +-``` +- +-Learn more in the +-[advanced installation instructions](doc/advanced.md#installing-unreleased-versions). +- +-Learn more about gopls releases in the [release policy](doc/releases.md). +- +-## Setting up your workspace +- +-`gopls` supports both Go module, multi-module and GOPATH modes. See the +-[workspace documentation](doc/workspace.md) for information on supported +-workspace layouts. +- +-## Configuration +- +-You can configure `gopls` to change your editor experience or view additional +-debugging information. Configuration options will be made available by your +-editor, so see your [editor's instructions](#editors) for specific details. A +-full list of `gopls` settings can be found in the [settings documentation](doc/settings.md). +- +-### Environment variables +- +-`gopls` inherits your editor's environment, so be aware of any environment +-variables you configure. Some editors, such as VS Code, allow users to +-selectively override the values of some environment variables. +- +-## Support Policy +- +-Gopls is maintained by engineers on the +-[Go tools team](https://github.com/orgs/golang/teams/tools-team/members), +-who actively monitor the +-[Go](https://github.com/golang/go/issues?q=is%3Aissue+is%3Aopen+label%3Agopls) +-and +-[VS Code Go](https://github.com/golang/vscode-go/issues) issue trackers. +- +-### Supported Go versions +- +-`gopls` follows the +-[Go Release Policy](https://golang.org/doc/devel/release.html#policy), +-meaning that it officially supports the last 2 major Go releases. Per +-[issue #39146](https://go.dev/issues/39146), we attempt to maintain best-effort +-support for the last 4 major Go releases, but this support extends only to not +-breaking the build and avoiding easily fixable regressions. +- +-In the context of this discussion, gopls "supports" a Go version if it supports +-being built with that Go version as well as integrating with the `go` command +-of that Go version. +- +-The following table shows the final gopls version that supports a given Go +-version. Go releases more recent than any in the table can be used with any +-version of gopls. +- +-| Go Version | Final gopls version with support (without warnings) | +-| ----------- | --------------------------------------------------- | +-| Go 1.12 | [gopls@v0.7.5](https://github.com/golang/tools/releases/tag/gopls%2Fv0.7.5) | +-| Go 1.15 | [gopls@v0.9.5](https://github.com/golang/tools/releases/tag/gopls%2Fv0.9.5) | +-| Go 1.17 | [gopls@v0.11.0](https://github.com/golang/tools/releases/tag/gopls%2Fv0.11.0) | +- +-Our extended support is enforced via [continuous integration with older Go +-versions](doc/contributing.md#ci). This legacy Go CI may not block releases: +-test failures may be skipped rather than fixed. Furthermore, if a regression in +-an older Go version causes irreconcilable CI failures, we may drop support for +-that Go version in CI if it is 3 or 4 Go versions old. +- +-### Supported build systems +- +-`gopls` currently only supports the `go` command, so if you are using +-a different build system, `gopls` will not work well. Bazel is not officially +-supported, but may be made to work with an appropriately configured +-`go/packages` driver. See +-[bazelbuild/rules_go#512](https://github.com/bazelbuild/rules_go/issues/512) +-for more information. +-You can follow [these instructions](https://github.com/bazelbuild/rules_go/wiki/Editor-setup) +-to configure your `gopls` to work with Bazel. +- +-### Troubleshooting +- +-If you are having issues with `gopls`, please follow the steps described in the +-[troubleshooting guide](doc/troubleshooting.md). +- +-## Additional information +- +-* [Features](doc/features.md) +-* [Command-line interface](doc/command-line.md) +-* [Advanced topics](doc/advanced.md) +-* [Contributing to `gopls`](doc/contributing.md) +-* [Integrating `gopls` with an editor](doc/design/integrating.md) +-* [Design requirements and decisions](doc/design/design.md) +-* [Implementation details](doc/design/implementation.md) +-* [Open issues](https://github.com/golang/go/issues?q=is%3Aissue+is%3Aopen+label%3Agopls) +- +-[language server]: https://langserver.org +-[LSP]: https://microsoft.github.io/language-server-protocol/ diff -urN a/gopls/release/release.go b/gopls/release/release.go --- a/gopls/release/release.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/release/release.go 1970-01-01 08:00:00 ++++ b/gopls/release/release.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,155 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -142101,7 +142484,7 @@ diff -urN a/gopls/release/release.go b/gopls/release/release.go -} diff -urN a/gopls/test/debug/debug_test.go b/gopls/test/debug/debug_test.go --- a/gopls/test/debug/debug_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/test/debug/debug_test.go 1970-01-01 08:00:00 ++++ b/gopls/test/debug/debug_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style @@ -142258,7 +142641,7 @@ diff -urN a/gopls/test/debug/debug_test.go b/gopls/test/debug/debug_test.go -} diff -urN a/gopls/test/json_test.go b/gopls/test/json_test.go --- a/gopls/test/json_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/test/json_test.go 1970-01-01 08:00:00 ++++ b/gopls/test/json_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,140 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style diff --git a/third_party/org_golang_x_tools-gazelle.patch b/third_party/org_golang_x_tools-gazelle.patch index 33d7c10a5b..d99ae0d222 100644 --- a/third_party/org_golang_x_tools-gazelle.patch +++ b/third_party/org_golang_x_tools-gazelle.patch @@ -1,5 +1,5 @@ diff -urN b/benchmark/parse/BUILD.bazel c/benchmark/parse/BUILD.bazel ---- b/benchmark/parse/BUILD.bazel 1970-01-01 08:00:00 +--- b/benchmark/parse/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/benchmark/parse/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -22,8 +22,26 @@ diff -urN b/benchmark/parse/BUILD.bazel c/benchmark/parse/BUILD.bazel + srcs = ["parse_test.go"], + embed = [":parse"], +) +diff -urN b/blog/atom/BUILD.bazel c/blog/atom/BUILD.bazel +--- b/blog/atom/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/blog/atom/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,14 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "atom", ++ srcs = ["atom.go"], ++ importpath = "golang.org/x/tools/blog/atom", ++ visibility = ["//visibility:public"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":atom", ++ visibility = ["//visibility:public"], ++) diff -urN b/blog/BUILD.bazel c/blog/BUILD.bazel ---- b/blog/BUILD.bazel 1970-01-01 08:00:00 +--- b/blog/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/blog/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -50,26 +68,8 @@ diff -urN b/blog/BUILD.bazel c/blog/BUILD.bazel + srcs = ["blog_test.go"], + embed = [":blog"], +) -diff -urN b/blog/atom/BUILD.bazel c/blog/atom/BUILD.bazel ---- b/blog/atom/BUILD.bazel 1970-01-01 08:00:00 -+++ c/blog/atom/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,14 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library") -+ -+go_library( -+ name = "atom", -+ srcs = ["atom.go"], -+ importpath = "golang.org/x/tools/blog/atom", -+ visibility = ["//visibility:public"], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":atom", -+ visibility = ["//visibility:public"], -+) diff -urN b/cmd/auth/authtest/BUILD.bazel c/cmd/auth/authtest/BUILD.bazel ---- b/cmd/auth/authtest/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/auth/authtest/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/auth/authtest/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -88,7 +88,7 @@ diff -urN b/cmd/auth/authtest/BUILD.bazel c/cmd/auth/authtest/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/auth/cookieauth/BUILD.bazel c/cmd/auth/cookieauth/BUILD.bazel ---- b/cmd/auth/cookieauth/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/auth/cookieauth/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/auth/cookieauth/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -106,7 +106,7 @@ diff -urN b/cmd/auth/cookieauth/BUILD.bazel c/cmd/auth/cookieauth/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/auth/gitauth/BUILD.bazel c/cmd/auth/gitauth/BUILD.bazel ---- b/cmd/auth/gitauth/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/auth/gitauth/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/auth/gitauth/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -125,7 +125,7 @@ diff -urN b/cmd/auth/gitauth/BUILD.bazel c/cmd/auth/gitauth/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/auth/netrcauth/BUILD.bazel c/cmd/auth/netrcauth/BUILD.bazel ---- b/cmd/auth/netrcauth/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/auth/netrcauth/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/auth/netrcauth/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -143,7 +143,7 @@ diff -urN b/cmd/auth/netrcauth/BUILD.bazel c/cmd/auth/netrcauth/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/benchcmp/BUILD.bazel c/cmd/benchcmp/BUILD.bazel ---- b/cmd/benchcmp/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/benchcmp/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/benchcmp/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -176,7 +176,7 @@ diff -urN b/cmd/benchcmp/BUILD.bazel c/cmd/benchcmp/BUILD.bazel + deps = ["//benchmark/parse"], +) diff -urN b/cmd/bisect/BUILD.bazel c/cmd/bisect/BUILD.bazel ---- b/cmd/bisect/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/bisect/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/bisect/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -203,7 +203,7 @@ diff -urN b/cmd/bisect/BUILD.bazel c/cmd/bisect/BUILD.bazel +go_test( + name = "bisect_test", + srcs = ["main_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), ++ data = glob(["testdata/**"]), + embed = [":bisect_lib"], + deps = [ + "//internal/bisect", @@ -213,9 +213,9 @@ diff -urN b/cmd/bisect/BUILD.bazel c/cmd/bisect/BUILD.bazel + ], +) diff -urN b/cmd/bundle/BUILD.bazel c/cmd/bundle/BUILD.bazel ---- b/cmd/bundle/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/bundle/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/bundle/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,23 @@ +@@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") + +go_library( @@ -235,12 +235,11 @@ diff -urN b/cmd/bundle/BUILD.bazel c/cmd/bundle/BUILD.bazel +go_test( + name = "bundle_test", + srcs = ["main_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + embed = [":bundle_lib"], + deps = ["//go/packages/packagestest"], +) diff -urN b/cmd/bundle/testdata/src/domain.name/importdecl/BUILD.bazel c/cmd/bundle/testdata/src/domain.name/importdecl/BUILD.bazel ---- b/cmd/bundle/testdata/src/domain.name/importdecl/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/bundle/testdata/src/domain.name/importdecl/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/bundle/testdata/src/domain.name/importdecl/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -258,7 +257,7 @@ diff -urN b/cmd/bundle/testdata/src/domain.name/importdecl/BUILD.bazel c/cmd/bun + visibility = ["//visibility:public"], +) diff -urN b/cmd/bundle/testdata/src/initial/BUILD.bazel c/cmd/bundle/testdata/src/initial/BUILD.bazel ---- b/cmd/bundle/testdata/src/initial/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/bundle/testdata/src/initial/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/bundle/testdata/src/initial/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -280,9 +279,9 @@ diff -urN b/cmd/bundle/testdata/src/initial/BUILD.bazel c/cmd/bundle/testdata/sr + visibility = ["//visibility:public"], +) diff -urN b/cmd/callgraph/BUILD.bazel c/cmd/callgraph/BUILD.bazel ---- b/cmd/callgraph/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/callgraph/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/callgraph/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,74 @@ +@@ -0,0 +1,73 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") + +go_library( @@ -312,7 +311,6 @@ diff -urN b/cmd/callgraph/BUILD.bazel c/cmd/callgraph/BUILD.bazel +go_test( + name = "callgraph_test", + srcs = ["main_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + embed = [":callgraph_lib"], + deps = select({ + "@io_bazel_rules_go//go/platform:aix": [ @@ -358,7 +356,7 @@ diff -urN b/cmd/callgraph/BUILD.bazel c/cmd/callgraph/BUILD.bazel + }), +) diff -urN b/cmd/callgraph/testdata/src/pkg/BUILD.bazel c/cmd/callgraph/testdata/src/pkg/BUILD.bazel ---- b/cmd/callgraph/testdata/src/pkg/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/callgraph/testdata/src/pkg/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/callgraph/testdata/src/pkg/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -382,7 +380,7 @@ diff -urN b/cmd/callgraph/testdata/src/pkg/BUILD.bazel c/cmd/callgraph/testdata/ + embed = [":pkg_lib"], +) diff -urN b/cmd/compilebench/BUILD.bazel c/cmd/compilebench/BUILD.bazel ---- b/cmd/compilebench/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/compilebench/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/compilebench/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -401,7 +399,7 @@ diff -urN b/cmd/compilebench/BUILD.bazel c/cmd/compilebench/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/digraph/BUILD.bazel c/cmd/digraph/BUILD.bazel ---- b/cmd/digraph/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/digraph/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/digraph/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -429,7 +427,7 @@ diff -urN b/cmd/digraph/BUILD.bazel c/cmd/digraph/BUILD.bazel + embed = [":digraph_lib"], +) diff -urN b/cmd/eg/BUILD.bazel c/cmd/eg/BUILD.bazel ---- b/cmd/eg/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/eg/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/eg/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -452,7 +450,7 @@ diff -urN b/cmd/eg/BUILD.bazel c/cmd/eg/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/file2fuzz/BUILD.bazel c/cmd/file2fuzz/BUILD.bazel ---- b/cmd/file2fuzz/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/file2fuzz/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/file2fuzz/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -477,9 +475,9 @@ diff -urN b/cmd/file2fuzz/BUILD.bazel c/cmd/file2fuzz/BUILD.bazel + deps = ["//internal/testenv"], +) diff -urN b/cmd/fiximports/BUILD.bazel c/cmd/fiximports/BUILD.bazel ---- b/cmd/fiximports/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/fiximports/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/fiximports/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,64 @@ +@@ -0,0 +1,63 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") + +go_library( @@ -499,7 +497,6 @@ diff -urN b/cmd/fiximports/BUILD.bazel c/cmd/fiximports/BUILD.bazel +go_test( + name = "fiximports_test", + srcs = ["main_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + embed = [":fiximports_lib"], + deps = select({ + "@io_bazel_rules_go//go/platform:aix": [ @@ -545,7 +542,7 @@ diff -urN b/cmd/fiximports/BUILD.bazel c/cmd/fiximports/BUILD.bazel + }), +) diff -urN b/cmd/fiximports/testdata/src/fruit.io/banana/BUILD.bazel c/cmd/fiximports/testdata/src/fruit.io/banana/BUILD.bazel ---- b/cmd/fiximports/testdata/src/fruit.io/banana/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/fiximports/testdata/src/fruit.io/banana/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/fiximports/testdata/src/fruit.io/banana/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -563,7 +560,7 @@ diff -urN b/cmd/fiximports/testdata/src/fruit.io/banana/BUILD.bazel c/cmd/fiximp + visibility = ["//visibility:public"], +) diff -urN b/cmd/fiximports/testdata/src/fruit.io/orange/BUILD.bazel c/cmd/fiximports/testdata/src/fruit.io/orange/BUILD.bazel ---- b/cmd/fiximports/testdata/src/fruit.io/orange/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/fiximports/testdata/src/fruit.io/orange/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/fiximports/testdata/src/fruit.io/orange/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -581,7 +578,7 @@ diff -urN b/cmd/fiximports/testdata/src/fruit.io/orange/BUILD.bazel c/cmd/fiximp + visibility = ["//visibility:public"], +) diff -urN b/cmd/fiximports/testdata/src/fruit.io/pear/BUILD.bazel c/cmd/fiximports/testdata/src/fruit.io/pear/BUILD.bazel ---- b/cmd/fiximports/testdata/src/fruit.io/pear/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/fiximports/testdata/src/fruit.io/pear/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/fiximports/testdata/src/fruit.io/pear/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -599,7 +596,7 @@ diff -urN b/cmd/fiximports/testdata/src/fruit.io/pear/BUILD.bazel c/cmd/fiximpor + visibility = ["//visibility:public"], +) diff -urN b/cmd/fiximports/testdata/src/new.com/one/BUILD.bazel c/cmd/fiximports/testdata/src/new.com/one/BUILD.bazel ---- b/cmd/fiximports/testdata/src/new.com/one/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/fiximports/testdata/src/new.com/one/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/fiximports/testdata/src/new.com/one/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -617,7 +614,7 @@ diff -urN b/cmd/fiximports/testdata/src/new.com/one/BUILD.bazel c/cmd/fiximports + visibility = ["//visibility:public"], +) diff -urN b/cmd/fiximports/testdata/src/old.com/bad/BUILD.bazel c/cmd/fiximports/testdata/src/old.com/bad/BUILD.bazel ---- b/cmd/fiximports/testdata/src/old.com/bad/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/fiximports/testdata/src/old.com/bad/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/fiximports/testdata/src/old.com/bad/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -635,7 +632,7 @@ diff -urN b/cmd/fiximports/testdata/src/old.com/bad/BUILD.bazel c/cmd/fiximports + visibility = ["//visibility:public"], +) diff -urN b/cmd/fiximports/testdata/src/old.com/one/BUILD.bazel c/cmd/fiximports/testdata/src/old.com/one/BUILD.bazel ---- b/cmd/fiximports/testdata/src/old.com/one/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/fiximports/testdata/src/old.com/one/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/fiximports/testdata/src/old.com/one/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -653,7 +650,7 @@ diff -urN b/cmd/fiximports/testdata/src/old.com/one/BUILD.bazel c/cmd/fiximports + visibility = ["//visibility:public"], +) diff -urN b/cmd/fiximports/testdata/src/titanic.biz/bar/BUILD.bazel c/cmd/fiximports/testdata/src/titanic.biz/bar/BUILD.bazel ---- b/cmd/fiximports/testdata/src/titanic.biz/bar/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/fiximports/testdata/src/titanic.biz/bar/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/fiximports/testdata/src/titanic.biz/bar/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -671,7 +668,7 @@ diff -urN b/cmd/fiximports/testdata/src/titanic.biz/bar/BUILD.bazel c/cmd/fiximp + visibility = ["//visibility:public"], +) diff -urN b/cmd/fiximports/testdata/src/titanic.biz/foo/BUILD.bazel c/cmd/fiximports/testdata/src/titanic.biz/foo/BUILD.bazel ---- b/cmd/fiximports/testdata/src/titanic.biz/foo/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/fiximports/testdata/src/titanic.biz/foo/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/fiximports/testdata/src/titanic.biz/foo/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -689,7 +686,7 @@ diff -urN b/cmd/fiximports/testdata/src/titanic.biz/foo/BUILD.bazel c/cmd/fiximp + visibility = ["//visibility:public"], +) diff -urN b/cmd/getgo/BUILD.bazel c/cmd/getgo/BUILD.bazel ---- b/cmd/getgo/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/getgo/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/getgo/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,74 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -767,7 +764,7 @@ diff -urN b/cmd/getgo/BUILD.bazel c/cmd/getgo/BUILD.bazel + embed = [":getgo_lib"], +) diff -urN b/cmd/getgo/server/BUILD.bazel c/cmd/getgo/server/BUILD.bazel ---- b/cmd/getgo/server/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/getgo/server/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/getgo/server/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -785,7 +782,7 @@ diff -urN b/cmd/getgo/server/BUILD.bazel c/cmd/getgo/server/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/go-contrib-init/BUILD.bazel c/cmd/go-contrib-init/BUILD.bazel ---- b/cmd/go-contrib-init/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/go-contrib-init/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/go-contrib-init/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -810,7 +807,7 @@ diff -urN b/cmd/go-contrib-init/BUILD.bazel c/cmd/go-contrib-init/BUILD.bazel + embed = [":go-contrib-init_lib"], +) diff -urN b/cmd/godex/BUILD.bazel c/cmd/godex/BUILD.bazel ---- b/cmd/godex/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/godex/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/godex/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -838,7 +835,7 @@ diff -urN b/cmd/godex/BUILD.bazel c/cmd/godex/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/godoc/BUILD.bazel c/cmd/godoc/BUILD.bazel ---- b/cmd/godoc/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/godoc/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/godoc/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,41 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -883,7 +880,7 @@ diff -urN b/cmd/godoc/BUILD.bazel c/cmd/godoc/BUILD.bazel + ], +) diff -urN b/cmd/goimports/BUILD.bazel c/cmd/goimports/BUILD.bazel ---- b/cmd/goimports/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/goimports/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/goimports/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -910,7 +907,7 @@ diff -urN b/cmd/goimports/BUILD.bazel c/cmd/goimports/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/gomvpkg/BUILD.bazel c/cmd/gomvpkg/BUILD.bazel ---- b/cmd/gomvpkg/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/gomvpkg/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/gomvpkg/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -932,9 +929,9 @@ diff -urN b/cmd/gomvpkg/BUILD.bazel c/cmd/gomvpkg/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/gonew/BUILD.bazel c/cmd/gonew/BUILD.bazel ---- b/cmd/gonew/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/gonew/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/gonew/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,30 @@ +@@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") + +go_library( @@ -958,15 +955,16 @@ diff -urN b/cmd/gonew/BUILD.bazel c/cmd/gonew/BUILD.bazel +go_test( + name = "gonew_test", + srcs = ["main_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), ++ data = glob(["testdata/**"]), + embed = [":gonew_lib"], + deps = [ + "//internal/diffp", ++ "//internal/testenv", + "//txtar", + ], +) diff -urN b/cmd/gorename/BUILD.bazel c/cmd/gorename/BUILD.bazel ---- b/cmd/gorename/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/gorename/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/gorename/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -994,7 +992,7 @@ diff -urN b/cmd/gorename/BUILD.bazel c/cmd/gorename/BUILD.bazel + deps = ["//internal/testenv"], +) diff -urN b/cmd/gotype/BUILD.bazel c/cmd/gotype/BUILD.bazel ---- b/cmd/gotype/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/gotype/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/gotype/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1016,7 +1014,7 @@ diff -urN b/cmd/gotype/BUILD.bazel c/cmd/gotype/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/goyacc/BUILD.bazel c/cmd/goyacc/BUILD.bazel ---- b/cmd/goyacc/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/goyacc/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/goyacc/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,17 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1037,27 +1035,27 @@ diff -urN b/cmd/goyacc/BUILD.bazel c/cmd/goyacc/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/goyacc/testdata/expr/BUILD.bazel c/cmd/goyacc/testdata/expr/BUILD.bazel ---- b/cmd/goyacc/testdata/expr/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/goyacc/testdata/expr/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/goyacc/testdata/expr/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") ++load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "expr_lib", + srcs = ["main.go"], + importpath = "golang.org/x/tools/cmd/goyacc/testdata/expr", -+ visibility = ["//visibility:private"], ++ visibility = ["//visibility:public"], +) + -+go_binary( -+ name = "expr", -+ embed = [":expr_lib"], ++alias( ++ name = "go_default_library", ++ actual = ":expr_lib", + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/BUILD.bazel c/cmd/guru/BUILD.bazel ---- b/cmd/guru/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,46 @@ +@@ -0,0 +1,45 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") + +go_library( @@ -1100,12 +1098,11 @@ diff -urN b/cmd/guru/BUILD.bazel c/cmd/guru/BUILD.bazel + "guru_test.go", + "unit_test.go", + ], -+ data = glob(["testdata/**"], allow_empty = True), + embed = [":guru_lib"], + deps = ["//internal/testenv"], +) diff -urN b/cmd/guru/serial/BUILD.bazel c/cmd/guru/serial/BUILD.bazel ---- b/cmd/guru/serial/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/serial/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/serial/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1123,7 +1120,7 @@ diff -urN b/cmd/guru/serial/BUILD.bazel c/cmd/guru/serial/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/testdata/src/alias/BUILD.bazel c/cmd/guru/testdata/src/alias/BUILD.bazel ---- b/cmd/guru/testdata/src/alias/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/alias/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/alias/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1141,7 +1138,7 @@ diff -urN b/cmd/guru/testdata/src/alias/BUILD.bazel c/cmd/guru/testdata/src/alia + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/testdata/src/definition-json/BUILD.bazel c/cmd/guru/testdata/src/definition-json/BUILD.bazel ---- b/cmd/guru/testdata/src/definition-json/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/definition-json/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/definition-json/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,17 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1162,7 +1159,7 @@ diff -urN b/cmd/guru/testdata/src/definition-json/BUILD.bazel c/cmd/guru/testdat + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/testdata/src/describe/BUILD.bazel c/cmd/guru/testdata/src/describe/BUILD.bazel ---- b/cmd/guru/testdata/src/describe/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/describe/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/describe/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1180,7 +1177,7 @@ diff -urN b/cmd/guru/testdata/src/describe/BUILD.bazel c/cmd/guru/testdata/src/d + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/testdata/src/describe-json/BUILD.bazel c/cmd/guru/testdata/src/describe-json/BUILD.bazel ---- b/cmd/guru/testdata/src/describe-json/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/describe-json/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/describe-json/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1198,7 +1195,7 @@ diff -urN b/cmd/guru/testdata/src/describe-json/BUILD.bazel c/cmd/guru/testdata/ + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/testdata/src/freevars/BUILD.bazel c/cmd/guru/testdata/src/freevars/BUILD.bazel ---- b/cmd/guru/testdata/src/freevars/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/freevars/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/freevars/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1216,7 +1213,7 @@ diff -urN b/cmd/guru/testdata/src/freevars/BUILD.bazel c/cmd/guru/testdata/src/f + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/testdata/src/implements/BUILD.bazel c/cmd/guru/testdata/src/implements/BUILD.bazel ---- b/cmd/guru/testdata/src/implements/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/implements/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/implements/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1234,7 +1231,7 @@ diff -urN b/cmd/guru/testdata/src/implements/BUILD.bazel c/cmd/guru/testdata/src + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/testdata/src/implements-json/BUILD.bazel c/cmd/guru/testdata/src/implements-json/BUILD.bazel ---- b/cmd/guru/testdata/src/implements-json/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/implements-json/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/implements-json/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1252,7 +1249,7 @@ diff -urN b/cmd/guru/testdata/src/implements-json/BUILD.bazel c/cmd/guru/testdat + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/testdata/src/implements-methods/BUILD.bazel c/cmd/guru/testdata/src/implements-methods/BUILD.bazel ---- b/cmd/guru/testdata/src/implements-methods/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/implements-methods/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/implements-methods/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1270,7 +1267,7 @@ diff -urN b/cmd/guru/testdata/src/implements-methods/BUILD.bazel c/cmd/guru/test + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/testdata/src/implements-methods-json/BUILD.bazel c/cmd/guru/testdata/src/implements-methods-json/BUILD.bazel ---- b/cmd/guru/testdata/src/implements-methods-json/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/implements-methods-json/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/implements-methods-json/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1288,7 +1285,7 @@ diff -urN b/cmd/guru/testdata/src/implements-methods-json/BUILD.bazel c/cmd/guru + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/testdata/src/imports/BUILD.bazel c/cmd/guru/testdata/src/imports/BUILD.bazel ---- b/cmd/guru/testdata/src/imports/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/imports/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/imports/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1306,7 +1303,7 @@ diff -urN b/cmd/guru/testdata/src/imports/BUILD.bazel c/cmd/guru/testdata/src/im + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/testdata/src/lib/BUILD.bazel c/cmd/guru/testdata/src/lib/BUILD.bazel ---- b/cmd/guru/testdata/src/lib/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/lib/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/lib/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1324,7 +1321,7 @@ diff -urN b/cmd/guru/testdata/src/lib/BUILD.bazel c/cmd/guru/testdata/src/lib/BU + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/testdata/src/lib/sublib/BUILD.bazel c/cmd/guru/testdata/src/lib/sublib/BUILD.bazel ---- b/cmd/guru/testdata/src/lib/sublib/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/lib/sublib/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/lib/sublib/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1342,7 +1339,7 @@ diff -urN b/cmd/guru/testdata/src/lib/sublib/BUILD.bazel c/cmd/guru/testdata/src + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/testdata/src/main/BUILD.bazel c/cmd/guru/testdata/src/main/BUILD.bazel ---- b/cmd/guru/testdata/src/main/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/main/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/main/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1360,7 +1357,7 @@ diff -urN b/cmd/guru/testdata/src/main/BUILD.bazel c/cmd/guru/testdata/src/main/ + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/testdata/src/referrers/BUILD.bazel c/cmd/guru/testdata/src/referrers/BUILD.bazel ---- b/cmd/guru/testdata/src/referrers/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/referrers/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/referrers/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -1387,7 +1384,7 @@ diff -urN b/cmd/guru/testdata/src/referrers/BUILD.bazel c/cmd/guru/testdata/src/ + embed = [":referrers_lib"], +) diff -urN b/cmd/guru/testdata/src/referrers-json/BUILD.bazel c/cmd/guru/testdata/src/referrers-json/BUILD.bazel ---- b/cmd/guru/testdata/src/referrers-json/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/referrers-json/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/referrers-json/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1405,7 +1402,7 @@ diff -urN b/cmd/guru/testdata/src/referrers-json/BUILD.bazel c/cmd/guru/testdata + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/testdata/src/what/BUILD.bazel c/cmd/guru/testdata/src/what/BUILD.bazel ---- b/cmd/guru/testdata/src/what/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/what/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/what/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1423,7 +1420,7 @@ diff -urN b/cmd/guru/testdata/src/what/BUILD.bazel c/cmd/guru/testdata/src/what/ + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/testdata/src/what-json/BUILD.bazel c/cmd/guru/testdata/src/what-json/BUILD.bazel ---- b/cmd/guru/testdata/src/what-json/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/guru/testdata/src/what-json/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/what-json/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1441,7 +1438,7 @@ diff -urN b/cmd/guru/testdata/src/what-json/BUILD.bazel c/cmd/guru/testdata/src/ + visibility = ["//visibility:public"], +) diff -urN b/cmd/html2article/BUILD.bazel c/cmd/html2article/BUILD.bazel ---- b/cmd/html2article/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/html2article/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/html2article/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1463,7 +1460,7 @@ diff -urN b/cmd/html2article/BUILD.bazel c/cmd/html2article/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/present/BUILD.bazel c/cmd/present/BUILD.bazel ---- b/cmd/present/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/present/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/present/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,42 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1509,7 +1506,7 @@ diff -urN b/cmd/present/BUILD.bazel c/cmd/present/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/present2md/BUILD.bazel c/cmd/present2md/BUILD.bazel ---- b/cmd/present2md/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/present2md/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/present2md/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1528,7 +1525,7 @@ diff -urN b/cmd/present2md/BUILD.bazel c/cmd/present2md/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/signature-fuzzer/fuzz-driver/BUILD.bazel c/cmd/signature-fuzzer/fuzz-driver/BUILD.bazel ---- b/cmd/signature-fuzzer/fuzz-driver/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/signature-fuzzer/fuzz-driver/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/signature-fuzzer/fuzz-driver/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -1554,7 +1551,7 @@ diff -urN b/cmd/signature-fuzzer/fuzz-driver/BUILD.bazel c/cmd/signature-fuzzer/ + deps = ["//internal/testenv"], +) diff -urN b/cmd/signature-fuzzer/fuzz-runner/BUILD.bazel c/cmd/signature-fuzzer/fuzz-runner/BUILD.bazel ---- b/cmd/signature-fuzzer/fuzz-runner/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/signature-fuzzer/fuzz-runner/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/signature-fuzzer/fuzz-runner/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -1580,7 +1577,7 @@ diff -urN b/cmd/signature-fuzzer/fuzz-runner/BUILD.bazel c/cmd/signature-fuzzer/ + deps = ["//internal/testenv"], +) diff -urN b/cmd/signature-fuzzer/fuzz-runner/testdata/BUILD.bazel c/cmd/signature-fuzzer/fuzz-runner/testdata/BUILD.bazel ---- b/cmd/signature-fuzzer/fuzz-runner/testdata/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/signature-fuzzer/fuzz-runner/testdata/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/signature-fuzzer/fuzz-runner/testdata/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1598,7 +1595,7 @@ diff -urN b/cmd/signature-fuzzer/fuzz-runner/testdata/BUILD.bazel c/cmd/signatur + visibility = ["//visibility:public"], +) diff -urN b/cmd/signature-fuzzer/internal/fuzz-generator/BUILD.bazel c/cmd/signature-fuzzer/internal/fuzz-generator/BUILD.bazel ---- b/cmd/signature-fuzzer/internal/fuzz-generator/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/signature-fuzzer/internal/fuzz-generator/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/signature-fuzzer/internal/fuzz-generator/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1634,7 +1631,7 @@ diff -urN b/cmd/signature-fuzzer/internal/fuzz-generator/BUILD.bazel c/cmd/signa + deps = ["//internal/testenv"], +) diff -urN b/cmd/splitdwarf/BUILD.bazel c/cmd/splitdwarf/BUILD.bazel ---- b/cmd/splitdwarf/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/splitdwarf/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/splitdwarf/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,44 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1682,7 +1679,7 @@ diff -urN b/cmd/splitdwarf/BUILD.bazel c/cmd/splitdwarf/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/splitdwarf/internal/macho/BUILD.bazel c/cmd/splitdwarf/internal/macho/BUILD.bazel ---- b/cmd/splitdwarf/internal/macho/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/splitdwarf/internal/macho/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/splitdwarf/internal/macho/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1709,11 +1706,11 @@ diff -urN b/cmd/splitdwarf/internal/macho/BUILD.bazel c/cmd/splitdwarf/internal/ +go_test( + name = "macho_test", + srcs = ["file_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), ++ data = glob(["testdata/**"]), + embed = [":macho"], +) diff -urN b/cmd/ssadump/BUILD.bazel c/cmd/ssadump/BUILD.bazel ---- b/cmd/ssadump/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/ssadump/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/ssadump/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1738,9 +1735,9 @@ diff -urN b/cmd/ssadump/BUILD.bazel c/cmd/ssadump/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/stress/BUILD.bazel c/cmd/stress/BUILD.bazel ---- b/cmd/stress/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/stress/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/stress/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,50 @@ +@@ -0,0 +1,53 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( @@ -1764,6 +1761,9 @@ diff -urN b/cmd/stress/BUILD.bazel c/cmd/stress/BUILD.bazel + "@io_bazel_rules_go//go/platform:freebsd": [ + "@org_golang_x_sys//execabs:go_default_library", + ], ++ "@io_bazel_rules_go//go/platform:illumos": [ ++ "@org_golang_x_sys//execabs:go_default_library", ++ ], + "@io_bazel_rules_go//go/platform:ios": [ + "@org_golang_x_sys//execabs:go_default_library", + ], @@ -1792,7 +1792,7 @@ diff -urN b/cmd/stress/BUILD.bazel c/cmd/stress/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/cmd/stringer/BUILD.bazel c/cmd/stringer/BUILD.bazel ---- b/cmd/stringer/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/stringer/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/stringer/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,69 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -1865,7 +1865,7 @@ diff -urN b/cmd/stringer/BUILD.bazel c/cmd/stringer/BUILD.bazel + }), +) diff -urN b/cmd/stringer/testdata/BUILD.bazel c/cmd/stringer/testdata/BUILD.bazel ---- b/cmd/stringer/testdata/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/stringer/testdata/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/stringer/testdata/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1896,7 +1896,7 @@ diff -urN b/cmd/stringer/testdata/BUILD.bazel c/cmd/stringer/testdata/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN b/cmd/stringer/testdata/typeparams/BUILD.bazel c/cmd/stringer/testdata/typeparams/BUILD.bazel ---- b/cmd/stringer/testdata/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/stringer/testdata/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/stringer/testdata/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,17 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1917,7 +1917,7 @@ diff -urN b/cmd/stringer/testdata/typeparams/BUILD.bazel c/cmd/stringer/testdata + visibility = ["//visibility:public"], +) diff -urN b/cmd/toolstash/BUILD.bazel c/cmd/toolstash/BUILD.bazel ---- b/cmd/toolstash/BUILD.bazel 1970-01-01 08:00:00 +--- b/cmd/toolstash/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/toolstash/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1939,7 +1939,7 @@ diff -urN b/cmd/toolstash/BUILD.bazel c/cmd/toolstash/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/container/intsets/BUILD.bazel c/container/intsets/BUILD.bazel ---- b/container/intsets/BUILD.bazel 1970-01-01 08:00:00 +--- b/container/intsets/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/container/intsets/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1966,7 +1966,7 @@ diff -urN b/container/intsets/BUILD.bazel c/container/intsets/BUILD.bazel + embed = [":intsets"], +) diff -urN b/copyright/BUILD.bazel c/copyright/BUILD.bazel ---- b/copyright/BUILD.bazel 1970-01-01 08:00:00 +--- b/copyright/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/copyright/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1990,7 +1990,7 @@ diff -urN b/copyright/BUILD.bazel c/copyright/BUILD.bazel + embed = [":copyright"], +) diff -urN b/cover/BUILD.bazel c/cover/BUILD.bazel ---- b/cover/BUILD.bazel 1970-01-01 08:00:00 +--- b/cover/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cover/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2013,37 +2013,8 @@ diff -urN b/cover/BUILD.bazel c/cover/BUILD.bazel + srcs = ["profile_test.go"], + embed = [":cover"], +) -diff -urN b/go/analysis/BUILD.bazel c/go/analysis/BUILD.bazel ---- b/go/analysis/BUILD.bazel 1970-01-01 08:00:00 -+++ c/go/analysis/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,25 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -+ -+go_library( -+ name = "analysis", -+ srcs = [ -+ "analysis.go", -+ "diagnostic.go", -+ "doc.go", -+ "validate.go", -+ ], -+ importpath = "golang.org/x/tools/go/analysis", -+ visibility = ["//visibility:public"], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":analysis", -+ visibility = ["//visibility:public"], -+) -+ -+go_test( -+ name = "analysis_test", -+ srcs = ["validate_test.go"], -+ embed = [":analysis"], -+) diff -urN b/go/analysis/analysistest/BUILD.bazel c/go/analysis/analysistest/BUILD.bazel ---- b/go/analysis/analysistest/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/analysistest/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/analysistest/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2078,8 +2049,37 @@ diff -urN b/go/analysis/analysistest/BUILD.bazel c/go/analysis/analysistest/BUIL + "//internal/testenv", + ], +) +diff -urN b/go/analysis/BUILD.bazel c/go/analysis/BUILD.bazel +--- b/go/analysis/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/analysis/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,25 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") ++ ++go_library( ++ name = "analysis", ++ srcs = [ ++ "analysis.go", ++ "diagnostic.go", ++ "doc.go", ++ "validate.go", ++ ], ++ importpath = "golang.org/x/tools/go/analysis", ++ visibility = ["//visibility:public"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":analysis", ++ visibility = ["//visibility:public"], ++) ++ ++go_test( ++ name = "analysis_test", ++ srcs = ["validate_test.go"], ++ embed = [":analysis"], ++) diff -urN b/go/analysis/internal/analysisflags/BUILD.bazel c/go/analysis/internal/analysisflags/BUILD.bazel ---- b/go/analysis/internal/analysisflags/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/internal/analysisflags/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/internal/analysisflags/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2114,7 +2114,7 @@ diff -urN b/go/analysis/internal/analysisflags/BUILD.bazel c/go/analysis/interna + ], +) diff -urN b/go/analysis/internal/checker/BUILD.bazel c/go/analysis/internal/checker/BUILD.bazel ---- b/go/analysis/internal/checker/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/internal/checker/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/internal/checker/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2156,7 +2156,7 @@ diff -urN b/go/analysis/internal/checker/BUILD.bazel c/go/analysis/internal/chec + ], +) diff -urN b/go/analysis/internal/versiontest/BUILD.bazel c/go/analysis/internal/versiontest/BUILD.bazel ---- b/go/analysis/internal/versiontest/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/internal/versiontest/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/internal/versiontest/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,13 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") @@ -2173,7 +2173,7 @@ diff -urN b/go/analysis/internal/versiontest/BUILD.bazel c/go/analysis/internal/ + ], +) diff -urN b/go/analysis/multichecker/BUILD.bazel c/go/analysis/multichecker/BUILD.bazel ---- b/go/analysis/multichecker/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/multichecker/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/multichecker/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2208,7 +2208,7 @@ diff -urN b/go/analysis/multichecker/BUILD.bazel c/go/analysis/multichecker/BUIL + ], +) diff -urN b/go/analysis/passes/appends/BUILD.bazel c/go/analysis/passes/appends/BUILD.bazel ---- b/go/analysis/passes/appends/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/appends/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/appends/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2227,6 +2227,7 @@ diff -urN b/go/analysis/passes/appends/BUILD.bazel c/go/analysis/passes/appends/ + "//go/analysis/passes/inspect", + "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", ++ "//go/types/typeutil", + ], +) + @@ -2239,14 +2240,13 @@ diff -urN b/go/analysis/passes/appends/BUILD.bazel c/go/analysis/passes/appends/ +go_test( + name = "appends_test", + srcs = ["appends_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":appends", + "//go/analysis/analysistest", + ], +) diff -urN b/go/analysis/passes/appends/testdata/src/a/BUILD.bazel c/go/analysis/passes/appends/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/appends/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/appends/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/appends/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2264,7 +2264,7 @@ diff -urN b/go/analysis/passes/appends/testdata/src/a/BUILD.bazel c/go/analysis/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/appends/testdata/src/b/BUILD.bazel c/go/analysis/passes/appends/testdata/src/b/BUILD.bazel ---- b/go/analysis/passes/appends/testdata/src/b/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/appends/testdata/src/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/appends/testdata/src/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2282,9 +2282,9 @@ diff -urN b/go/analysis/passes/appends/testdata/src/b/BUILD.bazel c/go/analysis/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/asmdecl/BUILD.bazel c/go/analysis/passes/asmdecl/BUILD.bazel ---- b/go/analysis/passes/asmdecl/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/asmdecl/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/asmdecl/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,32 @@ +@@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -2311,14 +2311,13 @@ diff -urN b/go/analysis/passes/asmdecl/BUILD.bazel c/go/analysis/passes/asmdecl/ +go_test( + name = "asmdecl_test", + srcs = ["asmdecl_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":asmdecl", + "//go/analysis/analysistest", + ], +) diff -urN b/go/analysis/passes/asmdecl/testdata/src/a/BUILD.bazel c/go/analysis/passes/asmdecl/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/asmdecl/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/asmdecl/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/asmdecl/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2348,9 +2347,9 @@ diff -urN b/go/analysis/passes/asmdecl/testdata/src/a/BUILD.bazel c/go/analysis/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/assign/BUILD.bazel c/go/analysis/passes/assign/BUILD.bazel ---- b/go/analysis/passes/assign/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/assign/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/assign/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,34 @@ +@@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -2366,6 +2365,7 @@ diff -urN b/go/analysis/passes/assign/BUILD.bazel c/go/analysis/passes/assign/BU + "//go/analysis", + "//go/analysis/passes/inspect", + "//go/analysis/passes/internal/analysisutil", ++ "//go/ast/astutil", + "//go/ast/inspector", + ], +) @@ -2386,7 +2386,7 @@ diff -urN b/go/analysis/passes/assign/BUILD.bazel c/go/analysis/passes/assign/BU + ], +) diff -urN b/go/analysis/passes/assign/testdata/src/a/BUILD.bazel c/go/analysis/passes/assign/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/assign/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/assign/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/assign/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2404,7 +2404,7 @@ diff -urN b/go/analysis/passes/assign/testdata/src/a/BUILD.bazel c/go/analysis/p + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/assign/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/assign/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/assign/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/assign/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/assign/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2422,7 +2422,7 @@ diff -urN b/go/analysis/passes/assign/testdata/src/typeparams/BUILD.bazel c/go/a + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/atomic/BUILD.bazel c/go/analysis/passes/atomic/BUILD.bazel ---- b/go/analysis/passes/atomic/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/atomic/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/atomic/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2441,6 +2441,7 @@ diff -urN b/go/analysis/passes/atomic/BUILD.bazel c/go/analysis/passes/atomic/BU + "//go/analysis/passes/inspect", + "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", ++ "//go/types/typeutil", + ], +) + @@ -2453,7 +2454,6 @@ diff -urN b/go/analysis/passes/atomic/BUILD.bazel c/go/analysis/passes/atomic/BU +go_test( + name = "atomic_test", + srcs = ["atomic_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":atomic", + "//go/analysis/analysistest", @@ -2461,7 +2461,7 @@ diff -urN b/go/analysis/passes/atomic/BUILD.bazel c/go/analysis/passes/atomic/BU + ], +) diff -urN b/go/analysis/passes/atomic/testdata/src/a/BUILD.bazel c/go/analysis/passes/atomic/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/atomic/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/atomic/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/atomic/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2479,7 +2479,7 @@ diff -urN b/go/analysis/passes/atomic/testdata/src/a/BUILD.bazel c/go/analysis/p + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/atomic/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/atomic/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/atomic/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/atomic/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/atomic/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2497,7 +2497,7 @@ diff -urN b/go/analysis/passes/atomic/testdata/src/typeparams/BUILD.bazel c/go/a + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/atomicalign/BUILD.bazel c/go/analysis/passes/atomicalign/BUILD.bazel ---- b/go/analysis/passes/atomicalign/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/atomicalign/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/atomicalign/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2512,6 +2512,7 @@ diff -urN b/go/analysis/passes/atomicalign/BUILD.bazel c/go/analysis/passes/atom + "//go/analysis/passes/inspect", + "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", ++ "//go/types/typeutil", + ], +) + @@ -2524,14 +2525,13 @@ diff -urN b/go/analysis/passes/atomicalign/BUILD.bazel c/go/analysis/passes/atom +go_test( + name = "atomicalign_test", + srcs = ["atomicalign_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":atomicalign", + "//go/analysis/analysistest", + ], +) diff -urN b/go/analysis/passes/atomicalign/testdata/src/a/BUILD.bazel c/go/analysis/passes/atomicalign/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/atomicalign/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/atomicalign/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/atomicalign/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,17 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2552,7 +2552,7 @@ diff -urN b/go/analysis/passes/atomicalign/testdata/src/a/BUILD.bazel c/go/analy + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/atomicalign/testdata/src/b/BUILD.bazel c/go/analysis/passes/atomicalign/testdata/src/b/BUILD.bazel ---- b/go/analysis/passes/atomicalign/testdata/src/b/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/atomicalign/testdata/src/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/atomicalign/testdata/src/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,17 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2573,7 +2573,7 @@ diff -urN b/go/analysis/passes/atomicalign/testdata/src/b/BUILD.bazel c/go/analy + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/bools/BUILD.bazel c/go/analysis/passes/bools/BUILD.bazel ---- b/go/analysis/passes/bools/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/bools/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/bools/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2587,6 +2587,7 @@ diff -urN b/go/analysis/passes/bools/BUILD.bazel c/go/analysis/passes/bools/BUIL + "//go/analysis", + "//go/analysis/passes/inspect", + "//go/analysis/passes/internal/analysisutil", ++ "//go/ast/astutil", + "//go/ast/inspector", + ], +) @@ -2600,7 +2601,6 @@ diff -urN b/go/analysis/passes/bools/BUILD.bazel c/go/analysis/passes/bools/BUIL +go_test( + name = "bools_test", + srcs = ["bools_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":bools", + "//go/analysis/analysistest", @@ -2608,7 +2608,7 @@ diff -urN b/go/analysis/passes/bools/BUILD.bazel c/go/analysis/passes/bools/BUIL + ], +) diff -urN b/go/analysis/passes/bools/testdata/src/a/BUILD.bazel c/go/analysis/passes/bools/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/bools/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/bools/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/bools/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2626,7 +2626,7 @@ diff -urN b/go/analysis/passes/bools/testdata/src/a/BUILD.bazel c/go/analysis/pa + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/bools/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/bools/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/bools/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/bools/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/bools/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2644,9 +2644,9 @@ diff -urN b/go/analysis/passes/bools/testdata/src/typeparams/BUILD.bazel c/go/an + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/buildssa/BUILD.bazel c/go/analysis/passes/buildssa/BUILD.bazel ---- b/go/analysis/passes/buildssa/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/buildssa/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/buildssa/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,29 @@ +@@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -2669,7 +2669,6 @@ diff -urN b/go/analysis/passes/buildssa/BUILD.bazel c/go/analysis/passes/buildss +go_test( + name = "buildssa_test", + srcs = ["buildssa_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":buildssa", + "//go/analysis/analysistest", @@ -2677,7 +2676,7 @@ diff -urN b/go/analysis/passes/buildssa/BUILD.bazel c/go/analysis/passes/buildss + ], +) diff -urN b/go/analysis/passes/buildssa/testdata/src/a/BUILD.bazel c/go/analysis/passes/buildssa/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/buildssa/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/buildssa/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/buildssa/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2695,7 +2694,7 @@ diff -urN b/go/analysis/passes/buildssa/testdata/src/a/BUILD.bazel c/go/analysis + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/buildssa/testdata/src/b/BUILD.bazel c/go/analysis/passes/buildssa/testdata/src/b/BUILD.bazel ---- b/go/analysis/passes/buildssa/testdata/src/b/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/buildssa/testdata/src/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/buildssa/testdata/src/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2713,7 +2712,7 @@ diff -urN b/go/analysis/passes/buildssa/testdata/src/b/BUILD.bazel c/go/analysis + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/buildssa/testdata/src/c/BUILD.bazel c/go/analysis/passes/buildssa/testdata/src/c/BUILD.bazel ---- b/go/analysis/passes/buildssa/testdata/src/c/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/buildssa/testdata/src/c/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/buildssa/testdata/src/c/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2731,9 +2730,9 @@ diff -urN b/go/analysis/passes/buildssa/testdata/src/c/BUILD.bazel c/go/analysis + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/buildtag/BUILD.bazel c/go/analysis/passes/buildtag/BUILD.bazel ---- b/go/analysis/passes/buildtag/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/buildtag/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/buildtag/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,32 @@ +@@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -2759,7 +2758,6 @@ diff -urN b/go/analysis/passes/buildtag/BUILD.bazel c/go/analysis/passes/buildta +go_test( + name = "buildtag_test", + srcs = ["buildtag_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":buildtag", + "//go/analysis", @@ -2767,7 +2765,7 @@ diff -urN b/go/analysis/passes/buildtag/BUILD.bazel c/go/analysis/passes/buildta + ], +) diff -urN b/go/analysis/passes/buildtag/testdata/src/a/BUILD.bazel c/go/analysis/passes/buildtag/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/buildtag/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/buildtag/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/buildtag/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2789,7 +2787,7 @@ diff -urN b/go/analysis/passes/buildtag/testdata/src/a/BUILD.bazel c/go/analysis + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/cgocall/BUILD.bazel c/go/analysis/passes/cgocall/BUILD.bazel ---- b/go/analysis/passes/cgocall/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/cgocall/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/cgocall/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2806,6 +2804,7 @@ diff -urN b/go/analysis/passes/cgocall/BUILD.bazel c/go/analysis/passes/cgocall/ + deps = [ + "//go/analysis", + "//go/analysis/passes/internal/analysisutil", ++ "//go/ast/astutil", + ], +) + @@ -2818,7 +2817,6 @@ diff -urN b/go/analysis/passes/cgocall/BUILD.bazel c/go/analysis/passes/cgocall/ +go_test( + name = "cgocall_test", + srcs = ["cgocall_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":cgocall", + "//go/analysis/analysistest", @@ -2826,7 +2824,7 @@ diff -urN b/go/analysis/passes/cgocall/BUILD.bazel c/go/analysis/passes/cgocall/ + ], +) diff -urN b/go/analysis/passes/cgocall/testdata/src/a/BUILD.bazel c/go/analysis/passes/cgocall/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/cgocall/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/cgocall/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/cgocall/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2848,7 +2846,7 @@ diff -urN b/go/analysis/passes/cgocall/testdata/src/a/BUILD.bazel c/go/analysis/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/cgocall/testdata/src/b/BUILD.bazel c/go/analysis/passes/cgocall/testdata/src/b/BUILD.bazel ---- b/go/analysis/passes/cgocall/testdata/src/b/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/cgocall/testdata/src/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/cgocall/testdata/src/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2866,7 +2864,7 @@ diff -urN b/go/analysis/passes/cgocall/testdata/src/b/BUILD.bazel c/go/analysis/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/cgocall/testdata/src/c/BUILD.bazel c/go/analysis/passes/cgocall/testdata/src/c/BUILD.bazel ---- b/go/analysis/passes/cgocall/testdata/src/c/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/cgocall/testdata/src/c/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/cgocall/testdata/src/c/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2884,7 +2882,7 @@ diff -urN b/go/analysis/passes/cgocall/testdata/src/c/BUILD.bazel c/go/analysis/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/cgocall/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/cgocall/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/cgocall/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/cgocall/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/cgocall/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2903,9 +2901,9 @@ diff -urN b/go/analysis/passes/cgocall/testdata/src/typeparams/BUILD.bazel c/go/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/composite/BUILD.bazel c/go/analysis/passes/composite/BUILD.bazel ---- b/go/analysis/passes/composite/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/composite/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/composite/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,34 @@ +@@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -2933,7 +2931,6 @@ diff -urN b/go/analysis/passes/composite/BUILD.bazel c/go/analysis/passes/compos +go_test( + name = "composite_test", + srcs = ["composite_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":composite", + "//go/analysis/analysistest", @@ -2941,7 +2938,7 @@ diff -urN b/go/analysis/passes/composite/BUILD.bazel c/go/analysis/passes/compos + ], +) diff -urN b/go/analysis/passes/composite/testdata/src/a/BUILD.bazel c/go/analysis/passes/composite/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/composite/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/composite/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/composite/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2965,7 +2962,7 @@ diff -urN b/go/analysis/passes/composite/testdata/src/a/BUILD.bazel c/go/analysi + embed = [":a"], +) diff -urN b/go/analysis/passes/composite/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/composite/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/composite/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/composite/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/composite/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2983,7 +2980,7 @@ diff -urN b/go/analysis/passes/composite/testdata/src/typeparams/BUILD.bazel c/g + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/composite/testdata/src/typeparams/lib/BUILD.bazel c/go/analysis/passes/composite/testdata/src/typeparams/lib/BUILD.bazel ---- b/go/analysis/passes/composite/testdata/src/typeparams/lib/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/composite/testdata/src/typeparams/lib/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/composite/testdata/src/typeparams/lib/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3001,7 +2998,7 @@ diff -urN b/go/analysis/passes/composite/testdata/src/typeparams/lib/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/copylock/BUILD.bazel c/go/analysis/passes/copylock/BUILD.bazel ---- b/go/analysis/passes/copylock/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/copylock/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/copylock/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3015,6 +3012,7 @@ diff -urN b/go/analysis/passes/copylock/BUILD.bazel c/go/analysis/passes/copyloc + "//go/analysis", + "//go/analysis/passes/inspect", + "//go/analysis/passes/internal/analysisutil", ++ "//go/ast/astutil", + "//go/ast/inspector", + "//internal/typeparams", + ], @@ -3029,7 +3027,6 @@ diff -urN b/go/analysis/passes/copylock/BUILD.bazel c/go/analysis/passes/copyloc +go_test( + name = "copylock_test", + srcs = ["copylock_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":copylock", + "//go/analysis/analysistest", @@ -3037,7 +3034,7 @@ diff -urN b/go/analysis/passes/copylock/BUILD.bazel c/go/analysis/passes/copyloc + ], +) diff -urN b/go/analysis/passes/copylock/testdata/src/a/BUILD.bazel c/go/analysis/passes/copylock/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/copylock/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/copylock/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/copylock/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3060,7 +3057,7 @@ diff -urN b/go/analysis/passes/copylock/testdata/src/a/BUILD.bazel c/go/analysis + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/copylock/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/copylock/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/copylock/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/copylock/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/copylock/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3078,9 +3075,9 @@ diff -urN b/go/analysis/passes/copylock/testdata/src/typeparams/BUILD.bazel c/go + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/ctrlflow/BUILD.bazel c/go/analysis/passes/ctrlflow/BUILD.bazel ---- b/go/analysis/passes/ctrlflow/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/ctrlflow/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/ctrlflow/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,32 @@ +@@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -3106,7 +3103,6 @@ diff -urN b/go/analysis/passes/ctrlflow/BUILD.bazel c/go/analysis/passes/ctrlflo +go_test( + name = "ctrlflow_test", + srcs = ["ctrlflow_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":ctrlflow", + "//go/analysis/analysistest", @@ -3114,7 +3110,7 @@ diff -urN b/go/analysis/passes/ctrlflow/BUILD.bazel c/go/analysis/passes/ctrlflo + ], +) diff -urN b/go/analysis/passes/ctrlflow/testdata/src/a/BUILD.bazel c/go/analysis/passes/ctrlflow/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/ctrlflow/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/ctrlflow/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/ctrlflow/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3132,7 +3128,7 @@ diff -urN b/go/analysis/passes/ctrlflow/testdata/src/a/BUILD.bazel c/go/analysis + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/ctrlflow/testdata/src/lib/BUILD.bazel c/go/analysis/passes/ctrlflow/testdata/src/lib/BUILD.bazel ---- b/go/analysis/passes/ctrlflow/testdata/src/lib/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/ctrlflow/testdata/src/lib/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/ctrlflow/testdata/src/lib/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3150,7 +3146,7 @@ diff -urN b/go/analysis/passes/ctrlflow/testdata/src/lib/BUILD.bazel c/go/analys + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/ctrlflow/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/ctrlflow/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/ctrlflow/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/ctrlflow/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/ctrlflow/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3168,9 +3164,9 @@ diff -urN b/go/analysis/passes/ctrlflow/testdata/src/typeparams/BUILD.bazel c/go + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/deepequalerrors/BUILD.bazel c/go/analysis/passes/deepequalerrors/BUILD.bazel ---- b/go/analysis/passes/deepequalerrors/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/deepequalerrors/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/deepequalerrors/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,32 @@ +@@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -3196,7 +3192,6 @@ diff -urN b/go/analysis/passes/deepequalerrors/BUILD.bazel c/go/analysis/passes/ +go_test( + name = "deepequalerrors_test", + srcs = ["deepequalerrors_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":deepequalerrors", + "//go/analysis/analysistest", @@ -3204,7 +3199,7 @@ diff -urN b/go/analysis/passes/deepequalerrors/BUILD.bazel c/go/analysis/passes/ + ], +) diff -urN b/go/analysis/passes/deepequalerrors/testdata/src/a/BUILD.bazel c/go/analysis/passes/deepequalerrors/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/deepequalerrors/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/deepequalerrors/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/deepequalerrors/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3222,7 +3217,7 @@ diff -urN b/go/analysis/passes/deepequalerrors/testdata/src/a/BUILD.bazel c/go/a + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/deepequalerrors/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/deepequalerrors/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/deepequalerrors/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/deepequalerrors/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/deepequalerrors/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3240,9 +3235,9 @@ diff -urN b/go/analysis/passes/deepequalerrors/testdata/src/typeparams/BUILD.baz + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/defers/BUILD.bazel c/go/analysis/passes/defers/BUILD.bazel ---- b/go/analysis/passes/defers/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/defers/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/defers/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,35 @@ +@@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -3272,14 +3267,13 @@ diff -urN b/go/analysis/passes/defers/BUILD.bazel c/go/analysis/passes/defers/BU +go_test( + name = "defers_test", + srcs = ["defers_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":defers", + "//go/analysis/analysistest", + ], +) diff -urN b/go/analysis/passes/defers/cmd/defers/BUILD.bazel c/go/analysis/passes/defers/cmd/defers/BUILD.bazel ---- b/go/analysis/passes/defers/cmd/defers/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/defers/cmd/defers/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/defers/cmd/defers/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -3301,7 +3295,7 @@ diff -urN b/go/analysis/passes/defers/cmd/defers/BUILD.bazel c/go/analysis/passe + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/defers/testdata/src/a/BUILD.bazel c/go/analysis/passes/defers/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/defers/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/defers/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/defers/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3319,9 +3313,9 @@ diff -urN b/go/analysis/passes/defers/testdata/src/a/BUILD.bazel c/go/analysis/p + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/directive/BUILD.bazel c/go/analysis/passes/directive/BUILD.bazel ---- b/go/analysis/passes/directive/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/directive/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/directive/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,29 @@ +@@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -3344,7 +3338,6 @@ diff -urN b/go/analysis/passes/directive/BUILD.bazel c/go/analysis/passes/direct +go_test( + name = "directive_test", + srcs = ["directive_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":directive", + "//go/analysis", @@ -3352,7 +3345,7 @@ diff -urN b/go/analysis/passes/directive/BUILD.bazel c/go/analysis/passes/direct + ], +) diff -urN b/go/analysis/passes/directive/testdata/src/a/BUILD.bazel c/go/analysis/passes/directive/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/directive/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/directive/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/directive/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3378,7 +3371,7 @@ diff -urN b/go/analysis/passes/directive/testdata/src/a/BUILD.bazel c/go/analysi + srcs = ["misplaced_test.go"], +) diff -urN b/go/analysis/passes/errorsas/BUILD.bazel c/go/analysis/passes/errorsas/BUILD.bazel ---- b/go/analysis/passes/errorsas/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/errorsas/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/errorsas/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3413,7 +3406,7 @@ diff -urN b/go/analysis/passes/errorsas/BUILD.bazel c/go/analysis/passes/errorsa + ], +) diff -urN b/go/analysis/passes/errorsas/testdata/src/a/BUILD.bazel c/go/analysis/passes/errorsas/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/errorsas/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/errorsas/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/errorsas/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3431,7 +3424,7 @@ diff -urN b/go/analysis/passes/errorsas/testdata/src/a/BUILD.bazel c/go/analysis + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/errorsas/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/errorsas/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/errorsas/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/errorsas/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/errorsas/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3449,9 +3442,9 @@ diff -urN b/go/analysis/passes/errorsas/testdata/src/typeparams/BUILD.bazel c/go + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/fieldalignment/BUILD.bazel c/go/analysis/passes/fieldalignment/BUILD.bazel ---- b/go/analysis/passes/fieldalignment/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/fieldalignment/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/fieldalignment/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,29 @@ +@@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -3475,14 +3468,13 @@ diff -urN b/go/analysis/passes/fieldalignment/BUILD.bazel c/go/analysis/passes/f +go_test( + name = "fieldalignment_test", + srcs = ["fieldalignment_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":fieldalignment", + "//go/analysis/analysistest", + ], +) diff -urN b/go/analysis/passes/fieldalignment/cmd/fieldalignment/BUILD.bazel c/go/analysis/passes/fieldalignment/cmd/fieldalignment/BUILD.bazel ---- b/go/analysis/passes/fieldalignment/cmd/fieldalignment/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/fieldalignment/cmd/fieldalignment/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/fieldalignment/cmd/fieldalignment/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -3504,7 +3496,7 @@ diff -urN b/go/analysis/passes/fieldalignment/cmd/fieldalignment/BUILD.bazel c/g + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/fieldalignment/testdata/src/a/BUILD.bazel c/go/analysis/passes/fieldalignment/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/fieldalignment/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/fieldalignment/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/fieldalignment/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3526,9 +3518,9 @@ diff -urN b/go/analysis/passes/fieldalignment/testdata/src/a/BUILD.bazel c/go/an + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/findcall/BUILD.bazel c/go/analysis/passes/findcall/BUILD.bazel ---- b/go/analysis/passes/findcall/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/findcall/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/findcall/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,25 @@ +@@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -3548,14 +3540,13 @@ diff -urN b/go/analysis/passes/findcall/BUILD.bazel c/go/analysis/passes/findcal +go_test( + name = "findcall_test", + srcs = ["findcall_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":findcall", + "//go/analysis/analysistest", + ], +) diff -urN b/go/analysis/passes/findcall/cmd/findcall/BUILD.bazel c/go/analysis/passes/findcall/cmd/findcall/BUILD.bazel ---- b/go/analysis/passes/findcall/cmd/findcall/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/findcall/cmd/findcall/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/findcall/cmd/findcall/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -3577,7 +3568,7 @@ diff -urN b/go/analysis/passes/findcall/cmd/findcall/BUILD.bazel c/go/analysis/p + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/findcall/testdata/src/a/BUILD.bazel c/go/analysis/passes/findcall/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/findcall/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/findcall/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/findcall/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -3595,9 +3586,9 @@ diff -urN b/go/analysis/passes/findcall/testdata/src/a/BUILD.bazel c/go/analysis + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/framepointer/BUILD.bazel c/go/analysis/passes/framepointer/BUILD.bazel ---- b/go/analysis/passes/framepointer/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/framepointer/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/framepointer/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,28 @@ +@@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -3620,14 +3611,13 @@ diff -urN b/go/analysis/passes/framepointer/BUILD.bazel c/go/analysis/passes/fra +go_test( + name = "framepointer_test", + srcs = ["framepointer_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":framepointer", + "//go/analysis/analysistest", + ], +) diff -urN b/go/analysis/passes/framepointer/testdata/src/a/BUILD.bazel c/go/analysis/passes/framepointer/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/framepointer/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/framepointer/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/framepointer/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3650,10 +3640,83 @@ diff -urN b/go/analysis/passes/framepointer/testdata/src/a/BUILD.bazel c/go/anal + actual = ":a", + visibility = ["//visibility:public"], +) +diff -urN b/go/analysis/passes/httpmux/BUILD.bazel c/go/analysis/passes/httpmux/BUILD.bazel +--- b/go/analysis/passes/httpmux/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/analysis/passes/httpmux/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,29 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") ++ ++go_library( ++ name = "httpmux", ++ srcs = ["httpmux.go"], ++ importpath = "golang.org/x/tools/go/analysis/passes/httpmux", ++ visibility = ["//visibility:public"], ++ deps = [ ++ "//go/analysis", ++ "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", ++ "//go/ast/inspector", ++ "//go/types/typeutil", ++ "@org_golang_x_mod//semver:go_default_library", ++ ], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":httpmux", ++ visibility = ["//visibility:public"], ++) ++ ++go_test( ++ name = "httpmux_test", ++ srcs = ["httpmux_test.go"], ++ embed = [":httpmux"], ++ deps = ["//go/analysis/analysistest"], ++) +diff -urN b/go/analysis/passes/httpmux/cmd/httpmux/BUILD.bazel c/go/analysis/passes/httpmux/cmd/httpmux/BUILD.bazel +--- b/go/analysis/passes/httpmux/cmd/httpmux/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/analysis/passes/httpmux/cmd/httpmux/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,18 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") ++ ++go_library( ++ name = "httpmux_lib", ++ srcs = ["main.go"], ++ importpath = "golang.org/x/tools/go/analysis/passes/httpmux/cmd/httpmux", ++ visibility = ["//visibility:private"], ++ deps = [ ++ "//go/analysis/passes/httpmux", ++ "//go/analysis/singlechecker", ++ ], ++) ++ ++go_binary( ++ name = "httpmux", ++ embed = [":httpmux_lib"], ++ visibility = ["//visibility:public"], ++) +diff -urN b/go/analysis/passes/httpmux/testdata/src/a/BUILD.bazel c/go/analysis/passes/httpmux/testdata/src/a/BUILD.bazel +--- b/go/analysis/passes/httpmux/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/analysis/passes/httpmux/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,14 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "a", ++ srcs = ["a.go"], ++ importpath = "golang.org/x/tools/go/analysis/passes/httpmux/testdata/src/a", ++ visibility = ["//visibility:public"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":a", ++ visibility = ["//visibility:public"], ++) diff -urN b/go/analysis/passes/httpresponse/BUILD.bazel c/go/analysis/passes/httpresponse/BUILD.bazel ---- b/go/analysis/passes/httpresponse/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/httpresponse/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/httpresponse/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,31 @@ +@@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -3678,7 +3741,6 @@ diff -urN b/go/analysis/passes/httpresponse/BUILD.bazel c/go/analysis/passes/htt +go_test( + name = "httpresponse_test", + srcs = ["httpresponse_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":httpresponse", + "//go/analysis/analysistest", @@ -3686,7 +3748,7 @@ diff -urN b/go/analysis/passes/httpresponse/BUILD.bazel c/go/analysis/passes/htt + ], +) diff -urN b/go/analysis/passes/httpresponse/testdata/src/a/BUILD.bazel c/go/analysis/passes/httpresponse/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/httpresponse/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/httpresponse/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/httpresponse/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3704,7 +3766,7 @@ diff -urN b/go/analysis/passes/httpresponse/testdata/src/a/BUILD.bazel c/go/anal + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/httpresponse/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/httpresponse/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/httpresponse/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/httpresponse/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/httpresponse/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3722,9 +3784,9 @@ diff -urN b/go/analysis/passes/httpresponse/testdata/src/typeparams/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/ifaceassert/BUILD.bazel c/go/analysis/passes/ifaceassert/BUILD.bazel ---- b/go/analysis/passes/ifaceassert/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/ifaceassert/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/ifaceassert/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,37 @@ +@@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -3755,7 +3817,6 @@ diff -urN b/go/analysis/passes/ifaceassert/BUILD.bazel c/go/analysis/passes/ifac +go_test( + name = "ifaceassert_test", + srcs = ["ifaceassert_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":ifaceassert", + "//go/analysis/analysistest", @@ -3763,7 +3824,7 @@ diff -urN b/go/analysis/passes/ifaceassert/BUILD.bazel c/go/analysis/passes/ifac + ], +) diff -urN b/go/analysis/passes/ifaceassert/cmd/ifaceassert/BUILD.bazel c/go/analysis/passes/ifaceassert/cmd/ifaceassert/BUILD.bazel ---- b/go/analysis/passes/ifaceassert/cmd/ifaceassert/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/ifaceassert/cmd/ifaceassert/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/ifaceassert/cmd/ifaceassert/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -3785,7 +3846,7 @@ diff -urN b/go/analysis/passes/ifaceassert/cmd/ifaceassert/BUILD.bazel c/go/anal + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/ifaceassert/testdata/src/a/BUILD.bazel c/go/analysis/passes/ifaceassert/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/ifaceassert/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/ifaceassert/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/ifaceassert/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3803,7 +3864,7 @@ diff -urN b/go/analysis/passes/ifaceassert/testdata/src/a/BUILD.bazel c/go/analy + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/ifaceassert/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/ifaceassert/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/ifaceassert/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/ifaceassert/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/ifaceassert/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3821,7 +3882,7 @@ diff -urN b/go/analysis/passes/ifaceassert/testdata/src/typeparams/BUILD.bazel c + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/inspect/BUILD.bazel c/go/analysis/passes/inspect/BUILD.bazel ---- b/go/analysis/passes/inspect/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/inspect/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/inspect/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3843,7 +3904,7 @@ diff -urN b/go/analysis/passes/inspect/BUILD.bazel c/go/analysis/passes/inspect/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/internal/analysisutil/BUILD.bazel c/go/analysis/passes/internal/analysisutil/BUILD.bazel ---- b/go/analysis/passes/internal/analysisutil/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/internal/analysisutil/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/internal/analysisutil/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3876,9 +3937,9 @@ diff -urN b/go/analysis/passes/internal/analysisutil/BUILD.bazel c/go/analysis/p + ], +) diff -urN b/go/analysis/passes/loopclosure/BUILD.bazel c/go/analysis/passes/loopclosure/BUILD.bazel ---- b/go/analysis/passes/loopclosure/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/loopclosure/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/loopclosure/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,36 @@ +@@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -3908,7 +3969,6 @@ diff -urN b/go/analysis/passes/loopclosure/BUILD.bazel c/go/analysis/passes/loop +go_test( + name = "loopclosure_test", + srcs = ["loopclosure_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":loopclosure", + "//go/analysis/analysistest", @@ -3916,7 +3976,7 @@ diff -urN b/go/analysis/passes/loopclosure/BUILD.bazel c/go/analysis/passes/loop + ], +) diff -urN b/go/analysis/passes/loopclosure/testdata/src/a/BUILD.bazel c/go/analysis/passes/loopclosure/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/loopclosure/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/loopclosure/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/loopclosure/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3938,7 +3998,7 @@ diff -urN b/go/analysis/passes/loopclosure/testdata/src/a/BUILD.bazel c/go/analy + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/loopclosure/testdata/src/golang.org/x/sync/errgroup/BUILD.bazel c/go/analysis/passes/loopclosure/testdata/src/golang.org/x/sync/errgroup/BUILD.bazel ---- b/go/analysis/passes/loopclosure/testdata/src/golang.org/x/sync/errgroup/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/loopclosure/testdata/src/golang.org/x/sync/errgroup/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/loopclosure/testdata/src/golang.org/x/sync/errgroup/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3956,7 +4016,7 @@ diff -urN b/go/analysis/passes/loopclosure/testdata/src/golang.org/x/sync/errgro + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/loopclosure/testdata/src/subtests/BUILD.bazel c/go/analysis/passes/loopclosure/testdata/src/subtests/BUILD.bazel ---- b/go/analysis/passes/loopclosure/testdata/src/subtests/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/loopclosure/testdata/src/subtests/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/loopclosure/testdata/src/subtests/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3974,7 +4034,7 @@ diff -urN b/go/analysis/passes/loopclosure/testdata/src/subtests/BUILD.bazel c/g + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/loopclosure/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/loopclosure/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/loopclosure/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/loopclosure/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/loopclosure/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3993,9 +4053,9 @@ diff -urN b/go/analysis/passes/loopclosure/testdata/src/typeparams/BUILD.bazel c + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/lostcancel/BUILD.bazel c/go/analysis/passes/lostcancel/BUILD.bazel ---- b/go/analysis/passes/lostcancel/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/lostcancel/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/lostcancel/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,37 @@ +@@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -4026,7 +4086,6 @@ diff -urN b/go/analysis/passes/lostcancel/BUILD.bazel c/go/analysis/passes/lostc +go_test( + name = "lostcancel_test", + srcs = ["lostcancel_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":lostcancel", + "//go/analysis/analysistest", @@ -4034,7 +4093,7 @@ diff -urN b/go/analysis/passes/lostcancel/BUILD.bazel c/go/analysis/passes/lostc + ], +) diff -urN b/go/analysis/passes/lostcancel/cmd/lostcancel/BUILD.bazel c/go/analysis/passes/lostcancel/cmd/lostcancel/BUILD.bazel ---- b/go/analysis/passes/lostcancel/cmd/lostcancel/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/lostcancel/cmd/lostcancel/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/lostcancel/cmd/lostcancel/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -4056,7 +4115,7 @@ diff -urN b/go/analysis/passes/lostcancel/cmd/lostcancel/BUILD.bazel c/go/analys + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/lostcancel/testdata/src/a/BUILD.bazel c/go/analysis/passes/lostcancel/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/lostcancel/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/lostcancel/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/lostcancel/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4074,7 +4133,7 @@ diff -urN b/go/analysis/passes/lostcancel/testdata/src/a/BUILD.bazel c/go/analys + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/lostcancel/testdata/src/b/BUILD.bazel c/go/analysis/passes/lostcancel/testdata/src/b/BUILD.bazel ---- b/go/analysis/passes/lostcancel/testdata/src/b/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/lostcancel/testdata/src/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/lostcancel/testdata/src/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -4092,7 +4151,7 @@ diff -urN b/go/analysis/passes/lostcancel/testdata/src/b/BUILD.bazel c/go/analys + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/lostcancel/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/lostcancel/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/lostcancel/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/lostcancel/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/lostcancel/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4110,7 +4169,7 @@ diff -urN b/go/analysis/passes/lostcancel/testdata/src/typeparams/BUILD.bazel c/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/nilfunc/BUILD.bazel c/go/analysis/passes/nilfunc/BUILD.bazel ---- b/go/analysis/passes/nilfunc/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/nilfunc/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/nilfunc/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4149,7 +4208,7 @@ diff -urN b/go/analysis/passes/nilfunc/BUILD.bazel c/go/analysis/passes/nilfunc/ + ], +) diff -urN b/go/analysis/passes/nilfunc/testdata/src/a/BUILD.bazel c/go/analysis/passes/nilfunc/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/nilfunc/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/nilfunc/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/nilfunc/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4167,7 +4226,7 @@ diff -urN b/go/analysis/passes/nilfunc/testdata/src/a/BUILD.bazel c/go/analysis/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/nilfunc/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/nilfunc/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/nilfunc/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/nilfunc/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/nilfunc/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4185,7 +4244,7 @@ diff -urN b/go/analysis/passes/nilfunc/testdata/src/typeparams/BUILD.bazel c/go/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/nilness/BUILD.bazel c/go/analysis/passes/nilness/BUILD.bazel ---- b/go/analysis/passes/nilness/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/nilness/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/nilness/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4227,7 +4286,7 @@ diff -urN b/go/analysis/passes/nilness/BUILD.bazel c/go/analysis/passes/nilness/ + ], +) diff -urN b/go/analysis/passes/nilness/cmd/nilness/BUILD.bazel c/go/analysis/passes/nilness/cmd/nilness/BUILD.bazel ---- b/go/analysis/passes/nilness/cmd/nilness/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/nilness/cmd/nilness/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/nilness/cmd/nilness/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -4249,7 +4308,7 @@ diff -urN b/go/analysis/passes/nilness/cmd/nilness/BUILD.bazel c/go/analysis/pas + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/nilness/testdata/src/a/BUILD.bazel c/go/analysis/passes/nilness/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/nilness/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/nilness/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/nilness/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4267,7 +4326,7 @@ diff -urN b/go/analysis/passes/nilness/testdata/src/a/BUILD.bazel c/go/analysis/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/nilness/testdata/src/b/BUILD.bazel c/go/analysis/passes/nilness/testdata/src/b/BUILD.bazel ---- b/go/analysis/passes/nilness/testdata/src/b/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/nilness/testdata/src/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/nilness/testdata/src/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4285,7 +4344,7 @@ diff -urN b/go/analysis/passes/nilness/testdata/src/b/BUILD.bazel c/go/analysis/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/nilness/testdata/src/c/BUILD.bazel c/go/analysis/passes/nilness/testdata/src/c/BUILD.bazel ---- b/go/analysis/passes/nilness/testdata/src/c/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/nilness/testdata/src/c/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/nilness/testdata/src/c/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4303,7 +4362,7 @@ diff -urN b/go/analysis/passes/nilness/testdata/src/c/BUILD.bazel c/go/analysis/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/nilness/testdata/src/d/BUILD.bazel c/go/analysis/passes/nilness/testdata/src/d/BUILD.bazel ---- b/go/analysis/passes/nilness/testdata/src/d/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/nilness/testdata/src/d/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/nilness/testdata/src/d/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4321,7 +4380,7 @@ diff -urN b/go/analysis/passes/nilness/testdata/src/d/BUILD.bazel c/go/analysis/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/pkgfact/BUILD.bazel c/go/analysis/passes/pkgfact/BUILD.bazel ---- b/go/analysis/passes/pkgfact/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/pkgfact/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/pkgfact/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4349,7 +4408,7 @@ diff -urN b/go/analysis/passes/pkgfact/BUILD.bazel c/go/analysis/passes/pkgfact/ + ], +) diff -urN b/go/analysis/passes/pkgfact/testdata/src/a/BUILD.bazel c/go/analysis/passes/pkgfact/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/pkgfact/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/pkgfact/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/pkgfact/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4367,7 +4426,7 @@ diff -urN b/go/analysis/passes/pkgfact/testdata/src/a/BUILD.bazel c/go/analysis/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/pkgfact/testdata/src/b/BUILD.bazel c/go/analysis/passes/pkgfact/testdata/src/b/BUILD.bazel ---- b/go/analysis/passes/pkgfact/testdata/src/b/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/pkgfact/testdata/src/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/pkgfact/testdata/src/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4385,7 +4444,7 @@ diff -urN b/go/analysis/passes/pkgfact/testdata/src/b/BUILD.bazel c/go/analysis/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/pkgfact/testdata/src/c/BUILD.bazel c/go/analysis/passes/pkgfact/testdata/src/c/BUILD.bazel ---- b/go/analysis/passes/pkgfact/testdata/src/c/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/pkgfact/testdata/src/c/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/pkgfact/testdata/src/c/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4403,7 +4462,7 @@ diff -urN b/go/analysis/passes/pkgfact/testdata/src/c/BUILD.bazel c/go/analysis/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/printf/BUILD.bazel c/go/analysis/passes/printf/BUILD.bazel ---- b/go/analysis/passes/printf/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/printf/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/printf/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4445,7 +4504,7 @@ diff -urN b/go/analysis/passes/printf/BUILD.bazel c/go/analysis/passes/printf/BU + ], +) diff -urN b/go/analysis/passes/printf/testdata/src/a/BUILD.bazel c/go/analysis/passes/printf/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/printf/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/printf/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/printf/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4463,7 +4522,7 @@ diff -urN b/go/analysis/passes/printf/testdata/src/a/BUILD.bazel c/go/analysis/p + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/printf/testdata/src/b/BUILD.bazel c/go/analysis/passes/printf/testdata/src/b/BUILD.bazel ---- b/go/analysis/passes/printf/testdata/src/b/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/printf/testdata/src/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/printf/testdata/src/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4481,7 +4540,7 @@ diff -urN b/go/analysis/passes/printf/testdata/src/b/BUILD.bazel c/go/analysis/p + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/printf/testdata/src/nofmt/BUILD.bazel c/go/analysis/passes/printf/testdata/src/nofmt/BUILD.bazel ---- b/go/analysis/passes/printf/testdata/src/nofmt/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/printf/testdata/src/nofmt/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/printf/testdata/src/nofmt/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4499,7 +4558,7 @@ diff -urN b/go/analysis/passes/printf/testdata/src/nofmt/BUILD.bazel c/go/analys + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/printf/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/printf/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/printf/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/printf/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/printf/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,17 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4520,7 +4579,7 @@ diff -urN b/go/analysis/passes/printf/testdata/src/typeparams/BUILD.bazel c/go/a + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/reflectvaluecompare/BUILD.bazel c/go/analysis/passes/reflectvaluecompare/BUILD.bazel ---- b/go/analysis/passes/reflectvaluecompare/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/reflectvaluecompare/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/reflectvaluecompare/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4558,7 +4617,7 @@ diff -urN b/go/analysis/passes/reflectvaluecompare/BUILD.bazel c/go/analysis/pas + ], +) diff -urN b/go/analysis/passes/reflectvaluecompare/testdata/src/a/BUILD.bazel c/go/analysis/passes/reflectvaluecompare/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/reflectvaluecompare/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/reflectvaluecompare/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/reflectvaluecompare/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4576,7 +4635,7 @@ diff -urN b/go/analysis/passes/reflectvaluecompare/testdata/src/a/BUILD.bazel c/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/shadow/BUILD.bazel c/go/analysis/passes/shadow/BUILD.bazel ---- b/go/analysis/passes/shadow/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/shadow/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/shadow/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4613,7 +4672,7 @@ diff -urN b/go/analysis/passes/shadow/BUILD.bazel c/go/analysis/passes/shadow/BU + ], +) diff -urN b/go/analysis/passes/shadow/cmd/shadow/BUILD.bazel c/go/analysis/passes/shadow/cmd/shadow/BUILD.bazel ---- b/go/analysis/passes/shadow/cmd/shadow/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/shadow/cmd/shadow/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/shadow/cmd/shadow/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -4635,7 +4694,7 @@ diff -urN b/go/analysis/passes/shadow/cmd/shadow/BUILD.bazel c/go/analysis/passe + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/shadow/testdata/src/a/BUILD.bazel c/go/analysis/passes/shadow/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/shadow/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/shadow/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/shadow/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4653,7 +4712,7 @@ diff -urN b/go/analysis/passes/shadow/testdata/src/a/BUILD.bazel c/go/analysis/p + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/shift/BUILD.bazel c/go/analysis/passes/shift/BUILD.bazel ---- b/go/analysis/passes/shift/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/shift/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/shift/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4691,7 +4750,7 @@ diff -urN b/go/analysis/passes/shift/BUILD.bazel c/go/analysis/passes/shift/BUIL + ], +) diff -urN b/go/analysis/passes/shift/testdata/src/a/BUILD.bazel c/go/analysis/passes/shift/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/shift/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/shift/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/shift/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4709,7 +4768,7 @@ diff -urN b/go/analysis/passes/shift/testdata/src/a/BUILD.bazel c/go/analysis/pa + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/shift/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/shift/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/shift/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/shift/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/shift/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4727,7 +4786,7 @@ diff -urN b/go/analysis/passes/shift/testdata/src/typeparams/BUILD.bazel c/go/an + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/sigchanyzer/BUILD.bazel c/go/analysis/passes/sigchanyzer/BUILD.bazel ---- b/go/analysis/passes/sigchanyzer/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/sigchanyzer/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/sigchanyzer/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4764,7 +4823,7 @@ diff -urN b/go/analysis/passes/sigchanyzer/BUILD.bazel c/go/analysis/passes/sigc + ], +) diff -urN b/go/analysis/passes/sigchanyzer/testdata/src/a/BUILD.bazel c/go/analysis/passes/sigchanyzer/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/sigchanyzer/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/sigchanyzer/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/sigchanyzer/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4782,7 +4841,7 @@ diff -urN b/go/analysis/passes/sigchanyzer/testdata/src/a/BUILD.bazel c/go/analy + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/slog/BUILD.bazel c/go/analysis/passes/slog/BUILD.bazel ---- b/go/analysis/passes/slog/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/slog/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/slog/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4821,7 +4880,7 @@ diff -urN b/go/analysis/passes/slog/BUILD.bazel c/go/analysis/passes/slog/BUILD. + ], +) diff -urN b/go/analysis/passes/slog/testdata/src/a/BUILD.bazel c/go/analysis/passes/slog/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/slog/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/slog/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/slog/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4839,7 +4898,7 @@ diff -urN b/go/analysis/passes/slog/testdata/src/a/BUILD.bazel c/go/analysis/pas + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/slog/testdata/src/b/BUILD.bazel c/go/analysis/passes/slog/testdata/src/b/BUILD.bazel ---- b/go/analysis/passes/slog/testdata/src/b/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/slog/testdata/src/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/slog/testdata/src/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4857,7 +4916,7 @@ diff -urN b/go/analysis/passes/slog/testdata/src/b/BUILD.bazel c/go/analysis/pas + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/sortslice/BUILD.bazel c/go/analysis/passes/sortslice/BUILD.bazel ---- b/go/analysis/passes/sortslice/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/sortslice/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/sortslice/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4891,7 +4950,7 @@ diff -urN b/go/analysis/passes/sortslice/BUILD.bazel c/go/analysis/passes/sortsl + ], +) diff -urN b/go/analysis/passes/sortslice/testdata/src/a/BUILD.bazel c/go/analysis/passes/sortslice/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/sortslice/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/sortslice/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/sortslice/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4909,9 +4968,9 @@ diff -urN b/go/analysis/passes/sortslice/testdata/src/a/BUILD.bazel c/go/analysi + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/stdmethods/BUILD.bazel c/go/analysis/passes/stdmethods/BUILD.bazel ---- b/go/analysis/passes/stdmethods/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/stdmethods/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/stdmethods/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,35 @@ +@@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -4940,7 +4999,6 @@ diff -urN b/go/analysis/passes/stdmethods/BUILD.bazel c/go/analysis/passes/stdme +go_test( + name = "stdmethods_test", + srcs = ["stdmethods_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":stdmethods", + "//go/analysis/analysistest", @@ -4948,7 +5006,7 @@ diff -urN b/go/analysis/passes/stdmethods/BUILD.bazel c/go/analysis/passes/stdme + ], +) diff -urN b/go/analysis/passes/stdmethods/testdata/src/a/BUILD.bazel c/go/analysis/passes/stdmethods/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/stdmethods/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/stdmethods/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/stdmethods/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,17 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4969,7 +5027,7 @@ diff -urN b/go/analysis/passes/stdmethods/testdata/src/a/BUILD.bazel c/go/analys + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/stdmethods/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/stdmethods/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/stdmethods/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/stdmethods/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/stdmethods/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4987,9 +5045,9 @@ diff -urN b/go/analysis/passes/stdmethods/testdata/src/typeparams/BUILD.bazel c/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/stringintconv/BUILD.bazel c/go/analysis/passes/stringintconv/BUILD.bazel ---- b/go/analysis/passes/stringintconv/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/stringintconv/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/stringintconv/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,36 @@ +@@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -5019,7 +5077,6 @@ diff -urN b/go/analysis/passes/stringintconv/BUILD.bazel c/go/analysis/passes/st +go_test( + name = "stringintconv_test", + srcs = ["string_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":stringintconv", + "//go/analysis/analysistest", @@ -5027,7 +5084,7 @@ diff -urN b/go/analysis/passes/stringintconv/BUILD.bazel c/go/analysis/passes/st + ], +) diff -urN b/go/analysis/passes/stringintconv/cmd/stringintconv/BUILD.bazel c/go/analysis/passes/stringintconv/cmd/stringintconv/BUILD.bazel ---- b/go/analysis/passes/stringintconv/cmd/stringintconv/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/stringintconv/cmd/stringintconv/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/stringintconv/cmd/stringintconv/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -5049,7 +5106,7 @@ diff -urN b/go/analysis/passes/stringintconv/cmd/stringintconv/BUILD.bazel c/go/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/stringintconv/testdata/src/a/BUILD.bazel c/go/analysis/passes/stringintconv/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/stringintconv/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/stringintconv/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/stringintconv/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5067,7 +5124,7 @@ diff -urN b/go/analysis/passes/stringintconv/testdata/src/a/BUILD.bazel c/go/ana + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/stringintconv/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/stringintconv/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/stringintconv/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/stringintconv/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/stringintconv/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5085,9 +5142,9 @@ diff -urN b/go/analysis/passes/stringintconv/testdata/src/typeparams/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/structtag/BUILD.bazel c/go/analysis/passes/structtag/BUILD.bazel ---- b/go/analysis/passes/structtag/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/structtag/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/structtag/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,29 @@ +@@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -5111,52 +5168,51 @@ diff -urN b/go/analysis/passes/structtag/BUILD.bazel c/go/analysis/passes/struct +go_test( + name = "structtag_test", + srcs = ["structtag_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":structtag", + "//go/analysis/analysistest", + ], +) -diff -urN b/go/analysis/passes/structtag/testdata/src/a/BUILD.bazel c/go/analysis/passes/structtag/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/structtag/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 -+++ c/go/analysis/passes/structtag/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +diff -urN b/go/analysis/passes/structtag/testdata/src/a/b/BUILD.bazel c/go/analysis/passes/structtag/testdata/src/a/b/BUILD.bazel +--- b/go/analysis/passes/structtag/testdata/src/a/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/analysis/passes/structtag/testdata/src/a/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( -+ name = "a", -+ srcs = ["a.go"], -+ importpath = "golang.org/x/tools/go/analysis/passes/structtag/testdata/src/a", ++ name = "b", ++ srcs = ["b.go"], ++ importpath = "golang.org/x/tools/go/analysis/passes/structtag/testdata/src/a/b", + visibility = ["//visibility:public"], +) + +alias( + name = "go_default_library", -+ actual = ":a", ++ actual = ":b", + visibility = ["//visibility:public"], +) -diff -urN b/go/analysis/passes/structtag/testdata/src/a/b/BUILD.bazel c/go/analysis/passes/structtag/testdata/src/a/b/BUILD.bazel ---- b/go/analysis/passes/structtag/testdata/src/a/b/BUILD.bazel 1970-01-01 08:00:00 -+++ c/go/analysis/passes/structtag/testdata/src/a/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +diff -urN b/go/analysis/passes/structtag/testdata/src/a/BUILD.bazel c/go/analysis/passes/structtag/testdata/src/a/BUILD.bazel +--- b/go/analysis/passes/structtag/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/analysis/passes/structtag/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( -+ name = "b", -+ srcs = ["b.go"], -+ importpath = "golang.org/x/tools/go/analysis/passes/structtag/testdata/src/a/b", ++ name = "a", ++ srcs = ["a.go"], ++ importpath = "golang.org/x/tools/go/analysis/passes/structtag/testdata/src/a", + visibility = ["//visibility:public"], +) + +alias( + name = "go_default_library", -+ actual = ":b", ++ actual = ":a", + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/testinggoroutine/BUILD.bazel c/go/analysis/passes/testinggoroutine/BUILD.bazel ---- b/go/analysis/passes/testinggoroutine/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/testinggoroutine/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/testinggoroutine/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,36 @@ +@@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -5186,7 +5242,6 @@ diff -urN b/go/analysis/passes/testinggoroutine/BUILD.bazel c/go/analysis/passes +go_test( + name = "testinggoroutine_test", + srcs = ["testinggoroutine_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":testinggoroutine", + "//go/analysis/analysistest", @@ -5194,7 +5249,7 @@ diff -urN b/go/analysis/passes/testinggoroutine/BUILD.bazel c/go/analysis/passes + ], +) diff -urN b/go/analysis/passes/testinggoroutine/testdata/src/a/BUILD.bazel c/go/analysis/passes/testinggoroutine/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/testinggoroutine/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/testinggoroutine/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/testinggoroutine/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,17 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5215,7 +5270,7 @@ diff -urN b/go/analysis/passes/testinggoroutine/testdata/src/a/BUILD.bazel c/go/ + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/testinggoroutine/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/testinggoroutine/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/testinggoroutine/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/testinggoroutine/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/testinggoroutine/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5233,9 +5288,9 @@ diff -urN b/go/analysis/passes/testinggoroutine/testdata/src/typeparams/BUILD.ba + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/tests/BUILD.bazel c/go/analysis/passes/tests/BUILD.bazel ---- b/go/analysis/passes/tests/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/tests/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/tests/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,34 @@ +@@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -5263,7 +5318,6 @@ diff -urN b/go/analysis/passes/tests/BUILD.bazel c/go/analysis/passes/tests/BUIL +go_test( + name = "tests_test", + srcs = ["tests_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":tests", + "//go/analysis/analysistest", @@ -5271,7 +5325,7 @@ diff -urN b/go/analysis/passes/tests/BUILD.bazel c/go/analysis/passes/tests/BUIL + ], +) diff -urN b/go/analysis/passes/tests/testdata/src/a/BUILD.bazel c/go/analysis/passes/tests/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/tests/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/tests/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/tests/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5299,7 +5353,7 @@ diff -urN b/go/analysis/passes/tests/testdata/src/a/BUILD.bazel c/go/analysis/pa + embed = [":a"], +) diff -urN b/go/analysis/passes/tests/testdata/src/b/BUILD.bazel c/go/analysis/passes/tests/testdata/src/b/BUILD.bazel ---- b/go/analysis/passes/tests/testdata/src/b/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/tests/testdata/src/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/tests/testdata/src/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5317,7 +5371,7 @@ diff -urN b/go/analysis/passes/tests/testdata/src/b/BUILD.bazel c/go/analysis/pa + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/tests/testdata/src/b_x_test/BUILD.bazel c/go/analysis/passes/tests/testdata/src/b_x_test/BUILD.bazel ---- b/go/analysis/passes/tests/testdata/src/b_x_test/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/tests/testdata/src/b_x_test/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/tests/testdata/src/b_x_test/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,6 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") @@ -5327,7 +5381,7 @@ diff -urN b/go/analysis/passes/tests/testdata/src/b_x_test/BUILD.bazel c/go/anal + srcs = ["b_test.go"], +) diff -urN b/go/analysis/passes/tests/testdata/src/divergent/BUILD.bazel c/go/analysis/passes/tests/testdata/src/divergent/BUILD.bazel ---- b/go/analysis/passes/tests/testdata/src/divergent/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/tests/testdata/src/divergent/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/tests/testdata/src/divergent/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5351,7 +5405,7 @@ diff -urN b/go/analysis/passes/tests/testdata/src/divergent/BUILD.bazel c/go/ana + embed = [":divergent"], +) diff -urN b/go/analysis/passes/tests/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/tests/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/tests/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/tests/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/tests/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5375,9 +5429,9 @@ diff -urN b/go/analysis/passes/tests/testdata/src/typeparams/BUILD.bazel c/go/an + embed = [":typeparams"], +) diff -urN b/go/analysis/passes/timeformat/BUILD.bazel c/go/analysis/passes/timeformat/BUILD.bazel ---- b/go/analysis/passes/timeformat/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/timeformat/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/timeformat/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,35 @@ +@@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -5407,14 +5461,13 @@ diff -urN b/go/analysis/passes/timeformat/BUILD.bazel c/go/analysis/passes/timef +go_test( + name = "timeformat_test", + srcs = ["timeformat_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":timeformat", + "//go/analysis/analysistest", + ], +) diff -urN b/go/analysis/passes/timeformat/testdata/src/a/BUILD.bazel c/go/analysis/passes/timeformat/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/timeformat/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/timeformat/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/timeformat/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5432,7 +5485,7 @@ diff -urN b/go/analysis/passes/timeformat/testdata/src/a/BUILD.bazel c/go/analys + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/timeformat/testdata/src/b/BUILD.bazel c/go/analysis/passes/timeformat/testdata/src/b/BUILD.bazel ---- b/go/analysis/passes/timeformat/testdata/src/b/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/timeformat/testdata/src/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/timeformat/testdata/src/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5450,9 +5503,9 @@ diff -urN b/go/analysis/passes/timeformat/testdata/src/b/BUILD.bazel c/go/analys + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/unmarshal/BUILD.bazel c/go/analysis/passes/unmarshal/BUILD.bazel ---- b/go/analysis/passes/unmarshal/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/unmarshal/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unmarshal/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,37 @@ +@@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -5483,7 +5536,6 @@ diff -urN b/go/analysis/passes/unmarshal/BUILD.bazel c/go/analysis/passes/unmars +go_test( + name = "unmarshal_test", + srcs = ["unmarshal_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":unmarshal", + "//go/analysis/analysistest", @@ -5491,7 +5543,7 @@ diff -urN b/go/analysis/passes/unmarshal/BUILD.bazel c/go/analysis/passes/unmars + ], +) diff -urN b/go/analysis/passes/unmarshal/cmd/unmarshal/BUILD.bazel c/go/analysis/passes/unmarshal/cmd/unmarshal/BUILD.bazel ---- b/go/analysis/passes/unmarshal/cmd/unmarshal/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/unmarshal/cmd/unmarshal/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unmarshal/cmd/unmarshal/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -5513,7 +5565,7 @@ diff -urN b/go/analysis/passes/unmarshal/cmd/unmarshal/BUILD.bazel c/go/analysis + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/unmarshal/testdata/src/a/BUILD.bazel c/go/analysis/passes/unmarshal/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/unmarshal/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/unmarshal/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unmarshal/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5531,7 +5583,7 @@ diff -urN b/go/analysis/passes/unmarshal/testdata/src/a/BUILD.bazel c/go/analysi + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/unmarshal/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/unmarshal/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/unmarshal/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/unmarshal/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unmarshal/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5549,9 +5601,9 @@ diff -urN b/go/analysis/passes/unmarshal/testdata/src/typeparams/BUILD.bazel c/g + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/unreachable/BUILD.bazel c/go/analysis/passes/unreachable/BUILD.bazel ---- b/go/analysis/passes/unreachable/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/unreachable/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unreachable/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,34 @@ +@@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -5580,14 +5632,13 @@ diff -urN b/go/analysis/passes/unreachable/BUILD.bazel c/go/analysis/passes/unre +go_test( + name = "unreachable_test", + srcs = ["unreachable_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":unreachable", + "//go/analysis/analysistest", + ], +) diff -urN b/go/analysis/passes/unreachable/testdata/src/a/BUILD.bazel c/go/analysis/passes/unreachable/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/unreachable/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/unreachable/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unreachable/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5605,7 +5656,7 @@ diff -urN b/go/analysis/passes/unreachable/testdata/src/a/BUILD.bazel c/go/analy + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/unsafeptr/BUILD.bazel c/go/analysis/passes/unsafeptr/BUILD.bazel ---- b/go/analysis/passes/unsafeptr/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/unsafeptr/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unsafeptr/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5623,6 +5674,7 @@ diff -urN b/go/analysis/passes/unsafeptr/BUILD.bazel c/go/analysis/passes/unsafe + "//go/analysis", + "//go/analysis/passes/inspect", + "//go/analysis/passes/internal/analysisutil", ++ "//go/ast/astutil", + "//go/ast/inspector", + ], +) @@ -5636,7 +5688,6 @@ diff -urN b/go/analysis/passes/unsafeptr/BUILD.bazel c/go/analysis/passes/unsafe +go_test( + name = "unsafeptr_test", + srcs = ["unsafeptr_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":unsafeptr", + "//go/analysis/analysistest", @@ -5644,7 +5695,7 @@ diff -urN b/go/analysis/passes/unsafeptr/BUILD.bazel c/go/analysis/passes/unsafe + ], +) diff -urN b/go/analysis/passes/unsafeptr/testdata/src/a/BUILD.bazel c/go/analysis/passes/unsafeptr/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/unsafeptr/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/unsafeptr/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unsafeptr/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,17 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5665,7 +5716,7 @@ diff -urN b/go/analysis/passes/unsafeptr/testdata/src/a/BUILD.bazel c/go/analysi + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/unsafeptr/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/unsafeptr/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/unsafeptr/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/unsafeptr/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unsafeptr/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5683,7 +5734,7 @@ diff -urN b/go/analysis/passes/unsafeptr/testdata/src/typeparams/BUILD.bazel c/g + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/unusedresult/BUILD.bazel c/go/analysis/passes/unusedresult/BUILD.bazel ---- b/go/analysis/passes/unusedresult/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/unusedresult/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unusedresult/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5701,6 +5752,7 @@ diff -urN b/go/analysis/passes/unusedresult/BUILD.bazel c/go/analysis/passes/unu + "//go/analysis", + "//go/analysis/passes/inspect", + "//go/analysis/passes/internal/analysisutil", ++ "//go/ast/astutil", + "//go/ast/inspector", + "//go/types/typeutil", + ], @@ -5715,7 +5767,6 @@ diff -urN b/go/analysis/passes/unusedresult/BUILD.bazel c/go/analysis/passes/unu +go_test( + name = "unusedresult_test", + srcs = ["unusedresult_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":unusedresult", + "//go/analysis/analysistest", @@ -5723,7 +5774,7 @@ diff -urN b/go/analysis/passes/unusedresult/BUILD.bazel c/go/analysis/passes/unu + ], +) diff -urN b/go/analysis/passes/unusedresult/cmd/unusedresult/BUILD.bazel c/go/analysis/passes/unusedresult/cmd/unusedresult/BUILD.bazel ---- b/go/analysis/passes/unusedresult/cmd/unusedresult/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/unusedresult/cmd/unusedresult/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unusedresult/cmd/unusedresult/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -5745,7 +5796,7 @@ diff -urN b/go/analysis/passes/unusedresult/cmd/unusedresult/BUILD.bazel c/go/an + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/unusedresult/testdata/src/a/BUILD.bazel c/go/analysis/passes/unusedresult/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/unusedresult/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/unusedresult/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unusedresult/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5763,7 +5814,7 @@ diff -urN b/go/analysis/passes/unusedresult/testdata/src/a/BUILD.bazel c/go/anal + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/unusedresult/testdata/src/typeparams/BUILD.bazel c/go/analysis/passes/unusedresult/testdata/src/typeparams/BUILD.bazel ---- b/go/analysis/passes/unusedresult/testdata/src/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/unusedresult/testdata/src/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unusedresult/testdata/src/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5781,7 +5832,7 @@ diff -urN b/go/analysis/passes/unusedresult/testdata/src/typeparams/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/unusedresult/testdata/src/typeparams/userdefs/BUILD.bazel c/go/analysis/passes/unusedresult/testdata/src/typeparams/userdefs/BUILD.bazel ---- b/go/analysis/passes/unusedresult/testdata/src/typeparams/userdefs/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/unusedresult/testdata/src/typeparams/userdefs/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unusedresult/testdata/src/typeparams/userdefs/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5799,9 +5850,9 @@ diff -urN b/go/analysis/passes/unusedresult/testdata/src/typeparams/userdefs/BUI + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/unusedwrite/BUILD.bazel c/go/analysis/passes/unusedwrite/BUILD.bazel ---- b/go/analysis/passes/unusedwrite/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/unusedwrite/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unusedwrite/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,34 @@ +@@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -5830,14 +5881,13 @@ diff -urN b/go/analysis/passes/unusedwrite/BUILD.bazel c/go/analysis/passes/unus +go_test( + name = "unusedwrite_test", + srcs = ["unusedwrite_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":unusedwrite", + "//go/analysis/analysistest", + ], +) diff -urN b/go/analysis/passes/unusedwrite/testdata/src/a/BUILD.bazel c/go/analysis/passes/unusedwrite/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/unusedwrite/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/unusedwrite/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unusedwrite/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5855,9 +5905,9 @@ diff -urN b/go/analysis/passes/unusedwrite/testdata/src/a/BUILD.bazel c/go/analy + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/usesgenerics/BUILD.bazel c/go/analysis/passes/usesgenerics/BUILD.bazel ---- b/go/analysis/passes/usesgenerics/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/usesgenerics/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/usesgenerics/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,36 @@ +@@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -5887,7 +5937,6 @@ diff -urN b/go/analysis/passes/usesgenerics/BUILD.bazel c/go/analysis/passes/use +go_test( + name = "usesgenerics_test", + srcs = ["usesgenerics_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":usesgenerics", + "//go/analysis/analysistest", @@ -5895,7 +5944,7 @@ diff -urN b/go/analysis/passes/usesgenerics/BUILD.bazel c/go/analysis/passes/use + ], +) diff -urN b/go/analysis/passes/usesgenerics/testdata/src/a/BUILD.bazel c/go/analysis/passes/usesgenerics/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/usesgenerics/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/usesgenerics/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/usesgenerics/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5913,7 +5962,7 @@ diff -urN b/go/analysis/passes/usesgenerics/testdata/src/a/BUILD.bazel c/go/anal + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/usesgenerics/testdata/src/b/BUILD.bazel c/go/analysis/passes/usesgenerics/testdata/src/b/BUILD.bazel ---- b/go/analysis/passes/usesgenerics/testdata/src/b/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/usesgenerics/testdata/src/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/usesgenerics/testdata/src/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5931,7 +5980,7 @@ diff -urN b/go/analysis/passes/usesgenerics/testdata/src/b/BUILD.bazel c/go/anal + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/usesgenerics/testdata/src/c/BUILD.bazel c/go/analysis/passes/usesgenerics/testdata/src/c/BUILD.bazel ---- b/go/analysis/passes/usesgenerics/testdata/src/c/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/usesgenerics/testdata/src/c/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/usesgenerics/testdata/src/c/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5949,7 +5998,7 @@ diff -urN b/go/analysis/passes/usesgenerics/testdata/src/c/BUILD.bazel c/go/anal + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/passes/usesgenerics/testdata/src/d/BUILD.bazel c/go/analysis/passes/usesgenerics/testdata/src/d/BUILD.bazel ---- b/go/analysis/passes/usesgenerics/testdata/src/d/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/passes/usesgenerics/testdata/src/d/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/usesgenerics/testdata/src/d/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5967,7 +6016,7 @@ diff -urN b/go/analysis/passes/usesgenerics/testdata/src/d/BUILD.bazel c/go/anal + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/singlechecker/BUILD.bazel c/go/analysis/singlechecker/BUILD.bazel ---- b/go/analysis/singlechecker/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/singlechecker/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/singlechecker/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5991,7 +6040,7 @@ diff -urN b/go/analysis/singlechecker/BUILD.bazel c/go/analysis/singlechecker/BU + visibility = ["//visibility:public"], +) diff -urN b/go/analysis/unitchecker/BUILD.bazel c/go/analysis/unitchecker/BUILD.bazel ---- b/go/analysis/unitchecker/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/analysis/unitchecker/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/unitchecker/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,69 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6064,7 +6113,7 @@ diff -urN b/go/analysis/unitchecker/BUILD.bazel c/go/analysis/unitchecker/BUILD. + ], +) diff -urN b/go/ast/astutil/BUILD.bazel c/go/ast/astutil/BUILD.bazel ---- b/go/ast/astutil/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ast/astutil/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ast/astutil/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6099,7 +6148,7 @@ diff -urN b/go/ast/astutil/BUILD.bazel c/go/ast/astutil/BUILD.bazel + deps = ["//internal/typeparams"], +) diff -urN b/go/ast/inspector/BUILD.bazel c/go/ast/inspector/BUILD.bazel ---- b/go/ast/inspector/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ast/inspector/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ast/inspector/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6130,7 +6179,7 @@ diff -urN b/go/ast/inspector/BUILD.bazel c/go/ast/inspector/BUILD.bazel + ], +) diff -urN b/go/buildutil/BUILD.bazel c/go/buildutil/BUILD.bazel ---- b/go/buildutil/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/buildutil/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/buildutil/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6169,7 +6218,7 @@ diff -urN b/go/buildutil/BUILD.bazel c/go/buildutil/BUILD.bazel + ], +) diff -urN b/go/callgraph/BUILD.bazel c/go/callgraph/BUILD.bazel ---- b/go/callgraph/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/callgraph/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/callgraph/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6206,7 +6255,7 @@ diff -urN b/go/callgraph/BUILD.bazel c/go/callgraph/BUILD.bazel + ], +) diff -urN b/go/callgraph/cha/BUILD.bazel c/go/callgraph/cha/BUILD.bazel ---- b/go/callgraph/cha/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/callgraph/cha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/callgraph/cha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,132 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6342,7 +6391,7 @@ diff -urN b/go/callgraph/cha/BUILD.bazel c/go/callgraph/cha/BUILD.bazel + }), +) diff -urN b/go/callgraph/cha/testdata/BUILD.bazel c/go/callgraph/cha/testdata/BUILD.bazel ---- b/go/callgraph/cha/testdata/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/callgraph/cha/testdata/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/callgraph/cha/testdata/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -6360,7 +6409,7 @@ diff -urN b/go/callgraph/cha/testdata/BUILD.bazel c/go/callgraph/cha/testdata/BU + visibility = ["//visibility:public"], +) diff -urN b/go/callgraph/rta/BUILD.bazel c/go/callgraph/rta/BUILD.bazel ---- b/go/callgraph/rta/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/callgraph/rta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/callgraph/rta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,133 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6387,7 +6436,7 @@ diff -urN b/go/callgraph/rta/BUILD.bazel c/go/callgraph/rta/BUILD.bazel +go_test( + name = "rta_test", + srcs = ["rta_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), ++ data = glob(["testdata/**"]), + deps = select({ + "@io_bazel_rules_go//go/platform:aix": [ + ":rta", @@ -6497,7 +6546,7 @@ diff -urN b/go/callgraph/rta/BUILD.bazel c/go/callgraph/rta/BUILD.bazel + }), +) diff -urN b/go/callgraph/static/BUILD.bazel c/go/callgraph/static/BUILD.bazel ---- b/go/callgraph/static/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/callgraph/static/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/callgraph/static/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6533,7 +6582,7 @@ diff -urN b/go/callgraph/static/BUILD.bazel c/go/callgraph/static/BUILD.bazel + ], +) diff -urN b/go/callgraph/vta/BUILD.bazel c/go/callgraph/vta/BUILD.bazel ---- b/go/callgraph/vta/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/callgraph/vta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/callgraph/vta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,50 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6587,7 +6636,7 @@ diff -urN b/go/callgraph/vta/BUILD.bazel c/go/callgraph/vta/BUILD.bazel + ], +) diff -urN b/go/callgraph/vta/internal/trie/BUILD.bazel c/go/callgraph/vta/internal/trie/BUILD.bazel ---- b/go/callgraph/vta/internal/trie/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/callgraph/vta/internal/trie/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/callgraph/vta/internal/trie/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6619,60 +6668,8 @@ diff -urN b/go/callgraph/vta/internal/trie/BUILD.bazel c/go/callgraph/vta/intern + ], + embed = [":trie"], +) -diff -urN b/go/callgraph/vta/testdata/src/BUILD.bazel c/go/callgraph/vta/testdata/src/BUILD.bazel ---- b/go/callgraph/vta/testdata/src/BUILD.bazel 1970-01-01 08:00:00 -+++ c/go/callgraph/vta/testdata/src/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,48 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library") -+ -+go_library( -+ name = "src", -+ srcs = [ -+ "arrays_generics.go", -+ "callgraph_collections.go", -+ "callgraph_field_funcs.go", -+ "callgraph_fields.go", -+ "callgraph_generics.go", -+ "callgraph_ho.go", -+ "callgraph_interfaces.go", -+ "callgraph_issue_57756.go", -+ "callgraph_nested_ptr.go", -+ "callgraph_pointers.go", -+ "callgraph_recursive_types.go", -+ "callgraph_static.go", -+ "channels.go", -+ "closures.go", -+ "dynamic_calls.go", -+ "fields.go", -+ "function_alias.go", -+ "go117.go", -+ "maps.go", -+ "node_uniqueness.go", -+ "panic.go", -+ "phi.go", -+ "phi_alias.go", -+ "ranges.go", -+ "returns.go", -+ "select.go", -+ "simple.go", -+ "static_calls.go", -+ "store.go", -+ "store_load_alias.go", -+ "stores_arrays.go", -+ "type_assertions.go", -+ "type_conversions.go", -+ ], -+ importpath = "golang.org/x/tools/go/callgraph/vta/testdata/src", -+ visibility = ["//visibility:public"], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":src", -+ visibility = ["//visibility:public"], -+) diff -urN b/go/callgraph/vta/testdata/src/d/BUILD.bazel c/go/callgraph/vta/testdata/src/d/BUILD.bazel ---- b/go/callgraph/vta/testdata/src/d/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/callgraph/vta/testdata/src/d/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/callgraph/vta/testdata/src/d/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6690,7 +6687,7 @@ diff -urN b/go/callgraph/vta/testdata/src/d/BUILD.bazel c/go/callgraph/vta/testd + visibility = ["//visibility:public"], +) diff -urN b/go/callgraph/vta/testdata/src/t/BUILD.bazel c/go/callgraph/vta/testdata/src/t/BUILD.bazel ---- b/go/callgraph/vta/testdata/src/t/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/callgraph/vta/testdata/src/t/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/callgraph/vta/testdata/src/t/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6708,7 +6705,7 @@ diff -urN b/go/callgraph/vta/testdata/src/t/BUILD.bazel c/go/callgraph/vta/testd + visibility = ["//visibility:public"], +) diff -urN b/go/cfg/BUILD.bazel c/go/cfg/BUILD.bazel ---- b/go/cfg/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/cfg/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/cfg/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6735,7 +6732,7 @@ diff -urN b/go/cfg/BUILD.bazel c/go/cfg/BUILD.bazel + embed = [":cfg"], +) diff -urN b/go/expect/BUILD.bazel c/go/expect/BUILD.bazel ---- b/go/expect/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/expect/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/expect/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6763,7 +6760,7 @@ diff -urN b/go/expect/BUILD.bazel c/go/expect/BUILD.bazel + deps = [":expect"], +) diff -urN b/go/expect/testdata/BUILD.bazel c/go/expect/testdata/BUILD.bazel ---- b/go/expect/testdata/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/expect/testdata/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/expect/testdata/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6781,7 +6778,7 @@ diff -urN b/go/expect/testdata/BUILD.bazel c/go/expect/testdata/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/go/gccgoexportdata/BUILD.bazel c/go/gccgoexportdata/BUILD.bazel ---- b/go/gccgoexportdata/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/gccgoexportdata/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/gccgoexportdata/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6803,13 +6800,13 @@ diff -urN b/go/gccgoexportdata/BUILD.bazel c/go/gccgoexportdata/BUILD.bazel +go_test( + name = "gccgoexportdata_test", + srcs = ["gccgoexportdata_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), ++ data = glob(["testdata/**"]), + deps = [":gccgoexportdata"], +) diff -urN b/go/gcexportdata/BUILD.bazel c/go/gcexportdata/BUILD.bazel ---- b/go/gcexportdata/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/gcexportdata/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/gcexportdata/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,56 @@ +@@ -0,0 +1,59 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -6845,7 +6842,10 @@ diff -urN b/go/gcexportdata/BUILD.bazel c/go/gcexportdata/BUILD.bazel + "@io_bazel_rules_go//go/platform:freebsd": [ + ":gcexportdata", + ], -+ "@io_bazel_rules_go//go/platform:linux": [ ++ "@io_bazel_rules_go//go/platform:illumos": [ ++ ":gcexportdata", ++ ], ++ "@io_bazel_rules_go//go/platform:linux": [ + ":gcexportdata", + ], + "@io_bazel_rules_go//go/platform:netbsd": [ @@ -6867,7 +6867,7 @@ diff -urN b/go/gcexportdata/BUILD.bazel c/go/gcexportdata/BUILD.bazel + }), +) diff -urN b/go/internal/cgo/BUILD.bazel c/go/internal/cgo/BUILD.bazel ---- b/go/internal/cgo/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/internal/cgo/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/internal/cgo/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6889,7 +6889,7 @@ diff -urN b/go/internal/cgo/BUILD.bazel c/go/internal/cgo/BUILD.bazel + visibility = ["//go:__subpackages__"], +) diff -urN b/go/internal/gccgoimporter/BUILD.bazel c/go/internal/gccgoimporter/BUILD.bazel ---- b/go/internal/gccgoimporter/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/internal/gccgoimporter/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/internal/gccgoimporter/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6924,12 +6924,12 @@ diff -urN b/go/internal/gccgoimporter/BUILD.bazel c/go/internal/gccgoimporter/BU + "parser_test.go", + "testenv_test.go", + ], -+ data = glob(["testdata/**"], allow_empty = True), ++ data = glob(["testdata/**"]), + embed = [":gccgoimporter"], + deps = ["//internal/testenv"], +) diff -urN b/go/internal/packagesdriver/BUILD.bazel c/go/internal/packagesdriver/BUILD.bazel ---- b/go/internal/packagesdriver/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/internal/packagesdriver/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/internal/packagesdriver/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6948,7 +6948,7 @@ diff -urN b/go/internal/packagesdriver/BUILD.bazel c/go/internal/packagesdriver/ + visibility = ["//go:__subpackages__"], +) diff -urN b/go/loader/BUILD.bazel c/go/loader/BUILD.bazel ---- b/go/loader/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/loader/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/loader/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,37 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6989,7 +6989,7 @@ diff -urN b/go/loader/BUILD.bazel c/go/loader/BUILD.bazel + ], +) diff -urN b/go/loader/testdata/BUILD.bazel c/go/loader/testdata/BUILD.bazel ---- b/go/loader/testdata/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/loader/testdata/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/loader/testdata/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7011,7 +7011,7 @@ diff -urN b/go/loader/testdata/BUILD.bazel c/go/loader/testdata/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/go/loader/testdata/issue46877/BUILD.bazel c/go/loader/testdata/issue46877/BUILD.bazel ---- b/go/loader/testdata/issue46877/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/loader/testdata/issue46877/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/loader/testdata/issue46877/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7033,7 +7033,7 @@ diff -urN b/go/loader/testdata/issue46877/BUILD.bazel c/go/loader/testdata/issue + visibility = ["//visibility:public"], +) diff -urN b/go/packages/BUILD.bazel c/go/packages/BUILD.bazel ---- b/go/packages/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/packages/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,47 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -7084,7 +7084,7 @@ diff -urN b/go/packages/BUILD.bazel c/go/packages/BUILD.bazel + ], +) diff -urN b/go/packages/gopackages/BUILD.bazel c/go/packages/gopackages/BUILD.bazel ---- b/go/packages/gopackages/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/packages/gopackages/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/gopackages/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -7107,7 +7107,7 @@ diff -urN b/go/packages/gopackages/BUILD.bazel c/go/packages/gopackages/BUILD.ba + visibility = ["//visibility:public"], +) diff -urN b/go/packages/internal/nodecount/BUILD.bazel c/go/packages/internal/nodecount/BUILD.bazel ---- b/go/packages/internal/nodecount/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/packages/internal/nodecount/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/internal/nodecount/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -7126,7 +7126,7 @@ diff -urN b/go/packages/internal/nodecount/BUILD.bazel c/go/packages/internal/no + visibility = ["//go/packages:__subpackages__"], +) diff -urN b/go/packages/packagestest/BUILD.bazel c/go/packages/packagestest/BUILD.bazel ---- b/go/packages/packagestest/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/packages/packagestest/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/packagestest/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,42 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -7172,7 +7172,7 @@ diff -urN b/go/packages/packagestest/BUILD.bazel c/go/packages/packagestest/BUIL + ], +) diff -urN b/go/packages/packagestest/testdata/BUILD.bazel c/go/packages/packagestest/testdata/BUILD.bazel ---- b/go/packages/packagestest/testdata/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/packages/packagestest/testdata/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/packagestest/testdata/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -7199,7 +7199,7 @@ diff -urN b/go/packages/packagestest/testdata/BUILD.bazel c/go/packages/packages + embed = [":testdata"], +) diff -urN b/go/packages/packagestest/testdata/groups/one/modules/example.com/extra/BUILD.bazel c/go/packages/packagestest/testdata/groups/one/modules/example.com/extra/BUILD.bazel ---- b/go/packages/packagestest/testdata/groups/one/modules/example.com/extra/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/packages/packagestest/testdata/groups/one/modules/example.com/extra/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/packagestest/testdata/groups/one/modules/example.com/extra/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7217,7 +7217,7 @@ diff -urN b/go/packages/packagestest/testdata/groups/one/modules/example.com/ext + visibility = ["//visibility:public"], +) diff -urN b/go/packages/packagestest/testdata/groups/one/primarymod/BUILD.bazel c/go/packages/packagestest/testdata/groups/one/primarymod/BUILD.bazel ---- b/go/packages/packagestest/testdata/groups/one/primarymod/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/packages/packagestest/testdata/groups/one/primarymod/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/packagestest/testdata/groups/one/primarymod/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7235,7 +7235,7 @@ diff -urN b/go/packages/packagestest/testdata/groups/one/primarymod/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/BUILD.bazel c/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/BUILD.bazel ---- b/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7253,7 +7253,7 @@ diff -urN b/go/packages/packagestest/testdata/groups/two/modules/example.com/ext + visibility = ["//visibility:public"], +) diff -urN b/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/geez/BUILD.bazel c/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/geez/BUILD.bazel ---- b/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/geez/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/geez/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/geez/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7271,7 +7271,7 @@ diff -urN b/go/packages/packagestest/testdata/groups/two/modules/example.com/ext + visibility = ["//visibility:public"], +) diff -urN b/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/v2/BUILD.bazel c/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/v2/BUILD.bazel ---- b/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/v2/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7289,7 +7289,7 @@ diff -urN b/go/packages/packagestest/testdata/groups/two/modules/example.com/ext + visibility = ["//visibility:public"], +) diff -urN b/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/v2/geez/BUILD.bazel c/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/v2/geez/BUILD.bazel ---- b/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/v2/geez/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/v2/geez/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/v2/geez/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7307,7 +7307,7 @@ diff -urN b/go/packages/packagestest/testdata/groups/two/modules/example.com/ext + visibility = ["//visibility:public"], +) diff -urN b/go/packages/packagestest/testdata/groups/two/modules/example.com/tempmod/BUILD.bazel c/go/packages/packagestest/testdata/groups/two/modules/example.com/tempmod/BUILD.bazel ---- b/go/packages/packagestest/testdata/groups/two/modules/example.com/tempmod/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/packages/packagestest/testdata/groups/two/modules/example.com/tempmod/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/packagestest/testdata/groups/two/modules/example.com/tempmod/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7325,7 +7325,7 @@ diff -urN b/go/packages/packagestest/testdata/groups/two/modules/example.com/tem + visibility = ["//visibility:public"], +) diff -urN b/go/packages/packagestest/testdata/groups/two/modules/example.com/what@v1.0.0/BUILD.bazel c/go/packages/packagestest/testdata/groups/two/modules/example.com/what@v1.0.0/BUILD.bazel ---- b/go/packages/packagestest/testdata/groups/two/modules/example.com/what@v1.0.0/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/packages/packagestest/testdata/groups/two/modules/example.com/what@v1.0.0/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/packagestest/testdata/groups/two/modules/example.com/what@v1.0.0/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7343,7 +7343,7 @@ diff -urN b/go/packages/packagestest/testdata/groups/two/modules/example.com/wha + visibility = ["//visibility:public"], +) diff -urN b/go/packages/packagestest/testdata/groups/two/modules/example.com/what@v1.1.0/BUILD.bazel c/go/packages/packagestest/testdata/groups/two/modules/example.com/what@v1.1.0/BUILD.bazel ---- b/go/packages/packagestest/testdata/groups/two/modules/example.com/what@v1.1.0/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/packages/packagestest/testdata/groups/two/modules/example.com/what@v1.1.0/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/packagestest/testdata/groups/two/modules/example.com/what@v1.1.0/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7361,7 +7361,7 @@ diff -urN b/go/packages/packagestest/testdata/groups/two/modules/example.com/wha + visibility = ["//visibility:public"], +) diff -urN b/go/packages/packagestest/testdata/groups/two/primarymod/BUILD.bazel c/go/packages/packagestest/testdata/groups/two/primarymod/BUILD.bazel ---- b/go/packages/packagestest/testdata/groups/two/primarymod/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/packages/packagestest/testdata/groups/two/primarymod/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/packagestest/testdata/groups/two/primarymod/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7379,7 +7379,7 @@ diff -urN b/go/packages/packagestest/testdata/groups/two/primarymod/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/go/packages/packagestest/testdata/groups/two/primarymod/expect/BUILD.bazel c/go/packages/packagestest/testdata/groups/two/primarymod/expect/BUILD.bazel ---- b/go/packages/packagestest/testdata/groups/two/primarymod/expect/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/packages/packagestest/testdata/groups/two/primarymod/expect/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/packagestest/testdata/groups/two/primarymod/expect/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -7402,9 +7402,9 @@ diff -urN b/go/packages/packagestest/testdata/groups/two/primarymod/expect/BUILD + srcs = ["yo_test.go"], +) diff -urN b/go/ssa/BUILD.bazel c/go/ssa/BUILD.bazel ---- b/go/ssa/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,118 @@ +@@ -0,0 +1,76 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -7420,8 +7420,6 @@ diff -urN b/go/ssa/BUILD.bazel c/go/ssa/BUILD.bazel + "dom.go", + "emit.go", + "func.go", -+ "identical.go", -+ "identical_17.go", + "instantiate.go", + "lift.go", + "lvalue.go", @@ -7434,6 +7432,7 @@ diff -urN b/go/ssa/BUILD.bazel c/go/ssa/BUILD.bazel + "ssa.go", + "subst.go", + "util.go", ++ "versions_go122.go", + "wrappers.go", + ], + importpath = "golang.org/x/tools/go/ssa", @@ -7455,13 +7454,12 @@ diff -urN b/go/ssa/BUILD.bazel c/go/ssa/BUILD.bazel + name = "ssa_test", + srcs = [ + "builder_generic_test.go", -+ "builder_go117_test.go", + "builder_go120_test.go", ++ "builder_go122_test.go", + "builder_test.go", + "const_test.go", + "coretype_test.go", + "example_test.go", -+ "identical_test.go", + "instantiate_test.go", + "methods_test.go", + "parameterized_test.go", @@ -7470,63 +7468,23 @@ diff -urN b/go/ssa/BUILD.bazel c/go/ssa/BUILD.bazel + "subst_test.go", + "testhelper_test.go", + ], -+ data = glob(["testdata/**"], allow_empty = True), + embed = [":ssa"], + deps = [ + "//go/ast/astutil", + "//go/buildutil", + "//go/expect", + "//go/loader", ++ "//go/packages", + "//go/ssa/ssautil", + "//internal/testenv", + "//internal/typeparams", -+ ] + select({ -+ "@io_bazel_rules_go//go/platform:aix": [ -+ "//go/packages", -+ ], -+ "@io_bazel_rules_go//go/platform:darwin": [ -+ "//go/packages", -+ ], -+ "@io_bazel_rules_go//go/platform:dragonfly": [ -+ "//go/packages", -+ ], -+ "@io_bazel_rules_go//go/platform:freebsd": [ -+ "//go/packages", -+ ], -+ "@io_bazel_rules_go//go/platform:illumos": [ -+ "//go/packages", -+ ], -+ "@io_bazel_rules_go//go/platform:ios": [ -+ "//go/packages", -+ ], -+ "@io_bazel_rules_go//go/platform:js": [ -+ "//go/packages", -+ ], -+ "@io_bazel_rules_go//go/platform:linux": [ -+ "//go/packages", -+ ], -+ "@io_bazel_rules_go//go/platform:netbsd": [ -+ "//go/packages", -+ ], -+ "@io_bazel_rules_go//go/platform:openbsd": [ -+ "//go/packages", -+ ], -+ "@io_bazel_rules_go//go/platform:plan9": [ -+ "//go/packages", -+ ], -+ "@io_bazel_rules_go//go/platform:solaris": [ -+ "//go/packages", -+ ], -+ "@io_bazel_rules_go//go/platform:windows": [ -+ "//go/packages", -+ ], -+ "//conditions:default": [], -+ }), ++ "//txtar", ++ ], +) diff -urN b/go/ssa/interp/BUILD.bazel c/go/ssa/interp/BUILD.bazel ---- b/go/ssa/interp/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,41 @@ +@@ -0,0 +1,43 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -7558,6 +7516,7 @@ diff -urN b/go/ssa/interp/BUILD.bazel c/go/ssa/interp/BUILD.bazel + srcs = [ + "interp_go120_test.go", + "interp_go121_test.go", ++ "interp_go122_test.go", + "interp_test.go", + ], + deps = [ @@ -7565,11 +7524,12 @@ diff -urN b/go/ssa/interp/BUILD.bazel c/go/ssa/interp/BUILD.bazel + "//go/loader", + "//go/ssa", + "//go/ssa/ssautil", ++ "//internal/testenv", + "//internal/typeparams", + ], +) diff -urN b/go/ssa/interp/testdata/fixedbugs/BUILD.bazel c/go/ssa/interp/testdata/fixedbugs/BUILD.bazel ---- b/go/ssa/interp/testdata/fixedbugs/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/fixedbugs/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/fixedbugs/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -7592,7 +7552,7 @@ diff -urN b/go/ssa/interp/testdata/fixedbugs/BUILD.bazel c/go/ssa/interp/testdat + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/interp/testdata/src/encoding/BUILD.bazel c/go/ssa/interp/testdata/src/encoding/BUILD.bazel ---- b/go/ssa/interp/testdata/src/encoding/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/src/encoding/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/src/encoding/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7610,7 +7570,7 @@ diff -urN b/go/ssa/interp/testdata/src/encoding/BUILD.bazel c/go/ssa/interp/test + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/interp/testdata/src/errors/BUILD.bazel c/go/ssa/interp/testdata/src/errors/BUILD.bazel ---- b/go/ssa/interp/testdata/src/errors/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/src/errors/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/src/errors/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7628,7 +7588,7 @@ diff -urN b/go/ssa/interp/testdata/src/errors/BUILD.bazel c/go/ssa/interp/testda + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/interp/testdata/src/fmt/BUILD.bazel c/go/ssa/interp/testdata/src/fmt/BUILD.bazel ---- b/go/ssa/interp/testdata/src/fmt/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/src/fmt/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/src/fmt/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7646,7 +7606,7 @@ diff -urN b/go/ssa/interp/testdata/src/fmt/BUILD.bazel c/go/ssa/interp/testdata/ + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/interp/testdata/src/io/BUILD.bazel c/go/ssa/interp/testdata/src/io/BUILD.bazel ---- b/go/ssa/interp/testdata/src/io/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/src/io/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/src/io/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7664,7 +7624,7 @@ diff -urN b/go/ssa/interp/testdata/src/io/BUILD.bazel c/go/ssa/interp/testdata/s + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/interp/testdata/src/log/BUILD.bazel c/go/ssa/interp/testdata/src/log/BUILD.bazel ---- b/go/ssa/interp/testdata/src/log/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/src/log/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/src/log/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7682,7 +7642,7 @@ diff -urN b/go/ssa/interp/testdata/src/log/BUILD.bazel c/go/ssa/interp/testdata/ + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/interp/testdata/src/math/BUILD.bazel c/go/ssa/interp/testdata/src/math/BUILD.bazel ---- b/go/ssa/interp/testdata/src/math/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/src/math/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/src/math/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7700,7 +7660,7 @@ diff -urN b/go/ssa/interp/testdata/src/math/BUILD.bazel c/go/ssa/interp/testdata + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/interp/testdata/src/os/BUILD.bazel c/go/ssa/interp/testdata/src/os/BUILD.bazel ---- b/go/ssa/interp/testdata/src/os/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/src/os/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/src/os/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7718,7 +7678,7 @@ diff -urN b/go/ssa/interp/testdata/src/os/BUILD.bazel c/go/ssa/interp/testdata/s + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/interp/testdata/src/reflect/BUILD.bazel c/go/ssa/interp/testdata/src/reflect/BUILD.bazel ---- b/go/ssa/interp/testdata/src/reflect/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/src/reflect/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/src/reflect/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,17 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7739,7 +7699,7 @@ diff -urN b/go/ssa/interp/testdata/src/reflect/BUILD.bazel c/go/ssa/interp/testd + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/interp/testdata/src/runtime/BUILD.bazel c/go/ssa/interp/testdata/src/runtime/BUILD.bazel ---- b/go/ssa/interp/testdata/src/runtime/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/src/runtime/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/src/runtime/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7757,7 +7717,7 @@ diff -urN b/go/ssa/interp/testdata/src/runtime/BUILD.bazel c/go/ssa/interp/testd + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/interp/testdata/src/sort/BUILD.bazel c/go/ssa/interp/testdata/src/sort/BUILD.bazel ---- b/go/ssa/interp/testdata/src/sort/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/src/sort/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/src/sort/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7775,7 +7735,7 @@ diff -urN b/go/ssa/interp/testdata/src/sort/BUILD.bazel c/go/ssa/interp/testdata + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/interp/testdata/src/strconv/BUILD.bazel c/go/ssa/interp/testdata/src/strconv/BUILD.bazel ---- b/go/ssa/interp/testdata/src/strconv/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/src/strconv/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/src/strconv/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7793,7 +7753,7 @@ diff -urN b/go/ssa/interp/testdata/src/strconv/BUILD.bazel c/go/ssa/interp/testd + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/interp/testdata/src/strings/BUILD.bazel c/go/ssa/interp/testdata/src/strings/BUILD.bazel ---- b/go/ssa/interp/testdata/src/strings/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/src/strings/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/src/strings/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7811,7 +7771,7 @@ diff -urN b/go/ssa/interp/testdata/src/strings/BUILD.bazel c/go/ssa/interp/testd + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/interp/testdata/src/sync/BUILD.bazel c/go/ssa/interp/testdata/src/sync/BUILD.bazel ---- b/go/ssa/interp/testdata/src/sync/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/src/sync/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/src/sync/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7829,7 +7789,7 @@ diff -urN b/go/ssa/interp/testdata/src/sync/BUILD.bazel c/go/ssa/interp/testdata + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/interp/testdata/src/time/BUILD.bazel c/go/ssa/interp/testdata/src/time/BUILD.bazel ---- b/go/ssa/interp/testdata/src/time/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/src/time/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/src/time/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7847,7 +7807,7 @@ diff -urN b/go/ssa/interp/testdata/src/time/BUILD.bazel c/go/ssa/interp/testdata + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/interp/testdata/src/unicode/utf8/BUILD.bazel c/go/ssa/interp/testdata/src/unicode/utf8/BUILD.bazel ---- b/go/ssa/interp/testdata/src/unicode/utf8/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/src/unicode/utf8/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/src/unicode/utf8/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7865,7 +7825,7 @@ diff -urN b/go/ssa/interp/testdata/src/unicode/utf8/BUILD.bazel c/go/ssa/interp/ + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/interp/testdata/src/unsafe/BUILD.bazel c/go/ssa/interp/testdata/src/unsafe/BUILD.bazel ---- b/go/ssa/interp/testdata/src/unsafe/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/interp/testdata/src/unsafe/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/src/unsafe/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7883,7 +7843,7 @@ diff -urN b/go/ssa/interp/testdata/src/unsafe/BUILD.bazel c/go/ssa/interp/testda + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/ssautil/BUILD.bazel c/go/ssa/ssautil/BUILD.bazel ---- b/go/ssa/ssautil/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/ssautil/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/ssautil/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,81 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -7917,7 +7877,7 @@ diff -urN b/go/ssa/ssautil/BUILD.bazel c/go/ssa/ssautil/BUILD.bazel + "load_test.go", + "switch_test.go", + ], -+ data = glob(["testdata/**"], allow_empty = True), ++ data = glob(["testdata/**"]), + deps = [ + ":ssautil", + "//go/packages", @@ -7968,7 +7928,7 @@ diff -urN b/go/ssa/ssautil/BUILD.bazel c/go/ssa/ssautil/BUILD.bazel + }), +) diff -urN b/go/ssa/testdata/src/bytes/BUILD.bazel c/go/ssa/testdata/src/bytes/BUILD.bazel ---- b/go/ssa/testdata/src/bytes/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/bytes/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/bytes/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7986,7 +7946,7 @@ diff -urN b/go/ssa/testdata/src/bytes/BUILD.bazel c/go/ssa/testdata/src/bytes/BU + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/context/BUILD.bazel c/go/ssa/testdata/src/context/BUILD.bazel ---- b/go/ssa/testdata/src/context/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/context/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/context/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8004,7 +7964,7 @@ diff -urN b/go/ssa/testdata/src/context/BUILD.bazel c/go/ssa/testdata/src/contex + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/encoding/BUILD.bazel c/go/ssa/testdata/src/encoding/BUILD.bazel ---- b/go/ssa/testdata/src/encoding/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/encoding/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/encoding/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8022,7 +7982,7 @@ diff -urN b/go/ssa/testdata/src/encoding/BUILD.bazel c/go/ssa/testdata/src/encod + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/encoding/json/BUILD.bazel c/go/ssa/testdata/src/encoding/json/BUILD.bazel ---- b/go/ssa/testdata/src/encoding/json/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/encoding/json/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/encoding/json/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8040,7 +8000,7 @@ diff -urN b/go/ssa/testdata/src/encoding/json/BUILD.bazel c/go/ssa/testdata/src/ + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/encoding/xml/BUILD.bazel c/go/ssa/testdata/src/encoding/xml/BUILD.bazel ---- b/go/ssa/testdata/src/encoding/xml/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/encoding/xml/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/encoding/xml/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8058,7 +8018,7 @@ diff -urN b/go/ssa/testdata/src/encoding/xml/BUILD.bazel c/go/ssa/testdata/src/e + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/errors/BUILD.bazel c/go/ssa/testdata/src/errors/BUILD.bazel ---- b/go/ssa/testdata/src/errors/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/errors/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/errors/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8076,7 +8036,7 @@ diff -urN b/go/ssa/testdata/src/errors/BUILD.bazel c/go/ssa/testdata/src/errors/ + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/fmt/BUILD.bazel c/go/ssa/testdata/src/fmt/BUILD.bazel ---- b/go/ssa/testdata/src/fmt/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/fmt/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/fmt/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8094,7 +8054,7 @@ diff -urN b/go/ssa/testdata/src/fmt/BUILD.bazel c/go/ssa/testdata/src/fmt/BUILD. + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/io/BUILD.bazel c/go/ssa/testdata/src/io/BUILD.bazel ---- b/go/ssa/testdata/src/io/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/io/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/io/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8112,7 +8072,7 @@ diff -urN b/go/ssa/testdata/src/io/BUILD.bazel c/go/ssa/testdata/src/io/BUILD.ba + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/log/BUILD.bazel c/go/ssa/testdata/src/log/BUILD.bazel ---- b/go/ssa/testdata/src/log/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/log/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/log/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8130,7 +8090,7 @@ diff -urN b/go/ssa/testdata/src/log/BUILD.bazel c/go/ssa/testdata/src/log/BUILD. + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/math/BUILD.bazel c/go/ssa/testdata/src/math/BUILD.bazel ---- b/go/ssa/testdata/src/math/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/math/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/math/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8148,7 +8108,7 @@ diff -urN b/go/ssa/testdata/src/math/BUILD.bazel c/go/ssa/testdata/src/math/BUIL + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/os/BUILD.bazel c/go/ssa/testdata/src/os/BUILD.bazel ---- b/go/ssa/testdata/src/os/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/os/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/os/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8166,7 +8126,7 @@ diff -urN b/go/ssa/testdata/src/os/BUILD.bazel c/go/ssa/testdata/src/os/BUILD.ba + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/reflect/BUILD.bazel c/go/ssa/testdata/src/reflect/BUILD.bazel ---- b/go/ssa/testdata/src/reflect/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/reflect/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/reflect/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8184,7 +8144,7 @@ diff -urN b/go/ssa/testdata/src/reflect/BUILD.bazel c/go/ssa/testdata/src/reflec + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/runtime/BUILD.bazel c/go/ssa/testdata/src/runtime/BUILD.bazel ---- b/go/ssa/testdata/src/runtime/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/runtime/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/runtime/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8202,7 +8162,7 @@ diff -urN b/go/ssa/testdata/src/runtime/BUILD.bazel c/go/ssa/testdata/src/runtim + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/sort/BUILD.bazel c/go/ssa/testdata/src/sort/BUILD.bazel ---- b/go/ssa/testdata/src/sort/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/sort/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/sort/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8220,7 +8180,7 @@ diff -urN b/go/ssa/testdata/src/sort/BUILD.bazel c/go/ssa/testdata/src/sort/BUIL + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/strconv/BUILD.bazel c/go/ssa/testdata/src/strconv/BUILD.bazel ---- b/go/ssa/testdata/src/strconv/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/strconv/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/strconv/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8238,7 +8198,7 @@ diff -urN b/go/ssa/testdata/src/strconv/BUILD.bazel c/go/ssa/testdata/src/strcon + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/strings/BUILD.bazel c/go/ssa/testdata/src/strings/BUILD.bazel ---- b/go/ssa/testdata/src/strings/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/strings/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/strings/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8255,44 +8215,44 @@ diff -urN b/go/ssa/testdata/src/strings/BUILD.bazel c/go/ssa/testdata/src/string + actual = ":strings", + visibility = ["//visibility:public"], +) -diff -urN b/go/ssa/testdata/src/sync/BUILD.bazel c/go/ssa/testdata/src/sync/BUILD.bazel ---- b/go/ssa/testdata/src/sync/BUILD.bazel 1970-01-01 08:00:00 -+++ c/go/ssa/testdata/src/sync/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +diff -urN b/go/ssa/testdata/src/sync/atomic/BUILD.bazel c/go/ssa/testdata/src/sync/atomic/BUILD.bazel +--- b/go/ssa/testdata/src/sync/atomic/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/ssa/testdata/src/sync/atomic/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( -+ name = "sync", -+ srcs = ["sync.go"], -+ importpath = "golang.org/x/tools/go/ssa/testdata/src/sync", ++ name = "atomic", ++ srcs = ["atomic.go"], ++ importpath = "golang.org/x/tools/go/ssa/testdata/src/sync/atomic", + visibility = ["//visibility:public"], +) + +alias( + name = "go_default_library", -+ actual = ":sync", ++ actual = ":atomic", + visibility = ["//visibility:public"], +) -diff -urN b/go/ssa/testdata/src/sync/atomic/BUILD.bazel c/go/ssa/testdata/src/sync/atomic/BUILD.bazel ---- b/go/ssa/testdata/src/sync/atomic/BUILD.bazel 1970-01-01 08:00:00 -+++ c/go/ssa/testdata/src/sync/atomic/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +diff -urN b/go/ssa/testdata/src/sync/BUILD.bazel c/go/ssa/testdata/src/sync/BUILD.bazel +--- b/go/ssa/testdata/src/sync/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/ssa/testdata/src/sync/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( -+ name = "atomic", -+ srcs = ["atomic.go"], -+ importpath = "golang.org/x/tools/go/ssa/testdata/src/sync/atomic", ++ name = "sync", ++ srcs = ["sync.go"], ++ importpath = "golang.org/x/tools/go/ssa/testdata/src/sync", + visibility = ["//visibility:public"], +) + +alias( + name = "go_default_library", -+ actual = ":atomic", ++ actual = ":sync", + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/time/BUILD.bazel c/go/ssa/testdata/src/time/BUILD.bazel ---- b/go/ssa/testdata/src/time/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/time/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/time/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8310,7 +8270,7 @@ diff -urN b/go/ssa/testdata/src/time/BUILD.bazel c/go/ssa/testdata/src/time/BUIL + visibility = ["//visibility:public"], +) diff -urN b/go/ssa/testdata/src/unsafe/BUILD.bazel c/go/ssa/testdata/src/unsafe/BUILD.bazel ---- b/go/ssa/testdata/src/unsafe/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/ssa/testdata/src/unsafe/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/testdata/src/unsafe/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8328,7 +8288,7 @@ diff -urN b/go/ssa/testdata/src/unsafe/BUILD.bazel c/go/ssa/testdata/src/unsafe/ + visibility = ["//visibility:public"], +) diff -urN b/go/types/internal/play/BUILD.bazel c/go/types/internal/play/BUILD.bazel ---- b/go/types/internal/play/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/types/internal/play/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/types/internal/play/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -8352,9 +8312,9 @@ diff -urN b/go/types/internal/play/BUILD.bazel c/go/types/internal/play/BUILD.ba + visibility = ["//go/types:__subpackages__"], +) diff -urN b/go/types/objectpath/BUILD.bazel c/go/types/objectpath/BUILD.bazel ---- b/go/types/objectpath/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/types/objectpath/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/types/objectpath/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,32 @@ +@@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -8362,10 +8322,7 @@ diff -urN b/go/types/objectpath/BUILD.bazel c/go/types/objectpath/BUILD.bazel + srcs = ["objectpath.go"], + importpath = "golang.org/x/tools/go/types/objectpath", + visibility = ["//visibility:public"], -+ deps = [ -+ "//internal/typeparams", -+ "//internal/typesinternal", -+ ], ++ deps = ["//internal/typeparams"], +) + +alias( @@ -8388,7 +8345,7 @@ diff -urN b/go/types/objectpath/BUILD.bazel c/go/types/objectpath/BUILD.bazel + ], +) diff -urN b/go/types/typeutil/BUILD.bazel c/go/types/typeutil/BUILD.bazel ---- b/go/types/typeutil/BUILD.bazel 1970-01-01 08:00:00 +--- b/go/types/typeutil/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/types/typeutil/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,39 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -8430,8 +8387,29 @@ diff -urN b/go/types/typeutil/BUILD.bazel c/go/types/typeutil/BUILD.bazel + "//internal/typeparams", + ], +) +diff -urN b/godoc/analysis/BUILD.bazel c/godoc/analysis/BUILD.bazel +--- b/godoc/analysis/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/godoc/analysis/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,17 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "analysis", ++ srcs = [ ++ "analysis.go", ++ "json.go", ++ ], ++ importpath = "golang.org/x/tools/godoc/analysis", ++ visibility = ["//visibility:public"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":analysis", ++ visibility = ["//visibility:public"], ++) diff -urN b/godoc/BUILD.bazel c/godoc/BUILD.bazel ---- b/godoc/BUILD.bazel 1970-01-01 08:00:00 +--- b/godoc/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/godoc/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,66 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -8500,29 +8478,8 @@ diff -urN b/godoc/BUILD.bazel c/godoc/BUILD.bazel + "//internal/typeparams", + ], +) -diff -urN b/godoc/analysis/BUILD.bazel c/godoc/analysis/BUILD.bazel ---- b/godoc/analysis/BUILD.bazel 1970-01-01 08:00:00 -+++ c/godoc/analysis/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,17 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library") -+ -+go_library( -+ name = "analysis", -+ srcs = [ -+ "analysis.go", -+ "json.go", -+ ], -+ importpath = "golang.org/x/tools/godoc/analysis", -+ visibility = ["//visibility:public"], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":analysis", -+ visibility = ["//visibility:public"], -+) diff -urN b/godoc/redirect/BUILD.bazel c/godoc/redirect/BUILD.bazel ---- b/godoc/redirect/BUILD.bazel 1970-01-01 08:00:00 +--- b/godoc/redirect/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/godoc/redirect/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -8546,7 +8503,7 @@ diff -urN b/godoc/redirect/BUILD.bazel c/godoc/redirect/BUILD.bazel + embed = [":redirect"], +) diff -urN b/godoc/static/BUILD.bazel c/godoc/static/BUILD.bazel ---- b/godoc/static/BUILD.bazel 1970-01-01 08:00:00 +--- b/godoc/static/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/godoc/static/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -8574,7 +8531,7 @@ diff -urN b/godoc/static/BUILD.bazel c/godoc/static/BUILD.bazel + embed = [":static"], +) diff -urN b/godoc/util/BUILD.bazel c/godoc/util/BUILD.bazel ---- b/godoc/util/BUILD.bazel 1970-01-01 08:00:00 +--- b/godoc/util/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/godoc/util/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8596,7 +8553,7 @@ diff -urN b/godoc/util/BUILD.bazel c/godoc/util/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/godoc/vfs/BUILD.bazel c/godoc/vfs/BUILD.bazel ---- b/godoc/vfs/BUILD.bazel 1970-01-01 08:00:00 +--- b/godoc/vfs/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/godoc/vfs/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -8632,7 +8589,7 @@ diff -urN b/godoc/vfs/BUILD.bazel c/godoc/vfs/BUILD.bazel + ], +) diff -urN b/godoc/vfs/gatefs/BUILD.bazel c/godoc/vfs/gatefs/BUILD.bazel ---- b/godoc/vfs/gatefs/BUILD.bazel 1970-01-01 08:00:00 +--- b/godoc/vfs/gatefs/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/godoc/vfs/gatefs/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -8660,7 +8617,7 @@ diff -urN b/godoc/vfs/gatefs/BUILD.bazel c/godoc/vfs/gatefs/BUILD.bazel + ], +) diff -urN b/godoc/vfs/httpfs/BUILD.bazel c/godoc/vfs/httpfs/BUILD.bazel ---- b/godoc/vfs/httpfs/BUILD.bazel 1970-01-01 08:00:00 +--- b/godoc/vfs/httpfs/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/godoc/vfs/httpfs/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8679,7 +8636,7 @@ diff -urN b/godoc/vfs/httpfs/BUILD.bazel c/godoc/vfs/httpfs/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/godoc/vfs/mapfs/BUILD.bazel c/godoc/vfs/mapfs/BUILD.bazel ---- b/godoc/vfs/mapfs/BUILD.bazel 1970-01-01 08:00:00 +--- b/godoc/vfs/mapfs/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/godoc/vfs/mapfs/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -8704,7 +8661,7 @@ diff -urN b/godoc/vfs/mapfs/BUILD.bazel c/godoc/vfs/mapfs/BUILD.bazel + embed = [":mapfs"], +) diff -urN b/godoc/vfs/zipfs/BUILD.bazel c/godoc/vfs/zipfs/BUILD.bazel ---- b/godoc/vfs/zipfs/BUILD.bazel 1970-01-01 08:00:00 +--- b/godoc/vfs/zipfs/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/godoc/vfs/zipfs/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -8730,7 +8687,7 @@ diff -urN b/godoc/vfs/zipfs/BUILD.bazel c/godoc/vfs/zipfs/BUILD.bazel + deps = ["//godoc/vfs"], +) diff -urN b/imports/BUILD.bazel c/imports/BUILD.bazel ---- b/imports/BUILD.bazel 1970-01-01 08:00:00 +--- b/imports/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/imports/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8752,7 +8709,7 @@ diff -urN b/imports/BUILD.bazel c/imports/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/internal/analysisinternal/BUILD.bazel c/internal/analysisinternal/BUILD.bazel ---- b/internal/analysisinternal/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/analysisinternal/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/analysisinternal/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8770,7 +8727,7 @@ diff -urN b/internal/analysisinternal/BUILD.bazel c/internal/analysisinternal/BU + visibility = ["//:__subpackages__"], +) diff -urN b/internal/apidiff/BUILD.bazel c/internal/apidiff/BUILD.bazel ---- b/internal/apidiff/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/apidiff/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/apidiff/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -8804,7 +8761,7 @@ diff -urN b/internal/apidiff/BUILD.bazel c/internal/apidiff/BUILD.bazel + ], +) diff -urN b/internal/apidiff/testdata/BUILD.bazel c/internal/apidiff/testdata/BUILD.bazel ---- b/internal/apidiff/testdata/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/apidiff/testdata/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/apidiff/testdata/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8822,7 +8779,7 @@ diff -urN b/internal/apidiff/testdata/BUILD.bazel c/internal/apidiff/testdata/BU + visibility = ["//:__subpackages__"], +) diff -urN b/internal/apidiff/testdata/exported_fields/BUILD.bazel c/internal/apidiff/testdata/exported_fields/BUILD.bazel ---- b/internal/apidiff/testdata/exported_fields/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/apidiff/testdata/exported_fields/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/apidiff/testdata/exported_fields/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8839,8 +8796,26 @@ diff -urN b/internal/apidiff/testdata/exported_fields/BUILD.bazel c/internal/api + actual = ":exported_fields", + visibility = ["//:__subpackages__"], +) +diff -urN b/internal/astutil/BUILD.bazel c/internal/astutil/BUILD.bazel +--- b/internal/astutil/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/internal/astutil/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,14 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "astutil", ++ srcs = ["clone.go"], ++ importpath = "golang.org/x/tools/internal/astutil", ++ visibility = ["//:__subpackages__"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":astutil", ++ visibility = ["//:__subpackages__"], ++) diff -urN b/internal/bisect/BUILD.bazel c/internal/bisect/BUILD.bazel ---- b/internal/bisect/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/bisect/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/bisect/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -8864,9 +8839,9 @@ diff -urN b/internal/bisect/BUILD.bazel c/internal/bisect/BUILD.bazel + embed = [":bisect"], +) diff -urN b/internal/cmd/deadcode/BUILD.bazel c/internal/cmd/deadcode/BUILD.bazel ---- b/internal/cmd/deadcode/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/cmd/deadcode/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/cmd/deadcode/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,34 @@ +@@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") + +go_library( @@ -8879,6 +8854,7 @@ diff -urN b/internal/cmd/deadcode/BUILD.bazel c/internal/cmd/deadcode/BUILD.baze + importpath = "golang.org/x/tools/internal/cmd/deadcode", + visibility = ["//visibility:private"], + deps = [ ++ "//go/callgraph", + "//go/callgraph/rta", + "//go/packages", + "//go/ssa", @@ -8895,14 +8871,14 @@ diff -urN b/internal/cmd/deadcode/BUILD.bazel c/internal/cmd/deadcode/BUILD.baze +go_test( + name = "deadcode_test", + srcs = ["deadcode_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), ++ data = glob(["testdata/**"]), + deps = [ + "//internal/testenv", + "//txtar", + ], +) diff -urN b/internal/compat/BUILD.bazel c/internal/compat/BUILD.bazel ---- b/internal/compat/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/compat/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/compat/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8924,7 +8900,7 @@ diff -urN b/internal/compat/BUILD.bazel c/internal/compat/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN b/internal/constraints/BUILD.bazel c/internal/constraints/BUILD.bazel ---- b/internal/constraints/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/constraints/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/constraints/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8942,7 +8918,7 @@ diff -urN b/internal/constraints/BUILD.bazel c/internal/constraints/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN b/internal/diff/BUILD.bazel c/internal/diff/BUILD.bazel ---- b/internal/diff/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/diff/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/diff/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -8978,7 +8954,7 @@ diff -urN b/internal/diff/BUILD.bazel c/internal/diff/BUILD.bazel + ], +) diff -urN b/internal/diff/difftest/BUILD.bazel c/internal/diff/difftest/BUILD.bazel ---- b/internal/diff/difftest/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/diff/difftest/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/diff/difftest/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -9006,7 +8982,7 @@ diff -urN b/internal/diff/difftest/BUILD.bazel c/internal/diff/difftest/BUILD.ba + ], +) diff -urN b/internal/diff/lcs/BUILD.bazel c/internal/diff/lcs/BUILD.bazel ---- b/internal/diff/lcs/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/diff/lcs/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/diff/lcs/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -9039,7 +9015,7 @@ diff -urN b/internal/diff/lcs/BUILD.bazel c/internal/diff/lcs/BUILD.bazel + embed = [":lcs"], +) diff -urN b/internal/diff/myers/BUILD.bazel c/internal/diff/myers/BUILD.bazel ---- b/internal/diff/myers/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/diff/myers/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/diff/myers/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -9067,7 +9043,7 @@ diff -urN b/internal/diff/myers/BUILD.bazel c/internal/diff/myers/BUILD.bazel + ], +) diff -urN b/internal/diffp/BUILD.bazel c/internal/diffp/BUILD.bazel ---- b/internal/diffp/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/diffp/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/diffp/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -9088,12 +9064,12 @@ diff -urN b/internal/diffp/BUILD.bazel c/internal/diffp/BUILD.bazel +go_test( + name = "diffp_test", + srcs = ["diff_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), ++ data = glob(["testdata/**"]), + embed = [":diffp"], + deps = ["//txtar"], +) diff -urN b/internal/edit/BUILD.bazel c/internal/edit/BUILD.bazel ---- b/internal/edit/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/edit/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/edit/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -9117,7 +9093,7 @@ diff -urN b/internal/edit/BUILD.bazel c/internal/edit/BUILD.bazel + embed = [":edit"], +) diff -urN b/internal/event/BUILD.bazel c/internal/event/BUILD.bazel ---- b/internal/event/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/event/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/event/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -9155,7 +9131,7 @@ diff -urN b/internal/event/BUILD.bazel c/internal/event/BUILD.bazel + ], +) diff -urN b/internal/event/core/BUILD.bazel c/internal/event/core/BUILD.bazel ---- b/internal/event/core/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/event/core/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/event/core/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9181,7 +9157,7 @@ diff -urN b/internal/event/core/BUILD.bazel c/internal/event/core/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN b/internal/event/export/BUILD.bazel c/internal/event/export/BUILD.bazel ---- b/internal/event/export/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/event/export/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/event/export/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -9223,7 +9199,7 @@ diff -urN b/internal/event/export/BUILD.bazel c/internal/event/export/BUILD.baze + ], +) diff -urN b/internal/event/export/eventtest/BUILD.bazel c/internal/event/export/eventtest/BUILD.bazel ---- b/internal/event/export/eventtest/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/event/export/eventtest/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/event/export/eventtest/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9247,7 +9223,7 @@ diff -urN b/internal/event/export/eventtest/BUILD.bazel c/internal/event/export/ + visibility = ["//:__subpackages__"], +) diff -urN b/internal/event/export/metric/BUILD.bazel c/internal/event/export/metric/BUILD.bazel ---- b/internal/event/export/metric/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/event/export/metric/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/event/export/metric/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9275,7 +9251,7 @@ diff -urN b/internal/event/export/metric/BUILD.bazel c/internal/event/export/met + visibility = ["//:__subpackages__"], +) diff -urN b/internal/event/export/ocagent/BUILD.bazel c/internal/event/export/ocagent/BUILD.bazel ---- b/internal/event/export/ocagent/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/event/export/ocagent/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/event/export/ocagent/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,44 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -9323,7 +9299,7 @@ diff -urN b/internal/event/export/ocagent/BUILD.bazel c/internal/event/export/oc + ], +) diff -urN b/internal/event/export/ocagent/wire/BUILD.bazel c/internal/event/export/ocagent/wire/BUILD.bazel ---- b/internal/event/export/ocagent/wire/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/event/export/ocagent/wire/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/event/export/ocagent/wire/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -9352,7 +9328,7 @@ diff -urN b/internal/event/export/ocagent/wire/BUILD.bazel c/internal/event/expo + embed = [":wire"], +) diff -urN b/internal/event/export/prometheus/BUILD.bazel c/internal/event/export/prometheus/BUILD.bazel ---- b/internal/event/export/prometheus/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/event/export/prometheus/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/event/export/prometheus/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9376,7 +9352,7 @@ diff -urN b/internal/event/export/prometheus/BUILD.bazel c/internal/event/export + visibility = ["//:__subpackages__"], +) diff -urN b/internal/event/keys/BUILD.bazel c/internal/event/keys/BUILD.bazel ---- b/internal/event/keys/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/event/keys/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/event/keys/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9398,7 +9374,7 @@ diff -urN b/internal/event/keys/BUILD.bazel c/internal/event/keys/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN b/internal/event/label/BUILD.bazel c/internal/event/label/BUILD.bazel ---- b/internal/event/label/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/event/label/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/event/label/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -9425,7 +9401,7 @@ diff -urN b/internal/event/label/BUILD.bazel c/internal/event/label/BUILD.bazel + ], +) diff -urN b/internal/event/tag/BUILD.bazel c/internal/event/tag/BUILD.bazel ---- b/internal/event/tag/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/event/tag/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/event/tag/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9444,9 +9420,9 @@ diff -urN b/internal/event/tag/BUILD.bazel c/internal/event/tag/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN b/internal/facts/BUILD.bazel c/internal/facts/BUILD.bazel ---- b/internal/facts/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/facts/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/facts/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,35 @@ +@@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -9461,14 +9437,13 @@ diff -urN b/internal/facts/BUILD.bazel c/internal/facts/BUILD.bazel + "//go/analysis", + "//go/types/objectpath", + "//internal/typeparams", -+ "//internal/typesinternal", + ], +) + +alias( + name = "go_default_library", + actual = ":facts", -+ visibility = ["//:__subpackages__"], ++ visibility = ["//visibility:public"], +) + +go_test( @@ -9483,7 +9458,7 @@ diff -urN b/internal/facts/BUILD.bazel c/internal/facts/BUILD.bazel + ], +) diff -urN b/internal/fakenet/BUILD.bazel c/internal/fakenet/BUILD.bazel ---- b/internal/fakenet/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/fakenet/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/fakenet/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9500,42 +9475,8 @@ diff -urN b/internal/fakenet/BUILD.bazel c/internal/fakenet/BUILD.bazel + actual = ":fakenet", + visibility = ["//:__subpackages__"], +) -diff -urN b/internal/fastwalk/BUILD.bazel c/internal/fastwalk/BUILD.bazel ---- b/internal/fastwalk/BUILD.bazel 1970-01-01 08:00:00 -+++ c/internal/fastwalk/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,30 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -+ -+go_library( -+ name = "fastwalk", -+ srcs = [ -+ "fastwalk.go", -+ "fastwalk_darwin.go", -+ "fastwalk_dirent_fileno.go", -+ "fastwalk_dirent_ino.go", -+ "fastwalk_dirent_namlen_bsd.go", -+ "fastwalk_dirent_namlen_linux.go", -+ "fastwalk_portable.go", -+ "fastwalk_unix.go", -+ ], -+ cgo = True, -+ importpath = "golang.org/x/tools/internal/fastwalk", -+ visibility = ["//:__subpackages__"], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":fastwalk", -+ visibility = ["//:__subpackages__"], -+) -+ -+go_test( -+ name = "fastwalk_test", -+ srcs = ["fastwalk_test.go"], -+ deps = [":fastwalk"], -+) diff -urN b/internal/fuzzy/BUILD.bazel c/internal/fuzzy/BUILD.bazel ---- b/internal/fuzzy/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/fuzzy/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/fuzzy/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -9571,7 +9512,7 @@ diff -urN b/internal/fuzzy/BUILD.bazel c/internal/fuzzy/BUILD.bazel + ], +) diff -urN b/internal/gcimporter/BUILD.bazel c/internal/gcimporter/BUILD.bazel ---- b/internal/gcimporter/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/gcimporter/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/gcimporter/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,60 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -9635,7 +9576,7 @@ diff -urN b/internal/gcimporter/BUILD.bazel c/internal/gcimporter/BUILD.bazel + ], +) diff -urN b/internal/gcimporter/testdata/a/BUILD.bazel c/internal/gcimporter/testdata/a/BUILD.bazel ---- b/internal/gcimporter/testdata/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/gcimporter/testdata/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/gcimporter/testdata/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9652,8 +9593,26 @@ diff -urN b/internal/gcimporter/testdata/a/BUILD.bazel c/internal/gcimporter/tes + actual = ":a", + visibility = ["//:__subpackages__"], +) +diff -urN b/internal/gcimporter/testdata/issue51836/a/BUILD.bazel c/internal/gcimporter/testdata/issue51836/a/BUILD.bazel +--- b/internal/gcimporter/testdata/issue51836/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/internal/gcimporter/testdata/issue51836/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,14 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "a", ++ srcs = ["a.go"], ++ importpath = "golang.org/x/tools/internal/gcimporter/testdata/issue51836/a", ++ visibility = ["//:__subpackages__"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":a", ++ visibility = ["//:__subpackages__"], ++) diff -urN b/internal/gcimporter/testdata/issue51836/BUILD.bazel c/internal/gcimporter/testdata/issue51836/BUILD.bazel ---- b/internal/gcimporter/testdata/issue51836/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/gcimporter/testdata/issue51836/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/gcimporter/testdata/issue51836/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9674,26 +9633,8 @@ diff -urN b/internal/gcimporter/testdata/issue51836/BUILD.bazel c/internal/gcimp + actual = ":issue51836", + visibility = ["//:__subpackages__"], +) -diff -urN b/internal/gcimporter/testdata/issue51836/a/BUILD.bazel c/internal/gcimporter/testdata/issue51836/a/BUILD.bazel ---- b/internal/gcimporter/testdata/issue51836/a/BUILD.bazel 1970-01-01 08:00:00 -+++ c/internal/gcimporter/testdata/issue51836/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,14 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library") -+ -+go_library( -+ name = "a", -+ srcs = ["a.go"], -+ importpath = "golang.org/x/tools/internal/gcimporter/testdata/issue51836/a", -+ visibility = ["//:__subpackages__"], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":a", -+ visibility = ["//:__subpackages__"], -+) diff -urN b/internal/gcimporter/testdata/issue58296/a/BUILD.bazel c/internal/gcimporter/testdata/issue58296/a/BUILD.bazel ---- b/internal/gcimporter/testdata/issue58296/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/gcimporter/testdata/issue58296/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/gcimporter/testdata/issue58296/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9711,7 +9652,7 @@ diff -urN b/internal/gcimporter/testdata/issue58296/a/BUILD.bazel c/internal/gci + visibility = ["//:__subpackages__"], +) diff -urN b/internal/gcimporter/testdata/issue58296/b/BUILD.bazel c/internal/gcimporter/testdata/issue58296/b/BUILD.bazel ---- b/internal/gcimporter/testdata/issue58296/b/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/gcimporter/testdata/issue58296/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/gcimporter/testdata/issue58296/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9729,7 +9670,7 @@ diff -urN b/internal/gcimporter/testdata/issue58296/b/BUILD.bazel c/internal/gci + visibility = ["//:__subpackages__"], +) diff -urN b/internal/gcimporter/testdata/issue58296/c/BUILD.bazel c/internal/gcimporter/testdata/issue58296/c/BUILD.bazel ---- b/internal/gcimporter/testdata/issue58296/c/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/gcimporter/testdata/issue58296/c/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/gcimporter/testdata/issue58296/c/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9747,7 +9688,7 @@ diff -urN b/internal/gcimporter/testdata/issue58296/c/BUILD.bazel c/internal/gci + visibility = ["//:__subpackages__"], +) diff -urN b/internal/gcimporter/testdata/versions/BUILD.bazel c/internal/gcimporter/testdata/versions/BUILD.bazel ---- b/internal/gcimporter/testdata/versions/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/gcimporter/testdata/versions/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/gcimporter/testdata/versions/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9765,7 +9706,7 @@ diff -urN b/internal/gcimporter/testdata/versions/BUILD.bazel c/internal/gcimpor + visibility = ["//:__subpackages__"], +) diff -urN b/internal/gocommand/BUILD.bazel c/internal/gocommand/BUILD.bazel ---- b/internal/gocommand/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/gocommand/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/gocommand/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -9805,9 +9746,9 @@ diff -urN b/internal/gocommand/BUILD.bazel c/internal/gocommand/BUILD.bazel + deps = ["//internal/testenv"], +) diff -urN b/internal/gopathwalk/BUILD.bazel c/internal/gopathwalk/BUILD.bazel ---- b/internal/gopathwalk/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/gopathwalk/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/gopathwalk/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,21 @@ +@@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -9815,7 +9756,6 @@ diff -urN b/internal/gopathwalk/BUILD.bazel c/internal/gopathwalk/BUILD.bazel + srcs = ["walk.go"], + importpath = "golang.org/x/tools/internal/gopathwalk", + visibility = ["//:__subpackages__"], -+ deps = ["//internal/fastwalk"], +) + +alias( @@ -9830,7 +9770,7 @@ diff -urN b/internal/gopathwalk/BUILD.bazel c/internal/gopathwalk/BUILD.bazel + embed = [":gopathwalk"], +) diff -urN b/internal/goroot/BUILD.bazel c/internal/goroot/BUILD.bazel ---- b/internal/goroot/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/goroot/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/goroot/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9848,7 +9788,7 @@ diff -urN b/internal/goroot/BUILD.bazel c/internal/goroot/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN b/internal/imports/BUILD.bazel c/internal/imports/BUILD.bazel ---- b/internal/imports/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/imports/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/imports/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,49 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -9888,7 +9828,7 @@ diff -urN b/internal/imports/BUILD.bazel c/internal/imports/BUILD.bazel + "mod_cache_test.go", + "mod_test.go", + ], -+ data = glob(["testdata/**"], allow_empty = True), ++ data = glob(["testdata/**"]), + embed = [":imports"], + deps = [ + "//go/packages/packagestest", @@ -9901,7 +9841,7 @@ diff -urN b/internal/imports/BUILD.bazel c/internal/imports/BUILD.bazel + ], +) diff -urN b/internal/jsonrpc2/BUILD.bazel c/internal/jsonrpc2/BUILD.bazel ---- b/internal/jsonrpc2/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/jsonrpc2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/jsonrpc2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,42 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -9947,7 +9887,7 @@ diff -urN b/internal/jsonrpc2/BUILD.bazel c/internal/jsonrpc2/BUILD.bazel + ], +) diff -urN b/internal/jsonrpc2/servertest/BUILD.bazel c/internal/jsonrpc2/servertest/BUILD.bazel ---- b/internal/jsonrpc2/servertest/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/jsonrpc2/servertest/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/jsonrpc2/servertest/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -9973,7 +9913,7 @@ diff -urN b/internal/jsonrpc2/servertest/BUILD.bazel c/internal/jsonrpc2/servert + deps = ["//internal/jsonrpc2"], +) diff -urN b/internal/jsonrpc2_v2/BUILD.bazel c/internal/jsonrpc2_v2/BUILD.bazel ---- b/internal/jsonrpc2_v2/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/jsonrpc2_v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/jsonrpc2_v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,45 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -10022,7 +9962,7 @@ diff -urN b/internal/jsonrpc2_v2/BUILD.bazel c/internal/jsonrpc2_v2/BUILD.bazel + ], +) diff -urN b/internal/memoize/BUILD.bazel c/internal/memoize/BUILD.bazel ---- b/internal/memoize/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/memoize/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/memoize/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -10047,7 +9987,7 @@ diff -urN b/internal/memoize/BUILD.bazel c/internal/memoize/BUILD.bazel + deps = [":memoize"], +) diff -urN b/internal/packagesinternal/BUILD.bazel c/internal/packagesinternal/BUILD.bazel ---- b/internal/packagesinternal/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/packagesinternal/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/packagesinternal/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10066,7 +10006,7 @@ diff -urN b/internal/packagesinternal/BUILD.bazel c/internal/packagesinternal/BU + visibility = ["//:__subpackages__"], +) diff -urN b/internal/persistent/BUILD.bazel c/internal/persistent/BUILD.bazel ---- b/internal/persistent/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/persistent/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/persistent/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -10098,7 +10038,7 @@ diff -urN b/internal/persistent/BUILD.bazel c/internal/persistent/BUILD.bazel + deps = ["//internal/constraints"], +) diff -urN b/internal/pkgbits/BUILD.bazel c/internal/pkgbits/BUILD.bazel ---- b/internal/pkgbits/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/pkgbits/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/pkgbits/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10128,7 +10068,7 @@ diff -urN b/internal/pkgbits/BUILD.bazel c/internal/pkgbits/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN b/internal/pprof/BUILD.bazel c/internal/pprof/BUILD.bazel ---- b/internal/pprof/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/pprof/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/pprof/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -10149,11 +10089,11 @@ diff -urN b/internal/pprof/BUILD.bazel c/internal/pprof/BUILD.bazel +go_test( + name = "pprof_test", + srcs = ["pprof_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), ++ data = glob(["testdata/**"]), + deps = [":pprof"], +) diff -urN b/internal/proxydir/BUILD.bazel c/internal/proxydir/BUILD.bazel ---- b/internal/proxydir/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/proxydir/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/proxydir/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -10177,64 +10117,10 @@ diff -urN b/internal/proxydir/BUILD.bazel c/internal/proxydir/BUILD.bazel + srcs = ["proxydir_test.go"], + embed = [":proxydir"], +) -diff -urN b/internal/refactor/inline/BUILD.bazel c/internal/refactor/inline/BUILD.bazel ---- b/internal/refactor/inline/BUILD.bazel 1970-01-01 08:00:00 -+++ c/internal/refactor/inline/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,50 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -+ -+go_library( -+ name = "inline", -+ srcs = [ -+ "callee.go", -+ "calleefx.go", -+ "doc.go", -+ "escape.go", -+ "falcon.go", -+ "inline.go", -+ "util.go", -+ ], -+ importpath = "golang.org/x/tools/internal/refactor/inline", -+ visibility = ["//:__subpackages__"], -+ deps = [ -+ "//go/ast/astutil", -+ "//go/types/typeutil", -+ "//imports", -+ "//internal/typeparams", -+ ], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":inline", -+ visibility = ["//:__subpackages__"], -+) -+ -+go_test( -+ name = "inline_test", -+ srcs = [ -+ "calleefx_test.go", -+ "everything_test.go", -+ "export_test.go", -+ "falcon_test.go", -+ "inline_test.go", -+ ], -+ data = glob(["testdata/**"], allow_empty = True), -+ embed = [":inline"], -+ deps = [ -+ "//go/ast/astutil", -+ "//go/expect", -+ "//go/packages", -+ "//go/types/typeutil", -+ "//internal/diff", -+ "//internal/testenv", -+ "//txtar", -+ ], -+) diff -urN b/internal/refactor/inline/analyzer/BUILD.bazel c/internal/refactor/inline/analyzer/BUILD.bazel ---- b/internal/refactor/inline/analyzer/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/refactor/inline/analyzer/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/refactor/inline/analyzer/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,32 @@ +@@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -10261,14 +10147,13 @@ diff -urN b/internal/refactor/inline/analyzer/BUILD.bazel c/internal/refactor/in +go_test( + name = "analyzer_test", + srcs = ["analyzer_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), + deps = [ + ":analyzer", + "//go/analysis/analysistest", + ], +) diff -urN b/internal/refactor/inline/analyzer/testdata/src/a/BUILD.bazel c/internal/refactor/inline/analyzer/testdata/src/a/BUILD.bazel ---- b/internal/refactor/inline/analyzer/testdata/src/a/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/refactor/inline/analyzer/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/refactor/inline/analyzer/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10286,7 +10171,7 @@ diff -urN b/internal/refactor/inline/analyzer/testdata/src/a/BUILD.bazel c/inter + visibility = ["//:__subpackages__"], +) diff -urN b/internal/refactor/inline/analyzer/testdata/src/b/BUILD.bazel c/internal/refactor/inline/analyzer/testdata/src/b/BUILD.bazel ---- b/internal/refactor/inline/analyzer/testdata/src/b/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/refactor/inline/analyzer/testdata/src/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/refactor/inline/analyzer/testdata/src/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10303,8 +10188,63 @@ diff -urN b/internal/refactor/inline/analyzer/testdata/src/b/BUILD.bazel c/inter + actual = ":b", + visibility = ["//:__subpackages__"], +) +diff -urN b/internal/refactor/inline/BUILD.bazel c/internal/refactor/inline/BUILD.bazel +--- b/internal/refactor/inline/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/internal/refactor/inline/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,51 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") ++ ++go_library( ++ name = "inline", ++ srcs = [ ++ "callee.go", ++ "calleefx.go", ++ "doc.go", ++ "escape.go", ++ "falcon.go", ++ "inline.go", ++ "util.go", ++ ], ++ importpath = "golang.org/x/tools/internal/refactor/inline", ++ visibility = ["//:__subpackages__"], ++ deps = [ ++ "//go/ast/astutil", ++ "//go/types/typeutil", ++ "//imports", ++ "//internal/astutil", ++ "//internal/typeparams", ++ ], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":inline", ++ visibility = ["//:__subpackages__"], ++) ++ ++go_test( ++ name = "inline_test", ++ srcs = [ ++ "calleefx_test.go", ++ "everything_test.go", ++ "export_test.go", ++ "falcon_test.go", ++ "inline_test.go", ++ ], ++ data = glob(["testdata/**"]), ++ embed = [":inline"], ++ deps = [ ++ "//go/ast/astutil", ++ "//go/expect", ++ "//go/packages", ++ "//go/types/typeutil", ++ "//internal/diff", ++ "//internal/testenv", ++ "//txtar", ++ ], ++) diff -urN b/internal/robustio/BUILD.bazel c/internal/robustio/BUILD.bazel ---- b/internal/robustio/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/robustio/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/robustio/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -10337,7 +10277,7 @@ diff -urN b/internal/robustio/BUILD.bazel c/internal/robustio/BUILD.bazel + deps = [":robustio"], +) diff -urN b/internal/stack/BUILD.bazel c/internal/stack/BUILD.bazel ---- b/internal/stack/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/stack/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/stack/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -10365,7 +10305,7 @@ diff -urN b/internal/stack/BUILD.bazel c/internal/stack/BUILD.bazel + deps = [":stack"], +) diff -urN b/internal/stack/gostacks/BUILD.bazel c/internal/stack/gostacks/BUILD.bazel ---- b/internal/stack/gostacks/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/stack/gostacks/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/stack/gostacks/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -10384,7 +10324,7 @@ diff -urN b/internal/stack/gostacks/BUILD.bazel c/internal/stack/gostacks/BUILD. + visibility = ["//:__subpackages__"], +) diff -urN b/internal/stack/stacktest/BUILD.bazel c/internal/stack/stacktest/BUILD.bazel ---- b/internal/stack/stacktest/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/stack/stacktest/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/stack/stacktest/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10403,7 +10343,7 @@ diff -urN b/internal/stack/stacktest/BUILD.bazel c/internal/stack/stacktest/BUIL + visibility = ["//:__subpackages__"], +) diff -urN b/internal/testenv/BUILD.bazel c/internal/testenv/BUILD.bazel ---- b/internal/testenv/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/testenv/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/testenv/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10431,7 +10371,7 @@ diff -urN b/internal/testenv/BUILD.bazel c/internal/testenv/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN b/internal/tokeninternal/BUILD.bazel c/internal/tokeninternal/BUILD.bazel ---- b/internal/tokeninternal/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/tokeninternal/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/tokeninternal/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -10455,7 +10395,7 @@ diff -urN b/internal/tokeninternal/BUILD.bazel c/internal/tokeninternal/BUILD.ba + deps = [":tokeninternal"], +) diff -urN b/internal/tool/BUILD.bazel c/internal/tool/BUILD.bazel ---- b/internal/tool/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/tool/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/tool/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10473,7 +10413,7 @@ diff -urN b/internal/tool/BUILD.bazel c/internal/tool/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN b/internal/typeparams/BUILD.bazel c/internal/typeparams/BUILD.bazel ---- b/internal/typeparams/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/typeparams/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/typeparams/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,39 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -10516,7 +10456,7 @@ diff -urN b/internal/typeparams/BUILD.bazel c/internal/typeparams/BUILD.bazel + ], +) diff -urN b/internal/typeparams/genericfeatures/BUILD.bazel c/internal/typeparams/genericfeatures/BUILD.bazel ---- b/internal/typeparams/genericfeatures/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/typeparams/genericfeatures/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/typeparams/genericfeatures/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10538,9 +10478,9 @@ diff -urN b/internal/typeparams/genericfeatures/BUILD.bazel c/internal/typeparam + visibility = ["//:__subpackages__"], +) diff -urN b/internal/typesinternal/BUILD.bazel c/internal/typesinternal/BUILD.bazel ---- b/internal/typesinternal/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/typesinternal/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/typesinternal/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,25 @@ +@@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -10548,7 +10488,6 @@ diff -urN b/internal/typesinternal/BUILD.bazel c/internal/typesinternal/BUILD.ba + srcs = [ + "errorcode.go", + "errorcode_string.go", -+ "objectpath.go", + "types.go", + "types_118.go", + ], @@ -10567,7 +10506,7 @@ diff -urN b/internal/typesinternal/BUILD.bazel c/internal/typesinternal/BUILD.ba + srcs = ["errorcode_test.go"], +) diff -urN b/internal/xcontext/BUILD.bazel c/internal/xcontext/BUILD.bazel ---- b/internal/xcontext/BUILD.bazel 1970-01-01 08:00:00 +--- b/internal/xcontext/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/xcontext/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10585,7 +10524,7 @@ diff -urN b/internal/xcontext/BUILD.bazel c/internal/xcontext/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN b/playground/BUILD.bazel c/playground/BUILD.bazel ---- b/playground/BUILD.bazel 1970-01-01 08:00:00 +--- b/playground/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/playground/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10603,7 +10542,7 @@ diff -urN b/playground/BUILD.bazel c/playground/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN b/playground/socket/BUILD.bazel c/playground/socket/BUILD.bazel ---- b/playground/socket/BUILD.bazel 1970-01-01 08:00:00 +--- b/playground/socket/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/playground/socket/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -10632,7 +10571,7 @@ diff -urN b/playground/socket/BUILD.bazel c/playground/socket/BUILD.bazel + embed = [":socket"], +) diff -urN b/present/BUILD.bazel c/present/BUILD.bazel ---- b/present/BUILD.bazel 1970-01-01 08:00:00 +--- b/present/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/present/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,44 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -10676,11 +10615,11 @@ diff -urN b/present/BUILD.bazel c/present/BUILD.bazel + "parse_test.go", + "style_test.go", + ], -+ data = glob(["testdata/**"], allow_empty = True), ++ data = glob(["testdata/**"]), + embed = [":present"], +) diff -urN b/refactor/eg/BUILD.bazel c/refactor/eg/BUILD.bazel ---- b/refactor/eg/BUILD.bazel 1970-01-01 08:00:00 +--- b/refactor/eg/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/refactor/eg/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,93 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -10706,7 +10645,7 @@ diff -urN b/refactor/eg/BUILD.bazel c/refactor/eg/BUILD.bazel +go_test( + name = "eg_test", + srcs = ["eg_test.go"], -+ data = glob(["testdata/**"], allow_empty = True), ++ data = glob(["testdata/**"]), + deps = select({ + "@io_bazel_rules_go//go/platform:aix": [ + ":eg", @@ -10777,7 +10716,7 @@ diff -urN b/refactor/eg/BUILD.bazel c/refactor/eg/BUILD.bazel + }), +) diff -urN b/refactor/importgraph/BUILD.bazel c/refactor/importgraph/BUILD.bazel ---- b/refactor/importgraph/BUILD.bazel 1970-01-01 08:00:00 +--- b/refactor/importgraph/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/refactor/importgraph/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,75 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -10856,7 +10795,7 @@ diff -urN b/refactor/importgraph/BUILD.bazel c/refactor/importgraph/BUILD.bazel + }), +) diff -urN b/refactor/rename/BUILD.bazel c/refactor/rename/BUILD.bazel ---- b/refactor/rename/BUILD.bazel 1970-01-01 08:00:00 +--- b/refactor/rename/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/refactor/rename/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,42 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -10902,7 +10841,7 @@ diff -urN b/refactor/rename/BUILD.bazel c/refactor/rename/BUILD.bazel + ], +) diff -urN b/refactor/satisfy/BUILD.bazel c/refactor/satisfy/BUILD.bazel ---- b/refactor/satisfy/BUILD.bazel 1970-01-01 08:00:00 +--- b/refactor/satisfy/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/refactor/satisfy/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -10934,7 +10873,7 @@ diff -urN b/refactor/satisfy/BUILD.bazel c/refactor/satisfy/BUILD.bazel + ], +) diff -urN b/txtar/BUILD.bazel c/txtar/BUILD.bazel ---- b/txtar/BUILD.bazel 1970-01-01 08:00:00 +--- b/txtar/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/txtar/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")