Skip to content

Commit 646aae1

Browse files
committed
Parser support for do..catch blocks with typed throws
1 parent 26bee7f commit 646aae1

File tree

4 files changed

+44
-5
lines changed

4 files changed

+44
-5
lines changed

Sources/SwiftParser/Specifiers.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ extension TokenConsumer {
583583

584584
extension Parser {
585585
/// Parse a throws clause after we've already parsed the 'throws' keyword to introduce it.
586-
private mutating func parseThrowsClause(after throwsKeyword: RawTokenSyntax) -> RawThrowsClauseSyntax {
586+
mutating func parseThrowsClause(after throwsKeyword: RawTokenSyntax) -> RawThrowsClauseSyntax {
587587
guard self.at(.leftParen) && experimentalFeatures.contains(.typedThrows) else {
588588
return RawThrowsClauseSyntax(
589589
throwsSpecifier: throwsKeyword,

Sources/SwiftParser/Statements.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,15 @@ extension Parser {
389389
/// Parse a do statement.
390390
mutating func parseDoStatement(doHandle: RecoveryConsumptionHandle) -> RawDoStmtSyntax {
391391
let (unexpectedBeforeDoKeyword, doKeyword) = self.eat(doHandle)
392+
393+
// Parse the optional throws clause.
394+
let throwsClause: RawThrowsClauseSyntax?
395+
if let throwsSpecifier = self.consume(if: .keyword(.throws)) {
396+
throwsClause = parseThrowsClause(after: throwsSpecifier)
397+
} else {
398+
throwsClause = nil
399+
}
400+
392401
let body = self.parseCodeBlock(introducer: doKeyword)
393402

394403
// If the next token is 'catch', this is a 'do'/'catch' statement.
@@ -402,6 +411,7 @@ extension Parser {
402411
return RawDoStmtSyntax(
403412
unexpectedBeforeDoKeyword,
404413
doKeyword: doKeyword,
414+
throwsClause: throwsClause,
405415
body: body,
406416
catchClauses: RawCatchClauseListSyntax(elements: elements, arena: self.arena),
407417
arena: self.arena

Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,13 +282,13 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
282282
}
283283
}
284284

285-
if let throwsSpecifier = node.throwsSpecifier {
285+
if let throwsClause = node.throwsClause {
286286
exchangeTokens(
287287
unexpected: node.unexpectedAfterThrowsClause,
288288
unexpectedTokenCondition: { AsyncEffectSpecifier(token: $0) != nil },
289289
correctTokens: [node.asyncSpecifier],
290-
message: { AsyncMustPrecedeThrows(asyncKeywords: $0, throwsKeyword: throwsSpecifier) },
291-
moveFixIt: { MoveTokensInFrontOfFixIt(movedTokens: $0, inFrontOf: throwsSpecifier.tokenKind) },
290+
message: { AsyncMustPrecedeThrows(asyncKeywords: $0, throwsKeyword: throwsClause.throwsSpecifier) },
291+
moveFixIt: { MoveTokensInFrontOfFixIt(movedTokens: $0, inFrontOf: throwsClause.throwsSpecifier.tokenKind) },
292292
removeRedundantFixIt: { RemoveRedundantFixIt(removeTokens: $0) }
293293
)
294294
}

Tests/SwiftParserTest/StatementTests.swift

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
@_spi(RawSyntax) import SwiftParser
13+
@_spi(RawSyntax) @_spi(ExperimentalLanguageFeatures) import SwiftParser
1414
@_spi(RawSyntax) import SwiftSyntax
1515
import XCTest
1616

@@ -895,4 +895,33 @@ final class StatementTests: ParserTestCase {
895895
"""
896896
)
897897
}
898+
899+
func testTypedThrows() {
900+
assertParse(
901+
"""
902+
do throws(any Error) {
903+
throw myError
904+
}
905+
""",
906+
experimentalFeatures: [.typedThrows]
907+
)
908+
909+
assertParse(
910+
"""
911+
do throws(MyError) {
912+
throw myError
913+
}
914+
""",
915+
experimentalFeatures: [.typedThrows]
916+
)
917+
918+
assertParse(
919+
"""
920+
do throws {
921+
throw myError
922+
}
923+
""",
924+
experimentalFeatures: [.typedThrows]
925+
)
926+
}
898927
}

0 commit comments

Comments
 (0)