@@ -134,6 +134,13 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
134
134
var onNewLine = true ;
135
135
var pipelineAsts = ast . FindAll ( testAst => testAst is PipelineAst && ( testAst as PipelineAst ) . PipelineElements . Count > 1 , true ) . ToList ( ) ;
136
136
int minimumPipelineAstIndex = 0 ;
137
+ /*
138
+ When an LParen and LBrace are on the same line, it can lead to too much de-indentation.
139
+ In order to prevent the RParen code from de-indenting too much, we keep a stack of when we skipped the indentation
140
+ caused by tokens that require a closing RParen (which are LParen, AtParen and DollarParen).
141
+ */
142
+ var lParenSkippedIndentation = new Stack < bool > ( ) ;
143
+
137
144
for ( int tokenIndex = 0 ; tokenIndex < tokens . Length ; tokenIndex ++ )
138
145
{
139
146
var token = tokens [ tokenIndex ] ;
@@ -146,10 +153,27 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
146
153
switch ( token . Kind )
147
154
{
148
155
case TokenKind . AtCurly :
149
- case TokenKind . AtParen :
150
- case TokenKind . LParen :
151
156
case TokenKind . LCurly :
157
+ AddViolation ( token , indentationLevel ++ , diagnosticRecords , ref onNewLine ) ;
158
+ break ;
159
+
152
160
case TokenKind . DollarParen :
161
+ case TokenKind . AtParen :
162
+ lParenSkippedIndentation . Push ( false ) ;
163
+ AddViolation ( token , indentationLevel ++ , diagnosticRecords , ref onNewLine ) ;
164
+ break ;
165
+
166
+ case TokenKind . LParen :
167
+ // When a line starts with a parenthesis and it is not the last non-comment token of that line,
168
+ // then indentation does not need to be increased.
169
+ if ( ( tokenIndex == 0 || tokens [ tokenIndex - 1 ] . Kind == TokenKind . NewLine ) &&
170
+ NextTokenIgnoringComments ( tokens , tokenIndex ) ? . Kind != TokenKind . NewLine )
171
+ {
172
+ onNewLine = false ;
173
+ lParenSkippedIndentation . Push ( true ) ;
174
+ break ;
175
+ }
176
+ lParenSkippedIndentation . Push ( false ) ;
153
177
AddViolation ( token , indentationLevel ++ , diagnosticRecords , ref onNewLine ) ;
154
178
break ;
155
179
@@ -181,6 +205,20 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
181
205
break ;
182
206
183
207
case TokenKind . RParen :
208
+ bool matchingLParenIncreasedIndentation = false ;
209
+ if ( lParenSkippedIndentation . Count > 0 )
210
+ {
211
+ matchingLParenIncreasedIndentation = lParenSkippedIndentation . Pop ( ) ;
212
+ }
213
+ if ( matchingLParenIncreasedIndentation )
214
+ {
215
+ onNewLine = false ;
216
+ break ;
217
+ }
218
+ indentationLevel = ClipNegative ( indentationLevel - 1 ) ;
219
+ AddViolation ( token , indentationLevel , diagnosticRecords , ref onNewLine ) ;
220
+ break ;
221
+
184
222
case TokenKind . RCurly :
185
223
indentationLevel = ClipNegative ( indentationLevel - 1 ) ;
186
224
AddViolation ( token , indentationLevel , diagnosticRecords , ref onNewLine ) ;
@@ -259,6 +297,29 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
259
297
return diagnosticRecords ;
260
298
}
261
299
300
+ private static Token NextTokenIgnoringComments ( Token [ ] tokens , int startIndex )
301
+ {
302
+ if ( startIndex >= tokens . Length - 1 )
303
+ {
304
+ return null ;
305
+ }
306
+
307
+ for ( int i = startIndex + 1 ; i < tokens . Length ; i ++ )
308
+ {
309
+ switch ( tokens [ i ] . Kind )
310
+ {
311
+ case TokenKind . Comment :
312
+ continue ;
313
+
314
+ default :
315
+ return tokens [ i ] ;
316
+ }
317
+ }
318
+
319
+ // We've run out of tokens
320
+ return null ;
321
+ }
322
+
262
323
private static bool PipelineIsFollowedByNewlineOrLineContinuation ( Token [ ] tokens , int startIndex )
263
324
{
264
325
if ( startIndex >= tokens . Length - 1 )
0 commit comments