Skip to content

Commit

Permalink
Fix test build reliability (#3429)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr authored Jan 9, 2025
1 parent ffb9078 commit aa600c0
Show file tree
Hide file tree
Showing 33 changed files with 221 additions and 205 deletions.
38 changes: 0 additions & 38 deletions crates/libs/bindgen/src/config.rs

This file was deleted.

10 changes: 5 additions & 5 deletions crates/libs/bindgen/src/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ use super::*;
pub struct Derive(HashMap<TypeName, Vec<String>>);

impl Derive {
pub fn new(types: &TypeMap, derive: &[&str]) -> Self {
pub fn new(reader: &Reader, types: &TypeMap, derive: &[&str]) -> Self {
let mut map = HashMap::new();

for derive in derive {
let Some((name, derive)) = derive.split_once('=') else {
panic!("`--derive` must be `<type name>=Comma,Separated,List");
};

let tn = get_type_name(name);
let tn = get_type_name(reader, name);

if !types.contains_key(&tn) {
panic!("type not included: `{name}`");
Expand All @@ -33,15 +33,15 @@ impl Derive {
}
}

fn get_type_name(path: &str) -> TypeName {
fn get_type_name(reader: &Reader, path: &str) -> TypeName {
if let Some((namespace, name)) = path.rsplit_once('.') {
if let Some((namespace, types)) = reader().get_key_value(namespace) {
if let Some((namespace, types)) = reader.get_key_value(namespace) {
if let Some((name, _)) = types.get_key_value(name) {
return TypeName(namespace, name);
}
}
} else {
for (namespace, types) in reader().iter() {
for (namespace, types) in reader.iter() {
if let Some((name, _)) = types.get_key_value(path) {
return TypeName(namespace, name);
}
Expand Down
4 changes: 2 additions & 2 deletions crates/libs/bindgen/src/derive_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use super::*;
pub struct DeriveWriter(BTreeSet<String>);

impl DeriveWriter {
pub fn new(type_name: TypeName) -> Self {
pub fn new(writer: &Writer, type_name: TypeName) -> Self {
let mut derive = BTreeSet::new();
derive.extend(config().derive.get(type_name));
derive.extend(writer.config.derive.get(type_name));
Self(derive)
}

Expand Down
10 changes: 4 additions & 6 deletions crates/libs/bindgen/src/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ use super::*;
pub struct Filter(Vec<(String, bool)>);

impl Filter {
pub fn new(include: &[&str], exclude: &[&str]) -> Self {
pub fn new(reader: &Reader, include: &[&str], exclude: &[&str]) -> Self {
let mut rules = vec![];

for filter in include {
push_filter(&mut rules, filter, true);
push_filter(reader, &mut rules, filter, true);
}

for filter in exclude {
push_filter(&mut rules, filter, false)
push_filter(reader, &mut rules, filter, false)
}

debug_assert!(!rules.is_empty());
Expand Down Expand Up @@ -68,9 +68,7 @@ impl Filter {
}
}

fn push_filter(rules: &mut Vec<(String, bool)>, filter: &str, include: bool) {
let reader = reader();

fn push_filter(reader: &Reader, rules: &mut Vec<(String, bool)>, filter: &str, include: bool) {
if reader.contains_key(filter) {
rules.push((filter.to_string(), include));
return;
Expand Down
41 changes: 30 additions & 11 deletions crates/libs/bindgen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
clippy::needless_doctest_main
)]

mod config;
mod derive;
mod derive_writer;
mod filter;
Expand All @@ -25,7 +24,6 @@ mod value;
mod winmd;
mod writer;

use config::*;
use derive::*;
use derive_writer::*;
use filter::*;
Expand All @@ -49,6 +47,22 @@ use writer::*;
mod method_names;
use method_names::*;

struct Config {
pub types: TypeMap,
pub references: References,
pub output: String,
pub flat: bool,
pub no_allow: bool,
pub no_comment: bool,
pub no_core: bool,
pub no_toml: bool,
pub package: bool,
pub rustfmt: String,
pub sys: bool,
pub implement: bool,
pub derive: Derive,
}

/// The Windows code generator.
#[track_caller]
pub fn bindgen<I, S>(args: I)
Expand Down Expand Up @@ -145,13 +159,13 @@ where
panic!("at least one `--filter` required");
}

Reader::init(expand_input(&input));
let filter = Filter::new(&include, &exclude);
let references = References::new(references);
let types = TypeMap::filter(&filter, &references);
let derive = Derive::new(&types, &derive);
let reader = Reader::new(expand_input(&input));
let filter = Filter::new(reader, &include, &exclude);
let references = References::new(reader, references);
let types = TypeMap::filter(reader, &filter, &references);
let derive = Derive::new(reader, &types, &derive);

Config::init(Config {
let config = Box::leak(Box::new(Config {
types,
flat,
references,
Expand All @@ -165,11 +179,16 @@ where
output,
sys,
implement,
});
}));

let writer = Writer { namespace: "" };
let tree = TypeTree::new(&config.types);

let writer = Writer {
config,
namespace: "",
};

writer.write(TypeTree::new())
writer.write(tree)
}

enum ArgKind {
Expand Down
20 changes: 13 additions & 7 deletions crates/libs/bindgen/src/libraries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,18 @@ pub enum CallingConvention {
// Returns the libraries and their function and stack sizes used by the gnu and msvc tools to build the umbrella libs.
#[doc(hidden)]
pub fn libraries() -> BTreeMap<String, BTreeMap<String, CallingConvention>> {
Reader::init(expand_input(&["default"]));
let mut result = BTreeMap::<String, BTreeMap<String, CallingConvention>>::new();
let mut libraries = BTreeMap::new();

for types in reader().values() {
let reader = Reader::new(expand_input(&["default"]));
combine_libraries(reader, &mut libraries);
libraries
}

fn combine_libraries(
reader: &Reader,
libraries: &mut BTreeMap<String, BTreeMap<String, CallingConvention>>,
) {
for types in reader.values() {
for ty in types.values() {
let Some(ty) = cpp_fn(ty) else {
continue;
Expand All @@ -32,12 +40,12 @@ pub fn libraries() -> BTreeMap<String, BTreeMap<String, CallingConvention>> {
0
};

result
libraries
.entry(library)
.or_default()
.insert(name, CallingConvention::Stdcall(params));
} else if flags.contains(PInvokeAttributes::CallConvCdecl) {
result
libraries
.entry(library)
.or_default()
.insert(name, CallingConvention::Cdecl);
Expand All @@ -46,8 +54,6 @@ pub fn libraries() -> BTreeMap<String, BTreeMap<String, CallingConvention>> {
}
}
}

result
}

fn cpp_fn(types: &[Type]) -> Option<CppFn> {
Expand Down
6 changes: 3 additions & 3 deletions crates/libs/bindgen/src/references.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ pub struct Reference {
pub struct References(Vec<Reference>);

impl References {
pub fn new(stage: Vec<ReferenceStage>) -> Self {
pub fn new(reader: &'static Reader, stage: Vec<ReferenceStage>) -> Self {
Self(
stage
.into_iter()
.map(|stage| {
let filter = Filter::new(&[&stage.path], &[]);
let types = TypeMap::filter(&filter, &References::default());
let filter = Filter::new(reader, &[&stage.path], &[]);
let types = TypeMap::filter(reader, &filter, &References::default());

Reference {
name: stage.name,
Expand Down
2 changes: 1 addition & 1 deletion crates/libs/bindgen/src/tables/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl Attribute {
let ret_type = sig.read_usize();
std::debug_assert_eq!(ret_type, 1);
let mut args = Vec::with_capacity(fixed_arg_count);
let reader = reader();
let reader = self.reader();

for _ in 0..fixed_arg_count {
let arg = match Type::from_blob(&mut sig, None, &[]) {
Expand Down
3 changes: 1 addition & 2 deletions crates/libs/bindgen/src/tables/method_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ impl MethodDef {
let _param_count = blob.read_usize();
let mut return_type = Type::from_blob(&mut blob, None, generics);
let mut return_param = None;
let reader = reader();

let mut params = vec![];

Expand All @@ -62,7 +61,7 @@ impl MethodDef {
if !param_is_output {
if let Some(attribute) = param.find_attribute("AssociatedEnumAttribute") {
if let Some((_, Value::Str(name))) = attribute.args().first() {
let overload = reader.unwrap_full_name(namespace, name);
let overload = param.reader().unwrap_full_name(namespace, name);

ty = Type::PrimitiveOrEnum(Box::new(ty), Box::new(overload));
}
Expand Down
2 changes: 1 addition & 1 deletion crates/libs/bindgen/src/tables/type_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ impl TypeDef {
if let Some(attribute) = self.find_attribute("RAIIFreeAttribute") {
if let Some((_, Value::Str(name))) = attribute.args().first() {
if let Some(Type::CppFn(ty)) =
reader().with_full_name(self.namespace(), name).next()
self.reader().with_full_name(self.namespace(), name).next()
{
return Some(ty);
}
Expand Down
9 changes: 4 additions & 5 deletions crates/libs/bindgen/src/type_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ impl TypeMap {
}

#[track_caller]
pub fn filter(filter: &Filter, references: &References) -> Self {
pub fn filter(reader: &'static Reader, filter: &Filter, references: &References) -> Self {
let mut dependencies = Self::new();
let reader = reader();

for namespace in reader.keys() {
if filter.includes_namespace(namespace) {
Expand Down Expand Up @@ -82,19 +81,19 @@ impl TypeMap {
)
}

pub fn included(&self) -> bool {
pub fn included(&self, config: &Config) -> bool {
self.0.iter().all(|(tn, _)| {
// An empty namespace covers core types like `HRESULT`. This way we don't exclude methods
// that depend on core types that aren't explicitly included in the filter.
if tn.namespace().is_empty() {
return true;
}

if config().types.contains_key(tn) {
if config.types.contains_key(tn) {
return true;
}

if config().references.contains(*tn).is_some() {
if config.references.contains(*tn).is_some() {
return true;
}

Expand Down
4 changes: 2 additions & 2 deletions crates/libs/bindgen/src/type_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ pub struct TypeTree {
}

impl TypeTree {
pub fn new() -> Self {
pub fn new(dependencies: &TypeMap) -> Self {
let mut tree = Self::with_namespace("");

for (tn, types) in config().types.iter() {
for (tn, types) in dependencies.iter() {
let tree = tree.insert_namespace(tn.namespace());
types.iter().for_each(|ty| {
tree.types.insert(ty.clone());
Expand Down
16 changes: 8 additions & 8 deletions crates/libs/bindgen/src/types/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl Class {
let name = to_ident(type_name.name());
let mut dependencies = TypeMap::new();

if config().package {
if writer.config.package {
self.dependencies(&mut dependencies);
}

Expand All @@ -38,7 +38,7 @@ impl Class {
let mut virtual_names = MethodNames::new();

for method in interface
.get_methods()
.get_methods(writer)
.iter()
.filter_map(|method| match &method {
MethodOrName::Method(method) => Some(method),
Expand All @@ -47,7 +47,7 @@ impl Class {
{
let mut difference = TypeMap::new();

if config().package {
if writer.config.package {
difference = method.dependencies.difference(&dependencies);
}

Expand Down Expand Up @@ -253,7 +253,7 @@ impl Class {
fn bases(&self) -> Vec<Self> {
let mut bases = Vec::new();
let mut def = self.def;
let reader = reader();
let reader = def.reader();

loop {
let extends = def.extends().unwrap();
Expand Down Expand Up @@ -309,8 +309,6 @@ impl Class {
walk(base.def, &[], true, &mut set);
}

let reader = reader();

for attribute in self.def.attributes() {
let kind = match attribute.name() {
"StaticAttribute" | "ActivatableAttribute" => InterfaceKind::Static,
Expand All @@ -320,8 +318,10 @@ impl Class {

for (_, arg) in attribute.args() {
if let Value::TypeName(tn) = arg {
let Type::Interface(mut interface) =
reader.unwrap_full_name(tn.namespace(), tn.name())
let Type::Interface(mut interface) = self
.def
.reader()
.unwrap_full_name(tn.namespace(), tn.name())
else {
panic!("type not found: {tn}");
};
Expand Down
Loading

0 comments on commit aa600c0

Please sign in to comment.