Skip to content

Strip partial modifier from generated COM interface method stubs#126719

Open
Copilot wants to merge 3 commits intomainfrom
copilot/fix-partial-interface-methods
Open

Strip partial modifier from generated COM interface method stubs#126719
Copilot wants to merge 3 commits intomainfrom
copilot/fix-partial-interface-methods

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 9, 2026

Description

ComInterfaceGenerator and VtableIndexStubGenerator copy method modifiers from user-declared interface methods into generated stub code. The new keyword and accessibility modifiers were already stripped, but partial was not — producing invalid C# when the user declares partial methods on a [GeneratedComInterface] interface.

Changes:

  • ComInterfaceGenerator.cs: Filter SyntaxKind.PartialKeyword alongside existing NewKeyword filter in CalculateStubInformation
  • VtableIndexStubGenerator.cs: Add PartialKeyword filter to modifier stripping in CalculateStubInformation
  • Compiles.cs: Add regression test confirming partial method modifiers don't produce invalid generated code

Note: LibraryImportGenerator and DownlevelLibraryImportGenerator are intentionally unchanged — they generate partial method implementations where partial must be preserved.

// User code that previously caused invalid generated output:
[GeneratedComInterface]
[Guid("...")]
internal partial interface ICalculator
{
    int Add(int a, int b);
    public partial int Subtract(int a, int b) => 0;
    public partial int Subtract(int a, int b);
}

…d VtableIndexStubGenerator

The ComInterfaceGenerator and VtableIndexStubGenerator were copying the
partial modifier from user-declared interface methods to the generated
stub code, producing invalid C#. This change strips the partial keyword
from method modifiers when creating the method syntax template, similar
to how the new keyword and accessibility modifiers are already stripped.

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/de757761-5c54-412d-9875-7403edd00714

Co-authored-by: jtschuster <36744439+jtschuster@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot April 9, 2026 17:48
Copilot AI changed the title [WIP] Fix ComInterfaceGenerator to handle partial interface methods correctly Strip partial modifier from generated COM interface method stubs Apr 9, 2026
Copilot AI requested a review from jtschuster April 9, 2026 17:52
Co-authored-by: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 9, 2026 18:33
@jtschuster jtschuster marked this pull request as ready for review April 9, 2026 18:33
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 updates the COM interface source generators to avoid emitting invalid C# when user-declared COM interface methods include the partial modifier, by stripping partial from copied method modifiers and adding a regression compilation test.

Changes:

  • Strip SyntaxKind.PartialKeyword from copied method modifiers in ComInterfaceGenerator and VtableIndexStubGenerator.
  • Add a regression test ensuring partial method modifiers on [GeneratedComInterface] methods don’t break generated code compilation.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/Compiles.cs Adds a new compilation regression test for partial method modifiers on COM interface methods.
src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VtableIndexStubGenerator.cs Filters out partial from method modifiers when constructing the syntax template for generated stubs.
src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs Filters out partial (alongside existing new filtering) from method modifiers used in generated stubs.

Comment on lines +388 to +393
internal virtual partial interface IComInterface
{
void Method();
public partial void PartialMethod();
}
internal virtual partial interface IComInterface
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

virtual is not a valid modifier on an interface declaration, so this test source will fail to compile before the generator runs. Remove virtual from both IComInterface declarations (keep partial).

Suggested change
internal virtual partial interface IComInterface
{
void Method();
public partial void PartialMethod();
}
internal virtual partial interface IComInterface
internal partial interface IComInterface
{
void Method();
public partial void PartialMethod();
}
internal partial interface IComInterface

Copilot uses AI. Check for mistakes.
}
""";

// CS0539 is expected because the partial method's default implementation
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

The comment about expecting CS0539 is incomplete and no expected diagnostic is provided to the verifier. Either remove this comment or add an explicit expected diagnostic if the test intentionally includes a compiler error.

Suggested change
// CS0539 is expected because the partial method's default implementation

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

🤖 Copilot Code Review — PR #126719

Note

This review was generated by Copilot.

Holistic Assessment

Motivation: The problem is real and clearly motivated — when a user declares a partial method inside a [GeneratedComInterface] interface, the source generators were copying the partial modifier into generated stub code, producing invalid C#. This is a straightforward bug fix.

Approach: The fix is the right approach. Stripping partial from the method modifier list mirrors how new and accessibility modifiers are already stripped. The change is minimal and correctly scoped to only the COM interface generators (LibraryImportGenerator and DownlevelLibraryImportGenerator correctly preserve partial since they generate partial method implementations).

Summary: ⚠️ Needs Human Review. The core generator fix is correct and well-motivated. However, the test has a stale/misleading comment from a prior iteration that should be cleaned up, and there's no test coverage for the VtableIndexStubGenerator code path. A human reviewer should confirm whether these are acceptable as-is or should be addressed before merge.


Detailed Findings

✅ Correctness — Generator fix is correct

Both ComInterfaceGenerator.cs (line 366) and VtableIndexStubGenerator.cs (line 271) correctly filter out SyntaxKind.PartialKeyword from the method modifier list before creating the ContainingSyntax template. The generated stub methods are emitted on a separate implementation type (not as partial method implementations), so partial would produce invalid C#. The fix follows the same established pattern used for stripping NewKeyword in ComInterfaceGenerator.cs.

The sibling generators (LibraryImportGenerator, DownlevelLibraryImportGenerator) correctly do NOT strip partial because they generate the partial method implementation body, where partial is required.

⚠️ Stale comment — Line 399 of Compiles.cs

// CS0539 is expected because the partial method's default implementation

This comment is a leftover from the prior commit iteration where CS0539 was explicitly expected in the test assertions. In that version, the interface was internal partial interface (no virtual), the generated explicit implementation conflicted with the sealed default implementation, and the test asserted the CS0539 diagnostic. After the review suggestion added virtual (making the default implementation overridable and thus eliminating CS0539), the assertion was removed but the comment was not updated. The comment now says CS0539 "is expected" while the test passes no expected diagnostics — this is confusing and should be removed or rewritten to explain the current behavior.

⚠️ Missing test for VtableIndexStubGenerator path

The PR modifies both ComInterfaceGenerator.cs and VtableIndexStubGenerator.cs, but the new test only exercises the ComInterfaceGenerator path (via VerifyComInterfaceGenerator). The VtableIndexStubGenerator handles [VirtualMethodIndex] on methods and has its own independent CalculateStubInformation method. A parallel test using VerifyVTableGenerator (already aliased in the test file at line 16) with a [VirtualMethodIndex] partial method would confirm the fix works for both code paths.

💡 virtual modifier on interface declaration

The test uses internal virtual partial interface IComInterface, which relies on C# preview language features. This is valid given the test framework uses LanguageVersion.Preview, and the virtual keyword is needed to make the partial method's default implementation overridable (avoiding CS0539). This is fine for the test's purpose but worth noting that it tests a preview-only scenario.

Generated by Code Review for issue #126719 ·

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status
Status: No status

Development

Successfully merging this pull request may close these issues.

ComInterfaceGenerator produces invalid C# for partial interface methods.

3 participants