src/language/goLanguageServer: fix signature help trigger injection

Triggering signature help after completion was implemented by
injecting the followup command for each Method/Function type completion
item from the middleware. Unfortunately, we used a wrong enum
(lsp proto CompletionItemKind instead of vscode API's CompletionItemKind).
LSP enums are 0-based, while vscode API's enums are 1-based. As a result,
we failed to correctly inject trigger parameter hint action for Method
type completion items.

For golang/vscode-go#2515

Change-Id: Ib75dd8f14f421aad9b2a2682a8e7e0621b2effd9
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/446816
TryBot-Result: kokoro <noreply+kokoro@google.com>
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
Reviewed-by: Peter Weinberger <pjw@google.com>
diff --git a/src/language/goLanguageServer.ts b/src/language/goLanguageServer.ts
index 8aa5f60..69f389f 100644
--- a/src/language/goLanguageServer.ts
+++ b/src/language/goLanguageServer.ts
@@ -17,7 +17,6 @@
 import {
 	CancellationToken,
 	CloseAction,
-	CompletionItemKind,
 	ConfigurationParams,
 	ConfigurationRequest,
 	ErrorAction,
@@ -51,7 +50,7 @@
 } from '../util';
 import { getToolFromToolPath } from '../utils/pathUtils';
 import WebRequest = require('web-request');
-import { FoldingContext } from 'vscode';
+import { CompletionItemKind, FoldingContext } from 'vscode';
 import { ProvideFoldingRangeSignature } from 'vscode-languageclient/lib/common/foldingRange';
 import { daysBetween, getStateConfig, maybePromptForGoplsSurvey, timeDay, timeMinute } from '../goSurvey';
 import { maybePromptForDeveloperSurvey } from '../goDeveloperSurvey';
@@ -712,7 +711,7 @@
 	if (!extensionInfo.isPreview) {
 		return workspaceConfig;
 	}
-	if (!workspaceConfig['allExperiments']) {
+	if (workspaceConfig && !workspaceConfig['allExperiments']) {
 		workspaceConfig['allExperiments'] = true;
 	}
 	return workspaceConfig;
diff --git a/test/gopls/extension.test.ts b/test/gopls/extension.test.ts
index 3ed44b6..5cced68 100644
--- a/test/gopls/extension.test.ts
+++ b/test/gopls/extension.test.ts
@@ -205,8 +205,12 @@
 
 	test('Completion middleware', async () => {
 		const { uri } = await env.openDoc(testdataDir, 'gogetdocTestData', 'test.go');
-		const testCases: [string, vscode.Position, string][] = [['fmt.P<>', new vscode.Position(19, 6), 'Print']];
-		for (const [name, position, wantFilterText] of testCases) {
+		const testCases: [string, vscode.Position, string, vscode.CompletionItemKind][] = [
+			['fmt.P<>', new vscode.Position(19, 6), 'Print', vscode.CompletionItemKind.Function],
+			['xyz.H<>', new vscode.Position(41, 13), 'Hello', vscode.CompletionItemKind.Method]
+		];
+
+		for (const [name, position, wantFilterText, wantItemKind] of testCases) {
 			let list: vscode.CompletionList<vscode.CompletionItem> | undefined;
 			// Query completion items. We expect the hard coded filter text hack
 			// has been applied and gopls returns an incomplete list by default
@@ -237,6 +241,7 @@
 			// Alternative is to directly query the language client, but that will
 			// prevent us from detecting problems caused by issues between the language
 			// client library and the vscode.
+			let itemKindFound = false;
 			for (const item of list.items) {
 				if (item.kind === vscode.CompletionItemKind.Snippet) {
 					continue;
@@ -248,6 +253,9 @@
 						`(got ${item.filterText ?? item.label}, want ${wantFilterText})\n` +
 						`${JSON.stringify(item, null, 2)}`
 				);
+				if (item.kind === wantItemKind) {
+					itemKindFound = true;
+				}
 				if (
 					item.kind === vscode.CompletionItemKind.Method ||
 					item.kind === vscode.CompletionItemKind.Function
@@ -258,6 +266,7 @@
 					);
 				}
 			}
+			assert(itemKindFound, `failed to find expected item kind ${wantItemKind}: got ${JSON.stringify(list)}`);
 		}
 	});