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-unnecessary-await": "off"
}
},
{
"files": ["src/js/builtins/**"],
"rules": {
"no-unused-expressions": "off"
}
}
]
}

View File

@@ -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();
}

View File

@@ -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) {

View File

@@ -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;
},

View File

@@ -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;
}

View File

@@ -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);
});
}

View File

@@ -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) {

View File

@@ -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;
}
};

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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]);