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 {
#[cfg_attr(alef, alef(skip))]
#[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,
max_source_bytes: Option<usize>,
timeout_ms: Option<u64>,
language_name: Option<String>,
}
impl Parser {
#[must_use]
pub fn new() -> Self {
Self {
inner: tree_sitter::Parser::new(),
max_source_bytes: None,
timeout_ms: None,
language_name: None,
}
}
pub fn set_max_source_bytes(&mut self, max_bytes: Option<usize>) {
self.max_source_bytes = max_bytes;
}
pub fn set_parse_timeout_ms(&mut self, timeout_ms: Option<u64>) {
self.timeout_ms = timeout_ms;
}
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}")))?;
self.language_name = Some(name.to_string());
Ok(())
}
#[must_use]
pub fn parse(&mut self, source: &str) -> Option<Tree> {
self.parse_bytes(source.as_bytes())
}
#[must_use]
pub fn parse_bytes(&mut self, source: &[u8]) -> Option<Tree> {
if let Some(limit) = self.max_source_bytes
&& source.len() > limit
{
tracing::warn!(
source_bytes = source.len(),
limit,
"source exceeds the configured max_source_bytes; refusing to parse"
);
return None;
}
let _guard = self
.language_name
.as_deref()
.and_then(crate::parse::lock_for_stateful_scanner);
match crate::parse::run_parse(&mut self.inner, source, self.timeout_ms) {
Ok(tree) => Some(Tree(Arc::new(tree))),
Err(error) => {
tracing::debug!(error = %error, "parse produced no tree");
None
}
}
}
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)
}
}