mod kind;
mod node_match;
mod pattern;
mod text;
use crate::Doc;
use crate::{meta_var::MetaVarEnv, Node};
use bit_set::BitSet;
use std::borrow::Cow;
pub use kind::{kind_utils, KindMatcher, KindMatcherError};
pub use node_match::NodeMatch;
pub use pattern::{DumpPattern, Pattern, PatternBuilder, PatternError, PatternNode};
pub use text::{RegexMatcher, RegexMatcherError};
pub trait Matcher {
fn match_node_with_env<'tree, D: Doc>(
&self,
_node: Node<'tree, D>,
_env: &mut Cow<MetaVarEnv<'tree, D>>,
) -> Option<Node<'tree, D>>;
fn potential_kinds(&self) -> Option<BitSet> {
None
}
fn get_match_len<D: Doc>(&self, _node: Node<'_, D>) -> Option<usize> {
None
}
}
pub trait MatcherExt: Matcher {
fn match_node<'tree, D: Doc>(&self, node: Node<'tree, D>) -> Option<NodeMatch<'tree, D>> {
let mut env = Cow::Owned(MetaVarEnv::new());
let node = self.match_node_with_env(node, &mut env)?;
Some(NodeMatch::new(node, env.into_owned()))
}
fn find_node<'tree, D: Doc>(&self, node: Node<'tree, D>) -> Option<NodeMatch<'tree, D>> {
for n in node.dfs() {
if let Some(ret) = self.match_node(n.clone()) {
return Some(ret);
}
}
None
}
}
impl<T> MatcherExt for T where T: Matcher {}
impl Matcher for str {
fn match_node_with_env<'tree, D: Doc>(
&self,
node: Node<'tree, D>,
env: &mut Cow<MetaVarEnv<'tree, D>>,
) -> Option<Node<'tree, D>> {
let pattern = Pattern::new(self, node.lang().clone());
pattern.match_node_with_env(node, env)
}
fn get_match_len<D: Doc>(&self, node: Node<'_, D>) -> Option<usize> {
let pattern = Pattern::new(self, node.lang().clone());
pattern.get_match_len(node)
}
}
impl<T> Matcher for &T
where
T: Matcher + ?Sized,
{
fn match_node_with_env<'tree, D: Doc>(
&self,
node: Node<'tree, D>,
env: &mut Cow<MetaVarEnv<'tree, D>>,
) -> Option<Node<'tree, D>> {
(**self).match_node_with_env(node, env)
}
fn potential_kinds(&self) -> Option<BitSet> {
(**self).potential_kinds()
}
fn get_match_len<D: Doc>(&self, node: Node<'_, D>) -> Option<usize> {
(**self).get_match_len(node)
}
}
pub struct MatchAll;
impl Matcher for MatchAll {
fn match_node_with_env<'tree, D: Doc>(
&self,
node: Node<'tree, D>,
_env: &mut Cow<MetaVarEnv<'tree, D>>,
) -> Option<Node<'tree, D>> {
Some(node)
}
fn potential_kinds(&self) -> Option<BitSet> {
None
}
}
pub struct MatchNone;
impl Matcher for MatchNone {
fn match_node_with_env<'tree, D: Doc>(
&self,
_node: Node<'tree, D>,
_env: &mut Cow<MetaVarEnv<'tree, D>>,
) -> Option<Node<'tree, D>> {
None
}
fn potential_kinds(&self) -> Option<BitSet> {
Some(BitSet::new())
}
}