Skip to content

Commit 53cb76e

Browse files
Increase the amount of recursive parsing calls for statements+blocks.
1 parent 5fb71c0 commit 53cb76e

File tree

1 file changed

+51
-53
lines changed

1 file changed

+51
-53
lines changed

src/Compilers/CSharp/Portable/Parser/LanguageParser.cs

Lines changed: 51 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2450,7 +2450,7 @@ private void ParseBlockAndExpressionBodiesWithSemicolon(
24502450

24512451
if (this.CurrentToken.Kind == SyntaxKind.OpenBraceToken)
24522452
{
2453-
blockBody = this.ParseBlock(isMethodBody: true);
2453+
blockBody = this.ParseMethodOrAccessorBodyBlock(isAccessorBody: false);
24542454
}
24552455

24562456
if (this.CurrentToken.Kind == SyntaxKind.EqualsGreaterThanToken)
@@ -2477,25 +2477,6 @@ private void ParseBlockAndExpressionBodiesWithSemicolon(
24772477
}
24782478
}
24792479

2480-
private void ParseBodyOrSemicolon(out BlockSyntax body, out SyntaxToken semicolon)
2481-
{
2482-
if (this.CurrentToken.Kind == SyntaxKind.OpenBraceToken)
2483-
{
2484-
body = this.ParseBlock(isMethodBody: true);
2485-
2486-
semicolon = null;
2487-
if (this.CurrentToken.Kind == SyntaxKind.SemicolonToken)
2488-
{
2489-
semicolon = this.EatTokenWithPrejudice(ErrorCode.ERR_UnexpectedSemicolon);
2490-
}
2491-
}
2492-
else
2493-
{
2494-
semicolon = this.EatToken(SyntaxKind.SemicolonToken);
2495-
body = null;
2496-
}
2497-
}
2498-
24992480
private bool IsEndOfTypeParameterList()
25002481
{
25012482
if (this.CurrentToken.Kind == SyntaxKind.OpenParenToken)
@@ -3305,7 +3286,7 @@ private AccessorDeclarationSyntax ParseAccessorDeclaration(bool isEvent)
33053286
{
33063287
if (!IsTerminator())
33073288
{
3308-
blockBody = this.ParseBlock(isMethodBody: true, isAccessorBody: true);
3289+
blockBody = this.ParseMethodOrAccessorBodyBlock(isAccessorBody: true);
33093290
}
33103291
else
33113292
{
@@ -6941,19 +6922,18 @@ private bool IsPossibleNewExpression()
69416922
return null;
69426923
}
69436924

6944-
// If "isMethodBody" is true, then this is the immediate body of a method/accessor.
6945-
// In this case, we create a many-child list if the body is not a small single statement.
6946-
// This then allows a "with many weak children" red node when the red node is created.
6947-
// If "isAccessorBody" is true, then we produce a special diagnostic if the open brace is
6948-
// missing. Also, "isMethodBody" must be true.
6949-
private BlockSyntax ParseBlock(bool isMethodBody = false, bool isAccessorBody = false)
6925+
/// <summary>
6926+
/// Used to parse the block-body for a method or accessor. For blocks that appear *inside*
6927+
/// method bodies, call <see cref="ParseBlock"/>.
6928+
/// </summary>
6929+
/// <param name="isAccessorBody">If is true, then we produce a special diagnostic if the
6930+
/// open brace is missing.</param>
6931+
private BlockSyntax ParseMethodOrAccessorBodyBlock(bool isAccessorBody)
69506932
{
6951-
// Check again for incremental re-use, since ParseBlock is called from a bunch of places
6952-
// other than ParseStatementCore()
6933+
// Check again for incremental re-use. This way if a method signature is edited we can
6934+
// still quickly re-sync on the body.
69536935
if (this.IsIncrementalAndFactoryContextMatches && this.CurrentNodeKind == SyntaxKind.Block)
6954-
{
69556936
return (BlockSyntax)this.EatNode();
6956-
}
69576937

69586938
// There's a special error code for a missing token after an accessor keyword
69596939
var openBrace = isAccessorBody && this.CurrentToken.Kind != SyntaxKind.OpenBraceToken
@@ -6965,30 +6945,48 @@ private BlockSyntax ParseBlock(bool isMethodBody = false, bool isAccessorBody =
69656945
: this.EatToken(SyntaxKind.OpenBraceToken);
69666946

69676947
var statements = _pool.Allocate<StatementSyntax>();
6968-
try
6969-
{
6970-
CSharpSyntaxNode tmp = openBrace;
6971-
this.ParseStatements(ref tmp, statements, stopOnSwitchSections: false);
6972-
openBrace = (SyntaxToken)tmp;
6973-
var closeBrace = this.EatToken(SyntaxKind.CloseBraceToken);
69746948

6975-
SyntaxList<StatementSyntax> statementList;
6976-
if (isMethodBody && IsLargeEnoughNonEmptyStatementList(statements))
6977-
{
6978-
// Force creation a many-children list, even if only 1, 2, or 3 elements in the statement list.
6979-
statementList = new SyntaxList<StatementSyntax>(SyntaxList.List(((SyntaxListBuilder)statements).ToArray()));
6980-
}
6981-
else
6982-
{
6983-
statementList = statements;
6984-
}
6949+
CSharpSyntaxNode tmp = openBrace;
6950+
this.ParseStatements(ref tmp, statements, stopOnSwitchSections: false);
69856951

6986-
return _syntaxFactory.Block(openBrace, statementList, closeBrace);
6987-
}
6988-
finally
6989-
{
6990-
_pool.Free(statements);
6991-
}
6952+
var block = _syntaxFactory.Block(
6953+
(SyntaxToken)tmp,
6954+
// Force creation a many-children list, even if only 1, 2, or 3 elements in the statement list.
6955+
IsLargeEnoughNonEmptyStatementList(statements)
6956+
? new SyntaxList<StatementSyntax>(SyntaxList.List(((SyntaxListBuilder)statements).ToArray()))
6957+
: statements,
6958+
this.EatToken(SyntaxKind.CloseBraceToken));
6959+
6960+
_pool.Free(statements);
6961+
return block;
6962+
}
6963+
6964+
/// <summary>
6965+
/// Used to parse normal blocks that appear inside method bodies. For the top level block
6966+
/// of a method/accessor use <see cref="ParseMethodOrAccessorBodyBlock"/>.
6967+
/// </summary>
6968+
private BlockSyntax ParseBlock()
6969+
{
6970+
// Check again for incremental re-use, since ParseBlock is called from a bunch of places
6971+
// other than ParseStatementCore()
6972+
if (this.IsIncrementalAndFactoryContextMatches && this.CurrentNodeKind == SyntaxKind.Block)
6973+
return (BlockSyntax)this.EatNode();
6974+
6975+
// There's a special error code for a missing token after an accessor keyword
6976+
var openBrace = this.EatToken(SyntaxKind.OpenBraceToken);
6977+
6978+
var statements = _pool.Allocate<StatementSyntax>();
6979+
6980+
CSharpSyntaxNode tmp = openBrace;
6981+
this.ParseStatements(ref tmp, statements, stopOnSwitchSections: false);
6982+
6983+
var block = _syntaxFactory.Block(
6984+
(SyntaxToken)tmp,
6985+
statements,
6986+
this.EatToken(SyntaxKind.CloseBraceToken));
6987+
6988+
_pool.Free(statements);
6989+
return block;
69926990
}
69936991

69946992
// Is this statement list non-empty, and large enough to make using weak children beneficial?

0 commit comments

Comments
 (0)