diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 57575b09e5..f44b28c3fe 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -251,7 +251,10 @@ WinRT.Runtime2/ - **Compilation symbols**: the implementation build defines `WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY`; the reference build defines `WINDOWS_RUNTIME_REFERENCE_ASSEMBLY`. Members that differ between the two (e.g. the explicit interface implementations on `WindowsRuntimeObject`, which become `throw null` stubs) are guarded with `#if`/`#elif` on these symbols. An entire source file can opt out of the reference assembly by placing `#define WINDOWS_RUNTIME_IMPLEMENTATION_ONLY_FILE` at the top: the `RemoveWindowsRuntimeImplementationOnlyFiles` target removes those files (plus the whole `ABI/`, `NativeObjects/`, `Exceptions/`, `Windows.UI.Xaml.Interop/`, and most `InteropServices/` subfolders) before `CoreCompile`. - **`ProduceReferenceAssembly = false`**: the implementation build disables the SDK's automatic reference assembly, because `WinRT.Runtime` ships its own (the SDK-generated one would leak the implementation-only types to consumers and break reference projections). -- **`[WindowsRuntimeImplementationOnlyMember]`** (`Attributes/WindowsRuntimeImplementationOnlyMemberAttribute.cs`): an `internal sealed`, `[Conditional("WINDOWS_RUNTIME_REFERENCE_ASSEMBLY")]` marker placed on implementation-only types/members (including most of the marker attributes under `Attributes/`). It replaces the older `[Obsolete] + [EditorBrowsable(Never)]` combination, makes the intent explicit, and is only ever emitted into the reference assembly (where it is stripped along with the members it marks). +- **`[WindowsRuntimeImplementationOnlyMember]`** (`Attributes/WindowsRuntimeImplementationOnlyMemberAttribute.cs`): an `internal sealed`, `[Conditional("WINDOWS_RUNTIME_REFERENCE_ASSEMBLY")]` marker placed on implementation-only types/members (including most of the marker attributes under `Attributes/`). For the **common case** (a type/member that nothing outside the implementation assembly needs to reference), it replaces the older `[Obsolete] + [EditorBrowsable(Never)]` combination, makes the intent explicit, and is only ever emitted into the reference assembly (where it is stripped along with the members it marks). +- **Two strategies for implementation-only API** — there are two ways CsWinRT keeps an implementation detail out of the supported surface, and the choice depends on whether *generated code that compiles against the reference assembly* needs to name the type: + 1. **Strip it entirely** (the default, preferred): mark it `[WindowsRuntimeImplementationOnlyMember]` (or place it in a file/folder excluded from the reference build) so it is **absent** from the reference assembly. This is the cleanest option and is used for everything that is only reached at runtime or via `[IgnoresAccessChecksTo]` from `WinRT.Interop.dll` (e.g. the ABI marshallers, native object wrappers, vtable helpers). + 2. **Keep it public but hidden** (the exception): leave the type in the reference assembly, but — only there (`#if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY`) — mark it `[Obsolete(..., DiagnosticId = "CSWINRT3xxx", UrlFormat = ...)]` + `[EditorBrowsable(Never)]`. This is required when **CsWinRT-generated code** references the type by name *and that code is compiled against the reference assembly* (so stripping would cause `CS0234`/`CS0246`). Such generated code suppresses the diagnostic (e.g. `#pragma warning disable`), so normal builds are unaffected, while direct use in user code surfaces the obsolete warning. The obsolete message/diagnostic-id constants live in `Properties/WindowsRuntimeConstants.cs`, and each id has a docs page under `docs/diagnostics/`. Current cases: the three type map group types (`CSWINRT3002`; referenced by the source generator's `[assembly: TypeMapAssemblyTarget]` output), the component authoring attributes `WindowsRuntimeComponentAssemblyAttribute`/`WindowsRuntimeComponentAssemblyExportsTypeAttribute` (`CSWINRT3003`; referenced by the authoring source generator's `ManagedExports.g.cs`), and `WindowsRuntimeReferenceAssemblyAttribute` (`CSWINRT3004`; emitted as `[assembly: WindowsRuntimeReferenceAssembly]` by the projection writer's `AssemblyAttributes.cs` base resource, and — unlike the others — also genuinely shipped in the reference projection assemblies of Windows Runtime projection NuGet packages). The reference-assembly-only `WindowsRuntimeObject()` constructor (`CSWINRT3001`) is the same mechanism applied to a constructor. - **Banned API analyzer**: the reference build references `Microsoft.CodeAnalysis.BannedApiAnalyzers` and lists `WindowsRuntimeImplementationOnlyMemberAttribute` in `BannedSymbols.txt`, with `RS0030` promoted to an error, so the build fails if any implementation-only type ever leaks into the reference surface. It also suppresses warnings that only appear in the stripped build (`CS8597`, `IDE0005`, `IDE0380`). - **Reference-assembly-only `WindowsRuntimeObject()` constructor**: a parameterless `protected` constructor exists only in the reference assembly (`#if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY`). It is marked `[Obsolete(..., DiagnosticId = "CSWINRT3001")]`, so user code that derives from `WindowsRuntimeObject` gets the `CSWINRT3001` warning; because the constructor is absent from the implementation assembly, doing so throws `MissingMethodException` at runtime. Only CsWinRT-generated projections may derive from `WindowsRuntimeObject`. The related messages live in `Properties/WindowsRuntimeConstants.cs`. - **Packaging**: the implementation assembly ships in `lib\net10.0\` of the `Microsoft.Windows.CsWinRT` NuGet package, and the reference assembly (with its XML documentation, trimmed to the reference surface) ships in `ref\net10.0\`. The dual build and staging are driven by `src/build.cmd` and the Azure Pipelines build steps. @@ -727,7 +730,7 @@ All five .NET build tools (`cswinrtprojectionrefgen`, `cswinrtprojectiongen`, `c | Impl Generator | `CSWINRTIMPLGENxxxx` | `0001`–`0014`, `9999` | | Interop Generator | `CSWINRTINTEROPGENxxxx` | `0001`–`0097`, `9999` | | WinMD Generator | `CSWINRTWINMDGENxxxx` | `0001`–`0010`, `9999` | -| Runtime (obsolete markers) | `CSWINRT3xxx` | `CSWINRT3001` (deriving from `WindowsRuntimeObject`) | +| Runtime (obsolete markers) | `CSWINRT3xxx` | `CSWINRT3001` (deriving from `WindowsRuntimeObject`), `CSWINRT3002` (type map group types), `CSWINRT3003` (component authoring attributes), `CSWINRT3004` (`WindowsRuntimeReferenceAssemblyAttribute`) | --- diff --git a/.github/skills/interop-generator/SKILL.md b/.github/skills/interop-generator/SKILL.md index a85c8beaa9..673a9d5f99 100644 --- a/.github/skills/interop-generator/SKILL.md +++ b/.github/skills/interop-generator/SKILL.md @@ -287,7 +287,7 @@ The generator processes two categories of assemblies: - `System.Collections.Concurrent.ConditionalWeakTable<,>` — Memory semantics conflict **Type inclusion criteria:** -- Must be a projected Windows Runtime type (marked with `[WindowsRuntimeMetadata]` or similar) +- Must be a projected Windows Runtime type. A type is recognized as projected in any of three ways: it carries the per-type `[WindowsRuntimeMetadata]` attribute (implementation projections and types in `WinRT.Runtime.dll`); it is a public type from an authored component assembly (`IsComponentWindowsRuntimeType`); or it is defined in a reference projection assembly marked `[WindowsRuntimeReferenceAssembly]` (`IsReferenceProjectionWindowsRuntimeType`). The latter two do **not** carry the per-type `[WindowsRuntimeMetadata]` attribute — reference projections shipped in NuGet packages have it stripped (it is an implementation-only attribute, absent from the `WinRT.Runtime.dll` reference assembly they compile against), so the interop generator recognizes them by their assembly-level marker instead. - Generic types must be fully constructed (no open generic parameters) - Type hierarchy must be fully resolvable (no missing dependencies) - Must not be a managed-only type (types that never cross the Windows Runtime boundary) @@ -737,6 +737,8 @@ Almost everything the generated code calls into lives in `WinRT.Runtime.dll` as Because these APIs are absent from the `WinRT.Runtime.dll` reference assembly, the generated `WinRT.Interop.dll` references types that exist only in the implementation assembly, and the generator emits assembly-level `[IgnoresAccessChecksTo]` to reach the non-public members among them. This is also why `cswinrtinteropgen` must be version-matched to the `WinRT.Runtime.dll` it targets (see "Version compatibility" above): the shape of these types can change at any time. +> **Note:** A small subset of the types listed above is not stripped but instead kept **public but hidden** in the reference assembly — most notably the three type map group types, which are marked reference-assembly-only `[Obsolete(DiagnosticId = "CSWINRT3002")]` + `[EditorBrowsable(Never)]`. The reason: those types are also named by the CsWinRT source generator's `[assembly: TypeMapAssemblyTarget]` output, which is compiled into user code **against the reference assembly**, so stripping them would break that compilation. The interop generator is unaffected by the distinction (it always resolves the implementation assembly), but it must still treat them as unstable, version-matched implementation details. See the "Two strategies for implementation-only API" note in `.github/copilot-instructions.md` for the full rationale and the other cases (`CSWINRT3003`, `CSWINRT3004`). + ## Key patterns and conventions ### Naming conventions for generated types diff --git a/.github/skills/interop-generator/references/name-mangling-scheme.md b/.github/skills/interop-generator/references/name-mangling-scheme.md index 9ddfa2a95a..9db179e955 100644 --- a/.github/skills/interop-generator/references/name-mangling-scheme.md +++ b/.github/skills/interop-generator/references/name-mangling-scheme.md @@ -38,7 +38,7 @@ These are the well-known assemblies and their compact identifiers: Compact identifiers are prefixed with `#` to distinguish them from user-defined assembly names. -For types not belonging to any well-known assembly, the implementation also checks for a `[WindowsRuntimeMetadata]` attribute on the resolved type definition. If the attribute is present, the Windows Runtime metadata name from the attribute is used as the assembly identifier instead of the actual assembly name. This allows types carrying WinRT metadata to be identified by their canonical Windows Runtime name rather than the .NET assembly they happen to live in. If the attribute is not present, the raw assembly name is used as-is. +For types not belonging to any well-known assembly, the implementation also derives the assembly identifier from the type's `[WindowsRuntimeMetadata]` value (the source `.winmd` module name, i.e. its "stem") instead of the actual assembly name. This allows types carrying WinRT metadata to be identified by their canonical Windows Runtime name rather than the .NET assembly they happen to live in. The stem is read directly from the attribute when present — implementation projections, the authored component projection, and manually projected types in `WinRT.Runtime.dll` all carry it. Reference projections shipped in Windows Runtime projection NuGet packages have the attribute **stripped** (it is an implementation-only attribute, absent from the `WinRT.Runtime.dll` reference assembly they compile against); for a type defined in such a reference projection (detected via `IsReferenceProjectionWindowsRuntimeType`), the stem is instead recovered from the matching type in the third-party implementation projection (`WinRT.Projection.dll`), located through `RuntimeContext.GetLoadedAssemblies()`. This recovery is essential because the projection writer encodes that very same stem into the `[UnsafeAccessorType]` references it emits into the implementation projection, and the reference projection's own assembly name can differ from the stem (e.g. when several `.winmd` files are merged into a single projection assembly, as with WinUI / Windows App SDK). If the stem cannot be found anywhere, the raw assembly name is used as-is. The recovery logic lives in `GetWindowsRuntimeMetadataName` (`src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs`). > [!NOTE] > Not all BCL types live in `System.Runtime`. For example, the `System.Numerics` types (`Matrix3x2`, `Matrix4x4`, `Plane`, `Quaternion`, `Vector2`, `Vector3`, `Vector4`) are in the `System.Numerics.Vectors` assembly, so their assembly identifier is `System-Numerics-Vectors` (not `#corlib`) after the `.` → `-` substitution. The assembly used is always the one from the type's actual metadata scope, not the namespace. diff --git a/.github/skills/testing/SKILL.md b/.github/skills/testing/SKILL.md index c735aa5d2d..7875decfeb 100644 --- a/.github/skills/testing/SKILL.md +++ b/.github/skills/testing/SKILL.md @@ -13,7 +13,7 @@ Before adding tests, always check whether tests for the same functionality alrea ## Test project overview -CsWinRT 3.0 has 5 primary test project areas, each serving a different purpose. Additional specialized test projects also exist under `src/Tests/`: +CsWinRT 3.0 has 6 primary test project areas, each serving a different purpose. Additional specialized test projects also exist under `src/Tests/`: ### 1. Unit tests (`src/Tests/UnitTest/`) @@ -25,8 +25,8 @@ CsWinRT 3.0 has 5 primary test project areas, each serving a different purpose. - **Test framework:** MSTest (`[TestClass]`, `[TestMethod]`, `Assert.*`) - **TFM:** Variable via `$(AppBuildTFMs)`, multi-platform (x86/x64) - **Output type:** Exe, self-contained, AOT-enabled -- **Key dependencies:** MSTest.TestFramework, MSTest.Engine, MSTest.SourceGeneration, Microsoft.Windows.CsWin32, Newtonsoft.Json -- **References:** WinRT.SourceGenerator2 (as analyzer), Test/Windows/WinAppSDK projections +- **Key dependencies:** MSTest.TestFramework, MSTest.Engine, MSTest.SourceGeneration, Microsoft.Windows.CsWin32, Newtonsoft.Json, Microsoft.VCRTForwarders.140 +- **References:** WinRT.SourceGenerator2 (as analyzer), Test/TestSubset/Windows/WinAppSDK projections **Test organization:** - Single namespace: `UnitTest` @@ -132,9 +132,16 @@ return 100; | Test class | What it tests | |------------|---------------| | `Test_CustomPropertyProviderGenerator` | `CustomPropertyProviderGenerator` source generator output | -| `Test_GeneratedCustomPropertyProviderAttributeArgumentAnalyzer` | CSWINRT2004–2008 diagnostics | | `Test_GeneratedCustomPropertyProviderTargetTypeAnalyzer` | CSWINRT2000–2001 diagnostics | | `Test_GeneratedCustomPropertyProviderExistingMemberImplementationAnalyzer` | CSWINRT2003 diagnostic | +| `Test_GeneratedCustomPropertyProviderAttributeArgumentAnalyzer` | CSWINRT2004–2008 diagnostics | +| `Test_ComImportInterfaceAnalyzer` | CSWINRT2009 diagnostic (casts to `[ComImport]` interfaces) | +| `Test_ValidApiContractEnumTypeAnalyzer` | CSWINRT2010 diagnostic | +| `Test_ValidContractVersionAttributeAnalyzer` | CSWINRT2011–2013 diagnostics | +| `Test_ApiContractTypeRequiresContractVersionAnalyzer` | CSWINRT2014 diagnostic | +| `Test_PublicTypeRequiresVersioningAnalyzer` | CSWINRT2015 diagnostic | +| `Test_PublicTypeRequiresContractVersionAnalyzer` | CSWINRT2016 diagnostic | +| `Test_PublicTypeMixedVersioningAttributesAnalyzer` | CSWINRT2017 diagnostic | **Test helpers (in `Helpers/`):** - `CSharpGeneratorTest` — runs a generator on source code and compares output @@ -183,6 +190,7 @@ public async Task InvalidType_Warns() - Use `{|DIAGNOSTIC_ID:target|}` inline syntax to mark expected diagnostics - Or use explicit `expectedDiagnostics` array with `DiagnosticResult` for complex cases +- Pass `isCsWinRTComponent: true` to `VerifyAnalyzerAsync` for analyzers that only apply to authored components (e.g. the contract-versioning analyzers) - Test naming convention: `Condition_ExpectedBehavior` (e.g. `NullPropertyName_Warns`, `ValidClass_DoesNotWarn`) ### 4. Object lifetime tests (`src/Tests/ObjectLifetimeTests/`) @@ -201,18 +209,41 @@ public async Task InvalidType_Warns() - `AsyncQueue` helper for scheduling actions on UI thread and forcing GC - Tests named `BasicTestN()`, `CycleTestN()`, `LeakTestN()` -### 5. Authoring tests (`src/Tests/AuthoringTest/`) — currently disabled, WIP +### 5. Authoring tests (`src/Tests/AuthoringTest/`) -**What it tests:** Authoring a WinRT component in C# — validates that diverse type patterns (enums, structs, classes, interfaces, delegates, collections, XAML controls, async operations, data binding types) can be successfully projected as a WinRT component. +**What it tests:** Authoring a WinRT component in C# — validates that diverse type patterns (enums, structs, classes, interfaces, delegates, collections, XAML controls, async operations, data binding types, and contract-versioning attributes) can be successfully projected as a WinRT component. The component itself builds (build-time validation); the C++ consumption tests that exercise it (`AuthoringConsumptionTest*`) are not yet enabled in the solution. -**When to add tests here:** Currently disabled. When enabled, for testing new WinRT component authoring scenarios. +**When to add tests here:** For testing new WinRT component authoring scenarios — new type shapes, attributes, or versioning patterns. **Project settings:** -- **Type:** Class library with `CsWinRTComponent=true` -- **TFM:** `net10.0` -- **Release x64:** NativeAOT self-contained mode +- **Type:** `CsWinRTComponent=true` class library; Release x64 publishes as a Native AOT shared library (`OutputType=Exe`, `PublishAot=true`, `SelfContained=true`, `NativeLib=Shared`) +- **TFM:** `net10.0-windows10.0.26100.1` - Build-time validation (compilation succeeds = test passes) +### 6. Smoke tests (`src/Tests/SmokeTests/`) + +**What it tests:** End-to-end consumption of the **real** `Microsoft.Windows.CsWinRT` NuGet package — a consuming app, an authoring component, a third-party projection, and the Windows SDK reference projections — fully isolated from the repository build infrastructure. Validates that the packaged `ref`/`lib` assemblies, the build targets, and all post-build generators work correctly for an external customer. + +**When to add tests here:** For verifying that the produced NuGet package works in a real, isolated environment (correct `ref`/`lib` assemblies referenced, generators running). Keep these minimal — they are smoke tests, not feature coverage. Use `UnitTest/` or `FunctionalTests/` for marshalling/feature coverage instead. + +**Project structure:** Five standalone projects, intentionally kept out of `cswinrt.slnx` (the package they consume only exists after the build packs it). They are isolated from the repo build infrastructure via blank `Directory.Build.props`/`.targets` and a local `Directory.Packages.props` (central package management disabled). All shared configuration lives in `Directory.Build.props`, so each `.csproj` only carries what makes it different; the two Windows SDK projection tests additionally share `WindowsSdkContracts.targets` (which stages the SDK `.winmd` inputs). + +**Existing tests:** +| Project | Tests | +|---------|-------| +| `Consumption/` | An `Exe` that calls `JsonObject.Parse(...)` then `Stringify()` from `Windows.Data.Json`, exercising the Windows SDK projection, the interop generator, and the `WinRT.Runtime` ref/impl assemblies | +| `Authoring/` | A `CsWinRTComponent` library exposing a `Greeter` class plus a richer catalog of authored type shapes in `Thermometer.cs` (enums, a flags enum, a struct, a delegate, an interface, and a sealed runtime class with constructors, properties, an event, and static members), exercising WinMD generation, the reference projection, and the forwarder assembly. The breadth deliberately gives the `Projection` smoke test more projection shapes to cover | +| `Projection/` | A `CsWinRTGenerateReferenceProjection` library that generates a reference projection for the `Authoring` component's `.winmd` (reused via a build-ordering `ProjectReference`), exercising `cswinrtprojectionrefgen` and `cswinrtimplgen`, exactly as a NuGet projection author would | +| `WindowsSdkProjection/` | A `CsWinRTGenerateReferenceProjection` library that generates the base Windows SDK reference projection from the `Microsoft.Windows.SDK.Contracts` `.winmd` files (staged by `WindowsSdkContracts.targets`), exactly as the `Microsoft.Windows.SDK.NET.Ref` projection package is produced. Catches reference-projection codegen regressions against the full Windows SDK surface | +| `WindowsSdkXamlProjection/` | As `WindowsSdkProjection`, but for the `Windows.UI.Xaml` surface; it references the `WindowsSdkProjection` reference assembly, mirroring how the UWP XAML projection package depends on the base Windows SDK projection package | + +**Shared configuration (`Directory.Build.props`):** +- **TFM:** `net10.0-windows10.0.26100.1` (the `.1` CsWinRT 3.0 revision), with a pinned `WindowsSdkPackageVersion` so the build uses the real .NET SDK targeting pack (mirrors `src/WinRT.Internal`). The two Windows SDK projection tests override this to plain `net10.0` (a `-windows` TFM would implicitly reference the prebuilt Windows SDK projection they regenerate, colliding with every generated type), exactly as `src/WinRT.Sdk.Projection` +- `RestoreSources` overrides all inherited NuGet sources: the local CsWinRT build output (`CsWinRTPackageSource`) plus the `CsWinRTDependencies` feed (`CsWinRTDependenciesSource`), which provides the preview Windows SDK ref pack and `Microsoft.Windows.SDK.Contracts` +- `CsWinRTPackageVersion`/`CsWinRTPackageSource` default to the local `build.cmd x64 Release` output and are overridden by the build/CI that produced the package + +**How they run:** `run-smoke-tests.ps1` (parameterized by `-Test` and `-Runtime`) builds and runs the consumption app (asserting a clean exit code), builds the authoring component and verifies the generated `Authoring.winmd` defines `Authoring.Greeter`, and builds each reference-projection library (`Projection`, `WindowsSdkProjection`, `WindowsSdkXamlProjection`) verifying it produces both a forwarder and a `ref` reference assembly (shared verification). The consumption and authoring tests run on both CoreCLR and Native AOT (`-Runtime`); the three reference-projection tests are build-only and run on CoreCLR only. It is invoked after the `nuget pack` step in `src/build.cmd` (x64 only; skippable via `cswinrt_run_smoke_tests=false`) and as individual steps in `build/AzurePipelineTemplates/CsWinRT-PublishToNuGet-Steps.yml`. + ## Deciding where to add tests | You want to test... | Add test to... | @@ -226,14 +257,15 @@ public async Task InvalidType_Warns() | An analyzer diagnostic | `SourceGenerator2Test/` (new `Test_*Analyzer` class or add to existing) | | GC/reference tracking behavior | `ObjectLifetimeTests/` | | XAML visual tree element lifetime | `ObjectLifetimeTests/` | -| WinRT component authoring patterns | `AuthoringTest/` (when enabled) | +| WinRT component authoring patterns | `AuthoringTest/` | +| The produced NuGet package works end-to-end (real `ref`/`lib` assemblies, generators) | `SmokeTests/` (`Consumption/`, `Authoring/`, or a reference-projection project) | | Generated projection code patterns or cross-ABI control flow | Update `TestComponentCSharp/` and add tests in `UnitTest/` or `FunctionalTests/` | ## Test component: TestComponentCSharp (`src/Tests/TestComponentCSharp/`) -A **WinRT test component** (defined in `class.idl`, implemented in C++) that complements the general `TestComponent` from the [TestWinRT](https://github.com/microsoft/TestWinRT/) submodule. It tests scenarios specific to the C#/WinRT language projection. +A **WinRT test component** (defined in `TestComponentCSharp.idl`, implemented in C++) that complements the general `TestComponent` from the [TestWinRT](https://github.com/microsoft/TestWinRT/) submodule. It tests scenarios specific to the C#/WinRT language projection. -**When to update this project:** When you need to validate generated projection code patterns or cross-ABI control flow — e.g. a C# type calling a method on a projected object with specific parameters, and the native implementation validating the result. New types and members can be added to `class.idl` as needed. +**When to update this project:** When you need to validate generated projection code patterns or cross-ABI control flow — e.g. a C# type calling a method on a projected object with specific parameters, and the native implementation validating the result. New types and members can be added to `TestComponentCSharp.idl` as needed. **Referenced from:** unit tests (`UnitTest/`), functional tests (`FunctionalTests/`), and projection test projects (`Projections/Test/`). diff --git a/.github/skills/update-copilot-instructions/SKILL.md b/.github/skills/update-copilot-instructions/SKILL.md index acb75cae46..b3ed52dd1c 100644 --- a/.github/skills/update-copilot-instructions/SKILL.md +++ b/.github/skills/update-copilot-instructions/SKILL.md @@ -28,9 +28,11 @@ Launch parallel explore agents for each of the 12 CsWinRT 3.0 projects listed in - Project settings (TFM, language version, nullable, unsafe, etc.) are current - Namespace organization matches - Reference assembly build is documented: the dual implementation/reference build driven by `CsWinRTBuildReferenceAssembly`, the `WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY` / `WINDOWS_RUNTIME_REFERENCE_ASSEMBLY` / `WINDOWS_RUNTIME_IMPLEMENTATION_ONLY_FILE` compilation symbols, the `[WindowsRuntimeImplementationOnlyMember]` marker attribute (`Attributes/WindowsRuntimeImplementationOnlyMemberAttribute.cs`), the `BannedSymbols.txt` + `Microsoft.CodeAnalysis.BannedApiAnalyzers` guard (`RS0030` as error), the reference-assembly-only `WindowsRuntimeObject()` constructor (`CSWINRT3001` obsolete diagnostic), and packaging into `ref\net10.0\` alongside the implementation in `lib\net10.0\` (`src/build.cmd`, `nuget/Microsoft.Windows.CsWinRT.nuspec`) + - The **two strategies for keeping API out of the supported surface** are documented and current: (1) **strip entirely** (the default — `[WindowsRuntimeImplementationOnlyMember]` or an excluded file/folder, so the type is absent from the reference assembly), and (2) **public but hidden** (the exception — the type stays in the reference assembly but is marked reference-assembly-only `[Obsolete(..., DiagnosticId = "CSWINRT3xxx")]` + `[EditorBrowsable(Never)]`). Strategy 2 is required only when CsWinRT-generated code that compiles against the reference assembly names the type (stripping would then cause `CS0234`/`CS0246`); the generated code suppresses the diagnostic so normal builds are unaffected. Verify the list of current strategy-2 cases is accurate and complete by checking the `CSWINRT3xxx` constants in `Properties/WindowsRuntimeConstants.cs` and the per-diagnostic pages under `docs/diagnostics/`: `CSWINRT3001` (the `WindowsRuntimeObject()` constructor), `CSWINRT3002` (the three type map group types, named by the source generator's `[assembly: TypeMapAssemblyTarget]` output), `CSWINRT3003` (`WindowsRuntimeComponentAssemblyAttribute` / `WindowsRuntimeComponentAssemblyExportsTypeAttribute`, named by the authoring generator's `ManagedExports.g.cs`), and `CSWINRT3004` (`WindowsRuntimeReferenceAssemblyAttribute`, emitted as `[assembly: WindowsRuntimeReferenceAssembly]` by the projection writer's `AssemblyAttributes.cs` base resource and shipped in reference projection assemblies). If a `CSWINRT3xxx` diagnostic is added or removed, update both the reference-assembly section and the runtime row of the "Error ID ranges" table in the instructions 2. **WinRT.SourceGenerator2 (`src/Authoring/WinRT.SourceGenerator2/`)** - Source generators listed still exist and generate what's described + - Generated output that references **public-but-hidden** runtime types still suppresses the corresponding obsolete diagnostics: `TypeMapAssemblyTargetGenerator`'s `[assembly: TypeMapAssemblyTarget]` output names the three type map group types (`CSWINRT3002`), and `AuthoringExportTypesGenerator`'s `ManagedExports.g.cs` names the component authoring attributes (`CSWINRT3003`). If a generator starts or stops emitting references to a strategy-2 type, keep this in sync with the "Two strategies for implementation-only API" coverage in the WinRT.Runtime entry above - Diagnostic analyzer list is complete and IDs are correct (check `DiagnosticDescriptors.cs` and `AnalyzerReleases.Shipped.md`) - Diagnostic ID range is accurate - Project dependencies are current diff --git a/.github/skills/update-interop-generator-instructions/SKILL.md b/.github/skills/update-interop-generator-instructions/SKILL.md index d5bd89f9c5..473f7c34f2 100644 --- a/.github/skills/update-interop-generator-instructions/SKILL.md +++ b/.github/skills/update-interop-generator-instructions/SKILL.md @@ -97,6 +97,7 @@ Launch an explore agent to verify: - **Resolver classes** in `Resolvers/` are complete and accurately described (including `InterfaceIIDResolver`, which resolves IIDs from generated `ABI.InterfaceIIDs` types) - **Reference classes** in `References/` are complete (note the CsWinRT public key and system public key tokens come from `WellKnownPublicKeys`/`WellKnownPublicKeyTokens` in `WinRT.Generator.Core`) - **Implementation-only types inventory** — verify the "Implementation-only types consumed from WinRT.Runtime" list in the `SKILL.md` "Control flow between generated code and WinRT.Runtime" section is complete and current. Cross-check its categories and representative type names against the WinRT.Runtime type references in `References/InteropReferences.cs` and against the `[WindowsRuntimeImplementationOnlyMember]`-marked types (and the stripped folders `ABI/`, `NativeObjects/`, and most of `InteropServices/`) in `src/WinRT.Runtime2/`. If implementation-only APIs were added to or removed from WinRT.Runtime, update the inventory accordingly +- **Public-but-hidden implementation-only types** — verify the `> **Note:**` that follows the implementation-only types inventory is accurate. A small subset of the consumed types (currently the three type map group types) is **not** stripped from the reference assembly but kept **public but hidden**, marked reference-assembly-only `[Obsolete(DiagnosticId = "CSWINRT3002")]` + `[EditorBrowsable(Never)]`, because CsWinRT-generated code compiled against the reference assembly names them (the source generator's `[assembly: TypeMapAssemblyTarget]` output). Confirm the note still names the right types and `CSWINRT3xxx` id(s), still states that the interop generator itself is unaffected by the distinction (it always resolves the implementation assembly, but must still treat the types as unstable and version-matched), and still points at the "Two strategies for implementation-only API" note in `.github/copilot-instructions.md`. If the set of public-but-hidden types the generator touches changes, update the note - **Well-known interface IIDs** are current (native interface entry order, and the `ReservedIIDsMap` set — verify whether `IMarshal` is included; it is currently excluded because it can be user-overridden) - **Marshaller type resolution** logic is current @@ -155,7 +156,7 @@ These docs describe the *design* of the generated code patterns. If the actual g - `marshalling-arrays.md` includes the element marshaller infrastructure (runtime interfaces, runtime array marshaller classes, generated element marshaller types, selection logic table) - `marshalling-generic-interfaces.md` includes the collection element marshaller infrastructure (runtime interfaces, GetMany adapter extension methods, generated element marshaller types, emission/reuse pattern) -- The "implementation details only" APIs in `WinRT.Runtime.dll` that the generator consumes (the runtime element-marshaller interfaces, array marshaller classes, etc.) are marked with `[WindowsRuntimeImplementationOnlyMember]` and stripped from the `WinRT.Runtime.dll` reference assembly. If this marking scheme changes, update the `SKILL.md` "Version compatibility" section and the runtime-interface descriptions in both reference docs accordingly +- The "implementation details only" APIs in `WinRT.Runtime.dll` that the generator consumes (the runtime element-marshaller interfaces, array marshaller classes, etc.) are marked with `[WindowsRuntimeImplementationOnlyMember]` and stripped from the `WinRT.Runtime.dll` reference assembly (a small subset — e.g. the type map group types — is instead kept **public but hidden** via reference-assembly-only `[Obsolete(DiagnosticId = "CSWINRT3xxx")]` + `[EditorBrowsable(Never)]`; see the public-but-hidden note in the `SKILL.md` "Control flow between generated code and WinRT.Runtime" section). If this marking scheme changes, update the `SKILL.md` "Version compatibility" section and the runtime-interface descriptions in both reference docs accordingly ### Step 14: update this skill if needed diff --git a/.github/skills/update-testing-instructions/SKILL.md b/.github/skills/update-testing-instructions/SKILL.md index 6ffe5ff9c8..5f2b42d2a2 100644 --- a/.github/skills/update-testing-instructions/SKILL.md +++ b/.github/skills/update-testing-instructions/SKILL.md @@ -68,7 +68,17 @@ Launch an explore agent to verify: - **Project settings** are current: output type, TFM, `CsWinRTComponent` setting, AOT mode - **What it tests** description is accurate -### Step 7: verify TestComponentCSharp (`src/Tests/TestComponentCSharp/`) +### Step 7: verify smoke tests (`src/Tests/SmokeTests/`) + +Launch an explore agent (or inspect directly) to verify: + +- **Project list** is accurate — the `Consumption/` app, the `Authoring/` component, the `Projection/` reference projection, and the `WindowsSdkProjection/`/`WindowsSdkXamlProjection/` Windows SDK reference projections, kept out of `cswinrt.slnx` +- **Isolation** is intact: blank `Directory.Build.props`/`.targets` and a local `Directory.Packages.props` (central package management disabled) +- **Shared configuration** in `Directory.Build.props` is current: TFM (`.1` revision; the two Windows SDK projection tests override to plain `net10.0`), pinned `WindowsSdkPackageVersion`, `RestoreSources` (local package output + the `CsWinRTDependencies` feed, which provides the preview Windows SDK ref pack and `Microsoft.Windows.SDK.Contracts`), `DisableRuntimeMarshalling`, and the `CsWinRTPackageVersion`/`CsWinRTPackageSource` defaults. Also verify `WindowsSdkContracts.targets` (the shared SDK `.winmd` staging the two SDK projection tests import) +- **What each test does** is accurate (the consumption app's `JsonObject.Parse`/`Stringify` call; the authoring component's class and `.winmd` verification; the `Projection`/`WindowsSdkProjection`/`WindowsSdkXamlProjection` libraries' reference projections, each verifying a forwarder and a `ref` assembly are produced — `Projection` over the authoring component's `.winmd`, the SDK ones over the `Microsoft.Windows.SDK.Contracts` `.winmd` files) +- **How they run** is current: the `run-smoke-tests.ps1` runner (its `-Test` and `-Runtime` parameters — consumption/authoring run on both CoreCLR and Native AOT, the three reference-projection tests on CoreCLR only via the shared forwarder + `ref` assembly verification), and the invocations in `src/build.cmd` and `build/AzurePipelineTemplates/CsWinRT-PublishToNuGet-Steps.yml` + +### Step 8: verify TestComponentCSharp (`src/Tests/TestComponentCSharp/`) Launch an explore agent to verify: @@ -76,7 +86,7 @@ Launch an explore agent to verify: - **"Referenced from" list** is current - **"When to update" guidance** is still correct -### Step 8: verify the "deciding where to add tests" table +### Step 9: verify the "deciding where to add tests" table Check every row in the routing table against the actual test projects. Verify: @@ -85,7 +95,7 @@ Check every row in the routing table against the actual test projects. Verify: - No new test project categories exist that should be added as rows - The `TestComponentCSharp` guidance is still accurate -### Step 9: verify code examples +### Step 10: verify code examples For each code example in the testing skill, verify it matches the conventions actually used in the test files: @@ -94,7 +104,7 @@ For each code example in the testing skill, verify it matches the conventions ac - **Generator test pattern**: verify the `VerifySources` call matches the actual method signature and style. Check an actual test method in `Test_CustomPropertyProviderGenerator` to confirm - **Analyzer test pattern**: verify the `VerifyAnalyzerAsync` call matches the actual method signature and style. Check an actual test method in the analyzer test files to confirm -### Step 10: update the testing instructions +### Step 11: update the testing instructions Apply surgical edits to `.github/skills/testing/SKILL.md` to fix any discrepancies found. Typical updates include: @@ -115,17 +125,17 @@ Apply surgical edits to `.github/skills/testing/SKILL.md` to fix any discrepanci - Do not add unnecessary commentary or explanation beyond what's needed for test placement guidance -### Step 11: update this skill if needed +### Step 12: update this skill if needed If significant changes to the test suite were discovered (e.g. test projects added or removed, new categories of tests, changed validation criteria), also update this skill file (`.github/skills/update-testing-instructions/SKILL.md`) to reflect those changes. In particular: -- The **per-project verification steps** (steps 2–7) must stay in sync with the actual test projects. If a test project is added or removed, add or remove its verification step accordingly. +- The **per-project verification steps** (steps 2–8) must stay in sync with the actual test projects. If a test project is added or removed, add or remove its verification step accordingly. - The **verification criteria** for each step should reflect what is actually worth checking. If a project gains new aspects worth validating (e.g. new test helper classes, new build settings), add those to the checklist. -- The **code example verification step** (step 9) should list all code examples present in the testing skill. +- The **code example verification step** (step 10) should list all code examples present in the testing skill. This ensures the skill remains useful and accurate for future runs. -### Step 12: summarize changes +### Step 13: summarize changes After editing, provide a clear summary of what was updated and why, so the user can review the changes before committing. diff --git a/build/AzurePipelineTemplates/CsWinRT-PublishToNuGet-Steps.yml b/build/AzurePipelineTemplates/CsWinRT-PublishToNuGet-Steps.yml index 4fb62c6480..0c318ce774 100644 --- a/build/AzurePipelineTemplates/CsWinRT-PublishToNuGet-Steps.yml +++ b/build/AzurePipelineTemplates/CsWinRT-PublishToNuGet-Steps.yml @@ -124,6 +124,101 @@ steps: commit=$(Build.SourceVersion)" packDestination: $(ob_outputDirectory)\packages + # Build and run the end-to-end smoke tests against the freshly packed NuGet package. These + # verify that the real package (ref/lib assemblies, generators, and build targets) works for + # a consuming app, a component author, a projection author, and the Windows SDK projection packages, + # fully isolated from the repo build infrastructure. The smoke tests restore the package being tested + # from the packed output above, and all other dependencies (notably the preview Windows SDK ref pack + # and 'Microsoft.Windows.SDK.Contracts') from the CsWinRTDependencies feed. + # + # Each smoke test runs as its own step with 'continueOnError' (so a failure only marks the job + # as 'SucceededWithIssues' and makes it obvious which one failed); a final gate step below turns + # any such issue into an actual failure. This mirrors the unit test steps in CsWinRT-Test-Steps.yml. + # The consumption and authoring tests each run twice: once on CoreCLR and once with Native AOT, so a + # failure points at the exact runtime. The projection, Windows SDK projection, and Windows SDK XAML + # projection tests are build-only, so they run once on CoreCLR. Native AOT publishes are x64 (this job + # only runs on an x64 host). + - task: UseDotNet@2 + displayName: Use .NET SDK for smoke tests + inputs: + packageType: sdk + version: $(_DotnetVersion) + + - task: PowerShell@2 + displayName: Run Consumption smoke test (CoreCLR) + continueOnError: true + inputs: + targetType: filePath + filePath: $(Build.SourcesDirectory)\src\Tests\SmokeTests\run-smoke-tests.ps1 + arguments: -PackageSource "$(ob_outputDirectory)\packages" -PackageVersion "$(NugetVersion)" -Test Consumption -Runtime CoreCLR + workingDirectory: $(Build.SourcesDirectory) + + - task: PowerShell@2 + displayName: Run Consumption smoke test (NAOT) + continueOnError: true + inputs: + targetType: filePath + filePath: $(Build.SourcesDirectory)\src\Tests\SmokeTests\run-smoke-tests.ps1 + arguments: -PackageSource "$(ob_outputDirectory)\packages" -PackageVersion "$(NugetVersion)" -Test Consumption -Runtime NativeAot + workingDirectory: $(Build.SourcesDirectory) + + - task: PowerShell@2 + displayName: Run Authoring smoke test (CoreCLR) + continueOnError: true + inputs: + targetType: filePath + filePath: $(Build.SourcesDirectory)\src\Tests\SmokeTests\run-smoke-tests.ps1 + arguments: -PackageSource "$(ob_outputDirectory)\packages" -PackageVersion "$(NugetVersion)" -Test Authoring -Runtime CoreCLR + workingDirectory: $(Build.SourcesDirectory) + + - task: PowerShell@2 + displayName: Run Authoring smoke test (NAOT) + continueOnError: true + inputs: + targetType: filePath + filePath: $(Build.SourcesDirectory)\src\Tests\SmokeTests\run-smoke-tests.ps1 + arguments: -PackageSource "$(ob_outputDirectory)\packages" -PackageVersion "$(NugetVersion)" -Test Authoring -Runtime NativeAot + workingDirectory: $(Build.SourcesDirectory) + + - task: PowerShell@2 + displayName: Run Projection smoke test (CoreCLR) + continueOnError: true + inputs: + targetType: filePath + filePath: $(Build.SourcesDirectory)\src\Tests\SmokeTests\run-smoke-tests.ps1 + arguments: -PackageSource "$(ob_outputDirectory)\packages" -PackageVersion "$(NugetVersion)" -Test Projection -Runtime CoreCLR + workingDirectory: $(Build.SourcesDirectory) + + - task: PowerShell@2 + displayName: Run Windows SDK projection smoke test (CoreCLR) + continueOnError: true + inputs: + targetType: filePath + filePath: $(Build.SourcesDirectory)\src\Tests\SmokeTests\run-smoke-tests.ps1 + arguments: -PackageSource "$(ob_outputDirectory)\packages" -PackageVersion "$(NugetVersion)" -Test WindowsSdkProjection -Runtime CoreCLR + workingDirectory: $(Build.SourcesDirectory) + + - task: PowerShell@2 + displayName: Run Windows SDK XAML projection smoke test (CoreCLR) + continueOnError: true + inputs: + targetType: filePath + filePath: $(Build.SourcesDirectory)\src\Tests\SmokeTests\run-smoke-tests.ps1 + arguments: -PackageSource "$(ob_outputDirectory)\packages" -PackageVersion "$(NugetVersion)" -Test WindowsSdkXamlProjection -Runtime CoreCLR + workingDirectory: $(Build.SourcesDirectory) + + # Fail the job if any smoke test above failed. Each smoke test uses 'continueOnError', so an + # individual failure only marks the job as 'SucceededWithIssues'; this turns that into a real + # failure, while still letting every smoke test run and report first. + - task: PowerShell@2 + displayName: Fail if any smoke test failed + condition: eq(variables['Agent.JobStatus'], 'SucceededWithIssues') + inputs: + targetType: inline + script: | + Write-Host "##vso[task.logissue type=error]One or more smoke tests failed. See above for details." + exit 1 + - ${{ if eq(parameters.IsGitHub, false) }}: # NuGet signing diff --git a/docs/diagnostics/cswinrt3002.md b/docs/diagnostics/cswinrt3002.md new file mode 100644 index 0000000000..193102af5b --- /dev/null +++ b/docs/diagnostics/cswinrt3002.md @@ -0,0 +1,28 @@ +# CsWinRT warning CSWINRT3002 + +The Windows Runtime type map group types (`WindowsRuntimeComWrappersTypeMapGroup`, `WindowsRuntimeMetadataTypeMapGroup`, and `DynamicInterfaceCastableImplementationTypeMapGroup`, all in the `WindowsRuntime.InteropServices` namespace) are a private implementation detail of `WinRT.Runtime.dll`. They are only meant to be used as type map group type arguments for the `System.Runtime.InteropServices.TypeMapping` APIs, in marshalling code generated by CsWinRT. They are exposed in the reference assembly for `WinRT.Runtime.dll` solely so that this generated code can reference them, and they are not intended for direct use in user code. + +For instance, the following sample generates CSWINRT3002: + +```csharp +using System.Runtime.InteropServices; +using WindowsRuntime.InteropServices; + +namespace MyProgram; + +// CSWINRT3002: the type map group types are a private implementation detail +[assembly: TypeMapAssemblyTarget("MyComponent")] +``` + +## Additional resources + +`CSWINRT3002` is emitted when user code references one of the Windows Runtime type map group types directly. These types act as type map group markers for the .NET interop type map infrastructure: the CsWinRT source generator emits `[assembly: TypeMapAssemblyTarget(...)]` attributes to register the assemblies that contain type map entries, and the interop generator (`cswinrtinteropgen.exe`) emits the corresponding entries. All of that generated code suppresses this diagnostic, so it never affects normal builds. + +The type map group types are not considered part of the versioned API surface of `WinRT.Runtime.dll`, and they may be modified or removed across any version change. Using them in user code is undefined behavior and not supported. + +## Recommended action + +- Do not reference the type map group types in user code, and let CsWinRT generate the type map registration for you. +- If you are authoring or consuming a Windows Runtime component, the required `[assembly: TypeMapAssemblyTarget(...)]` attributes are generated automatically; no manual registration is needed. + +Keeping the type map group types exclusive to generated code is what allows CsWinRT to evolve the interop type map infrastructure rapidly. Respecting the diagnostic ensures your applications remain stable across updates. diff --git a/docs/diagnostics/cswinrt3003.md b/docs/diagnostics/cswinrt3003.md new file mode 100644 index 0000000000..c5840a7d07 --- /dev/null +++ b/docs/diagnostics/cswinrt3003.md @@ -0,0 +1,25 @@ +# CsWinRT warning CSWINRT3003 + +The Windows Runtime component assembly attributes (`WindowsRuntimeComponentAssemblyAttribute` and `WindowsRuntimeComponentAssemblyExportsTypeAttribute`, both in the `WindowsRuntime.InteropServices` namespace) are a private implementation detail of `WinRT.Runtime.dll`. They are only meant to be applied to authored Windows Runtime component assemblies by CsWinRT, to mark them and to identify the generated type that contains their activation factory entry point. They are exposed in the reference assembly for `WinRT.Runtime.dll` solely so that this generated code can reference them, and they are not intended for direct use in user code. + +For instance, the following sample generates CSWINRT3003: + +```csharp +using WindowsRuntime.InteropServices; + +// CSWINRT3003: the component assembly attributes are a private implementation detail +[assembly: WindowsRuntimeComponentAssembly] +``` + +## Additional resources + +`CSWINRT3003` is emitted when user code references one of the Windows Runtime component assembly attributes directly. These attributes identify an authored Windows Runtime component assembly and the generated type that exposes its managed `GetActivationFactory` method: the CsWinRT source generator emits them automatically when building a Windows Runtime component (when `CsWinRTComponent` is set to `true`), and other CsWinRT tooling (the source generator, the projection generator, and the interop generator) reads them to merge activation factories across referenced components. All of that generated code suppresses this diagnostic, so it never affects normal builds. + +The component assembly attributes are not considered part of the versioned API surface of `WinRT.Runtime.dll`, and they may be modified or removed across any version change. Using them in user code is undefined behavior and not supported. + +## Recommended action + +- Do not reference the component assembly attributes in user code, and let CsWinRT emit them for you. +- If you are authoring a Windows Runtime component, set `CsWinRTComponent` to `true` and let CsWinRT generate the activation factory exports (and the attributes that identify them) automatically; no manual annotation is needed. + +Keeping the component assembly attributes exclusive to generated code is what allows CsWinRT to evolve the authoring infrastructure rapidly. Respecting the diagnostic ensures your applications remain stable across updates. diff --git a/docs/diagnostics/cswinrt3004.md b/docs/diagnostics/cswinrt3004.md new file mode 100644 index 0000000000..4874c87c32 --- /dev/null +++ b/docs/diagnostics/cswinrt3004.md @@ -0,0 +1,25 @@ +# CsWinRT warning CSWINRT3004 + +The `WindowsRuntimeReferenceAssemblyAttribute` type (in the `WindowsRuntime.InteropServices` namespace) is a private implementation detail of `WinRT.Runtime.dll`. It is only meant to be applied (via `[assembly: WindowsRuntimeReferenceAssembly]`) to generated Windows Runtime projection assemblies by CsWinRT, to identify them as containing projected Windows Runtime APIs. Unlike most other CsWinRT implementation details, it is not stripped from the reference assembly for `WinRT.Runtime.dll`, because the reference projection assemblies that ship in Windows Runtime projection NuGet packages carry it and it must remain resolvable when those assemblies are consumed. It is not intended for direct use in user code. + +For instance, the following sample generates CSWINRT3004: + +```csharp +using WindowsRuntime.InteropServices; + +// CSWINRT3004: the reference assembly attribute is a private implementation detail +[assembly: WindowsRuntimeReferenceAssembly] +``` + +## Additional resources + +`CSWINRT3004` is emitted when user code references the `WindowsRuntimeReferenceAssemblyAttribute` type directly. This attribute marks an assembly as containing generated Windows Runtime APIs from a given Windows Runtime metadata file (`.winmd`): CsWinRT emits it automatically into the reference projection assemblies it produces (via `cswinrtprojectionrefgen.exe` and `cswinrtprojectiongen.exe`), and CsWinRT tooling reads it to recognize those assemblies. All of that generated code suppresses this diagnostic, so it never affects normal builds. + +The reference assembly attribute is not considered part of the versioned API surface of `WinRT.Runtime.dll`, and it may be modified or removed across any version change. Using it in user code is undefined behavior and not supported. + +## Recommended action + +- Do not reference the `WindowsRuntimeReferenceAssemblyAttribute` type in user code, and let CsWinRT emit it for you. +- If you are authoring a Windows Runtime projection to ship in a NuGet package, set `CsWinRTGenerateReferenceProjection` to `true` and let CsWinRT generate the reference projection (and the attribute that identifies it) automatically; no manual annotation is needed. + +Keeping the reference assembly attribute exclusive to generated code is what allows CsWinRT to evolve the projection infrastructure rapidly. Respecting the diagnostic ensures your applications remain stable across updates. diff --git a/docs/structure.md b/docs/structure.md index e0895712cd..e6d320fbab 100644 --- a/docs/structure.md +++ b/docs/structure.md @@ -41,15 +41,31 @@ Contains several projects for generating and building projections from the Windo Contains various testing-related projects: -- [`TestComponentCSharp`](../src/Tests/TestComponentCSharp): This is an implementation of a WinRT test component, defined in `class.idl` and used by the UnitTest project. To complement the general TestComponent above, the TestComponentCSharp tests scenarios specific to the C#/WinRT language projection. +- [`TestComponentCSharp`](../src/Tests/TestComponentCSharp): An implementation of a WinRT test component, defined in `TestComponentCSharp.idl` and used by the UnitTest and functional test projects. To complement the general TestComponent above, the TestComponentCSharp tests scenarios specific to the C#/WinRT language projection. -- [`UnitTest`](../src/Tests/UnitTest): Unit tests for validating the Windows SDK, WinUI, and Test projections generated above. All pull requests should ensure that this project executes without errors. +- [`UnitTest`](../src/Tests/UnitTest): MSTest unit tests for validating the Windows SDK, WinUI, and Test projections generated above, plus core marshalling, COM interop, exceptions, and source-generator integration. All pull requests should ensure that this project executes without errors. -- [`HostTest`](../src/Tests/HostTest): Unit tests for WinRT.Host.dll, which provides hosting for runtime components written in C#. +- [`FunctionalTests`](../src/Tests/FunctionalTests): A collection of standalone console applications, each validating a specific interop scenario (async, collections, events, CCW, dynamic casting, structs, and more) under real publishing conditions such as trimming and Native AOT. Each test reports success with exit code `100`. + +- [`SourceGenerator2Test`](../src/Tests/SourceGenerator2Test): MSTest unit tests for the source generators and diagnostic analyzers in `WinRT.SourceGenerator2`, built on the Roslyn testing libraries. + +- [`ObjectLifetimeTests`](../src/Tests/ObjectLifetimeTests): A WinUI application-style MSTest project validating reference tracking, garbage collection behavior, and XAML element lifetime. + +- [`SmokeTests`](../src/Tests/SmokeTests): Minimal, isolated end-to-end smoke tests that consume the real `Microsoft.Windows.CsWinRT` NuGet package — a consumption app (`Consumption`), an authoring component (`Authoring`), a reference projection for a third-party `.winmd` (`Projection`), and reference projections for the Windows SDK (`WindowsSdkProjection`) and its `Windows.UI.Xaml` surface (`WindowsSdkXamlProjection`) — to verify the produced package works correctly outside the repository build infrastructure. + +- [`AuthoringTest`](../src/Tests/AuthoringTest): A C#-authored WinRT component (`CsWinRTComponent=true`) covering a broad set of authoring type patterns. Companion projects exercise consuming authored components — `AuthoringTest2`/`AuthoringTest3`, the `AuthoringConsumptionTest*` C++ consumers, and the WUX (`Windows.UI.Xaml`) and WinUI variants — several of which are still work in progress. + +- [`HostTest`](../src/Tests/HostTest): C++ (gtest) tests for `WinRT.Host.dll`, which provides hosting for runtime components written in C#. + +- [`DiagnosticTests`](../src/Tests/DiagnosticTests): Tests for the CsWinRT diagnostic and analyzer rules, driven by positive and negative source snippets. + +- [`BuildDeterminismTest`](../src/Tests/BuildDeterminismTest): Builds a component twice and compares the hashes of the generated `WinRT.Interop.dll` to verify deterministic builds. + +- [`OOPExe`](../src/Tests/OOPExe): An out-of-process executable harness used by the authoring test scenarios. ## [`src/TestWinRT`](https://github.com/microsoft/TestWinRT/) -C#/WinRT makes use of the standalone [TestWinRT](https://github.com/microsoft/TestWinRT/) repository for general language projection test coverage. This repo is cloned into the root of the C#/WinRT repo, via `get_testwinrt.cmd`, so that `cswinrt.sln` can resolve its reference to `TestComponent.vcxproj`. The resulting `TestComponent` and `BenchmarkComponent` files are consumed by the UnitTest and Benchmarks projects above. +C#/WinRT makes use of the standalone [TestWinRT](https://github.com/microsoft/TestWinRT/) repository for general language projection test coverage. This repo is cloned into the root of the C#/WinRT repo, via `get_testwinrt.cmd`, so that `cswinrt.slnx` can resolve its reference to `TestComponent.vcxproj`. The resulting `TestComponent` and `BenchmarkComponent` files are consumed by the UnitTest and Benchmarks projects above. ## [`src/WinRT.Generator.Tasks`](../src/WinRT.Generator.Tasks) diff --git a/nuget/Microsoft.Windows.CsWinRT.CsWinRTGen.targets b/nuget/Microsoft.Windows.CsWinRT.CsWinRTGen.targets index bf683b9dff..8886ce220b 100644 --- a/nuget/Microsoft.Windows.CsWinRT.CsWinRTGen.targets +++ b/nuget/Microsoft.Windows.CsWinRT.CsWinRTGen.targets @@ -81,6 +81,27 @@ Copyright (C) Microsoft Corporation. All rights reserved. --> <_CsWinRTSdkProjectionAssemblyPath>$([MSBuild]::NormalizePath('$(MSBuildProjectDirectory)', '$(IntermediateOutputPath)', 'WinRT.Sdk.Projection.dll')) + + $([MSBuild]::NormalizePath('$(CsWinRTPath)', 'lib', 'net10.0', 'WinRT.Runtime.dll')) + + + true + $(DefineConstants);CSWINRT_REFERENCE_PROJECTION @@ -171,10 +192,18 @@ Copyright (C) Microsoft Corporation. All rights reserved. Outputs="$(_CsWinRTGeneratorInteropAssemblyPath)" Condition="'$(CsWinRTGenerateInteropAssembly2)' == 'true'"> + + + <_InteropReferenceAssemblyPaths Include="@(ReferencePathWithRefAssemblies)" Condition="'%(FileName)' != 'WinRT.Runtime' or '$(CsWinRTSwapRuntimeReferenceAssembly)' != 'true'" /> + <_InteropReferenceAssemblyPaths Include="$(CsWinRTRuntimeImplementationAssemblyPath)" Condition="'$(CsWinRTSwapRuntimeReferenceAssembly)' == 'true'" /> + <_InteropImplementationAssemblyPaths Include="@(ReferencePath)" Condition="'%(FileName)' != 'WinRT.Runtime' or '$(CsWinRTSwapRuntimeReferenceAssembly)' != 'true'" /> + <_InteropImplementationAssemblyPaths Include="$(CsWinRTRuntimeImplementationAssemblyPath)" Condition="'$(CsWinRTSwapRuntimeReferenceAssembly)' == 'true'" /> + + <_WinMDPathsList Include="$(CsWinRTInteropMetadata)" /> - <_MergedProjectionReferenceAssemblyPaths Include="@(ReferencePathWithRefAssemblies)" /> + + + <_MergedProjectionReferenceAssemblyPaths Include="@(ReferencePathWithRefAssemblies)" Condition="'%(FileName)' != 'WinRT.Runtime' or '$(CsWinRTSwapRuntimeReferenceAssembly)' != 'true'" /> + <_MergedProjectionReferenceAssemblyPaths Include="$(CsWinRTRuntimeImplementationAssemblyPath)" Condition="'$(CsWinRTSwapRuntimeReferenceAssembly)' == 'true'" /> <_MergedProjectionReferenceAssemblyPaths Include="$(_CsWinRTSdkProjectionAssemblyPath)" /> <_MergedProjectionReferenceAssemblyPaths Include="$(_CsWinRTSdkXamlAssemblyPath)" Condition="'$(CsWinRTUseWindowsUIXamlProjections)' == 'true'" /> @@ -397,8 +429,12 @@ Copyright (C) Microsoft Corporation. All rights reserved. Condition="'$(CsWinRTGenerateInteropAssembly2)' == 'true'"> - <_ComponentProjectionReferenceAssemblyPaths Include="@(ReferencePath)" Condition="!$([System.String]::new('%(Identity)').EndsWith('.winmd'))" /> + + + <_ComponentProjectionReferenceAssemblyPaths Include="@(ReferencePath)" Condition="!$([System.String]::new('%(Identity)').EndsWith('.winmd')) and ('%(FileName)' != 'WinRT.Runtime' or '$(CsWinRTSwapRuntimeReferenceAssembly)' != 'true')" /> + <_ComponentProjectionReferenceAssemblyPaths Include="$(CsWinRTRuntimeImplementationAssemblyPath)" Condition="'$(CsWinRTSwapRuntimeReferenceAssembly)' == 'true'" /> <_ComponentProjectionReferenceAssemblyPaths Include="@(IntermediateAssembly)" Condition="'$(CsWinRTComponent)' == 'true'" /> + <_ComponentWinMDPaths Include="@(_WinMDPathsList)" /> <_ComponentWinMDPaths Include="$([MSBuild]::NormalizePath('$(MSBuildProjectDirectory)', '$(IntermediateOutputPath)', '$(AssemblyName).winmd'))" @@ -479,11 +515,15 @@ Copyright (C) Microsoft Corporation. All rights reserved. <_SdkWinMDPathsList Include="$([MSBuild]::ValueOrDefault('%(_SdkReferencePathsWithWinMDs.CsWinRTInputs)', '').Split(';'))" Condition="'%(_SdkReferencePathsWithWinMDs.CsWinRTInputs)' != ''" /> <_SdkWinMDPathsList Include="$(CsWinRTInteropMetadata)" /> + + + <_SdkProjectionReferenceAssemblyPaths Include="@(ReferencePathWithRefAssemblies)" Condition="'%(FileName)' != 'WinRT.Runtime' or '$(CsWinRTSwapRuntimeReferenceAssembly)' != 'true'" /> + <_SdkProjectionReferenceAssemblyPaths Include="$(CsWinRTRuntimeImplementationAssemblyPath)" Condition="'$(CsWinRTSwapRuntimeReferenceAssembly)' == 'true'" /> <_SdkXamlWinMDPathsList Include="$(CsWinRTInteropMetadata)" /> - <_SdkXamlProjectionReferenceAssemblyPaths Include="@(ReferencePathWithRefAssemblies)" /> + + + <_SdkXamlProjectionReferenceAssemblyPaths Include="@(ReferencePathWithRefAssemblies)" Condition="'%(FileName)' != 'WinRT.Runtime' or '$(CsWinRTSwapRuntimeReferenceAssembly)' != 'true'" /> + <_SdkXamlProjectionReferenceAssemblyPaths Include="$(CsWinRTRuntimeImplementationAssemblyPath)" Condition="'$(CsWinRTSwapRuntimeReferenceAssembly)' == 'true'" /> <_SdkXamlProjectionReferenceAssemblyPaths Include="$(_CsWinRTSdkProjectionAssemblyPath)" /> diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index f49b39b545..af55bcd22b 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -237,12 +237,25 @@ Copyright (C) Microsoft Corporation. All rights reserved. DependsOnTargets="CsWinRTPrepareProjection;CsWinRTRemoveWinMDReferences;CsWinRTResolveWindowsMetadata;_ResolveCsWinRToolsDirectory" Condition="'$(CsWinRTGenerateProjection)' == 'true'"> + + + <_CsWinRTSkipProjectionRefGeneration Condition="'$(CsWinRTComponent)' == 'true' and '@(CsWinRTInputs)' == ''">true + + - @@ -319,8 +332,10 @@ Copyright (C) Microsoft Corporation. All rights reserved. <_CsWinRTRefInputs Include="@(_CsWinRTRefInteropInputs)" /> - + + $(MSBuildThisFileDirectory)WinRT.Projection.Ref.Generator\bin\$(Configuration)\net10.0\$(_CsWinRTToolsArchFolder) $(MSBuildThisFileDirectory)WinRT.WinMD.Generator\bin\$(Configuration)\net10.0\$(_CsWinRTToolsArchFolder) AnyCPU + + + false diff --git a/src/Tests/SmokeTests/.gitignore b/src/Tests/SmokeTests/.gitignore new file mode 100644 index 0000000000..3f4be6546e --- /dev/null +++ b/src/Tests/SmokeTests/.gitignore @@ -0,0 +1,5 @@ +# The smoke tests are isolated from the repository build infrastructure and use the default +# project-relative build output folders (rather than the repo's '_build' output), so ignore +# them here to keep build artifacts out of source control. +bin/ +obj/ diff --git a/src/Tests/SmokeTests/Authoring/Authoring.csproj b/src/Tests/SmokeTests/Authoring/Authoring.csproj new file mode 100644 index 0000000000..42d7c28cfe --- /dev/null +++ b/src/Tests/SmokeTests/Authoring/Authoring.csproj @@ -0,0 +1,15 @@ + + + + + + + true + + diff --git a/src/Tests/SmokeTests/Authoring/Greeter.cs b/src/Tests/SmokeTests/Authoring/Greeter.cs new file mode 100644 index 0000000000..12a1de64df --- /dev/null +++ b/src/Tests/SmokeTests/Authoring/Greeter.cs @@ -0,0 +1,9 @@ +namespace Authoring; + +public sealed class Greeter +{ + public string Greet(string name) + { + return $"Hello, {name}!"; + } +} diff --git a/src/Tests/SmokeTests/Authoring/Thermometer.cs b/src/Tests/SmokeTests/Authoring/Thermometer.cs new file mode 100644 index 0000000000..2832e9e3ac --- /dev/null +++ b/src/Tests/SmokeTests/Authoring/Thermometer.cs @@ -0,0 +1,105 @@ +using System; + +namespace Authoring; + +// A richer set of authored Windows Runtime types, exercised end-to-end by the projection smoke +// test: building the component produces 'Authoring.winmd', which the projection smoke test then +// generates a reference projection for. Between them, these cover the main projection shapes: +// enums, a flags enum, a struct, a delegate, an interface, a sealed runtime class with multiple +// constructors, instance methods, properties, an event, and static members, and an unsealed +// (derivable) runtime class. + +public enum Season +{ + Spring, + Summer, + Autumn, + Winter +} + +[Flags] +public enum SensorCapabilities : uint +{ + None = 0, + Temperature = 1, + Humidity = 2, + All = Temperature | Humidity +} + +public struct Measurement +{ + public int Value; + public Season Season; +} + +public delegate void TemperatureChangedHandler(int previousValue, int currentValue); + +public interface IThermometer +{ + int Temperature { get; } + + void Reset(); +} + +public sealed class Thermometer : IThermometer +{ + private int _temperature; + + public event TemperatureChangedHandler? TemperatureChanged; + + public Thermometer() + { + } + + public Thermometer(int initialTemperature) + { + _temperature = initialTemperature; + } + + public static int AbsoluteZero => -273; + + public int Temperature => _temperature; + + public string Label { get; set; } + + public Season CurrentSeason { get; set; } + + public SensorCapabilities Capabilities { get; set; } + + public static Thermometer CreateFreezing() + { + return new Thermometer(0); + } + + public void Reset() + { + SetTemperature(0); + } + + public void SetTemperature(int value) + { + int previousValue = _temperature; + + _temperature = value; + + TemperatureChanged?.Invoke(previousValue, value); + } + + public Measurement Measure() + { + return new Measurement { Value = _temperature, Season = CurrentSeason }; + } +} + +// TODO: uncomment this when authoring unsealed classes is supported +// public class Weather +// { +// public string Location { get; set; } +// +// public Season CurrentSeason { get; set; } +// +// public int Forecast() +// { +// return CurrentSeason == Season.Winter ? -5 : 20; +// } +// } diff --git a/src/Tests/SmokeTests/Consumption/Consumption.csproj b/src/Tests/SmokeTests/Consumption/Consumption.csproj new file mode 100644 index 0000000000..e473292ceb --- /dev/null +++ b/src/Tests/SmokeTests/Consumption/Consumption.csproj @@ -0,0 +1,13 @@ + + + + + Exe + + diff --git a/src/Tests/SmokeTests/Consumption/Program.cs b/src/Tests/SmokeTests/Consumption/Program.cs new file mode 100644 index 0000000000..81318c24f0 --- /dev/null +++ b/src/Tests/SmokeTests/Consumption/Program.cs @@ -0,0 +1,8 @@ +using System; +using Windows.Data.Json; + +JsonObject json = JsonObject.Parse("""{ "a": 42 }"""); + +string stringified = json.Stringify(); + +return stringified.Contains("42") ? 0 : 1; diff --git a/src/Tests/SmokeTests/Directory.Build.props b/src/Tests/SmokeTests/Directory.Build.props new file mode 100644 index 0000000000..c08d0cc326 --- /dev/null +++ b/src/Tests/SmokeTests/Directory.Build.props @@ -0,0 +1,55 @@ + + + + + net10.0-windows10.0.26100.1 + 10.0.17763.0 + 10.0.26100.85-preview + + + true + + + + + 0.0.0-private.0 + $([MSBuild]::NormalizeDirectory('$(MSBuildThisFileDirectory)', '..', '..', '_build', 'x64', 'Release', 'cswinrt', 'bin')) + + + https://pkgs.dev.azure.com/shine-oss/CsWinRT/_packaging/CsWinRTDependencies/nuget/v3/index.json + + + $(CsWinRTPackageSource);$(CsWinRTDependenciesSource) + + + + + + diff --git a/src/Tests/SmokeTests/Directory.Build.targets b/src/Tests/SmokeTests/Directory.Build.targets new file mode 100644 index 0000000000..9751b5521c --- /dev/null +++ b/src/Tests/SmokeTests/Directory.Build.targets @@ -0,0 +1,10 @@ + + + + diff --git a/src/Tests/SmokeTests/Directory.Packages.props b/src/Tests/SmokeTests/Directory.Packages.props new file mode 100644 index 0000000000..631be2ff9a --- /dev/null +++ b/src/Tests/SmokeTests/Directory.Packages.props @@ -0,0 +1,13 @@ + + + + + false + + diff --git a/src/Tests/SmokeTests/Projection/Projection.csproj b/src/Tests/SmokeTests/Projection/Projection.csproj new file mode 100644 index 0000000000..066d7854a9 --- /dev/null +++ b/src/Tests/SmokeTests/Projection/Projection.csproj @@ -0,0 +1,39 @@ + + + + + + + true + + + Authoring + + + + + + + + + + + diff --git a/src/Tests/SmokeTests/WindowsSdkContracts.targets b/src/Tests/SmokeTests/WindowsSdkContracts.targets new file mode 100644 index 0000000000..fa2f0425d2 --- /dev/null +++ b/src/Tests/SmokeTests/WindowsSdkContracts.targets @@ -0,0 +1,56 @@ + + + + + <_SdkContractsPackageName>Microsoft.Windows.SDK.Contracts + + + <_SdkContractsPackageVersion>10.0.26100.7705 + + + + + + + + + + + + <_SdkContractsWinMDFolder>$([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', '$(_SdkContractsPackageName)', '$(_SdkContractsPackageVersion)', 'ref', 'netstandard2.0')) + + + + + + + + + diff --git a/src/Tests/SmokeTests/WindowsSdkProjection/WindowsSdkProjection.csproj b/src/Tests/SmokeTests/WindowsSdkProjection/WindowsSdkProjection.csproj new file mode 100644 index 0000000000..9fec3e58a4 --- /dev/null +++ b/src/Tests/SmokeTests/WindowsSdkProjection/WindowsSdkProjection.csproj @@ -0,0 +1,59 @@ + + + + + + + net10.0 + + + true + + + Windows; + Windows.UI.Xaml.Interop; + Windows.UI.Xaml.Data.BindableAttribute; + Windows.UI.Xaml.Markup.ContentPropertyAttribute + + + Windows.UI.Colors; + Windows.UI.ColorHelper; + Windows.UI.IColorHelper; + Windows.UI.IColors; + Windows.UI.Text.FontWeights; + Windows.UI.Text.IFontWeights; + Windows.UI.Xaml; + Windows.ApplicationModel.Store.Preview.WebAuthenticationCoreManagerHelper; + Windows.ApplicationModel.Store.Preview.IWebAuthenticationCoreManagerHelper + + + + + + diff --git a/src/Tests/SmokeTests/WindowsSdkXamlProjection/WindowsSdkXamlProjection.csproj b/src/Tests/SmokeTests/WindowsSdkXamlProjection/WindowsSdkXamlProjection.csproj new file mode 100644 index 0000000000..926598c697 --- /dev/null +++ b/src/Tests/SmokeTests/WindowsSdkXamlProjection/WindowsSdkXamlProjection.csproj @@ -0,0 +1,66 @@ + + + + + + + net10.0 + + + true + + + Windows.UI.Colors; + Windows.UI.ColorHelper; + Windows.UI.IColorHelper; + Windows.UI.IColors; + Windows.UI.Text.FontWeights; + Windows.UI.Text.IFontWeights; + Windows.UI.Xaml; + Windows.ApplicationModel.Store.Preview.WebAuthenticationCoreManagerHelper; + Windows.ApplicationModel.Store.Preview.IWebAuthenticationCoreManagerHelper + + + Windows; + Windows.UI.Xaml.Interop; + Windows.UI.Xaml.Data.BindableAttribute; + Windows.UI.Xaml.Markup.ContentPropertyAttribute + + + + + + + + + + $(MSBuildThisFileDirectory)..\WindowsSdkProjection\bin\$(Configuration)\$(TargetFramework)\ref\WindowsSdkProjection.dll + false + + + + + + diff --git a/src/Tests/SmokeTests/run-smoke-tests.ps1 b/src/Tests/SmokeTests/run-smoke-tests.ps1 new file mode 100644 index 0000000000..a58dd0ff2c --- /dev/null +++ b/src/Tests/SmokeTests/run-smoke-tests.ps1 @@ -0,0 +1,280 @@ +#!/usr/bin/env pwsh + +<# +.SYNOPSIS + Builds and runs the C#/WinRT end-to-end smoke tests against a real + 'Microsoft.Windows.CsWinRT' NuGet package. + +.DESCRIPTION + These smoke tests verify that the real NuGet package works for the two main consumer + scenarios, in isolation from the CsWinRT repository build infrastructure: + + * Consumption: a .NET app that uses a Windows SDK projection ('Windows.Data.Json') is + built and run, validating that the generated projection and interop assemblies, and + the 'WinRT.Runtime' ref/impl assemblies, are wired up correctly. + + * Authoring: a Windows Runtime component library is built, validating WinMD + generation, the reference projection, and the forwarder assembly. + + * Projection: a class library generates a reference projection for a third-party + component's '.winmd' (reusing the one emitted by the authoring test), validating the + reference projection generator and the forwarder generator, exactly as a NuGet + projection author would. + + * WindowsSdkProjection: a class library generates the base Windows SDK reference projection + from the 'Microsoft.Windows.SDK.Contracts' '.winmd' files, exactly as the + 'Microsoft.Windows.SDK.NET.Ref' projection package is produced. This validates that the full + Windows SDK surface generates and compiles against the packaged 'WinRT.Runtime' reference + assembly, catching reference-projection codegen regressions before they break that package. + + * WindowsSdkXamlProjection: as above, but for the 'Windows.UI.Xaml' surface, which references the + base Windows SDK reference projection (mirroring how the UWP XAML projection package depends on + the base Windows SDK projection package). + + The smoke tests reference the package via 'RestoreSources' (see the '.csproj' files), so + no global NuGet configuration changes are required. + +.PARAMETER PackageSource + Folder containing the built 'Microsoft.Windows.CsWinRT' NuGet package. + +.PARAMETER PackageVersion + Version of the 'Microsoft.Windows.CsWinRT' package to consume. + +.PARAMETER Test + Which smoke test(s) to run: 'Consumption', 'Authoring', 'Projection', 'WindowsSdkProjection', + 'WindowsSdkXamlProjection', or 'All' (the default). The CI runs each test as its own step (passing a + single value), so an individual failure is reported in isolation; local builds use the default 'All'. + +.PARAMETER Runtime + Which runtime to target: 'CoreCLR' (the default) builds and runs on the managed runtime; + 'NativeAot' publishes the project with Native AOT ('PublishAot=true', win-x64), exercising the + full publish pipeline (projection and interop generators, then ILC). The CI runs both as + separate steps so a failure points at the exact runtime. The 'Projection', 'WindowsSdkProjection', + and 'WindowsSdkXamlProjection' tests are build-only and therefore CoreCLR-only; they are skipped for + 'NativeAot'. + +.PARAMETER Configuration + Build configuration to use (defaults to 'Release'). + +.EXAMPLE + ./run-smoke-tests.ps1 -PackageSource ../../_build/x64/Release/cswinrt/bin -PackageVersion 0.0.0-private.0 + +.EXAMPLE + ./run-smoke-tests.ps1 -PackageSource ./packages -PackageVersion 3.0.0-preview.1 -Test Consumption -Runtime NativeAot +#> + +[CmdletBinding()] +param ( + [Parameter(Mandatory = $true)] + [string] $PackageSource, + + [Parameter(Mandatory = $true)] + [string] $PackageVersion, + + [ValidateSet('All', 'Consumption', 'Authoring', 'Projection', 'WindowsSdkProjection', 'WindowsSdkXamlProjection')] + [string] $Test = 'All', + + [ValidateSet('CoreCLR', 'NativeAot')] + [string] $Runtime = 'CoreCLR', + + [string] $Configuration = 'Release' +) + +$ErrorActionPreference = 'Stop' + +# Native AOT publishes are always x64: the NuGet publish job that runs the smoke tests only runs +# on an x64 host. +$nativeAotRid = 'win-x64' + +$smokeTestsRoot = $PSScriptRoot +$consumptionProject = [IO.Path]::Combine($smokeTestsRoot, 'Consumption', 'Consumption.csproj') +$authoringProject = [IO.Path]::Combine($smokeTestsRoot, 'Authoring', 'Authoring.csproj') +$projectionProject = [IO.Path]::Combine($smokeTestsRoot, 'Projection', 'Projection.csproj') +$windowsSdkProjectionProject = [IO.Path]::Combine($smokeTestsRoot, 'WindowsSdkProjection', 'WindowsSdkProjection.csproj') +$windowsSdkXamlProjectionProject = [IO.Path]::Combine($smokeTestsRoot, 'WindowsSdkXamlProjection', 'WindowsSdkXamlProjection.csproj') + +# Resolve the package source to an absolute path (NuGet rejects relative '--source' values). +$resolvedPackageSource = (Resolve-Path -Path $PackageSource).Path + +Write-Host "Smoke tests: consuming CsWinRT package '$PackageVersion' from '$resolvedPackageSource'" -ForegroundColor Cyan + +$commonBuildArgs = @( + '--configuration', $Configuration + "-p:CsWinRTPackageSource=$resolvedPackageSource" + "-p:CsWinRTPackageVersion=$PackageVersion" +) + +function Invoke-Dotnet { + param ([string[]] $Arguments) + + Write-Host "> dotnet $($Arguments -join ' ')" -ForegroundColor DarkGray + & dotnet @Arguments + if ($LASTEXITCODE -ne 0) { + throw "Command 'dotnet $($Arguments -join ' ')' failed with exit code $LASTEXITCODE." + } +} + +function Assert-WinMDDefinesType { + param ( + [Parameter(Mandatory = $true)] [string] $Path, + [Parameter(Mandatory = $true)] [string] $Namespace, + [Parameter(Mandatory = $true)] [string] $TypeName + ) + + # Deliberately lightweight inspection (no managed-metadata dependencies, works in any + # PowerShell host): a Windows Runtime metadata file carries the 'WindowsRuntime 1.4' + # metadata version, and a type's namespace and name are stored as separate, null-terminated + # entries in the metadata strings heap. + $text = [Text.Encoding]::ASCII.GetString([IO.File]::ReadAllBytes($Path)) + + if (-not $text.Contains('WindowsRuntime 1.4')) { + throw "'$Path' is not a Windows Runtime metadata (.winmd) file." + } + + foreach ($name in @($Namespace, $TypeName)) { + if (-not $text.Contains("$name`0")) { + throw "'$Path' does not define '$Namespace.$TypeName' (missing '$name')." + } + } + + Write-Host "Verified '$([IO.Path]::GetFileName($Path))' defines '$Namespace.$TypeName'." -ForegroundColor DarkGray +} + +# Consumption: build (CoreCLR) or Native AOT publish, then run (must not crash). +function Invoke-ConsumptionSmokeTest { + Write-Host "`n=== Consumption smoke test ($Runtime) ===" -ForegroundColor Green + + if ($Runtime -eq 'NativeAot') { + # Publish the whole app with Native AOT (self-contained, no managed host). + Invoke-Dotnet (@('publish', $consumptionProject, '--runtime', $nativeAotRid, '-p:PublishAot=true') + $commonBuildArgs) + } + else { + Invoke-Dotnet (@('build', $consumptionProject) + $commonBuildArgs) + } + + # Locate the freshly built app, asserting a clean (zero) exit code when run. A Native AOT + # publish drops a self-contained '.exe' under a 'publish' folder, so filter to it; a CoreCLR + # build leaves the '.exe' directly under the target framework folder. + $consumptionExe = Get-ChildItem -Path ([IO.Path]::Combine($smokeTestsRoot, 'Consumption', 'bin')) -Filter 'Consumption.exe' -Recurse | + Where-Object { $Runtime -ne 'NativeAot' -or $_.FullName -match '\\publish\\' } | + Sort-Object LastWriteTime -Descending | + Select-Object -First 1 + + if ($null -eq $consumptionExe) { + throw "Could not find the built 'Consumption.exe'." + } + + Write-Host "Running '$($consumptionExe.FullName)'" -ForegroundColor DarkGray + & $consumptionExe.FullName + if ($LASTEXITCODE -ne 0) { + throw "Consumption smoke test crashed or failed with exit code $LASTEXITCODE." + } +} + +# Authoring: build and verify the generated Windows Runtime metadata (CoreCLR), or just verify the +# component publishes cleanly with Native AOT (we don't load the published output). +function Invoke-AuthoringSmokeTest { + Write-Host "`n=== Authoring smoke test ($Runtime) ===" -ForegroundColor Green + + if ($Runtime -eq 'NativeAot') { + Invoke-Dotnet (@('publish', $authoringProject, '--runtime', $nativeAotRid, '-p:PublishAot=true') + $commonBuildArgs) + return + } + + Invoke-Dotnet (@('build', $authoringProject) + $commonBuildArgs) + + # The authoring build emits a '.winmd' next to the component assembly. Verify it was produced + # and that it defines the expected Windows Runtime type. + $authoringWinMD = Get-ChildItem -Path ([IO.Path]::Combine($smokeTestsRoot, 'Authoring', 'bin')) -Filter 'Authoring.winmd' -Recurse -ErrorAction SilentlyContinue | + Sort-Object LastWriteTime -Descending | + Select-Object -First 1 + + if ($null -eq $authoringWinMD) { + throw "The authoring build did not produce 'Authoring.winmd'." + } + + Assert-WinMDDefinesType -Path $authoringWinMD.FullName -Namespace 'Authoring' -TypeName 'Greeter' +} + +# Projection: build a reference projection for a third-party component's '.winmd' (CoreCLR only). This +# is a build-time artifact, so there is nothing to publish with Native AOT. +function Invoke-ProjectionSmokeTest { + Write-Host "`n=== Projection smoke test ($Runtime) ===" -ForegroundColor Green + + Invoke-ReferenceProjectionSmokeTest -Name 'Projection' -Project $projectionProject +} + +# Windows SDK projection: build the base Windows SDK reference projection, exactly as the +# 'Microsoft.Windows.SDK.NET.Ref' projection package is produced (CoreCLR only; build-time artifact). +function Invoke-WindowsSdkProjectionSmokeTest { + Write-Host "`n=== Windows SDK projection smoke test ($Runtime) ===" -ForegroundColor Green + + Invoke-ReferenceProjectionSmokeTest -Name 'WindowsSdkProjection' -Project $windowsSdkProjectionProject +} + +# Windows SDK XAML projection: build the 'Windows.UI.Xaml' reference projection (which references the +# base Windows SDK reference projection above), exactly as the UWP XAML projection package is produced +# (CoreCLR only; build-time artifact). +function Invoke-WindowsSdkXamlProjectionSmokeTest { + Write-Host "`n=== Windows SDK XAML projection smoke test ($Runtime) ===" -ForegroundColor Green + + Invoke-ReferenceProjectionSmokeTest -Name 'WindowsSdkXamlProjection' -Project $windowsSdkXamlProjectionProject +} + +# Shared implementation for the reference-projection smoke tests. Building a reference projection produces +# a forwarder assembly (from 'cswinrtimplgen') next to a 'ref' reference assembly (compiled from the +# 'cswinrtprojectionrefgen' sources). Verifying both were produced confirms the package wired up and ran +# both generators correctly, and that the generated reference projection compiled against the packaged +# 'WinRT.Runtime' reference assembly. A reference projection is a build-time artifact, so there is nothing +# to publish with Native AOT and these tests run on CoreCLR only. +function Invoke-ReferenceProjectionSmokeTest { + param ( + [Parameter(Mandatory = $true)] [string] $Name, + [Parameter(Mandatory = $true)] [string] $Project + ) + + if ($Runtime -eq 'NativeAot') { + Write-Host "Skipping the $Name smoke test for Native AOT (a reference projection is a build-time artifact)." -ForegroundColor DarkGray + return + } + + Invoke-Dotnet (@('build', $Project) + $commonBuildArgs) + + $projectDirectory = [IO.Path]::GetDirectoryName($Project) + $assemblies = Get-ChildItem -Path ([IO.Path]::Combine($projectDirectory, 'bin')) -Filter "$Name.dll" -Recurse -ErrorAction SilentlyContinue + + $forwarder = $assemblies | Where-Object { $_.FullName -notmatch '\\ref\\' } | Select-Object -First 1 + $referenceAssembly = $assemblies | Where-Object { $_.FullName -match '\\ref\\' } | Select-Object -First 1 + + if ($null -eq $forwarder) { + throw "The $Name build did not produce the '$Name.dll' forwarder assembly." + } + + if ($null -eq $referenceAssembly) { + throw "The $Name build did not produce the 'ref\$Name.dll' reference assembly." + } + + Write-Host "Verified the $Name projection produced both a forwarder and a reference assembly." -ForegroundColor DarkGray +} + +if ($Test -in @('All', 'Consumption')) { + Invoke-ConsumptionSmokeTest +} + +if ($Test -in @('All', 'Authoring')) { + Invoke-AuthoringSmokeTest +} + +if ($Test -in @('All', 'Projection')) { + Invoke-ProjectionSmokeTest +} + +if ($Test -in @('All', 'WindowsSdkProjection')) { + Invoke-WindowsSdkProjectionSmokeTest +} + +if ($Test -in @('All', 'WindowsSdkXamlProjection')) { + Invoke-WindowsSdkXamlProjectionSmokeTest +} + +Write-Host "`nSmoke tests passed." -ForegroundColor Green diff --git a/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.ICommand.cs b/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.ICommand.cs index 90a94dbee9..0b1ea36bef 100644 --- a/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.ICommand.cs +++ b/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.ICommand.cs @@ -37,7 +37,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(interfaceType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(interfaceType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(interfaceType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { diff --git a/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.INotifyCollectionChanged.cs b/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.INotifyCollectionChanged.cs index b023b0b4da..d3274eae85 100644 --- a/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.INotifyCollectionChanged.cs +++ b/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.INotifyCollectionChanged.cs @@ -37,7 +37,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(interfaceType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(interfaceType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(interfaceType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { diff --git a/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.INotifyPropertyChanged.cs b/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.INotifyPropertyChanged.cs index aa5f3d6320..d875da4620 100644 --- a/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.INotifyPropertyChanged.cs +++ b/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.INotifyPropertyChanged.cs @@ -37,7 +37,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(interfaceType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(interfaceType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(interfaceType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { diff --git a/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.cs b/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.cs index f8a752bfcc..e93ecaa7b8 100644 --- a/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.cs +++ b/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.cs @@ -38,6 +38,7 @@ public static void AssemblyAttributes( windowsUIXamlMetadata: "Windows.Foundation.UniversalApiContract", microsoftUIXamlMetadata: "Microsoft.UI.Xaml.WinUIContract", trimTarget: interopReferences.IEnumerable.ToReferenceTypeSignature(), + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -47,6 +48,7 @@ public static void AssemblyAttributes( windowsUIXamlMetadata: "Windows.Foundation.UniversalApiContract", microsoftUIXamlMetadata: "Microsoft.UI.Xaml.WinUIContract", trimTarget: interopReferences.IEnumerator.ToReferenceTypeSignature(), + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -56,6 +58,7 @@ public static void AssemblyAttributes( windowsUIXamlMetadata: "Windows.Foundation.UniversalApiContract", microsoftUIXamlMetadata: "Microsoft.UI.Xaml.WinUIContract", trimTarget: interopReferences.IList.ToReferenceTypeSignature(), + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -83,6 +86,7 @@ public static void AssemblyAttributes( windowsUIXamlMetadata: "Windows.Foundation.UniversalApiContract", microsoftUIXamlMetadata: "Microsoft.UI.Xaml.WinUIContract", trimTarget: interopReferences.NotifyCollectionChangedEventArgs.ToReferenceTypeSignature(), + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections); @@ -91,6 +95,7 @@ public static void AssemblyAttributes( windowsUIXamlMetadata: "Windows.Foundation.UniversalApiContract", microsoftUIXamlMetadata: "Microsoft.UI.Xaml.WinUIContract", trimTarget: interopReferences.PropertyChangedEventArgs.ToReferenceTypeSignature(), + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections); @@ -99,6 +104,7 @@ public static void AssemblyAttributes( windowsUIXamlMetadata: "Windows.Foundation.UniversalApiContract", microsoftUIXamlMetadata: "Microsoft.UI.Xaml.WinUIContract", trimTarget: interopReferences.NotifyCollectionChangedEventHandler.ToReferenceTypeSignature(), + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections); @@ -107,6 +113,7 @@ public static void AssemblyAttributes( windowsUIXamlMetadata: "Windows.Foundation.UniversalApiContract", microsoftUIXamlMetadata: "Microsoft.UI.Xaml.WinUIContract", trimTarget: interopReferences.PropertyChangedEventHandler.ToReferenceTypeSignature(), + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections); @@ -115,11 +122,13 @@ public static void AssemblyAttributes( windowsUIXamlMetadata: "Windows.Foundation.UniversalApiContract", microsoftUIXamlMetadata: "Microsoft.UI.Xaml.WinUIContract", trimTarget: interopReferences.NotifyCollectionChangedAction.ToValueTypeSignature(), + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections); IBindableVectorViewType( + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections); @@ -131,6 +140,7 @@ public static void AssemblyAttributes( /// The metadata name for Windows.UI.Xaml. /// The metadata name for Microsoft.UI.Xaml. /// + /// The instance to use. /// The instance to use. /// The module that the attribute will be used from. /// Whether to use Windows.UI.Xaml projections. @@ -139,6 +149,7 @@ private static void InterfaceType( string windowsUIXamlMetadata, string microsoftUIXamlMetadata, TypeSignature trimTarget, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -157,7 +168,7 @@ private static void InterfaceType( // that is used, we can't define this proxy type in advance even if the interface type itself is not generic. InteropTypeDefinitionBuilder.Proxy( ns: InteropUtf8NameFactory.TypeNamespace(trimTarget, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(trimTarget, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(trimTarget, interopDefinitions), mappedMetadata: metadata, runtimeClassName: null, metadataTypeName: MetadataTypeNameGenerator.GetMetadataTypeName(trimTarget, useWindowsUIXamlProjections), @@ -209,7 +220,7 @@ private static void ICommandInterfaceType( // Define the proxy type for the 'ICommand' interface type (it needs a dynamic one, same as the other interface types above) InteropTypeDefinitionBuilder.Proxy( ns: InteropUtf8NameFactory.TypeNamespace(trimTarget, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(trimTarget, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(trimTarget, interopDefinitions), mappedMetadata: metadata, runtimeClassName: null, metadataTypeName: MetadataTypeNameGenerator.GetMetadataTypeName(trimTarget, useWindowsUIXamlProjections), @@ -266,7 +277,7 @@ private static void INotifyCollectionChangedInterfaceType( // Define the proxy type for the 'INotifyCollectionChanged' interface type InteropTypeDefinitionBuilder.Proxy( ns: InteropUtf8NameFactory.TypeNamespace(trimTarget, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(trimTarget, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(trimTarget, interopDefinitions), mappedMetadata: metadata, runtimeClassName: null, metadataTypeName: MetadataTypeNameGenerator.GetMetadataTypeName(trimTarget, useWindowsUIXamlProjections), @@ -323,7 +334,7 @@ private static void INotifyPropertyChangedInterfaceType( // Define the proxy type for the 'INotifyPropertyChanged' interface type InteropTypeDefinitionBuilder.Proxy( ns: InteropUtf8NameFactory.TypeNamespace(trimTarget, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(trimTarget, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(trimTarget, interopDefinitions), mappedMetadata: metadata, runtimeClassName: null, metadataTypeName: MetadataTypeNameGenerator.GetMetadataTypeName(trimTarget, useWindowsUIXamlProjections), @@ -364,6 +375,7 @@ private static void INotifyPropertyChangedInterfaceType( /// The metadata name for Windows.UI.Xaml. /// The metadata name for Microsoft.UI.Xaml. /// + /// The instance to use. /// The instance to use. /// The module that the attribute will be used from. /// Whether to use Windows.UI.Xaml projections. @@ -371,6 +383,7 @@ private static void ClassType( string windowsUIXamlMetadata, string microsoftUIXamlMetadata, TypeSignature trimTarget, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections) @@ -382,7 +395,7 @@ private static void ClassType( // able to do lookups correctly (this attribute will be used, since the input type is a normal class type). InteropTypeDefinitionBuilder.Proxy( ns: InteropUtf8NameFactory.TypeNamespace(trimTarget, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(trimTarget, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(trimTarget, interopDefinitions), mappedMetadata: metadata, runtimeClassName: RuntimeClassNameGenerator.GetRuntimeClassName(trimTarget, interopReferences.RuntimeContext, useWindowsUIXamlProjections), metadataTypeName: null, @@ -417,6 +430,7 @@ private static void ClassType( /// The metadata name for Windows.UI.Xaml. /// The metadata name for Microsoft.UI.Xaml. /// + /// The instance to use. /// The instance to use. /// The module that the attribute will be used from. /// Whether to use Windows.UI.Xaml projections. @@ -424,6 +438,7 @@ private static void DelegateType( string windowsUIXamlMetadata, string microsoftUIXamlMetadata, TypeSignature trimTarget, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections) @@ -434,7 +449,7 @@ private static void DelegateType( // metadata type name is not fixed. This type can be instantiated and boxed, so we need both possible names. InteropTypeDefinitionBuilder.Proxy( ns: InteropUtf8NameFactory.TypeNamespace(trimTarget, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(trimTarget, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(trimTarget, interopDefinitions), mappedMetadata: metadata, runtimeClassName: RuntimeClassNameGenerator.GetRuntimeClassName(trimTarget, interopReferences.RuntimeContext, useWindowsUIXamlProjections), metadataTypeName: MetadataTypeNameGenerator.GetMetadataTypeName(trimTarget, useWindowsUIXamlProjections), @@ -467,6 +482,7 @@ private static void DelegateType( /// The metadata name for Windows.UI.Xaml. /// The metadata name for Microsoft.UI.Xaml. /// + /// The instance to use. /// The instance to use. /// The module that the attribute will be used from. /// Whether to use Windows.UI.Xaml projections. @@ -474,6 +490,7 @@ private static void ValueType( string windowsUIXamlMetadata, string microsoftUIXamlMetadata, TypeSignature trimTarget, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections) @@ -484,7 +501,7 @@ private static void ValueType( // metadata type name, as above, but we also need to reference the boxed type instantiation for this type. InteropTypeDefinitionBuilder.Proxy( ns: InteropUtf8NameFactory.TypeNamespace(trimTarget, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(trimTarget, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(trimTarget, interopDefinitions), mappedMetadata: metadata, runtimeClassName: RuntimeClassNameGenerator.GetRuntimeClassName(trimTarget, interopReferences.RuntimeContext, useWindowsUIXamlProjections), metadataTypeName: MetadataTypeNameGenerator.GetMetadataTypeName(trimTarget, useWindowsUIXamlProjections), @@ -514,10 +531,12 @@ private static void ValueType( /// /// Creates a new custom attribute value for for IBindableVectorView. /// + /// The instance to use. /// The instance to use. /// The module that the attribute will be used from. /// Whether to use Windows.UI.Xaml projections. private static void IBindableVectorViewType( + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections) @@ -533,7 +552,7 @@ private static void IBindableVectorViewType( // a proxy type for it, with the correct runtime class name, and an entry just in the marshalling proxy type map. InteropTypeDefinitionBuilder.Proxy( ns: InteropUtf8NameFactory.TypeNamespace(adapterType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(adapterType, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(adapterType, interopDefinitions), mappedMetadata: null, runtimeClassName: runtimeClassName, metadataTypeName: null, @@ -646,4 +665,4 @@ private static TypeDefinition GetMethodsType(TypeSignature type, InteropReferenc return methodsType; } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.Delegate.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.Delegate.cs index ffc5895aaa..aec8b8286b 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.Delegate.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.Delegate.cs @@ -42,7 +42,7 @@ public static void IIDs( { // 'IDelegate' IID IID( - name: InteropUtf8NameFactory.TypeName(delegateType, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(delegateType, interopDefinitions), interopDefinitions: interopDefinitions, interopReferences: interopReferences, iid: GuidGenerator.CreateIID(delegateType, interopDefinitions, interopReferences, useWindowsUIXamlProjections), @@ -55,7 +55,7 @@ public static void IIDs( // scenario. This is different than boxed value type, which instead are // just always projected as and using 'Nullable' to represent this. IID( - name: InteropUtf8NameFactory.TypeName(delegateType, interopReferences.RuntimeContext, "Reference"), + name: InteropUtf8NameFactory.TypeName(delegateType, interopDefinitions, "Reference"), interopDefinitions: interopDefinitions, interopReferences: interopReferences, iid: GuidGenerator.CreateIID(delegateType.MakeBoxedType(), interopDefinitions, interopReferences, useWindowsUIXamlProjections), @@ -104,7 +104,7 @@ public static void Vftbl( { vftblType = WellKnownTypeDefinitionFactory.DelegateVftbl( ns: InteropUtf8NameFactory.TypeNamespace(delegateType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(delegateType, interopReferences.RuntimeContext, "Vftbl"), + name: InteropUtf8NameFactory.TypeName(delegateType, interopDefinitions, "Vftbl"), senderType: senderType.GetAbiType(interopReferences), argsType: argsType.GetAbiType(interopReferences), interopReferences: interopReferences); @@ -120,6 +120,7 @@ static void GetOrCreateVftbl( TypeSignature argsType, TypeSignature displaySenderType, TypeSignature displayArgsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -139,7 +140,7 @@ static void GetOrCreateVftbl( // Construct a new specialized vtable type TypeDefinition newVftblType = WellKnownTypeDefinitionFactory.DelegateVftbl( ns: InteropUtf8NameFactory.TypeNamespace(sharedEventHandlerType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(sharedEventHandlerType, interopReferences.RuntimeContext, "Vftbl"), + name: InteropUtf8NameFactory.TypeName(sharedEventHandlerType, interopDefinitions, "Vftbl"), senderType: senderType, argsType: argsType, interopReferences: interopReferences); @@ -162,6 +163,7 @@ static void GetOrCreateVftbl( argsType: argsType.GetAbiType(interopReferences), displaySenderType: interopReferences.Object, displayArgsType: argsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -174,6 +176,7 @@ static void GetOrCreateVftbl( argsType: interopReferences.Void.MakePointerType(), displaySenderType: senderType, displayArgsType: interopReferences.Object, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -288,7 +291,7 @@ public static void ImplType( Impl( interfaceType: ComInterfaceType.InterfaceIsIUnknown, ns: InteropUtf8NameFactory.TypeNamespace(delegateType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(delegateType, interopReferences.RuntimeContext, "Impl"), + name: InteropUtf8NameFactory.TypeName(delegateType, interopDefinitions, "Impl"), vftblType: vftblType, interopDefinitions: interopDefinitions, interopReferences: interopReferences, @@ -396,7 +399,7 @@ public static void ReferenceImplType( Impl( interfaceType: ComInterfaceType.InterfaceIsIInspectable, ns: InteropUtf8NameFactory.TypeNamespace(delegateType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(delegateType, interopReferences.RuntimeContext, "ReferenceImpl"), + name: InteropUtf8NameFactory.TypeName(delegateType, interopDefinitions, "ReferenceImpl"), vftblType: interopDefinitions.DelegateReferenceVftbl, interopDefinitions: interopDefinitions, interopReferences: interopReferences, @@ -430,7 +433,7 @@ public static void InterfaceEntriesImpl( { InteropTypeDefinitionBuilder.InterfaceEntriesImpl( ns: InteropUtf8NameFactory.TypeNamespace(delegateType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(delegateType, interopReferences.RuntimeContext, "InterfaceEntriesImpl"), + name: InteropUtf8NameFactory.TypeName(delegateType, interopDefinitions, "InterfaceEntriesImpl"), entriesFieldType: interopDefinitions.DelegateInterfaceEntries, interopReferences: interopReferences, module: module, @@ -453,6 +456,7 @@ public static void InterfaceEntriesImpl( /// The for the type. /// The type returned by . /// The 'IID' get method for the 'IDelegate' interface. + /// The instance to use. /// The instance to use. /// The interop module being built. /// The resulting callback type. @@ -460,6 +464,7 @@ public static void ComWrappersCallbackType( TypeSignature delegateType, TypeDefinition nativeDelegateType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition callbackType) @@ -467,7 +472,7 @@ public static void ComWrappersCallbackType( // We're declaring an 'internal abstract class' type callbackType = new( ns: InteropUtf8NameFactory.TypeNamespace(delegateType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(delegateType, interopReferences.RuntimeContext, "ComWrappersCallback"), + name: InteropUtf8NameFactory.TypeName(delegateType, interopDefinitions, "ComWrappersCallback"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -538,7 +543,7 @@ public static void NativeDelegateType( // We're declaring an 'internal static class' type nativeDelegateType = new( ns: InteropUtf8NameFactory.TypeNamespace(delegateType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(delegateType, interopReferences.RuntimeContext, "NativeDelegate"), + name: InteropUtf8NameFactory.TypeName(delegateType, interopDefinitions, "NativeDelegate"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()); @@ -685,7 +690,7 @@ public static void ComWrappersMarshallerAttribute( // We're declaring an 'internal sealed class' type marshallerType = new( ns: InteropUtf8NameFactory.TypeNamespace(delegateType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(delegateType, interopReferences.RuntimeContext, "ComWrappersMarshallerAttribute"), + name: InteropUtf8NameFactory.TypeName(delegateType, interopDefinitions, "ComWrappersMarshallerAttribute"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, baseType: interopReferences.WindowsRuntimeComWrappersMarshallerAttribute); @@ -785,6 +790,7 @@ public static void ComWrappersMarshallerAttribute( /// The instance returned by . /// The 'IID' get method for the 'IDelegate' interface. /// The resulting 'IID' get method for the boxed 'IDelegate' interface. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The module that will contain the type being created. @@ -794,6 +800,7 @@ public static void Marshaller( TypeDefinition delegateComWrappersCallbackType, MethodDefinition get_IidMethod, MethodDefinition get_ReferenceIidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -802,7 +809,7 @@ public static void Marshaller( // We're declaring an 'internal static class' type marshallerType = new( ns: InteropUtf8NameFactory.TypeNamespace(delegateType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(delegateType, interopReferences.RuntimeContext, "Marshaller"), + name: InteropUtf8NameFactory.TypeName(delegateType, interopDefinitions, "Marshaller"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()); @@ -913,6 +920,7 @@ public static void Marshaller( /// /// The for the type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// Whether to use Windows.UI.Xaml projections. @@ -920,6 +928,7 @@ public static void Marshaller( public static void Proxy( TypeSignature delegateType, TypeDefinition comWrappersMarshallerAttributeType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -930,7 +939,7 @@ public static void Proxy( // '[WindowsRuntimeMetadataTypeName]', as that's different than the runtime class name (which uses 'IReference'). InteropTypeDefinitionBuilder.Proxy( ns: InteropUtf8NameFactory.TypeNamespace(delegateType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(delegateType, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(delegateType, interopDefinitions), mappedMetadata: "Windows.Foundation.FoundationContract", runtimeClassName: RuntimeClassNameGenerator.GetRuntimeClassName(delegateType, interopReferences.RuntimeContext, useWindowsUIXamlProjections), metadataTypeName: MetadataTypeNameGenerator.GetMetadataTypeName(delegateType, useWindowsUIXamlProjections), @@ -946,7 +955,7 @@ public static void Proxy( /// Creates the type map attributes for some type. /// /// The for the type. - /// The instance returned by . + /// The instance returned by . /// The instance to use. /// The module that will contain the type being created. /// Whether to use Windows.UI.Xaml projections. @@ -975,4 +984,4 @@ public static void TypeMapAttributes( module: module); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.EventSource.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.EventSource.cs index 4caf22e65b..dbcec17d58 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.EventSource.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.EventSource.cs @@ -24,12 +24,14 @@ public static class EventSource /// /// The for the type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting event source type. public static void EventHandler1( GenericInstanceTypeSignature delegateType, TypeDefinition marshallerType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition eventSourceType) @@ -41,6 +43,7 @@ public static void EventHandler1( baseEventSourceType: interopReferences.EventHandler1EventSource, baseEventSource_ctor: interopReferences.EventHandler1EventSource_ctor(eventArgsType), marshallerType: marshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, eventSourceType: out eventSourceType); @@ -51,12 +54,14 @@ public static void EventHandler1( /// /// The for the type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting event source type. public static void EventHandler2( GenericInstanceTypeSignature delegateType, TypeDefinition marshallerType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition eventSourceType) @@ -69,6 +74,7 @@ public static void EventHandler2( baseEventSourceType: interopReferences.EventHandler2EventSource, baseEventSource_ctor: interopReferences.EventHandler2EventSource_ctor(senderType, eventArgsType), marshallerType: marshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, eventSourceType: out eventSourceType); @@ -79,6 +85,7 @@ public static void EventHandler2( /// /// The for the delegate type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The module that will contain the type being created. @@ -86,6 +93,7 @@ public static void EventHandler2( public static void VectorChangedEventHandler1( GenericInstanceTypeSignature delegateType, TypeDefinition marshallerType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -98,6 +106,7 @@ public static void VectorChangedEventHandler1( baseEventSourceType: interopReferences.VectorChangedEventHandler1EventSource, baseEventSource_ctor: interopReferences.VectorChangedEventHandler1EventSource_ctor(elementType), marshallerType: marshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, eventSourceType: out eventSourceType); @@ -111,6 +120,7 @@ public static void VectorChangedEventHandler1( /// /// The for the delegate type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The module that will contain the type being created. @@ -118,6 +128,7 @@ public static void VectorChangedEventHandler1( public static void MapChangedEventHandler2( GenericInstanceTypeSignature delegateType, TypeDefinition marshallerType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -131,6 +142,7 @@ public static void MapChangedEventHandler2( baseEventSourceType: interopReferences.MapChangedEventHandler2EventSource, baseEventSource_ctor: interopReferences.MapChangedEventHandler2EventSource_ctor(keyType, valueType), marshallerType: marshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, eventSourceType: out eventSourceType); @@ -146,6 +158,7 @@ public static void MapChangedEventHandler2( /// The for the base event source type. /// The for the constructor of the base event source type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting event source type. @@ -154,6 +167,7 @@ private static void DerivedEventSource( TypeReference baseEventSourceType, MemberReference baseEventSource_ctor, TypeDefinition marshallerType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition eventSourceType) @@ -163,7 +177,7 @@ private static void DerivedEventSource( // We're declaring an 'internal sealed class' type eventSourceType = new( ns: "ABI.WindowsRuntime.InteropServices"u8, - name: InteropUtf8NameFactory.TypeName(baseEventSourceSignature, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(baseEventSourceSignature, interopDefinitions), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, baseType: baseEventSourceSignature.ToTypeDefOrRef()); @@ -207,4 +221,4 @@ private static void DerivedEventSource( eventSourceType.Methods.Add(convertToUnmanagedMethod); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IAsyncActionWithProgress1.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IAsyncActionWithProgress1.cs index 95b61f0379..4839e06e79 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IAsyncActionWithProgress1.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IAsyncActionWithProgress1.cs @@ -43,7 +43,7 @@ public static void Methods( // We're declaring an 'internal abstract class' type actionMethodsType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(actionType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(actionType, interopReferences.RuntimeContext, "Methods"), + name: InteropUtf8NameFactory.TypeName(actionType, interopDefinitions, "Methods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -148,12 +148,14 @@ public static void Methods( /// /// The for the async action type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The interop module being built. /// The resulting native object type. public static void NativeObject( GenericInstanceTypeSignature actionType, TypeDefinition actionMethodsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition nativeObjectType) @@ -166,6 +168,7 @@ public static void NativeObject( InteropTypeDefinitionBuilder.NativeObject( typeSignature: actionType, nativeObjectBaseType: windowsRuntimeAsyncActionWithProgress1Type, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out nativeObjectType); @@ -177,6 +180,7 @@ public static void NativeObject( /// The for the async action type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The interop module being built. /// Whether to use Windows.UI.Xaml projections. @@ -185,6 +189,7 @@ public static void ComWrappersCallbackType( TypeSignature actionType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -195,6 +200,7 @@ public static void ComWrappersCallbackType( typeSignature: actionType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out callbackType); @@ -206,6 +212,7 @@ public static void ComWrappersCallbackType( /// The for the async action type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. @@ -213,6 +220,7 @@ public static void ComWrappersMarshallerAttribute( GenericInstanceTypeSignature actionType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition marshallerType) @@ -221,6 +229,7 @@ public static void ComWrappersMarshallerAttribute( typeSignature: actionType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out marshallerType); @@ -250,7 +259,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(actionType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(actionType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(actionType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { @@ -473,7 +482,7 @@ public static void ImplType( Impl( interfaceType: ComInterfaceType.InterfaceIsIInspectable, ns: InteropUtf8NameFactory.TypeNamespace(actionType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(actionType, interopReferences.RuntimeContext, "Impl"), + name: InteropUtf8NameFactory.TypeName(actionType, interopDefinitions, "Impl"), vftblType: interopDefinitions.IAsyncActionWithProgressVftbl, interopDefinitions: interopDefinitions, interopReferences: interopReferences, @@ -490,4 +499,4 @@ public static void ImplType( emitState.TrackTypeDefinition(implType, actionType, "Impl"); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IAsyncOperation1.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IAsyncOperation1.cs index 53b10c7b92..6712afce90 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IAsyncOperation1.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IAsyncOperation1.cs @@ -42,7 +42,7 @@ public static void Methods( // We're declaring an 'internal abstract class' type operationMethodsType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(operationType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(operationType, interopReferences.RuntimeContext, "Methods"), + name: InteropUtf8NameFactory.TypeName(operationType, interopDefinitions, "Methods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -102,12 +102,14 @@ public static void Methods( /// /// The for the async operation type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The interop module being built. /// The resulting native object type. public static void NativeObject( GenericInstanceTypeSignature operationType, TypeDefinition operationMethodsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition nativeObjectType) @@ -120,6 +122,7 @@ public static void NativeObject( InteropTypeDefinitionBuilder.NativeObject( typeSignature: operationType, nativeObjectBaseType: windowsRuntimeAsyncOperation1Type, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out nativeObjectType); @@ -131,6 +134,7 @@ public static void NativeObject( /// The for the async operation type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The interop module being built. /// Whether to use Windows.UI.Xaml projections. @@ -139,6 +143,7 @@ public static void ComWrappersCallbackType( TypeSignature operationType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -149,6 +154,7 @@ public static void ComWrappersCallbackType( typeSignature: operationType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out callbackType); @@ -160,6 +166,7 @@ public static void ComWrappersCallbackType( /// The for the async operation type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. @@ -167,6 +174,7 @@ public static void ComWrappersMarshallerAttribute( GenericInstanceTypeSignature operationType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition marshallerType) @@ -175,6 +183,7 @@ public static void ComWrappersMarshallerAttribute( typeSignature: operationType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out marshallerType); @@ -204,7 +213,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(operationType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(operationType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(operationType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { @@ -349,7 +358,7 @@ public static void ImplType( Impl( interfaceType: ComInterfaceType.InterfaceIsIInspectable, ns: InteropUtf8NameFactory.TypeNamespace(operationType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(operationType, interopReferences.RuntimeContext, "Impl"), + name: InteropUtf8NameFactory.TypeName(operationType, interopDefinitions, "Impl"), vftblType: interopDefinitions.IAsyncOperationVftbl, interopDefinitions: interopDefinitions, interopReferences: interopReferences, @@ -364,4 +373,4 @@ public static void ImplType( emitState.TrackTypeDefinition(implType, operationType, "Impl"); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IAsyncOperationWithProgress2.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IAsyncOperationWithProgress2.cs index 74cb522378..d9096570a3 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IAsyncOperationWithProgress2.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IAsyncOperationWithProgress2.cs @@ -43,7 +43,7 @@ public static void Methods( // We're declaring an 'internal abstract class' type operationMethodsType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(operationType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(operationType, interopReferences.RuntimeContext, "Methods"), + name: InteropUtf8NameFactory.TypeName(operationType, interopDefinitions, "Methods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -141,12 +141,14 @@ public static void Methods( /// /// The for the async operation type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The interop module being built. /// The resulting native object type. public static void NativeObject( GenericInstanceTypeSignature operationType, TypeDefinition operationMethodsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition nativeObjectType) @@ -160,6 +162,7 @@ public static void NativeObject( InteropTypeDefinitionBuilder.NativeObject( typeSignature: operationType, nativeObjectBaseType: windowsRuntimeAsyncOperationWithProgress2Type, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out nativeObjectType); @@ -171,6 +174,7 @@ public static void NativeObject( /// The for the async operation type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The interop module being built. /// Whether to use Windows.UI.Xaml projections. @@ -179,6 +183,7 @@ public static void ComWrappersCallbackType( TypeSignature operationType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -189,6 +194,7 @@ public static void ComWrappersCallbackType( typeSignature: operationType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out callbackType); @@ -200,6 +206,7 @@ public static void ComWrappersCallbackType( /// The for the async operation type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. @@ -207,6 +214,7 @@ public static void ComWrappersMarshallerAttribute( GenericInstanceTypeSignature operationType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition marshallerType) @@ -215,6 +223,7 @@ public static void ComWrappersMarshallerAttribute( typeSignature: operationType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out marshallerType); @@ -245,7 +254,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(operationType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(operationType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(operationType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { @@ -475,7 +484,7 @@ public static void ImplType( Impl( interfaceType: ComInterfaceType.InterfaceIsIInspectable, ns: InteropUtf8NameFactory.TypeNamespace(operationType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(operationType, interopReferences.RuntimeContext, "Impl"), + name: InteropUtf8NameFactory.TypeName(operationType, interopDefinitions, "Impl"), vftblType: interopDefinitions.IAsyncOperationWithProgressVftbl, interopDefinitions: interopDefinitions, interopReferences: interopReferences, @@ -492,4 +501,4 @@ public static void ImplType( emitState.TrackTypeDefinition(implType, operationType, "Impl"); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.ICollectionKeyValuePair2.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.ICollectionKeyValuePair2.cs index 2e6c816b47..3899658126 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.ICollectionKeyValuePair2.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.ICollectionKeyValuePair2.cs @@ -23,11 +23,13 @@ public static class ICollectionKeyValuePair2 /// Creates a new type definition for the forwarder attribute for a of type. /// /// The for the generic interface type. + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. public static void ForwarderAttribute( GenericInstanceTypeSignature collectionType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition forwarderAttributeType) @@ -40,6 +42,7 @@ public static void ForwarderAttribute( readOnlyCollectionType: collectionType, readOnlyDictionaryType: interopReferences.IDictionary2.MakeGenericReferenceType([keyType, valueType]), readOnlyListType: interopReferences.IList1.MakeGenericReferenceType([keyValuePairType]), + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, forwarderAttributeType: out forwarderAttributeType); @@ -50,6 +53,7 @@ public static void ForwarderAttribute( /// /// The for the generic interface type. /// The type returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The module that will contain the type being created. @@ -57,6 +61,7 @@ public static void ForwarderAttribute( public static void InterfaceImpl( GenericInstanceTypeSignature collectionType, TypeDefinition forwarderAttributeType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -72,7 +77,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(collectionType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(collectionType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(collectionType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { @@ -278,4 +283,4 @@ public static void TypeMapAttributes( module: module); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IDictionary2.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IDictionary2.cs index 220ec2d23a..3576808ec6 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IDictionary2.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IDictionary2.cs @@ -26,6 +26,7 @@ public static class IDictionary2 /// /// The for the type. /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -33,6 +34,7 @@ public static class IDictionary2 public static void Interface( GenericInstanceTypeSignature dictionaryType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -41,7 +43,7 @@ public static void Interface( // We're declaring an 'internal abstract class' type interfaceType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(dictionaryType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(dictionaryType, interopReferences.RuntimeContext, "Interface"), + name: InteropUtf8NameFactory.TypeName(dictionaryType, interopDefinitions, "Interface"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -105,7 +107,7 @@ public static void Vftbl( { vftblType = WellKnownTypeDefinitionFactory.IDictionary2Vftbl( ns: InteropUtf8NameFactory.TypeNamespace(dictionaryType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(dictionaryType, interopReferences.RuntimeContext, "Vftbl"), + name: InteropUtf8NameFactory.TypeName(dictionaryType, interopDefinitions, "Vftbl"), keyType: keyType, valueType: valueType, interopReferences: interopReferences); @@ -121,6 +123,7 @@ static void GetOrCreateVftbl( TypeSignature valueType, TypeSignature displayKeyType, TypeSignature displayValueType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -140,7 +143,7 @@ static void GetOrCreateVftbl( // Construct a new specialized vtable type TypeDefinition newVftblType = WellKnownTypeDefinitionFactory.IDictionary2Vftbl( ns: InteropUtf8NameFactory.TypeNamespace(sharedDictionaryType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(sharedDictionaryType, interopReferences.RuntimeContext, "Vftbl"), + name: InteropUtf8NameFactory.TypeName(sharedDictionaryType, interopDefinitions, "Vftbl"), keyType: keyType, valueType: valueType, interopReferences: interopReferences); @@ -163,6 +166,7 @@ static void GetOrCreateVftbl( valueType: valueType, displayKeyType: interopReferences.Object, displayValueType: valueType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -175,6 +179,7 @@ static void GetOrCreateVftbl( valueType: interopReferences.Void.MakePointerType(), displayKeyType: keyType, displayValueType: interopReferences.Object, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -187,6 +192,7 @@ static void GetOrCreateVftbl( /// /// The for the type. /// The type returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -194,6 +200,7 @@ static void GetOrCreateVftbl( public static void IMapMethods( GenericInstanceTypeSignature dictionaryType, TypeDefinition vftblType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -205,7 +212,7 @@ public static void IMapMethods( // We're declaring an 'internal abstract class' type mapMethodsType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(dictionaryType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(dictionaryType, interopReferences.RuntimeContext, "IMapMethods"), + name: InteropUtf8NameFactory.TypeName(dictionaryType, interopDefinitions, "IMapMethods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -271,6 +278,7 @@ public static void IMapMethods( /// /// The for the type. /// The type returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -278,6 +286,7 @@ public static void IMapMethods( public static void Methods( GenericInstanceTypeSignature dictionaryType, TypeDefinition mapMethodsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -289,7 +298,7 @@ public static void Methods( // We're declaring an 'internal static class' type dictionaryMethodsType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(dictionaryType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(dictionaryType, interopReferences.RuntimeContext, "Methods"), + name: InteropUtf8NameFactory.TypeName(dictionaryType, interopDefinitions, "Methods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()); @@ -639,6 +648,7 @@ public static void Methods( /// /// The for the type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -646,6 +656,7 @@ public static void Methods( public static void NativeObject( GenericInstanceTypeSignature dictionaryType, TypeDefinition mapMethodsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -667,6 +678,7 @@ public static void NativeObject( InteropTypeDefinitionBuilder.NativeObject( typeSignature: dictionaryType, nativeObjectBaseType: windowsRuntimeDictionary5Type, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out nativeObjectType); @@ -678,6 +690,7 @@ public static void NativeObject( /// The for the type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The interop module being built. /// Whether to use Windows.UI.Xaml projections. @@ -686,6 +699,7 @@ public static void ComWrappersCallbackType( TypeSignature dictionaryType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -696,6 +710,7 @@ public static void ComWrappersCallbackType( typeSignature: dictionaryType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out callbackType); @@ -707,6 +722,7 @@ public static void ComWrappersCallbackType( /// The for the type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. @@ -714,6 +730,7 @@ public static void ComWrappersMarshallerAttribute( GenericInstanceTypeSignature dictionaryType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition marshallerType) @@ -722,6 +739,7 @@ public static void ComWrappersMarshallerAttribute( typeSignature: dictionaryType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out marshallerType); @@ -755,7 +773,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(dictionaryType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(dictionaryType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(dictionaryType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { @@ -1039,7 +1057,7 @@ public static void ImplType( Impl( interfaceType: ComInterfaceType.InterfaceIsIInspectable, ns: InteropUtf8NameFactory.TypeNamespace(dictionaryType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(dictionaryType, interopReferences.RuntimeContext, "Impl"), + name: InteropUtf8NameFactory.TypeName(dictionaryType, interopDefinitions, "Impl"), vftblType: vftblType, interopDefinitions: interopDefinitions, interopReferences: interopReferences, @@ -1058,4 +1076,4 @@ public static void ImplType( emitState.TrackTypeDefinition(implType, dictionaryType, "Impl"); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IEnumerable1.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IEnumerable1.cs index c2b66936d7..c20a92fb8c 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IEnumerable1.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IEnumerable1.cs @@ -28,6 +28,7 @@ public static class IEnumerable1 /// /// The for the type. /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -35,6 +36,7 @@ public static class IEnumerable1 public static void Interface( GenericInstanceTypeSignature enumerableType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -43,7 +45,7 @@ public static void Interface( // We're declaring an 'internal abstract class' type interfaceType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(enumerableType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(enumerableType, interopReferences.RuntimeContext, "Interface"), + name: InteropUtf8NameFactory.TypeName(enumerableType, interopDefinitions, "Interface"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -92,7 +94,7 @@ public static void IIterableMethods( // We're declaring an 'internal static class' type iterableMethodsType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(enumerableType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(enumerableType, interopReferences.RuntimeContext, "IIterableMethods"), + name: InteropUtf8NameFactory.TypeName(enumerableType, interopDefinitions, "IIterableMethods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -211,12 +213,14 @@ public static void IIterableMethods( /// /// The for the type. /// The type returned by . + /// The instance to use. /// The instance to use. /// The interop module being built. /// The resulting methods type. public static void Methods( GenericInstanceTypeSignature enumerableType, TypeDefinition iterableMethodsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition enumerableMethodsType) @@ -226,7 +230,7 @@ public static void Methods( // We're declaring an 'internal static class' type enumerableMethodsType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(enumerableType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(enumerableType, interopReferences.RuntimeContext, "Methods"), + name: InteropUtf8NameFactory.TypeName(enumerableType, interopDefinitions, "Methods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()); @@ -258,12 +262,14 @@ public static void Methods( /// /// The for the type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The interop module being built. /// The resulting native object type. public static void NativeObject( GenericInstanceTypeSignature enumerableType, TypeDefinition iterableMethodsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition nativeObjectType) @@ -276,6 +282,7 @@ public static void NativeObject( InteropTypeDefinitionBuilder.NativeObject( typeSignature: enumerableType, nativeObjectBaseType: windowsRuntimeEnumerable1Type, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out nativeObjectType); @@ -287,6 +294,7 @@ public static void NativeObject( /// The for the type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The interop module being built. /// Whether to use Windows.UI.Xaml projections. @@ -295,6 +303,7 @@ public static void ComWrappersCallbackType( TypeSignature enumerableType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -305,6 +314,7 @@ public static void ComWrappersCallbackType( typeSignature: enumerableType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out callbackType); @@ -316,6 +326,7 @@ public static void ComWrappersCallbackType( /// The for the type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. @@ -323,6 +334,7 @@ public static void ComWrappersMarshallerAttribute( GenericInstanceTypeSignature enumerableType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition marshallerType) @@ -331,6 +343,7 @@ public static void ComWrappersMarshallerAttribute( typeSignature: enumerableType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out marshallerType); @@ -360,7 +373,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(enumerableType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(enumerableType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(enumerableType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { @@ -445,7 +458,7 @@ public static void ImplType( Impl( interfaceType: ComInterfaceType.InterfaceIsIInspectable, ns: InteropUtf8NameFactory.TypeNamespace(enumerableType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(enumerableType, interopReferences.RuntimeContext, "Impl"), + name: InteropUtf8NameFactory.TypeName(enumerableType, interopDefinitions, "Impl"), vftblType: interopDefinitions.IEnumerable1Vftbl, interopDefinitions: interopDefinitions, interopReferences: interopReferences, @@ -457,4 +470,4 @@ public static void ImplType( emitState.TrackTypeDefinition(implType, enumerableType, "Impl"); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IEnumerator1.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IEnumerator1.cs index f3447076cf..e908cc2876 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IEnumerator1.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IEnumerator1.cs @@ -41,7 +41,7 @@ public static void IID( out MethodDefinition get_IidMethod) { InteropTypeDefinitionBuilder.IID( - name: InteropUtf8NameFactory.TypeName(enumeratorType, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(enumeratorType, interopDefinitions), interopDefinitions: interopDefinitions, interopReferences: interopReferences, iid: GuidGenerator.CreateIID(enumeratorType, interopDefinitions, interopReferences, useWindowsUIXamlProjections), @@ -73,7 +73,7 @@ public static void IIteratorMethods( // We're declaring an 'internal abstract class' type iteratorMethodsType = new( ns: InteropUtf8NameFactory.TypeNamespace(enumeratorType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(enumeratorType, interopReferences.RuntimeContext, "IIteratorMethods"), + name: InteropUtf8NameFactory.TypeName(enumeratorType, interopDefinitions, "IIteratorMethods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -210,12 +210,14 @@ public static void IIteratorMethods( /// /// The for the type. /// The type returned by . + /// The instance to use. /// The instance to use. /// The interop module being built. /// The resulting methods type. public static void Methods( GenericInstanceTypeSignature enumeratorType, TypeDefinition iteratorMethodsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition enumeratorMethodsType) @@ -225,7 +227,7 @@ public static void Methods( // We're declaring an 'internal static class' type enumeratorMethodsType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(enumeratorType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(enumeratorType, interopReferences.RuntimeContext, "Methods"), + name: InteropUtf8NameFactory.TypeName(enumeratorType, interopDefinitions, "Methods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()); @@ -277,12 +279,14 @@ public static void Methods( /// /// The for the type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The interop module being built. /// The resulting native object type. public static void NativeObject( GenericInstanceTypeSignature enumeratorType, TypeDefinition iteratorMethodsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition nativeObjectType) @@ -295,6 +299,7 @@ public static void NativeObject( InteropTypeDefinitionBuilder.NativeObject( typeSignature: enumeratorType, nativeObjectBaseType: windowsRuntimeEnumerator2Type, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out nativeObjectType); @@ -306,6 +311,7 @@ public static void NativeObject( /// The for the type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The interop module being built. /// Whether to use Windows.UI.Xaml projections. @@ -314,6 +320,7 @@ public static void ComWrappersCallbackType( TypeSignature enumeratorType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -324,6 +331,7 @@ public static void ComWrappersCallbackType( typeSignature: enumeratorType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out callbackType); @@ -335,6 +343,7 @@ public static void ComWrappersCallbackType( /// The for the type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. @@ -342,6 +351,7 @@ public static void ComWrappersMarshallerAttribute( GenericInstanceTypeSignature enumeratorType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition marshallerType) @@ -350,6 +360,7 @@ public static void ComWrappersMarshallerAttribute( typeSignature: enumeratorType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out marshallerType); @@ -379,7 +390,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(enumeratorType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(enumeratorType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(enumeratorType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { @@ -529,12 +540,14 @@ public static void InterfaceImpl( /// Creates a new type definition for the element marshaller for some IIterator<T> interface. /// /// The for the type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The module that will contain the type being created. /// The resulting element marshaller type. public static void ElementMarshaller( GenericInstanceTypeSignature enumeratorType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -559,6 +572,7 @@ public static void ElementMarshaller( { elementMarshallerType = InteropTypeDefinitionFactory.IEnumeratorElementMarshaller.KeyValuePair( enumeratorType: enumeratorType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); @@ -568,6 +582,7 @@ public static void ElementMarshaller( { elementMarshallerType = InteropTypeDefinitionFactory.IEnumeratorElementMarshaller.NullableValueType( enumeratorType: enumeratorType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); @@ -577,6 +592,7 @@ public static void ElementMarshaller( { elementMarshallerType = InteropTypeDefinitionFactory.IEnumeratorElementMarshaller.ManagedValueType( enumeratorType: enumeratorType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); @@ -586,6 +602,7 @@ public static void ElementMarshaller( { elementMarshallerType = InteropTypeDefinitionFactory.IEnumeratorElementMarshaller.UnmanagedValueType( enumeratorType: enumeratorType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); @@ -595,6 +612,7 @@ public static void ElementMarshaller( { elementMarshallerType = InteropTypeDefinitionFactory.IEnumeratorElementMarshaller.ReferenceType( enumeratorType: enumeratorType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); @@ -647,7 +665,7 @@ public static void ImplType( Impl( interfaceType: ComInterfaceType.InterfaceIsIInspectable, ns: InteropUtf8NameFactory.TypeNamespace(enumeratorType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(enumeratorType, interopReferences.RuntimeContext, "Impl"), + name: InteropUtf8NameFactory.TypeName(enumeratorType, interopDefinitions, "Impl"), vftblType: interopDefinitions.IEnumerator1Vftbl, interopDefinitions: interopDefinitions, interopReferences: interopReferences, @@ -663,4 +681,4 @@ public static void ImplType( emitState.TrackTypeDefinition(implType, enumeratorType, "Impl"); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IList1.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IList1.cs index 460d4c078a..515977fb58 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IList1.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IList1.cs @@ -27,6 +27,7 @@ public static class IList1 /// /// The for the type. /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -34,6 +35,7 @@ public static class IList1 public static void Interface( GenericInstanceTypeSignature listType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -42,7 +44,7 @@ public static void Interface( // We're declaring an 'internal abstract class' type interfaceType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(listType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(listType, interopReferences.RuntimeContext, "Interface"), + name: InteropUtf8NameFactory.TypeName(listType, interopDefinitions, "Interface"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -97,7 +99,7 @@ public static void Vftbl( // Otherwise, we must construct a new specialized vtable type vftblType = WellKnownTypeDefinitionFactory.IList1Vftbl( ns: InteropUtf8NameFactory.TypeNamespace(listType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(listType, interopReferences.RuntimeContext, "Vftbl"), + name: InteropUtf8NameFactory.TypeName(listType, interopDefinitions, "Vftbl"), elementType: elementType.GetAbiType(interopReferences), interopReferences: interopReferences); @@ -109,6 +111,7 @@ public static void Vftbl( /// /// The for the type. /// The type returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -116,6 +119,7 @@ public static void Vftbl( public static void IVectorMethods( GenericInstanceTypeSignature listType, TypeDefinition vftblType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -126,7 +130,7 @@ public static void IVectorMethods( // We're declaring an 'internal abstract class' type vectorMethodsType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(listType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(listType, interopReferences.RuntimeContext, "IVectorMethods"), + name: InteropUtf8NameFactory.TypeName(listType, interopDefinitions, "IVectorMethods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -204,6 +208,7 @@ public static void IVectorMethods( /// /// The for the type. /// The type returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -211,6 +216,7 @@ public static void IVectorMethods( public static void Methods( GenericInstanceTypeSignature listType, TypeDefinition vectorMethodsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -221,7 +227,7 @@ public static void Methods( // We're declaring an 'internal static class' type listMethodsType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(listType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(listType, interopReferences.RuntimeContext, "Methods"), + name: InteropUtf8NameFactory.TypeName(listType, interopDefinitions, "Methods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()); @@ -522,6 +528,7 @@ public static void Methods( /// /// The for the type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -529,6 +536,7 @@ public static void Methods( public static void NativeObject( GenericInstanceTypeSignature listType, TypeDefinition vectorMethodsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -547,6 +555,7 @@ public static void NativeObject( InteropTypeDefinitionBuilder.NativeObject( typeSignature: listType, nativeObjectBaseType: windowsRuntimeList4Type, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out nativeObjectType); @@ -558,6 +567,7 @@ public static void NativeObject( /// The for the type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The interop module being built. /// Whether to use Windows.UI.Xaml projections. @@ -566,6 +576,7 @@ public static void ComWrappersCallbackType( TypeSignature listType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -576,6 +587,7 @@ public static void ComWrappersCallbackType( typeSignature: listType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out callbackType); @@ -587,6 +599,7 @@ public static void ComWrappersCallbackType( /// The for the type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. @@ -594,6 +607,7 @@ public static void ComWrappersMarshallerAttribute( GenericInstanceTypeSignature listType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition marshallerType) @@ -602,6 +616,7 @@ public static void ComWrappersMarshallerAttribute( typeSignature: listType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out marshallerType); @@ -633,7 +648,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(listType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(listType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(listType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { @@ -1018,7 +1033,7 @@ public static void ImplType( Impl( interfaceType: ComInterfaceType.InterfaceIsIInspectable, ns: InteropUtf8NameFactory.TypeNamespace(listType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(listType, interopReferences.RuntimeContext, "Impl"), + name: InteropUtf8NameFactory.TypeName(listType, interopDefinitions, "Impl"), vftblType: vftblType, interopDefinitions: interopDefinitions, interopReferences: interopReferences, @@ -1046,7 +1061,7 @@ public static void ImplType( /// Creates the type map attributes for some IVector<T> interface. /// /// The for the type. - /// The instance returned by . + /// The instance returned by . /// The instance returned by . /// The instance to use. /// The module that will contain the type being created. @@ -1095,4 +1110,4 @@ public static void TypeMapAttributes( } } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IMapChangedEventArgs1.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IMapChangedEventArgs1.cs index d0c4dc0e0f..9c47f7da1f 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IMapChangedEventArgs1.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IMapChangedEventArgs1.cs @@ -43,7 +43,7 @@ public static void Methods( // We're declaring an 'internal abstract class' type argsMethodsType = new( ns: InteropUtf8NameFactory.TypeNamespace(argsType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(argsType, interopReferences.RuntimeContext, "Methods"), + name: InteropUtf8NameFactory.TypeName(argsType, interopDefinitions, "Methods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -90,12 +90,14 @@ public static void Methods( /// /// The for the args type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The interop module being built. /// The resulting native object type. public static void NativeObject( GenericInstanceTypeSignature argsType, TypeDefinition argsMethodsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition nativeObjectType) @@ -108,6 +110,7 @@ public static void NativeObject( InteropTypeDefinitionBuilder.NativeObject( typeSignature: argsType, nativeObjectBaseType: windowsRuntimeMapChangedEventArgs2Type, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out nativeObjectType); @@ -119,6 +122,7 @@ public static void NativeObject( /// The for the args type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The interop module being built. /// Whether to use Windows.UI.Xaml projections. @@ -127,6 +131,7 @@ public static void ComWrappersCallbackType( TypeSignature argsType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -137,6 +142,7 @@ public static void ComWrappersCallbackType( typeSignature: argsType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out callbackType); @@ -148,6 +154,7 @@ public static void ComWrappersCallbackType( /// The for the args type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. @@ -155,6 +162,7 @@ public static void ComWrappersMarshallerAttribute( GenericInstanceTypeSignature argsType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition marshallerType) @@ -163,6 +171,7 @@ public static void ComWrappersMarshallerAttribute( typeSignature: argsType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out marshallerType); @@ -192,7 +201,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(argsType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(argsType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(argsType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { @@ -296,7 +305,7 @@ public static void ImplType( Impl( interfaceType: ComInterfaceType.InterfaceIsIInspectable, ns: InteropUtf8NameFactory.TypeNamespace(argsType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(argsType, interopReferences.RuntimeContext, "Impl"), + name: InteropUtf8NameFactory.TypeName(argsType, interopDefinitions, "Impl"), vftblType: interopDefinitions.IMapChangedEventArgsVftbl, interopDefinitions: interopDefinitions, interopReferences: interopReferences, @@ -308,4 +317,4 @@ public static void ImplType( emitState.TrackTypeDefinition(implType, argsType, "Impl"); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableMap2.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableMap2.cs index ea4708ee8d..4e043664c3 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableMap2.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableMap2.cs @@ -25,12 +25,14 @@ public static class IObservableMap2 /// Creates a new type definition for the event source factory for an IObservableMap<K, V> interface. /// /// The for the map type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. /// The resulting factory type. public static void EventSourceFactory( GenericInstanceTypeSignature mapType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -42,7 +44,7 @@ public static void EventSourceFactory( // We're declaring an 'internal abstract class' type factoryType = new( ns: InteropUtf8NameFactory.TypeNamespace(mapType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(mapType, interopReferences.RuntimeContext, "EventSourceFactory"), + name: InteropUtf8NameFactory.TypeName(mapType, interopDefinitions, "EventSourceFactory"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -88,12 +90,14 @@ public static void EventSourceFactory( /// Creates the cached callback type for the property for the event args for the map. /// /// The for the map type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. /// The resulting callback type. public static void EventSourceCallback( GenericInstanceTypeSignature mapType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -105,7 +109,7 @@ public static void EventSourceCallback( // We're declaring an 'internal sealed class' type callbackType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(mapType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(mapType, interopReferences.RuntimeContext, "EventSourceCallback"), + name: InteropUtf8NameFactory.TypeName(mapType, interopDefinitions, "EventSourceCallback"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()); @@ -182,12 +186,14 @@ public static void EventSourceCallback( /// /// The for the map type. /// The type returned by . + /// The instance to use. /// The instance to use. /// The interop module being built. /// The resulting methods type. public static void Methods( GenericInstanceTypeSignature mapType, TypeDefinition eventSourceCallbackType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition methodsType) @@ -198,7 +204,7 @@ public static void Methods( // We're declaring an 'internal static class' type methodsType = new( ns: InteropUtf8NameFactory.TypeNamespace(mapType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(mapType, interopReferences.RuntimeContext, "Methods"), + name: InteropUtf8NameFactory.TypeName(mapType, interopDefinitions, "Methods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()); @@ -262,6 +268,7 @@ public static void Methods( /// /// The for the map type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -269,6 +276,7 @@ public static void Methods( public static void NativeObject( GenericInstanceTypeSignature mapType, TypeDefinition factoryType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -295,6 +303,7 @@ public static void NativeObject( InteropTypeDefinitionBuilder.NativeObject( typeSignature: mapType, nativeObjectBaseType: windowsRuntimeObservableMap2Type, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out nativeObjectType); @@ -306,6 +315,7 @@ public static void NativeObject( /// The for the map type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The interop module being built. /// Whether to use Windows.UI.Xaml projections. @@ -314,6 +324,7 @@ public static void ComWrappersCallbackType( TypeSignature mapType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -324,6 +335,7 @@ public static void ComWrappersCallbackType( typeSignature: mapType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out callbackType); @@ -335,6 +347,7 @@ public static void ComWrappersCallbackType( /// The for the map type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. @@ -342,6 +355,7 @@ public static void ComWrappersMarshallerAttribute( GenericInstanceTypeSignature mapType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition marshallerType) @@ -350,6 +364,7 @@ public static void ComWrappersMarshallerAttribute( typeSignature: mapType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out marshallerType); @@ -386,7 +401,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(mapType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(mapType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(mapType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { @@ -518,7 +533,7 @@ public static void ImplType( Impl( interfaceType: ComInterfaceType.InterfaceIsIInspectable, ns: InteropUtf8NameFactory.TypeNamespace(mapType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(mapType, interopReferences.RuntimeContext, "Impl"), + name: InteropUtf8NameFactory.TypeName(mapType, interopDefinitions, "Impl"), vftblType: interopDefinitions.IObservableMapVftbl, interopDefinitions: interopDefinitions, interopReferences: interopReferences, @@ -533,4 +548,4 @@ public static void ImplType( implType.Properties.Add(mapChangedTableProperty); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableVector1.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableVector1.cs index 90707e9a96..09e980d25f 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableVector1.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableVector1.cs @@ -25,12 +25,14 @@ public static class IObservableVector1 /// Creates a new type definition for the event source factory for an IObservableVector<T> interface. /// /// The for the vector type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. /// The resulting factory type. public static void EventSourceFactory( GenericInstanceTypeSignature vectorType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -41,7 +43,7 @@ public static void EventSourceFactory( // We're declaring an 'internal abstract class' type factoryType = new( ns: InteropUtf8NameFactory.TypeNamespace(vectorType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(vectorType, interopReferences.RuntimeContext, "EventSourceFactory"), + name: InteropUtf8NameFactory.TypeName(vectorType, interopDefinitions, "EventSourceFactory"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -87,12 +89,14 @@ public static void EventSourceFactory( /// Creates the cached callback type for an IObservableVector<T> interface. /// /// The for the vector type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. /// The resulting callback type. public static void EventSourceCallback( GenericInstanceTypeSignature vectorType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -103,7 +107,7 @@ public static void EventSourceCallback( // We're declaring an 'internal sealed class' type callbackType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(vectorType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(vectorType, interopReferences.RuntimeContext, "EventSourceCallback"), + name: InteropUtf8NameFactory.TypeName(vectorType, interopDefinitions, "EventSourceCallback"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()); @@ -179,12 +183,14 @@ public static void EventSourceCallback( /// /// The for the vector type. /// The type returned by . + /// The instance to use. /// The instance to use. /// The interop module being built. /// The resulting methods type. public static void Methods( GenericInstanceTypeSignature vectorType, TypeDefinition eventSourceCallbackType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition methodsType) @@ -194,7 +200,7 @@ public static void Methods( // We're declaring an 'internal static class' type methodsType = new( ns: InteropUtf8NameFactory.TypeNamespace(vectorType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(vectorType, interopReferences.RuntimeContext, "Methods"), + name: InteropUtf8NameFactory.TypeName(vectorType, interopDefinitions, "Methods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()); @@ -258,6 +264,7 @@ public static void Methods( /// /// The for the vector type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -265,6 +272,7 @@ public static void Methods( public static void NativeObject( GenericInstanceTypeSignature vectorType, TypeDefinition factoryType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -288,6 +296,7 @@ public static void NativeObject( InteropTypeDefinitionBuilder.NativeObject( typeSignature: vectorType, nativeObjectBaseType: windowsRuntimeObservableVector1Type, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out nativeObjectType); @@ -299,6 +308,7 @@ public static void NativeObject( /// The for the vector type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The interop module being built. /// Whether to use Windows.UI.Xaml projections. @@ -307,6 +317,7 @@ public static void ComWrappersCallbackType( TypeSignature vectorType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -317,6 +328,7 @@ public static void ComWrappersCallbackType( typeSignature: vectorType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out callbackType); @@ -328,6 +340,7 @@ public static void ComWrappersCallbackType( /// The for the vector type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. @@ -335,6 +348,7 @@ public static void ComWrappersMarshallerAttribute( GenericInstanceTypeSignature vectorType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition marshallerType) @@ -343,6 +357,7 @@ public static void ComWrappersMarshallerAttribute( typeSignature: vectorType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out marshallerType); @@ -372,7 +387,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(vectorType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(vectorType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(vectorType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { @@ -503,7 +518,7 @@ public static void ImplType( Impl( interfaceType: ComInterfaceType.InterfaceIsIInspectable, ns: InteropUtf8NameFactory.TypeNamespace(vectorType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(vectorType, interopReferences.RuntimeContext, "Impl"), + name: InteropUtf8NameFactory.TypeName(vectorType, interopDefinitions, "Impl"), vftblType: interopDefinitions.IObservableVectorVftbl, interopDefinitions: interopDefinitions, interopReferences: interopReferences, @@ -521,4 +536,4 @@ public static void ImplType( emitState.TrackTypeDefinition(implType, vectorType, "Impl"); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IReadOnlyCollectionKeyValuePair2.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IReadOnlyCollectionKeyValuePair2.cs index fb351c5ee7..ed8db77ec2 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IReadOnlyCollectionKeyValuePair2.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IReadOnlyCollectionKeyValuePair2.cs @@ -22,11 +22,13 @@ public static class IReadOnlyCollectionKeyValuePair2 /// Creates a new type definition for the forwarder attribute for a of type. /// /// The for the generic interface type. + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. public static void ForwarderAttribute( GenericInstanceTypeSignature readOnlyCollectionType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition forwarderAttributeType) @@ -39,6 +41,7 @@ public static void ForwarderAttribute( readOnlyCollectionType: readOnlyCollectionType, readOnlyDictionaryType: interopReferences.IReadOnlyDictionary2.MakeGenericReferenceType([keyType, valueType]), readOnlyListType: interopReferences.IReadOnlyList1.MakeGenericReferenceType([keyValuePairType]), + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, forwarderAttributeType: out forwarderAttributeType); @@ -49,6 +52,7 @@ public static void ForwarderAttribute( /// /// The for the generic interface type. /// The type returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The module that will contain the type being created. @@ -56,6 +60,7 @@ public static void ForwarderAttribute( public static void InterfaceImpl( GenericInstanceTypeSignature readOnlyCollectionType, TypeDefinition forwarderAttributeType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -71,7 +76,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(readOnlyCollectionType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(readOnlyCollectionType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(readOnlyCollectionType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { @@ -148,4 +153,4 @@ public static void TypeMapAttributes( module: module); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IReadOnlyDictionary2.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IReadOnlyDictionary2.cs index 031deed436..26c762b133 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IReadOnlyDictionary2.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IReadOnlyDictionary2.cs @@ -67,7 +67,7 @@ public static void Vftbl( // Otherwise, we must construct a new specialized vtable type TypeDefinition newVftblType = WellKnownTypeDefinitionFactory.IReadOnlyDictionary2Vftbl( ns: InteropUtf8NameFactory.TypeNamespace(sharedReadOnlyDictionaryType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(sharedReadOnlyDictionaryType, interopReferences.RuntimeContext, "Vftbl"), + name: InteropUtf8NameFactory.TypeName(sharedReadOnlyDictionaryType, interopDefinitions, "Vftbl"), keyType: keyType, valueType: interopReferences.Void, interopReferences: interopReferences); @@ -87,6 +87,7 @@ public static void Vftbl( /// /// The for the type. /// The type returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -94,6 +95,7 @@ public static void Vftbl( public static void IMapViewMethods( GenericInstanceTypeSignature readOnlyDictionaryType, TypeDefinition vftblType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -105,7 +107,7 @@ public static void IMapViewMethods( // We're declaring an 'internal abstract class' type mapViewMethodsType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(readOnlyDictionaryType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(readOnlyDictionaryType, interopReferences.RuntimeContext, "IMapViewMethods"), + name: InteropUtf8NameFactory.TypeName(readOnlyDictionaryType, interopDefinitions, "IMapViewMethods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -144,6 +146,7 @@ public static void IMapViewMethods( /// /// The for the type. /// The type returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -151,6 +154,7 @@ public static void IMapViewMethods( public static void Methods( GenericInstanceTypeSignature readOnlyDictionaryType, TypeDefinition mapViewMethodsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -162,7 +166,7 @@ public static void Methods( // We're declaring an 'internal static class' type readOnlyDictionaryMethodsType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(readOnlyDictionaryType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(readOnlyDictionaryType, interopReferences.RuntimeContext, "Methods"), + name: InteropUtf8NameFactory.TypeName(readOnlyDictionaryType, interopDefinitions, "Methods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()); @@ -323,6 +327,7 @@ public static void Methods( /// /// The for the type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -330,6 +335,7 @@ public static void Methods( public static void NativeObject( GenericInstanceTypeSignature readOnlyDictionaryType, TypeDefinition mapViewMethodsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -351,6 +357,7 @@ public static void NativeObject( InteropTypeDefinitionBuilder.NativeObject( typeSignature: readOnlyDictionaryType, nativeObjectBaseType: windowsRuntimeReadOnlyDictionary5Type, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out nativeObjectType); @@ -362,6 +369,7 @@ public static void NativeObject( /// The for the type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The interop module being built. /// Whether to use Windows.UI.Xaml projections. @@ -370,6 +378,7 @@ public static void ComWrappersCallbackType( TypeSignature readOnlyDictionaryType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -380,6 +389,7 @@ public static void ComWrappersCallbackType( typeSignature: readOnlyDictionaryType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out callbackType); @@ -391,6 +401,7 @@ public static void ComWrappersCallbackType( /// The for the type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. @@ -398,6 +409,7 @@ public static void ComWrappersMarshallerAttribute( GenericInstanceTypeSignature readOnlyDictionaryType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition marshallerType) @@ -406,6 +418,7 @@ public static void ComWrappersMarshallerAttribute( typeSignature: readOnlyDictionaryType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out marshallerType); @@ -439,7 +452,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(readOnlyDictionaryType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(readOnlyDictionaryType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(readOnlyDictionaryType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { @@ -641,7 +654,7 @@ public static void ImplType( Impl( interfaceType: ComInterfaceType.InterfaceIsIInspectable, ns: InteropUtf8NameFactory.TypeNamespace(readOnlyDictionaryType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(readOnlyDictionaryType, interopReferences.RuntimeContext, "Impl"), + name: InteropUtf8NameFactory.TypeName(readOnlyDictionaryType, interopDefinitions, "Impl"), vftblType: vftblType, interopDefinitions: interopDefinitions, interopReferences: interopReferences, @@ -657,4 +670,4 @@ public static void ImplType( emitState.TrackTypeDefinition(implType, readOnlyDictionaryType, "Impl"); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IReadOnlyList1.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IReadOnlyList1.cs index 8a3afa9f1f..aa7b4284d7 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IReadOnlyList1.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IReadOnlyList1.cs @@ -50,7 +50,7 @@ public static void Vftbl( // Otherwise, we must construct a new specialized vtable type vftblType = WellKnownTypeDefinitionFactory.IReadOnlyList1Vftbl( ns: InteropUtf8NameFactory.TypeNamespace(readOnlyListType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(readOnlyListType, interopReferences.RuntimeContext, "Vftbl"), + name: InteropUtf8NameFactory.TypeName(readOnlyListType, interopDefinitions, "Vftbl"), elementType: elementType.GetAbiType(interopReferences), interopReferences: interopReferences); @@ -62,6 +62,7 @@ public static void Vftbl( /// /// The for the type. /// The type returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -69,6 +70,7 @@ public static void Vftbl( public static void IVectorViewMethods( GenericInstanceTypeSignature readOnlyListType, TypeDefinition vftblType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -79,7 +81,7 @@ public static void IVectorViewMethods( // We're declaring an 'internal abstract class' type vectorViewMethodsType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(readOnlyListType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(readOnlyListType, interopReferences.RuntimeContext, "IVectorViewMethods"), + name: InteropUtf8NameFactory.TypeName(readOnlyListType, interopDefinitions, "IVectorViewMethods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -106,6 +108,7 @@ public static void IVectorViewMethods( /// /// The for the type. /// The type returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -113,6 +116,7 @@ public static void IVectorViewMethods( public static void Methods( GenericInstanceTypeSignature readOnlyListType, TypeDefinition vectorViewMethodsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -123,7 +127,7 @@ public static void Methods( // We're declaring an 'internal static class' type readOnlyListMethodsType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(readOnlyListType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(readOnlyListType, interopReferences.RuntimeContext, "Methods"), + name: InteropUtf8NameFactory.TypeName(readOnlyListType, interopDefinitions, "Methods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()); @@ -187,6 +191,7 @@ public static void Methods( /// /// The for the type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The interop module being built. @@ -194,6 +199,7 @@ public static void Methods( public static void NativeObject( GenericInstanceTypeSignature readOnlyListType, TypeDefinition vectorViewMethodsType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -212,6 +218,7 @@ public static void NativeObject( InteropTypeDefinitionBuilder.NativeObject( typeSignature: readOnlyListType, nativeObjectBaseType: windowsRuntimeReadOnlyList4Type, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out nativeObjectType); @@ -223,6 +230,7 @@ public static void NativeObject( /// The for the type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The interop module being built. /// Whether to use Windows.UI.Xaml projections. @@ -231,6 +239,7 @@ public static void ComWrappersCallbackType( TypeSignature readOnlyListType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -241,6 +250,7 @@ public static void ComWrappersCallbackType( typeSignature: readOnlyListType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out callbackType); @@ -252,6 +262,7 @@ public static void ComWrappersCallbackType( /// The for the type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. @@ -259,6 +270,7 @@ public static void ComWrappersMarshallerAttribute( GenericInstanceTypeSignature readOnlyListType, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition marshallerType) @@ -267,6 +279,7 @@ public static void ComWrappersMarshallerAttribute( typeSignature: readOnlyListType, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out marshallerType); @@ -298,7 +311,7 @@ public static void InterfaceImpl( // We're declaring an 'internal interface class' type interfaceImplType = new( ns: InteropUtf8NameFactory.TypeNamespace(readOnlyListType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(readOnlyListType, interopReferences.RuntimeContext, "InterfaceImpl"), + name: InteropUtf8NameFactory.TypeName(readOnlyListType, interopDefinitions, "InterfaceImpl"), attributes: TypeAttributes.Interface | TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: null) { @@ -429,7 +442,7 @@ public static void ImplType( Impl( interfaceType: ComInterfaceType.InterfaceIsIInspectable, ns: InteropUtf8NameFactory.TypeNamespace(readOnlyListType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(readOnlyListType, interopReferences.RuntimeContext, "Impl"), + name: InteropUtf8NameFactory.TypeName(readOnlyListType, interopDefinitions, "Impl"), vftblType: vftblType, interopDefinitions: interopDefinitions, interopReferences: interopReferences, @@ -449,7 +462,7 @@ public static void ImplType( /// Creates the type map attributes for some IVectorView<T> interface. /// /// The for the type. - /// The instance returned by . + /// The instance returned by . /// The instance returned by . /// The instance to use. /// The module that will contain the type being created. @@ -499,4 +512,4 @@ public static void TypeMapAttributes( } } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.KeyValuePair.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.KeyValuePair.cs index b0c973bec2..d3814bdc27 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.KeyValuePair.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.KeyValuePair.cs @@ -28,10 +28,12 @@ public static class KeyValuePair /// Creates a new type definition for the KeyValuePairMethods type to contain shared accessor /// methods for types. /// + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting methods type. public static void Methods( + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition methodsType) @@ -39,7 +41,7 @@ public static void Methods( // We're declaring an 'internal static class' type methodsType = new TypeDefinition( ns: InteropUtf8NameFactory.TypeNamespace(interopReferences.KeyValuePair.ToReferenceTypeSignature(), interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(interopReferences.KeyValuePair.ToReferenceTypeSignature(), interopReferences.RuntimeContext, "Methods"), + name: InteropUtf8NameFactory.TypeName(interopReferences.KeyValuePair.ToReferenceTypeSignature(), interopDefinitions, "Methods"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()); @@ -69,8 +71,8 @@ public static void Accessors( TypeSignature valueType = keyValuePairType.TypeArguments[1]; // Prepare the names of the accessor methods, to define or look them up - Utf8String get_KeyMethodName = $"get_Key({InteropUtf8NameFactory.TypeName(keyType, interopReferences.RuntimeContext)})"; - Utf8String get_ValueMethodName = $"get_Value({InteropUtf8NameFactory.TypeName(valueType, interopReferences.RuntimeContext)})"; + Utf8String get_KeyMethodName = $"get_Key({InteropUtf8NameFactory.TypeName(keyType, interopDefinitions)})"; + Utf8String get_ValueMethodName = $"get_Value({InteropUtf8NameFactory.TypeName(valueType, interopDefinitions)})"; // Get or define the 'get_Key' accessor method if (!methodsType.TryGetMethod(get_KeyMethodName, out keyAccessorMethod!)) @@ -108,6 +110,7 @@ public static void Accessors( /// The 'IID' get method for . /// The accessor method for the key. /// The accessor method for the value. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The module that will contain the type being created. @@ -117,6 +120,7 @@ public static void Marshaller( MethodDefinition get_IidMethod, MethodDefinition keyAccessorMethod, MethodDefinition valueAccessorMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -125,7 +129,7 @@ public static void Marshaller( // We're declaring an 'internal static class' type marshallerType = new( ns: InteropUtf8NameFactory.TypeNamespace(keyValuePairType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(keyValuePairType, interopReferences.RuntimeContext, "Marshaller"), + name: InteropUtf8NameFactory.TypeName(keyValuePairType, interopDefinitions, "Marshaller"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()); @@ -242,7 +246,7 @@ public static void ImplType( Impl( interfaceType: ComInterfaceType.InterfaceIsIInspectable, ns: InteropUtf8NameFactory.TypeNamespace(keyValuePairType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(keyValuePairType, interopReferences.RuntimeContext, "Impl"), + name: InteropUtf8NameFactory.TypeName(keyValuePairType, interopDefinitions, "Impl"), vftblType: interopDefinitions.IKeyValuePairVftbl, interopDefinitions: interopDefinitions, interopReferences: interopReferences, @@ -272,7 +276,7 @@ public static void InterfaceEntriesImplType( { InterfaceEntriesImpl( ns: InteropUtf8NameFactory.TypeNamespace(keyValuePairType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(keyValuePairType, interopReferences.RuntimeContext, "InterfaceEntriesImpl"), + name: InteropUtf8NameFactory.TypeName(keyValuePairType, interopDefinitions, "InterfaceEntriesImpl"), entriesFieldType: interopDefinitions.IKeyValuePairInterfaceEntries, interopReferences: interopReferences, module: module, @@ -311,7 +315,7 @@ public static void ComWrappersMarshallerAttribute( // We're declaring an 'internal sealed class' type marshallerAttributeType = new( ns: InteropUtf8NameFactory.TypeNamespace(keyValuePairType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(keyValuePairType, interopReferences.RuntimeContext, "ComWrappersMarshallerAttribute"), + name: InteropUtf8NameFactory.TypeName(keyValuePairType, interopDefinitions, "ComWrappersMarshallerAttribute"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, baseType: interopReferences.WindowsRuntimeComWrappersMarshallerAttribute); @@ -453,6 +457,7 @@ public static void ComWrappersMarshallerAttribute( /// /// The for the type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// Whether to use Windows.UI.Xaml projections. @@ -460,6 +465,7 @@ public static void ComWrappersMarshallerAttribute( public static void Proxy( TypeSignature keyValuePairType, TypeDefinition comWrappersMarshallerAttributeType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -470,7 +476,7 @@ public static void Proxy( // reference the mapped type, so that we can retrieve the original 'Type' instance when marshalling from native. InteropTypeDefinitionBuilder.Proxy( ns: InteropUtf8NameFactory.TypeNamespace(keyValuePairType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(keyValuePairType, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(keyValuePairType, interopDefinitions), mappedMetadata: "Windows.Foundation.FoundationContract", runtimeClassName: RuntimeClassNameGenerator.GetRuntimeClassName(keyValuePairType, interopReferences.RuntimeContext, useWindowsUIXamlProjections), metadataTypeName: null, @@ -512,4 +518,4 @@ public static void TypeMapAttributes( module: module); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.SzArray.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.SzArray.cs index 2eb895169e..36c8df6095 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.SzArray.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.SzArray.cs @@ -39,12 +39,14 @@ public static class SzArray /// Creates a new type definition for the marshaller for some SZ array type. /// /// The for the SZ array type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The module that will contain the type being created. /// The resulting marshaller type. public static void Marshaller( SzArrayTypeSignature arrayType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -59,6 +61,7 @@ public static void Marshaller( { marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.BlittableValueType( arrayType: arrayType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); module.TopLevelTypes.Add(marshallerType); @@ -67,6 +70,7 @@ public static void Marshaller( { TypeDefinition elementMarshallerType = InteropTypeDefinitionFactory.SzArrayElementMarshaller.KeyValuePair( arrayType: arrayType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); @@ -75,6 +79,7 @@ public static void Marshaller( marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.KeyValuePair( arrayType: arrayType, elementMarshallerType: elementMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); module.TopLevelTypes.Add(marshallerType); @@ -83,6 +88,7 @@ public static void Marshaller( { TypeDefinition elementMarshallerType = InteropTypeDefinitionFactory.SzArrayElementMarshaller.NullableValueType( arrayType: arrayType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); @@ -91,6 +97,7 @@ public static void Marshaller( marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.NullableValueType( arrayType: arrayType, elementMarshallerType: elementMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); module.TopLevelTypes.Add(marshallerType); @@ -99,6 +106,7 @@ public static void Marshaller( { TypeDefinition elementMarshallerType = InteropTypeDefinitionFactory.SzArrayElementMarshaller.ManagedValueType( arrayType: arrayType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); @@ -107,6 +115,7 @@ public static void Marshaller( marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.ManagedValueType( arrayType: arrayType, elementMarshallerType: elementMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); module.TopLevelTypes.Add(marshallerType); @@ -115,6 +124,7 @@ public static void Marshaller( { TypeDefinition elementMarshallerType = InteropTypeDefinitionFactory.SzArrayElementMarshaller.UnmanagedValueType( arrayType: arrayType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); @@ -123,6 +133,7 @@ public static void Marshaller( marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.UnmanagedValueType( arrayType: arrayType, elementMarshallerType: elementMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); module.TopLevelTypes.Add(marshallerType); @@ -131,6 +142,7 @@ public static void Marshaller( { marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.Object( arrayType: arrayType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); module.TopLevelTypes.Add(marshallerType); @@ -139,6 +151,7 @@ public static void Marshaller( { marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.String( arrayType: arrayType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); module.TopLevelTypes.Add(marshallerType); @@ -147,6 +160,7 @@ public static void Marshaller( { marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.Type( arrayType: arrayType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); module.TopLevelTypes.Add(marshallerType); @@ -155,6 +169,7 @@ public static void Marshaller( { marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.Exception( arrayType: arrayType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); module.TopLevelTypes.Add(marshallerType); @@ -163,6 +178,7 @@ public static void Marshaller( { TypeDefinition elementMarshallerType = InteropTypeDefinitionFactory.SzArrayElementMarshaller.ReferenceType( arrayType: arrayType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); @@ -171,6 +187,7 @@ public static void Marshaller( marshallerType = InteropTypeDefinitionFactory.SzArrayMarshaller.ReferenceType( arrayType: arrayType, elementMarshallerType: elementMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); module.TopLevelTypes.Add(marshallerType); @@ -182,12 +199,14 @@ public static void Marshaller( /// /// The for the SZ array type. /// The type returned by . + /// The instance to use. /// The instance to use. /// The interop module being built. /// The resulting callback type. public static void ComWrappersCallback( SzArrayTypeSignature arrayType, TypeDefinition marshallerType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition callbackType) @@ -195,7 +214,7 @@ public static void ComWrappersCallback( // We're declaring an 'internal abstract class' type callbackType = new( ns: InteropUtf8NameFactory.TypeNamespace(arrayType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(arrayType, interopReferences.RuntimeContext, "ComWrappersCallback"), + name: InteropUtf8NameFactory.TypeName(arrayType, interopDefinitions, "ComWrappersCallback"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -334,7 +353,7 @@ public static void ArrayImpl( Impl( interfaceType: ComInterfaceType.InterfaceIsIInspectable, ns: InteropUtf8NameFactory.TypeNamespace(arrayType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(arrayType, interopReferences.RuntimeContext, "Impl"), + name: InteropUtf8NameFactory.TypeName(arrayType, interopDefinitions, "Impl"), vftblType: interopDefinitions.IReferenceArrayVftbl, interopDefinitions: interopDefinitions, interopReferences: interopReferences, @@ -402,7 +421,7 @@ public static void InterfaceEntriesImpl( InteropTypeDefinitionBuilder.InterfaceEntriesImpl( ns: InteropUtf8NameFactory.TypeNamespace(arrayType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(arrayType, interopReferences.RuntimeContext, "InterfaceEntriesImpl"), + name: InteropUtf8NameFactory.TypeName(arrayType, interopDefinitions, "InterfaceEntriesImpl"), entriesFieldType: interfaceEntriesType, interopReferences: interopReferences, module: module, @@ -418,6 +437,7 @@ public static void InterfaceEntriesImpl( /// The instance returned by . /// The instance returned by . /// The 'IID' get method for the 'IReferenceArray`1<T>' interface. + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. @@ -427,6 +447,7 @@ public static void ComWrappersMarshallerAttribute( TypeDefinition arrayInterfaceEntriesImplType, TypeDefinition arrayComWrappersCallbackType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition marshallerType) @@ -434,7 +455,7 @@ public static void ComWrappersMarshallerAttribute( // We're declaring an 'internal sealed class' type marshallerType = new( ns: InteropUtf8NameFactory.TypeNamespace(arrayType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(arrayType, interopReferences.RuntimeContext, "ComWrappersMarshallerAttribute"), + name: InteropUtf8NameFactory.TypeName(arrayType, interopDefinitions, "ComWrappersMarshallerAttribute"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, baseType: interopReferences.WindowsRuntimeComWrappersMarshallerAttribute); @@ -537,6 +558,7 @@ public static void ComWrappersMarshallerAttribute( /// /// The for the SZ array type. /// The instance for the marshaller attribute type. + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// Whether to use Windows.UI.Xaml projections. @@ -544,6 +566,7 @@ public static void ComWrappersMarshallerAttribute( public static void Proxy( SzArrayTypeSignature arrayType, TypeDefinition comWrappersMarshallerAttributeType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -555,7 +578,7 @@ public static void Proxy( // type map (as they're treated the same as normal user-defined types), so this allows us to distinguish them. InteropTypeDefinitionBuilder.Proxy( ns: InteropUtf8NameFactory.TypeNamespace(arrayType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(arrayType, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(arrayType, interopDefinitions), mappedMetadata: "Windows.Foundation.FoundationContract", runtimeClassName: RuntimeClassNameGenerator.GetRuntimeClassName(arrayType, interopReferences.RuntimeContext, useWindowsUIXamlProjections), metadataTypeName: null, @@ -597,4 +620,4 @@ public static void TypeMapAttributes( module: module); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.UserDefinedType.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.UserDefinedType.cs index 57d95bfc78..db955fe35e 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.UserDefinedType.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.UserDefinedType.cs @@ -86,7 +86,7 @@ public static void InterfaceEntriesImpl( InteropTypeDefinitionBuilder.InterfaceEntriesImpl( ns: "WindowsRuntime.Interop.UserDefinedTypes"u8, - name: InteropUtf8NameFactory.TypeName(userDefinedType, interopReferences.RuntimeContext, "InterfaceEntriesImpl"), + name: InteropUtf8NameFactory.TypeName(userDefinedType, interopDefinitions, "InterfaceEntriesImpl"), entriesFieldType: interfaceEntriesType, interopReferences: interopReferences, module: module, @@ -100,6 +100,7 @@ public static void InterfaceEntriesImpl( /// The for the user-defined type. /// The for the interface entries type returned by . /// The for the interface entries implementation type returned by . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. @@ -107,6 +108,7 @@ public static void ComWrappersMarshallerAttribute( TypeSignature userDefinedType, TypeDefinition interfaceEntriesType, TypeDefinition interfaceEntriesImplType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition marshallerType) @@ -114,7 +116,7 @@ public static void ComWrappersMarshallerAttribute( // We're declaring an 'internal sealed class' type marshallerType = new( ns: "WindowsRuntime.Interop.UserDefinedTypes"u8, - name: InteropUtf8NameFactory.TypeName(userDefinedType, interopReferences.RuntimeContext, "ComWrappersMarshallerAttribute"), + name: InteropUtf8NameFactory.TypeName(userDefinedType, interopDefinitions, "ComWrappersMarshallerAttribute"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, baseType: interopReferences.WindowsRuntimeComWrappersMarshallerAttribute); @@ -180,6 +182,7 @@ public static void ComWrappersMarshallerAttribute( /// /// The for the user-defined type. /// The instance returned by . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// Whether to use Windows.UI.Xaml projections. @@ -187,6 +190,7 @@ public static void ComWrappersMarshallerAttribute( public static void Proxy( TypeSignature userDefinedType, TypeDefinition comWrappersMarshallerAttributeType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -201,7 +205,7 @@ public static void Proxy( { InteropTypeDefinitionBuilder.Proxy( ns: InteropUtf8NameFactory.TypeNamespace(userDefinedType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(userDefinedType, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(userDefinedType, interopDefinitions), mappedMetadata: null, runtimeClassName: null, metadataTypeName: null, @@ -218,7 +222,7 @@ public static void Proxy( // For authored component types, the runtime class name is the type's own fully-qualified name. InteropTypeDefinitionBuilder.Proxy( ns: InteropUtf8NameFactory.TypeNamespace(userDefinedType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(userDefinedType, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(userDefinedType, interopDefinitions), mappedMetadata: null, runtimeClassName: MetadataTypeNameGenerator.GetMetadataTypeName(userDefinedType, useWindowsUIXamlProjections), metadataTypeName: null, @@ -244,7 +248,7 @@ public static void Proxy( InteropTypeDefinitionBuilder.Proxy( ns: InteropUtf8NameFactory.TypeNamespace(userDefinedType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(userDefinedType, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(userDefinedType, interopDefinitions), mappedMetadata: null, runtimeClassName: RuntimeClassNameGenerator.GetRuntimeClassName(interfaceType, interopReferences.RuntimeContext, useWindowsUIXamlProjections), metadataTypeName: null, @@ -285,4 +289,4 @@ public static void TypeMapAttributes( module: module); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.cs index 610317be80..c179c5295d 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.cs @@ -42,7 +42,7 @@ public static void IID( out MethodDefinition get_IidMethod) { IID( - name: InteropUtf8NameFactory.TypeName(interfaceType, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(interfaceType, interopDefinitions), interopDefinitions: interopDefinitions, interopReferences: interopReferences, iid: GuidGenerator.CreateIID(interfaceType, interopDefinitions, interopReferences, useWindowsUIXamlProjections), @@ -84,12 +84,14 @@ private static void IID( /// /// The for the generic interface type. /// The for the base native object type. + /// The instance to use. /// The instance to use. /// The interop module being built. /// The resulting native object type. private static void NativeObject( TypeSignature typeSignature, TypeSignature nativeObjectBaseType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition nativeObjectType) @@ -97,7 +99,7 @@ private static void NativeObject( // We're declaring an 'internal sealed class' type nativeObjectType = new( ns: InteropUtf8NameFactory.TypeNamespace(typeSignature, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(typeSignature, interopReferences.RuntimeContext, "NativeObject"), + name: InteropUtf8NameFactory.TypeName(typeSignature, interopDefinitions, "NativeObject"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, baseType: nativeObjectBaseType.ToTypeDefOrRef()); @@ -119,6 +121,7 @@ private static void NativeObject( /// The for the generic interface type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The interop module being built. /// The resulting callback type. @@ -127,6 +130,7 @@ private static void ComWrappersCallback( TypeSignature typeSignature, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition callbackType) @@ -134,7 +138,7 @@ private static void ComWrappersCallback( // We're declaring an 'internal abstract class' type callbackType = new( ns: InteropUtf8NameFactory.TypeNamespace(typeSignature, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(typeSignature, interopReferences.RuntimeContext, "ComWrappersCallback"), + name: InteropUtf8NameFactory.TypeName(typeSignature, interopDefinitions, "ComWrappersCallback"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()) { @@ -251,6 +255,7 @@ private static void ComWrappersCallback( /// The for the generic interface type. /// The type returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. @@ -258,6 +263,7 @@ private static void ComWrappersMarshallerAttribute( TypeSignature typeSignature, TypeDefinition nativeObjectType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition marshallerType) @@ -265,7 +271,7 @@ private static void ComWrappersMarshallerAttribute( // We're declaring an 'internal sealed class' type marshallerType = new( ns: InteropUtf8NameFactory.TypeNamespace(typeSignature, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(typeSignature, interopReferences.RuntimeContext, "ComWrappersMarshallerAttribute"), + name: InteropUtf8NameFactory.TypeName(typeSignature, interopDefinitions, "ComWrappersMarshallerAttribute"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, baseType: interopReferences.WindowsRuntimeComWrappersMarshallerAttribute); @@ -312,6 +318,7 @@ private static void ComWrappersMarshallerAttribute( /// The for the generic interface type. /// The instance returned by . /// The 'IID' get method for . + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The module that will contain the type being created. @@ -320,6 +327,7 @@ public static void Marshaller( TypeSignature typeSignature, TypeDefinition interfaceComWrappersCallbackType, MethodDefinition get_IidMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState, ModuleDefinition module, @@ -328,7 +336,7 @@ public static void Marshaller( // We're declaring an 'internal static class' type marshallerType = new( ns: InteropUtf8NameFactory.TypeNamespace(typeSignature, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(typeSignature, interopReferences.RuntimeContext, "Marshaller"), + name: InteropUtf8NameFactory.TypeName(typeSignature, interopDefinitions, "Marshaller"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()); @@ -704,6 +712,7 @@ private static void InterfaceEntriesImpl( /// /// The for the mapped type the proxy type is for. /// The instance for the marshaller attribute type. + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// Whether to use Windows.UI.Xaml projections. @@ -711,6 +720,7 @@ private static void InterfaceEntriesImpl( public static void Proxy( TypeSignature interfaceType, TypeDefinition comWrappersMarshallerAttributeType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, bool useWindowsUIXamlProjections, @@ -723,7 +733,7 @@ public static void Proxy( // when marshalling 'TypeName' instances. Nobody would need a runtime class name here. Proxy( ns: InteropUtf8NameFactory.TypeNamespace(interfaceType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(interfaceType, interopReferences.RuntimeContext), + name: InteropUtf8NameFactory.TypeName(interfaceType, interopDefinitions), mappedMetadata: null, runtimeClassName: null, metadataTypeName: MetadataTypeNameGenerator.GetMetadataTypeName(interfaceType, useWindowsUIXamlProjections), @@ -943,4 +953,4 @@ public static void TypeMapAttributes( interopReferences: interopReferences)); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Discovery/InteropTypeDiscovery.cs b/src/WinRT.Interop.Generator/Discovery/InteropTypeDiscovery.cs index c044ab3e13..d33fd3d69e 100644 --- a/src/WinRT.Interop.Generator/Discovery/InteropTypeDiscovery.cs +++ b/src/WinRT.Interop.Generator/Discovery/InteropTypeDiscovery.cs @@ -56,15 +56,17 @@ public static void TryTrackTypeHierarchyType( } // We need to resolve the base type to be able to look up attributes on it - if (!baseType.IsFullyResolvable(interopReferences.RuntimeContext, out _)) + if (!baseType.IsFullyResolvable(interopReferences.RuntimeContext, out TypeDefinition? baseTypeDefinition)) { WellKnownInteropExceptions.WindowsRuntimeClassTypeNotResolvedWarning(baseType, typeDefinition).LogOrThrow(args.TreatWarningsAsErrors); return; } - // If the base type is also a projected Windows Runtime type, track it - if (baseType.IsProjectedWindowsRuntimeType) + // If the base type is also a projected Windows Runtime type, track it. The base type is recognized + // either by its '[WindowsRuntimeMetadata]' attribute (implementation projections) or by being defined + // in a reference projection assembly (reference projections don't carry that per-type attribute). + if (baseTypeDefinition.IsProjectedWindowsRuntimeType || baseTypeDefinition.IsReferenceProjectionWindowsRuntimeType) { discoveryState.TrackTypeHierarchyEntry(typeDefinition.FullName, baseType.FullName); } diff --git a/src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs b/src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs index ce70b8a1a2..31a449b614 100644 --- a/src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs +++ b/src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs @@ -115,6 +115,17 @@ public bool IsProjectedWindowsSdkXamlType /// public bool IsComponentWindowsRuntimeType => type.Scope?.GetAssembly() is { IsWindowsRuntimeComponentAssembly: true }; + /// + /// Gets a value indicating whether the type is from a Windows Runtime reference projection assembly. + /// + /// + /// Types in a reference projection assembly (marked with [WindowsRuntimeReferenceAssembly]) are + /// projected Windows Runtime types, but they do not carry the per-type [WindowsRuntimeMetadata] + /// attribute that implementation projections use (it is stripped from reference projections). This mirrors + /// how authored component assemblies expose projected types without that attribute (the IsComponentWindowsRuntimeType extension property). + /// + public bool IsReferenceProjectionWindowsRuntimeType => type.Scope?.GetAssembly() is { IsWindowsRuntimeReferenceAssembly: true }; + /// /// Checks whether an is some type. /// @@ -725,8 +736,10 @@ public bool IsProjectedWindowsRuntimeClassType return false; } - // The type also must be a projected type - return type.IsProjectedWindowsRuntimeType; + // The type also must be a projected type (recognized either by its '[WindowsRuntimeMetadata]' + // attribute, for implementation projections, or by being defined in a reference projection + // assembly, which doesn't carry that per-type attribute). + return type.IsProjectedWindowsRuntimeType || type.IsReferenceProjectionWindowsRuntimeType; } } @@ -774,6 +787,74 @@ public bool IsWindowsRuntimeManagedOnlyType(InteropReferences interopReferences) return attribute?.Signature?.FixedArguments?[0]?.Element as Utf8String; } + + /// + /// Gets the Windows Runtime metadata name for a , recovering it from the + /// implementation projection when the type comes from a reference projection. + /// + /// The instance to use. + /// The Windows Runtime metadata name (i.e. the source .winmd module name), or if not found. + /// + /// + /// The per-type [WindowsRuntimeMetadata] attribute is present on implementation projections, the + /// authored component projection, and manually projected types in WinRT.Runtime.dll, so for those the + /// value is read directly off the type. + /// + /// + /// Reference projections shipped in Windows Runtime projection NuGet packages have that attribute stripped (it + /// is an implementation-only attribute, absent from the WinRT.Runtime.dll reference assembly they compile + /// against). For a type defined in such a reference projection, the source .winmd stem is recovered from + /// the matching type in the implementation projection (located via ), + /// which retains it. That is the authoritative value the interop type-name marker must agree with: the projection + /// writer encodes the very same stem into the [UnsafeAccessorType] references it emits into that + /// implementation projection, so falling back to the reference projection's own assembly name (which can differ + /// from the stem, e.g. when several .winmd files are merged into one projection) would produce mismatched names. + /// + /// + public Utf8String? GetWindowsRuntimeMetadataName(InteropDefinitions interopDefinitions) + { + // Fast path: the attribute is present directly on the type (implementation projections, authored + // components, and 'WinRT.Runtime.dll' types all carry '[WindowsRuntimeMetadata]'). + if (type.GetWindowsRuntimeMetadataName() is { } metadataName) + { + return metadataName; + } + + // The only remaining case we can recover is a type from a reference projection, whose per-type attribute + // was stripped. For those, the metadata name lives on the matching type in the implementation projection. + if (!type.IsReferenceProjectionWindowsRuntimeType) + { + return null; + } + + // Resolve the equivalent type in the right implementation projection (via the cached top-level types + // lookup) and read the '[WindowsRuntimeMetadata]' attribute off it, which it retains. + if (type.GetImplementationProjectionModule(interopDefinitions) is { } projectionModule && + projectionModule.GetTopLevelTypesLookup().TryGetValue((type.Namespace, type.Name), out TypeDefinition? projectionType)) + { + return projectionType.GetWindowsRuntimeMetadataName(); + } + + return null; + } + + /// + /// Gets the implementation projection module that contains the marshalling code for a projected . + /// + /// The instance to use. + /// + /// The for the implementation projection the type belongs to: the Windows SDK projection + /// (WinRT.Sdk.Projection.dll), the Windows SDK XAML projection (WinRT.Sdk.Xaml.Projection.dll), or the merged + /// third-party projection (WinRT.Projection.dll); or if that projection is not available. + /// + public ModuleDefinition? GetImplementationProjectionModule(InteropDefinitions interopDefinitions) + { + return type.IsProjectedWindowsSdkType + ? interopDefinitions.WindowsRuntimeSdkProjectionModule + : type.IsProjectedWindowsSdkXamlType + ? interopDefinitions.WindowsRuntimeSdkXamlProjectionModule + : interopDefinitions.WindowsRuntimeProjectionModule; + } } extension(TypeSignature signature) @@ -1006,8 +1087,9 @@ public bool IsWindowsRuntimeType(InteropReferences interopReferences) // For all other cases, just check that the type is projected. This will also include manually // projected types that are defined in 'WinRT.Runtime.dll' (same attributes). Public types from - // authored component assemblies are also considered Windows Runtime types. - return type.IsProjectedWindowsRuntimeType || type.IsComponentWindowsRuntimeType; + // authored component assemblies, and types from reference projection assemblies, are also + // considered Windows Runtime types (they don't carry the per-type '[WindowsRuntimeMetadata]' attribute). + return type.IsProjectedWindowsRuntimeType || type.IsComponentWindowsRuntimeType || type.IsReferenceProjectionWindowsRuntimeType; } /// @@ -1073,8 +1155,9 @@ arrayType.BaseType is not SzArrayTypeSignature && TypeDefinition type = signature.Resolve(interopReferences.RuntimeContext); // For all other cases, first check that the type is projected. Public types from authored - // component assemblies are also considered projected, even without '[WindowsRuntimeMetadata]'. - if (!type.IsProjectedWindowsRuntimeType && !type.IsComponentWindowsRuntimeType) + // component assemblies, and types from reference projection assemblies, are also considered + // projected, even without '[WindowsRuntimeMetadata]'. + if (!type.IsProjectedWindowsRuntimeType && !type.IsComponentWindowsRuntimeType && !type.IsReferenceProjectionWindowsRuntimeType) { return false; } @@ -1088,22 +1171,25 @@ arrayType.BaseType is not SzArrayTypeSignature && /// /// Gets the Windows Runtime metadata name for a , if available. /// - /// The context to assume when resolving types. - /// The Windows Runtime metadata name from the underlying type's WindowsRuntimeMetadataAttribute, or if not found. + /// The instance to use. + /// The Windows Runtime metadata name for the underlying type, or if not found. /// /// /// This method resolves the underlying type definition from the signature and retrieves its Windows Runtime metadata name. /// For generic instance types, it uses the generic type definition. For array types, it uses the base element type. - /// For other types, it resolves the type definition directly. + /// For other types, it resolves the type definition directly. The metadata name is recovered from the implementation + /// projection for types coming from reference projections (see the overload of this method). /// /// - public Utf8String? GetWindowsRuntimeMetadataName(RuntimeContext? runtimeContext) + public Utf8String? GetWindowsRuntimeMetadataName(InteropDefinitions interopDefinitions) { + RuntimeContext? runtimeContext = interopDefinitions.RuntimeContext; + return signature switch { - GenericInstanceTypeSignature generic => generic.GenericType.Resolve(runtimeContext).GetWindowsRuntimeMetadataName(), - ArrayTypeSignature array => array.BaseType.Resolve(runtimeContext).GetWindowsRuntimeMetadataName(), - _ => signature.ToTypeDefOrRef().Resolve(runtimeContext).GetWindowsRuntimeMetadataName() + GenericInstanceTypeSignature generic => generic.GenericType.Resolve(runtimeContext).GetWindowsRuntimeMetadataName(interopDefinitions), + ArrayTypeSignature array => array.BaseType.Resolve(runtimeContext).GetWindowsRuntimeMetadataName(interopDefinitions), + _ => signature.ToTypeDefOrRef().Resolve(runtimeContext).GetWindowsRuntimeMetadataName(interopDefinitions) }; } } diff --git a/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.IEnumeratorElementMarshaller.cs b/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.IEnumeratorElementMarshaller.cs index fa5a979d96..eca50d9d0a 100644 --- a/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.IEnumeratorElementMarshaller.cs +++ b/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.IEnumeratorElementMarshaller.cs @@ -28,11 +28,13 @@ public static class IEnumeratorElementMarshaller /// Creates a for the element marshaller for an unmanaged value type. /// /// The for the type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The resulting element marshaller type. public static TypeDefinition UnmanagedValueType( GenericInstanceTypeSignature enumeratorType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState) { @@ -49,6 +51,7 @@ public static TypeDefinition UnmanagedValueType( interfaceType: interfaceType, convertToUnmanagedInterfaceMethod: interopReferences.IWindowsRuntimeUnmanagedValueTypeElementMarshallerConvertToUnmanaged(elementType, elementAbiType), isValueType: true, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); } @@ -57,11 +60,13 @@ public static TypeDefinition UnmanagedValueType( /// Creates a for the element marshaller for a managed value type. /// /// The for the type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The resulting element marshaller type. public static TypeDefinition ManagedValueType( GenericInstanceTypeSignature enumeratorType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState) { @@ -79,6 +84,7 @@ public static TypeDefinition ManagedValueType( interfaceType: interfaceType, convertToUnmanagedInterfaceMethod: interopReferences.IWindowsRuntimeManagedValueTypeElementMarshallerConvertToUnmanaged(elementType, elementAbiType), isValueType: true, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); @@ -119,11 +125,13 @@ public static TypeDefinition ManagedValueType( /// Creates a for the element marshaller for a type. /// /// The for the type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The resulting element marshaller type. public static TypeDefinition KeyValuePair( GenericInstanceTypeSignature enumeratorType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState) { @@ -144,6 +152,7 @@ public static TypeDefinition KeyValuePair( interfaceType: interfaceType, convertToUnmanagedInterfaceMethod: interopReferences.IWindowsRuntimeKeyValuePairTypeElementMarshallerConvertToUnmanaged(keyType, valueType), isValueType: isValueType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); } @@ -152,11 +161,13 @@ public static TypeDefinition KeyValuePair( /// Creates a for the element marshaller for a type. /// /// The for the type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The resulting element marshaller type. public static TypeDefinition NullableValueType( GenericInstanceTypeSignature enumeratorType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState) { @@ -173,6 +184,7 @@ public static TypeDefinition NullableValueType( interfaceType: interfaceType, convertToUnmanagedInterfaceMethod: interopReferences.IWindowsRuntimeNullableTypeElementMarshallerConvertToUnmanaged(underlyingType), isValueType: true, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); } @@ -181,11 +193,13 @@ public static TypeDefinition NullableValueType( /// Creates a for the element marshaller for a reference type. /// /// The for the type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The resulting element marshaller type. public static TypeDefinition ReferenceType( GenericInstanceTypeSignature enumeratorType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState) { @@ -201,6 +215,7 @@ public static TypeDefinition ReferenceType( interfaceType: interfaceType, convertToUnmanagedInterfaceMethod: interopReferences.IWindowsRuntimeReferenceTypeElementMarshallerConvertToUnmanaged(elementType), isValueType: false, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); } @@ -212,6 +227,7 @@ public static TypeDefinition ReferenceType( /// The interface type the element marshaller type should implement. /// The ConvertToUnmanaged interface method being implemented. /// Indicates whether the element marshaller type should be emitted as a value type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The resulting element marshaller type. @@ -220,6 +236,7 @@ public static TypeDefinition ElementMarshaller( TypeSignature interfaceType, MemberReference convertToUnmanagedInterfaceMethod, bool isValueType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState) { @@ -231,7 +248,7 @@ public static TypeDefinition ElementMarshaller( // We're declaring an 'internal abstract class' type TypeDefinition elementMarshallerType = new( ns: InteropUtf8NameFactory.TypeNamespace(elementType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(elementType, interopReferences.RuntimeContext, "ElementMarshaller"), + name: InteropUtf8NameFactory.TypeName(elementType, interopDefinitions, "ElementMarshaller"), attributes: attributes, baseType: baseType) { @@ -273,4 +290,4 @@ public static TypeDefinition ElementMarshaller( return elementMarshallerType; } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.IReadOnlyCollectionKeyValuePair2.cs b/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.IReadOnlyCollectionKeyValuePair2.cs index 36fdab5649..0f7018eada 100644 --- a/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.IReadOnlyCollectionKeyValuePair2.cs +++ b/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.IReadOnlyCollectionKeyValuePair2.cs @@ -26,6 +26,7 @@ public static class IReadOnlyCollectionKeyValuePair2 /// The for the generic interface type. /// The for the corresponding type. /// The for the corresponding type. + /// The instance to use. /// The instance to use. /// The module that will contain the type being created. /// The resulting marshaller type. @@ -36,6 +37,7 @@ public static void ForwarderAttribute( GenericInstanceTypeSignature readOnlyCollectionType, TypeSignature readOnlyDictionaryType, TypeSignature readOnlyListType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module, out TypeDefinition forwarderAttributeType) @@ -43,7 +45,7 @@ public static void ForwarderAttribute( // We're declaring an 'internal sealed class' type forwarderAttributeType = new( ns: InteropUtf8NameFactory.TypeNamespace(readOnlyCollectionType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(readOnlyCollectionType, interopReferences.RuntimeContext, "ForwarderAttribute"), + name: InteropUtf8NameFactory.TypeName(readOnlyCollectionType, interopDefinitions, "ForwarderAttribute"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, baseType: interopReferences.DynamicInterfaceCastableForwarderAttribute); @@ -99,4 +101,4 @@ public static void ForwarderAttribute( forwarderAttributeType.Methods.Add(isInterfaceImplementedMethod); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.SzArrayElementMarshaller.cs b/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.SzArrayElementMarshaller.cs index e0f41b7e3f..31d223e3d6 100644 --- a/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.SzArrayElementMarshaller.cs +++ b/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.SzArrayElementMarshaller.cs @@ -25,11 +25,13 @@ public static class SzArrayElementMarshaller /// Creates a for the element marshaller for an unmanaged value type. /// /// The for the SZ array type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The resulting element marshaller type. public static TypeDefinition UnmanagedValueType( SzArrayTypeSignature arrayType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState) { @@ -47,6 +49,7 @@ public static TypeDefinition UnmanagedValueType( convertToUnmanagedInterfaceMethod: interopReferences.IWindowsRuntimeUnmanagedValueTypeArrayElementMarshallerConvertToUnmanaged(elementType, elementAbiType), convertToManagedInterfaceMethod: interopReferences.IWindowsRuntimeUnmanagedValueTypeArrayElementMarshallerConvertToManaged(elementType, elementAbiType), isValueType: true, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); } @@ -55,11 +58,13 @@ public static TypeDefinition UnmanagedValueType( /// Creates a for the element marshaller for a managed value type. /// /// The for the SZ array type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The resulting element marshaller type. public static TypeDefinition ManagedValueType( SzArrayTypeSignature arrayType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState) { @@ -78,6 +83,7 @@ public static TypeDefinition ManagedValueType( convertToUnmanagedInterfaceMethod: interopReferences.IWindowsRuntimeManagedValueTypeArrayElementMarshallerConvertToUnmanaged(elementType, elementAbiType), convertToManagedInterfaceMethod: interopReferences.IWindowsRuntimeManagedValueTypeArrayElementMarshallerConvertToManaged(elementType, elementAbiType), isValueType: true, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); @@ -118,11 +124,13 @@ public static TypeDefinition ManagedValueType( /// Creates a for the element marshaller for a type. /// /// The for the SZ array type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The resulting element marshaller type. public static TypeDefinition KeyValuePair( SzArrayTypeSignature arrayType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState) { @@ -147,6 +155,7 @@ public static TypeDefinition KeyValuePair( convertToUnmanagedInterfaceMethod: interopReferences.IWindowsRuntimeKeyValuePairTypeArrayElementMarshallerConvertToUnmanaged(keyType, valueType), convertToManagedInterfaceMethod: interopReferences.IWindowsRuntimeKeyValuePairTypeArrayElementMarshallerConvertToManaged(keyType, valueType), isValueType: isValueType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); } @@ -155,11 +164,13 @@ public static TypeDefinition KeyValuePair( /// Creates a for the element marshaller for a type. /// /// The for the SZ array type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The resulting element marshaller type. public static TypeDefinition NullableValueType( SzArrayTypeSignature arrayType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState) { @@ -177,6 +188,7 @@ public static TypeDefinition NullableValueType( convertToUnmanagedInterfaceMethod: interopReferences.IWindowsRuntimeNullableTypeArrayElementMarshallerConvertToUnmanaged(underlyingType), convertToManagedInterfaceMethod: interopReferences.IWindowsRuntimeNullableTypeArrayElementMarshallerConvertToManaged(underlyingType), isValueType: true, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); } @@ -185,11 +197,13 @@ public static TypeDefinition NullableValueType( /// Creates a for the element marshaller for a reference type. /// /// The for the SZ array type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The resulting element marshaller type. public static TypeDefinition ReferenceType( SzArrayTypeSignature arrayType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState) { @@ -206,6 +220,7 @@ public static TypeDefinition ReferenceType( convertToUnmanagedInterfaceMethod: interopReferences.IWindowsRuntimeReferenceTypeArrayElementMarshallerConvertToUnmanaged(elementType), convertToManagedInterfaceMethod: interopReferences.IWindowsRuntimeReferenceTypeArrayElementMarshallerConvertToManaged(elementType), isValueType: false, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState); } @@ -218,6 +233,7 @@ public static TypeDefinition ReferenceType( /// The ConvertToUnmanaged interface method being implemented. /// The ConvertToManaged interface method being implemented. /// Indicates whether the element marshaller type should be emitted as a value type. + /// The instance to use. /// The instance to use. /// The emit state for this invocation. /// The resulting element marshaller type. @@ -227,6 +243,7 @@ public static TypeDefinition ElementMarshaller( MemberReference convertToUnmanagedInterfaceMethod, MemberReference convertToManagedInterfaceMethod, bool isValueType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, InteropGeneratorEmitState emitState) { @@ -240,7 +257,7 @@ public static TypeDefinition ElementMarshaller( // We're declaring an 'internal abstract class' type TypeDefinition elementMarshallerType = new( ns: InteropUtf8NameFactory.TypeNamespace(arrayType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(arrayType, interopReferences.RuntimeContext, "ElementMarshaller"), + name: InteropUtf8NameFactory.TypeName(arrayType, interopDefinitions, "ElementMarshaller"), attributes: attributes, baseType: baseType) { @@ -312,4 +329,4 @@ public static TypeDefinition ElementMarshaller( return elementMarshallerType; } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.SzArrayMarshaller.cs b/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.SzArrayMarshaller.cs index f86c4007c9..0e6512c7c8 100644 --- a/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.SzArrayMarshaller.cs +++ b/src/WinRT.Interop.Generator/Factories/InteropTypeDefinitionFactory.SzArrayMarshaller.cs @@ -23,10 +23,12 @@ public static class SzArrayMarshaller /// Creates a for the marshaller for a blittable value type. /// /// The for the SZ array type. + /// The instance to use. /// The instance to use. /// The resulting marshaller type. public static TypeDefinition BlittableValueType( SzArrayTypeSignature arrayType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences) { TypeSignature elementType = arrayType.BaseType; @@ -39,6 +41,7 @@ public static TypeDefinition BlittableValueType( copyToManagedMethod: interopReferences.WindowsRuntimeBlittableValueTypeArrayMarshallerCopyToManaged(elementType), disposeMethod: null, freeMethod: interopReferences.WindowsRuntimeBlittableValueTypeArrayMarshallerFree, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); } @@ -47,11 +50,13 @@ public static TypeDefinition BlittableValueType( /// /// The for the SZ array type. /// The element marshaller type produced by . + /// The instance to use. /// The instance to use. /// The resulting marshaller type. public static TypeDefinition UnmanagedValueType( SzArrayTypeSignature arrayType, TypeDefinition elementMarshallerType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences) { TypeSignature elementType = arrayType.BaseType; @@ -66,6 +71,7 @@ public static TypeDefinition UnmanagedValueType( copyToManagedMethod: interopReferences.WindowsRuntimeUnmanagedValueTypeArrayMarshallerCopyToManaged(elementType, elementAbiType, elementMarshallerTypeSignature), disposeMethod: null, freeMethod: interopReferences.WindowsRuntimeBlittableValueTypeArrayMarshallerFree, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); } @@ -74,11 +80,13 @@ public static TypeDefinition UnmanagedValueType( /// /// The for the SZ array type. /// The element marshaller type produced by . + /// The instance to use. /// The instance to use. /// The resulting marshaller type. public static TypeDefinition ManagedValueType( SzArrayTypeSignature arrayType, TypeDefinition elementMarshallerType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences) { TypeSignature elementType = arrayType.BaseType; @@ -93,6 +101,7 @@ public static TypeDefinition ManagedValueType( copyToManagedMethod: interopReferences.WindowsRuntimeManagedValueTypeArrayMarshallerCopyToManaged(elementType, elementAbiType, elementMarshallerTypeSignature), disposeMethod: interopReferences.WindowsRuntimeManagedValueTypeArrayMarshallerDispose(elementType, elementAbiType, elementMarshallerTypeSignature), freeMethod: interopReferences.WindowsRuntimeManagedValueTypeArrayMarshallerFree(elementType, elementAbiType, elementMarshallerTypeSignature), + interopDefinitions: interopDefinitions, interopReferences: interopReferences); } @@ -101,11 +110,13 @@ public static TypeDefinition ManagedValueType( /// /// The for the SZ array type. /// The element marshaller type produced by . + /// The instance to use. /// The instance to use. /// The resulting marshaller type. public static TypeDefinition KeyValuePair( SzArrayTypeSignature arrayType, TypeDefinition elementMarshallerType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences) { GenericInstanceTypeSignature elementType = (GenericInstanceTypeSignature)arrayType.BaseType; @@ -121,6 +132,7 @@ public static TypeDefinition KeyValuePair( copyToManagedMethod: interopReferences.WindowsRuntimeKeyValuePairTypeArrayMarshallerCopyToManaged(keyType, valueType, elementMarshallerTypeSignature), disposeMethod: interopReferences.WindowsRuntimeUnknownArrayMarshallerDispose, freeMethod: interopReferences.WindowsRuntimeUnknownArrayMarshallerFree, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); } @@ -129,11 +141,13 @@ public static TypeDefinition KeyValuePair( /// /// The for the SZ array type. /// The element marshaller type produced by . + /// The instance to use. /// The instance to use. /// The resulting marshaller type. public static TypeDefinition NullableValueType( SzArrayTypeSignature arrayType, TypeDefinition elementMarshallerType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences) { GenericInstanceTypeSignature elementType = (GenericInstanceTypeSignature)arrayType.BaseType; @@ -148,6 +162,7 @@ public static TypeDefinition NullableValueType( copyToManagedMethod: interopReferences.WindowsRuntimeNullableTypeArrayMarshallerCopyToManaged(underlyingType, elementMarshallerTypeSignature), disposeMethod: interopReferences.WindowsRuntimeUnknownArrayMarshallerDispose, freeMethod: interopReferences.WindowsRuntimeUnknownArrayMarshallerFree, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); } @@ -156,11 +171,13 @@ public static TypeDefinition NullableValueType( /// /// The for the SZ array type. /// The element marshaller type produced by . + /// The instance to use. /// The instance to use. /// The resulting marshaller type. public static TypeDefinition ReferenceType( SzArrayTypeSignature arrayType, TypeDefinition elementMarshallerType, + InteropDefinitions interopDefinitions, InteropReferences interopReferences) { TypeSignature elementType = arrayType.BaseType; @@ -174,6 +191,7 @@ public static TypeDefinition ReferenceType( copyToManagedMethod: interopReferences.WindowsRuntimeReferenceTypeArrayMarshallerCopyToManaged(elementType, elementMarshallerTypeSignature), disposeMethod: interopReferences.WindowsRuntimeUnknownArrayMarshallerDispose, freeMethod: interopReferences.WindowsRuntimeUnknownArrayMarshallerFree, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); } @@ -181,9 +199,10 @@ public static TypeDefinition ReferenceType( /// Creates a for the marshaller for the type. /// /// The for the SZ array type. + /// The instance to use. /// The instance to use. /// The resulting marshaller type. - public static TypeDefinition Object(SzArrayTypeSignature arrayType, InteropReferences interopReferences) + public static TypeDefinition Object(SzArrayTypeSignature arrayType, InteropDefinitions interopDefinitions, InteropReferences interopReferences) { return Marshaller( arrayType: arrayType, @@ -193,6 +212,7 @@ public static TypeDefinition Object(SzArrayTypeSignature arrayType, InteropRefer copyToManagedMethod: interopReferences.WindowsRuntimeObjectArrayMarshallerCopyToManaged, disposeMethod: interopReferences.WindowsRuntimeUnknownArrayMarshallerDispose, freeMethod: interopReferences.WindowsRuntimeUnknownArrayMarshallerFree, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); } @@ -200,9 +220,10 @@ public static TypeDefinition Object(SzArrayTypeSignature arrayType, InteropRefer /// Creates a for the marshaller for the type. /// /// The for the SZ array type. + /// The instance to use. /// The instance to use. /// The resulting marshaller type. - public static TypeDefinition String(SzArrayTypeSignature arrayType, InteropReferences interopReferences) + public static TypeDefinition String(SzArrayTypeSignature arrayType, InteropDefinitions interopDefinitions, InteropReferences interopReferences) { return Marshaller( arrayType: arrayType, @@ -212,6 +233,7 @@ public static TypeDefinition String(SzArrayTypeSignature arrayType, InteropRefer copyToManagedMethod: interopReferences.HStringArrayMarshallerCopyToManaged, disposeMethod: interopReferences.HStringArrayMarshallerDispose, freeMethod: interopReferences.HStringArrayMarshallerFree, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); } @@ -219,9 +241,10 @@ public static TypeDefinition String(SzArrayTypeSignature arrayType, InteropRefer /// Creates a for the marshaller for the type. /// /// The for the SZ array type. + /// The instance to use. /// The instance to use. /// The resulting marshaller type. - public static TypeDefinition Type(SzArrayTypeSignature arrayType, InteropReferences interopReferences) + public static TypeDefinition Type(SzArrayTypeSignature arrayType, InteropDefinitions interopDefinitions, InteropReferences interopReferences) { return Marshaller( arrayType: arrayType, @@ -231,6 +254,7 @@ public static TypeDefinition Type(SzArrayTypeSignature arrayType, InteropReferen copyToManagedMethod: interopReferences.TypeArrayMarshallerCopyToManaged, disposeMethod: interopReferences.TypeArrayMarshallerDispose, freeMethod: interopReferences.TypeArrayMarshallerFree, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); } @@ -238,9 +262,10 @@ public static TypeDefinition Type(SzArrayTypeSignature arrayType, InteropReferen /// Creates a for the marshaller for the type. /// /// The for the SZ array type. + /// The instance to use. /// The instance to use. /// The resulting marshaller type. - public static TypeDefinition Exception(SzArrayTypeSignature arrayType, InteropReferences interopReferences) + public static TypeDefinition Exception(SzArrayTypeSignature arrayType, InteropDefinitions interopDefinitions, InteropReferences interopReferences) { return Marshaller( arrayType: arrayType, @@ -250,6 +275,7 @@ public static TypeDefinition Exception(SzArrayTypeSignature arrayType, InteropRe copyToManagedMethod: interopReferences.ExceptionArrayMarshallerCopyToManaged, freeMethod: interopReferences.WindowsRuntimeBlittableValueTypeArrayMarshallerFree, disposeMethod: null, + interopDefinitions: interopDefinitions, interopReferences: interopReferences); } @@ -263,6 +289,7 @@ public static TypeDefinition Exception(SzArrayTypeSignature arrayType, InteropRe /// The CopyToManaged implementation method to call. /// The Dispose implementation method to call, if applicable. /// The Free implementation method to call. + /// The instance to use. /// The instance to use. /// The resulting marshaller type. private static TypeDefinition Marshaller( @@ -273,6 +300,7 @@ private static TypeDefinition Marshaller( IMethodDescriptor copyToManagedMethod, IMethodDescriptor? disposeMethod, IMethodDescriptor freeMethod, + InteropDefinitions interopDefinitions, InteropReferences interopReferences) { TypeSignature elementType = arrayType.BaseType; @@ -281,7 +309,7 @@ private static TypeDefinition Marshaller( // We're declaring an 'internal static class' type TypeDefinition marshallerType = new( ns: InteropUtf8NameFactory.TypeNamespace(arrayType, interopReferences.RuntimeContext), - name: InteropUtf8NameFactory.TypeName(arrayType, interopReferences.RuntimeContext, "Marshaller"), + name: InteropUtf8NameFactory.TypeName(arrayType, interopDefinitions, "Marshaller"), attributes: TypeAttributes.AutoLayout | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, baseType: interopReferences.Object.ToTypeDefOrRef()); @@ -436,4 +464,4 @@ private static TypeDefinition Marshaller( return marshallerType; } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Factories/InteropUtf8NameFactory.cs b/src/WinRT.Interop.Generator/Factories/InteropUtf8NameFactory.cs index 866d3d5b87..bf6da83b2d 100644 --- a/src/WinRT.Interop.Generator/Factories/InteropUtf8NameFactory.cs +++ b/src/WinRT.Interop.Generator/Factories/InteropUtf8NameFactory.cs @@ -9,6 +9,7 @@ using AsmResolver.DotNet; using AsmResolver.DotNet.Signatures; using AsmResolver.PE.DotNet.Metadata.Tables; +using WindowsRuntime.InteropGenerator.References; namespace WindowsRuntime.InteropGenerator.Factories; @@ -55,10 +56,10 @@ public static Utf8String TypeNamespace(TypeSignature typeSignature, RuntimeConte /// Gets the name for a generated interop type. /// /// The source for the type to generate. - /// The context to assume when resolving types. + /// The instance to use (for resolving types and locating implementation projections). /// The optional name suffix to use. /// The name to use. - public static Utf8String TypeName(TypeSignature typeSignature, RuntimeContext? runtimeContext, string? nameSuffix = null) + public static Utf8String TypeName(TypeSignature typeSignature, InteropDefinitions interopDefinitions, string? nameSuffix = null) { DefaultInterpolatedStringHandler interpolatedStringHandler = new(literalLength: 2, formattedCount: 1); @@ -66,7 +67,7 @@ public static Utf8String TypeName(TypeSignature typeSignature, RuntimeContext? r static void AppendTypeName( ref DefaultInterpolatedStringHandler interpolatedStringHandler, TypeSignature typeSignature, - RuntimeContext? runtimeContext, + InteropDefinitions interopDefinitions, int depth) { // Special case for well known type identifiers (eg. 'string', 'int', etc.) @@ -82,7 +83,7 @@ static void AppendTypeName( { interpolatedStringHandler.AppendLiteral("<"); - AppendTypeName(ref interpolatedStringHandler, arrayTypeSignature.BaseType, runtimeContext, depth); + AppendTypeName(ref interpolatedStringHandler, arrayTypeSignature.BaseType, interopDefinitions, depth); interpolatedStringHandler.AppendLiteral(">Array"); } @@ -91,7 +92,7 @@ static void AppendTypeName( Utf8String assemblyName = AssemblyNameOrWellKnownIdentifier( assemblyName: typeSignature.Scope!.GetAssembly()!.Name!, typeSignature: typeSignature, - runtimeContext: runtimeContext); + interopDefinitions: interopDefinitions); // Each type name uses this format: 'TYPE_NAME' interpolatedStringHandler.AppendLiteral("<"); @@ -108,7 +109,7 @@ static void AppendTypeName( // type descriptor here, because we also want to detect arrays with an element type that's generic. if (typeSignature is GenericInstanceTypeSignature genericInstanceTypeSignature) { - AppendTypeArguments(ref interpolatedStringHandler, genericInstanceTypeSignature, runtimeContext, depth); + AppendTypeArguments(ref interpolatedStringHandler, genericInstanceTypeSignature, interopDefinitions, depth); } } } @@ -157,7 +158,7 @@ static void AppendRawTypeName( static void AppendTypeArguments( ref DefaultInterpolatedStringHandler interpolatedStringHandler, GenericInstanceTypeSignature type, - RuntimeContext? runtimeContext, + InteropDefinitions interopDefinitions, int depth) { interpolatedStringHandler.AppendLiteral("<"); @@ -172,14 +173,14 @@ static void AppendTypeArguments( // Append the type argument with the same format as the root type. This is // important to ensure that nested generic types will be handled correctly. - AppendTypeName(ref interpolatedStringHandler, typeArgumentSignature, runtimeContext, depth: depth + 1); + AppendTypeName(ref interpolatedStringHandler, typeArgumentSignature, interopDefinitions, depth: depth + 1); } interpolatedStringHandler.AppendLiteral(">"); } // Append the full type name first - AppendTypeName(ref interpolatedStringHandler, typeSignature, runtimeContext, depth: 0); + AppendTypeName(ref interpolatedStringHandler, typeSignature, interopDefinitions, depth: 0); // Append the suffix, if we have one interpolatedStringHandler.AppendFormatted(nameSuffix); @@ -204,13 +205,13 @@ static void AppendTypeArguments( /// /// The input assembly name to convert. /// The type signature for which to convert. - /// The context to assume when resolving the type. + /// The instance to use. /// The resulting assembly name to use. [return: NotNullIfNotNull(nameof(assemblyName))] private static Utf8String? AssemblyNameOrWellKnownIdentifier( Utf8String? assemblyName, TypeSignature typeSignature, - RuntimeContext? runtimeContext) + InteropDefinitions interopDefinitions) { // Replace some assembly names with well known constants, to make the names more compact return assemblyName switch @@ -218,7 +219,7 @@ static void AppendTypeArguments( { Value: "System.Runtime" } => "#corlib"u8, { Value: "Microsoft.Windows.SDK.NET" or "Microsoft.Windows.UI.Xaml" } => "#Windows"u8, { Value: "WinRT.Runtime" } => "#CsWinRT"u8, - _ => typeSignature.GetWindowsRuntimeMetadataName(runtimeContext) ?? assemblyName + _ => typeSignature.GetWindowsRuntimeMetadataName(interopDefinitions) ?? assemblyName }; } diff --git a/src/WinRT.Interop.Generator/Generation/InteropGenerator.Emit.cs b/src/WinRT.Interop.Generator/Generation/InteropGenerator.Emit.cs index 012efd323f..7c3752cf19 100644 --- a/src/WinRT.Interop.Generator/Generation/InteropGenerator.Emit.cs +++ b/src/WinRT.Interop.Generator/Generation/InteropGenerator.Emit.cs @@ -146,12 +146,12 @@ private static void Emit(InteropGeneratorArgs args, InteropGeneratorDiscoverySta args.Token.ThrowIfCancellationRequested(); // Emit interop types for 'IReadOnlyCollection>' types - DefineIReadOnlyCollectionKeyValuePair2Types(args, discoveryState, emitState, interopReferences, module); + DefineIReadOnlyCollectionKeyValuePair2Types(args, discoveryState, emitState, interopDefinitions, interopReferences, module); args.Token.ThrowIfCancellationRequested(); // Emit interop types for 'ICollection>' types - DefineICollectionKeyValuePair2Types(args, discoveryState, emitState, interopReferences, module); + DefineICollectionKeyValuePair2Types(args, discoveryState, emitState, interopDefinitions, interopReferences, module); args.Token.ThrowIfCancellationRequested(); @@ -329,6 +329,7 @@ private static void DefineGenericDelegateTypes( delegateType: typeSignature, nativeDelegateType: nativeDelegateType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition delegateComWrappersCallbackType); @@ -338,6 +339,7 @@ private static void DefineGenericDelegateTypes( delegateComWrappersCallbackType: delegateComWrappersCallbackType, get_IidMethod: get_IidMethod, get_ReferenceIidMethod: get_ReferenceIidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -384,6 +386,7 @@ private static void DefineGenericDelegateTypes( InteropTypeDefinitionBuilder.Delegate.Proxy( delegateType: typeSignature, comWrappersMarshallerAttributeType: delegateComWrappersMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -402,6 +405,7 @@ private static void DefineGenericDelegateTypes( InteropTypeDefinitionBuilder.EventSource.EventHandler1( delegateType: typeSignature, marshallerType: marshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, eventSourceType: out _); @@ -411,6 +415,7 @@ private static void DefineGenericDelegateTypes( InteropTypeDefinitionBuilder.EventSource.EventHandler2( delegateType: typeSignature, marshallerType: marshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, eventSourceType: out _); @@ -420,6 +425,7 @@ private static void DefineGenericDelegateTypes( InteropTypeDefinitionBuilder.EventSource.VectorChangedEventHandler1( delegateType: typeSignature, marshallerType: marshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -430,6 +436,7 @@ private static void DefineGenericDelegateTypes( InteropTypeDefinitionBuilder.EventSource.MapChangedEventHandler2( delegateType: typeSignature, marshallerType: marshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -476,6 +483,7 @@ private static void DefineIEnumeratorTypes( InteropTypeDefinitionBuilder.IEnumerator1.ElementMarshaller( enumeratorType: typeSignature, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -500,6 +508,7 @@ private static void DefineIEnumeratorTypes( InteropTypeDefinitionBuilder.IEnumerator1.Methods( enumeratorType: typeSignature, iteratorMethodsType: iteratorMethodsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, enumeratorMethodsType: out _); @@ -507,6 +516,7 @@ private static void DefineIEnumeratorTypes( InteropTypeDefinitionBuilder.IEnumerator1.NativeObject( enumeratorType: typeSignature, iteratorMethodsType: iteratorMethodsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, nativeObjectType: out TypeDefinition nativeObjectType); @@ -515,6 +525,7 @@ private static void DefineIEnumeratorTypes( enumeratorType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -524,6 +535,7 @@ private static void DefineIEnumeratorTypes( enumeratorType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, marshallerType: out TypeDefinition enumeratorComWrappersMarshallerType); @@ -532,6 +544,7 @@ private static void DefineIEnumeratorTypes( typeSignature: typeSignature, interfaceComWrappersCallbackType: enumeratorComWrappersCallbackType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -549,6 +562,7 @@ private static void DefineIEnumeratorTypes( InteropTypeDefinitionBuilder.Proxy( interfaceType: typeSignature, comWrappersMarshallerAttributeType: enumeratorComWrappersMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -602,6 +616,7 @@ private static void DefineIEnumerableTypes( InteropTypeDefinitionBuilder.IEnumerable1.Interface( enumerableType: typeSignature, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -626,6 +641,7 @@ private static void DefineIEnumerableTypes( InteropTypeDefinitionBuilder.IEnumerable1.Methods( enumerableType: typeSignature, iterableMethodsType: iterableMethodsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, enumerableMethodsType: out _); @@ -633,6 +649,7 @@ private static void DefineIEnumerableTypes( InteropTypeDefinitionBuilder.IEnumerable1.NativeObject( enumerableType: typeSignature, iterableMethodsType: iterableMethodsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, nativeObjectType: out TypeDefinition nativeObjectType); @@ -641,6 +658,7 @@ private static void DefineIEnumerableTypes( enumerableType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -650,6 +668,7 @@ private static void DefineIEnumerableTypes( enumerableType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, marshallerType: out TypeDefinition enumerableComWrappersMarshallerType); @@ -658,6 +677,7 @@ private static void DefineIEnumerableTypes( typeSignature: typeSignature, interfaceComWrappersCallbackType: enumerableComWrappersCallbackType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -675,6 +695,7 @@ private static void DefineIEnumerableTypes( InteropTypeDefinitionBuilder.Proxy( interfaceType: typeSignature, comWrappersMarshallerAttributeType: enumerableComWrappersMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -744,6 +765,7 @@ private static void DefineIReadOnlyListTypes( InteropTypeDefinitionBuilder.IReadOnlyList1.IVectorViewMethods( readOnlyListType: typeSignature, vftblType: vftblType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -752,6 +774,7 @@ private static void DefineIReadOnlyListTypes( InteropTypeDefinitionBuilder.IReadOnlyList1.Methods( readOnlyListType: typeSignature, vectorViewMethodsType: vectorViewMethodsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -760,6 +783,7 @@ private static void DefineIReadOnlyListTypes( InteropTypeDefinitionBuilder.IReadOnlyList1.NativeObject( readOnlyListType: typeSignature, vectorViewMethodsType: vectorViewMethodsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -769,6 +793,7 @@ private static void DefineIReadOnlyListTypes( readOnlyListType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -778,6 +803,7 @@ private static void DefineIReadOnlyListTypes( readOnlyListType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition readOnlyListComWrappersMarshallerType); @@ -786,6 +812,7 @@ private static void DefineIReadOnlyListTypes( typeSignature: typeSignature, interfaceComWrappersCallbackType: readOnlyListComWrappersCallbackType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -803,6 +830,7 @@ private static void DefineIReadOnlyListTypes( InteropTypeDefinitionBuilder.Proxy( interfaceType: typeSignature, comWrappersMarshallerAttributeType: readOnlyListComWrappersMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -856,6 +884,7 @@ private static void DefineIListTypes( InteropTypeDefinitionBuilder.IList1.Interface( listType: typeSignature, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -880,6 +909,7 @@ private static void DefineIListTypes( InteropTypeDefinitionBuilder.IList1.IVectorMethods( listType: typeSignature, vftblType: vftblType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -888,6 +918,7 @@ private static void DefineIListTypes( InteropTypeDefinitionBuilder.IList1.Methods( listType: typeSignature, vectorMethodsType: vectorMethodsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -896,6 +927,7 @@ private static void DefineIListTypes( InteropTypeDefinitionBuilder.IList1.NativeObject( listType: typeSignature, vectorMethodsType: vectorMethodsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -905,6 +937,7 @@ private static void DefineIListTypes( listType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -914,6 +947,7 @@ private static void DefineIListTypes( listType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition listComWrappersMarshallerType); @@ -922,6 +956,7 @@ private static void DefineIListTypes( typeSignature: typeSignature, interfaceComWrappersCallbackType: listComWrappersCallbackType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -939,6 +974,7 @@ private static void DefineIListTypes( InteropTypeDefinitionBuilder.Proxy( interfaceType: typeSignature, comWrappersMarshallerAttributeType: listComWrappersMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1009,6 +1045,7 @@ private static void DefineIReadOnlyDictionaryTypes( InteropTypeDefinitionBuilder.IReadOnlyDictionary2.IMapViewMethods( readOnlyDictionaryType: typeSignature, vftblType: vftblType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1017,6 +1054,7 @@ private static void DefineIReadOnlyDictionaryTypes( InteropTypeDefinitionBuilder.IReadOnlyDictionary2.Methods( readOnlyDictionaryType: typeSignature, mapViewMethodsType: mapViewMethodsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1025,6 +1063,7 @@ private static void DefineIReadOnlyDictionaryTypes( InteropTypeDefinitionBuilder.IReadOnlyDictionary2.NativeObject( readOnlyDictionaryType: typeSignature, mapViewMethodsType: mapViewMethodsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1034,6 +1073,7 @@ private static void DefineIReadOnlyDictionaryTypes( readOnlyDictionaryType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1043,6 +1083,7 @@ private static void DefineIReadOnlyDictionaryTypes( readOnlyDictionaryType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition readOnlyDictionaryComWrappersMarshallerType); @@ -1051,6 +1092,7 @@ private static void DefineIReadOnlyDictionaryTypes( typeSignature: typeSignature, interfaceComWrappersCallbackType: readOnlyDictionaryComWrappersCallbackType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1068,6 +1110,7 @@ private static void DefineIReadOnlyDictionaryTypes( InteropTypeDefinitionBuilder.Proxy( interfaceType: typeSignature, comWrappersMarshallerAttributeType: readOnlyDictionaryComWrappersMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1121,6 +1164,7 @@ private static void DefineIDictionaryTypes( InteropTypeDefinitionBuilder.IDictionary2.Interface( dictionaryType: typeSignature, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1146,6 +1190,7 @@ private static void DefineIDictionaryTypes( InteropTypeDefinitionBuilder.IDictionary2.IMapMethods( dictionaryType: typeSignature, vftblType: vftblType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1154,6 +1199,7 @@ private static void DefineIDictionaryTypes( InteropTypeDefinitionBuilder.IDictionary2.Methods( dictionaryType: typeSignature, mapMethodsType: mapMethodsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1162,6 +1208,7 @@ private static void DefineIDictionaryTypes( InteropTypeDefinitionBuilder.IDictionary2.NativeObject( dictionaryType: typeSignature, mapMethodsType: mapMethodsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1171,6 +1218,7 @@ private static void DefineIDictionaryTypes( dictionaryType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1180,6 +1228,7 @@ private static void DefineIDictionaryTypes( dictionaryType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition dictionaryComWrappersMarshallerType); @@ -1188,6 +1237,7 @@ private static void DefineIDictionaryTypes( typeSignature: typeSignature, interfaceComWrappersCallbackType: dictionaryComWrappersCallbackType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1205,6 +1255,7 @@ private static void DefineIDictionaryTypes( InteropTypeDefinitionBuilder.Proxy( interfaceType: typeSignature, comWrappersMarshallerAttributeType: dictionaryComWrappersMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1248,6 +1299,7 @@ private static void DefineKeyValuePairTypes( try { InteropTypeDefinitionBuilder.KeyValuePair.Methods( + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, methodsType: out methodsType); @@ -1302,6 +1354,7 @@ private static void DefineKeyValuePairTypes( get_IidMethod: get_IidMethod, keyAccessorMethod: keyAccessorMethod, valueAccessorMethod: valueAccessorMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1320,6 +1373,7 @@ private static void DefineKeyValuePairTypes( InteropTypeDefinitionBuilder.KeyValuePair.Proxy( keyValuePairType: typeSignature, comWrappersMarshallerAttributeType: marshallerAttributeType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1388,6 +1442,7 @@ private static void DefineIMapChangedEventArgsTypes( InteropTypeDefinitionBuilder.IMapChangedEventArgs1.NativeObject( argsType: typeSignature, argsMethodsType: argsMethodsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition nativeObjectType); @@ -1396,6 +1451,7 @@ private static void DefineIMapChangedEventArgsTypes( argsType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1405,6 +1461,7 @@ private static void DefineIMapChangedEventArgsTypes( argsType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition argsComWrappersMarshallerType); @@ -1413,6 +1470,7 @@ private static void DefineIMapChangedEventArgsTypes( typeSignature: typeSignature, interfaceComWrappersCallbackType: argsComWrappersCallbackType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1430,6 +1488,7 @@ private static void DefineIMapChangedEventArgsTypes( InteropTypeDefinitionBuilder.Proxy( interfaceType: typeSignature, comWrappersMarshallerAttributeType: argsComWrappersMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1490,6 +1549,7 @@ private static void DefineIObservableVectorTypes( InteropTypeDefinitionBuilder.IObservableVector1.EventSourceFactory( vectorType: typeSignature, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1497,6 +1557,7 @@ private static void DefineIObservableVectorTypes( InteropTypeDefinitionBuilder.IObservableVector1.EventSourceCallback( vectorType: typeSignature, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1505,6 +1566,7 @@ private static void DefineIObservableVectorTypes( InteropTypeDefinitionBuilder.IObservableVector1.Methods( vectorType: typeSignature, eventSourceCallbackType: callbackType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, methodsType: out TypeDefinition methodsType); @@ -1512,6 +1574,7 @@ private static void DefineIObservableVectorTypes( InteropTypeDefinitionBuilder.IObservableVector1.NativeObject( vectorType: typeSignature, factoryType: factoryType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1521,6 +1584,7 @@ private static void DefineIObservableVectorTypes( vectorType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1530,6 +1594,7 @@ private static void DefineIObservableVectorTypes( vectorType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition comWrappersMarshallerType); @@ -1538,6 +1603,7 @@ private static void DefineIObservableVectorTypes( typeSignature: typeSignature, interfaceComWrappersCallbackType: comWrappersCallbackType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1555,6 +1621,7 @@ private static void DefineIObservableVectorTypes( InteropTypeDefinitionBuilder.Proxy( interfaceType: typeSignature, comWrappersMarshallerAttributeType: comWrappersMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1615,6 +1682,7 @@ private static void DefineIObservableMapTypes( InteropTypeDefinitionBuilder.IObservableMap2.EventSourceFactory( mapType: typeSignature, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1622,6 +1690,7 @@ private static void DefineIObservableMapTypes( InteropTypeDefinitionBuilder.IObservableMap2.EventSourceCallback( mapType: typeSignature, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1630,6 +1699,7 @@ private static void DefineIObservableMapTypes( InteropTypeDefinitionBuilder.IObservableMap2.Methods( mapType: typeSignature, eventSourceCallbackType: callbackType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, methodsType: out TypeDefinition methodsType); @@ -1637,6 +1707,7 @@ private static void DefineIObservableMapTypes( InteropTypeDefinitionBuilder.IObservableMap2.NativeObject( mapType: typeSignature, factoryType: factoryType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1646,6 +1717,7 @@ private static void DefineIObservableMapTypes( mapType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1655,6 +1727,7 @@ private static void DefineIObservableMapTypes( mapType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition comWrappersMarshallerType); @@ -1663,6 +1736,7 @@ private static void DefineIObservableMapTypes( typeSignature: typeSignature, interfaceComWrappersCallbackType: comWrappersCallbackType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1680,6 +1754,7 @@ private static void DefineIObservableMapTypes( InteropTypeDefinitionBuilder.Proxy( interfaceType: typeSignature, comWrappersMarshallerAttributeType: comWrappersMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1749,6 +1824,7 @@ private static void DefineIAsyncActionWithProgressTypes( InteropTypeDefinitionBuilder.IAsyncActionWithProgress1.NativeObject( actionType: typeSignature, actionMethodsType: actionMethodsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition nativeObjectType); @@ -1757,6 +1833,7 @@ private static void DefineIAsyncActionWithProgressTypes( actionType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1766,6 +1843,7 @@ private static void DefineIAsyncActionWithProgressTypes( actionType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition actionComWrappersMarshallerType); @@ -1774,6 +1852,7 @@ private static void DefineIAsyncActionWithProgressTypes( typeSignature: typeSignature, interfaceComWrappersCallbackType: actionComWrappersCallbackType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1791,6 +1870,7 @@ private static void DefineIAsyncActionWithProgressTypes( InteropTypeDefinitionBuilder.Proxy( interfaceType: typeSignature, comWrappersMarshallerAttributeType: actionComWrappersMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1860,6 +1940,7 @@ private static void DefineIAsyncOperationTypes( InteropTypeDefinitionBuilder.IAsyncOperation1.NativeObject( operationType: typeSignature, operationMethodsType: operationMethodsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition nativeObjectType); @@ -1868,6 +1949,7 @@ private static void DefineIAsyncOperationTypes( operationType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1877,6 +1959,7 @@ private static void DefineIAsyncOperationTypes( operationType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition operationComWrappersMarshallerType); @@ -1885,6 +1968,7 @@ private static void DefineIAsyncOperationTypes( typeSignature: typeSignature, interfaceComWrappersCallbackType: operationComWrappersCallbackType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -1902,6 +1986,7 @@ private static void DefineIAsyncOperationTypes( InteropTypeDefinitionBuilder.Proxy( interfaceType: typeSignature, comWrappersMarshallerAttributeType: operationComWrappersMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1971,6 +2056,7 @@ private static void DefineIAsyncOperationWithProgressTypes( InteropTypeDefinitionBuilder.IAsyncOperationWithProgress2.NativeObject( operationType: typeSignature, operationMethodsType: operationMethodsType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition nativeObjectType); @@ -1979,6 +2065,7 @@ private static void DefineIAsyncOperationWithProgressTypes( operationType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -1988,6 +2075,7 @@ private static void DefineIAsyncOperationWithProgressTypes( operationType: typeSignature, nativeObjectType: nativeObjectType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition operationComWrappersMarshallerType); @@ -1996,6 +2084,7 @@ private static void DefineIAsyncOperationWithProgressTypes( typeSignature: typeSignature, interfaceComWrappersCallbackType: operationComWrappersCallbackType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -2013,6 +2102,7 @@ private static void DefineIAsyncOperationWithProgressTypes( InteropTypeDefinitionBuilder.Proxy( interfaceType: typeSignature, comWrappersMarshallerAttributeType: operationComWrappersMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -2039,12 +2129,14 @@ private static void DefineIAsyncOperationWithProgressTypes( /// /// /// The emit state for this invocation. + /// The instance to use. /// The instance to use. /// The interop module being built. private static void DefineIReadOnlyCollectionKeyValuePair2Types( InteropGeneratorArgs args, InteropGeneratorDiscoveryState discoveryState, InteropGeneratorEmitState emitState, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module) { @@ -2065,6 +2157,7 @@ private static void DefineIReadOnlyCollectionKeyValuePair2Types( { InteropTypeDefinitionBuilder.IReadOnlyCollectionKeyValuePair2.ForwarderAttribute( readOnlyCollectionType: readOnlyCollectionType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, forwarderAttributeType: out TypeDefinition forwarderAttributeType); @@ -2072,6 +2165,7 @@ private static void DefineIReadOnlyCollectionKeyValuePair2Types( InteropTypeDefinitionBuilder.IReadOnlyCollectionKeyValuePair2.InterfaceImpl( readOnlyCollectionType: readOnlyCollectionType, forwarderAttributeType: forwarderAttributeType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -2096,12 +2190,14 @@ private static void DefineIReadOnlyCollectionKeyValuePair2Types( /// /// /// The emit state for this invocation. + /// The instance to use. /// The instance to use. /// The interop module being built. private static void DefineICollectionKeyValuePair2Types( InteropGeneratorArgs args, InteropGeneratorDiscoveryState discoveryState, InteropGeneratorEmitState emitState, + InteropDefinitions interopDefinitions, InteropReferences interopReferences, ModuleDefinition module) { @@ -2122,6 +2218,7 @@ private static void DefineICollectionKeyValuePair2Types( { InteropTypeDefinitionBuilder.ICollectionKeyValuePair2.ForwarderAttribute( collectionType: collectionType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, forwarderAttributeType: out TypeDefinition forwarderAttributeType); @@ -2129,6 +2226,7 @@ private static void DefineICollectionKeyValuePair2Types( InteropTypeDefinitionBuilder.ICollectionKeyValuePair2.InterfaceImpl( collectionType: collectionType, forwarderAttributeType: forwarderAttributeType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -2179,6 +2277,7 @@ private static void DefineSzArrayTypes( InteropTypeDefinitionBuilder.SzArray.Marshaller( arrayType: typeSignature, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, emitState: emitState, module: module, @@ -2187,6 +2286,7 @@ private static void DefineSzArrayTypes( InteropTypeDefinitionBuilder.SzArray.ComWrappersCallback( arrayType: typeSignature, marshallerType: marshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition arrayComWrappersCallbackType); @@ -2218,6 +2318,7 @@ private static void DefineSzArrayTypes( arrayInterfaceEntriesImplType: arrayInterfaceEntriesImplType, arrayComWrappersCallbackType: arrayComWrappersCallbackType, get_IidMethod: get_IidMethod, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition arrayComWrappersMarshallerType); @@ -2225,6 +2326,7 @@ private static void DefineSzArrayTypes( InteropTypeDefinitionBuilder.SzArray.Proxy( arrayType: typeSignature, comWrappersMarshallerAttributeType: arrayComWrappersMarshallerType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -2442,6 +2544,7 @@ private static void DefineUserDefinedTypes( userDefinedType: typeSignature, interfaceEntriesType: interfaceEntriesType, interfaceEntriesImplType: interfaceEntriesImplType, + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, out TypeDefinition comWrappersMarshallerType); @@ -2465,6 +2568,7 @@ private static void DefineUserDefinedTypes( InteropTypeDefinitionBuilder.UserDefinedType.Proxy( userDefinedType: typeSignature, comWrappersMarshallerAttributeType: marshallerAttributeMap[vtableTypes], + interopDefinitions: interopDefinitions, interopReferences: interopReferences, module: module, useWindowsUIXamlProjections: args.UseWindowsUIXamlProjections, @@ -2647,4 +2751,4 @@ private static void WriteInteropModuleToDisk(InteropGeneratorArgs args, ModuleDe WellKnownInteropExceptions.EmitDllError(e).ThrowOrAttach(e); } } -} \ No newline at end of file +} diff --git a/src/WinRT.Interop.Generator/Helpers/SignatureGenerator.cs b/src/WinRT.Interop.Generator/Helpers/SignatureGenerator.cs index d790a5e6ae..e01c9a9b0a 100644 --- a/src/WinRT.Interop.Generator/Helpers/SignatureGenerator.cs +++ b/src/WinRT.Interop.Generator/Helpers/SignatureGenerator.cs @@ -163,15 +163,8 @@ private static bool TryGetIIDFromAttribute( // These are only needed to generate signatures, so we hide them from the reference assemblies, as they're not useful there. if (type.IsDelegate) { - // Determine the right implementation projection .dll to use for the lookup - ModuleDefinition? projectionModule = type.IsProjectedWindowsSdkType - ? interopDefinitions.WindowsRuntimeSdkProjectionModule - : type.IsProjectedWindowsSdkXamlType - ? interopDefinitions.WindowsRuntimeSdkXamlProjectionModule - : interopDefinitions.WindowsRuntimeProjectionModule; - // Try to get the implementation type via a fast lookup, if we did get a valid projection module - if (projectionModule?.GetTopLevelTypesLookup().TryGetValue((type.Namespace, type.Name), out TypeDefinition? projectedType) is true) + if (type.GetImplementationProjectionModule(interopDefinitions)?.GetTopLevelTypesLookup().TryGetValue((type.Namespace, type.Name), out TypeDefinition? projectedType) is true) { return projectedType.TryGetGuidAttribute(interopReferences, out iid); } @@ -205,11 +198,7 @@ private static bool TryGetDefaultInterfaceFromAttribute( [NotNullWhen(true)] out TypeSignature? defaultInterface) { // Determine the right implementation projection .dll (see notes above) - ModuleDefinition? projectionModule = type.IsProjectedWindowsSdkType - ? interopDefinitions.WindowsRuntimeSdkProjectionModule - : type.IsProjectedWindowsSdkXamlType - ? interopDefinitions.WindowsRuntimeSdkXamlProjectionModule - : interopDefinitions.WindowsRuntimeProjectionModule; + ModuleDefinition? projectionModule = type.GetImplementationProjectionModule(interopDefinitions); // Use the cached default interfaces lookup for O(1) lookups by (Namespace, Name) key if (projectionModule?.GetDefaultInterfacesLookup().TryGetValue((type.Namespace, type.Name), out TypeSignature? signature) is true) diff --git a/src/WinRT.Interop.Generator/References/InteropDefinitions.cs b/src/WinRT.Interop.Generator/References/InteropDefinitions.cs index 3fb8dd5c3c..b105b96121 100644 --- a/src/WinRT.Interop.Generator/References/InteropDefinitions.cs +++ b/src/WinRT.Interop.Generator/References/InteropDefinitions.cs @@ -53,6 +53,11 @@ public InteropDefinitions( WindowsRuntimeComponentModule = windowsRuntimeComponentModule; } + /// + /// Gets the currently in use. + /// + public RuntimeContext RuntimeContext => _interopReferences.RuntimeContext; + /// /// Gets the for the Windows Runtime projection assembly for the Windows SDK (i.e. WinRT.Sdk.Projection.dll). /// diff --git a/src/WinRT.Interop.Generator/Resolvers/InteropImplTypeResolver.cs b/src/WinRT.Interop.Generator/Resolvers/InteropImplTypeResolver.cs index 1e6dd29662..4f74e7567f 100644 --- a/src/WinRT.Interop.Generator/Resolvers/InteropImplTypeResolver.cs +++ b/src/WinRT.Interop.Generator/Resolvers/InteropImplTypeResolver.cs @@ -21,13 +21,11 @@ internal static class InteropImplTypeResolver /// /// The type to get the "Impl" method for. /// The instance to use. - /// The instance to use. /// The emit state for this invocation. /// The "Impl" methods for . public static (IMethodDefOrRef get_IID, IMethodDefOrRef get_Vtable) GetGenericInstanceTypeImpl( GenericInstanceTypeSignature type, InteropDefinitions interopDefinitions, - InteropReferences interopReferences, InteropGeneratorEmitState emitState) { // For generic types (i.e. generic interfaces), their marshalling code will be in 'WinRT.Interop.dll', @@ -36,7 +34,7 @@ public static (IMethodDefOrRef get_IID, IMethodDefOrRef get_Vtable) GetGenericIn MethodDefinition get_VtableMethod = implTypeDefinition.GetMethod("get_Vtable"u8); // The IID will be in the generated 'ABI.InterfaceIIDs' type in 'WinRT.Interop.dll' - Utf8String get_IIDMethodName = $"get_IID_{InteropUtf8NameFactory.TypeName(type, interopReferences.RuntimeContext)}"; + Utf8String get_IIDMethodName = $"get_IID_{InteropUtf8NameFactory.TypeName(type, interopDefinitions)}"; MethodDefinition get_IIDMethod = interopDefinitions.InterfaceIIDs.GetMethod(get_IIDMethodName); // Return the pair of methods from the ABI type in 'WinRT.Interop.dll' diff --git a/src/WinRT.Interop.Generator/Resolvers/InteropInterfaceEntriesResolver.cs b/src/WinRT.Interop.Generator/Resolvers/InteropInterfaceEntriesResolver.cs index 0de717e4f6..3925921064 100644 --- a/src/WinRT.Interop.Generator/Resolvers/InteropInterfaceEntriesResolver.cs +++ b/src/WinRT.Interop.Generator/Resolvers/InteropInterfaceEntriesResolver.cs @@ -60,7 +60,6 @@ public static IEnumerable EnumerateMetadataInterfaceE (IMethodDefOrRef get_IIDMethod, IMethodDefOrRef get_VtableMethod) = InteropImplTypeResolver.GetGenericInstanceTypeImpl( type: genericTypeSignature, interopDefinitions: interopDefinitions, - interopReferences: interopReferences, emitState: emitState); yield return new WindowsRuntimeInterfaceEntryInfo(get_IIDMethod, get_VtableMethod); @@ -113,7 +112,9 @@ public static IEnumerable EnumerateMetadataInterfaceE // Handle the common case for all normally projected, non-generic Windows Runtime interface types. For those, all the // interop code will just live in the 'WinRT.Projection.dll' assembly, with all projected types for the application domain. - if (interfaceType.IsProjectedWindowsRuntimeType) + // The interface is recognized either by its '[WindowsRuntimeMetadata]' attribute (implementation projections) or by being + // defined in a reference projection assembly (reference projections don't carry that per-type attribute). + if (interfaceType.IsProjectedWindowsRuntimeType || interfaceType.IsReferenceProjectionWindowsRuntimeType) { (IMethodDefOrRef get_IIDMethod, IMethodDefOrRef get_VtableMethod) = InteropImplTypeResolver.GetProjectedTypeImpl( type: interfaceType, diff --git a/src/WinRT.Projection.Writer/Builders/ProjectionFileBuilder.cs b/src/WinRT.Projection.Writer/Builders/ProjectionFileBuilder.cs index 44c4c8faa6..5bc218b1a1 100644 --- a/src/WinRT.Projection.Writer/Builders/ProjectionFileBuilder.cs +++ b/src/WinRT.Projection.Writer/Builders/ProjectionFileBuilder.cs @@ -94,7 +94,7 @@ private static void WriteEnum(IndentedTextWriter writer, ProjectionEmitContext c string enumUnderlyingType = isFlags ? "uint" : "int"; string typeName = type.GetRawName(); - IndentedTextWriterCallback metadataAttr = MetadataAttributeFactory.WriteWinRTMetadataAttribute(type, context.Cache); + IndentedTextWriterCallback metadataAttr = MetadataAttributeFactory.WriteWinRTMetadataAttribute(context, type); IndentedTextWriterCallback valueTypeAttr = MetadataAttributeFactory.WriteValueTypeWinRTClassNameAttribute(context, type); IndentedTextWriterCallback customAttrs = CustomAttributeFactory.WriteTypeCustomAttributes(context, type, true); IndentedTextWriterCallback comWrappersAttr = MetadataAttributeFactory.WriteComWrapperMarshallerAttribute(context, type); @@ -174,7 +174,7 @@ private static void WriteStruct(IndentedTextWriter writer, ProjectionEmitContext string projectionName = type.GetRawName(); // Header attributes + struct declaration as a single multiline template. - IndentedTextWriterCallback metadataAttr = MetadataAttributeFactory.WriteWinRTMetadataAttribute(type, context.Cache); + IndentedTextWriterCallback metadataAttr = MetadataAttributeFactory.WriteWinRTMetadataAttribute(context, type); IndentedTextWriterCallback valueTypeAttr = MetadataAttributeFactory.WriteValueTypeWinRTClassNameAttribute(context, type); IndentedTextWriterCallback customAttrs = CustomAttributeFactory.WriteTypeCustomAttributes(context, type, true); IndentedTextWriterCallback comWrappersAttr = MetadataAttributeFactory.WriteComWrapperMarshallerAttribute(context, type); @@ -321,7 +321,7 @@ private static void WriteDelegate(IndentedTextWriter writer, ProjectionEmitConte MethodSignatureInfo sig = new(invoke); - IndentedTextWriterCallback metadataAttr = MetadataAttributeFactory.WriteWinRTMetadataAttribute(type, context.Cache); + IndentedTextWriterCallback metadataAttr = MetadataAttributeFactory.WriteWinRTMetadataAttribute(context, type); IndentedTextWriterCallback customAttrs = CustomAttributeFactory.WriteTypeCustomAttributes(context, type, false); IndentedTextWriterCallback comWrappersAttr = MetadataAttributeFactory.WriteComWrapperMarshallerAttribute(context, type); string guidAttr = context.Settings.ReferenceProjection @@ -349,7 +349,7 @@ private static void WriteAttribute(IndentedTextWriter writer, ProjectionEmitCont { string typeName = type.GetRawName(); - IndentedTextWriterCallback metadataAttr = MetadataAttributeFactory.WriteWinRTMetadataAttribute(type, context.Cache); + IndentedTextWriterCallback metadataAttr = MetadataAttributeFactory.WriteWinRTMetadataAttribute(context, type); IndentedTextWriterCallback customAttrs = CustomAttributeFactory.WriteTypeCustomAttributes(context, type, true); writer.WriteLine(); diff --git a/src/WinRT.Projection.Writer/Extensions/ProjectionWriterExtensions.cs b/src/WinRT.Projection.Writer/Extensions/ProjectionWriterExtensions.cs index 1f04dbaf7a..860263526c 100644 --- a/src/WinRT.Projection.Writer/Extensions/ProjectionWriterExtensions.cs +++ b/src/WinRT.Projection.Writer/Extensions/ProjectionWriterExtensions.cs @@ -51,6 +51,7 @@ public void WriteFileHeader(ProjectionEmitContext context) #pragma warning disable CS0649 // "Field '...' is never assigned to" #pragma warning disable CA2207, CA1063, CA1033, CA1001, CA2213 #pragma warning disable CSWINRT3001 // "Type or member '...' is a private implementation detail" + #pragma warning disable CSWINRT3002 // "Type '...' is a private implementation detail" #pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type """); diff --git a/src/WinRT.Projection.Writer/Factories/ClassFactory.cs b/src/WinRT.Projection.Writer/Factories/ClassFactory.cs index c2b5d789c4..1aff3fdc8d 100644 --- a/src/WinRT.Projection.Writer/Factories/ClassFactory.cs +++ b/src/WinRT.Projection.Writer/Factories/ClassFactory.cs @@ -226,7 +226,7 @@ public static void WriteStaticClass(IndentedTextWriter writer, ProjectionEmitCon { using (context.EnterPlatformSuppressionScope(string.Empty)) { - IndentedTextWriterCallback metadataAttr = MetadataAttributeFactory.WriteWinRTMetadataAttribute(type, context.Cache); + IndentedTextWriterCallback metadataAttr = MetadataAttributeFactory.WriteWinRTMetadataAttribute(context, type); IndentedTextWriterCallback customAttrs = CustomAttributeFactory.WriteTypeCustomAttributes(context, type, true); IndentedTextWriterCallback name = TypedefNameWriter.WriteTypedefNameWithTypeParams(context, type, TypedefNameType.Projected, false); writer.WriteLine(isMultiline: true, $$""" @@ -453,31 +453,32 @@ public static event {{eventType}} {{evtName}} /// internal static void WriteStaticFactoryObjRef(IndentedTextWriter writer, ProjectionEmitContext context, TypeDefinition staticIface, string runtimeClassFullName, string objRefName) { - writer.WriteLine(); - + // The static factory '_objRef_*' field is a private implementation detail typed as the + // implementation-only 'WindowsRuntimeObjectReference', so it is omitted from reference + // projections (which compile against the stripped 'WinRT.Runtime' reference assembly). if (context.Settings.ReferenceProjection) { - writer.WriteLine($"private static WindowsRuntimeObjectReference {objRefName} => throw null;"); + return; } - else - { - IndentedTextWriterCallback iid = ObjRefNameGenerator.WriteIidExpression(context, staticIface); - writer.WriteLine(isMultiline: true, $$""" - private static WindowsRuntimeObjectReference {{objRefName}} + writer.WriteLine(); + + IndentedTextWriterCallback iid = ObjRefNameGenerator.WriteIidExpression(context, staticIface); + + writer.WriteLine(isMultiline: true, $$""" + private static WindowsRuntimeObjectReference {{objRefName}} + { + get { - get + var __{{objRefName}} = field; + if (__{{objRefName}} != null && __{{objRefName}}.IsInCurrentContext) { - var __{{objRefName}} = field; - if (__{{objRefName}} != null && __{{objRefName}}.IsInCurrentContext) - { - return __{{objRefName}}; - } - return field = WindowsRuntimeObjectReference.GetActivationFactory("{{runtimeClassFullName}}", {{iid}}); + return __{{objRefName}}; } + return field = WindowsRuntimeObjectReference.GetActivationFactory("{{runtimeClassFullName}}", {{iid}}); } - """); - } + } + """); } /// @@ -510,7 +511,7 @@ private static void WriteClassCore(IndentedTextWriter writer, ProjectionEmitCont int gcPressure = GetGcPressureAmount(type); // Header attributes + class declaration as a single multiline template. - IndentedTextWriterCallback metadataAttr = MetadataAttributeFactory.WriteWinRTMetadataAttribute(type, context.Cache); + IndentedTextWriterCallback metadataAttr = MetadataAttributeFactory.WriteWinRTMetadataAttribute(context, type); IndentedTextWriterCallback customAttrs = CustomAttributeFactory.WriteTypeCustomAttributes(context, type, true); IndentedTextWriterCallback comWrappersAttr = MetadataAttributeFactory.WriteComWrapperMarshallerAttribute(context, type); @@ -577,35 +578,42 @@ void WriteCtorBody(IndentedTextWriter writer) } else { - // In ref mode, if WriteAttributedTypes will not emit any public constructors, - // we need a 'private TypeName() { throw null; }' to suppress the C# compiler's - // implicit public default constructor (which would expose an unintended API). - // either: - // - factory.activatable is true (parameterless or parameterized — Activatable - // always emits at least one ctor), OR - // - factory.composable && factory.type && factory.type.MethodList().size() > 0 - // (composable factories with NO methods don't emit any ctors). - bool hasRefModeCtors = false; - foreach (KeyValuePair kv in AttributedTypes.Get(type, context.Cache)) + // In ref mode, a synthetic non-public parameterless ctor is emitted in two situations: + // + // 1. To suppress the C# compiler's implicit public default constructor (which would expose + // an unintended API) when 'WriteAttributedTypes' emits no constructors at all. + // 2. To give derived projected classes a base-chain target. A derived class's ref-mode ctor + // implicitly calls 'base()', but the real 'WindowsRuntimeObjectReference'-based base ctor + // is not emitted in ref mode, so an unsealed class must expose an accessible parameterless + // ctor unless it already emits a public one (a default '[Activatable]', or a factory / + // composable method with no user parameters). + // + // Sealed classes can never be a base, so they only need case 1; unsealed classes need a + // parameterless ctor whenever they don't already emit one (which also covers case 1). + if (type.IsSealed) { - AttributedType factory = kv.Value; - - if (factory.Activatable) + bool hasRefModeCtors = false; + foreach (KeyValuePair kv in AttributedTypes.Get(type, context.Cache)) { - hasRefModeCtors = true; - break; + AttributedType factory = kv.Value; + + // Activatable always emits at least one ctor; a composable factory only emits ctors + // when it has methods (a composable factory with no methods emits none). + if (factory.Activatable || (factory.Composable && factory.Type is not null && factory.Type.Methods.Count > 0)) + { + hasRefModeCtors = true; + break; + } } - if (factory.Composable && factory.Type is not null && factory.Type.Methods.Count > 0) + if (!hasRefModeCtors) { - hasRefModeCtors = true; - break; + RefModeStubFactory.EmitSyntheticPrivateCtor(writer, typeName, isSealed: true); } } - - if (!hasRefModeCtors) + else if (!ConstructorFactory.EmitsParameterlessConstructor(type, context.Cache)) { - RefModeStubFactory.EmitSyntheticPrivateCtor(writer, typeName); + RefModeStubFactory.EmitSyntheticPrivateCtor(writer, typeName, isSealed: false); } } diff --git a/src/WinRT.Projection.Writer/Factories/ClassMembersFactory.WriteClassMembers.cs b/src/WinRT.Projection.Writer/Factories/ClassMembersFactory.WriteClassMembers.cs index 900167fbb1..6442a5120f 100644 --- a/src/WinRT.Projection.Writer/Factories/ClassMembersFactory.WriteClassMembers.cs +++ b/src/WinRT.Projection.Writer/Factories/ClassMembersFactory.WriteClassMembers.cs @@ -40,7 +40,9 @@ public static void WriteClassMembers(IndentedTextWriter writer, ProjectionEmitCo // For generic-interface properties, emit the UnsafeAccessor static externs above the // property declaration. Note: getter and setter use the same accessor name (because // C# allows method overloading on parameter list for the static externs). - if (s.HasGetter && s.GetterIsGeneric && !string.IsNullOrEmpty(s.GetterGenericInteropType)) + // These externs are impl-only plumbing for the accessor bodies; in ref mode the bodies + // are 'throw null' so the externs (which reference 'WindowsRuntimeObjectReference') are omitted. + if (!context.Settings.ReferenceProjection && s.HasGetter && s.GetterIsGeneric && !string.IsNullOrEmpty(s.GetterGenericInteropType)) { writer.WriteLine(); UnsafeAccessorFactory.EmitStaticMethod( @@ -52,7 +54,7 @@ public static void WriteClassMembers(IndentedTextWriter writer, ProjectionEmitCo parameterList: "WindowsRuntimeObjectReference thisReference"); } - if (s.HasSetter && s.SetterIsGeneric && !string.IsNullOrEmpty(s.SetterGenericInteropType)) + if (!context.Settings.ReferenceProjection && s.HasSetter && s.SetterIsGeneric && !string.IsNullOrEmpty(s.SetterGenericInteropType)) { writer.WriteLine(); UnsafeAccessorFactory.EmitStaticMethod( diff --git a/src/WinRT.Projection.Writer/Factories/ClassMembersFactory.WriteInterfaceMembers.cs b/src/WinRT.Projection.Writer/Factories/ClassMembersFactory.WriteInterfaceMembers.cs index efd44d6aff..b4c7a0f846 100644 --- a/src/WinRT.Projection.Writer/Factories/ClassMembersFactory.WriteInterfaceMembers.cs +++ b/src/WinRT.Projection.Writer/Factories/ClassMembersFactory.WriteInterfaceMembers.cs @@ -19,9 +19,16 @@ namespace WindowsRuntime.ProjectionWriter.Factories; internal static partial class ClassMembersFactory { - private static void WriteInterfaceMembersRecursive(IndentedTextWriter writer, ProjectionEmitContext context, TypeDefinition classType, TypeDefinition declaringType, + private static void WriteInterfaceMembersRecursive( + IndentedTextWriter writer, + ProjectionEmitContext context, + TypeDefinition classType, + TypeDefinition declaringType, GenericInstanceTypeSignature? currentInstance, - HashSet writtenMethods, IDictionary propertyState, HashSet writtenEvents, HashSet writtenInterfaces) + HashSet writtenMethods, + IDictionary propertyState, + HashSet writtenEvents, + HashSet writtenInterfaces) { GenericContext genericContext = new(currentInstance, null); @@ -84,14 +91,14 @@ private static void WriteInterfaceMembersRecursive(IndentedTextWriter writer, Pr } // Emit GetInterface() / GetDefaultInterface() impl for this interface BEFORE its - // members. For - // overridable interfaces or non-exclusive direct interfaces, emit + // members. For overridable interfaces or non-exclusive direct interfaces, emit // IWindowsRuntimeInterface.GetInterface(). For the default interface on an // unsealed class with an exclusive default, emit "internal new GetDefaultInterface()". - // The IWindowsRuntimeInterface markers are NOT emitted in ref mode (gated by - // !context.Settings.ReferenceProjection here). The 'internal new - // GetDefaultInterface()' helper IS emitted in both modes since it's referenced by - // overrides on derived classes. + // Both helpers are implementation-only: they return 'WindowsRuntimeObjectReferenceValue' + // (which is stripped from the 'WinRT.Runtime' reference assembly), and are only ever + // called from the ABI marshallers (which are themselves implementation-only and not + // emitted in ref mode). They are therefore gated off in reference-projection mode, where + // they would otherwise be dead code that fails to compile against the reference assembly. if (IsInterfaceInInheritanceList(context.Cache, impl, includeExclusiveInterface: false) && !context.Settings.ReferenceProjection) { string giObjRefName = ObjRefNameGenerator.GetObjRefName(context, substitutedInterface); @@ -104,15 +111,15 @@ private static void WriteInterfaceMembersRecursive(IndentedTextWriter writer, Pr } """); } - else if (impl.IsDefaultInterface() && !classType.IsSealed) + else if (impl.IsDefaultInterface() && !classType.IsSealed && !context.Settings.ReferenceProjection) { // 'internal new GetDefaultInterface()' helper whenever the interface is the // default interface and the class is unsealed -- regardless of exclusive-to - // status. In ref-projection mode this is the only branch that emits the helper - // (the prior 'IWindowsRuntimeInterface.GetInterface' branch is gated off). - // In non-ref mode this branch is only reached when the prior branch's + // status. This branch is only reached when the prior branch's // IsInterfaceInInheritanceList check fails (i.e., ExclusiveTo default interfaces), - // because non-exclusive default interfaces are routed to the prior branch. + // because non-exclusive default interfaces are routed to the prior branch. Like the + // prior branch, this helper is implementation-only (see above), so it is gated off + // in reference-projection mode. string giObjRefName = ObjRefNameGenerator.GetObjRefName(context, substitutedInterface); bool hasBaseType = false; @@ -238,10 +245,10 @@ private static void WriteInterfaceMembers(IndentedTextWriter writer, ProjectionE genericInteropType = InteropTypeNameWriter.GetInteropAssemblyQualifiedName(currentInstance, TypedefNameType.StaticAbiClass); } - // Compute the platform attribute string from the interface type's [ContractVersion] + // Compute the platform attribute string from the interface type's '[ContractVersion]' // attribute. In ref mode, this is prepended to each member emission so the projected - // class members carry [SupportedOSPlatform("WindowsX.Y.Z.0")] mirroring the interface's - // contract version. Only emitted in ref mode (WritePlatformAttribute internally returns + // class members carry '[SupportedOSPlatform("WindowsX.Y.Z.0")]' mirroring the interface's + // contract version. Only emitted in ref mode ('WritePlatformAttribute' internally returns // immediately if not ref) string platformAttribute = CustomAttributeFactory.GetPlatformAttribute(context, ifaceType); @@ -251,7 +258,7 @@ private static void WriteInterfaceMembers(IndentedTextWriter writer, ProjectionE string name = method.GetRawName(); // Track by full signature (name + each param's element-type code) to avoid trivial overload duplicates. - // This prevents collapsing distinct overloads like Format(double) and Format(ulong). + // This prevents collapsing distinct overloads like 'Format(double)' and 'Format(ulong)'. MethodSignatureInfo sig = new(method, genericContext); string key = sig.GetDedupeKey(name); @@ -309,13 +316,21 @@ private static void WriteInterfaceMembers(IndentedTextWriter writer, ProjectionE string platformTrimmed = platformAttribute.TrimEnd('\r', '\n'); writer.WriteLine(); - UnsafeAccessorFactory.EmitStaticMethod( - writer, - accessName: name, - returnType: unsafeRet.Format(), - functionName: accessorName, - interopType: genericInteropType, - parameterList: $"WindowsRuntimeObjectReference thisReference{accessorParams}"); + + // The '[UnsafeAccessor]' extern is impl-only plumbing for the dispatch body; in ref mode + // the body is 'throw null' (see 'body' above), so the extern (which references the + // implementation-only 'WindowsRuntimeObjectReference') is omitted. + if (!context.Settings.ReferenceProjection) + { + UnsafeAccessorFactory.EmitStaticMethod( + writer, + accessName: name, + returnType: unsafeRet.Format(), + functionName: accessorName, + interopType: genericInteropType, + parameterList: $"WindowsRuntimeObjectReference thisReference{accessorParams}"); + } + writer.WriteLine(isMultiline: true, $$""" {{platformTrimmed}} {{access}}{{methodSpecForThis}}{{ret}} {{name}}({{parms}}) => {{body}} diff --git a/src/WinRT.Projection.Writer/Factories/ConstructorFactory.AttributedTypes.cs b/src/WinRT.Projection.Writer/Factories/ConstructorFactory.AttributedTypes.cs index 1694c6611d..72d2093c89 100644 --- a/src/WinRT.Projection.Writer/Factories/ConstructorFactory.AttributedTypes.cs +++ b/src/WinRT.Projection.Writer/Factories/ConstructorFactory.AttributedTypes.cs @@ -6,6 +6,7 @@ using AsmResolver.DotNet; using WindowsRuntime.ProjectionWriter.Generation; using WindowsRuntime.ProjectionWriter.Helpers; +using WindowsRuntime.ProjectionWriter.Metadata; using WindowsRuntime.ProjectionWriter.Models; using WindowsRuntime.ProjectionWriter.Writers; using static WindowsRuntime.ProjectionWriter.References.ProjectionNames; @@ -34,35 +35,29 @@ public static void WriteAttributedTypes(IndentedTextWriter writer, ProjectionEmi } } - if (needsClassObjRef) + // The activation factory '_objRef_*' field is a private implementation detail typed as the + // implementation-only 'WindowsRuntimeObjectReference', so it is omitted from reference projections + // (which compile against the stripped 'WinRT.Runtime' reference assembly). + if (needsClassObjRef && !context.Settings.ReferenceProjection) { string fullName = classType.FullName ?? string.Empty; string objRefName = "_objRef_" + IidExpressionGenerator.EscapeTypeNameForIdentifier(GlobalPrefix + fullName, stripGlobal: true); writer.WriteLine(); writer.Write($"private static WindowsRuntimeObjectReference {objRefName}"); - - if (context.Settings.ReferenceProjection) - { - // in ref mode the activation factory objref getter body is just 'throw null;'. - RefModeStubFactory.EmitRefModeObjRefGetterBody(writer); - } - else - { - writer.WriteLine(); - writer.WriteLine(isMultiline: true, $$""" + writer.WriteLine(); + writer.WriteLine(isMultiline: true, $$""" + { + get { - get + var __{{objRefName}} = field; + if (__{{objRefName}} != null && __{{objRefName}}.IsInCurrentContext) { - var __{{objRefName}} = field; - if (__{{objRefName}} != null && __{{objRefName}}.IsInCurrentContext) - { - return __{{objRefName}}; - } - return field = WindowsRuntimeObjectReference.GetActivationFactory("{{fullName}}"); + return __{{objRefName}}; } + return field = WindowsRuntimeObjectReference.GetActivationFactory("{{fullName}}"); } - """); - } + } + """); } foreach (KeyValuePair kv in AttributedTypes.Get(classType, context.Cache)) @@ -122,6 +117,18 @@ public static void WriteFactoryConstructors(IndentedTextWriter writer, Projectio writer.Write($"public unsafe {typeName}("); MethodFactory.WriteParameterList(writer, context, sig); + + // In ref mode the constructor keeps its public signature but gets a 'throw null' body, + // and the args struct + factory callback class below are skipped (they are private + // implementation details referencing implementation-only 'WinRT.Runtime' types). + if (context.Settings.ReferenceProjection) + { + RefModeStubFactory.EmitRefModeConstructorBody(writer); + methodIndex++; + + continue; + } + writer.Write(isMultiline: true, """ ) :base( @@ -165,9 +172,20 @@ public static void WriteFactoryConstructors(IndentedTextWriter writer, Projectio } else { - // No factory type means [Activatable(uint version)] - emit a default ctor that calls - // the WindowsRuntimeObject base constructor with the activation factory objref. - // The default interface IID is needed too. + // No factory type means '[Activatable(uint version)]', emit a parameterless default ctor + if (context.Settings.ReferenceProjection) + { + // Ref mode keeps the public signature with a 'throw null' body (the impl-mode body + // calls the base ctor with implementation-only activation types). + writer.WriteLine(); + writer.Write($"public {typeName}("); + RefModeStubFactory.EmitRefModeConstructorBody(writer); + + return; + } + + // The impl-mode default ctor calls the 'WindowsRuntimeObject' base constructor with + // the activation factory object reference. The default interface IID is needed too. string fullName = classType.FullName ?? string.Empty; string objRefName = "_objRef_" + IidExpressionGenerator.EscapeTypeNameForIdentifier(GlobalPrefix + fullName, stripGlobal: true); @@ -188,4 +206,59 @@ public static void WriteFactoryConstructors(IndentedTextWriter writer, Projectio writer.WriteLine("}"); } } + + /// + /// Determines whether emits at least one parameterless public + /// constructor for the given runtime class (a default [Activatable] ctor, an activation-factory + /// method with no parameters, or a composable-factory method with no user parameters). + /// + /// + /// Used in reference-projection mode to decide whether an unsealed class already exposes a + /// parameterless constructor that derived projected classes can chain to, or whether a synthetic + /// non-public one must be emitted (see ). + /// + public static bool EmitsParameterlessConstructor(TypeDefinition classType, MetadataCache cache) + { + foreach (KeyValuePair kv in AttributedTypes.Get(classType, cache)) + { + AttributedType factory = kv.Value; + + // A default '[Activatable(uint version)]' (no factory interface) emits 'public TypeName()'. + if (factory.Activatable && factory.Type is null) + { + return true; + } + + if (factory.Type is null) + { + continue; + } + + // An activation- or composable-factory method emits a parameterless ctor when it has no user + // parameters. Composable factory methods carry two trailing ABI parameters (the base and inner + // interfaces) that are not surfaced on the projected constructor, so they are excluded. + if (factory.Activatable || factory.Composable) + { + foreach (MethodDefinition method in factory.Type.Methods) + { + if (method.IsSpecial) + { + continue; + } + + MethodSignatureInfo sig = new(method); + int userParamCount = factory.Composable && sig.Parameters.Count >= 2 + ? sig.Parameters.Count - 2 + : sig.Parameters.Count; + + if (userParamCount == 0) + { + return true; + } + } + } + } + + return false; + } } diff --git a/src/WinRT.Projection.Writer/Factories/ConstructorFactory.Composable.cs b/src/WinRT.Projection.Writer/Factories/ConstructorFactory.Composable.cs index 002fa51c65..20eb77b554 100644 --- a/src/WinRT.Projection.Writer/Factories/ConstructorFactory.Composable.cs +++ b/src/WinRT.Projection.Writer/Factories/ConstructorFactory.Composable.cs @@ -92,6 +92,17 @@ public static void WriteComposableConstructors(IndentedTextWriter writer, Projec writer.Write($"{(i > 0 ? ", " : "")}{p}"); } + // In ref mode the composable constructor keeps its public signature but gets a 'throw null' + // body; the base call and the args struct + factory callback class below are skipped (they + // are private implementation details referencing implementation-only 'WinRT.Runtime' types). + if (context.Settings.ReferenceProjection) + { + RefModeStubFactory.EmitRefModeConstructorBody(writer); + methodIndex++; + + continue; + } + writer.Write(isMultiline: true, """ ) :base( @@ -142,11 +153,9 @@ void WriteCtorBody(IndentedTextWriter writer) } """); - // Emit args struct + callback class for parameterized composable factories. - // skips both the args struct AND the callback class entirely in ref mode. The - // public ctor above still references these types, but reference assemblies don't - // need their bodies' references to resolve (only the public API surface matters). - if (!isParameterless && !context.Settings.ReferenceProjection) + // Emit the args struct + factory callback class for parameterized composable factories. + // (Ref mode 'continue'd above before reaching here, since it emits no factory plumbing.) + if (!isParameterless) { EmitFactoryArgsStruct(writer, context, sig, argsName, userParamCount); string factoryObjRefName = ObjRefNameGenerator.GetObjRefName(context, composableType); diff --git a/src/WinRT.Projection.Writer/Factories/InterfaceFactory.cs b/src/WinRT.Projection.Writer/Factories/InterfaceFactory.cs index 9a49411cf7..7a0448b19a 100644 --- a/src/WinRT.Projection.Writer/Factories/InterfaceFactory.cs +++ b/src/WinRT.Projection.Writer/Factories/InterfaceFactory.cs @@ -401,7 +401,7 @@ public static void WriteInterface(IndentedTextWriter writer, ProjectionEmitConte } writer.WriteLine(); - IndentedTextWriterCallback metadataAttr = MetadataAttributeFactory.WriteWinRTMetadataAttribute(type, context.Cache); + IndentedTextWriterCallback metadataAttr = MetadataAttributeFactory.WriteWinRTMetadataAttribute(context, type); IndentedTextWriterCallback guidAttr = WriteGuidAttribute(type); writer.WriteLine(isMultiline: true, $$""" {{metadataAttr}} diff --git a/src/WinRT.Projection.Writer/Factories/MappedInterfaceStubFactory.cs b/src/WinRT.Projection.Writer/Factories/MappedInterfaceStubFactory.cs index 44e4a49464..1b8c1a9364 100644 --- a/src/WinRT.Projection.Writer/Factories/MappedInterfaceStubFactory.cs +++ b/src/WinRT.Projection.Writer/Factories/MappedInterfaceStubFactory.cs @@ -69,7 +69,7 @@ public static void WriteMappedInterfaceStubs(IndentedTextWriter writer, Projecti switch (ifaceName) { case "IClosable": - EmitDisposable(writer, objRefName); + EmitDisposable(writer, context, objRefName); break; case "IIterable`1": EmitGenericEnumerable(writer, context, typeArgs, typeArgSigs, objRefName); @@ -90,40 +90,107 @@ public static void WriteMappedInterfaceStubs(IndentedTextWriter writer, Projecti EmitReadOnlyList(writer, context, typeArgs, typeArgSigs, objRefName); break; case "IBindableIterable": - writer.WriteLine(); - writer.WriteLine($"IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => global::ABI.System.Collections.IEnumerableMethods.GetEnumerator({objRefName});"); + EmitNonGenericEnumerable(writer, context, objRefName); break; case "IBindableIterator": - writer.WriteLine(); - writer.WriteLine(isMultiline: true, $$""" - public bool MoveNext() => global::ABI.System.Collections.IEnumeratorMethods.MoveNext({{objRefName}}); - public void Reset() => throw new NotSupportedException(); - public object Current => global::ABI.System.Collections.IEnumeratorMethods.Current({{objRefName}}); - """); + EmitNonGenericEnumerator(writer, context, objRefName); break; case "IBindableVector": - EmitNonGenericList(writer, objRefName); + EmitNonGenericList(writer, context, objRefName); break; case "INotifyDataErrorInfo": - writer.WriteLine(); - writer.WriteLine(isMultiline: true, $$""" - public global::System.Collections.IEnumerable GetErrors(string propertyName) => global::ABI.System.ComponentModel.INotifyDataErrorInfoMethods.GetErrors({{objRefName}}, propertyName); - public bool HasErrors {get => global::ABI.System.ComponentModel.INotifyDataErrorInfoMethods.HasErrors({{objRefName}}); } - public event global::System.EventHandler ErrorsChanged - { - add => global::ABI.System.ComponentModel.INotifyDataErrorInfoMethods.ErrorsChanged(this, {{objRefName}}).Subscribe(value); - remove => global::ABI.System.ComponentModel.INotifyDataErrorInfoMethods.ErrorsChanged(this, {{objRefName}}).Unsubscribe(value); - } - """); + EmitNotifyDataErrorInfo(writer, context, objRefName); break; } } - private static void EmitDisposable(IndentedTextWriter writer, string objRefName) + + private static void EmitDisposable(IndentedTextWriter writer, ProjectionEmitContext context, string objRefName) { + // In a reference projection the member bodies dispatch to implementation-only plumbing + // (the 'ABI.*Methods' helpers, the '[UnsafeAccessor]' externs, and the '_objRef_*' fields, + // all of which are absent from the 'WinRT.Runtime' reference assembly), so the entire body is + // emitted as a stub. The public member signatures stay identical to the implementation projection. + if (context.Settings.ReferenceProjection) + { + writer.WriteLine(); + writer.WriteLine("public void Dispose() => throw null;"); + + return; + } + writer.WriteLine(); writer.WriteLine($"public void Dispose() => global::ABI.System.IDisposableMethods.Dispose({objRefName});"); } + private static void EmitNonGenericEnumerable(IndentedTextWriter writer, ProjectionEmitContext context, string objRefName) + { + // See 'EmitDisposable' for why the body is stubbed in a reference projection. + if (context.Settings.ReferenceProjection) + { + writer.WriteLine(); + writer.WriteLine("IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => throw null;"); + + return; + } + + writer.WriteLine(); + writer.WriteLine($"IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => global::ABI.System.Collections.IEnumerableMethods.GetEnumerator({objRefName});"); + } + + private static void EmitNonGenericEnumerator(IndentedTextWriter writer, ProjectionEmitContext context, string objRefName) + { + // See 'EmitDisposable' for why the body is stubbed in a reference projection. + if (context.Settings.ReferenceProjection) + { + writer.WriteLine(); + writer.WriteLine(isMultiline: true, """ + public bool MoveNext() => throw null; + public void Reset() => throw null; + public object Current => throw null; + """); + + return; + } + + writer.WriteLine(); + writer.WriteLine(isMultiline: true, $""" + public bool MoveNext() => global::ABI.System.Collections.IEnumeratorMethods.MoveNext({objRefName}); + public void Reset() => throw new NotSupportedException(); + public object Current => global::ABI.System.Collections.IEnumeratorMethods.Current({objRefName}); + """); + } + + private static void EmitNotifyDataErrorInfo(IndentedTextWriter writer, ProjectionEmitContext context, string objRefName) + { + // See 'EmitDisposable' for why the body is stubbed in a reference projection. + if (context.Settings.ReferenceProjection) + { + writer.WriteLine(); + writer.WriteLine(isMultiline: true, """ + public global::System.Collections.IEnumerable GetErrors(string propertyName) => throw null; + public bool HasErrors {get => throw null; } + public event global::System.EventHandler ErrorsChanged + { + add => throw null; + remove => throw null; + } + """); + + return; + } + + writer.WriteLine(); + writer.WriteLine(isMultiline: true, $$""" + public global::System.Collections.IEnumerable GetErrors(string propertyName) => global::ABI.System.ComponentModel.INotifyDataErrorInfoMethods.GetErrors({{objRefName}}, propertyName); + public bool HasErrors {get => global::ABI.System.ComponentModel.INotifyDataErrorInfoMethods.HasErrors({{objRefName}}); } + public event global::System.EventHandler ErrorsChanged + { + add => global::ABI.System.ComponentModel.INotifyDataErrorInfoMethods.ErrorsChanged(this, {{objRefName}}).Subscribe(value); + remove => global::ABI.System.ComponentModel.INotifyDataErrorInfoMethods.ErrorsChanged(this, {{objRefName}}).Unsubscribe(value); + } + """); + } + private static void EmitGenericEnumerable(IndentedTextWriter writer, ProjectionEmitContext context, List args, List argSigs, string objRefName) { if (args.Count != 1) @@ -132,13 +199,28 @@ private static void EmitGenericEnumerable(IndentedTextWriter writer, ProjectionE } string t = WriteTypeNameToString(context, args[0], TypedefNameType.Projected, true); + + // See 'EmitDisposable' for why the body is stubbed in a reference projection. Only the + // projected type name is needed for the signatures; the implementation-only interop plumbing + // (interop type, '[UnsafeAccessor]' externs) is not computed or emitted. + if (context.Settings.ReferenceProjection) + { + writer.WriteLine(); + writer.WriteLine(isMultiline: true, $""" + public IEnumerator<{t}> GetEnumerator() => throw null; + global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => throw null; + """); + + return; + } + string elementId = EncodeArgIdentifier(context, args[0]); string interopTypeArgs = InteropTypeNameWriter.EncodeInteropTypeName(argSigs[0], TypedefNameType.Projected); string interopType = "ABI.System.Collections.Generic.<#corlib>IEnumerable'1<" + interopTypeArgs + ">Methods, WinRT.Interop"; string prefix = "IEnumerableMethods_" + elementId + "_"; writer.WriteLine(); - EmitUnsafeAccessor(writer, "GetEnumerator", $"IEnumerator<{t}>", $"{prefix}GetEnumerator", interopType, ""); + EmitUnsafeAccessor(writer, context, "GetEnumerator", $"IEnumerator<{t}>", $"{prefix}GetEnumerator", interopType, ""); writer.WriteLine(); writer.WriteLine($"public IEnumerator<{t}> GetEnumerator() => {prefix}GetEnumerator(null, {objRefName});"); @@ -153,13 +235,29 @@ private static void EmitGenericEnumerator(IndentedTextWriter writer, ProjectionE } string t = WriteTypeNameToString(context, args[0], TypedefNameType.Projected, true); + + // See 'EmitDisposable' for why the body is stubbed in a reference projection. + if (context.Settings.ReferenceProjection) + { + writer.WriteLine(); + writer.WriteLine(isMultiline: true, $""" + public bool MoveNext() => throw null; + public void Reset() => throw null; + public void Dispose() => throw null; + public {t} Current => throw null; + object global::System.Collections.IEnumerator.Current => throw null; + """); + + return; + } + string elementId = EncodeArgIdentifier(context, args[0]); string interopTypeArgs = InteropTypeNameWriter.EncodeInteropTypeName(argSigs[0], TypedefNameType.Projected); string interopType = "ABI.System.Collections.Generic.<#corlib>IEnumerator'1<" + interopTypeArgs + ">Methods, WinRT.Interop"; string prefix = "IEnumeratorMethods_" + elementId + "_"; writer.WriteLine(); - EmitUnsafeAccessors(writer, interopType, [ + EmitUnsafeAccessors(writer, context, interopType, [ new("Current", t, $"{prefix}Current", ""), new("MoveNext", "bool", $"{prefix}MoveNext", "")]); @@ -189,6 +287,36 @@ private static void EmitDictionary(IndentedTextWriter writer, ProjectionEmitCont string kv = $"KeyValuePair<{k}, {v}>"; string kvNested = $"global::System.Collections.Generic.KeyValuePair<{k}, {v}>"; + // See 'EmitDisposable' for why the body is stubbed in a reference projection. Only the projected + // type names are needed for the signatures; the implementation-only interop plumbing (interop + // type, '[UnsafeAccessor]' externs, '_objRef_*' fields) is not computed or emitted. + if (context.Settings.ReferenceProjection) + { + writer.WriteLine(); + writer.WriteLine(isMultiline: true, $$""" + public ICollection<{{k}}> Keys => throw null; + public ICollection<{{v}}> Values => throw null; + public int Count => throw null; + public bool IsReadOnly => false; + public {{v}} this[{{k}} key] + { + get => throw null; + set => throw null; + } + public void Add({{k}} key, {{v}} value) => throw null; + public bool ContainsKey({{k}} key) => throw null; + public bool Remove({{k}} key) => throw null; + public bool TryGetValue({{k}} key, out {{v}} value) => throw null; + public void Add({{kv}} item) => throw null; + public void Clear() => throw null; + public bool Contains({{kv}} item) => throw null; + public void CopyTo({{kv}}[] array, int arrayIndex) => throw null; + bool ICollection<{{kv}}>.Remove({{kv}} item) => throw null; + """); + + return; + } + // Long form (always fully qualified) used for objref field-name computation // (matches the form WriteClassObjRefDefinitions emits transitively). string kvLong = kvNested; @@ -207,9 +335,9 @@ private static void EmitDictionary(IndentedTextWriter writer, ProjectionEmitCont // 'Keys'/'Values' take the projected runtime class directly (passed as 'this'), rather than the // interface object reference like the other accessors. This lets the returned collection be cached // in the public property's backing 'field' so it preserves reference identity across accesses. - EmitUnsafeAccessor(writer, "Keys", $"ICollection<{k}>", $"{prefix}Keys", interopType, "", receiver: "WindowsRuntimeObject windowsRuntimeObject"); - EmitUnsafeAccessor(writer, "Values", $"ICollection<{v}>", $"{prefix}Values", interopType, "", receiver: "WindowsRuntimeObject windowsRuntimeObject"); - EmitUnsafeAccessors(writer, interopType, [ + EmitUnsafeAccessor(writer, context, "Keys", $"ICollection<{k}>", $"{prefix}Keys", interopType, "", receiver: "WindowsRuntimeObject windowsRuntimeObject"); + EmitUnsafeAccessor(writer, context, "Values", $"ICollection<{v}>", $"{prefix}Values", interopType, "", receiver: "WindowsRuntimeObject windowsRuntimeObject"); + EmitUnsafeAccessors(writer, context, interopType, [ new("Count", "int", $"{prefix}Count", ""), new("Item", v, $"{prefix}Item", $", {k} key"), new("Item", "void", $"{prefix}Item", $", {k} key, {v} value"), @@ -257,6 +385,23 @@ private static void EmitReadOnlyDictionary(IndentedTextWriter writer, Projection string k = WriteTypeNameToString(context, args[0], TypedefNameType.Projected, true); string v = WriteTypeNameToString(context, args[1], TypedefNameType.Projected, true); + + // See 'EmitDisposable' for why the body is stubbed in a reference projection. + if (context.Settings.ReferenceProjection) + { + writer.WriteLine(); + writer.WriteLine(isMultiline: true, $""" + public {v} this[{k} key] => throw null; + public IEnumerable<{k}> Keys => throw null; + public IEnumerable<{v}> Values => throw null; + public int Count => throw null; + public bool ContainsKey({k} key) => throw null; + public bool TryGetValue({k} key, out {v} value) => throw null; + """); + + return; + } + string keyId = EncodeArgIdentifier(context, args[0]); string valId = EncodeArgIdentifier(context, args[1]); string keyInteropArg = InteropTypeNameWriter.EncodeInteropTypeName(argSigs[0], TypedefNameType.Projected); @@ -269,9 +414,9 @@ private static void EmitReadOnlyDictionary(IndentedTextWriter writer, Projection // 'Keys'/'Values' take the projected runtime class directly (passed as 'this'), rather than the // interface object reference like the other accessors. This lets the returned collection be cached // in the public property's backing 'field' so it preserves reference identity across accesses. - EmitUnsafeAccessor(writer, "Keys", $"IEnumerable<{k}>", $"{prefix}Keys", interopType, "", receiver: "WindowsRuntimeObject windowsRuntimeObject"); - EmitUnsafeAccessor(writer, "Values", $"IEnumerable<{v}>", $"{prefix}Values", interopType, "", receiver: "WindowsRuntimeObject windowsRuntimeObject"); - EmitUnsafeAccessors(writer, interopType, [ + EmitUnsafeAccessor(writer, context, "Keys", $"IEnumerable<{k}>", $"{prefix}Keys", interopType, "", receiver: "WindowsRuntimeObject windowsRuntimeObject"); + EmitUnsafeAccessor(writer, context, "Values", $"IEnumerable<{v}>", $"{prefix}Values", interopType, "", receiver: "WindowsRuntimeObject windowsRuntimeObject"); + EmitUnsafeAccessors(writer, context, interopType, [ new("Count", "int", $"{prefix}Count", ""), new("Item", v, $"{prefix}Item", $", {k} key"), new("ContainsKey", "bool", $"{prefix}ContainsKey", $", {k} key"), @@ -296,23 +441,37 @@ private static void EmitReadOnlyList(IndentedTextWriter writer, ProjectionEmitCo } string t = WriteTypeNameToString(context, args[0], TypedefNameType.Projected, true); + + // See 'EmitDisposable' for why the body is stubbed in a reference projection. + if (context.Settings.ReferenceProjection) + { + writer.WriteLine(); + writer.WriteLine(isMultiline: true, $""" + [global::System.Runtime.CompilerServices.IndexerName("ReadOnlyListItem")] + public {t} this[int index] => throw null; + public int Count => throw null; + """); + + return; + } + string elementId = EncodeArgIdentifier(context, args[0]); string interopTypeArgs = InteropTypeNameWriter.EncodeInteropTypeName(argSigs[0], TypedefNameType.Projected); string interopType = "ABI.System.Collections.Generic.<#corlib>IReadOnlyList'1<" + interopTypeArgs + ">Methods, WinRT.Interop"; string prefix = "IReadOnlyListMethods_" + elementId + "_"; writer.WriteLine(); - EmitUnsafeAccessors(writer, interopType, [ + EmitUnsafeAccessors(writer, context, interopType, [ new("Count", "int", $"{prefix}Count", ""), new("Item", t, $"{prefix}Item", ", int index")]); // GetEnumerator is NOT emitted here -- it's handled separately by IIterable's // EmitGenericEnumerable invocation. writer.WriteLine(); - writer.WriteLine(isMultiline: true, $$""" + writer.WriteLine(isMultiline: true, $""" [global::System.Runtime.CompilerServices.IndexerName("ReadOnlyListItem")] - public {{t}} this[int index] => {{prefix}}Item(null, {{objRefName}}, index); - public int Count => {{prefix}}Count(null, {{objRefName}}); + public {t} this[int index] => {prefix}Item(null, {objRefName}, index); + public int Count => {prefix}Count(null, {objRefName}); """); } @@ -343,13 +502,41 @@ private static void EmitList(IndentedTextWriter writer, ProjectionEmitContext co } string t = WriteTypeNameToString(context, args[0], TypedefNameType.Projected, true); + + // See 'EmitDisposable' for why the body is stubbed in a reference projection. + if (context.Settings.ReferenceProjection) + { + writer.WriteLine(); + writer.WriteLine(isMultiline: true, $$""" + public int Count => throw null; + public bool IsReadOnly => false; + + [global::System.Runtime.CompilerServices.IndexerName("ListItem")] + public {{t}} this[int index] + { + get => throw null; + set => throw null; + } + public int IndexOf({{t}} item) => throw null; + public void Insert(int index, {{t}} item) => throw null; + public void RemoveAt(int index) => throw null; + public void Add({{t}} item) => throw null; + public void Clear() => throw null; + public bool Contains({{t}} item) => throw null; + public void CopyTo({{t}}[] array, int arrayIndex) => throw null; + public bool Remove({{t}} item) => throw null; + """); + + return; + } + string elementId = EncodeArgIdentifier(context, args[0]); string interopTypeArgs = InteropTypeNameWriter.EncodeInteropTypeName(argSigs[0], TypedefNameType.Projected); string interopType = "ABI.System.Collections.Generic.<#corlib>IList'1<" + interopTypeArgs + ">Methods, WinRT.Interop"; string prefix = "IListMethods_" + elementId + "_"; writer.WriteLine(); - EmitUnsafeAccessors(writer, interopType, [ + EmitUnsafeAccessors(writer, context, interopType, [ new("Count", "int", $"{prefix}Count", ""), new("Item", t, $"{prefix}Item", ", int index"), new("Item", "void", $"{prefix}Item", $", int index, {t} value"), @@ -393,8 +580,25 @@ private static void EmitList(IndentedTextWriter writer, ProjectionEmitContext co /// (WindowsRuntimeObjectReference objRef); a few accessors (e.g. dictionary /// Keys/Values) instead take the projected runtime class (WindowsRuntimeObject). /// - private static void EmitUnsafeAccessor(IndentedTextWriter writer, string accessName, string returnType, string functionName, string interopType, string extraParams, string receiver = "WindowsRuntimeObjectReference objRef") + private static void EmitUnsafeAccessor( + IndentedTextWriter writer, + ProjectionEmitContext context, + string accessName, + string returnType, + string functionName, + string interopType, + string extraParams, + string receiver = "WindowsRuntimeObjectReference objRef") { + // The '[UnsafeAccessor]' extern is impl-only plumbing for the stub member bodies; in a reference + // projection those bodies are not bound (the reference assembly only needs the public member + // signatures), so the extern (which typically references the implementation-only + // 'WindowsRuntimeObjectReference') is omitted. + if (context.Settings.ReferenceProjection) + { + return; + } + UnsafeAccessorFactory.EmitStaticMethod( writer, accessName: accessName, @@ -408,22 +612,54 @@ private static void EmitUnsafeAccessor(IndentedTextWriter writer, string accessN /// /// Emits a sequence of [UnsafeAccessor] static extern declarations sharing the same /// . Each row of is forwarded to - /// . + /// . /// Used by the collection-stub emitters which emit table-shaped sets of accessors. /// private static void EmitUnsafeAccessors( IndentedTextWriter writer, + ProjectionEmitContext context, string interopType, params ReadOnlySpan<(string AccessName, string ReturnType, string FunctionName, string ExtraParams)> accessors) { foreach ((string accessName, string returnType, string functionName, string extraParams) in accessors) { - EmitUnsafeAccessor(writer, accessName, returnType, functionName, interopType, extraParams); + EmitUnsafeAccessor(writer, context, accessName, returnType, functionName, interopType, extraParams); } } - private static void EmitNonGenericList(IndentedTextWriter writer, string objRefName) + private static void EmitNonGenericList(IndentedTextWriter writer, ProjectionEmitContext context, string objRefName) { + // See 'EmitDisposable' for why the body is stubbed in a reference projection. + if (context.Settings.ReferenceProjection) + { + writer.WriteLine(); + writer.WriteLine(isMultiline: true, """ + [global::System.Runtime.CompilerServices.IndexerName("NonGenericListItem")] + public object this[int index] + { + get => throw null; + set => throw null; + } + public int Count => throw null; + public bool IsReadOnly => false; + public bool IsFixedSize => false; + public bool IsSynchronized => false; + public object SyncRoot => this; + public int Add(object value) => throw null; + public void Clear() => throw null; + public bool Contains(object value) => throw null; + public int IndexOf(object value) => throw null; + public void Insert(int index, object value) => throw null; + public void Remove(object value) => throw null; + public void RemoveAt(int index) => throw null; + public void CopyTo(Array array, int index) => throw null; + """); + + // GetEnumerator is NOT emitted here -- it's handled separately by IBindableIterable's + // EmitNonGenericEnumerable invocation. + return; + } + writer.WriteLine(); writer.WriteLine(isMultiline: true, $$""" [global::System.Runtime.CompilerServices.IndexerName("NonGenericListItem")] diff --git a/src/WinRT.Projection.Writer/Factories/MetadataAttributeFactory.cs b/src/WinRT.Projection.Writer/Factories/MetadataAttributeFactory.cs index 97b167173d..cc3ba08608 100644 --- a/src/WinRT.Projection.Writer/Factories/MetadataAttributeFactory.cs +++ b/src/WinRT.Projection.Writer/Factories/MetadataAttributeFactory.cs @@ -80,30 +80,45 @@ public static string GetFileHeader() /// /// Writes a [WindowsRuntimeMetadata("<stem>")] attribute decorating with its source .winmd module name. + /// Skipped entirely in reference-projection mode. /// /// The writer to emit to. + /// The active emit context. /// The type definition. - /// The metadata cache used to resolve the source module path. - public static void WriteWinRTMetadataAttribute(IndentedTextWriter writer, TypeDefinition type, MetadataCache cache) + public static void WriteWinRTMetadataAttribute(IndentedTextWriter writer, ProjectionEmitContext context, TypeDefinition type) { - WriteWinRTMetadataAttributeBody(writer, type, cache); + if (context.Settings.ReferenceProjection) + { + return; + } + + WriteWinRTMetadataAttributeBody(writer, context, type); + writer.WriteLine(); } - /// - /// A callback emitting the attribute body (no trailing newline) so it can be interpolated into a multiline template. - public static IndentedTextWriterCallback WriteWinRTMetadataAttribute(TypeDefinition type, MetadataCache cache) + /// + /// A callback emitting the attribute body (no trailing newline) so it can be interpolated into a multiline template. Emits nothing in reference-projection mode. + public static IndentedTextWriterCallback WriteWinRTMetadataAttribute(ProjectionEmitContext context, TypeDefinition type) { - return writer => WriteWinRTMetadataAttributeBody(writer, type, cache); + return writer => WriteWinRTMetadataAttributeBody(writer, context, type); } /// - /// Writes just the attribute body (no trailing newline) for . - /// Used by the callback variant to allow the attribute to be inlined inside a multiline raw-string template line. + /// Writes just the attribute body (no trailing newline) for . + /// In reference-projection mode this emits nothing: [WindowsRuntimeMetadata] is an implementation-only + /// type, stripped from the WinRT.Runtime reference assembly that a reference projection compiles against. + /// It is only consumed (by the interop generator) from implementation projections, never from the reference + /// projections shipped in Windows Runtime projection NuGet packages. /// - internal static void WriteWinRTMetadataAttributeBody(IndentedTextWriter writer, TypeDefinition type, MetadataCache cache) + internal static void WriteWinRTMetadataAttributeBody(IndentedTextWriter writer, ProjectionEmitContext context, TypeDefinition type) { - string path = cache.GetSourcePath(type); + if (context.Settings.ReferenceProjection) + { + return; + } + + string path = context.Cache.GetSourcePath(type); string stem = string.IsNullOrEmpty(path) ? string.Empty : Path.GetFileNameWithoutExtension(path); writer.Write($"[WindowsRuntimeMetadata(\"{stem}\")]"); } diff --git a/src/WinRT.Projection.Writer/Factories/RefModeStubFactory.cs b/src/WinRT.Projection.Writer/Factories/RefModeStubFactory.cs index 19f6b68f30..16b4a2c003 100644 --- a/src/WinRT.Projection.Writer/Factories/RefModeStubFactory.cs +++ b/src/WinRT.Projection.Writer/Factories/RefModeStubFactory.cs @@ -14,33 +14,50 @@ namespace WindowsRuntime.ProjectionWriter.Factories; internal static class RefModeStubFactory { /// - /// Emits the body of an _objRef_* property getter in reference projection mode. + /// Emits the synthetic private TypeName() { throw null; } ctor used in reference + /// projection mode to suppress the C# compiler's implicit public default constructor when + /// no explicit ctors are emitted by WriteAttributedTypes. /// + /// + /// For an unsealed class the ctor is emitted as private protected rather than private: + /// a projected class can derive from another projected class (e.g. UriActionEntity : ActionEntity), + /// and the derived class's own synthetic ctor implicitly chains to the base's parameterless ctor. The + /// real WindowsRuntimeObjectReference-based ctor that derived classes chain to in the + /// implementation projection is not emitted in a reference projection, so the synthetic ctor must be + /// accessible to derived classes in the same projection. It stays non-public, so it still suppresses the + /// implicit public default constructor. + /// /// The writer to emit to. - public static void EmitRefModeObjRefGetterBody(IndentedTextWriter writer) + /// The type name to emit the synthetic constructor for. + /// Whether the type is sealed (and so can never be a base class). + public static void EmitSyntheticPrivateCtor(IndentedTextWriter writer, string typeName, bool isSealed) { + string accessibility = isSealed ? "private" : "private protected"; + writer.WriteLine(); - writer.WriteLine(isMultiline: true, """ - { - get - { - throw null; - } - } - """); + writer.WriteLine($"{accessibility} {typeName}() {{ throw null; }}"); } /// - /// Emits the synthetic private TypeName() { throw null; } ctor used in reference - /// projection mode to suppress the C# compiler's implicit public default constructor when - /// no explicit ctors are emitted by WriteAttributedTypes. + /// Emits the closing ) of a constructor parameter list followed by a throw null body, + /// for constructors emitted in reference projection mode. The caller must already have written the + /// constructor signature up to (but not including) the closing ) of the parameter list. /// + /// + /// Reference projections only need the public constructor signatures (their bodies are never run and + /// are stripped from the produced reference assembly), so the body is emitted as throw null + /// rather than the real activation logic, which would reference implementation-only 'WinRT.Runtime' + /// types (object references, activation factory callbacks, ABI IID accessors). + /// /// The writer to emit to. - /// The type name to emit the synthetic constructor for. - public static void EmitSyntheticPrivateCtor(IndentedTextWriter writer, string typeName) + public static void EmitRefModeConstructorBody(IndentedTextWriter writer) { - writer.WriteLine(); - writer.WriteLine($"private {typeName}() {{ throw null; }}"); + writer.WriteLine(isMultiline: true, """ + ) + { + throw null; + } + """); } /// diff --git a/src/WinRT.Projection.Writer/Factories/ReferenceImplFactory.cs b/src/WinRT.Projection.Writer/Factories/ReferenceImplFactory.cs index 62aedfa1a9..31294fea09 100644 --- a/src/WinRT.Projection.Writer/Factories/ReferenceImplFactory.cs +++ b/src/WinRT.Projection.Writer/Factories/ReferenceImplFactory.cs @@ -134,7 +134,7 @@ public static int get_Value(void* thisPtr, void* result) {{visibility}} static unsafe class {{nameStripped}}ReferenceImpl { [FixedAddressValueType] - private static readonly ReferenceVftbl Vftbl; + private static readonly IReferenceVftbl Vftbl; static {{nameStripped}}ReferenceImpl() { diff --git a/src/WinRT.Projection.Writer/Helpers/ObjRefNameGenerator.cs b/src/WinRT.Projection.Writer/Helpers/ObjRefNameGenerator.cs index 8e971f9dcf..bc0d0bf121 100644 --- a/src/WinRT.Projection.Writer/Helpers/ObjRefNameGenerator.cs +++ b/src/WinRT.Projection.Writer/Helpers/ObjRefNameGenerator.cs @@ -245,9 +245,14 @@ public static IndentedTextWriterCallback WriteIidReferenceExpression(TypeDefinit /// public static void WriteClassObjRefDefinitions(IndentedTextWriter writer, ProjectionEmitContext context, TypeDefinition type) { - // Per-interface _objRef_* getters are emitted in BOTH impl and ref modes with full - // bodies. (Only the static factory _objRef_* getters become `throw null;` in ref mode -- - // see WriteStaticFactoryObjRef and WriteAttributedTypes.) + // The per-interface '_objRef_*' fields are private implementation details that reference + // implementation-only 'WinRT.Runtime' types ('WindowsRuntimeObjectReference', 'NativeObjectReference', + // the ABI IID accessors, etc.). A reference projection compiles against the stripped 'WinRT.Runtime' + // reference assembly and only needs the public API surface, so none of these are emitted. + if (context.Settings.ReferenceProjection) + { + return; + } // Track names emitted so we don't emit duplicates (e.g. when both IFoo and IFoo2 // produce the same _objRef_). diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Dispatching/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Dispatching/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs index d09b751561..eb925d5a72 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Dispatching/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Dispatching/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs @@ -8,10 +8,12 @@ namespace Microsoft.UI.Dispatching /// public sealed class DispatcherQueueSynchronizationContext : global::System.Threading.SynchronizationContext { +#if !CSWINRT_REFERENCE_PROJECTION /// /// The instance to use. /// private readonly WindowsRuntime.InteropServices.DispatcherQueueSynchronizationContext _innerContext; +#endif /// /// Creates a new instance with the specified parameters. @@ -20,9 +22,14 @@ public sealed class DispatcherQueueSynchronizationContext : global::System.Threa /// Thrown if is . public DispatcherQueueSynchronizationContext(global::Microsoft.UI.Dispatching.DispatcherQueue dispatcherQueue) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else _innerContext = new WindowsRuntime.InteropServices.DispatcherQueueSynchronizationContext(dispatcherQueue); +#endif } +#if !CSWINRT_REFERENCE_PROJECTION /// /// Creates a new instance with the specified parameters. /// @@ -31,23 +38,36 @@ private DispatcherQueueSynchronizationContext(WindowsRuntime.InteropServices.Dis { _innerContext = innerContext; } +#endif /// public override void Post(global::System.Threading.SendOrPostCallback d, object? state) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else _innerContext.Post(d, state); +#endif } /// public override void Send(global::System.Threading.SendOrPostCallback d, object? state) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else _innerContext.Send(d, state); +#endif } /// public override global::System.Threading.SynchronizationContext CreateCopy() { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else return new DispatcherQueueSynchronizationContext(_innerContext); +#endif } } } diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.KeyTime.cs b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.KeyTime.cs index 61e8f3509a..3d646f27e6 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.KeyTime.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.KeyTime.cs @@ -3,8 +3,8 @@ namespace Microsoft.UI.Xaml.Media.Animation { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Microsoft.UI")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeMetadata("Microsoft.UI")] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Microsoft.UI.Xaml.Media.Animation.KeyTimeComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.RepeatBehavior.cs b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.RepeatBehavior.cs index 972909273e..c768ea8449 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.RepeatBehavior.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.RepeatBehavior.cs @@ -3,8 +3,8 @@ namespace Microsoft.UI.Xaml.Media.Animation { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Microsoft.UI")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeMetadata("Microsoft.UI")] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Microsoft.UI.Xaml.Media.Animation.RepeatBehaviorComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Media3D/Microsoft.UI.Xaml.Media.Media3D.Matrix3D.cs b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Media3D/Microsoft.UI.Xaml.Media.Media3D.Matrix3D.cs index 873cc52c02..0fa0e83f5c 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Media3D/Microsoft.UI.Xaml.Media.Media3D.Matrix3D.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Media3D/Microsoft.UI.Xaml.Media.Media3D.Matrix3D.cs @@ -3,8 +3,8 @@ namespace Microsoft.UI.Xaml.Media.Media3D { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Microsoft.UI")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeMetadata("Microsoft.UI")] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Microsoft.UI.Xaml.Media.Media3D.Matrix3DComWrappersMarshaller] #endif @@ -406,6 +406,9 @@ readonly string IFormattable.ToString(string format, IFormatProvider provider) private readonly string ConvertToString(string format, IFormatProvider provider) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else if (IsIdentity) { return "Identity"; @@ -446,6 +449,7 @@ private readonly string ConvertToString(string format, IFormatProvider provider) handler.AppendFormatted(separator); handler.AppendFormatted(_m44, format); return handler.ToStringAndClear(); +#endif } public readonly override int GetHashCode() diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media/Microsoft.UI.Xaml.Media.Matrix.cs b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media/Microsoft.UI.Xaml.Media.Matrix.cs index 85c7a3ae72..e57974e62c 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media/Microsoft.UI.Xaml.Media.Matrix.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media/Microsoft.UI.Xaml.Media.Matrix.cs @@ -44,6 +44,9 @@ readonly string IFormattable.ToString(string format, IFormatProvider provider) private readonly string ConvertToString(string format, IFormatProvider provider) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else if (IsIdentity) { return "Identity"; @@ -64,6 +67,7 @@ private readonly string ConvertToString(string format, IFormatProvider provider) handler.AppendFormatted(separator); handler.AppendFormatted(OffsetY, format); return handler.ToStringAndClear(); +#endif } public readonly Point Transform(Point point) diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.CornerRadius.cs b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.CornerRadius.cs index 539d6ac177..275ac52d6d 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.CornerRadius.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.CornerRadius.cs @@ -3,8 +3,8 @@ namespace Microsoft.UI.Xaml { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Microsoft.UI")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeMetadata("Microsoft.UI")] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Microsoft.UI.Xaml.CornerRadiusComWrappersMarshaller] #endif @@ -53,6 +53,9 @@ public readonly override string ToString() private readonly string ToString(global::System.Globalization.CultureInfo cultureInfo) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else char listSeparator = global::WindowsRuntime.InteropServices.TokenizerHelper.GetNumericListSeparator(cultureInfo); // Initial capacity [64] is an estimate based on a sum of: @@ -67,6 +70,7 @@ private readonly string ToString(global::System.Globalization.CultureInfo cultur handler.AppendFormatted(listSeparator); InternalAddToHandler(_BottomLeft, ref handler); return handler.ToStringAndClear(); +#endif } private static void InternalAddToHandler(double l, ref DefaultInterpolatedStringHandler handler) diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.Duration.cs b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.Duration.cs index 524df87d27..c36ab0e3c8 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.Duration.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.Duration.cs @@ -3,8 +3,8 @@ namespace Microsoft.UI.Xaml { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Microsoft.UI")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeMetadata("Microsoft.UI")] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Microsoft.UI.Xaml.DurationComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.GridLength.cs b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.GridLength.cs index 78a1fabadb..ae79055125 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.GridLength.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.GridLength.cs @@ -3,8 +3,8 @@ namespace Microsoft.UI.Xaml { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Microsoft.UI")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeMetadata("Microsoft.UI")] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Microsoft.UI.Xaml.GridLengthComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.Thickness.cs b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.Thickness.cs index d902878b13..579ab5ca78 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.Thickness.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.Thickness.cs @@ -17,6 +17,9 @@ public readonly override string ToString() private readonly string ToString(global::System.Globalization.CultureInfo cultureInfo) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else char listSeparator = global::WindowsRuntime.InteropServices.TokenizerHelper.GetNumericListSeparator(cultureInfo); // Initial capacity [64] is an estimate based on a sum of: @@ -31,6 +34,7 @@ private readonly string ToString(global::System.Globalization.CultureInfo cultur handler.AppendFormatted(listSeparator); InternalAddToHandler(Bottom, ref handler); return handler.ToStringAndClear(); +#endif } private static void InternalAddToHandler(double l, ref DefaultInterpolatedStringHandler handler) diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.Storage/WindowsRuntimeStorageExtensions.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.Storage/WindowsRuntimeStorageExtensions.cs index a48ffa4ec6..6f876ac5ae 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.Storage/WindowsRuntimeStorageExtensions.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.Storage/WindowsRuntimeStorageExtensions.cs @@ -29,6 +29,9 @@ public static class WindowsRuntimeStorageExtensions [SupportedOSPlatform("windows10.0.10240.0")] public static Task OpenStreamForReadAsync(this IStorageFile windowsRuntimeFile) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else ArgumentNullException.ThrowIfNull(windowsRuntimeFile); // Helper with the actual read logic @@ -53,6 +56,7 @@ static async Task OpenStreamForReadCoreAsync(IStorageFile windowsRuntime } return OpenStreamForReadCoreAsync(windowsRuntimeFile); +#endif } /// @@ -82,6 +86,9 @@ public static Task OpenStreamForWriteAsync(this IStorageFile windowsRunt [SupportedOSPlatform("windows10.0.10240.0")] public static Task OpenStreamForReadAsync(this IStorageFolder rootDirectory, string relativePath) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else ArgumentNullException.ThrowIfNull(rootDirectory); ArgumentException.ThrowIfNullOrWhiteSpace(relativePath); @@ -110,6 +117,7 @@ static async Task OpenStreamForReadCoreAsync(IStorageFolder rootDirector } return OpenStreamForReadCoreAsync(rootDirectory, relativePath); +#endif } /// @@ -128,6 +136,9 @@ public static Task OpenStreamForWriteAsync( string relativePath, CreationCollisionOption creationCollisionOption) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else ArgumentNullException.ThrowIfNull(rootDirectory); ArgumentException.ThrowIfNullOrWhiteSpace(relativePath); @@ -187,6 +198,7 @@ CreationCollisionOption.OpenIfExists or } return OpenStreamForWriteCoreAsync(rootDirectory, relativePath, creationCollisionOption); +#endif } /// @@ -204,6 +216,9 @@ CreationCollisionOption.OpenIfExists or FileShare share = FileShare.Read, FileOptions options = FileOptions.None) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else ArgumentNullException.ThrowIfNull(windowsRuntimeFile); return global::WindowsRuntime.InteropServices.IStorageItemHandleAccessMethods.Create( @@ -211,6 +226,7 @@ CreationCollisionOption.OpenIfExists or access, share, options); +#endif } /// @@ -247,6 +263,9 @@ CreationCollisionOption.OpenIfExists or FileShare share = FileShare.Read, FileOptions options = FileOptions.None) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else ArgumentNullException.ThrowIfNull(rootDirectory); ArgumentNullException.ThrowIfNull(relativePath); @@ -257,6 +276,7 @@ CreationCollisionOption.OpenIfExists or access, share, options); +#endif } /// @@ -264,6 +284,9 @@ CreationCollisionOption.OpenIfExists or [SupportedOSPlatform("windows10.0.10240.0")] private static async Task OpenStreamForWriteWithOffsetAsync(IStorageFile windowsRuntimeFile, long offset) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else Debug.Assert(windowsRuntimeFile is not null); Debug.Assert(offset >= 0); @@ -287,6 +310,7 @@ private static async Task OpenStreamForWriteWithOffsetAsync(IStorageFile return null; } +#endif } } #nullable restore diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.KeyTime.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.KeyTime.cs index 0b5d196c20..f5ac263652 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.KeyTime.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.KeyTime.cs @@ -3,8 +3,8 @@ namespace Windows.UI.Xaml.Media.Animation { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Windows.UI.Xaml.Media.Animation.KeyTimeComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.RepeatBehavior.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.RepeatBehavior.cs index c19f73bc48..5cc7ef1abf 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.RepeatBehavior.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.RepeatBehavior.cs @@ -3,8 +3,8 @@ namespace Windows.UI.Xaml.Media.Animation { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Windows.UI.Xaml.Media.Animation.RepeatBehaviorComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.Matrix3D.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.Matrix3D.cs index f11fe74cbb..ed17ff3efc 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.Matrix3D.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.Matrix3D.cs @@ -3,8 +3,8 @@ namespace Windows.UI.Xaml.Media.Media3D { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Windows.UI.Xaml.Media.Media3D.Matrix3DComWrappersMarshaller] #endif @@ -406,6 +406,9 @@ readonly string IFormattable.ToString(string format, IFormatProvider provider) private readonly string ConvertToString(string format, IFormatProvider provider) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else if (IsIdentity) { return "Identity"; @@ -446,6 +449,7 @@ private readonly string ConvertToString(string format, IFormatProvider provider) handler.AppendFormatted(separator); handler.AppendFormatted(_m44, format); return handler.ToStringAndClear(); +#endif } public readonly override int GetHashCode() diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.Matrix.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.Matrix.cs index 3ffce829f5..a643aa0a03 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.Matrix.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.Matrix.cs @@ -44,6 +44,9 @@ readonly string IFormattable.ToString(string format, IFormatProvider provider) private readonly string ConvertToString(string format, IFormatProvider provider) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else if (IsIdentity) { return "Identity"; @@ -64,6 +67,7 @@ private readonly string ConvertToString(string format, IFormatProvider provider) handler.AppendFormatted(separator); handler.AppendFormatted(OffsetY, format); return handler.ToStringAndClear(); +#endif } public readonly Point Transform(Point point) diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.System.DispatcherQueueSynchronizationContext.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.System.DispatcherQueueSynchronizationContext.cs index 59c3dac908..a61f9424f3 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.System.DispatcherQueueSynchronizationContext.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.System.DispatcherQueueSynchronizationContext.cs @@ -8,10 +8,12 @@ namespace Windows.System /// public sealed class DispatcherQueueSynchronizationContext : global::System.Threading.SynchronizationContext { +#if !CSWINRT_REFERENCE_PROJECTION /// /// The instance to use. /// private readonly WindowsRuntime.InteropServices.DispatcherQueueSynchronizationContext _innerContext; +#endif /// /// Creates a new instance with the specified parameters. @@ -20,9 +22,14 @@ public sealed class DispatcherQueueSynchronizationContext : global::System.Threa /// Thrown if is . public DispatcherQueueSynchronizationContext(global::Windows.System.DispatcherQueue dispatcherQueue) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else _innerContext = new WindowsRuntime.InteropServices.DispatcherQueueSynchronizationContext(dispatcherQueue); +#endif } +#if !CSWINRT_REFERENCE_PROJECTION /// /// Creates a new instance with the specified parameters. /// @@ -31,23 +38,36 @@ private DispatcherQueueSynchronizationContext(WindowsRuntime.InteropServices.Dis { _innerContext = innerContext; } +#endif /// public override void Post(global::System.Threading.SendOrPostCallback d, object? state) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else _innerContext.Post(d, state); +#endif } /// public override void Send(global::System.Threading.SendOrPostCallback d, object? state) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else _innerContext.Send(d, state); +#endif } /// public override global::System.Threading.SynchronizationContext CreateCopy() { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else return new DispatcherQueueSynchronizationContext(_innerContext); +#endif } } } diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.CornerRadius.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.CornerRadius.cs index 0e51a5163c..74c03e0be0 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.CornerRadius.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.CornerRadius.cs @@ -3,8 +3,8 @@ namespace Windows.UI.Xaml { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Windows.UI.Xaml.CornerRadiusComWrappersMarshaller] #endif @@ -53,6 +53,9 @@ public readonly override string ToString() private readonly string ToString(global::System.Globalization.CultureInfo cultureInfo) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else char listSeparator = global::WindowsRuntime.InteropServices.TokenizerHelper.GetNumericListSeparator(cultureInfo); // Initial capacity [64] is an estimate based on a sum of: @@ -67,6 +70,7 @@ private readonly string ToString(global::System.Globalization.CultureInfo cultur handler.AppendFormatted(listSeparator); InternalAddToHandler(_BottomLeft, ref handler); return handler.ToStringAndClear(); +#endif } private static void InternalAddToHandler(double l, ref DefaultInterpolatedStringHandler handler) diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.Duration.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.Duration.cs index d8dd051cb9..00e6de2077 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.Duration.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.Duration.cs @@ -3,8 +3,8 @@ namespace Windows.UI.Xaml { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Windows.UI.Xaml.DurationComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.GridLength.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.GridLength.cs index 15be3b17a7..cd6db72037 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.GridLength.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.GridLength.cs @@ -3,8 +3,8 @@ namespace Windows.UI.Xaml { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Windows.UI.Xaml.GridLengthComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.Thickness.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.Thickness.cs index cc67420d37..46673ef80a 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.Thickness.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.Thickness.cs @@ -17,6 +17,9 @@ public readonly override string ToString() private readonly string ToString(global::System.Globalization.CultureInfo cultureInfo) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else char listSeparator = global::WindowsRuntime.InteropServices.TokenizerHelper.GetNumericListSeparator(cultureInfo); // Initial capacity [64] is an estimate based on a sum of: @@ -31,6 +34,7 @@ private readonly string ToString(global::System.Globalization.CultureInfo cultur handler.AppendFormatted(listSeparator); InternalAddToHandler(Bottom, ref handler); return handler.ToStringAndClear(); +#endif } private static void InternalAddToHandler(double l, ref DefaultInterpolatedStringHandler handler) diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI/Windows.UI.Color.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI/Windows.UI.Color.cs index f66ad04b79..aef6921859 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI/Windows.UI.Color.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI/Windows.UI.Color.cs @@ -31,6 +31,9 @@ readonly string IFormattable.ToString(string format, IFormatProvider provider) private readonly string ConvertToString(string format, IFormatProvider provider) { +#if CSWINRT_REFERENCE_PROJECTION + throw null; +#else if (format == null) { DefaultInterpolatedStringHandler handler = new(1, 4, provider, stackalloc char[32]); @@ -60,6 +63,7 @@ private readonly string ConvertToString(string format, IFormatProvider provider) handler.AppendFormatted(B, format); return handler.ToStringAndClear(); } +#endif } } } \ No newline at end of file diff --git a/src/WinRT.Projection.Writer/Resources/Base/AssemblyAttributes.cs b/src/WinRT.Projection.Writer/Resources/Base/AssemblyAttributes.cs new file mode 100644 index 0000000000..4df31b8f82 --- /dev/null +++ b/src/WinRT.Projection.Writer/Resources/Base/AssemblyAttributes.cs @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#if CSWINRT_REFERENCE_PROJECTION +#pragma warning disable CSWINRT3004 // "Type or member '...' is a private implementation detail" +[assembly: WindowsRuntime.InteropServices.WindowsRuntimeReferenceAssembly] +#else +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly: DisableRuntimeMarshallingAttribute] +[assembly: AssemblyMetadata("IsTrimmable", "True")] +[assembly: AssemblyMetadata("IsAotCompatible", "True")] +#endif \ No newline at end of file diff --git a/src/WinRT.Projection.Writer/Resources/Base/InspectableVftbl.cs b/src/WinRT.Projection.Writer/Resources/Base/InspectableVftbl.cs deleted file mode 100644 index d11da42786..0000000000 --- a/src/WinRT.Projection.Writer/Resources/Base/InspectableVftbl.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#if CSWINRT_REFERENCE_PROJECTION -[assembly: WindowsRuntime.InteropServices.WindowsRuntimeReferenceAssembly] -#else -using System; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Windows.Foundation; - -[assembly: DisableRuntimeMarshallingAttribute] -[assembly: AssemblyMetadata("IsTrimmable", "True")] -[assembly: AssemblyMetadata("IsAotCompatible", "True")] - -namespace WindowsRuntime.InteropServices; - -[StructLayout(LayoutKind.Sequential)] -internal unsafe struct IInspectableVftbl -{ - public delegate* unmanaged[MemberFunction] QueryInterface; - public delegate* unmanaged[MemberFunction] AddRef; - public delegate* unmanaged[MemberFunction] Release; - public delegate* unmanaged[MemberFunction] GetIids; - public delegate* unmanaged[MemberFunction] GetRuntimeClassName; - public delegate* unmanaged[MemberFunction] GetTrustLevel; -} - -[StructLayout(LayoutKind.Sequential)] -internal unsafe struct ReferenceVftbl -{ - public delegate* unmanaged[MemberFunction] QueryInterface; - public delegate* unmanaged[MemberFunction] AddRef; - public delegate* unmanaged[MemberFunction] Release; - public delegate* unmanaged[MemberFunction] GetIids; - public delegate* unmanaged[MemberFunction] GetRuntimeClassName; - public delegate* unmanaged[MemberFunction] GetTrustLevel; - public delegate* unmanaged[MemberFunction] get_Value; -} - -[StructLayout(LayoutKind.Sequential)] -internal unsafe struct IUnknownVftbl -{ - public delegate* unmanaged[MemberFunction] QueryInterface; - public delegate* unmanaged[MemberFunction] AddRef; - public delegate* unmanaged[MemberFunction] Release; -} -#endif \ No newline at end of file diff --git a/src/WinRT.Runtime2/InteropServices/Attributes/WindowsRuntimeComponentAssemblyAttribute.cs b/src/WinRT.Runtime2/InteropServices/Attributes/WindowsRuntimeComponentAssemblyAttribute.cs index bc1c1b1492..79da463700 100644 --- a/src/WinRT.Runtime2/InteropServices/Attributes/WindowsRuntimeComponentAssemblyAttribute.cs +++ b/src/WinRT.Runtime2/InteropServices/Attributes/WindowsRuntimeComponentAssemblyAttribute.cs @@ -1,9 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -#define WINDOWS_RUNTIME_IMPLEMENTATION_ONLY_FILE - using System; +#if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY +using System.ComponentModel; +#endif namespace WindowsRuntime.InteropServices; @@ -17,7 +18,13 @@ namespace WindowsRuntime.InteropServices; /// /// [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)] -[WindowsRuntimeImplementationOnlyMember] +#if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY +[Obsolete( + WindowsRuntimeConstants.WindowsRuntimeComponentAssemblyObsoleteMessage, + DiagnosticId = WindowsRuntimeConstants.WindowsRuntimeComponentAssemblyObsoleteDiagnosticId, + UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)] +[EditorBrowsable(EditorBrowsableState.Never)] +#endif public sealed class WindowsRuntimeComponentAssemblyAttribute : Attribute { /// diff --git a/src/WinRT.Runtime2/InteropServices/Attributes/WindowsRuntimeComponentAssemblyExportsTypeAttribute.cs b/src/WinRT.Runtime2/InteropServices/Attributes/WindowsRuntimeComponentAssemblyExportsTypeAttribute.cs index 484d3322d3..5c14c13308 100644 --- a/src/WinRT.Runtime2/InteropServices/Attributes/WindowsRuntimeComponentAssemblyExportsTypeAttribute.cs +++ b/src/WinRT.Runtime2/InteropServices/Attributes/WindowsRuntimeComponentAssemblyExportsTypeAttribute.cs @@ -1,9 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -#define WINDOWS_RUNTIME_IMPLEMENTATION_ONLY_FILE - using System; +#if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY +using System.ComponentModel; +#endif namespace WindowsRuntime.InteropServices; @@ -16,7 +17,13 @@ namespace WindowsRuntime.InteropServices; /// /// [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)] -[WindowsRuntimeImplementationOnlyMember] +#if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY +[Obsolete( + WindowsRuntimeConstants.WindowsRuntimeComponentAssemblyObsoleteMessage, + DiagnosticId = WindowsRuntimeConstants.WindowsRuntimeComponentAssemblyObsoleteDiagnosticId, + UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)] +[EditorBrowsable(EditorBrowsableState.Never)] +#endif public sealed class WindowsRuntimeComponentAssemblyExportsTypeAttribute : Attribute { /// diff --git a/src/WinRT.Runtime2/InteropServices/Attributes/WindowsRuntimeReferenceAssemblyAttribute.cs b/src/WinRT.Runtime2/InteropServices/Attributes/WindowsRuntimeReferenceAssemblyAttribute.cs index a7d2d0a06c..d13a59f423 100644 --- a/src/WinRT.Runtime2/InteropServices/Attributes/WindowsRuntimeReferenceAssemblyAttribute.cs +++ b/src/WinRT.Runtime2/InteropServices/Attributes/WindowsRuntimeReferenceAssemblyAttribute.cs @@ -1,9 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -#define WINDOWS_RUNTIME_IMPLEMENTATION_ONLY_FILE - using System; +#if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY +using System.ComponentModel; +#endif namespace WindowsRuntime.InteropServices; @@ -14,11 +15,20 @@ namespace WindowsRuntime.InteropServices; /// for Windows Runtime projections consumed directly from a local project reference. /// /// -/// This attribute is emitted by the CsWinRT generator, and it is not meant to be used directly. +/// This attribute is emitted by the CsWinRT generator, and it is not meant to be used directly. Unlike most other CsWinRT +/// implementation details, it is not stripped from the WinRT.Runtime.dll reference assembly: it is applied (via +/// [assembly: WindowsRuntimeReferenceAssembly]) to the reference projection assemblies that ship in Windows Runtime +/// projection NuGet packages, so it must remain resolvable when those assemblies are consumed. /// /// [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)] -[WindowsRuntimeImplementationOnlyMember] +#if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY +[Obsolete( + WindowsRuntimeConstants.WindowsRuntimeReferenceAssemblyObsoleteMessage, + DiagnosticId = WindowsRuntimeConstants.WindowsRuntimeReferenceAssemblyObsoleteDiagnosticId, + UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)] +[EditorBrowsable(EditorBrowsableState.Never)] +#endif public sealed class WindowsRuntimeReferenceAssemblyAttribute : Attribute { /// diff --git a/src/WinRT.Runtime2/InteropServices/TypeMapGroups/DynamicInterfaceCastableImplementationTypeMapGroup.cs b/src/WinRT.Runtime2/InteropServices/TypeMapGroups/DynamicInterfaceCastableImplementationTypeMapGroup.cs index dfddd5369b..f5d212dc26 100644 --- a/src/WinRT.Runtime2/InteropServices/TypeMapGroups/DynamicInterfaceCastableImplementationTypeMapGroup.cs +++ b/src/WinRT.Runtime2/InteropServices/TypeMapGroups/DynamicInterfaceCastableImplementationTypeMapGroup.cs @@ -1,6 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +#if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY +using System; +using System.ComponentModel; +#endif + namespace WindowsRuntime.InteropServices; /// @@ -10,7 +15,13 @@ namespace WindowsRuntime.InteropServices; /// /// This type is only meant to be used as type map group for APIs. /// -[WindowsRuntimeImplementationOnlyMember] +#if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY +[Obsolete( + WindowsRuntimeConstants.WindowsRuntimeTypeMapGroupObsoleteMessage, + DiagnosticId = WindowsRuntimeConstants.WindowsRuntimeTypeMapGroupObsoleteDiagnosticId, + UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)] +[EditorBrowsable(EditorBrowsableState.Never)] +#endif public abstract class DynamicInterfaceCastableImplementationTypeMapGroup { /// diff --git a/src/WinRT.Runtime2/InteropServices/TypeMapGroups/WindowsRuntimeComWrappersTypeMapGroup.cs b/src/WinRT.Runtime2/InteropServices/TypeMapGroups/WindowsRuntimeComWrappersTypeMapGroup.cs index b124e507a5..80aab02a3b 100644 --- a/src/WinRT.Runtime2/InteropServices/TypeMapGroups/WindowsRuntimeComWrappersTypeMapGroup.cs +++ b/src/WinRT.Runtime2/InteropServices/TypeMapGroups/WindowsRuntimeComWrappersTypeMapGroup.cs @@ -1,6 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +#if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY +using System; +using System.ComponentModel; +#endif + namespace WindowsRuntime.InteropServices; /// @@ -9,7 +14,13 @@ namespace WindowsRuntime.InteropServices; /// /// This type is only meant to be used as type map group for APIs. /// -[WindowsRuntimeImplementationOnlyMember] +#if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY +[Obsolete( + WindowsRuntimeConstants.WindowsRuntimeTypeMapGroupObsoleteMessage, + DiagnosticId = WindowsRuntimeConstants.WindowsRuntimeTypeMapGroupObsoleteDiagnosticId, + UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)] +[EditorBrowsable(EditorBrowsableState.Never)] +#endif public abstract class WindowsRuntimeComWrappersTypeMapGroup { /// diff --git a/src/WinRT.Runtime2/InteropServices/TypeMapGroups/WindowsRuntimeMetadataTypeMapGroup.cs b/src/WinRT.Runtime2/InteropServices/TypeMapGroups/WindowsRuntimeMetadataTypeMapGroup.cs index 31b2121757..1916754edc 100644 --- a/src/WinRT.Runtime2/InteropServices/TypeMapGroups/WindowsRuntimeMetadataTypeMapGroup.cs +++ b/src/WinRT.Runtime2/InteropServices/TypeMapGroups/WindowsRuntimeMetadataTypeMapGroup.cs @@ -1,17 +1,26 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +#if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY using System; +using System.ComponentModel; +#endif namespace WindowsRuntime.InteropServices; /// -/// The type map group placeholder for all Windows Runtime types that need to support marshalling. +/// The type map group placeholder for all Windows Runtime types that need to support marshalling. /// /// /// This type is only meant to be used as type map group for APIs. /// -[WindowsRuntimeImplementationOnlyMember] +#if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY +[Obsolete( + WindowsRuntimeConstants.WindowsRuntimeTypeMapGroupObsoleteMessage, + DiagnosticId = WindowsRuntimeConstants.WindowsRuntimeTypeMapGroupObsoleteDiagnosticId, + UrlFormat = WindowsRuntimeConstants.CsWinRTDiagnosticsUrlFormat)] +[EditorBrowsable(EditorBrowsableState.Never)] +#endif public abstract class WindowsRuntimeMetadataTypeMapGroup { /// diff --git a/src/WinRT.Runtime2/InteropServices/Vtables/IInspectableVftbl.cs b/src/WinRT.Runtime2/InteropServices/Vtables/IInspectableVftbl.cs index 9db00a22d7..2a4bb7361a 100644 --- a/src/WinRT.Runtime2/InteropServices/Vtables/IInspectableVftbl.cs +++ b/src/WinRT.Runtime2/InteropServices/Vtables/IInspectableVftbl.cs @@ -6,14 +6,17 @@ using System.Runtime.InteropServices; using Windows.Foundation; +#pragma warning disable CS1591 + namespace WindowsRuntime.InteropServices; /// /// Binding type for the IInspectable interface vtable. /// /// +[WindowsRuntimeImplementationOnlyMember] [StructLayout(LayoutKind.Sequential)] -internal unsafe struct IInspectableVftbl +public unsafe struct IInspectableVftbl { public delegate* unmanaged[MemberFunction] QueryInterface; public delegate* unmanaged[MemberFunction] AddRef; @@ -36,7 +39,7 @@ internal unsafe struct IInspectableVftbl /// /// The HRESULT for the operation. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static HRESULT GetIidsUnsafe(void* thisPtr, uint* iidCount, Guid** iids) + internal static HRESULT GetIidsUnsafe(void* thisPtr, uint* iidCount, Guid** iids) { return ((IInspectableVftbl*)*(void***)thisPtr)->GetIids(thisPtr, iidCount, iids); } @@ -48,7 +51,7 @@ public static HRESULT GetIidsUnsafe(void* thisPtr, uint* iidCount, Guid** iids) /// The fully qualified name of the current Windows Runtime object. /// The HRESULT for the operation. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static HRESULT GetRuntimeClassNameUnsafe(void* thisPtr, HSTRING* className) + internal static HRESULT GetRuntimeClassNameUnsafe(void* thisPtr, HSTRING* className) { return ((IInspectableVftbl*)*(void***)thisPtr)->GetRuntimeClassName(thisPtr, className); } @@ -60,7 +63,7 @@ public static HRESULT GetRuntimeClassNameUnsafe(void* thisPtr, HSTRING* classNam /// The trust level of the current Windows Runtime object. The default is . /// This method always returns S_OK. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static HRESULT GetTrustLevelUnsafe(void* thisPtr, TrustLevel* trustLevel) + internal static HRESULT GetTrustLevelUnsafe(void* thisPtr, TrustLevel* trustLevel) { return ((IInspectableVftbl*)*(void***)thisPtr)->GetTrustLevel(thisPtr, trustLevel); } diff --git a/src/WinRT.Runtime2/InteropServices/Vtables/IReferenceVftbl.cs b/src/WinRT.Runtime2/InteropServices/Vtables/IReferenceVftbl.cs index 8f1c892b85..44ae96a4e3 100644 --- a/src/WinRT.Runtime2/InteropServices/Vtables/IReferenceVftbl.cs +++ b/src/WinRT.Runtime2/InteropServices/Vtables/IReferenceVftbl.cs @@ -6,7 +6,7 @@ using System.Runtime.InteropServices; using Windows.Foundation; -#pragma warning disable IDE1006 +#pragma warning disable CS1591, IDE1006 namespace WindowsRuntime.InteropServices; @@ -14,8 +14,9 @@ namespace WindowsRuntime.InteropServices; /// Binding type for the IReference`1 interface vtable. /// /// +[WindowsRuntimeImplementationOnlyMember] [StructLayout(LayoutKind.Sequential)] -internal unsafe struct IReferenceVftbl +public unsafe struct IReferenceVftbl { public delegate* unmanaged[MemberFunction] QueryInterface; public delegate* unmanaged[MemberFunction] AddRef; @@ -32,7 +33,7 @@ internal unsafe struct IReferenceVftbl /// The resulting value. /// The HRESULT for the operation. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static HRESULT get_ValueUnsafe(void* thisPtr, void* value) + internal static HRESULT get_ValueUnsafe(void* thisPtr, void* value) { return ((IReferenceVftbl*)*(void***)thisPtr)->get_Value(thisPtr, value); } diff --git a/src/WinRT.Runtime2/InteropServices/Vtables/IUnknownVftbl.cs b/src/WinRT.Runtime2/InteropServices/Vtables/IUnknownVftbl.cs index 1ef471420d..36cdc3cbb5 100644 --- a/src/WinRT.Runtime2/InteropServices/Vtables/IUnknownVftbl.cs +++ b/src/WinRT.Runtime2/InteropServices/Vtables/IUnknownVftbl.cs @@ -5,14 +5,17 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +#pragma warning disable CS1591 + namespace WindowsRuntime.InteropServices; /// /// Binding type for the IUnknown interface vtable. /// /// +[WindowsRuntimeImplementationOnlyMember] [StructLayout(LayoutKind.Sequential)] -internal unsafe struct IUnknownVftbl +public unsafe struct IUnknownVftbl { public delegate* unmanaged[MemberFunction] QueryInterface; public delegate* unmanaged[MemberFunction] AddRef; @@ -26,7 +29,7 @@ internal unsafe struct IUnknownVftbl /// The address of a pointer to an interface with the IID specified in the parameter. /// This method returns S_OK if the interface is supported, and E_NOINTERFACE otherwise. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static HRESULT QueryInterfaceUnsafe(void* thisPtr, Guid* riid, void** ppvObject) + internal static HRESULT QueryInterfaceUnsafe(void* thisPtr, Guid* riid, void** ppvObject) { return ((IUnknownVftbl*)*(void***)thisPtr)->QueryInterface(thisPtr, riid, ppvObject); } @@ -36,7 +39,7 @@ public static HRESULT QueryInterfaceUnsafe(void* thisPtr, Guid* riid, void** ppv /// The pointer to an interface with the IID specified in the parameter. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static HRESULT QueryInterfaceUnsafe(void* thisPtr, in Guid iid, out void* pvObject) + internal static HRESULT QueryInterfaceUnsafe(void* thisPtr, in Guid iid, out void* pvObject) { fixed (Guid* riid = &iid) fixed (void** ppvObject = &pvObject) @@ -51,7 +54,7 @@ public static HRESULT QueryInterfaceUnsafe(void* thisPtr, in Guid iid, out void* /// The target COM object. /// The method returns the new reference count. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint AddRefUnsafe(void* thisPtr) + internal static uint AddRefUnsafe(void* thisPtr) { return ((IUnknownVftbl*)*(void***)thisPtr)->AddRef(thisPtr); } @@ -62,7 +65,7 @@ public static uint AddRefUnsafe(void* thisPtr) /// The target COM object. /// The method returns the new reference count. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint ReleaseUnsafe(void* thisPtr) + internal static uint ReleaseUnsafe(void* thisPtr) { return ((IUnknownVftbl*)*(void***)thisPtr)->Release(thisPtr); } diff --git a/src/WinRT.Runtime2/Properties/WindowsRuntimeConstants.cs b/src/WinRT.Runtime2/Properties/WindowsRuntimeConstants.cs index befb33eb05..b6609a3f28 100644 --- a/src/WinRT.Runtime2/Properties/WindowsRuntimeConstants.cs +++ b/src/WinRT.Runtime2/Properties/WindowsRuntimeConstants.cs @@ -22,6 +22,51 @@ internal static class WindowsRuntimeConstants /// public const string WindowsRuntimeObjectConstructorObsoleteDiagnosticId = "CSWINRT3001"; + /// + /// A message for the type map group types (see the WindowsRuntime.InteropServices type map group placeholders). + /// + public const string WindowsRuntimeTypeMapGroupObsoleteMessage = + "This type is a private implementation detail, and it must never be used directly. It is only meant to be used as a type map " + + "group type argument for the 'System.Runtime.InteropServices.TypeMapping' APIs, in marshalling code generated by CsWinRT " + + "(produced by 'cswinrtinteropgen.exe' and by the CsWinRT source generator). It is not considered part of the versioned API " + + "surface, and it may be modified or removed across any version change for 'WinRT.Runtime.dll'. Using it in user code is " + + "undefined behavior and not supported."; + + /// + /// The diagnostic id for the type map group types. + /// + public const string WindowsRuntimeTypeMapGroupObsoleteDiagnosticId = "CSWINRT3002"; + + /// + /// A message for the Windows Runtime component assembly attributes (see WindowsRuntimeComponentAssemblyAttribute and WindowsRuntimeComponentAssemblyExportsTypeAttribute). + /// + public const string WindowsRuntimeComponentAssemblyObsoleteMessage = + "This attribute is a private implementation detail, and it must never be used directly. It is only meant to be applied to " + + "authored Windows Runtime component assemblies by CsWinRT (produced by the CsWinRT source generator), to mark them and " + + "identify their generated activation factory entry point. It is not considered part of the versioned API surface, and it " + + "may be modified or removed across any version change for 'WinRT.Runtime.dll'. Using it in user code is undefined behavior " + + "and not supported."; + + /// + /// The diagnostic id for the Windows Runtime component assembly attributes. + /// + public const string WindowsRuntimeComponentAssemblyObsoleteDiagnosticId = "CSWINRT3003"; + + /// + /// A message for the WindowsRuntimeReferenceAssemblyAttribute type. + /// + public const string WindowsRuntimeReferenceAssemblyObsoleteMessage = + "This attribute is a private implementation detail, and it must never be used directly. It is only meant to be applied to " + + "generated Windows Runtime projection assemblies by CsWinRT (produced by 'cswinrtprojectiongen.exe' and " + + "'cswinrtprojectionrefgen.exe'), to identify them as containing projected Windows Runtime APIs. It is not considered part " + + "of the versioned API surface, and it may be modified or removed across any version change for 'WinRT.Runtime.dll'. Using " + + "it in user code is undefined behavior and not supported."; + + /// + /// The diagnostic id for the WindowsRuntimeReferenceAssemblyAttribute type. + /// + public const string WindowsRuntimeReferenceAssemblyObsoleteDiagnosticId = "CSWINRT3004"; + /// /// The URL format for all custom diagnostics for CsWinRT. /// diff --git a/src/WinRT.Runtime2/WinRT.Runtime.csproj b/src/WinRT.Runtime2/WinRT.Runtime.csproj index 74e4743a30..70c3ae673d 100644 --- a/src/WinRT.Runtime2/WinRT.Runtime.csproj +++ b/src/WinRT.Runtime2/WinRT.Runtime.csproj @@ -168,12 +168,29 @@ + + + + + - + + diff --git a/src/WinRT.Runtime2/Windows.Foundation/TrustLevel.cs b/src/WinRT.Runtime2/Windows.Foundation/TrustLevel.cs index 727f34a9f0..a7d652be2a 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/TrustLevel.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/TrustLevel.cs @@ -10,9 +10,6 @@ namespace Windows.Foundation; /// /// Represents the trust level of an activatable class. /// -/// -/// This type is required for ABI projection of Windows Runtime types, but marshalling it is not supported. -/// /// [WindowsRuntimeImplementationOnlyMember] public enum TrustLevel diff --git a/src/WinRT.Runtime2/Windows.UI.Xaml.Interop/TypeKind.cs b/src/WinRT.Runtime2/Windows.UI.Xaml.Interop/TypeKind.cs index f97858b6ce..8c4a1d3c8b 100644 --- a/src/WinRT.Runtime2/Windows.UI.Xaml.Interop/TypeKind.cs +++ b/src/WinRT.Runtime2/Windows.UI.Xaml.Interop/TypeKind.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -using System; using WindowsRuntime; namespace Windows.UI.Xaml.Interop; @@ -9,9 +8,6 @@ namespace Windows.UI.Xaml.Interop; /// /// Provides basic guidance about the origin of a type. /// -/// -/// This type is required for ABI projection of the class, but marshalling it is not supported. -/// /// [WindowsRuntimeImplementationOnlyMember] public enum TypeKind diff --git a/src/build.cmd b/src/build.cmd index ab4c18a5eb..e7342f9756 100644 --- a/src/build.cmd +++ b/src/build.cmd @@ -314,6 +314,23 @@ set run_cswinrt_generator_task=%this_dir%WinRT.Generator.Tasks\bin\%cswinrt_conf rem Now call pack echo Creating nuget package call :exec %nuget_dir%\nuget pack %this_dir%..\nuget\Microsoft.Windows.CsWinRT.nuspec -Properties interop_winmd=%interop_winmd%;net10_runtime=%net10_runtime%;net10_runtime_ref=%net10_runtime_ref%;net10_runtime_ref_xml=%net10_runtime_ref_xml%;source_generator=%source_generator%;cswinrt_nuget_version=%cswinrt_version_string%;winrt_host_x86=%winrt_host_x86%;winrt_host_x64=%winrt_host_x64%;winrt_host_arm=%winrt_host_arm%;winrt_host_arm64=%winrt_host_arm64%;winrt_host_resource_x86=%winrt_host_resource_x86%;winrt_host_resource_x64=%winrt_host_resource_x64%;winrt_host_resource_arm=%winrt_host_resource_arm%;winrt_host_resource_arm64=%winrt_host_resource_arm64%;winrt_shim=%winrt_shim%;cswinrtinteropgen_x64=%cswinrtinteropgen_x64%;cswinrtinteropgen_arm64=%cswinrtinteropgen_arm64%;cswinrtimplgen_x64=%cswinrtimplgen_x64%;cswinrtimplgen_arm64=%cswinrtimplgen_arm64%;cswinrtprojectiongen_x64=%cswinrtprojectiongen_x64%;cswinrtprojectiongen_arm64=%cswinrtprojectiongen_arm64%;cswinrtprojectionrefgen_x64=%cswinrtprojectionrefgen_x64%;cswinrtprojectionrefgen_arm64=%cswinrtprojectionrefgen_arm64%;cswinrtwinmdgen_x64=%cswinrtwinmdgen_x64%;cswinrtwinmdgen_arm64=%cswinrtwinmdgen_arm64%;run_cswinrt_generator_task=%run_cswinrt_generator_task%; -OutputDirectory %cswinrt_bin_dir% -NonInteractive -Verbosity Detailed -NoPackageAnalysis + +:smoketest +rem Build and run the end-to-end smoke tests against the just-built NuGet package. These +rem verify that the real package (ref/lib assemblies, generators, and build targets) works +rem for a consuming app, a component author, and a projection author, fully isolated from the +rem repo build infrastructure. They run only on x64 (matching the native build tools packaged +rem for the host architecture) and can be skipped by setting 'cswinrt_run_smoke_tests=false'. +if /I not "%cswinrt_platform%"=="x64" goto :eof +if /I "%cswinrt_run_smoke_tests%"=="false" goto :eof + +echo Running smoke tests for %cswinrt_platform% %cswinrt_configuration% +call :exec powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%this_dir%Tests\SmokeTests\run-smoke-tests.ps1" -PackageSource "%cswinrt_bin_dir%" -PackageVersion %cswinrt_version_string% -Configuration %cswinrt_configuration% +if ErrorLevel 1 ( + echo. + echo ERROR: Smoke tests failed + exit /b !ErrorLevel! +) goto :eof :exec