Skip to content

Commit

Permalink
Merge pull request #13608 from sjmelia/Issue_10428_formatting_of_empt…
Browse files Browse the repository at this point in the history
…y_for_loops

Issue #10428: Formatting of empty loops now respects CSharp spacing options
  • Loading branch information
sharwell authored May 18, 2017
2 parents 1e444cf + e09ae57 commit 62be375
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,26 +124,24 @@ public override AdjustSpacesOperation GetAdjustSpacesOperation(SyntaxToken previ
return AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinCastParentheses);
}

// For spacing between the parenthesis and the expression inside the control flow expression
if (previousKind == SyntaxKind.OpenParenToken && IsControlFlowLikeKeywordStatementKind(previousParentKind))
{
return AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinOtherParentheses);
}

// Semicolons in an empty for statement. i.e. for(;;)
if (previousKind == SyntaxKind.OpenParenToken || previousKind == SyntaxKind.SemicolonToken)
if (previousParentKind == SyntaxKind.ForStatement
&& this.IsEmptyForStatement((ForStatementSyntax)previousToken.Parent))
{
if (previousToken.Parent.Kind() == SyntaxKind.ForStatement)
if (currentKind == SyntaxKind.SemicolonToken
&& (previousKind != SyntaxKind.SemicolonToken
|| optionSet.GetOption<bool>(CSharpFormattingOptions.SpaceBeforeSemicolonsInForStatement)))
{
var forStatement = (ForStatementSyntax)previousToken.Parent;
if (forStatement.Initializers.Count == 0 &&
forStatement.Declaration == null &&
forStatement.Condition == null &&
forStatement.Incrementors.Count == 0)
{
return CreateAdjustSpacesOperation(0, AdjustSpacesOption.ForceSpaces);
}
return AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceBeforeSemicolonsInForStatement);
}

return AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceAfterSemicolonsInForStatement);
}

// For spacing between the parenthesis and the expression inside the control flow expression
if (previousKind == SyntaxKind.OpenParenToken && IsControlFlowLikeKeywordStatementKind(previousParentKind))
{
return AdjustSpacesOperationZeroOrOne(optionSet, CSharpFormattingOptions.SpaceWithinOtherParentheses);
}

if (currentKind == SyntaxKind.CloseParenToken && IsControlFlowLikeKeywordStatementKind(currentParentKind))
Expand Down Expand Up @@ -337,6 +335,12 @@ public override void AddSuppressOperations(List<SuppressOperation> list, SyntaxN
SuppressVariableDeclaration(list, node, optionSet);
}

private bool IsEmptyForStatement(ForStatementSyntax forStatement) =>
forStatement.Initializers.Count == 0
&& forStatement.Declaration == null
&& forStatement.Condition == null
&& forStatement.Incrementors.Count == 0;

private void SuppressVariableDeclaration(List<SuppressOperation> list, SyntaxNode node, OptionSet optionSet)
{
if (node.IsKind(SyntaxKind.FieldDeclaration) || node.IsKind(SyntaxKind.EventDeclaration) ||
Expand Down
98 changes: 96 additions & 2 deletions src/Workspaces/CSharpTest/Formatting/FormattingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6792,6 +6792,32 @@ public async Task SpacingForForStatementInfiniteLoop()
{
var code = @"
class Program
{
void Main()
{
for ( ;;)
{
}
}
}";
var expected = @"
class Program
{
void Main()
{
for (; ; )
{
}
}
}";
await AssertFormatAsync(expected, code);
}

[Fact, Trait(Traits.Feature, Traits.Features.Formatting)]
public async Task SpacingForForStatementInfiniteLoopWithNoSpaces()
{
var code = @"
class Program
{
void Main()
{
Expand All @@ -6810,7 +6836,75 @@ void Main()
}
}
}";
await AssertFormatAsync(expected, code);
var optionSet = new Dictionary<OptionKey, object>
{
{ CSharpFormattingOptions.SpaceAfterSemicolonsInForStatement, false },
};

await AssertFormatAsync(expected, code, changedOptionSet: optionSet);
}

[Fact, Trait(Traits.Feature, Traits.Features.Formatting)]
public async Task SpacingForForStatementInfiniteLoopWithSpacesBefore()
{
var code = @"
class Program
{
void Main()
{
for (;; )
{
}
}
}";
var expected = @"
class Program
{
void Main()
{
for ( ; ;)
{
}
}
}";
var optionSet = new Dictionary<OptionKey, object>
{
{ CSharpFormattingOptions.SpaceBeforeSemicolonsInForStatement, true },
{ CSharpFormattingOptions.SpaceAfterSemicolonsInForStatement, false },
};

await AssertFormatAsync(expected, code, changedOptionSet: optionSet);
}

[Fact, Trait(Traits.Feature, Traits.Features.Formatting)]
public async Task SpacingForForStatementInfiniteLoopWithSpacesBeforeAndAfter()
{
var code = @"
class Program
{
void Main()
{
for (;;)
{
}
}
}";
var expected = @"
class Program
{
void Main()
{
for ( ; ; )
{
}
}
}";
var optionSet = new Dictionary<OptionKey, object>
{
{ CSharpFormattingOptions.SpaceBeforeSemicolonsInForStatement, true },
};

await AssertFormatAsync(expected, code, changedOptionSet: optionSet);
}

[WorkItem(4421, "https://github.com/dotnet/roslyn/issues/4421")]
Expand Down Expand Up @@ -7434,7 +7528,7 @@ await AssertFormatBodyAsync(expected, @"

private Task AssertFormatBodyAsync(string expected, string input)
{
Func<string, string> transform = s =>
Func<string, string> transform = s =>
{
var lines = s.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
for (int i = 0; i < lines.Length; i++)
Expand Down

0 comments on commit 62be375

Please sign in to comment.