use std::collections::HashMap;
use crate::graph;
use super::index::{InboundEntry, OutboundEntry};
#[derive(Debug, Clone, Default)]
pub struct TsKinds {
pub call: Vec<usize>,
pub jsx_use: Vec<usize>,
pub dispatch: Vec<usize>,
pub import: Vec<usize>,
}
impl TsKinds {
pub fn lists(&self) -> [&Vec<usize>; 4] {
[&self.call, &self.jsx_use, &self.dispatch, &self.import]
}
pub(super) fn extend_from(&mut self, other: &TsKinds) {
self.call.extend(other.call.iter().copied());
self.jsx_use.extend(other.jsx_use.iter().copied());
self.dispatch.extend(other.dispatch.iter().copied());
self.import.extend(other.import.iter().copied());
}
}
struct Admitted<'e> {
from_file: &'e String,
to_file: &'e String,
targets: Vec<&'e String>,
list: fn(&mut TsKinds) -> &mut Vec<usize>,
}
fn admitted(e: &graph::Edge) -> Option<Admitted<'_>> {
let (from_file, to_file, targets, list): (_, _, _, fn(&mut TsKinds) -> &mut Vec<usize>) =
match e {
graph::Edge::Call {
from_file,
to,
to_file,
..
} => (from_file, to_file, vec![to], |k| &mut k.call),
graph::Edge::JsxUse {
from_file,
to,
to_file,
..
} => (from_file, to_file, vec![to], |k| &mut k.jsx_use),
graph::Edge::Dispatch {
from_file,
to,
to_file,
..
} => (from_file, to_file, vec![to], |k| &mut k.dispatch),
graph::Edge::Import {
from_file,
to_file,
bound_defs,
..
} if !bound_defs.is_empty() => (from_file, to_file, bound_defs.iter().collect(), |k| {
&mut k.import
}),
_ => return None,
};
Some(Admitted {
from_file,
to_file,
targets,
list,
})
}
pub(super) fn record_ts_edge<'e>(
e: &'e graph::Edge,
i: usize,
inbound: &mut HashMap<String, InboundEntry>,
outbound_by_file: &mut HashMap<String, OutboundEntry>,
) -> Option<(&'e str, &'e str)> {
let edge = admitted(e)?;
for to in edge.targets {
(edge.list)(&mut inbound.entry(to.clone()).or_default().ts).push(i);
}
(edge.list)(
&mut outbound_by_file
.entry(edge.from_file.clone())
.or_default()
.ts,
)
.push(i);
Some((edge.from_file.as_str(), edge.to_file.as_str()))
}