From 55d6317a4f3670f159b762a37e046385b91d9583 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 30 May 2019 16:59:32 -0700 Subject: [PATCH] Don't update js/ts diagnostics if they have not changed Fixes #74633 This was the indirect cause of #74633. See that issue for an explaination of why it was problematic. In summary, updating diagnostics can retrigger code actions even if the user facing diagnostics have not actually changed --- .../src/features/diagnostics.ts | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/extensions/typescript-language-features/src/features/diagnostics.ts b/extensions/typescript-language-features/src/features/diagnostics.ts index a9de15ab539..25e867687be 100644 --- a/extensions/typescript-language-features/src/features/diagnostics.ts +++ b/extensions/typescript-language-features/src/features/diagnostics.ts @@ -6,6 +6,25 @@ import * as vscode from 'vscode'; import { ResourceMap } from '../utils/resourceMap'; import { DiagnosticLanguage, allDiagnosticLanguages } from '../utils/languageDescription'; +import * as arrays from '../utils/arrays'; + +function diagnosticsEquals(a: vscode.Diagnostic, b: vscode.Diagnostic): boolean { + if (a === b) { + return true; + } + + return a.code === b.code + && a.message === b.message + && a.severity === b.severity + && a.source === b.source + && a.range.isEqual(b.range) + && arrays.equals(a.relatedInformation || [], b.relatedInformation || [], (a, b) => { + return a.message === b.message + && a.location.range.isEqual(b.location.range) + && a.location.uri.fsPath === b.location.uri.fsPath; + }) + && arrays.equals(a.tags || [], b.tags || []); +} export const enum DiagnosticKind { Syntax, @@ -31,12 +50,10 @@ class FileDiagnostics { this.language = language; } - if (diagnostics.length === 0) { - const existing = this._diagnostics.get(kind); - if (!existing || existing && existing.length === 0) { - // No need to update - return false; - } + const existing = this._diagnostics.get(kind); + if (arrays.equals(existing || [], diagnostics, diagnosticsEquals)) { + // No need to update + return false; } this._diagnostics.set(kind, diagnostics);