Skip to content

Commit e8c8087

Browse files
authored
Merge pull request #16158 from nkcsgexi/synthesize-node
libSyntax: add a mechanism to synthesize syntax nodes in SyntaxParsingContext.
2 parents 43eb3f4 + a1a6c19 commit e8c8087

File tree

5 files changed

+55
-2
lines changed

5 files changed

+55
-2
lines changed

include/swift/Parse/SyntaxParsingContext.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,14 @@ class alignas(1 << SyntaxAlignInBits) SyntaxParsingContext {
255255
/// the syntax tree before closing the root context.
256256
void finalizeRoot();
257257

258+
/// Make a missing node corresponding to the given token kind and text, and
259+
/// push this node into the context. The synthesized node can help
260+
/// the creation of valid syntax nodes.
261+
void synthesize(tok Kind, StringRef Text = "");
262+
263+
/// Make a missing node corresponding to the given node kind, and
264+
/// push this node into the context.
265+
void synthesize(SyntaxKind Kind);
258266
};
259267

260268
} // namespace swift

lib/Parse/ParseStmt.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,8 +637,11 @@ ParserResult<BraceStmt> Parser::parseBraceItemList(Diag<> ID) {
637637

638638
ParserStatus Status = parseBraceItems(Entries, BraceItemListKind::Brace,
639639
BraceItemListKind::Brace);
640-
parseMatchingToken(tok::r_brace, RBLoc,
641-
diag::expected_rbrace_in_brace_stmt, LBLoc);
640+
if (parseMatchingToken(tok::r_brace, RBLoc,
641+
diag::expected_rbrace_in_brace_stmt, LBLoc)) {
642+
// Synthesize a r-brace if the source doesn't have any.
643+
LocalContext.synthesize(tok::r_brace);
644+
}
642645

643646
return makeParserResult(Status,
644647
BraceStmt::create(Context, LBLoc, Entries, RBLoc));

lib/Parse/SyntaxParsingContext.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,20 @@ void SyntaxParsingContext::finalizeRoot() {
318318
getRootData().Storage.clear();
319319
}
320320

321+
void SyntaxParsingContext::synthesize(tok Kind, StringRef Text) {
322+
if (!Enabled)
323+
return;
324+
if (Text.empty())
325+
Text = getTokenText(Kind);
326+
Storage.push_back(RawSyntax::missing(Kind, Text));
327+
}
328+
329+
void SyntaxParsingContext::synthesize(SyntaxKind Kind) {
330+
if (!Enabled)
331+
return;
332+
Storage.push_back(RawSyntax::missing(Kind));
333+
}
334+
321335
SyntaxParsingContext::~SyntaxParsingContext() {
322336
assert(isTopOfContextStack() && "destructed in wrong order");
323337

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<FunctionDecl>// RUN: rm -rf %t
2+
// RUN: %swift-syntax-test -input-source-filename %s -parse-gen > %t
3+
// RUN: diff -u %s %t
4+
// RUN: %swift-syntax-test -input-source-filename %s -parse-gen -print-node-kind > %t.withkinds
5+
// RUN: diff -u %S/Outputs/round_trip_invalid.swift.withkinds %t.withkinds
6+
// RUN: %swift-syntax-test -input-source-filename %s -eof > %t
7+
// RUN: diff -u %s %t
8+
// RUN: %swift-syntax-test -serialize-raw-tree -input-source-filename %s > %t.dump
9+
// RUN: %swift-syntax-test -deserialize-raw-tree -input-source-filename %t.dump -output-filename %t
10+
// RUN: diff -u %s %t
11+
12+
// Function body without closing brace token.
13+
func foo<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature><CodeBlock>{<VariableDecl>
14+
var <PatternBinding><IdentifierPattern>a </IdentifierPattern><InitializerClause>= <IntegerLiteralExpr>2</IntegerLiteralExpr></InitializerClause></PatternBinding></VariableDecl></CodeBlock></FunctionDecl>

test/Syntax/round_trip_invalid.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: rm -rf %t
2+
// RUN: %swift-syntax-test -input-source-filename %s -parse-gen > %t
3+
// RUN: diff -u %s %t
4+
// RUN: %swift-syntax-test -input-source-filename %s -parse-gen -print-node-kind > %t.withkinds
5+
// RUN: diff -u %S/Outputs/round_trip_invalid.swift.withkinds %t.withkinds
6+
// RUN: %swift-syntax-test -input-source-filename %s -eof > %t
7+
// RUN: diff -u %s %t
8+
// RUN: %swift-syntax-test -serialize-raw-tree -input-source-filename %s > %t.dump
9+
// RUN: %swift-syntax-test -deserialize-raw-tree -input-source-filename %t.dump -output-filename %t
10+
// RUN: diff -u %s %t
11+
12+
// Function body without closing brace token.
13+
func foo() {
14+
var a = 2

0 commit comments

Comments
 (0)