mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 20:38:55 +00:00
fix(console): never invoke Proxy traps when logging a Proxy
This commit is contained in:
parent
57cd2951f1
commit
0c26d9b638
@ -367,6 +367,9 @@ const nodeCustomInspectSymbol = SymbolFor("nodejs.util.inspect.custom");
|
||||
// Internal only, shouldn't be used by users.
|
||||
const privateCustomInspect = SymbolFor("Deno.privateCustomInspect");
|
||||
|
||||
// Used to keep track if it's a wrapped inspect proxy
|
||||
const privateCustomInspectProxy = SymbolFor("Deno.privateCustomInspectProxy");
|
||||
|
||||
function getUserOptions(ctx, isCrossContext) {
|
||||
const ret = {
|
||||
stylize: ctx.stylize,
|
||||
@ -618,7 +621,24 @@ function formatRaw(ctx, value, recurseTimes, typedArray, proxyDetails) {
|
||||
protoProps = undefined;
|
||||
}
|
||||
|
||||
let tag = value[SymbolToStringTag];
|
||||
let base = "";
|
||||
let formatter = () => [];
|
||||
let braces;
|
||||
let noIterator = true;
|
||||
let i = 0;
|
||||
const filter = ctx.showHidden ? 0 : 2;
|
||||
|
||||
let extrasType = kObjectType;
|
||||
|
||||
if (proxyDetails !== null && !ReflectGet(value, privateCustomInspectProxy)) {
|
||||
if (ctx.showProxy) {
|
||||
return `Proxy ` + formatValue(ctx, proxyDetails, recurseTimes);
|
||||
}
|
||||
|
||||
return formatValue(ctx, proxyDetails[0], recurseTimes);
|
||||
}
|
||||
|
||||
let tag = ReflectGet(value, SymbolToStringTag);
|
||||
// Only list the tag in case it's non-enumerable / not an own property.
|
||||
// Otherwise we'd print this twice.
|
||||
if (
|
||||
@ -634,294 +654,282 @@ function formatRaw(ctx, value, recurseTimes, typedArray, proxyDetails) {
|
||||
) {
|
||||
tag = "";
|
||||
}
|
||||
let base = "";
|
||||
let formatter = () => [];
|
||||
let braces;
|
||||
let noIterator = true;
|
||||
let i = 0;
|
||||
const filter = ctx.showHidden ? 0 : 2;
|
||||
|
||||
let extrasType = kObjectType;
|
||||
|
||||
if (proxyDetails !== null && ctx.showProxy) {
|
||||
return `Proxy ` + formatValue(ctx, proxyDetails, recurseTimes);
|
||||
} else {
|
||||
// Iterators and the rest are split to reduce checks.
|
||||
// We have to check all values in case the constructor is set to null.
|
||||
// Otherwise it would not possible to identify all types properly.
|
||||
if (ReflectHas(value, SymbolIterator) || constructor === null) {
|
||||
noIterator = false;
|
||||
if (ArrayIsArray(value)) {
|
||||
// Only set the constructor for non ordinary ("Array [...]") arrays.
|
||||
const prefix = (constructor !== "Array" || tag !== "")
|
||||
? getPrefix(constructor, tag, "Array", `(${value.length})`)
|
||||
: "";
|
||||
keys = op_get_non_index_property_names(value, filter);
|
||||
braces = [`${prefix}[`, "]"];
|
||||
if (
|
||||
value.length === 0 && keys.length === 0 && protoProps === undefined
|
||||
) {
|
||||
return `${braces[0]}]`;
|
||||
}
|
||||
extrasType = kArrayExtrasType;
|
||||
formatter = formatArray;
|
||||
} else if (
|
||||
(proxyDetails === null && isSet(value)) ||
|
||||
(proxyDetails !== null && isSet(proxyDetails[0]))
|
||||
// Iterators and the rest are split to reduce checks.
|
||||
// We have to check all values in case the constructor is set to null.
|
||||
// Otherwise it would not possible to identify all types properly.
|
||||
if (ReflectHas(value, SymbolIterator) || constructor === null) {
|
||||
noIterator = false;
|
||||
if (ArrayIsArray(value)) {
|
||||
// Only set the constructor for non ordinary ("Array [...]") arrays.
|
||||
const prefix = (constructor !== "Array" || tag !== "")
|
||||
? getPrefix(constructor, tag, "Array", `(${value.length})`)
|
||||
: "";
|
||||
keys = op_get_non_index_property_names(value, filter);
|
||||
braces = [`${prefix}[`, "]"];
|
||||
if (
|
||||
value.length === 0 && keys.length === 0 && protoProps === undefined
|
||||
) {
|
||||
const set = proxyDetails?.[0] ?? value;
|
||||
const size = SetPrototypeGetSize(set);
|
||||
const prefix = getPrefix(constructor, tag, "Set", `(${size})`);
|
||||
keys = getKeys(set, ctx.showHidden);
|
||||
formatter = constructor !== null
|
||||
? FunctionPrototypeBind(formatSet, null, set)
|
||||
: FunctionPrototypeBind(formatSet, null, SetPrototypeValues(set));
|
||||
if (size === 0 && keys.length === 0 && protoProps === undefined) {
|
||||
return `${prefix}{}`;
|
||||
}
|
||||
braces = [`${prefix}{`, "}"];
|
||||
} else if (
|
||||
(proxyDetails === null && isMap(value)) ||
|
||||
(proxyDetails !== null && isMap(proxyDetails[0]))
|
||||
) {
|
||||
const map = proxyDetails?.[0] ?? value;
|
||||
const size = MapPrototypeGetSize(map);
|
||||
const prefix = getPrefix(constructor, tag, "Map", `(${size})`);
|
||||
keys = getKeys(map, ctx.showHidden);
|
||||
formatter = constructor !== null
|
||||
? FunctionPrototypeBind(formatMap, null, map)
|
||||
: FunctionPrototypeBind(formatMap, null, MapPrototypeEntries(map));
|
||||
if (size === 0 && keys.length === 0 && protoProps === undefined) {
|
||||
return `${prefix}{}`;
|
||||
}
|
||||
braces = [`${prefix}{`, "}"];
|
||||
} else if (
|
||||
(proxyDetails === null && isTypedArray(value)) ||
|
||||
(proxyDetails !== null && isTypedArray(proxyDetails[0]))
|
||||
) {
|
||||
const typedArray = proxyDetails?.[0] ?? value;
|
||||
keys = op_get_non_index_property_names(typedArray, filter);
|
||||
const bound = typedArray;
|
||||
const fallback = "";
|
||||
if (constructor === null) {
|
||||
// TODO(wafuwafu13): Implement
|
||||
// fallback = TypedArrayPrototypeGetSymbolToStringTag(value);
|
||||
// // Reconstruct the array information.
|
||||
// bound = new primordials[fallback](value);
|
||||
}
|
||||
const size = TypedArrayPrototypeGetLength(typedArray);
|
||||
const prefix = getPrefix(constructor, tag, fallback, `(${size})`);
|
||||
braces = [`${prefix}[`, "]"];
|
||||
if (typedArray.length === 0 && keys.length === 0 && !ctx.showHidden) {
|
||||
return `${braces[0]}]`;
|
||||
}
|
||||
// Special handle the value. The original value is required below. The
|
||||
// bound function is required to reconstruct missing information.
|
||||
formatter = FunctionPrototypeBind(formatTypedArray, null, bound, size);
|
||||
extrasType = kArrayExtrasType;
|
||||
} else if (
|
||||
(proxyDetails === null && isMapIterator(value)) ||
|
||||
(proxyDetails !== null && isMapIterator(proxyDetails[0]))
|
||||
) {
|
||||
const mapIterator = proxyDetails?.[0] ?? value;
|
||||
keys = getKeys(mapIterator, ctx.showHidden);
|
||||
braces = getIteratorBraces("Map", tag);
|
||||
// Add braces to the formatter parameters.
|
||||
formatter = FunctionPrototypeBind(formatIterator, null, braces);
|
||||
} else if (
|
||||
(proxyDetails === null && isSetIterator(value)) ||
|
||||
(proxyDetails !== null && isSetIterator(proxyDetails[0]))
|
||||
) {
|
||||
const setIterator = proxyDetails?.[0] ?? value;
|
||||
keys = getKeys(setIterator, ctx.showHidden);
|
||||
braces = getIteratorBraces("Set", tag);
|
||||
// Add braces to the formatter parameters.
|
||||
formatter = FunctionPrototypeBind(formatIterator, null, braces);
|
||||
} else {
|
||||
noIterator = true;
|
||||
return `${braces[0]}]`;
|
||||
}
|
||||
extrasType = kArrayExtrasType;
|
||||
formatter = formatArray;
|
||||
} else if (
|
||||
(proxyDetails === null && isSet(value)) ||
|
||||
(proxyDetails !== null && isSet(proxyDetails[0]))
|
||||
) {
|
||||
const set = proxyDetails?.[0] ?? value;
|
||||
const size = SetPrototypeGetSize(set);
|
||||
const prefix = getPrefix(constructor, tag, "Set", `(${size})`);
|
||||
keys = getKeys(set, ctx.showHidden);
|
||||
formatter = constructor !== null
|
||||
? FunctionPrototypeBind(formatSet, null, set)
|
||||
: FunctionPrototypeBind(formatSet, null, SetPrototypeValues(set));
|
||||
if (size === 0 && keys.length === 0 && protoProps === undefined) {
|
||||
return `${prefix}{}`;
|
||||
}
|
||||
braces = [`${prefix}{`, "}"];
|
||||
} else if (
|
||||
(proxyDetails === null && isMap(value)) ||
|
||||
(proxyDetails !== null && isMap(proxyDetails[0]))
|
||||
) {
|
||||
const map = proxyDetails?.[0] ?? value;
|
||||
const size = MapPrototypeGetSize(map);
|
||||
const prefix = getPrefix(constructor, tag, "Map", `(${size})`);
|
||||
keys = getKeys(map, ctx.showHidden);
|
||||
formatter = constructor !== null
|
||||
? FunctionPrototypeBind(formatMap, null, map)
|
||||
: FunctionPrototypeBind(formatMap, null, MapPrototypeEntries(map));
|
||||
if (size === 0 && keys.length === 0 && protoProps === undefined) {
|
||||
return `${prefix}{}`;
|
||||
}
|
||||
braces = [`${prefix}{`, "}"];
|
||||
} else if (
|
||||
(proxyDetails === null && isTypedArray(value)) ||
|
||||
(proxyDetails !== null && isTypedArray(proxyDetails[0]))
|
||||
) {
|
||||
const typedArray = proxyDetails?.[0] ?? value;
|
||||
keys = op_get_non_index_property_names(typedArray, filter);
|
||||
const bound = typedArray;
|
||||
const fallback = "";
|
||||
if (constructor === null) {
|
||||
// TODO(wafuwafu13): Implement
|
||||
// fallback = TypedArrayPrototypeGetSymbolToStringTag(value);
|
||||
// // Reconstruct the array information.
|
||||
// bound = new primordials[fallback](value);
|
||||
}
|
||||
const size = TypedArrayPrototypeGetLength(typedArray);
|
||||
const prefix = getPrefix(constructor, tag, fallback, `(${size})`);
|
||||
braces = [`${prefix}[`, "]"];
|
||||
if (typedArray.length === 0 && keys.length === 0 && !ctx.showHidden) {
|
||||
return `${braces[0]}]`;
|
||||
}
|
||||
// Special handle the value. The original value is required below. The
|
||||
// bound function is required to reconstruct missing information.
|
||||
formatter = FunctionPrototypeBind(formatTypedArray, null, bound, size);
|
||||
extrasType = kArrayExtrasType;
|
||||
} else if (
|
||||
(proxyDetails === null && isMapIterator(value)) ||
|
||||
(proxyDetails !== null && isMapIterator(proxyDetails[0]))
|
||||
) {
|
||||
const mapIterator = proxyDetails?.[0] ?? value;
|
||||
keys = getKeys(mapIterator, ctx.showHidden);
|
||||
braces = getIteratorBraces("Map", tag);
|
||||
// Add braces to the formatter parameters.
|
||||
formatter = FunctionPrototypeBind(formatIterator, null, braces);
|
||||
} else if (
|
||||
(proxyDetails === null && isSetIterator(value)) ||
|
||||
(proxyDetails !== null && isSetIterator(proxyDetails[0]))
|
||||
) {
|
||||
const setIterator = proxyDetails?.[0] ?? value;
|
||||
keys = getKeys(setIterator, ctx.showHidden);
|
||||
braces = getIteratorBraces("Set", tag);
|
||||
// Add braces to the formatter parameters.
|
||||
formatter = FunctionPrototypeBind(formatIterator, null, braces);
|
||||
} else {
|
||||
noIterator = true;
|
||||
}
|
||||
if (noIterator) {
|
||||
keys = getKeys(value, ctx.showHidden);
|
||||
braces = ["{", "}"];
|
||||
if (constructor === "Object") {
|
||||
if (isArgumentsObject(value)) {
|
||||
braces[0] = "[Arguments] {";
|
||||
} else if (tag !== "") {
|
||||
braces[0] = `${getPrefix(constructor, tag, "Object")}{`;
|
||||
}
|
||||
if (keys.length === 0 && protoProps === undefined) {
|
||||
return `${braces[0]}}`;
|
||||
}
|
||||
} else if (typeof value === "function") {
|
||||
base = getFunctionBase(value, constructor, tag);
|
||||
if (keys.length === 0 && protoProps === undefined) {
|
||||
return ctx.stylize(base, "special");
|
||||
}
|
||||
} else if (
|
||||
(proxyDetails === null && isRegExp(value)) ||
|
||||
(proxyDetails !== null && isRegExp(proxyDetails[0]))
|
||||
) {
|
||||
const regExp = proxyDetails?.[0] ?? value;
|
||||
// Make RegExps say that they are RegExps
|
||||
base = RegExpPrototypeToString(
|
||||
constructor !== null ? regExp : new SafeRegExp(regExp),
|
||||
);
|
||||
const prefix = getPrefix(constructor, tag, "RegExp");
|
||||
if (prefix !== "RegExp ") {
|
||||
base = `${prefix}${base}`;
|
||||
}
|
||||
if (
|
||||
(keys.length === 0 && protoProps === undefined) ||
|
||||
(recurseTimes > ctx.depth && ctx.depth !== null)
|
||||
) {
|
||||
return ctx.stylize(base, "regexp");
|
||||
}
|
||||
} else if (
|
||||
(proxyDetails === null && isDate(value)) ||
|
||||
(proxyDetails !== null && isDate(proxyDetails[0]))
|
||||
) {
|
||||
const date = proxyDetails?.[0] ?? value;
|
||||
if (NumberIsNaN(DatePrototypeGetTime(date))) {
|
||||
return ctx.stylize("Invalid Date", "date");
|
||||
} else {
|
||||
base = DatePrototypeToISOString(date);
|
||||
if (keys.length === 0 && protoProps === undefined) {
|
||||
return ctx.stylize(base, "date");
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
proxyDetails === null &&
|
||||
ObjectPrototypeIsPrototypeOf(globalThis.Intl.Locale.prototype, value)
|
||||
) {
|
||||
braces[0] = `${getPrefix(constructor, tag, "Intl.Locale")}{`;
|
||||
ArrayPrototypeUnshift(
|
||||
keys,
|
||||
"baseName",
|
||||
"calendar",
|
||||
"caseFirst",
|
||||
"collation",
|
||||
"hourCycle",
|
||||
"language",
|
||||
"numberingSystem",
|
||||
"numeric",
|
||||
"region",
|
||||
"script",
|
||||
);
|
||||
} else if (
|
||||
proxyDetails === null &&
|
||||
typeof globalThis.Temporal !== "undefined" &&
|
||||
(
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.Instant.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.ZonedDateTime.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.PlainDate.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.PlainTime.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.PlainDateTime.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.PlainYearMonth.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.PlainMonthDay.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.Duration.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.TimeZone.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.Calendar.prototype,
|
||||
value,
|
||||
)
|
||||
)
|
||||
) {
|
||||
// Temporal is not available in primordials yet
|
||||
// deno-lint-ignore prefer-primordials
|
||||
return ctx.stylize(value.toString(), "temporal");
|
||||
} else if (
|
||||
(proxyDetails === null &&
|
||||
(isNativeError(value) ||
|
||||
ObjectPrototypeIsPrototypeOf(ErrorPrototype, value))) ||
|
||||
(proxyDetails !== null &&
|
||||
(isNativeError(proxyDetails[0]) ||
|
||||
ObjectPrototypeIsPrototypeOf(ErrorPrototype, proxyDetails[0])))
|
||||
) {
|
||||
const error = proxyDetails?.[0] ?? value;
|
||||
base = inspectError(error, ctx);
|
||||
if (keys.length === 0 && protoProps === undefined) {
|
||||
return base;
|
||||
}
|
||||
} else if (isAnyArrayBuffer(value)) {
|
||||
// Fast path for ArrayBuffer and SharedArrayBuffer.
|
||||
// Can't do the same for DataView because it has a non-primitive
|
||||
// .buffer property that we need to recurse for.
|
||||
const arrayType = isArrayBuffer(value)
|
||||
? "ArrayBuffer"
|
||||
: "SharedArrayBuffer";
|
||||
|
||||
const prefix = getPrefix(constructor, tag, arrayType);
|
||||
if (typedArray === undefined) {
|
||||
formatter = formatArrayBuffer;
|
||||
} else if (keys.length === 0 && protoProps === undefined) {
|
||||
return prefix +
|
||||
`{ byteLength: ${
|
||||
formatNumber(ctx.stylize, TypedArrayPrototypeGetByteLength(value))
|
||||
} }`;
|
||||
}
|
||||
braces[0] = `${prefix}{`;
|
||||
ArrayPrototypeUnshift(keys, "byteLength");
|
||||
} else if (isDataView(value)) {
|
||||
braces[0] = `${getPrefix(constructor, tag, "DataView")}{`;
|
||||
// .buffer goes last, it's not a primitive like the others.
|
||||
ArrayPrototypeUnshift(keys, "byteLength", "byteOffset", "buffer");
|
||||
} else if (isPromise(value)) {
|
||||
braces[0] = `${getPrefix(constructor, tag, "Promise")}{`;
|
||||
formatter = formatPromise;
|
||||
} else if (isWeakSet(value)) {
|
||||
braces[0] = `${getPrefix(constructor, tag, "WeakSet")}{`;
|
||||
formatter = ctx.showHidden ? formatWeakSet : formatWeakCollection;
|
||||
} else if (isWeakMap(value)) {
|
||||
braces[0] = `${getPrefix(constructor, tag, "WeakMap")}{`;
|
||||
formatter = ctx.showHidden ? formatWeakMap : formatWeakCollection;
|
||||
} else if (isModuleNamespaceObject(value)) {
|
||||
braces[0] = `${getPrefix(constructor, tag, "Module")}{`;
|
||||
// Special handle keys for namespace objects.
|
||||
formatter = FunctionPrototypeBind(formatNamespaceObject, null, keys);
|
||||
} else if (isBoxedPrimitive(value)) {
|
||||
base = getBoxedBase(value, ctx, keys, constructor, tag);
|
||||
if (keys.length === 0 && protoProps === undefined) {
|
||||
return base;
|
||||
}
|
||||
} else {
|
||||
if (keys.length === 0 && protoProps === undefined) {
|
||||
// TODO(wafuwafu13): Implement
|
||||
// if (isExternal(value)) {
|
||||
// const address = getExternalValue(value).toString(16);
|
||||
// return ctx.stylize(`[External: ${address}]`, 'special');
|
||||
// }
|
||||
return `${getCtxStyle(value, constructor, tag)}{}`;
|
||||
}
|
||||
braces[0] = `${getCtxStyle(value, constructor, tag)}{`;
|
||||
}
|
||||
if (noIterator) {
|
||||
keys = getKeys(value, ctx.showHidden);
|
||||
braces = ["{", "}"];
|
||||
if (constructor === "Object") {
|
||||
if (isArgumentsObject(value)) {
|
||||
braces[0] = "[Arguments] {";
|
||||
} else if (tag !== "") {
|
||||
braces[0] = `${getPrefix(constructor, tag, "Object")}{`;
|
||||
}
|
||||
if (keys.length === 0 && protoProps === undefined) {
|
||||
return `${braces[0]}}`;
|
||||
}
|
||||
} else if (typeof value === "function") {
|
||||
base = getFunctionBase(value, constructor, tag);
|
||||
if (keys.length === 0 && protoProps === undefined) {
|
||||
return ctx.stylize(base, "special");
|
||||
}
|
||||
} else if (
|
||||
(proxyDetails === null && isRegExp(value)) ||
|
||||
(proxyDetails !== null && isRegExp(proxyDetails[0]))
|
||||
) {
|
||||
const regExp = proxyDetails?.[0] ?? value;
|
||||
// Make RegExps say that they are RegExps
|
||||
base = RegExpPrototypeToString(
|
||||
constructor !== null ? regExp : new SafeRegExp(regExp),
|
||||
);
|
||||
const prefix = getPrefix(constructor, tag, "RegExp");
|
||||
if (prefix !== "RegExp ") {
|
||||
base = `${prefix}${base}`;
|
||||
}
|
||||
if (
|
||||
(keys.length === 0 && protoProps === undefined) ||
|
||||
(recurseTimes > ctx.depth && ctx.depth !== null)
|
||||
) {
|
||||
return ctx.stylize(base, "regexp");
|
||||
}
|
||||
} else if (
|
||||
(proxyDetails === null && isDate(value)) ||
|
||||
(proxyDetails !== null && isDate(proxyDetails[0]))
|
||||
) {
|
||||
const date = proxyDetails?.[0] ?? value;
|
||||
if (NumberIsNaN(DatePrototypeGetTime(date))) {
|
||||
return ctx.stylize("Invalid Date", "date");
|
||||
} else {
|
||||
base = DatePrototypeToISOString(date);
|
||||
if (keys.length === 0 && protoProps === undefined) {
|
||||
return ctx.stylize(base, "date");
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
proxyDetails === null &&
|
||||
ObjectPrototypeIsPrototypeOf(globalThis.Intl.Locale.prototype, value)
|
||||
) {
|
||||
braces[0] = `${getPrefix(constructor, tag, "Intl.Locale")}{`;
|
||||
ArrayPrototypeUnshift(
|
||||
keys,
|
||||
"baseName",
|
||||
"calendar",
|
||||
"caseFirst",
|
||||
"collation",
|
||||
"hourCycle",
|
||||
"language",
|
||||
"numberingSystem",
|
||||
"numeric",
|
||||
"region",
|
||||
"script",
|
||||
);
|
||||
} else if (
|
||||
proxyDetails === null &&
|
||||
typeof globalThis.Temporal !== "undefined" &&
|
||||
(
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.Instant.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.ZonedDateTime.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.PlainDate.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.PlainTime.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.PlainDateTime.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.PlainYearMonth.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.PlainMonthDay.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.Duration.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.TimeZone.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.Calendar.prototype,
|
||||
value,
|
||||
)
|
||||
)
|
||||
) {
|
||||
// Temporal is not available in primordials yet
|
||||
// deno-lint-ignore prefer-primordials
|
||||
return ctx.stylize(value.toString(), "temporal");
|
||||
} else if (
|
||||
(proxyDetails === null &&
|
||||
(isNativeError(value) ||
|
||||
ObjectPrototypeIsPrototypeOf(ErrorPrototype, value))) ||
|
||||
(proxyDetails !== null &&
|
||||
(isNativeError(proxyDetails[0]) ||
|
||||
ObjectPrototypeIsPrototypeOf(ErrorPrototype, proxyDetails[0])))
|
||||
) {
|
||||
const error = proxyDetails?.[0] ?? value;
|
||||
base = inspectError(error, ctx);
|
||||
if (keys.length === 0 && protoProps === undefined) {
|
||||
return base;
|
||||
}
|
||||
} else if (isAnyArrayBuffer(value)) {
|
||||
// Fast path for ArrayBuffer and SharedArrayBuffer.
|
||||
// Can't do the same for DataView because it has a non-primitive
|
||||
// .buffer property that we need to recurse for.
|
||||
const arrayType = isArrayBuffer(value)
|
||||
? "ArrayBuffer"
|
||||
: "SharedArrayBuffer";
|
||||
|
||||
const prefix = getPrefix(constructor, tag, arrayType);
|
||||
if (typedArray === undefined) {
|
||||
formatter = formatArrayBuffer;
|
||||
} else if (keys.length === 0 && protoProps === undefined) {
|
||||
return prefix +
|
||||
`{ byteLength: ${
|
||||
formatNumber(ctx.stylize, TypedArrayPrototypeGetByteLength(value))
|
||||
} }`;
|
||||
}
|
||||
braces[0] = `${prefix}{`;
|
||||
ArrayPrototypeUnshift(keys, "byteLength");
|
||||
} else if (isDataView(value)) {
|
||||
braces[0] = `${getPrefix(constructor, tag, "DataView")}{`;
|
||||
// .buffer goes last, it's not a primitive like the others.
|
||||
ArrayPrototypeUnshift(keys, "byteLength", "byteOffset", "buffer");
|
||||
} else if (isPromise(value)) {
|
||||
braces[0] = `${getPrefix(constructor, tag, "Promise")}{`;
|
||||
formatter = formatPromise;
|
||||
} else if (isWeakSet(value)) {
|
||||
braces[0] = `${getPrefix(constructor, tag, "WeakSet")}{`;
|
||||
formatter = ctx.showHidden ? formatWeakSet : formatWeakCollection;
|
||||
} else if (isWeakMap(value)) {
|
||||
braces[0] = `${getPrefix(constructor, tag, "WeakMap")}{`;
|
||||
formatter = ctx.showHidden ? formatWeakMap : formatWeakCollection;
|
||||
} else if (isModuleNamespaceObject(value)) {
|
||||
braces[0] = `${getPrefix(constructor, tag, "Module")}{`;
|
||||
// Special handle keys for namespace objects.
|
||||
formatter = FunctionPrototypeBind(formatNamespaceObject, null, keys);
|
||||
} else if (isBoxedPrimitive(value)) {
|
||||
base = getBoxedBase(value, ctx, keys, constructor, tag);
|
||||
if (keys.length === 0 && protoProps === undefined) {
|
||||
return base;
|
||||
}
|
||||
} else {
|
||||
if (keys.length === 0 && protoProps === undefined) {
|
||||
// TODO(wafuwafu13): Implement
|
||||
// if (isExternal(value)) {
|
||||
// const address = getExternalValue(value).toString(16);
|
||||
// return ctx.stylize(`[External: ${address}]`, 'special');
|
||||
// }
|
||||
return `${getCtxStyle(value, constructor, tag)}{}`;
|
||||
}
|
||||
braces[0] = `${getCtxStyle(value, constructor, tag)}{`;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3441,6 +3449,10 @@ function inspect(
|
||||
return formatValue(ctx, value, 0);
|
||||
}
|
||||
|
||||
class FilteredProxy extends Proxy {
|
||||
privateCustomInspectProxy;
|
||||
}
|
||||
|
||||
/** Creates a proxy that represents a subset of the properties
|
||||
* of the original object optionally without evaluating the properties
|
||||
* in order to get the values. */
|
||||
@ -3454,6 +3466,8 @@ function createFilteredInspectProxy({ object, keys, evaluate }) {
|
||||
get(_target, key) {
|
||||
if (key === SymbolToStringTag) {
|
||||
return object.constructor?.name;
|
||||
} else if (key === privateCustomInspectProxy) {
|
||||
return true;
|
||||
} else if (ArrayPrototypeIncludes(keys, key)) {
|
||||
return ReflectGet(object, key);
|
||||
} else {
|
||||
|
@ -1919,6 +1919,52 @@ Deno.test(function consoleLogShouldNotThrowErrorWhenInputIsProxiedError() {
|
||||
});
|
||||
});
|
||||
|
||||
Deno.test(function consoleLogShouldNotInvokeProxyGetters() {
|
||||
mockConsole((console, out) => {
|
||||
const throw_ = () => {
|
||||
throw new Error();
|
||||
};
|
||||
const proxy = new Proxy(
|
||||
{ foo: 123 },
|
||||
{ get: throw_ },
|
||||
);
|
||||
console.log(proxy);
|
||||
assertStringIncludes(stripAnsiCode(out.toString()), "{ foo: 123 }\n");
|
||||
});
|
||||
});
|
||||
|
||||
Deno.test(function consoleLogShouldNotInvokeProxyHas() {
|
||||
mockConsole((console, out) => {
|
||||
const throw_ = () => {
|
||||
throw new Error();
|
||||
};
|
||||
const proxy = new Proxy(
|
||||
{},
|
||||
{
|
||||
get: throw_,
|
||||
has: throw_,
|
||||
},
|
||||
);
|
||||
console.log(proxy);
|
||||
assertStringIncludes(stripAnsiCode(out.toString()), "{}\n");
|
||||
});
|
||||
});
|
||||
|
||||
Deno.test(function consoleLogShouldNotInvokeProxyOwnDescriptor() {
|
||||
mockConsole((console, out) => {
|
||||
const proxy = new Proxy(
|
||||
{ x: 10 },
|
||||
{
|
||||
getOwnPropertyDescriptor: () => {
|
||||
throw new Error(`oops`);
|
||||
},
|
||||
},
|
||||
);
|
||||
console.log(proxy);
|
||||
assertStringIncludes(stripAnsiCode(out.toString()), "{ x: 10 }\n");
|
||||
});
|
||||
});
|
||||
|
||||
// console.dir test
|
||||
Deno.test(function consoleDir() {
|
||||
mockConsole((console, out) => {
|
||||
@ -2118,30 +2164,6 @@ Deno.test(function inspectProxy() {
|
||||
)),
|
||||
`{ key: "value" }`,
|
||||
);
|
||||
assertEquals(
|
||||
stripAnsiCode(Deno.inspect(
|
||||
new Proxy({}, {
|
||||
get(_target, key) {
|
||||
if (key === Symbol.toStringTag) {
|
||||
return "MyProxy";
|
||||
} else {
|
||||
return 5;
|
||||
}
|
||||
},
|
||||
getOwnPropertyDescriptor() {
|
||||
return {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
value: 5,
|
||||
};
|
||||
},
|
||||
ownKeys() {
|
||||
return ["prop1", "prop2"];
|
||||
},
|
||||
}),
|
||||
)),
|
||||
`Object [MyProxy] { prop1: 5, prop2: 5 }`,
|
||||
);
|
||||
assertEquals(
|
||||
stripAnsiCode(Deno.inspect(
|
||||
new Proxy([1, 2, 3], { get() {} }),
|
||||
|
Loading…
Reference in New Issue
Block a user