Skip to content
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
5088d17
Replace bindgen v1 and v2 with one generator that also does classes
dylan-conway Oct 13, 2026
ea1ad16
Include FunctionPrototype.h in ModuleGraph.cpp and make the forged-er…
dylan-conway Oct 13, 2026
dedec64
Rename klass, values, .nullable.loose and the string and buffer types…
dylan-conway Oct 13, 2026
b561935
Load schemas with import() so the generator runs under Node, and fix …
dylan-conway Oct 13, 2026
bb9d2d8
Fix a use-after-free of substring bytes, read buffers and members lat…
dylan-conway Oct 13, 2026
50fe671
Name both .bind.ts files when two of them generate the same header
dylan-conway Oct 13, 2026
81a7bf3
Test that native node:os functions are not constructors and that Glob…
dylan-conway Oct 13, 2026
f555dfb
Stop naming Glob in the .classes.ts skill's example
dylan-conway Oct 13, 2026
937eed1
[autofix.ci] apply automated fixes
autofix-ci[bot] Oct 13, 2026
d2849b2
Use a cwd over every platform's path limit in the Glob option-order test
dylan-conway Oct 13, 2026
6c64a49
Generate compiling Rust for nullable byte views, assert the exact err…
dylan-conway Oct 13, 2026
acbac08
Build string views in place, make small arrays in one call, encode la…
dylan-conway Oct 13, 2026
5482813
Delete the compile-fail tests for bun_jsc::bindgen
dylan-conway Oct 13, 2026
7eaf467
Share one dictionary member read, let a dictionary ignore non-objects…
dylan-conway Oct 13, 2026
db99ca2
Describe allowArray and allowNonObject correctly and refuse allowNonO…
dylan-conway Oct 13, 2026
8bde319
Check the size of returned dictionaries at compile time against JSC's…
dylan-conway Oct 13, 2026
69080b7
Leave bindgen_test.bind.ts out of builds without assertions
dylan-conway Oct 13, 2026
669eb2f
Merge main, keeping Glob's shared pattern buffer and prepared matcher…
dylan-conway Oct 13, 2026
511afb8
Describe every schema in Bindgen.d.ts whatever the profile, and run t…
dylan-conway Oct 13, 2026
b3bb7e0
Refuse views of shared memory in b.bufferSource.arrayBuffer and keep …
dylan-conway Oct 13, 2026
83a8361
Merge main
dylan-conway Oct 13, 2026
3ab2c90
Merge branch 'main' into claude/bun-jsc-bindgen-unify-348a32
dylan-conway Oct 13, 2026
5d5406a
Merge main
dylan-conway Oct 15, 2026
511f86b
Choose a union's alternative and an overload by the kind of the value…
dylan-conway Oct 15, 2026
670c522
Hold a union as a struct with a member for each alternative instead o…
dylan-conway Oct 15, 2026
6febce3
Remove the rules that the conservative stack scanner is never the cause
dylan-conway Oct 15, 2026
ba8ebab
Restore the conservative stack scanner rules in CLAUDE.md and REVIEW.md
dylan-conway Oct 15, 2026
3137a34
Inline the string test of both UTF-8 conversions, make a union's larg…
dylan-conway Oct 15, 2026
15c2e6b
Inline the fast path of every strict conversion, and give a nested op…
dylan-conway Oct 15, 2026
ab05686
Always assign a nullable member that does not convert in place
dylan-conway Oct 15, 2026
da328db
Delete what the generic union converter left behind, make the UTF-8 v…
dylan-conway Oct 15, 2026
88fa693
Apply the conventions and simplification reviews to the generator, it…
dylan-conway Oct 15, 2026
05362c9
Make the list of a union's alternatives a complete type
dylan-conway Oct 15, 2026
9819231
Give a view's own bytes to b.bufferSource.arrayBuffer, make the array…
dylan-conway Oct 15, 2026
7affdf9
Stop looking at the number of arguments: one that was not passed is u…
dylan-conway Oct 15, 2026
8b7bab6
Give a dictionary that is only returned a lifetime only when it holds…
dylan-conway Oct 15, 2026
b433f83
Merge branch 'main' of github.com:oven-sh/bun into claude/bun-jsc-bin…
dylan-conway Oct 15, 2026
68559e5
Rename what the naming review found false or ambiguous, apply the con…
dylan-conway Oct 15, 2026
1129bcf
Declare the buffer converter's throw scope where it throws
dylan-conway Oct 15, 2026
b81d83a
Rename JsValue, JsCall, the error makers, $bindgenFn, internalName an…
dylan-conway Oct 15, 2026
994b62d
Move everything only generated bindings use into Bindgen/ and Bun::Bi…
dylan-conway Oct 15, 2026
ae57651
[autofix.ci] apply automated fixes
autofix-ci[bot] Oct 15, 2026
8013de7
Merge branch 'main' of github.com:oven-sh/bun into claude/bun-jsc-bin…
dylan-conway Oct 16, 2026
638d42f
Tie every borrowed argument to its call, purify NaN results, use JSC'…
dylan-conway Oct 16, 2026
ef741e4
Match the receiver error's message with a matcher that exists
dylan-conway Oct 16, 2026
b952b54
Build a returned dictionary with putDirect instead of a prebuilt Stru…
dylan-conway Oct 16, 2026
9af4c09
Use JSC's, WTF's and the tree's own helpers where generated bindings …
dylan-conway Oct 16, 2026
afdb6fa
Refuse a type used from another crate and a field named by a C++ keyw…
dylan-conway Oct 16, 2026
52f5c7a
Validate an int32 in range inline, and make a short array with one call
dylan-conway Oct 16, 2026
24567b6
Refuse an array whose elements hold JS values as a result too, not on…
dylan-conway Oct 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .claude/skills/implementing-jsc-classes-rust/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Bridge JavaScript and Rust through `.classes.ts` definitions and Rust implementa
```typescript
export default [
define({
name: "Glob",
name: "Matcher",
construct: true,
finalize: true,
hasPendingActivity: true,
Expand All @@ -45,16 +45,16 @@ use bun_jsc::{CallFrame, JSGlobalObject, JSValue, JsResult};
use std::sync::atomic::{AtomicUsize, Ordering};

#[bun_jsc::JsClass]
pub struct Glob {
pub struct Matcher {
pattern: Box<[u8]>,
has_pending_activity: AtomicUsize,
}

impl Glob {
pub fn constructor(global: &JSGlobalObject, frame: &CallFrame) -> JsResult<Box<Glob>> {
impl Matcher {
pub fn constructor(global: &JSGlobalObject, frame: &CallFrame) -> JsResult<Box<Matcher>> {
let arg = frame.argument(0);
let pattern = bun_core::String::from_js(arg, global)?.to_utf8_bytes().into();
Ok(Box::new(Glob { pattern, has_pending_activity: AtomicUsize::new(0) }))
Ok(Box::new(Matcher { pattern, has_pending_activity: AtomicUsize::new(0) }))
}

#[bun_jsc::host_fn(method)]
Expand Down Expand Up @@ -88,7 +88,7 @@ A missing or mis-typed hook is a **compile error** in `cargo check -p bun_runtim
The codegen also emits a `js_$T` module with the cached-value accessors. Re-export it when you need `*_set_cached` / `*_get_cached` or `detach_ptr`:

```rust
pub use crate::generated_classes::js_Glob as js;
pub use crate::generated_classes::js_Image as js;
// or
bun_jsc::impl_js_class_via_generated!(Archive => crate::generated_classes::js_Archive);
```
Expand Down Expand Up @@ -124,7 +124,7 @@ Never store raw `JSValue` in a struct field. Declare a slot in `.classes.ts` (`v

## Reference implementations

- `src/runtime/api/glob.rs` + `Glob.classes.ts` — constructor, methods, `hasPendingActivity`, default finalize
- `src/runtime/api/Shell.classes.ts` — constructor, methods, `hasPendingActivity`
- `src/runtime/api/cron.rs` + `cron.classes.ts` — `noConstructor`, cached getter, `values: [...]`, custom finalize
- `src/runtime/image/Image.rs:56` — the `pub use crate::generated_classes::js_Image as js;` one-liner
- `src/jsc/host_fn.rs` — the host-fn adapters the codegen dispatches through
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/rust-lints.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- "src/**/*.rs"
- "src/**/Cargo.toml"
- "src/**/*.classes.ts"
- "src/**/*.bind.ts"
- "src/codegen/**"
- "scripts/build/**"
- "scripts/build.ts"
Expand Down
6 changes: 0 additions & 6 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@
"printWidth": 80
}
},
{
"files": ["src/codegen/bindgenv2/**/*.ts", "*.bindv2.ts"],
"options": {
"printWidth": 100
}
},
{
"files": ["src/runtime/cli/init/**"],
"options": {
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ When implementing JavaScript classes in C++:

Code generation happens automatically as part of the build process. The main scripts are:

- `src/codegen/bindgen.ts` - Generates Rust, C++ & TypeScript bindings from `*.bind.ts` files (`docs/project/bindgen.mdx`)
- `src/codegen/generate-classes.ts` - Generates Rust & C++ bindings from `*.classes.ts` files
- `src/codegen/generate-jssink.ts` - Generates stream-related classes
- `src/codegen/bundle-modules.ts` - Bundles built-in modules like `node:fs`
Expand Down
548 changes: 347 additions & 201 deletions docs/project/bindgen.mdx

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion mordant-baseline.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@
"defaulted_failure:src/jsc/ConsoleObject.rs" = 4
"generic_body_not_generic:src/jsc/ConsoleObject.rs" = 6
"generic_body_not_generic:src/jsc/JSPropertyIterator.rs" = 1
"unused_pub:src/jsc/bindgen.rs" = 6
"unused_pub:src/jsc/host_fn.rs" = 2
"unused_pub:src/jsc/lib.rs" = 1

Expand Down
2 changes: 1 addition & 1 deletion scripts/build/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ CI's `build-bun` step builds the same graph (`ci-build` profile: release, prebui

`--mode=codegen` configures a graph of the codegen steps only, default target `codegen`, for what needs their outputs and no binary. It has a build directory of its own (`build/debug-codegen`): its manifest and `compile_commands.json` have no native edges in them, and `build/debug` is where clangd reads `compile_commands.json`. `bun run build:types` (`--mode=codegen --target=generated-types`) is what `lint.yml` runs before typechecking `src/js`.

**`build/types/` (`cfg.typesDir`)** holds the type declarations `src/js/builtins.d.ts` references: `generated.d.ts`, `ErrorCode.d.ts`, `ZigGeneratedClasses.d.ts`, `WebCoreJSBuiltins.d.ts`. They are made from source alone (byte-identical between debug and release), so they do not live under a profile's build directory: every profile's graph declares the same files there, the way a dep's `vendor/<name>/.ref` is, and any build keeps them current for the editor. They are declared outputs of the edges that write them (`CodegenOutputs.generatedTypes`, target `generated-types`), so ninja regenerates one that is deleted or whose edge inputs changed. `src/runtime/bake/generated.ts` (the dev server's message enums, which the bake project imports) is in the same target, declared by the bake codegen edge that writes it.
**`build/types/` (`cfg.typesDir`)** holds the type declarations `src/js/builtins.d.ts` references: `generated.d.ts`, `ErrorCode.d.ts`, `ZigGeneratedClasses.d.ts`, `WebCoreJSBuiltins.d.ts`, `Bindgen.d.ts`. They are made from source alone (byte-identical between debug and release), so they do not live under a profile's build directory: every profile's graph declares the same files there, the way a dep's `vendor/<name>/.ref` is, and any build keeps them current for the editor. They are declared outputs of the edges that write them (`CodegenOutputs.generatedTypes`, target `generated-types`), so ninja regenerates one that is deleted or whose edge inputs changed. `src/runtime/bake/generated.ts` (the dev server's message enums, which the bake project imports) is in the same target, declared by the bake codegen edge that writes it.

It is configured by `configureCodegen()`, not `configure()`, and resolves a `CodegenConfig`, not a `Config`:

Expand Down
1 change: 0 additions & 1 deletion scripts/build/bun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,6 @@ export function emitBun(n: Ninja, cfg: Config, sources: Sources): BunOutput {

// Codegen .cpp files — compiled like regular sources.
cxxSources.push(...codegen.cppSources);
cxxSources.push(...codegen.bindgenV2Cpp);

// All deps must be ready (headers extracted, libs built) before compile.
//
Expand Down
158 changes: 67 additions & 91 deletions scripts/build/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@
* configure time via `globAllSources()`. The expanded
* paths are baked into build.ninja; adding a file picks up on next configure.
*
* bindgenv2 is special: its output set is dynamic (depends on which types
* the .bindv2.ts files export). We invoke it with `--command=list-outputs`
* at CONFIGURE time to get the actual output paths.
*
* ## Undeclared outputs
*
* Every generated file that is compiled or #included must be a declared
Expand All @@ -22,7 +18,7 @@
* depfile entry does that within the same run only if it names a declared
* output, which ninja re-stats after the step ran. A file no edge declares
* is stat'd once at startup, so a compile that includes it picks up a rerun
* of the step one build late. That is why emitBindgen/emitBindgenV2 declare
* of the step one build late. That is why emitBindgen declares
* the per-file Generated*.h headers and not just the .cpp that gets compiled.
*
* Files nothing compiles may stay undeclared (bundle-modules' eval/ dir,
Expand All @@ -32,8 +28,7 @@
* reached through the PCH.
*/

import { spawnSync } from "node:child_process";
import { mkdirSync, readFileSync } from "node:fs";
import { existsSync, mkdirSync, readFileSync } from "node:fs";
import { basename, dirname, relative, resolve } from "node:path";
import type { Sources } from "../glob-sources.ts";
import { generateBuildOptionsRs } from "./buildOptionsRs.ts";
Expand Down Expand Up @@ -245,8 +240,8 @@ export interface CodegenOutputs {
cppHeaders: string[];

/**
* ALL cpp-relevant codegen outputs — the union of cppHeaders, cppSources,
* bindgenV2Cpp. cxx compilation order-depends on THIS (not `all`): cxx
* ALL cpp-relevant codegen outputs — the union of cppHeaders and
* cppSources. cxx compilation order-depends on THIS (not `all`): cxx
* doesn't need bake.*.js, runtime.out.js, or any other rust-side embedded
* outputs: those are inputs of the Rust crates, not of any C++ object.
*
Expand All @@ -256,9 +251,6 @@ export interface CodegenOutputs {
*/
cppAll: string[];

/** The bindgenv2 .cpp outputs (compiled separately from handwritten C++). */
bindgenV2Cpp: string[];

/**
* The InternalModuleRegistryConstants.S path — compiled via cc() in bun.ts
* and linked alongside the C++ objects. Carries the concatenated JS module
Expand Down Expand Up @@ -299,7 +291,6 @@ export function emitCodegen(n: Ninja, cfg: CodegenFields, sources: Sources): Cod
cppSources: [],
cppHeaders: [],
cppAll: [],
bindgenV2Cpp: [],
internalModulesAsm: resolve(cfg.codegenDir, "InternalModuleRegistryConstants.S"),
internalModulesBin: resolve(cfg.codegenDir, "InternalModuleRegistryConstants.bin"),
rootInstall,
Expand Down Expand Up @@ -335,7 +326,6 @@ export function emitCodegen(n: Ninja, cfg: CodegenFields, sources: Sources): Cod
emitCppBind(ctx);
emitJsModules(ctx);
emitBakeCodegen(ctx);
emitBindgenV2(ctx);
emitBindgen(ctx);
emitJsSink(ctx);
emitObjectLuts(ctx);
Expand All @@ -347,7 +337,7 @@ export function emitCodegen(n: Ninja, cfg: CodegenFields, sources: Sources): Cod
n.blank();

// Assemble cppAll — the cxx-relevant subset. See field docstring.
o.cppAll = [...new Set([...o.cppHeaders, ...o.cppSources, ...o.bindgenV2Cpp])];
o.cppAll = [...new Set([...o.cppHeaders, ...o.cppSources])];

return o;
}
Expand Down Expand Up @@ -880,7 +870,7 @@ function emitJsModules({ n, cfg, sources, o, dirStamp }: Ctx): void {
desc: "JS modules (bundle-modules)",
// Note: arg is BUILD_PATH (buildDir), not CODEGEN_PATH. The script
// derives CODEGEN_DIR = join(BUILD_PATH, "codegen") internally.
args: shJoin(cfg, ["run", script, debugFlag(cfg), cfg.buildDir, cfg.typesDir]),
args: shJoin(cfg, ["run", script, debugFlag(cfg), cfg.buildDir, cfg.typesDir, typesOnlyFlag(cfg, sources)]),
},
});

Expand Down Expand Up @@ -931,99 +921,85 @@ function emitBakeCodegen({ n, cfg, sources, o, dirStamp }: Ctx): void {
o.rustInputs.push(...outputs);
}

/** Exported (with emitBindgen) for test/internal/build-codegen-declared-outputs.test.ts. */
export function emitBindgenV2({ n, cfg, sources, o, dirStamp }: Ctx): void {
const script = resolve(cfg.cwd, "src", "codegen", "bindgenv2", "script.ts");

// The script's output set depends on which NamedTypes the .bindv2.ts files
// export. We run `--command=list-outputs` SYNCHRONOUSLY at configure time
// to get the real list. This is a configure-time dependency on the
// sources — same tradeoff CMake makes with execute_process().
//
// It runs with cfg.jsRuntime, the runtime that runs configure. It is a
// child process, not an import: in this process, node would print
// MODULE_TYPELESS_PACKAGE_JSON for the .ts files under src/. cfg.jsRuntime
// is a shell command prefix, so the command goes through the host shell.
//
// If list-outputs fails (e.g. syntax error in a .bindv2.ts file), we fail
// configure immediately with a clear error. Better to catch that here than
// get a cryptic "multiple rules generate <unknown>" from ninja.
const sourcesArg = sources.bindgenV2.join(",");
const listArgs = [script, "--command=list-outputs", `--sources=${sourcesArg}`, `--codegen-path=${cfg.codegenDir}`];
const listResult = spawnSync(`${cfg.jsRuntime} ${shJoin(cfg, listArgs)}`, {
cwd: cfg.cwd,
encoding: "utf8",
shell: true,
});
if (listResult.status !== 0) {
throw new BuildError(`bindgenv2 list-outputs failed (exit ${listResult.status})`, {
file: script,
hint: listResult.stderr?.trim(),
});
}
// Output is semicolon-separated (CMake list format).
const allOutputs = listResult.stdout
.trim()
.split(";")
.filter(p => p.length > 0);

assert(allOutputs.length > 0, "bindgenv2 list-outputs returned no files");

const cppOutputs = allOutputs.filter(p => p.endsWith(".cpp"));
const headerOutputs = allOutputs.filter(p => p.endsWith(".h"));
const other = allOutputs.filter(p => !p.endsWith(".cpp") && !p.endsWith(".h"));
assert(other.length === 0, `bindgenv2 emitted unexpected output type: ${other.join(", ")}`);

n.build({
outputs: allOutputs,
rule: "codegen",
inputs: [script, ...sources.bindgenV2, ...sources.bindgenV2Internal],
orderOnlyInputs: [dirStamp],
vars: {
cwd: cfg.cwd,
desc: "bindgenv2",
args: shJoin(cfg, [script, "--command=generate", `--codegen-path=${cfg.codegenDir}`, `--sources=${sourcesArg}`]),
},
});
/** A `*_test.bind.ts` binds what exists for tests. Only a build where Rust has `debug_assertions` has it, and none ships. */
function isCompiled(cfg: CodegenFields, src: string): boolean {
return cfg.debug || cfg.assertions || !src.endsWith("_test.bind.ts");
}

o.all.push(...allOutputs);
o.bindgenV2Cpp.push(...cppOutputs);
o.cppHeaders.push(...headerOutputs);
function typesOnlyFlag(cfg: CodegenFields, sources: Sources): string {
return `--types-only=${sources.bindgen
.filter(src => !isCompiled(cfg, src))
.map(src => basename(src))
.join(",")}`;
}

/** Exported for test/internal/build-codegen-declared-outputs.test.ts. */
export function emitBindgen({ n, cfg, sources, o, dirStamp }: Ctx): void {
const script = resolve(cfg.cwd, "src", "codegen", "bindgen.ts");

const cppOut = resolve(cfg.codegenDir, "GeneratedBindings.cpp");
// Plus one header per .bind.ts (node_os.bind.ts → GeneratedNodeOs.h), which
// hand-written .cpp files include; see "Undeclared outputs" above.
const headers = sources.bindgen.map(src =>
resolve(cfg.codegenDir, `Generated${pascalCase(basename(src, ".bind.ts"))}.h`),
const crates = new Map(sources.bindgen.map(src => [src, crateOf(src)]));
const compiled = sources.bindgen.filter(src => isCompiled(cfg, src));

// What bindgen.ts writes follows from the names and places of its inputs alone.
const outputNames = compiled.map(src => `Generated${pascalCase(basename(src, ".bind.ts"))}`);
outputNames.forEach((name, i) => {
const first = outputNames.indexOf(name);
if (first !== i) throw new BuildError(`${compiled[first]} and ${compiled[i]} both generate ${name}.h`);
});
const cpp = outputNames.map(name => resolve(cfg.codegenDir, `${name}.cpp`));
const headers = [
...outputNames.map(name => resolve(cfg.codegenDir, `${name}.h`)),
resolve(cfg.codegenDir, "GeneratedBindings+Tables.h"),
resolve(cfg.codegenDir, "GeneratedBindings+Counts.h"),
];
const rust = [...new Set(compiled.map(src => crates.get(src)))].map(crate =>
resolve(cfg.codegenDir, `generated_bindgen_${crate}.rs`),
);
Comment thread
dylan-conway marked this conversation as resolved.
Resolved
const types = resolve(cfg.typesDir, "Bindgen.d.ts");

// bindgen.ts scans src/ for .bind.ts files itself; this list only tells
// ninja the inputs and which headers come out. New .bind.ts files need a
// reconfigure to be picked up (next glob gets them).
n.build({
outputs: [cppOut, ...headers],
rule: "codegen_bun",
inputs: [script, ...sources.bindgen],
outputs: [...cpp, ...headers, ...rust, types],
rule: "codegen",
inputs: [...sources.bindgen, ...sources.bindgenCodegen],
orderOnlyInputs: [dirStamp],
vars: {
cwd: cfg.cwd,
desc: ".bind.ts → GeneratedBindings.cpp",
args: shJoin(cfg, ["run", script, debugFlag(cfg), `--codegen-root=${cfg.codegenDir}`]),
desc: ".bind.ts → Generated*.{cpp,h}, generated_bindgen_*.rs",
args: shJoin(cfg, [
script,
// Every schema: build/types is shared by every profile, so Bindgen.d.ts describes them all.
`--sources=${sources.bindgen.map(src => `${crates.get(src)}=${src}`).join(",")}`,
typesOnlyFlag(cfg, sources),
`--codegen-path=${cfg.codegenDir}`,
`--types-path=${cfg.typesDir}`,
]),
},
});

o.all.push(cppOut, ...headers);
o.cppSources.push(cppOut);
o.all.push(...cpp, ...headers, ...rust, types);
o.generatedTypes.push(types);
o.rustInputs.push(...rust);
o.cppSources.push(...cpp);
o.cppHeaders.push(...headers);
}

/** Same transform as `pascal()` in src/codegen/bindgen-lib-internal.ts: `node_os` → `NodeOs`. */
/** `node_os` → `NodeOs`. A copy of `pascalCase()` in src/codegen/bindgen-lib-internal.ts, which node warns about importing here (MODULE_TYPELESS_PACKAGE_JSON). build-codegen-declared-outputs.test.ts holds the two together. */
function pascalCase(s: string): string {
return s[0]!.toUpperCase() + s.slice(1).replace(/[_-](\w)?/g, (_, c?: string) => c?.toUpperCase() ?? "");
return s
.split(/[^A-Za-z0-9]+/)
.filter(part => part.length > 0)
.map(part => part[0]!.toUpperCase() + part.slice(1))
.join("");
}

/** The Cargo package whose directory contains `file`. */
function crateOf(file: string): string {
for (let dir = dirname(file); dir !== dirname(dir); dir = dirname(dir)) {
const manifest = resolve(dir, "Cargo.toml");
if (!existsSync(manifest)) continue;
const name = /^\s*name\s*=\s*"([^"]+)"/m.exec(readFileSync(manifest, "utf8"));
if (name) return name[1]!;
}
throw new BuildError(`${file} is not inside a Cargo package`);
}

function emitJsSink({ n, cfg, o, dirStamp }: Ctx): void {
Expand Down
13 changes: 5 additions & 8 deletions scripts/glob-sources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,13 @@ const patterns = {
paths: ["src/runtime/bake/*.ts", "src/runtime/bake/*/*.{ts,css}", "src/runtime/bake/dev_server/mod.rs"],
exclude: ["src/runtime/bake/generated.ts"],
},
/** legacy bindgen input */
/** bindgen input */
bindgen: {
paths: ["src/**/*.bind.ts"],
},
/** v2 bindgen input */
bindgenV2: {
paths: ["src/**/*.bindv2.ts"],
},
/** bindgen v2 generator code */
bindgenV2Internal: {
paths: ["src/codegen/bindgenv2/**/*.ts"],
/** bindgen generator code */
bindgenCodegen: {
paths: ["src/codegen/bindgen*.ts", "src/codegen/helpers.ts"],
},
/**
* all `*.rs` + workspace manifests — implicit inputs to the cargo step.
Expand All @@ -101,6 +97,7 @@ const patterns = {
"src/io/*.cpp",
"src/jsc/modules/*.cpp",
"src/jsc/bindings/*.cpp",
"src/jsc/bindings/Bindgen/*.cpp",
"src/jsc/bindings/webcore/*.cpp",
"src/jsc/bindings/webcore/streams/*.cpp",
"src/jsc/bindings/sqlite/*.cpp",
Expand Down
Loading
Loading