src/goMain: use lint tool's name as the lint diagnostic collection name

Fixes golang/vscode-go#948

Change-Id: I997d94eacd6b078da30174477700c5f2ee06c758
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/276972
Trust: Hyang-Ah Hana Kim <hyangah@gmail.com>
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Suzy Mueller <suzmue@golang.org>
diff --git a/src/goLint.ts b/src/goLint.ts
index 1cd4346..cad38de 100644
--- a/src/goLint.ts
+++ b/src/goLint.ts
@@ -42,7 +42,7 @@
 
 	goLint(documentUri, goConfig, scope)
 		.then((warnings) => {
-			handleDiagnosticErrors(editor ? editor.document : null, warnings, lintDiagnosticCollection);
+			handleDiagnosticErrors(editor ? editor.document : null, warnings, lintDiagnosticCollection, 'go-lint');
 			diagnosticsStatusBarItem.hide();
 		})
 		.catch((err) => {
diff --git a/src/goMain.ts b/src/goMain.ts
index cb8e3bb..d45c431 100644
--- a/src/goMain.ts
+++ b/src/goMain.ts
@@ -239,7 +239,9 @@
 
 	buildDiagnosticCollection = vscode.languages.createDiagnosticCollection('go');
 	ctx.subscriptions.push(buildDiagnosticCollection);
-	lintDiagnosticCollection = vscode.languages.createDiagnosticCollection('go-lint');
+	lintDiagnosticCollection = vscode.languages.createDiagnosticCollection(
+		lintDiagnosticCollectionName(getGoConfig()['lintTool'])
+	);
 	ctx.subscriptions.push(lintDiagnosticCollection);
 	vetDiagnosticCollection = vscode.languages.createDiagnosticCollection('go-vet');
 	ctx.subscriptions.push(vetDiagnosticCollection);
@@ -471,6 +473,15 @@
 					});
 				}
 			}
+			if (e.affectsConfiguration('go.lintTool')) {
+				const lintTool = lintDiagnosticCollectionName(updatedGoConfig['lintTool']);
+				if (lintDiagnosticCollection && lintDiagnosticCollection.name !== lintTool) {
+					lintDiagnosticCollection.dispose();
+					lintDiagnosticCollection = vscode.languages.createDiagnosticCollection(lintTool);
+					ctx.subscriptions.push(lintDiagnosticCollection);
+					// TODO: actively maintain our own disposables instead of keeping pushing to ctx.subscription.
+				}
+			}
 		})
 	);
 
@@ -947,3 +958,10 @@
 		}
 	}
 }
+
+function lintDiagnosticCollectionName(lintToolName: string) {
+	if (!lintToolName || lintToolName === 'golint') {
+		return 'go-lint';
+	}
+	return `go-${lintToolName}`;
+}
diff --git a/src/util.ts b/src/util.ts
index 9439481..2c3d3e0 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -845,7 +845,8 @@
 export function handleDiagnosticErrors(
 	document: vscode.TextDocument,
 	errors: ICheckResult[],
-	diagnosticCollection: vscode.DiagnosticCollection
+	diagnosticCollection: vscode.DiagnosticCollection,
+	diagnosticSource?: string
 ) {
 	diagnosticCollection.clear();
 
@@ -891,7 +892,8 @@
 		const range = new vscode.Range(error.line - 1, startColumn, error.line - 1, endColumn);
 		const severity = mapSeverityToVSCodeSeverity(error.severity);
 		const diagnostic = new vscode.Diagnostic(range, error.msg, severity);
-		diagnostic.source = diagnosticCollection.name;
+		// vscode uses source for deduping diagnostics.
+		diagnostic.source = diagnosticSource || diagnosticCollection.name;
 		let diagnostics = diagnosticMap.get(canonicalFile);
 		if (!diagnostics) {
 			diagnostics = [];