Suzy Mueller has uploaded this change for review.
src/goOutline: use the language server to get the outline
Change-Id: Ib3ce4fe04c3ffe9428f6701ffaa24dd8444781c0
---
M src/goOutline.ts
M src/testUtils.ts
2 files changed, 91 insertions(+), 4 deletions(-)
diff --git a/src/goOutline.ts b/src/goOutline.ts
index 8c9a8f7..12103d6 100644
--- a/src/goOutline.ts
+++ b/src/goOutline.ts
@@ -8,9 +8,11 @@
import cp = require('child_process');
import vscode = require('vscode');
+import { ExecuteCommandParams, ExecuteCommandRequest } from 'vscode-languageserver-protocol';
import { getGoConfig } from './config';
import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool, promptForUpdatingTool } from './goInstallTools';
+import { buildLanguageServerConfig, getLocalGoplsVersion, languageClient } from './goLanguageServer';
import { getBinPath, getFileArchive, makeMemoizedByteOffsetConverter } from './util';
import { killProcess } from './utils/processUtils';
@@ -192,14 +194,53 @@
export class GoDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
constructor(private includeImports?: boolean) {}
- public provideDocumentSymbols(
+ public async provideDocumentSymbols(
document: vscode.TextDocument,
token: vscode.CancellationToken
- ): Thenable<vscode.DocumentSymbol[]> {
+ ): Promise<vscode.DocumentSymbol[]> {
if (typeof this.includeImports !== 'boolean') {
const gotoSymbolConfig = getGoConfig(document.uri)['gotoSymbol'];
this.includeImports = gotoSymbolConfig ? gotoSymbolConfig['includeImports'] : false;
}
+
+ // const cfg = buildLanguageServerConfig(getGoConfig());
+ // const goplsVersion = await getLocalGoplsVersion(cfg);
+ // Make sure gopls version is > 0.8.0.
+ if (languageClient) {
+ const documentSymbolProvider = languageClient
+ .getFeature('textDocument/documentSymbol')
+ .getProvider(document);
+ const symbols = await documentSymbolProvider.provideDocumentSymbols(document, token);
+ if (!symbols || symbols.length === 0) {
+ return;
+ }
+
+ // Stitch the results together to make the results look like
+ // go-outline.
+ const packageSymbol = new vscode.DocumentSymbol(
+ 'unknown',
+ 'package',
+ vscode.SymbolKind.Package,
+ new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 0)),
+ new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 0))
+ );
+ packageSymbol.children = convertToDocumentSymbols(symbols);
+ if (this.includeImports) {
+ (await listImports(document)).forEach((value) => {
+ packageSymbol.children.unshift(
+ new vscode.DocumentSymbol(
+ value.Path,
+ value.Name,
+ vscode.SymbolKind.Package,
+ new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 0)),
+ new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 0))
+ )
+ );
+ });
+ }
+ return [packageSymbol];
+ }
+
const options: GoOutlineOptions = {
fileName: document.fileName,
document,
@@ -208,3 +249,38 @@
return documentSymbols(options, token);
}
}
+
+async function listImports(doc: vscode.TextDocument): Promise<{ Path: string; Name: string }[]> {
+ if (languageClient) {
+ try {
+ const uri = languageClient.code2ProtocolConverter.asTextDocumentIdentifier(doc).uri;
+ const params: ExecuteCommandParams = {
+ command: 'gopls.list_imports',
+ arguments: [
+ {
+ URI: uri
+ }
+ ]
+ };
+ const resp = await languageClient.sendRequest(ExecuteCommandRequest.type, params);
+ return resp.Imports;
+ } catch (e) {
+ console.log(`error with gopls.list_imports: ${e}`);
+ }
+ }
+ // TODO: fallback to something
+ return;
+}
+
+function convertToDocumentSymbols(args: vscode.DocumentSymbol[] | vscode.SymbolInformation[]): vscode.DocumentSymbol[] {
+ if (args.length === 0) {
+ return [];
+ }
+ return args.map((val) => {
+ if (val instanceof vscode.DocumentSymbol) {
+ return val;
+ }
+ // gopls should always return vscode.DocumentSymbol.
+ return undefined;
+ });
+}
diff --git a/src/testUtils.ts b/src/testUtils.ts
index d340168..0025db4 100644
--- a/src/testUtils.ts
+++ b/src/testUtils.ts
@@ -155,11 +155,13 @@
}
const children = symbol.children;
const testify = children.some(
- (sym) => sym.kind === vscode.SymbolKind.Namespace && sym.name === '"github.com/stretchr/testify/suite"'
+ (sym) =>
+ sym.kind === vscode.SymbolKind.Namespace &&
+ (sym.name === '"github.com/stretchr/testify/suite"' || sym.name === 'github.com/stretchr/testify/suite')
);
return children.filter(
(sym) =>
- sym.kind === vscode.SymbolKind.Function &&
+ (sym.kind === vscode.SymbolKind.Function || sym.kind === vscode.SymbolKind.Method) &&
(testFuncRegex.test(sym.name) || fuzzFuncRegx.test(sym.name) || (testify && testMethodRegex.test(sym.name)))
);
}
To view, visit change 384574. To unsubscribe, or for help writing mail filters, visit settings.
Suzy Mueller uploaded patch set #4 to this change.
src/goOutline: use language server to get document symbols
This change replaces the use of go-outline with gopls when
available. This is done by fixing up the results from gopls
to resemble those returned by go-outline to avoid having to
handle these document symbols differently in various places.
Updates golang/vscode-go#1020
Change-Id: Ib3ce4fe04c3ffe9428f6701ffaa24dd8444781c0
---
M src/goOutline.ts
M src/goTest/resolve.ts
M src/testUtils.ts
3 files changed, 92 insertions(+), 12 deletions(-)
To view, visit change 384574. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Suzy Mueller.
Kokoro presubmit build finished with status: FAILURE
Logs at: https://source.cloud.google.com/results/invocations/9984df03-2254-4e22-b1b2-68691d667ccb
Patch set 3:TryBot-Result -1
Attention is currently required from: Suzy Mueller.
Kokoro presubmit build finished with status: FAILURE
Logs at: https://source.cloud.google.com/results/invocations/0dc2ca1c-ed51-4d13-a774-bb4fa6dd3977
Patch set 4:TryBot-Result -1
Attention is currently required from: Suzy Mueller.
Suzy Mueller uploaded patch set #5 to this change.
src/goOutline: use language server to get document symbols
This change replaces the use of go-outline with gopls when
available. This is done by fixing up the results from gopls
to resemble those returned by go-outline to avoid having to
handle these document symbols differently in various places.
Updates golang/vscode-go#1020
Change-Id: Ib3ce4fe04c3ffe9428f6701ffaa24dd8444781c0
---
M src/goOutline.ts
M src/goTest/resolve.ts
M src/testUtils.ts
3 files changed, 95 insertions(+), 12 deletions(-)
To view, visit change 384574. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Suzy Mueller.
Kokoro presubmit build finished with status: FAILURE
Logs at: https://source.cloud.google.com/results/invocations/6b9791a6-f682-4bee-8cf8-aa5717fede6d
Patch set 5:TryBot-Result -1
Attention is currently required from: Suzy Mueller.
Suzy Mueller uploaded patch set #6 to this change.
src/goOutline: use language server to get document symbols
This change replaces the use of go-outline with gopls when
available. This is done by fixing up the results from gopls
to resemble those returned by go-outline to avoid having to
handle these document symbols differently in various places.
Updates golang/vscode-go#1020
Change-Id: Ib3ce4fe04c3ffe9428f6701ffaa24dd8444781c0
---
M src/goOutline.ts
M src/goTest/resolve.ts
M src/testUtils.ts
3 files changed, 95 insertions(+), 12 deletions(-)
To view, visit change 384574. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
Patch set 5:Run-TryBot +1Trust +1
Attention is currently required from: Suzy Mueller, Hyang-Ah Hana Kim.
Kokoro presubmit build finished with status: FAILURE
Logs at: https://source.cloud.google.com/results/invocations/292e1800-7c12-4b4d-a23c-c80e912ae5ca
Patch set 6:TryBot-Result -1
Attention is currently required from: Suzy Mueller.
Patch set 6:Code-Review +2Trust +1
3 comments:
Patchset:
Does this Cl need rebasing?
File src/goOutline.ts:
if (languageClient && (goplsVersion === '(devel)' || semver.gt(sv, 'v0.7.6'))) {
We won't execute this code path since we are using the latest gopls.
Maybe we should consider adjusting vscode-go/tools/installTools/main.go to pick the prerelease if available until gopls release.
Patch Set #6, Line 267: console.log(`error with gopls.list_imports: ${e}`);
What do you think if we let listImports throw an error instead of catching it (e.g. gopls is not available or it is too old to have gopls.list_imports), and if listImports fails, we fall back to the old way from the call site?
To view, visit change 384574. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
Suzy Mueller uploaded patch set #7 to this change.
src/goOutline: use language server to get document symbols
This change replaces the use of go-outline with gopls when
available. This is done by fixing up the results from gopls
to resemble those returned by go-outline to avoid having to
handle these document symbols differently in various places.
Updates golang/vscode-go#1020
Change-Id: Ib3ce4fe04c3ffe9428f6701ffaa24dd8444781c0
---
M src/goOutline.ts
M src/goTest/resolve.ts
M src/testUtils.ts
3 files changed, 98 insertions(+), 12 deletions(-)
To view, visit change 384574. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
1 comment:
File src/goOutline.ts:
Patch Set #6, Line 267: console.log(`error with gopls.list_imports: ${e}`);
What do you think if we let listImports throw an error instead of catching it (e.g. […]
Sounds good! Done.
To view, visit change 384574. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
Suzy Mueller uploaded patch set #8 to this change.
src/goOutline: use language server to get document symbols
This change replaces the use of go-outline with gopls when
available. This is done by fixing up the results from gopls
to resemble those returned by go-outline to avoid having to
handle these document symbols differently in various places.
Also sets the testing gopls version to pre release.
Updates golang/vscode-go#1020
Change-Id: Ib3ce4fe04c3ffe9428f6701ffaa24dd8444781c0
---
M src/goOutline.ts
M src/goTest/resolve.ts
M src/testUtils.ts
M tools/installtools/main.go
4 files changed, 101 insertions(+), 13 deletions(-)
To view, visit change 384574. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Suzy Mueller, Hyang-Ah Hana Kim.
Kokoro presubmit build finished with status: FAILURE
Logs at: https://source.cloud.google.com/results/invocations/60ed72cb-e32c-4c8c-99ce-71937979ba07
Patch set 7:TryBot-Result -1
Attention is currently required from: Suzy Mueller, Hyang-Ah Hana Kim.
Kokoro presubmit build finished with status: FAILURE
Logs at: https://source.cloud.google.com/results/invocations/4a361377-1952-4885-b5d3-aefe373b7e49
Patch set 8:TryBot-Result -1
Attention is currently required from: Suzy Mueller, Hyang-Ah Hana Kim.
Suzy Mueller uploaded patch set #9 to this change.
src/goOutline: use language server to get document symbols
This change replaces the use of go-outline with gopls when
available. This is done by fixing up the results from gopls
to resemble those returned by go-outline to avoid having to
handle these document symbols differently in various places.
Also sets the testing gopls version to pre release.
Updates golang/vscode-go#1020
Change-Id: Ib3ce4fe04c3ffe9428f6701ffaa24dd8444781c0
---
M src/goOutline.ts
M src/goTest/resolve.ts
M src/testUtils.ts
M tools/installtools/main.go
4 files changed, 104 insertions(+), 13 deletions(-)
To view, visit change 384574. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Suzy Mueller, Hyang-Ah Hana Kim.
Kokoro presubmit build finished with status: FAILURE
Logs at: https://source.cloud.google.com/results/invocations/79c5b902-a4a3-4f44-80b0-791fa8344274
Patch set 9:TryBot-Result -1
Attention is currently required from: Suzy Mueller, Hyang-Ah Hana Kim.
Suzy Mueller uploaded patch set #10 to this change.
src/goOutline: use language server to get document symbols
This change replaces the use of go-outline with gopls when
available. This is done by fixing up the results from gopls
to resemble those returned by go-outline to avoid having to
handle these document symbols differently in various places.
Also sets the testing gopls version to pre release.
Updates golang/vscode-go#1020
Change-Id: Ib3ce4fe04c3ffe9428f6701ffaa24dd8444781c0
---
M docs/settings.md
M package.json
M src/goOutline.ts
M src/goTest/resolve.ts
M src/testUtils.ts
M tools/installtools/main.go
6 files changed, 108 insertions(+), 17 deletions(-)
To view, visit change 384574. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Suzy Mueller, Hyang-Ah Hana Kim.
Kokoro presubmit build finished with status: SUCCESS
Logs at: https://source.cloud.google.com/results/invocations/c3941684-efe2-4aa0-8f56-88d19c34d37f
Patch set 10:TryBot-Result +1
Suzy Mueller submitted this change.
6 is the latest approved patch-set.
The change was submitted with unreviewed changes in the following files:
```
The name of the file: src/testUtils.ts
Insertions: 3, Deletions: 3.
@@ -154,7 +154,7 @@
return;
}
const children = symbol.children;
- const testify = importsTestify(symbols)
+ const testify = importsTestify(symbols);
return children.filter(
(sym) =>
(sym.kind === vscode.SymbolKind.Function || sym.kind === vscode.SymbolKind.Method) &&
@@ -632,9 +632,9 @@
}
export function importsTestify(syms: vscode.DocumentSymbol[]): boolean {
- if (!syms || syms.length == 0 || !syms[0]) {
+ if (!syms || syms.length === 0 || !syms[0]) {
return false;
- }
+ }
const children = syms[0].children;
return children.some(
(sym) =>
```
```
The name of the file: src/goOutline.ts
Insertions: 35, Deletions: 29.
@@ -208,7 +208,10 @@
const goplsVersion = await getLocalGoplsVersion(latestConfig);
const sv = semver.parse(goplsVersion, true);
if (languageClient && (goplsVersion === '(devel)' || semver.gt(sv, 'v0.7.6'))) {
- const symbols: vscode.DocumentSymbol[] = await vscode.commands.executeCommand('vscode.executeDocumentSymbolProvider', document.uri);
+ const symbols: vscode.DocumentSymbol[] = await vscode.commands.executeCommand(
+ 'vscode.executeDocumentSymbolProvider',
+ document.uri
+ );
if (!symbols || symbols.length === 0) {
return [];
}
@@ -225,22 +228,30 @@
);
packageSymbol.children = symbols;
if (this.includeImports) {
- const imports = await listImports(document);
- imports?.forEach((value) => {
- packageSymbol.children.unshift(
- new vscode.DocumentSymbol(
- value.Path,
- 'import',
- vscode.SymbolKind.Namespace,
- new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 0)),
- new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 0))
- )
- );
- });
+ try {
+ const imports = await listImports(document);
+ imports?.forEach((value) => {
+ packageSymbol.children.unshift(
+ new vscode.DocumentSymbol(
+ value.Path,
+ 'import',
+ vscode.SymbolKind.Namespace,
+ new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 0)),
+ new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 0))
+ )
+ );
+ });
+ } catch (e) {
+ // Fall back to use go-outline.
+ return this.runGoOutline(document, token);
+ }
}
return [packageSymbol];
}
+ return this.runGoOutline(document, token);
+ }
+ private runGoOutline(document: vscode.TextDocument, token: vscode.CancellationToken) {
const options: GoOutlineOptions = {
fileName: document.fileName,
document,
@@ -251,20 +262,15 @@
}
async function listImports(document: vscode.TextDocument): Promise<{ Path: string; Name: string }[]> {
- try {
- const uri = languageClient.code2ProtocolConverter.asTextDocumentIdentifier(document).uri;
- const params: ExecuteCommandParams = {
- command: 'gopls.list_imports',
- arguments: [
- {
- URI: uri
- }
- ]
- };
- const resp = await languageClient.sendRequest(ExecuteCommandRequest.type, params);
- return resp.Imports;
- } catch (e) {
- console.log(`error with gopls.list_imports: ${e}`);
- }
- return [];
+ const uri = languageClient.code2ProtocolConverter.asTextDocumentIdentifier(document).uri;
+ const params: ExecuteCommandParams = {
+ command: 'gopls.list_imports',
+ arguments: [
+ {
+ URI: uri
+ }
+ ]
+ };
+ const resp = await languageClient.sendRequest(ExecuteCommandRequest.type, params);
+ return resp.Imports;
}
```
```
The name of the file: docs/settings.md
Insertions: 2, Deletions: 2.
@@ -730,7 +730,7 @@
| `nilfunc` | check for useless comparisons between functions and nil <br/> A useless comparison is one like f == nil as opposed to f() == nil. <br/> Default: `true` |
| `nilness` | check for redundant or impossible nil comparisons <br/> The nilness checker inspects the control-flow graph of each function in a package and reports nil pointer dereferences, degenerate nil pointers, and panics with nil values. A degenerate comparison is of the form x==nil or x!=nil where x is statically known to be nil or non-nil. These are often a mistake, especially in control flow related to errors. Panics with nil values are checked because they are not detectable by <br/> <pre>if r := recover(); r != nil {</pre><br/> This check reports conditions such as: <br/> <pre>if f == nil { // impossible condition (f is a function)<br/>}</pre><br/> and: <br/> <pre>p := &v<br/>...<br/>if p != nil { // tautological condition<br/>}</pre><br/> and: <br/> <pre>if p == nil {<br/> print(*p) // nil dereference<br/>}</pre><br/> and: <br/> <pre>if p == nil {<br/> panic(p)<br/>}</pre><br/> <br/> Default: `false` |
| `nonewvars` | suggested fixes for "no new vars on left side of :=" <br/> This checker provides suggested fixes for type errors of the type "no new vars on left side of :=". For example: <pre>z := 1<br/>z := 2</pre>will turn into <pre>z := 1<br/>z = 2</pre><br/> <br/> Default: `true` |
-| `noresultvalues` | suggested fixes for "no result values expected" <br/> This checker provides suggested fixes for type errors of the type "no result values expected". For example: <pre>func z() { return nil }</pre>will turn into <pre>func z() { return }</pre><br/> <br/> Default: `true` |
+| `noresultvalues` | suggested fixes for unexpected return values <br/> This checker provides suggested fixes for type errors of the type "no result values expected" or "too many return values". For example: <pre>func z() { return nil }</pre>will turn into <pre>func z() { return }</pre><br/> <br/> Default: `true` |
| `printf` | check consistency of Printf format strings and arguments <br/> The check applies to known functions (for example, those in package fmt) as well as any detected wrappers of known functions. <br/> A function that wants to avail itself of printf checking but is not found by this analyzer's heuristics (for example, due to use of dynamic calls) can insert a bogus call: <br/> <pre>if false {<br/> _ = fmt.Sprintf(format, args...) // enable printf checking<br/>}</pre><br/> The -funcs flag specifies a comma-separated list of names of additional known formatting functions or methods. If the name contains a period, it must denote a specific function using one of the following forms: <br/> <pre>dir/pkg.Function<br/>dir/pkg.Type.Method<br/>(*dir/pkg.Type).Method</pre><br/> Otherwise the name is interpreted as a case-insensitive unqualified identifier such as "errorf". Either way, if a listed name ends in f, the function is assumed to be Printf-like, taking a format string before the argument list. Otherwise it is assumed to be Print-like, taking a list of arguments with no format string. <br/> <br/> Default: `true` |
| `shadow` | check for possible unintended shadowing of variables <br/> This analyzer check for shadowed variables. A shadowed variable is a variable declared in an inner scope with the same name and type as a variable in an outer scope, and where the outer variable is mentioned after the inner one is declared. <br/> (This definition can be refined; the module generates too many false positives and is not yet enabled by default.) <br/> For example: <br/> <pre>func BadRead(f *os.File, buf []byte) error {<br/> var err error<br/> for {<br/> n, err := f.Read(buf) // shadows the function variable 'err'<br/> if err != nil {<br/> break // causes return of wrong value<br/> }<br/> foo(buf)<br/> }<br/> return err<br/>}</pre><br/> <br/> Default: `false` |
| `shift` | check for shifts that equal or exceed the width of the integer <br/> Default: `true` |
@@ -840,7 +840,7 @@
<br/>
Allowed Options: `CaseInsensitive`, `CaseSensitive`, `FastFuzzy`, `Fuzzy`
-Default: `"Fuzzy"`
+Default: `"FastFuzzy"`
### `ui.navigation.symbolStyle`
(Advanced) symbolStyle controls how symbols are qualified in symbol responses.
```
```
The name of the file: tools/installtools/main.go
Insertions: 1, Deletions: 1.
@@ -17,7 +17,7 @@
dest string
}{
// TODO: auto-generate based on allTools.ts.in.
- {"golang.org/x/tools/gopls", "", ""},
+ {"golang.org/x/tools/gopls", "v0.8.0-pre.1", ""}, // TODO: make this not hardcoded
{"github.com/acroca/go-symbols", "", ""},
{"github.com/cweill/gotests/gotests", "", ""},
{"github.com/davidrjenni/reftools/cmd/fillstruct", "", ""},
```
```
The name of the file: package.json
Insertions: 2, Deletions: 2.
@@ -2272,7 +2272,7 @@
},
"noresultvalues": {
"type": "boolean",
- "markdownDescription": "suggested fixes for \"no result values expected\"\n\nThis checker provides suggested fixes for type errors of the\ntype \"no result values expected\". For example:\n\tfunc z() { return nil }\nwill turn into\n\tfunc z() { return }\n",
+ "markdownDescription": "suggested fixes for unexpected return values\n\nThis checker provides suggested fixes for type errors of the\ntype \"no result values expected\" or \"too many return values\".\nFor example:\n\tfunc z() { return nil }\nwill turn into\n\tfunc z() { return }\n",
"default": true
},
"printf": {
@@ -2485,7 +2485,7 @@
"",
""
],
- "default": "Fuzzy",
+ "default": "FastFuzzy",
"scope": "resource"
},
"ui.navigation.symbolStyle": {
```
src/goOutline: use language server to get document symbols
This change replaces the use of go-outline with gopls when
available. This is done by fixing up the results from gopls
to resemble those returned by go-outline to avoid having to
handle these document symbols differently in various places.
Also sets the testing gopls version to pre release.
Updates golang/vscode-go#1020
Change-Id: Ib3ce4fe04c3ffe9428f6701ffaa24dd8444781c0
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/384574
Trust: Suzy Mueller <suz...@golang.org>
Run-TryBot: Suzy Mueller <suz...@golang.org>
Trust: Hyang-Ah Hana Kim <hya...@gmail.com>
Reviewed-by: Hyang-Ah Hana Kim <hya...@gmail.com>
TryBot-Result: kokoro <noreply...@google.com>
---
M docs/settings.md
M package.json
M src/goOutline.ts
M src/goTest/resolve.ts
M src/testUtils.ts
M tools/installtools/main.go
6 files changed, 114 insertions(+), 17 deletions(-)
diff --git a/docs/settings.md b/docs/settings.md
index d241197..d45bb62 100644
--- a/docs/settings.md
+++ b/docs/settings.md
@@ -730,7 +730,7 @@
| `nilfunc` | check for useless comparisons between functions and nil <br/> A useless comparison is one like f == nil as opposed to f() == nil. <br/> Default: `true` |
| `nilness` | check for redundant or impossible nil comparisons <br/> The nilness checker inspects the control-flow graph of each function in a package and reports nil pointer dereferences, degenerate nil pointers, and panics with nil values. A degenerate comparison is of the form x==nil or x!=nil where x is statically known to be nil or non-nil. These are often a mistake, especially in control flow related to errors. Panics with nil values are checked because they are not detectable by <br/> <pre>if r := recover(); r != nil {</pre><br/> This check reports conditions such as: <br/> <pre>if f == nil { // impossible condition (f is a function)<br/>}</pre><br/> and: <br/> <pre>p := &v<br/>...<br/>if p != nil { // tautological condition<br/>}</pre><br/> and: <br/> <pre>if p == nil {<br/> print(*p) // nil dereference<br/>}</pre><br/> and: <br/> <pre>if p == nil {<br/> panic(p)<br/>}</pre><br/> <br/> Default: `false` |
| `nonewvars` | suggested fixes for "no new vars on left side of :=" <br/> This checker provides suggested fixes for type errors of the type "no new vars on left side of :=". For example: <pre>z := 1<br/>z := 2</pre>will turn into <pre>z := 1<br/>z = 2</pre><br/> <br/> Default: `true` |
-| `noresultvalues` | suggested fixes for "no result values expected" <br/> This checker provides suggested fixes for type errors of the type "no result values expected". For example: <pre>func z() { return nil }</pre>will turn into <pre>func z() { return }</pre><br/> <br/> Default: `true` |
+| `noresultvalues` | suggested fixes for unexpected return values <br/> This checker provides suggested fixes for type errors of the type "no result values expected" or "too many return values". For example: <pre>func z() { return nil }</pre>will turn into <pre>func z() { return }</pre><br/> <br/> Default: `true` |
| `printf` | check consistency of Printf format strings and arguments <br/> The check applies to known functions (for example, those in package fmt) as well as any detected wrappers of known functions. <br/> A function that wants to avail itself of printf checking but is not found by this analyzer's heuristics (for example, due to use of dynamic calls) can insert a bogus call: <br/> <pre>if false {<br/> _ = fmt.Sprintf(format, args...) // enable printf checking<br/>}</pre><br/> The -funcs flag specifies a comma-separated list of names of additional known formatting functions or methods. If the name contains a period, it must denote a specific function using one of the following forms: <br/> <pre>dir/pkg.Function<br/>dir/pkg.Type.Method<br/>(*dir/pkg.Type).Method</pre><br/> Otherwise the name is interpreted as a case-insensitive unqualified identifier such as "errorf". Either way, if a listed name ends in f, the function is assumed to be Printf-like, taking a format string before the argument list. Otherwise it is assumed to be Print-like, taking a list of arguments with no format string. <br/> <br/> Default: `true` |
| `shadow` | check for possible unintended shadowing of variables <br/> This analyzer check for shadowed variables. A shadowed variable is a variable declared in an inner scope with the same name and type as a variable in an outer scope, and where the outer variable is mentioned after the inner one is declared. <br/> (This definition can be refined; the module generates too many false positives and is not yet enabled by default.) <br/> For example: <br/> <pre>func BadRead(f *os.File, buf []byte) error {<br/> var err error<br/> for {<br/> n, err := f.Read(buf) // shadows the function variable 'err'<br/> if err != nil {<br/> break // causes return of wrong value<br/> }<br/> foo(buf)<br/> }<br/> return err<br/>}</pre><br/> <br/> Default: `false` |
| `shift` | check for shifts that equal or exceed the width of the integer <br/> Default: `true` |
@@ -840,7 +840,7 @@
<br/>
Allowed Options: `CaseInsensitive`, `CaseSensitive`, `FastFuzzy`, `Fuzzy`
-Default: `"Fuzzy"`
+Default: `"FastFuzzy"`
### `ui.navigation.symbolStyle`
(Advanced) symbolStyle controls how symbols are qualified in symbol responses.
diff --git a/package.json b/package.json
index dfc8948..e8ee774 100644
--- a/package.json
+++ b/package.json
@@ -2272,7 +2272,7 @@
},
"noresultvalues": {
"type": "boolean",
- "markdownDescription": "suggested fixes for \"no result values expected\"\n\nThis checker provides suggested fixes for type errors of the\ntype \"no result values expected\". For example:\n\tfunc z() { return nil }\nwill turn into\n\tfunc z() { return }\n",
+ "markdownDescription": "suggested fixes for unexpected return values\n\nThis checker provides suggested fixes for type errors of the\ntype \"no result values expected\" or \"too many return values\".\nFor example:\n\tfunc z() { return nil }\nwill turn into\n\tfunc z() { return }\n",
"default": true
},
"printf": {
@@ -2485,7 +2485,7 @@
"",
""
],
- "default": "Fuzzy",
+ "default": "FastFuzzy",
"scope": "resource"
},
"ui.navigation.symbolStyle": {
diff --git a/src/goOutline.ts b/src/goOutline.ts
index 8c9a8f7..9251835 100644
--- a/src/goOutline.ts
+++ b/src/goOutline.ts
@@ -7,10 +7,13 @@
'use strict';
import cp = require('child_process');
+import semver = require('semver');
import vscode = require('vscode');
+import { ExecuteCommandParams, ExecuteCommandRequest } from 'vscode-languageserver-protocol';
import { getGoConfig } from './config';
import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool, promptForUpdatingTool } from './goInstallTools';
+import { getLocalGoplsVersion, languageClient, latestConfig } from './goLanguageServer';
import { getBinPath, getFileArchive, makeMemoizedByteOffsetConverter } from './util';
import { killProcess } from './utils/processUtils';
@@ -192,14 +195,63 @@
export class GoDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
constructor(private includeImports?: boolean) {}
- public provideDocumentSymbols(
+ public async provideDocumentSymbols(
document: vscode.TextDocument,
token: vscode.CancellationToken
- ): Thenable<vscode.DocumentSymbol[]> {
+ ): Promise<vscode.DocumentSymbol[]> {
if (typeof this.includeImports !== 'boolean') {
const gotoSymbolConfig = getGoConfig(document.uri)['gotoSymbol'];
this.includeImports = gotoSymbolConfig ? gotoSymbolConfig['includeImports'] : false;
}
+
+ // TODO(suzmue): Check the commands available instead of the version.
+ const goplsVersion = await getLocalGoplsVersion(latestConfig);
+ const sv = semver.parse(goplsVersion, true);
+ if (languageClient && (goplsVersion === '(devel)' || semver.gt(sv, 'v0.7.6'))) {
+ const symbols: vscode.DocumentSymbol[] = await vscode.commands.executeCommand(
+ 'vscode.executeDocumentSymbolProvider',
+ document.uri
+ );
+ if (!symbols || symbols.length === 0) {
+ return [];
+ }
+
+ // Stitch the results together to make the results look like
+ // go-outline.
+ // TODO(suzmue): use regexp to find the package declaration.
+ const packageSymbol = new vscode.DocumentSymbol(
+ 'unknown',
+ 'package',
+ vscode.SymbolKind.Package,
+ new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 0)),
+ new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 0))
+ );
+ packageSymbol.children = symbols;
+ if (this.includeImports) {
+ try {
+ const imports = await listImports(document);
+ imports?.forEach((value) => {
+ packageSymbol.children.unshift(
+ new vscode.DocumentSymbol(
+ value.Path,
+ 'import',
+ vscode.SymbolKind.Namespace,
+ new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 0)),
+ new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 0))
+ )
+ );
+ });
+ } catch (e) {
+ // Fall back to use go-outline.
+ return this.runGoOutline(document, token);
+ }
+ }
+ return [packageSymbol];
+ }
+ return this.runGoOutline(document, token);
+ }
+
+ private runGoOutline(document: vscode.TextDocument, token: vscode.CancellationToken) {
const options: GoOutlineOptions = {
fileName: document.fileName,
document,
@@ -208,3 +260,17 @@
return documentSymbols(options, token);
}
}
+
+async function listImports(document: vscode.TextDocument): Promise<{ Path: string; Name: string }[]> {
+ const uri = languageClient.code2ProtocolConverter.asTextDocumentIdentifier(document).uri;
+ const params: ExecuteCommandParams = {
+ command: 'gopls.list_imports',
+ arguments: [
+ {
+ URI: uri
+ }
+ ]
+ };
+ const resp = await languageClient.sendRequest(ExecuteCommandRequest.type, params);
+ return resp.Imports;
+}
diff --git a/src/goTest/resolve.ts b/src/goTest/resolve.ts
index f1fb8c1..a4b4491 100644
--- a/src/goTest/resolve.ts
+++ b/src/goTest/resolve.ts
@@ -24,6 +24,7 @@
import { getGoConfig } from '../config';
import { dispose, disposeIfEmpty, FileSystem, GoTest, GoTestKind, isInTest, Workspace } from './utils';
import { walk, WalkStop } from './walk';
+import { importsTestify } from '../testUtils';
export type ProvideSymbols = (doc: TextDocument, token: CancellationToken) => Thenable<DocumentSymbol[]>;
@@ -202,11 +203,7 @@
const seen = new Set<string>();
const item = await this.getFile(doc.uri);
const symbols = await this.provideDocumentSymbols(doc, null);
- const testify = symbols.some((s) =>
- s.children.some(
- (sym) => sym.kind === SymbolKind.Namespace && sym.name === '"github.com/stretchr/testify/suite"'
- )
- );
+ const testify = importsTestify(symbols);
for (const symbol of symbols) {
await this.processSymbol(doc, item, seen, testify, symbol);
}
@@ -410,7 +407,7 @@
}
// Recursively process symbols that are nested
- if (symbol.kind !== SymbolKind.Function) {
+ if (symbol.kind !== SymbolKind.Function && symbol.kind !== SymbolKind.Method) {
for (const sym of symbol.children) await this.processSymbol(doc, file, seen, importsTestify, sym);
return;
}
diff --git a/src/testUtils.ts b/src/testUtils.ts
index d340168..2698bf6 100644
--- a/src/testUtils.ts
+++ b/src/testUtils.ts
@@ -154,12 +154,10 @@
return;
}
const children = symbol.children;
- const testify = children.some(
- (sym) => sym.kind === vscode.SymbolKind.Namespace && sym.name === '"github.com/stretchr/testify/suite"'
- );
+ const testify = importsTestify(symbols);
return children.filter(
(sym) =>
- sym.kind === vscode.SymbolKind.Function &&
+ (sym.kind === vscode.SymbolKind.Function || sym.kind === vscode.SymbolKind.Method) &&
(testFuncRegex.test(sym.name) || fuzzFuncRegx.test(sym.name) || (testify && testMethodRegex.test(sym.name)))
);
}
@@ -632,3 +630,15 @@
flags.splice(index, 2);
}
}
+
+export function importsTestify(syms: vscode.DocumentSymbol[]): boolean {
+ if (!syms || syms.length === 0 || !syms[0]) {
+ return false;
+ }
+ const children = syms[0].children;
+ return children.some(
+ (sym) =>
+ sym.kind === vscode.SymbolKind.Namespace &&
+ (sym.name === '"github.com/stretchr/testify/suite"' || sym.name === 'github.com/stretchr/testify/suite')
+ );
+}
diff --git a/tools/installtools/main.go b/tools/installtools/main.go
index d892bd2..b4a3f9e 100644
--- a/tools/installtools/main.go
+++ b/tools/installtools/main.go
@@ -17,7 +17,7 @@
dest string
}{
// TODO: auto-generate based on allTools.ts.in.
- {"golang.org/x/tools/gopls", "", ""},
+ {"golang.org/x/tools/gopls", "v0.8.0-pre.1", ""}, // TODO: make this not hardcoded
{"github.com/acroca/go-symbols", "", ""},
{"github.com/cweill/gotests/gotests", "", ""},
{"github.com/davidrjenni/reftools/cmd/fillstruct", "", ""},
To view, visit change 384574. To unsubscribe, or for help writing mail filters, visit settings.
1 comment:
File src/goOutline.ts:
if (languageClient && (goplsVersion === '(devel)' || semver.gt(sv, 'v0.7.6'))) {
We won't execute this code path since we are using the latest gopls. […]
Updates this to pick the current prerelease. will set a follow up to make the version # not hard coded.
To view, visit change 384574. To unsubscribe, or for help writing mail filters, visit settings.