#![cfg_attr(coverage_nightly, coverage(off))]
use super::{Variable, VariableInspector};
use tree_sitter::Node;
impl VariableInspector {
pub(super) fn find_scope_at_line<'a>(
&self,
node: Node<'a>,
target_line: usize,
) -> Option<Node<'a>> {
let node_start_line = node.start_position().row;
let node_end_line = node.end_position().row;
if target_line < node_start_line || target_line > node_end_line {
return None;
}
let mut cursor = node.walk();
for child in node.children(&mut cursor) {
if let Some(child_scope) = self.find_scope_at_line(child, target_line) {
return Some(child_scope);
}
}
Some(node)
}
pub(super) fn find_parent_function<'a>(&self, mut node: Node<'a>) -> Option<Node<'a>> {
loop {
let kind = node.kind();
if kind == "function_item"
|| kind == "function_declaration"
|| kind == "function_definition"
|| kind == "arrow_function"
|| kind == "method_definition"
{
return Some(node);
}
if kind == "lexical_declaration" {
let mut cursor = node.walk();
for child in node.children(&mut cursor) {
if child.kind() == "variable_declarator" {
let mut decl_cursor = child.walk();
for decl_child in child.children(&mut decl_cursor) {
if decl_child.kind() == "arrow_function" {
return Some(decl_child);
}
}
}
}
}
match node.parent() {
Some(parent) => node = parent,
None => return None,
}
}
}
pub(super) fn deduplicate_variables(&self, variables: Vec<Variable>) -> Vec<Variable> {
use std::collections::HashMap;
let mut unique_vars: HashMap<String, Variable> = HashMap::new();
for var in variables {
unique_vars.insert(var.name.clone(), var);
}
unique_vars.into_values().collect()
}
}