fn match_sequential_siblings()

in crates/concrete-syntax/src/models/concrete_syntax/interpreter.rs [110:164]


fn match_sequential_siblings(
  cursor: &mut TreeCursor, source_code_ref: &[u8], cs_elements: &[ResolvedCsElement],
) -> PatternMatchResult {
  let parent_node = cursor.node();

  let mut child_seq_match_start = 0;
  if cursor.goto_first_child() {
    // Iterate through siblings to find a match
    loop {
      // Clone the cursor in order to attempt matching the sequence starting at cursor.node
      // Cloning here is necessary other we won't be able to advance to the next sibling if the matching fails
      let result = {
        match_cs_pattern(
          &mut MatchingContext {
            cursor: cursor.clone(),
            source_code: source_code_ref,
            top_node: &parent_node,
          },
          cs_elements,
          true,
        )
      };

      // If we got a successful match, extract the mapping and index
      if let PatternMatchResult::Success {
        captures: mapping,
        consumed_nodes: last_node_index,
        range: None,
      } = result
      {
        // Determine the last matched node. Remember, we are matching subsequences of children [n ... k]
        let last_node = parent_node.child(last_node_index);
        let start_range = cursor.node().range();
        let end_range = last_node.unwrap().range();
        let range = Range::span_ranges(start_range, end_range);
        if last_node_index != child_seq_match_start || parent_node.child_count() == 1 {
          return PatternMatchResult::Success {
            captures: mapping,
            consumed_nodes: last_node_index,
            range: Some(range),
          };
        }
        // This is to prevent double matches when unrolling a node. i.e., matching the statement in a function body,
        // as well as the statement itself when unrolled.
        return PatternMatchResult::failed();
      }

      child_seq_match_start += 1;
      if !cursor.goto_next_sibling() {
        break;
      }
    }
  } // Not currently handing matching of leaf nodes. Current semantics would never match it anyway.
  PatternMatchResult::failed()
}