From 2b7fc1809205dc95f9fff46ff29d1ec1a0077d88 Mon Sep 17 00:00:00 2001 From: robobun Date: Tue, 30 Sep 2025 04:45:34 -0700 Subject: [PATCH] fix(lint): resolve no-unused-expressions errors (#23127) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Fixes all oxlint `no-unused-expressions` violations across the codebase by: - Adding an oxlint override to disable the rule for `src/js/builtins/**`, where special syntax markers like `$getter`, `$constructor`, etc. are intentionally used as standalone expressions - Converting short-circuit expressions (`condition && fn()`) to proper if statements for improved code clarity - Wrapping intentional property access side effects (e.g., `this.stdio;`, `err.stack;`) with the `void` operator - Converting ternary expressions used for control flow to if/else statements ## Test plan - [x] `bun lint` passes with no errors 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Bot Co-authored-by: Claude Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- oxlint.json | 6 ++++++ src/js/bun/sqlite.ts | 16 ++++++++++------ src/js/internal/util/inspect.js | 4 ++-- src/js/node/_http_incoming.ts | 4 ++-- src/js/node/_http_server.ts | 15 ++++++++------- src/js/node/child_process.ts | 2 +- src/js/node/fs.ts | 6 ++++-- src/js/node/tls.ts | 8 ++++---- src/js/node/url.ts | 1 - src/js/thirdparty/node-fetch.ts | 12 ++++++------ src/js/thirdparty/ws.js | 20 ++++++++++---------- 11 files changed, 53 insertions(+), 41 deletions(-) diff --git a/oxlint.json b/oxlint.json index 60d61d72fb..68e55c74a1 100644 --- a/oxlint.json +++ b/oxlint.json @@ -78,6 +78,12 @@ "no-empty-file": "off", "no-unnecessary-await": "off" } + }, + { + "files": ["src/js/builtins/**"], + "rules": { + "no-unused-expressions": "off" + } } ] } diff --git a/src/js/bun/sqlite.ts b/src/js/bun/sqlite.ts index 395c0cd70b..f76ab69387 100644 --- a/src/js/bun/sqlite.ts +++ b/src/js/bun/sqlite.ts @@ -299,9 +299,11 @@ class Statement { var arg0 = args[0]; - !isArray(arg0) && (!arg0 || typeof arg0 !== "object" || isTypedArray(arg0)) - ? this.#raw.run(internalFieldTuple, args) - : this.#raw.run(internalFieldTuple, ...args); + if (!isArray(arg0) && (!arg0 || typeof arg0 !== "object" || isTypedArray(arg0))) { + this.#raw.run(internalFieldTuple, args); + } else { + this.#raw.run(internalFieldTuple, ...args); + } return createChangesObject(); } @@ -516,9 +518,11 @@ class Database implements SqliteTypes.Database { } var arg0 = params[0]; - !isArray(arg0) && (!arg0 || typeof arg0 !== "object" || isTypedArray(arg0)) - ? SQL.run(this.#handle, this.#internalFlags, internalFieldTuple, query, params) - : SQL.run(this.#handle, this.#internalFlags, internalFieldTuple, query, ...params); + if (!isArray(arg0) && (!arg0 || typeof arg0 !== "object" || isTypedArray(arg0))) { + SQL.run(this.#handle, this.#internalFlags, internalFieldTuple, query, params); + } else { + SQL.run(this.#handle, this.#internalFlags, internalFieldTuple, query, ...params); + } return createChangesObject(); } diff --git a/src/js/internal/util/inspect.js b/src/js/internal/util/inspect.js index 2a86431c76..52ad43eae7 100644 --- a/src/js/internal/util/inspect.js +++ b/src/js/internal/util/inspect.js @@ -339,7 +339,7 @@ const codes = {}; // exported from errors.js ErrorCaptureStackTrace(err); Error.stackTraceLimit = userStackTraceLimit; // Reset the limit err.name = `${TypeError.name} [${sym}]`; // Add the error code to the name to include it in the stack trace. - err.stack; // Access the stack to generate the error message including the error code from the name. + void err.stack; // Access the stack to generate the error message including the error code from the name. delete err.name; // Reset the name to the actual name. error.code = sym; return error; @@ -987,7 +987,7 @@ function initializeWellKnownPrototypes() { function getConstructorName(obj, ctx, recurseTimes, protoProps) { let firstProto; const tmp = obj; - wellKnownPrototypes ?? initializeWellKnownPrototypes(); + if (!wellKnownPrototypes) initializeWellKnownPrototypes(); while (obj || isUndetectableObject(obj)) { const wellKnownPrototypeNameAndConstructor = wellKnownPrototypes.get(obj); if (wellKnownPrototypeNameAndConstructor != null) { diff --git a/src/js/node/_http_incoming.ts b/src/js/node/_http_incoming.ts index cb3b92ccd4..aa8c1b993c 100644 --- a/src/js/node/_http_incoming.ts +++ b/src/js/node/_http_incoming.ts @@ -393,12 +393,12 @@ const IncomingMessagePrototype = { // noop }, setTimeout(msecs, callback) { - this.take; + void this.take; const req = this[kHandle] || this[webRequestOrResponse]; if (req) { setRequestTimeout(req, Math.ceil(msecs / 1000)); - typeof callback === "function" && this.once("timeout", callback); + if (typeof callback === "function") this.once("timeout", callback); } return this; }, diff --git a/src/js/node/_http_server.ts b/src/js/node/_http_server.ts index 9d9314074a..2981ae75ca 100644 --- a/src/js/node/_http_server.ts +++ b/src/js/node/_http_server.ts @@ -589,7 +589,7 @@ Server.prototype[kRealListen] = function (tls, port, host, socketPath, reusePort } function onClose() { didFinish = true; - resolveFunction && resolveFunction(); + if (resolveFunction) resolveFunction(); } setCloseCallback(http_res, onClose); @@ -732,7 +732,7 @@ Server.prototype.setTimeout = function (msecs, callback) { const server = this[serverSymbol]; if (server) { setServerIdleTimeout(server, Math.ceil(msecs / 1000)); - typeof callback === "function" && this.once("timeout", callback); + if (typeof callback === "function") this.once("timeout", callback); } else { (this[kDeferredTimeouts] ??= []).push({ msecs, callback }); } @@ -905,7 +905,7 @@ const NodeHTTPServerSocket = class Socket extends Duplex { } #onCloseForDestroy(closeCallback) { this.#onClose(); - $isCallable(closeCallback) && closeCallback(); + if ($isCallable(closeCallback)) closeCallback(); } _onTimeout() { @@ -937,7 +937,7 @@ const NodeHTTPServerSocket = class Socket extends Duplex { _destroy(err, callback) { const handle = this[kHandle]; if (!handle) { - $isCallable(callback) && callback(err); + if ($isCallable(callback)) callback(err); return; } handle.ondata = undefined; @@ -947,7 +947,7 @@ const NodeHTTPServerSocket = class Socket extends Duplex { if ($isCallable(onclose)) { onclose.$call(handle); } - $isCallable(callback) && callback(err); + if ($isCallable(callback)) callback(err); return; } @@ -1081,7 +1081,8 @@ const NodeHTTPServerSocket = class Socket extends Duplex { } catch (e) { err = e; } - err ? _callback(err) : _callback(); + if (err) _callback(err); + else _callback(); } pause() { @@ -1510,7 +1511,7 @@ ServerResponse.prototype._finish = function () { ServerResponse.prototype.detachSocket = function (socket) { if (socket._httpMessage === this) { - socket[kCloseCallback] && (socket[kCloseCallback] = undefined); + if (socket[kCloseCallback]) socket[kCloseCallback] = undefined; socket.removeListener("close", onServerResponseClose); socket._httpMessage = null; } diff --git a/src/js/node/child_process.ts b/src/js/node/child_process.ts index 35354dfdda..774397876d 100644 --- a/src/js/node/child_process.ts +++ b/src/js/node/child_process.ts @@ -1340,7 +1340,7 @@ class ChildProcess extends EventEmitter { if (hasSocketsToEagerlyLoad) { process.nextTick(() => { - this.stdio; + void this.stdio; $debug("ChildProcess: onExit", exitCode, signalCode, err, this.pid); }); } diff --git a/src/js/node/fs.ts b/src/js/node/fs.ts index d2d8aebad0..ae9a97eb1c 100644 --- a/src/js/node/fs.ts +++ b/src/js/node/fs.ts @@ -731,10 +731,11 @@ const realpathSync: typeof import("node:fs").realpathSync = if (options) { if (typeof options === "string") encoding = options; else encoding = options?.encoding; - encoding && + if (encoding) { (assertEncodingForWindows ?? $newZigFunction("bun.js/node/types.zig", "jsAssertEncodingValid", 1))( encoding, ); + } } // This function is ported 1:1 from node.js, to emulate how it is unable to // resolve subst drives to their underlying location. The native call is @@ -852,10 +853,11 @@ const realpath: typeof import("node:fs").realpath = if (options) { if (typeof options === "string") encoding = options; else encoding = options?.encoding; - encoding && + if (encoding) { (assertEncodingForWindows ?? $newZigFunction("bun.js/node/types.zig", "jsAssertEncodingValid", 1))( encoding, ); + } } if (p instanceof URL) { if (p.pathname.indexOf("%00") != -1) { diff --git a/src/js/node/tls.ts b/src/js/node/tls.ts index 25bbc96d8e..0933e71972 100644 --- a/src/js/node/tls.ts +++ b/src/js/node/tls.ts @@ -504,7 +504,7 @@ function TLSSocket(socket?, options?) { this._SNICallback = undefined; this.servername = undefined; this.authorized = false; - this.authorizationError; + void this.authorizationError; this[krenegotiationDisabled] = undefined; this.encrypted = true; @@ -582,7 +582,7 @@ TLSSocket.prototype.renegotiate = function renegotiate(options, callback) { if (this[krenegotiationDisabled]) { // if renegotiation is disabled should emit error event in nextTick for nodejs compatibility const error = $ERR_TLS_RENEGOTIATION_DISABLED(); - typeof callback === "function" && process.nextTick(callback, error); + if (typeof callback === "function") process.nextTick(callback, error); return false; } @@ -606,11 +606,11 @@ TLSSocket.prototype.renegotiate = function renegotiate(options, callback) { try { socket.renegotiate?.(); // if renegotiate is successful should emit secure event when done - typeof callback === "function" && this.once("secure", () => callback(null)); + if (typeof callback === "function") this.once("secure", () => callback(null)); return true; } catch (err) { // if renegotiate fails should emit error event in nextTick for nodejs compatibility - typeof callback === "function" && process.nextTick(callback, err); + if (typeof callback === "function") process.nextTick(callback, err); return false; } }; diff --git a/src/js/node/url.ts b/src/js/node/url.ts index ae3ebba001..75f0be4983 100644 --- a/src/js/node/url.ts +++ b/src/js/node/url.ts @@ -871,7 +871,6 @@ Url.prototype.parseHost = function parseHost() { if (host) this.hostname = host; }; -"".charCodeAt; // function fileURLToPath(...args) { // // Since we use WTF::URL::fileSystemPath directly in Bun.fileURLToPath, we don't get invalid windows // // path checking. We patch this in to `node:url` for compatibility. Note that diff --git a/src/js/thirdparty/node-fetch.ts b/src/js/thirdparty/node-fetch.ts index 42a5a7c275..82845195cb 100644 --- a/src/js/thirdparty/node-fetch.ts +++ b/src/js/thirdparty/node-fetch.ts @@ -69,25 +69,25 @@ class Response extends WebResponse { async arrayBuffer() { // load the getter - this.body; + void this.body; return await super.arrayBuffer(); } async blob() { // load the getter - this.body; + void this.body; return await super.blob(); } async formData() { // load the getter - this.body; + void this.body; return await super.formData(); } async json() { // load the getter - this.body; + void this.body; return await super.json(); } @@ -95,13 +95,13 @@ class Response extends WebResponse { // but is still used by some libraries and frameworks (like Astro) async buffer() { // load the getter - this.body; + void this.body; return new $Buffer(await super.arrayBuffer()); } async text() { // load the getter - this.body; + void this.body; return await super.text(); } diff --git a/src/js/thirdparty/ws.js b/src/js/thirdparty/ws.js index 024a2f5d3d..0a101e8149 100644 --- a/src/js/thirdparty/ws.js +++ b/src/js/thirdparty/ws.js @@ -262,12 +262,12 @@ class BunWebSocket extends EventEmitter { this.#ws.send(normalizeData(data, opts), opts?.compress); } catch (error) { // Node.js APIs expect callback arguments to be called after the current stack pops - typeof cb === "function" && process.nextTick(cb, error); + if (typeof cb === "function") process.nextTick(cb, error); return; } // deviation: this should be called once the data is written, not immediately // Node.js APIs expect callback arguments to be called after the current stack pops - typeof cb === "function" && process.nextTick(cb, null); + if (typeof cb === "function") process.nextTick(cb, null); } close(code, reason) { @@ -393,7 +393,7 @@ class BunWebSocket extends EventEmitter { return; } - typeof cb === "function" && cb(); + if (typeof cb === "function") cb(); } pong(data, mask, cb) { @@ -422,7 +422,7 @@ class BunWebSocket extends EventEmitter { return; } - typeof cb === "function" && cb(); + if (typeof cb === "function") cb(); } pause() { @@ -792,7 +792,7 @@ class BunWebSocketMocked extends EventEmitter { this.#bufferedAmount -= chunk.length; this.#enquedMessages.shift(); - typeof cb === "function" && queueMicrotask(cb); + if (typeof cb === "function") queueMicrotask(cb); } } @@ -814,11 +814,11 @@ class BunWebSocketMocked extends EventEmitter { try { this.#ws.ping(data); } catch (error) { - typeof cb === "function" && cb(error); + if (typeof cb === "function") cb(error); return; } - typeof cb === "function" && cb(); + if (typeof cb === "function") cb(); } pong(data, mask, cb) { @@ -839,11 +839,11 @@ class BunWebSocketMocked extends EventEmitter { try { this.#ws.pong(data); } catch (error) { - typeof cb === "function" && cb(error); + if (typeof cb === "function") cb(error); return; } - typeof cb === "function" && cb(); + if (typeof cb === "function") cb(); } send(data, opts, cb) { @@ -868,7 +868,7 @@ class BunWebSocketMocked extends EventEmitter { return; } - typeof cb === "function" && process.nextTick(cb); + if (typeof cb === "function") process.nextTick(cb); } else if (this.#state === ReadyState_CONNECTING) { // not connected yet this.#enquedMessages.push([data, opts?.compress, cb]);