Skip to content

Commit 73aefd8

Browse files
author
Kapil Borle
committed
Move the fixing in formatting to ScriptAnalyzer class
1 parent 3057c03 commit 73aefd8

File tree

2 files changed

+89
-45
lines changed

2 files changed

+89
-45
lines changed

Engine/Formatter.cs

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -37,54 +37,10 @@ public static string Format<TCmdlet>(
3737
}
3838

3939
cmdlet.WriteVerbose("Running " + rule);
40-
4140
var currentSettings = GetCurrentSettings(settings, rule);
4241
ScriptAnalyzer.Instance.UpdateSettings(currentSettings);
4342
ScriptAnalyzer.Instance.Initialize(cmdlet, null, null, null, null, true, false);
44-
45-
var corrections = new List<CorrectionExtent>();
46-
var records = Enumerable.Empty<DiagnosticRecord>();
47-
var numPreviousCorrections = corrections.Count;
48-
49-
do
50-
{
51-
// TODO create better verbose messages
52-
var correctionApplied = new HashSet<int>();
53-
foreach (var correction in corrections)
54-
{
55-
// apply only one edit per line
56-
if (correctionApplied.Contains(correction.StartLineNumber))
57-
{
58-
continue;
59-
}
60-
61-
correctionApplied.Add(correction.StartLineNumber);
62-
text.ApplyEdit(correction);
63-
}
64-
65-
records = ScriptAnalyzer.Instance.AnalyzeScriptDefinition(text.ToString());
66-
corrections = records.Select(r => r.SuggestedCorrections.ElementAt(0)).ToList();
67-
if (numPreviousCorrections > 0 && numPreviousCorrections == corrections.Count)
68-
{
69-
cmdlet.ThrowTerminatingError(new ErrorRecord(
70-
new InvalidOperationException(),
71-
"FORMATTER_ERROR",
72-
ErrorCategory.InvalidOperation,
73-
corrections));
74-
}
75-
76-
numPreviousCorrections = corrections.Count;
77-
78-
// get unique correction instances
79-
// sort them by line numbers
80-
corrections.Sort((x, y) =>
81-
{
82-
return x.StartLineNumber < x.StartLineNumber ?
83-
1 :
84-
(x.StartLineNumber == x.StartLineNumber ? 0 : -1);
85-
});
86-
87-
} while (numPreviousCorrections > 0);
43+
text = ScriptAnalyzer.Instance.Fix(text);
8844
}
8945

9046
return text.ToString();

Engine/ScriptAnalyzer.cs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,94 @@ public IEnumerable<DiagnosticRecord> AnalyzeScriptDefinition(string scriptDefini
15271527
return this.AnalyzeSyntaxTree(scriptAst, scriptTokens, String.Empty);
15281528
}
15291529

1530+
/// <summary>
1531+
/// Fix the violations in the given script text.
1532+
/// </summary>
1533+
/// <param name="scriptDefinition">The script text to be fixed.</param>
1534+
/// <returns>The fixed script text.</returns>
1535+
public string Fix(string scriptDefinition)
1536+
{
1537+
if (scriptDefinition == null)
1538+
{
1539+
throw new ArgumentNullException(nameof(scriptDefinition));
1540+
}
1541+
1542+
return Fix(new EditableText(scriptDefinition)).ToString();
1543+
}
1544+
1545+
/// <summary>
1546+
/// Fix the violations in the given script text.
1547+
/// </summary>
1548+
/// <param name="text">An object of type `EditableText` that encapsulates the script text to be fixed.</param>
1549+
/// <returns>The same instance of `EditableText` that was passed to the method, but the instance encapsulates the fixed script text. This helps in chaining the Fix method.</returns>
1550+
public EditableText Fix(EditableText text)
1551+
{
1552+
if (text == null)
1553+
{
1554+
throw new ArgumentNullException(nameof(text));
1555+
}
1556+
1557+
var previousUnusedCorrections = 0;
1558+
do
1559+
{
1560+
var records = AnalyzeScriptDefinition(text.ToString());
1561+
var corrections = records
1562+
.Select(r => r.SuggestedCorrections)
1563+
.Where(sc => sc != null && sc.Any())
1564+
.Select(sc => sc.First())
1565+
.ToList();
1566+
1567+
int unusedCorrections;
1568+
Fix(text, corrections, out unusedCorrections);
1569+
1570+
// This is an indication of an infinite loop. There is a small chance of this.
1571+
// It is better to abort the fixing operation at this point.
1572+
if (previousUnusedCorrections > 0 && previousUnusedCorrections == unusedCorrections)
1573+
{
1574+
this.outputWriter.ThrowTerminatingError(new ErrorRecord(
1575+
new InvalidOperationException(),
1576+
"FIX_ERROR",
1577+
ErrorCategory.InvalidOperation,
1578+
corrections));
1579+
}
1580+
1581+
previousUnusedCorrections = unusedCorrections;
1582+
} while (previousUnusedCorrections > 0);
1583+
1584+
return text;
1585+
}
1586+
1587+
private static IEnumerable<CorrectionExtent> GetCorrectionExtentsForFix(
1588+
IEnumerable<CorrectionExtent> correctionExtents)
1589+
{
1590+
var ceList = correctionExtents.ToList();
1591+
ceList.Sort((x, y) =>
1592+
{
1593+
return x.StartLineNumber < x.StartLineNumber ?
1594+
1 :
1595+
(x.StartLineNumber == x.StartLineNumber ? 0 : -1);
1596+
});
1597+
1598+
return ceList.GroupBy(ce => ce.StartLineNumber).Select(g => g.First());
1599+
}
1600+
1601+
private static EditableText Fix(
1602+
EditableText text,
1603+
IEnumerable<CorrectionExtent> correctionExtents,
1604+
out int unusedCorrections)
1605+
{
1606+
var correctionsToUse = GetCorrectionExtentsForFix(correctionExtents);
1607+
var count = 0;
1608+
foreach (var correction in correctionsToUse)
1609+
{
1610+
count++;
1611+
text.ApplyEdit(correction);
1612+
}
1613+
1614+
unusedCorrections = correctionExtents.Count() - count;
1615+
return text;
1616+
}
1617+
15301618
private void BuildScriptPathList(
15311619
string path,
15321620
bool searchRecursively,

0 commit comments

Comments
 (0)