Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/vs/base/common/objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,18 @@ export function equals(one: any, other: any): boolean {
* "Uncaught TypeError: Converting circular structure to JSON"
*/
export function safeStringify(obj: any): string {
const seen = new Set<any>();
return JSON.stringify(obj, (key, value) => {
if (isObject(value) || Array.isArray(value)) {
if (seen.has(value)) {
// Track only current ancestors so shared sibling references are serialized in full.
const ancestors: unknown[] = [];
return JSON.stringify(obj, function (this: unknown, key: string, value: unknown) {
if (typeof value === 'object' && value !== null) {
// `this` is the object holding `key`, pop the subtrees that are already done
while (ancestors.length > 0 && ancestors[ancestors.length - 1] !== this) {
ancestors.pop();
}
if (ancestors.includes(value)) {
return '[Circular]';
} else {
seen.add(value);
}
ancestors.push(value);
}
if (typeof value === 'bigint') {
return `[BigInt ${value.toString()}]`;
Expand Down
11 changes: 10 additions & 1 deletion src/vs/base/test/common/objects.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,22 @@ suite('Objects', () => {
friend: '[Circular]'
}
},
'[Circular]'
{
friend: {
friend: '[Circular]'
}
}
],
d: [1, '[Circular]', '[Circular]'],
e: '[BigInt 42]'
});
});

test('safeStringify does not treat shared references as circular', () => {
const shared = { a: 1 };
assert.strictEqual(objects.safeStringify([shared, { x: shared, y: [shared] }]), '[{"a":1},{"x":{"a":1},"y":[{"a":1}]}]');
});

test('stableStringify', () => {
// Stable key order regardless of insertion order
const a = { b: 1, a: 2, c: { y: 1, x: 2 } };
Expand Down