Commit graph

211 commits

Author SHA1 Message Date
Will Lillis 65e8b25413
wip(generate): emit 3-way per-state parse table layout (plan B)
Replace the per-grammar CSR-vs-hybrid choice with a per-state picker
that places each state in the smallest of dense / CSR / small. State
ids are partitioned into contiguous tiers [Dense | CSR | Small] driven
by `large_state_count` and a new `csr_state_count` field on
TSLanguage. The runtime dispatches on two range checks; the rest of
the lookup logic per tier is unchanged.

States 0 (error) and 1 (start state) are pinned to the Dense tier so
they remain at indices 0 and 1, matching the runtime's hard-coded
expectations. Cost is bounded at ~2 * SYMBOL_COUNT * 2 bytes per
grammar.

Cleanup: drop --table-fmt CLI, OptLevel::ForceHybridTable /
ForceCompressedTable, RenderError::ConflictingParseTableFlags,
heuristic_should_compress, and use_compressed_tables since the free
picker provably picks the smallest representation per state.

Tests pass against the regenerated fixtures. The size savings are
measured in a follow-up corpus run.
2026-05-19 18:18:20 -04:00
Will Lillis ea90489d7a
perf(generate): add CSR-compressed parse tables (ABI 16)
Apply Compressed Sparse Row (CSR) compression to the parse table for
grammars that benefit, replacing the original dense + small split with
three flat arrays:

  uint32_t parse_table_row_offsets[STATE_COUNT + 1]
  uint16_t parse_table_columns[TOTAL_NNZ]
  uint16_t parse_table_values[TOTAL_NNZ]

Heuristic for enabling CSR (per grammar, all three must hold):

  1. LARGE_STATE_COUNT * SYMBOL_COUNT > STATE_COUNT * 40
     Ensures the dense table is large enough relative to total state
     count that savings outweigh the small-state grouping penalty.

  2. dense table density < 45%
     Ensures CSR actually saves space. Above ~50% density, CSR's
     per-entry column indices cost more than the zeros they eliminate.
     45% adds margin below the theoretical crossover.

  3. LARGE_STATE_COUNT * SYMBOL_COUNT > 50,000
     Avoids applying a format change to tiny grammars where fixed
     overhead dominates.

Co-authored-by: Tuomas Hietanen <thorium@iki.fi>
2026-05-19 17:57:49 -04:00
Will Lillis f535c3bb97 fix(test): write fixture headers once
Several test functions compile the same grammar fixture.
Tests sharing a grammar name also share a src_dir. Each test also
unconditionally writes the three tree-sitter headers into
src_dir/tree_sitter/, leading to a race.

Write the three headers exactly once per src_dir, controlled via a
global `HashSet`.
2026-05-17 19:55:37 -04:00
Will Lillis 71040925fe perf(cli): stream CST rendering via Display wrappers
Co-authored-by: Amaan Qureshi <git@amaanq.com>
2026-05-17 15:02:08 -04:00
Will Lillis ffea4e8e58 fix(cli): rework coloring abstraction and fix NO_COLOR handling
Co-authored-by: Amaan Qureshi <git@amaanq.com>
2026-05-17 15:02:08 -04:00
Will Lillis 5cac4316db fix(cli): account for process versions > 5 in the parse command's pretty
debug output.

The initial implementation of `--debug pretty` assumed process version
was bounded by `MAX_VERSION_COUNT`. However, we also have to account for
`MAX_VERSION_COUNT_OVERFLOW` as well as `halted_version_count`.
2026-05-05 18:17:07 -04:00
Daniel Jalkut 0f6780b9a3 lexer: pass code-unit length to U16_NEXT in UTF-16 decoders
`ts_decode_utf16_le` and `ts_decode_utf16_be` passed a byte length to
`U16_NEXT_LE` and `U16_NEXT_BE`, but those macros count `uint16_t` code
units. If a lead surrogate was the last code unit in a chunk, the decoder
could peek past the chunk and combine it with adjacent memory.

This commit passes the code-unit length to the UTF-16 macros, and fails
with `TS_DECODE_ERROR` when a chunk is too short to contain even one full
code unit. This lets the lexer retry with a fresh chunk or advance through
the invalid byte as it already does.

Co-authored-by: Will Lillis <will.lillis24@gmail.com>
Co-authored-by: Amaan Qureshi <git@amaanq.com>
2026-04-26 03:38:47 -04:00
Antonin Delpeuch eccef997df
feat(dist): enable install via cargo binstall (#5533) 2026-04-24 08:52:01 +02:00
Volker Mische 4cb11acd46
fix(loader): allow filenames with dots (#5529) 2026-04-22 03:41:04 -04:00
Chinmay Dalal 20bdf3a8a0
feat(bindings): update zig template to 0.16 2026-04-20 09:31:18 +02:00
changw98ic aff9b9d92e fix: update broken link to Parser.Language in template
The link `https://tree-sitter.github.io/node-tree-sitter/interfaces/Parser.Language.html` returns a 404 error.

In the current typedoc output, the Language interface is at `/interfaces/Language.html` (without the `Parser.` prefix), as the documentation flattens namespace members.

Fixes #5525
2026-04-17 08:20:05 +02:00
Will Lillis 8eafafaa16 fix(test): split up cli testing test
Now that the loader race condition is resolved, these tests no longer
need to be grouped together.
2026-03-31 04:00:43 -04:00
Will Lillis 3294a64027 perf(cli): replace regex with manual parsing in test file parser
This started as a simple one to one rewrite, just removing the regexes,
and quickly devolved into a rewrite of the test parsing logic. In
addition to the memory enhancements, the general flow should be much
clearer now. A few data points:

- JS:   walltime -1.3%, peak rss -10.2%
- C:    walltime -5.7%, peak rss -4.5%
- Rust: walltime -3.8%, peak rss -2.2%
2026-03-31 04:00:43 -04:00
Max Brunsfeld d3ff0ce81d
Fix wasm loading of languages w/ multiple reserved word sets (#5475) 2026-03-30 22:27:57 -07:00
Will Lillis 791d7cead4 perf(cli): minor allocation and write call reductions
- Cache tree byte range length to avoid redundant FFI calls per test
- Combine 5 separate XML attribute write! calls into one
- Pre-allocate format_sexp output buffer to avoid repeated growth
2026-03-31 01:27:05 -04:00
Will Lillis 827bcdabd9 perf(cli): buffer stdout in parse and query output
Wrap stdout in a 64KB BufWriter when writing `parse` output. The tree
walking loop makes many small write calls (parentheses, indentation,
node kinds, ranges, etc.) which are expensive without buffering.

When parsing the jquery.js corpus file, cuts the total time roughly in
half. These savings only show when piping the result to a file,
otherwise terminal rendering time usually dominates, hiding all gains.

Also do the same for the `query` command's output.
2026-03-31 01:27:05 -04:00
Will Lillis 1ec3b3aabe generate: remove comment cleaning for grammar.json
A quick search through github shows that nobody utilizes this, so it's
effectively dead code.
2026-03-31 01:23:15 -04:00
Will Lillis cf8719f132 fix(rust): correct various typos 2026-03-28 05:23:10 -04:00
Will Lillis 1a82df3cac fix(rust): address new nightly lints 2026-03-28 05:23:10 -04:00
dependabot[bot] cc2ed5e85f build(deps): bump brace-expansion in /crates/cli/eslint
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 5.0.2 to 5.0.5.
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v5.0.2...v5.0.5)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 5.0.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-27 14:57:11 +01:00
dependabot[bot] e957e8ce0d build(deps): bump flatted from 3.4.1 to 3.4.2 in /crates/cli/eslint
Bumps [flatted](https://github.com/WebReflection/flatted) from 3.4.1 to 3.4.2.
- [Commits](https://github.com/WebReflection/flatted/compare/v3.4.1...v3.4.2)

---
updated-dependencies:
- dependency-name: flatted
  dependency-version: 3.4.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-27 14:55:25 +01:00
Will Lillis df3fa372a6 fix(generate): allow disabling qjs-rt feature from CLI
The workspace dependency for `tree-sitter-generate` did not set
`default-features = false`, so Cargo always enabled its default
features (including `qjs-rt` and thus `rquickjs`) regardless of
the CLI's `--no-default-features` flag.

Additionally, `tree-sitter-generate` failed to compile without the
`load` feature due to unconditional references to `cfg`-gated items.

- Set `default-features = false` on the workspace `tree-sitter-generate`
  dependency so the CLI's feature forwarding actually takes effect.
- Explicitly enable the `load` feature in the CLI's dependency on
  `tree-sitter-generate`, since the CLI needs `load`-gated functions
  unconditionally.
- Gate necessary imports behind `#[cfg(feature = "load")]` to fix
  `tree-sitter-generate`'s build without the `load` feature.
2026-03-21 05:51:10 -04:00
dependabot[bot] 94f48e3ebf build(deps): bump flatted from 3.3.1 to 3.4.1 in /crates/cli/eslint
Bumps [flatted](https://github.com/WebReflection/flatted) from 3.3.1 to 3.4.1.
- [Commits](https://github.com/WebReflection/flatted/compare/v3.3.1...v3.4.1)

---
updated-dependencies:
- dependency-name: flatted
  dependency-version: 3.4.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-14 19:19:06 +01:00
Riley Bruins cf302b07d1 fix(query): don't add copies for quantifier steps outside alternations 2026-03-04 10:32:50 +01:00
John Eismeier 1f9b274dfb
chore: fix typos in messages and documentation
Signed-off-by: John E <jeis4wpi@outlook.com>
2026-03-01 11:40:15 +01:00
dependabot[bot] 6cefea704e build(deps): bump minimatch from 10.2.2 to 10.2.4 in /crates/cli/eslint
Bumps [minimatch](https://github.com/isaacs/minimatch) from 10.2.2 to 10.2.4.
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v10.2.2...v10.2.4)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 10.2.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-28 15:05:37 +01:00
MFS-code 146ea6e12b fix: skip missing Makefile in version command 2026-02-27 10:01:59 +01:00
Amaan Qureshi 0561079b6e cli(init): extract per-binding generators and named update functions
This commit just refactors the init command's update code, as it's quite messy. The main changes are that most bindings now go through their own generate_{lang} function.
2026-02-27 02:13:03 -05:00
Will Lillis 6ae37120b3 fix(cli): correct condition to perform __init__.py replacement for
`tree-sitter init -u` command
2026-02-23 22:53:06 -05:00
Will Lillis 5210ca0b51 fix(cli): update tree-sitter init -u for recent Package.swift
changes
2026-02-23 22:53:06 -05:00
Will Lillis f1f493e59e fix(cli): actually write updated Package.swift file 2026-02-23 22:53:06 -05:00
Amaan Qureshi 787800dda6 cli(init): fix Package.swift scanner detection when used as a dependency
The template used `FileManager.default.fileExists(atPath: "src/scanner.c")` with a relative path, which resolves against the process cwd. When SwiftPM evaluates a dependency's manifest, the cwd is the consumer's directory, so the check returns `false` even when `scanner.c` exists, causing undefined symbol linker errors.

This commit uses `Context.packageDirectory`, which is available since `swift-tools-version:5.6`, to resolve the path against the package root. This does bump the minimum tools version from 5.3 to 5.6.
2026-02-22 10:55:16 -05:00
dependabot[bot] 224598586c build(deps): bump minimatch, eslint and eslint-plugin-jsdoc
Bumps [minimatch](https://github.com/isaacs/minimatch) to 10.2.2 and updates ancestor dependencies [minimatch](https://github.com/isaacs/minimatch), [eslint](https://github.com/eslint/eslint) and [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc). These dependencies need to be updated together.


Updates `minimatch` from 3.1.2 to 10.2.2
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v10.2.2)

Updates `eslint` from 9.39.2 to 10.0.1
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v9.39.2...v10.0.1)

Updates `eslint-plugin-jsdoc` from 50.2.4 to 62.7.0
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v50.2.4...v62.7.0)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 10.2.2
  dependency-type: indirect
- dependency-name: eslint
  dependency-version: 10.0.1
  dependency-type: indirect
- dependency-name: eslint-plugin-jsdoc
  dependency-version: 62.7.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-21 16:48:12 +01:00
dependabot[bot] 8e330c7f24 build(deps): bump ajv from 6.12.6 to 6.14.0 in /crates/cli/eslint
Bumps [ajv](https://github.com/ajv-validator/ajv) from 6.12.6 to 6.14.0.
- [Release notes](https://github.com/ajv-validator/ajv/releases)
- [Commits](https://github.com/ajv-validator/ajv/compare/v6.12.6...v6.14.0)

---
updated-dependencies:
- dependency-name: ajv
  dependency-version: 6.14.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-21 16:43:21 +01:00
Will Lillis 256df9304f rust: explicitly align CLI's encoding enum with constants from
tree_sitter::ffi
2026-02-18 01:54:20 -05:00
Will Lillis 27e1199387 feat(highlight)!: utf16 support 2026-02-18 01:54:20 -05:00
Amaan Qureshi b8fcf27661 build(rust): update deps 2026-02-18 00:59:34 -05:00
Amaan Qureshi ebd2a56b5d treewide: add taplo config and reformat toml files 2026-02-18 00:59:34 -05:00
Amaan Qureshi 7deb5092c6 cli: fix clippy warnings from edition bump 2026-02-18 00:59:34 -05:00
dependabot[bot] 377c3d1c75 build(deps): bump eslint from 9.11.0 to 9.39.2 in /crates/cli/eslint
Bumps [eslint](https://github.com/eslint/eslint) from 9.11.0 to 9.39.2.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v9.11.0...v9.39.2)

---
updated-dependencies:
- dependency-name: eslint
  dependency-version: 9.39.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-09 22:55:27 -05:00
Will Lillis 596a4d69bb fix(query): prevent cross-branch capture contamination in alternations with quantifiers
When a branch inside an alternation has a + or * quantifier, the
quantifier's pass_through step loops back to the branch's first step.
The alternation linking also sets that step's alternative_index to
point to the next branch. This causes the quantifier loop-back to
incorrectly explore other branches in the case of a failed match that
follows a successful match, contaminating captures.

This is corrected by redirecting the quantifier loop-back to a
"clean" copy of the target step without the alternative index pointing
to the next alternation branch.

Co-authored-by: Riley Bruins <ribru17@hotmail.com>
2026-02-09 21:57:29 -05:00
Will Lillis 48e921883a fix(rust)!: return u32 from Node::child_count
This matches the type returned from the underlying C library, and also
composes more cleanly with other functions like `Node::child`
2026-02-09 21:05:48 -05:00
Will Lillis 9dd09fec1e fix(cli): require tree-sitter CLI in CMake template 2026-02-08 18:40:57 -05:00
Will Lillis 73b2f981d5 fix(cli): allow for both debug logs and graphs 2026-02-07 17:03:56 -05:00
Will Lillis eab567a02d fix(rust): place std::env::set_var inside unsafe blocks
This is optional for the 2021 but required for 2024. The function is
unsafe either way and should be marked as such.
2026-02-02 04:29:13 -05:00
Will Lillis 7e1d8add13 feat(cli): add --verbose flag to build command
This displays the working directory of the command (if present),
compiler used, all of its arguments, any environment variables set,
and anything written to stdout/stderr by the compilation tool.
2026-02-01 13:00:02 -05:00
Will Lillis 0b8f124453 fix(cli): include default values for --edits and --iterations in
`fuzz` command help
2026-02-01 12:31:13 -05:00
Will Lillis c9d9ce6cbb fix(cli): use --edits value for fuzz tests 2026-02-01 12:31:13 -05:00
Will Lillis 337e20e0f2 fix(wasm): when reallocating the last allocated region, properly grow
the region in place.

Previous changes to `malloc` caused `realloc` to sometimes pull regions
off of the free list during this optimization. Because no `memcpy` is
performed, this resulted in corrupted data returning to the caller.

Co-authored-by: trim21 <i@trim21.me>
2026-01-31 18:24:31 -05:00
Will Lillis 8fe076695f test: rename wasm corpus test "wasm_realloc"->"wasm_realloc_overflow_heap" 2026-01-31 18:24:31 -05:00