Skip to content

Commit

Permalink
fix(NODE-6552): remove cache and use toStringTag in type helpers (#740)
Browse files Browse the repository at this point in the history
  • Loading branch information
nbbeeken authored Nov 27, 2024
1 parent dbeda2f commit 3ede13e
Showing 1 changed file with 30 additions and 51 deletions.
81 changes: 30 additions & 51 deletions src/parser/utils.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,44 @@
const map = new WeakMap<object, string>();
const TypedArrayPrototypeGetSymbolToStringTag = (() => {
// Type check system lovingly referenced from:
// https://github.com/nodejs/node/blob/7450332339ed40481f470df2a3014e2ec355d8d8/lib/internal/util/types.js#L13-L15
// eslint-disable-next-line @typescript-eslint/unbound-method -- the intention is to call this method with a bound value
const g = Object.getOwnPropertyDescriptor(
Object.getPrototypeOf(Uint8Array.prototype),
Symbol.toStringTag
)!.get!;

const TYPES = {
ArrayBuffer: '[object ArrayBuffer]',
SharedArrayBuffer: '[object SharedArrayBuffer]',
Uint8Array: '[object Uint8Array]',
BigInt64Array: '[object BigInt64Array]',
BigUint64Array: '[object BigUint64Array]',
RegExp: '[object RegExp]',
Map: '[object Map]',
Date: '[object Date]'
};

/**
* Retrieves the prototype.toString() of a value.
* If the value is an object, it will cache the result in a WeakMap for future use.
*/
function getPrototypeString(value: unknown): string {
let str = map.get(value as object);

if (!str) {
str = Object.prototype.toString.call(value);
if (value !== null && typeof value === 'object') {
map.set(value, str);
}
}
return str;
}

export function isAnyArrayBuffer(value: unknown): value is ArrayBuffer {
const type = getPrototypeString(value);
return type === TYPES.ArrayBuffer || type === TYPES.SharedArrayBuffer;
}
return (value: unknown) => g.call(value);
})();

export function isUint8Array(value: unknown): value is Uint8Array {
const type = getPrototypeString(value);
return type === TYPES.Uint8Array;
return TypedArrayPrototypeGetSymbolToStringTag(value) === 'Uint8Array';
}

export function isBigInt64Array(value: unknown): value is BigInt64Array {
const type = getPrototypeString(value);
return type === TYPES.BigInt64Array;
}

export function isBigUInt64Array(value: unknown): value is BigUint64Array {
const type = getPrototypeString(value);
return type === TYPES.BigUint64Array;
export function isAnyArrayBuffer(value: unknown): value is ArrayBuffer {
return (
typeof value === 'object' &&
value != null &&
Symbol.toStringTag in value &&
(value[Symbol.toStringTag] === 'ArrayBuffer' ||
value[Symbol.toStringTag] === 'SharedArrayBuffer')
);
}

export function isRegExp(d: unknown): d is RegExp {
const type = getPrototypeString(d);
return type === TYPES.RegExp;
export function isRegExp(regexp: unknown): regexp is RegExp {
return regexp instanceof RegExp || Object.prototype.toString.call(regexp) === '[object RegExp]';
}

export function isMap(d: unknown): d is Map<unknown, unknown> {
const type = getPrototypeString(d);
return type === TYPES.Map;
export function isMap(value: unknown): value is Map<unknown, unknown> {
return (
typeof value === 'object' &&
value != null &&
Symbol.toStringTag in value &&
value[Symbol.toStringTag] === 'Map'
);
}

export function isDate(d: unknown): d is Date {
const type = getPrototypeString(d);
return type === TYPES.Date;
export function isDate(date: unknown): date is Date {
return date instanceof Date || Object.prototype.toString.call(date) === '[object Date]';
}

export type InspectFn = (x: unknown, options?: unknown) => string;
Expand Down

0 comments on commit 3ede13e

Please sign in to comment.