fix(lint): resolve no-unused-expressions errors (#23127)

## 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 <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
robobun
2025-09-30 04:45:34 -07:00
committed by GitHub
parent e3a1ae09f3
commit 2b7fc18092
11 changed files with 53 additions and 41 deletions

View File

@@ -78,6 +78,12 @@
"no-empty-file": "off", "no-empty-file": "off",
"no-unnecessary-await": "off" "no-unnecessary-await": "off"
} }
},
{
"files": ["src/js/builtins/**"],
"rules": {
"no-unused-expressions": "off"
}
} }
] ]
} }

View File

@@ -299,9 +299,11 @@ class Statement {
var arg0 = args[0]; var arg0 = args[0];
!isArray(arg0) && (!arg0 || typeof arg0 !== "object" || isTypedArray(arg0)) if (!isArray(arg0) && (!arg0 || typeof arg0 !== "object" || isTypedArray(arg0))) {
? this.#raw.run(internalFieldTuple, args) this.#raw.run(internalFieldTuple, args);
: this.#raw.run(internalFieldTuple, ...args); } else {
this.#raw.run(internalFieldTuple, ...args);
}
return createChangesObject(); return createChangesObject();
} }
@@ -516,9 +518,11 @@ class Database implements SqliteTypes.Database {
} }
var arg0 = params[0]; var arg0 = params[0];
!isArray(arg0) && (!arg0 || typeof arg0 !== "object" || isTypedArray(arg0)) if (!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);
: SQL.run(this.#handle, this.#internalFlags, internalFieldTuple, query, ...params); } else {
SQL.run(this.#handle, this.#internalFlags, internalFieldTuple, query, ...params);
}
return createChangesObject(); return createChangesObject();
} }

View File

@@ -339,7 +339,7 @@ const codes = {}; // exported from errors.js
ErrorCaptureStackTrace(err); ErrorCaptureStackTrace(err);
Error.stackTraceLimit = userStackTraceLimit; // Reset the limit 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.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. delete err.name; // Reset the name to the actual name.
error.code = sym; error.code = sym;
return error; return error;
@@ -987,7 +987,7 @@ function initializeWellKnownPrototypes() {
function getConstructorName(obj, ctx, recurseTimes, protoProps) { function getConstructorName(obj, ctx, recurseTimes, protoProps) {
let firstProto; let firstProto;
const tmp = obj; const tmp = obj;
wellKnownPrototypes ?? initializeWellKnownPrototypes(); if (!wellKnownPrototypes) initializeWellKnownPrototypes();
while (obj || isUndetectableObject(obj)) { while (obj || isUndetectableObject(obj)) {
const wellKnownPrototypeNameAndConstructor = wellKnownPrototypes.get(obj); const wellKnownPrototypeNameAndConstructor = wellKnownPrototypes.get(obj);
if (wellKnownPrototypeNameAndConstructor != null) { if (wellKnownPrototypeNameAndConstructor != null) {

View File

@@ -393,12 +393,12 @@ const IncomingMessagePrototype = {
// noop // noop
}, },
setTimeout(msecs, callback) { setTimeout(msecs, callback) {
this.take; void this.take;
const req = this[kHandle] || this[webRequestOrResponse]; const req = this[kHandle] || this[webRequestOrResponse];
if (req) { if (req) {
setRequestTimeout(req, Math.ceil(msecs / 1000)); setRequestTimeout(req, Math.ceil(msecs / 1000));
typeof callback === "function" && this.once("timeout", callback); if (typeof callback === "function") this.once("timeout", callback);
} }
return this; return this;
}, },

View File

@@ -589,7 +589,7 @@ Server.prototype[kRealListen] = function (tls, port, host, socketPath, reusePort
} }
function onClose() { function onClose() {
didFinish = true; didFinish = true;
resolveFunction && resolveFunction(); if (resolveFunction) resolveFunction();
} }
setCloseCallback(http_res, onClose); setCloseCallback(http_res, onClose);
@@ -732,7 +732,7 @@ Server.prototype.setTimeout = function (msecs, callback) {
const server = this[serverSymbol]; const server = this[serverSymbol];
if (server) { if (server) {
setServerIdleTimeout(server, Math.ceil(msecs / 1000)); setServerIdleTimeout(server, Math.ceil(msecs / 1000));
typeof callback === "function" && this.once("timeout", callback); if (typeof callback === "function") this.once("timeout", callback);
} else { } else {
(this[kDeferredTimeouts] ??= []).push({ msecs, callback }); (this[kDeferredTimeouts] ??= []).push({ msecs, callback });
} }
@@ -905,7 +905,7 @@ const NodeHTTPServerSocket = class Socket extends Duplex {
} }
#onCloseForDestroy(closeCallback) { #onCloseForDestroy(closeCallback) {
this.#onClose(); this.#onClose();
$isCallable(closeCallback) && closeCallback(); if ($isCallable(closeCallback)) closeCallback();
} }
_onTimeout() { _onTimeout() {
@@ -937,7 +937,7 @@ const NodeHTTPServerSocket = class Socket extends Duplex {
_destroy(err, callback) { _destroy(err, callback) {
const handle = this[kHandle]; const handle = this[kHandle];
if (!handle) { if (!handle) {
$isCallable(callback) && callback(err); if ($isCallable(callback)) callback(err);
return; return;
} }
handle.ondata = undefined; handle.ondata = undefined;
@@ -947,7 +947,7 @@ const NodeHTTPServerSocket = class Socket extends Duplex {
if ($isCallable(onclose)) { if ($isCallable(onclose)) {
onclose.$call(handle); onclose.$call(handle);
} }
$isCallable(callback) && callback(err); if ($isCallable(callback)) callback(err);
return; return;
} }
@@ -1081,7 +1081,8 @@ const NodeHTTPServerSocket = class Socket extends Duplex {
} catch (e) { } catch (e) {
err = e; err = e;
} }
err ? _callback(err) : _callback(); if (err) _callback(err);
else _callback();
} }
pause() { pause() {
@@ -1510,7 +1511,7 @@ ServerResponse.prototype._finish = function () {
ServerResponse.prototype.detachSocket = function (socket) { ServerResponse.prototype.detachSocket = function (socket) {
if (socket._httpMessage === this) { if (socket._httpMessage === this) {
socket[kCloseCallback] && (socket[kCloseCallback] = undefined); if (socket[kCloseCallback]) socket[kCloseCallback] = undefined;
socket.removeListener("close", onServerResponseClose); socket.removeListener("close", onServerResponseClose);
socket._httpMessage = null; socket._httpMessage = null;
} }

View File

@@ -1340,7 +1340,7 @@ class ChildProcess extends EventEmitter {
if (hasSocketsToEagerlyLoad) { if (hasSocketsToEagerlyLoad) {
process.nextTick(() => { process.nextTick(() => {
this.stdio; void this.stdio;
$debug("ChildProcess: onExit", exitCode, signalCode, err, this.pid); $debug("ChildProcess: onExit", exitCode, signalCode, err, this.pid);
}); });
} }

View File

@@ -731,10 +731,11 @@ const realpathSync: typeof import("node:fs").realpathSync =
if (options) { if (options) {
if (typeof options === "string") encoding = options; if (typeof options === "string") encoding = options;
else encoding = options?.encoding; else encoding = options?.encoding;
encoding && if (encoding) {
(assertEncodingForWindows ?? $newZigFunction("bun.js/node/types.zig", "jsAssertEncodingValid", 1))( (assertEncodingForWindows ?? $newZigFunction("bun.js/node/types.zig", "jsAssertEncodingValid", 1))(
encoding, encoding,
); );
}
} }
// This function is ported 1:1 from node.js, to emulate how it is unable to // 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 // 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 (options) {
if (typeof options === "string") encoding = options; if (typeof options === "string") encoding = options;
else encoding = options?.encoding; else encoding = options?.encoding;
encoding && if (encoding) {
(assertEncodingForWindows ?? $newZigFunction("bun.js/node/types.zig", "jsAssertEncodingValid", 1))( (assertEncodingForWindows ?? $newZigFunction("bun.js/node/types.zig", "jsAssertEncodingValid", 1))(
encoding, encoding,
); );
}
} }
if (p instanceof URL) { if (p instanceof URL) {
if (p.pathname.indexOf("%00") != -1) { if (p.pathname.indexOf("%00") != -1) {

View File

@@ -504,7 +504,7 @@ function TLSSocket(socket?, options?) {
this._SNICallback = undefined; this._SNICallback = undefined;
this.servername = undefined; this.servername = undefined;
this.authorized = false; this.authorized = false;
this.authorizationError; void this.authorizationError;
this[krenegotiationDisabled] = undefined; this[krenegotiationDisabled] = undefined;
this.encrypted = true; this.encrypted = true;
@@ -582,7 +582,7 @@ TLSSocket.prototype.renegotiate = function renegotiate(options, callback) {
if (this[krenegotiationDisabled]) { if (this[krenegotiationDisabled]) {
// if renegotiation is disabled should emit error event in nextTick for nodejs compatibility // if renegotiation is disabled should emit error event in nextTick for nodejs compatibility
const error = $ERR_TLS_RENEGOTIATION_DISABLED(); const error = $ERR_TLS_RENEGOTIATION_DISABLED();
typeof callback === "function" && process.nextTick(callback, error); if (typeof callback === "function") process.nextTick(callback, error);
return false; return false;
} }
@@ -606,11 +606,11 @@ TLSSocket.prototype.renegotiate = function renegotiate(options, callback) {
try { try {
socket.renegotiate?.(); socket.renegotiate?.();
// if renegotiate is successful should emit secure event when done // 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; return true;
} catch (err) { } catch (err) {
// if renegotiate fails should emit error event in nextTick for nodejs compatibility // 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; return false;
} }
}; };

View File

@@ -871,7 +871,6 @@ Url.prototype.parseHost = function parseHost() {
if (host) this.hostname = host; if (host) this.hostname = host;
}; };
"".charCodeAt;
// function fileURLToPath(...args) { // function fileURLToPath(...args) {
// // Since we use WTF::URL::fileSystemPath directly in Bun.fileURLToPath, we don't get invalid windows // // 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 // // path checking. We patch this in to `node:url` for compatibility. Note that

View File

@@ -69,25 +69,25 @@ class Response extends WebResponse {
async arrayBuffer() { async arrayBuffer() {
// load the getter // load the getter
this.body; void this.body;
return await super.arrayBuffer(); return await super.arrayBuffer();
} }
async blob() { async blob() {
// load the getter // load the getter
this.body; void this.body;
return await super.blob(); return await super.blob();
} }
async formData() { async formData() {
// load the getter // load the getter
this.body; void this.body;
return await super.formData(); return await super.formData();
} }
async json() { async json() {
// load the getter // load the getter
this.body; void this.body;
return await super.json(); return await super.json();
} }
@@ -95,13 +95,13 @@ class Response extends WebResponse {
// but is still used by some libraries and frameworks (like Astro) // but is still used by some libraries and frameworks (like Astro)
async buffer() { async buffer() {
// load the getter // load the getter
this.body; void this.body;
return new $Buffer(await super.arrayBuffer()); return new $Buffer(await super.arrayBuffer());
} }
async text() { async text() {
// load the getter // load the getter
this.body; void this.body;
return await super.text(); return await super.text();
} }

View File

@@ -262,12 +262,12 @@ class BunWebSocket extends EventEmitter {
this.#ws.send(normalizeData(data, opts), opts?.compress); this.#ws.send(normalizeData(data, opts), opts?.compress);
} catch (error) { } catch (error) {
// Node.js APIs expect callback arguments to be called after the current stack pops // 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; return;
} }
// deviation: this should be called once the data is written, not immediately // 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 // 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) { close(code, reason) {
@@ -393,7 +393,7 @@ class BunWebSocket extends EventEmitter {
return; return;
} }
typeof cb === "function" && cb(); if (typeof cb === "function") cb();
} }
pong(data, mask, cb) { pong(data, mask, cb) {
@@ -422,7 +422,7 @@ class BunWebSocket extends EventEmitter {
return; return;
} }
typeof cb === "function" && cb(); if (typeof cb === "function") cb();
} }
pause() { pause() {
@@ -792,7 +792,7 @@ class BunWebSocketMocked extends EventEmitter {
this.#bufferedAmount -= chunk.length; this.#bufferedAmount -= chunk.length;
this.#enquedMessages.shift(); this.#enquedMessages.shift();
typeof cb === "function" && queueMicrotask(cb); if (typeof cb === "function") queueMicrotask(cb);
} }
} }
@@ -814,11 +814,11 @@ class BunWebSocketMocked extends EventEmitter {
try { try {
this.#ws.ping(data); this.#ws.ping(data);
} catch (error) { } catch (error) {
typeof cb === "function" && cb(error); if (typeof cb === "function") cb(error);
return; return;
} }
typeof cb === "function" && cb(); if (typeof cb === "function") cb();
} }
pong(data, mask, cb) { pong(data, mask, cb) {
@@ -839,11 +839,11 @@ class BunWebSocketMocked extends EventEmitter {
try { try {
this.#ws.pong(data); this.#ws.pong(data);
} catch (error) { } catch (error) {
typeof cb === "function" && cb(error); if (typeof cb === "function") cb(error);
return; return;
} }
typeof cb === "function" && cb(); if (typeof cb === "function") cb();
} }
send(data, opts, cb) { send(data, opts, cb) {
@@ -868,7 +868,7 @@ class BunWebSocketMocked extends EventEmitter {
return; return;
} }
typeof cb === "function" && process.nextTick(cb); if (typeof cb === "function") process.nextTick(cb);
} else if (this.#state === ReadyState_CONNECTING) { } else if (this.#state === ReadyState_CONNECTING) {
// not connected yet // not connected yet
this.#enquedMessages.push([data, opts?.compress, cb]); this.#enquedMessages.push([data, opts?.compress, cb]);