Skip to content

Commit

Permalink
Trait-based implement macro (#1450)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr committed Jan 25, 2022
1 parent 918be0e commit f06b0bb
Show file tree
Hide file tree
Showing 1,925 changed files with 1,287,114 additions and 548,110 deletions.
71 changes: 17 additions & 54 deletions .github/workflows/build.yml
Expand Up @@ -9,31 +9,8 @@ env:
RUSTFLAGS: -Dwarnings

jobs:
build_components:
name: Build test components
runs-on: windows-latest
strategy:
matrix:
platform: [x86, x64]
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Configure MSBuild
uses: microsoft/setup-msbuild@v1.0.3

- name: Install CLangSharpPInvokeGenerator
run: dotnet tool install -g ClangSharpPInvokeGenerator --version 11.0.0-beta3

- name: Restore NuGet Packages (${{ matrix.platform }})
run: msbuild crates\tests\components\components.sln /t:Restore /p:Platform=${{ matrix.platform }} /p:RestorePackagesConfig=true /m

- name: Build components (${{ matrix.platform }})
run: msbuild crates\tests\components\components.sln /t:Build /p:Platform=${{ matrix.platform }} /p:Configuration=Release /m

test:
name: Test
needs: build_components
name: Build
runs-on: ${{ matrix.os }}
strategy:
matrix:
Expand Down Expand Up @@ -88,13 +65,13 @@ jobs:
$MingwPath | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
if: contains(matrix.other, 'windows-gnu')

- name: Check (${{ matrix.os }})
run: cargo check --target ${{ matrix.other }}
if: contains(matrix.other, 'windows-gnu')
# - name: Check (${{ matrix.os }})
# run: cargo check --target ${{ matrix.other }}
# if: contains(matrix.other, 'windows-gnu')

- name: Test (${{ matrix.os }})
run: cargo test --all --target ${{ matrix.other }}
if: contains(matrix.other, 'windows-msvc')
# - name: Test (${{ matrix.os }})
# run: cargo test --all --target ${{ matrix.other }}
# if: contains(matrix.other, 'windows-msvc')

cargo_fmt:
name: Check cargo formatting
Expand All @@ -106,16 +83,16 @@ jobs:
- name: Run cargo fmt
run: cargo fmt --all -- --check

cargo_clippy:
name: Check cargo clippy
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v2
# cargo_clippy:
# name: Check cargo clippy
# runs-on: windows-latest
# steps:
# - name: Checkout
# uses: actions/checkout@v2

- name: Run cargo clippy
# TODO: Add --all-targets when the tests adhere to clippy lints
run: cargo clippy --all -- -D warnings
# - name: Run cargo clippy
# # TODO: Add --all-targets when the tests adhere to clippy lints
# run: cargo clippy --all -- -D warnings

cargo_doc:
name: Check cargo docs
Expand All @@ -127,26 +104,12 @@ jobs:
- name: Run cargo doc
run: cargo doc --no-deps -p windows

windows_fmt:
name: Check macro formatting
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Run windows_fmt
run: cargo run -p windows_fmt

- name: Compare
shell: bash
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)

generation:
name: Check generation of `windows_${{ matrix.generator }}`
runs-on: windows-latest
strategy:
matrix:
generator: [bindings, api, sys]
generator: [bindings, api, sys, yml]

steps:
- name: Checkout
Expand Down
100 changes: 100 additions & 0 deletions .github/workflows/test.yml
@@ -1 +1,101 @@

name: CI

on:
pull_request:
push:
branches:
- master
env:
RUSTFLAGS: -Dwarnings

jobs:
test:
name: Test
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: windows-latest
rust: stable
other: x86_64-pc-windows-msvc
platform: x64
- os: windows-latest
rust: nightly
other: i686-pc-windows-msvc
platform: x86
- os: windows-latest
rust: nightly
other: x86_64-pc-windows-gnu
platform: x64
- os: windows-latest
rust: stable
other: i686-pc-windows-gnu
platform: x86
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Update toolchain
run: rustup update --no-self-update ${{ matrix.rust }} && rustup default ${{ matrix.rust }}

- name: Add toolchain target
run: rustup target add ${{ matrix.other }}

- name: Configure Cargo for GNU toolchain
shell: pwsh
run: |
Add-Content $env:USERPROFILE\.cargo\config @"
[target.x86_64-pc-windows-gnu]
linker = `"C:\\msys64\\mingw64\\bin\\x86_64-w64-mingw32-gcc.exe`"
ar = `"C:\\msys64\\mingw64\\bin\\ar.exe`"
[target.i686-pc-windows-gnu]
linker = `"C:\\msys64\\mingw32\\bin\\i686-w64-mingw32-gcc.exe`"
ar = `"C:\\msys64\\mingw32\\bin\\ar.exe`"
"@
if: contains(matrix.other, 'windows-gnu')

- name: Configure environment for GNU toolchain
shell: pwsh
run: |
if("${{ matrix.other }}" -eq "i686-pc-windows-gnu") {
$MingwPath = "C:\msys64\mingw32\bin"
} else {
$MingwPath = "C:\msys64\mingw64\bin"
}
$MingwPath | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
if: contains(matrix.other, 'windows-gnu')

- name: Test (${{ matrix.os }})
run: cargo test --target ${{ matrix.other }} -p test_agile
run: cargo test --target ${{ matrix.other }} -p test_alternate_success_code
run: cargo test --target ${{ matrix.other }} -p test_arch
run: cargo test --target ${{ matrix.other }} -p test_arch_feature
run: cargo test --target ${{ matrix.other }} -p test_bstr
run: cargo test --target ${{ matrix.other }} -p test_class_factory
run: cargo test --target ${{ matrix.other }} -p test_core
run: cargo test --target ${{ matrix.other }} -p test_data_object
run: cargo test --target ${{ matrix.other }} -p test_debug
run: cargo test --target ${{ matrix.other }} -p test_deprecated
run: cargo test --target ${{ matrix.other }} -p test_dep_map
run: cargo test --target ${{ matrix.other }} -p test_enums
run: cargo test --target ${{ matrix.other }} -p test_handles
run: cargo test --target ${{ matrix.other }} -p test_helpers
run: cargo test --target ${{ matrix.other }} -p test_implement
run: cargo test --target ${{ matrix.other }} -p test_implement_identity
run: cargo test --target ${{ matrix.other }} -p test_implement_no_use
run: cargo test --target ${{ matrix.other }} -p test_implement_null_result
run: cargo test --target ${{ matrix.other }} -p test_interop
run: cargo test --target ${{ matrix.other }} -p test_lib
run: cargo test --target ${{ matrix.other }} -p test_matrix3x2
run: cargo test --target ${{ matrix.other }} -p test_mshtml
run: cargo test --target ${{ matrix.other }} -p test_ntstatus
run: cargo test --target ${{ matrix.other }} -p test_pwstr
run: cargo test --target ${{ matrix.other }} -p test_return_struct
run: cargo test --target ${{ matrix.other }} -p test_structs
run: cargo test --target ${{ matrix.other }} -p test_sys
run: cargo test --target ${{ matrix.other }} -p test_unions
run: cargo test --target ${{ matrix.other }} -p test_weak
run: cargo test --target ${{ matrix.other }} -p test_win32
run: cargo test --target ${{ matrix.other }} -p test_win32_arrays
run: cargo test --target ${{ matrix.other }} -p test_winrt
Binary file removed .windows/arm64/component.dll
Binary file not shown.
Binary file removed .windows/arm64/component.lib
Binary file not shown.
Binary file removed .windows/arm64/static_component.lib
Binary file not shown.
Binary file removed .windows/winmd/Component.Win32.winmd
Binary file not shown.
Binary file removed .windows/winmd/Component.winmd
Binary file not shown.
Binary file removed .windows/winmd/StaticComponent.Win32.winmd
Binary file not shown.
Binary file removed .windows/x64/component.dll
Binary file not shown.
Binary file removed .windows/x64/component.lib
Binary file not shown.
Binary file removed .windows/x64/static_component.lib
Binary file not shown.
Binary file removed .windows/x86/component.dll
Binary file not shown.
Binary file removed .windows/x86/component.lib
Binary file not shown.
13 changes: 2 additions & 11 deletions Cargo.toml
@@ -1,17 +1,8 @@
[workspace]
members = [
"crates/libs/*",
"crates/samples/*",
"crates/targets/*",
"crates/tests/*",
"crates/tools/*",
"crates/tests/legacy/*",
"crates/tests/metadata/*",
"crates/tests/winrt/*",
"crates/tests/win32/*",
"crates/tests/core",
"crates/tests/debug",
"crates/tests/enums",
"crates/tests/sys",
"crates/tests/handles",
"crates/tests/agile",
]
exclude = ["crates/tests/component"]
21 changes: 4 additions & 17 deletions crates/libs/bindgen/src/classes.rs
Expand Up @@ -20,7 +20,7 @@ fn gen_class(def: &TypeDef, gen: &Gen) -> TokenStream {
let has_default = def.default_interface().is_some();
let interfaces = def.class_interfaces();
let mut methods = quote! {};
let mut method_names = BTreeMap::<String, u32>::new();
let mut method_names = MethodNames::new();

let cfg = gen.type_cfg(def);
let features = cfg.gen(gen);
Expand All @@ -31,10 +31,10 @@ fn gen_class(def: &TypeDef, gen: &Gen) -> TokenStream {
continue;
}

let mut vtable_offset = 6;
let mut virtual_names = MethodNames::new();

for method in def.methods() {
methods.combine(&gen_winrt_method(def, *kind, &method, vtable_offset, &mut method_names, gen));
vtable_offset += 1;
methods.combine(&gen_winrt_method(def, *kind, &method, &mut method_names, &mut virtual_names, gen));
}
}

Expand Down Expand Up @@ -141,19 +141,6 @@ fn gen_agile(def: &TypeDef, cfg: &Cfg, gen: &Gen) -> TokenStream {
}
}

fn gen_runtime_name(def: &TypeDef, cfg: &Cfg, gen: &Gen) -> TokenStream {
let name = gen_type_ident(def, gen);
let runtime_name = format!("{}", def.type_name());
let cfg = cfg.gen(gen);

quote! {
#cfg
impl ::windows::core::RuntimeName for #name {
const NAME: &'static str = #runtime_name;
}
}
}

fn gen_conversions(def: &TypeDef, cfg: &Cfg, gen: &Gen) -> TokenStream {
let name = gen_type_ident(def, gen);
let mut tokens = quote! {};
Expand Down
67 changes: 13 additions & 54 deletions crates/libs/bindgen/src/delegates.rs
Expand Up @@ -13,22 +13,23 @@ pub fn gen(def: &TypeDef, gen: &Gen) -> TokenStream {
}

fn gen_win_delegate(def: &TypeDef, gen: &Gen) -> TokenStream {
let name = gen_type_ident2(def);
let vtbl = name.join("Vtbl");
let name = gen_ident(def.name());
let vtbl = name.join("_Vtbl");
let boxed = name.join("Box");

let phantoms = gen_phantoms(def, gen);
let named_phantoms = gen_named_phantoms(def, gen);
let constraints = gen_type_constraints(def, gen);
let generics = gen_type_generics(def, gen);

let method = def.invoke_method();
let signature = method.signature(&def.generics);
let fn_constraint = gen_fn_constraint(&signature, gen);
let fn_constraint = gen_fn_constraint(def, &method, gen);
let cfg = gen.type_cfg(def);
let doc = cfg.gen_doc(gen);
let features = cfg.gen(gen);
let vtbl_signature = gen_vtbl_signature(def, &method, gen);
let invoke = gen_winrt_method(def, InterfaceKind::Default, &method, 3, &mut BTreeMap::new(), gen);
let invoke = gen_winrt_method(def, InterfaceKind::Default, &method, &mut MethodNames::new(), &mut MethodNames::new(), gen);
let invoke_upcall = gen_winrt_upcall(&signature, quote! { ((*this).invoke) }, gen);

let mut tokens = quote! {
Expand Down Expand Up @@ -59,13 +60,11 @@ fn gen_win_delegate(def: &TypeDef, gen: &Gen) -> TokenStream {
}
#features
impl<#(#constraints)* #fn_constraint> #boxed<#(#generics)* F> {
const VTABLE: #vtbl<#(#generics)*> = #vtbl::<#(#generics)*>(
Self::QueryInterface,
Self::AddRef,
Self::Release,
Self::Invoke,
#(#phantoms)*
);
const VTABLE: #vtbl<#(#generics)*> = #vtbl::<#(#generics)*>{
base: ::windows::core::IUnknownVtbl{QueryInterface: Self::QueryInterface, AddRef: Self::AddRef, Release: Self::Release},
Invoke: Self::Invoke,
#(#named_phantoms)*
};
unsafe extern "system" fn QueryInterface(this: ::windows::core::RawPtr, iid: &::windows::core::GUID, interface: *mut ::windows::core::RawPtr) -> ::windows::core::HRESULT {
let this = this as *mut ::windows::core::RawPtr as *mut Self;

Expand Down Expand Up @@ -115,48 +114,8 @@ fn gen_win_delegate(def: &TypeDef, gen: &Gen) -> TokenStream {
tokens
}

fn gen_fn_constraint(sig: &MethodSignature, gen: &Gen) -> TokenStream {
let params = sig.params.iter().map(|p| gen_produce_type(p, gen));
fn gen_fn_constraint(def: &TypeDef, method: &MethodDef, gen: &Gen) -> TokenStream {
let signature = gen_impl_signature(def, method, gen);

let return_sig = if let Some(return_sig) = &sig.return_sig {
let tokens = gen_element_name(&return_sig.kind, gen);

if return_sig.is_array {
quote! { ::windows::core::Array<#tokens> }
} else {
tokens
}
} else {
quote! { () }
};

quote! { F: FnMut(#(#params),*) -> ::windows::core::Result<#return_sig> + 'static }
}

fn gen_produce_type(param: &MethodParam, gen: &Gen) -> TokenStream {
let tokens = gen_element_name(&param.signature.kind, gen);

if param.signature.is_array {
if param.param.is_input() {
quote! { &[<#tokens as ::windows::core::DefaultType>::DefaultType] }
} else if param.signature.by_ref {
quote! { &mut ::windows::core::Array<#tokens> }
} else {
quote! { &mut [<#tokens as ::windows::core::DefaultType>::DefaultType] }
}
} else if param.param.is_input() {
if let ElementType::GenericParam(_) = param.signature.kind {
quote! { &<#tokens as ::windows::core::DefaultType>::DefaultType }
} else if param.signature.kind.is_primitive() {
quote! { #tokens }
} else if param.signature.kind.is_nullable() {
quote! { &::core::option::Option<#tokens> }
} else {
quote! { &#tokens }
}
} else if param.signature.kind.is_nullable() {
quote! { &mut ::core::option::Option<#tokens> }
} else {
quote! { &mut #tokens }
}
quote! { F: FnMut #signature + 'static }
}

0 comments on commit f06b0bb

Please sign in to comment.