readseek 0.6.3

structural source reader with stable line hashes
// SPDX-License-Identifier: LGPL-2.1-or-later
// Copyright (c) 2026 Jarkko Sakkinen

//! Swift-specific binding helpers.

use tree_sitter::Node;

/// Collect identifiers that introduce bindings in Swift.
pub(super) fn declared_idents<'tree>(node: Node<'tree>, _src: &[u8]) -> Vec<Node<'tree>> {
    let mut out = Vec::new();
    match node.kind() {
        "property_declaration" => {
            let mut cursor = node.walk();
            for name in node.children_by_field_name("name", &mut cursor) {
                collect_pattern_idents(name, &mut out);
            }
        }
        "parameter" => {
            if let Some(name) = node.child_by_field_name("name") {
                collect_pattern_idents(name, &mut out);
            }
        }
        "for_statement" => {
            if let Some(item) = node.child_by_field_name("item") {
                collect_pattern_idents(item, &mut out);
            }
        }
        _ => {}
    }
    out
}

fn collect_pattern_idents<'tree>(node: Node<'tree>, out: &mut Vec<Node<'tree>>) {
    if node.kind() == "simple_identifier" {
        out.push(node);
        return;
    }
    let mut cursor = node.walk();
    for child in node.named_children(&mut cursor) {
        collect_pattern_idents(child, out);
    }
}

/// Exclude member names in navigation expressions from local binding resolution.
pub(super) fn is_reference(node: Node<'_>) -> bool {
    node.parent()
        .is_none_or(|parent| parent.kind() != "navigation_suffix")
}