Skip to content

Fix GenAPI omitting explicitly implemented interface events - #54492

Merged
ViktorHofer merged 3 commits into
dotnet:mainfrom
ViktorHofer:fix-genapi-explicit-interface-events
May 29, 2026
Merged

ViktorHofer merged 3 commits into
dotnet:mainfrom
ViktorHofer:fix-genapi-explicit-interface-events

Conversation

@ViktorHofer

Copy link
Copy Markdown
Member

Fixes #54464

GenAPI silently dropped explicit interface event implementations, causing generated reference assemblies to fail compilation with CS0535.

Root cause

Two layers:

  1. SymbolExtensions.IsExplicitInterfaceImplementation only recognized IMethodSymbol and IPropertySymbol. Explicit-impl events have DeclaredAccessibility=Private and were filtered out as private members before reaching the syntax generator.
  2. SyntaxGeneratorExtensions.DeclarationExt routed all events through SyntaxGenerator.CustomEventDeclaration, which has no overload that accepts an ExplicitInterfaceSpecifier, so the explicit qualification was lost even when the symbol made it through.

Changes

  • SymbolExtensions: recognize IEventSymbol explicit impls. This shared helper is used by ApiCompat, ApiDiff and GenAPI, so the fix benefits all three.
  • SyntaxGeneratorExtensions: new CreateExplicitInterfaceEventDeclaration helper emits EventDeclarationSyntax with ExplicitInterfaceSpecifier and empty add/remove blocks.
  • CSharpAssemblyDocumentGenerator: mirror the existing method/property filter for events. An explicit-impl event whose containing interface is excluded by the symbol filter is also excluded. This preserves the invariant (already honored for methods and properties) that explicit interface implementations are part of the public API only when the underlying interface is public.
  • ImplicitSymbolFilter: extend the explicit-impl accessor filter to also drop EventAdd / EventRemove accessor methods, paralleling the existing PropertyGet / PropertySet handling so accessors are not emitted twice.

Tests

  • TestExplicitInterfaceEventGeneration — happy path, asserts the explicit event is emitted with the correct interface qualifier.
  • TestExplicitInterfaceEventFromInternalInterfaceIsExcluded — asserts the new filter actually drops explicit events whose underlying interface is internal.

Full GenAPI test suite: 100 pass, 2 pre-existing skips, 0 failures.

Fixes dotnet#54464

GenAPI silently dropped explicit interface event implementations, causing
generated reference assemblies to fail compilation with CS0535.

Root causes (two layers):

1. SymbolExtensions.IsExplicitInterfaceImplementation only recognized
   IMethodSymbol and IPropertySymbol. Explicit-impl events have
   DeclaredAccessibility=Private and were filtered as private members.

2. SyntaxGeneratorExtensions.DeclarationExt routed all events through
   SyntaxGenerator.CustomEventDeclaration, which has no overload that
   accepts an ExplicitInterfaceSpecifier, so the explicit qualification
   was lost.

Changes:

* SymbolExtensions: recognize IEventSymbol explicit impls.
* SyntaxGeneratorExtensions: new CreateExplicitInterfaceEventDeclaration
  helper emitting EventDeclarationSyntax with ExplicitInterfaceSpecifier
  and empty add/remove blocks.
* CSharpAssemblyDocumentGenerator: mirror the existing method/property
  filter for events, so an explicit-impl event whose containing interface
  is excluded by the symbol filter is also excluded. This keeps the
  invariant that explicit interface implementations are part of the
  public API only when the underlying interface is public.
* ImplicitSymbolFilter: extend the explicit-impl accessor filter to also
  drop EventAdd / EventRemove accessor methods, paralleling the existing
  PropertyGet / PropertySet handling so accessors are not emitted twice.

Tests: added TestExplicitInterfaceEventGeneration and
TestExplicitInterfaceEventFromInternalInterfaceIsExcluded.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 28, 2026 14:28
@ViktorHofer
ViktorHofer requested a review from a team as a code owner May 28, 2026 14:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes GenAPI handling for explicit interface event implementations so generated reference source includes required event members and avoids CS0535 failures.

Changes:

  • Recognizes explicit interface implementations for IEventSymbol.
  • Emits explicit interface event declarations directly when SyntaxGenerator cannot represent them.
  • Adds filtering and tests for explicit events, including excluded internal interfaces.
Show a summary per file
File Description
src/Compatibility/Microsoft.DotNet.ApiSymbolExtensions/SymbolExtensions.cs Extends explicit-interface detection to events.
src/Compatibility/Microsoft.DotNet.ApiSymbolExtensions/Filtering/ImplicitSymbolFilter.cs Filters explicit event add/remove accessor methods.
src/Compatibility/GenAPI/Microsoft.DotNet.GenAPI/SyntaxGeneratorExtensions.cs Adds direct syntax generation for explicit interface event declarations.
src/Compatibility/GenAPI/Microsoft.DotNet.GenAPI/CSharpAssemblyDocumentGenerator.cs Filters explicit events from interfaces excluded by the symbol filter.
test/Microsoft.DotNet.GenAPI.Tests/CSharpFileBuilderTests.cs Adds GenAPI tests for explicit interface event generation and filtering.

Copilot's findings

  • Files reviewed: 5/5 changed files
  • Comments generated: 1

…vent and property impls

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
MemoryOutputDiffGenerator.GetMembersOfType filtered out all members lacking public/protected modifiers, which excluded explicit interface implementations (methods, properties, events, indexers). Explicit impls of public interfaces are part of the public API surface and must be reported in diffs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ViktorHofer
ViktorHofer merged commit 056dfbc into dotnet:main May 29, 2026
25 checks passed
@ViktorHofer
ViktorHofer deleted the fix-genapi-explicit-interface-events branch May 29, 2026 08:05
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 11.0-preview6 milestone May 29, 2026
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.

GenAPI omits explicitly implemented interface events from generated reference source

3 participants