use std::sync::Arc;
use crate::error::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Point {
pub row: usize,
pub column: usize,
}
impl Point {
#[must_use]
pub fn new(row: usize, column: usize) -> Self {
Self { row, column }
}
}
impl From<tree_sitter::Point> for Point {
fn from(p: tree_sitter::Point) -> Self {
Self {
row: p.row,
column: p.column,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ByteRange {
pub start: usize,
pub end: usize,
}
pub struct Parser {
inner: tree_sitter::Parser,
}
impl Parser {
#[must_use]
pub fn new() -> Self {
Self {
inner: tree_sitter::Parser::new(),
}
}
pub fn set_language(&mut self, name: &str) -> Result<(), Error> {
let language = crate::get_language(name)?;
self.inner
.set_language(&language)
.map_err(|e| Error::ParserSetup(format!("{e}")))
}
#[must_use]
pub fn parse(&mut self, source: &str) -> Option<Tree> {
self.inner.parse(source, None).map(|t| Tree(Arc::new(t)))
}
#[must_use]
pub fn parse_bytes(&mut self, source: &[u8]) -> Option<Tree> {
self.inner.parse(source, None).map(|t| Tree(Arc::new(t)))
}
pub fn reset(&mut self) {
self.inner.reset();
}
}
impl Default for Parser {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone)]
pub struct Tree(Arc<tree_sitter::Tree>);
impl Tree {
#[must_use]
pub fn root_node(&self) -> Node {
let raw: tree_sitter::Node<'static> = unsafe { std::mem::transmute(self.0.root_node()) };
Node {
tree: Arc::clone(&self.0),
raw,
}
}
#[must_use]
pub fn walk(&self) -> TreeCursor {
let raw: tree_sitter::TreeCursor<'static> = unsafe { std::mem::transmute(self.0.walk()) };
TreeCursor {
tree: Arc::clone(&self.0),
raw,
}
}
}
pub struct Node {
tree: Arc<tree_sitter::Tree>,
raw: tree_sitter::Node<'static>,
}
impl Clone for Node {
fn clone(&self) -> Self {
Self {
tree: Arc::clone(&self.tree),
raw: self.raw,
}
}
}
impl Node {
#[must_use]
pub fn kind(&self) -> String {
self.raw.kind().to_string()
}
#[must_use]
pub fn kind_id(&self) -> u16 {
self.raw.kind_id()
}
#[must_use]
pub fn start_byte(&self) -> usize {
self.raw.start_byte()
}
#[must_use]
pub fn end_byte(&self) -> usize {
self.raw.end_byte()
}
#[must_use]
pub fn byte_range(&self) -> ByteRange {
let r = self.raw.byte_range();
ByteRange {
start: r.start,
end: r.end,
}
}
#[must_use]
pub fn start_position(&self) -> Point {
self.raw.start_position().into()
}
#[must_use]
pub fn end_position(&self) -> Point {
self.raw.end_position().into()
}
#[must_use]
pub fn is_named(&self) -> bool {
self.raw.is_named()
}
#[must_use]
pub fn is_error(&self) -> bool {
self.raw.is_error()
}
#[must_use]
pub fn is_missing(&self) -> bool {
self.raw.is_missing()
}
#[must_use]
pub fn is_extra(&self) -> bool {
self.raw.is_extra()
}
#[must_use]
pub fn has_error(&self) -> bool {
self.raw.has_error()
}
#[must_use]
pub fn parent(&self) -> Option<Node> {
self.raw.parent().map(|raw| Node {
tree: Arc::clone(&self.tree),
raw: unsafe { std::mem::transmute::<tree_sitter::Node<'_>, tree_sitter::Node<'static>>(raw) },
})
}
#[must_use]
pub fn child(&self, index: u32) -> Option<Node> {
self.raw.child(index).map(|raw| Node {
tree: Arc::clone(&self.tree),
raw: unsafe { std::mem::transmute::<tree_sitter::Node<'_>, tree_sitter::Node<'static>>(raw) },
})
}
#[must_use]
pub fn child_count(&self) -> usize {
self.raw.child_count()
}
#[must_use]
pub fn named_child(&self, index: u32) -> Option<Node> {
self.raw.named_child(index).map(|raw| Node {
tree: Arc::clone(&self.tree),
raw: unsafe { std::mem::transmute::<tree_sitter::Node<'_>, tree_sitter::Node<'static>>(raw) },
})
}
#[must_use]
pub fn named_child_count(&self) -> usize {
self.raw.named_child_count()
}
#[must_use]
pub fn child_by_field_name(&self, name: &str) -> Option<Node> {
self.raw.child_by_field_name(name).map(|raw| Node {
tree: Arc::clone(&self.tree),
raw: unsafe { std::mem::transmute::<tree_sitter::Node<'_>, tree_sitter::Node<'static>>(raw) },
})
}
#[must_use]
pub fn to_sexp(&self) -> String {
self.raw.to_sexp()
}
#[must_use]
pub fn walk(&self) -> TreeCursor {
let raw: tree_sitter::TreeCursor<'static> = unsafe { std::mem::transmute(self.raw.walk()) };
TreeCursor {
tree: Arc::clone(&self.tree),
raw,
}
}
}
pub struct TreeCursor {
tree: Arc<tree_sitter::Tree>,
raw: tree_sitter::TreeCursor<'static>,
}
impl TreeCursor {
#[must_use]
pub fn node(&self) -> Node {
let raw: tree_sitter::Node<'static> = unsafe { std::mem::transmute(self.raw.node()) };
Node {
tree: Arc::clone(&self.tree),
raw,
}
}
pub fn goto_first_child(&mut self) -> bool {
self.raw.goto_first_child()
}
pub fn goto_parent(&mut self) -> bool {
self.raw.goto_parent()
}
pub fn goto_next_sibling(&mut self) -> bool {
self.raw.goto_next_sibling()
}
#[must_use]
pub fn field_name(&self) -> Option<String> {
self.raw.field_name().map(str::to_string)
}
}