willbooster-tree-sitter-ruby 17.0.0

Ruby grammar for tree-sitter
Documentation

@willbooster/tree-sitter-ruby

npm version license Test Test rust semantic-release wbfy crates.io

Ruby grammar for tree-sitter, forked from tree-sitter/tree-sitter-ruby. We are grateful to its authors and contributors. This is not an official release of that project.

This fork extends the upstream grammar to parse anonymous block forwarding, spaced block arguments, and command calls in endless methods, with a parser generated by WillBooster/tree-sitter, whose compact parse tables make the parser smaller. The parser carries that fork's own ABI number (0x5742000c); upstream's tree-sitter runtime and incompatible ABI versions of the fork's runtime reject it. The scanner preserves long heredoc identifiers when their state fits the runtime's serialization buffer. If the open heredocs cannot fit, their bodies are parsed as code instead of aborting the process.

Support Scope

This fork maintains only full parsing: valid input yields a correct tree, and invalid input yields ERROR or MISSING nodes without crashing, hanging, or taking more than linear time. Incremental parsing and queries (highlights, locals, injections, tags) are not supported. Node types, field names, and the trees that error recovery produces may change; such changes are released as new major versions.

Usage

The npm package ships tree-sitter-ruby.wasm for @willbooster/web-tree-sitter 20.x, which runs in Node.js, Bun, browsers, and Cloudflare Workers.

In Node.js and Bun, load the grammar from its path:

import { fileURLToPath } from 'node:url';

import { Language, Parser } from '@willbooster/web-tree-sitter';

await Parser.init();
const parser = new Parser();
const wasmPath = fileURLToPath(import.meta.resolve('@willbooster/tree-sitter-ruby/tree-sitter-ruby.wasm'));
parser.setLanguage(await Language.load(wasmPath));
const tree = parser.parse('puts "Hello"\n');

In browsers, load the grammar from its URL. With Vite:

import rubyUrl from '@willbooster/tree-sitter-ruby/tree-sitter-ruby.wasm?url';
import { Language, Parser } from '@willbooster/web-tree-sitter';
import runtimeUrl from '@willbooster/web-tree-sitter/web-tree-sitter.wasm?url';

await Parser.init({ locateFile: () => runtimeUrl });
const parser = new Parser();
parser.setLanguage(await Language.load(rubyUrl));

In Cloudflare Workers, which do not allow compiling Wasm at run time, import both .wasm files as modules:

import ruby from '@willbooster/tree-sitter-ruby/tree-sitter-ruby.wasm';
import { Language, Parser } from '@willbooster/web-tree-sitter';
import runtime from '@willbooster/web-tree-sitter/web-tree-sitter.wasm';

await Parser.init({ wasmModule: runtime });
const parser = new Parser();
parser.setLanguage(await Language.load(ruby));

The package also ships the node types in src/node-types.json.

In Rust, depend on the crate and on willbooster-tree-sitter 20.x, the runtime this package is tested and fuzzed with:

cargo add willbooster-tree-sitter@20.0.0 --rename tree-sitter
cargo add willbooster-tree-sitter-ruby --rename tree-sitter-ruby
let mut parser = tree_sitter::Parser::new();
parser.set_language(&tree_sitter_ruby::LANGUAGE.into())?;

Development

mise install
bun install --frozen-lockfile
bun run test/ci-setup
bun run build/ci
bun run verify
bun run test
cargo test
  • bun run test/ci-setup: run once to install Chromium before bun run test.
  • bun run build/ci: run before bun run test, and commit src/ after changing grammar.js, tree-sitter.json, test/corpus/, or tracked files in examples/. Stage added or removed examples/ files with git add -A examples before generating so the profile sees them.
  • script/parse-examples: run without arguments to update script/known-failures.txt after a grammar or pin change alters which ruby/spec files fail to parse.
  • script/tree-sitter: use for direct CLI commands such as script/tree-sitter parse file.rb so they run the WillBooster/tree-sitter version locked in Cargo.lock.

References