Skip to content

User/chriwall/deprecated#2376

Open
Dreynor87 wants to merge 9 commits intomasterfrom
user/chriwall/deprecated
Open

User/chriwall/deprecated#2376
Dreynor87 wants to merge 9 commits intomasterfrom
user/chriwall/deprecated

Conversation

@Dreynor87
Copy link
Copy Markdown

Chris Wall (WIN SDE) and others added 9 commits March 2, 2026 14:58
Added is_deprecated(), get_deprecated_message(), and is_removed() helpers
to helpers.h. When DeprecatedAttribute has DeprecationType.Remove (arg[1]==1):
- Classes, delegates, enums, structs are completely skipped
- Removed enum fields are skipped
- Removed methods, properties, and events are skipped from interface
  member projections
- ABI-level vtable structures are preserved for binary compatibility

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix pre-existing MSB4096 build error in Strings.props (qualify metadata)
- Add is_deprecated(), get_deprecated_message(), is_removed(),
  is_deprecated_not_removed() helpers in helpers.h
- Add write_obsolete_attribute() to emit [System.Obsolete] for deprecated types
- Add [Obsolete] annotations for classes, delegates, enums, structs,
  methods, properties, events, and enum fields
- Skip fully removed types/members from generated C# projection
- cswinrt.exe builds and generates correct output

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Create test IDL with mix of normal, deprecated, and removed types:
  RemovedEnum, PartiallyRemovedEnum, DeprecatedEnum, NormalEnum,
  IVtableTest (normal/deprecated/removed methods), delegates, classes, structs
- Compile to WinMD using MIDL 3.0
- run_test.ps1 verifies 22 checks:
  * Removed types excluded from user projection (enum, class, delegate, struct)
  * Deprecated types have [Obsolete] annotations with messages
  * Normal types present without [Obsolete]
  * PartiallyRemovedEnum: Hidden field excluded, Visible/AlsoVisible present
  * IVtableTest: ABI vtable preserves RemovedMethod slot
  * Method-level removal: removed methods hidden, deprecated have [Obsolete]

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
write_class_method and write_class_event were missing is_removed() checks
and write_obsolete_attribute() calls, so deprecated methods on runtime classes
had no [Obsolete] attribute and removed methods were still visible.

Also fixed write_interface_member_signatures to skip removed members and
emit [Obsolete] on deprecated interface member signatures.

Added is_removed() check and deprecation tracking for properties in
write_class_members.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ct/class paths

When a WinRT type has DeprecatedAttribute with DeprecationType.Remove, CsWinRT
now properly skips generating code for it in all ABI code paths:
- write_interface: Skip projected interface definition for removed interfaces
- write_abi_interface / write_abi_interface_netstandard: Skip ABI implementation
- write_static_abi_classes: Skip static ABI helper classes
- write_abi_class: Skip ABI class code
- write_abi_delegate: Skip ABI delegate code
- write_abi_struct: Skip ABI struct marshaling code
- write_winrt_exposed_type_class: Skip WinRT exposed type class
- write_winrt_implementation_type_rcw_factory_attribute_type: Skip RCW factory

Previously, the ABI code for removed types would reference projected types
(e.g., RemovedClass, IRemovedInterface) that were correctly omitted from the
projection, causing CS0234 compile errors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… row

MIDL places the DeprecatedAttribute on the getter/add accessor methods,
not on the Property/Event metadata rows. The previous checks using
is_removed(prop)/is_removed(evt) always returned false because those
rows never carry the attribute.

Fixed in write_class_members:
- Property collection: check is_removed(getter) instead of is_removed(prop)
- property_deprecation map: store getter MethodDef for write_obsolete_attribute

Fixed in write_class_event:
- Check is_removed(add) instead of is_removed(event)
- Use write_obsolete_attribute(w, add) instead of write_obsolete_attribute(w, event)

Fixed in write_interface_member_signatures:
- Property loop: check is_removed(getter) and is_deprecated_not_removed(getter)
- Event loop: check is_removed(add) and is_deprecated_not_removed(add)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Expand the test IDL and run_test.ps1 to cover all gaps found during
functional testing against a real WinRT IDL:

Test IDL additions:
- Properties (normal/deprecated/removed) on [default_interface] runtimeclass
- Events (normal/deprecated/removed) with TestEventHandler delegate
- Deprecated and removed interface types (IDeprecatedInterface, IRemovedInterface)
- [default_interface] on TestClass and classes

New regression tests (Steps 9-13 in run_test.ps1):
- Step 9: Property deprecation/removal on projected class
  (Regression: MIDL puts DeprecatedAttr on getter, not Property row)
- Step 10: Event deprecation/removal on projected class
  (Regression: MIDL puts DeprecatedAttr on add method, not Event row)
- Step 11: Interface member signatures filter removed members and
  emit [Obsolete] on deprecated methods, properties, and events
- Step 12: ABI code integrity — no WindowsRuntimeHelperType or
  RcwFactoryAttribute references to removed types
- Step 13: Compilation test — compiles all generated C# code with
  dotnet to catch any ABI reference to missing projected types

Code fixes in code_writers.h:
- write_method_abi_invoke: Generate E_NOTIMPL stub for removed methods
  (vtable slot preserved for ABI compat, but CCW returns error)
- write_property_abi_invoke: Generate E_NOTIMPL stubs for removed
  property getter/setter (vtable slots preserved)
- write_event_abi_invoke: Generate E_NOTIMPL stubs for removed
  event add/remove (vtable slots preserved)

All 40 regression tests pass, including compilation verification.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Bugs fixed in code_writers.h:
- write_static_method: Add is_removed(method) check to skip removed
  static methods from user-facing projection
- write_static_members: Add is_removed(getter) check on static property
  loop to skip removed static properties (MIDL attribute on getter)
- write_factory_constructors: Add is_removed(method) check to skip
  removed constructor overloads from projected class

Test IDL expansion (DeprecatedRemovedTest.idl):
- Read-write properties: WritableProp, WritableDeprecatedProp,
  WritableRemovedProp (tests setter path)
- Static properties: StaticProp, StaticDeprecatedProp,
  StaticRemovedProp (tests static property removal)
- Constructor overloads: TestClass(String) deprecated,
  TestClass(String, Int32) removed

Regression test expansion (run_test.ps1): 40 -> 53 checks
- Step 13: Read-write property deprecation/removal
- Step 14: Static property deprecation/removal
- Step 15: Constructor deprecation/removal
- Step 16: Interface checks for new constructs (WritableProp)

All 53 regression tests pass including compilation verification.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…gression tests

- main.cpp: filter removed types from componentActivatableClasses
- code_writers.h: early return in write_factory_class for removed types
- run_test.ps1: add Step 18 component factory exclusion test (57 tests total)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant