@@ -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 ( ) ,
0 commit comments