Skip to main content

Rome Tools

· 3 min read

Rome uses a different set of techniques for parsing JavaScript and TypeScript. This tutorial summarizes them in learning order for better understanding.

History

  • The Rome codebase was rewritten from TypeScript to Rust, see Rome will be rewritten in Rust
  • The decision was made after talking to the author of rslint and rust-analyzer
  • rust-analyzer proved that IDE-centric tools built around concrete syntax tree are possible
  • rslint proved that it is possible to write a JavaScript parser in Rust, with the same base libraries as rust-analyzer
  • Rome ported the rslint codebase to their own repo with permission from rslint's author

Concrete Syntax Tree

  • The base library is called rowan, see overview of rowan
  • Rowan, also known as red-green trees, is named after the real green rowan tree that makes red berries
  • The origin of red-green trees is described in this blog post, by the authors of the C# programming language
  • The whole point of rowan is to define a lossless concrete syntax tree (CST) that describes all the details of the source code and provides a set of traversal APIs (parent, children, siblings, etc)
  • Read the advantage of having a CST over an AST: Pure AST based linting sucks
  • CST provides the ability to build a fully recoverable parser

Grammar

Entry Point

The Rome codebase is getting large and slightly difficult to find the parser entry point.

For first-time contributors, the rome_cli crate is the binary entry point for running the code:

cargo run -p rome_cli

touch test.js
cargo run -p rome_cli -- check ./test.js

rome_cli will eventually call rome_js_parser::parse

https://github.com/rome/tools/blob/9815467c66688773bc1bb6ef9a5b2d86ca7b3682/crates/rome_js_parser/src/parse.rs#L178-L187

and finally the actual parsing code

https://github.com/rome/tools/blob/9815467c66688773bc1bb6ef9a5b2d86ca7b3682/crates/rome_js_parser/src/syntax/program.rs#L14-L17

Contributing

info

The JavaScript / TypeScript parser is 99% complete, the best way to help is to test Rome in your own codebases or take a look at the issues on Github.