Skip to content

Commit db2dd20

Browse files
committed
Parse concurrency syntax when parsing for syntax-tree-only mode.
This allows the syntax parser library and SwiftSyntax to successfully parse code using this experimental feature without requiring an API to pass compiler flags into the parser.
1 parent f86b951 commit db2dd20

File tree

6 files changed

+47
-13
lines changed

6 files changed

+47
-13
lines changed

include/swift/Parse/Parser.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,14 @@ class Parser {
688688
Optional<StringRef>
689689
getStringLiteralIfNotInterpolated(SourceLoc Loc, StringRef DiagText);
690690

691+
/// Returns true to indicate that experimental concurrency syntax should be
692+
/// parsed if the parser is generating only a syntax tree or if the user has
693+
/// passed the `-enable-experimental-concurrency` flag to the frontend.
694+
bool shouldParseExperimentalConcurrency() const {
695+
return Context.LangOpts.EnableExperimentalConcurrency ||
696+
Context.LangOpts.ParseForSyntaxTreeOnly;
697+
}
698+
691699
public:
692700
InFlightDiagnostic diagnose(SourceLoc Loc, Diagnostic Diag) {
693701
if (Diags.isDiagnosticPointsToFirstBadToken(Diag.getID()) &&

lib/Parse/ParseExpr.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ ParserResult<Expr> Parser::parseExprSequence(Diag<> Message,
330330
case tok::identifier: {
331331
// 'async' followed by 'throws' or '->' implies that we have an arrow
332332
// expression.
333-
if (!(Context.LangOpts.EnableExperimentalConcurrency &&
333+
if (!(shouldParseExperimentalConcurrency() &&
334334
Tok.isContextualKeyword("async") &&
335335
peekToken().isAny(tok::arrow, tok::kw_throws)))
336336
goto done;
@@ -392,8 +392,7 @@ ParserResult<Expr> Parser::parseExprSequenceElement(Diag<> message,
392392
SyntaxParsingContext ElementContext(SyntaxContext,
393393
SyntaxContextKind::Expr);
394394

395-
if (Context.LangOpts.EnableExperimentalConcurrency &&
396-
Tok.is(tok::kw___await)) {
395+
if (shouldParseExperimentalConcurrency() && Tok.is(tok::kw___await)) {
397396
SourceLoc awaitLoc = consumeToken(tok::kw___await);
398397
ParserResult<Expr> sub = parseExprUnary(message, isExprBasic);
399398
if (!sub.hasCodeCompletion() && !sub.isNull()) {
@@ -2448,7 +2447,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
24482447
// Consume 'async', 'throws', and 'rethrows', but in any order.
24492448
auto consumeAsyncThrows = [&] {
24502449
bool hadAsync = false;
2451-
if (Context.LangOpts.EnableExperimentalConcurrency &&
2450+
if (shouldParseExperimentalConcurrency() &&
24522451
Tok.isContextualKeyword("async")) {
24532452
consumeToken();
24542453
hadAsync = true;
@@ -2457,7 +2456,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
24572456
if (!consumeIf(tok::kw_throws) && !consumeIf(tok::kw_rethrows))
24582457
return;
24592458

2460-
if (Context.LangOpts.EnableExperimentalConcurrency && !hadAsync &&
2459+
if (shouldParseExperimentalConcurrency() && !hadAsync &&
24612460
Tok.isContextualKeyword("async")) {
24622461
consumeToken();
24632462
}

lib/Parse/ParsePattern.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,7 @@ Parser::parseFunctionSignature(Identifier SimpleName,
824824
void Parser::parseAsyncThrows(
825825
SourceLoc existingArrowLoc, SourceLoc &asyncLoc, SourceLoc &throwsLoc,
826826
bool *rethrows) {
827-
if (Context.LangOpts.EnableExperimentalConcurrency &&
827+
if (shouldParseExperimentalConcurrency() &&
828828
Tok.isContextualKeyword("async")) {
829829
asyncLoc = consumeToken();
830830

@@ -857,7 +857,7 @@ void Parser::parseAsyncThrows(
857857
.fixItInsert(existingArrowLoc, (keyword + " ").str());
858858
}
859859

860-
if (Context.LangOpts.EnableExperimentalConcurrency &&
860+
if (shouldParseExperimentalConcurrency() &&
861861
Tok.isContextualKeyword("async")) {
862862
asyncLoc = consumeToken();
863863

lib/Parse/ParseType.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ ParserResult<TypeRepr> Parser::parseType(Diag<> MessageID,
412412

413413
// Parse an async specifier.
414414
SourceLoc asyncLoc;
415-
if (Context.LangOpts.EnableExperimentalConcurrency &&
415+
if (shouldParseExperimentalConcurrency() &&
416416
Tok.isContextualKeyword("async")) {
417417
asyncLoc = consumeToken();
418418
}
@@ -423,7 +423,7 @@ ParserResult<TypeRepr> Parser::parseType(Diag<> MessageID,
423423
SourceLoc throwsLoc;
424424
if (Tok.isAny(tok::kw_throws, tok::kw_rethrows, tok::kw_throw, tok::kw_try) &&
425425
(peekToken().is(tok::arrow) ||
426-
(Context.LangOpts.EnableExperimentalConcurrency &&
426+
(shouldParseExperimentalConcurrency() &&
427427
peekToken().isContextualKeyword("async")))) {
428428
if (Tok.isAny(tok::kw_rethrows, tok::kw_throw, tok::kw_try)) {
429429
// 'rethrows' is only allowed on function declarations for now.
@@ -436,7 +436,7 @@ ParserResult<TypeRepr> Parser::parseType(Diag<> MessageID,
436436
throwsLoc = consumeToken();
437437

438438
// 'async' must preceed 'throws'; accept this but complain.
439-
if (Context.LangOpts.EnableExperimentalConcurrency &&
439+
if (shouldParseExperimentalConcurrency() &&
440440
Tok.isContextualKeyword("async")) {
441441
asyncLoc = consumeToken();
442442

@@ -1589,7 +1589,7 @@ bool Parser::canParseType() {
15891589
}
15901590

15911591
// Handle type-function if we have an 'async'.
1592-
if (Context.LangOpts.EnableExperimentalConcurrency &&
1592+
if (shouldParseExperimentalConcurrency() &&
15931593
Tok.isContextualKeyword("async")) {
15941594
consumeToken();
15951595

@@ -1605,7 +1605,7 @@ bool Parser::canParseType() {
16051605

16061606
// Allow 'async' here even though it is ill-formed, so we can provide
16071607
// a better error.
1608-
if (Context.LangOpts.EnableExperimentalConcurrency &&
1608+
if (shouldParseExperimentalConcurrency() &&
16091609
Tok.isContextualKeyword("async"))
16101610
consumeToken();
16111611

test/Syntax/Parser/async.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Verify that async parses correctly via the parser lib even without the
2+
// experimental flag being set in LangOpts.
3+
//
4+
// REQUIRES: syntax_parser_lib
5+
// RUN: %swift-syntax-parser-test %s -dump-diags 2>&1 | %FileCheck %s
6+
7+
func asyncGlobal1() async { }
8+
func asyncGlobal2() async throws { }
9+
10+
typealias AsyncFunc1 = () async -> ()
11+
typealias AsyncFunc2 = () async throws -> ()
12+
13+
func testTypeExprs() {
14+
let _ = [() async -> ()]()
15+
let _ = [() async throws -> ()]()
16+
}
17+
18+
func testAwaitOperator() async {
19+
let _ = __await asyncGlobal1()
20+
}
21+
22+
func testAsyncClosure() {
23+
let _ = { () async in 5 }
24+
let _ = { () throws in 5 }
25+
let _ = { () async throws in 5 }
26+
}
27+
28+
// CHECK: 0 error(s) 0 warnings(s) 0 note(s)

tools/swift-syntax-test/swift-syntax-test.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,6 @@ int parseFile(
610610
Invocation.getLangOptions().VerifySyntaxTree = options::VerifySyntaxTree;
611611
Invocation.getLangOptions().RequestEvaluatorGraphVizPath = options::GraphVisPath;
612612
Invocation.getLangOptions().DisablePoundIfEvaluation = true;
613-
Invocation.getLangOptions().EnableExperimentalConcurrency = true;
614613

615614
Invocation.getFrontendOptions().InputsAndOutputs.addInputFile(InputFileName);
616615

0 commit comments

Comments
 (0)