@@ -57,6 +57,24 @@ public string Kind
57
57
}
58
58
}
59
59
60
+
61
+ [ ConfigurableRuleProperty ( defaultValue : "IncreaseIndentationForFirstPipeline" ) ]
62
+ public string PipelineIndentation
63
+ {
64
+ get
65
+ {
66
+ return pipelineIndentationStyle . ToString ( ) ;
67
+ }
68
+ set
69
+ {
70
+ if ( String . IsNullOrWhiteSpace ( value ) ||
71
+ ! Enum . TryParse ( value , true , out pipelineIndentationStyle ) )
72
+ {
73
+ pipelineIndentationStyle = PipelineIndentationStyle . IncreaseIndentationAfterEveryPipeline ;
74
+ }
75
+ }
76
+ }
77
+
60
78
private bool insertSpaces ;
61
79
private char indentationChar ;
62
80
private int indentationLevelMultiplier ;
@@ -68,9 +86,17 @@ private enum IndentationKind {
68
86
// Auto
69
87
} ;
70
88
89
+ private enum PipelineIndentationStyle
90
+ {
91
+ IncreaseIndentationForFirstPipeline ,
92
+ IncreaseIndentationAfterEveryPipeline ,
93
+ NoIndentation
94
+ }
95
+
71
96
// TODO make this configurable
72
97
private IndentationKind indentationKind = IndentationKind . Space ;
73
98
99
+ private PipelineIndentationStyle pipelineIndentationStyle = PipelineIndentationStyle . IncreaseIndentationAfterEveryPipeline ;
74
100
75
101
/// <summary>
76
102
/// Analyzes the given ast to find violations.
@@ -104,6 +130,7 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
104
130
var diagnosticRecords = new List < DiagnosticRecord > ( ) ;
105
131
var indentationLevel = 0 ;
106
132
var onNewLine = true ;
133
+ var pipelineAsts = ast . FindAll ( testAst => testAst is PipelineAst && ( testAst as PipelineAst ) . PipelineElements . Count > 1 , true ) ;
107
134
for ( int k = 0 ; k < tokens . Length ; k ++ )
108
135
{
109
136
var token = tokens [ k ] ;
@@ -123,6 +150,28 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
123
150
AddViolation ( token , indentationLevel ++ , diagnosticRecords , ref onNewLine ) ;
124
151
break ;
125
152
153
+ case TokenKind . Pipe :
154
+ bool pipelineIsFollowedByNewlineOrLineContinuation = k < tokens . Length - 1 && k > 0 &&
155
+ ( tokens [ k + 1 ] . Kind == TokenKind . NewLine || tokens [ k + 1 ] . Kind == TokenKind . LineContinuation ) ;
156
+ if ( ! pipelineIsFollowedByNewlineOrLineContinuation )
157
+ {
158
+ break ;
159
+ }
160
+ if ( pipelineIndentationStyle == PipelineIndentationStyle . IncreaseIndentationAfterEveryPipeline )
161
+ {
162
+ AddViolation ( token , indentationLevel ++ , diagnosticRecords , ref onNewLine ) ;
163
+ break ;
164
+ }
165
+ if ( pipelineIndentationStyle == PipelineIndentationStyle . IncreaseIndentationForFirstPipeline )
166
+ {
167
+ bool isFirstPipeInPipeline = pipelineAsts . Any ( pipelineAst => PositionIsEqual ( ( ( PipelineAst ) pipelineAst ) . PipelineElements [ 0 ] . Extent . EndScriptPosition , tokens [ k - 1 ] . Extent . EndScriptPosition ) ) ;
168
+ if ( isFirstPipeInPipeline )
169
+ {
170
+ AddViolation ( token , indentationLevel ++ , diagnosticRecords , ref onNewLine ) ;
171
+ }
172
+ }
173
+ break ;
174
+
126
175
case TokenKind . RParen :
127
176
case TokenKind . RCurly :
128
177
indentationLevel = ClipNegative ( indentationLevel - 1 ) ;
@@ -156,22 +205,44 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
156
205
{
157
206
-- j ;
158
207
}
159
-
160
- if ( j >= 0 && tokens [ j ] . Kind == TokenKind . Pipe )
161
- {
162
- ++ tempIndentationLevel ;
163
- }
164
208
}
165
209
166
- AddViolation ( token , tempIndentationLevel , diagnosticRecords , ref onNewLine ) ;
210
+ var lineHasPipelineBeforeToken = tokens . Any ( oneToken =>
211
+ oneToken . Kind == TokenKind . Pipe &&
212
+ oneToken . Extent . StartLineNumber == token . Extent . StartLineNumber &&
213
+ oneToken . Extent . StartColumnNumber < token . Extent . StartColumnNumber ) ;
214
+
215
+ AddViolation ( token , tempIndentationLevel , diagnosticRecords , ref onNewLine , lineHasPipelineBeforeToken ) ;
167
216
}
168
217
break ;
169
218
}
219
+
220
+ // Check if the current token matches the end of a PipelineAst
221
+ var matchingPipeLineAstEnd = pipelineAsts . FirstOrDefault ( pipelineAst =>
222
+ PositionIsEqual ( pipelineAst . Extent . EndScriptPosition , token . Extent . EndScriptPosition ) ) as PipelineAst ;
223
+ if ( matchingPipeLineAstEnd != null )
224
+ {
225
+ if ( pipelineIndentationStyle == PipelineIndentationStyle . IncreaseIndentationForFirstPipeline )
226
+ {
227
+ indentationLevel = ClipNegative ( indentationLevel - 1 ) ;
228
+ }
229
+ else if ( pipelineIndentationStyle == PipelineIndentationStyle . IncreaseIndentationAfterEveryPipeline )
230
+ {
231
+ indentationLevel = ClipNegative ( indentationLevel - ( matchingPipeLineAstEnd . PipelineElements . Count - 1 ) ) ;
232
+ }
233
+ }
170
234
}
171
235
172
236
return diagnosticRecords ;
173
237
}
174
238
239
+ private static bool PositionIsEqual ( IScriptPosition position1 , IScriptPosition position2 )
240
+ {
241
+ return position1 . ColumnNumber == position2 . ColumnNumber &&
242
+ position1 . LineNumber == position2 . LineNumber &&
243
+ position1 . File == position2 . File ;
244
+ }
245
+
175
246
/// <summary>
176
247
/// Retrieves the common name of this rule.
177
248
/// </summary>
@@ -237,7 +308,8 @@ private void AddViolation(
237
308
Token token ,
238
309
int expectedIndentationLevel ,
239
310
List < DiagnosticRecord > diagnosticRecords ,
240
- ref bool onNewLine )
311
+ ref bool onNewLine ,
312
+ bool lineHasPipelineBeforeToken = false )
241
313
{
242
314
if ( onNewLine )
243
315
{
@@ -265,26 +337,28 @@ private void AddViolation(
265
337
GetDiagnosticSeverity ( ) ,
266
338
fileName ,
267
339
null ,
268
- GetSuggestedCorrections ( token , expectedIndentationLevel ) ) ) ;
340
+ GetSuggestedCorrections ( token , expectedIndentationLevel , lineHasPipelineBeforeToken ) ) ) ;
269
341
}
270
342
}
271
343
}
272
344
273
345
private List < CorrectionExtent > GetSuggestedCorrections (
274
346
Token token ,
275
- int indentationLevel )
347
+ int indentationLevel ,
348
+ bool lineHasPipelineBeforeToken = false )
276
349
{
277
350
// TODO Add another constructor for correction extent that takes extent
278
351
// TODO handle param block
279
352
// TODO handle multiline commands
280
353
281
354
var corrections = new List < CorrectionExtent > ( ) ;
355
+ var optionalPipeline = lineHasPipelineBeforeToken ? "| " : string . Empty ;
282
356
corrections . Add ( new CorrectionExtent (
283
357
token . Extent . StartLineNumber ,
284
358
token . Extent . EndLineNumber ,
285
359
1 ,
286
360
token . Extent . EndColumnNumber ,
287
- GetIndentationString ( indentationLevel ) + token . Extent . Text ,
361
+ GetIndentationString ( indentationLevel ) + optionalPipeline + token . Extent . Text ,
288
362
token . Extent . File ) ) ;
289
363
return corrections ;
290
364
}
0 commit comments