pattern.rs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. use lib_ruby_parser as p;
  2. #[derive(Eq, PartialEq, Copy, Clone)]
  3. pub enum NodeType {
  4. Send,
  5. Local,
  6. Const,
  7. Anything,
  8. }
  9. #[derive(Eq, PartialEq, Clone)]
  10. pub struct Pattern {
  11. pub node_type: NodeType,
  12. pub name: Option<String>,
  13. pub children: Vec<Pattern>,
  14. pub rest: bool,
  15. }
  16. impl Pattern {
  17. pub fn matches(&self, p: &p::Node) -> bool {
  18. match p {
  19. p::Node::Const(cnst) => {
  20. if let Some(name) = &self.name {
  21. &cnst.name == name
  22. } else {
  23. false
  24. }
  25. }
  26. _ => false,
  27. }
  28. }
  29. pub fn find_matches<'a>(&self, p: &'a p::Node) -> Vec<&'a p::Node> {
  30. let mut matches = Vec::new();
  31. self.find_matches_ref(p, &mut matches);
  32. matches
  33. }
  34. fn find_matches_ref<'a, 'b>(&self, p: &'a p::Node, res: &'b mut Vec<&'a p::Node>) {
  35. if self.matches(p) {
  36. res.push(p);
  37. }
  38. match p {
  39. p::Node::Alias(_) => {}
  40. p::Node::AndAsgn(_) => {}
  41. p::Node::And(_) => {}
  42. p::Node::Arg(_) => {}
  43. p::Node::Args(_) => {}
  44. p::Node::Array(_) => {}
  45. p::Node::ArrayPattern(_) => {}
  46. p::Node::ArrayPatternWithTail(_) => {}
  47. p::Node::BackRef(_) => {}
  48. p::Node::Begin(begin) => {
  49. for stmt in begin.statements.iter() {
  50. self.find_matches_ref(stmt, res);
  51. }
  52. }
  53. p::Node::Block(_) => {}
  54. p::Node::BlockPass(_) => {}
  55. p::Node::Blockarg(_) => {}
  56. p::Node::Break(_) => {}
  57. p::Node::Case(_) => {}
  58. p::Node::CaseMatch(_) => {}
  59. p::Node::Casgn(_) => {}
  60. p::Node::Cbase(_) => {}
  61. p::Node::Class(class) => {
  62. self.find_matches_ref(&class.name, res);
  63. if let Some(ref superclass) = class.superclass {
  64. self.find_matches_ref(superclass, res);
  65. }
  66. if let Some(ref body) = class.body {
  67. self.find_matches_ref(body, res);
  68. }
  69. }
  70. p::Node::Complex(_) => {}
  71. p::Node::Const(_) => {}
  72. p::Node::ConstPattern(_) => {}
  73. p::Node::CSend(_) => {}
  74. p::Node::Cvar(_) => {}
  75. p::Node::Cvasgn(_) => {}
  76. p::Node::Def(_) => {}
  77. p::Node::Defined(_) => {}
  78. p::Node::Defs(_) => {}
  79. p::Node::Dstr(_) => {}
  80. p::Node::Dsym(_) => {}
  81. p::Node::EFlipFlop(_) => {}
  82. p::Node::EmptyElse(_) => {}
  83. p::Node::Encoding(_) => {}
  84. p::Node::Ensure(_) => {}
  85. p::Node::Erange(_) => {}
  86. p::Node::False(_) => {}
  87. p::Node::File(_) => {}
  88. p::Node::FindPattern(_) => {}
  89. p::Node::Float(_) => {}
  90. p::Node::For(_) => {}
  91. p::Node::ForwardArg(_) => {}
  92. p::Node::ForwardedArgs(_) => {}
  93. p::Node::Gvar(_) => {}
  94. p::Node::Gvasgn(_) => {}
  95. p::Node::Hash(_) => {}
  96. p::Node::Kwargs(_) => {}
  97. p::Node::HashPattern(_) => {}
  98. p::Node::Heredoc(_) => {}
  99. p::Node::If(_) => {}
  100. p::Node::IfGuard(_) => {}
  101. p::Node::IfMod(_) => {}
  102. p::Node::IfTernary(_) => {}
  103. p::Node::IFlipFlop(_) => {}
  104. p::Node::MatchPattern(_) => {}
  105. p::Node::MatchPatternP(_) => {}
  106. p::Node::InPattern(_) => {}
  107. p::Node::Index(_) => {}
  108. p::Node::IndexAsgn(_) => {}
  109. p::Node::Int(_) => {}
  110. p::Node::Irange(_) => {}
  111. p::Node::Ivar(_) => {}
  112. p::Node::Ivasgn(_) => {}
  113. p::Node::Kwarg(_) => {}
  114. p::Node::KwBegin(_) => {}
  115. p::Node::Kwnilarg(_) => {}
  116. p::Node::Kwoptarg(_) => {}
  117. p::Node::Kwrestarg(_) => {}
  118. p::Node::Kwsplat(_) => {}
  119. p::Node::Lambda(_) => {}
  120. p::Node::Line(_) => {}
  121. p::Node::Lvar(_) => {}
  122. p::Node::Lvasgn(_) => {}
  123. p::Node::Masgn(_) => {}
  124. p::Node::MatchAlt(_) => {}
  125. p::Node::MatchAs(_) => {}
  126. p::Node::MatchCurrentLine(_) => {}
  127. p::Node::MatchNilPattern(_) => {}
  128. p::Node::MatchRest(_) => {}
  129. p::Node::MatchVar(_) => {}
  130. p::Node::MatchWithLvasgn(_) => {}
  131. p::Node::Mlhs(_) => {}
  132. p::Node::Module(module) => {
  133. self.find_matches_ref(&module.name, res);
  134. if let Some(ref body) = module.body {
  135. self.find_matches_ref(body, res);
  136. }
  137. }
  138. p::Node::Next(_) => {}
  139. p::Node::Nil(_) => {}
  140. p::Node::NthRef(_) => {}
  141. p::Node::Numblock(_) => {}
  142. p::Node::OpAsgn(_) => {}
  143. p::Node::Optarg(_) => {}
  144. p::Node::Or(_) => {}
  145. p::Node::OrAsgn(_) => {}
  146. p::Node::Pair(_) => {}
  147. p::Node::Pin(_) => {}
  148. p::Node::Postexe(_) => {}
  149. p::Node::Preexe(_) => {}
  150. p::Node::Procarg0(_0) => {}
  151. p::Node::Rational(_) => {}
  152. p::Node::Redo(_) => {}
  153. p::Node::RegOpt(_) => {}
  154. p::Node::Regexp(_) => {}
  155. p::Node::Rescue(_) => {}
  156. p::Node::RescueBody(_) => {}
  157. p::Node::Restarg(_) => {}
  158. p::Node::Retry(_) => {}
  159. p::Node::Return(_) => {}
  160. p::Node::SClass(_) => {}
  161. p::Node::Self_(__) => {}
  162. p::Node::Send(_) => {}
  163. p::Node::Shadowarg(_) => {}
  164. p::Node::Splat(_) => {}
  165. p::Node::Str(_) => {}
  166. p::Node::Super(_) => {}
  167. p::Node::Sym(_) => {}
  168. p::Node::True(_) => {}
  169. p::Node::Undef(_) => {}
  170. p::Node::UnlessGuard(_) => {}
  171. p::Node::Until(_) => {}
  172. p::Node::UntilPost(_) => {}
  173. p::Node::When(_) => {}
  174. p::Node::While(_) => {}
  175. p::Node::WhilePost(_) => {}
  176. p::Node::XHeredoc(_) => {}
  177. p::Node::Xstr(_) => {}
  178. p::Node::Yield(_) => {}
  179. p::Node::ZSuper(_) => {}
  180. }
  181. }
  182. }