[release] prepare v0.35.2 release
073136db3 CHANGELOG.md: update for v0.35.2
8e5969fe0 src/goToolsInformation: pick up gopls release
55683f5fd src/goToolsInformation: update hardcoded gopls version
886decb92 tools: generate inlay hints settings from gopls settings
7467f2672 README: edit Quickstart and Features section for clarity
e4a94d253 .github/workflows: fix wiki.yml
84fe4e7da .github/workflows: add go1.19rc2 to long/smoke tests
d11476774 commands: add go.goroot command
484a3ba45 test/gopls/vulncheck: add logging for viewer test failure
5bf723727 test/integration/extension: disable all "Test Completion Snippets *"
f4fcd7ad6 test/integration/goDebug: make invalid flag test faster
cbecbf8a2 test/integration/goExplorer: fix 'env tree items' test
e91d0e84f test/integration/install: stub languageserver restart command
a6729ef68 test/integration/goDebug: speed up setUpRemoteProgram
78c2fac41 Revert "src/goInstallTools: show error if go.languageserver.restart fails"
aa3de7f87 test/integration: catch failed await in lint test
b90e57e68 .vscode/launch.json: remove outFiles and deprecated attributes
d2afd7d70 src/goTest/resolve: fix nested packageDisplayMode handling on win32
47f6dfae8 test/integration/goTest: fix populateModulePathCache
1adebbbee test/integration/goTest.run: increase discover&run timeout
ffae00196 test/integration/goDebug: skip redundant tests in withConsole mode
c90973864 test/integration/goDebug: skip legacy da testing on windows
a39ef240a package.json: remove tslint
1dfac1444 .github/workflows: drop 1.15 from long test
944b1d477 .github/workflows: remove 'stable' unnecessary in setup-go@v3
21bbd7be8 test: skip flaky debug test
305bea73a .github/workflows: upgrade setup-go to v3 and enable caching
b6aad3e65 .github/workflows: upgrade checkout/node workflows to v3
9bb57d8ac test/integration: skip tests broken on windows
b012df443 src/goInstallTools: show error if go.languageserver.restart fails
c8598b13c test/integration/goDebug: catch any error while cleaning up
8f6cb5dee goGenerateTests: resolve config file path
aba30790d CHANGELOG.md: add v0.35.1 description
bfdb91c89 package.json: update dev version
4bd0f3323 docs/debugging.md: fix missing "" in example
Change-Id: I7504ae5e6d9c40009ad0feb6317f7f1000987012
diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml
index 18af3bf..1da361c 100644
--- a/.github/workflows/release-nightly.yml
+++ b/.github/workflows/release-nightly.yml
@@ -18,17 +18,20 @@
steps:
- name: Clone repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Setup Node
- uses: actions/setup-node@v1
+ uses: actions/setup-node@v3
with:
- node-version: '14.x'
+ node-version: '16'
+ cache: 'npm'
- name: Setup Go
- uses: actions/setup-go@v2
+ uses: actions/setup-go@v3
with:
- go-version: '1.18'
+ go-version: '1.19'
+ check-latest: true
+ cache: true
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index f2156ad..46bba60 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -37,8 +37,14 @@
if: github.repository == 'golang/vscode-go'
steps:
- - name: checkout code
- uses: actions/checkout@v2
+ - name: Clone repository
+ uses: actions/checkout@v3
+
+ - name: Setup Node
+ uses: actions/setup-node@v3
+ with:
+ node-version: '16'
+ cache: 'npm'
- name: get release version
id: release_version
diff --git a/.github/workflows/test-long-all.yml b/.github/workflows/test-long-all.yml
index 611f636..0a39a63 100644
--- a/.github/workflows/test-long-all.yml
+++ b/.github/workflows/test-long-all.yml
@@ -17,22 +17,24 @@
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
version: ['stable', 'insiders']
- go: ['1.15', '1.16', '1.17', '1.18']
+ go: ['1.16', '1.17', '1.18', '1.19']
steps:
- name: Clone repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Setup Node
- uses: actions/setup-node@v1
+ uses: actions/setup-node@v3
with:
- node-version: '14.x'
+ node-version: '16'
+ cache: 'npm'
- name: Setup Go
- uses: actions/setup-go@v2
+ uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go }}
- stable: '!contains(${{ matrix.go }}, "beta") && !contains(${{ matrix.go }}, "rc")'
+ check-latest: true
+ cache: true
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/test-long.yml b/.github/workflows/test-long.yml
index aee3b90..79b783d 100644
--- a/.github/workflows/test-long.yml
+++ b/.github/workflows/test-long.yml
@@ -16,22 +16,24 @@
matrix:
os: [ubuntu-latest, windows-latest] # TODO: reenable macos-latest
version: ['stable']
- go: ['1.15', '1.16', '1.17', '1.18']
+ go: ['1.16', '1.17', '1.18', '1.19']
steps:
- name: Clone repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Setup Node
- uses: actions/setup-node@v1
+ uses: actions/setup-node@v3
with:
- node-version: '14.x'
+ node-version: '16'
+ cache: 'npm'
- name: Setup Go
- uses: actions/setup-go@v2
+ uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go }}
- stable: '!contains(${{ matrix.go }}, "beta") && !contains(${{ matrix.go }}, "rc")'
+ check-latest: true
+ cache: true
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/test-smoke.yml b/.github/workflows/test-smoke.yml
index 1bfc8ed..2c24d20 100644
--- a/.github/workflows/test-smoke.yml
+++ b/.github/workflows/test-smoke.yml
@@ -14,22 +14,25 @@
strategy:
fail-fast: false
matrix:
- os: [ubuntu-latest]
+ os: [ubuntu-latest, windows-latest]
version: ['stable']
steps:
- name: Clone repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Setup Node
- uses: actions/setup-node@v1
+ uses: actions/setup-node@v3
with:
- node-version: '14.x'
+ node-version: '16'
+ cache: 'npm'
- name: Setup Go
- uses: actions/setup-go@v2
+ uses: actions/setup-go@v3
with:
- go-version: '1.18'
+ go-version: '1.19.0'
+ check-latest: true
+ cache: true
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/wiki.yml b/.github/workflows/wiki.yml
index d4fc608..45ed20d 100644
--- a/.github/workflows/wiki.yml
+++ b/.github/workflows/wiki.yml
@@ -6,6 +6,7 @@
branches: [ master ]
paths:
- 'docs/**'
+ - '.github/workflows/wiki.yml'
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
permissions:
@@ -32,7 +33,13 @@
repository: ${{github.repository}}.wiki
path: wiki
- name: Setup Go
- uses: actions/setup-go@v2
+ uses: actions/setup-go@v3
+ with:
+ go-version: '1.19'
+ check-latest: true
+ cache: true
+ cache-dependency-path: '**/go.sum'
+
- name: Push to wiki
run: |
cd vscode-go
diff --git a/.vscode/launch.json b/.vscode/launch.json
index ab3634d..3411a6f 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -22,7 +22,6 @@
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
],
- "stopOnEntry": false,
"sourceMaps": true,
"smartStep": true,
"preLaunchTask": "npm: bundle-dev",
@@ -33,7 +32,6 @@
{
"name": "Launch as server",
"type": "node",
- "protocol": "inspector",
"request": "launch",
"program": "${workspaceFolder}/dist/debugAdapter.js",
"args": [
@@ -64,14 +62,9 @@
"VSCODE_GO_IN_TEST": "1", // Disable code that shouldn't be used in test
"MOCHA_TIMEOUT": "999999",
},
- "stopOnEntry": false,
"sourceMaps": true,
"smartStep": true,
- "outFiles": [
- "${workspaceFolder}/out/**/*.js",
- "${workspaceFolder}/out/test/**/*.js"
- ],
- "preLaunchTask": "npm: watch"
+ "preLaunchTask": "npm: watch",
},
{
"name": "Launch Extension Tests with Gopls",
@@ -89,12 +82,7 @@
"env": {
"VSCODE_GO_IN_TEST": "1" // Disable code that shouldn't be used in test
},
- "stopOnEntry": false,
"sourceMaps": true,
- "outFiles": [
- "${workspaceFolder}/out/**/*.js",
- "${workspaceFolder}/out/test/**/*.js"
- ],
"preLaunchTask": "npm: watch",
},
{
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ea5e763..7d29819 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+## v0.35.2 - 15 Aug, 2022
+A list of all issues and changes can be found in the [v0.35.2 milestone](https://github.com/golang/vscode-go/milestone/51) and [commit history](https://github.com/golang/vscode-go/compare/v0.35.1...v0.35.2).
+
+### Changes
+
+This release includes a new [go.goroot command](https://github.com/golang/vscode-go/issues/2379), [fixes](https://github.com/golang/vscode-go/issues/2342) to the `Generate Tests` commands, and improvements for windows users.
+
+### Thanks
+
+Thank you for your contribution, @OrBin, @Ras96, @hyangah, @jamalcarvalho, and @suzmue!
+
## v0.35.1 - 19 July, 2022
A list of all issues and changes can be found in the [v0.35.1 milestone](https://github.com/golang/vscode-go/milestone/50) and [commit history](https://github.com/golang/vscode-go/compare/v0.35.0...v0.35.1).
diff --git a/README.md b/README.md
index a96896f..358dfbd 100644
--- a/README.md
+++ b/README.md
@@ -24,17 +24,22 @@
Whether you are new to Go or an experienced Go developer, we hope this
extension fits your needs and enhances your development experience.
-* **Step 1.** If you haven't done so already, install [Go](https://golang.org)
- and the [VS Code Go extension].
- * [Go installation guide]. This extension works best with Go 1.14+.
- * [Managing extensions in VS Code].
-* **Step 2.** To activate the extension, open any directory or workspace
- containing Go code. Once activated, the [Go status bar](https://github.com/golang/vscode-go/wiki/ui) will
- appear in the bottom left corner of the window and show the recognized Go
- version.
-* **Step 3.** The extension depends on [a set of extra command-line tools](#tools).
- If they are missing, the extension will show the "β οΈ Analysis Tools Missing"
- warning. Click the notification to complete the installation.
+1. Install [Go](https://golang.org) 1.14 or newer if you haven't already.
+
+1. Install the [VS Code Go extension].
+
+1. Open any directory or workspace containing Go code to automatically activate
+ the extension. The
+ [Go status bar](https://github.com/golang/vscode-go/wiki/ui) appears in the
+ bottom left corner of the window and displays your Go version.
+
+1. The extension depends on `go`, `gopls`, `dlv` and other optional tools. If
+ any of the dependencies are missing, the β οΈ `Analysis Tools Missing` warning
+ is displayed. Click on the warning to download dependencies.
+
+ See the
+ [tools documentation](https://github.com/golang/vscode-go/wiki/tools) for a
+ complete list of tools the extension depends on.
<p align="center">
<img src="docs/images/installtools.gif" width=75%>
@@ -44,23 +49,32 @@
You are ready to Go :-) πππ
-Please be sure to learn more about the many [features](#features) of this
-extension, as well as how to [customize](#customization) them. Take a look at
-[Troubleshooting](https://github.com/golang/vscode-go/wiki/troubleshooting) and [Help](#ask-for-help) for further
-guidance.
+## What's next
+
+* Explore more [features](#features) of the VS Code Go extension.
+* Learn how to [customize](#customization) your settings.
+* Solve issues with
+ [Troubleshooting](https://github.com/golang/vscode-go/wiki/troubleshooting).
+* [file an issue](https://github.com/golang/vscode-go/issues/new/choose) for
+ problems with the extension.
+* Start a [GitHub discussion](https://github.com/golang/vscode-go/discussions)
+ or get help on [Stack Overflow].
If you are new to Go, [this article](https://golang.org/doc/code.html) provides
the overview on Go code organization and basic `go` commands. Watch ["Getting
started with VS Code Go"] for an explanation of how to build your first Go
application using VS Code Go.
-## Features
+## Feature highlights
-This extension provides many features, including [IntelliSense],
-[code navigation], and [code editing] support. It also shows [diagnostics] as
-you work and provides enhanced support for [testing] and [debugging] your
-programs. See the [full feature breakdown] for more details and to learn how to
-tune its behavior.
+* [IntelliSense] - Results appear for symbols as you type.
+* [Code navigation] - Jump to or peek at a symbol's declaration.
+* [Code editing] - Support for saved snippets, formatting and code organization,
+ and automatic organization of imports.
+* [Diagnostics] - Build, vet, and lint errors shown as you type or on save.
+* Enhanced support for [testing] and [debugging]
+
+See the [full feature breakdown] for more details.
<p align=center>
<img src="docs/images/completion-signature-help.gif" width=75%>
@@ -182,8 +196,8 @@
[Go installation guide]: https://golang.org/doc/install
["Getting started with VS Code Go"]: https://youtu.be/1MXIGYrMk80
[IntelliSense]: https://github.com/golang/vscode-go/wiki/features#intellisense
-[code navigation]: https://github.com/golang/vscode-go/wiki/features#code-navigation
-[code editing]: https://github.com/golang/vscode-go/wiki/features#code-editing
+[Code navigation]: https://github.com/golang/vscode-go/wiki/features#code-navigation
+[Code editing]: https://github.com/golang/vscode-go/wiki/features#code-editing
[diagnostics]: https://github.com/golang/vscode-go/wiki/features#diagnostics
[testing]: https://github.com/golang/vscode-go/wiki/features#run-and-test-in-the-editor
[debugging]: https://github.com/golang/vscode-go/wiki/debugging#features
diff --git a/docs/commands.md b/docs/commands.md
index fede59f..b525b85 100644
--- a/docs/commands.md
+++ b/docs/commands.md
@@ -27,6 +27,10 @@
See the currently set GOPATH.
+### `Go: Current GOROOT`
+
+See the currently set GOROOT.
+
### `Go: Locate Configured Go Tools`
List all the Go tools being used by this extension along with their locations.
diff --git a/docs/debugging-legacy.md b/docs/debugging-legacy.md
index f196221..6af77db 100644
--- a/docs/debugging-legacy.md
+++ b/docs/debugging-legacy.md
@@ -143,7 +143,7 @@
### Specifying other build flags
-The flags specified in `buildFlags` and `env.GOFLAGS` are passed to the Go compiler when building your program for debugging. Delve adds `-gcflags='all=-N -l'` to the list of build flags to disable optimizations. User specified buildFlags conflict with this setting, so the extension removes them ([Issue #117](https://github.com/golang/vscode-go/issues/117)). If you wish to debug a program using custom `-gcflags`, build the program using `go build` and launch using `exec` mode:
+The flags specified in `buildFlags` and `env.GOFLAGS` are passed to the Go compiler when building your program for debugging. Delve adds `-gcflags=all="-N -l"` to the list of build flags to disable optimizations. User specified buildFlags conflict with this setting, so the extension removes them ([Issue #117](https://github.com/golang/vscode-go/issues/117)). If you wish to debug a program using custom `-gcflags`, build the program using `go build` and launch using `exec` mode:
```json
{
diff --git a/docs/debugging.md b/docs/debugging.md
index bd53164..37f5b42 100644
--- a/docs/debugging.md
+++ b/docs/debugging.md
@@ -568,7 +568,7 @@
$ dlv dap --listen=:12345
```
-Use the following `launch` configuration to tell `dlv` to execute a binary precompiled with `go build -gcflags='all=-N -l'`:
+Use the following `launch` configuration to tell `dlv` to execute a binary precompiled with `go build -gcflags=all="-N -l"`:
```json5
{
@@ -581,7 +581,7 @@
"mode": "exec",
"program": "/absolute/path/to/remote/workspace/program/executable",
"substitutePath": [
- { "from": ${workspaceFolder}, "to": "/path/to/remote/workspace" },
+ { "from": "${workspaceFolder}", "to": "/path/to/remote/workspace" },
...
]
}
@@ -655,7 +655,7 @@
### Starting a debug session fails with `decoding dwarf section info at offset 0x0: too short` or `could not open debug info` error.
-These errors indicate that your binary was built with linker flags that stripped the symbol table (`-s`) or the DWARF debug information (`-w`), making debugging impossible. If the binary is built while launching the session, make sure your `launch.json` configuration does not contain `"buildFlags": "--ldflags '-s -w'"`. If you use `debug test` or Test Explorer, check `go.buildFlags` in `settings.json`. If the binary is built externally, check the command-line flags and do not use `go run`. Unlike `go build`, `go run` passes `-s -w` to the linker under the hood. If you try to attach to such a binary with a debugger, it will fail with one of the above errors (see Go Issue [24833](https://github.com/golang/go/issues/24833)). Instead let dlv build the binary for you or use `go build -gcflags='all=-N -l'`.
+These errors indicate that your binary was built with linker flags that stripped the symbol table (`-s`) or the DWARF debug information (`-w`), making debugging impossible. If the binary is built while launching the session, make sure your `launch.json` configuration does not contain `"buildFlags": "--ldflags '-s -w'"`. If you use `debug test` or Test Explorer, check `go.buildFlags` in `settings.json`. If the binary is built externally, check the command-line flags and do not use `go run`. Unlike `go build`, `go run` passes `-s -w` to the linker under the hood. If you try to attach to such a binary with a debugger, it will fail with one of the above errors (see Go Issue [24833](https://github.com/golang/go/issues/24833)). Instead let dlv build the binary for you or use `go build -gcflags=all="-N -l"`.
## Reporting Issues
diff --git a/docs/settings.md b/docs/settings.md
index 0b0299e..c6f9975 100644
--- a/docs/settings.md
+++ b/docs/settings.md
@@ -272,85 +272,68 @@
Default: `false`
### `go.inlayHints.assignVariableTypes`
-Enable/disable inlay hints for variable types in assign statements.
+Enable/disable inlay hints for variable types in assign statements:
```go
-
-i /*int*/, j /*int*/ := 0, len(r)-1
+ i/* int*/, j/* int*/ := 0, len(r)-1
```
Default: `false`
### `go.inlayHints.compositeLiteralFields`
-Enable/disable inlay hints for composite literal field names.
+Enable/disable inlay hints for composite literal field names:
```go
-
-for _, c := range []struct {in, want string}{
- {/*in:*/ "Hello, world", /*want:*/ "dlrow ,olleH"},
- {/*in:*/ "Hello, δΈη", /*want:*/ "ηδΈ ,olleH"},
- {/*in:*/ "", /*want:*/ ""},
-} {
- ...
-}
+ {/*in: */"Hello, world", /*want: */"dlrow ,olleH"}
```
Default: `false`
### `go.inlayHints.compositeLiteralTypes`
-Enable/disable inlay hints for composite literal types.
+Enable/disable inlay hints for composite literal types:
```go
-
-for _, c := range []struct {in, want string}{
- /*struct{ in, want string }*/{"Hello, world", "dlrow ,olleH"},
- /*struct{ in, want string }*/{"Hello, δΈη", "ηδΈ ,olleH"},
- /*struct{ in, want string }*/{"", ""},
-} {
- ...
-}
+ for _, c := range []struct {
+ in, want string
+ }{
+ /*struct{ in string; want string }*/{"Hello, world", "dlrow ,olleH"},
+ }
```
Default: `false`
### `go.inlayHints.constantValues`
-Enable/disable inlay hints for constant values.
+Enable/disable inlay hints for constant values:
```go
-
-const (
- KindNone = iota /*= 0*/
- KindPrint /*= 1*/
- KindPrintf /*= 2*/
- KindErrorf /*= 3*/
-)
+ const (
+ KindNone Kind = iota/* = 0*/
+ KindPrint/* = 1*/
+ KindPrintf/* = 2*/
+ KindErrorf/* = 3*/
+ )
```
Default: `false`
### `go.inlayHints.functionTypeParameters`
-Enable/disable inlay hints for implicit type parameters on generic functions.
+Enable/disable inlay hints for implicit type parameters on generic functions:
```go
-
-func myFunc[T any](a T) { ... }
-
-func main() {
- myFunc/*[int]*/(1)
-}
+ myFoo/*[int, string]*/(1, "hello")
```
Default: `false`
### `go.inlayHints.parameterNames`
-Enable/disable inlay hints for parameter names.
+Enable/disable inlay hints for parameter names:
```go
-
-http.HandleFunc(/*pattern:*/ "/", /*handler:*/ indexHandler)
+ parseInt(/* str: */ "123", /* radix: */ 8)
```
Default: `false`
### `go.inlayHints.rangeVariableTypes`
-Enable/disable inlay hints for variable types in range statements.
+Enable/disable inlay hints for variable types in range statements:
```go
-
-for k /*int*/, v /*string*/ := range []string{} { ... }
+ for k/* int*/, v/* string*/ := range []string{} {
+ fmt.Println(k, v)
+ }
```
Default: `false`
@@ -744,6 +727,7 @@
| `gc_details` | Toggle the calculation of gc annotations. <br/> Default: `false` |
| `generate` | Runs `go generate` for a given directory. <br/> Default: `true` |
| `regenerate_cgo` | Regenerates cgo definitions. <br/> Default: `true` |
+| `run_vulncheck_exp` | Run vulnerability check (`govulncheck`). <br/> Default: `false` |
| `test` | Runs `go test` for a specific set of test or benchmark functions. <br/> Default: `false` |
| `tidy` | Runs `go mod tidy` for a module. <br/> Default: `true` |
| `upgrade_dependency` | Upgrades a dependency in the go.mod file for a module. <br/> Default: `true` |
@@ -837,12 +821,14 @@
| `stubmethods` | stub methods analyzer <br/> This analyzer generates method stubs for concrete types in order to implement a target interface <br/> Default: `true` |
| `testinggoroutine` | report calls to (*testing.T).Fatal from goroutines started by a test. <br/> Functions that abruptly terminate a test, such as the Fatal, Fatalf, FailNow, and Skip{,f,Now} methods of *testing.T, must be called from the test goroutine itself. This checker detects calls to these functions that occur within a goroutine started by the test. For example: <br/> func TestFoo(t *testing.T) { go func() { t.Fatal("oops") // error: (*T).Fatal called from non-test goroutine }() } <br/> <br/> Default: `true` |
| `tests` | check for common mistaken usages of tests and examples <br/> The tests checker walks Test, Benchmark and Example functions checking malformed names, wrong signatures and examples documenting non-existent identifiers. <br/> Please see the documentation for package testing in golang.org/pkg/testing for the conventions that are enforced for Tests, Benchmarks, and Examples. <br/> Default: `true` |
+| `timeformat` | check for calls of (time.Time).Format or time.Parse with 2006-02-01 <br/> The timeformat checker looks for time formats with the 2006-02-01 (yyyy-dd-mm) format. Internationally, "yyyy-dd-mm" does not occur in common calendar date standards, and so it is more likely that 2006-01-02 (yyyy-mm-dd) was intended. <br/> <br/> Default: `true` |
| `undeclaredname` | suggested fixes for "undeclared name: <>" <br/> This checker provides suggested fixes for type errors of the type "undeclared name: <>". It will either insert a new statement, such as: <br/> "<> := " <br/> or a new function declaration, such as: <br/> func <>(inferred parameters) { <pre>panic("implement me!")</pre>} <br/> <br/> Default: `true` |
| `unmarshal` | report passing non-pointer or non-interface values to unmarshal <br/> The unmarshal analysis reports calls to functions such as json.Unmarshal in which the argument type is not a pointer or an interface. <br/> Default: `true` |
| `unreachable` | check for unreachable code <br/> The unreachable analyzer finds statements that execution can never reach because they are preceded by an return statement, a call to panic, an infinite loop, or similar constructs. <br/> Default: `true` |
| `unsafeptr` | check for invalid conversions of uintptr to unsafe.Pointer <br/> The unsafeptr analyzer reports likely incorrect uses of unsafe.Pointer to convert integers to pointers. A conversion from uintptr to unsafe.Pointer is invalid if it implies that there is a uintptr-typed word in memory that holds a pointer value, because that word will be invisible to stack copying and to the garbage collector. <br/> Default: `true` |
| `unusedparams` | check for unused parameters of functions <br/> The unusedparams analyzer checks functions to see if there are any parameters that are not being used. <br/> To reduce false positives it ignores: - methods - parameters that do not have a name or are underscored - functions in test files - functions with empty bodies or those with just a return stmt <br/> Default: `false` |
| `unusedresult` | check for unused results of calls to some functions <br/> Some functions like fmt.Errorf return a result and have no side effects, so it is always a mistake to discard the result. This analyzer reports calls to certain functions in which the result of the call is ignored. <br/> The set of functions may be controlled using flags. <br/> Default: `true` |
+| `unusedvariable` | check for unused variables <br/> The unusedvariable analyzer suggests fixes for unused variables errors. <br/> <br/> Default: `false` |
| `unusedwrite` | checks for unused writes <br/> The analyzer reports instances of writes to struct fields and arrays that are never read. Specifically, when a struct object or an array is copied, its elements are copied implicitly by the compiler, and any element write to this copy does nothing with the original object. <br/> For example: <br/> <pre>type T struct { x int }<br/>func f(input []T) {<br/> for i, v := range input { // v is a copy<br/> v.x = i // unused write to field x<br/> }<br/>}</pre><br/> Another example is about non-pointer receiver: <br/> <pre>type T struct { x int }<br/>func (t T) f() { // t is a copy<br/> t.x = i // unused write to field x<br/>}</pre><br/> <br/> Default: `false` |
| `useany` | check for constraints that could be simplified to "any" <br/> Default: `false` |
### `ui.diagnostic.annotations`
@@ -912,6 +898,9 @@
If company chooses to use its own `godoc.org`, its address can be used as well.
+Modules matching the GOPRIVATE environment variable will not have
+documentation links in hover.
+
Default: `"pkg.go.dev"`
### `ui.documentation.linksInHover`
@@ -962,6 +951,18 @@
Default: `"Dynamic"`
+### `ui.noSemanticNumber`
+
+(Experimental) noSemanticNumber turns off the sending of the semantic token 'number'
+
+
+Default: `false`
+### `ui.noSemanticString`
+
+(Experimental) noSemanticString turns off the sending of the semantic token 'string'
+
+
+Default: `false`
### `ui.semanticTokens`
(Experimental) semanticTokens controls whether the LSP server will send
diff --git a/package-lock.json b/package-lock.json
index 347256c..bc1ce3d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "go",
- "version": "0.35.1",
+ "version": "0.35.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "go",
- "version": "0.35.0",
+ "version": "0.35.2",
"license": "MIT",
"dependencies": {
"diff": "4.0.2",
@@ -42,7 +42,6 @@
"prettier": "2.2.1",
"sinon": "9.2.4",
"ts-loader": "7.0.5",
- "tslint": "6.1.3",
"typescript": "4.6.4",
"yarn": "1.22.10"
},
@@ -838,15 +837,6 @@
"node": ">= 8"
}
},
- "node_modules/argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
- "dependencies": {
- "sprintf-js": "~1.0.2"
- }
- },
"node_modules/array-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@@ -1020,15 +1010,6 @@
"node": ">=0.2.0"
}
},
- "node_modules/builtin-modules": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
- "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -1191,12 +1172,6 @@
"node": ">= 0.8"
}
},
- "node_modules/commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
- },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -1729,19 +1704,6 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
- "node_modules/esprima": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
- "dev": true,
- "bin": {
- "esparse": "bin/esparse.js",
- "esvalidate": "bin/esvalidate.js"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/esquery": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
@@ -2609,19 +2571,6 @@
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
},
- "node_modules/js-yaml": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
- "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
- "dev": true,
- "dependencies": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
"node_modules/jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
@@ -3998,12 +3947,6 @@
"integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==",
"dev": true
},
- "node_modules/sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
- "dev": true
- },
"node_modules/sshpk": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
@@ -4283,120 +4226,6 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
},
- "node_modules/tslint": {
- "version": "6.1.3",
- "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz",
- "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==",
- "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.0.0",
- "builtin-modules": "^1.1.1",
- "chalk": "^2.3.0",
- "commander": "^2.12.1",
- "diff": "^4.0.1",
- "glob": "^7.1.1",
- "js-yaml": "^3.13.1",
- "minimatch": "^3.0.4",
- "mkdirp": "^0.5.3",
- "resolve": "^1.3.2",
- "semver": "^5.3.0",
- "tslib": "^1.13.0",
- "tsutils": "^2.29.0"
- },
- "bin": {
- "tslint": "bin/tslint"
- },
- "engines": {
- "node": ">=4.8.0"
- },
- "peerDependencies": {
- "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev"
- }
- },
- "node_modules/tslint/node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tslint/node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tslint/node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dev": true,
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/tslint/node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
- "dev": true
- },
- "node_modules/tslint/node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tslint/node_modules/semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
- "dev": true,
- "bin": {
- "semver": "bin/semver"
- }
- },
- "node_modules/tslint/node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tslint/node_modules/tsutils": {
- "version": "2.29.0",
- "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
- "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
- "dev": true,
- "dependencies": {
- "tslib": "^1.8.1"
- },
- "peerDependencies": {
- "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev"
- }
- },
"node_modules/tsutils": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
@@ -5415,15 +5244,6 @@
"picomatch": "^2.0.4"
}
},
- "argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
- "requires": {
- "sprintf-js": "~1.0.2"
- }
- },
"array-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@@ -5558,12 +5378,6 @@
"integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=",
"dev": true
},
- "builtin-modules": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
- "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
- "dev": true
- },
"callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -5682,12 +5496,6 @@
"delayed-stream": "~1.0.0"
}
},
- "commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
- },
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -6077,12 +5885,6 @@
"eslint-visitor-keys": "^3.3.0"
}
},
- "esprima": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
- "dev": true
- },
"esquery": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
@@ -6729,16 +6531,6 @@
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
},
- "js-yaml": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
- "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
- "dev": true,
- "requires": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- }
- },
"jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
@@ -7778,12 +7570,6 @@
"integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==",
"dev": true
},
- "sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
- "dev": true
- },
"sshpk": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
@@ -7996,94 +7782,6 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
},
- "tslint": {
- "version": "6.1.3",
- "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz",
- "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.0.0",
- "builtin-modules": "^1.1.1",
- "chalk": "^2.3.0",
- "commander": "^2.12.1",
- "diff": "^4.0.1",
- "glob": "^7.1.1",
- "js-yaml": "^3.13.1",
- "minimatch": "^3.0.4",
- "mkdirp": "^0.5.3",
- "resolve": "^1.3.2",
- "semver": "^5.3.0",
- "tslib": "^1.13.0",
- "tsutils": "^2.29.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
- "requires": {
- "color-convert": "^1.9.0"
- }
- },
- "chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- }
- },
- "color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dev": true,
- "requires": {
- "color-name": "1.1.3"
- }
- },
- "color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
- "dev": true
- },
- "has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
- "dev": true
- },
- "semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
- "dev": true
- },
- "supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "requires": {
- "has-flag": "^3.0.0"
- }
- },
- "tsutils": {
- "version": "2.29.0",
- "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
- "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
- "dev": true,
- "requires": {
- "tslib": "^1.8.1"
- }
- }
- }
- },
"tsutils": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
diff --git a/package.json b/package.json
index 9884ac0..15bf017 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "go",
"displayName": "Go",
- "version": "0.35.1",
+ "version": "0.35.2",
"publisher": "golang",
"description": "Rich Go language support for Visual Studio Code",
"author": {
@@ -81,12 +81,12 @@
"prettier": "2.2.1",
"sinon": "9.2.4",
"ts-loader": "7.0.5",
- "tslint": "6.1.3",
"typescript": "4.6.4",
"yarn": "1.22.10"
},
"engines": {
- "vscode": "^1.67.0"
+ "vscode": "^1.67.0",
+ "node": ">=12.0.0"
},
"activationEvents": [
"onLanguage:go",
@@ -94,6 +94,7 @@
"workspaceContains:*/*.go",
"workspaceContains:*/*/*.go",
"onCommand:go.gopath",
+ "onCommand:go.goroot",
"onCommand:go.tools.install",
"onCommand:go.locate.tools",
"onCommand:go.show.commands",
@@ -211,6 +212,11 @@
"description": "See the currently set GOPATH."
},
{
+ "command": "go.goroot",
+ "title": "Go: Current GOROOT",
+ "description": "See the currently set GOROOT."
+ },
+ {
"command": "go.locate.tools",
"title": "Go: Locate Configured Go Tools",
"description": "List all the Go tools being used by this extension along with their locations."
@@ -2042,41 +2048,6 @@
"scope": "resource",
"type": "boolean"
},
- "go.inlayHints.assignVariableTypes": {
- "type": "boolean",
- "markdownDescription": "Enable/disable inlay hints for variable types in assign statements.\n```go\n\ni /*int*/, j /*int*/ := 0, len(r)-1\n```",
- "default": false
- },
- "go.inlayHints.compositeLiteralFields": {
- "type": "boolean",
- "markdownDescription": "Enable/disable inlay hints for composite literal field names.\n```go\n\nfor _, c := range []struct {in, want string}{\n\t{/*in:*/ \"Hello, world\", /*want:*/ \"dlrow ,olleH\"},\n\t{/*in:*/ \"Hello, δΈη\", /*want:*/ \"ηδΈ ,olleH\"},\n\t{/*in:*/ \"\", /*want:*/ \"\"},\n} {\n\t...\n}\n```",
- "default": false
- },
- "go.inlayHints.compositeLiteralTypes": {
- "type": "boolean",
- "markdownDescription": "Enable/disable inlay hints for composite literal types.\n```go\n\nfor _, c := range []struct {in, want string}{\n\t/*struct{ in, want string }*/{\"Hello, world\", \"dlrow ,olleH\"},\n\t/*struct{ in, want string }*/{\"Hello, δΈη\", \"ηδΈ ,olleH\"},\n\t/*struct{ in, want string }*/{\"\", \"\"},\n} {\n\t...\n}\n```",
- "default": false
- },
- "go.inlayHints.constantValues": {
- "type": "boolean",
- "markdownDescription": "Enable/disable inlay hints for constant values.\n```go\n\nconst (\n\tKindNone = iota\t/*= 0*/\n\tKindPrint\t/*= 1*/\n\tKindPrintf\t/*= 2*/\n\tKindErrorf\t/*= 3*/\n)\n```",
- "default": false
- },
- "go.inlayHints.functionTypeParameters": {
- "type": "boolean",
- "markdownDescription": "Enable/disable inlay hints for implicit type parameters on generic functions.\n```go\n\nfunc myFunc[T any](a T) { ... }\n\nfunc main() {\n\tmyFunc/*[int]*/(1)\n}\n```",
- "default": false
- },
- "go.inlayHints.parameterNames": {
- "type": "boolean",
- "markdownDescription": "Enable/disable inlay hints for parameter names.\n```go\n\nhttp.HandleFunc(/*pattern:*/ \"/\", /*handler:*/ indexHandler)\n```",
- "default": false
- },
- "go.inlayHints.rangeVariableTypes": {
- "type": "boolean",
- "markdownDescription": "Enable/disable inlay hints for variable types in range statements.\n```go\n\nfor k /*int*/, v /*string*/ := range []string{} { ... }\n```",
- "default": false
- },
"gopls": {
"type": "object",
"markdownDescription": "Configure the default Go language server ('gopls'). In most cases, configuring this section is unnecessary. See [the documentation](https://github.com/golang/tools/blob/master/gopls/doc/settings.md) for all available settings.",
@@ -2189,6 +2160,11 @@
"markdownDescription": "Regenerates cgo definitions.",
"default": true
},
+ "run_vulncheck_exp": {
+ "type": "boolean",
+ "markdownDescription": "Run vulnerability check (`govulncheck`).",
+ "default": false
+ },
"test": {
"type": "boolean",
"markdownDescription": "Runs `go test` for a specific set of test or benchmark functions.",
@@ -2435,6 +2411,11 @@
"markdownDescription": "check for common mistaken usages of tests and examples\n\nThe tests checker walks Test, Benchmark and Example functions checking\nmalformed names, wrong signatures and examples documenting non-existent\nidentifiers.\n\nPlease see the documentation for package testing in golang.org/pkg/testing\nfor the conventions that are enforced for Tests, Benchmarks, and Examples.",
"default": true
},
+ "timeformat": {
+ "type": "boolean",
+ "markdownDescription": "check for calls of (time.Time).Format or time.Parse with 2006-02-01\n\nThe timeformat checker looks for time formats with the 2006-02-01 (yyyy-dd-mm)\nformat. Internationally, \"yyyy-dd-mm\" does not occur in common calendar date\nstandards, and so it is more likely that 2006-01-02 (yyyy-mm-dd) was intended.\n",
+ "default": true
+ },
"undeclaredname": {
"type": "boolean",
"markdownDescription": "suggested fixes for \"undeclared name: <>\"\n\nThis checker provides suggested fixes for type errors of the\ntype \"undeclared name: <>\". It will either insert a new statement,\nsuch as:\n\n\"<> := \"\n\nor a new function declaration, such as:\n\nfunc <>(inferred parameters) {\n\tpanic(\"implement me!\")\n}\n",
@@ -2465,6 +2446,11 @@
"markdownDescription": "check for unused results of calls to some functions\n\nSome functions like fmt.Errorf return a result and have no side effects,\nso it is always a mistake to discard the result. This analyzer reports\ncalls to certain functions in which the result of the call is ignored.\n\nThe set of functions may be controlled using flags.",
"default": true
},
+ "unusedvariable": {
+ "type": "boolean",
+ "markdownDescription": "check for unused variables\n\nThe unusedvariable analyzer suggests fixes for unused variables errors.\n",
+ "default": false
+ },
"unusedwrite": {
"type": "boolean",
"markdownDescription": "checks for unused writes\n\nThe analyzer reports instances of writes to struct fields and\narrays that are never read. Specifically, when a struct object\nor an array is copied, its elements are copied implicitly by\nthe compiler, and any element write to this copy does nothing\nwith the original object.\n\nFor example:\n\n\ttype T struct { x int }\n\tfunc f(input []T) {\n\t\tfor i, v := range input { // v is a copy\n\t\t\tv.x = i // unused write to field x\n\t\t}\n\t}\n\nAnother example is about non-pointer receiver:\n\n\ttype T struct { x int }\n\tfunc (t T) f() { // t is a copy\n\t\tt.x = i // unused write to field x\n\t}\n",
@@ -2544,7 +2530,7 @@
},
"ui.documentation.linkTarget": {
"type": "string",
- "markdownDescription": "linkTarget controls where documentation links go.\nIt might be one of:\n\n* `\"godoc.org\"`\n* `\"pkg.go.dev\"`\n\nIf company chooses to use its own `godoc.org`, its address can be used as well.\n",
+ "markdownDescription": "linkTarget controls where documentation links go.\nIt might be one of:\n\n* `\"godoc.org\"`\n* `\"pkg.go.dev\"`\n\nIf company chooses to use its own `godoc.org`, its address can be used as well.\n\nModules matching the GOPRIVATE environment variable will not have\ndocumentation links in hover.\n",
"default": "pkg.go.dev",
"scope": "resource"
},
@@ -2604,6 +2590,18 @@
"default": "Dynamic",
"scope": "resource"
},
+ "ui.noSemanticNumber": {
+ "type": "boolean",
+ "markdownDescription": "(Experimental) noSemanticNumber turns off the sending of the semantic token 'number'\n",
+ "default": false,
+ "scope": "resource"
+ },
+ "ui.noSemanticString": {
+ "type": "boolean",
+ "markdownDescription": "(Experimental) noSemanticString turns off the sending of the semantic token 'string'\n",
+ "default": false,
+ "scope": "resource"
+ },
"ui.semanticTokens": {
"type": "boolean",
"markdownDescription": "(Experimental) semanticTokens controls whether the LSP server will send\nsemantic tokens to the client.\n",
@@ -2617,6 +2615,41 @@
"scope": "resource"
}
}
+ },
+ "go.inlayHints.assignVariableTypes": {
+ "type": "boolean",
+ "markdownDescription": "Enable/disable inlay hints for variable types in assign statements:\n```go\n\ti/* int*/, j/* int*/ := 0, len(r)-1\n```",
+ "default": false
+ },
+ "go.inlayHints.compositeLiteralFields": {
+ "type": "boolean",
+ "markdownDescription": "Enable/disable inlay hints for composite literal field names:\n```go\n\t{/*in: */\"Hello, world\", /*want: */\"dlrow ,olleH\"}\n```",
+ "default": false
+ },
+ "go.inlayHints.compositeLiteralTypes": {
+ "type": "boolean",
+ "markdownDescription": "Enable/disable inlay hints for composite literal types:\n```go\n\tfor _, c := range []struct {\n\t\tin, want string\n\t}{\n\t\t/*struct{ in string; want string }*/{\"Hello, world\", \"dlrow ,olleH\"},\n\t}\n```",
+ "default": false
+ },
+ "go.inlayHints.constantValues": {
+ "type": "boolean",
+ "markdownDescription": "Enable/disable inlay hints for constant values:\n```go\n\tconst (\n\t\tKindNone Kind = iota/* = 0*/\n\t\tKindPrint/* = 1*/\n\t\tKindPrintf/* = 2*/\n\t\tKindErrorf/* = 3*/\n\t)\n```",
+ "default": false
+ },
+ "go.inlayHints.functionTypeParameters": {
+ "type": "boolean",
+ "markdownDescription": "Enable/disable inlay hints for implicit type parameters on generic functions:\n```go\n\tmyFoo/*[int, string]*/(1, \"hello\")\n```",
+ "default": false
+ },
+ "go.inlayHints.parameterNames": {
+ "type": "boolean",
+ "markdownDescription": "Enable/disable inlay hints for parameter names:\n```go\n\tparseInt(/* str: */ \"123\", /* radix: */ 8)\n```",
+ "default": false
+ },
+ "go.inlayHints.rangeVariableTypes": {
+ "type": "boolean",
+ "markdownDescription": "Enable/disable inlay hints for variable types in range statements:\n```go\n\tfor k/* int*/, v/* string*/ := range []string{} {\n\t\tfmt.Println(k, v)\n\t}\n```",
+ "default": false
}
}
},
diff --git a/src/commands/getCurrentGoRoot.ts b/src/commands/getCurrentGoRoot.ts
new file mode 100644
index 0000000..cd0a5af
--- /dev/null
+++ b/src/commands/getCurrentGoRoot.ts
@@ -0,0 +1,18 @@
+/*---------------------------------------------------------
+ * Copyright 2022 The Go Authors. All rights reserved.
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
+ *--------------------------------------------------------*/
+
+import * as vscode from 'vscode';
+
+import { CommandFactory } from '.';
+import { getCurrentGoRoot as utilGetCurrentGoRoot } from '../utils/pathUtils';
+
+export const getCurrentGoRoot: CommandFactory = () => {
+ return () => {
+ const goroot = utilGetCurrentGoRoot();
+ const msg = `${goroot} is the current GOROOT.`;
+ vscode.window.showInformationMessage(msg);
+ return goroot;
+ };
+};
diff --git a/src/commands/index.ts b/src/commands/index.ts
index d82ba4a..d15dffc 100644
--- a/src/commands/index.ts
+++ b/src/commands/index.ts
@@ -10,6 +10,7 @@
export { applyCoverprofile } from './applyCoverprofile';
export { getConfiguredGoTools } from './getConfiguredGoTools';
export { getCurrentGoPath } from './getCurrentGoPath';
+export { getCurrentGoRoot } from './getCurrentGoRoot';
export { extractFunction, extractVariable } from '../goDoctor';
export { runFillStruct } from '../goFillStruct';
export { implCursor } from '../goImpl';
diff --git a/src/goGenerateTests.ts b/src/goGenerateTests.ts
index eb67da3..12e0e42 100644
--- a/src/goGenerateTests.ts
+++ b/src/goGenerateTests.ts
@@ -16,7 +16,7 @@
import { promptForMissingTool } from './goInstallTools';
import { GoDocumentSymbolProvider } from './goDocumentSymbols';
import { outputChannel } from './goStatus';
-import { getBinPath } from './util';
+import { getBinPath, resolvePath } from './util';
import { CommandFactory } from './commands';
import { GoExtensionContext } from './context';
@@ -178,6 +178,12 @@
i++;
continue;
}
+ if (i + 1 < goGenerateTestsFlags.length && (flag === '-template_dir' || flag === '-template_params_file')) {
+ const configFilePath = resolvePath(goGenerateTestsFlags[i + 1]);
+ args.push(flag, configFilePath);
+ i++;
+ continue;
+ }
args.push(flag);
}
diff --git a/src/goMain.ts b/src/goMain.ts
index db31bbb..a525684 100644
--- a/src/goMain.ts
+++ b/src/goMain.ts
@@ -136,6 +136,7 @@
ctx.subscriptions.push(goCtx.vetDiagnosticCollection);
registerCommand('go.gopath', commands.getCurrentGoPath);
+ registerCommand('go.goroot', commands.getCurrentGoRoot);
registerCommand('go.locate.tools', commands.getConfiguredGoTools);
registerCommand('go.add.tags', commands.addTags);
registerCommand('go.remove.tags', commands.removeTags);
diff --git a/src/goModules.ts b/src/goModules.ts
index 9d3f39d..6305caf 100644
--- a/src/goModules.ts
+++ b/src/goModules.ts
@@ -48,8 +48,12 @@
return getModFolderPath(fileuri, isDir).then((modPath) => !!modPath);
}
+// packagePathToGoModPathMap is a cache that maps from a file path (of a package directory)
+// to the module root directory path (directory of `go env GOMOD`) if the file belongs to a module.
export const packagePathToGoModPathMap: { [key: string]: string } = {};
+// getModFolderPath returns the module root of the file. '' or undefined value indicates
+// the file is outside of any module or Go module is disabled.
export async function getModFolderPath(fileuri?: vscode.Uri, isDir?: boolean): Promise<string | undefined> {
const pkgUri = isDir ? fileuri : fileuri && vscodeUri.Utils.dirname(fileuri);
const pkgPath = pkgUri?.fsPath ?? '';
diff --git a/src/goTest/resolve.ts b/src/goTest/resolve.ts
index b096657..2b4d93c 100644
--- a/src/goTest/resolve.ts
+++ b/src/goTest/resolve.ts
@@ -328,12 +328,16 @@
}
if (nested) {
- const bits = parent.uri ? path.relative(parent.uri.path, uri.path).split(path.sep) : [];
+ const bits = parent.uri ? path.relative(parent.uri.fsPath, uri.fsPath).split(path.sep) : [];
while (bits.length > 1) {
if (!parent.uri?.path) continue;
const dir = bits.shift();
if (!dir) continue;
- const dirUri = uri.with({ path: path.join(parent.uri.path, dir), query: '', fragment: '' });
+ const dirUri = uri.with({
+ path: Uri.file(path.join(parent.uri.fsPath, dir)).path,
+ query: '',
+ fragment: ''
+ });
parent = this.getOrCreateItem(parent, dir, dirUri, 'package');
}
}
diff --git a/src/goToolsInformation.ts b/src/goToolsInformation.ts
index 4a009c4..bdb617b 100644
--- a/src/goToolsInformation.ts
+++ b/src/goToolsInformation.ts
@@ -195,10 +195,10 @@
description: 'Language Server from Google',
usePrereleaseInPreviewMode: true,
minimumGoVersion: semver.coerce('1.13'),
- latestVersion: semver.parse('v0.9.1'),
- latestVersionTimestamp: moment('2022-07-13', 'YYYY-MM-DD'),
- latestPrereleaseVersion: semver.parse('v0.9.1'),
- latestPrereleaseVersionTimestamp: moment('2022-07-13', 'YYYY-MM-DD')
+ latestVersion: semver.parse('v0.9.3'),
+ latestVersionTimestamp: moment('2022-08-11', 'YYYY-MM-DD'),
+ latestPrereleaseVersion: semver.parse('v0.9.3'),
+ latestPrereleaseVersionTimestamp: moment('2022-08-11', 'YYYY-MM-DD')
},
'dlv': {
name: 'dlv',
diff --git a/test/gopls/vulncheck.test.ts b/test/gopls/vulncheck.test.ts
index 70a622f..2706b66 100644
--- a/test/gopls/vulncheck.test.ts
+++ b/test/gopls/vulncheck.test.ts
@@ -29,44 +29,60 @@
vscode.Disposable.from(...disposables).dispose();
});
- test('populates webview', async function () {
- this.timeout(5000);
- const webviewPanel = _register(
- vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, {})
- );
- const source = path.join(fixtureDir, 'test.vulncheck.json');
- const doc = await vscode.workspace.openTextDocument(source);
- const canceller = new vscode.CancellationTokenSource();
- _register(canceller);
+ test('populates webview', async () => {
+ const doTest = async (tag: string) => {
+ const webviewPanel = _register(
+ vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, {})
+ );
+ const source = path.join(fixtureDir, 'test.vulncheck.json');
+ const doc = await vscode.workspace.openTextDocument(source);
+ console.timeLog(tag, 'opened document');
+ const canceller = new vscode.CancellationTokenSource();
+ _register(canceller);
- const watcher = getMessage<{ type: string; target?: string }>(webviewPanel);
+ const watcher = getMessage<{ type: string; target?: string }>(webviewPanel);
- await provider.resolveCustomTextEditor(doc, webviewPanel, canceller.token);
- webviewPanel.reveal();
+ await provider.resolveCustomTextEditor(doc, webviewPanel, canceller.token);
+ console.timeLog(tag, 'resolved custom text editor');
- // Trigger snapshotContent that sends `snapshot-result` as a result.
- webviewPanel.webview.postMessage({ type: 'snapshot-request' });
- const res = await watcher;
+ webviewPanel.reveal();
- assert.deepStrictEqual(res.type, 'snapshot-result', `want snapshot-result, got ${JSON.stringify(res)}`);
- // res.target type is defined in vulncheckView.js.
- const { log = '', vulns = '', unaffecting = '' } = JSON.parse(res.target ?? '{}');
+ // Trigger snapshotContent that sends `snapshot-result` as a result.
+ webviewPanel.webview.postMessage({ type: 'snapshot-request' });
+ console.timeLog(tag, 'posted snapshot-request');
- assert(
- log.includes('Found 1 known vulnerabilities'),
- `expected "1 known vulnerabilities", got ${JSON.stringify(res.target)}`
- );
- assert(
- vulns.includes('GO-2021-0113') &&
- vulns.includes('<td>Affecting</td><td>github.com/golang/vscode-go/test/testdata/vuln</td>'),
- `expected "Affecting" section, got ${JSON.stringify(res.target)}`
- );
- // Unaffecting vulnerability's detail is omitted, but its ID is reported.
- assert(
- unaffecting.includes('GO-2021-0000') && unaffecting.includes('golang.org/x/text'),
- `expected reports about unaffecting vulns, got ${JSON.stringify(res.target)}`
- );
- });
+ const res = await watcher;
+ console.timeLog(tag, 'received message');
+
+ assert.deepStrictEqual(res.type, 'snapshot-result', `want snapshot-result, got ${JSON.stringify(res)}`);
+ // res.target type is defined in vulncheckView.js.
+ const { log = '', vulns = '', unaffecting = '' } = JSON.parse(res.target ?? '{}');
+
+ assert(
+ log.includes('Found 1 known vulnerabilities'),
+ `expected "1 known vulnerabilities", got ${JSON.stringify(res.target)}`
+ );
+ assert(
+ vulns.includes('GO-2021-0113') &&
+ vulns.includes('<td>Affecting</td><td>github.com/golang/vscode-go/test/testdata/vuln</td>'),
+ `expected "Affecting" section, got ${JSON.stringify(res.target)}`
+ );
+ // Unaffecting vulnerability's detail is omitted, but its ID is reported.
+ assert(
+ unaffecting.includes('GO-2021-0000') && unaffecting.includes('golang.org/x/text'),
+ `expected reports about unaffecting vulns, got ${JSON.stringify(res.target)}`
+ );
+ };
+ try {
+ console.time('populates-webview');
+ await doTest('populates-webview');
+ } catch (e) {
+ console.timeLog('populates-webview', `error thrown: ${e}`);
+ throw e;
+ } finally {
+ console.timeEnd('populates-webview');
+ }
+ }).timeout(5_000);
test('handles empty input', async () => {
const webviewPanel = _register(
diff --git a/test/integration/extension.test.ts b/test/integration/extension.test.ts
index 6446c55..d155347 100644
--- a/test/integration/extension.test.ts
+++ b/test/integration/extension.test.ts
@@ -46,6 +46,7 @@
import cp = require('child_process');
import os = require('os');
import { MockExtensionContext } from '../mocks/MockContext';
+import { affectedByIssue832 } from './testutils';
const testAll = (isModuleMode: boolean) => {
const dummyCancellationSource = new vscode.CancellationTokenSource();
@@ -151,7 +152,7 @@
const uri = vscode.Uri.file(path.join(fixturePath, 'gogetdocTestData', 'test.go'));
const textDocument = await vscode.workspace.openTextDocument(uri);
- const promises = testCases.map(([position, expected, expectedDoc, expectedParams]) =>
+ const promises = testCases.map(([position, expected, expectedDocPrefix, expectedParams]) =>
provider.provideSignatureHelp(textDocument, position, dummyCancellationSource.token).then((sigHelp) => {
assert.ok(
sigHelp,
@@ -159,7 +160,10 @@
);
assert.equal(sigHelp.signatures.length, 1, 'unexpected number of overloads');
assert.equal(sigHelp.signatures[0].label, expected);
- assert.equal(sigHelp.signatures[0].documentation, expectedDoc);
+ assert(
+ sigHelp.signatures[0].documentation?.toString().startsWith(expectedDocPrefix),
+ `expected doc starting with ${expectedDocPrefix}, got ${JSON.stringify(sigHelp.signatures[0])}`
+ );
assert.equal(sigHelp.signatures[0].parameters.length, expectedParams.length);
for (let i = 0; i < expectedParams.length; i++) {
assert.equal(sigHelp.signatures[0].parameters[i].label, expectedParams[i]);
@@ -189,7 +193,10 @@
}
assert(res);
assert.equal(res.contents.length, 1);
- assert.equal((<vscode.MarkdownString>res.contents[0]).value, expectedHover);
+ assert(
+ (<vscode.MarkdownString>res.contents[0]).value.startsWith(expectedHover),
+ `expected hover starting with ${expectedHover}, got ${JSON.stringify(res.contents[0])}`
+ );
})
);
return Promise.all(promises);
@@ -226,11 +233,7 @@
this.skip();
} // not working in module mode
- const printlnDoc = `Println formats using the default formats for its operands and writes to
-standard output. Spaces are always added between operands and a newline is
-appended. It returns the number of bytes written and any write error
-encountered.
-`;
+ const printlnDocPrefix = 'Println formats using the default formats for its operands and writes';
const printlnSig = goVersion.lt('1.18')
? 'Println(a ...interface{}) (n int, err error)'
: 'Println(a ...any) (n int, err error)';
@@ -239,7 +242,7 @@
[
new vscode.Position(19, 13),
printlnSig,
- printlnDoc,
+ printlnDocPrefix,
[goVersion.lt('1.18') ? 'a ...interface{}' : 'a ...any']
],
[
@@ -277,10 +280,7 @@
return;
}
- const printlnDoc = `Println formats using the default formats for its operands and writes to standard output.
-Spaces are always added between operands and a newline is appended.
-It returns the number of bytes written and any write error encountered.
-`;
+ const printlnDocPrefix = 'Println formats using the default formats for its operands and writes';
const printlnSig = goVersion.lt('1.18')
? 'Println(a ...interface{}) (n int, err error)'
: 'Println(a ...any) (n int, err error)';
@@ -289,7 +289,7 @@
[
new vscode.Position(19, 13),
printlnSig,
- printlnDoc,
+ printlnDocPrefix,
[goVersion.lt('1.18') ? 'a ...interface{}' : 'a ...any']
],
[
@@ -322,11 +322,7 @@
this.skip();
} // not working in module mode
- const printlnDoc = `Println formats using the default formats for its operands and writes to
-standard output. Spaces are always added between operands and a newline is
-appended. It returns the number of bytes written and any write error
-encountered.
-`;
+ const printlnDocPrefix = 'Println formats using the default formats for its operands and writes';
const printlnSig = goVersion.lt('1.18')
? 'Println func(a ...interface{}) (n int, err error)'
: 'Println func(a ...any) (n int, err error)';
@@ -339,7 +335,7 @@
[new vscode.Position(28, 16), null, null], // inside a number
[new vscode.Position(22, 5), 'main func()', '\n'],
[new vscode.Position(40, 23), 'import (math "math")', null],
- [new vscode.Position(19, 6), printlnSig, printlnDoc],
+ [new vscode.Position(19, 6), printlnSig, printlnDocPrefix],
[
new vscode.Position(23, 4),
'print func(txt string)',
@@ -363,10 +359,7 @@
return;
}
- const printlnDoc = `Println formats using the default formats for its operands and writes to standard output.
-Spaces are always added between operands and a newline is appended.
-It returns the number of bytes written and any write error encountered.
-`;
+ const printlnDocPrefix = 'Println formats using the default formats for its operands and writes';
const printlnSig = goVersion.lt('1.18')
? 'func Println(a ...interface{}) (n int, err error)'
: 'func Println(a ...any) (n int, err error)';
@@ -387,7 +380,7 @@
'package math',
'Package math provides basic constants and mathematical functions.\n\nThis package does not guarantee bit-identical results across architectures.\n'
],
- [new vscode.Position(19, 6), printlnSig, printlnDoc],
+ [new vscode.Position(19, 6), printlnSig, printlnDocPrefix],
[
new vscode.Position(27, 14),
'type ABC struct {\n a int\n b int\n c int\n}',
@@ -435,40 +428,45 @@
});
test('Linting - lint errors with multiple open files', async () => {
- // handleDiagnosticErrors may adjust the lint errors' ranges to make the error more visible.
- // This adjustment applies only to the text documents known to vscode. This test checks
- // the adjustment is made consistently across multiple open text documents.
- const file1 = await vscode.workspace.openTextDocument(
- vscode.Uri.file(path.join(fixturePath, 'linterTest', 'linter_1.go'))
- );
- const file2 = await vscode.workspace.openTextDocument(
- vscode.Uri.file(path.join(fixturePath, 'linterTest', 'linter_2.go'))
- );
- const warnings = await goLint(
- file2.uri,
- Object.create(getGoConfig(), {
- lintTool: { value: 'staticcheck' },
- lintFlags: { value: ['-checks', 'all,-ST1000,-ST1016'] }
- // staticcheck skips debatable checks such as ST1003 by default,
- // but this test depends on ST1003 (MixedCaps package name) presented in both files
- // in the same package. So, enable that.
- }),
- Object.create(getGoplsConfig(), {}),
- 'package'
- );
+ try {
+ // handleDiagnosticErrors may adjust the lint errors' ranges to make the error more visible.
+ // This adjustment applies only to the text documents known to vscode. This test checks
+ // the adjustment is made consistently across multiple open text documents.
+ const file1 = await vscode.workspace.openTextDocument(
+ vscode.Uri.file(path.join(fixturePath, 'linterTest', 'linter_1.go'))
+ );
+ const file2 = await vscode.workspace.openTextDocument(
+ vscode.Uri.file(path.join(fixturePath, 'linterTest', 'linter_2.go'))
+ );
+ console.log('start linting');
+ const warnings = await goLint(
+ file2.uri,
+ Object.create(getGoConfig(), {
+ lintTool: { value: 'staticcheck' },
+ lintFlags: { value: ['-checks', 'all,-ST1000,-ST1016'] }
+ // staticcheck skips debatable checks such as ST1003 by default,
+ // but this test depends on ST1003 (MixedCaps package name) presented in both files
+ // in the same package. So, enable that.
+ }),
+ Object.create(getGoplsConfig(), {}),
+ 'package'
+ );
- const diagnosticCollection = vscode.languages.createDiagnosticCollection('linttest');
- handleDiagnosticErrors({}, file2, warnings, diagnosticCollection);
+ const diagnosticCollection = vscode.languages.createDiagnosticCollection('linttest');
+ handleDiagnosticErrors({}, file2, warnings, diagnosticCollection);
- // The first diagnostic message for each file should be about the use of MixedCaps in package name.
- // Both files belong to the same package name, and we want them to be identical.
- const file1Diagnostics = diagnosticCollection.get(file1.uri);
- const file2Diagnostics = diagnosticCollection.get(file2.uri);
- assert(file1Diagnostics);
- assert(file2Diagnostics);
- assert(file1Diagnostics.length > 0);
- assert(file2Diagnostics.length > 0);
- assert.deepStrictEqual(file1Diagnostics[0], file2Diagnostics[0]);
+ // The first diagnostic message for each file should be about the use of MixedCaps in package name.
+ // Both files belong to the same package name, and we want them to be identical.
+ const file1Diagnostics = diagnosticCollection.get(file1.uri);
+ const file2Diagnostics = diagnosticCollection.get(file2.uri);
+ assert(file1Diagnostics);
+ assert(file2Diagnostics);
+ assert(file1Diagnostics.length > 0);
+ assert(file2Diagnostics.length > 0);
+ assert.deepStrictEqual(file1Diagnostics[0], file2Diagnostics[0]);
+ } catch (e) {
+ assert.fail(`failed to lint: ${e}`);
+ }
});
test('Error checking', async () => {
@@ -741,7 +739,10 @@
assert.equal(interfaces[0].name, 'circle');
});
- test('Test listPackages', async () => {
+ test('Test listPackages', async function () {
+ if (affectedByIssue832()) {
+ this.skip(); // timeout on windows
+ }
const uri = vscode.Uri.file(path.join(fixturePath, 'baseTest', 'test.go'));
const document = await vscode.workspace.openTextDocument(uri);
await vscode.window.showTextDocument(document);
@@ -793,7 +794,10 @@
});
});
- test('Workspace Symbols', () => {
+ test('Workspace Symbols', function () {
+ if (affectedByIssue832()) {
+ this.skip(); // frequent timeout on windows
+ }
const workspacePath = path.join(fixturePath, 'vendoring');
const configWithoutIgnoringFolders = Object.create(getGoConfig(), {
gotoSymbol: {
@@ -861,12 +865,12 @@
return Promise.all([withIgnoringFolders, withoutIgnoringFolders, withIncludingGoroot, withoutIncludingGoroot]);
});
- test('Test Completion', async () => {
- const printlnDoc = `Println formats using the default formats for its operands and writes to
-standard output. Spaces are always added between operands and a newline is
-appended. It returns the number of bytes written and any write error
-encountered.
-`;
+ test('Test Completion', async function () {
+ if (affectedByIssue832()) {
+ this.skip(); // timeout on windows
+ }
+
+ const printlnDocPrefix = 'Println formats using the default formats for its operands';
const printlnSig = goVersion.lt('1.18')
? 'func(a ...interface{}) (n int, err error)'
: 'func(a ...any) (n int, err error)';
@@ -874,7 +878,7 @@
const provider = new GoCompletionItemProvider();
const testCases: [vscode.Position, string, string | null, string | null][] = [
[new vscode.Position(7, 4), 'fmt', 'fmt', null],
- [new vscode.Position(7, 6), 'Println', printlnSig, printlnDoc]
+ [new vscode.Position(7, 6), 'Println', printlnSig, printlnDocPrefix]
];
const uri = vscode.Uri.file(path.join(fixturePath, 'baseTest', 'test.go'));
const textDocument = await vscode.workspace.openTextDocument(uri);
@@ -896,22 +900,30 @@
if (!resolvedItemResult) {
return;
}
- if (resolvedItemResult instanceof vscode.CompletionItem) {
- if (resolvedItemResult.documentation) {
- assert.equal((<vscode.MarkdownString>resolvedItemResult.documentation).value, expectedDoc);
+ const resolvedItem =
+ resolvedItemResult instanceof vscode.CompletionItem
+ ? resolvedItemResult
+ : await resolvedItemResult;
+ if (resolvedItem?.documentation) {
+ const got = (<vscode.MarkdownString>resolvedItem.documentation).value;
+ if (expectedDoc) {
+ assert(
+ got.startsWith(expectedDoc),
+ `expected doc starting with ${expectedDoc}, got ${got}`
+ );
+ } else {
+ assert.equal(got, expectedDoc);
}
- return;
- }
- const resolvedItem = await resolvedItemResult;
- if (resolvedItem) {
- assert.equal((<vscode.MarkdownString>resolvedItem.documentation).value, expectedDoc);
}
})
);
await Promise.all(promises);
});
- test('Test Completion Snippets For Functions', async () => {
+ test('Test Completion Snippets For Functions', async function () {
+ if (affectedByIssue832()) {
+ this.skip(); // timeout on windows
+ }
const provider = new GoCompletionItemProvider();
const uri = vscode.Uri.file(path.join(fixturePath, 'completions', 'snippets.go'));
const baseConfig = getGoConfig();
@@ -1109,6 +1121,9 @@
});
test('Test No Completion Snippets For Functions', async () => {
+ if (affectedByIssue832()) {
+ return;
+ }
const provider = new GoCompletionItemProvider();
const uri = vscode.Uri.file(path.join(fixturePath, 'completions', 'nosnippets.go'));
const baseConfig = getGoConfig();
@@ -1176,7 +1191,7 @@
});
test('Test Completion on unimported packages', async function () {
- if (isModuleMode) {
+ if (isModuleMode || affectedByIssue832()) {
this.skip();
}
// gocode-gomod does not handle unimported package completion.
@@ -1212,7 +1227,10 @@
await Promise.all(promises);
});
- test('Test Completion on unimported packages (multiple)', async () => {
+ test('Test Completion on unimported packages (multiple)', async function () {
+ if (affectedByIssue832()) {
+ this.skip();
+ }
const config = Object.create(getGoConfig(), {
gocodeFlags: { value: ['-builtin'] }
});
diff --git a/test/integration/goDebug.test.ts b/test/integration/goDebug.test.ts
index 471db8b..1a6ac4b 100644
--- a/test/integration/goDebug.test.ts
+++ b/test/integration/goDebug.test.ts
@@ -32,6 +32,7 @@
import getPort = require('get-port');
import util = require('util');
import { TimestampedLogger } from '../../src/goLogging';
+import { affectedByIssue832 } from './testutils';
// For debugging test and streaming the trace instead of buffering, set this.
const PRINT_TO_CONSOLE = false;
@@ -412,14 +413,45 @@
if (continueOnStart) {
args.push('--continue');
}
- const childProcess = cp.spawn(toolPath, args, {
- cwd: serverFolder,
- env: { PORT: `${serverPort}`, ...process.env }
- });
- // Give dlv a few seconds to start.
- await new Promise((resolve) => setTimeout(resolve, 10_000));
- return childProcess;
+ const promise = new Promise<cp.ChildProcess>((resolve, reject) => {
+ const p = cp.spawn(toolPath, args, {
+ cwd: serverFolder,
+ env: { PORT: `${serverPort}`, ...process.env }
+ });
+
+ let started = false;
+ const timeoutToken: NodeJS.Timer = setTimeout(() => {
+ console.log(`dlv debug server (PID: ${p.pid}) is not responding`);
+ reject(new Error('timed out while waiting for DAP server to start'));
+ }, 30_000);
+
+ const stopWaitingForServerToStart = () => {
+ clearTimeout(timeoutToken);
+ started = true;
+ resolve(p);
+ };
+
+ if (continueOnStart) {
+ // wait till helloWorldServer starts and prints its log message to STDERR.
+ p.stderr.on('data', (chunk) => {
+ const msg = chunk.toString();
+ if (!started && msg.includes('helloWorldServer starting to listen on')) {
+ stopWaitingForServerToStart();
+ }
+ console.log(msg);
+ });
+ } else {
+ p.stdout.on('data', (chunk) => {
+ const msg = chunk.toString();
+ if (!started && msg.includes('listening at:')) {
+ stopWaitingForServerToStart();
+ }
+ console.log(msg);
+ });
+ }
+ });
+ return promise;
}
/**
@@ -438,7 +470,9 @@
// an initialized event.
await Promise.all([
new Promise<void>(async (resolve) => {
- console.log(`Setting up attach request for ${JSON.stringify(debugConfig)}.`);
+ const debugConfigCopy = Object.assign({}, debugConfig);
+ delete debugConfigCopy.env;
+ console.log(`Setting up attach request for ${JSON.stringify(debugConfigCopy)}.`);
const attachResult = await dc.attachRequest(debugConfig as DebugProtocol.AttachRequestArguments);
assert.ok(attachResult.success);
resolve();
@@ -477,6 +511,24 @@
}
/**
+ * Helper function to create a promise that's resolved when
+ * output event with any of the provided strings is observed.
+ */
+ async function waitForOutputMessage(dc: DebugClient, ...patterns: string[]): Promise<DebugProtocol.Event> {
+ return await new Promise<DebugProtocol.Event>((resolve, reject) => {
+ dc.on('output', (event) => {
+ for (const pattern of patterns) {
+ if (event.body.output.includes(pattern)) {
+ // Resolve when we have found the event that we want.
+ resolve(event);
+ return;
+ }
+ }
+ });
+ });
+ }
+
+ /**
* Helper function to assert that a variable has a particular value.
* This should be called when the program is stopped.
*
@@ -555,6 +607,10 @@
});
suite('env', () => {
+ if (!isDlvDap) {
+ return;
+ }
+
let sandbox: sinon.SinonSandbox;
setup(() => {
@@ -619,6 +675,9 @@
});
suite('launch', () => {
+ if (!isDlvDap) {
+ return;
+ }
test('should run program to the end', async () => {
const PROGRAM = path.join(DATA_ROOT, 'baseTest');
@@ -734,7 +793,6 @@
this.skip(); // not working in dlv-dap.
}
- // TODO(hyangah): why does it take 30sec?
const PROGRAM = path.join(DATA_ROOT, 'baseTest');
const config = {
name: 'Launch',
@@ -744,13 +802,16 @@
program: PROGRAM,
dlvFlags: ['--invalid']
};
- try {
- await initializeDebugConfig(config);
- await dc.initializeRequest();
- } catch (err) {
- return;
- }
- throw new Error('does not report error on invalid delve flag');
+
+ await initializeDebugConfig(config);
+
+ await Promise.race([
+ // send an initialize request, which triggers launchDelveDAP
+ // from the thin adapter. We expect no response.
+ dc.initializeRequest().then(() => Promise.reject('unexpected initialization success')),
+ // we expect the useful error message.
+ waitForOutputMessage(dc, 'Error: unknown flag: --invalid')
+ ]);
});
test('should run program with showLog=false and logOutput specified', async () => {
@@ -827,6 +888,9 @@
});
suite('set current working directory', () => {
+ if (!isDlvDap) {
+ return;
+ }
test('should debug program with cwd set', async () => {
const WD = path.join(DATA_ROOT, 'cwdTest');
const PROGRAM = path.join(WD, 'cwdTest');
@@ -907,15 +971,7 @@
});
async function waitForHelloGoodbyeOutput(dc: DebugClient): Promise<DebugProtocol.Event> {
- return await new Promise<DebugProtocol.Event>((resolve, reject) => {
- dc.on('output', (event) => {
- if (event.body.output === 'Hello, World!\n' || event.body.output === 'Goodbye, World.\n') {
- // Resolve when we have found the event that we want.
- resolve(event);
- return;
- }
- });
- });
+ return waitForOutputMessage(dc, 'Hello, World!\n', 'Goodbye, World.\n');
}
test('should run program with cwd set (noDebug)', async () => {
@@ -993,6 +1049,9 @@
});
suite('remote attach', () => {
+ if (withConsole) {
+ return;
+ }
let childProcess: cp.ChildProcess;
let server: number;
let debugConfig: DebugConfiguration;
@@ -1093,6 +1152,11 @@
await dc.hitBreakpoint(debugConfig, getBreakpointLocation(FILE, BREAKPOINT_LINE));
});
+ // stop here for integrated terminal test mode.
+ if (withConsole) {
+ return;
+ }
+
test('stopped for a breakpoint set during initialization (remote attach)', async () => {
const FILE = path.join(DATA_ROOT, 'helloWorldServer', 'main.go');
const BREAKPOINT_LINE = 29;
@@ -1211,21 +1275,16 @@
]);
}
- test('should set breakpoints during next', async function () {
- if (!isDlvDap) {
- this.skip();
- }
+ // Skip this test because it is flaky.
+ test.skip('should set breakpoints during next', async () => {
await setBreakpointsWhileRunningStep(async () => {
const nextResponse = await dc.nextRequest({ threadId: 1 });
assert.ok(nextResponse.success);
});
});
- test('should set breakpoints during step out', async function () {
- if (!isDlvDap) {
- this.skip();
- }
-
+ // Skip this test because it is flaky.
+ test.skip('should set breakpoints during step out', async () => {
await setBreakpointsWhileRunningStep(async () => {
await Promise.all([dc.stepInRequest({ threadId: 1 }), dc.assertStoppedLocation('step', {})]);
@@ -1302,6 +1361,9 @@
});
suite('conditionalBreakpoints', () => {
+ if (withConsole) {
+ return;
+ }
test('should stop on conditional breakpoint', async () => {
const PROGRAM = path.join(DATA_ROOT, 'condbp');
const FILE = path.join(DATA_ROOT, 'condbp', 'condbp.go');
@@ -1436,6 +1498,9 @@
});
suite('panicBreakpoints', () => {
+ if (withConsole) {
+ return;
+ }
test('should stop on panic', async () => {
const PROGRAM_WITH_EXCEPTION = path.join(DATA_ROOT, 'panic');
@@ -1523,6 +1588,9 @@
});
suite('disconnect', () => {
+ if (withConsole) {
+ return;
+ }
// The teardown code for the Go Debug Adapter test suite issues a disconnectRequest.
// In order for these tests to pass, the debug adapter must not fail if a
// disconnectRequest is sent after it has already disconnected.
@@ -1728,7 +1796,7 @@
// has a chance to clean up.
// BUG(https://github.com/golang/vscode-go/issues/1993)
test('should cleanup when stopped', async function () {
- if (!isDlvDap) {
+ if (!isDlvDap || affectedByIssue832()) {
this.skip();
}
const PROGRAM = path.join(DATA_ROOT, 'loop');
@@ -1779,6 +1847,9 @@
});
suite('switch goroutine', () => {
+ if (withConsole) {
+ return;
+ }
async function continueAndFindParkedGoroutine(file: string): Promise<number> {
// Find a goroutine that is stopped in parked.
const bp = getBreakpointLocation(file, 8);
@@ -1919,6 +1990,9 @@
});
suite('logDest attribute tests', () => {
+ if (!isDlvDap) {
+ return;
+ }
const PROGRAM = path.join(DATA_ROOT, 'baseTest');
let tmpDir: string;
@@ -1926,7 +2000,7 @@
tmpDir = fs.mkdtempSync(path.join(tmpdir(), 'logDestTest'));
});
suiteTeardown(() => {
- rmdirRecursive(tmpDir);
+ tryRmdirRecursive(tmpDir);
});
test('logs are written to logDest file', async function () {
@@ -1990,6 +2064,9 @@
});
suite('substitute path', () => {
+ if (withConsole || affectedByIssue832()) {
+ return;
+ }
// TODO(suzmue): add unit tests for substitutePath.
let tmpDir: string;
@@ -1998,7 +2075,7 @@
});
suiteTeardown(() => {
- rmdirRecursive(tmpDir);
+ tryRmdirRecursive(tmpDir);
});
function copyDirectory(name: string) {
@@ -2014,7 +2091,7 @@
async function buildGoProgram(cwd: string, outputFile: string): Promise<string> {
const goRuntimePath = getBinPath('go');
const execFile = util.promisify(cp.execFile);
- const child = await execFile(goRuntimePath, ['build', '-o', outputFile, "--gcflags='all=-N -l'", '.'], {
+ const child = await execFile(goRuntimePath, ['build', '-o', outputFile, '--gcflags=all=-N -l', '.'], {
cwd
});
if (child.stderr.length > 0) {
@@ -2030,13 +2107,13 @@
});
suiteTeardown(() => {
- rmdirRecursive(goBuildOutput);
+ tryRmdirRecursive(goBuildOutput);
});
async function copyBuildDelete(program: string): Promise<{ program: string; output: string }> {
const wd = copyDirectory(program);
const output = await buildGoProgram(wd, path.join(goBuildOutput, program));
- rmdirRecursive(wd);
+ tryRmdirRecursive(wd);
return { program: wd, output };
}
@@ -2081,7 +2158,7 @@
});
suiteTeardown(() => {
- rmdirRecursive(helloWorldLocal);
+ tryRmdirRecursive(helloWorldLocal);
});
test('stopped for a breakpoint set during initialization using substitutePath (remote attach)', async () => {
@@ -2149,7 +2226,7 @@
});
suiteTeardown(() => {
fs.unlinkSync(symlinkPath);
- rmdirRecursive(realPath);
+ tryRmdirRecursive(realPath);
});
test('should stop on a breakpoint', async function () {
if (!isDlvDap) this.skip(); // BUG: the legacy adapter fails with 'breakpoint verification mismatch' error.
@@ -2227,6 +2304,9 @@
};
suite('Go Debug Adapter Tests (legacy)', function () {
+ if (affectedByIssue832()) {
+ return;
+ }
this.timeout(60_000);
testAll(this.ctx, false);
});
@@ -2428,3 +2508,11 @@
function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
+
+function tryRmdirRecursive(dir: string) {
+ try {
+ rmdirRecursive(dir);
+ } catch (e) {
+ console.log(`failed to delete ${dir}: ${e}`);
+ }
+}
diff --git a/test/integration/goDebugConfiguration.test.ts b/test/integration/goDebugConfiguration.test.ts
index d95f9a6..8b9ab7f 100644
--- a/test/integration/goDebugConfiguration.test.ts
+++ b/test/integration/goDebugConfiguration.test.ts
@@ -14,6 +14,7 @@
import goEnv = require('../../src/goEnv');
import { MockCfg } from '../mocks/MockCfg';
import { extensionId } from '../../src/const';
+import { affectedByIssue832 } from './testutils';
suite('Debug Environment Variable Merge Test', () => {
const debugConfigProvider = new GoDebugConfigurationProvider();
@@ -630,6 +631,9 @@
});
suite('Debug Configuration Converts Relative Paths', () => {
+ if (affectedByIssue832()) {
+ return;
+ }
const debugConfigProvider = new GoDebugConfigurationProvider();
let workspaceDir = '';
diff --git a/test/integration/goExplorer.test.ts b/test/integration/goExplorer.test.ts
index 2cb3e83..27ce150 100644
--- a/test/integration/goExplorer.test.ts
+++ b/test/integration/goExplorer.test.ts
@@ -41,7 +41,7 @@
const [goenv, gomod] = (await explorer.getChildren(env)) as { key: string; value: string }[];
assert.strictEqual(goenv.key, 'GOENV');
assert.strictEqual(gomod.key, 'GOMOD');
- assert.strictEqual(resolveHomeDir(gomod.value), `${fixtureDir}/go.mod`);
+ assert.strictEqual(resolveHomeDir(gomod.value), path.join(fixtureDir, 'go.mod'));
});
test('tools tree', async () => {
diff --git a/test/integration/goTest.run.test.ts b/test/integration/goTest.run.test.ts
index a16ad33..ac9ceaa 100644
--- a/test/integration/goTest.run.test.ts
+++ b/test/integration/goTest.run.test.ts
@@ -118,6 +118,10 @@
});
suite('Subtest', () => {
+ // WARNING: each call to testExplorer.runner.run triggers one or more
+ // `go test` command runs (testUtils.goTest is spied, not mocked or replaced).
+ // Each `go test` command invocation can take seconds on slow machines.
+ // As we add more cases, the timeout should be increased accordingly.
const sandbox = sinon.createSandbox();
const subTestDir = path.join(fixtureDir, 'subTest');
const ctx = MockExtensionContext.new();
@@ -214,6 +218,6 @@
'Failed to execute `go test`'
);
assert.strictEqual(spy.callCount, 0, 'expected no calls to goTest');
- }).timeout(4000);
+ }).timeout(10000);
});
});
diff --git a/test/integration/goTest.utils.ts b/test/integration/goTest.utils.ts
index 914ea18..caa727f 100644
--- a/test/integration/goTest.utils.ts
+++ b/test/integration/goTest.utils.ts
@@ -24,14 +24,14 @@
function walk(dir: Uri, modpath?: string) {
const dirs: Uri[] = [];
for (const [name, type] of workspace.fs.dirs.get(dir.toString()) ?? []) {
- const uri = dir.with({ path: path.join(dir.path, name) });
+ const uri = Uri.file(path.join(dir.fsPath, name));
if (type === FileType.Directory) {
dirs.push(uri);
} else if (name === 'go.mod') {
- modpath = dir.path;
+ modpath = dir.fsPath;
}
}
- packagePathToGoModPathMap[dir.path] = modpath || '';
+ packagePathToGoModPathMap[dir.fsPath] = modpath || '';
for (const dir of dirs) {
walk(dir, modpath);
}
diff --git a/test/integration/install.test.ts b/test/integration/install.test.ts
index f14c028..18adf18 100644
--- a/test/integration/install.test.ts
+++ b/test/integration/install.test.ts
@@ -104,6 +104,9 @@
const missingTools = testCases.map((tc) => getToolAtVersion(tc.name));
const goVersion = await getGoVersion();
+
+ sandbox.stub(vscode.commands, 'executeCommand').withArgs('go.languageserver.restart');
+
await installTools(missingTools, goVersion);
// Confirm that each expected tool has been installed.
diff --git a/test/integration/testutils.ts b/test/integration/testutils.ts
new file mode 100644
index 0000000..7f85315
--- /dev/null
+++ b/test/integration/testutils.ts
@@ -0,0 +1,3 @@
+export function affectedByIssue832(): boolean {
+ return process.platform === 'win32';
+}
diff --git a/test/testdata/helloWorldServer/main.go b/test/testdata/helloWorldServer/main.go
index a1598af..ff35e27 100644
--- a/test/testdata/helloWorldServer/main.go
+++ b/test/testdata/helloWorldServer/main.go
@@ -16,8 +16,8 @@
if p := os.Getenv("PORT"); p != "" {
addr = ":" + p
}
-
- log.Printf("server starting to listen on %s", addr)
+ // NOTE: goDebug.test.ts setupRemoteProgram expects this log message.
+ log.Printf("helloWorldServer starting to listen on %s", addr)
http.HandleFunc("/", home)
if err := http.ListenAndServe(addr, nil); err != nil {
log.Fatalf("server listen error: %+v", err)
@@ -26,6 +26,6 @@
// home logs the received request and returns a simple response.
func home(w http.ResponseWriter, r *http.Request) {
- log.Printf("received request: %s %s", r.Method, r.URL.Path)
+ log.Printf("received request: %s %s", r.Method, r.URL.Path) // Breakpoint
fmt.Fprintf(w, "Hello, world!")
}
diff --git a/tools/goplssetting/goplssetting.go b/tools/goplssetting/goplssetting.go
index e78d26c..b300ec1 100644
--- a/tools/goplssetting/goplssetting.go
+++ b/tools/goplssetting/goplssetting.go
@@ -17,10 +17,6 @@
"strings"
)
-var skipHierarchy map[string]bool = map[string]bool{
- "ui.inlayhint": true,
-}
-
// Generate reads package.json and updates the gopls settings section
// based on `gopls api-json` output. This function requires `jq` to
// manipulate package.json.
@@ -185,22 +181,21 @@
return v[i].Name < v[j].Name
})
}
- properties, err := collectProperties(seen)
+ goplsProperties, goProperties, err := collectProperties(seen)
if err != nil {
return nil, err
}
- return json.Marshal(map[string]*Object{
- "gopls": {
- Type: "object",
- MarkdownDescription: "Configure the default Go language server ('gopls'). In most cases, configuring this section is unnecessary. See [the documentation](https://github.com/golang/tools/blob/master/gopls/doc/settings.md) for all available settings.",
- Scope: "resource",
- AdditionalProperties: false,
- Properties: properties,
- },
- })
+ goProperties["gopls"] = &Object{
+ Type: "object",
+ MarkdownDescription: "Configure the default Go language server ('gopls'). In most cases, configuring this section is unnecessary. See [the documentation](https://github.com/golang/tools/blob/master/gopls/doc/settings.md) for all available settings.",
+ Scope: "resource",
+ AdditionalProperties: false,
+ Properties: goplsProperties,
+ }
+ return json.Marshal(goProperties)
}
-func collectProperties(m map[string][]*OptionJSON) (map[string]*Object, error) {
+func collectProperties(m map[string][]*OptionJSON) (goplsProperties, goProperties map[string]*Object, err error) {
var sorted []string
var containsEmpty bool
for k := range m {
@@ -214,9 +209,23 @@
if containsEmpty {
sorted = append(sorted, "")
}
- properties := map[string]*Object{}
+ goplsProperties, goProperties = map[string]*Object{}, map[string]*Object{}
for _, hierarchy := range sorted {
- if skip := skipHierarchy[hierarchy]; skip {
+ if hierarchy == "ui.inlayhint" {
+ for _, opt := range m[hierarchy] {
+ for _, k := range opt.EnumKeys.Keys {
+ unquotedName, err := strconv.Unquote(k.Name)
+ if err != nil {
+ return nil, nil, err
+ }
+ key := "go.inlayHints." + unquotedName
+ goProperties[key] = &Object{
+ MarkdownDescription: k.Doc,
+ Type: "boolean",
+ Default: formatDefault(k.Default, "boolean"),
+ }
+ }
+ }
continue
}
for _, opt := range m[hierarchy] {
@@ -237,7 +246,7 @@
for _, v := range opt.EnumValues {
unquotedName, err := strconv.Unquote(v.Value)
if err != nil {
- return nil, err
+ return nil, nil, err
}
obj.Enum = append(obj.Enum, unquotedName)
obj.MarkdownEnumDescriptions = append(obj.MarkdownEnumDescriptions, v.Doc)
@@ -251,7 +260,7 @@
for _, k := range opt.EnumKeys.Keys {
unquotedName, err := strconv.Unquote(k.Name)
if err != nil {
- return nil, err
+ return nil, nil, err
}
obj.Properties[unquotedName] = &Object{
Type: propertyType(opt.EnumKeys.ValueType),
@@ -267,10 +276,10 @@
if hierarchy != "" {
key = hierarchy + "." + key
}
- properties[key] = obj
+ goplsProperties[key] = obj
}
}
- return properties, nil
+ return goplsProperties, goProperties, nil
}
func formatOptionDefault(opt *OptionJSON) interface{} {