@@ -57,6 +57,24 @@ public string Kind
5757 }
5858 }
5959
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+
6078 private bool insertSpaces ;
6179 private char indentationChar ;
6280 private int indentationLevelMultiplier ;
@@ -68,9 +86,17 @@ private enum IndentationKind {
6886 // Auto
6987 } ;
7088
89+ private enum PipelineIndentationStyle
90+ {
91+ IncreaseIndentationForFirstPipeline ,
92+ IncreaseIndentationAfterEveryPipeline ,
93+ NoIndentation
94+ }
95+
7196 // TODO make this configurable
7297 private IndentationKind indentationKind = IndentationKind . Space ;
7398
99+ private PipelineIndentationStyle pipelineIndentationStyle = PipelineIndentationStyle . IncreaseIndentationAfterEveryPipeline ;
74100
75101 /// <summary>
76102 /// Analyzes the given ast to find violations.
@@ -104,6 +130,7 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
104130 var diagnosticRecords = new List < DiagnosticRecord > ( ) ;
105131 var indentationLevel = 0 ;
106132 var onNewLine = true ;
133+ var pipelineAsts = ast . FindAll ( testAst => testAst is PipelineAst && ( testAst as PipelineAst ) . PipelineElements . Count > 1 , true ) ;
107134 for ( int k = 0 ; k < tokens . Length ; k ++ )
108135 {
109136 var token = tokens [ k ] ;
@@ -123,6 +150,28 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
123150 AddViolation ( token , indentationLevel ++ , diagnosticRecords , ref onNewLine ) ;
124151 break ;
125152
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+
126175 case TokenKind . RParen :
127176 case TokenKind . RCurly :
128177 indentationLevel = ClipNegative ( indentationLevel - 1 ) ;
@@ -156,22 +205,44 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
156205 {
157206 -- j ;
158207 }
159-
160- if ( j >= 0 && tokens [ j ] . Kind == TokenKind . Pipe )
161- {
162- ++ tempIndentationLevel ;
163- }
164208 }
165209
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 ) ;
167216 }
168217 break ;
169218 }
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+ }
170234 }
171235
172236 return diagnosticRecords ;
173237 }
174238
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+
175246 /// <summary>
176247 /// Retrieves the common name of this rule.
177248 /// </summary>
@@ -237,7 +308,8 @@ private void AddViolation(
237308 Token token ,
238309 int expectedIndentationLevel ,
239310 List < DiagnosticRecord > diagnosticRecords ,
240- ref bool onNewLine )
311+ ref bool onNewLine ,
312+ bool lineHasPipelineBeforeToken = false )
241313 {
242314 if ( onNewLine )
243315 {
@@ -265,26 +337,28 @@ private void AddViolation(
265337 GetDiagnosticSeverity ( ) ,
266338 fileName ,
267339 null ,
268- GetSuggestedCorrections ( token , expectedIndentationLevel ) ) ) ;
340+ GetSuggestedCorrections ( token , expectedIndentationLevel , lineHasPipelineBeforeToken ) ) ) ;
269341 }
270342 }
271343 }
272344
273345 private List < CorrectionExtent > GetSuggestedCorrections (
274346 Token token ,
275- int indentationLevel )
347+ int indentationLevel ,
348+ bool lineHasPipelineBeforeToken = false )
276349 {
277350 // TODO Add another constructor for correction extent that takes extent
278351 // TODO handle param block
279352 // TODO handle multiline commands
280353
281354 var corrections = new List < CorrectionExtent > ( ) ;
355+ var optionalPipeline = lineHasPipelineBeforeToken ? "| " : string . Empty ;
282356 corrections . Add ( new CorrectionExtent (
283357 token . Extent . StartLineNumber ,
284358 token . Extent . EndLineNumber ,
285359 1 ,
286360 token . Extent . EndColumnNumber ,
287- GetIndentationString ( indentationLevel ) + token . Extent . Text ,
361+ GetIndentationString ( indentationLevel ) + optionalPipeline + token . Extent . Text ,
288362 token . Extent . File ) ) ;
289363 return corrections ;
290364 }
0 commit comments