use std::collections::HashSet;
use crate::types::{Node, NodeKind};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct AmbiguityRefKey {
pub from_node_id: String,
pub reference_name: String,
pub file_path: String,
pub line: u32,
}
impl From<&crate::types::UnresolvedRef> for AmbiguityRefKey {
fn from(uref: &crate::types::UnresolvedRef) -> Self {
Self {
from_node_id: uref.from_node_id.clone(),
reference_name: uref.reference_name.clone(),
file_path: uref.file_path.clone(),
line: uref.line,
}
}
}
#[derive(Debug, Clone)]
pub struct TouchedNode {
pub kind: NodeKind,
pub name: String,
pub qualified_name: String,
}
impl From<&Node> for TouchedNode {
fn from(node: &Node) -> Self {
Self {
kind: node.kind.clone(),
name: node.name.clone(),
qualified_name: node.qualified_name.clone(),
}
}
}
pub fn index_keys(node: &TouchedNode, out: &mut HashSet<String>) {
if node.kind == NodeKind::Use {
return;
}
out.insert(node.name.clone());
let qn = node.qualified_name.as_str();
out.insert(qn.to_string());
let mut pos = 0;
while let Some(idx) = qn[pos..].find("::") {
let suffix = &qn[pos + idx + 2..];
if !suffix.is_empty() {
out.insert(suffix.to_string());
}
pos += idx + 2;
}
}
#[derive(Debug, Default)]
pub struct TouchedSet {
files: HashSet<String>,
names: HashSet<String>,
}
impl TouchedSet {
pub fn new() -> Self {
Self::default()
}
pub fn touch_file(&mut self, path: &str) {
self.files.insert(path.to_string());
}
pub fn touch_nodes<'n>(&mut self, nodes: impl IntoIterator<Item = &'n TouchedNode>) {
for node in nodes {
index_keys(node, &mut self.names);
}
}
pub fn needs_resolve(&self, file_path: &str, reference_name: &str) -> bool {
self.files.contains(file_path)
|| self.names.contains(reference_name)
|| self.names.contains(super::simple_ref_name(reference_name))
}
pub fn files(&self) -> &HashSet<String> {
&self.files
}
pub fn name_count(&self) -> usize {
self.names.len()
}
}
pub fn index_keys_for_test(nodes: &[Node]) -> HashSet<String> {
let mut out = HashSet::new();
for node in nodes {
index_keys(&TouchedNode::from(node), &mut out);
}
out
}