Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix test build reliability #3429

Merged
merged 1 commit into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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