Skip to content

Use TrueFor All instead of All rule + fixer (#115)#124

Open
PendingChanges wants to merge 2 commits into
green-code-initiative:mainfrom
PendingChanges:main
Open

Use TrueFor All instead of All rule + fixer (#115)#124
PendingChanges wants to merge 2 commits into
green-code-initiative:mainfrom
PendingChanges:main

Conversation

@PendingChanges
Copy link
Copy Markdown
Contributor

GCI2334: Use List<T>.TrueForAll instead of Enumerable.All

Summary

Adds a new performance analyzer GCI2334 that detects calls to the LINQ Enumerable.All extension method on a List<T> receiver and suggests replacing them with List<T>.TrueForAll, which is a direct instance method that avoids LINQ overhead (no enumerator allocation, no delegate indirection through the LINQ pipeline).

Changes

  • Rule.cs — registered GCI2334_TrueForAllInsteadOfAll = "GCI2334" in the Ids class.
  • GCI2334.TrueForAllInsteadOfAll.cs — new DiagnosticAnalyzer. Uses RegisterCompilationStartAction to resolve System.Linq.Enumerable and System.Collections.Generic.List<T> once per compilation, then RegisterSyntaxNodeAction on InvocationExpression to flag calls where the method name is All, the method is an extension method from Enumerable, and the static type of the receiver is List<T>. Reports on the method name identifier.
  • GCI2334.TrueForAllInsteadOfAll.Fixer.cs — new CodeFixProvider. Walks up from the reported IdentifierNameSyntax to the enclosing InvocationExpressionSyntax and replaces the method name All with TrueForAll, preserving trivia. Supports batch fix via WellKnownFixAllProviders.BatchFixer.
  • GCI2334.TrueForAllInsteadOfAll.Tests.cs — 10 tests:
    • 5 negative cases: .All() on an array, on IEnumerable<T>, on IList<T>, already using .TrueForAll(), and a custom type with its own All method (not from Enumerable).
    • 5 positive cases: lambda predicate, method group, List<T> parameter, multiple lists in the same method; each verifies both the diagnostic location and the fixed output.

Example

// Before
bool allPositive = list.All(x => x > 0);

// After (applied fix)
bool allPositive = list.TrueForAll(x => x > 0);

Why only List<T>?

TrueForAll is defined only on List<T>. Receivers typed as IEnumerable<T>, IList<T>, arrays, or any other collection are not flagged — the fix would not be valid for them.

@vdebellabre vdebellabre requested a review from Copilot May 20, 2026 12:16
Copy link
Copy Markdown

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

Adds a new performance analyzer/code-fix pair (GCI2334) to detect LINQ Enumerable.All calls when the receiver is a List<T> and suggest replacing them with List<T>.TrueForAll to avoid LINQ overhead.

Changes:

  • Registered new rule ID GCI2334 in Rule.Ids.
  • Added TrueForAllInsteadOfAll analyzer to report diagnostics for List<T>.All(...) when it binds to System.Linq.Enumerable.All.
  • Added TrueForAllInsteadOfAllFixer plus a dedicated test suite validating diagnostics and the applied fix.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/Creedengo.Tests/Tests/GCI2334.TrueForAllInsteadOfAll.Tests.cs Adds positive/negative analyzer+fix tests for replacing All with TrueForAll on List<T>.
src/Creedengo.Core/Models/Rule.cs Registers the new rule ID constant for GCI2334.
src/Creedengo.Core/Analyzers/GCI2334.TrueForAllInsteadOfAll.Fixer.cs Introduces the code fix that renames .All(...) to .TrueForAll(...).
src/Creedengo.Core/Analyzers/GCI2334.TrueForAllInsteadOfAll.cs Implements the analyzer identifying Enumerable.All invoked on a List<T> receiver.

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

Comment on lines +56 to +60
if (receiverType is null || !SymbolEqualityComparer.Default.Equals(receiverType.OriginalDefinition, listType))
return;

context.ReportDiagnostic(Diagnostic.Create(Descriptor, memberAccess.Name.GetLocation()));
}
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