|
@@ -1,12 +1,188 @@
|
|
-#[derive(Eq, PartialEq)]
|
|
|
|
-enum NodeType {
|
|
|
|
|
|
+use lib_ruby_parser as p;
|
|
|
|
+
|
|
|
|
+#[derive(Eq, PartialEq, Copy, Clone)]
|
|
|
|
+pub enum NodeType {
|
|
Send,
|
|
Send,
|
|
Local,
|
|
Local,
|
|
Const,
|
|
Const,
|
|
Anything,
|
|
Anything,
|
|
}
|
|
}
|
|
|
|
|
|
-#[derive(Eq, PartialEq)]
|
|
|
|
-struct Pattern {
|
|
|
|
- node_type: NodeType,
|
|
|
|
|
|
+#[derive(Eq, PartialEq, Clone)]
|
|
|
|
+pub struct Pattern {
|
|
|
|
+ pub node_type: NodeType,
|
|
|
|
+ pub name: Option<String>,
|
|
|
|
+ pub children: Vec<Pattern>,
|
|
|
|
+ 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(_) => {}
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|