Skip to content

Commit

Permalink
Include nested dependencies in standalone code generation (#2480)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jake-Shadle authored Apr 27, 2023
1 parent 01fb045 commit 7c835e3
Show file tree
Hide file tree
Showing 6 changed files with 258 additions and 5 deletions.
10 changes: 8 additions & 2 deletions crates/libs/bindgen/src/standalone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,10 @@ fn standalone_imp(gen: &mut Gen, names: &[&str]) -> String {
let name = gen.reader.type_def_name(def);
if gen.sys {
let ident = to_ident(name);
sorted.insert(name, quote! { type #ident = *mut ::core::ffi::c_void; });
sorted.insert(
name,
quote! { pub type #ident = *mut ::core::ffi::c_void; },
);
} else {
sorted.insert(name, classes::gen(gen, def));
}
Expand All @@ -165,7 +168,10 @@ fn standalone_imp(gen: &mut Gen, names: &[&str]) -> String {
let name = gen.reader.type_def_name(def);
if gen.sys {
let ident = to_ident(name);
sorted.insert(name, quote! { type #ident = *mut ::core::ffi::c_void; });
sorted.insert(
name,
quote! { pub type #ident = *mut ::core::ffi::c_void; },
);
} else {
sorted.insert(name, interfaces::gen(gen, def));
}
Expand Down
4 changes: 2 additions & 2 deletions crates/libs/core/src/imp/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ pub type HEAP_FLAGS = u32;
pub type HMODULE = isize;
pub type HRESULT = i32;
pub type HeapHandle = isize;
type IAgileReference = *mut ::core::ffi::c_void;
type IErrorInfo = *mut ::core::ffi::c_void;
pub type IAgileReference = *mut ::core::ffi::c_void;
pub type IErrorInfo = *mut ::core::ffi::c_void;
pub type IUnknown = *mut ::core::ffi::c_void;
pub const JSCRIPT_E_CANTEXECUTE: HRESULT = -1996357631i32;
pub type LOAD_LIBRARY_FLAGS = u32;
Expand Down
2 changes: 1 addition & 1 deletion crates/libs/core/src/imp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ mod sha1;
mod waiter;
mod weak_ref_count;

pub use bindings::*;
pub use bindings::{CloseHandle, CoCreateGuid, CoTaskMemAlloc, CoTaskMemFree, CreateEventW, EncodePointer, FormatMessageW, FreeLibrary, GetErrorInfo, GetLastError, GetProcAddress, GetProcessHeap, HeapAlloc, HeapFree, LoadLibraryExA, RoGetAgileReference, SetErrorInfo, SetEvent, SysAllocStringLen, SysFreeString, SysStringLen, WaitForSingleObject, AGILEREFERENCE_DEFAULT, CLASS_E_CLASSNOTAVAILABLE, CO_E_NOTINITIALIZED, ERROR_NO_UNICODE_TRANSLATION, E_BOUNDS, E_NOINTERFACE, E_OUTOFMEMORY, FORMAT_MESSAGE_ALLOCATE_BUFFER, FORMAT_MESSAGE_FROM_SYSTEM, FORMAT_MESSAGE_IGNORE_INSERTS, GUID, HRESULT, JSCRIPT_E_CANTEXECUTE, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS, RPC_E_DISCONNECTED, S_OK};
pub use com_bindings::*;
pub use delay_load::*;
pub use factory_cache::*;
Expand Down
22 changes: 22 additions & 0 deletions crates/libs/metadata/src/reader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1535,9 +1535,31 @@ impl<'a> Reader<'a> {
if self.type_def_kind(*def) == TypeKind::Struct && self.type_def_fields(*def).next().is_none() && self.type_def_guid(*def).is_some() {
set.insert(Type::GUID);
}

self.type_collect_standalone_nested(*def, set);
}
}
}

fn type_collect_standalone_nested(&self, td: TypeDef, set: &mut BTreeSet<Type>) {
for nested in self.nested_types(td) {
self.type_collect_standalone_nested(nested, set);

for field in self.type_def_fields(nested) {
let ty = self.field_type(field, 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 self.type_def_namespace(*def).is_empty() {
continue;
}

self.type_collect_standalone(&ty, set);
}
}
}
}

pub fn type_cfg(&self, ty: &Type) -> Cfg {
let mut cfg = Cfg::default();
self.type_cfg_combine(ty, &mut cfg);
Expand Down
9 changes: 9 additions & 0 deletions crates/tests/standalone/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ fn main() {
"Windows.Win32.UI.WindowsAndMessaging.wsprintfA",
],
);

// Ensures nested records write out all the types they depend on
write_sys(
"src/b_nested.rs",
&[
"Windows.Win32.System.Com.STGMEDIUM",
"Windows.Win32.Graphics.Gdi.DEVMODEW",
],
);
}

fn write_sys(filename: &str, apis: &[&str]) {
Expand Down
216 changes: 216 additions & 0 deletions crates/tests/standalone/src/b_nested.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
// Bindings generated by `windows-bindgen` 0.49.0

#![allow(
non_snake_case,
non_upper_case_globals,
non_camel_case_types,
dead_code,
clippy::all
)]
#[repr(C)]
pub struct DEVMODEW {
pub dmDeviceName: [u16; 32],
pub dmSpecVersion: u16,
pub dmDriverVersion: u16,
pub dmSize: u16,
pub dmDriverExtra: u16,
pub dmFields: DEVMODE_FIELD_FLAGS,
pub Anonymous1: DEVMODEW_0,
pub dmColor: DEVMODE_COLOR,
pub dmDuplex: DEVMODE_DUPLEX,
pub dmYResolution: i16,
pub dmTTOption: DEVMODE_TRUETYPE_OPTION,
pub dmCollate: DEVMODE_COLLATE,
pub dmFormName: [u16; 32],
pub dmLogPixels: u16,
pub dmBitsPerPel: u32,
pub dmPelsWidth: u32,
pub dmPelsHeight: u32,
pub Anonymous2: DEVMODEW_1,
pub dmDisplayFrequency: u32,
pub dmICMMethod: u32,
pub dmICMIntent: u32,
pub dmMediaType: u32,
pub dmDitherType: u32,
pub dmReserved1: u32,
pub dmReserved2: u32,
pub dmPanningWidth: u32,
pub dmPanningHeight: u32,
}
impl ::core::marker::Copy for DEVMODEW {}
impl ::core::clone::Clone for DEVMODEW {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
pub union DEVMODEW_0 {
pub Anonymous1: DEVMODEW_0_0,
pub Anonymous2: DEVMODEW_0_1,
}
impl ::core::marker::Copy for DEVMODEW_0 {}
impl ::core::clone::Clone for DEVMODEW_0 {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
pub struct DEVMODEW_0_0 {
pub dmOrientation: i16,
pub dmPaperSize: i16,
pub dmPaperLength: i16,
pub dmPaperWidth: i16,
pub dmScale: i16,
pub dmCopies: i16,
pub dmDefaultSource: i16,
pub dmPrintQuality: i16,
}
impl ::core::marker::Copy for DEVMODEW_0_0 {}
impl ::core::clone::Clone for DEVMODEW_0_0 {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
pub struct DEVMODEW_0_1 {
pub dmPosition: POINTL,
pub dmDisplayOrientation: DEVMODE_DISPLAY_ORIENTATION,
pub dmDisplayFixedOutput: DEVMODE_DISPLAY_FIXED_OUTPUT,
}
impl ::core::marker::Copy for DEVMODEW_0_1 {}
impl ::core::clone::Clone for DEVMODEW_0_1 {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
pub union DEVMODEW_1 {
pub dmDisplayFlags: u32,
pub dmNup: u32,
}
impl ::core::marker::Copy for DEVMODEW_1 {}
impl ::core::clone::Clone for DEVMODEW_1 {
fn clone(&self) -> Self {
*self
}
}
pub type DEVMODE_COLLATE = u16;
pub type DEVMODE_COLOR = u16;
pub type DEVMODE_DISPLAY_FIXED_OUTPUT = u32;
pub type DEVMODE_DISPLAY_ORIENTATION = u32;
pub type DEVMODE_DUPLEX = u16;
pub type DEVMODE_FIELD_FLAGS = u32;
pub type DEVMODE_TRUETYPE_OPTION = u16;
#[repr(C)]
pub struct FILETIME {
pub dwLowDateTime: u32,
pub dwHighDateTime: u32,
}
impl ::core::marker::Copy for FILETIME {}
impl ::core::clone::Clone for FILETIME {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
#[derive(
::core::marker::Copy,
::core::clone::Clone,
::core::default::Default,
::core::cmp::PartialEq,
::core::cmp::Eq,
::core::hash::Hash,
)]
pub struct GUID {
pub data1: u32,
pub data2: u16,
pub data3: u16,
pub data4: [u8; 8],
}
impl GUID {
pub const fn from_u128(uuid: u128) -> Self {
Self {
data1: (uuid >> 96) as u32,
data2: (uuid >> 80 & 0xffff) as u16,
data3: (uuid >> 64 & 0xffff) as u16,
data4: (uuid as u64).to_be_bytes(),
}
}
}
pub type HBITMAP = isize;
pub type HENHMETAFILE = isize;
pub type HGLOBAL = isize;
pub type HRESULT = i32;
pub type IEnumSTATSTG = *mut ::core::ffi::c_void;
pub type ISequentialStream = *mut ::core::ffi::c_void;
pub type IStorage = *mut ::core::ffi::c_void;
pub type IStream = *mut ::core::ffi::c_void;
pub type IUnknown = *mut ::core::ffi::c_void;
pub type LOCKTYPE = i32;
pub type PCWSTR = *const u16;
#[repr(C)]
pub struct POINTL {
pub x: i32,
pub y: i32,
}
impl ::core::marker::Copy for POINTL {}
impl ::core::clone::Clone for POINTL {
fn clone(&self) -> Self {
*self
}
}
pub type PWSTR = *mut u16;
pub type STATFLAG = i32;
#[repr(C)]
pub struct STATSTG {
pub pwcsName: PWSTR,
pub r#type: u32,
pub cbSize: u64,
pub mtime: FILETIME,
pub ctime: FILETIME,
pub atime: FILETIME,
pub grfMode: STGM,
pub grfLocksSupported: LOCKTYPE,
pub clsid: GUID,
pub grfStateBits: u32,
pub reserved: u32,
}
impl ::core::marker::Copy for STATSTG {}
impl ::core::clone::Clone for STATSTG {
fn clone(&self) -> Self {
*self
}
}
pub type STGC = i32;
pub type STGM = u32;
#[repr(C)]
pub struct STGMEDIUM {
pub tymed: TYMED,
pub u: STGMEDIUM_0,
pub pUnkForRelease: IUnknown,
}
impl ::core::marker::Copy for STGMEDIUM {}
impl ::core::clone::Clone for STGMEDIUM {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
pub union STGMEDIUM_0 {
pub hBitmap: HBITMAP,
pub hMetaFilePict: *mut ::core::ffi::c_void,
pub hEnhMetaFile: HENHMETAFILE,
pub hGlobal: HGLOBAL,
pub lpszFileName: PWSTR,
pub pstm: IStream,
pub pstg: IStorage,
}
impl ::core::marker::Copy for STGMEDIUM_0 {}
impl ::core::clone::Clone for STGMEDIUM_0 {
fn clone(&self) -> Self {
*self
}
}
pub type STGMOVE = i32;
pub type STREAM_SEEK = u32;
pub type TYMED = i32;

0 comments on commit 7c835e3

Please sign in to comment.