Skip to content

Fix ERP042 false positive on properties#327

Merged
SergeyTeplyakov merged 3 commits into
masterfrom
sergeyteplyakov/fix-erp042-properties
Jun 10, 2026
Merged

Fix ERP042 false positive on properties#327
SergeyTeplyakov merged 3 commits into
masterfrom
sergeyteplyakov/fix-erp042-properties

Conversation

@SergeyTeplyakov

Copy link
Copy Markdown
Owner

Problem

ERP042 (EventSource implementation correctness) emitted a warning that a private method "does not call WriteEvent" for properties declared in an EventSource-derived class.

Root cause

In EventSourceAnalyzer.TryGetEventMethod, implicit event-method detection treated any non-static, non-virtual, void-returning method as an ETW event method. A property setter matches all of those criteria (it returns void), so properties were incorrectly flagged.

Fix

Restrict implicit event-method detection to MethodKind.Ordinary, excluding property/event accessors, operators, etc. Applied to both the event-method check and the ordinal index computation used to infer event IDs.

Testing

  • Added No_Warn_On_Properties unit test covering auto-properties, expression-bodied properties, and full get/set properties alongside a valid event method.
  • Extended the DemoEventSource sample with properties to manually reproduce the original false positive.
  • All 18 EventSource analyzer tests pass.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

EventSource implicit event-method detection treated property setters as
event methods because they are non-static, non-virtual and void-returning.
Restrict detection to ordinary methods so properties no longer trigger
ERP042.

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

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

Fixes a false positive in ERP042 (EventSource implementation correctness) where property setters in EventSource-derived types were mistakenly treated as implicit ETW event methods.

Changes:

  • Restricts implicit event-method detection to MethodKind.Ordinary to ignore accessors/operators.
  • Applies the same filtering when computing ordinal-based implicit event IDs.
  • Adds a unit test ensuring properties do not trigger ERP042, and updates the sample DemoEventSource accordingly.

Reviewed changes

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

File Description
src/ErrorProne.NET.CoreAnalyzers/EventSourceAnalysis/EventSourceAnalyzer.cs Narrows implicit event-method detection and ordinal inference to ordinary methods.
src/ErrorProne.NET.CoreAnalyzers.Tests/CoreAnalyzers/EventSourceAnalyzerTests.cs Adds a regression test ensuring properties don’t trigger ERP042.
samples/ErrorProne.Samples/CoreAnalyzers/DemoEventSource.cs Adds properties to reproduce/validate the original false positive scenario manually.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +289 to +291
// Only ordinary methods can be event methods. Property/event accessors, operators, etc. must be ignored even
// though some of them (like property setters) are non-static, non-virtual and void-returning.
if (method.MethodKind == MethodKind.Ordinary && !method.IsStatic && !method.IsVirtual && method.ReturnsVoid && !method.IsConstructor() && method.MethodKind != MethodKind.Destructor)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Good catch - removed the redundant !IsConstructor() and MethodKind != Destructor checks; MethodKind.Ordinary already covers those.

Comment on lines 294 to 296
// "Implicitly: by the ordinal number of the method in the class (thus the first method in the class is 1, second 2 …)"
var methods = method.ContainingType.GetMembers().OfType<IMethodSymbol>().Where(m => !m.IsStatic && !m.IsVirtual && m.ReturnsVoid).ToList();
var methods = method.ContainingType.GetMembers().OfType<IMethodSymbol>().Where(m => m.MethodKind == MethodKind.Ordinary && !m.IsStatic && !m.IsVirtual && m.ReturnsVoid).ToList();

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed. Extracted IsImplicitEventMethodCandidate and the ordinal list now uses the same eligibility rules, so [NonEvent] methods no longer shift the inferred id. Added a regression test.

SergeyTeplyakov and others added 2 commits June 10, 2026 08:09
…al shift

- Extract IsImplicitEventMethodCandidate; MethodKind.Ordinary already
  excludes constructors/destructors so drop the redundant checks.
- Exclude [NonEvent] methods from the ordinal list so they no longer shift
  the inferred implicit event ID.
- Add regression test for the NonEvent ordinal shift.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a dedicated No_Warn_On_Non_Void_Method unit test and a non-void method
in the DemoEventSource sample to document that only void-returning methods
are implicit event methods.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@SergeyTeplyakov SergeyTeplyakov merged commit 75ed080 into master Jun 10, 2026
1 check passed
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.

2 participants