From 8440794d5720577405e4bb63bec0e65d3b7c6ed3 Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Sat, 15 Aug 2026 06:10:15 +0000 Subject: [PATCH] Remove dead code from node:http2, the HTTP/2 parser, JSC bindings, uSockets, and the builtin-name tables node:http2 bound every entry of `constants` as a local; 178 of the 240 bindings were never read, nor were `Socket`, two ServerHttp2Session fields and the native assertSettings binding that http2.ts stopped using when it grew its own assertSettings(). With the binding gone the js2native codegen no longer names `js_assert_settings`, so the Rust host function, its facade re-export and the Zig-era BUN__HTTP2_* declarations go too. Also removed: the four InspectorHTTPServerAgent command stubs (the HTTPServer inspector domain only defines enable/disable, so nothing can dispatch to them), declaration-only leftovers in BunObject.cpp, JSBuffer.cpp and CryptoUtil.h, the IsIDLEnumeration helper and the globalBuiltinFunction macro, two uncalled uSockets TLS helpers plus the darwin Security.framework teardown hook, ExprData::is_e_string, ArrayHashMap::get_adapted, Behavior::eq, js_parser::FunctionKind (its Stmt variant was never constructed), nine builtin-name entries with no users, the unused $stream* defines, and scripts/find-dead-exports.ts, which the hawk setup in tools/hawk/ replaced. A source lint pins every removed symbol. --- packages/bun-usockets/src/crypto/openssl.c | 9 - .../src/crypto/root_certs_darwin.cpp | 9 - .../src/crypto/root_certs_platform.h | 5 - packages/bun-usockets/src/internal/internal.h | 2 - scripts/find-dead-exports.ts | 303 ------------------ src/ast/expr.rs | 5 - src/codegen/replacements.ts | 9 - src/collections/array_hash_map.rs | 9 - src/install_types/resolver_hooks.rs | 6 - src/js/builtins.d.ts | 11 - src/js/builtins/BunBuiltinNames.h | 9 - src/js/node/http2.ts | 182 ----------- src/js_parser/p.rs | 10 +- src/js_parser/parse/parse_fn.rs | 4 +- src/js_parser/parser.rs | 6 - src/jsc/bindings/BunObject.cpp | 2 - src/jsc/bindings/IDLTypes.h | 4 - src/jsc/bindings/InspectorHTTPServerAgent.cpp | 37 --- src/jsc/bindings/InspectorHTTPServerAgent.h | 4 - src/jsc/bindings/JSBuffer.cpp | 1 - src/jsc/bindings/ZigGlobalObject.cpp | 6 - src/jsc/bindings/node/crypto/CryptoUtil.h | 1 - src/runtime/api.rs | 3 +- src/runtime/api/bun/h2_frame_parser.rs | 144 --------- src/semver/lib.rs | 2 +- ...ols-http2-settings-inspector-stubs.test.ts | 153 +++++++++ 26 files changed, 161 insertions(+), 775 deletions(-) delete mode 100644 scripts/find-dead-exports.ts create mode 100644 test/internal/source-lints/dead-symbols-http2-settings-inspector-stubs.test.ts diff --git a/packages/bun-usockets/src/crypto/openssl.c b/packages/bun-usockets/src/crypto/openssl.c index 1ae954c56e63..0df0d0996f25 100644 --- a/packages/bun-usockets/src/crypto/openssl.c +++ b/packages/bun-usockets/src/crypto/openssl.c @@ -2655,11 +2655,6 @@ void us_socket_sni_resolve(struct us_socket_t *s, struct ssl_ctx_st *ctx, int er ssl_update_handshake(s); } -void us_internal_ssl_handshake_abort(struct us_socket_t *s) { - s->ssl_fatal_error = 1; - ssl_close(s, 0, NULL); -} - /* ── Adopt-TLS (STARTTLS / Bun.connect upgrade) ──────────────────────────── */ /* Feed bytes that were already read off the wire (e.g. a ClientHello consumed @@ -3068,10 +3063,6 @@ void *us_socket_server_name_userdata(struct us_socket_t *s) { return SSL_CTX_get_ex_data(SSL_get_SSL_CTX(s_ssl(s)), us_sni_ex_idx); } -void *us_internal_ssl_sni_userdata(struct us_socket_t *s) { - return us_socket_server_name_userdata(s); -} - const char *us_internal_ssl_sni_servername(struct us_socket_t *s) { if (!s->ssl || !s_ssl(s)) return NULL; return SSL_get_servername(s_ssl(s), TLSEXT_NAMETYPE_host_name); diff --git a/packages/bun-usockets/src/crypto/root_certs_darwin.cpp b/packages/bun-usockets/src/crypto/root_certs_darwin.cpp index acd4b05df909..507d433ece29 100644 --- a/packages/bun-usockets/src/crypto/root_certs_darwin.cpp +++ b/packages/bun-usockets/src/crypto/root_certs_darwin.cpp @@ -13,7 +13,6 @@ typedef struct OpaqueSecTrustRef* SecTrustRef; typedef struct OpaqueSecPolicyRef* SecPolicyRef; typedef int32_t OSStatus; typedef uint32_t SecTrustSettingsDomain; -typedef uint32_t SecTrustSettingsResult; // Security framework constants enum { @@ -564,12 +563,4 @@ extern "C" void us_load_system_certificates_macos(STACK_OF(X509) **system_certs) security->CFRelease(certificates); } -// Cleanup function for Security framework -extern "C" void us_cleanup_security_framework() { - SecurityFramework* framework = g_security_framework.exchange(nullptr); - if (framework) { - delete framework; - } -} - #endif // __APPLE__ diff --git a/packages/bun-usockets/src/crypto/root_certs_platform.h b/packages/bun-usockets/src/crypto/root_certs_platform.h index e357b63ffb5e..e94da8f15f8d 100644 --- a/packages/bun-usockets/src/crypto/root_certs_platform.h +++ b/packages/bun-usockets/src/crypto/root_certs_platform.h @@ -10,9 +10,4 @@ void us_load_system_certificates_linux(STACK_OF(X509) **system_certs); void us_load_system_certificates_macos(STACK_OF(X509) **system_certs); void us_load_system_certificates_windows(STACK_OF(X509) **system_certs); -// Platform-specific cleanup functions -#ifdef __APPLE__ -void us_cleanup_security_framework(); -#endif - } \ No newline at end of file diff --git a/packages/bun-usockets/src/internal/internal.h b/packages/bun-usockets/src/internal/internal.h index 3122b51de922..494c78be1717 100644 --- a/packages/bun-usockets/src/internal/internal.h +++ b/packages/bun-usockets/src/internal/internal.h @@ -240,9 +240,7 @@ int us_internal_ssl_write(us_socket_r s, const char *data, int length); unsigned int us_internal_ssl_spill_pending(us_socket_r s); void *us_internal_ssl_get_native_handle(us_socket_r s); struct us_bun_verify_error_t us_internal_ssl_verify_error(us_socket_r s); -void *us_internal_ssl_sni_userdata(us_socket_r s); const char *us_internal_ssl_sni_servername(us_socket_r s); -void us_internal_ssl_handshake_abort(us_socket_r s); /* SSL_CTX_free(ls->ssl_ctx) + sni_free(ls->sni). Called from us_listen_socket_close. */ void us_internal_listen_socket_ssl_free(struct us_listen_socket_t *ls); /* Opaque SSL_CTX_up_ref/SSL_CTX_free so context.c needn't include OpenSSL. */ diff --git a/scripts/find-dead-exports.ts b/scripts/find-dead-exports.ts deleted file mode 100644 index 39512f5ed922..000000000000 --- a/scripts/find-dead-exports.ts +++ /dev/null @@ -1,303 +0,0 @@ -#!/usr/bin/env bun -/** - * Find `pub` items that no other workspace crate references. - * - * `dead_code` treats every externally-reachable `pub` item as an API root and - * never analyzes it; `unreachable_pub` only fires when the *module path* blocks - * external access. Neither asks "does another crate actually import this?" — - * in a workspace where every crate is an internal implementation detail of one - * binary, that is the question that matters. This script answers it by diffing - * each crate's exported names against the union of names every other crate - * references through that crate's paths. - * - * The output is a *candidate* list, not a verdict: name matching is textual - * (an identifier appearing anywhere in a `bun_x::…` path or `use bun_x::…` - * statement counts as a use), so macro-expanded references that never appear - * in the consuming crate's source are missed. Verify by demoting a candidate - * to `pub(crate)` and compiling the workspace — a miss shows up as E0603. - * - * bun scripts/find-dead-exports.ts # full report - * bun scripts/find-dead-exports.ts bun_ast # one crate - * bun scripts/find-dead-exports.ts --json # machine-readable - */ - -import { readdirSync, readFileSync, statSync } from "node:fs"; -import { join, relative, resolve } from "node:path"; - -const ROOT = resolve(import.meta.dir, ".."); -const args = process.argv.slice(2); -const asJson = args.includes("--json"); -const onlyCrate = args.find(a => !a.startsWith("--")); - -// ── workspace layout ──────────────────────────────────────────────────────── - -interface Crate { - name: string; - dir: string; // relative to ROOT - files: string[]; // .rs files, relative to ROOT -} - -function rustFiles(dir: string): string[] { - const out: string[] = []; - for (const e of readdirSync(dir)) { - const p = join(dir, e); - const st = statSync(p); - if (st.isDirectory()) { - if (e === "target" || e === "node_modules") continue; - out.push(...rustFiles(p)); - } else if (e.endsWith(".rs")) { - out.push(p); - } - } - return out; -} - -function loadWorkspace(): Crate[] { - const rootToml = readFileSync(join(ROOT, "Cargo.toml"), "utf8"); - const membersBlock = rootToml.match(/members\s*=\s*\[([\s\S]*?)\]/)?.[1] ?? ""; - const dirs = [...membersBlock.matchAll(/"([^"]+)"/g)].map(m => m[1]); - const crates: Crate[] = []; - for (const dir of dirs) { - const tomlPath = join(ROOT, dir, "Cargo.toml"); - let name: string; - try { - name = readFileSync(tomlPath, "utf8").match(/^name\s*=\s*"([^"]+)"/m)![1]; - } catch { - continue; - } - // Crate names with `-` are referenced in Rust paths with `_`. - crates.push({ name: name.replace(/-/g, "_"), dir, files: rustFiles(join(ROOT, dir)).map(f => relative(ROOT, f)) }); - } - return crates; -} - -// ── export side: every `pub `-declared item ───────────────────────────────── -// After `unreachable_pub = deny`, a surviving bare-`pub` item is necessarily in -// a fully-public module chain, i.e. externally reachable. So "all pub items" -// IS the export set — no module-tree walk needed. - -interface Export { - name: string; - kind: string; - file: string; - line: number; -} - -const ITEM_RE = - /^\s*pub\s+(?:(?:unsafe|async|extern\s+"[^"]*"|const|safe)\s+)*(fn|struct|enum|trait|union|type|static|const|mod)\s+([A-Za-z_][A-Za-z0-9_]*)/; -// `pub use path::{A, B as C, D}` / `pub use path::Name` / `pub use path as Alias` -const USE_RE = /^\s*pub\s+use\s+(.+);\s*$/; - -function collectExports(crate: Crate): Export[] { - const out: Export[] = []; - for (const file of crate.files) { - const lines = readFileSync(join(ROOT, file), "utf8").split("\n"); - let inTestMod = false; - let testModDepth = 0; - let depth = 0; - // Methods and associated items are referenced through their *type* - // (`val.method()`, `Type::CONST`), never through a crate-qualified path, - // so grep cannot see their uses. Exclude everything inside impl/trait - // blocks — only path-addressable free items are auditable here. - const implStack: number[] = []; - // Set when an impl/trait header has no `{` on its own line (rustfmt wraps - // the brace onto a later line for long headers and where-clauses); the - // push happens on the first subsequent line that opens the block. - let pendingImpl = false; - for (let i = 0; i < lines.length; i++) { - const l = lines[i]; - // crude #[cfg(test)] mod skip — items only compiled for tests are not API - if (/^\s*#\[cfg\(test\)\]/.test(l) && /^\s*(pub\s+)?mod\s/.test(lines[i + 1] ?? "")) { - inTestMod = true; - testModDepth = depth; - continue; - } - const isImplOrTrait = /^\s*(unsafe\s+)?impl[\s<]/.test(l) || /^\s*(pub\s+)?(unsafe\s+)?trait\s/.test(l); - if (isImplOrTrait && l.includes("{")) implStack.push(depth); - else if (isImplOrTrait && !l.includes(";")) pendingImpl = true; - else if (pendingImpl && l.includes("{")) { - implStack.push(depth); - pendingImpl = false; - } - const opens = (l.match(/\{/g) ?? []).length; - const closes = (l.match(/\}/g) ?? []).length; - const inImpl = implStack.length > 0; - depth += opens - closes; - while (implStack.length && depth <= implStack[implStack.length - 1]) implStack.pop(); - if (inTestMod && depth <= testModDepth) inTestMod = false; - if (inTestMod) continue; - if (inImpl && !isImplOrTrait) continue; - - const m = ITEM_RE.exec(l); - if (m) { - out.push({ name: m[2], kind: m[1], file, line: i + 1 }); - continue; - } - const u = USE_RE.exec(l) ?? (l.trimStart().startsWith("pub use") ? collectMultilineUse(lines, i) : null); - if (u) { - for (const name of namesFromUseTail(u[1])) { - out.push({ name, kind: "use", file, line: i + 1 }); - } - } - } - } - return out; -} - -/** `pub use a::b::{C, D as E, f::G};` → the names this re-export *introduces*. */ -function namesFromUseTail(tail: string): string[] { - tail = tail.replace(/\s+/g, " ").trim(); - const names: string[] = []; - const brace = tail.match(/\{([\s\S]*)\}/); - if (brace) { - for (const part of brace[1].split(",")) { - const p = part.trim(); - if (!p || p === "self") continue; - const as = p.match(/\bas\s+([A-Za-z_][A-Za-z0-9_]*)$/); - if (as) names.push(as[1]); - else { - const last = p.split("::").pop()!.trim(); - if (last !== "*" && /^[A-Za-z_]/.test(last)) names.push(last); - } - } - } else { - const as = tail.match(/\bas\s+([A-Za-z_][A-Za-z0-9_]*)$/); - if (as) names.push(as[1]); - else { - const last = tail.split("::").pop()!.trim(); - if (last !== "*" && /^[A-Za-z_]/.test(last)) names.push(last); - } - } - return names; -} - -function collectMultilineUse(lines: string[], i: number): RegExpExecArray | null { - // `pub use foo::{\n A,\n B,\n};` spans lines — join until the `;` - let buf = ""; - for (let j = i; j < Math.min(i + 40, lines.length); j++) { - buf += lines[j] + " "; - if (lines[j].includes(";")) break; - } - return USE_RE.exec(buf.trim()); -} - -// ── import side: identifiers referenced through `crate_name::…` paths ─────── - -function collectReferences(crates: Crate[]): Map> { - // crate name → set of identifiers seen in any path rooted at that crate, - // from any *other* crate's source (plus generated code). - const refs = new Map>(crates.map(c => [c.name, new Set()])); - const crateNames = new Set(crates.map(c => c.name)); - - // `extern crate X as Y;` → references to `Y::…` are references to `X`. - const aliases = new Map(); - for (const c of crates) { - for (const f of c.files) { - for (const m of readFileSync(join(ROOT, f), "utf8").matchAll( - /extern crate ([A-Za-z_][A-Za-z0-9_]*) as ([A-Za-z_][A-Za-z0-9_]*)/g, - )) { - if (crateNames.has(m[1]) && m[2] !== m[1]) aliases.set(m[2], m[1]); - } - } - } - - const sources: { file: string; ownerCrate: string | null }[] = []; - for (const c of crates) for (const f of c.files) sources.push({ file: f, ownerCrate: c.name }); - // Generated code references workspace items but belongs to whichever crate - // include!()s it — attribute it to no crate so all its references count. - for (const genDir of ["build/debug/codegen", "build/release/codegen"]) { - try { - for (const f of rustFiles(join(ROOT, genDir))) sources.push({ file: relative(ROOT, f), ownerCrate: null }); - } catch {} - } - - // Two reference forms: - // (a) qualified paths in code: `bun_core::strings::index_of(...)` - // (b) use statements, possibly brace-grouped over multiple lines: - // `use bun_core::{String, output::{self, Output}};` - // (b) is the dominant style (rustfmt groups imports) and its leaf names are - // bare identifiers inside braces, not `::`-joined paths — handle separately. - const PATH_RE = /\b([A-Za-z_][A-Za-z0-9_]*)((?:::[A-Za-z_*][A-Za-z0-9_]*)+)/g; - const USE_STMT_RE = /^[ \t]*(?:pub(?:\([^)]*\))?[ \t]+)?use[ \t]+(?:::)?([A-Za-z_][A-Za-z0-9_]*)([^;]*);/gms; - for (const { file, ownerCrate } of sources) { - let text: string; - try { - text = readFileSync(join(ROOT, file), "utf8"); - } catch { - continue; - } - for (const m of text.matchAll(PATH_RE)) { - const root = aliases.get(m[1]) ?? m[1]; - if (!crateNames.has(root)) continue; - if (root === ownerCrate) continue; // self-references don't count - const set = refs.get(root)!; - for (const seg of m[2].split("::")) { - if (seg && seg !== "*") set.add(seg); - } - } - for (const m of text.matchAll(USE_STMT_RE)) { - const root = aliases.get(m[1]) ?? m[1]; - if (!crateNames.has(root)) continue; - if (root === ownerCrate) continue; - const set = refs.get(root)!; - for (const ident of m[2].matchAll(/[A-Za-z_][A-Za-z0-9_]*/g)) { - if (ident[0] !== "self" && ident[0] !== "as") set.add(ident[0]); - } - } - } - return refs; -} - -// ── diff ──────────────────────────────────────────────────────────────────── - -const crates = loadWorkspace(); -const refs = collectReferences(crates); - -// Crates consumed via `use crate::module::*` cross-crate glob imports: every -// name in them must be considered used. (Currently: bun_bundler::mal_prelude, -// bun_sql::…::FieldType.) Detect them so the report can flag the blind spot. -const globImportTargets = new Set(); -for (const c of crates) { - for (const f of c.files) { - for (const m of readFileSync(join(ROOT, f), "utf8").matchAll(/^\s*use ((?:::)?[A-Za-z_][A-Za-z0-9_:]*)::\*;/gm)) { - const root = m[1].replace(/^::/, "").split("::")[0]; - if (crates.some(x => x.name === root) && root !== c.name) globImportTargets.add(m[1]); - } - } -} - -interface Finding extends Export { - crate: string; -} -const findings: Finding[] = []; -let totalExports = 0; -for (const crate of crates) { - if (onlyCrate && crate.name !== onlyCrate) continue; - if (crate.name === "bun_bin") continue; // the staticlib root exports the C ABI, not Rust items - const exports = collectExports(crate); - totalExports += exports.length; - const used = refs.get(crate.name)!; - for (const e of exports) { - if (e.kind === "mod") continue; // a dead pub mod falls out once its contents are dead - if (!used.has(e.name)) findings.push({ ...e, crate: crate.name }); - } -} - -if (asJson) { - console.log(JSON.stringify(findings, null, 1)); -} else { - const byCrate = new Map(); - for (const f of findings) (byCrate.get(f.crate) ?? byCrate.set(f.crate, []).get(f.crate)!).push(f); - for (const [crate, list] of [...byCrate].sort((a, b) => b[1].length - a[1].length)) { - console.log(`\n${crate} — ${list.length} exported item(s) no other crate references`); - for (const f of list.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line)) { - console.log(` ${f.file}:${f.line} ${f.kind} ${f.name}`); - } - } - console.log(`\n────────────────────────────────────────`); - console.log(`${findings.length} candidate dead exports out of ${totalExports} exported items`); - if (globImportTargets.size) { - console.log(`note: cross-crate glob imports blind this analysis for: ${[...globImportTargets].join(", ")}`); - } - console.log(`verify a candidate by demoting it to pub(crate) and running cargo check --workspace`); -} diff --git a/src/ast/expr.rs b/src/ast/expr.rs index e61f8fa11a02..b8edc77420f0 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -1630,11 +1630,6 @@ impl Data { None } } - /// True if this is an `EString`. - #[inline] - pub fn is_e_string(&self) -> bool { - matches!(self, Data::EString(_)) - } // ── Remaining StoreRef field-style accessors ────────────────── // Callers `.unwrap()` (or pattern-match) — the `Option` is the cheapest diff --git a/src/codegen/replacements.ts b/src/codegen/replacements.ts index af31730db055..0c42d85ed9fb 100644 --- a/src/codegen/replacements.ts +++ b/src/codegen/replacements.ts @@ -62,7 +62,6 @@ export const globalsToPrefix = [ "ArrayBuffer", "Buffer", "Infinity", - "Loader", "Promise", "ReadableByteStreamController", "ReadableStream", @@ -74,7 +73,6 @@ export const globalsToPrefix = [ "TransformStreamDefaultController", "Uint8Array", "String", - "Buffer", "RegExp", "WritableStream", "WritableStreamDefaultController", @@ -136,13 +134,6 @@ export const define: Record = { "process.env.NODE_ENV": JSON.stringify(debug ? "development" : "production"), "IS_BUN_DEVELOPMENT": String(debug), - $streamClosed: "1", - $streamClosing: "2", - $streamErrored: "3", - $streamReadable: "4", - $streamWaiting: "5", - $streamWritable: "6", - "process.platform": JSON.stringify(Bun.env.TARGET_PLATFORM ?? process.platform), "process.arch": JSON.stringify(Bun.env.TARGET_ARCH ?? process.arch), }; diff --git a/src/collections/array_hash_map.rs b/src/collections/array_hash_map.rs index 9a638abec709..e6cb25a38dbc 100644 --- a/src/collections/array_hash_map.rs +++ b/src/collections/array_hash_map.rs @@ -942,15 +942,6 @@ impl ArrayHashMap { self.find_hash(h, |k, idx| adapter.eql(key, k, idx)) } - #[inline] - pub fn get_adapted(&self, key: &Q, adapter: &Ad) -> Option<&V> - where - Ad: ArrayHashAdapter, - { - self.get_index_adapted(key, adapter) - .map(|i| &self.values[i]) - } - #[inline] pub fn contains_adapted(&self, key: &Q, adapter: &Ad) -> bool where diff --git a/src/install_types/resolver_hooks.rs b/src/install_types/resolver_hooks.rs index 902921588134..8923728f9ef5 100644 --- a/src/install_types/resolver_hooks.rs +++ b/src/install_types/resolver_hooks.rs @@ -233,12 +233,6 @@ impl Behavior { !self.is_optional() } - #[inline] - #[cfg(debug_assertions)] - pub fn eq(lhs: Behavior, rhs: Behavior) -> bool { - lhs.bits() == rhs.bits() - } - #[inline] pub fn add(self, kind: Behavior) -> Behavior { self | kind diff --git a/src/js/builtins.d.ts b/src/js/builtins.d.ts index 7d43df169845..d613d43855a0 100644 --- a/src/js/builtins.d.ts +++ b/src/js/builtins.d.ts @@ -328,11 +328,9 @@ declare function $autoAllocateChunkSize(): TODO; declare function $basename(): TODO; declare function $body(): TODO; declare function $bunNativePtr(): TODO; -declare function $byobRequest(): TODO; declare function $cancel(): TODO; declare function $close(): TODO; declare function $code(): TODO; -declare function $controller(): TODO; declare function $createFIFO(): TODO; declare function $createUninitializedArrayBuffer(size: number): ArrayBuffer; declare function $data(): TODO; @@ -374,7 +372,6 @@ declare function $normalize(): TODO; declare function $parse(): TODO; declare function $path(): TODO; declare function $port(): TODO; -declare function $post(): TODO; declare function $pull(): TODO; declare function $read(): TODO; declare function $readable(): TODO; @@ -393,24 +390,16 @@ declare function $resolveSync( isUserRequireResolve?: boolean, paths?: string[], ): string; -declare function $resume(): TODO; declare function $search(): TODO; declare function $searchParams(): TODO; declare function $self(): TODO; declare function $size(): TODO; declare function $start(): TODO; -declare function $started(): TODO; -declare function $state(): TODO; declare function $status(): TODO; declare function $stream(): TODO; -declare function $streamClosed(): TODO; -declare function $streamErrored(): TODO; -declare function $streamReadable(): TODO; -declare function $streamWritable(): TODO; declare function $syscall(): TODO; declare function $toNamespacedPath(): TODO; declare function $url(): TODO; -declare function $view(): TODO; declare function $whenSignalAborted(signal: AbortSignal, cb: (reason: any) => void): TODO; declare function $writable(): TODO; declare function $write(): TODO; diff --git a/src/js/builtins/BunBuiltinNames.h b/src/js/builtins/BunBuiltinNames.h index b3a6202f05f6..091ccd0aeab9 100644 --- a/src/js/builtins/BunBuiltinNames.h +++ b/src/js/builtins/BunBuiltinNames.h @@ -25,7 +25,6 @@ using namespace JSC; macro($$typeof) \ macro(AbortSignal) \ macro(Buffer) \ - macro(Loader) \ macro(ReadableByteStreamController) \ macro(ReadableStream) \ macro(ReadableStreamBYOBReader) \ @@ -56,7 +55,6 @@ using namespace JSC; macro(blob) \ macro(body) \ macro(bunNativePtr) \ - macro(byobRequest) \ macro(bytes) \ macro(cancel) \ macro(checkBufferRead) \ @@ -64,7 +62,6 @@ using namespace JSC; macro(close) \ macro(cmd) \ macro(code) \ - macro(controller) \ macro(createCommonJSModule) \ macro(createFIFO) \ macro(createInternalModuleById) \ @@ -149,7 +146,6 @@ using namespace JSC; macro(peekPromiseStatus) \ macro(pokePromiseAsHandled) \ macro(port) \ - macro(post) \ macro(preventAbort) \ macro(preventCancel) \ macro(preventClose) \ @@ -168,7 +164,6 @@ using namespace JSC; macro(requireMap) \ macro(requireNativeModule) \ macro(resolveSync) \ - macro(resume) \ macro(sameSite) \ macro(secure) \ macro(self) \ @@ -177,8 +172,6 @@ using namespace JSC; macro(size) \ macro(specifier) \ macro(start) \ - macro(started) \ - macro(state) \ macro(status) \ macro(statusCode) \ macro(statusMessage) \ @@ -186,7 +179,6 @@ using namespace JSC; macro(stream) \ macro(syscall) \ macro(text) \ - macro(textDecoder) \ macro(textDecoderStreamDecoder) \ macro(textEncoderStreamEncoder) \ macro(toClass) \ @@ -196,7 +188,6 @@ using namespace JSC; macro(updateRef) \ macro(url) \ macro(validated) \ - macro(view) \ macro(vmErrorDecorated) \ macro(warning) \ macro(webStreamClosedPromise) \ diff --git a/src/js/node/http2.ts b/src/js/node/http2.ts index ff7409618401..250e8a39d17b 100644 --- a/src/js/node/http2.ts +++ b/src/js/node/http2.ts @@ -67,7 +67,6 @@ type Http2ConnectOptions = { createConnection?: Function; }; const TLSSocket = tls.TLSSocket; -const Socket = net.Socket; const EventEmitter = require("node:events"); const { Duplex } = Stream; const { SafeArrayIterator, SafeSet } = require("internal/primordials"); @@ -88,7 +87,6 @@ const DatePrototypeToUTCString = Date.prototype.toUTCString; const DatePrototypeGetMilliseconds = Date.prototype.getMilliseconds; const H2FrameParser = $rust("h2_frame_parser.rs", "H2FrameParserConstructor"); -const _nativeAssertSettings = $newRustFunction("h2_frame_parser.rs", "jsAssertSettings", 1); const { upgradeRawSocketToH2 } = require("node:_http2_upgrade"); const kSettingNames = { @@ -1707,246 +1705,68 @@ const constants = { HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED: 511, }; const { - NGHTTP2_ERR_FRAME_SIZE_ERROR, NGHTTP2_SESSION_SERVER, NGHTTP2_SESSION_CLIENT, - NGHTTP2_STREAM_STATE_IDLE, - NGHTTP2_STREAM_STATE_OPEN, - NGHTTP2_STREAM_STATE_RESERVED_LOCAL, - NGHTTP2_STREAM_STATE_RESERVED_REMOTE, - NGHTTP2_STREAM_STATE_HALF_CLOSED_LOCAL, - NGHTTP2_STREAM_STATE_HALF_CLOSED_REMOTE, - NGHTTP2_STREAM_STATE_CLOSED, - NGHTTP2_FLAG_NONE, - NGHTTP2_FLAG_END_STREAM, - NGHTTP2_FLAG_END_HEADERS, - NGHTTP2_FLAG_ACK, - NGHTTP2_FLAG_PADDED, - NGHTTP2_FLAG_PRIORITY, - DEFAULT_SETTINGS_HEADER_TABLE_SIZE, - DEFAULT_SETTINGS_ENABLE_PUSH, - DEFAULT_SETTINGS_MAX_CONCURRENT_STREAMS, - DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE, - DEFAULT_SETTINGS_MAX_FRAME_SIZE, - DEFAULT_SETTINGS_MAX_HEADER_LIST_SIZE, - DEFAULT_SETTINGS_ENABLE_CONNECT_PROTOCOL, - MAX_MAX_FRAME_SIZE, - MIN_MAX_FRAME_SIZE, - MAX_INITIAL_WINDOW_SIZE, - NGHTTP2_SETTINGS_HEADER_TABLE_SIZE, - NGHTTP2_SETTINGS_ENABLE_PUSH, - NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, - NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, - NGHTTP2_SETTINGS_MAX_FRAME_SIZE, - NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE, - NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL, - PADDING_STRATEGY_NONE, - PADDING_STRATEGY_ALIGNED, - PADDING_STRATEGY_MAX, - PADDING_STRATEGY_CALLBACK, NGHTTP2_NO_ERROR, - NGHTTP2_PROTOCOL_ERROR, NGHTTP2_INTERNAL_ERROR, - NGHTTP2_FLOW_CONTROL_ERROR, - NGHTTP2_SETTINGS_TIMEOUT, - NGHTTP2_STREAM_CLOSED, - NGHTTP2_FRAME_SIZE_ERROR, - NGHTTP2_REFUSED_STREAM, NGHTTP2_CANCEL, - NGHTTP2_COMPRESSION_ERROR, - NGHTTP2_CONNECT_ERROR, - NGHTTP2_ENHANCE_YOUR_CALM, - NGHTTP2_INADEQUATE_SECURITY, - NGHTTP2_HTTP_1_1_REQUIRED, - NGHTTP2_DEFAULT_WEIGHT, HTTP2_HEADER_STATUS, HTTP2_HEADER_METHOD, HTTP2_HEADER_AUTHORITY, HTTP2_HEADER_SCHEME, HTTP2_HEADER_PATH, HTTP2_HEADER_PROTOCOL, - HTTP2_HEADER_ACCEPT_ENCODING, - HTTP2_HEADER_ACCEPT_LANGUAGE, - HTTP2_HEADER_ACCEPT_RANGES, - HTTP2_HEADER_ACCEPT, HTTP2_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS, - HTTP2_HEADER_ACCESS_CONTROL_ALLOW_HEADERS, - HTTP2_HEADER_ACCESS_CONTROL_ALLOW_METHODS, - HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, - HTTP2_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS, - HTTP2_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, HTTP2_HEADER_ACCESS_CONTROL_REQUEST_METHOD, HTTP2_HEADER_AGE, HTTP2_HEADER_AUTHORIZATION, - HTTP2_HEADER_CACHE_CONTROL, HTTP2_HEADER_CONNECTION, - HTTP2_HEADER_CONTENT_DISPOSITION, HTTP2_HEADER_CONTENT_ENCODING, HTTP2_HEADER_CONTENT_LENGTH, HTTP2_HEADER_CONTENT_TYPE, HTTP2_HEADER_COOKIE, HTTP2_HEADER_DATE, HTTP2_HEADER_ETAG, - HTTP2_HEADER_FORWARDED, HTTP2_HEADER_HOST, HTTP2_HEADER_IF_MODIFIED_SINCE, HTTP2_HEADER_IF_NONE_MATCH, HTTP2_HEADER_IF_RANGE, HTTP2_HEADER_LAST_MODIFIED, - HTTP2_HEADER_LINK, HTTP2_HEADER_LOCATION, HTTP2_HEADER_RANGE, HTTP2_HEADER_REFERER, - HTTP2_HEADER_SERVER, HTTP2_HEADER_SET_COOKIE, - HTTP2_HEADER_STRICT_TRANSPORT_SECURITY, - HTTP2_HEADER_TRANSFER_ENCODING, - HTTP2_HEADER_TE, HTTP2_HEADER_UPGRADE_INSECURE_REQUESTS, - HTTP2_HEADER_UPGRADE, HTTP2_HEADER_USER_AGENT, - HTTP2_HEADER_VARY, HTTP2_HEADER_X_CONTENT_TYPE_OPTIONS, - HTTP2_HEADER_X_FRAME_OPTIONS, - HTTP2_HEADER_KEEP_ALIVE, - HTTP2_HEADER_PROXY_CONNECTION, - HTTP2_HEADER_X_XSS_PROTECTION, - HTTP2_HEADER_ALT_SVC, - HTTP2_HEADER_CONTENT_SECURITY_POLICY, - HTTP2_HEADER_EARLY_DATA, - HTTP2_HEADER_EXPECT_CT, HTTP2_HEADER_ORIGIN, - HTTP2_HEADER_PURPOSE, - HTTP2_HEADER_TIMING_ALLOW_ORIGIN, - HTTP2_HEADER_X_FORWARDED_FOR, - HTTP2_HEADER_PRIORITY, - HTTP2_HEADER_ACCEPT_CHARSET, HTTP2_HEADER_ACCESS_CONTROL_MAX_AGE, - HTTP2_HEADER_ALLOW, HTTP2_HEADER_CONTENT_LANGUAGE, HTTP2_HEADER_CONTENT_LOCATION, HTTP2_HEADER_CONTENT_MD5, HTTP2_HEADER_CONTENT_RANGE, HTTP2_HEADER_DNT, - HTTP2_HEADER_EXPECT, HTTP2_HEADER_EXPIRES, HTTP2_HEADER_FROM, HTTP2_HEADER_IF_MATCH, HTTP2_HEADER_IF_UNMODIFIED_SINCE, HTTP2_HEADER_MAX_FORWARDS, - HTTP2_HEADER_PREFER, - HTTP2_HEADER_PROXY_AUTHENTICATE, HTTP2_HEADER_PROXY_AUTHORIZATION, - HTTP2_HEADER_REFRESH, HTTP2_HEADER_RETRY_AFTER, - HTTP2_HEADER_TRAILER, HTTP2_HEADER_TK, - HTTP2_HEADER_VIA, - HTTP2_HEADER_WARNING, - HTTP2_HEADER_WWW_AUTHENTICATE, - HTTP2_HEADER_HTTP2_SETTINGS, - HTTP2_METHOD_ACL, - HTTP2_METHOD_BASELINE_CONTROL, - HTTP2_METHOD_BIND, - HTTP2_METHOD_CHECKIN, - HTTP2_METHOD_CHECKOUT, HTTP2_METHOD_CONNECT, - HTTP2_METHOD_COPY, HTTP2_METHOD_DELETE, HTTP2_METHOD_GET, HTTP2_METHOD_HEAD, - HTTP2_METHOD_LABEL, - HTTP2_METHOD_LINK, - HTTP2_METHOD_LOCK, - HTTP2_METHOD_MERGE, - HTTP2_METHOD_MKACTIVITY, - HTTP2_METHOD_MKCALENDAR, - HTTP2_METHOD_MKCOL, - HTTP2_METHOD_MKREDIRECTREF, - HTTP2_METHOD_MKWORKSPACE, - HTTP2_METHOD_MOVE, - HTTP2_METHOD_OPTIONS, - HTTP2_METHOD_ORDERPATCH, - HTTP2_METHOD_PATCH, - HTTP2_METHOD_POST, - HTTP2_METHOD_PRI, - HTTP2_METHOD_PROPFIND, - HTTP2_METHOD_PROPPATCH, - HTTP2_METHOD_PUT, - HTTP2_METHOD_REBIND, - HTTP2_METHOD_REPORT, - HTTP2_METHOD_SEARCH, - HTTP2_METHOD_TRACE, - HTTP2_METHOD_UNBIND, - HTTP2_METHOD_UNCHECKOUT, - HTTP2_METHOD_UNLINK, - HTTP2_METHOD_UNLOCK, - HTTP2_METHOD_UPDATE, - HTTP2_METHOD_UPDATEREDIRECTREF, - HTTP2_METHOD_VERSION_CONTROL, HTTP_STATUS_CONTINUE, HTTP_STATUS_SWITCHING_PROTOCOLS, - HTTP_STATUS_PROCESSING, HTTP_STATUS_EARLY_HINTS, HTTP_STATUS_OK, - HTTP_STATUS_CREATED, - HTTP_STATUS_ACCEPTED, - HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION, HTTP_STATUS_NO_CONTENT, HTTP_STATUS_RESET_CONTENT, - HTTP_STATUS_PARTIAL_CONTENT, - HTTP_STATUS_MULTI_STATUS, - HTTP_STATUS_ALREADY_REPORTED, - HTTP_STATUS_IM_USED, - HTTP_STATUS_MULTIPLE_CHOICES, - HTTP_STATUS_MOVED_PERMANENTLY, - HTTP_STATUS_FOUND, - HTTP_STATUS_SEE_OTHER, HTTP_STATUS_NOT_MODIFIED, - HTTP_STATUS_USE_PROXY, - HTTP_STATUS_TEMPORARY_REDIRECT, - HTTP_STATUS_PERMANENT_REDIRECT, - HTTP_STATUS_BAD_REQUEST, - HTTP_STATUS_UNAUTHORIZED, - HTTP_STATUS_PAYMENT_REQUIRED, - HTTP_STATUS_FORBIDDEN, - HTTP_STATUS_NOT_FOUND, HTTP_STATUS_METHOD_NOT_ALLOWED, - HTTP_STATUS_NOT_ACCEPTABLE, - HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED, - HTTP_STATUS_REQUEST_TIMEOUT, - HTTP_STATUS_CONFLICT, - HTTP_STATUS_GONE, - HTTP_STATUS_LENGTH_REQUIRED, - HTTP_STATUS_PRECONDITION_FAILED, - HTTP_STATUS_PAYLOAD_TOO_LARGE, - HTTP_STATUS_URI_TOO_LONG, - HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE, - HTTP_STATUS_RANGE_NOT_SATISFIABLE, HTTP_STATUS_EXPECTATION_FAILED, - HTTP_STATUS_TEAPOT, - HTTP_STATUS_MISDIRECTED_REQUEST, - HTTP_STATUS_UNPROCESSABLE_ENTITY, - HTTP_STATUS_LOCKED, - HTTP_STATUS_FAILED_DEPENDENCY, - HTTP_STATUS_TOO_EARLY, - HTTP_STATUS_UPGRADE_REQUIRED, - HTTP_STATUS_PRECONDITION_REQUIRED, - HTTP_STATUS_TOO_MANY_REQUESTS, - HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE, - HTTP_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS, - HTTP_STATUS_INTERNAL_SERVER_ERROR, - HTTP_STATUS_NOT_IMPLEMENTED, - HTTP_STATUS_BAD_GATEWAY, - HTTP_STATUS_SERVICE_UNAVAILABLE, - HTTP_STATUS_GATEWAY_TIMEOUT, - HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED, - HTTP_STATUS_VARIANT_ALSO_NEGOTIATES, - HTTP_STATUS_INSUFFICIENT_STORAGE, - HTTP_STATUS_LOOP_DETECTED, - HTTP_STATUS_BANDWIDTH_LIMIT_EXCEEDED, - HTTP_STATUS_NOT_EXTENDED, - HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED, } = constants; //TODO: desconstruct used constants. @@ -4177,8 +3997,6 @@ class ServerHttp2Session extends Http2Session { #connections: number = 0; #socket_proxy: Proxy; #parser: typeof H2FrameParser | null; - #url: URL; - #isServer: boolean = false; #alpnProtocol: string | undefined = undefined; #localSettings: Settings | null = null; #encrypted: boolean = false; diff --git a/src/js_parser/p.rs b/src/js_parser/p.rs index e14684e6a2f2..972eb7fcd98f 100644 --- a/src/js_parser/p.rs +++ b/src/js_parser/p.rs @@ -21,8 +21,8 @@ use crate::renamer; use crate::{ ARGUMENTS_STR as arguments_str, DeferredArrowArgErrors, DeferredErrors, DeferredImportNamespace, EXPORTS_STRING_NAME as exports_string_name, ExprBindingTuple, - FindLabelSymbolResult, FnOnlyDataVisit, FnOrArrowDataParse, FnOrArrowDataVisit, FunctionKind, - IdentifierOpts, ImportItemForNamespaceMap, InvalidLoc, JSXImport, JSXTransformType, Jest, + FindLabelSymbolResult, FnOnlyDataVisit, FnOrArrowDataParse, FnOrArrowDataVisit, IdentifierOpts, + ImportItemForNamespaceMap, InvalidLoc, JSXImport, JSXTransformType, Jest, LOC_MODULE_SCOPE as loc_module_scope, LocList, MacroState, ParseStatementOptions, ParsedPath, PrependTempRefsOpts, ReactRefresh, Ref, RefMap, RefRefMap, RuntimeImports, ScopeOrder, ScopeOrderList, StrictModeFeature, StringBoolMap, Substitution, TempRef, ThenCatchChain, @@ -4633,7 +4633,7 @@ impl<'a, const TYPESCRIPT: bool, const SCAN_ONLY: bool> P<'a, TYPESCRIPT, SCAN_O Ok(ref_) } - pub(crate) fn validate_function_name(&mut self, func: &G::Fn, kind: FunctionKind) { + pub(crate) fn validate_function_name(&mut self, func: &G::Fn) { if let Some(name) = &func.name { // SAFETY: Symbol.original_name is an arena/source-contents slice valid for 'a. let original_name: &[u8] = self.symbols[name.ref_.inner_index() as usize] @@ -4646,9 +4646,7 @@ impl<'a, const TYPESCRIPT: bool, const SCAN_ONLY: bool> P<'a, TYPESCRIPT, SCAN_O js_lexer::range_of_identifier(self.source, name.loc), b"An async function cannot be named \"await\"", ); - } else if kind == FunctionKind::Expr - && func.flags.contains(Flags::Function::IsGenerator) - && original_name == b"yield" + } else if func.flags.contains(Flags::Function::IsGenerator) && original_name == b"yield" { self.log().add_range_error( Some(self.source), diff --git a/src/js_parser/parse/parse_fn.rs b/src/js_parser/parse/parse_fn.rs index 084b395075b0..9b6f21b24863 100644 --- a/src/js_parser/parse/parse_fn.rs +++ b/src/js_parser/parse/parse_fn.rs @@ -5,7 +5,7 @@ use crate::js_lexer; use crate::js_lexer::T; use crate::p::P; use crate::parser::{ - ARGUMENTS_STR as arguments_str, AwaitOrYield, FnOrArrowDataParse, FunctionKind, LexicalDecl, + ARGUMENTS_STR as arguments_str, AwaitOrYield, FnOrArrowDataParse, LexicalDecl, ParseStatementOptions, TypeParameterFlag, }; use bun_ast as js_ast; @@ -479,7 +479,7 @@ impl<'a, const TYPESCRIPT: bool, const SCAN_ONLY: bool> P<'a, TYPESCRIPT, SCAN_O )?; p.fn_or_arrow_data_parse.has_argument_decorators = false; - p.validate_function_name(&func, FunctionKind::Expr); + p.validate_function_name(&func); p.pop_scope(); Ok(p.new_expr(E::Function { func }, loc)) diff --git a/src/js_parser/parser.rs b/src/js_parser/parser.rs index cf8248bf4b40..d3d20a3b0350 100644 --- a/src/js_parser/parser.rs +++ b/src/js_parser/parser.rs @@ -847,12 +847,6 @@ impl Default for ExprOrLetStmt { } } -#[derive(Clone, Copy, PartialEq, Eq)] -pub enum FunctionKind { - Stmt, - Expr, -} - #[repr(u8)] #[derive(Clone, Copy, PartialEq, Eq)] pub(crate) enum AsyncPrefixExpression { diff --git a/src/jsc/bindings/BunObject.cpp b/src/jsc/bindings/BunObject.cpp index 04c1c4ca808b..3703bc8cfce1 100644 --- a/src/jsc/bindings/BunObject.cpp +++ b/src/jsc/bindings/BunObject.cpp @@ -73,8 +73,6 @@ BUN_DECLARE_HOST_FUNCTION(Bun__DNS__reverse); BUN_DECLARE_HOST_FUNCTION(Bun__DNS__lookupService); BUN_DECLARE_HOST_FUNCTION(Bun__DNS__prefetch); BUN_DECLARE_HOST_FUNCTION(Bun__DNS__getCacheStats); -BUN_DECLARE_HOST_FUNCTION(Bun__DNSResolver__new); -BUN_DECLARE_HOST_FUNCTION(Bun__DNSResolver__cancel); BUN_DECLARE_HOST_FUNCTION(Bun__fetch); BUN_DECLARE_HOST_FUNCTION(Bun__fetchPreconnect); BUN_DECLARE_HOST_FUNCTION(Bun__randomUUIDv7); diff --git a/src/jsc/bindings/IDLTypes.h b/src/jsc/bindings/IDLTypes.h index 7ff9eaeaaf20..380b664864b3 100644 --- a/src/jsc/bindings/IDLTypes.h +++ b/src/jsc/bindings/IDLTypes.h @@ -386,10 +386,6 @@ template struct IsIDLDictionary : public std::integral_constant::value> { }; -template -struct IsIDLEnumeration : public std::integral_constant::value> { -}; - template struct IsIDLSequence : public std::integral_constant::value> { }; diff --git a/src/jsc/bindings/InspectorHTTPServerAgent.cpp b/src/jsc/bindings/InspectorHTTPServerAgent.cpp index db5a0b891bbe..1b236bf4cb79 100644 --- a/src/jsc/bindings/InspectorHTTPServerAgent.cpp +++ b/src/jsc/bindings/InspectorHTTPServerAgent.cpp @@ -67,43 +67,6 @@ Protocol::ErrorStringOr InspectorHTTPServerAgent::disable() return {}; } -Protocol::ErrorStringOr InspectorHTTPServerAgent::startListening(int serverId) -{ - if (!m_enabled) - return {}; - - return {}; -} - -Protocol::ErrorStringOr InspectorHTTPServerAgent::stopListening(int serverId) -{ - if (!m_enabled) - return {}; - - // TODO: - // Bun__HTTPServerAgentStopListening(this, serverId); - return {}; -} - -Protocol::ErrorStringOr InspectorHTTPServerAgent::getRequestBody(int requestId, int serverId) -{ - if (!m_enabled) - return {}; - - // TODO: - // Bun__HTTPServerAgentGetRequestBody(this, requestId, serverId); - return {}; -} - -Protocol::ErrorStringOr InspectorHTTPServerAgent::getResponseBody(int requestId, int serverId) -{ - if (!m_enabled) - return {}; - // TODO: - // Bun__HTTPServerAgentGetResponseBody(this, requestId, serverId); - return {}; -} - // Event dispatchers void InspectorHTTPServerAgent::serverStarted(int serverId, const String& url, double startTime, AnyServerPtr serverInstance) diff --git a/src/jsc/bindings/InspectorHTTPServerAgent.h b/src/jsc/bindings/InspectorHTTPServerAgent.h index 432a5fc87786..18d0060e3643 100644 --- a/src/jsc/bindings/InspectorHTTPServerAgent.h +++ b/src/jsc/bindings/InspectorHTTPServerAgent.h @@ -34,10 +34,6 @@ class InspectorHTTPServerAgent final : public InspectorAgentBase, public Inspect // HTTPServerBackendDispatcherHandler virtual Inspector::CommandResult enable() final; virtual Inspector::CommandResult disable() final; - virtual Inspector::CommandResult startListening(int serverId) final; - virtual Inspector::CommandResult stopListening(int serverId) final; - virtual Inspector::CommandResult getRequestBody(int requestId, int serverId) final; - virtual Inspector::CommandResult getResponseBody(int requestId, int serverId) final; // Events API void serverStarted(int serverId, const String& url, double startTime, AnyServerPtr serverInstance); diff --git a/src/jsc/bindings/JSBuffer.cpp b/src/jsc/bindings/JSBuffer.cpp index 217d29703063..c97046349280 100644 --- a/src/jsc/bindings/JSBuffer.cpp +++ b/src/jsc/bindings/JSBuffer.cpp @@ -111,7 +111,6 @@ JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_byteLength); JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_compare); JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_concat); JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_copyBytesFrom); -JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_isBuffer); JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_isEncoding); JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_compare); diff --git a/src/jsc/bindings/ZigGlobalObject.cpp b/src/jsc/bindings/ZigGlobalObject.cpp index ca0613b6d856..75e19bc44387 100644 --- a/src/jsc/bindings/ZigGlobalObject.cpp +++ b/src/jsc/bindings/ZigGlobalObject.cpp @@ -235,9 +235,6 @@ using namespace Bun; BUN_DECLARE_HOST_FUNCTION(Bun__NodeUtil__jsParseArgs); -BUN_DECLARE_HOST_FUNCTION(BUN__HTTP2__getUnpackedSettings); -BUN_DECLARE_HOST_FUNCTION(BUN__HTTP2_getPackedSettings); -BUN_DECLARE_HOST_FUNCTION(BUN__HTTP2_assertSettings); JSC_DECLARE_HOST_FUNCTION(jsFunctionMakeAbortError); @@ -3111,9 +3108,6 @@ JSValue GlobalObject_getGlobalThis(VM& vm, JSObject* globalObject) return uncheckedDowncast(globalObject)->globalThis(); } -// This is like `putDirectBuiltinFunction` but for the global static list. -#define globalBuiltinFunction(vm, globalObject, identifier, function, attributes) JSC::JSGlobalObject::GlobalPropertyInfo(identifier, JSFunction::create(vm, function, globalObject), attributes) - void GlobalObject::addBuiltinGlobals(JSC::VM& vm) { auto scope = DECLARE_TOP_EXCEPTION_SCOPE(vm); diff --git a/src/jsc/bindings/node/crypto/CryptoUtil.h b/src/jsc/bindings/node/crypto/CryptoUtil.h index b70ce9223f76..3e35a40745e4 100644 --- a/src/jsc/bindings/node/crypto/CryptoUtil.h +++ b/src/jsc/bindings/node/crypto/CryptoUtil.h @@ -63,7 +63,6 @@ bool convertP1363ToDER(const ncrypto::Buffer& p1363Sig, con GCOwnedDataScope> getArrayBufferOrView2(JSGlobalObject* globalObject, ThrowScope& scope, JSValue dataValue, ASCIILiteral argName, JSValue encodingValue, bool arrayBufferViewOnly = false); JSC::JSArrayBufferView* getArrayBufferOrView(JSGlobalObject* globalObject, ThrowScope& scope, JSValue value, ASCIILiteral argName, JSValue encodingValue, bool defaultBufferEncoding = false); JSC::JSArrayBufferView* getArrayBufferOrView(JSGlobalObject* globalObject, ThrowScope& scope, JSValue value, ASCIILiteral argName, BufferEncodingType encoding); -JSValue getStringOption(JSGlobalObject* globalObject, JSValue options, const WTF::ASCIILiteral& name); bool isKeyValidForCurve(const EC_GROUP* group, const ncrypto::BignumPointer& privateKey); std::optional> getBuffer(JSC::JSValue maybeBuffer); diff --git a/src/runtime/api.rs b/src/runtime/api.rs index 680029fafff1..0e1cddc94915 100644 --- a/src/runtime/api.rs +++ b/src/runtime/api.rs @@ -157,9 +157,8 @@ pub mod bun { pub mod h2_frame_parser { pub use crate::api::h2_frame_parser_body::H2FrameParser; - // js2native thunks (`$rust(h2_frame_parser.rs, …)` in generated_js2native.rs). + // js2native thunk (`$rust(h2_frame_parser.rs, …)` in generated_js2native.rs). pub(crate) use crate::api::h2_frame_parser_body::h2_frame_parser_constructor; - pub(crate) use crate::api::h2_frame_parser_body::js_assert_settings; } pub use h2_frame_parser::H2FrameParser; } diff --git a/src/runtime/api/bun/h2_frame_parser.rs b/src/runtime/api/bun/h2_frame_parser.rs index d49694b433da..c8a9a418d495 100644 --- a/src/runtime/api/bun/h2_frame_parser.rs +++ b/src/runtime/api/bun/h2_frame_parser.rs @@ -750,150 +750,6 @@ fn single_value_headers_index_of(name: &[u8]) -> Option { SINGLE_VALUE_HEADERS.get(name).copied() } -// ────────────────────────────────────────────────────────────────────────── -// Standalone host functions -// ────────────────────────────────────────────────────────────────────────── - -#[bun_jsc::host_fn] -pub fn js_assert_settings( - global_object: &JSGlobalObject, - callframe: &CallFrame, -) -> JsResult { - let [options] = callframe.arguments_as_array::<1>(); - if callframe.arguments_count() < 1 { - return Err(global_object.throw(format_args!("Expected settings to be a object"))); - } - - if callframe.arguments_count() > 0 && !options.is_empty_or_undefined_or_null() { - if !options.is_object() { - return Err(global_object.throw(format_args!("Expected settings to be a object"))); - } - - if let Some(header_table_size) = options.get(global_object, "headerTableSize")? { - if header_table_size.is_number() { - let value = header_table_size.as_number(); - if value < 0.0 || value > MAX_HEADER_TABLE_SIZE_F64 { - return global_object - .err_http2_invalid_setting_value_range_error( - "Expected headerTableSize to be a number between 0 and 2^32-1", - ) - .throw(); - } - } else if !header_table_size.is_empty_or_undefined_or_null() { - return global_object - .err_http2_invalid_setting_value_range_error( - "Expected headerTableSize to be a number", - ) - .throw(); - } - } - - if let Some(enable_push) = options.get(global_object, "enablePush")? { - if !enable_push.is_boolean() && !enable_push.is_undefined() { - return global_object - .err_http2_invalid_setting_value("Expected enablePush to be a boolean") - .throw(); - } - } - - if let Some(initial_window_size) = options.get(global_object, "initialWindowSize")? { - if initial_window_size.is_number() { - let value = initial_window_size.as_number(); - if value < 0.0 || value > MAX_WINDOW_SIZE_F64 { - return global_object - .err_http2_invalid_setting_value_range_error( - "Expected initialWindowSize to be a number between 0 and 2^32-1", - ) - .throw(); - } - } else if !initial_window_size.is_empty_or_undefined_or_null() { - return global_object - .err_http2_invalid_setting_value_range_error( - "Expected initialWindowSize to be a number", - ) - .throw(); - } - } - - if let Some(max_frame_size) = options.get(global_object, "maxFrameSize")? { - if max_frame_size.is_number() { - let value = max_frame_size.as_number(); - if value < 16384.0 || value > MAX_FRAME_SIZE_F64 { - return global_object - .err_http2_invalid_setting_value_range_error( - "Expected maxFrameSize to be a number between 16,384 and 2^24-1", - ) - .throw(); - } - } else if !max_frame_size.is_empty_or_undefined_or_null() { - return global_object - .err_http2_invalid_setting_value_range_error( - "Expected maxFrameSize to be a number", - ) - .throw(); - } - } - - if let Some(max_concurrent_streams) = options.get(global_object, "maxConcurrentStreams")? { - if max_concurrent_streams.is_number() { - let value = max_concurrent_streams.as_number(); - if value < 0.0 || value > MAX_HEADER_TABLE_SIZE_F64 { - return global_object - .err_http2_invalid_setting_value_range_error( - "Expected maxConcurrentStreams to be a number between 0 and 2^32-1", - ) - .throw(); - } - } else if !max_concurrent_streams.is_empty_or_undefined_or_null() { - return global_object - .err_http2_invalid_setting_value_range_error( - "Expected maxConcurrentStreams to be a number", - ) - .throw(); - } - } - - if let Some(max_header_list_size) = options.get(global_object, "maxHeaderListSize")? { - if max_header_list_size.is_number() { - let value = max_header_list_size.as_number(); - if value < 0.0 || value > MAX_HEADER_TABLE_SIZE_F64 { - return global_object - .err_http2_invalid_setting_value_range_error( - "Expected maxHeaderListSize to be a number between 0 and 2^32-1", - ) - .throw(); - } - } else if !max_header_list_size.is_empty_or_undefined_or_null() { - return global_object - .err_http2_invalid_setting_value_range_error( - "Expected maxHeaderListSize to be a number", - ) - .throw(); - } - } - - if let Some(max_header_size) = options.get(global_object, "maxHeaderSize")? { - if max_header_size.is_number() { - let value = max_header_size.as_number(); - if value < 0.0 || value > MAX_HEADER_TABLE_SIZE_F64 { - return global_object - .err_http2_invalid_setting_value_range_error( - "Expected maxHeaderSize to be a number between 0 and 2^32-1", - ) - .throw(); - } - } else if !max_header_size.is_empty_or_undefined_or_null() { - return global_object - .err_http2_invalid_setting_value_range_error( - "Expected maxHeaderSize to be a number", - ) - .throw(); - } - } - } - Ok(JSValue::UNDEFINED) -} - // ────────────────────────────────────────────────────────────────────────── // Handlers // ────────────────────────────────────────────────────────────────────────── diff --git a/src/semver/lib.rs b/src/semver/lib.rs index aadba242a72f..343b563c21b1 100644 --- a/src/semver/lib.rs +++ b/src/semver/lib.rs @@ -757,7 +757,7 @@ pub mod semver_string { } // Bridge to `bun_collections::ArrayHashMap` adapted lookups so callers can - // pass `ArrayHashContext` directly to `get_adapted` / `get_or_put_adapted` + // pass `ArrayHashContext` directly to `get_index_adapted` / `get_or_put_adapted` // / `put_assume_capacity_context` without a per-crate orphan-rule wrapper. impl<'a> bun_collections::array_hash_map::ArrayHashAdapter for ArrayHashContext<'a> diff --git a/test/internal/source-lints/dead-symbols-http2-settings-inspector-stubs.test.ts b/test/internal/source-lints/dead-symbols-http2-settings-inspector-stubs.test.ts new file mode 100644 index 000000000000..ad0ac67d77d9 --- /dev/null +++ b/test/internal/source-lints/dead-symbols-http2-settings-inspector-stubs.test.ts @@ -0,0 +1,153 @@ +// Guards against reintroduction of symbols removed as dead code from the +// node:http2 settings plumbing (JS, Rust and C++ sides), the inspector +// HTTPServer agent, a few declaration-only C++ leftovers, two uSockets TLS +// helpers, a handful of never-called Rust items, and the builtin-name tables. +// Each entry was verified to have zero references across src/, packages/, +// scripts/, test/ and freshly regenerated build/debug/codegen/ output before +// deletion (the Rust items additionally by a cross-crate reachability analysis +// on six target triples), and the removal was validated by `cargo check` on +// every CI target triple plus a full `bun bd` build. +// +// This is a source-tree lint: it reads files from src/ and packages/ and does +// not touch the built binary, so it belongs in test/internal/source-lints/ per +// the README. + +import { expect, test } from "bun:test"; +import { existsSync, readFileSync } from "node:fs"; +import path from "node:path"; + +const repoRoot = path.resolve(import.meta.dir, "..", "..", ".."); + +function src(p: string): string { + return readFileSync(path.join(repoRoot, p), "utf8"); +} + +function resurrected(checks: Array<[string, RegExp]>): string[] { + return checks.filter(([file, re]) => re.test(src(file))).map(([file, re]) => `${file}: ${re.source}`); +} + +test("the unused node:http2 settings plumbing does not reappear", () => { + const http2 = src("src/js/node/http2.ts"); + + // The native assertSettings binding: http2.ts has had its own JS + // assertSettings() since #28074, so the binding, the Rust host function + // behind it and the Zig-era C++ declarations of the settings helpers were + // all unreachable. + expect(http2).not.toMatch(/_nativeAssertSettings|jsAssertSettings/); + expect(src("src/runtime/api/bun/h2_frame_parser.rs")).not.toMatch(/\bjs_assert_settings\b/); + expect(src("src/jsc/bindings/ZigGlobalObject.cpp")).not.toMatch(/BUN__HTTP2/); + + // `const Socket = net.Socket` and the two ServerHttp2Session private fields + // were never read. + expect(http2).not.toMatch(/^const Socket = net\.Socket;$/m); + expect(http2).not.toMatch(/^\s+#isServer\b/m); + expect(http2.match(/^\s+#url: URL;$/gm) ?? []).toHaveLength(1); // ClientHttp2Session's, which is read + + // The `const { ... } = constants;` block used to bind every constant as a + // local; 178 of the 240 bindings were unused (all call sites read + // `constants.X`). Pin a sample spanning each family of the block. + const end = http2.indexOf("} = constants;"); + expect(end).toBeGreaterThan(-1); + const start = http2.lastIndexOf("const {", end); + expect(start).toBeGreaterThan(-1); + const bound = new Set( + http2 + .slice(start, end) + .split("\n") + .slice(1) + .map(line => line.trim().replace(/,$/, "")) + .filter(Boolean), + ); + const removed = [ + "NGHTTP2_ERR_FRAME_SIZE_ERROR", + "NGHTTP2_PROTOCOL_ERROR", + "NGHTTP2_REFUSED_STREAM", + "NGHTTP2_FLAG_END_STREAM", + "NGHTTP2_SETTINGS_HEADER_TABLE_SIZE", + "DEFAULT_SETTINGS_MAX_FRAME_SIZE", + "PADDING_STRATEGY_ALIGNED", + "HTTP2_HEADER_ACCEPT", + "HTTP2_HEADER_CONTENT_DISPOSITION", + "HTTP2_METHOD_POST", + "HTTP_STATUS_NOT_FOUND", + "HTTP_STATUS_INTERNAL_SERVER_ERROR", + ]; + expect(removed.filter(name => bound.has(name))).toEqual([]); + // ...while the bindings that are actually used are still there. + expect(bound.has("NGHTTP2_SESSION_SERVER")).toBe(true); + expect(bound.has("HTTP2_HEADER_STATUS")).toBe(true); + expect(bound.has("HTTP_STATUS_OK")).toBe(true); +}); + +test("dead C++ bindings do not reappear", () => { + expect( + resurrected([ + // Protocol command stubs the HTTPServer inspector domain never had + // (the generated HTTPServerBackendDispatcherHandler only declares + // enable/disable), so nothing could dispatch to them. + ["src/jsc/bindings/InspectorHTTPServerAgent.h", /startListening|stopListening|getRequestBody|getResponseBody/], + ["src/jsc/bindings/InspectorHTTPServerAgent.cpp", /startListening|stopListening|getRequestBody|getResponseBody/], + // Declarations whose definitions no longer exist anywhere. + ["src/jsc/bindings/BunObject.cpp", /Bun__DNSResolver__(new|cancel)\b/], + ["src/jsc/bindings/JSBuffer.cpp", /jsBufferConstructorFunction_isBuffer\b/], + ["src/jsc/bindings/node/crypto/CryptoUtil.h", /\bgetStringOption\b/], + // Helper template and macro with zero uses. + ["src/jsc/bindings/IDLTypes.h", /\bIsIDLEnumeration\b/], + ["src/jsc/bindings/ZigGlobalObject.cpp", /\bglobalBuiltinFunction\b/], + ]), + ).toEqual([]); +}); + +test("dead uSockets TLS helpers do not reappear", () => { + expect( + resurrected([ + // Declared and defined since #29932, never called. + ["packages/bun-usockets/src/internal/internal.h", /us_internal_ssl_sni_userdata|us_internal_ssl_handshake_abort/], + ["packages/bun-usockets/src/crypto/openssl.c", /us_internal_ssl_sni_userdata|us_internal_ssl_handshake_abort/], + // The Security.framework teardown hook had no caller; the loader's + // failure paths are the only thing that ever frees a SecurityFramework. + ["packages/bun-usockets/src/crypto/root_certs_platform.h", /us_cleanup_security_framework/], + [ + "packages/bun-usockets/src/crypto/root_certs_darwin.cpp", + /us_cleanup_security_framework|\bSecTrustSettingsResult;/, + ], + ]), + ).toEqual([]); +}); + +test("dead Rust items do not reappear", () => { + expect( + resurrected([ + // validate_function_name only ever ran for function expressions, so the + // FunctionKind parameter (and its never-constructed Stmt variant) went. + ["src/js_parser/parser.rs", /\bFunctionKind\b/], + ["src/js_parser/p.rs", /\bFunctionKind\b/], + ["src/js_parser/parse/parse_fn.rs", /\bFunctionKind\b/], + // Accessors nothing in the workspace called. + ["src/ast/expr.rs", /\bfn is_e_string\b/], + ["src/collections/array_hash_map.rs", /\bfn get_adapted\b/], + ["src/install_types/resolver_hooks.rs", /\bpub fn eq\(/], + ]), + ).toEqual([]); +}); + +test("dead builtin-name table entries do not reappear", () => { + const names = src("src/js/builtins/BunBuiltinNames.h"); + const dead = ["Loader", "byobRequest", "controller", "post", "resume", "started", "state", "textDecoder", "view"]; + expect(dead.filter(name => names.includes(`macro(${name})`))).toEqual([]); + + const dts = src("src/js/builtins.d.ts"); + expect(dead.filter(name => new RegExp(`^declare function \\$${name}\\(`, "m").test(dts))).toEqual([]); + expect(dts).not.toMatch(/\$stream(Closed|Closing|Errored|Readable|Waiting|Writable)\b/); + + const replacements = src("src/codegen/replacements.ts"); + expect(replacements).not.toMatch(/\$stream(Closed|Closing|Errored|Readable|Waiting|Writable)\b/); + expect(replacements).not.toMatch(/^\s*"Loader",$/m); + expect(replacements.match(/^\s*"Buffer",$/gm)).toHaveLength(1); +}); + +test("orphaned files stay deleted", () => { + // Superseded by the hawk setup in tools/hawk/ and hawk.toml; nothing + // referenced it. + expect(existsSync(path.join(repoRoot, "scripts/find-dead-exports.ts"))).toBe(false); +});