Skip to content

MA0060: generalize do-not-ignore return value detection - #1259

Merged
meziantou merged 20 commits into
mainfrom
meziantou-ma0060-do-not-ignore-attribute
Aug 7, 2026
Merged

MA0060: generalize do-not-ignore return value detection#1259
meziantou merged 20 commits into
mainfrom
meziantou-ma0060-do-not-ignore-attribute

Conversation

@meziantou

Copy link
Copy Markdown
Owner

This updates MA0060 from a Stream-specific rule into a broader do-not-ignore return value analyzer so it can catch more real bugs across framework APIs and user code.

It adds three ways to identify values that must be observed: built-in CLR method handling, [Pure] support, and a new Meziantou.Analyzer.Annotations.DoNotIgnoreAttribute that can be applied to return values, out parameters, or at the assembly level with XML documentation IDs for methods that cannot be modified directly.

It also expands the built-in coverage to include selected Stream, TextReader, BinaryReader, string, System.Collections.Immutable, and Windows.Win32.Foundation.HRESULT patterns, plus configurable TryParse* detection. The TryParse heuristic now uses a ConfigurationDefinition<bool> option (MA0060.enable_tryparse_pattern) so projects can turn that pattern off when it is too noisy.

The implementation was also refactored to use the usual nested AnalyzerContext pattern, split out _ handling into a dedicated argument analysis path, and switched assembly-level XML doc ID matching to symbol-based resolution so generic methods are matched correctly.

Tests were expanded substantially to cover built-in categories, arrow-expression methods, HRESULT, assembly-level annotations (including nested/generic/generic-method IDs), and TryParse configuration behavior. Documentation was updated to reflect the new rule scope, attribute usage, assembly-level support, and configuration.

meziantou and others added 20 commits August 5, 2026 20:51
…nd expanded CLR list

- Rename ValueReturnedByStreamReadShouldBeUsedAnalyzer → DoNotIgnoreReturnValueAnalyzer
- Update RuleIdentifiers const: TheReturnValueOfStreamReadShouldBeUsed → DoNotIgnoreReturnValue
- Expand built-in CLR list: Stream (Read/ReadAsync/ReadByte/ReadAtLeast/ReadAtLeastAsync),
  TextReader (Read/ReadAsync/ReadLine/ReadLineAsync), BinaryReader (all Read* methods)
- Add DoNotIgnoreAttribute in Meziantou.Analyzer.Annotations (targets ReturnValue|Parameter)
- Detect [return: DoNotIgnore] on called methods and report when return value is ignored
- Detect [DoNotIgnore] on out parameters and report when call site uses out _ discard
- Bump Meziantou.Analyzer.Annotations version 1.5.0 → 1.6.0
- Update docs/Rules/MA0060.md with new title and examples
- Update Annotations README with new attribute entry

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…eep only Read

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…er on OperationKind.Argument

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ethods and use them

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…tBrains.Annotations)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…Immutable built-in list

String methods: ToUpper/ToLower/Trim/TrimEnd/TrimStart/ToUpperInvariant/ToLowerInvariant/
Clone/Format/Concat/Copy/Insert/Join/Normalize/Remove/Replace/Split/PadLeft/PadRight/Substring

TryParse pattern: any method starting with TryParse returning bool with >=2 params and an out/ref param

Immutable collections (from dotnet/runtime#35118 – [Pure] removal):
- IImmutableDictionary: Clear/Add/AddRange/SetItem/SetItems/Remove/RemoveRange/Contains/TryGetKey
- IImmutableList: Clear/Add/AddRange/Insert/InsertRange/Remove/RemoveAll/RemoveRange/RemoveAt/SetItem/Replace/IndexOf/LastIndexOf
- IImmutableQueue: Clear/Enqueue/Dequeue/Peek
- IImmutableSet: Clear/Add/Remove/Contains/TryGetValue/Intersect/Except/SymmetricExcept/Union/SetEquals/IsProperSubsetOf/IsProperSupersetOf/IsSubsetOf/IsSupersetOf/Overlaps
- IImmutableStack: Clear/Push/Pop/Peek
- ImmutableArray (static): Create/CreateRange/CreateBuilder/ToImmutableArray/BinarySearch
- ImmutableArray<T>.Builder: IndexOf/LastIndexOf

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Any method returning HRESULT (generated by CsWin32) must have its return
value observed, since HRESULT encodes success/failure of Win32 API calls.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Added coverage for:
- Stream.ReadAtLeast
- TextReader.Read
- BinaryReader.Read
- string.ToUpper, string.Join
- ImmutableDictionary.Add
- ImmutableQueue.Enqueue
- ImmutableHashSet.Add
- ImmutableArray<T>.Builder.IndexOf

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- void arrow method using string.Format should report (return value ignored)
- string arrow method using string.Format should not report (value is returned)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Extend DoNotIgnoreAttribute to target assembly and allow multiple entries
- Add ctor with xml documentation id and XmlDocumentationId property
- Detect assembly-level DoNotIgnore attributes in analyzer and match against
  method documentation IDs
- Add tests for simple, nested, generic type, generic method, and multiple
  assembly-level entries

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Resolve assembly-level XML documentation ids to symbols once
- Store as ImmutableHashSet<ISymbol> with SymbolEqualityComparer.Default
- Compare invocation target symbols directly
- Compare using targetMethod.OriginalDefinition to support generic methods

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Replace inline DoNotIgnoreAttributeSource with the shared AddMeziantouAttributes
helper in ProjectBuilder and remove source concatenations.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This was referenced Aug 10, 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.

1 participant