Skip to content

Commit c6a311e

Browse files
author
Kapil Borle
committed
Handle open brace in command element
1 parent 6a631d7 commit c6a311e

File tree

2 files changed

+52
-9
lines changed

2 files changed

+52
-9
lines changed

Rules/PlaceOpenBrace.cs

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules
3030
#endif
3131
public class PlaceOpenBrace : ConfigurableScriptRule
3232
{
33-
private List<Func<Token[], string, IEnumerable<DiagnosticRecord>>> violationFinders = new List<Func<Token[], string, IEnumerable<DiagnosticRecord>>>();
33+
private List<Func<Token[], Ast, string, IEnumerable<DiagnosticRecord>>> violationFinders
34+
= new List<Func<Token[], Ast, string, IEnumerable<DiagnosticRecord>>>();
3435

3536
[ConfigurableRuleProperty()]
3637
public bool OnSameLine { get; protected set; } = true;
@@ -53,21 +54,48 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
5354

5455
// TODO Should have the following option
5556
// * no-empty-lines-after
56-
// TODO handle open brace for a command parameter.
57+
var diagnosticRecords = new List<DiagnosticRecord>();
58+
if (!Enable)
59+
{
60+
return diagnosticRecords;
61+
}
62+
63+
var tokens = Helper.Instance.Tokens;
64+
foreach (var violationFinder in violationFinders)
65+
{
66+
diagnosticRecords.AddRange(violationFinder(tokens, ast, fileName));
67+
}
68+
69+
return diagnosticRecords;
70+
}
71+
72+
private static HashSet<Token> FindTokensToIgnore(Token[] tokens, Ast ast)
73+
{
74+
// Ignore open braces that are part of arguments to a command
5775
// * E.g. get-process | % { "blah }
5876
// In the above case even if OnSameLine == false, we should not
5977
// flag the open brace as it would move the brace to the next line
60-
// and it will invalidate the command
61-
var diagnosticRecords = new List<DiagnosticRecord>();
62-
if (Enable)
78+
// and will invalidate the command
79+
80+
var cmdElemAsts = ast.FindAll(x => x is CommandElementAst && x is ScriptBlockExpressionAst, true);
81+
var tokensToIgnore = new HashSet<Token> ();
82+
if (cmdElemAsts == null)
6383
{
64-
foreach (var violationFinder in violationFinders)
84+
return tokensToIgnore;
85+
}
86+
87+
foreach (var cmdElemAst in cmdElemAsts)
88+
{
89+
var tokenToIgnore = tokens.FirstOrDefault(
90+
token => token.Kind == TokenKind.LCurly
91+
&& cmdElemAst.Extent.StartOffset == token.Extent.StartOffset);
92+
if (tokenToIgnore != null)
6593
{
66-
diagnosticRecords.AddRange(violationFinder(Helper.Instance.Tokens, fileName));
94+
tokensToIgnore.Add(tokenToIgnore);
6795
}
6896
}
6997

70-
return diagnosticRecords;
98+
return tokensToIgnore;
7199
}
72100

73101
public override void ConfigureRule(IDictionary<string, object> paramValueMap)
@@ -90,6 +118,7 @@ public override void ConfigureRule(IDictionary<string, object> paramValueMap)
90118

91119
private IEnumerable<DiagnosticRecord> FindViolationsForBraceShouldBeOnSameLine(
92120
Token[] tokens,
121+
Ast ast,
93122
string fileName)
94123
{
95124
for (int k = 2; k < tokens.Length; k++)
@@ -111,6 +140,7 @@ private IEnumerable<DiagnosticRecord> FindViolationsForBraceShouldBeOnSameLine(
111140

112141
private IEnumerable<DiagnosticRecord> FindViolationsForNoNewLineAfterBrace(
113142
Token[] tokens,
143+
Ast ast,
114144
string fileName)
115145
{
116146
for (int k = 0; k < tokens.Length - 1; k++)
@@ -158,8 +188,11 @@ private List<CorrectionExtent> GetCorrectionsForNoNewLineAfterBrace(
158188

159189
private IEnumerable<DiagnosticRecord> FindViolationsForBraceShouldNotBeOnSameLine(
160190
Token[] tokens,
191+
Ast ast,
161192
string fileName)
162193
{
194+
195+
var tokensToIgnore = FindTokensToIgnore(tokens, ast);
163196
for (int k = 1; k < tokens.Length; k++)
164197
{
165198
if (tokens[k].Kind == TokenKind.EndOfInput)
@@ -168,7 +201,8 @@ private IEnumerable<DiagnosticRecord> FindViolationsForBraceShouldNotBeOnSameLin
168201
}
169202

170203
if (tokens[k].Kind == TokenKind.LCurly
171-
&& tokens[k - 1].Kind != TokenKind.NewLine)
204+
&& tokens[k - 1].Kind != TokenKind.NewLine
205+
&& !tokensToIgnore.Contains(tokens[k]))
172206
{
173207
yield return new DiagnosticRecord(
174208
GetError(),

Tests/Rules/PlaceOpenBrace.tests.ps1

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,12 @@ function foo ($param1) {
4242
}
4343
'@
4444
$ruleConfiguration.'OnSameLine' = $false
45+
$ruleConfiguration.'NewLineAfter' = $false
4546
$violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings
47+
$defShouldIgnore = @'
48+
Get-Process | % { "blah" }
49+
'@
50+
$violationsShouldIgnore = Invoke-ScriptAnalyzer -ScriptDefinition $defShouldIgnore -Settings $settings
4651
}
4752

4853
It "Should find a violation" {
@@ -52,6 +57,10 @@ function foo ($param1) {
5257
It "Should mark only the open brace" {
5358
$violations[0].Extent.Text | Should Be '{'
5459
}
60+
61+
It "Should ignore violations for a command element" {
62+
$violationsShouldIgnore.Count | Should Be 0
63+
}
5564
}
5665

5766
Context "When a new line should follow an open brace" {

0 commit comments

Comments
 (0)