Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
289 changes: 99 additions & 190 deletions CLAUDE.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ tsv/
Each language crate exports a consistent API:

- `parse(source, arena) -> Result<AST>` — the AST allocates into the caller's `bumpalo` arena (the bindings reuse a per-thread arena across calls via `tsv_arena`)
- `format(ast, source) -> String` — plus `format_in(ast, source, doc_arena)`, the same formatter writing through a reusable doc arena for the bindings' hot loop
- `format(ast, source) -> String` — plus `format_in(ast, source, doc_arena)`, the same formatter writing through a reusable doc arena for the bindings' hot loop, and `format_str(source)`, the parse+format one-shot
- `convert_ast_json_bytes(ast, source) -> Vec<u8>` — the wire JSON, emitted directly from the internal AST, with `convert_ast_json_string`/`convert_ast_json` wrappers and span-only `_no_locations` variants alongside (default-on `convert` cargo feature; turn off for parse+format-only builds)

For more details see [CLAUDE.md](CLAUDE.md).
Expand Down
6 changes: 5 additions & 1 deletion benches/js/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1207,13 +1207,17 @@ benches/js/
├── types.ts # Shared types + `BaseImplementation` (the language-support pair)
├── versions.ts # Version loading from package.json
├── wasm.ts # WASM module loader (WasmImplementation — deno/nodejs target)
├── wire_inject.ts # The wire:audit's MANUFACTURED inputs: whitespace injected into every
│ # Svelte tag/block head, each variant graded against the canonical wire
├── yuku.ts # yuku-parser wrapper, BOTH bindings from one class (parse-only)
└── divergence/ # Divergence detection module
├── mod.ts # Main exports
├── safety.ts # Safety check (differential char-frequency vs prettier)
├── patterns.ts # Known divergence pattern detectors (with traceability)
├── panic_errors.ts # Native-panic classification (shared by both corpus tools)
├── expected_errors.ts # Expected-error fixtures (parse-rejection cases)
├── fixture_cases.ts # Detector cases derived from the committed divergence fixtures
│ # (input = ours, the pinned prettier file = theirs; no sidecar)
└── validation.ts # Audit: cross-ref patterns vs conformance_prettier*.md
```

Expand Down Expand Up @@ -1366,7 +1370,7 @@ internal state), the coverage report and skip counts make it visible without
`await wait(cooldown_ms)`, which never fires. Workaround: `cooldown_ms: 0` in
`run_benchmark_group`'s `Benchmark` config. Async measurement loops (`prettier`,
`oxfmt` itself) are unaffected because their per-iteration awaits resolve via
microtasks, not timers. The inter-task SETTLE the cooldown used to supply is not
microtasks, not timers. The inter-task SETTLE the cooldown would supply is not
lost with it: each task's untimed `setup` forces a major GC (`settle_heap`), which
is timer-free and uniform across the three runtimes — a runtime-conditional
cooldown would put a settle under Node/Bun and none under Deno, biasing the very
Expand Down
11 changes: 8 additions & 3 deletions benches/js/lib/ffi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ const symbols = {
parameters: ['pointer', 'usize', 'pointer'],
result: 'pointer'
},
// goal-aware TS parse (extra `u32` goal: 0 = Module, 1 = Script) — the
// conformance surface's test262 files
// goal-aware TS exports (extra `u32` goal: 0 = Module, 1 = Script) — the parse
// trio serves the conformance surface's test262 files; the format twin is declared
// for parity with the N-API addon's `format_typescript_with_goal` (unused here too)
tsv_parse_typescript_with_goal: {
parameters: ['pointer', 'usize', 'u32', 'pointer'],
result: 'pointer'
Expand All @@ -88,6 +89,10 @@ const symbols = {
parameters: ['pointer', 'usize', 'u32', 'pointer'],
result: 'pointer'
},
tsv_format_typescript_with_goal: {
parameters: ['pointer', 'usize', 'u32', 'pointer'],
result: 'pointer'
},
tsv_format_css: {
parameters: ['pointer', 'usize', 'pointer'],
result: 'pointer'
Expand All @@ -103,7 +108,7 @@ type FfiFn = (
len: number | bigint,
out_len: Deno.PointerValue
) => Deno.PointerValue;
/** Goal-aware TS parse symbol: an extra `u32` goal (0 = Module, 1 = Script). */
/** Goal-aware TS symbol (parse or format): an extra `u32` goal (0 = Module, 1 = Script). */
type FfiGoalFn = (
source: Deno.PointerValue,
len: number | bigint,
Expand Down
33 changes: 6 additions & 27 deletions benches/js/lib/gate_counts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,12 @@
* green run. This is `scripts/validate_artifacts.ts`'s tight-bounds philosophy
* applied to counts: every real move in a number is a deliberate, visible edit.
*
* Three pin categories, chosen per surface:
*
* - **Exact pins** (`*_PINS` / `*_PIN`) — surfaces whose inputs are pinned or
* committed: the fixtures gates and harvests (suite checkouts version-gated
* by `deno task pins:audit`) and ts-repo/test262/wpt (checkouts updated
* deliberately). Any mismatch — up or down — fails. No slack: slack lets
* small regressions creep and silently widens after every refresh.
* - **Minimums** (`*_MIN`) — success counts. Two flavors: the FORMAT `match`
* minimum (`CORPUS_FORMAT_MATCH_MIN`) is over the REPRODUCIBLE subset (pinned
* framework + prettier suites), so it's exact-on-aligned-checkouts — the
* minimum is only there so a fixed win needn't re-pin; over pinned inputs a
* drop is always a real regression. The PARSE `compared` minimum
* (`CORPUS_PARSE_COMPARED_MIN`) and the committed-fixtures audits stay
* genuine live-growth minimums (dev repos / reviewed fixture diffs grow, so
* growth passes, a drop fails) — except `SVELTE_STYLES_BLOCKS_MIN`, which
* counts pure input material off daily-churning repos, so a small drop only
* warns and only a >10% collapse fails (see its comment).
* - **Failure-bucket pins** (`*_PIN`, exact two-sided `!==`): the triage buckets
* on `corpus:compare:* --all`. The FORMAT `unknown`/`partial` pins are over
* the REPRODUCIBLE subset (deterministic on aligned checkouts — the live dev
* repos are a non-gating WARN); the PARSE tsv-side parse-failure pin stays over
* the live corpus (a tsv over-rejection of real code is a regression wherever
* it occurs). A rise fails until triaged — fix it, add a divergence
* detector/sanction, or consciously re-pin (a legitimately-unsupported new
* file); a drop also fails, so the pin ratchets DOWN deliberately and wins
* stay recorded. **SAFETY (content loss) always gates over EVERY file,
* reproducible or live — data loss is never churn.**
* Three pin categories, chosen per surface — exact pins (`*_PINS` / `*_PIN`),
* minimums (`*_MIN`), and failure-bucket pins (exact two-sided `!==`). What each
* means, which surface takes which, and why (the reproducible-subset rule, the
* `SVELTE_STYLES_BLOCKS_MIN` drift band, SAFETY gating over EVERY file) is stated
* once in docs/gate_counts.md §Semantics; the per-constant docstrings below carry
* only what is specific to that constant.
*
* Pins are enforced only on FULL runs (default suite root, `--all`, default
* harvest source) — a subtree or filtered run legitimately grades a slice.
Expand Down
2 changes: 1 addition & 1 deletion crates/tsv_cli/src/json_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ pub fn to_json_with_tabs<T: Serialize>(value: &T) -> Result<String, serde_json::
let mut ser = serde_json::Serializer::with_formatter(&mut buf, formatter);
value.serialize(&mut ser)?;
// SAFETY: serde_json always produces valid UTF-8
#[allow(clippy::unwrap_used)]
#[expect(clippy::unwrap_used)]
Ok(String::from_utf8(buf).unwrap())
}
Loading