diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
commit | 9918693037dce8aa4bb6f08741b6812923486c18 (patch) | |
tree | 21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /vendor/windows-bindgen/src | |
parent | Releasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff) | |
download | rustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip |
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/windows-bindgen/src')
35 files changed, 1605 insertions, 1626 deletions
diff --git a/vendor/windows-bindgen/src/error.rs b/vendor/windows-bindgen/src/error.rs index 6d783d084..16122bbf6 100644 --- a/vendor/windows-bindgen/src/error.rs +++ b/vendor/windows-bindgen/src/error.rs @@ -44,12 +44,4 @@ impl Error { pub(crate) fn with_path(self, path: &str) -> Self { Self { path: path.to_string(), ..self } } - - // pub(crate) fn with_span(self, span: proc_macro2::Span) -> Self { - // let start = span.start(); - // Self { - // span: Some((start.line, start.column)), - // ..self - // } - // } } diff --git a/vendor/windows-bindgen/src/lib.rs b/vendor/windows-bindgen/src/lib.rs index c9eec0e95..5a8b5ef1f 100644 --- a/vendor/windows-bindgen/src/lib.rs +++ b/vendor/windows-bindgen/src/lib.rs @@ -104,15 +104,14 @@ where let output = canonicalize(output)?; let input = read_input(&input)?; - let reader = metadata::Reader::new(&input); - let filter = metadata::Filter::new(&include, &exclude); + let reader = metadata::Reader::filter(input, &include, &exclude); - winmd::verify(&reader, &filter)?; + winmd::verify(reader)?; match extension(&output) { - "rdl" => rdl::from_reader(&reader, &filter, config, &output)?, - "winmd" => winmd::from_reader(&reader, &filter, config, &output)?, - "rs" => rust::from_reader(&reader, &filter, config, &output)?, + "rdl" => rdl::from_reader(reader, config, &output)?, + "winmd" => winmd::from_reader(reader, config, &output)?, + "rs" => rust::from_reader(reader, config, &output)?, _ => return Err(Error::new("output extension must be one of winmd/rdl/rs")), } @@ -258,11 +257,3 @@ fn extension(path: &str) -> &str { fn directory(path: &str) -> &str { path.rsplit_once(&['/', '\\']).map_or("", |(directory, _)| directory) } - -fn trim_tick(name: &str) -> &str { - if name.as_bytes().iter().rev().nth(1) == Some(&b'`') { - &name[..name.len() - 2] - } else { - name - } -} diff --git a/vendor/windows-bindgen/src/metadata.rs b/vendor/windows-bindgen/src/metadata.rs new file mode 100644 index 000000000..b678c4b32 --- /dev/null +++ b/vendor/windows-bindgen/src/metadata.rs @@ -0,0 +1,824 @@ +use std::collections::*; +pub use windows_metadata::*; + +#[derive(Clone)] +pub struct Interface { + pub ty: Type, + pub kind: InterfaceKind, +} + +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum InterfaceKind { + None, + Default, + Overridable, + Static, + Base, +} + +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct QueryPosition { + pub object: usize, + pub guid: usize, +} + +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum SignatureKind { + Query(QueryPosition), + QueryOptional(QueryPosition), + ResultValue, + ResultVoid, + ReturnStruct, + ReturnValue, + ReturnVoid, + PreserveSig, +} + +#[derive(Copy, Clone, Eq, PartialEq)] +pub enum SignatureParamKind { + ArrayFixed(usize), + ArrayRelativeLen(usize), + ArrayRelativeByteLen(usize), + ArrayRelativePtr(usize), + TryInto, + IntoParam, + OptionalPointer, + ValueType, + Blittable, + Other, +} + +pub struct Signature { + pub def: MethodDef, + pub params: Vec<SignatureParam>, + pub return_type: Type, + pub call_flags: MethodCallAttributes, +} + +pub struct SignatureParam { + pub def: Param, + pub ty: Type, + pub kind: SignatureParamKind, +} + +#[derive(PartialEq, Eq, Debug)] +pub enum AsyncKind { + None, + Action, + ActionWithProgress, + Operation, + OperationWithProgress, +} + +#[derive(Clone, PartialEq, Eq, Default)] +pub struct Guid(pub u32, pub u16, pub u16, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8); + +impl Guid { + pub fn from_args(args: &[(&str, Value)]) -> Self { + fn unwrap_u32(value: &Value) -> u32 { + match value { + Value::U32(value) => *value, + rest => unimplemented!("{rest:?}"), + } + } + fn unwrap_u16(value: &Value) -> u16 { + match value { + Value::U16(value) => *value, + rest => unimplemented!("{rest:?}"), + } + } + fn unwrap_u8(value: &Value) -> u8 { + match value { + Value::U8(value) => *value, + rest => unimplemented!("{rest:?}"), + } + } + Self(unwrap_u32(&args[0].1), unwrap_u16(&args[1].1), unwrap_u16(&args[2].1), unwrap_u8(&args[3].1), unwrap_u8(&args[4].1), unwrap_u8(&args[5].1), unwrap_u8(&args[6].1), unwrap_u8(&args[7].1), unwrap_u8(&args[8].1), unwrap_u8(&args[9].1), unwrap_u8(&args[10].1)) + } + + pub fn from_string_args(args: &[&str]) -> Self { + Self(args[0].parse().unwrap(), args[1].parse().unwrap(), args[2].parse().unwrap(), args[3].parse().unwrap(), args[4].parse().unwrap(), args[5].parse().unwrap(), args[6].parse().unwrap(), args[7].parse().unwrap(), args[8].parse().unwrap(), args[9].parse().unwrap(), args[10].parse().unwrap()) + } +} + +impl std::fmt::Debug for Guid { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:08x?}-{:04x?}-{:04x?}-{:02x?}{:02x?}-{:02x?}{:02x?}{:02x?}{:02x?}{:02x?}{:02x?}", self.0, self.1, self.2, self.3, self.4, self.5, self.6, self.7, self.8, self.9, self.10) + } +} + +impl SignatureParamKind { + fn is_array(&self) -> bool { + matches!(self, Self::ArrayFixed(_) | Self::ArrayRelativeLen(_) | Self::ArrayRelativeByteLen(_) | Self::ArrayRelativePtr(_)) + } +} + +impl SignatureParam { + pub fn is_convertible(&self) -> bool { + !self.def.flags().contains(ParamAttributes::Out) && !self.ty.is_winrt_array() && !self.ty.is_pointer() && !self.kind.is_array() && (type_is_borrowed(&self.ty) || type_is_non_exclusive_winrt_interface(&self.ty) || type_is_trivially_convertible(&self.ty)) + } + + fn is_retval(&self) -> bool { + // The Win32 metadata uses `RetValAttribute` to call out retval methods but it is employed + // very sparingly, so this heuristic is used to apply the transformation more uniformly. + if self.def.has_attribute("RetValAttribute") { + return true; + } + if !self.ty.is_pointer() { + return false; + } + if self.ty.is_void() { + return false; + } + let flags = self.def.flags(); + if flags.contains(ParamAttributes::In) || !flags.contains(ParamAttributes::Out) || flags.contains(ParamAttributes::Optional) || self.kind.is_array() { + return false; + } + if param_kind(self.def).is_array() { + return false; + } + // If it's bigger than 128 bits, best to pass as a reference. + if self.ty.deref().size() > 16 { + return false; + } + // Win32 callbacks are defined as `Option<T>` so we don't include them here to avoid + // producing the `Result<Option<T>>` anti-pattern. + match self.ty.deref() { + Type::TypeDef(def, _) => !type_def_is_callback(def), + _ => true, + } + } +} + +impl Signature { + pub fn kind(&self) -> SignatureKind { + if self.def.has_attribute("CanReturnMultipleSuccessValuesAttribute") { + return SignatureKind::PreserveSig; + } + match &self.return_type { + Type::Void if self.is_retval() => SignatureKind::ReturnValue, + Type::Void => SignatureKind::ReturnVoid, + Type::HRESULT => { + if self.params.len() >= 2 { + if let Some((guid, object)) = signature_param_is_query(&self.params) { + if self.params[object].def.flags().contains(ParamAttributes::Optional) { + return SignatureKind::QueryOptional(QueryPosition { object, guid }); + } else { + return SignatureKind::Query(QueryPosition { object, guid }); + } + } + } + if self.is_retval() { + SignatureKind::ResultValue + } else { + SignatureKind::ResultVoid + } + } + Type::TypeDef(def, _) if def.type_name() == TypeName::WIN32_ERROR => SignatureKind::ResultVoid, + Type::TypeDef(def, _) if def.type_name() == TypeName::BOOL && method_def_last_error(self.def) => SignatureKind::ResultVoid, + _ if type_is_struct(&self.return_type) => SignatureKind::ReturnStruct, + _ => SignatureKind::PreserveSig, + } + } + + fn is_retval(&self) -> bool { + self.params.last().map_or(false, |param| param.is_retval()) + && self.params[..self.params.len() - 1].iter().all(|param| { + let flags = param.def.flags(); + !flags.contains(ParamAttributes::Out) + }) + } +} + +pub fn type_def_invoke_method(row: TypeDef) -> MethodDef { + row.methods().find(|method| method.name() == "Invoke").expect("`Invoke` method not found") +} + +pub fn type_def_generics(def: TypeDef) -> Vec<Type> { + def.generics().map(Type::GenericParam).collect() +} + +// TODO: namespace should not be required - it's a hack to accomodate Win32 metadata +// TODO: this is very Rust-specific and Win32-metadata specific with all of its translation. Replace with literal signature parser that just returns slice of types. +pub fn method_def_signature(namespace: &str, row: MethodDef, generics: &[Type]) -> Signature { + let reader = row.reader(); + let mut blob = row.blob(4); + let call_flags = MethodCallAttributes(blob.read_usize() as u8); + let _param_count = blob.read_usize(); + let mut return_type = reader.type_from_blob(&mut blob, None, generics); + + let mut params: Vec<SignatureParam> = row + .params() + .filter_map(|param| { + let param_is_const = param.has_attribute("ConstAttribute"); + if param.sequence() == 0 { + if param_is_const { + return_type = return_type.clone().to_const_type(); + } + None + } else { + let is_output = param.flags().contains(ParamAttributes::Out); + let mut ty = reader.type_from_blob(&mut blob, None, generics); + + if let Some(name) = param_or_enum(param) { + let def = reader.get_type_def(namespace, &name).next().expect("Enum not found"); + ty = Type::PrimitiveOrEnum(Box::new(ty), Box::new(Type::TypeDef(def, Vec::new()))); + } + + if param_is_const || !is_output { + ty = ty.to_const_type(); + } + if !is_output { + ty = ty.to_const_ptr(); + } + let kind = param_kind(param); + Some(SignatureParam { def: param, ty, kind }) + } + }) + .collect(); + + for position in 0..params.len() { + // Point len params back to the corresponding ptr params. + match params[position].kind { + SignatureParamKind::ArrayRelativeLen(relative) | SignatureParamKind::ArrayRelativeByteLen(relative) => { + // The len params must be input only. + if !params[relative].def.flags().contains(ParamAttributes::Out) && position != relative && !params[relative].ty.is_pointer() { + params[relative].kind = SignatureParamKind::ArrayRelativePtr(position); + } else { + params[position].kind = SignatureParamKind::Other; + } + } + SignatureParamKind::ArrayFixed(_) => { + if params[position].def.has_attribute("FreeWithAttribute") { + params[position].kind = SignatureParamKind::Other; + } + } + _ => {} + } + } + + let mut sets = BTreeMap::<usize, Vec<usize>>::new(); + + // Finds sets of ptr params pointing at the same len param. + for (position, param) in params.iter().enumerate() { + match param.kind { + SignatureParamKind::ArrayRelativeLen(relative) | SignatureParamKind::ArrayRelativeByteLen(relative) => { + sets.entry(relative).or_default().push(position); + } + _ => {} + } + } + + // Remove all sets. + for (len, ptrs) in sets { + if ptrs.len() > 1 { + params[len].kind = SignatureParamKind::Other; + for ptr in ptrs { + params[ptr].kind = SignatureParamKind::Other; + } + } + } + + // Remove any byte arrays that aren't byte-sized types. + for position in 0..params.len() { + if let SignatureParamKind::ArrayRelativeByteLen(relative) = params[position].kind { + if !params[position].ty.is_byte_size() { + params[position].kind = SignatureParamKind::Other; + params[relative].kind = SignatureParamKind::Other; + } + } + } + + for param in &mut params { + if param.kind == SignatureParamKind::Other { + if param.is_convertible() { + if type_is_non_exclusive_winrt_interface(¶m.ty) { + param.kind = SignatureParamKind::TryInto; + } else { + param.kind = SignatureParamKind::IntoParam; + } + } else { + let flags = param.def.flags(); + if param.ty.is_pointer() && (flags.contains(ParamAttributes::Optional) || param.def.has_attribute("ReservedAttribute")) { + param.kind = SignatureParamKind::OptionalPointer; + } else if type_is_primitive(¶m.ty) && (!param.ty.is_pointer() || type_is_blittable(¶m.ty.deref())) { + param.kind = SignatureParamKind::ValueType; + } else if type_is_blittable(¶m.ty) { + param.kind = SignatureParamKind::Blittable; + } + } + } + } + + Signature { def: row, params, return_type, call_flags } +} + +fn param_kind(row: Param) -> SignatureParamKind { + for attribute in row.attributes() { + match attribute.name() { + "NativeArrayInfoAttribute" => { + for (_, value) in attribute.args() { + match value { + Value::I16(value) => return SignatureParamKind::ArrayRelativeLen(value as usize), + Value::I32(value) => return SignatureParamKind::ArrayFixed(value as usize), + _ => {} + } + } + } + "MemorySizeAttribute" => { + for (_, value) in attribute.args() { + if let Value::I16(value) = value { + return SignatureParamKind::ArrayRelativeByteLen(value as usize); + } + } + } + _ => {} + } + } + SignatureParamKind::Other +} + +// TODO: this is a terribly broken Win32 metadata attribute - need to get rid of it. +fn param_or_enum(row: Param) -> Option<String> { + row.find_attribute("AssociatedEnumAttribute").and_then(|attribute| { + for (_, arg) in attribute.args() { + if let Value::String(name) = arg { + return Some(name); + } + } + None + }) +} + +fn signature_param_is_query(params: &[SignatureParam]) -> Option<(usize, usize)> { + if let Some(guid) = params.iter().rposition(|param| param.ty == Type::ConstPtr(Box::new(Type::GUID), 1) && !param.def.flags().contains(ParamAttributes::Out)) { + if let Some(object) = params.iter().rposition(|param| param.ty == Type::MutPtr(Box::new(Type::Void), 2) && param.def.has_attribute("ComOutPtrAttribute")) { + return Some((guid, object)); + } + } + + None +} + +fn method_def_last_error(row: MethodDef) -> bool { + if let Some(map) = row.impl_map() { + map.flags().contains(PInvokeAttributes::SupportsLastError) + } else { + false + } +} + +pub fn type_is_borrowed(ty: &Type) -> bool { + match ty { + Type::TypeDef(row, _) => !type_def_is_blittable(*row), + Type::BSTR | Type::PCSTR | Type::PCWSTR | Type::IInspectable | Type::IUnknown | Type::GenericParam(_) => true, + _ => false, + } +} + +pub fn type_is_non_exclusive_winrt_interface(ty: &Type) -> bool { + match ty { + Type::TypeDef(row, _) => { + let flags = row.flags(); + if !flags.contains(TypeAttributes::WindowsRuntime) { + false + } else { + match row.kind() { + TypeKind::Interface => !type_def_is_exclusive(*row), + TypeKind::Class => row.has_attribute("ComposableAttribute"), + _ => false, + } + } + } + _ => false, + } +} + +fn type_is_trivially_convertible(ty: &Type) -> bool { + match ty { + Type::TypeDef(row, _) => match row.kind() { + TypeKind::Struct => type_def_is_handle(*row), + _ => false, + }, + _ => false, + } +} + +fn type_def_is_callback(row: TypeDef) -> bool { + !row.flags().contains(TypeAttributes::WindowsRuntime) && row.kind() == TypeKind::Delegate +} + +pub fn type_has_callback(ty: &Type) -> bool { + match ty { + Type::TypeDef(row, _) => type_def_has_callback(*row), + Type::Win32Array(ty, _) => type_has_callback(ty), + _ => false, + } +} + +pub fn type_def_has_callback(row: TypeDef) -> bool { + if type_def_is_callback(row) { + return true; + } + if row.kind() != TypeKind::Struct { + return false; + } + fn check(row: TypeDef) -> bool { + if row.fields().any(|field| type_has_callback(&field.ty(Some(row)))) { + return true; + } + false + } + let type_name = row.type_name(); + if type_name.namespace.is_empty() { + check(row) + } else { + for row in row.reader().get_type_def(type_name.namespace, type_name.name) { + if check(row) { + return true; + } + } + false + } +} + +pub fn type_interfaces(ty: &Type) -> Vec<Interface> { + // TODO: collect into btree map and then return collected vec + // This will both sort the results and should make finding dupes faster + fn walk(result: &mut Vec<Interface>, parent: &Type, is_base: bool) { + if let Type::TypeDef(row, generics) = parent { + for mut child in type_def_interfaces(*row, generics) { + child.kind = if !is_base && child.kind == InterfaceKind::Default { + InterfaceKind::Default + } else if child.kind == InterfaceKind::Overridable { + continue; + } else if is_base { + InterfaceKind::Base + } else { + InterfaceKind::None + }; + let mut found = false; + for existing in result.iter_mut() { + if existing.ty == child.ty { + found = true; + if child.kind == InterfaceKind::Default { + existing.kind = child.kind + } + } + } + if !found { + walk(result, &child.ty, is_base); + result.push(child); + } + } + } + } + let mut result = Vec::new(); + walk(&mut result, ty, false); + if let Type::TypeDef(row, _) = ty { + if row.kind() == TypeKind::Class { + for base in type_def_bases(*row) { + walk(&mut result, &Type::TypeDef(base, Vec::new()), true); + } + for attribute in row.attributes() { + match attribute.name() { + "StaticAttribute" | "ActivatableAttribute" => { + for (_, arg) in attribute.args() { + if let Value::TypeName(type_name) = arg { + let def = row.reader().get_type_def(type_name.namespace, type_name.name).next().expect("Type not found"); + result.push(Interface { ty: Type::TypeDef(def, Vec::new()), kind: InterfaceKind::Static }); + break; + } + } + } + _ => {} + } + } + } + } + result.sort_by(|a, b| type_name(&a.ty).cmp(type_name(&b.ty))); + result +} + +fn type_name(ty: &Type) -> &str { + match ty { + Type::TypeDef(row, _) => row.name(), + _ => "", + } +} + +pub fn field_is_blittable(row: Field, enclosing: TypeDef) -> bool { + type_is_blittable(&row.ty(Some(enclosing))) +} + +pub fn field_is_copyable(row: Field, enclosing: TypeDef) -> bool { + type_is_copyable(&row.ty(Some(enclosing))) +} + +pub fn type_is_blittable(ty: &Type) -> bool { + match ty { + Type::TypeDef(row, _) => type_def_is_blittable(*row), + Type::String | Type::BSTR | Type::IInspectable | Type::IUnknown | Type::GenericParam(_) => false, + Type::Win32Array(kind, _) => type_is_blittable(kind), + Type::WinrtArray(kind) => type_is_blittable(kind), + _ => true, + } +} + +fn type_is_copyable(ty: &Type) -> bool { + match ty { + Type::TypeDef(row, _) => type_def_is_copyable(*row), + Type::String | Type::BSTR | Type::IInspectable | Type::IUnknown | Type::GenericParam(_) => false, + Type::Win32Array(kind, _) => type_is_copyable(kind), + Type::WinrtArray(kind) => type_is_copyable(kind), + _ => true, + } +} + +pub fn type_def_is_blittable(row: TypeDef) -> bool { + match row.kind() { + TypeKind::Struct => { + if row.flags().contains(TypeAttributes::WindowsRuntime) { + row.fields().all(|field| field_is_blittable(field, row)) + } else { + true + } + } + TypeKind::Enum => true, + TypeKind::Delegate => !row.flags().contains(TypeAttributes::WindowsRuntime), + _ => false, + } +} + +pub fn type_def_is_copyable(row: TypeDef) -> bool { + match row.kind() { + TypeKind::Struct => row.fields().all(|field| field_is_copyable(field, row)), + TypeKind::Enum => true, + TypeKind::Delegate => !row.flags().contains(TypeAttributes::WindowsRuntime), + _ => false, + } +} + +pub fn type_def_is_exclusive(row: TypeDef) -> bool { + row.has_attribute("ExclusiveToAttribute") +} + +pub fn type_is_struct(ty: &Type) -> bool { + // This check is used to detect virtual functions that return C-style PODs that affect how the stack is packed for x86. + // It could be defined as a struct with more than one field but that check is complicated as it would have to detect + // nested structs. Fortunately, this is rare enough that this check is sufficient. + match ty { + Type::TypeDef(row, _) => row.kind() == TypeKind::Struct && !type_def_is_handle(*row), + Type::GUID => true, + _ => false, + } +} + +fn type_def_is_primitive(row: TypeDef) -> bool { + match row.kind() { + TypeKind::Enum => true, + TypeKind::Struct => type_def_is_handle(row), + TypeKind::Delegate => !row.flags().contains(TypeAttributes::WindowsRuntime), + _ => false, + } +} + +pub fn type_is_primitive(ty: &Type) -> bool { + match ty { + Type::TypeDef(row, _) => type_def_is_primitive(*row), + Type::Bool | Type::Char | Type::I8 | Type::U8 | Type::I16 | Type::U16 | Type::I32 | Type::U32 | Type::I64 | Type::U64 | Type::F32 | Type::F64 | Type::ISize | Type::USize | Type::HRESULT | Type::ConstPtr(_, _) | Type::MutPtr(_, _) => true, + _ => false, + } +} + +fn type_has_explicit_layout(ty: &Type) -> bool { + match ty { + Type::TypeDef(row, _) => type_def_has_explicit_layout(*row), + Type::Win32Array(ty, _) => type_has_explicit_layout(ty), + _ => false, + } +} + +pub fn type_def_has_explicit_layout(row: TypeDef) -> bool { + if row.kind() != TypeKind::Struct { + return false; + } + fn check(row: TypeDef) -> bool { + if row.flags().contains(TypeAttributes::ExplicitLayout) { + return true; + } + if row.fields().any(|field| type_has_explicit_layout(&field.ty(Some(row)))) { + return true; + } + false + } + let type_name = row.type_name(); + if type_name.namespace.is_empty() { + check(row) + } else { + for row in row.reader().get_type_def(type_name.namespace, type_name.name) { + if check(row) { + return true; + } + } + false + } +} + +fn type_has_packing(ty: &Type) -> bool { + match ty { + Type::TypeDef(row, _) => type_def_has_packing(*row), + Type::Win32Array(ty, _) => type_has_packing(ty), + _ => false, + } +} + +pub fn type_def_has_packing(row: TypeDef) -> bool { + if row.kind() != TypeKind::Struct { + return false; + } + fn check(row: TypeDef) -> bool { + if row.class_layout().is_some() { + return true; + } + if row.fields().any(|field| type_has_packing(&field.ty(Some(row)))) { + return true; + } + false + } + let type_name = row.type_name(); + if type_name.namespace.is_empty() { + check(row) + } else { + for row in row.reader().get_type_def(type_name.namespace, type_name.name) { + if check(row) { + return true; + } + } + false + } +} + +pub fn type_def_interfaces(def: TypeDef, generics: &[Type]) -> impl Iterator<Item = Interface> + '_ { + def.interface_impls().map(|imp| { + let kind = if imp.has_attribute("DefaultAttribute") { InterfaceKind::Default } else { InterfaceKind::None }; + Interface { kind, ty: imp.ty(generics) } + }) +} + +pub fn type_def_default_interface(row: TypeDef) -> Option<Type> { + type_def_interfaces(row, &[]).find_map(move |interface| if interface.kind == InterfaceKind::Default { Some(interface.ty) } else { None }) +} + +fn type_signature(ty: &Type) -> String { + match ty { + Type::Bool => "b1".to_string(), + Type::Char => "c2".to_string(), + Type::I8 => "i1".to_string(), + Type::U8 => "u1".to_string(), + Type::I16 => "i2".to_string(), + Type::U16 => "u2".to_string(), + Type::I32 => "i4".to_string(), + Type::U32 => "u4".to_string(), + Type::I64 => "i8".to_string(), + Type::U64 => "u8".to_string(), + Type::F32 => "f4".to_string(), + Type::F64 => "f8".to_string(), + Type::ISize => "is".to_string(), + Type::USize => "us".to_string(), + Type::String => "string".to_string(), + Type::IInspectable => "cinterface(IInspectable)".to_string(), + Type::GUID => "g16".to_string(), + Type::HRESULT => "struct(Windows.Foundation.HResult;i4)".to_string(), + Type::TypeDef(row, generics) => type_def_signature(*row, generics), + rest => unimplemented!("{rest:?}"), + } +} + +pub fn type_def_signature(row: TypeDef, generics: &[Type]) -> String { + match row.kind() { + TypeKind::Interface => type_def_interface_signature(row, generics), + TypeKind::Class => { + if let Some(Type::TypeDef(default, generics)) = type_def_default_interface(row) { + format!("rc({};{})", row.type_name(), type_def_interface_signature(default, &generics)) + } else { + unimplemented!(); + } + } + TypeKind::Enum => format!("enum({};{})", row.type_name(), type_signature(&row.underlying_type())), + TypeKind::Struct => { + let mut result = format!("struct({}", row.type_name()); + for field in row.fields() { + result.push(';'); + result.push_str(&type_signature(&field.ty(Some(row)))); + } + result.push(')'); + result + } + TypeKind::Delegate => { + if generics.is_empty() { + format!("delegate({})", type_def_interface_signature(row, generics)) + } else { + type_def_interface_signature(row, generics) + } + } + } +} + +fn type_def_interface_signature(row: TypeDef, generics: &[Type]) -> String { + let guid = type_def_guid(row).unwrap(); + if generics.is_empty() { + format!("{{{guid:#?}}}") + } else { + let mut result = format!("pinterface({{{guid:#?}}}"); + for generic in generics { + result.push(';'); + result.push_str(&type_signature(generic)); + } + result.push(')'); + result + } +} + +pub fn type_def_is_handle(row: TypeDef) -> bool { + row.has_attribute("NativeTypedefAttribute") +} + +pub fn type_def_guid(row: TypeDef) -> Option<Guid> { + row.find_attribute("GuidAttribute").map(|attribute| Guid::from_args(&attribute.args())) +} + +pub fn type_def_bases(mut row: TypeDef) -> Vec<TypeDef> { + let mut bases = Vec::new(); + loop { + match row.extends() { + Some(base) if base != TypeName::Object => { + row = row.reader().get_type_def(base.namespace, base.name).next().expect("Type not found"); + bases.push(row); + } + _ => break, + } + } + bases +} + +pub fn type_def_invalid_values(row: TypeDef) -> Vec<i64> { + let mut values = Vec::new(); + for attribute in row.attributes() { + if attribute.name() == "InvalidHandleValueAttribute" { + if let Some((_, Value::I64(value))) = attribute.args().first() { + values.push(*value); + } + } + } + values +} + +fn type_def_is_nullable(row: TypeDef) -> bool { + match row.kind() { + TypeKind::Interface | TypeKind::Class => true, + // Win32 callbacks are defined as `Option<T>` so we don't include them here to avoid them + // from being doubly wrapped in `Option`. + TypeKind::Delegate => row.flags().contains(TypeAttributes::WindowsRuntime), + _ => false, + } +} + +pub fn type_is_nullable(ty: &Type) -> bool { + match ty { + Type::TypeDef(row, _) => type_def_is_nullable(*row), + Type::IInspectable | Type::IUnknown => true, + _ => false, + } +} + +pub fn type_def_vtables(row: TypeDef) -> Vec<Type> { + let mut result = Vec::new(); + if row.flags().contains(TypeAttributes::WindowsRuntime) { + result.push(Type::IUnknown); + if row.kind() != TypeKind::Delegate { + result.push(Type::IInspectable); + } + } else { + let mut next = row; + while let Some(base) = next.interface_impls().map(move |imp| imp.ty(&[])).next() { + match base { + Type::TypeDef(row, _) => { + next = row; + result.insert(0, base); + } + Type::IInspectable => { + result.insert(0, Type::IUnknown); + result.insert(1, Type::IInspectable); + break; + } + Type::IUnknown => { + result.insert(0, Type::IUnknown); + break; + } + rest => unimplemented!("{rest:?}"), + } + } + } + result +} diff --git a/vendor/windows-bindgen/src/metadata/mod.rs b/vendor/windows-bindgen/src/metadata/mod.rs deleted file mode 100644 index 027a282ac..000000000 --- a/vendor/windows-bindgen/src/metadata/mod.rs +++ /dev/null @@ -1,926 +0,0 @@ -use std::collections::*; -pub use windows_metadata::*; - -#[derive(Clone)] -pub struct Interface { - pub ty: Type, - pub kind: InterfaceKind, -} - -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum InterfaceKind { - None, - Default, - Overridable, - Static, - Base, -} - -#[derive(Copy, Clone, PartialEq, Eq)] -pub struct QueryPosition { - pub object: usize, - pub guid: usize, -} - -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum SignatureKind { - Query(QueryPosition), - QueryOptional(QueryPosition), - ResultValue, - ResultVoid, - ReturnStruct, - ReturnValue, - ReturnVoid, - PreserveSig, -} - -#[derive(Copy, Clone, Eq, PartialEq)] -pub enum SignatureParamKind { - ArrayFixed(usize), - ArrayRelativeLen(usize), - ArrayRelativeByteLen(usize), - ArrayRelativePtr(usize), - TryInto, - IntoParam, - OptionalPointer, - ValueType, - Blittable, - Other, -} - -impl SignatureParamKind { - fn is_array(&self) -> bool { - matches!(self, Self::ArrayFixed(_) | Self::ArrayRelativeLen(_) | Self::ArrayRelativeByteLen(_) | Self::ArrayRelativePtr(_)) - } -} - -pub struct Signature { - pub def: MethodDef, - pub params: Vec<SignatureParam>, - pub return_type: Type, - pub call_flags: MethodCallAttributes, -} - -pub struct SignatureParam { - pub def: Param, - pub ty: Type, - pub kind: SignatureParamKind, -} - -#[derive(PartialEq, Eq, Debug)] -pub enum AsyncKind { - None, - Action, - ActionWithProgress, - Operation, - OperationWithProgress, -} - -pub fn type_def_invoke_method(reader: &Reader, row: TypeDef) -> MethodDef { - reader.type_def_methods(row).find(|method| reader.method_def_name(*method) == "Invoke").expect("`Invoke` method not found") -} - -pub fn type_def_generics(reader: &Reader, def: TypeDef) -> Vec<Type> { - reader.type_def_generics(def).map(Type::GenericParam).collect() -} - -// TODO: namespace should not be required - it's a hack to accomodate Win32 metadata -// TODO: this is very Rust-specific and Win32-metadata specific with all of its translation. Replace with literal signature parser that just returns slice of types. -pub fn method_def_signature(reader: &Reader, namespace: &str, row: MethodDef, generics: &[Type]) -> Signature { - let mut blob = reader.row_blob(row, 4); - let call_flags = MethodCallAttributes(blob.read_usize() as u8); - let _param_count = blob.read_usize(); - let mut return_type = reader.type_from_blob(&mut blob, None, generics); - - let mut params: Vec<SignatureParam> = reader - .method_def_params(row) - .filter_map(|param| { - let param_is_const = reader.has_attribute(param, "ConstAttribute"); - if reader.param_sequence(param) == 0 { - if param_is_const { - return_type = return_type.clone().to_const_type(); - } - None - } else { - let is_output = reader.param_flags(param).contains(ParamAttributes::Out); - let mut ty = reader.type_from_blob(&mut blob, None, generics); - - if let Some(name) = param_or_enum(reader, param) { - let def = reader.get_type_def(TypeName::new(namespace, &name)).next().expect("Enum not found"); - ty = Type::PrimitiveOrEnum(Box::new(ty), Box::new(Type::TypeDef(def, Vec::new()))); - } - - if param_is_const || !is_output { - ty = ty.to_const_type(); - } - if !is_output { - ty = ty.to_const_ptr(); - } - let kind = param_kind(reader, param); - Some(SignatureParam { def: param, ty, kind }) - } - }) - .collect(); - - for position in 0..params.len() { - // Point len params back to the corresponding ptr params. - match params[position].kind { - SignatureParamKind::ArrayRelativeLen(relative) | SignatureParamKind::ArrayRelativeByteLen(relative) => { - // The len params must be input only. - if !reader.param_flags(params[relative].def).contains(ParamAttributes::Out) && position != relative && !params[relative].ty.is_pointer() { - params[relative].kind = SignatureParamKind::ArrayRelativePtr(position); - } else { - params[position].kind = SignatureParamKind::Other; - } - } - SignatureParamKind::ArrayFixed(_) => { - if reader.has_attribute(params[position].def, "FreeWithAttribute") { - params[position].kind = SignatureParamKind::Other; - } - } - _ => {} - } - } - - let mut sets = BTreeMap::<usize, Vec<usize>>::new(); - - // Finds sets of ptr params pointing at the same len param. - for (position, param) in params.iter().enumerate() { - match param.kind { - SignatureParamKind::ArrayRelativeLen(relative) | SignatureParamKind::ArrayRelativeByteLen(relative) => { - sets.entry(relative).or_default().push(position); - } - _ => {} - } - } - - // Remove all sets. - for (len, ptrs) in sets { - if ptrs.len() > 1 { - params[len].kind = SignatureParamKind::Other; - for ptr in ptrs { - params[ptr].kind = SignatureParamKind::Other; - } - } - } - - // Remove any byte arrays that aren't byte-sized types. - for position in 0..params.len() { - if let SignatureParamKind::ArrayRelativeByteLen(relative) = params[position].kind { - if !params[position].ty.is_byte_size() { - params[position].kind = SignatureParamKind::Other; - params[relative].kind = SignatureParamKind::Other; - } - } - } - - for param in &mut params { - if param.kind == SignatureParamKind::Other { - if signature_param_is_convertible(reader, param) { - if type_is_non_exclusive_winrt_interface(reader, ¶m.ty) { - param.kind = SignatureParamKind::TryInto; - } else { - param.kind = SignatureParamKind::IntoParam; - } - } else { - let flags = reader.param_flags(param.def); - if param.ty.is_pointer() && (flags.contains(ParamAttributes::Optional) || reader.has_attribute(param.def, "ReservedAttribute")) { - param.kind = SignatureParamKind::OptionalPointer; - } else if type_is_primitive(reader, ¶m.ty) && (!param.ty.is_pointer() || type_is_blittable(reader, ¶m.ty.deref())) { - param.kind = SignatureParamKind::ValueType; - } else if type_is_blittable(reader, ¶m.ty) { - param.kind = SignatureParamKind::Blittable; - } - } - } - } - - Signature { def: row, params, return_type, call_flags } -} - -fn param_kind(reader: &Reader, row: Param) -> SignatureParamKind { - for attribute in reader.attributes(row) { - match reader.attribute_name(attribute) { - "NativeArrayInfoAttribute" => { - for (_, value) in reader.attribute_args(attribute) { - match value { - Value::I16(value) => return SignatureParamKind::ArrayRelativeLen(value as usize), - Value::I32(value) => return SignatureParamKind::ArrayFixed(value as usize), - _ => {} - } - } - } - "MemorySizeAttribute" => { - for (_, value) in reader.attribute_args(attribute) { - if let Value::I16(value) = value { - return SignatureParamKind::ArrayRelativeByteLen(value as usize); - } - } - } - _ => {} - } - } - SignatureParamKind::Other -} - -// TODO: this is a terribly broken Win32 metadata attribute - need to get rid of it. -fn param_or_enum(reader: &Reader, row: Param) -> Option<String> { - reader.find_attribute(row, "AssociatedEnumAttribute").and_then(|attribute| { - for (_, arg) in reader.attribute_args(attribute) { - if let Value::String(name) = arg { - return Some(name); - } - } - None - }) -} - -pub fn signature_param_is_borrowed(reader: &Reader, param: &SignatureParam) -> bool { - type_is_borrowed(reader, ¶m.ty) -} - -pub fn signature_param_is_convertible(reader: &Reader, param: &SignatureParam) -> bool { - !reader.param_flags(param.def).contains(ParamAttributes::Out) && !param.ty.is_winrt_array() && !param.ty.is_pointer() && !param.kind.is_array() && (type_is_borrowed(reader, ¶m.ty) || type_is_non_exclusive_winrt_interface(reader, ¶m.ty) || type_is_trivially_convertible(reader, ¶m.ty)) -} - -fn signature_param_is_retval(reader: &Reader, param: &SignatureParam) -> bool { - // The Win32 metadata uses `RetValAttribute` to call out retval methods but it is employed - // very sparingly, so this heuristic is used to apply the transformation more uniformly. - if reader.has_attribute(param.def, "RetValAttribute") { - return true; - } - if !param.ty.is_pointer() { - return false; - } - if param.ty.is_void() { - return false; - } - let flags = reader.param_flags(param.def); - if flags.contains(ParamAttributes::In) || !flags.contains(ParamAttributes::Out) || flags.contains(ParamAttributes::Optional) || param.kind.is_array() { - return false; - } - if param_kind(reader, param.def).is_array() { - return false; - } - // If it's bigger than 128 bits, best to pass as a reference. - if reader.type_size(¶m.ty.deref()) > 16 { - return false; - } - // Win32 callbacks are defined as `Option<T>` so we don't include them here to avoid - // producing the `Result<Option<T>>` anti-pattern. - !type_is_callback(reader, ¶m.ty.deref()) -} - -pub fn signature_kind(reader: &Reader, signature: &Signature) -> SignatureKind { - if reader.has_attribute(signature.def, "CanReturnMultipleSuccessValuesAttribute") { - return SignatureKind::PreserveSig; - } - match &signature.return_type { - Type::Void if signature_is_retval(reader, signature) => SignatureKind::ReturnValue, - Type::Void => SignatureKind::ReturnVoid, - Type::HRESULT => { - if signature.params.len() >= 2 { - if let Some(guid) = signature_param_is_query_guid(reader, &signature.params) { - if let Some(object) = signature_param_is_query_object(reader, &signature.params) { - if reader.param_flags(signature.params[object].def).contains(ParamAttributes::Optional) { - return SignatureKind::QueryOptional(QueryPosition { object, guid }); - } else { - return SignatureKind::Query(QueryPosition { object, guid }); - } - } - } - } - if signature_is_retval(reader, signature) { - SignatureKind::ResultValue - } else { - SignatureKind::ResultVoid - } - } - Type::TypeDef(def, _) if reader.type_def_type_name(*def) == TypeName::NTSTATUS => SignatureKind::ResultVoid, - Type::TypeDef(def, _) if reader.type_def_type_name(*def) == TypeName::WIN32_ERROR => SignatureKind::ResultVoid, - Type::TypeDef(def, _) if reader.type_def_type_name(*def) == TypeName::BOOL && method_def_last_error(reader, signature.def) => SignatureKind::ResultVoid, - _ if type_is_struct(reader, &signature.return_type) => SignatureKind::ReturnStruct, - _ => SignatureKind::PreserveSig, - } -} - -fn signature_is_retval(reader: &Reader, signature: &Signature) -> bool { - signature.params.last().map_or(false, |param| signature_param_is_retval(reader, param)) - && signature.params[..signature.params.len() - 1].iter().all(|param| { - let flags = reader.param_flags(param.def); - !flags.contains(ParamAttributes::Out) - }) -} - -fn signature_param_is_query_guid(reader: &Reader, params: &[SignatureParam]) -> Option<usize> { - params.iter().rposition(|param| param.ty == Type::ConstPtr(Box::new(Type::GUID), 1) && !reader.param_flags(param.def).contains(ParamAttributes::Out)) -} - -fn signature_param_is_query_object(reader: &Reader, params: &[SignatureParam]) -> Option<usize> { - params.iter().rposition(|param| param.ty == Type::MutPtr(Box::new(Type::Void), 2) && reader.has_attribute(param.def, "ComOutPtrAttribute")) -} - -fn method_def_last_error(reader: &Reader, row: MethodDef) -> bool { - if let Some(map) = reader.method_def_impl_map(row) { - reader.impl_map_flags(map).contains(PInvokeAttributes::SupportsLastError) - } else { - false - } -} - -fn type_is_borrowed(reader: &Reader, ty: &Type) -> bool { - match ty { - Type::TypeDef(row, _) => !type_def_is_blittable(reader, *row), - Type::BSTR | Type::PCSTR | Type::PCWSTR | Type::IInspectable | Type::IUnknown | Type::GenericParam(_) => true, - _ => false, - } -} - -pub fn type_is_non_exclusive_winrt_interface(reader: &Reader, ty: &Type) -> bool { - match ty { - Type::TypeDef(row, _) => { - let flags = reader.type_def_flags(*row); - if !flags.contains(TypeAttributes::WindowsRuntime) { - false - } else { - match reader.type_def_kind(*row) { - TypeKind::Interface => !type_def_is_exclusive(reader, *row), - TypeKind::Class => reader.has_attribute(*row, "ComposableAttribute"), - _ => false, - } - } - } - _ => false, - } -} - -fn type_is_trivially_convertible(reader: &Reader, ty: &Type) -> bool { - match ty { - Type::TypeDef(row, _) => match reader.type_def_kind(*row) { - TypeKind::Struct => type_def_is_handle(reader, *row), - _ => false, - }, - Type::PCSTR | Type::PCWSTR => true, - _ => false, - } -} - -fn type_is_callback(reader: &Reader, ty: &Type) -> bool { - match ty { - Type::TypeDef(row, _) => type_def_is_callback(reader, *row), - _ => false, - } -} - -fn type_def_is_callback(reader: &Reader, row: TypeDef) -> bool { - !reader.type_def_flags(row).contains(TypeAttributes::WindowsRuntime) && reader.type_def_kind(row) == TypeKind::Delegate -} - -pub fn type_has_callback(reader: &Reader, ty: &Type) -> bool { - match ty { - Type::TypeDef(row, _) => type_def_has_callback(reader, *row), - Type::Win32Array(ty, _) => type_has_callback(reader, ty), - _ => false, - } -} -pub fn type_def_has_callback(reader: &Reader, row: TypeDef) -> bool { - if type_def_is_callback(reader, row) { - return true; - } - if reader.type_def_kind(row) != TypeKind::Struct { - return false; - } - fn check(reader: &Reader, row: TypeDef) -> bool { - if reader.type_def_fields(row).any(|field| type_has_callback(reader, &reader.field_type(field, Some(row)))) { - return true; - } - false - } - let type_name = reader.type_def_type_name(row); - if type_name.namespace.is_empty() { - check(reader, row) - } else { - for row in reader.get_type_def(type_name) { - if check(reader, row) { - return true; - } - } - false - } -} - -pub fn type_interfaces(reader: &Reader, ty: &Type) -> Vec<Interface> { - // TODO: collect into btree map and then return collected vec - // This will both sort the results and should make finding dupes faster - fn walk(reader: &Reader, result: &mut Vec<Interface>, parent: &Type, is_base: bool) { - if let Type::TypeDef(row, generics) = parent { - for imp in reader.type_def_interface_impls(*row) { - let mut child = Interface { - ty: reader.interface_impl_type(imp, generics), - kind: if reader.has_attribute(imp, "DefaultAttribute") { InterfaceKind::Default } else { InterfaceKind::None }, - }; - - child.kind = if !is_base && child.kind == InterfaceKind::Default { - InterfaceKind::Default - } else if child.kind == InterfaceKind::Overridable { - continue; - } else if is_base { - InterfaceKind::Base - } else { - InterfaceKind::None - }; - let mut found = false; - for existing in result.iter_mut() { - if existing.ty == child.ty { - found = true; - if child.kind == InterfaceKind::Default { - existing.kind = child.kind - } - } - } - if !found { - walk(reader, result, &child.ty, is_base); - result.push(child); - } - } - } - } - let mut result = Vec::new(); - walk(reader, &mut result, ty, false); - if let Type::TypeDef(row, _) = ty { - if reader.type_def_kind(*row) == TypeKind::Class { - for base in type_def_bases(reader, *row) { - walk(reader, &mut result, &Type::TypeDef(base, Vec::new()), true); - } - for attribute in reader.attributes(*row) { - match reader.attribute_name(attribute) { - "StaticAttribute" | "ActivatableAttribute" => { - for (_, arg) in reader.attribute_args(attribute) { - if let Value::TypeName(type_name) = arg { - let def = reader.get_type_def(TypeName::parse(&type_name)).next().expect("Type not found"); - result.push(Interface { ty: Type::TypeDef(def, Vec::new()), kind: InterfaceKind::Static }); - break; - } - } - } - _ => {} - } - } - } - } - result.sort_by(|a, b| type_name(reader, &a.ty).cmp(type_name(reader, &b.ty))); - result -} - -fn type_name<'a>(reader: &Reader<'a>, ty: &Type) -> &'a str { - match ty { - Type::TypeDef(row, _) => reader.type_def_name(*row), - _ => "", - } -} - -pub fn type_def_async_kind(reader: &Reader, row: TypeDef) -> AsyncKind { - match reader.type_def_type_name(row) { - TypeName::IAsyncAction => AsyncKind::Action, - TypeName::IAsyncActionWithProgress => AsyncKind::ActionWithProgress, - TypeName::IAsyncOperation => AsyncKind::Operation, - TypeName::IAsyncOperationWithProgress => AsyncKind::OperationWithProgress, - _ => AsyncKind::None, - } -} - -pub fn field_is_blittable(reader: &Reader, row: Field, enclosing: TypeDef) -> bool { - type_is_blittable(reader, &reader.field_type(row, Some(enclosing))) -} - -pub fn field_is_copyable(reader: &Reader, row: Field, enclosing: TypeDef) -> bool { - type_is_copyable(reader, &reader.field_type(row, Some(enclosing))) -} - -pub fn field_guid(reader: &Reader, row: Field) -> Option<GUID> { - reader.find_attribute(row, "GuidAttribute").map(|attribute| GUID::from_args(&reader.attribute_args(attribute))) -} - -pub fn field_is_ansi(reader: &Reader, row: Field) -> bool { - reader.find_attribute(row, "NativeEncodingAttribute").is_some_and(|attribute| matches!(reader.attribute_args(attribute).get(0), Some((_, Value::String(encoding))) if encoding == "ansi")) -} - -pub fn type_is_blittable(reader: &Reader, ty: &Type) -> bool { - match ty { - Type::TypeDef(row, _) => type_def_is_blittable(reader, *row), - Type::String | Type::BSTR | Type::IInspectable | Type::IUnknown | Type::GenericParam(_) => false, - Type::Win32Array(kind, _) => type_is_blittable(reader, kind), - Type::WinrtArray(kind) => type_is_blittable(reader, kind), - _ => true, - } -} - -fn type_is_copyable(reader: &Reader, ty: &Type) -> bool { - match ty { - Type::TypeDef(row, _) => type_def_is_copyable(reader, *row), - Type::String | Type::BSTR | Type::IInspectable | Type::IUnknown | Type::GenericParam(_) => false, - Type::Win32Array(kind, _) => type_is_copyable(reader, kind), - Type::WinrtArray(kind) => type_is_copyable(reader, kind), - _ => true, - } -} - -pub fn type_def_is_blittable(reader: &Reader, row: TypeDef) -> bool { - match reader.type_def_kind(row) { - TypeKind::Struct => { - if reader.type_def_flags(row).contains(TypeAttributes::WindowsRuntime) { - reader.type_def_fields(row).all(|field| field_is_blittable(reader, field, row)) - } else { - true - } - } - TypeKind::Enum => true, - TypeKind::Delegate => !reader.type_def_flags(row).contains(TypeAttributes::WindowsRuntime), - _ => false, - } -} - -pub fn type_def_is_copyable(reader: &Reader, row: TypeDef) -> bool { - match reader.type_def_kind(row) { - TypeKind::Struct => reader.type_def_fields(row).all(|field| field_is_copyable(reader, field, row)), - TypeKind::Enum => true, - TypeKind::Delegate => !reader.type_def_flags(row).contains(TypeAttributes::WindowsRuntime), - _ => false, - } -} - -pub fn method_def_special_name(reader: &Reader, row: MethodDef) -> String { - let name = reader.method_def_name(row); - if reader.method_def_flags(row).contains(MethodAttributes::SpecialName) { - if name.starts_with("get") { - name[4..].to_string() - } else if name.starts_with("put") { - format!("Set{}", &name[4..]) - } else if name.starts_with("add") { - name[4..].to_string() - } else if name.starts_with("remove") { - format!("Remove{}", &name[7..]) - } else { - name.to_string() - } - } else { - if let Some(attribute) = reader.find_attribute(row, "OverloadAttribute") { - for (_, arg) in reader.attribute_args(attribute) { - if let Value::String(name) = arg { - return name; - } - } - } - name.to_string() - } -} - -pub fn method_def_static_lib(reader: &Reader, row: MethodDef) -> Option<String> { - reader.find_attribute(row, "StaticLibraryAttribute").and_then(|attribute| { - let args = reader.attribute_args(attribute); - if let Value::String(value) = &args[0].1 { - return Some(value.clone()); - } - None - }) -} - -pub fn method_def_extern_abi(reader: &Reader, def: MethodDef) -> &'static str { - let impl_map = reader.method_def_impl_map(def).expect("ImplMap not found"); - let flags = reader.impl_map_flags(impl_map); - - if flags.contains(PInvokeAttributes::CallConvPlatformapi) { - "system" - } else if flags.contains(PInvokeAttributes::CallConvCdecl) { - "cdecl" - } else { - unimplemented!() - } -} - -pub fn type_def_has_default_constructor(reader: &Reader, row: TypeDef) -> bool { - for attribute in reader.attributes(row) { - if reader.attribute_name(attribute) == "ActivatableAttribute" { - if reader.attribute_args(attribute).iter().any(|arg| matches!(arg.1, Value::TypeName(_))) { - continue; - } else { - return true; - } - } - } - false -} - -pub fn type_def_has_default_interface(reader: &Reader, row: TypeDef) -> bool { - reader.type_def_interface_impls(row).any(|imp| reader.has_attribute(imp, "DefaultAttribute")) -} - -pub fn type_def_is_exclusive(reader: &Reader, row: TypeDef) -> bool { - reader.has_attribute(row, "ExclusiveToAttribute") -} - -pub fn type_is_exclusive(reader: &Reader, ty: &Type) -> bool { - match ty { - Type::TypeDef(row, _) => type_def_is_exclusive(reader, *row), - _ => false, - } -} - -pub fn type_is_struct(reader: &Reader, ty: &Type) -> bool { - // This check is used to detect virtual functions that return C-style PODs that affect how the stack is packed for x86. - // It could be defined as a struct with more than one field but that check is complicated as it would have to detect - // nested structs. Fortunately, this is rare enough that this check is sufficient. - match ty { - Type::TypeDef(row, _) => reader.type_def_kind(*row) == TypeKind::Struct && !type_def_is_handle(reader, *row), - Type::GUID => true, - _ => false, - } -} - -fn type_def_is_primitive(reader: &Reader, row: TypeDef) -> bool { - match reader.type_def_kind(row) { - TypeKind::Enum => true, - TypeKind::Struct => type_def_is_handle(reader, row), - TypeKind::Delegate => !reader.type_def_flags(row).contains(TypeAttributes::WindowsRuntime), - _ => false, - } -} - -pub fn type_is_primitive(reader: &Reader, ty: &Type) -> bool { - match ty { - Type::TypeDef(row, _) => type_def_is_primitive(reader, *row), - Type::Bool | Type::Char | Type::I8 | Type::U8 | Type::I16 | Type::U16 | Type::I32 | Type::U32 | Type::I64 | Type::U64 | Type::F32 | Type::F64 | Type::ISize | Type::USize | Type::HRESULT | Type::ConstPtr(_, _) | Type::MutPtr(_, _) => true, - _ => false, - } -} - -fn type_has_explicit_layout(reader: &Reader, ty: &Type) -> bool { - match ty { - Type::TypeDef(row, _) => type_def_has_explicit_layout(reader, *row), - Type::Win32Array(ty, _) => type_has_explicit_layout(reader, ty), - _ => false, - } -} - -pub fn type_def_has_explicit_layout(reader: &Reader, row: TypeDef) -> bool { - if reader.type_def_kind(row) != TypeKind::Struct { - return false; - } - fn check(reader: &Reader, row: TypeDef) -> bool { - if reader.type_def_flags(row).contains(TypeAttributes::ExplicitLayout) { - return true; - } - if reader.type_def_fields(row).any(|field| type_has_explicit_layout(reader, &reader.field_type(field, Some(row)))) { - return true; - } - false - } - let type_name = reader.type_def_type_name(row); - if type_name.namespace.is_empty() { - check(reader, row) - } else { - for row in reader.get_type_def(type_name) { - if check(reader, row) { - return true; - } - } - false - } -} - -fn type_has_packing(reader: &Reader, ty: &Type) -> bool { - match ty { - Type::TypeDef(row, _) => type_def_has_packing(reader, *row), - Type::Win32Array(ty, _) => type_has_packing(reader, ty), - _ => false, - } -} - -pub fn type_def_has_packing(reader: &Reader, row: TypeDef) -> bool { - if reader.type_def_kind(row) != TypeKind::Struct { - return false; - } - fn check(reader: &Reader, row: TypeDef) -> bool { - if reader.type_def_class_layout(row).is_some() { - return true; - } - if reader.type_def_fields(row).any(|field| type_has_packing(reader, &reader.field_type(field, Some(row)))) { - return true; - } - false - } - let type_name = reader.type_def_type_name(row); - if type_name.namespace.is_empty() { - check(reader, row) - } else { - for row in reader.get_type_def(type_name) { - if check(reader, row) { - return true; - } - } - false - } -} - -pub fn type_def_default_interface(reader: &Reader, row: TypeDef) -> Option<Type> { - reader.type_def_interface_impls(row).find_map(move |row| if reader.has_attribute(row, "DefaultAttribute") { Some(reader.interface_impl_type(row, &[])) } else { None }) -} - -fn type_signature(reader: &Reader, ty: &Type) -> String { - match ty { - Type::Bool => "b1".to_string(), - Type::Char => "c2".to_string(), - Type::I8 => "i1".to_string(), - Type::U8 => "u1".to_string(), - Type::I16 => "i2".to_string(), - Type::U16 => "u2".to_string(), - Type::I32 => "i4".to_string(), - Type::U32 => "u4".to_string(), - Type::I64 => "i8".to_string(), - Type::U64 => "u8".to_string(), - Type::F32 => "f4".to_string(), - Type::F64 => "f8".to_string(), - Type::ISize => "is".to_string(), - Type::USize => "us".to_string(), - Type::String => "string".to_string(), - Type::IInspectable => "cinterface(IInspectable)".to_string(), - Type::GUID => "g16".to_string(), - Type::HRESULT => "struct(Windows.Foundation.HResult;i4)".to_string(), - Type::TypeDef(row, generics) => type_def_signature(reader, *row, generics), - rest => unimplemented!("{rest:?}"), - } -} - -pub fn type_def_signature(reader: &Reader, row: TypeDef, generics: &[Type]) -> String { - match reader.type_def_kind(row) { - TypeKind::Interface => type_def_interface_signature(reader, row, generics), - TypeKind::Class => { - if let Some(Type::TypeDef(default, generics)) = type_def_default_interface(reader, row) { - format!("rc({};{})", reader.type_def_type_name(row), type_def_interface_signature(reader, default, &generics)) - } else { - unimplemented!(); - } - } - TypeKind::Enum => format!("enum({};{})", reader.type_def_type_name(row), type_signature(reader, &reader.type_def_underlying_type(row))), - TypeKind::Struct => { - let mut result = format!("struct({}", reader.type_def_type_name(row)); - for field in reader.type_def_fields(row) { - result.push(';'); - result.push_str(&type_signature(reader, &reader.field_type(field, Some(row)))); - } - result.push(')'); - result - } - TypeKind::Delegate => { - if generics.is_empty() { - format!("delegate({})", type_def_interface_signature(reader, row, generics)) - } else { - type_def_interface_signature(reader, row, generics) - } - } - } -} - -fn type_def_interface_signature(reader: &Reader, row: TypeDef, generics: &[Type]) -> String { - let guid = type_def_guid(reader, row).unwrap(); - if generics.is_empty() { - format!("{{{guid:#?}}}") - } else { - let mut result = format!("pinterface({{{guid:#?}}}"); - for generic in generics { - result.push(';'); - result.push_str(&type_signature(reader, generic)); - } - result.push(')'); - result - } -} - -pub fn type_def_is_handle(reader: &Reader, row: TypeDef) -> bool { - reader.has_attribute(row, "NativeTypedefAttribute") -} - -pub fn type_has_replacement(reader: &Reader, ty: &Type) -> bool { - match ty { - Type::HRESULT | Type::PCSTR | Type::PCWSTR => true, - Type::TypeDef(row, _) => type_def_is_handle(reader, *row) || reader.type_def_kind(*row) == TypeKind::Enum, - _ => false, - } -} - -pub fn type_def_guid(reader: &Reader, row: TypeDef) -> Option<GUID> { - reader.find_attribute(row, "GuidAttribute").map(|attribute| GUID::from_args(&reader.attribute_args(attribute))) -} - -pub fn type_def_bases(reader: &Reader, mut row: TypeDef) -> Vec<TypeDef> { - let mut bases = Vec::new(); - loop { - match reader.type_def_extends(row) { - Some(base) if base != TypeName::Object => { - row = reader.get_type_def(base).next().expect("Type not found"); - bases.push(row); - } - _ => break, - } - } - bases -} - -pub fn type_def_is_agile(reader: &Reader, row: TypeDef) -> bool { - for attribute in reader.attributes(row) { - match reader.attribute_name(attribute) { - "AgileAttribute" => return true, - "MarshalingBehaviorAttribute" => { - if let Some((_, Value::EnumDef(_, value))) = reader.attribute_args(attribute).get(0) { - if let Value::I32(2) = **value { - return true; - } - } - } - _ => {} - } - } - matches!(reader.type_def_type_name(row), TypeName::IAsyncAction | TypeName::IAsyncActionWithProgress | TypeName::IAsyncOperation | TypeName::IAsyncOperationWithProgress) -} - -pub fn type_def_invalid_values(reader: &Reader, row: TypeDef) -> Vec<i64> { - let mut values = Vec::new(); - for attribute in reader.attributes(row) { - if reader.attribute_name(attribute) == "InvalidHandleValueAttribute" { - if let Some((_, Value::I64(value))) = reader.attribute_args(attribute).get(0) { - values.push(*value); - } - } - } - values -} - -pub fn type_def_usable_for(reader: &Reader, row: TypeDef) -> Option<TypeDef> { - if let Some(attribute) = reader.find_attribute(row, "AlsoUsableForAttribute") { - if let Some((_, Value::String(name))) = reader.attribute_args(attribute).get(0) { - return reader.get_type_def(TypeName::new(reader.type_def_namespace(row), name.as_str())).next(); - } - } - None -} - -fn type_def_is_nullable(reader: &Reader, row: TypeDef) -> bool { - match reader.type_def_kind(row) { - TypeKind::Interface | TypeKind::Class => true, - // Win32 callbacks are defined as `Option<T>` so we don't include them here to avoid them - // from being doubly wrapped in `Option`. - TypeKind::Delegate => reader.type_def_flags(row).contains(TypeAttributes::WindowsRuntime), - _ => false, - } -} - -pub fn type_is_nullable(reader: &Reader, ty: &Type) -> bool { - match ty { - Type::TypeDef(row, _) => type_def_is_nullable(reader, *row), - Type::IInspectable | Type::IUnknown => true, - _ => false, - } -} - -pub fn type_def_vtables(reader: &Reader, row: TypeDef) -> Vec<Type> { - let mut result = Vec::new(); - if reader.type_def_flags(row).contains(TypeAttributes::WindowsRuntime) { - result.push(Type::IUnknown); - if reader.type_def_kind(row) != TypeKind::Delegate { - result.push(Type::IInspectable); - } - } else { - let mut next = row; - while let Some(base) = type_def_interfaces(reader, next, &[]).next() { - match base { - Type::TypeDef(row, _) => { - next = row; - result.insert(0, base); - } - Type::IInspectable => { - result.insert(0, Type::IUnknown); - result.insert(1, Type::IInspectable); - break; - } - Type::IUnknown => { - result.insert(0, Type::IUnknown); - break; - } - rest => unimplemented!("{rest:?}"), - } - } - } - result -} - -pub fn type_def_interfaces<'a>(reader: &'a Reader<'a>, row: TypeDef, generics: &'a [Type]) -> impl Iterator<Item = Type> + 'a { - reader.type_def_interface_impls(row).map(move |row| reader.interface_impl_type(row, generics)) -} - -pub fn type_underlying_type(reader: &Reader, ty: &Type) -> Type { - match ty { - Type::TypeDef(row, _) => reader.type_def_underlying_type(*row), - Type::HRESULT => Type::I32, - _ => ty.clone(), - } -} diff --git a/vendor/windows-bindgen/src/rdl/from_reader.rs b/vendor/windows-bindgen/src/rdl/from_reader.rs index 136430a9a..856e8a131 100644 --- a/vendor/windows-bindgen/src/rdl/from_reader.rs +++ b/vendor/windows-bindgen/src/rdl/from_reader.rs @@ -1,16 +1,16 @@ use super::*; use crate::tokens::{quote, to_ident, TokenStream}; use crate::{rdl, Error, Result, Tree}; -use metadata::RowReader; +use metadata::*; -pub fn from_reader(reader: &metadata::Reader, filter: &metadata::Filter, mut config: std::collections::BTreeMap<&str, &str>, output: &str) -> Result<()> { +pub fn from_reader(reader: &'static metadata::Reader, mut config: std::collections::BTreeMap<&str, &str>, output: &str) -> Result<()> { let dialect = match config.remove("type") { Some("winrt") => Dialect::WinRT, Some("win32") => Dialect::Win32, _ => return Err(Error::new("configuration value `type` must be `win32` or `winrt`")), }; - let mut writer = Writer::new(reader, filter, output, dialect); + let mut writer = Writer::new(reader, output, dialect); // TODO: be sure to use the same "split" key for winmd splitting. // May also want to support split=N similar to the way MIDLRT supports winmd splitting @@ -29,8 +29,8 @@ pub fn from_reader(reader: &metadata::Reader, filter: &metadata::Filter, mut con } fn gen_split(writer: &Writer) -> Result<()> { - let tree = Tree::new(writer.reader, writer.filter); - let directory = crate::directory(writer.output); + let tree = Tree::new(writer.reader); + let directory = crate::directory(&writer.output); // TODO: parallelize for tree in tree.flatten() { @@ -46,9 +46,9 @@ fn gen_split(writer: &Writer) -> Result<()> { } fn gen_file(writer: &Writer) -> Result<()> { - let tree = Tree::new(writer.reader, writer.filter); + let tree = Tree::new(writer.reader); let tokens = writer.tree(&tree); - writer.write_to_file(writer.output, tokens) + writer.write_to_file(&writer.output, tokens) } #[derive(Debug, Copy, Clone, PartialEq)] @@ -57,22 +57,21 @@ enum Dialect { WinRT, } -struct Writer<'a> { - reader: &'a metadata::Reader<'a>, - filter: &'a metadata::Filter<'a>, - namespace: &'a str, +struct Writer { + reader: &'static metadata::Reader, + namespace: &'static str, dialect: Dialect, split: bool, - output: &'a str, + output: String, } -impl<'a> Writer<'a> { - fn new(reader: &'a metadata::Reader, filter: &'a metadata::Filter, output: &'a str, dialect: Dialect) -> Self { - Self { reader, filter, namespace: "", output, dialect, split: false } +impl Writer { + fn new(reader: &'static metadata::Reader, output: &str, dialect: Dialect) -> Self { + Self { reader, namespace: "", output: output.to_string(), dialect, split: false } } - fn with_namespace(&self, namespace: &'a str) -> Self { - Self { reader: self.reader, filter: self.filter, namespace, dialect: self.dialect, output: self.output, split: self.split } + fn with_namespace(&self, namespace: &'static str) -> Self { + Self { reader: self.reader, namespace, dialect: self.dialect, output: self.output.clone(), split: self.split } } fn write_to_file(&self, output: &str, tokens: TokenStream) -> Result<()> { @@ -91,7 +90,7 @@ impl<'a> Writer<'a> { //crate::write_to_file(output, tokens.into_string()) } - fn tree(&self, tree: &'a Tree) -> TokenStream { + fn tree(&self, tree: &Tree) -> TokenStream { let items = self.items(tree); if self.split { @@ -129,15 +128,15 @@ impl<'a> Writer<'a> { } } - fn items(&self, tree: &'a Tree) -> TokenStream { + fn items(&self, tree: &Tree) -> TokenStream { let mut functions = vec![]; let mut constants = vec![]; let mut types = vec![]; if !tree.namespace.is_empty() { - for item in self.reader.namespace_items(tree.namespace, self.filter).filter(|item| match item { + for item in self.reader.namespace_items(tree.namespace).filter(|item| match item { metadata::Item::Type(def) => { - let winrt = self.reader.type_def_flags(*def).contains(metadata::TypeAttributes::WindowsRuntime); + let winrt = def.flags().contains(metadata::TypeAttributes::WindowsRuntime); match self.dialect { Dialect::Win32 => !winrt, Dialect::WinRT => winrt, @@ -148,7 +147,7 @@ impl<'a> Writer<'a> { match item { metadata::Item::Type(def) => types.push(self.type_def(def)), metadata::Item::Const(field) => constants.push(self.constant(field)), - metadata::Item::Fn(method, namespace) => functions.push(self.function(method, &namespace)), + metadata::Item::Fn(method, namespace) => functions.push(self.function(method, namespace)), } } } @@ -161,17 +160,17 @@ impl<'a> Writer<'a> { } fn function(&self, def: metadata::MethodDef, _namespace: &str) -> TokenStream { - let name = to_ident(self.reader.method_def_name(def)); + let name = to_ident(def.name()); quote! { fn #name(); } } fn constant(&self, def: metadata::Field) -> TokenStream { - let name = to_ident(self.reader.field_name(def)); + let name = to_ident(def.name()); quote! { const #name: i32 = 0; } } fn type_def(&self, def: metadata::TypeDef) -> TokenStream { - if let Some(extends) = self.reader.type_def_extends(def) { + if let Some(extends) = def.extends() { if extends.namespace == "System" { if extends.name == "Enum" { self.enum_def(def) @@ -191,7 +190,7 @@ impl<'a> Writer<'a> { } fn enum_def(&self, def: metadata::TypeDef) -> TokenStream { - let name = to_ident(self.reader.type_def_name(def)); + let name = to_ident(def.name()); quote! { struct #name { @@ -201,11 +200,11 @@ impl<'a> Writer<'a> { } fn struct_def(&self, def: metadata::TypeDef) -> TokenStream { - let name = to_ident(self.reader.type_def_name(def)); + let name = to_ident(def.name()); - let fields = self.reader.type_def_fields(def).map(|field| { - let name = to_ident(self.reader.field_name(field)); - let ty = self.ty(&self.reader.field_type(field, Some(def))); + let fields = def.fields().map(|field| { + let name = to_ident(field.name()); + let ty = self.ty(&field.ty(Some(def))); quote! { #name: #ty } @@ -219,7 +218,7 @@ impl<'a> Writer<'a> { } fn delegate_def(&self, def: metadata::TypeDef) -> TokenStream { - let name = to_ident(self.reader.type_def_name(def)); + let name = to_ident(def.name()); quote! { struct #name { @@ -229,7 +228,7 @@ impl<'a> Writer<'a> { } fn class_def(&self, def: metadata::TypeDef) -> TokenStream { - let name = to_ident(self.reader.type_def_name(def)); + let name = to_ident(def.name()); let implements = self.implements(def, &[]); quote! { @@ -238,20 +237,20 @@ impl<'a> Writer<'a> { } fn interface_def(&self, def: metadata::TypeDef) -> TokenStream { - let name = to_ident(self.reader.type_def_name(def)); - let generics = &metadata::type_def_generics(self.reader, def); + let name = to_ident(def.name()); + let generics = &metadata::type_def_generics(def); let implements = self.implements(def, generics); - let methods = self.reader.type_def_methods(def).map(|method| { - let name = to_ident(self.reader.method_def_name(method)); + let methods = def.methods().map(|method| { + let name = to_ident(method.name()); // TODO: use reader.method_def_signature instead - let signature = metadata::method_def_signature(self.reader, self.reader.type_def_namespace(def), method, generics); + let signature = metadata::method_def_signature(def.namespace(), method, generics); let return_type = self.return_type(&signature.return_type); let params = signature.params.iter().map(|param| { - let name = to_ident(self.reader.param_name(param.def)); + let name = to_ident(param.def.name()); let ty = self.ty(¶m.ty); quote! { #name: #ty } }); @@ -287,16 +286,15 @@ impl<'a> Writer<'a> { // TODO: then list default interface first // Then everything else - for imp in self.reader.type_def_interface_impls(def) { - let ty = self.reader.interface_impl_type(imp, generics); - if self.reader.has_attribute(imp, "DefaultAttribute") { - types.insert(0, self.ty(&ty)); + for interface in type_def_interfaces(def, generics) { + if interface.kind == InterfaceKind::Default { + types.insert(0, self.ty(&interface.ty)); } else { - types.push(self.ty(&ty)); + types.push(self.ty(&interface.ty)); } } - if let Some(type_name) = self.reader.type_def_extends(def) { + if let Some(type_name) = def.extends() { if type_name != metadata::TypeName::Object { let namespace = self.namespace(type_name.namespace); let name = to_ident(type_name.name); @@ -349,8 +347,8 @@ impl<'a> Writer<'a> { metadata::Type::IUnknown => quote! { IUnknown }, metadata::Type::TypeDef(def, generics) => { - let namespace = self.namespace(self.reader.type_def_namespace(*def)); - let name = to_ident(self.reader.type_def_name(*def)); + let namespace = self.namespace(def.namespace()); + let name = to_ident(def.name()); if generics.is_empty() { quote! { #namespace #name } } else { @@ -359,14 +357,13 @@ impl<'a> Writer<'a> { } } - metadata::Type::TypeRef(code) => { - let type_name = self.reader.type_def_or_ref(*code); + metadata::Type::TypeRef(type_name) => { let namespace = self.namespace(type_name.namespace); let name = to_ident(type_name.name); quote! { #namespace #name } } - metadata::Type::GenericParam(generic) => self.reader.generic_param_name(*generic).into(), + metadata::Type::GenericParam(generic) => generic.name().into(), metadata::Type::WinrtArray(ty) => self.ty(ty), metadata::Type::WinrtArrayRef(ty) => self.ty(ty), metadata::Type::ConstRef(ty) => self.ty(ty), diff --git a/vendor/windows-bindgen/src/rust/cfg.rs b/vendor/windows-bindgen/src/rust/cfg.rs index db77497bf..a6d9b4783 100644 --- a/vendor/windows-bindgen/src/rust/cfg.rs +++ b/vendor/windows-bindgen/src/rust/cfg.rs @@ -1,15 +1,15 @@ use super::*; #[derive(Default, Clone)] -pub struct Cfg<'a> { - pub types: BTreeMap<&'a str, BTreeSet<TypeDef>>, +pub struct Cfg { + pub types: BTreeMap<&'static str, BTreeSet<TypeDef>>, pub core_types: BTreeSet<Type>, pub arches: BTreeSet<&'static str>, pub implement: bool, } -impl<'a> Cfg<'a> { - pub fn add_feature(&mut self, feature: &'a str) { +impl Cfg { + pub fn add_feature(&mut self, feature: &'static str) { self.types.entry(feature).or_default(); } pub fn union(&self, other: &Self) -> Self { @@ -30,106 +30,98 @@ impl<'a> Cfg<'a> { } } -pub fn field_cfg<'a>(reader: &'a Reader<'a>, row: Field) -> Cfg<'a> { +pub fn field_cfg(row: Field) -> Cfg { let mut cfg = Cfg::default(); - field_cfg_combine(reader, row, None, &mut cfg); + field_cfg_combine(row, None, &mut cfg); cfg } -fn field_cfg_combine<'a>(reader: &'a Reader, row: Field, enclosing: Option<TypeDef>, cfg: &mut Cfg<'a>) { - type_cfg_combine(reader, &reader.field_type(row, enclosing), cfg) +fn field_cfg_combine(row: Field, enclosing: Option<TypeDef>, cfg: &mut Cfg) { + type_cfg_combine(&row.ty(enclosing), cfg) } -pub fn type_def_cfg<'a>(reader: &'a Reader, row: TypeDef, generics: &[Type]) -> Cfg<'a> { +pub fn type_def_cfg(row: TypeDef, generics: &[Type]) -> Cfg { let mut cfg = Cfg::default(); - type_def_cfg_combine(reader, row, generics, &mut cfg); - cfg_add_attributes(reader, &mut cfg, row); + type_def_cfg_combine(row, generics, &mut cfg); + cfg_add_attributes(&mut cfg, row); cfg } -pub fn type_def_cfg_impl<'a>(reader: &'a Reader, def: TypeDef, generics: &[Type]) -> Cfg<'a> { +pub fn type_def_cfg_impl(def: TypeDef, generics: &[Type]) -> Cfg { let mut cfg = Cfg { implement: true, ..Default::default() }; - fn combine<'a>(reader: &'a Reader, def: TypeDef, generics: &[Type], cfg: &mut Cfg<'a>) { - type_def_cfg_combine(reader, def, generics, cfg); + fn combine(def: TypeDef, generics: &[Type], cfg: &mut Cfg) { + type_def_cfg_combine(def, generics, cfg); - for method in reader.type_def_methods(def) { - signature_cfg_combine(reader, &reader.method_def_signature(method, generics), cfg); + for method in def.methods() { + signature_cfg_combine(&method.signature(generics), cfg); } } - combine(reader, def, generics, &mut cfg); + combine(def, generics, &mut cfg); - for def in type_def_vtables(reader, def) { - if let Type::TypeDef(def, generics) = def { - combine(reader, def, &generics, &mut cfg); + for interface in type_interfaces(&Type::TypeDef(def, generics.to_vec())) { + if let Type::TypeDef(def, generics) = interface.ty { + combine(def, &generics, &mut cfg); } } - if reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) { - for interface in type_def_interfaces(reader, def, generics) { - if let Type::TypeDef(def, generics) = interface { - combine(reader, def, &generics, &mut cfg); - } - } - } - - cfg_add_attributes(reader, &mut cfg, def); + cfg_add_attributes(&mut cfg, def); cfg } -pub fn type_def_cfg_combine<'a>(reader: &'a Reader, row: TypeDef, generics: &[Type], cfg: &mut Cfg<'a>) { - let type_name = reader.type_def_type_name(row); +pub fn type_def_cfg_combine(row: TypeDef, generics: &[Type], cfg: &mut Cfg) { + let type_name = row.type_name(); for generic in generics { - type_cfg_combine(reader, generic, cfg); + type_cfg_combine(generic, cfg); } if cfg.types.entry(type_name.namespace).or_default().insert(row) { - match reader.type_def_kind(row) { + match row.kind() { TypeKind::Class => { - if let Some(default_interface) = type_def_default_interface(reader, row) { - type_cfg_combine(reader, &default_interface, cfg); + if let Some(default_interface) = type_def_default_interface(row) { + type_cfg_combine(&default_interface, cfg); } } TypeKind::Interface => { - if !reader.type_def_flags(row).contains(TypeAttributes::WindowsRuntime) { - for def in type_def_vtables(reader, row) { + if !row.flags().contains(TypeAttributes::WindowsRuntime) { + for def in type_def_vtables(row) { if let Type::TypeDef(def, _) = def { - cfg.add_feature(reader.type_def_namespace(def)); + cfg.add_feature(def.namespace()); } } } } TypeKind::Struct => { - reader.type_def_fields(row).for_each(|field| field_cfg_combine(reader, field, Some(row), cfg)); + row.fields().for_each(|field| field_cfg_combine(field, Some(row), cfg)); if !type_name.namespace.is_empty() { - for def in reader.get_type_def(type_name) { + for def in row.reader().get_type_def(type_name.namespace, type_name.name) { if def != row { - type_def_cfg_combine(reader, def, &[], cfg); + type_def_cfg_combine(def, &[], cfg); } } } } - TypeKind::Delegate => signature_cfg_combine(reader, &reader.method_def_signature(type_def_invoke_method(reader, row), generics), cfg), + TypeKind::Delegate => signature_cfg_combine(&type_def_invoke_method(row).signature(generics), cfg), _ => {} } } } -pub fn signature_cfg<'a>(reader: &'a Reader, method: MethodDef) -> Cfg<'a> { +pub fn signature_cfg(method: MethodDef) -> Cfg { let mut cfg = Cfg::default(); - signature_cfg_combine(reader, &reader.method_def_signature(method, &[]), &mut cfg); - cfg_add_attributes(reader, &mut cfg, method); + signature_cfg_combine(&method.signature(&[]), &mut cfg); + cfg_add_attributes(&mut cfg, method); cfg } -fn signature_cfg_combine<'a>(reader: &'a Reader, signature: &MethodDefSig, cfg: &mut Cfg<'a>) { - type_cfg_combine(reader, &signature.return_type, cfg); - signature.params.iter().for_each(|param| type_cfg_combine(reader, param, cfg)); +fn signature_cfg_combine(signature: &MethodDefSig, cfg: &mut Cfg) { + type_cfg_combine(&signature.return_type, cfg); + signature.params.iter().for_each(|param| type_cfg_combine(param, cfg)); } -fn cfg_add_attributes<R: AsRow + Into<HasAttribute>>(reader: &Reader, cfg: &mut Cfg, row: R) { - for attribute in reader.attributes(row) { - match reader.attribute_name(attribute) { +fn cfg_add_attributes<R: AsRow + Into<HasAttribute>>(cfg: &mut Cfg, row: R) { + for attribute in row.attributes() { + match attribute.name() { "SupportedArchitectureAttribute" => { - if let Some((_, Value::EnumDef(_, value))) = reader.attribute_args(attribute).get(0) { + if let Some((_, Value::EnumDef(_, value))) = attribute.args().first() { if let Value::I32(value) = **value { if value & 1 == 1 { cfg.arches.insert("x86"); @@ -151,19 +143,20 @@ fn cfg_add_attributes<R: AsRow + Into<HasAttribute>>(reader: &Reader, cfg: &mut } } -pub fn type_cfg<'a>(reader: &'a Reader, ty: &Type) -> Cfg<'a> { +pub fn type_cfg(ty: &Type) -> Cfg { let mut cfg = Cfg::default(); - type_cfg_combine(reader, ty, &mut cfg); + type_cfg_combine(ty, &mut cfg); cfg } -fn type_cfg_combine<'a>(reader: &'a Reader, ty: &Type, cfg: &mut Cfg<'a>) { + +fn type_cfg_combine(ty: &Type, cfg: &mut Cfg) { match ty { - Type::TypeDef(row, generics) => type_def_cfg_combine(reader, *row, generics, cfg), - Type::Win32Array(ty, _) => type_cfg_combine(reader, ty, cfg), - Type::ConstPtr(ty, _) => type_cfg_combine(reader, ty, cfg), - Type::MutPtr(ty, _) => type_cfg_combine(reader, ty, cfg), - Type::WinrtArray(ty) => type_cfg_combine(reader, ty, cfg), - Type::WinrtArrayRef(ty) => type_cfg_combine(reader, ty, cfg), + Type::TypeDef(row, generics) => type_def_cfg_combine(*row, generics, cfg), + Type::Win32Array(ty, _) => type_cfg_combine(ty, cfg), + Type::ConstPtr(ty, _) => type_cfg_combine(ty, cfg), + Type::MutPtr(ty, _) => type_cfg_combine(ty, cfg), + Type::WinrtArray(ty) => type_cfg_combine(ty, cfg), + Type::WinrtArrayRef(ty) => type_cfg_combine(ty, cfg), ty => _ = cfg.core_types.insert(ty.clone()), } } diff --git a/vendor/windows-bindgen/src/rust/classes.rs b/vendor/windows-bindgen/src/rust/classes.rs index 397abff10..d30cde31a 100644 --- a/vendor/windows-bindgen/src/rust/classes.rs +++ b/vendor/windows-bindgen/src/rust/classes.rs @@ -2,8 +2,8 @@ use super::*; pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream { if writer.sys { - if type_def_has_default_interface(writer.reader, def) { - let name = to_ident(writer.reader.type_def_name(def)); + if def.interface_impls().next().is_some() { + let name = to_ident(def.name()); quote! { pub type #name = *mut ::core::ffi::c_void; } @@ -16,16 +16,16 @@ pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream { } fn gen_class(writer: &Writer, def: TypeDef) -> TokenStream { - if writer.reader.type_def_extends(def) == Some(TypeName::Attribute) { + if def.extends() == Some(TypeName::Attribute) { return TokenStream::new(); } - let name = to_ident(writer.reader.type_def_name(def)); - let interfaces = type_interfaces(writer.reader, &Type::TypeDef(def, Vec::new())); + let name = to_ident(def.name()); + let interfaces = type_interfaces(&Type::TypeDef(def, Vec::new())); let mut methods = quote! {}; let mut method_names = MethodNames::new(); - let cfg = type_def_cfg(writer.reader, def, &[]); + let cfg = type_def_cfg(def, &[]); let doc = writer.cfg_doc(&cfg); let features = writer.cfg_features(&cfg); @@ -33,7 +33,7 @@ fn gen_class(writer: &Writer, def: TypeDef) -> TokenStream { if let Type::TypeDef(def, generics) = &interface.ty { let mut virtual_names = MethodNames::new(); - for method in writer.reader.type_def_methods(*def) { + for method in def.methods() { methods.combine(&winrt_methods::writer(writer, *def, generics, interface.kind, method, &mut method_names, &mut virtual_names)); } } @@ -42,9 +42,9 @@ fn gen_class(writer: &Writer, def: TypeDef) -> TokenStream { let factories = interfaces.iter().filter_map(|interface| match interface.kind { InterfaceKind::Static => { if let Type::TypeDef(def, generics) = &interface.ty { - if writer.reader.type_def_methods(*def).next().is_some() { + if def.methods().next().is_some() { let interface_type = writer.type_name(&interface.ty); - let features = writer.cfg_features(&type_def_cfg(writer.reader, *def, generics)); + let features = writer.cfg_features(&type_def_cfg(*def, generics)); return Some(quote! { #[doc(hidden)] @@ -64,8 +64,8 @@ fn gen_class(writer: &Writer, def: TypeDef) -> TokenStream { _ => None, }); - if type_def_has_default_interface(writer.reader, def) { - let new = if type_def_has_default_constructor(writer.reader, def) { + if def.interface_impls().next().is_some() { + let new = if type_def_has_default_constructor(def) { quote! { pub fn new() -> ::windows_core::Result<Self> { Self::IActivationFactory(|f| f.ActivateInstance::<Self>()) @@ -86,6 +86,7 @@ fn gen_class(writer: &Writer, def: TypeDef) -> TokenStream { #doc #features #[repr(transparent)] + #[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)] pub struct #name(::windows_core::IUnknown); #features impl #name { @@ -95,7 +96,6 @@ fn gen_class(writer: &Writer, def: TypeDef) -> TokenStream { } }; - tokens.combine(&writer.interface_core_traits(def, &[], &name, &TokenStream::new(), &TokenStream::new(), &features)); tokens.combine(&writer.interface_winrt_trait(def, &[], &name, &TokenStream::new(), &TokenStream::new(), &features)); tokens.combine(&writer.interface_trait(def, &[], &name, &TokenStream::new(), &features, true)); tokens.combine(&writer.runtime_name_trait(def, &[], &name, &TokenStream::new(), &features)); @@ -129,7 +129,7 @@ fn gen_conversions(writer: &Writer, def: TypeDef, name: &TokenStream, interfaces }; for interface in interfaces { - if type_is_exclusive(writer.reader, &interface.ty) { + if type_is_exclusive(&interface.ty) { continue; } @@ -138,7 +138,7 @@ fn gen_conversions(writer: &Writer, def: TypeDef, name: &TokenStream, interfaces } let into = writer.type_name(&interface.ty); - let features = writer.cfg_features(&cfg.union(&type_cfg(writer.reader, &interface.ty))); + let features = writer.cfg_features(&cfg.union(&type_cfg(&interface.ty))); tokens.combine("e! { #features @@ -146,9 +146,9 @@ fn gen_conversions(writer: &Writer, def: TypeDef, name: &TokenStream, interfaces }); } - for def in type_def_bases(writer.reader, def) { + for def in type_def_bases(def) { let into = writer.type_def_name(def, &[]); - let features = writer.cfg_features(&cfg.union(&type_def_cfg(writer.reader, def, &[]))); + let features = writer.cfg_features(&cfg.union(&type_def_cfg(def, &[]))); tokens.combine("e! { #features @@ -158,3 +158,23 @@ fn gen_conversions(writer: &Writer, def: TypeDef, name: &TokenStream, interfaces tokens } + +fn type_def_has_default_constructor(row: TypeDef) -> bool { + for attribute in row.attributes() { + if attribute.name() == "ActivatableAttribute" { + if attribute.args().iter().any(|arg| matches!(arg.1, Value::TypeName(_))) { + continue; + } else { + return true; + } + } + } + false +} + +fn type_is_exclusive(ty: &Type) -> bool { + match ty { + Type::TypeDef(row, _) => type_def_is_exclusive(*row), + _ => false, + } +} diff --git a/vendor/windows-bindgen/src/rust/com_methods.rs b/vendor/windows-bindgen/src/rust/com_methods.rs index 132e7f220..7a9e64d74 100644 --- a/vendor/windows-bindgen/src/rust/com_methods.rs +++ b/vendor/windows-bindgen/src/rust/com_methods.rs @@ -1,14 +1,14 @@ use super::*; pub fn writer(writer: &Writer, def: TypeDef, kind: InterfaceKind, method: MethodDef, method_names: &mut MethodNames, virtual_names: &mut MethodNames, base_count: usize) -> TokenStream { - let signature = method_def_signature(writer.reader, writer.reader.type_def_namespace(def), method, &[]); + let signature = method_def_signature(def.namespace(), method, &[]); - let name = method_names.add(writer, method); - let vname = virtual_names.add(writer, method); + let name = method_names.add(method); + let vname = virtual_names.add(method); let generics = writer.constraint_generics(&signature.params); let where_clause = writer.where_clause(&signature.params); - let mut cfg = signature_cfg(writer.reader, method); - cfg.add_feature(writer.reader.type_def_namespace(def)); + let mut cfg = signature_cfg(method); + cfg.add_feature(def.namespace()); let doc = writer.cfg_method_doc(&cfg); let features = writer.cfg_features(&cfg); @@ -22,7 +22,7 @@ pub fn writer(writer: &Writer, def: TypeDef, kind: InterfaceKind, method: Method bases.combine("e! { .base__ }); } - let kind = signature_kind(writer.reader, &signature); + let kind = signature.kind(); match kind { SignatureKind::Query(_) => { let args = writer.win32_args(&signature.params, kind); @@ -84,7 +84,7 @@ pub fn writer(writer: &Writer, def: TypeDef, kind: InterfaceKind, method: Method let args = writer.win32_args(&signature.params, kind); let params = writer.win32_params(&signature.params, kind); let return_type = signature.params[signature.params.len() - 1].ty.deref(); - let is_nullable = type_is_nullable(writer.reader, &return_type); + let is_nullable = type_is_nullable(&return_type); let return_type = writer.type_name(&return_type); if is_nullable { @@ -153,7 +153,7 @@ pub fn writer(writer: &Writer, def: TypeDef, kind: InterfaceKind, method: Method } pub fn gen_upcall(writer: &Writer, sig: &Signature, inner: TokenStream) -> TokenStream { - match signature_kind(writer.reader, sig) { + match sig.kind() { SignatureKind::ResultValue => { let invoke_args = sig.params[..sig.params.len() - 1].iter().map(|param| gen_win32_invoke_arg(writer, param)); @@ -197,9 +197,9 @@ pub fn gen_upcall(writer: &Writer, sig: &Signature, inner: TokenStream) -> Token fn gen_win32_invoke_arg(writer: &Writer, param: &SignatureParam) -> TokenStream { let name = writer.param_name(param.def); - if writer.reader.param_flags(param.def).contains(ParamAttributes::In) && type_is_nullable(writer.reader, ¶m.ty) { + if param.def.flags().contains(ParamAttributes::In) && type_is_nullable(¶m.ty) { quote! { ::windows_core::from_raw_borrowed(&#name) } - } else if (!param.ty.is_pointer() && type_is_nullable(writer.reader, ¶m.ty)) || (writer.reader.param_flags(param.def).contains(ParamAttributes::In) && !type_is_primitive(writer.reader, ¶m.ty)) { + } else if (!param.ty.is_pointer() && type_is_nullable(¶m.ty)) || (param.def.flags().contains(ParamAttributes::In) && !type_is_primitive(¶m.ty)) { quote! { ::core::mem::transmute(&#name) } } else { quote! { ::core::mem::transmute_copy(&#name) } diff --git a/vendor/windows-bindgen/src/rust/constants.rs b/vendor/windows-bindgen/src/rust/constants.rs index 672dbcc8a..5acca64b9 100644 --- a/vendor/windows-bindgen/src/rust/constants.rs +++ b/vendor/windows-bindgen/src/rust/constants.rs @@ -1,27 +1,27 @@ use super::*; pub fn writer(writer: &Writer, def: Field) -> TokenStream { - let name = to_ident(writer.reader.field_name(def)); - let ty = writer.reader.field_type(def, None).to_const_type(); - let cfg = field_cfg(writer.reader, def); + let name = to_ident(def.name()); + let ty = def.ty(None).to_const_type(); + let cfg = field_cfg(def); let doc = writer.cfg_doc(&cfg); let features = writer.cfg_features(&cfg); - if let Some(constant) = writer.reader.field_constant(def) { - let constant_type = writer.reader.constant_type(constant); + if let Some(constant) = def.constant() { + let constant_type = constant.ty(); if ty == constant_type { if ty == Type::String { let crate_name = writer.crate_name(); - if field_is_ansi(writer.reader, def) { - let value = writer.value(&writer.reader.constant_value(constant)); + if field_is_ansi(def) { + let value = writer.value(&constant.value()); quote! { #doc #features pub const #name: #crate_name PCSTR = #crate_name s!(#value); } } else { - let value = writer.value(&writer.reader.constant_value(constant)); + let value = writer.value(&constant.value()); quote! { #doc #features @@ -29,7 +29,7 @@ pub fn writer(writer: &Writer, def: Field) -> TokenStream { } } } else { - let value = writer.typed_value(&writer.reader.constant_value(constant)); + let value = writer.typed_value(&constant.value()); quote! { #doc #features @@ -38,8 +38,8 @@ pub fn writer(writer: &Writer, def: Field) -> TokenStream { } } else { let kind = writer.type_default_name(&ty); - let value = writer.value(&writer.reader.constant_value(constant)); - let underlying_type = type_underlying_type(writer.reader, &ty); + let value = writer.value(&constant.value()); + let underlying_type = type_underlying_type(&ty); let value = if underlying_type == constant_type { value @@ -49,7 +49,7 @@ pub fn writer(writer: &Writer, def: Field) -> TokenStream { quote! { #value as _ } }; - if !writer.sys && type_has_replacement(writer.reader, &ty) { + if !writer.sys && type_has_replacement(&ty) { quote! { #doc #features @@ -63,7 +63,7 @@ pub fn writer(writer: &Writer, def: Field) -> TokenStream { } } } - } else if let Some(guid) = field_guid(writer.reader, def) { + } else if let Some(guid) = field_guid(def) { let value = writer.guid(&guid); let guid = writer.type_name(&Type::GUID); quote! { @@ -84,19 +84,19 @@ pub fn writer(writer: &Writer, def: Field) -> TokenStream { } fn initializer(writer: &Writer, def: Field) -> Option<TokenStream> { - let Some(value) = constant(writer, def) else { + let Some(value) = constant(def) else { return None; }; let mut input = value.as_str(); - let Type::TypeDef(def, _) = writer.reader.field_type(def, None) else { + let Type::TypeDef(def, _) = def.ty(None) else { unimplemented!(); }; let mut result = quote! {}; - for field in writer.reader.type_def_fields(def) { + for field in def.fields() { let (value, rest) = field_initializer(writer, field, input); input = rest; result.combine(&value); @@ -106,12 +106,12 @@ fn initializer(writer: &Writer, def: Field) -> Option<TokenStream> { } fn field_initializer<'a>(writer: &Writer, field: Field, input: &'a str) -> (TokenStream, &'a str) { - let name = to_ident(writer.reader.field_name(field)); + let name = to_ident(field.name()); - match writer.reader.field_type(field, None) { + match field.ty(None) { Type::GUID => { let (literals, rest) = read_literal_array(input, 11); - let value = writer.guid(&GUID::from_string_args(&literals)); + let value = writer.guid(&Guid::from_string_args(&literals)); (quote! { #name: #value, }, rest) } Type::Win32Array(_, len) => { @@ -127,9 +127,9 @@ fn field_initializer<'a>(writer: &Writer, field: Field, input: &'a str) -> (Toke } } -fn constant(writer: &Writer, def: Field) -> Option<String> { - writer.reader.find_attribute(def, "ConstantAttribute").map(|attribute| { - let args = writer.reader.attribute_args(attribute); +fn constant(def: Field) -> Option<String> { + def.find_attribute("ConstantAttribute").map(|attribute| { + let args = attribute.args(); match &args[0].1 { Value::String(value) => value.clone(), rest => unimplemented!("{rest:?}"), @@ -183,3 +183,27 @@ fn read_literal_array(input: &str, len: usize) -> (Vec<&str>, &str) { (result, read_token(input, b'}')) } + +fn field_guid(row: Field) -> Option<Guid> { + row.find_attribute("GuidAttribute").map(|attribute| Guid::from_args(&attribute.args())) +} + +fn field_is_ansi(row: Field) -> bool { + row.find_attribute("NativeEncodingAttribute").is_some_and(|attribute| matches!(attribute.args().first(), Some((_, Value::String(encoding))) if encoding == "ansi")) +} + +fn type_has_replacement(ty: &Type) -> bool { + match ty { + Type::HRESULT | Type::PCSTR | Type::PCWSTR => true, + Type::TypeDef(row, _) => type_def_is_handle(*row) || row.kind() == TypeKind::Enum, + _ => false, + } +} + +fn type_underlying_type(ty: &Type) -> Type { + match ty { + Type::TypeDef(row, _) => row.underlying_type(), + Type::HRESULT => Type::I32, + _ => ty.clone(), + } +} diff --git a/vendor/windows-bindgen/src/rust/delegates.rs b/vendor/windows-bindgen/src/rust/delegates.rs index 5b1b12022..479d8db62 100644 --- a/vendor/windows-bindgen/src/rust/delegates.rs +++ b/vendor/windows-bindgen/src/rust/delegates.rs @@ -1,7 +1,7 @@ use super::*; pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream { - if writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) { + if def.flags().contains(TypeAttributes::WindowsRuntime) { gen_delegate(writer, def) } else { gen_callback(writer, def) @@ -9,13 +9,13 @@ pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream { } fn gen_callback(writer: &Writer, def: TypeDef) -> TokenStream { - let name = to_ident(writer.reader.type_def_name(def)); - let method = type_def_invoke_method(writer.reader, def); + let name = to_ident(def.name()); + let method = type_def_invoke_method(def); - let signature = method_def_signature(writer.reader, writer.reader.type_def_namespace(def), method, &[]); + let signature = method_def_signature(def.namespace(), method, &[]); let return_type = writer.return_sig(&signature); - let cfg = type_def_cfg(writer.reader, def, &[]); + let cfg = type_def_cfg(def, &[]); let doc = writer.cfg_doc(&cfg); let features = writer.cfg_features(&cfg); @@ -34,7 +34,7 @@ fn gen_callback(writer: &Writer, def: TypeDef) -> TokenStream { fn gen_delegate(writer: &Writer, def: TypeDef) -> TokenStream { if writer.sys { - let name = to_ident(writer.reader.type_def_name(def)); + let name = to_ident(def.name()); quote! { pub type #name = *mut ::core::ffi::c_void; } @@ -44,23 +44,23 @@ fn gen_delegate(writer: &Writer, def: TypeDef) -> TokenStream { } fn gen_win_delegate(writer: &Writer, def: TypeDef) -> TokenStream { - let name = to_ident(writer.reader.type_def_name(def)); + let name = to_ident(def.name()); let vtbl = name.join("_Vtbl"); let boxed = name.join("Box"); - let generics = &type_def_generics(writer.reader, def); + let generics = &type_def_generics(def); let phantoms = writer.generic_phantoms(generics); let named_phantoms = writer.generic_named_phantoms(generics); let constraints = writer.generic_constraints(generics); let generic_names = writer.generic_names(generics); let ident = writer.type_def_name(def, generics); - let method = type_def_invoke_method(writer.reader, def); + let method = type_def_invoke_method(def); - let signature = method_def_signature(writer.reader, writer.reader.type_def_namespace(def), method, generics); + let signature = method_def_signature(def.namespace(), method, generics); let fn_constraint = gen_fn_constraint(writer, def, &signature); - let cfg = type_def_cfg(writer.reader, def, generics); + let cfg = type_def_cfg(def, generics); let doc = writer.cfg_doc(&cfg); let features = writer.cfg_features(&cfg); @@ -72,6 +72,7 @@ fn gen_win_delegate(writer: &Writer, def: TypeDef) -> TokenStream { #doc #features #[repr(transparent)] + #[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)] pub struct #ident(pub ::windows_core::IUnknown, #phantoms) where #constraints; #features impl<#constraints> #ident { @@ -101,12 +102,16 @@ fn gen_win_delegate(writer: &Writer, def: TypeDef) -> TokenStream { Invoke: Self::Invoke, #(#named_phantoms)* }; - unsafe extern "system" fn QueryInterface(this: *mut ::core::ffi::c_void, iid: &::windows_core::GUID, interface: *mut *const ::core::ffi::c_void) -> ::windows_core::HRESULT { + unsafe extern "system" fn QueryInterface(this: *mut ::core::ffi::c_void, iid: *const ::windows_core::GUID, interface: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT { let this = this as *mut *mut ::core::ffi::c_void as *mut Self; - *interface = if iid == &<#ident as ::windows_core::ComInterface>::IID || - iid == &<::windows_core::IUnknown as ::windows_core::ComInterface>::IID || - iid == &<::windows_core::imp::IAgileObject as ::windows_core::ComInterface>::IID { + if iid.is_null() || interface.is_null() { + return ::windows_core::HRESULT(-2147467261); // E_POINTER + } + + *interface = if *iid == <#ident as ::windows_core::ComInterface>::IID || + *iid == <::windows_core::IUnknown as ::windows_core::ComInterface>::IID || + *iid == <::windows_core::imp::IAgileObject as ::windows_core::ComInterface>::IID { &mut (*this).vtable as *mut _ as _ } else { ::core::ptr::null_mut() @@ -142,7 +147,6 @@ fn gen_win_delegate(writer: &Writer, def: TypeDef) -> TokenStream { } }; - tokens.combine(&writer.interface_core_traits(def, generics, &ident, &constraints, &phantoms, &features)); tokens.combine(&writer.interface_trait(def, generics, &ident, &constraints, &features, true)); tokens.combine(&writer.interface_winrt_trait(def, generics, &ident, &constraints, &phantoms, &features)); tokens.combine(&writer.interface_vtbl(def, generics, &ident, &constraints, &features)); diff --git a/vendor/windows-bindgen/src/rust/enums.rs b/vendor/windows-bindgen/src/rust/enums.rs index 344ca28ae..3039aebd0 100644 --- a/vendor/windows-bindgen/src/rust/enums.rs +++ b/vendor/windows-bindgen/src/rust/enums.rs @@ -1,26 +1,25 @@ use super::*; pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream { - let type_name = writer.reader.type_def_type_name(def); + let type_name = def.type_name(); let ident = to_ident(type_name.name); - let underlying_type = writer.reader.type_def_underlying_type(def); + let underlying_type = def.underlying_type(); let underlying_type = writer.type_name(&underlying_type); // TODO: unscoped enums should be removed from metadata - let is_scoped = writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) || writer.reader.has_attribute(def, "ScopedEnumAttribute"); + let is_scoped = def.flags().contains(TypeAttributes::WindowsRuntime) || def.has_attribute("ScopedEnumAttribute"); - let cfg = type_def_cfg(writer.reader, def, &[]); + let cfg = type_def_cfg(def, &[]); let doc = writer.cfg_doc(&cfg); let features = writer.cfg_features(&cfg); - let fields: Vec<(TokenStream, TokenStream)> = writer - .reader - .type_def_fields(def) + let fields: Vec<(TokenStream, TokenStream)> = def + .fields() .filter_map(|field| { - if writer.reader.field_flags(field).contains(FieldAttributes::Literal) { - let field_name = to_ident(writer.reader.field_name(field)); - let constant = writer.reader.field_constant(field).unwrap(); - let value = writer.value(&writer.reader.constant_value(constant)); + if field.flags().contains(FieldAttributes::Literal) { + let field_name = to_ident(field.name()); + let constant = field.constant().unwrap(); + let value = writer.value(&constant.value()); Some((field_name, value)) } else { @@ -111,7 +110,7 @@ pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream { // Win32 enums use the Flags attribute. WinRT enums don't have the Flags attribute but are paritioned merely based // on whether they are signed. // TODO: Win32 metadata should just follow WinRT's example here. - let type_def_is_flags = writer.reader.has_attribute(def, "FlagsAttribute") || (writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) && writer.reader.type_def_underlying_type(def) == Type::U32); + let type_def_is_flags = def.has_attribute("FlagsAttribute") || (def.flags().contains(TypeAttributes::WindowsRuntime) && def.underlying_type() == Type::U32); if type_def_is_flags { tokens.combine("e! { @@ -160,8 +159,8 @@ pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream { }); } - if writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) { - let signature = Literal::byte_string(type_def_signature(writer.reader, def, &[]).as_bytes()); + if def.flags().contains(TypeAttributes::WindowsRuntime) { + let signature = Literal::byte_string(type_def_signature(def, &[]).as_bytes()); tokens.combine("e! { #features diff --git a/vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/MapView.rs b/vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/MapView.rs index 72b39f56e..9176b5d90 100644 --- a/vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/MapView.rs +++ b/vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/MapView.rs @@ -44,7 +44,7 @@ where V::from_default(value) } fn Size(&self) -> ::windows_core::Result<u32> { - Ok(self.map.len() as u32) + Ok(self.map.len().try_into()?) } fn HasKey(&self, key: &K::Default) -> ::windows_core::Result<bool> { Ok(self.map.contains_key(key)) diff --git a/vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/VectorView.rs b/vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/VectorView.rs index cc482b70f..561681b16 100644 --- a/vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/VectorView.rs +++ b/vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/VectorView.rs @@ -38,7 +38,7 @@ where T::from_default(item) } fn Size(&self) -> ::windows_core::Result<u32> { - Ok(self.values.len() as u32) + Ok(self.values.len().try_into()?) } fn IndexOf(&self, value: &T::Default, result: &mut u32) -> ::windows_core::Result<bool> { match self.values.iter().position(|element| element == value) { diff --git a/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/BOOLEAN.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/BOOLEAN.rs index dd113d100..33b32a8d6 100644 --- a/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/BOOLEAN.rs +++ b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/BOOLEAN.rs @@ -66,3 +66,8 @@ impl ::core::ops::Not for BOOLEAN { } } } +impl ::windows_core::IntoParam<BOOLEAN> for bool { + fn into_param(self) -> ::windows_core::Param<BOOLEAN> { + ::windows_core::Param::Owned(self.into()) + } +} diff --git a/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/WIN32_ERROR.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/WIN32_ERROR.rs index 2c9441efb..bb994bd66 100644 --- a/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/WIN32_ERROR.rs +++ b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/WIN32_ERROR.rs @@ -9,7 +9,7 @@ impl WIN32_ERROR { } #[inline] pub const fn to_hresult(self) -> ::windows_core::HRESULT { - ::windows_core::HRESULT(if self.0 == 0 { self.0 } else { (self.0 & 0x0000_FFFF) | (7 << 16) | 0x8000_0000 } as i32) + ::windows_core::HRESULT::from_win32(self.0) } #[inline] pub fn from_error(error: &::windows_core::Error) -> ::core::option::Option<Self> { diff --git a/vendor/windows-bindgen/src/rust/functions.rs b/vendor/windows-bindgen/src/rust/functions.rs index 2dd4e0157..82199866a 100644 --- a/vendor/windows-bindgen/src/rust/functions.rs +++ b/vendor/windows-bindgen/src/rust/functions.rs @@ -2,13 +2,13 @@ use super::*; pub fn writer(writer: &Writer, namespace: &str, def: MethodDef) -> TokenStream { // TODO: remove inline functions from metadata - if writer.reader.method_def_module_name(def) == "forceinline" { + if def.module_name() == "forceinline" { return quote! {}; } // TODO: remove ordinal functions from metadata - if let Some(impl_map) = writer.reader.method_def_impl_map(def) { - if writer.reader.impl_map_import_name(impl_map).starts_with('#') { + if let Some(impl_map) = def.impl_map() { + if impl_map.import_name().starts_with('#') { return quote! {}; } } @@ -21,25 +21,25 @@ pub fn writer(writer: &Writer, namespace: &str, def: MethodDef) -> TokenStream { } fn gen_sys_function(writer: &Writer, namespace: &str, def: MethodDef) -> TokenStream { - let signature = method_def_signature(writer.reader, namespace, def, &[]); - let cfg = signature_cfg(writer.reader, def); + let signature = method_def_signature(namespace, def, &[]); + let cfg = signature_cfg(def); let mut tokens = writer.cfg_features(&cfg); tokens.combine(&gen_link(writer, namespace, &signature, &cfg)); tokens } fn gen_win_function(writer: &Writer, namespace: &str, def: MethodDef) -> TokenStream { - let name = to_ident(writer.reader.method_def_name(def)); - let signature = method_def_signature(writer.reader, namespace, def, &[]); + let name = to_ident(def.name()); + let signature = method_def_signature(namespace, def, &[]); 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 = signature_cfg(writer.reader, def); + let cfg = signature_cfg(def); let doc = writer.cfg_doc(&cfg); let features = writer.cfg_features(&cfg); let link = gen_link(writer, namespace, &signature, &cfg); - let kind = signature_kind(writer.reader, &signature); + let kind = signature.kind(); match kind { SignatureKind::Query(_) => { let args = writer.win32_args(&signature.params, kind); @@ -109,7 +109,7 @@ fn gen_win_function(writer: &Writer, namespace: &str, def: MethodDef) -> TokenSt let args = writer.win32_args(&signature.params, kind); let params = writer.win32_params(&signature.params, kind); let return_type = signature.params[signature.params.len() - 1].ty.deref(); - let is_nullable = type_is_nullable(writer.reader, &return_type); + let is_nullable = type_is_nullable(&return_type); let return_type = writer.type_name(&return_type); if is_nullable { @@ -139,7 +139,7 @@ fn gen_win_function(writer: &Writer, namespace: &str, def: MethodDef) -> TokenSt } } SignatureKind::ReturnStruct | SignatureKind::PreserveSig => { - if handle_last_error(writer, def, &signature) { + if handle_last_error(def, &signature) { let args = writer.win32_args(&signature.params, kind); let params = writer.win32_params(&signature.params, kind); let return_type = writer.type_name(&signature.return_type); @@ -172,7 +172,7 @@ fn gen_win_function(writer: &Writer, namespace: &str, def: MethodDef) -> TokenSt SignatureKind::ReturnVoid => { let args = writer.win32_args(&signature.params, kind); let params = writer.win32_params(&signature.params, kind); - let does_not_return = does_not_return(writer, def); + let does_not_return = does_not_return(def); quote! { #doc @@ -188,12 +188,12 @@ fn gen_win_function(writer: &Writer, namespace: &str, def: MethodDef) -> TokenSt } fn gen_link(writer: &Writer, namespace: &str, signature: &Signature, cfg: &Cfg) -> TokenStream { - let name = writer.reader.method_def_name(signature.def); + let name = signature.def.name(); let ident = to_ident(name); - let library = writer.reader.method_def_module_name(signature.def); - let abi = method_def_extern_abi(writer.reader, signature.def); + let library = signature.def.module_name(); + let abi = method_def_extern_abi(signature.def); - let symbol = if let Some(impl_map) = writer.reader.method_def_impl_map(signature.def) { writer.reader.impl_map_import_name(impl_map) } else { name }; + let symbol = if let Some(impl_map) = signature.def.impl_map() { impl_map.import_name() } else { name }; let link_name = if symbol != name { quote! { #[link_name = #symbol] } @@ -225,14 +225,6 @@ fn gen_link(writer: &Writer, namespace: &str, signature: &Signature, cfg: &Cfg) pub fn #ident(#(#params,)* #vararg) #return_type; } } - } else if let Some(library) = method_def_static_lib(writer.reader, signature.def) { - quote! { - #[link(name = #library, kind = "static")] - extern #abi { - #link_name - pub fn #ident(#(#params,)* #vararg) #return_type; - } - } } else { let symbol = if symbol != name { format!(" \"{symbol}\"") } else { String::new() }; @@ -248,23 +240,23 @@ fn gen_link(writer: &Writer, namespace: &str, signature: &Signature, cfg: &Cfg) } } -fn does_not_return(writer: &Writer, def: MethodDef) -> TokenStream { - if writer.reader.has_attribute(def, "DoesNotReturnAttribute") { +fn does_not_return(def: MethodDef) -> TokenStream { + if def.has_attribute("DoesNotReturnAttribute") { quote! { -> ! } } else { quote! {} } } -fn handle_last_error(writer: &Writer, def: MethodDef, signature: &Signature) -> bool { - if let Some(map) = writer.reader.method_def_impl_map(def) { - if writer.reader.impl_map_flags(map).contains(PInvokeAttributes::SupportsLastError) { +fn handle_last_error(def: MethodDef, signature: &Signature) -> bool { + if let Some(map) = def.impl_map() { + if map.flags().contains(PInvokeAttributes::SupportsLastError) { if let Type::TypeDef(return_type, _) = &signature.return_type { - if type_def_is_handle(writer.reader, *return_type) { - if writer.reader.type_def_underlying_type(*return_type).is_pointer() { + if type_def_is_handle(*return_type) { + if return_type.underlying_type().is_pointer() { return true; } - if !type_def_invalid_values(writer.reader, *return_type).is_empty() { + if !type_def_invalid_values(*return_type).is_empty() { return true; } } @@ -273,3 +265,16 @@ fn handle_last_error(writer: &Writer, def: MethodDef, signature: &Signature) -> } false } + +fn method_def_extern_abi(def: MethodDef) -> &'static str { + let impl_map = def.impl_map().expect("ImplMap not found"); + let flags = impl_map.flags(); + + if flags.contains(PInvokeAttributes::CallConvPlatformapi) { + "system" + } else if flags.contains(PInvokeAttributes::CallConvCdecl) { + "cdecl" + } else { + unimplemented!() + } +} diff --git a/vendor/windows-bindgen/src/rust/handles.rs b/vendor/windows-bindgen/src/rust/handles.rs index e213679e0..ef06b8bbc 100644 --- a/vendor/windows-bindgen/src/rust/handles.rs +++ b/vendor/windows-bindgen/src/rust/handles.rs @@ -9,8 +9,8 @@ pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream { } pub fn gen_sys_handle(writer: &Writer, def: TypeDef) -> TokenStream { - let ident = to_ident(writer.reader.type_def_name(def)); - match writer.reader.type_def_underlying_type(def) { + let ident = to_ident(def.name()); + match def.underlying_type() { Type::ISize if writer.std => quote! { pub type #ident = *mut ::core::ffi::c_void; }, @@ -25,9 +25,9 @@ pub fn gen_sys_handle(writer: &Writer, def: TypeDef) -> TokenStream { } pub fn gen_win_handle(writer: &Writer, def: TypeDef) -> TokenStream { - let name = writer.reader.type_def_name(def); + let name = def.name(); let ident = to_ident(name); - let underlying_type = writer.reader.type_def_underlying_type(def); + let underlying_type = def.underlying_type(); let signature = writer.type_default_name(&underlying_type); let check = if underlying_type.is_pointer() { quote! { @@ -38,7 +38,7 @@ pub fn gen_win_handle(writer: &Writer, def: TypeDef) -> TokenStream { } } } else { - let invalid = type_def_invalid_values(writer.reader, def); + let invalid = type_def_invalid_values(def); if !invalid.is_empty() { let invalid = invalid.iter().map(|value| { @@ -89,8 +89,8 @@ pub fn gen_win_handle(writer: &Writer, def: TypeDef) -> TokenStream { } }; - if let Some(dependency) = type_def_usable_for(writer.reader, def) { - let type_name = writer.reader.type_def_type_name(dependency); + if let Some(dependency) = type_def_usable_for(def) { + let type_name = dependency.type_name(); let mut dependency = writer.namespace(type_name.namespace); dependency.push_str(type_name.name); @@ -106,3 +106,12 @@ pub fn gen_win_handle(writer: &Writer, def: TypeDef) -> TokenStream { tokens } + +fn type_def_usable_for(row: TypeDef) -> Option<TypeDef> { + if let Some(attribute) = row.find_attribute("AlsoUsableForAttribute") { + if let Some((_, Value::String(name))) = attribute.args().first() { + return row.reader().get_type_def(row.namespace(), name.as_str()).next(); + } + } + None +} diff --git a/vendor/windows-bindgen/src/rust/implements.rs b/vendor/windows-bindgen/src/rust/implements.rs index 742ae9984..d06d8f8f1 100644 --- a/vendor/windows-bindgen/src/rust/implements.rs +++ b/vendor/windows-bindgen/src/rust/implements.rs @@ -1,24 +1,24 @@ use super::*; pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream { - if writer.reader.type_def_kind(def) != TypeKind::Interface || (!writer.implement && writer.reader.has_attribute(def, "ExclusiveToAttribute")) { + if def.kind() != TypeKind::Interface || (!writer.implement && def.has_attribute("ExclusiveToAttribute")) { return quote! {}; } - let generics = &type_def_generics(writer.reader, def); - let type_ident = to_ident(writer.reader.type_def_name(def)); + let generics = &type_def_generics(def); + let type_ident = to_ident(def.name()); let impl_ident = type_ident.join("_Impl"); let vtbl_ident = type_ident.join("_Vtbl"); let implvtbl_ident = impl_ident.join("Vtbl"); let constraints = writer.generic_constraints(generics); let generic_names = writer.generic_names(generics); let named_phantoms = writer.generic_named_phantoms(generics); - let cfg = type_def_cfg_impl(writer.reader, def, generics); + let cfg = type_def_cfg_impl(def, generics); let doc = writer.cfg_doc(&cfg); let features = writer.cfg_features(&cfg); let mut requires = quote! {}; let type_ident = quote! { #type_ident<#generic_names> }; - let vtables = type_def_vtables(writer.reader, def); + let vtables = type_def_vtables(def); let has_unknown_base = matches!(vtables.first(), Some(Type::IUnknown)); fn gen_required_trait(writer: &Writer, def: TypeDef, generics: &[Type]) -> TokenStream { @@ -28,7 +28,7 @@ pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream { } } - let mut matches = quote! { iid == &<#type_ident as ::windows_core::ComInterface>::IID }; + let mut matches = quote! { *iid == <#type_ident as ::windows_core::ComInterface>::IID }; if let Some(Type::TypeDef(def, _)) = vtables.last() { requires.combine(&gen_required_trait(writer, *def, &[])) @@ -39,14 +39,14 @@ pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream { let name = writer.type_def_name(*def, generics); matches.combine("e! { - || iid == &<#name as ::windows_core::ComInterface>::IID + || *iid == <#name as ::windows_core::ComInterface>::IID }) } } - if writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) { + if def.flags().contains(TypeAttributes::WindowsRuntime) { // TODO: this awkward wrapping of TypeDefs needs fixing - for interface in type_interfaces(writer.reader, &Type::TypeDef(def, generics.to_vec())) { + for interface in type_interfaces(&Type::TypeDef(def, generics.to_vec())) { if let Type::TypeDef(def, generics) = interface.ty { requires.combine(&gen_required_trait(writer, def, &generics)); } @@ -56,26 +56,26 @@ pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream { let runtime_name = writer.runtime_name_trait(def, generics, &type_ident, &constraints, &features); let mut method_names = MethodNames::new(); - method_names.add_vtable_types(writer, def); + method_names.add_vtable_types(def); - let method_traits = writer.reader.type_def_methods(def).map(|method| { - let name = method_names.add(writer, method); + let method_traits = def.methods().map(|method| { + let name = method_names.add(method); - let signature = method_def_signature(writer.reader, writer.reader.type_def_namespace(def), method, generics); + let signature = method_def_signature(def.namespace(), method, generics); let signature_tokens = writer.impl_signature(def, &signature); quote! { fn #name #signature_tokens; } }); let mut method_names = MethodNames::new(); - method_names.add_vtable_types(writer, def); + method_names.add_vtable_types(def); - let method_impls = writer.reader.type_def_methods(def).map(|method| { - let name = method_names.add(writer, method); - let signature = method_def_signature(writer.reader, writer.reader.type_def_namespace(def), method, generics); + let method_impls = def.methods().map(|method| { + let name = method_names.add(method); + let signature = method_def_signature(def.namespace(), method, generics); let vtbl_signature = writer.vtbl_signature(def, generics, &signature); - let invoke_upcall = if writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) { winrt_methods::gen_upcall(writer, &signature, quote! { this.#name }) } else { com_methods::gen_upcall(writer, &signature, quote! { this.#name }) }; + let invoke_upcall = if def.flags().contains(TypeAttributes::WindowsRuntime) { winrt_methods::gen_upcall(writer, &signature, quote! { this.#name }) } else { com_methods::gen_upcall(writer, &signature, quote! { this.#name }) }; if has_unknown_base { quote! { @@ -114,10 +114,10 @@ pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream { } let mut method_names = MethodNames::new(); - method_names.add_vtable_types(writer, def); + method_names.add_vtable_types(def); - for method in writer.reader.type_def_methods(def) { - let name = method_names.add(writer, method); + for method in def.methods() { + let name = method_names.add(method); if has_unknown_base { methods.combine("e! { #name: #name::<#generic_names Identity, Impl, OFFSET>, }); } else { @@ -142,7 +142,7 @@ pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream { #(#named_phantoms)* } } - pub fn matches(iid: &::windows_core::GUID) -> bool { + pub unsafe fn matches(iid: *const ::windows_core::GUID) -> bool { #matches } } diff --git a/vendor/windows-bindgen/src/rust/interfaces.rs b/vendor/windows-bindgen/src/rust/interfaces.rs index a552af433..05ef63e01 100644 --- a/vendor/windows-bindgen/src/rust/interfaces.rs +++ b/vendor/windows-bindgen/src/rust/interfaces.rs @@ -2,17 +2,17 @@ use super::*; pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream { if writer.sys { - gen_sys_interface(writer, def) + gen_sys_interface(def) } else { gen_win_interface(writer, def) } } -fn gen_sys_interface(writer: &Writer, def: TypeDef) -> TokenStream { - let name = writer.reader.type_def_name(def); +fn gen_sys_interface(def: TypeDef) -> TokenStream { + let name = def.name(); let ident = to_ident(name); - if type_def_is_exclusive(writer.reader, def) { + if type_def_is_exclusive(def) { quote! {} } else { quote! { @@ -22,16 +22,16 @@ fn gen_sys_interface(writer: &Writer, def: TypeDef) -> TokenStream { } fn gen_win_interface(writer: &Writer, def: TypeDef) -> TokenStream { - let generics = &type_def_generics(writer.reader, def); + let generics = &type_def_generics(def); let ident = writer.type_def_name(def, generics); - let is_exclusive = type_def_is_exclusive(writer.reader, def); + let is_exclusive = type_def_is_exclusive(def); let phantoms = writer.generic_phantoms(generics); let constraints = writer.generic_constraints(generics); - let cfg = type_def_cfg(writer.reader, def, &[]); + let cfg = type_def_cfg(def, &[]); let doc = writer.cfg_doc(&cfg); let features = writer.cfg_features(&cfg); - let interfaces = type_interfaces(writer.reader, &Type::TypeDef(def, generics.to_vec())); - let vtables = type_def_vtables(writer.reader, def); + let interfaces = type_interfaces(&Type::TypeDef(def, generics.to_vec())); + let vtables = type_def_vtables(def); let has_unknown_base = matches!(vtables.first(), Some(Type::IUnknown)); let mut tokens = if is_exclusive { @@ -44,12 +44,14 @@ fn gen_win_interface(writer: &Writer, def: TypeDef) -> TokenStream { tokens.combine("e! { #features #[repr(transparent)] + #[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)] pub struct #ident(::windows_core::IUnknown, #phantoms) where #constraints; }); } else { tokens.combine("e! { #features #[repr(transparent)] + #[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)] pub struct #ident(::std::ptr::NonNull<::std::ffi::c_void>); }); } @@ -61,13 +63,13 @@ fn gen_win_interface(writer: &Writer, def: TypeDef) -> TokenStream { let method_names = &mut MethodNames::new(); let virtual_names = &mut MethodNames::new(); - if writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) { - for method in writer.reader.type_def_methods(def) { + if def.flags().contains(TypeAttributes::WindowsRuntime) { + for method in def.methods() { methods.combine(&winrt_methods::writer(writer, def, generics, InterfaceKind::Default, method, method_names, virtual_names)); } for interface in &interfaces { if let Type::TypeDef(def, generics) = &interface.ty { - for method in writer.reader.type_def_methods(*def) { + for method in def.methods() { methods.combine(&winrt_methods::writer(writer, *def, generics, InterfaceKind::None, method, method_names, virtual_names)); } } @@ -78,8 +80,8 @@ fn gen_win_interface(writer: &Writer, def: TypeDef) -> TokenStream { match ty { Type::IUnknown | Type::IInspectable => {} Type::TypeDef(def, _) => { - let kind = if writer.reader.type_def_type_name(*def) == TypeName::IDispatch { InterfaceKind::None } else { InterfaceKind::Default }; - for method in writer.reader.type_def_methods(*def) { + let kind = if def.type_name() == TypeName::IDispatch { InterfaceKind::None } else { InterfaceKind::Default }; + for method in def.methods() { methods.combine(&com_methods::writer(writer, *def, kind, method, method_names, virtual_names, bases)); } } @@ -88,7 +90,7 @@ fn gen_win_interface(writer: &Writer, def: TypeDef) -> TokenStream { bases -= 1; } - for method in writer.reader.type_def_methods(def) { + for method in def.methods() { methods.combine(&com_methods::writer(writer, def, InterfaceKind::Default, method, method_names, virtual_names, 0)); } } @@ -108,7 +110,7 @@ fn gen_win_interface(writer: &Writer, def: TypeDef) -> TokenStream { let into = writer.type_name(ty); write!(&mut hierarchy, ", {into}").unwrap(); - hierarchy_cfg = hierarchy_cfg.union(&type_cfg(writer.reader, ty)); + hierarchy_cfg = hierarchy_cfg.union(&type_cfg(ty)); } hierarchy.push_str(");"); @@ -117,7 +119,7 @@ fn gen_win_interface(writer: &Writer, def: TypeDef) -> TokenStream { } else { for ty in &vtables { let into = writer.type_name(ty); - let cfg = writer.cfg_features(&cfg.union(&type_cfg(writer.reader, ty))); + let cfg = writer.cfg_features(&cfg.union(&type_cfg(ty))); tokens.combine("e! { #cfg impl<#constraints> ::windows_core::CanInto<#into> for #ident {} @@ -125,10 +127,10 @@ fn gen_win_interface(writer: &Writer, def: TypeDef) -> TokenStream { } } - if writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) { + if def.flags().contains(TypeAttributes::WindowsRuntime) { for interface in &interfaces { let into = writer.type_name(&interface.ty); - let cfg = writer.cfg_features(&cfg.union(&type_cfg(writer.reader, &interface.ty))); + let cfg = writer.cfg_features(&cfg.union(&type_cfg(&interface.ty))); tokens.combine("e! { #cfg impl<#constraints> ::windows_core::CanTryInto<#into> for #ident {} @@ -136,7 +138,6 @@ fn gen_win_interface(writer: &Writer, def: TypeDef) -> TokenStream { } } - tokens.combine(&writer.interface_core_traits(def, generics, &ident, &constraints, &phantoms, &features)); tokens.combine(&writer.interface_winrt_trait(def, generics, &ident, &constraints, &phantoms, &features)); tokens.combine(&writer.async_get(def, generics, &ident, &constraints, &phantoms, &features)); tokens.combine(&iterators::writer(writer, def, generics, &ident, &constraints, &phantoms, &cfg)); diff --git a/vendor/windows-bindgen/src/rust/iterators.rs b/vendor/windows-bindgen/src/rust/iterators.rs index 63ba56aaf..76483129c 100644 --- a/vendor/windows-bindgen/src/rust/iterators.rs +++ b/vendor/windows-bindgen/src/rust/iterators.rs @@ -1,7 +1,7 @@ use super::*; pub fn writer(writer: &Writer, def: TypeDef, generics: &[Type], ident: &TokenStream, constraints: &TokenStream, _phantoms: &TokenStream, cfg: &Cfg) -> TokenStream { - match writer.reader.type_def_type_name(def) { + match def.type_name() { // If the type is IIterator<T> then simply implement the Iterator trait over top. TypeName::IIterator => { return quote! { @@ -143,17 +143,17 @@ pub fn writer(writer: &Writer, def: TypeDef, generics: &[Type], ident: &TokenStr let wfc = writer.namespace("Windows.Foundation.Collections"); let mut iterable = None; - let interfaces = type_interfaces(writer.reader, &Type::TypeDef(def, generics.to_vec())); + let interfaces = type_interfaces(&Type::TypeDef(def, generics.to_vec())); // If the class or interface is not one of the well-known collection interfaces, we then see whether it // implements any one of them. Here is where we favor IVectorView/IVector over IIterable. for interface in interfaces { if let Type::TypeDef(interface, interface_generics) = &interface.ty { - match writer.reader.type_def_type_name(*interface) { + match interface.type_name() { TypeName::IVectorView => { let item = writer.type_name(&interface_generics[0]); let mut cfg = cfg.clone(); - type_def_cfg_combine(writer.reader, *interface, interface_generics, &mut cfg); + type_def_cfg_combine(*interface, interface_generics, &mut cfg); let features = writer.cfg_features(&cfg); return quote! { @@ -180,7 +180,7 @@ pub fn writer(writer: &Writer, def: TypeDef, generics: &[Type], ident: &TokenStr TypeName::IVector => { let item = writer.type_name(&interface_generics[0]); let mut cfg = cfg.clone(); - type_def_cfg_combine(writer.reader, *interface, interface_generics, &mut cfg); + type_def_cfg_combine(*interface, interface_generics, &mut cfg); let features = writer.cfg_features(&cfg); return quote! { @@ -217,7 +217,7 @@ pub fn writer(writer: &Writer, def: TypeDef, generics: &[Type], ident: &TokenStr Some((interface, interface_generics)) => { let item = writer.type_name(&interface_generics[0]); let mut cfg = cfg.clone(); - type_def_cfg_combine(writer.reader, interface, &interface_generics, &mut cfg); + type_def_cfg_combine(interface, &interface_generics, &mut cfg); let features = writer.cfg_features(&cfg); quote! { diff --git a/vendor/windows-bindgen/src/rust/method_names.rs b/vendor/windows-bindgen/src/rust/method_names.rs index 2d5a508ae..14a9d6501 100644 --- a/vendor/windows-bindgen/src/rust/method_names.rs +++ b/vendor/windows-bindgen/src/rust/method_names.rs @@ -7,8 +7,8 @@ impl MethodNames { Self(BTreeMap::new()) } - pub fn add(&mut self, writer: &Writer, method: MethodDef) -> TokenStream { - let name = method_def_special_name(writer.reader, method); + pub fn add(&mut self, method: MethodDef) -> TokenStream { + let name = method_def_special_name(method); let overload = self.0.entry(name.to_string()).or_insert(0); *overload += 1; if *overload > 1 { @@ -18,13 +18,39 @@ impl MethodNames { } } - pub fn add_vtable_types(&mut self, writer: &Writer, def: TypeDef) { - for def in type_def_vtables(writer.reader, def) { + pub fn add_vtable_types(&mut self, def: TypeDef) { + for def in type_def_vtables(def) { if let Type::TypeDef(def, _) = def { - for method in writer.reader.type_def_methods(def) { - self.add(writer, method); + for method in def.methods() { + self.add(method); } } } } } + +fn method_def_special_name(row: MethodDef) -> String { + let name = row.name(); + if row.flags().contains(MethodAttributes::SpecialName) { + if name.starts_with("get") { + name[4..].to_string() + } else if name.starts_with("put") { + format!("Set{}", &name[4..]) + } else if name.starts_with("add") { + name[4..].to_string() + } else if name.starts_with("remove") { + format!("Remove{}", &name[7..]) + } else { + name.to_string() + } + } else { + if let Some(attribute) = row.find_attribute("OverloadAttribute") { + for (_, arg) in attribute.args() { + if let Value::String(name) = arg { + return name; + } + } + } + name.to_string() + } +} diff --git a/vendor/windows-bindgen/src/rust/mod.rs b/vendor/windows-bindgen/src/rust/mod.rs index 0f781c8f8..342a6879a 100644 --- a/vendor/windows-bindgen/src/rust/mod.rs +++ b/vendor/windows-bindgen/src/rust/mod.rs @@ -21,14 +21,15 @@ use crate::{Error, Result, Tree}; use cfg::*; use rayon::prelude::*; -pub fn from_reader(reader: &metadata::Reader, filter: &metadata::Filter, mut config: std::collections::BTreeMap<&str, &str>, output: &str) -> Result<()> { - let mut writer = Writer::new(reader, filter, output); +pub fn from_reader(reader: &'static metadata::Reader, mut config: std::collections::BTreeMap<&str, &str>, output: &str) -> Result<()> { + let mut writer = Writer::new(reader, output); writer.package = config.remove("package").is_some(); writer.flatten = config.remove("flatten").is_some(); writer.std = config.remove("std").is_some(); writer.sys = writer.std || config.remove("sys").is_some(); writer.implement = config.remove("implement").is_some(); writer.minimal = config.remove("minimal").is_some(); + writer.no_inner_attributes = config.remove("no-inner-attributes").is_some(); if writer.package && writer.flatten { return Err(Error::new("cannot combine `package` and `flatten` configuration values")); @@ -55,22 +56,22 @@ fn gen_file(writer: &Writer) -> Result<()> { if writer.flatten { let tokens = standalone::standalone_imp(writer); - crate::write_to_file(writer.output, try_format(writer, &tokens)) + crate::write_to_file(&writer.output, try_format(writer, &tokens)) } else { let mut tokens = String::new(); - let root = Tree::new(writer.reader, writer.filter); + let root = Tree::new(writer.reader); for tree in root.nested.values() { tokens.push_str(&namespace(writer, tree)); } - crate::write_to_file(writer.output, try_format(writer, &tokens)) + crate::write_to_file(&writer.output, try_format(writer, &tokens)) } } fn gen_package(writer: &Writer) -> Result<()> { - let directory = crate::directory(writer.output); - let root = Tree::new(writer.reader, writer.filter); + let directory = crate::directory(&writer.output); + let root = Tree::new(writer.reader); let mut root_len = 0; for tree in root.nested.values() { @@ -143,10 +144,12 @@ fn namespace(writer: &Writer, tree: &Tree) -> String { for (name, tree) in &tree.nested { let name = to_ident(name); - let namespace_feature = tree.namespace[tree.namespace.find('.').unwrap() + 1..].replace('.', "_"); + let feature = tree.namespace[tree.namespace.find('.').unwrap() + 1..].replace('.', "_"); + let doc = format!(r#"Required features: `\"{feature}\"`"#); if writer.package { tokens.combine("e! { - #[cfg(feature = #namespace_feature)] + #[cfg(feature = #feature)] + #[doc = #doc] pub mod #name; }); } else { @@ -160,10 +163,10 @@ fn namespace(writer: &Writer, tree: &Tree) -> String { let mut functions = BTreeMap::<&str, TokenStream>::new(); let mut types = BTreeMap::<TypeKind, BTreeMap<&str, TokenStream>>::new(); - for item in writer.reader.namespace_items(writer.namespace, writer.filter) { + for item in writer.reader.namespace_items(writer.namespace) { match item { Item::Type(def) => { - let type_name = writer.reader.type_def_type_name(def); + let type_name = def.type_name(); if REMAP_TYPES.iter().any(|(x, _)| x == &type_name) { continue; } @@ -171,22 +174,22 @@ fn namespace(writer: &Writer, tree: &Tree) -> String { continue; } let name = type_name.name; - let kind = writer.reader.type_def_kind(def); + let kind = def.kind(); match kind { TypeKind::Class => { - if writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) { + if def.flags().contains(TypeAttributes::WindowsRuntime) { types.entry(kind).or_default().insert(name, classes::writer(writer, def)); } } TypeKind::Interface => types.entry(kind).or_default().entry(name).or_default().combine(&interfaces::writer(writer, def)), TypeKind::Enum => types.entry(kind).or_default().entry(name).or_default().combine(&enums::writer(writer, def)), TypeKind::Struct => { - if writer.reader.type_def_fields(def).next().is_none() { - if let Some(guid) = type_def_guid(writer.reader, def) { + if def.fields().next().is_none() { + if let Some(guid) = type_def_guid(def) { let ident = to_ident(name); let value = writer.guid(&guid); let guid = writer.type_name(&Type::GUID); - let cfg = type_def_cfg(writer.reader, def, &[]); + let cfg = type_def_cfg(def, &[]); let doc = writer.cfg_doc(&cfg); let constant = quote! { #doc @@ -202,11 +205,11 @@ fn namespace(writer: &Writer, tree: &Tree) -> String { } } Item::Fn(def, namespace) => { - let name = writer.reader.method_def_name(def); - functions.entry(name).or_default().combine(&functions::writer(writer, &namespace, def)); + let name = def.name(); + functions.entry(name).or_default().combine(&functions::writer(writer, namespace, def)); } Item::Const(def) => { - let name = writer.reader.field_name(def); + let name = def.name(); types.entry(TypeKind::Class).or_default().entry(name).or_default().combine(&constants::writer(writer, def)); } } @@ -234,13 +237,13 @@ fn namespace_impl(writer: &Writer, tree: &Tree) -> String { writer.namespace = tree.namespace; let mut types = BTreeMap::<&str, TokenStream>::new(); - for item in writer.reader.namespace_items(writer.namespace, writer.filter) { + for item in writer.reader.namespace_items(tree.namespace) { if let Item::Type(def) = item { - let type_name = writer.reader.type_def_type_name(def); + let type_name = def.type_name(); if CORE_TYPES.iter().any(|(x, _)| x == &type_name) { continue; } - if writer.reader.type_def_kind(def) != TypeKind::Interface { + if def.kind() != TypeKind::Interface { continue; } let tokens = implements::writer(writer, def); diff --git a/vendor/windows-bindgen/src/rust/standalone.rs b/vendor/windows-bindgen/src/rust/standalone.rs index f74c34647..7ac9e0a55 100644 --- a/vendor/windows-bindgen/src/rust/standalone.rs +++ b/vendor/windows-bindgen/src/rust/standalone.rs @@ -5,12 +5,12 @@ pub fn standalone_imp(writer: &Writer) -> String { let mut functions = BTreeSet::new(); let mut constants = BTreeSet::new(); - for item in writer.reader.items(writer.filter) { - item_collect_standalone(writer.reader, item.clone(), &mut types); + for item in writer.reader.items() { + item_collect_standalone(item.clone(), &mut types); match item { Item::Type(_) => {} - Item::Fn(def, namespace) => _ = functions.insert((def, namespace.clone())), + Item::Fn(def, namespace) => _ = functions.insert((def, namespace)), Item::Const(def) => _ = constants.insert(def), } } @@ -54,10 +54,10 @@ pub fn standalone_imp(writer: &Writer) -> String { ); } Type::TypeDef(def, _) => { - let kind = writer.reader.type_def_kind(def); + let kind = def.kind(); match kind { TypeKind::Class => { - let name = writer.reader.type_def_name(def); + let name = def.name(); if writer.sys { let ident = to_ident(name); sorted.insert(name, quote! { pub type #ident = *mut ::core::ffi::c_void; }); @@ -66,7 +66,7 @@ pub fn standalone_imp(writer: &Writer) -> String { } } TypeKind::Interface => { - let name = writer.reader.type_def_name(def); + let name = def.name(); if writer.sys { let ident = to_ident(name); sorted.insert(name, quote! { pub type #ident = *mut ::core::ffi::c_void; }); @@ -75,12 +75,12 @@ pub fn standalone_imp(writer: &Writer) -> String { } } TypeKind::Enum => { - sorted.insert(writer.reader.type_def_name(def), enums::writer(writer, def)); + sorted.insert(def.name(), enums::writer(writer, def)); } TypeKind::Struct => { - let name = writer.reader.type_def_name(def); - if writer.reader.type_def_fields(def).next().is_none() { - if let Some(guid) = type_def_guid(writer.reader, def) { + let name = def.name(); + if def.fields().next().is_none() { + if let Some(guid) = type_def_guid(def) { let ident = to_ident(name); let value = writer.guid(&guid); let guid = writer.type_name(&Type::GUID); @@ -96,7 +96,7 @@ pub fn standalone_imp(writer: &Writer) -> String { sorted.insert(name, structs::writer(writer, def)); } TypeKind::Delegate => { - sorted.insert(writer.reader.type_def_name(def), delegates::writer(writer, def)); + sorted.insert(def.name(), delegates::writer(writer, def)); } } } @@ -105,11 +105,11 @@ pub fn standalone_imp(writer: &Writer) -> String { } for (function, namespace) in functions { - sorted.insert(&format!(".{}.{}", writer.reader.method_def_module_name(function), writer.reader.method_def_name(function)), functions::writer(writer, &namespace, function)); + sorted.insert(&format!(".{}.{}", function.module_name(), function.name()), functions::writer(writer, namespace, function)); } for constant in constants { - sorted.insert(writer.reader.field_name(constant), constants::writer(writer, constant)); + sorted.insert(constant.name(), constants::writer(writer, constant)); } let mut tokens = TokenStream::new(); @@ -126,19 +126,19 @@ impl SortedTokens { } } -fn item_collect_standalone(reader: &Reader, item: Item, set: &mut BTreeSet<Type>) { +fn item_collect_standalone(item: Item, set: &mut BTreeSet<Type>) { match item { - Item::Type(def) => type_collect_standalone(reader, &Type::TypeDef(def, vec![]), set), - Item::Const(def) => type_collect_standalone(reader, &reader.field_type(def, None).to_const_type(), set), + Item::Type(def) => type_collect_standalone(&Type::TypeDef(def, vec![]), set), + Item::Const(def) => type_collect_standalone(&def.ty(None).to_const_type(), set), Item::Fn(def, namespace) => { - let signature = method_def_signature(reader, &namespace, def, &[]); - type_collect_standalone(reader, &signature.return_type, set); - signature.params.iter().for_each(|param| type_collect_standalone(reader, ¶m.ty, set)); + let signature = method_def_signature(namespace, def, &[]); + type_collect_standalone(&signature.return_type, set); + signature.params.iter().for_each(|param| type_collect_standalone(¶m.ty, set)); } } } // TODO: remove or move to riddle -fn type_collect_standalone(reader: &Reader, ty: &Type, set: &mut BTreeSet<Type>) { +fn type_collect_standalone(ty: &Type, set: &mut BTreeSet<Type>) { let ty = ty.to_underlying_type(); if !set.insert(ty.clone()) { return; @@ -157,60 +157,60 @@ fn type_collect_standalone(reader: &Reader, ty: &Type, set: &mut BTreeSet<Type>) // // Note this is a bit overeager as we can collect a typedef that is used // by one architecture but not by another - let type_name = reader.type_def_type_name(def); + let type_name = def.type_name(); if !type_name.namespace.is_empty() { - for row in reader.get_type_def(type_name) { + for row in def.reader().get_type_def(type_name.namespace, type_name.name) { if def != row { - type_collect_standalone(reader, &Type::TypeDef(row, Vec::new()), set); + type_collect_standalone(&Type::TypeDef(row, Vec::new()), set); } } } for generic in generics { - type_collect_standalone(reader, generic, set); + type_collect_standalone(generic, set); } - for field in reader.type_def_fields(def) { - let ty = reader.field_type(field, Some(def)); + for field in def.fields() { + let ty = field.ty(Some(def)); if let Type::TypeDef(def, _) = &ty { - if reader.type_def_namespace(*def).is_empty() { + if def.namespace().is_empty() { continue; } } - type_collect_standalone(reader, &ty, set); + type_collect_standalone(&ty, set); } - for method in reader.type_def_methods(def) { + for method in def.methods() { // Skip delegate pseudo-constructors. - if reader.method_def_name(method) == ".ctor" { + if method.name() == ".ctor" { continue; } - let signature = method_def_signature(reader, reader.type_def_namespace(def), method, generics); - type_collect_standalone(reader, &signature.return_type, set); - signature.params.iter().for_each(|param| type_collect_standalone(reader, ¶m.ty, set)); + let signature = method_def_signature(def.namespace(), method, generics); + type_collect_standalone(&signature.return_type, set); + signature.params.iter().for_each(|param| type_collect_standalone(¶m.ty, set)); } - for interface in type_interfaces(reader, &ty) { - type_collect_standalone(reader, &interface.ty, set); + for interface in type_interfaces(&ty) { + type_collect_standalone(&interface.ty, set); } - if reader.type_def_kind(def) == TypeKind::Struct && reader.type_def_fields(def).next().is_none() && type_def_guid(reader, def).is_some() { + if def.kind() == TypeKind::Struct && def.fields().next().is_none() && type_def_guid(def).is_some() { set.insert(Type::GUID); } - type_collect_standalone_nested(reader, def, set); + type_collect_standalone_nested(def, set); } -fn type_collect_standalone_nested(reader: &Reader, td: TypeDef, set: &mut BTreeSet<Type>) { - for nested in reader.nested_types(td) { - type_collect_standalone_nested(reader, nested, set); +fn type_collect_standalone_nested(td: TypeDef, set: &mut BTreeSet<Type>) { + for nested in td.reader().nested_types(td) { + type_collect_standalone_nested(nested, set); - for field in reader.type_def_fields(nested) { - let ty = reader.field_type(field, Some(nested)); + for field in nested.fields() { + let ty = field.ty(Some(nested)); if let Type::TypeDef(def, _) = &ty { // Skip the fields that actually refer to the anonymous nested // type, otherwise it will get added to the typeset and emitted - if reader.type_def_namespace(*def).is_empty() { + if def.namespace().is_empty() { continue; } - type_collect_standalone(reader, &ty, set); + type_collect_standalone(&ty, set); } } } diff --git a/vendor/windows-bindgen/src/rust/structs.rs b/vendor/windows-bindgen/src/rust/structs.rs index 249b293dc..dda7fc21b 100644 --- a/vendor/windows-bindgen/src/rust/structs.rs +++ b/vendor/windows-bindgen/src/rust/structs.rs @@ -1,21 +1,21 @@ use super::*; pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream { - if writer.reader.has_attribute(def, "ApiContractAttribute") { + if def.has_attribute("ApiContractAttribute") { return quote! {}; } - if type_def_is_handle(writer.reader, def) { + if type_def_is_handle(def) { return handles::writer(writer, def); } - gen_struct_with_name(writer, def, writer.reader.type_def_name(def), &Cfg::default()) + gen_struct_with_name(writer, def, def.name(), &Cfg::default()) } fn gen_struct_with_name(writer: &Writer, def: TypeDef, struct_name: &str, cfg: &Cfg) -> TokenStream { let name = to_ident(struct_name); - if writer.reader.type_def_fields(def).next().is_none() { + if def.fields().next().is_none() { let mut tokens = quote! { #[repr(C)] pub struct #name(pub u8); @@ -36,26 +36,26 @@ fn gen_struct_with_name(writer: &Writer, def: TypeDef, struct_name: &str, cfg: & return tokens; } - let flags = writer.reader.type_def_flags(def); - let cfg = cfg.union(&type_def_cfg(writer.reader, def, &[])); + let flags = def.flags(); + let cfg = cfg.union(&type_def_cfg(def, &[])); - let repr = if let Some(layout) = writer.reader.type_def_class_layout(def) { - let packing = Literal::usize_unsuffixed(writer.reader.class_layout_packing_size(layout)); + let repr = if let Some(layout) = def.class_layout() { + let packing = Literal::usize_unsuffixed(layout.packing_size()); quote! { #[repr(C, packed(#packing))] } } else { quote! { #[repr(C)] } }; - let fields = writer.reader.type_def_fields(def).map(|f| { - let name = to_ident(writer.reader.field_name(f)); - let ty = writer.reader.field_type(f, Some(def)); + let fields = def.fields().map(|f| { + let name = to_ident(f.name()); + let ty = f.ty(Some(def)); - if writer.reader.field_flags(f).contains(FieldAttributes::Literal) { + if f.flags().contains(FieldAttributes::Literal) { quote! {} - } else if !writer.sys && flags.contains(TypeAttributes::ExplicitLayout) && !field_is_copyable(writer.reader, f, def) { + } else if !writer.sys && flags.contains(TypeAttributes::ExplicitLayout) && !field_is_copyable(f, def) { let ty = writer.type_default_name(&ty); quote! { pub #name: ::std::mem::ManuallyDrop<#ty>, } - } else if !writer.sys && !flags.contains(TypeAttributes::WindowsRuntime) && !field_is_blittable(writer.reader, f, def) { + } else if !writer.sys && !flags.contains(TypeAttributes::WindowsRuntime) && !field_is_blittable(f, def) { if let Type::Win32Array(ty, len) = ty { let ty = writer.type_default_name(&ty); quote! { pub #name: [::std::mem::ManuallyDrop<#ty>; #len], } @@ -115,7 +115,7 @@ fn gen_windows_traits(writer: &Writer, def: TypeDef, name: &TokenStream, cfg: &C quote! {} } else { let features = writer.cfg_features(cfg); - let is_copy = type_def_is_blittable(writer.reader, def); + let is_copy = type_def_is_blittable(def); let type_kind = if is_copy { quote! { CopyType } @@ -130,8 +130,8 @@ fn gen_windows_traits(writer: &Writer, def: TypeDef, name: &TokenStream, cfg: &C } }; - if writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) { - let signature = Literal::byte_string(type_def_signature(writer.reader, def, &[]).as_bytes()); + if def.flags().contains(TypeAttributes::WindowsRuntime) { + let signature = Literal::byte_string(type_def_signature(def, &[]).as_bytes()); tokens.combine("e! { #features @@ -148,12 +148,12 @@ fn gen_windows_traits(writer: &Writer, def: TypeDef, name: &TokenStream, cfg: &C fn gen_compare_traits(writer: &Writer, def: TypeDef, name: &TokenStream, cfg: &Cfg) -> TokenStream { let features = writer.cfg_features(cfg); - if writer.sys || type_def_has_explicit_layout(writer.reader, def) || type_def_has_packing(writer.reader, def) || type_def_has_callback(writer.reader, def) { + if writer.sys || type_def_has_explicit_layout(def) || type_def_has_packing(def) || type_def_has_callback(def) { quote! {} } else { - let fields = writer.reader.type_def_fields(def).filter_map(|f| { - let name = to_ident(writer.reader.field_name(f)); - if writer.reader.field_flags(f).contains(FieldAttributes::Literal) { + let fields = def.fields().filter_map(|f| { + let name = to_ident(f.name()); + if f.flags().contains(FieldAttributes::Literal) { None } else { Some(quote! { self.#name == other.#name }) @@ -174,20 +174,20 @@ fn gen_compare_traits(writer: &Writer, def: TypeDef, name: &TokenStream, cfg: &C } fn gen_debug(writer: &Writer, def: TypeDef, ident: &TokenStream, cfg: &Cfg) -> TokenStream { - if writer.sys || type_def_has_explicit_layout(writer.reader, def) || type_def_has_packing(writer.reader, def) { + if writer.sys || type_def_has_explicit_layout(def) || type_def_has_packing(def) { quote! {} } else { let name = ident.as_str(); let features = writer.cfg_features(cfg); - let fields = writer.reader.type_def_fields(def).filter_map(|f| { - if writer.reader.field_flags(f).contains(FieldAttributes::Literal) { + let fields = def.fields().filter_map(|f| { + if f.flags().contains(FieldAttributes::Literal) { None } else { - let name = writer.reader.field_name(f); + let name = f.name(); let ident = to_ident(name); - let ty = writer.reader.field_type(f, Some(def)); - if type_has_callback(writer.reader, &ty) { + let ty = f.ty(Some(def)); + if type_has_callback(&ty) { None } else { Some(quote! { .field(#name, &self.#ident) }) @@ -209,7 +209,7 @@ fn gen_debug(writer: &Writer, def: TypeDef, ident: &TokenStream, cfg: &Cfg) -> T fn gen_copy_clone(writer: &Writer, def: TypeDef, name: &TokenStream, cfg: &Cfg) -> TokenStream { let features = writer.cfg_features(cfg); - if writer.sys || type_def_is_copyable(writer.reader, def) { + if writer.sys || type_def_is_copyable(def) { quote! { #features impl ::core::marker::Copy for #name {} @@ -220,10 +220,10 @@ fn gen_copy_clone(writer: &Writer, def: TypeDef, name: &TokenStream, cfg: &Cfg) } } } - } else if writer.reader.type_def_class_layout(def).is_some() { + } else if def.class_layout().is_some() { // Don't support copy/clone of packed structs: https://github.com/rust-lang/rust/issues/82523 quote! {} - } else if !writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) { + } else if !def.flags().contains(TypeAttributes::WindowsRuntime) { quote! { #features impl ::core::clone::Clone for #name { @@ -233,11 +233,11 @@ fn gen_copy_clone(writer: &Writer, def: TypeDef, name: &TokenStream, cfg: &Cfg) } } } else { - let fields = writer.reader.type_def_fields(def).map(|f| { - let name = to_ident(writer.reader.field_name(f)); - if writer.reader.field_flags(f).contains(FieldAttributes::Literal) { + let fields = def.fields().map(|f| { + let name = to_ident(f.name()); + if f.flags().contains(FieldAttributes::Literal) { quote! {} - } else if field_is_blittable(writer.reader, f, def) { + } else if field_is_blittable(f, def) { quote! { #name: self.#name } } else { quote! { #name: self.#name.clone() } @@ -258,11 +258,11 @@ fn gen_copy_clone(writer: &Writer, def: TypeDef, name: &TokenStream, cfg: &Cfg) fn gen_struct_constants(writer: &Writer, def: TypeDef, struct_name: &TokenStream, cfg: &Cfg) -> TokenStream { let features = writer.cfg_features(cfg); - let constants = writer.reader.type_def_fields(def).filter_map(|f| { - if writer.reader.field_flags(f).contains(FieldAttributes::Literal) { - if let Some(constant) = writer.reader.field_constant(f) { - let name = to_ident(writer.reader.field_name(f)); - let value = writer.typed_value(&writer.reader.constant_value(constant)); + let constants = def.fields().filter_map(|f| { + if f.flags().contains(FieldAttributes::Literal) { + if let Some(constant) = f.constant() { + let name = to_ident(f.name()); + let value = writer.typed_value(&constant.value()); return Some(quote! { pub const #name: #value; diff --git a/vendor/windows-bindgen/src/rust/try_format.rs b/vendor/windows-bindgen/src/rust/try_format.rs index c871517b1..0d7047105 100644 --- a/vendor/windows-bindgen/src/rust/try_format.rs +++ b/vendor/windows-bindgen/src/rust/try_format.rs @@ -16,7 +16,7 @@ pub fn try_format(writer: &super::Writer, tokens: &str) -> String { }; // Packaging - e.g. windows/windows-sys crates - assumes the crate will allow whatever warnings it deems fit. - let allow = if writer.package { "" } else { "#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]\n" }; + let allow = if writer.package || writer.no_inner_attributes { "" } else { "#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]\n" }; let tokens = format!("{preamble}{allow}{tokens}"); let Ok(mut child) = std::process::Command::new("rustfmt").stdin(std::process::Stdio::piped()).stdout(std::process::Stdio::piped()).stderr(std::process::Stdio::null()).spawn() else { diff --git a/vendor/windows-bindgen/src/rust/winrt_methods.rs b/vendor/windows-bindgen/src/rust/winrt_methods.rs index f98843e66..a43594fb7 100644 --- a/vendor/windows-bindgen/src/rust/winrt_methods.rs +++ b/vendor/windows-bindgen/src/rust/winrt_methods.rs @@ -2,15 +2,15 @@ use super::*; // TODO take Signature instead of MethodDef (wherever MethodDef is found) pub fn writer(writer: &Writer, def: TypeDef, generic_types: &[Type], kind: InterfaceKind, method: MethodDef, method_names: &mut MethodNames, virtual_names: &mut MethodNames) -> TokenStream { - let signature = method_def_signature(writer.reader, writer.reader.type_def_namespace(def), method, generic_types); + let signature = method_def_signature(def.namespace(), method, generic_types); let params = &signature.params; - let name = method_names.add(writer, method); + let name = method_names.add(method); let interface_name = writer.type_def_name(def, generic_types); - let vname = virtual_names.add(writer, method); + let vname = virtual_names.add(method); let generics = writer.constraint_generics(params); let where_clause = writer.where_clause(params); - let mut cfg = signature_cfg(writer.reader, method); - type_def_cfg_combine(writer.reader, def, generic_types, &mut cfg); + let mut cfg = signature_cfg(method); + type_def_cfg_combine(def, generic_types, &mut cfg); let doc = writer.cfg_method_doc(&cfg); let features = writer.cfg_features(&cfg); let args = gen_winrt_abi_args(writer, params); @@ -106,14 +106,14 @@ fn gen_winrt_params(writer: &Writer, params: &[SignatureParam]) -> TokenStream { let kind = writer.type_name(¶m.ty); let default_type = writer.type_default_name(¶m.ty); - if writer.reader.param_flags(param.def).contains(ParamAttributes::In) { + if param.def.flags().contains(ParamAttributes::In) { if param.ty.is_winrt_array() { result.combine("e! { #name: &[#default_type], }); - } else if signature_param_is_convertible(writer.reader, param) { + } else if param.is_convertible() { let (position, _) = generic_params.next().unwrap(); let kind: TokenStream = format!("P{position}").into(); result.combine("e! { #name: #kind, }); - } else if type_is_blittable(writer.reader, ¶m.ty) { + } else if type_is_blittable(¶m.ty) { result.combine("e! { #name: #kind, }); } else { result.combine("e! { #name: &#kind, }); @@ -135,18 +135,18 @@ fn gen_winrt_abi_args(writer: &Writer, params: &[SignatureParam]) -> TokenStream for param in params { let name = writer.param_name(param.def); - let param = if writer.reader.param_flags(param.def).contains(ParamAttributes::In) { + let param = if param.def.flags().contains(ParamAttributes::In) { if param.ty.is_winrt_array() { - if type_is_blittable(writer.reader, ¶m.ty) { - quote! { #name.len() as u32, #name.as_ptr(), } + if type_is_blittable(¶m.ty) { + quote! { #name.len().try_into().unwrap(), #name.as_ptr(), } } else { - quote! { #name.len() as u32, ::core::mem::transmute(#name.as_ptr()), } + quote! { #name.len().try_into().unwrap(), ::core::mem::transmute(#name.as_ptr()), } } - } else if type_is_non_exclusive_winrt_interface(writer.reader, ¶m.ty) { + } else if type_is_non_exclusive_winrt_interface(¶m.ty) { quote! { #name.try_into_param()?.abi(), } - } else if signature_param_is_borrowed(writer.reader, param) { + } else if type_is_borrowed(¶m.ty) { quote! { #name.into_param().abi(), } - } else if type_is_blittable(writer.reader, ¶m.ty) { + } else if type_is_blittable(¶m.ty) { if param.ty.is_const_ref() { quote! { &#name, } } else { @@ -156,14 +156,14 @@ fn gen_winrt_abi_args(writer: &Writer, params: &[SignatureParam]) -> TokenStream quote! { ::core::mem::transmute_copy(#name), } } } else if param.ty.is_winrt_array() { - if type_is_blittable(writer.reader, ¶m.ty) { - quote! { #name.len() as u32, #name.as_mut_ptr(), } + if type_is_blittable(¶m.ty) { + quote! { #name.len().try_into().unwrap(), #name.as_mut_ptr(), } } else { - quote! { #name.len() as u32, ::core::mem::transmute_copy(&#name), } + quote! { #name.len().try_into().unwrap(), ::core::mem::transmute_copy(&#name), } } } else if param.ty.is_winrt_array_ref() { quote! { #name.set_abi_len(), #name as *mut _ as _, } - } else if type_is_blittable(writer.reader, ¶m.ty) { + } else if type_is_blittable(¶m.ty) { quote! { #name, } } else { quote! { #name as *mut _ as _, } @@ -195,7 +195,7 @@ pub fn gen_upcall(writer: &Writer, sig: &Signature, inner: TokenStream) -> Token } } _ => { - let forget = if type_is_blittable(writer.reader, &sig.return_type) { + let forget = if type_is_blittable(&sig.return_type) { quote! {} } else { quote! { ::core::mem::forget(ok__); } @@ -218,16 +218,16 @@ pub fn gen_upcall(writer: &Writer, sig: &Signature, inner: TokenStream) -> Token fn gen_winrt_invoke_arg(writer: &Writer, param: &SignatureParam) -> TokenStream { let name = writer.param_name(param.def); - let abi_size_name: TokenStream = format!("{}_array_size", writer.reader.param_name(param.def)).into(); + let abi_size_name: TokenStream = format!("{}_array_size", param.def.name()).into(); - if writer.reader.param_flags(param.def).contains(ParamAttributes::In) { + if param.def.flags().contains(ParamAttributes::In) { if param.ty.is_winrt_array() { quote! { ::core::slice::from_raw_parts(::core::mem::transmute_copy(&#name), #abi_size_name as usize) } - } else if type_is_primitive(writer.reader, ¶m.ty) { + } else if type_is_primitive(¶m.ty) { quote! { #name } } else if param.ty.is_const_ref() { quote! { ::core::mem::transmute_copy(&#name) } - } else if type_is_nullable(writer.reader, ¶m.ty) { + } else if type_is_nullable(¶m.ty) { quote! { ::windows_core::from_raw_borrowed(&#name) } } else { quote! { ::core::mem::transmute(&#name) } diff --git a/vendor/windows-bindgen/src/rust/writer.rs b/vendor/windows-bindgen/src/rust/writer.rs index 9d81c9951..175519cd8 100644 --- a/vendor/windows-bindgen/src/rust/writer.rs +++ b/vendor/windows-bindgen/src/rust/writer.rs @@ -1,11 +1,10 @@ use super::*; #[derive(Clone)] -pub struct Writer<'a> { - pub reader: &'a Reader<'a>, - pub filter: &'a metadata::Filter<'a>, - pub output: &'a str, - pub namespace: &'a str, +pub struct Writer { + pub reader: &'static Reader, + pub output: String, + pub namespace: &'static str, pub implement: bool, // TODO: ideally we can use this to generate implementation traits on the fly and // and have a single interface definition macro for consumption that expands to include // impl traits when the `implement` cfg flag is set and then this writer option would be @@ -13,16 +12,28 @@ pub struct Writer<'a> { // // Maybe this macro is the embedable version of the IDL format?! like a more intelligient // version of the existing interface macro... - pub std: bool, // tweaks for internal std library support - pub sys: bool, // writer sys-style bindings - pub flatten: bool, // strips out namespaces - implies !package - pub package: bool, // default is single file with no cfg - implies !flatten - pub minimal: bool, // strips out enumerators - in future possibly other helpers as well + pub std: bool, // tweaks for internal std library support + pub sys: bool, // writer sys-style bindings + pub flatten: bool, // strips out namespaces - implies !package + pub package: bool, // default is single file with no cfg - implies !flatten + pub minimal: bool, // strips out enumerators - in future possibly other helpers as well + pub no_inner_attributes: bool, // skips the inner attributes at the start of the file } -impl<'a> Writer<'a> { - pub fn new(reader: &'a Reader, filter: &'a metadata::Filter, output: &'a str) -> Self { - Self { reader, filter, output, namespace: "", implement: false, std: false, sys: false, flatten: false, package: false, minimal: false } +impl Writer { + pub fn new(reader: &'static Reader, output: &str) -> Self { + Self { + reader, + output: output.to_string(), + namespace: "", + implement: false, + std: false, + sys: false, + flatten: false, + package: false, + minimal: false, + no_inner_attributes: false, + } } // @@ -36,7 +47,7 @@ impl<'a> Writer<'a> { self.type_def_name_imp(def, generics, "_Vtbl") } pub fn type_def_name_imp(&self, def: TypeDef, generics: &[Type], suffix: &str) -> TokenStream { - let type_name = self.reader.type_def_type_name(def); + let type_name = def.type_name(); if type_name.namespace.is_empty() { to_ident(&self.scoped_name(def)) @@ -73,7 +84,7 @@ impl<'a> Writer<'a> { if ty.is_generic() { quote! { <#kind as ::windows_core::Type<#kind>>::Default } - } else if type_is_nullable(self.reader, ty) && !self.sys { + } else if type_is_nullable(ty) && !self.sys { quote! { ::core::option::Option<#kind> } } else { kind @@ -143,7 +154,7 @@ impl<'a> Writer<'a> { let len = Literal::usize_unsuffixed(*len); quote! { [#name; #len] } } - Type::GenericParam(generic) => self.reader.generic_param_name(*generic).into(), + Type::GenericParam(generic) => generic.name().into(), Type::TypeDef(def, generics) => self.type_def_name(*def, generics), Type::MutPtr(ty, pointers) => { let pointers = mut_ptrs(*pointers); @@ -192,21 +203,21 @@ impl<'a> Writer<'a> { quote! { [#name; #len] } } Type::GenericParam(generic) => { - let name = to_ident(self.reader.generic_param_name(*generic)); + let name = to_ident(generic.name()); quote! { ::windows_core::AbiType<#name> } } - Type::TypeDef(def, _) => match self.reader.type_def_kind(*def) { + Type::TypeDef(def, _) => match def.kind() { TypeKind::Enum => self.type_def_name(*def, &[]), TypeKind::Struct => { let tokens = self.type_def_name(*def, &[]); - if type_def_is_blittable(self.reader, *def) { + if type_def_is_blittable(*def) { tokens } else { quote! { ::std::mem::MaybeUninit<#tokens> } } } TypeKind::Delegate => { - if self.reader.type_def_flags(*def).contains(TypeAttributes::WindowsRuntime) { + if def.flags().contains(TypeAttributes::WindowsRuntime) { quote! { *mut ::core::ffi::c_void } } else { self.type_def_name(*def, &[]) @@ -270,7 +281,7 @@ impl<'a> Writer<'a> { } /// The signature params which are generic (along with their relative index) pub fn generic_params<'b>(&'b self, params: &'b [SignatureParam]) -> impl Iterator<Item = (usize, &SignatureParam)> + 'b { - params.iter().filter(move |param| signature_param_is_convertible(self.reader, param)).enumerate() + params.iter().filter(move |param| param.is_convertible()).enumerate() } /// The generic param names (i.e., `T` in `fn foo<T>()`) pub fn constraint_generics(&self, params: &[SignatureParam]) -> TokenStream { @@ -325,18 +336,18 @@ impl<'a> Writer<'a> { if !self.package { quote! {} } else { - let mut tokens = format!(r#"`\"{}\"`"#, to_feature(self.namespace)); - let features = self.cfg_features_imp(cfg, self.namespace); + let mut tokens = String::new(); - for features in features { - write!(tokens, r#", `\"{}\"`"#, to_feature(features)).unwrap(); + for features in self.cfg_features_imp(cfg, self.namespace) { + write!(tokens, r#"`\"{}\"`, "#, to_feature(features)).unwrap(); } - if cfg.implement { - tokens.push_str(r#", `\"implement\"`"#) + if tokens.is_empty() { + TokenStream::new() + } else { + tokens.truncate(tokens.len() - 2); + format!(r#" #[doc = "Required features: {tokens}"]"#).into() } - - format!(r#" #[doc = "*Required features: {tokens}*"]"#).into() } } @@ -347,15 +358,18 @@ impl<'a> Writer<'a> { quote! {} } else { let features = self.cfg_features_imp(cfg, self.namespace); + if features.is_empty() { quote! {} } else { let mut tokens = String::new(); + for features in features { write!(tokens, r#"`\"{}\"`, "#, to_feature(features)).unwrap(); } + tokens.truncate(tokens.len() - 2); - format!(r#"#[doc = "*Required features: {tokens}*"]"#).into() + format!(r#"#[doc = "Required features: {tokens}"]"#).into() } } } @@ -389,7 +403,7 @@ impl<'a> Writer<'a> { quote! { #arch #features } } - fn cfg_features_imp(&self, cfg: &'a Cfg, namespace: &'a str) -> Vec<&'a str> { + fn cfg_features_imp(&self, cfg: &Cfg, namespace: &str) -> Vec<&'static str> { let mut compact = Vec::<&'static str>::new(); if self.package { for feature in cfg.types.keys() { @@ -477,14 +491,14 @@ impl<'a> Writer<'a> { } } fn scoped_name(&self, def: TypeDef) -> String { - if let Some(enclosing_type) = self.reader.type_def_enclosing_type(def) { + if let Some(enclosing_type) = def.enclosing_type() { for (index, nested_type) in self.reader.nested_types(enclosing_type).enumerate() { - if self.reader.type_def_name(nested_type) == self.reader.type_def_name(def) { + if nested_type.name() == def.name() { return format!("{}_{index}", &self.scoped_name(enclosing_type)); } } } - self.reader.type_def_name(def).to_string() + def.name().to_string() } pub fn value(&self, value: &Value) -> TokenStream { match value { @@ -533,31 +547,12 @@ impl<'a> Writer<'a> { } } - pub fn guid(&self, value: &GUID) -> TokenStream { + pub fn guid(&self, value: &Guid) -> TokenStream { let guid = self.type_name(&Type::GUID); format!("{}::from_u128(0x{:08x?}_{:04x?}_{:04x?}_{:02x?}{:02x?}_{:02x?}{:02x?}{:02x?}{:02x?}{:02x?}{:02x?})", guid.into_string(), value.0, value.1, value.2, value.3, value.4, value.5, value.6, value.7, value.8, value.9, value.10).into() } - pub fn interface_core_traits(&self, def: TypeDef, _generics: &[Type], ident: &TokenStream, constraints: &TokenStream, _phantoms: &TokenStream, features: &TokenStream) -> TokenStream { - let name = crate::trim_tick(self.reader.type_def_name(def)); - quote! { - #features - impl<#constraints> ::core::cmp::PartialEq for #ident { - fn eq(&self, other: &Self) -> bool { - self.0 == other.0 - } - } - #features - impl<#constraints> ::core::cmp::Eq for #ident {} - #features - impl<#constraints> ::core::fmt::Debug for #ident { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_tuple(#name).field(&self.0).finish() - } - } - } - } pub fn agile(&self, def: TypeDef, ident: &TokenStream, constraints: &TokenStream, features: &TokenStream) -> TokenStream { - if type_def_is_agile(self.reader, def) { + if type_def_is_agile(def) { quote! { #features unsafe impl<#constraints> ::core::marker::Send for #ident {} @@ -569,13 +564,13 @@ impl<'a> Writer<'a> { } } pub fn async_get(&self, def: TypeDef, generics: &[Type], ident: &TokenStream, constraints: &TokenStream, _phantoms: &TokenStream, features: &TokenStream) -> TokenStream { - let mut kind = type_def_async_kind(self.reader, def); + let mut kind = type_def_async_kind(def); let mut async_generics = generics.to_vec(); if kind == AsyncKind::None { - for interface in type_def_interfaces(self.reader, def, generics) { + for interface in def.interface_impls().map(move |imp| imp.ty(generics)) { if let Type::TypeDef(interface_def, interface_generics) = &interface { - kind = type_def_async_kind(self.reader, *interface_def); + kind = type_def_async_kind(*interface_def); if kind != AsyncKind::None { async_generics = interface_generics.to_vec(); break; @@ -642,14 +637,14 @@ impl<'a> Writer<'a> { } } pub fn interface_winrt_trait(&self, def: TypeDef, generics: &[Type], ident: &TokenStream, constraints: &TokenStream, _phantoms: &TokenStream, features: &TokenStream) -> TokenStream { - if self.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) { - let type_signature = if self.reader.type_def_kind(def) == TypeKind::Class { - let type_signature = Literal::byte_string(type_def_signature(self.reader, def, generics).as_bytes()); + if def.flags().contains(TypeAttributes::WindowsRuntime) { + let type_signature = if def.kind() == TypeKind::Class { + let type_signature = Literal::byte_string(type_def_signature(def, generics).as_bytes()); quote! { ::windows_core::imp::ConstBuffer::from_slice(#type_signature) } } else { let signature = Literal::byte_string( // TODO: workaround for riddle winmd generation (no attribute support) - if let Some(guid) = type_def_guid(self.reader, def) { format!("{{{:#?}}}", guid) } else { "TODO".to_string() }.as_bytes(), + if let Some(guid) = type_def_guid(def) { format!("{{{:#?}}}", guid) } else { "TODO".to_string() }.as_bytes(), ); if generics.is_empty() { @@ -695,9 +690,9 @@ impl<'a> Writer<'a> { } } pub fn runtime_name_trait(&self, def: TypeDef, _generics: &[Type], name: &TokenStream, constraints: &TokenStream, features: &TokenStream) -> TokenStream { - if self.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) { + if def.flags().contains(TypeAttributes::WindowsRuntime) { // TODO: this needs to use a ConstBuffer-like facility to accomodate generics - let runtime_name = format!("{}", self.reader.type_def_type_name(def)); + let runtime_name = format!("{}", def.type_name()); quote! { #features @@ -714,17 +709,11 @@ impl<'a> Writer<'a> { } pub fn interface_trait(&self, def: TypeDef, generics: &[Type], ident: &TokenStream, constraints: &TokenStream, features: &TokenStream, has_unknown_base: bool) -> TokenStream { - if let Some(default) = type_def_default_interface(self.reader, def) { + if let Some(default) = type_def_default_interface(def) { let default_name = self.type_name(&default); let vtbl = self.type_vtbl_name(&default); quote! { #features - impl<#constraints> ::core::clone::Clone for #ident { - fn clone(&self) -> Self { - Self(self.0.clone()) - } - } - #features unsafe impl ::windows_core::Interface for #ident { type Vtable = #vtbl; } @@ -736,7 +725,7 @@ impl<'a> Writer<'a> { } else { let vtbl = self.type_def_vtbl_name(def, generics); let guid = if generics.is_empty() { - match type_def_guid(self.reader, def) { + match type_def_guid(def) { Some(guid) => self.guid(&guid), None => { quote! { @@ -750,19 +739,11 @@ impl<'a> Writer<'a> { } }; - let phantoms = self.generic_phantoms(generics); - let mut tokens = quote! { #features unsafe impl<#constraints> ::windows_core::Interface for #ident { type Vtable = #vtbl; } - #features - impl<#constraints> ::core::clone::Clone for #ident { - fn clone(&self) -> Self { - Self(self.0.clone(), #phantoms) - } - } }; if has_unknown_base { @@ -781,10 +762,10 @@ impl<'a> Writer<'a> { let vtbl = self.type_def_vtbl_name(def, generics); let mut methods = quote! {}; let mut method_names = MethodNames::new(); - method_names.add_vtable_types(self, def); + method_names.add_vtable_types(def); let phantoms = self.generic_named_phantoms(generics); - match type_def_vtables(self.reader, def).last() { + match type_def_vtables(def).last() { Some(Type::IUnknown) => methods.combine("e! { pub base__: ::windows_core::IUnknown_Vtbl, }), Some(Type::IInspectable) => methods.combine("e! { pub base__: ::windows_core::IInspectable_Vtbl, }), Some(Type::TypeDef(def, _)) => { @@ -794,15 +775,15 @@ impl<'a> Writer<'a> { _ => {} } - for method in self.reader.type_def_methods(def) { - if self.reader.method_def_name(method) == ".ctor" { + for method in def.methods() { + if method.name() == ".ctor" { continue; } - let name = method_names.add(self, method); - let signature = method_def_signature(self.reader, self.reader.type_def_namespace(def), method, generics); - let mut cfg = signature_cfg(self.reader, method); + let name = method_names.add(method); + let signature = method_def_signature(def.namespace(), method, generics); + let mut cfg = signature_cfg(method); let signature = self.vtbl_signature(def, generics, &signature); - cfg.add_feature(self.reader.type_def_namespace(def)); + cfg.add_feature(def.namespace()); let cfg_all = self.cfg_features(&cfg); let cfg_not = self.cfg_not_features(&cfg); @@ -829,7 +810,7 @@ impl<'a> Writer<'a> { } } pub fn vtbl_signature(&self, def: TypeDef, _generics: &[Type], signature: &Signature) -> TokenStream { - let is_winrt = self.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime); + let is_winrt = def.flags().contains(TypeAttributes::WindowsRuntime); let crate_name = self.crate_name(); @@ -844,7 +825,7 @@ impl<'a> Writer<'a> { let tokens = self.type_abi_name(&signature.return_type); (quote! { result__: *mut #tokens }, quote! { -> #crate_name HRESULT }, quote! {}) } - _ if type_is_struct(self.reader, &signature.return_type) => { + _ if type_is_struct(&signature.return_type) => { let tokens = self.type_abi_name(&signature.return_type); (quote! {}, quote! {}, quote! { result__: *mut #tokens, }) } @@ -858,9 +839,9 @@ impl<'a> Writer<'a> { let name = self.param_name(p.def); if is_winrt { let abi = self.type_abi_name(&p.ty); - let abi_size_name: TokenStream = format!("{}_array_size", self.reader.param_name(p.def)).into(); + let abi_size_name: TokenStream = format!("{}_array_size", p.def.name()).into(); - if self.reader.param_flags(p.def).contains(ParamAttributes::In) { + if p.def.flags().contains(ParamAttributes::In) { if p.ty.is_winrt_array() { quote! { #abi_size_name: u32, #name: *const #abi, } } else if p.ty.is_const_ref() { @@ -894,11 +875,11 @@ impl<'a> Writer<'a> { pub fn param_name(&self, param: Param) -> TokenStream { // In Rust, function parameters cannot be named the same as structs. This avoids some collisions that occur in the win32 metadata. // See Icmp6SendEcho2 for an example. - to_ident(&self.reader.param_name(param).to_lowercase()) + to_ident(¶m.name().to_lowercase()) } pub fn return_sig(&self, signature: &Signature) -> TokenStream { match &signature.return_type { - Type::Void if self.reader.has_attribute(signature.def, "DoesNotReturnAttribute") => " -> !".into(), + Type::Void if signature.def.has_attribute("DoesNotReturnAttribute") => " -> !".into(), Type::Void => " -> ()".into(), _ => { let tokens = self.type_default_name(&signature.return_type); @@ -925,7 +906,7 @@ impl<'a> Writer<'a> { } _ => { let name = self.param_name(param.def); - let flags = self.reader.param_flags(param.def); + let flags = param.def.flags(); match param.kind { SignatureParamKind::ArrayFixed(_) | SignatureParamKind::ArrayRelativeLen(_) | SignatureParamKind::ArrayRelativeByteLen(_) => { let map = if flags.contains(ParamAttributes::Optional) { @@ -937,11 +918,11 @@ impl<'a> Writer<'a> { } SignatureParamKind::ArrayRelativePtr(relative) => { let name = self.param_name(params[relative].def); - let flags = self.reader.param_flags(params[relative].def); + let flags = params[relative].def.flags(); if flags.contains(ParamAttributes::Optional) { - quote! { #name.as_deref().map_or(0, |slice|slice.len() as _), } + quote! { #name.as_deref().map_or(0, |slice|slice.len().try_into().unwrap()), } } else { - quote! { #name.len() as _, } + quote! { #name.len().try_into().unwrap(), } } } SignatureParamKind::TryInto => { @@ -1002,12 +983,12 @@ impl<'a> Writer<'a> { let ty = param.ty.deref(); let ty = self.type_default_name(&ty); let len = Literal::u32_unsuffixed(fixed as u32); - let ty = if self.reader.param_flags(param.def).contains(ParamAttributes::Out) { + let ty = if param.def.flags().contains(ParamAttributes::Out) { quote! { &mut [#ty; #len] } } else { quote! { &[#ty; #len] } }; - if self.reader.param_flags(param.def).contains(ParamAttributes::Optional) { + if param.def.flags().contains(ParamAttributes::Optional) { tokens.combine("e! { #name: ::core::option::Option<#ty>, }); } else { tokens.combine("e! { #name: #ty, }); @@ -1016,24 +997,24 @@ impl<'a> Writer<'a> { SignatureParamKind::ArrayRelativeLen(_) => { let ty = param.ty.deref(); let ty = self.type_default_name(&ty); - let ty = if self.reader.param_flags(param.def).contains(ParamAttributes::Out) { + let ty = if param.def.flags().contains(ParamAttributes::Out) { quote! { &mut [#ty] } } else { quote! { &[#ty] } }; - if self.reader.param_flags(param.def).contains(ParamAttributes::Optional) { + if param.def.flags().contains(ParamAttributes::Optional) { tokens.combine("e! { #name: ::core::option::Option<#ty>, }); } else { tokens.combine("e! { #name: #ty, }); } } SignatureParamKind::ArrayRelativeByteLen(_) => { - let ty = if self.reader.param_flags(param.def).contains(ParamAttributes::Out) { + let ty = if param.def.flags().contains(ParamAttributes::Out) { quote! { &mut [u8] } } else { quote! { &[u8] } }; - if self.reader.param_flags(param.def).contains(ParamAttributes::Optional) { + if param.def.flags().contains(ParamAttributes::Optional) { tokens.combine("e! { #name: ::core::option::Option<#ty>, }); } else { tokens.combine("e! { #name: #ty, }); @@ -1064,8 +1045,8 @@ impl<'a> Writer<'a> { } pub fn impl_signature(&self, def: TypeDef, signature: &Signature) -> TokenStream { - if self.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) { - let is_delegate = self.reader.type_def_kind(def) == TypeKind::Delegate; + if def.flags().contains(TypeAttributes::WindowsRuntime) { + let is_delegate = def.kind() == TypeKind::Delegate; let params = signature.params.iter().map(|p| self.winrt_produce_type(p, !is_delegate)); let return_type = match &signature.return_type { @@ -1089,7 +1070,7 @@ impl<'a> Writer<'a> { quote! { (#this #(#params),*) -> ::windows_core::Result<#return_type> } } else { - let signature_kind = signature_kind(self.reader, signature); + let signature_kind = signature.kind(); let mut params = quote! {}; if signature_kind == SignatureKind::ResultValue { @@ -1120,12 +1101,12 @@ impl<'a> Writer<'a> { fn winrt_produce_type(&self, param: &SignatureParam, include_param_names: bool) -> TokenStream { let default_type = self.type_default_name(¶m.ty); - let sig = if self.reader.param_flags(param.def).contains(ParamAttributes::In) { + let sig = if param.def.flags().contains(ParamAttributes::In) { if param.ty.is_winrt_array() { quote! { &[#default_type] } - } else if type_is_primitive(self.reader, ¶m.ty) { + } else if type_is_primitive(¶m.ty) { quote! { #default_type } - } else if type_is_nullable(self.reader, ¶m.ty) { + } else if type_is_nullable(¶m.ty) { let type_name = self.type_name(¶m.ty); quote! { ::core::option::Option<&#type_name> } } else { @@ -1151,10 +1132,10 @@ impl<'a> Writer<'a> { let name = self.param_name(param.def); let kind = self.type_default_name(¶m.ty); - if self.reader.param_flags(param.def).contains(ParamAttributes::In) { - if type_is_primitive(self.reader, ¶m.ty) { + if param.def.flags().contains(ParamAttributes::In) { + if type_is_primitive(¶m.ty) { quote! { #name: #kind, } - } else if type_is_nullable(self.reader, ¶m.ty) { + } else if type_is_nullable(¶m.ty) { let kind = self.type_name(¶m.ty); quote! { #name: ::core::option::Option<&#kind>, } } else { @@ -1211,6 +1192,33 @@ fn gen_const_ptrs(pointers: usize) -> TokenStream { "*const ".repeat(pointers).into() } +fn type_def_async_kind(row: TypeDef) -> AsyncKind { + match row.type_name() { + TypeName::IAsyncAction => AsyncKind::Action, + TypeName::IAsyncActionWithProgress => AsyncKind::ActionWithProgress, + TypeName::IAsyncOperation => AsyncKind::Operation, + TypeName::IAsyncOperationWithProgress => AsyncKind::OperationWithProgress, + _ => AsyncKind::None, + } +} + +fn type_def_is_agile(row: TypeDef) -> bool { + for attribute in row.attributes() { + match attribute.name() { + "AgileAttribute" => return true, + "MarshalingBehaviorAttribute" => { + if let Some((_, Value::EnumDef(_, value))) = attribute.args().first() { + if let Value::I32(2) = **value { + return true; + } + } + } + _ => {} + } + } + matches!(row.type_name(), TypeName::IAsyncAction | TypeName::IAsyncActionWithProgress | TypeName::IAsyncOperation | TypeName::IAsyncOperationWithProgress) +} + #[cfg(test)] mod tests { use super::*; diff --git a/vendor/windows-bindgen/src/tokens/mod.rs b/vendor/windows-bindgen/src/tokens/mod.rs index e5f019a8b..12a54142f 100644 --- a/vendor/windows-bindgen/src/tokens/mod.rs +++ b/vendor/windows-bindgen/src/tokens/mod.rs @@ -438,6 +438,6 @@ pub fn to_ident(name: &str) -> TokenStream { "abstract" | "as" | "become" | "box" | "break" | "const" | "continue" | "crate" | "do" | "else" | "enum" | "extern" | "false" | "final" | "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" | "macro" | "match" | "mod" | "move" | "mut" | "override" | "priv" | "pub" | "ref" | "return" | "static" | "struct" | "super" | "trait" | "true" | "type" | "typeof" | "unsafe" | "unsized" | "use" | "virtual" | "where" | "while" | "yield" | "try" | "async" | "await" | "dyn" => format!("r#{name}").into(), "Self" | "self" => format!("{name}_").into(), "_" => "unused".into(), - _ => crate::trim_tick(name).into(), + _ => name.into(), } } diff --git a/vendor/windows-bindgen/src/tree.rs b/vendor/windows-bindgen/src/tree.rs index 474d2a271..6a619940e 100644 --- a/vendor/windows-bindgen/src/tree.rs +++ b/vendor/windows-bindgen/src/tree.rs @@ -1,26 +1,26 @@ use super::*; #[derive(Debug)] -pub struct Tree<'a> { - pub namespace: &'a str, - pub nested: std::collections::BTreeMap<&'a str, Tree<'a>>, +pub struct Tree { + pub namespace: &'static str, + pub nested: std::collections::BTreeMap<&'static str, Tree>, } -impl<'a> Tree<'a> { - pub fn new(reader: &'a metadata::Reader, filter: &'a metadata::Filter) -> Self { +impl Tree { + pub fn new(reader: &'static metadata::Reader) -> Self { let mut tree = Tree::from_namespace(""); for ns in reader.namespaces() { - if filter.includes_namespace(ns) { + if reader.includes_namespace(ns) { tree.insert_namespace(ns, 0); } } tree } - fn from_namespace(namespace: &'a str) -> Self { + fn from_namespace(namespace: &'static str) -> Self { Self { namespace, nested: std::collections::BTreeMap::new() } } - fn insert_namespace(&mut self, namespace: &'a str, pos: usize) -> &mut Self { + fn insert_namespace(&mut self, namespace: &'static str, pos: usize) -> &mut Self { if let Some(next) = namespace[pos..].find('.') { let next = pos + next; self.nested.entry(&namespace[pos..next]).or_insert_with(|| Self::from_namespace(&namespace[..next])).insert_namespace(namespace, next + 1) diff --git a/vendor/windows-bindgen/src/winmd/from_reader.rs b/vendor/windows-bindgen/src/winmd/from_reader.rs index b535caed0..ed5f4d178 100644 --- a/vendor/windows-bindgen/src/winmd/from_reader.rs +++ b/vendor/windows-bindgen/src/winmd/from_reader.rs @@ -1,8 +1,7 @@ use super::*; use crate::winmd::{self, writer}; -use metadata::RowReader; -pub fn from_reader(reader: &metadata::Reader, filter: &metadata::Filter, config: std::collections::BTreeMap<&str, &str>, output: &str) -> crate::Result<()> { +pub fn from_reader(reader: &metadata::Reader, config: std::collections::BTreeMap<&str, &str>, output: &str) -> crate::Result<()> { let mut writer = winmd::Writer::new(output); // TODO: do we need any configuration values for winmd generation? @@ -16,37 +15,36 @@ pub fn from_reader(reader: &metadata::Reader, filter: &metadata::Filter, config: // TODO: just use the reader directly since we now have everything in the reader, there's no need to abstract // away the source format. Few reprs is always better. - for item in reader.items(filter) { + for item in reader.items() { // TODO: cover all variants let metadata::Item::Type(def) = item else { continue; }; - let generics = &metadata::type_def_generics(reader, def); + let generics = &metadata::type_def_generics(def); - let extends = if let Some(extends) = reader.type_def_extends(def) { writer.insert_type_ref(extends.namespace, extends.name) } else { 0 }; + let extends = if let Some(extends) = def.extends() { writer.insert_type_ref(extends.namespace, extends.name) } else { 0 }; writer.tables.TypeDef.push(writer::TypeDef { Extends: extends, FieldList: writer.tables.Field.len() as u32, - Flags: reader.type_def_flags(def).0, + Flags: def.flags().0, MethodList: writer.tables.MethodDef.len() as u32, - TypeName: writer.strings.insert(reader.type_def_name(def)), - TypeNamespace: writer.strings.insert(reader.type_def_namespace(def)), + TypeName: writer.strings.insert(def.name()), + TypeNamespace: writer.strings.insert(def.namespace()), }); - for generic in reader.type_def_generics(def) { + for generic in def.generics() { writer.tables.GenericParam.push(writer::GenericParam { - Number: reader.generic_param_number(generic), + Number: generic.number(), // TODO: isn't this just going to be incremental? Flags: 0, Owner: writer::TypeOrMethodDef::TypeDef(writer.tables.TypeDef.len() as u32 - 1).encode(), - Name: writer.strings.insert(reader.generic_param_name(generic)), + Name: writer.strings.insert(generic.name()), }); } - for imp in reader.type_def_interface_impls(def) { - let ty = reader.interface_impl_type(imp, generics); - let ty = winmd_type(reader, &ty); + for interface in metadata::type_def_interfaces(def, generics) { + let ty = winmd_type(&interface.ty); let reference = match &ty { winmd::Type::TypeRef(type_name) if type_name.generics.is_empty() => writer.insert_type_ref(&type_name.namespace, &type_name.name), @@ -61,31 +59,31 @@ pub fn from_reader(reader: &metadata::Reader, filter: &metadata::Filter, config: // TODO: if the class is "Apis" then should we sort the fields (constants) and methods (functions) for stability - for field in reader.type_def_fields(def) { - let ty = winmd_type(reader, &reader.field_type(field, Some(def))); + for field in def.fields() { + let ty = winmd_type(&field.ty(Some(def))); let signature = writer.insert_field_sig(&ty); - writer.tables.Field.push(writer::Field { Flags: reader.field_flags(field).0, Name: writer.strings.insert(reader.field_name(field)), Signature: signature }); + writer.tables.Field.push(writer::Field { Flags: field.flags().0, Name: writer.strings.insert(field.name()), Signature: signature }); } - for method in reader.type_def_methods(def) { - let signature = reader.method_def_signature(method, generics); - let return_type = winmd_type(reader, &signature.return_type); - let param_types: Vec<Type> = signature.params.iter().map(|param| winmd_type(reader, param)).collect(); + for method in def.methods() { + let signature = method.signature(generics); + let return_type = winmd_type(&signature.return_type); + let param_types: Vec<Type> = signature.params.iter().map(winmd_type).collect(); let signature = writer.insert_method_sig(signature.call_flags, &return_type, ¶m_types); writer.tables.MethodDef.push(winmd::MethodDef { RVA: 0, - ImplFlags: reader.method_def_impl_flags(method).0, - Flags: reader.method_def_flags(method).0, - Name: writer.strings.insert(reader.method_def_name(method)), + ImplFlags: method.impl_flags().0, + Flags: method.flags().0, + Name: writer.strings.insert(method.name()), Signature: signature, ParamList: writer.tables.Param.len() as u32, }); - for param in reader.method_def_params(method) { - writer.tables.Param.push(writer::Param { Flags: reader.param_flags(param).0, Sequence: reader.param_sequence(param), Name: writer.strings.insert(reader.param_name(param)) }); + for param in method.params() { + writer.tables.Param.push(writer::Param { Flags: param.flags().0, Sequence: param.sequence(), Name: writer.strings.insert(param.name()) }); } } } @@ -96,7 +94,7 @@ pub fn from_reader(reader: &metadata::Reader, filter: &metadata::Filter, config: } // TODO: keep the basic type conversion -fn winmd_type(reader: &metadata::Reader, ty: &metadata::Type) -> winmd::Type { +fn winmd_type(ty: &metadata::Type) -> winmd::Type { match ty { metadata::Type::Void => winmd::Type::Void, metadata::Type::Bool => winmd::Type::Bool, @@ -123,19 +121,15 @@ fn winmd_type(reader: &metadata::Reader, ty: &metadata::Type) -> winmd::Type { metadata::Type::PCSTR => winmd::Type::PCSTR, metadata::Type::PCWSTR => winmd::Type::PCWSTR, metadata::Type::BSTR => winmd::Type::BSTR, - metadata::Type::TypeName => winmd::Type::TypeName, - metadata::Type::TypeDef(def, generics) => winmd::Type::TypeRef(winmd::TypeName { - namespace: reader.type_def_namespace(*def).to_string(), - name: reader.type_def_name(*def).to_string(), - generics: generics.iter().map(|ty| winmd_type(reader, ty)).collect(), - }), - metadata::Type::GenericParam(generic) => winmd::Type::GenericParam(reader.generic_param_number(*generic)), - metadata::Type::ConstRef(ty) => winmd::Type::ConstRef(Box::new(winmd_type(reader, ty))), - metadata::Type::WinrtArrayRef(ty) => winmd::Type::WinrtArrayRef(Box::new(winmd_type(reader, ty))), - metadata::Type::WinrtArray(ty) => winmd::Type::WinrtArray(Box::new(winmd_type(reader, ty))), - metadata::Type::MutPtr(ty, pointers) => winmd::Type::MutPtr(Box::new(winmd_type(reader, ty)), *pointers), - metadata::Type::ConstPtr(ty, pointers) => winmd::Type::ConstPtr(Box::new(winmd_type(reader, ty)), *pointers), - metadata::Type::Win32Array(ty, len) => winmd::Type::Win32Array(Box::new(winmd_type(reader, ty)), *len), + metadata::Type::Type => winmd::Type::Type, + metadata::Type::TypeDef(def, generics) => winmd::Type::TypeRef(winmd::TypeName { namespace: def.namespace().to_string(), name: def.name().to_string(), generics: generics.iter().map(winmd_type).collect() }), + metadata::Type::GenericParam(generic) => winmd::Type::GenericParam(generic.number()), + metadata::Type::ConstRef(ty) => winmd::Type::ConstRef(Box::new(winmd_type(ty))), + metadata::Type::WinrtArrayRef(ty) => winmd::Type::WinrtArrayRef(Box::new(winmd_type(ty))), + metadata::Type::WinrtArray(ty) => winmd::Type::WinrtArray(Box::new(winmd_type(ty))), + metadata::Type::MutPtr(ty, pointers) => winmd::Type::MutPtr(Box::new(winmd_type(ty)), *pointers), + metadata::Type::ConstPtr(ty, pointers) => winmd::Type::ConstPtr(Box::new(winmd_type(ty)), *pointers), + metadata::Type::Win32Array(ty, len) => winmd::Type::Win32Array(Box::new(winmd_type(ty)), *len), rest => unimplemented!("{rest:?}"), } } diff --git a/vendor/windows-bindgen/src/winmd/verify.rs b/vendor/windows-bindgen/src/winmd/verify.rs index f10bd6524..c376d9d19 100644 --- a/vendor/windows-bindgen/src/winmd/verify.rs +++ b/vendor/windows-bindgen/src/winmd/verify.rs @@ -1,31 +1,42 @@ use super::*; -use metadata::RowReader; -pub fn verify(reader: &metadata::Reader, filter: &metadata::Filter) -> crate::Result<()> { - for item in reader.items(filter) { +pub fn verify(reader: &metadata::Reader) -> crate::Result<()> { + let unused: Vec<&str> = reader.unused().collect(); + + if !unused.is_empty() { + let mut message = "unused filters".to_string(); + + for unused in unused { + message.push_str(&format!("\n {unused}")); + } + + return Err(crate::Error::new(&message)); + } + + for item in reader.items() { // TODO: cover all variants let metadata::Item::Type(def) = item else { continue; }; - let generics = &metadata::type_def_generics(reader, def); + let generics = &metadata::type_def_generics(def); - reader.type_def_fields(def).try_for_each(|field| not_type_ref(reader, &reader.field_type(field, Some(def))))?; + def.fields().try_for_each(|field| not_type_ref(&field.ty(Some(def))))?; - reader.type_def_methods(def).try_for_each(|method| { - let sig = reader.method_def_signature(method, generics); - not_type_ref(reader, &sig.return_type)?; + def.methods().try_for_each(|method| { + let sig = method.signature(generics); + not_type_ref(&sig.return_type)?; - sig.params.iter().try_for_each(|param| not_type_ref(reader, param)) + sig.params.iter().try_for_each(not_type_ref) })?; } Ok(()) } -fn not_type_ref(reader: &metadata::Reader, ty: &metadata::Type) -> crate::Result<()> { +fn not_type_ref(ty: &metadata::Type) -> crate::Result<()> { if let metadata::Type::TypeRef(ty) = ty { - return Err(crate::Error::new(&format!("missing type definition `{}`", reader.type_def_or_ref(*ty)))); + return Err(crate::Error::new(&format!("missing type definition `{}`", ty))); } Ok(()) } diff --git a/vendor/windows-bindgen/src/winmd/writer/file.rs b/vendor/windows-bindgen/src/winmd/writer/file.rs index b452ba559..204358d94 100644 --- a/vendor/windows-bindgen/src/winmd/writer/file.rs +++ b/vendor/windows-bindgen/src/winmd/writer/file.rs @@ -1,5 +1,5 @@ use super::*; -use metadata::imp::*; +use metadata::*; use std::mem::*; pub fn write(mut tables: Vec<u8>, mut strings: Vec<u8>, mut blobs: Vec<u8>) -> Vec<u8> { diff --git a/vendor/windows-bindgen/src/winmd/writer/mod.rs b/vendor/windows-bindgen/src/winmd/writer/mod.rs index af49ecfeb..7ac4a08d6 100644 --- a/vendor/windows-bindgen/src/winmd/writer/mod.rs +++ b/vendor/windows-bindgen/src/winmd/writer/mod.rs @@ -9,7 +9,6 @@ mod r#type; use super::*; use blobs::Blobs; pub use codes::*; -use metadata::imp::*; pub use r#type::*; use std::collections::HashMap; use strings::Strings; @@ -150,39 +149,39 @@ impl Writer { fn type_blob(&mut self, ty: &Type, blob: &mut Vec<u8>) { match ty { - Type::Void => blob.push(ELEMENT_TYPE_VOID), - Type::Bool => blob.push(ELEMENT_TYPE_BOOLEAN), - Type::Char => blob.push(ELEMENT_TYPE_CHAR), - Type::I8 => blob.push(ELEMENT_TYPE_I1), - Type::U8 => blob.push(ELEMENT_TYPE_U1), - Type::I16 => blob.push(ELEMENT_TYPE_I2), - Type::U16 => blob.push(ELEMENT_TYPE_U2), - Type::I32 => blob.push(ELEMENT_TYPE_I4), - Type::U32 => blob.push(ELEMENT_TYPE_U4), - Type::I64 => blob.push(ELEMENT_TYPE_I8), - Type::U64 => blob.push(ELEMENT_TYPE_U8), - Type::F32 => blob.push(ELEMENT_TYPE_R4), - Type::F64 => blob.push(ELEMENT_TYPE_R8), - Type::ISize => blob.push(ELEMENT_TYPE_I), - Type::USize => blob.push(ELEMENT_TYPE_U), - Type::String => blob.push(ELEMENT_TYPE_STRING), - Type::IInspectable => blob.push(ELEMENT_TYPE_OBJECT), + Type::Void => blob.push(metadata::ELEMENT_TYPE_VOID), + Type::Bool => blob.push(metadata::ELEMENT_TYPE_BOOLEAN), + Type::Char => blob.push(metadata::ELEMENT_TYPE_CHAR), + Type::I8 => blob.push(metadata::ELEMENT_TYPE_I1), + Type::U8 => blob.push(metadata::ELEMENT_TYPE_U1), + Type::I16 => blob.push(metadata::ELEMENT_TYPE_I2), + Type::U16 => blob.push(metadata::ELEMENT_TYPE_U2), + Type::I32 => blob.push(metadata::ELEMENT_TYPE_I4), + Type::U32 => blob.push(metadata::ELEMENT_TYPE_U4), + Type::I64 => blob.push(metadata::ELEMENT_TYPE_I8), + Type::U64 => blob.push(metadata::ELEMENT_TYPE_U8), + Type::F32 => blob.push(metadata::ELEMENT_TYPE_R4), + Type::F64 => blob.push(metadata::ELEMENT_TYPE_R8), + Type::ISize => blob.push(metadata::ELEMENT_TYPE_I), + Type::USize => blob.push(metadata::ELEMENT_TYPE_U), + Type::String => blob.push(metadata::ELEMENT_TYPE_STRING), + Type::IInspectable => blob.push(metadata::ELEMENT_TYPE_OBJECT), Type::GUID => { let code = self.insert_type_ref("System", "Guid"); - blob.push(ELEMENT_TYPE_VALUETYPE); + blob.push(metadata::ELEMENT_TYPE_VALUETYPE); usize_blob(code as usize, blob); } Type::HRESULT => { let code = self.insert_type_ref("Windows.Foundation", "HResult"); - blob.push(ELEMENT_TYPE_VALUETYPE); + blob.push(metadata::ELEMENT_TYPE_VALUETYPE); usize_blob(code as usize, blob); } Type::TypeRef(ty) => { if !ty.generics.is_empty() { - blob.push(ELEMENT_TYPE_GENERICINST); + blob.push(metadata::ELEMENT_TYPE_GENERICINST); } let code = self.insert_type_ref(&ty.namespace, &ty.name); - blob.push(ELEMENT_TYPE_VALUETYPE); + blob.push(metadata::ELEMENT_TYPE_VALUETYPE); usize_blob(code as usize, blob); if !ty.generics.is_empty() { @@ -195,59 +194,59 @@ impl Writer { } Type::BSTR => { let code = self.insert_type_ref("Windows.Win32.Foundation", "BSTR"); - blob.push(ELEMENT_TYPE_VALUETYPE); + blob.push(metadata::ELEMENT_TYPE_VALUETYPE); usize_blob(code as usize, blob); } Type::IUnknown => { let code = self.insert_type_ref("Windows.Win32.Foundation", "IUnknown"); - blob.push(ELEMENT_TYPE_VALUETYPE); + blob.push(metadata::ELEMENT_TYPE_VALUETYPE); usize_blob(code as usize, blob); } Type::PCWSTR | Type::PWSTR => { let code = self.insert_type_ref("Windows.Win32.Foundation", "PWSTR"); - blob.push(ELEMENT_TYPE_VALUETYPE); + blob.push(metadata::ELEMENT_TYPE_VALUETYPE); usize_blob(code as usize, blob); } Type::PCSTR | Type::PSTR => { let code = self.insert_type_ref("Windows.Win32.Foundation", "PSTR"); - blob.push(ELEMENT_TYPE_VALUETYPE); + blob.push(metadata::ELEMENT_TYPE_VALUETYPE); usize_blob(code as usize, blob); } Type::ConstRef(ty) => { - usize_blob(ELEMENT_TYPE_CMOD_OPT as usize, blob); + usize_blob(metadata::ELEMENT_TYPE_CMOD_OPT as usize, blob); usize_blob(self.insert_type_ref("System.Runtime.CompilerServices", "IsConst") as usize, blob); - usize_blob(ELEMENT_TYPE_BYREF as usize, blob); + usize_blob(metadata::ELEMENT_TYPE_BYREF as usize, blob); self.type_blob(ty, blob); } Type::WinrtArrayRef(ty) => { - usize_blob(ELEMENT_TYPE_BYREF as usize, blob); - usize_blob(ELEMENT_TYPE_SZARRAY as usize, blob); + usize_blob(metadata::ELEMENT_TYPE_BYREF as usize, blob); + usize_blob(metadata::ELEMENT_TYPE_SZARRAY as usize, blob); self.type_blob(ty, blob); } Type::WinrtArray(ty) => { - usize_blob(ELEMENT_TYPE_SZARRAY as usize, blob); + usize_blob(metadata::ELEMENT_TYPE_SZARRAY as usize, blob); self.type_blob(ty, blob); } Type::Win32Array(ty, bounds) => { - usize_blob(ELEMENT_TYPE_ARRAY as usize, blob); + usize_blob(metadata::ELEMENT_TYPE_ARRAY as usize, blob); self.type_blob(ty, blob); usize_blob(1, blob); // rank usize_blob(1, blob); // count usize_blob(*bounds, blob); } - Type::TypeName => { + Type::Type => { let code = self.insert_type_ref("System", "Type"); - blob.push(ELEMENT_TYPE_CLASS); + blob.push(metadata::ELEMENT_TYPE_CLASS); usize_blob(code as usize, blob); } Type::MutPtr(ty, pointers) | Type::ConstPtr(ty, pointers) => { for _ in 0..*pointers { - usize_blob(ELEMENT_TYPE_PTR as usize, blob); + usize_blob(metadata::ELEMENT_TYPE_PTR as usize, blob); } self.type_blob(ty, blob); } Type::GenericParam(index) => { - blob.push(ELEMENT_TYPE_VAR); + blob.push(metadata::ELEMENT_TYPE_VAR); usize_blob(*index as usize, blob); } } @@ -276,54 +275,54 @@ fn usize_blob(value: usize, blob: &mut Vec<u8>) { } } -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_usize_blob() { - let mut blob = vec![]; - usize_blob(0, &mut blob); - usize_blob(1, &mut blob); - usize_blob(2, &mut blob); - - usize_blob(0x80 - 2, &mut blob); - usize_blob(0x80 - 1, &mut blob); - usize_blob(0x80, &mut blob); - usize_blob(0x80 + 1, &mut blob); - usize_blob(0x80 + 2, &mut blob); - - usize_blob(0x4000 - 2, &mut blob); - usize_blob(0x4000 - 1, &mut blob); - usize_blob(0x4000, &mut blob); - usize_blob(0x4000 + 1, &mut blob); - usize_blob(0x4000 + 2, &mut blob); - - usize_blob(0x20000000 - 3, &mut blob); - usize_blob(0x20000000 - 2, &mut blob); - usize_blob(0x20000000 - 1, &mut blob); - - let mut blob = metadata::Blob::new(0, &blob); - assert_eq!(blob.read_usize(), 0); - assert_eq!(blob.read_usize(), 1); - assert_eq!(blob.read_usize(), 2); - - assert_eq!(blob.read_usize(), 0x80 - 2); - assert_eq!(blob.read_usize(), 0x80 - 1); - assert_eq!(blob.read_usize(), 0x80); - assert_eq!(blob.read_usize(), 0x80 + 1); - assert_eq!(blob.read_usize(), 0x80 + 2); - - assert_eq!(blob.read_usize(), 0x4000 - 2); - assert_eq!(blob.read_usize(), 0x4000 - 1); - assert_eq!(blob.read_usize(), 0x4000); - assert_eq!(blob.read_usize(), 0x4000 + 1); - assert_eq!(blob.read_usize(), 0x4000 + 2); - - assert_eq!(blob.read_usize(), 0x20000000 - 3); - assert_eq!(blob.read_usize(), 0x20000000 - 2); - assert_eq!(blob.read_usize(), 0x20000000 - 1); - - assert_eq!(blob.slice.len(), 0); - } -} +// #[cfg(test)] +// mod tests { +// use super::*; + +// #[test] +// fn test_usize_blob() { +// let mut blob = vec![]; +// usize_blob(0, &mut blob); +// usize_blob(1, &mut blob); +// usize_blob(2, &mut blob); + +// usize_blob(0x80 - 2, &mut blob); +// usize_blob(0x80 - 1, &mut blob); +// usize_blob(0x80, &mut blob); +// usize_blob(0x80 + 1, &mut blob); +// usize_blob(0x80 + 2, &mut blob); + +// usize_blob(0x4000 - 2, &mut blob); +// usize_blob(0x4000 - 1, &mut blob); +// usize_blob(0x4000, &mut blob); +// usize_blob(0x4000 + 1, &mut blob); +// usize_blob(0x4000 + 2, &mut blob); + +// usize_blob(0x20000000 - 3, &mut blob); +// usize_blob(0x20000000 - 2, &mut blob); +// usize_blob(0x20000000 - 1, &mut blob); + +// let mut blob = metadata::Blob::new(0, &blob); +// assert_eq!(blob.read_usize(), 0); +// assert_eq!(blob.read_usize(), 1); +// assert_eq!(blob.read_usize(), 2); + +// assert_eq!(blob.read_usize(), 0x80 - 2); +// assert_eq!(blob.read_usize(), 0x80 - 1); +// assert_eq!(blob.read_usize(), 0x80); +// assert_eq!(blob.read_usize(), 0x80 + 1); +// assert_eq!(blob.read_usize(), 0x80 + 2); + +// assert_eq!(blob.read_usize(), 0x4000 - 2); +// assert_eq!(blob.read_usize(), 0x4000 - 1); +// assert_eq!(blob.read_usize(), 0x4000); +// assert_eq!(blob.read_usize(), 0x4000 + 1); +// assert_eq!(blob.read_usize(), 0x4000 + 2); + +// assert_eq!(blob.read_usize(), 0x20000000 - 3); +// assert_eq!(blob.read_usize(), 0x20000000 - 2); +// assert_eq!(blob.read_usize(), 0x20000000 - 1); + +// assert_eq!(blob.slice.len(), 0); +// } +// } diff --git a/vendor/windows-bindgen/src/winmd/writer/tables.rs b/vendor/windows-bindgen/src/winmd/writer/tables.rs index 4d4b8e354..a18aceae8 100644 --- a/vendor/windows-bindgen/src/winmd/writer/tables.rs +++ b/vendor/windows-bindgen/src/winmd/writer/tables.rs @@ -2,7 +2,7 @@ use super::Write; use super::*; -use metadata::imp::coded_index_size; +use metadata::*; #[derive(Default)] pub struct Tables { diff --git a/vendor/windows-bindgen/src/winmd/writer/type.rs b/vendor/windows-bindgen/src/winmd/writer/type.rs index 3f0178654..f04f86636 100644 --- a/vendor/windows-bindgen/src/winmd/writer/type.rs +++ b/vendor/windows-bindgen/src/winmd/writer/type.rs @@ -1,4 +1,4 @@ -#![allow(dead_code, clippy::upper_case_acronyms)] +#![allow(dead_code, clippy::upper_case_acronyms, clippy::enum_variant_names)] #[derive(Clone, Debug, Hash, PartialEq, Eq)] pub struct TypeName { @@ -34,7 +34,7 @@ pub enum Type { PCSTR, PCWSTR, BSTR, - TypeName, + Type, TypeRef(TypeName), GenericParam(u16), MutPtr(Box<Self>, usize), |