Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Include nested dependencies in standalone code generation #2480

Merged
merged 6 commits into from
Apr 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

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