use lib_ruby_parser as p; #[derive(Eq, PartialEq, Copy, Clone)] pub enum NodeType { Send, Local, Const, Anything, } #[derive(Eq, PartialEq, Clone)] pub struct Pattern { pub node_type: NodeType, pub name: Option, pub children: Vec, pub rest: bool, } impl Pattern { pub fn matches(&self, p: &p::Node) -> bool { match p { p::Node::Const(cnst) => { if let Some(name) = &self.name { &cnst.name == name } else { false } } _ => false, } } pub fn find_matches<'a>(&self, p: &'a p::Node) -> Vec<&'a p::Node> { let mut matches = Vec::new(); self.find_matches_ref(p, &mut matches); matches } fn find_matches_ref<'a, 'b>(&self, p: &'a p::Node, res: &'b mut Vec<&'a p::Node>) { if self.matches(p) { res.push(p); } match p { p::Node::Alias(_) => {} p::Node::AndAsgn(_) => {} p::Node::And(_) => {} p::Node::Arg(_) => {} p::Node::Args(_) => {} p::Node::Array(_) => {} p::Node::ArrayPattern(_) => {} p::Node::ArrayPatternWithTail(_) => {} p::Node::BackRef(_) => {} p::Node::Begin(begin) => { for stmt in begin.statements.iter() { self.find_matches_ref(stmt, res); } } p::Node::Block(_) => {} p::Node::BlockPass(_) => {} p::Node::Blockarg(_) => {} p::Node::Break(_) => {} p::Node::Case(_) => {} p::Node::CaseMatch(_) => {} p::Node::Casgn(_) => {} p::Node::Cbase(_) => {} p::Node::Class(class) => { self.find_matches_ref(&class.name, res); if let Some(ref superclass) = class.superclass { self.find_matches_ref(superclass, res); } if let Some(ref body) = class.body { self.find_matches_ref(body, res); } } p::Node::Complex(_) => {} p::Node::Const(_) => {} p::Node::ConstPattern(_) => {} p::Node::CSend(_) => {} p::Node::Cvar(_) => {} p::Node::Cvasgn(_) => {} p::Node::Def(_) => {} p::Node::Defined(_) => {} p::Node::Defs(_) => {} p::Node::Dstr(_) => {} p::Node::Dsym(_) => {} p::Node::EFlipFlop(_) => {} p::Node::EmptyElse(_) => {} p::Node::Encoding(_) => {} p::Node::Ensure(_) => {} p::Node::Erange(_) => {} p::Node::False(_) => {} p::Node::File(_) => {} p::Node::FindPattern(_) => {} p::Node::Float(_) => {} p::Node::For(_) => {} p::Node::ForwardArg(_) => {} p::Node::ForwardedArgs(_) => {} p::Node::Gvar(_) => {} p::Node::Gvasgn(_) => {} p::Node::Hash(_) => {} p::Node::Kwargs(_) => {} p::Node::HashPattern(_) => {} p::Node::Heredoc(_) => {} p::Node::If(_) => {} p::Node::IfGuard(_) => {} p::Node::IfMod(_) => {} p::Node::IfTernary(_) => {} p::Node::IFlipFlop(_) => {} p::Node::MatchPattern(_) => {} p::Node::MatchPatternP(_) => {} p::Node::InPattern(_) => {} p::Node::Index(_) => {} p::Node::IndexAsgn(_) => {} p::Node::Int(_) => {} p::Node::Irange(_) => {} p::Node::Ivar(_) => {} p::Node::Ivasgn(_) => {} p::Node::Kwarg(_) => {} p::Node::KwBegin(_) => {} p::Node::Kwnilarg(_) => {} p::Node::Kwoptarg(_) => {} p::Node::Kwrestarg(_) => {} p::Node::Kwsplat(_) => {} p::Node::Lambda(_) => {} p::Node::Line(_) => {} p::Node::Lvar(_) => {} p::Node::Lvasgn(_) => {} p::Node::Masgn(_) => {} p::Node::MatchAlt(_) => {} p::Node::MatchAs(_) => {} p::Node::MatchCurrentLine(_) => {} p::Node::MatchNilPattern(_) => {} p::Node::MatchRest(_) => {} p::Node::MatchVar(_) => {} p::Node::MatchWithLvasgn(_) => {} p::Node::Mlhs(_) => {} p::Node::Module(module) => { self.find_matches_ref(&module.name, res); if let Some(ref body) = module.body { self.find_matches_ref(body, res); } } p::Node::Next(_) => {} p::Node::Nil(_) => {} p::Node::NthRef(_) => {} p::Node::Numblock(_) => {} p::Node::OpAsgn(_) => {} p::Node::Optarg(_) => {} p::Node::Or(_) => {} p::Node::OrAsgn(_) => {} p::Node::Pair(_) => {} p::Node::Pin(_) => {} p::Node::Postexe(_) => {} p::Node::Preexe(_) => {} p::Node::Procarg0(_0) => {} p::Node::Rational(_) => {} p::Node::Redo(_) => {} p::Node::RegOpt(_) => {} p::Node::Regexp(_) => {} p::Node::Rescue(_) => {} p::Node::RescueBody(_) => {} p::Node::Restarg(_) => {} p::Node::Retry(_) => {} p::Node::Return(_) => {} p::Node::SClass(_) => {} p::Node::Self_(__) => {} p::Node::Send(_) => {} p::Node::Shadowarg(_) => {} p::Node::Splat(_) => {} p::Node::Str(_) => {} p::Node::Super(_) => {} p::Node::Sym(_) => {} p::Node::True(_) => {} p::Node::Undef(_) => {} p::Node::UnlessGuard(_) => {} p::Node::Until(_) => {} p::Node::UntilPost(_) => {} p::Node::When(_) => {} p::Node::While(_) => {} p::Node::WhilePost(_) => {} p::Node::XHeredoc(_) => {} p::Node::Xstr(_) => {} p::Node::Yield(_) => {} p::Node::ZSuper(_) => {} } } }