use crate::graph;
#[allow(dead_code)]
const REF_KINDS: [&str; 3] = ["inherits", "uses-type", "uses-member"];
pub const DEFAULT_CAP: usize = 50;
pub const INBOUND_CAP: usize = 30;
pub const OUTBOUND_CAP: usize = 30;
pub const SOURCE_MAX: usize = 120;
pub(super) fn cap_rows<T>(mut rows: Vec<T>, cap: usize) -> (Vec<T>, usize) {
if rows.len() <= cap {
(rows, 0)
} else {
let dropped = rows.len() - cap;
rows.truncate(cap);
(rows, dropped)
}
}
pub(super) fn edge_loc(e: &graph::Edge) -> (&str, usize) {
match e {
graph::Edge::Inherits { from_file, from_line, .. }
| graph::Edge::UsesType { from_file, from_line, .. }
| graph::Edge::UsesMember { from_file, from_line, .. }
| graph::Edge::Implements { from_file, from_line, .. }
| graph::Edge::Overrides { from_file, from_line, .. }
| graph::Edge::Imports { from_file, from_line, .. }
| graph::Edge::Ambiguous { from_file, from_line, .. }
| graph::Edge::CtorDi { from_file, from_line, .. }
| graph::Edge::Import { from_file, from_line, .. }
| graph::Edge::Call { from_file, from_line, .. }
| graph::Edge::JsxUse { from_file, from_line, .. }
| graph::Edge::Dispatch { from_file, from_line, .. } => (from_file.as_str(), *from_line),
}
}
pub(super) fn loc_cmp(a: &graph::Edge, b: &graph::Edge) -> std::cmp::Ordering {
let (af, al) = edge_loc(a);
let (bf, bl) = edge_loc(b);
if af == bf {
al.cmp(&bl)
} else {
af.cmp(bf)
}
}
pub(super) fn row_tier(heuristic: bool, ext_seen: bool) -> Option<graph::HeuristicTier> {
if !heuristic {
return None;
}
Some(if ext_seen {
graph::HeuristicTier::Ext
} else {
graph::HeuristicTier::Guess
})
}
#[derive(Debug, Clone, PartialEq)]
pub struct InboundRow {
pub file: String,
pub line: usize,
pub heuristic: bool,
pub tier: Option<graph::HeuristicTier>,
pub source: String,
}
#[derive(Debug, Clone, PartialEq)]
pub struct OutboundRow {
pub file: String,
pub line: usize,
pub to_file: String,
pub to: String,
pub heuristic: bool,
pub tier: Option<graph::HeuristicTier>,
pub source: String,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ImportRow {
pub file: String,
pub line: usize,
pub target: String,
pub source: String,
}
#[derive(Debug, Clone, PartialEq)]
pub struct AmbiguousRow {
pub file: String,
pub line: usize,
pub origin: String,
pub raw: String,
pub candidate_count: usize,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Table<R> {
pub total: usize,
pub dropped: usize,
pub rows: Vec<R>,
}
pub(super) fn build_table<R>(
mut idxs: Vec<usize>,
edges: &[graph::Edge],
cap: usize,
map_row: fn(&graph::Edge) -> R,
) -> Table<R> {
idxs.sort_by(|&a, &b| loc_cmp(&edges[a], &edges[b]));
let total = idxs.len();
let (shown, dropped) = cap_rows(idxs, cap);
let rows = shown.into_iter().map(|i| map_row(&edges[i])).collect();
Table {
total,
dropped,
rows,
}
}
pub(super) fn ambiguous_row(e: &graph::Edge) -> AmbiguousRow {
match e {
graph::Edge::Ambiguous {
origin,
from_file,
from_line,
raw,
candidate_count,
..
} => AmbiguousRow {
file: from_file.clone(),
line: *from_line,
origin: origin.clone(),
raw: raw.clone(),
candidate_count: *candidate_count,
},
_ => unreachable!("ambiguous table only ever holds ambiguous edge indices"),
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct InboundTables {
pub inherits: Table<InboundRow>,
pub uses_type: Table<InboundRow>,
pub uses_member: Table<InboundRow>,
pub implements: Table<InboundRow>,
pub overrides: Table<InboundRow>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct OutboundTables {
pub inherits: Table<OutboundRow>,
pub uses_type: Table<OutboundRow>,
pub uses_member: Table<OutboundRow>,
pub implements: Table<OutboundRow>,
pub overrides: Table<OutboundRow>,
pub imports: Table<ImportRow>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct AmbiguousTables {
pub inbound: Table<AmbiguousRow>,
pub outbound: Table<AmbiguousRow>,
}