fix(console): inspect for {Set,Map}Iterator and Weak{Set,Map} (#21554)

This commit is contained in:
Kenta Moriuchi 2023-12-19 15:05:49 +09:00 committed by GitHub
parent 476f5d3deb
commit 68241234fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 204 additions and 200 deletions

View file

@ -268,6 +268,14 @@ Deno.test(function consoleTestStringifyCircular() {
"2018-12-10T02:26:59.002Z", "2018-12-10T02:26:59.002Z",
); );
assertEquals(stringify(new Set([1, 2, 3])), "Set(3) { 1, 2, 3 }"); assertEquals(stringify(new Set([1, 2, 3])), "Set(3) { 1, 2, 3 }");
assertEquals(
stringify(new Set([1, 2, 3]).values()),
"[Set Iterator] { 1, 2, 3 }",
);
assertEquals(
stringify(new Set([1, 2, 3]).entries()),
"[Set Entries] { [ 1, 1 ], [ 2, 2 ], [ 3, 3 ] }",
);
assertEquals( assertEquals(
stringify( stringify(
new Map([ new Map([
@ -277,6 +285,14 @@ Deno.test(function consoleTestStringifyCircular() {
), ),
`Map(2) { 1 => "one", 2 => "two" }`, `Map(2) { 1 => "one", 2 => "two" }`,
); );
assertEquals(
stringify(new Map([[1, "one"], [2, "two"]]).values()),
`[Map Iterator] { "one", "two" }`,
);
assertEquals(
stringify(new Map([[1, "one"], [2, "two"]]).entries()),
`[Map Entries] { [ 1, "one" ], [ 2, "two" ] }`,
);
assertEquals(stringify(new WeakSet()), "WeakSet { <items unknown> }"); assertEquals(stringify(new WeakSet()), "WeakSet { <items unknown> }");
assertEquals(stringify(new WeakMap()), "WeakMap { <items unknown> }"); assertEquals(stringify(new WeakMap()), "WeakMap { <items unknown> }");
assertEquals(stringify(Symbol(1)), `Symbol("1")`); assertEquals(stringify(Symbol(1)), `Symbol("1")`);
@ -378,13 +394,16 @@ Deno.test(function consoleTestStringifyFunctionWithPrototypeRemoved() {
assertEquals(stringify(f), "[Function (null prototype): f]"); assertEquals(stringify(f), "[Function (null prototype): f]");
const af = async function af() {}; const af = async function af() {};
Reflect.setPrototypeOf(af, null); Reflect.setPrototypeOf(af, null);
assertEquals(stringify(af), "[Function (null prototype): af]"); assertEquals(stringify(af), "[AsyncFunction (null prototype): af]");
const gf = function* gf() {}; const gf = function* gf() {};
Reflect.setPrototypeOf(gf, null); Reflect.setPrototypeOf(gf, null);
assertEquals(stringify(gf), "[Function (null prototype): gf]"); assertEquals(stringify(gf), "[GeneratorFunction (null prototype): gf]");
const agf = async function* agf() {}; const agf = async function* agf() {};
Reflect.setPrototypeOf(agf, null); Reflect.setPrototypeOf(agf, null);
assertEquals(stringify(agf), "[Function (null prototype): agf]"); assertEquals(
stringify(agf),
"[AsyncGeneratorFunction (null prototype): agf]",
);
}); });
Deno.test(function consoleTestStringifyFunctionWithProperties() { Deno.test(function consoleTestStringifyFunctionWithProperties() {
@ -1002,6 +1021,26 @@ Deno.test(function consoleTestStringifyIterableWhenGrouped() {
); );
}); });
Deno.test(function consoleTestIteratorValueAreNotConsumed() {
const setIterator = new Set([1, 2, 3]).values();
assertEquals(
stringify(setIterator),
"[Set Iterator] { 1, 2, 3 }",
);
assertEquals([...setIterator], [1, 2, 3]);
});
Deno.test(function consoleTestWeakSetAndWeakMapWithShowHidden() {
assertEquals(
stripColor(Deno.inspect(new WeakSet([{}]), { showHidden: true })),
"WeakSet { {} }",
);
assertEquals(
stripColor(Deno.inspect(new WeakMap([[{}, "foo"]]), { showHidden: true })),
'WeakMap { {} => "foo" }',
);
});
Deno.test(async function consoleTestStringifyPromises() { Deno.test(async function consoleTestStringifyPromises() {
const pendingPromise = new Promise((_res, _rej) => {}); const pendingPromise = new Promise((_res, _rej) => {});
assertEquals(stringify(pendingPromise), "Promise { <pending> }"); assertEquals(stringify(pendingPromise), "Promise { <pending> }");
@ -2279,7 +2318,7 @@ Deno.test(function inspectWithPrototypePollution() {
Deno.test(function inspectPromiseLike() { Deno.test(function inspectPromiseLike() {
assertEquals( assertEquals(
Deno.inspect(Object.create(Promise.prototype)), Deno.inspect(Object.create(Promise.prototype)),
"Promise { <unknown> }", "Promise {}",
); );
}); });

View file

@ -10,7 +10,6 @@ const {
ArrayBufferPrototypeGetByteLength, ArrayBufferPrototypeGetByteLength,
ArrayIsArray, ArrayIsArray,
ArrayPrototypeFill, ArrayPrototypeFill,
ArrayPrototypeConcat,
ArrayPrototypeFilter, ArrayPrototypeFilter,
ArrayPrototypeFind, ArrayPrototypeFind,
ArrayPrototypeForEach, ArrayPrototypeForEach,
@ -75,7 +74,6 @@ const {
ObjectPrototype, ObjectPrototype,
ObjectPrototypeIsPrototypeOf, ObjectPrototypeIsPrototypeOf,
ObjectPrototypePropertyIsEnumerable, ObjectPrototypePropertyIsEnumerable,
ObjectPrototypeToString,
ObjectSetPrototypeOf, ObjectSetPrototypeOf,
ObjectValues, ObjectValues,
Proxy, Proxy,
@ -135,22 +133,7 @@ const {
WeakMapPrototypeHas, WeakMapPrototypeHas,
WeakSetPrototypeHas, WeakSetPrototypeHas,
} = primordials; } = primordials;
const ops = core.ops;
// supposed to be in node/internal_binding/util.ts
export function previewEntries(iter, isKeyValue) {
if (isKeyValue) {
// deno-lint-ignore prefer-primordials
const arr = [...iter];
if (ArrayIsArray(arr[0]) && arr[0].length === 2) {
// deno-lint-ignore prefer-primordials
return [ArrayPrototypeConcat([], ...arr), true];
}
return [arr, false];
} else {
// deno-lint-ignore prefer-primordials
return [...iter];
}
}
let noColor = () => false; let noColor = () => false;
@ -284,19 +267,15 @@ function isObjectLike(value) {
return value !== null && typeof value === "object"; return value !== null && typeof value === "object";
} }
export function isAnyArrayBuffer(value) { function isAnyArrayBuffer(value) {
return isArrayBuffer(value) || isSharedArrayBuffer(value); return ops.op_is_any_arraybuffer(value);
} }
export function isArgumentsObject(value) { function isArgumentsObject(value) {
return ( return ops.op_is_arguments_object(value);
isObjectLike(value) &&
value[SymbolToStringTag] === undefined &&
ObjectPrototypeToString(value) === "[object Arguments]"
);
} }
export function isArrayBuffer(value) { function isArrayBuffer(value) {
try { try {
ArrayBufferPrototypeGetByteLength(value); ArrayBufferPrototypeGetByteLength(value);
return true; return true;
@ -305,21 +284,11 @@ export function isArrayBuffer(value) {
} }
} }
export function isAsyncFunction(value) { function isAsyncFunction(value) {
return ( return ops.op_is_async_function(value);
typeof value === "function" &&
(value[SymbolToStringTag] === "AsyncFunction")
);
} }
export function isAsyncGeneratorFunction(value) { function isBooleanObject(value) {
return (
typeof value === "function" &&
(value[SymbolToStringTag] === "AsyncGeneratorFunction")
);
}
export function isBooleanObject(value) {
if (!isObjectLike(value)) { if (!isObjectLike(value)) {
return false; return false;
} }
@ -332,7 +301,7 @@ export function isBooleanObject(value) {
} }
} }
export function isBoxedPrimitive( function isBoxedPrimitive(
value, value,
) { ) {
return ( return (
@ -344,27 +313,22 @@ export function isBoxedPrimitive(
); );
} }
export function isDataView(value) { function isDataView(value) {
return ( return (
ArrayBufferIsView(value) && ArrayBufferIsView(value) &&
TypedArrayPrototypeGetSymbolToStringTag(value) === undefined TypedArrayPrototypeGetSymbolToStringTag(value) === undefined
); );
} }
export function isTypedArray(value) { function isTypedArray(value) {
return TypedArrayPrototypeGetSymbolToStringTag(value) !== undefined; return TypedArrayPrototypeGetSymbolToStringTag(value) !== undefined;
} }
export function isGeneratorFunction( function isGeneratorFunction(value) {
value, return ops.op_is_generator_function(value);
) {
return (
typeof value === "function" &&
value[SymbolToStringTag] === "GeneratorFunction"
);
} }
export function isMap(value) { function isMap(value) {
try { try {
MapPrototypeGetSize(value); MapPrototypeGetSize(value);
return true; return true;
@ -373,33 +337,19 @@ export function isMap(value) {
} }
} }
export function isMapIterator( function isMapIterator(value) {
value, return ops.op_is_map_iterator(value);
) {
return (
isObjectLike(value) &&
value[SymbolToStringTag] === "Map Iterator"
);
} }
export function isModuleNamespaceObject( function isModuleNamespaceObject(value) {
value, return ops.op_is_module_namespace_object(value);
) {
return (
isObjectLike(value) &&
value[SymbolToStringTag] === "Module"
);
} }
export function isNativeError(value) { function isNativeError(value) {
return ( return ops.op_is_native_error(value);
isObjectLike(value) &&
value[SymbolToStringTag] === undefined &&
ObjectPrototypeToString(value) === "[object Error]"
);
} }
export function isNumberObject(value) { function isNumberObject(value) {
if (!isObjectLike(value)) { if (!isObjectLike(value)) {
return false; return false;
} }
@ -412,7 +362,7 @@ export function isNumberObject(value) {
} }
} }
export function isBigIntObject(value) { function isBigIntObject(value) {
if (!isObjectLike(value)) { if (!isObjectLike(value)) {
return false; return false;
} }
@ -425,21 +375,15 @@ export function isBigIntObject(value) {
} }
} }
export function isPromise(value) { function isPromise(value) {
return ( return ops.op_is_promise(value);
isObjectLike(value) &&
value[SymbolToStringTag] === "Promise"
);
}
export function isRegExp(value) {
return (
isObjectLike(value) &&
value[SymbolToStringTag] === undefined &&
ObjectPrototypeToString(value) === "[object RegExp]"
);
} }
export function isSet(value) { function isRegExp(value) {
return ops.op_is_reg_exp(value);
}
function isSet(value) {
try { try {
SetPrototypeGetSize(value); SetPrototypeGetSize(value);
return true; return true;
@ -448,27 +392,11 @@ export function isSet(value) {
} }
} }
export function isSetIterator( function isSetIterator(value) {
value, return ops.op_is_set_iterator(value);
) {
return (
isObjectLike(value) &&
value[SymbolToStringTag] === "Set Iterator"
);
} }
export function isSharedArrayBuffer( function isStringObject(value) {
value,
) {
try {
getSharedArrayBufferByteLength(value);
return true;
} catch {
return false;
}
}
export function isStringObject(value) {
if (!isObjectLike(value)) { if (!isObjectLike(value)) {
return false; return false;
} }
@ -481,7 +409,7 @@ export function isStringObject(value) {
} }
} }
export function isSymbolObject(value) { function isSymbolObject(value) {
if (!isObjectLike(value)) { if (!isObjectLike(value)) {
return false; return false;
} }
@ -494,7 +422,7 @@ export function isSymbolObject(value) {
} }
} }
export function isWeakMap( function isWeakMap(
value, value,
) { ) {
try { try {
@ -505,7 +433,7 @@ export function isWeakMap(
} }
} }
export function isWeakSet( function isWeakSet(
value, value,
) { ) {
try { try {
@ -793,9 +721,6 @@ function getFunctionBase(value, constructor, tag) {
if (isAsyncFunction(value)) { if (isAsyncFunction(value)) {
type = `Async${type}`; type = `Async${type}`;
} }
if (isAsyncGeneratorFunction(value)) {
type = `AsyncGenerator${type}`;
}
let base = `[${type}`; let base = `[${type}`;
if (constructor === null) { if (constructor === null) {
base += " (null prototype)"; base += " (null prototype)";
@ -866,7 +791,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray, proxyDetails) {
const prefix = (constructor !== "Array" || tag !== "") const prefix = (constructor !== "Array" || tag !== "")
? getPrefix(constructor, tag, "Array", `(${value.length})`) ? getPrefix(constructor, tag, "Array", `(${value.length})`)
: ""; : "";
keys = core.ops.op_get_non_index_property_names(value, filter); keys = ops.op_get_non_index_property_names(value, filter);
braces = [`${prefix}[`, "]"]; braces = [`${prefix}[`, "]"];
if ( if (
value.length === 0 && keys.length === 0 && protoProps === undefined value.length === 0 && keys.length === 0 && protoProps === undefined
@ -1465,7 +1390,7 @@ function formatTypedArray(
) { ) {
const maxLength = MathMin(MathMax(0, ctx.maxArrayLength), length); const maxLength = MathMin(MathMax(0, ctx.maxArrayLength), length);
const remaining = value.length - maxLength; const remaining = value.length - maxLength;
const output = new Array(maxLength); const output = [];
const elementFormatter = value.length > 0 && typeof value[0] === "number" const elementFormatter = value.length > 0 && typeof value[0] === "number"
? formatNumber ? formatNumber
: formatBigInt; : formatBigInt;
@ -1508,7 +1433,7 @@ function getIteratorBraces(type, tag) {
const iteratorRegExp = new SafeRegExp(" Iterator] {$"); const iteratorRegExp = new SafeRegExp(" Iterator] {$");
function formatIterator(braces, ctx, value, recurseTimes) { function formatIterator(braces, ctx, value, recurseTimes) {
const { 0: entries, 1: isKeyValue } = previewEntries(value, true); const { 0: entries, 1: isKeyValue } = ops.op_preview_entries(value, true);
if (isKeyValue) { if (isKeyValue) {
// Mark entry iterators as such. // Mark entry iterators as such.
braces[0] = StringPrototypeReplace( braces[0] = StringPrototypeReplace(
@ -1625,7 +1550,7 @@ function inspectError(value, ctx) {
const hexSliceLookupTable = function () { const hexSliceLookupTable = function () {
const alphabet = "0123456789abcdef"; const alphabet = "0123456789abcdef";
const table = new Array(256); const table = [];
for (let i = 0; i < 16; ++i) { for (let i = 0; i < 16; ++i) {
const i16 = i * 16; const i16 = i * 16;
for (let j = 0; j < 16; ++j) { for (let j = 0; j < 16; ++j) {
@ -1689,14 +1614,7 @@ const PromiseState = {
function formatPromise(ctx, value, recurseTimes) { function formatPromise(ctx, value, recurseTimes) {
let output; let output;
let opResult; const { 0: state, 1: result } = core.getPromiseDetails(value);
// This op will fail for non-promises, but we get here for some promise-likes.
try {
opResult = core.getPromiseDetails(value);
} catch {
return [ctx.stylize("<unknown>", "special")];
}
const { 0: state, 1: result } = opResult;
if (state === PromiseState.Pending) { if (state === PromiseState.Pending) {
output = [ctx.stylize("<pending>", "special")]; output = [ctx.stylize("<pending>", "special")];
} else { } else {
@ -1717,12 +1635,12 @@ function formatWeakCollection(ctx) {
} }
function formatWeakSet(ctx, value, recurseTimes) { function formatWeakSet(ctx, value, recurseTimes) {
const entries = previewEntries(value); const entries = ops.op_preview_entries(value, false);
return formatSetIterInner(ctx, recurseTimes, entries, kWeak); return formatSetIterInner(ctx, recurseTimes, entries, kWeak);
} }
function formatWeakMap(ctx, value, recurseTimes) { function formatWeakMap(ctx, value, recurseTimes) {
const entries = previewEntries(value); const entries = ops.op_preview_entries(value, false);
return formatMapIterInner(ctx, recurseTimes, entries, kWeak); return formatMapIterInner(ctx, recurseTimes, entries, kWeak);
} }
@ -1843,7 +1761,7 @@ function formatNamespaceObject(
value, value,
recurseTimes, recurseTimes,
) { ) {
const output = new Array(keys.length); const output = [];
for (let i = 0; i < keys.length; i++) { for (let i = 0; i < keys.length; i++) {
try { try {
output[i] = formatProperty( output[i] = formatProperty(
@ -2062,7 +1980,7 @@ function groupArrayElements(ctx, output, value) {
outputLength--; outputLength--;
} }
const separatorSpace = 2; // Add 1 for the space and 1 for the separator. const separatorSpace = 2; // Add 1 for the space and 1 for the separator.
const dataLen = new Array(outputLength); const dataLen = [];
// Calculate the total length of all output entries and the individual max // Calculate the total length of all output entries and the individual max
// entries length of all output entries. We have to remove colors first, // entries length of all output entries. We have to remove colors first,
// otherwise the length would not be calculated properly. // otherwise the length would not be calculated properly.
@ -2176,7 +2094,7 @@ function formatMapIterInner(
const len = entries.length / 2; const len = entries.length / 2;
const remaining = len - maxArrayLength; const remaining = len - maxArrayLength;
const maxLength = MathMin(maxArrayLength, len); const maxLength = MathMin(maxArrayLength, len);
const output = new Array(maxLength); const output = [];
let i = 0; let i = 0;
ctx.indentationLvl += 2; ctx.indentationLvl += 2;
if (state === kWeak) { if (state === kWeak) {
@ -2227,7 +2145,7 @@ function formatSetIterInner(
) { ) {
const maxArrayLength = MathMax(ctx.maxArrayLength, 0); const maxArrayLength = MathMax(ctx.maxArrayLength, 0);
const maxLength = MathMin(maxArrayLength, entries.length); const maxLength = MathMin(maxArrayLength, entries.length);
const output = new Array(maxLength); const output = [];
ctx.indentationLvl += 2; ctx.indentationLvl += 2;
for (let i = 0; i < maxLength; i++) { for (let i = 0; i < maxLength; i++) {
output[i] = formatValue(ctx, entries[i], recurseTimes); output[i] = formatValue(ctx, entries[i], recurseTimes);

View file

@ -1,8 +1,103 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use deno_core::op2;
use deno_core::v8;
use std::path::PathBuf; use std::path::PathBuf;
deno_core::extension!(deno_console, esm = ["01_console.js"],); deno_core::extension!(
deno_console,
ops = [
op_is_any_arraybuffer,
op_is_arguments_object,
op_is_async_function,
op_is_generator_function,
op_is_generator_object,
op_is_map_iterator,
op_is_module_namespace_object,
op_is_native_error,
op_is_promise,
op_is_reg_exp,
op_is_set_iterator,
op_preview_entries,
],
esm = ["01_console.js"],
);
pub fn get_declaration() -> PathBuf { pub fn get_declaration() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_console.d.ts") PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_console.d.ts")
} }
#[op2(fast)]
fn op_is_any_arraybuffer(value: &v8::Value) -> bool {
value.is_array_buffer() || value.is_shared_array_buffer()
}
#[op2(fast)]
pub fn op_is_arguments_object(value: &v8::Value) -> bool {
value.is_arguments_object()
}
#[op2(fast)]
pub fn op_is_async_function(value: &v8::Value) -> bool {
value.is_async_function()
}
#[op2(fast)]
pub fn op_is_generator_function(value: &v8::Value) -> bool {
value.is_generator_function()
}
#[op2(fast)]
pub fn op_is_generator_object(value: &v8::Value) -> bool {
value.is_generator_object()
}
#[op2(fast)]
pub fn op_is_map_iterator(value: &v8::Value) -> bool {
value.is_map_iterator()
}
#[op2(fast)]
pub fn op_is_module_namespace_object(value: &v8::Value) -> bool {
value.is_module_namespace_object()
}
#[op2(fast)]
pub fn op_is_native_error(value: &v8::Value) -> bool {
value.is_native_error()
}
#[op2(fast)]
pub fn op_is_promise(value: &v8::Value) -> bool {
value.is_promise()
}
#[op2(fast)]
pub fn op_is_reg_exp(value: &v8::Value) -> bool {
value.is_reg_exp()
}
#[op2(fast)]
pub fn op_is_set_iterator(value: &v8::Value) -> bool {
value.is_set_iterator()
}
#[op2]
pub fn op_preview_entries<'s>(
scope: &mut v8::HandleScope<'s>,
object: &v8::Object,
slow_path: bool,
) -> v8::Local<'s, v8::Value> {
let (entries, is_key_value) = object.preview_entries(scope);
match entries {
None => v8::undefined(scope).into(),
Some(entries) => {
if !slow_path {
return entries.into();
}
let ret: [v8::Local<v8::Value>; 2] =
[entries.into(), v8::Boolean::new(scope, is_key_value).into()];
v8::Array::new_with_elements(scope, &ret).into()
}
}
}

View file

@ -150,11 +150,6 @@ fn op_node_build_os() -> String {
env!("TARGET").split('-').nth(2).unwrap().to_string() env!("TARGET").split('-').nth(2).unwrap().to_string()
} }
#[op2(fast)]
fn op_is_any_arraybuffer(value: &v8::Value) -> bool {
value.is_array_buffer() || value.is_shared_array_buffer()
}
#[op2(fast)] #[op2(fast)]
fn op_node_is_promise_rejected(value: v8::Local<v8::Value>) -> bool { fn op_node_is_promise_rejected(value: v8::Local<v8::Value>) -> bool {
let Ok(promise) = v8::Local::<v8::Promise>::try_from(value) else { let Ok(promise) = v8::Local::<v8::Promise>::try_from(value) else {
@ -286,7 +281,6 @@ deno_core::extension!(deno_node,
ops::os::op_node_os_username<P>, ops::os::op_node_os_username<P>,
ops::os::op_geteuid<P>, ops::os::op_geteuid<P>,
op_node_build_os, op_node_build_os,
op_is_any_arraybuffer,
op_node_is_promise_rejected, op_node_is_promise_rejected,
op_npm_process_state, op_npm_process_state,
ops::require::op_require_init_paths, ops::require::op_require_init_paths,

View file

@ -4,6 +4,9 @@
// TODO(petamoriken): enable prefer-primordials for node polyfills // TODO(petamoriken): enable prefer-primordials for node polyfills
// deno-lint-ignore-file prefer-primordials // deno-lint-ignore-file prefer-primordials
import { core } from "ext:core/mod.js";
const ops = core.ops;
// Mock trace for now // Mock trace for now
const trace = () => {}; const trace = () => {};
import { import {
@ -17,7 +20,6 @@ import {
validateInteger, validateInteger,
validateObject, validateObject,
} from "ext:deno_node/internal/validators.mjs"; } from "ext:deno_node/internal/validators.mjs";
import { previewEntries } from "ext:deno_node/internal_binding/util.ts";
import { Buffer } from "node:buffer"; import { Buffer } from "node:buffer";
const { isBuffer } = Buffer; const { isBuffer } = Buffer;
import { import {
@ -500,7 +502,7 @@ const consoleMethods = {
let isKeyValue = false; let isKeyValue = false;
let i = 0; let i = 0;
if (mapIter) { if (mapIter) {
const res = previewEntries(tabularData, true); const res = ops.op_preview_entries(tabularData, true);
tabularData = res[0]; tabularData = res[0];
isKeyValue = res[1]; isKeyValue = res[1];
} }
@ -535,7 +537,7 @@ const consoleMethods = {
const setIter = isSetIterator(tabularData); const setIter = isSetIterator(tabularData);
if (setIter) { if (setIter) {
tabularData = previewEntries(tabularData); tabularData = ops.op_preview_entries(tabularData, false);
} }
const setlike = setIter || mapIter || isSet(tabularData); const setlike = setIter || mapIter || isSet(tabularData);

View file

@ -27,9 +27,6 @@
const { core } = globalThis.__bootstrap; const { core } = globalThis.__bootstrap;
const { ops } = core; const { ops } = core;
// https://tc39.es/ecma262/#sec-object.prototype.tostring
const _toString = Object.prototype.toString;
// https://tc39.es/ecma262/#sec-bigint.prototype.valueof // https://tc39.es/ecma262/#sec-bigint.prototype.valueof
const _bigIntValueOf = BigInt.prototype.valueOf; const _bigIntValueOf = BigInt.prototype.valueOf;
@ -94,11 +91,7 @@ export function isAnyArrayBuffer(
} }
export function isArgumentsObject(value: unknown): value is IArguments { export function isArgumentsObject(value: unknown): value is IArguments {
return ( return ops.op_is_arguments_object(value);
isObjectLike(value) &&
value[Symbol.toStringTag] === undefined &&
_toString.call(value) === "[object Arguments]"
);
} }
export function isArrayBuffer(value: unknown): value is ArrayBuffer { export function isArrayBuffer(value: unknown): value is ArrayBuffer {
@ -113,11 +106,7 @@ export function isArrayBuffer(value: unknown): value is ArrayBuffer {
export function isAsyncFunction( export function isAsyncFunction(
value: unknown, value: unknown,
): value is (...args: unknown[]) => Promise<unknown> { ): value is (...args: unknown[]) => Promise<unknown> {
return ( return ops.op_is_async_function(value);
typeof value === "function" &&
// @ts-ignore: function is a kind of object
value[Symbol.toStringTag] === "AsyncFunction"
);
} }
// deno-lint-ignore ban-types // deno-lint-ignore ban-types
@ -166,18 +155,11 @@ export function isDate(value: unknown): value is Date {
export function isGeneratorFunction( export function isGeneratorFunction(
value: unknown, value: unknown,
): value is GeneratorFunction { ): value is GeneratorFunction {
return ( return ops.op_is_generator_function(value);
typeof value === "function" &&
// @ts-ignore: function is a kind of object
value[Symbol.toStringTag] === "GeneratorFunction"
);
} }
export function isGeneratorObject(value: unknown): value is Generator { export function isGeneratorObject(value: unknown): value is Generator {
return ( return ops.op_is_generator_object(value);
isObjectLike(value) &&
value[Symbol.toStringTag] === "Generator"
);
} }
export function isMap(value: unknown): value is Map<unknown, unknown> { export function isMap(value: unknown): value is Map<unknown, unknown> {
@ -192,27 +174,17 @@ export function isMap(value: unknown): value is Map<unknown, unknown> {
export function isMapIterator( export function isMapIterator(
value: unknown, value: unknown,
): value is IterableIterator<[unknown, unknown]> { ): value is IterableIterator<[unknown, unknown]> {
return ( return ops.op_is_map_iterator(value);
isObjectLike(value) &&
value[Symbol.toStringTag] === "Map Iterator"
);
} }
export function isModuleNamespaceObject( export function isModuleNamespaceObject(
value: unknown, value: unknown,
): value is Record<string | number | symbol, unknown> { ): value is Record<string | number | symbol, unknown> {
return ( return ops.op_is_module_namespace_object(value);
isObjectLike(value) &&
value[Symbol.toStringTag] === "Module"
);
} }
export function isNativeError(value: unknown): value is Error { export function isNativeError(value: unknown): value is Error {
return ( return ops.op_is_native_error(value);
isObjectLike(value) &&
value[Symbol.toStringTag] === undefined &&
_toString.call(value) === "[object Error]"
);
} }
// deno-lint-ignore ban-types // deno-lint-ignore ban-types
@ -243,10 +215,7 @@ export function isBigIntObject(value: unknown): value is bigint {
} }
export function isPromise(value: unknown): value is Promise<unknown> { export function isPromise(value: unknown): value is Promise<unknown> {
return ( return ops.op_is_promise(value);
isObjectLike(value) &&
value[Symbol.toStringTag] === "Promise"
);
} }
export function isProxy( export function isProxy(
@ -256,11 +225,7 @@ export function isProxy(
} }
export function isRegExp(value: unknown): value is RegExp { export function isRegExp(value: unknown): value is RegExp {
return ( return ops.op_is_reg_exp(value);
isObjectLike(value) &&
value[Symbol.toStringTag] === undefined &&
_toString.call(value) === "[object RegExp]"
);
} }
export function isSet(value: unknown): value is Set<unknown> { export function isSet(value: unknown): value is Set<unknown> {
@ -275,10 +240,7 @@ export function isSet(value: unknown): value is Set<unknown> {
export function isSetIterator( export function isSetIterator(
value: unknown, value: unknown,
): value is IterableIterator<unknown> { ): value is IterableIterator<unknown> {
return ( return ops.op_is_set_iterator(value);
isObjectLike(value) &&
value[Symbol.toStringTag] === "Set Iterator"
);
} }
export function isSharedArrayBuffer( export function isSharedArrayBuffer(

View file

@ -129,5 +129,3 @@ export function getOwnNonIndexProperties(
} }
return result; return result;
} }
export { previewEntries } from "ext:deno_console/01_console.js";

View file

@ -109,15 +109,11 @@ export function isFunction(value: unknown): boolean {
return typeof value === "function"; return typeof value === "function";
} }
/** @deprecated Use util.types.RegExp() instead. */ /** @deprecated Use util.types.isRegExp() instead. */
export function isRegExp(value: unknown): boolean { export const isRegExp = types.isRegExp;
return types.isRegExp(value);
}
/** @deprecated Use util.types.isDate() instead. */ /** @deprecated Use util.types.isDate() instead. */
export function isDate(value: unknown): boolean { export const isDate = types.isDate;
return types.isDate(value);
}
/** @deprecated - use `value === null || (typeof value !== "object" && typeof value !== "function")` instead. */ /** @deprecated - use `value === null || (typeof value !== "object" && typeof value !== "function")` instead. */
export function isPrimitive(value: unknown): boolean { export function isPrimitive(value: unknown): boolean {