use indexmap::set::IndexSet as HashSet;
use super::deps::HasDependencies;
use super::fun::{FnAnalysis, FnKind, FnPhase};
use crate::conversion::apivec::ApiVec;
use crate::conversion::{convert_error::ErrorContext, ConvertErrorFromCpp};
use crate::{conversion::api::Api, known_types};
pub(crate) fn filter_apis_by_ignored_dependents(mut apis: ApiVec<FnPhase>) -> ApiVec<FnPhase> {
let (ignored_items, valid_items): (Vec<&Api<_>>, Vec<&Api<_>>) = apis
.iter()
.partition(|api| matches!(api, Api::IgnoredItem { .. }));
let mut ignored_items: HashSet<_> = ignored_items
.into_iter()
.map(|api| api.name().clone())
.collect();
let valid_types: HashSet<_> = valid_items
.into_iter()
.flat_map(|api| api.valid_types())
.collect();
let mut iterate_again = true;
while iterate_again {
iterate_again = false;
apis = apis
.into_iter()
.map(|api| {
let ignored_dependents: HashSet<_> = api
.deps()
.filter(|dep| ignored_items.contains(*dep))
.cloned()
.collect();
if !ignored_dependents.is_empty() {
iterate_again = true;
ignored_items.insert(api.name().clone());
create_ignore_item(
api,
ConvertErrorFromCpp::IgnoredDependent(ignored_dependents),
)
} else {
let mut missing_deps = api.deps().filter(|dep| {
!valid_types.contains(*dep) && !known_types().is_known_type(dep)
});
let first = missing_deps.next();
std::mem::drop(missing_deps);
if let Some(missing_dep) = first.cloned() {
create_ignore_item(
api,
ConvertErrorFromCpp::UnknownDependentType(missing_dep),
)
} else {
api
}
}
})
.collect();
}
apis
}
fn create_ignore_item(api: Api<FnPhase>, err: ConvertErrorFromCpp) -> Api<FnPhase> {
let id = api.name().get_final_ident();
log::info!("Marking as ignored: {} because {}", id.to_string(), err);
Api::IgnoredItem {
name: api.name_info().clone(),
err,
ctx: match api {
Api::Function {
analysis:
FnAnalysis {
kind: FnKind::TraitMethod { .. },
..
},
..
} => None,
Api::Function {
analysis:
FnAnalysis {
kind:
FnKind::Method {
impl_for: self_ty, ..
},
..
},
..
} => Some(ErrorContext::new_for_method(self_ty.get_final_ident(), id)),
_ => Some(ErrorContext::new_for_item(id)),
},
}
}