use std::collections::HashSet;
use crate::graph::{Edge, SemanticProvenance};
use crate::resolve::DefIndex;
use super::layer::{LookupOutcome, SemanticLayer, SemanticTarget};
pub fn project(
layer: &SemanticLayer,
index: &DefIndex,
referenced_sites: &HashSet<(String, usize, String)>,
edges: &mut Vec<Edge>,
) -> usize {
let mut site_keys: Vec<&(String, usize, String)> = layer.site_keys().collect();
site_keys.sort();
let mut discovered = 0;
for (file, line, member) in site_keys {
if referenced_sites.contains(&(file.clone(), *line, member.clone())) {
continue;
}
match layer.lookup(index, file, *line, member, None) {
LookupOutcome::Confirmed(target) => {
push_discovered(edges, file, *line, member, &target);
discovered += 1;
}
LookupOutcome::ConfirmedMany(targets)
if targets.iter().all(|t| {
(&t.to_def_id, &t.to_file) == (&targets[0].to_def_id, &targets[0].to_file)
}) =>
{
for target in &targets {
push_discovered(edges, file, *line, member, target);
discovered += 1;
}
}
LookupOutcome::ConfirmedMany(_) | LookupOutcome::Other(_) | LookupOutcome::NoFact => {}
}
}
discovered
}
fn push_discovered(
edges: &mut Vec<Edge>,
file: &str,
line: usize,
member: &str,
target: &SemanticTarget,
) {
edges.push(Edge::uses_member_semantic(
file.to_string(),
line,
target.to_def_id.clone(),
target.to_file.clone(),
Some(member.to_string()),
SemanticProvenance::SemanticDiscovered,
target.overload_signature.clone(),
));
}