Rust bindings to the Tree-sitter parsing library.
First, create a parser:
rust
let parser = Parser::new();
Then assign a language to the parser. Tree-sitter languages consist of generated C code. To use them from rust, you must declare them as extern "C"
functions and invoke them with unsafe
:
```rust extern "C" fn treesitterc() -> Language; extern "C" fn treesitterrust() -> Language; extern "C" fn treesitterjavascript() -> Language;
parser.setlanguage(unsafe { treesitter_rust() }).unwrap(); ```
Now you can parse source code:
```rust let source_code = "fn test() {}";
let tree = parser.parsestr(sourcecode, None); let rootnode = tree.rootnode(); asserteq!(rootnode.kind(), "sourcefile"); asserteq!(rootnode.startposition().column, 0); asserteq!(rootnode.end_position().column, 12); ```
Once you have a syntax tree, you can update it when your source code changes:
```rust let newsourcecode = "fn test(a: u32) {}"
tree.edit(InputEdit { startbyte: 8, oldendbyte: 8, newendbyte: 14, startposition: Point::new(0, 8), oldendposition: Point::new(0, 8), newendposition: Point::new(0, 14), }); let newtree = parser.parsestr(newsourcecode, Some(tree)); ```
The code can be provided either as a simple string or by any type that implements Tree-sitter's Utf8Input
or Utf16Input
traits:
```rust struct LineWiseInput { lines: &'static [&'static str], row: usize, column: usize, }
impl treesitter::Utf8Input for LineWiseInput { fn read(&mut self) -> &[u8] { if self.row < self.lines.len() { let result = &self.lines[self.row].asbytes()[self.column..]; self.row += 1; self.column = 0; result } else { &[] } }
fn seek(&mut self, _byte: u32, position: Point) {
self.row = position.row as usize;
self.column = position.column as usize;
}
}
let mut input = LineBasedInput { lines: &[ "pub fn main() {", "}", ], row: 0, column: 0 };
let tree = parser.parse_utf8(&mut input, None).unwrap(); ```