From 1f5fe4839413ec19ab12286e00fbd81540d80e27 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 30 Oct 2023 02:43:22 +0900 Subject: [PATCH 1/7] Update dlint version for CI --- tools/util.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/util.js b/tools/util.js index 1a4ee89be7defa..a9962fc56e8a7f 100644 --- a/tools/util.js +++ b/tools/util.js @@ -16,7 +16,7 @@ export { delay } from "../test_util/std/async/delay.ts"; // [toolName] --version output const versions = { "dprint": "dprint 0.40.0", - "dlint": "dlint 0.51.0", + "dlint": "dlint 0.52.2", }; export const ROOT_PATH = dirname(dirname(fromFileUrl(import.meta.url))); From da70e153addd45dddfe576cc96f22c23fe8fdb89 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 30 Oct 2023 03:20:24 +0900 Subject: [PATCH 2/7] Fix: primitive wrapper objects shouldn't be detected --- cli/tests/unit_node/util_test.ts | 9 ++-- ext/node/polyfills/util.ts | 78 ++++++++++++++++++++------------ 2 files changed, 53 insertions(+), 34 deletions(-) diff --git a/cli/tests/unit_node/util_test.ts b/cli/tests/unit_node/util_test.ts index 81794c856ff4c2..ef01c6698ca5c0 100644 --- a/cli/tests/unit_node/util_test.ts +++ b/cli/tests/unit_node/util_test.ts @@ -46,8 +46,8 @@ Deno.test({ name: "[util] isBoolean", fn() { assert(util.isBoolean(true)); - assert(util.isBoolean(new Boolean())); - assert(util.isBoolean(new Boolean(true))); + assert(!util.isBoolean(new Boolean())); + assert(!util.isBoolean(new Boolean(true))); assert(util.isBoolean(false)); assert(!util.isBoolean("deno")); assert(!util.isBoolean("true")); @@ -80,7 +80,7 @@ Deno.test({ name: "[util] isNumber", fn() { assert(util.isNumber(666)); - assert(util.isNumber(new Number(666))); + assert(!util.isNumber(new Number(666))); assert(!util.isNumber("999")); assert(!util.isNumber(null)); }, @@ -90,7 +90,7 @@ Deno.test({ name: "[util] isString", fn() { assert(util.isString("deno")); - assert(util.isString(new String("DIO"))); + assert(!util.isString(new String("DIO"))); assert(!util.isString(1337)); }, }); @@ -99,6 +99,7 @@ Deno.test({ name: "[util] isSymbol", fn() { assert(util.isSymbol(Symbol())); + assert(!util.isSymbol(Object(Symbol()))); assert(!util.isSymbol(123)); assert(!util.isSymbol("string")); }, diff --git a/ext/node/polyfills/util.ts b/ext/node/polyfills/util.ts index 69cd373d7450e9..1d628cc0615dbb 100644 --- a/ext/node/polyfills/util.ts +++ b/ext/node/polyfills/util.ts @@ -18,6 +18,28 @@ import { Buffer } from "node:buffer"; import { isDeepStrictEqual } from "ext:deno_node/internal/util/comparisons.ts"; import process from "node:process"; import { validateString } from "ext:deno_node/internal/validators.mjs"; +const primordials = globalThis.__bootstrap.primordials; +const { + ArrayIsArray, + ArrayPrototypeJoin, + Date, + DatePrototypeGetDate, + DatePrototypeGetHours, + DatePrototypeGetMiuntes, + DatePrototypeGetMonth, + DatePrototypeGetSeconds, + ErrorPrototype, + ObjectDefineProperty, + ObjectKeys, + ObjectPrototypeIsPrototypeOf, + ObjectSetPrototypeOf, + ReflectApply, + ReflectConstruct, + SafeSet, + SetPrototypeAdd, + SetPrototypeHas, + StringPrototypePadStart, +} = primordials; export { callbackify, @@ -31,13 +53,11 @@ export { }; /** @deprecated - use `Array.isArray()` instead. */ -export function isArray(value: unknown): boolean { - return Array.isArray(value); -} +export const isArray = ArrayIsArray; -/** @deprecated - use `typeof value === "boolean" || value instanceof Boolean` instead. */ +/** @deprecated - use `typeof value === "boolean" instead. */ export function isBoolean(value: unknown): boolean { - return typeof value === "boolean" || value instanceof Boolean; + return typeof value === "boolean"; } /** @deprecated - use `value === null` instead. */ @@ -50,14 +70,14 @@ export function isNullOrUndefined(value: unknown): boolean { return value === null || value === undefined; } -/** @deprecated - use `typeof value === "number" || value instanceof Number` instead. */ +/** @deprecated - use `typeof value === "number" instead. */ export function isNumber(value: unknown): boolean { - return typeof value === "number" || value instanceof Number; + return typeof value === "number"; } -/** @deprecated - use `typeof value === "string" || value instanceof String` instead. */ +/** @deprecated - use `typeof value === "string" instead. */ export function isString(value: unknown): boolean { - return typeof value === "string" || value instanceof String; + return typeof value === "string"; } /** @deprecated - use `typeof value === "symbol"` instead. */ @@ -77,7 +97,7 @@ export function isObject(value: unknown): boolean { /** @deprecated - use `e instanceof Error` instead. */ export function isError(e: unknown): boolean { - return e instanceof Error; + return ObjectPrototypeIsPrototypeOf(ErrorPrototype, e); } /** @deprecated - use `typeof value === "function"` instead. */ @@ -103,9 +123,7 @@ export function isPrimitive(value: unknown): boolean { } /** @deprecated Use Buffer.isBuffer() instead. */ -export function isBuffer(value: unknown): boolean { - return Buffer.isBuffer(value); -} +export const isBuffer = Buffer.isBuffer; /** @deprecated Use Object.assign() instead. */ export function _extend( @@ -115,7 +133,7 @@ export function _extend( // Don't do anything if source isn't an object if (source === null || typeof source !== "object") return target; - const keys = Object.keys(source!); + const keys = ObjectKeys(source!); let i = keys.length; while (i--) { target[keys[i]] = (source as Record)[keys[i]]; @@ -147,12 +165,12 @@ export function inherits( superCtor.prototype, ); } - Object.defineProperty(ctor, "super_", { + ObjectDefineProperty(ctor, "super_", { value: superCtor, writable: true, configurable: true, }); - Object.setPrototypeOf(ctor.prototype, superCtor.prototype); + ObjectSetPrototypeOf(ctor.prototype, superCtor.prototype); } import { @@ -170,7 +188,7 @@ export type TextEncoder = import("./_utils.ts")._TextEncoder; export const TextEncoder = _TextEncoder; function pad(n: number) { - return n.toString().padStart(2, "0"); + return StringPrototypePadStart(n.toString(), 2, "0"); } const months = [ @@ -193,12 +211,12 @@ const months = [ */ function timestamp(): string { const d = new Date(); - const t = [ - pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds()), - ].join(":"); - return `${(d.getDate())} ${months[d.getMonth()]} ${t}`; + const t = ArrayPrototypeJoin([ + pad(DatePrototypeGetHours(d)), + pad(DatePrototypeGetMiuntes(d)), + pad(DatePrototypeGetSeconds(d)), + ], ":"); + return `${DatePrototypeGetDate(d)} ${months[DatePrototypeGetMonth(d)]} ${t}`; } /** @@ -207,12 +225,12 @@ function timestamp(): string { */ // deno-lint-ignore no-explicit-any export function log(...args: any[]) { - console.log("%s - %s", timestamp(), format(...args)); + console.log("%s - %s", timestamp(), ReflectApply(format, undefined, args)); } // Keep a list of deprecation codes that have been warned on so we only warn on // each one once. -const codesWarned = new Set(); +const codesWarned = new SafeSet(); // Mark that a method should not be used. // Returns a modified function which warns once by default. @@ -233,9 +251,9 @@ export function deprecate(fn: any, msg: string, code?: any) { if (!warned) { warned = true; if (code !== undefined) { - if (!codesWarned.has(code)) { + if (!SetPrototypeHas(codesWarned, code)) { process.emitWarning(msg, "DeprecationWarning", code, deprecated); - codesWarned.add(code); + SetPrototypeAdd(codesWarned, code); } } else { // deno-lint-ignore no-explicit-any @@ -243,13 +261,13 @@ export function deprecate(fn: any, msg: string, code?: any) { } } if (new.target) { - return Reflect.construct(fn, args, new.target); + return ReflectConstruct(fn, args, new.target); } - return Reflect.apply(fn, this, args); + return ReflectApply(fn, this, args); } // The wrapper will keep the same prototype as fn to maintain prototype chain - Object.setPrototypeOf(deprecated, fn); + ObjectSetPrototypeOf(deprecated, fn); if (fn.prototype) { // Setting this (rather than using Object.setPrototype, as above) ensures // that calling the unwrapped constructor gives an instanceof the wrapped From f35fad42b8edaa074258f8da071d072ac41bed0c Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 30 Oct 2023 03:20:39 +0900 Subject: [PATCH 3/7] Fix: `util.isError` should also check `[[ErrorData]]` internal slot --- cli/tests/unit_node/util_test.ts | 2 +- ext/node/polyfills/util.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cli/tests/unit_node/util_test.ts b/cli/tests/unit_node/util_test.ts index ef01c6698ca5c0..64020141a13a4e 100644 --- a/cli/tests/unit_node/util_test.ts +++ b/cli/tests/unit_node/util_test.ts @@ -129,7 +129,7 @@ Deno.test({ name: "[util] isError", fn() { const java = new Error(); - const nodejs = new TypeError(); + const nodejs = Reflect.construct(Error, [], Object); const deno = "Future"; assert(util.isError(java)); assert(util.isError(nodejs)); diff --git a/ext/node/polyfills/util.ts b/ext/node/polyfills/util.ts index 1d628cc0615dbb..984f6eaafd7aef 100644 --- a/ext/node/polyfills/util.ts +++ b/ext/node/polyfills/util.ts @@ -32,6 +32,7 @@ const { ObjectDefineProperty, ObjectKeys, ObjectPrototypeIsPrototypeOf, + ObjectPrototypeToString, ObjectSetPrototypeOf, ReflectApply, ReflectConstruct, @@ -97,7 +98,7 @@ export function isObject(value: unknown): boolean { /** @deprecated - use `e instanceof Error` instead. */ export function isError(e: unknown): boolean { - return ObjectPrototypeIsPrototypeOf(ErrorPrototype, e); + return ObjectPrototypeToString(e) === "[object Error]" || ObjectPrototypeIsPrototypeOf(ErrorPrototype, e); } /** @deprecated - use `typeof value === "function"` instead. */ From 5272fb9f68e554c565571424314937c5a5ed3a0d Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 30 Oct 2023 03:52:19 +0900 Subject: [PATCH 4/7] Chore: enable prefer-primordials --- ext/node/polyfills/util.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ext/node/polyfills/util.ts b/ext/node/polyfills/util.ts index 984f6eaafd7aef..4a5e61c487e040 100644 --- a/ext/node/polyfills/util.ts +++ b/ext/node/polyfills/util.ts @@ -1,8 +1,5 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -// TODO(petamoriken): enable prefer-primordials for node polyfills -// deno-lint-ignore-file prefer-primordials - import { promisify } from "ext:deno_node/internal/util.mjs"; import { callbackify } from "ext:deno_node/_util/_util_callbackify.ts"; import { debuglog } from "ext:deno_node/internal/util/debuglog.ts"; @@ -189,6 +186,7 @@ export type TextEncoder = import("./_utils.ts")._TextEncoder; export const TextEncoder = _TextEncoder; function pad(n: number) { + // deno-lint-ignore prefer-primordials return StringPrototypePadStart(n.toString(), 2, "0"); } From 73916aa394b73a8f919c41a04a6f90f9a58b5ed8 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 30 Oct 2023 03:52:41 +0900 Subject: [PATCH 5/7] Format --- ext/node/polyfills/util.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/node/polyfills/util.ts b/ext/node/polyfills/util.ts index 4a5e61c487e040..830bc7e779e97e 100644 --- a/ext/node/polyfills/util.ts +++ b/ext/node/polyfills/util.ts @@ -95,7 +95,8 @@ export function isObject(value: unknown): boolean { /** @deprecated - use `e instanceof Error` instead. */ export function isError(e: unknown): boolean { - return ObjectPrototypeToString(e) === "[object Error]" || ObjectPrototypeIsPrototypeOf(ErrorPrototype, e); + return ObjectPrototypeToString(e) === "[object Error]" || + ObjectPrototypeIsPrototypeOf(ErrorPrototype, e); } /** @deprecated - use `typeof value === "function"` instead. */ From d6ab5f69dc94f8b752edefb1071dd09c573f9aa6 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 30 Oct 2023 04:09:25 +0900 Subject: [PATCH 6/7] Fix --- ext/node/polyfills/util.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/node/polyfills/util.ts b/ext/node/polyfills/util.ts index 830bc7e779e97e..b1f884d9a893d0 100644 --- a/ext/node/polyfills/util.ts +++ b/ext/node/polyfills/util.ts @@ -26,6 +26,7 @@ const { DatePrototypeGetMonth, DatePrototypeGetSeconds, ErrorPrototype, + NumberPrototypeToString, ObjectDefineProperty, ObjectKeys, ObjectPrototypeIsPrototypeOf, @@ -187,8 +188,7 @@ export type TextEncoder = import("./_utils.ts")._TextEncoder; export const TextEncoder = _TextEncoder; function pad(n: number) { - // deno-lint-ignore prefer-primordials - return StringPrototypePadStart(n.toString(), 2, "0"); + return StringPrototypePadStart(NumberPrototypeToString(n), 2, "0"); } const months = [ From decf5366c60b2d0d55da8c69c340e999bf6290d5 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 30 Oct 2023 04:10:46 +0900 Subject: [PATCH 7/7] Fix typo --- ext/node/polyfills/util.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/node/polyfills/util.ts b/ext/node/polyfills/util.ts index b1f884d9a893d0..1b611b1fd58700 100644 --- a/ext/node/polyfills/util.ts +++ b/ext/node/polyfills/util.ts @@ -22,7 +22,7 @@ const { Date, DatePrototypeGetDate, DatePrototypeGetHours, - DatePrototypeGetMiuntes, + DatePrototypeGetMinutes, DatePrototypeGetMonth, DatePrototypeGetSeconds, ErrorPrototype, @@ -213,7 +213,7 @@ function timestamp(): string { const d = new Date(); const t = ArrayPrototypeJoin([ pad(DatePrototypeGetHours(d)), - pad(DatePrototypeGetMiuntes(d)), + pad(DatePrototypeGetMinutes(d)), pad(DatePrototypeGetSeconds(d)), ], ":"); return `${DatePrototypeGetDate(d)} ${months[DatePrototypeGetMonth(d)]} ${t}`;