use super::index::DefIndex;
use super::ladder::{resolve_ref, Resolution};
use super::scope::FileContext;
use crate::graph::FragRef;
use std::collections::{HashMap, HashSet};
pub(super) fn resolve_ref_by_arity(
mut probe: FragRef,
arity: Option<usize>,
usings: &HashSet<String>,
ns: &str,
index: &DefIndex,
aliases: &HashMap<String, String>,
file_contexts: &HashMap<String, FileContext>,
) -> Resolution {
if let Some(n) = arity {
let full = aliases.get(&probe.name).unwrap_or(&probe.name);
let simple = full.rsplit('.').next().unwrap_or(full);
let shared = index.simple_name_to_defs.get(simple).map_or(0, Vec::len) >= 2;
if shared {
probe.type_arg_count = Some(n);
let exact = resolve_ref(&probe, usings, ns, index, aliases, file_contexts);
if !matches!(exact, Resolution::External) {
return exact;
}
probe.type_arg_count = None;
}
}
resolve_ref(&probe, usings, ns, index, aliases, file_contexts)
}
pub(super) fn resolve_receiver_type(
mut probe: FragRef,
arity: Option<usize>,
usings: &HashSet<String>,
ns: &str,
index: &DefIndex,
aliases: &HashMap<String, String>,
file_contexts: &HashMap<String, FileContext>,
) -> Resolution {
if let Some(n) = arity {
if n >= 1 {
let full = aliases.get(&probe.name).unwrap_or(&probe.name);
let simple = full.rsplit('.').next().unwrap_or(full);
let shared = index.simple_name_to_defs.get(simple).map_or(0, Vec::len) >= 2;
if shared {
probe.type_arg_count = Some(n);
return resolve_ref(&probe, usings, ns, index, aliases, file_contexts);
}
}
}
resolve_ref_by_arity(probe, arity, usings, ns, index, aliases, file_contexts)
}
pub(super) fn base_arity(index: &DefIndex, idx: usize, base: &str) -> usize {
index.member_lists[idx]
.base_generic_args
.iter()
.find(|(k, _)| k == base)
.map_or(0, |(_, v)| v.len())
}
pub(super) fn method_arity_admits(
index: &DefIndex,
idx: usize,
member: &str,
arg_count: usize,
) -> bool {
match index.member_lists[idx].method_arities.get(member) {
Some(ranges) => ranges
.iter()
.any(|&(min, max)| min <= arg_count && (max == -1 || (arg_count as i64) <= max)),
None => true,
}
}
pub(super) fn arity_accepts(entry: &crate::graph::FragExtensionMethod, arg_count: usize) -> bool {
entry.arity_min <= arg_count && (entry.arity_max == -1 || (arg_count as i64) <= entry.arity_max)
}
pub(super) fn generic_args_unify(
this_args: Option<&Vec<String>>,
receiver_args: Option<&Vec<String>>,
) -> bool {
match (this_args, receiver_args) {
(None, None) => true,
(Some(a), Some(b)) => {
a.len() == b.len() && a.iter().zip(b).all(|(x, y)| x == "*" || y == "*" || x == y)
}
_ => false,
}
}