Move diagnostics from ComInterfaceGenerator and VtableIndexStubGenerator into separate analyzers#124669
Move diagnostics from ComInterfaceGenerator and VtableIndexStubGenerator into separate analyzers#124669
Conversation
…tor into separate analyzers Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
jkoritzinsky
left a comment
There was a problem hiding this comment.
@copilot please address this feedback.
...eropServices/gen/ComInterfaceGenerator/Analyzers/ComInterfaceGeneratorDiagnosticsAnalyzer.cs
Outdated
Show resolved
Hide resolved
…e RegisterSymbolAction Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
|
Tagging subscribers to this area: @dotnet/interop-contrib |
There was a problem hiding this comment.
Pull request overview
This PR follows the pattern established in #123780 to move diagnostic generation from source generators (ComInterfaceGenerator and VtableIndexStubGenerator) into dedicated DiagnosticAnalyzer classes. This architectural change gives the IDE better control over when and how diagnostics appear, improving the user experience.
Changes:
- Created two new diagnostic analyzers (
VtableIndexStubDiagnosticsAnalyzerandComInterfaceGeneratorDiagnosticsAnalyzer) that independently run the same diagnostic logic previously embedded in the generators - Removed all diagnostic reporting code from the generators and promoted
CalculateStubInformationmethods tointernal staticfor reuse by analyzers - Updated test infrastructure to wire in the new analyzers instead of
EmptyDiagnosticAnalyzer
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
VtableIndexStubDiagnosticsAnalyzer.cs |
New analyzer that validates [VirtualMethodIndex] methods using per-method symbol actions; calls generator's stub calculation to collect diagnostics |
ComInterfaceGeneratorDiagnosticsAnalyzer.cs |
New analyzer that validates [GeneratedComInterface] interfaces with per-interface symbol actions; uses cached interface info and builds ancestor chains to enable cross-interface diagnostics |
VtableIndexStubGenerator.cs |
Removed diagnostic generation code, invalid method filtering, and RegisterDiagnostics calls; promoted CalculateStubInformation to internal static |
ComInterfaceGenerator.cs |
Removed RegisterDiagnostics calls; promoted CalculateStubInformation to internal static |
TargetSignatureTests.cs |
Updated verifier alias from EmptyDiagnosticAnalyzer to ComInterfaceGeneratorDiagnosticsAnalyzer |
CompileFails.cs |
Updated verifier alias from EmptyDiagnosticAnalyzer to ComInterfaceGeneratorDiagnosticsAnalyzer |
ByValueContentsMarshalling.cs |
Updated verifier alias from EmptyDiagnosticAnalyzer to ComInterfaceGeneratorDiagnosticsAnalyzer |
AddMarshalAsToElementTests.cs |
Updated verifier alias from EmptyDiagnosticAnalyzer to ComInterfaceGeneratorDiagnosticsAnalyzer |
The changes look clean and consistent with the established pattern from LibraryImportGenerator. The code is well-structured, thread-safe (using ConcurrentDictionary for caching), and maintains the same diagnostic behavior as before.
Description
Follows the pattern established in #123780 for
LibraryImportGenerator: moves all diagnostic reporting out ofComInterfaceGeneratorandVtableIndexStubGeneratorand into dedicatedDiagnosticAnalyzerclasses, giving the IDE better control over when and how diagnostics appear.Changes
VtableIndexStubDiagnosticsAnalyzer— runs per-method viaRegisterSymbolActionon all[VirtualMethodIndex]-attributed methods; re-uses the validation logic (formerlyGetDiagnosticIfInvalidMethodForGeneration) and calls the stub generators to collect diagnosticsComInterfaceGeneratorDiagnosticsAnalyzer— analyzes each[GeneratedComInterface]interface independently inRegisterSymbolAction; uses aConcurrentDictionary<INamedTypeSymbol, DiagnosticOr<(ComInterfaceInfo, INamedTypeSymbol)>>(created inRegisterCompilationStartAction) for deduplication; builds an ancestor chain per-interface viaBuildContextChainto enable cross-interface diagnostics likeBaseInterfaceIsNotGeneratedwithout a compilation-end action; vtable indices are not required to be correct since no code is emittedVtableIndexStubGenerator— removedGetDiagnosticIfInvalidMethodForGeneration, allRegisterDiagnosticscalls, andRegisterSourceOutputfor invalid methods;CalculateStubInformationpromoted tointernal staticComInterfaceGenerator— removed bothRegisterDiagnosticscalls;CalculateStubInformationpromoted tointernal staticCompileFails.cs,ByValueContentsMarshalling.cs,TargetSignatureTests.cs,AddMarshalAsToElementTests.cs) — updated verifier aliases to useComInterfaceGeneratorDiagnosticsAnalyzerinstead ofEmptyDiagnosticAnalyzerso existing diagnostic tests continue to passTesting
Existing unit tests in
ComInterfaceGenerator.Unit.Testscover the diagnostic scenarios. The test aliases were updated to wire in the new analyzers, so all existingCompileFails,ByValueContentsMarshalling,TargetSignatureTests, andAddMarshalAsToElementTeststests validate the analyzer behavior directly. All 839 tests pass.💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.