use crate::error::MinusOneResult;
use crate::rule::{Rule, RuleMut};
use std::collections::HashMap;
use std::ops;
use std::str::Utf8Error;
use tree_sitter::{Node as TreeNode, Tree as TreeSitter};
use tree_sitter_traversal2::{traverse, Order};
pub trait Storage {
type Component;
fn get(&self, node: TreeNode) -> Option<&Self::Component>;
fn set(&mut self, node: TreeNode, data: Self::Component);
fn start(&mut self);
fn end(&mut self) -> bool;
fn remove(&mut self, node: TreeNode);
}
#[derive(Default)]
pub struct EmptyStorage;
impl Storage for EmptyStorage {
type Component = ();
fn get(&self, _: TreeNode) -> Option<&Self::Component> {
None
}
fn set(&mut self, _: TreeNode, _: Self::Component) {
}
fn start(&mut self) {
}
fn end(&mut self) -> bool {
false
}
fn remove(&mut self, _: TreeNode) {
}
}
pub struct HashMapStorage<T> {
map: HashMap<usize, T>,
is_updated: bool,
}
impl<T> Default for HashMapStorage<T> {
fn default() -> Self {
Self {
map: HashMap::new(),
is_updated: false,
}
}
}
impl<T> Storage for HashMapStorage<T> {
type Component = T;
fn get(&self, node: TreeNode) -> Option<&Self::Component> {
if !self.map.contains_key(&node.id()) {
return None;
}
Some(self.map.get(&node.id()).unwrap())
}
fn set(&mut self, node: TreeNode, data: Self::Component) {
self.map.insert(node.id(), data);
self.is_updated = true;
}
fn start(&mut self) {
self.is_updated = false;
}
fn end(&mut self) -> bool {
self.is_updated
}
fn remove(&mut self, node: TreeNode) {
self.map.remove(&node.id());
}
}
pub struct NodeMut<'a, T> {
pub inner: TreeNode<'a>,
source: &'a [u8],
storage: &'a mut dyn Storage<Component = T>,
}
impl<'a, T> NodeMut<'a, T> {
pub fn new(
root: TreeNode<'a>,
source: &'a [u8],
storage: &'a mut dyn Storage<Component = T>,
) -> Self {
Self {
inner: root,
source,
storage,
}
}
pub fn view(&self) -> Node<'_, T> {
Node::new(self.inner, self.source, self.storage)
}
pub fn set(&mut self, data: T) {
self.storage.set(self.inner, data)
}
pub fn reduce(&mut self, data: T) {
self.storage.set(self.inner, data);
for i in 0..self.inner.child_count() {
self.storage.remove(self.inner.child(i).unwrap());
}
}
pub fn apply(&mut self, rule: &mut impl RuleMut<'a, Language = T>) -> MinusOneResult<()> {
let mut stack: Vec<(TreeNode, usize)> = vec![];
for node in traverse(self.inner.walk(), Order::Pre) {
self.inner = node;
stack.push((node, node.child_count()));
rule.enter(self, ControlFlow::Continue(BranchFlow::Unpredictable))?;
loop {
let head = stack.last();
if head.is_none() {
break;
}
let head_element = head.unwrap();
if head_element.1 != 0 {
break;
}
self.inner = head_element.0;
rule.leave(self, ControlFlow::Continue(BranchFlow::Unpredictable))?;
stack.pop();
if let Some(l) = stack.last_mut() {
l.1 -= 1;
}
}
}
Ok(())
}
pub fn apply_with_strategy_recurcive(
&mut self,
rule: &mut impl RuleMut<'a, Language = T>,
strategy: &impl Strategy<T>,
flow: ControlFlow,
) -> MinusOneResult<()> {
let mut computed_flow = flow;
computed_flow = computed_flow | strategy.control(self.view())?;
if computed_flow == ControlFlow::Break {
return Ok(());
}
rule.enter(self, computed_flow)?;
let mut cursor = self.inner.walk();
let current_node = self.inner;
for child in self.inner.children(&mut cursor) {
self.inner = child;
self.apply_with_strategy(rule, strategy, computed_flow)?;
}
self.inner = current_node;
rule.leave(self, computed_flow)?;
Ok(())
}
pub fn apply_with_strategy(
&mut self,
rule: &mut impl RuleMut<'a, Language = T>,
strategy: &impl Strategy<T>,
flow: ControlFlow,
) -> MinusOneResult<()> {
let mut control_flow = flow;
let mut stack: Vec<(TreeNode, usize, ControlFlow)> = vec![];
for node in traverse(self.inner.walk(), Order::Pre) {
self.inner = node;
stack.push((node, node.child_count(), control_flow));
control_flow = control_flow | strategy.control(self.view())?;
if control_flow != ControlFlow::Break {
rule.enter(self, control_flow)?;
}
loop {
let head = stack.last();
if head.is_none() {
break;
}
let head_element = head.unwrap();
if head_element.1 != 0 {
break;
}
self.inner = head_element.0;
if control_flow != ControlFlow::Break {
rule.leave(self, control_flow)?;
}
control_flow = head_element.2;
stack.pop();
if let Some(l) = stack.last_mut() {
l.1 -= 1;
}
}
}
Ok(())
}
}
pub struct Node<'a, T> {
node: TreeNode<'a>,
source: &'a [u8],
storage: &'a dyn Storage<Component = T>,
}
impl<'a, T> PartialEq for Node<'a, T> {
fn eq(&self, other: &Self) -> bool {
self.node.id() == other.node.id()
}
}
impl<'a, T> Node<'a, T> {
pub fn new(
node: TreeNode<'a>,
source: &'a [u8],
storage: &'a dyn Storage<Component = T>,
) -> Self {
Self {
node,
source,
storage,
}
}
pub fn child(&self, index: usize) -> Option<Node<'a, T>> {
Some(Node::new(
self.node.child(index)?,
self.source,
self.storage,
))
}
pub fn named_child(&self, index: &str) -> Option<Node<'a, T>> {
self.node
.child_by_field_name(index)
.map(|node| Node::new(node, self.source, self.storage))
}
pub fn iter(&self) -> NodeIterator<'a, T> {
NodeIterator::new(Self::new(self.node, self.source, self.storage), 0, None, 1)
}
pub fn range(
&self,
start: Option<usize>,
end: Option<usize>,
gap: Option<usize>,
) -> NodeIterator<'a, T> {
NodeIterator::new(
Self::new(self.node, self.source, self.storage),
start.unwrap_or(0),
end,
gap.unwrap_or(1),
)
}
pub fn kind(&self) -> &'static str {
self.node.kind()
}
pub fn start_rel(&self) -> usize {
self.node.start_byte() - self.node.parent().unwrap().start_byte()
}
pub fn end_rel(&self) -> usize {
self.node.end_byte() - self.node.parent().unwrap().start_byte()
}
pub fn start_abs(&self) -> usize {
self.node.start_byte()
}
pub fn end_abs(&self) -> usize {
self.node.end_byte()
}
pub fn is_extra(&self) -> bool {
self.node.is_extra()
}
pub fn child_count(&self) -> usize {
self.node.child_count()
}
pub fn data(&self) -> Option<&T> {
self.storage.get(self.node)
}
pub fn text(&self) -> Result<&str, Utf8Error> {
self.node.utf8_text(self.source)
}
pub fn parent(&self) -> Option<Node<'a, T>> {
self.node
.parent()
.map(|node| Self::new(node, self.source, self.storage))
}
pub fn get_parent_of_types(&self, kinds: Vec<&str>) -> Option<Node<'a, T>> {
let mut current = self.parent();
loop {
if let Some(current_node) = current {
if kinds.contains(¤t_node.kind()) {
return Some(current_node);
}
current = current_node.parent();
} else {
return None;
}
}
}
fn apply(&self, rule: &mut impl Rule<'a, Language = T>) -> MinusOneResult<()> {
let mut is_visiting = true;
let mut stack: Vec<(TreeNode, usize, bool)> = vec![];
for node in traverse(self.node.walk(), Order::Pre) {
stack.push((node, node.child_count(), is_visiting));
if is_visiting {
is_visiting =
is_visiting && rule.enter(&Node::new(node, self.source, self.storage))?;
}
loop {
let head = stack.last();
if head.is_none() {
break;
}
let head_element = head.unwrap();
if head_element.1 != 0 {
break;
}
if is_visiting {
rule.leave(&Node::new(head_element.0, self.source, self.storage))?;
}
is_visiting = head_element.2;
stack.pop();
if let Some(l) = stack.last_mut() {
l.1 -= 1;
}
}
}
Ok(())
}
}
pub struct NodeIterator<'a, T> {
inner: Node<'a, T>,
index: usize,
end: Option<usize>,
gap: usize,
}
impl<'a, T> NodeIterator<'a, T> {
fn new(node: Node<'a, T>, start: usize, end: Option<usize>, gap: usize) -> Self {
Self {
inner: node,
index: start,
end,
gap,
}
}
}
impl<'a, T> Iterator for NodeIterator<'a, T> {
type Item = Node<'a, T>;
fn next(&mut self) -> Option<Self::Item> {
if let Some(end) = self.end {
if self.index >= end {
return None;
}
}
match self.inner.child(self.index) {
Some(node) => {
self.index += self.gap;
Some(node)
}
None => None,
}
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum BranchFlow {
Predictable, Unpredictable, }
impl ops::BitOr<BranchFlow> for BranchFlow {
type Output = BranchFlow;
fn bitor(self, rhs: BranchFlow) -> Self::Output {
match (self, rhs) {
(BranchFlow::Predictable, BranchFlow::Predictable) => BranchFlow::Predictable,
(BranchFlow::Predictable, BranchFlow::Unpredictable) => BranchFlow::Unpredictable,
(BranchFlow::Unpredictable, BranchFlow::Predictable) => BranchFlow::Unpredictable,
(BranchFlow::Unpredictable, BranchFlow::Unpredictable) => BranchFlow::Unpredictable,
}
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ControlFlow {
Break, Continue(BranchFlow), }
impl ops::BitOr<ControlFlow> for ControlFlow {
type Output = ControlFlow;
fn bitor(self, rhs: ControlFlow) -> Self::Output {
match (self, rhs) {
(ControlFlow::Break, _) => ControlFlow::Break,
(_, ControlFlow::Break) => ControlFlow::Break,
(ControlFlow::Continue(left), ControlFlow::Continue(right)) => {
ControlFlow::Continue(left | right)
}
}
}
}
pub trait Strategy<T> {
fn control(&self, node: Node<T>) -> MinusOneResult<ControlFlow>;
}
pub struct Tree<'a, S: Storage> {
storage: S,
tree_sitter: TreeSitter,
source: &'a [u8],
}
impl<'a, S> Tree<'a, S>
where
S: Storage + Default,
{
pub fn new(source: &'a [u8], tree_sitter: TreeSitter) -> Self {
Self {
storage: S::default(),
tree_sitter,
source,
}
}
pub fn apply_mut<'b>(
&'b mut self,
rule: &mut (impl RuleMut<'b, Language = S::Component> + Sized),
) -> MinusOneResult<()> {
let mut node = NodeMut::new(self.tree_sitter.root_node(), self.source, &mut self.storage);
node.apply(rule)
}
pub fn apply_mut_with_strategy<'b>(
&'b mut self,
rule: &mut (impl RuleMut<'b, Language = S::Component> + Sized),
strategy: impl Strategy<S::Component>,
) -> MinusOneResult<()> {
let mut node = NodeMut::new(self.tree_sitter.root_node(), self.source, &mut self.storage);
node.apply_with_strategy(
rule,
&strategy,
ControlFlow::Continue(BranchFlow::Predictable),
)
}
pub fn apply<'b>(
&'b self,
rule: &mut (impl Rule<'b, Language = S::Component> + Sized),
) -> MinusOneResult<()> {
let node = Node::new(self.tree_sitter.root_node(), self.source, &self.storage);
node.apply(rule)
}
pub fn root(&self) -> MinusOneResult<Node<'_, S::Component>> {
Ok(Node::new(
self.tree_sitter.root_node(),
self.source,
&self.storage,
))
}
}