Find the most recent definition of `$var_name` before `cursor_offset` within the same scope. The caller should obtain `scope_start` via [`find_enclosing_scope`].
(
&self,
var_name: &str,
cursor_offset: u32,
scope_start: u32,
)
| 629 | /// The caller should obtain `scope_start` via |
| 630 | /// [`find_enclosing_scope`]. |
| 631 | pub fn find_var_definition( |
| 632 | &self, |
| 633 | var_name: &str, |
| 634 | cursor_offset: u32, |
| 635 | scope_start: u32, |
| 636 | ) -> Option<&VarDefSite> { |
| 637 | // Find all visible definitions for this variable in this scope. |
| 638 | // Prefer the most recent one, but if a shallower (outer) definition |
| 639 | // exists, prefer it over a deeper (conditional) one when the cursor |
| 640 | // is outside the conditional block. |
| 641 | let mut best: Option<&VarDefSite> = None; |
| 642 | for d in self.var_defs.iter() { |
| 643 | if d.name != var_name |
| 644 | || d.scope_start != scope_start |
| 645 | || d.effective_from > cursor_offset |
| 646 | { |
| 647 | continue; |
| 648 | } |
| 649 | match best { |
| 650 | None => best = Some(d), |
| 651 | Some(prev) => { |
| 652 | if d.nesting_depth <= prev.nesting_depth { |
| 653 | // Same or shallower depth: more recent wins. |
| 654 | best = Some(d); |
| 655 | } else if cursor_offset <= d.block_end { |
| 656 | // Deeper, but cursor is inside the block: use it. |
| 657 | best = Some(d); |
| 658 | } |
| 659 | // Deeper and cursor is past the block: keep prev. |
| 660 | } |
| 661 | } |
| 662 | } |
| 663 | best |
| 664 | } |
| 665 | |
| 666 | /// Return the `effective_from` offset of the most recent definition |
| 667 | /// of `$var_name` that is visible at `cursor_offset`, or `0` if no |