提交 a5561ad9 编写于 作者: J Johannes Rieken

don't update markers when there is no real change, #57875

上级 5bd80f00
......@@ -27,6 +27,14 @@ export function tail2<T>(arr: T[]): [T[], T] {
}
export function equals<T>(one: ReadonlyArray<T>, other: ReadonlyArray<T>, itemEquals: (a: T, b: T) => boolean = (a, b) => a === b): boolean {
if (one === other) {
return true;
}
if (!one || !other) {
return false;
}
if (one.length !== other.length) {
return false;
}
......
......@@ -9,9 +9,9 @@ import { IMarkerData, MarkerSeverity } from 'vs/platform/markers/common/markers'
import { URI } from 'vs/base/common/uri';
import * as vscode from 'vscode';
import { MainContext, MainThreadDiagnosticsShape, ExtHostDiagnosticsShape, IMainContext } from './extHost.protocol';
import { DiagnosticSeverity } from './extHostTypes';
import { DiagnosticSeverity, Diagnostic } from './extHostTypes';
import * as converter from './extHostTypeConverters';
import { mergeSort } from 'vs/base/common/arrays';
import { mergeSort, equals } from 'vs/base/common/arrays';
import { Event, Emitter, debounceEvent, mapEvent } from 'vs/base/common/event';
import { keys } from 'vs/base/common/map';
......@@ -62,9 +62,13 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
this._checkDisposed();
let toSync: vscode.Uri[];
let hasChanged = true;
if (first instanceof URI) {
// check if this has actually changed
hasChanged = hasChanged && !equals(diagnostics, this.get(first), Diagnostic.isEqual);
if (!diagnostics) {
// remove this entry
this.delete(first);
......@@ -103,6 +107,17 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
}
}
// send event for extensions
this._onDidChangeDiagnostics.fire(toSync);
// if nothing has changed then there is nothing else to do
// we have updated the diagnostics but we don't send a message
// to the renderer. tho we have still send an event for other
// extensions because the diagnostic might carry more information
// than known to us
if (!hasChanged) {
return;
}
// compute change and send to main side
const entries: [URI, IMarkerData[]][] = [];
for (let uri of toSync) {
......@@ -142,7 +157,6 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
entries.push([uri, marker]);
}
this._onDidChangeDiagnostics.fire(toSync);
this._proxy.$changeMany(this._owner, entries);
}
......
......@@ -14,7 +14,7 @@ import { IRelativePattern } from 'vs/base/common/glob';
import { relative } from 'path';
import { startsWith } from 'vs/base/common/strings';
import { values } from 'vs/base/common/map';
import { coalesce } from 'vs/base/common/arrays';
import { coalesce, equals } from 'vs/base/common/arrays';
export class Disposable {
......@@ -771,6 +771,18 @@ export class DiagnosticRelatedInformation {
this.location = location;
this.message = message;
}
static isEqual(a: DiagnosticRelatedInformation, b: DiagnosticRelatedInformation): boolean {
if (a === b) {
return true;
}
if (!a || !b) {
return false;
}
return a.message === b.message
&& a.location.range.isEqual(b.location.range)
&& a.location.uri.toString() === b.location.uri.toString();
}
}
export class Diagnostic {
......@@ -798,6 +810,23 @@ export class Diagnostic {
code: this.code,
};
}
static isEqual(a: Diagnostic, b: Diagnostic): boolean {
if (a === b) {
return true;
}
if (!a || !b) {
return false;
}
return a.message === b.message
&& a.severity === b.severity
&& a.code === b.code
&& a.severity === b.severity
&& a.source === b.source
&& a.range.isEqual(b.range)
&& equals(a.tags, b.tags)
&& equals(a.relatedInformation, b.relatedInformation, DiagnosticRelatedInformation.isEqual);
}
}
export class Hover {
......
......@@ -190,6 +190,31 @@ suite('ExtHostDiagnostics', () => {
lastEntries = undefined;
});
test('don\'t send message when not making a change', function () {
let changeCount = 0;
let eventCount = 0;
const emitter = new Emitter<any>();
emitter.event(_ => eventCount += 1);
const collection = new DiagnosticCollection('test', 'test', 100, new class extends DiagnosticsShape {
$changeMany() {
changeCount += 1;
}
}, emitter);
let uri = URI.parse('sc:hightower');
let diag = new Diagnostic(new Range(0, 0, 0, 1), 'ffff');
collection.set(uri, [diag]);
assert.equal(changeCount, 1);
assert.equal(eventCount, 1);
collection.set(uri, [diag]);
assert.equal(changeCount, 1);
assert.equal(eventCount, 2);
});
test('diagnostics collection, tuples and undefined (small array), #15585', function () {
const collection = new DiagnosticCollection('test', 'test', 100, new DiagnosticsShape(), new Emitter());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册