refactor(dedup): extract self-duplicated helpers in three src/ files
Tackles the in-file copy-paste duplications SonarQube flagged on
`sql-utilities`, narrowing the dedup target to the cases where the
extraction is a clear readability win.
- `LinqToSql.Converters.ReverseConverterExtensions`: the three
`ToLinqQueryBreakdown` overloads (SqlServer / PostgreSql / Snowflake)
had identical 26-line bodies. Routes all three through a single
`BuildLinqBreakdownFrom(QueryBreakdown)` private helper — works
because Snowflake/PostgreSql `QueryBreakdown` derive from the
SqlServer one, so the parameter type accepts all three. Public API
preserved.
- `Markdown.Expressions.ExpressionGenerator`: `VisitInExpression` and
`VisitNotInExpression` had identical 18-line bodies differing only in
the "IN"/"NOT IN" label. Both now delegate to a new private
`RenderInList(label, searchExpression, values)`.
- `PostgreSql.Statements.StatementExpressionParser`: the qualified-
column-name building loop and the column-id switch were duplicated
across `HandleStringToken` (qualified-column branch) and
`GrabColumnExpression`. Extracted to a shared
`BuildQualifiedColumnExpression(seededBuilder, reader)` private helper.
Deliberately *not* refactored: `PostgreSql.Statements.StatementReader`'s
`<` / `>` operator handlers, which Sonar also flags as duplicate. The
shared pattern there is a structural sequence of "MovePosition;
character check; emit Token; return" repeated across single-/two-char
operator variants; folding it into a helper would replace four short,
self-explanatory inline checks with `TryMatchTwoCharOperator('=', ...)`
indirection that obscures what each branch actually emits. The dedup
isn't worth the readability tax.
All 1180 tests stay green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
f362ec7e53
commit
d4b66838b5
@@ -485,37 +485,23 @@ public class ExpressionGenerator : IVisitor<string>
|
||||
}
|
||||
|
||||
public string VisitInExpression(InExpression inExpression)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine($"{Indent()}IN:");
|
||||
_indentLevel++;
|
||||
sb.AppendLine($"{Indent()}Search Expression:");
|
||||
_indentLevel++;
|
||||
sb.AppendLine(inExpression.SearchExpression.Accept(this));
|
||||
_indentLevel--;
|
||||
sb.AppendLine($"{Indent()}Values:");
|
||||
_indentLevel++;
|
||||
foreach (var value in inExpression.ValuesToCompare)
|
||||
{
|
||||
sb.AppendLine(value.Accept(this));
|
||||
}
|
||||
_indentLevel--;
|
||||
_indentLevel--;
|
||||
return sb.ToString();
|
||||
}
|
||||
=> RenderInList("IN", inExpression.SearchExpression, inExpression.ValuesToCompare);
|
||||
|
||||
public string VisitNotInExpression(NotInExpression inExpression)
|
||||
=> RenderInList("NOT IN", inExpression.SearchExpression, inExpression.ValuesToCompare);
|
||||
|
||||
private string RenderInList(string label, Expression searchExpression, IEnumerable<Expression> values)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine($"{Indent()}NOT IN:");
|
||||
sb.AppendLine($"{Indent()}{label}:");
|
||||
_indentLevel++;
|
||||
sb.AppendLine($"{Indent()}Search Expression:");
|
||||
_indentLevel++;
|
||||
sb.AppendLine(inExpression.SearchExpression.Accept(this));
|
||||
sb.AppendLine(searchExpression.Accept(this));
|
||||
_indentLevel--;
|
||||
sb.AppendLine($"{Indent()}Values:");
|
||||
_indentLevel++;
|
||||
foreach (var value in inExpression.ValuesToCompare)
|
||||
foreach (var value in values)
|
||||
{
|
||||
sb.AppendLine(value.Accept(this));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user