Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
23 changes: 20 additions & 3 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,16 @@ The runtime library (`WinRT.Runtime.dll`) provides all common infrastructure for
- **Warnings as errors**: release only. `EnforceCodeStyleInBuild` enabled, `AnalysisLevelStyle` = `latest-all`.
- **Strong-name signed** with `key.snk`
- **AOT compatible**: `IsAotCompatible = true`
- **Dual-built**: produces both the implementation assembly and a stripped **reference assembly** (see "Reference assembly" below); the reference build adds a `Microsoft.CodeAnalysis.BannedApiAnalyzers` reference

**Directory structure:**

```
WinRT.Runtime2/
├── WindowsRuntimeObject.cs # Base class for ALL projected runtime classes
├── WindowsRuntimeObject.cs # Base class for ALL projected runtime classes (partial; reference + shared surface)
├── WindowsRuntimeObject.Impl.cs # Implementation-only half of WindowsRuntimeObject (excluded from the reference assembly)
├── WindowsRuntimeInspectable.cs # Fallback type for unknown native objects
├── BannedSymbols.txt # Banned API list for the reference assembly build (blocks implementation-only types from leaking)
├── ABI/ # ABI type mappings (managed ↔ native)
│ ├── System/ # Primitives, String, Uri, DateTimeOffset, collections, etc.
│ ├── Windows.Foundation/ # Foundation types (Point, Rect, Size, etc.)
Expand Down Expand Up @@ -242,6 +245,20 @@ WinRT.Runtime2/
- **T4 templates**: 6 `.tt` files generate constants (`HRESULT` codes, interface IIDs, XAML class names) and specialized marshallers (blittable array types).
- **Feature switches**: opt-in/opt-out runtime features are controlled via `[FeatureSwitchDefinition]`-annotated properties in `WindowsRuntimeFeatureSwitches` (`Properties/WindowsRuntimeFeatureSwitches.cs`). Each switch is backed by an `AppContext` configuration property (e.g. `CSWINRT_ENABLE_MANIFEST_FREE_ACTIVATION`) and wired to an MSBuild property (e.g. `CsWinRTEnableManifestFreeActivation`) in `nuget/Microsoft.Windows.CsWinRT.targets`, which emits `RuntimeHostConfigurationOption` items with `Trim="true"`. This lets ILLink (trimming) and ILC (Native AOT) treat the switch values as constants and dead-code-eliminate all code behind disabled switches, making opt-in features fully pay-for-play.

**Reference assembly:**

`WinRT.Runtime` is built **twice**: once as the implementation assembly (the actual `WinRT.Runtime.dll` that runs) and once as a lightweight **reference assembly** that downstream tooling and `ProjectReference` consumers compile against. The reference build is selected via the `CsWinRTBuildReferenceAssembly` MSBuild property and strips out every implementation-only type and member, so none of them are exposed on the public API surface.

- **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/`). 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<TGroup>]` 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.

**Types projected in WinRT.Runtime:**

Not all WinRT types are generated automatically by the projection writer into SDK projection assemblies. `WinRT.Runtime` contains two categories of types that require special handling:
Expand Down Expand Up @@ -669,7 +686,7 @@ The MSBuild integration is orchestrated through several `.props` and `.targets`
- **Compiler strict mode**: `<Features>strict</Features>` in all projects
- **XML documentation**: generated for all projects
- **`SkipLocalsInit`**: enabled in runtime and build tools for performance
- **Suppressed warnings**: `CS8500` (ref safety in unsafe contexts), `AD0001` (analyzer crashes), `CSWINRT3001` (obsolete internal members)
- **Suppressed warnings**: `CS8500` (ref safety in unsafe contexts), `AD0001` (analyzer crashes)
- **Strong-name signing**: all assemblies signed with `src/WinRT.Runtime2/key.snk`

### Naming conventions
Expand Down Expand Up @@ -713,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` |
| Runtime (obsolete markers) | `CSWINRT3xxx` | `CSWINRT3001` (deriving from `WindowsRuntimeObject`), `CSWINRT3002` (type map group types), `CSWINRT3003` (component authoring attributes), `CSWINRT3004` (`WindowsRuntimeReferenceAssemblyAttribute`) |

---

Expand Down
Loading