1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
use std::iter::FromIterator;
use crate::{nodes::Identifier, process::NodeProcessor};
/// A processor to find usage of a given set of identifiers.
///
/// # Example
/// The following example illustrate how you can use this processor to find usage of the
/// `foo` variable.
/// ```
/// # use darklua_core::nodes::Expression;
/// # use darklua_core::process::processors::FindVariables;
/// # use darklua_core::process::{DefaultVisitor, NodeProcessor, NodeVisitor};
/// let variables = vec!["foo".to_owned()];
/// let mut find_foo: FindVariables = variables.iter().collect();
///
/// let mut foo_expression = Expression::identifier("foo");
/// DefaultVisitor::visit_expression(&mut foo_expression, &mut find_foo);
///
/// assert!(find_foo.has_found_usage());
/// ```
/// If you pass a node that does not contain the given variable, the processor will return
/// false when calling the `has_found_usage()` method.
/// ```
/// # use darklua_core::nodes::Expression;
/// # use darklua_core::process::processors::FindVariables;
/// # use darklua_core::process::{DefaultVisitor, NodeProcessor, NodeVisitor};
/// # let variables = vec!["foo".to_owned()];
/// # let mut find_foo: FindVariables = variables.iter().collect();
/// let mut bar_expression = Expression::identifier("bar");
/// DefaultVisitor::visit_expression(&mut bar_expression, &mut find_foo);
///
/// assert!(!find_foo.has_found_usage());
/// ```
pub struct FindVariables<'a> {
variables: Vec<&'a String>,
usage_found: bool,
}
impl<'a> FindVariables<'a> {
#[inline]
pub fn has_found_usage(&self) -> bool {
self.usage_found
}
}
impl<'a> FromIterator<&'a String> for FindVariables<'a> {
fn from_iter<T: IntoIterator<Item = &'a String>>(iter: T) -> Self {
Self {
variables: iter.into_iter().collect(),
usage_found: false,
}
}
}
impl<'a> NodeProcessor for FindVariables<'a> {
fn process_variable_expression(&mut self, variable: &mut Identifier) {
if !self.usage_found {
let name = variable.get_name();
self.usage_found = self.variables.iter().any(|v| *v == name)
}
}
}