chore(sonar)!: mark instance-data-free members static (CA1822)

Applied via `dotnet format analyzers --diagnostics CA1822 --severity info`.
12 files touched. The fixer also updated internal callers in tests to use
the type-name form (e.g. `gen.Method(x)` -> `Generator.Method(x)`); build
and full test suite remain green.

BREAKING CHANGE: two public methods become static and therefore can no
longer be invoked through an instance reference by external consumers:
- Strata.SqlTools.Markdown.LinqToSql.QueryBreakdownGenerator.GenerateMethodChainDiagram
- Strata.SqlTools.Markdown.LinqToSql.SqlStatementGenerator.GenerateLinqPipelineDiagram

Both are stateless utility methods on Generator classes — the static form
is the correct shape; the only callers in this repo already used the
type-name form. External code should change `gen.GenerateMethodChainDiagram(...)`
to `QueryBreakdownGenerator.GenerateMethodChainDiagram(...)`.

All other CA1822 hits in this commit are on private/protected members
(no public-surface impact).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Thom Lamb
2026-05-26 15:41:46 -05:00
co-authored by Claude Opus 4.7
parent 8b7fc1a327
commit 84b06557e5
12 changed files with 62 additions and 62 deletions
@@ -222,7 +222,7 @@ public class QueryValidator
}
}
private void ValidateWhereClause(LinqQueryBreakdown breakdown)
private static void ValidateWhereClause(LinqQueryBreakdown breakdown)
{
// No validation needed - WHERE is optional
}
@@ -242,12 +242,12 @@ public class QueryValidator
}
}
private void ValidateHavingClause(LinqQueryBreakdown breakdown)
private static void ValidateHavingClause(LinqQueryBreakdown breakdown)
{
// Validation delegated to ValidateGroupByClause
}
private void ValidateOrderByClause(LinqQueryBreakdown breakdown)
private static void ValidateOrderByClause(LinqQueryBreakdown breakdown)
{
// No validation needed - ORDER BY is optional
}
@@ -323,7 +323,7 @@ public class LinqExpressionVisitor : ExpressionVisitor
return expression.ToString();
}
private string GetFullMemberName(MemberExpression expression)
private static string GetFullMemberName(MemberExpression expression)
{
var parts = new Stack<string>();
var current = expression;
@@ -354,7 +354,7 @@ public class LinqExpressionVisitor : ExpressionVisitor
return string.Join(".", parts);
}
private string GetOperator(ExpressionType nodeType)
private static string GetOperator(ExpressionType nodeType)
{
return nodeType switch
{
@@ -260,7 +260,7 @@ public class ExpressionGenerator : IVisitor<string>
return sb.ToString();
}
private int GenerateMermaidNodes(Expression expression, StringBuilder sb, Dictionary<object, int> nodeMap, ref int nodeCounter)
private static int GenerateMermaidNodes(Expression expression, StringBuilder sb, Dictionary<object, int> nodeMap, ref int nodeCounter)
{
var currentNode = nodeCounter++;
nodeMap[expression] = currentNode;
@@ -106,7 +106,7 @@ public class SimpleExpressionGenerator
return sb.ToString();
}
private string GetExpressionDescription(Expression expression)
private static string GetExpressionDescription(Expression expression)
{
var typeName = expression.GetType().Name;
@@ -37,7 +37,7 @@ public class QueryBreakdownGenerator
/// <param name="queryBreakdown">The LINQ QueryBreakdown to visualize.</param>
/// <param name="title">Optional title for the diagram.</param>
/// <returns>A string containing the Mermaid flowchart showing method calls.</returns>
public string GenerateMethodChainDiagram(LinqQueryBreakdown queryBreakdown, string? title = null)
public static string GenerateMethodChainDiagram(LinqQueryBreakdown queryBreakdown, string? title = null)
{
var sb = new System.Text.StringBuilder();
@@ -58,7 +58,7 @@ public class SqlStatementGenerator
/// <param name="queryBreakdown">The query breakdown containing query information.</param>
/// <param name="title">Optional title for the diagram.</param>
/// <returns>A string containing the Mermaid diagram markdown.</returns>
public string GenerateLinqPipelineDiagram(IQueryBreakdown queryBreakdown, string? title = null)
public static string GenerateLinqPipelineDiagram(IQueryBreakdown queryBreakdown, string? title = null)
{
var sb = new System.Text.StringBuilder();
@@ -177,7 +177,7 @@ public class QueryBreakdownGenerator
/// <summary>
/// Escapes text for Mermaid diagram labels to prevent syntax errors.
/// </summary>
private string EscapeMermaidText(string text)
private static string EscapeMermaidText(string text)
{
return text
.Replace("\"", "&quot;")
@@ -194,7 +194,7 @@ public class QueryBreakdownGenerator
/// <summary>
/// Truncates text to a maximum length and adds ellipsis if needed.
/// </summary>
private string TruncateText(string text, int maxLength)
private static string TruncateText(string text, int maxLength)
{
if (string.IsNullOrWhiteSpace(text) || text.Length <= maxLength)
{
@@ -104,7 +104,7 @@ public class SqlStatementGenerator
/// <summary>
/// Escapes text for Mermaid diagram labels.
/// </summary>
private string EscapeMermaidText(string text)
private static string EscapeMermaidText(string text)
{
return text
.Replace("\"", "&quot;")
@@ -115,7 +115,7 @@ public class SqlStatementGenerator
/// <summary>
/// Truncates text to a maximum length.
/// </summary>
private string TruncateText(string text, int maxLength)
private static string TruncateText(string text, int maxLength)
{
if (string.IsNullOrWhiteSpace(text) || text.Length <= maxLength)
{
@@ -128,7 +128,7 @@ public class SqlStatementGenerator
/// <summary>
/// Cleans table name for use in Mermaid diagrams.
/// </summary>
private string CleanTableName(string tableName)
private static string CleanTableName(string tableName)
{
return tableName
.Replace("[", "")
@@ -18,7 +18,7 @@ public class LinqQueryBreakdownTests
public void Analyze_SimpleSelectQuery_ExtractsCorrectClauses()
{
// Arrange
var query = from user in _context.Users
var query = from user in TestDataContext.Users
select user;
// Act
@@ -34,7 +34,7 @@ public class LinqQueryBreakdownTests
public void Analyze_WhereClause_ExtractsCondition()
{
// Arrange
var query = from user in _context.Users
var query = from user in TestDataContext.Users
where user.Age > 21
select user;
@@ -51,7 +51,7 @@ public class LinqQueryBreakdownTests
public void Analyze_SelectWithProjection_ExtractsSelectedFields()
{
// Arrange
var query = from user in _context.Users
var query = from user in TestDataContext.Users
select new { user.Id, user.Name };
// Act
@@ -67,7 +67,7 @@ public class LinqQueryBreakdownTests
public void Analyze_OrderByClause_ExtractsOrdering()
{
// Arrange
var query = from user in _context.Users
var query = from user in TestDataContext.Users
orderby user.Name
select user;
@@ -83,7 +83,7 @@ public class LinqQueryBreakdownTests
public void Analyze_MethodSyntax_ExtractsCorrectClauses()
{
// Arrange
var query = _context.Users
var query = TestDataContext.Users
.Where(u => u.Age > 18)
.OrderBy(u => u.Name)
.Select(u => new { u.Id, u.Name });
@@ -101,7 +101,7 @@ public class LinqQueryBreakdownTests
public void Analyze_MethodSyntax_TracksMethodChain()
{
// Arrange
var query = _context.Users
var query = TestDataContext.Users
.Where(u => u.Age > 18)
.OrderBy(u => u.Name)
.Select(u => u.Name);
@@ -120,7 +120,7 @@ public class LinqQueryBreakdownTests
public void GetQuerySummary_ReturnsFormattedString()
{
// Arrange
var query = _context.Users.Where(u => u.Age > 21);
var query = TestDataContext.Users.Where(u => u.Age > 21);
var breakdown = LinqQueryBreakdown.Analyze(query);
// Act
@@ -137,7 +137,7 @@ public class LinqQueryBreakdownTests
public void GetMethodChain_ReturnsMethodSequence()
{
// Arrange
var query = _context.Users.Where(u => u.Age > 18).OrderBy(u => u.Name);
var query = TestDataContext.Users.Where(u => u.Age > 18).OrderBy(u => u.Name);
var breakdown = LinqQueryBreakdown.Analyze(query);
// Act
@@ -153,7 +153,7 @@ public class LinqQueryBreakdownTests
public void TryAnalyze_ValidQuery_ReturnsTrue()
{
// Arrange
var query = _context.Users.Where(u => u.Age > 21);
var query = TestDataContext.Users.Where(u => u.Age > 21);
// Act
var success = LinqQueryBreakdown.TryAnalyze(query, out var breakdown, out var error);
@@ -182,7 +182,7 @@ public class LinqQueryBreakdownTests
public void Analyze_ComplexQuery_HandlesCombinedClauses()
{
// Arrange
var query = from user in _context.Users
var query = from user in TestDataContext.Users
where user.Age > 21 && user.IsActive
orderby user.Name descending
select new { user.Id, user.Name, user.Email };
@@ -205,7 +205,7 @@ public class LinqQueryBreakdownTests
public void AnalyzeAndModify_AddWhereClause_GeneratesUpdatedSql()
{
// Arrange - Analyze an existing LINQ query
var originalQuery = _context.Users.Where(u => u.Age > 21);
var originalQuery = TestDataContext.Users.Where(u => u.Age > 21);
var breakdown = LinqQueryBreakdown.Analyze(originalQuery);
// Act - Add additional filter using breakdown
@@ -222,7 +222,7 @@ public class LinqQueryBreakdownTests
public void AnalyzeAndModify_ChangeSelectClause_GeneratesNewProjection()
{
// Arrange - Analyze query with projection
var originalQuery = _context.Users.Select(u => new { u.Id, u.Name });
var originalQuery = TestDataContext.Users.Select(u => new { u.Id, u.Name });
var breakdown = LinqQueryBreakdown.Analyze(originalQuery);
// Act - Modify the SELECT clause
@@ -243,7 +243,7 @@ public class LinqQueryBreakdownTests
public void AnalyzeAndModify_CloneAndExtend_CreatesIndependentQuery()
{
// Arrange - Analyze base query
var baseQuery = _context.Users.Where(u => u.Age > 18);
var baseQuery = TestDataContext.Users.Where(u => u.Age > 18);
var baseBreakdown = LinqQueryBreakdown.Analyze(baseQuery);
// Act - Clone and extend
@@ -267,10 +267,10 @@ public class LinqQueryBreakdownTests
public void AnalyzeAndCompose_MultipleQueries_CreatesUnionScenario()
{
// Arrange - Analyze two different queries
var activeUsersQuery = _context.Users.Where(u => u.IsActive);
var activeUsersQuery = TestDataContext.Users.Where(u => u.IsActive);
var activeBreakdown = LinqQueryBreakdown.Analyze(activeUsersQuery);
var recentUsersQuery = _context.Users.Where(u => u.Age < 25);
var recentUsersQuery = TestDataContext.Users.Where(u => u.Age < 25);
var recentBreakdown = LinqQueryBreakdown.Analyze(recentUsersQuery);
// Act - Get SQL for both (could be used in UNION scenario)
@@ -287,7 +287,7 @@ public class LinqQueryBreakdownTests
public void AnalyzeAndBuildFilter_IncrementallyAddConditions_BuildsComplexFilter()
{
// Arrange - Start with simple query
var query = _context.Users;
var query = TestDataContext.Users;
var breakdown = LinqQueryBreakdown.Analyze(query);
// Act - Incrementally add filter conditions (simulating filter builder UI)
@@ -311,7 +311,7 @@ public class LinqQueryBreakdownTests
public void AnalyzeAndPaginate_AddOrderAndLimits_CreatesPaginatedQuery()
{
// Arrange - Analyze base query
var query = _context.Users.Where(u => u.IsActive);
var query = TestDataContext.Users.Where(u => u.IsActive);
var breakdown = LinqQueryBreakdown.Analyze(query);
// Act - Add pagination (ORDER BY required for consistent pagination)
@@ -335,7 +335,7 @@ public class LinqQueryBreakdownTests
public void AnalyzeAndGenerateReport_ExtractQueryMetrics_ProvidesAnalytics()
{
// Arrange - Complex query to analyze
var query = _context.Users
var query = TestDataContext.Users
.Where(u => u.Age > 21)
.Where(u => u.IsActive)
.OrderBy(u => u.Name)
@@ -364,7 +364,7 @@ public class LinqQueryBreakdownTests
public void AnalyzeAndOptimize_RemoveSelectStar_ImprovedProjection()
{
// Arrange - Analyze query with SELECT *
var query = _context.Users.Where(u => u.IsActive);
var query = TestDataContext.Users.Where(u => u.IsActive);
var breakdown = LinqQueryBreakdown.Analyze(query);
// Verify it initially has SELECT *
@@ -390,10 +390,10 @@ public class LinqQueryBreakdownTests
public void AnalyzeMultipleQueries_CompareAndMerge_CreatesCompositeQuery()
{
// Arrange - Analyze two related queries
var usersQuery = _context.Users.Where(u => u.Age > 21);
var usersQuery = TestDataContext.Users.Where(u => u.Age > 21);
var usersBreakdown = LinqQueryBreakdown.Analyze(usersQuery);
var activeQuery = _context.Users.Where(u => u.IsActive);
var activeQuery = TestDataContext.Users.Where(u => u.IsActive);
var activeBreakdown = LinqQueryBreakdown.Analyze(activeQuery);
// Act - Merge conditions from both queries
@@ -416,7 +416,7 @@ public class LinqQueryBreakdownTests
public void AnalyzeAndDocument_GenerateQueryDocumentation_CreatesReadableOutput()
{
// Arrange - Analyze a business query
var query = _context.Orders
var query = TestDataContext.Orders
.Where(o => o.Amount > 1000)
.Where(o => o.OrderDate > DateTime.Now.AddDays(-30))
.OrderBy(o => o.OrderDate);
@@ -451,8 +451,8 @@ public class LinqQueryBreakdownTests
// Test data context and entities
public class TestDataContext
{
public IQueryable<User> Users => new List<User>().AsQueryable();
public IQueryable<Order> Orders => new List<Order>().AsQueryable();
public static IQueryable<User> Users => new List<User>().AsQueryable();
public static IQueryable<Order> Orders => new List<Order>().AsQueryable();
}
public class User
@@ -488,7 +488,7 @@ public class GetQueryTests
public void GetQuery_LinqBreakdown_ReturnsNullByDefault()
{
// Arrange
var query = _context.Users.Where(u => u.Age > 18);
var query = TestDataContext.Users.Where(u => u.Age > 18);
var breakdown = LinqQueryBreakdown.Analyze(query);
// Act - GetQuery returns null because LinqQueryBreakdown needs the original provider
@@ -515,7 +515,7 @@ public class GetQueryTests
public void GetQuery_MultipleBreakdownTypes_AllReturnNull()
{
// Arrange
var linqBreakdown = LinqQueryBreakdown.Analyze(_context.Users);
var linqBreakdown = LinqQueryBreakdown.Analyze(TestDataContext.Users);
var sqlBreakdown = new QueryBreakdown("*", "Users");
// Act
@@ -710,7 +710,7 @@ public class GetQueryTests
public void AnalyzeTrace_WithValidQuery_ReturnsTraceString()
{
// Arrange
var query = _context.Users.Where(u => u.Age > 18);
var query = TestDataContext.Users.Where(u => u.Age > 18);
// Act
var trace = LinqQueryBreakdown.AnalyzeTrace(query);
@@ -726,7 +726,7 @@ public class GetQueryTests
public void AnalyzeTrace_WithExecutionContext_IncludesContextInTrace()
{
// Arrange
var query = _context.Users;
var query = TestDataContext.Users;
const string context = "Initial Load";
// Act
@@ -754,7 +754,7 @@ public class GetQueryTests
public void ConvertToSqlServerBreakdown_CopiesAllClauses()
{
// Arrange
var query = _context.Users.Where(u => u.Age > 21).OrderBy(u => u.Name);
var query = TestDataContext.Users.Where(u => u.Age > 21).OrderBy(u => u.Name);
var breakdown = LinqQueryBreakdown.Analyze(query);
// Act
@@ -772,7 +772,7 @@ public class GetQueryTests
public void ConvertToPostgreSqlBreakdown_CopiesAllClauses()
{
// Arrange
var query = _context.Users
var query = TestDataContext.Users
.Where(u => u.IsActive)
.OrderBy(u => u.Name)
.Select(u => new { u.Id, u.Name });
@@ -793,7 +793,7 @@ public class GetQueryTests
public void ConvertToSnowflakeBreakdown_CopiesAllClauses()
{
// Arrange
var query = _context.Users.Where(u => u.Age > 21).OrderBy(u => u.Name);
var query = TestDataContext.Users.Where(u => u.Age > 21).OrderBy(u => u.Name);
var breakdown = LinqQueryBreakdown.Analyze(query);
// Act
@@ -827,7 +827,7 @@ public class GetQueryTests
public void ConvertToPostgreSqlBreakdown_WithComplexQuery_CopieAllClauses()
{
// Arrange
var query = _context.Users
var query = TestDataContext.Users
.Where(u => u.IsActive && u.Age >= 18)
.OrderByDescending(u => u.Age);
@@ -848,7 +848,7 @@ public class GetQueryTests
public void ConvertToSnowflakeBreakdown_PreservesAllClauseInformation()
{
// Arrange
var breakdown = LinqQueryBreakdown.Analyze(_context.Users.OrderBy(u => u.Name));
var breakdown = LinqQueryBreakdown.Analyze(TestDataContext.Users.OrderBy(u => u.Name));
// Act
var snowflakeBreakdown = breakdown.ConvertToSnowflakeBreakdown();
@@ -862,7 +862,7 @@ public class GetQueryTests
public void ConvertToSqlServerBreakdown_InstancesAreIndependent()
{
// Arrange
var breakdown = LinqQueryBreakdown.Analyze(_context.Users.Where(u => u.Age > 21));
var breakdown = LinqQueryBreakdown.Analyze(TestDataContext.Users.Where(u => u.Age > 21));
var sqlServerBreakdown = breakdown.ConvertToSqlServerBreakdown();
// Act - Modify the SQL Server breakdown
@@ -876,7 +876,7 @@ public class GetQueryTests
public void ConvertChainMultipleTimes_EachConversionIndependent()
{
// Arrange
var breakdown = LinqQueryBreakdown.Analyze(_context.Users.OrderBy(u => u.Name));
var breakdown = LinqQueryBreakdown.Analyze(TestDataContext.Users.OrderBy(u => u.Name));
// Act
var sqlServer1 = breakdown.ConvertToSqlServerBreakdown();
@@ -20,7 +20,7 @@ public class QueryBreakdownGeneratorTests
public void GenerateMermaidDiagram_SimpleLinqQuery_GeneratesValidMermaid()
{
// Arrange
var query = _context.Users.Where(u => u.Age > 21);
var query = TestDataContext.Users.Where(u => u.Age > 21);
var breakdown = LinqQueryBreakdown.Analyze(query);
// Act
@@ -39,14 +39,14 @@ public class QueryBreakdownGeneratorTests
public void GenerateMethodChainDiagram_WithMethodCalls_ShowsChain()
{
// Arrange
var query = _context.Users
var query = TestDataContext.Users
.Where(u => u.Age > 18)
.OrderBy(u => u.Name)
.Select(u => new { u.Id, u.Name });
var breakdown = LinqQueryBreakdown.Analyze(query);
// Act
var result = _generator.GenerateMethodChainDiagram(breakdown, "Method Chain");
var result = QueryBreakdownGenerator.GenerateMethodChainDiagram(breakdown, "Method Chain");
// Assert
Assert.That(result, Does.Contain("```mermaid"));
@@ -66,7 +66,7 @@ public class QueryBreakdownGeneratorTests
var breakdown = new LinqQueryBreakdown("*", "Users");
// Act
var result = _generator.GenerateMethodChainDiagram(breakdown);
var result = QueryBreakdownGenerator.GenerateMethodChainDiagram(breakdown);
// Assert
Assert.That(result, Does.Contain("IQueryable"));
@@ -77,7 +77,7 @@ public class QueryBreakdownGeneratorTests
public void GenerateCombinedDiagram_IncludesBothDiagrams()
{
// Arrange
var query = _context.Users.Where(u => u.Age > 21).OrderBy(u => u.Name);
var query = TestDataContext.Users.Where(u => u.Age > 21).OrderBy(u => u.Name);
var breakdown = LinqQueryBreakdown.Analyze(query);
// Act
@@ -95,7 +95,7 @@ public class QueryBreakdownGeneratorTests
public void GenerateMermaidDiagram_WithProjection_ShowsSelectedFields()
{
// Arrange
var query = _context.Users.Select(u => new { u.Id, u.Name, u.Email });
var query = TestDataContext.Users.Select(u => new { u.Id, u.Name, u.Email });
var breakdown = LinqQueryBreakdown.Analyze(query);
// Act
@@ -110,7 +110,7 @@ public class QueryBreakdownGeneratorTests
public void GenerateMermaidDiagram_NullTitle_GeneratesWithoutTitle()
{
// Arrange
var query = _context.Users;
var query = TestDataContext.Users;
var breakdown = LinqQueryBreakdown.Analyze(query);
// Act
@@ -125,7 +125,7 @@ public class QueryBreakdownGeneratorTests
// Test data context
public class TestDataContext
{
public IQueryable<User> Users => new List<User>().AsQueryable();
public static IQueryable<User> Users => new List<User>().AsQueryable();
}
public class User
@@ -21,7 +21,7 @@ public class SqlStatementGeneratorTests
var query = new LinqQueryBreakdown("*", "Users");
// Act
var result = _generator.GenerateLinqPipelineDiagram(query, "User Query Pipeline");
var result = SqlStatementGenerator.GenerateLinqPipelineDiagram(query, "User Query Pipeline");
// Assert
Assert.That(result, Does.Contain("```mermaid"));
@@ -42,7 +42,7 @@ public class SqlStatementGeneratorTests
query.AddWhereClause("Age > 21");
// Act
var result = _generator.GenerateLinqPipelineDiagram(query);
var result = SqlStatementGenerator.GenerateLinqPipelineDiagram(query);
// Assert
Assert.That(result, Does.Contain("Where Predicate"));
@@ -57,7 +57,7 @@ public class SqlStatementGeneratorTests
var query = new LinqQueryBreakdown("Id, Name, Email", "Users");
// Act
var result = _generator.GenerateLinqPipelineDiagram(query);
var result = SqlStatementGenerator.GenerateLinqPipelineDiagram(query);
// Assert
Assert.That(result, Does.Contain("Select Projection"));
@@ -72,7 +72,7 @@ public class SqlStatementGeneratorTests
var query = new LinqQueryBreakdown("*", "Users");
// Act
var result = _generator.GenerateLinqPipelineDiagram(query, null);
var result = SqlStatementGenerator.GenerateLinqPipelineDiagram(query, null);
// Assert
Assert.That(result, Does.Not.Contain("###"));
@@ -57,7 +57,7 @@ public abstract class ExpressionTestsBase
/// Executes an expression test case with arrange, act, and assert phases.
/// </summary>
/// <param name="testCase">The test case to execute.</param>
protected void ExecuteExpressionTest(ExpressionTestCase testCase)
protected static void ExecuteExpressionTest(ExpressionTestCase testCase)
{
// Arrange
var visitor = new CommandVisitor();