Skip to content

Commit

Permalink
Leaner interface representation for windows-sys crate (#2818)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr authored Jan 26, 2024
1 parent fd997b9 commit 993bfa0
Show file tree
Hide file tree
Showing 105 changed files with 1,485 additions and 5,542 deletions.
72 changes: 39 additions & 33 deletions crates/libs/bindgen/src/rust/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,55 +31,61 @@ impl Cfg {
}
}

pub fn field_cfg(row: metadata::Field) -> Cfg {
pub fn field_cfg(writer: &Writer, row: metadata::Field) -> Cfg {
let mut cfg = Cfg::default();
field_cfg_combine(row, None, &mut cfg);
field_cfg_combine(writer, row, None, &mut cfg);
cfg
}
fn field_cfg_combine(row: metadata::Field, enclosing: Option<metadata::TypeDef>, cfg: &mut Cfg) {
type_cfg_combine(&row.ty(enclosing), cfg)
fn field_cfg_combine(writer: &Writer, row: metadata::Field, enclosing: Option<metadata::TypeDef>, cfg: &mut Cfg) {
type_cfg_combine(writer, &row.ty(enclosing), cfg)
}

pub fn type_def_cfg(row: metadata::TypeDef, generics: &[metadata::Type]) -> Cfg {
pub fn type_def_cfg(writer: &Writer, row: metadata::TypeDef, generics: &[metadata::Type]) -> Cfg {
let mut cfg = Cfg::default();
type_def_cfg_combine(row, generics, &mut cfg);
type_def_cfg_combine(writer, row, generics, &mut cfg);
cfg_add_attributes(&mut cfg, row);
cfg
}
pub fn type_def_cfg_impl(def: metadata::TypeDef, generics: &[metadata::Type]) -> Cfg {
pub fn type_def_cfg_impl(writer: &Writer, def: metadata::TypeDef, generics: &[metadata::Type]) -> Cfg {
let mut cfg = Cfg { implement: true, ..Default::default() };

fn combine(def: metadata::TypeDef, generics: &[metadata::Type], cfg: &mut Cfg) {
type_def_cfg_combine(def, generics, cfg);
fn combine(writer: &Writer, def: metadata::TypeDef, generics: &[metadata::Type], cfg: &mut Cfg) {
type_def_cfg_combine(writer, def, generics, cfg);

for method in def.methods() {
signature_cfg_combine(&method.signature(generics), cfg);
signature_cfg_combine(writer, &method.signature(generics), cfg);
}
}

combine(def, generics, &mut cfg);
combine(writer, def, generics, &mut cfg);

for interface in metadata::type_interfaces(&metadata::Type::TypeDef(def, generics.to_vec())) {
if let metadata::Type::TypeDef(def, generics) = interface.ty {
combine(def, &generics, &mut cfg);
combine(writer, def, &generics, &mut cfg);
}
}

cfg_add_attributes(&mut cfg, def);
cfg
}
pub fn type_def_cfg_combine(row: metadata::TypeDef, generics: &[metadata::Type], cfg: &mut Cfg) {
pub fn type_def_cfg_combine(writer: &Writer, row: metadata::TypeDef, generics: &[metadata::Type], cfg: &mut Cfg) {
let type_kind = row.kind();

if writer.sys && type_kind == metadata::TypeKind::Interface {
return;
}

let type_name = row.type_name();

for generic in generics {
type_cfg_combine(generic, cfg);
type_cfg_combine(writer, generic, cfg);
}

if cfg.types.entry(type_name.namespace).or_default().insert(row) {
match row.kind() {
match type_kind {
metadata::TypeKind::Class => {
if let Some(default_interface) = metadata::type_def_default_interface(row) {
type_cfg_combine(&default_interface, cfg);
type_cfg_combine(writer, &default_interface, cfg);
}
}
metadata::TypeKind::Interface => {
Expand All @@ -92,30 +98,30 @@ pub fn type_def_cfg_combine(row: metadata::TypeDef, generics: &[metadata::Type],
}
}
metadata::TypeKind::Struct => {
row.fields().for_each(|field| field_cfg_combine(field, Some(row), cfg));
row.fields().for_each(|field| field_cfg_combine(writer, field, Some(row), cfg));
if !type_name.namespace.is_empty() {
for def in row.reader().get_type_def(type_name.namespace, type_name.name) {
if def != row {
type_def_cfg_combine(def, &[], cfg);
type_def_cfg_combine(writer, def, &[], cfg);
}
}
}
}
metadata::TypeKind::Delegate => signature_cfg_combine(&metadata::type_def_invoke_method(row).signature(generics), cfg),
metadata::TypeKind::Delegate => signature_cfg_combine(writer, &metadata::type_def_invoke_method(row).signature(generics), cfg),
_ => {}
}
}
}

pub fn signature_cfg(method: metadata::MethodDef) -> Cfg {
pub fn signature_cfg(writer: &Writer, method: metadata::MethodDef) -> Cfg {
let mut cfg = Cfg::default();
signature_cfg_combine(&method.signature(&[]), &mut cfg);
signature_cfg_combine(writer, &method.signature(&[]), &mut cfg);
cfg_add_attributes(&mut cfg, method);
cfg
}
fn signature_cfg_combine(signature: &metadata::MethodDefSig, cfg: &mut Cfg) {
type_cfg_combine(&signature.return_type, cfg);
signature.params.iter().for_each(|param| type_cfg_combine(param, cfg));
fn signature_cfg_combine(writer: &Writer, signature: &metadata::MethodDefSig, cfg: &mut Cfg) {
type_cfg_combine(writer, &signature.return_type, cfg);
signature.params.iter().for_each(|param| type_cfg_combine(writer, param, cfg));
}

fn cfg_add_attributes<R: AsRow + Into<metadata::HasAttribute>>(cfg: &mut Cfg, row: R) {
Expand Down Expand Up @@ -144,20 +150,20 @@ fn cfg_add_attributes<R: AsRow + Into<metadata::HasAttribute>>(cfg: &mut Cfg, ro
}
}

pub fn type_cfg(ty: &metadata::Type) -> Cfg {
pub fn type_cfg(writer: &Writer, ty: &metadata::Type) -> Cfg {
let mut cfg = Cfg::default();
type_cfg_combine(ty, &mut cfg);
type_cfg_combine(writer, ty, &mut cfg);
cfg
}

fn type_cfg_combine(ty: &metadata::Type, cfg: &mut Cfg) {
fn type_cfg_combine(writer: &Writer, ty: &metadata::Type, cfg: &mut Cfg) {
match ty {
metadata::Type::TypeDef(row, generics) => type_def_cfg_combine(*row, generics, cfg),
metadata::Type::Win32Array(ty, _) => type_cfg_combine(ty, cfg),
metadata::Type::ConstPtr(ty, _) => type_cfg_combine(ty, cfg),
metadata::Type::MutPtr(ty, _) => type_cfg_combine(ty, cfg),
metadata::Type::WinrtArray(ty) => type_cfg_combine(ty, cfg),
metadata::Type::WinrtArrayRef(ty) => type_cfg_combine(ty, cfg),
metadata::Type::TypeDef(row, generics) => type_def_cfg_combine(writer, *row, generics, cfg),
metadata::Type::Win32Array(ty, _) => type_cfg_combine(writer, ty, cfg),
metadata::Type::ConstPtr(ty, _) => type_cfg_combine(writer, ty, cfg),
metadata::Type::MutPtr(ty, _) => type_cfg_combine(writer, ty, cfg),
metadata::Type::WinrtArray(ty) => type_cfg_combine(writer, ty, cfg),
metadata::Type::WinrtArrayRef(ty) => type_cfg_combine(writer, ty, cfg),
ty => _ = cfg.core_types.insert(ty.clone()),
}
}
8 changes: 4 additions & 4 deletions crates/libs/bindgen/src/rust/classes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fn gen_class(writer: &Writer, def: metadata::TypeDef) -> TokenStream {
let mut methods = quote! {};
let mut method_names = MethodNames::new();

let cfg = cfg::type_def_cfg(def, &[]);
let cfg = cfg::type_def_cfg(writer, def, &[]);
let doc = writer.cfg_doc(&cfg);
let features = writer.cfg_features(&cfg);

Expand All @@ -45,7 +45,7 @@ fn gen_class(writer: &Writer, def: metadata::TypeDef) -> TokenStream {
if let metadata::Type::TypeDef(def, generics) = &interface.ty {
if def.methods().next().is_some() {
let interface_type = writer.type_name(&interface.ty);
let features = writer.cfg_features(&cfg::type_def_cfg(*def, generics));
let features = writer.cfg_features(&cfg::type_def_cfg(writer, *def, generics));

return Some(quote! {
#[doc(hidden)]
Expand Down Expand Up @@ -148,14 +148,14 @@ fn gen_conversions(writer: &Writer, def: metadata::TypeDef, ident: &TokenStream,

let into = writer.type_name(&interface.ty);
write!(&mut hierarchy, ", {into}").unwrap();
hierarchy_cfg = hierarchy_cfg.union(&cfg::type_cfg(&interface.ty));
hierarchy_cfg = hierarchy_cfg.union(&cfg::type_cfg(writer, &interface.ty));
hierarchy_added = true;
}

for def in metadata::type_def_bases(def) {
let into = writer.type_def_name(def, &[]);
write!(&mut hierarchy, ", {into}").unwrap();
hierarchy_cfg = hierarchy_cfg.union(&cfg::type_def_cfg(def, &[]));
hierarchy_cfg = hierarchy_cfg.union(&cfg::type_def_cfg(writer, def, &[]));
hierarchy_added = true;
}

Expand Down
2 changes: 1 addition & 1 deletion crates/libs/bindgen/src/rust/com_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub fn writer(writer: &Writer, def: metadata::TypeDef, kind: metadata::Interface
let vname = virtual_names.add(method);
let generics = writer.constraint_generics(&signature.params);
let where_clause = writer.where_clause(&signature.params);
let mut cfg = cfg::signature_cfg(method);
let mut cfg = cfg::signature_cfg(writer, method);
cfg.add_feature(def.namespace());
let doc = writer.cfg_method_doc(&cfg);
let features = writer.cfg_features(&cfg);
Expand Down
2 changes: 1 addition & 1 deletion crates/libs/bindgen/src/rust/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use metadata::HasAttributes;
pub fn writer(writer: &Writer, def: metadata::Field) -> TokenStream {
let name = to_ident(def.name());
let ty = def.ty(None).to_const_type();
let cfg = cfg::field_cfg(def);
let cfg = cfg::field_cfg(writer, def);
let doc = writer.cfg_doc(&cfg);
let features = writer.cfg_features(&cfg);

Expand Down
4 changes: 2 additions & 2 deletions crates/libs/bindgen/src/rust/delegates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn gen_callback(writer: &Writer, def: metadata::TypeDef) -> TokenStream {
let signature = metadata::method_def_signature(def.namespace(), method, &[]);

let return_type = writer.return_sig(&signature);
let cfg = cfg::type_def_cfg(def, &[]);
let cfg = cfg::type_def_cfg(writer, def, &[]);
let doc = writer.cfg_doc(&cfg);
let features = writer.cfg_features(&cfg);

Expand Down Expand Up @@ -60,7 +60,7 @@ fn gen_win_delegate(writer: &Writer, def: metadata::TypeDef) -> TokenStream {
let signature = metadata::method_def_signature(def.namespace(), method, generics);

let fn_constraint = gen_fn_constraint(writer, def, &signature);
let cfg = cfg::type_def_cfg(def, generics);
let cfg = cfg::type_def_cfg(writer, def, generics);
let doc = writer.cfg_doc(&cfg);
let features = writer.cfg_features(&cfg);

Expand Down
2 changes: 1 addition & 1 deletion crates/libs/bindgen/src/rust/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub fn writer(writer: &Writer, def: metadata::TypeDef) -> TokenStream {
// TODO: unscoped enums should be removed from metadata
let is_scoped = def.flags().contains(metadata::TypeAttributes::WindowsRuntime) || def.has_attribute("ScopedEnumAttribute");

let cfg = cfg::type_def_cfg(def, &[]);
let cfg = cfg::type_def_cfg(writer, def, &[]);
let doc = writer.cfg_doc(&cfg);
let features = writer.cfg_features(&cfg);

Expand Down
4 changes: 2 additions & 2 deletions crates/libs/bindgen/src/rust/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub fn writer(writer: &Writer, namespace: &str, def: metadata::MethodDef) -> Tok

fn gen_sys_function(writer: &Writer, namespace: &str, def: metadata::MethodDef) -> TokenStream {
let signature = metadata::method_def_signature(namespace, def, &[]);
let cfg = cfg::signature_cfg(def);
let cfg = cfg::signature_cfg(writer, def);
let mut tokens = writer.cfg_features(&cfg);
tokens.combine(&gen_link(writer, namespace, &signature, &cfg));
tokens
Expand All @@ -35,7 +35,7 @@ fn gen_win_function(writer: &Writer, namespace: &str, def: metadata::MethodDef)
let generics = writer.constraint_generics(&signature.params);
let where_clause = writer.where_clause(&signature.params);
let abi_return_type = writer.return_sig(&signature);
let cfg = cfg::signature_cfg(def);
let cfg = cfg::signature_cfg(writer, def);
let doc = writer.cfg_doc(&cfg);
let features = writer.cfg_features(&cfg);
let link = gen_link(writer, namespace, &signature, &cfg);
Expand Down
2 changes: 1 addition & 1 deletion crates/libs/bindgen/src/rust/implements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub fn writer(writer: &Writer, def: metadata::TypeDef) -> TokenStream {
let constraints = writer.generic_constraints(generics);
let generic_names = writer.generic_names(generics);
let named_phantoms = writer.generic_named_phantoms(generics);
let cfg = cfg::type_def_cfg_impl(def, generics);
let cfg = cfg::type_def_cfg_impl(writer, def, generics);
let doc = writer.cfg_doc(&cfg);
let features = writer.cfg_features(&cfg);
let mut requires = quote! {};
Expand Down
25 changes: 6 additions & 19 deletions crates/libs/bindgen/src/rust/interfaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,9 @@ use super::*;

pub fn writer(writer: &Writer, def: metadata::TypeDef) -> TokenStream {
if writer.sys {
gen_sys_interface(def)
} else {
gen_win_interface(writer, def)
}
}

fn gen_sys_interface(def: metadata::TypeDef) -> TokenStream {
let name = def.name();
let ident = to_ident(name);

if metadata::type_def_is_exclusive(def) {
quote! {}
} else {
quote! {
pub type #ident = *mut ::core::ffi::c_void;
}
gen_win_interface(writer, def)
}
}

Expand All @@ -28,7 +15,7 @@ fn gen_win_interface(writer: &Writer, def: metadata::TypeDef) -> TokenStream {
let is_exclusive = metadata::type_def_is_exclusive(def);
let phantoms = writer.generic_phantoms(generics);
let constraints = writer.generic_constraints(generics);
let cfg = cfg::type_def_cfg(def, &[]);
let cfg = cfg::type_def_cfg(writer, def, &[]);
let doc = writer.cfg_doc(&cfg);
let features = writer.cfg_features(&cfg);
let interfaces = metadata::type_interfaces(&metadata::Type::TypeDef(def, generics.to_vec()));
Expand Down Expand Up @@ -108,7 +95,7 @@ fn gen_win_interface(writer: &Writer, def: metadata::TypeDef) -> TokenStream {
let into = writer.type_name(ty);

write!(&mut hierarchy, ", {into}").unwrap();
hierarchy_cfg = hierarchy_cfg.union(&cfg::type_cfg(ty));
hierarchy_cfg = hierarchy_cfg.union(&cfg::type_cfg(writer, ty));
}

hierarchy.push_str(");");
Expand All @@ -117,7 +104,7 @@ fn gen_win_interface(writer: &Writer, def: metadata::TypeDef) -> TokenStream {
} else {
for ty in &vtables {
let into = writer.type_name(ty);
let cfg = writer.cfg_features(&cfg.union(&cfg::type_cfg(ty)));
let cfg = writer.cfg_features(&cfg.union(&cfg::type_cfg(writer, ty)));
tokens.combine(&quote! {
#cfg
impl<#constraints> ::windows_core::CanInto<#into> for #ident {}
Expand All @@ -134,7 +121,7 @@ fn gen_win_interface(writer: &Writer, def: metadata::TypeDef) -> TokenStream {
let into = writer.type_name(&interface.ty);

write!(&mut hierarchy, ", {into}").unwrap();
hierarchy_cfg = hierarchy_cfg.union(&cfg::type_cfg(&interface.ty));
hierarchy_cfg = hierarchy_cfg.union(&cfg::type_cfg(writer, &interface.ty));
}

hierarchy.push_str(");");
Expand All @@ -143,7 +130,7 @@ fn gen_win_interface(writer: &Writer, def: metadata::TypeDef) -> TokenStream {
} else {
for interface in &interfaces {
let into = writer.type_name(&interface.ty);
let cfg = writer.cfg_features(&cfg.union(&cfg::type_cfg(&interface.ty)));
let cfg = writer.cfg_features(&cfg.union(&cfg::type_cfg(writer, &interface.ty)));
tokens.combine(&quote! {
#cfg
impl<#constraints> ::windows_core::CanInto<#into> for #ident { const QUERY: bool = true; }
Expand Down
6 changes: 3 additions & 3 deletions crates/libs/bindgen/src/rust/iterators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ pub fn writer(writer: &Writer, def: metadata::TypeDef, generics: &[metadata::Typ
metadata::TypeName::IVectorView => {
let item = writer.type_name(&interface_generics[0]);
let mut cfg = cfg.clone();
cfg::type_def_cfg_combine(*interface, interface_generics, &mut cfg);
cfg::type_def_cfg_combine(writer, *interface, interface_generics, &mut cfg);
let features = writer.cfg_features(&cfg);

return quote! {
Expand All @@ -180,7 +180,7 @@ pub fn writer(writer: &Writer, def: metadata::TypeDef, generics: &[metadata::Typ
metadata::TypeName::IVector => {
let item = writer.type_name(&interface_generics[0]);
let mut cfg = cfg.clone();
cfg::type_def_cfg_combine(*interface, interface_generics, &mut cfg);
cfg::type_def_cfg_combine(writer, *interface, interface_generics, &mut cfg);
let features = writer.cfg_features(&cfg);

return quote! {
Expand Down Expand Up @@ -217,7 +217,7 @@ pub fn writer(writer: &Writer, def: metadata::TypeDef, generics: &[metadata::Typ
Some((interface, interface_generics)) => {
let item = writer.type_name(&interface_generics[0]);
let mut cfg = cfg.clone();
cfg::type_def_cfg_combine(interface, &interface_generics, &mut cfg);
cfg::type_def_cfg_combine(writer, interface, &interface_generics, &mut cfg);
let features = writer.cfg_features(&cfg);

quote! {
Expand Down
2 changes: 1 addition & 1 deletion crates/libs/bindgen/src/rust/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ fn namespace(writer: &Writer, tree: &Tree) -> String {
let ident = to_ident(name);
let value = writer.guid(&guid);
let guid = writer.type_name(&metadata::Type::GUID);
let cfg = cfg::type_def_cfg(def, &[]);
let cfg = cfg::type_def_cfg(writer, def, &[]);
let doc = writer.cfg_doc(&cfg);
let constant = quote! {
#doc
Expand Down
16 changes: 2 additions & 14 deletions crates/libs/bindgen/src/rust/standalone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,22 +58,10 @@ pub fn standalone_imp(writer: &Writer) -> String {
let kind = def.kind();
match kind {
metadata::TypeKind::Class => {
let name = def.name();
if writer.sys {
let ident = to_ident(name);
sorted.insert(name, quote! { pub type #ident = *mut ::core::ffi::c_void; });
} else {
sorted.insert(name, classes::writer(writer, def));
}
sorted.insert(def.name(), classes::writer(writer, def));
}
metadata::TypeKind::Interface => {
let name = def.name();
if writer.sys {
let ident = to_ident(name);
sorted.insert(name, quote! { pub type #ident = *mut ::core::ffi::c_void; });
} else {
sorted.insert(name, interfaces::writer(writer, def));
}
sorted.insert(def.name(), interfaces::writer(writer, def));
}
metadata::TypeKind::Enum => {
sorted.insert(def.name(), enums::writer(writer, def));
Expand Down
2 changes: 1 addition & 1 deletion crates/libs/bindgen/src/rust/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ fn gen_struct_with_name(writer: &Writer, def: metadata::TypeDef, struct_name: &s
}

let flags = def.flags();
let cfg = cfg.union(&cfg::type_def_cfg(def, &[]));
let cfg = cfg.union(&cfg::type_def_cfg(writer, def, &[]));

let repr = if let Some(layout) = def.class_layout() {
let packing = Literal::usize_unsuffixed(layout.packing_size());
Expand Down
Loading

0 comments on commit 993bfa0

Please sign in to comment.