Skip to content

Commit

Permalink
Code gen overhaul (#577)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr authored Mar 9, 2021
1 parent b434fcb commit 6b37abc
Show file tree
Hide file tree
Showing 219 changed files with 7,455 additions and 7,591 deletions.
Binary file removed .windows/winmd/Windows.Win32.winmd
Binary file not shown.
Binary file removed .windows/winmd/Windows.WinRT.winmd
Binary file not shown.
11 changes: 6 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
[package]
name = "windows"
version = "0.3.1"
version = "0.4.0"
authors = ["Microsoft"]
edition = "2018"
license = "MIT OR Apache-2.0"
description = "Windows Runtime language projection"
description = "Rust for Windows"
repository = "https://github.com/microsoft/windows-rs"
documentation = "https://docs.rs/windows"
readme = "README.md"

[dependencies]
windows_macros = { path = "crates/macros", version = "0.3.1" }
gen = { package = "windows_gen", path = "crates/gen", version = "0.3.1" }
windows_macros = { path = "crates/macros", version = "0.4.0" }
gen = { package = "windows_gen", path = "crates/gen", version = "0.4.0" }
const-sha1 = "0.2"

[build-dependencies]
windows_macros = { path = "crates/macros", version = "0.3.1" }
windows_macros = { path = "crates/macros", version = "0.4.0" }

[dev-dependencies]
doc-comment = "0.3"
Expand All @@ -25,6 +25,7 @@ gen = { package = "windows_gen", path = "crates/gen" }
members = [
"crates/*",
"examples/*",
"tests/*",
]

[package.metadata.docs.rs]
Expand Down
7 changes: 6 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
fn main() {
windows_macros::build!();
windows_macros::build!(
windows::foundation::{IReference, IStringable, PropertyValue},
windows::win32::automation::{BSTR, GetErrorInfo, IErrorInfo, SetErrorInfo},
windows::win32::winrt::{IRestrictedErrorInfo, ILanguageExceptionErrorInfo2},
windows::win32::debug::GetLastError,
);
}
4 changes: 2 additions & 2 deletions crates/gen/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[package]
name = "windows_gen"
version = "0.3.1"
version = "0.4.0"
authors = ["Microsoft"]
edition = "2018"
license = "MIT OR Apache-2.0"
description = "Code generation for the windows crate"

[dependencies]
macros = { package = "windows_gen_macros", path = "macros", version = "0.3.1" }
macros = { package = "windows_gen_macros", path = "macros", version = "0.4.0" }
quote = "1.0"
syn = "1.0"
proc-macro2 = "1.0"
Expand Down
Binary file modified crates/gen/default/Windows.Win32.winmd
Binary file not shown.
12 changes: 12 additions & 0 deletions crates/gen/default/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
These `.winmd` files together provide the default metadata for the Windows API. This is only used when the
dependent crate or workspace has an empty or non-existent `.windows/winmd` directory.

## Windows.Win32.winmd
- Source: https://www.nuget.org/packages/Microsoft.Windows.SDK.Win32Metadata/
- Version: 10.0.19041.5-preview.20

## Windows.WinRT.winmd
- Source: https://www.nuget.org/packages/Microsoft.Windows.SDK.Contracts
- Version: 10.0.19041.1

TODO: describe how the merged WinRT winmd is created.
2 changes: 1 addition & 1 deletion crates/gen/macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "windows_gen_macros"
version = "0.3.1"
version = "0.4.0"
authors = ["Microsoft"]
edition = "2018"
license = "MIT OR Apache-2.0"
Expand Down
17 changes: 4 additions & 13 deletions crates/gen/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use std::iter::FromIterator;
#[proc_macro]
pub fn table(name: TokenStream) -> TokenStream {
let ident = syn::parse_macro_input!(name as syn::Ident);
let name = ident.to_string();

quote!(
#[derive(Copy, Clone)]
Expand All @@ -17,14 +16,6 @@ pub fn table(name: TokenStream) -> TokenStream {
pub row: super::Row,
}

impl std::fmt::Debug for #ident {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct(#name)
.field("row", &self.row)
.finish()
}
}

impl PartialEq for #ident {
fn eq(&self, other: &Self) -> bool {
self.row == other.row
Expand Down Expand Up @@ -54,7 +45,7 @@ pub fn type_code(args: TokenStream, input: TokenStream) -> TokenStream {
let input = syn::parse_macro_input!(input as syn::ItemEnum);

if args.len() != 1 {
panic!("The `type_code` attribute expects a single integer literal argument");
panic!("type_code");
}

let bits = &args[0];
Expand All @@ -75,11 +66,11 @@ pub fn type_code(args: TokenStream, input: TokenStream) -> TokenStream {
}

variants.push(quote!(
#name(#name),
#name(tables::#name),
));

decodes.push(quote!(
#enumerator => Self::#name( #name{ reader, row:Row::new(code.1, TableIndex::#table, file) }),
#enumerator => Self::#name( tables::#name{ reader, row:Row::new(code.1, TableIndex::#table, file) }),
));

encodes.push(quote!(
Expand All @@ -103,7 +94,7 @@ pub fn type_code(args: TokenStream, input: TokenStream) -> TokenStream {
let code = (code & ((1 << #bits) - 1), (code >> #bits) - 1);
match code.0 {
#decodes
_ => panic!("Failed to decode type code"),
_ => panic!("type_code"),
}
}
}
Expand Down
46 changes: 26 additions & 20 deletions crates/gen/src/futures.rs → crates/gen/src/async.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,42 @@
use crate::*;
use squote::{quote, TokenStream};
use super::*;

pub fn gen_async(
def: &GenericType,
interfaces: &[InterfaceInfo],
gen: Gen,
) -> (TokenStream, TokenStream) {
let kind = async_kind(def);

pub fn gen_async(name: &TypeName, interfaces: &[RequiredInterface]) -> (TokenStream, TokenStream) {
let kind = async_kind(name);
if kind != AsyncKind::None {
return gen_async_kind(kind, name, name);
return gen_async_kind(kind, def, def, gen);
}

for interface in interfaces {
let kind = async_kind(&interface.name);
let kind = async_kind(&interface.def);

if kind != AsyncKind::None {
return gen_async_kind(kind, &interface.name, name);
return gen_async_kind(kind, &interface.def, def, gen);
}
}

(TokenStream::new(), TokenStream::new())
}

#[derive(PartialEq)]
enum AsyncKind {
pub enum AsyncKind {
None,
Action,
ActionWithProgress,
Operation,
OperationWithProgress,
}

fn async_kind(name: &TypeName) -> AsyncKind {
if name.namespace != "Windows.Foundation" {
pub fn async_kind(def: &GenericType) -> AsyncKind {
if def.def.namespace() != "Windows.Foundation" {
return AsyncKind::None;
}

match name.name.as_ref() {
match def.def.name() {
"IAsyncAction" => AsyncKind::Action,
"IAsyncActionWithProgress`1" => AsyncKind::ActionWithProgress,
"IAsyncOperation`1" => AsyncKind::Operation,
Expand All @@ -43,11 +47,12 @@ fn async_kind(name: &TypeName) -> AsyncKind {

fn gen_async_kind(
kind: AsyncKind,
name: &TypeName,
self_name: &TypeName,
name: &GenericType,
self_name: &GenericType,
gen: Gen,
) -> (TokenStream, TokenStream) {
let return_type = match kind {
AsyncKind::Operation | AsyncKind::OperationWithProgress => name.generics[0].gen(),
AsyncKind::Operation | AsyncKind::OperationWithProgress => name.generics[0].gen_name(gen),
_ => quote! { () },
};

Expand All @@ -59,15 +64,16 @@ fn gen_async_kind(
_ => panic!("Unexpected AsyncKind"),
};

let constraints = self_name.gen_constraint();
let name = self_name.gen();
let constraints = self_name.gen_constraints();
let name = self_name.gen_name(gen);
let namespace = gen.namespace("Windows.Foundation");

(
quote! {
pub fn get(&self) -> ::windows::Result<#return_type> {
if self.status()? == ::windows::foundation::AsyncStatus::Started {
if self.status()? == #namespace AsyncStatus::Started {
let (waiter, signaler) = ::windows::Waiter::new();
self.set_completed(::windows::foundation:: #handler::new(move |_sender, _args| {
self.set_completed(#namespace #handler::new(move |_sender, _args| {
// Safe because the waiter will only be dropped after being signaled.
unsafe { signaler.signal(); }
Ok(())
Expand All @@ -81,10 +87,10 @@ fn gen_async_kind(
type Output = ::windows::Result<#return_type>;

fn poll(self: ::std::pin::Pin<&mut Self>, context: &mut ::std::task::Context) -> ::std::task::Poll<Self::Output> {
if self.status()? == ::windows::foundation::AsyncStatus::Started {
if self.status()? == #namespace AsyncStatus::Started {
let waker = context.waker().clone();

let _ = self.set_completed(::windows::foundation:: #handler::new(move |_sender, _args| {
let _ = self.set_completed(#namespace #handler::new(move |_sender, _args| {
waker.wake_by_ref();
Ok(())
}));
Expand Down
47 changes: 0 additions & 47 deletions crates/gen/src/callback.rs

This file was deleted.

Loading

0 comments on commit 6b37abc

Please sign in to comment.