Skip to content

Commit 2134494

Browse files
authored
Merge branch 'master' into fix-cross-compilation
2 parents f74af29 + 4819651 commit 2134494

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+5334
-1480
lines changed

.github/workflows/build.yml

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: Build and Test
22

3-
on:
3+
on:
44
pull_request:
55
push:
66
branches:
@@ -12,7 +12,7 @@ env:
1212
jobs:
1313
test:
1414
runs-on: ${{ matrix.os }}
15-
strategy:
15+
strategy:
1616
matrix:
1717
include:
1818
- os: windows-latest
@@ -50,3 +50,21 @@ jobs:
5050
- name: fmt
5151
run: cargo fmt --all -- --check
5252
if: matrix.os == 'windows-latest' && matrix.rust == 'stable'
53+
54+
- name: generate bindings
55+
run: |
56+
cargo run -p windows_bindings --target ${{ matrix.other }}
57+
git diff --exit-code || (echo '::error::Generated bindings are out-of-date. Make sure to update them by running `cargo run -p windows_bindings`'; exit 1)
58+
shell: bash
59+
if: matrix.os == 'windows-latest' && matrix.rust == 'stable'
60+
61+
format-macro:
62+
runs-on: windows-latest
63+
name: Format `build!` macros
64+
steps:
65+
- uses: actions/checkout@v2
66+
- name: Invoke `windows_fmt`
67+
run: cargo r -p windows_fmt
68+
- name: Diff formatting result
69+
shell: bash
70+
run: git diff --exit-code || (echo '::error::Some `build!` macros were improperly formatted. Please run `cargo run -p windows_fmt` and push again'; exit 1)

crates/bindings/src/main.rs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,25 @@
11
use std::io::prelude::*;
22

33
fn main() -> std::io::Result<()> {
4-
let tokens = windows_macros::generate!(
4+
let tokens = windows_macros::generate! {
55
Windows::Foundation::{IReference, IStringable, PropertyValue},
66
Windows::Win32::System::Com::{
7-
CoCreateGuid, CoTaskMemAlloc, CoTaskMemFree, CLSIDFromProgID, CoInitializeEx, CoCreateInstance,
8-
IAgileObject, COINIT_MULTITHREADED, COINIT_APARTMENTTHREADED, CLSCTX_ALL,
7+
CLSIDFromProgID, CoCreateGuid, CoCreateInstance, CoInitializeEx, CoTaskMemAlloc,
8+
CoTaskMemFree, IAgileObject,
99
},
10-
Windows::Win32::System::Diagnostics::Debug::{
11-
GetLastError, FormatMessageW, FORMAT_MESSAGE_ALLOCATE_BUFFER, FORMAT_MESSAGE_FROM_SYSTEM,
12-
FORMAT_MESSAGE_IGNORE_INSERTS,
13-
},
14-
Windows::Win32::System::Memory::{
15-
GetProcessHeap, HeapAlloc, HeapFree, HEAP_NONE,
16-
},
17-
Windows::Win32::System::OleAutomation::{BSTR, GetErrorInfo, IErrorInfo, SetErrorInfo},
10+
Windows::Win32::System::Diagnostics::Debug::{FormatMessageW, GetLastError},
11+
Windows::Win32::System::Memory::{GetProcessHeap, HeapAlloc, HeapFree},
12+
Windows::Win32::System::OleAutomation::{GetErrorInfo, IErrorInfo, SetErrorInfo, BSTR},
1813
Windows::Win32::System::SystemServices::{
19-
GetProcAddress, LoadLibraryA, FreeLibrary, CO_E_NOTINITIALIZED, E_POINTER,
20-
},
21-
Windows::Win32::System::Threading::{
22-
CreateEventA, SetEvent, WaitForSingleObject,
14+
FreeLibrary, GetProcAddress, LoadLibraryA, CO_E_NOTINITIALIZED, E_POINTER,
2315
},
24-
Windows::Win32::System::WindowsProgramming::CloseHandle,
16+
Windows::Win32::System::Threading::{CreateEventA, SetEvent, WaitForSingleObject},
2517
Windows::Win32::System::WinRT::{
26-
IRestrictedErrorInfo, ILanguageExceptionErrorInfo2, IWeakReference, IWeakReferenceSource,
18+
ILanguageExceptionErrorInfo2, IRestrictedErrorInfo, IWeakReference,
19+
IWeakReferenceSource,
2720
},
28-
);
21+
Windows::Win32::System::WindowsProgramming::CloseHandle,
22+
};
2923

3024
let mut path = windows_gen::workspace_dir();
3125
path.push("src");

crates/fmt/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "windows_fmt"
3+
version = "0.0.0"
4+
edition = "2018"
5+
6+
[dependencies]
7+
windows_gen = { path = "../gen" }

crates/fmt/src/main.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
use std::ffi::OsStr;
2+
use std::io::Result;
3+
use std::io::Write;
4+
use std::path::*;
5+
use std::process::Command;
6+
use std::process::Stdio;
7+
8+
fn format_file(file: &Path, pattern: &str) -> Result<()> {
9+
const SHIM: &str = "use format_build_macro::{";
10+
11+
let contents = std::fs::read(file)?;
12+
let contents = String::from_utf8(contents).expect("Failed to parse UTF-8");
13+
14+
// Replace macro call with our `use` pattern
15+
let contents = contents.replace(pattern, SHIM);
16+
17+
// Spawn `rustfmt` and pipe string through it, instead of writing it to disk
18+
let mut child = Command::new("rustfmt")
19+
.stdin(Stdio::piped())
20+
.stdout(Stdio::piped())
21+
.spawn()
22+
.expect("Failed to spawn `rustfmt`");
23+
let mut stdin = child.stdin.take().expect("Failed to open stdin");
24+
stdin.write_all(contents.as_bytes())?;
25+
drop(stdin);
26+
27+
// Read formatted output from `rustfmt`
28+
let output = child.wait_with_output().expect("Failed to read stdout");
29+
let contents = String::from_utf8(output.stdout).expect("Failed to parse UTF-8");
30+
31+
// Some build macros contain a single item, where curly braces are removed. Those
32+
// cannot easily be formatted yet.
33+
if contents.contains(SHIM) {
34+
std::fs::write(file, contents.replace(SHIM, pattern))?;
35+
}
36+
37+
Ok(())
38+
}
39+
40+
fn walk_path(path: &Path) -> Result<()> {
41+
if path.is_dir() {
42+
for entry in path.read_dir()? {
43+
walk_path(&entry?.path())?;
44+
}
45+
} else if path.file_name() == Some(OsStr::new("build.rs")) {
46+
format_file(path, "windows::build! {")?;
47+
}
48+
49+
Ok(())
50+
}
51+
52+
fn main() -> Result<()> {
53+
let dir = windows_gen::workspace_dir();
54+
walk_path(&dir)?;
55+
56+
format_file(
57+
&dir.join("crates/bindings/src/main.rs"),
58+
"let tokens = windows_macros::generate! {",
59+
)
60+
}

crates/gen/src/async.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use super::*;
1+
use crate::*;
22

33
pub fn gen_async(
4-
def: &GenericType,
4+
def: &tables::TypeDef,
55
interfaces: &[InterfaceInfo],
66
gen: &Gen,
77
) -> (TokenStream, TokenStream) {
@@ -31,12 +31,12 @@ pub enum AsyncKind {
3131
OperationWithProgress,
3232
}
3333

34-
pub fn async_kind(def: &GenericType) -> AsyncKind {
35-
if def.def.namespace() != "Windows.Foundation" {
34+
pub fn async_kind(def: &tables::TypeDef) -> AsyncKind {
35+
if def.namespace() != "Windows.Foundation" {
3636
return AsyncKind::None;
3737
}
3838

39-
match def.def.name() {
39+
match def.name() {
4040
"IAsyncAction" => AsyncKind::Action,
4141
"IAsyncActionWithProgress`1" => AsyncKind::ActionWithProgress,
4242
"IAsyncOperation`1" => AsyncKind::Operation,
@@ -47,8 +47,8 @@ pub fn async_kind(def: &GenericType) -> AsyncKind {
4747

4848
fn gen_async_kind(
4949
kind: AsyncKind,
50-
name: &GenericType,
51-
self_name: &GenericType,
50+
name: &tables::TypeDef,
51+
self_name: &tables::TypeDef,
5252
gen: &Gen,
5353
) -> (TokenStream, TokenStream) {
5454
let return_type = match kind {

crates/gen/src/iterator.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use super::*;
55
// only falls back to IIterator<T> if nothing faster is available. VectorIterator and
66
// VectorViewIterator are faster iterators than IIterator<T> because they only require a single
77
// vcall per iteration wheras IIterator<T> requires two.
8-
pub fn gen_iterator(def: &GenericType, interfaces: &[InterfaceInfo], gen: &Gen) -> TokenStream {
9-
let name = def.def.full_name();
8+
pub fn gen_iterator(def: &tables::TypeDef, interfaces: &[InterfaceInfo], gen: &Gen) -> TokenStream {
9+
let name = def.full_name();
1010

1111
// If the type is IIterator<T> then simply implement the Iterator trait over top.
1212
if name == ("Windows.Foundation.Collections", "IIterator`1") {
@@ -154,7 +154,7 @@ pub fn gen_iterator(def: &GenericType, interfaces: &[InterfaceInfo], gen: &Gen)
154154
// If the class or interface is not one of the well-known collection interfaces, we then see whether it
155155
// implements any one of them. Here is where we favor IVectorView/IVector over IIterable.
156156
for interface in interfaces {
157-
let name = interface.def.def.full_name();
157+
let name = interface.def.full_name();
158158

159159
if name == ("Windows.Foundation.Collections", "IVectorView`1") {
160160
let constraints = def.gen_constraints(gen);

crates/gen/src/parser/codes.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pub trait Decode {
44
fn decode(file: &'static File, code: u32) -> Self;
55
}
66

7-
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord)]
7+
#[derive(Clone, Debug)]
88
pub enum TypeDefOrRef {
99
TypeDef(tables::TypeDef),
1010
TypeRef(tables::TypeRef),
@@ -15,7 +15,7 @@ impl Decode for TypeDefOrRef {
1515
fn decode(file: &'static File, code: u32) -> Self {
1616
let code = (code & ((1 << 2) - 1), (code >> 2) - 1);
1717
match code.0 {
18-
0 => Self::TypeDef(tables::TypeDef(Row::new(code.1, TableIndex::TypeDef, file))),
18+
0 => Self::TypeDef(Row::new(code.1, TableIndex::TypeDef, file).into()),
1919
1 => Self::TypeRef(tables::TypeRef(Row::new(code.1, TableIndex::TypeRef, file))),
2020
2 => Self::TypeSpec(tables::TypeSpec(Row::new(
2121
code.1,
@@ -30,14 +30,14 @@ impl Decode for TypeDefOrRef {
3030
impl TypeDefOrRef {
3131
pub fn encode(&self) -> u32 {
3232
match self {
33-
Self::TypeDef(value) => ((value.0.row + 1) << 2),
33+
Self::TypeDef(value) => ((value.row.row + 1) << 2),
3434
Self::TypeRef(value) => ((value.0.row + 1) << 2) | 1,
3535
Self::TypeSpec(value) => ((value.0.row + 1) << 2) | 2,
3636
}
3737
}
3838
}
3939

40-
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord)]
40+
#[derive(Clone, Debug)]
4141
pub enum TypeOrMethodDef {
4242
TypeDef(tables::TypeDef),
4343
MethodDef(tables::MethodDef),
@@ -47,7 +47,7 @@ impl Decode for TypeOrMethodDef {
4747
fn decode(file: &'static File, code: u32) -> Self {
4848
let code = (code & ((1 << 1) - 1), (code >> 1) - 1);
4949
match code.0 {
50-
0 => Self::TypeDef(tables::TypeDef(Row::new(code.1, TableIndex::TypeDef, file))),
50+
0 => Self::TypeDef(Row::new(code.1, TableIndex::TypeDef, file).into()),
5151
1 => Self::MethodDef(tables::MethodDef(Row::new(
5252
code.1,
5353
TableIndex::MethodDef,
@@ -61,13 +61,13 @@ impl Decode for TypeOrMethodDef {
6161
impl TypeOrMethodDef {
6262
pub fn encode(&self) -> u32 {
6363
match self {
64-
Self::TypeDef(value) => ((value.0.row + 1) << 1),
64+
Self::TypeDef(value) => ((value.row.row + 1) << 1),
6565
Self::MethodDef(value) => ((value.0.row + 1) << 1) | 1,
6666
}
6767
}
6868
}
6969

70-
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord)]
70+
#[derive(Clone, Debug)]
7171
pub enum HasAttribute {
7272
MethodDef(tables::MethodDef),
7373
Field(tables::Field),
@@ -91,7 +91,7 @@ impl Decode for HasAttribute {
9191
))),
9292
1 => Self::Field(tables::Field(Row::new(code.1, TableIndex::Field, file))),
9393
2 => Self::TypeRef(tables::TypeRef(Row::new(code.1, TableIndex::TypeRef, file))),
94-
3 => Self::TypeDef(tables::TypeDef(Row::new(code.1, TableIndex::TypeDef, file))),
94+
3 => Self::TypeDef(Row::new(code.1, TableIndex::TypeDef, file).into()),
9595
4 => Self::Param(tables::Param(Row::new(code.1, TableIndex::Param, file))),
9696
5 => Self::InterfaceImpl(tables::InterfaceImpl(Row::new(
9797
code.1,
@@ -124,7 +124,7 @@ impl HasAttribute {
124124
Self::MethodDef(value) => ((value.0.row + 1) << 5),
125125
Self::Field(value) => ((value.0.row + 1) << 5) | 1,
126126
Self::TypeRef(value) => ((value.0.row + 1) << 5) | 2,
127-
Self::TypeDef(value) => ((value.0.row + 1) << 5) | 3,
127+
Self::TypeDef(value) => ((value.row.row + 1) << 5) | 3,
128128
Self::Param(value) => ((value.0.row + 1) << 5) | 4,
129129
Self::InterfaceImpl(value) => ((value.0.row + 1) << 5) | 5,
130130
Self::MemberRef(value) => ((value.0.row + 1) << 5) | 6,
@@ -134,7 +134,7 @@ impl HasAttribute {
134134
}
135135
}
136136

137-
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord)]
137+
#[derive(Clone, Debug)]
138138
pub enum MemberRefParent {
139139
TypeDef(tables::TypeDef),
140140
TypeRef(tables::TypeRef),
@@ -146,7 +146,7 @@ impl Decode for MemberRefParent {
146146
fn decode(file: &'static File, code: u32) -> Self {
147147
let code = (code & ((1 << 3) - 1), (code >> 3) - 1);
148148
match code.0 {
149-
0 => Self::TypeDef(tables::TypeDef(Row::new(code.1, TableIndex::TypeDef, file))),
149+
0 => Self::TypeDef(Row::new(code.1, TableIndex::TypeDef, file).into()),
150150
1 => Self::TypeRef(tables::TypeRef(Row::new(code.1, TableIndex::TypeRef, file))),
151151
3 => Self::MethodDef(tables::MethodDef(Row::new(
152152
code.1,
@@ -166,15 +166,15 @@ impl Decode for MemberRefParent {
166166
impl MemberRefParent {
167167
pub fn encode(&self) -> u32 {
168168
match self {
169-
Self::TypeDef(value) => ((value.0.row + 1) << 3),
169+
Self::TypeDef(value) => ((value.row.row + 1) << 3),
170170
Self::TypeRef(value) => ((value.0.row + 1) << 3) | 1,
171171
Self::MethodDef(value) => ((value.0.row + 1) << 3) | 3,
172172
Self::TypeSpec(value) => ((value.0.row + 1) << 3) | 4,
173173
}
174174
}
175175
}
176176

177-
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord)]
177+
#[derive(Clone, Debug)]
178178
pub enum HasConstant {
179179
Field(tables::Field),
180180
Param(tables::Param),
@@ -200,7 +200,7 @@ impl HasConstant {
200200
}
201201
}
202202

203-
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord)]
203+
#[derive(Clone, Debug)]
204204
pub enum AttributeType {
205205
MethodDef(tables::MethodDef),
206206
MemberRef(tables::MemberRef),
@@ -234,7 +234,7 @@ impl AttributeType {
234234
}
235235
}
236236

237-
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord)]
237+
#[derive(Clone, Debug)]
238238
pub enum MemberForwarded {
239239
Field(tables::Field),
240240
MethodDef(tables::MethodDef),
@@ -264,7 +264,7 @@ impl MemberForwarded {
264264
}
265265
}
266266

267-
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord)]
267+
#[derive(Clone, Debug)]
268268
pub enum ResolutionScope {
269269
Module(tables::Module),
270270
ModuleRef(tables::ModuleRef),
@@ -331,7 +331,7 @@ impl TypeDefOrRef {
331331

332332
pub fn resolve(&self) -> tables::TypeDef {
333333
match self {
334-
Self::TypeDef(value) => *value,
334+
Self::TypeDef(value) => value.clone(),
335335
Self::TypeRef(value) => value.resolve(),
336336
_ => unexpected!(),
337337
}

0 commit comments

Comments
 (0)