From 5202d93e8e75af7c861258c11508abc9909b409c Mon Sep 17 00:00:00 2001 From: Thom Lamb Date: Wed, 27 May 2026 14:22:27 -0500 Subject: [PATCH] chore(sonar)!: mark public Markdown generator methods static (CA1822) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three public methods on the SqlServer-namespaced Markdown generators no longer touch instance state and now carry the `static` keyword: - `Markdown.SqlServer.QueryBreakdownGenerator.GenerateMermaidDiagram(QueryBreakdown, string?)` - `Markdown.SqlServer.SqlStatementGenerator.GenerateSequenceDiagram(ISqlBreakdown, string?)` - `Markdown.SqlServer.SqlStatementGenerator.GenerateEntityRelationshipDiagram(IEnumerable, string?)` Plus one private bonus the analyzer caught on the same pass: - `LinqExpressionVisitor.ExtractSelectExpression` → static (non-breaking). Internal callers in the Snowflake/LinqToSql/PostgreSql wrapper classes and in the test fixtures are updated to the type-name form (`SqlServer.SqlStatementGenerator.GenerateSequenceDiagram(...)`). The wrappers retain their `_baseGenerator` field for now even though it is no longer used — that S4487 / unused-field cleanup is its own commit. BREAKING CHANGE: External NuGet consumers calling `generatorInstance.GenerateMermaidDiagram(...)`, `generatorInstance.GenerateSequenceDiagram(...)`, or `generatorInstance.GenerateEntityRelationshipDiagram(...)` on the SqlServer-namespaced generators must switch to type-name form, e.g. `Markdown.SqlServer.SqlStatementGenerator.GenerateSequenceDiagram(...)`. Calls through the Snowflake / LinqToSql / PostgreSql wrapper classes are unaffected at the call site. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Visitors/LinqExpressionVisitor.cs | 2 +- .../LinqToSql/QueryBreakdownGenerator.cs | 2 +- .../LinqToSql/SqlStatementGenerator.cs | 4 ++-- .../PostgreSql/QueryBreakdownGenerator.cs | 2 +- .../PostgreSql/SqlStatementGenerator.cs | 4 ++-- .../Snowflake/QueryBreakdownGenerator.cs | 2 +- .../Snowflake/SqlStatementGenerator.cs | 4 ++-- .../SqlServer/QueryBreakdownGenerator.cs | 2 +- .../SqlServer/SqlStatementGenerator.cs | 4 ++-- .../SqlServer/QueryBreakdownGeneratorTests.cs | 14 +++++++------- .../SqlServer/QueryMarkdownGenerationTests.cs | 4 ++-- .../SqlServer/SqlStatementGeneratorTests.cs | 14 +++++++------- 12 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/Strata.SqlTools.LinqToSql/Visitors/LinqExpressionVisitor.cs b/src/Strata.SqlTools.LinqToSql/Visitors/LinqExpressionVisitor.cs index ab548fb..72b8902 100644 --- a/src/Strata.SqlTools.LinqToSql/Visitors/LinqExpressionVisitor.cs +++ b/src/Strata.SqlTools.LinqToSql/Visitors/LinqExpressionVisitor.cs @@ -277,7 +277,7 @@ public class LinqExpressionVisitor : ExpressionVisitor return base.VisitMember(node); } - private string ExtractSelectExpression(Expression expression) + private static string ExtractSelectExpression(Expression expression) { if (expression is NewExpression newExpr) { diff --git a/src/Strata.SqlTools.Markdown/LinqToSql/QueryBreakdownGenerator.cs b/src/Strata.SqlTools.Markdown/LinqToSql/QueryBreakdownGenerator.cs index c55953b..3281319 100644 --- a/src/Strata.SqlTools.Markdown/LinqToSql/QueryBreakdownGenerator.cs +++ b/src/Strata.SqlTools.Markdown/LinqToSql/QueryBreakdownGenerator.cs @@ -28,7 +28,7 @@ public class QueryBreakdownGenerator { // Since LinqQueryBreakdown inherits from SqlServer.QueryBreakdown, // we can use the base generator which works with the shared properties - return _baseGenerator.GenerateMermaidDiagram(queryBreakdown, title); + return SqlServer.QueryBreakdownGenerator.GenerateMermaidDiagram(queryBreakdown, title); } /// diff --git a/src/Strata.SqlTools.Markdown/LinqToSql/SqlStatementGenerator.cs b/src/Strata.SqlTools.Markdown/LinqToSql/SqlStatementGenerator.cs index b46c933..2d76349 100644 --- a/src/Strata.SqlTools.Markdown/LinqToSql/SqlStatementGenerator.cs +++ b/src/Strata.SqlTools.Markdown/LinqToSql/SqlStatementGenerator.cs @@ -28,7 +28,7 @@ public class SqlStatementGenerator /// A string containing the Mermaid sequence diagram markdown. public string GenerateSequenceDiagram(ISqlBreakdown sqlBreakdown, string? title = null) { - return _baseGenerator.GenerateSequenceDiagram(sqlBreakdown, title); + return SqlServer.SqlStatementGenerator.GenerateSequenceDiagram(sqlBreakdown, title); } /// @@ -49,7 +49,7 @@ public class SqlStatementGenerator tableNames.Add(fromClauseText); } - return _baseGenerator.GenerateEntityRelationshipDiagram(tableNames, title); + return SqlServer.SqlStatementGenerator.GenerateEntityRelationshipDiagram(tableNames, title); } /// diff --git a/src/Strata.SqlTools.Markdown/PostgreSql/QueryBreakdownGenerator.cs b/src/Strata.SqlTools.Markdown/PostgreSql/QueryBreakdownGenerator.cs index 17aaa1b..e92bf27 100644 --- a/src/Strata.SqlTools.Markdown/PostgreSql/QueryBreakdownGenerator.cs +++ b/src/Strata.SqlTools.Markdown/PostgreSql/QueryBreakdownGenerator.cs @@ -28,6 +28,6 @@ public class QueryBreakdownGenerator { // Since PostgreSql.QueryBreakdown inherits from SqlServer.QueryBreakdown, // we can use the base generator which works with the shared properties - return _baseGenerator.GenerateMermaidDiagram(queryBreakdown, title); + return SqlServer.QueryBreakdownGenerator.GenerateMermaidDiagram(queryBreakdown, title); } } diff --git a/src/Strata.SqlTools.Markdown/PostgreSql/SqlStatementGenerator.cs b/src/Strata.SqlTools.Markdown/PostgreSql/SqlStatementGenerator.cs index b63011d..c17bd25 100644 --- a/src/Strata.SqlTools.Markdown/PostgreSql/SqlStatementGenerator.cs +++ b/src/Strata.SqlTools.Markdown/PostgreSql/SqlStatementGenerator.cs @@ -26,7 +26,7 @@ public class SqlStatementGenerator /// A string containing the Mermaid sequence diagram markdown. public string GenerateSequenceDiagram(SqlBreakdownBase sqlBreakdown, string? title = null) { - return _baseGenerator.GenerateSequenceDiagram(sqlBreakdown, title); + return SqlServer.SqlStatementGenerator.GenerateSequenceDiagram(sqlBreakdown, title); } /// @@ -37,6 +37,6 @@ public class SqlStatementGenerator /// A string containing the Mermaid ER diagram markdown. public string GenerateEntityRelationshipDiagram(IEnumerable tables, string? title = null) { - return _baseGenerator.GenerateEntityRelationshipDiagram(tables, title); + return SqlServer.SqlStatementGenerator.GenerateEntityRelationshipDiagram(tables, title); } } diff --git a/src/Strata.SqlTools.Markdown/Snowflake/QueryBreakdownGenerator.cs b/src/Strata.SqlTools.Markdown/Snowflake/QueryBreakdownGenerator.cs index 47c8e9a..b01cbe8 100644 --- a/src/Strata.SqlTools.Markdown/Snowflake/QueryBreakdownGenerator.cs +++ b/src/Strata.SqlTools.Markdown/Snowflake/QueryBreakdownGenerator.cs @@ -28,6 +28,6 @@ public class QueryBreakdownGenerator { // Since Snowflake.QueryBreakdown inherits from SqlServer.QueryBreakdown, // we can use the base generator which works with the shared properties - return _baseGenerator.GenerateMermaidDiagram(queryBreakdown, title); + return SqlServer.QueryBreakdownGenerator.GenerateMermaidDiagram(queryBreakdown, title); } } diff --git a/src/Strata.SqlTools.Markdown/Snowflake/SqlStatementGenerator.cs b/src/Strata.SqlTools.Markdown/Snowflake/SqlStatementGenerator.cs index 725ea8e..c246b35 100644 --- a/src/Strata.SqlTools.Markdown/Snowflake/SqlStatementGenerator.cs +++ b/src/Strata.SqlTools.Markdown/Snowflake/SqlStatementGenerator.cs @@ -26,7 +26,7 @@ public class SqlStatementGenerator /// A string containing the Mermaid sequence diagram markdown. public string GenerateSequenceDiagram(SqlBreakdownBase sqlBreakdown, string? title = null) { - return _baseGenerator.GenerateSequenceDiagram(sqlBreakdown, title); + return SqlServer.SqlStatementGenerator.GenerateSequenceDiagram(sqlBreakdown, title); } /// @@ -37,6 +37,6 @@ public class SqlStatementGenerator /// A string containing the Mermaid ER diagram markdown. public string GenerateEntityRelationshipDiagram(IEnumerable tables, string? title = null) { - return _baseGenerator.GenerateEntityRelationshipDiagram(tables, title); + return SqlServer.SqlStatementGenerator.GenerateEntityRelationshipDiagram(tables, title); } } diff --git a/src/Strata.SqlTools.Markdown/SqlServer/QueryBreakdownGenerator.cs b/src/Strata.SqlTools.Markdown/SqlServer/QueryBreakdownGenerator.cs index aa735a3..1a02e09 100644 --- a/src/Strata.SqlTools.Markdown/SqlServer/QueryBreakdownGenerator.cs +++ b/src/Strata.SqlTools.Markdown/SqlServer/QueryBreakdownGenerator.cs @@ -16,7 +16,7 @@ public class QueryBreakdownGenerator /// The QueryBreakdown to visualize. /// Optional title for the diagram. /// A string containing the Mermaid markdown diagram. - public string GenerateMermaidDiagram(QueryBreakdown queryBreakdown, string? title = null) + public static string GenerateMermaidDiagram(QueryBreakdown queryBreakdown, string? title = null) { var sb = new StringBuilder(); diff --git a/src/Strata.SqlTools.Markdown/SqlServer/SqlStatementGenerator.cs b/src/Strata.SqlTools.Markdown/SqlServer/SqlStatementGenerator.cs index 30cce70..0905715 100644 --- a/src/Strata.SqlTools.Markdown/SqlServer/SqlStatementGenerator.cs +++ b/src/Strata.SqlTools.Markdown/SqlServer/SqlStatementGenerator.cs @@ -14,7 +14,7 @@ public class SqlStatementGenerator /// The SQL breakdown to visualize. /// Optional title for the diagram. /// A string containing the Mermaid markdown sequence diagram. - public string GenerateSequenceDiagram(ISqlBreakdown sqlBreakdown, string? title = null) + public static string GenerateSequenceDiagram(ISqlBreakdown sqlBreakdown, string? title = null) { var sb = new StringBuilder(); @@ -74,7 +74,7 @@ public class SqlStatementGenerator /// List of table names referenced in the query. /// Optional title for the diagram. /// A string containing the Mermaid markdown ER diagram. - public string GenerateEntityRelationshipDiagram(IEnumerable tableNames, string? title = null) + public static string GenerateEntityRelationshipDiagram(IEnumerable tableNames, string? title = null) { var sb = new StringBuilder(); diff --git a/tests/Strata.SqlTools.Markdown.Tests/SqlServer/QueryBreakdownGeneratorTests.cs b/tests/Strata.SqlTools.Markdown.Tests/SqlServer/QueryBreakdownGeneratorTests.cs index 2414830..d92bcce 100644 --- a/tests/Strata.SqlTools.Markdown.Tests/SqlServer/QueryBreakdownGeneratorTests.cs +++ b/tests/Strata.SqlTools.Markdown.Tests/SqlServer/QueryBreakdownGeneratorTests.cs @@ -22,7 +22,7 @@ public class QueryBreakdownGeneratorTests var query = new QueryBreakdown("ID, Name", "Users"); // Act - var result = _generator.GenerateMermaidDiagram(query); + var result = QueryBreakdownGenerator.GenerateMermaidDiagram(query); // Assert Assert.That(result, Does.Contain("```mermaid")); @@ -46,7 +46,7 @@ public class QueryBreakdownGeneratorTests query.OrderByClause.Clause = "OrderCount DESC"; // Act - var result = _generator.GenerateMermaidDiagram(query, "User Orders Query"); + var result = QueryBreakdownGenerator.GenerateMermaidDiagram(query, "User Orders Query"); // Assert Assert.That(result, Does.Contain("### User Orders Query")); @@ -65,7 +65,7 @@ public class QueryBreakdownGeneratorTests var query = new QueryBreakdown("*", "Products", "Price > 100"); // Act - var result = _generator.GenerateMermaidDiagram(query); + var result = QueryBreakdownGenerator.GenerateMermaidDiagram(query); // Assert Assert.That(result, Does.Contain("WHERE")); @@ -86,7 +86,7 @@ public class QueryBreakdownGeneratorTests var query = QueryBreakdown.Parse(sql); // Act - var result = _generator.GenerateMermaidDiagram(query); + var result = QueryBreakdownGenerator.GenerateMermaidDiagram(query); // Assert Assert.That(result, Is.Not.Null); @@ -102,7 +102,7 @@ public class QueryBreakdownGeneratorTests var query = new QueryBreakdown("*", "Users"); // Act - var result = _generator.GenerateMermaidDiagram(query, "Test Query"); + var result = QueryBreakdownGenerator.GenerateMermaidDiagram(query, "Test Query"); // Assert Assert.That(result, Does.StartWith("### Test Query")); @@ -115,7 +115,7 @@ public class QueryBreakdownGeneratorTests var query = new QueryBreakdown("*", "Users"); // Act - var result = _generator.GenerateMermaidDiagram(query); + var result = QueryBreakdownGenerator.GenerateMermaidDiagram(query); // Assert Assert.That(result, Does.Not.StartWith("###")); @@ -130,7 +130,7 @@ public class QueryBreakdownGeneratorTests var query = new QueryBreakdown(longSelect, "LargeTable"); // Act - var result = _generator.GenerateMermaidDiagram(query); + var result = QueryBreakdownGenerator.GenerateMermaidDiagram(query); // Assert Assert.That(result, Does.Contain("...")); diff --git a/tests/Strata.SqlTools.Markdown.Tests/SqlServer/QueryMarkdownGenerationTests.cs b/tests/Strata.SqlTools.Markdown.Tests/SqlServer/QueryMarkdownGenerationTests.cs index 5ffd0aa..e01392d 100644 --- a/tests/Strata.SqlTools.Markdown.Tests/SqlServer/QueryMarkdownGenerationTests.cs +++ b/tests/Strata.SqlTools.Markdown.Tests/SqlServer/QueryMarkdownGenerationTests.cs @@ -59,7 +59,7 @@ public class QueryMarkdownGenerationTests var queryBreakdown = QueryBreakdown.Parse(sqlContent); // Generate markdown with the filename as title - var markdown = _generator.GenerateMermaidDiagram(queryBreakdown, fileName); + var markdown = QueryBreakdownGenerator.GenerateMermaidDiagram(queryBreakdown, fileName); // Verify markdown was generated Assert.That(markdown, Is.Not.Null); @@ -107,7 +107,7 @@ public class QueryMarkdownGenerationTests try { var queryBreakdown = QueryBreakdown.Parse(sqlContent); - var markdown = _generator.GenerateMermaidDiagram(queryBreakdown, fileName); + var markdown = QueryBreakdownGenerator.GenerateMermaidDiagram(queryBreakdown, fileName); // Add source SQL to the markdown var fullMarkdown = $"{markdown}\n\n## Source SQL\n\n```sql\n{sqlContent}\n```\n"; diff --git a/tests/Strata.SqlTools.Markdown.Tests/SqlServer/SqlStatementGeneratorTests.cs b/tests/Strata.SqlTools.Markdown.Tests/SqlServer/SqlStatementGeneratorTests.cs index bed15a7..570f43d 100644 --- a/tests/Strata.SqlTools.Markdown.Tests/SqlServer/SqlStatementGeneratorTests.cs +++ b/tests/Strata.SqlTools.Markdown.Tests/SqlServer/SqlStatementGeneratorTests.cs @@ -21,7 +21,7 @@ public class SqlStatementGeneratorTests var query = new QueryBreakdown("*", "Users"); // Act - var result = _generator.GenerateSequenceDiagram(query); + var result = SqlStatementGenerator.GenerateSequenceDiagram(query); // Assert Assert.That(result, Does.Contain("```mermaid")); @@ -39,7 +39,7 @@ public class SqlStatementGeneratorTests query.SetupClauses.Add("CREATE TEMP TABLE #Temp (ID INT)"); // Act - var result = _generator.GenerateSequenceDiagram(query); + var result = SqlStatementGenerator.GenerateSequenceDiagram(query); // Assert Assert.That(result, Does.Contain("Setup Clauses")); @@ -55,7 +55,7 @@ public class SqlStatementGeneratorTests query.FinishClauses.Add("DROP TABLE #Temp"); // Act - var result = _generator.GenerateSequenceDiagram(query); + var result = SqlStatementGenerator.GenerateSequenceDiagram(query); // Assert Assert.That(result, Does.Contain("Finish Clauses")); @@ -69,7 +69,7 @@ public class SqlStatementGeneratorTests var query = new QueryBreakdown("*", "Users"); // Act - var result = _generator.GenerateSequenceDiagram(query, "Query Execution"); + var result = SqlStatementGenerator.GenerateSequenceDiagram(query, "Query Execution"); // Assert Assert.That(result, Does.StartWith("### Query Execution")); @@ -82,7 +82,7 @@ public class SqlStatementGeneratorTests var tables = new[] { "Users", "Orders", "Products" }; // Act - var result = _generator.GenerateEntityRelationshipDiagram(tables); + var result = SqlStatementGenerator.GenerateEntityRelationshipDiagram(tables); // Assert Assert.That(result, Does.Contain("```mermaid")); @@ -100,7 +100,7 @@ public class SqlStatementGeneratorTests var tables = new[] { "Users", "Orders" }; // Act - var result = _generator.GenerateEntityRelationshipDiagram(tables, "Database Schema"); + var result = SqlStatementGenerator.GenerateEntityRelationshipDiagram(tables, "Database Schema"); // Assert Assert.That(result, Does.StartWith("### Database Schema")); @@ -113,7 +113,7 @@ public class SqlStatementGeneratorTests var tables = new[] { "[dbo].[Users]", "schema.Orders" }; // Act - var result = _generator.GenerateEntityRelationshipDiagram(tables); + var result = SqlStatementGenerator.GenerateEntityRelationshipDiagram(tables); // Assert Assert.That(result, Does.Contain("dbo_Users"));