Skip to content

Commit 4a29151

Browse files
authored
Additional type system support (#389)
1 parent 5ca7704 commit 4a29151

File tree

4 files changed

+76
-8
lines changed

4 files changed

+76
-8
lines changed

crates/gen/src/function.rs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,78 @@ use squote::{quote, TokenStream};
55
pub struct Function {
66
pub name: TypeName,
77
pub method: winmd::MethodDef,
8+
pub params: Vec<(&'static str, Type)>,
9+
pub return_type: Option<Type>,
810
}
911

1012
impl Function {
1113
pub fn new(name: TypeName, method: &winmd::MethodDef) -> Self {
14+
let mut blob = method.sig();
15+
16+
if blob.read_unsigned() & 0x10 != 0 {
17+
blob.read_unsigned();
18+
}
19+
20+
let param_count = blob.read_unsigned();
21+
blob.read_modifiers();
22+
blob.read_expected(0x10);
23+
24+
let mut params = Vec::with_capacity(param_count as usize);
25+
26+
let return_type = if blob.read_expected(0x01) {
27+
None
28+
} else {
29+
Some(Type::from_blob(&mut blob, &[], name.namespace))
30+
};
31+
32+
for param in method.params() {
33+
if return_type.is_none() || param.sequence() != 0 {
34+
blob.read_modifiers(); // const
35+
blob.read_expected(0x10); // ref
36+
params.push((
37+
param.name(),
38+
Type::from_blob(&mut blob, &[], name.namespace),
39+
));
40+
}
41+
}
42+
1243
Self {
1344
name,
1445
method: *method,
46+
params,
47+
return_type,
1548
}
1649
}
1750

1851
pub fn gen(&self) -> TokenStream {
1952
let name = format_ident(self.method.name());
2053

54+
let return_type = if let Some(t) = &self.return_type {
55+
let tokens = t.gen_field();
56+
quote! { -> #tokens }
57+
} else {
58+
TokenStream::new()
59+
};
60+
61+
let params = self.params.iter().map(|(name, t)| {
62+
let name = format_ident(name);
63+
let tokens = t.gen_field();
64+
quote! { #name: #tokens }
65+
});
66+
2167
quote! {
2268
#[link(name = "onecoreuap")]
2369
extern "system" {
24-
pub fn #name();
70+
pub fn #name(#(#params),*) #return_type;
2571
}
2672
}
2773
}
2874

2975
pub fn dependencies(&self) -> Vec<winmd::TypeDef> {
30-
Vec::new()
76+
self.return_type
77+
.iter()
78+
.chain(self.params.iter().map(|(_, t)| t))
79+
.flat_map(|t| t.kind.dependencies())
80+
.collect()
3181
}
3282
}

crates/tests/build.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ fn main() {
3333
windows::win32::{
3434
ACCESS_MODE, CHOOSECOLORW, DXGI_ADAPTER_FLAG, DXGI_FORMAT, DXGI_MODE_DESC, DXGI_MODE_SCALING,
3535
DXGI_MODE_SCANLINE_ORDER, DXGI_RATIONAL, RECT, WM_KEYUP, ALLJOYN_BIG_ENDIAN, ALLJOYN_CRED_CERT_CHAIN,
36-
D3D12_DEFAULT_BLEND_FACTOR_ALPHA, UIA_ScrollPatternNoScroll, D3DCOMPILER_DLL
36+
D3D12_DEFAULT_BLEND_FACTOR_ALPHA, UIA_ScrollPatternNoScroll, D3DCOMPILER_DLL,
37+
CreateEventW, SetEvent, WaitForSingleObject, CloseHandle
3738
}
3839
);
3940
}

crates/tests/tests/win32.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use tests::windows::win32::{
2-
UIA_ScrollPatternNoScroll, ACCESS_MODE, ALLJOYN_BIG_ENDIAN, ALLJOYN_CRED_CERT_CHAIN,
3-
CHOOSECOLORW, D3D12_DEFAULT_BLEND_FACTOR_ALPHA, D3DCOMPILER_DLL, DXGI_ADAPTER_FLAG,
4-
DXGI_FORMAT, DXGI_MODE_DESC, DXGI_MODE_SCALING, DXGI_MODE_SCANLINE_ORDER, DXGI_RATIONAL, RECT,
5-
WM_KEYUP,
2+
CloseHandle, CreateEventW, SetEvent, UIA_ScrollPatternNoScroll, WaitForSingleObject,
3+
ACCESS_MODE, ALLJOYN_BIG_ENDIAN, ALLJOYN_CRED_CERT_CHAIN, CHOOSECOLORW,
4+
D3D12_DEFAULT_BLEND_FACTOR_ALPHA, D3DCOMPILER_DLL, DXGI_ADAPTER_FLAG, DXGI_FORMAT,
5+
DXGI_MODE_DESC, DXGI_MODE_SCALING, DXGI_MODE_SCANLINE_ORDER, DXGI_RATIONAL, RECT, WM_KEYUP,
66
};
77
use winrt::Abi;
88

@@ -96,3 +96,20 @@ fn constant() {
9696
assert!(UIA_ScrollPatternNoScroll == -1f64);
9797
assert!(D3DCOMPILER_DLL == "d3dcompiler_47.dll");
9898
}
99+
100+
#[test]
101+
fn function() {
102+
unsafe {
103+
let event = CreateEventW(std::ptr::null_mut(), 1, 0, std::ptr::null_mut());
104+
assert!(event != 0);
105+
106+
let result = SetEvent(event);
107+
assert!(result != 0);
108+
109+
let result = WaitForSingleObject(event, 0);
110+
assert!(result == 0); // https://github.com/microsoft/win32metadata/issues/77
111+
112+
let result = CloseHandle(event);
113+
assert!(result != 0);
114+
}
115+
}

crates/winmd/src/parsed/param.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ impl Param {
1616
self.reader.u32(self.row, 1)
1717
}
1818

19-
pub fn name(&self) -> &str {
19+
pub fn name(&self) -> &'static str {
2020
self.reader.str(self.row, 2)
2121
}
2222
}

0 commit comments

Comments
 (0)