@@ -33,7 +33,7 @@ public class PlaceCloseBrace : ConfigurableRule
3333 ///
3434 /// Default value is false.
3535 /// </summary>
36- [ ConfigurableRuleProperty ( defaultValue : false ) ]
36+ [ ConfigurableRuleProperty ( defaultValue : false ) ]
3737 public bool NoEmptyLineBefore { get ; protected set ; }
3838
3939 /// <summary>
@@ -82,11 +82,11 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
8282
8383 var tokens = Helper . Instance . Tokens ;
8484 var diagnosticRecords = new List < DiagnosticRecord > ( ) ;
85- var curlyStack = new Stack < Tuple < Token , int > > ( ) ;
85+ var curlyStack = new Stack < Tuple < Token , int > > ( ) ;
8686
8787 // TODO move part common with PlaceOpenBrace to one place
8888 var tokenOps = new TokenOperations ( tokens , ast ) ;
89- tokensToIgnore = new HashSet < Token > ( tokenOps . GetCloseBracesInCommandElements ( ) ) ;
89+ tokensToIgnore = new HashSet < Token > ( tokenOps . GetCloseBracesInCommandElements ( ) ) ;
9090
9191 // Ignore close braces that are part of a one line if-else statement
9292 // E.g. $x = if ($true) { "blah" } else { "blah blah" }
@@ -138,6 +138,12 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
138138 GetViolationForBraceShouldHaveNewLineAfter ( tokens , k , openBracePos , fileName ) ,
139139 ref diagnosticRecords ) ;
140140 }
141+ else
142+ {
143+ AddToDiagnosticRecords (
144+ GetViolationsForUncuddledBranches ( tokens , k , openBracePos , fileName ) ,
145+ ref diagnosticRecords ) ;
146+ }
141147 }
142148 else
143149 {
@@ -317,7 +323,7 @@ private DiagnosticRecord GetViolationForBraceShouldHaveNewLineAfter(
317323 if ( ( tokens [ expectedNewLinePos ] . Kind == TokenKind . Else
318324 || tokens [ expectedNewLinePos ] . Kind == TokenKind . ElseIf )
319325 && ! tokensToIgnore . Contains ( closeBraceToken ) )
320- {
326+ {
321327 return new DiagnosticRecord (
322328 GetError ( Strings . PlaceCloseBraceErrorShouldFollowNewLine ) ,
323329 closeBraceToken . Extent ,
@@ -326,12 +332,74 @@ private DiagnosticRecord GetViolationForBraceShouldHaveNewLineAfter(
326332 fileName ,
327333 null ,
328334 GetCorrectionsForBraceShouldHaveNewLineAfter ( tokens , closeBracePos , openBracePos , fileName ) ) ;
329- }
335+ }
330336 }
331337
332338 return null ;
333339 }
334340
341+ private DiagnosticRecord GetViolationsForUncuddledBranches (
342+ Token [ ] tokens ,
343+ int closeBracePos ,
344+ int openBracePos ,
345+ string fileName )
346+ {
347+ // this will not work if there is a comment in between any tokens.
348+ var closeBraceToken = tokens [ closeBracePos ] ;
349+ if ( tokens . Length <= closeBracePos + 2 ||
350+ tokensToIgnore . Contains ( closeBraceToken ) )
351+ {
352+ return null ;
353+ }
354+
355+ var token1 = tokens [ closeBracePos + 1 ] ;
356+ var token2 = tokens [ closeBracePos + 2 ] ;
357+ var branchTokenPos = IsBranchingStatementToken ( token1 ) && ! ApartByWhitespace ( closeBraceToken , token1 ) ?
358+ closeBracePos + 1 :
359+ token1 . Kind == TokenKind . NewLine && IsBranchingStatementToken ( token2 ) ?
360+ closeBracePos + 2 :
361+ - 1 ;
362+
363+ return branchTokenPos == - 1 ?
364+ null :
365+ new DiagnosticRecord (
366+ GetError ( Strings . PlaceCloseBraceErrorShouldCuddleBranchStatement ) ,
367+ closeBraceToken . Extent ,
368+ GetName ( ) ,
369+ GetDiagnosticSeverity ( ) ,
370+ fileName ,
371+ null ,
372+ GetCorrectionsForUncuddledBranches ( tokens , closeBracePos , branchTokenPos , fileName ) ) ;
373+ }
374+
375+ private static bool ApartByWhitespace ( Token token1 , Token token2 )
376+ {
377+ var e1 = token1 . Extent ;
378+ var e2 = token2 . Extent ;
379+ return e1 . StartLineNumber == e2 . StartLineNumber &&
380+ e2 . StartColumnNumber - e1 . EndColumnNumber == 1 ;
381+ }
382+
383+ private List < CorrectionExtent > GetCorrectionsForUncuddledBranches (
384+ Token [ ] tokens ,
385+ int closeBracePos ,
386+ int branchStatementPos ,
387+ string fileName )
388+ {
389+ var corrections = new List < CorrectionExtent > ( ) ;
390+ var closeBraceToken = tokens [ closeBracePos ] ;
391+ var branchStatementToken = tokens [ branchStatementPos ] ;
392+ corrections . Add ( new CorrectionExtent (
393+ closeBraceToken . Extent . StartLineNumber ,
394+ branchStatementToken . Extent . EndLineNumber ,
395+ closeBraceToken . Extent . StartColumnNumber ,
396+ branchStatementToken . Extent . EndColumnNumber ,
397+ closeBraceToken . Extent . Text + ' ' + branchStatementToken . Extent . Text ,
398+ fileName ) ) ;
399+ return corrections ;
400+
401+ }
402+
335403 private DiagnosticRecord GetViolationForBraceShouldBeOnNewLine (
336404 Token [ ] tokens ,
337405 int closeBracePos ,
@@ -376,6 +444,20 @@ private List<CorrectionExtent> GetCorrectionsForBraceShouldBeOnNewLine(
376444 return corrections ;
377445 }
378446
447+ private bool IsBranchingStatementToken ( Token token )
448+ {
449+ switch ( token . Kind )
450+ {
451+ case TokenKind . Else :
452+ case TokenKind . ElseIf :
453+ case TokenKind . Catch :
454+ case TokenKind . Finally :
455+ return true ;
456+
457+ default :
458+ return false ;
459+ }
460+ }
379461 private void AddToDiagnosticRecords (
380462 DiagnosticRecord diagnosticRecord ,
381463 ref List < DiagnosticRecord > diagnosticRecords )
0 commit comments