Skip to content

Commit 046a603

Browse files
authored
Merge pull request #2381 from DougGregor/do-throws
2 parents 5cec9bd + 2d348b2 commit 046a603

File tree

11 files changed

+137
-38
lines changed

11 files changed

+137
-38
lines changed

CodeGeneration/Sources/SyntaxSupport/StmtNodes.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,13 @@ public let STMT_NODES: [Node] = [
216216
name: "doKeyword",
217217
kind: .token(choices: [.keyword(.do)])
218218
),
219+
Child(
220+
name: "throwsClause",
221+
kind: .node(kind: .throwsClause),
222+
experimentalFeature: .typedThrows,
223+
documentation: "The clause specifying the type of errors thrown from the 'do' block.",
224+
isOptional: true
225+
),
219226
Child(
220227
name: "body",
221228
kind: .node(kind: .codeBlock),

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
}

Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,8 +1029,12 @@ public func childName(_ keyPath: AnyKeyPath) -> String? {
10291029
return "unexpectedBeforeDoKeyword"
10301030
case \DoStmtSyntax.doKeyword:
10311031
return "doKeyword"
1032-
case \DoStmtSyntax.unexpectedBetweenDoKeywordAndBody:
1033-
return "unexpectedBetweenDoKeywordAndBody"
1032+
case \DoStmtSyntax.unexpectedBetweenDoKeywordAndThrowsClause:
1033+
return "unexpectedBetweenDoKeywordAndThrowsClause"
1034+
case \DoStmtSyntax.throwsClause:
1035+
return "throwsClause"
1036+
case \DoStmtSyntax.unexpectedBetweenThrowsClauseAndBody:
1037+
return "unexpectedBetweenThrowsClauseAndBody"
10341038
case \DoStmtSyntax.body:
10351039
return "body"
10361040
case \DoStmtSyntax.unexpectedBetweenBodyAndCatchClauses:

Sources/SwiftSyntax/generated/raw/RawSyntaxNodesD.swift

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2025,23 +2025,27 @@ public struct RawDoStmtSyntax: RawStmtSyntaxNodeProtocol {
20252025
public init(
20262026
_ unexpectedBeforeDoKeyword: RawUnexpectedNodesSyntax? = nil,
20272027
doKeyword: RawTokenSyntax,
2028-
_ unexpectedBetweenDoKeywordAndBody: RawUnexpectedNodesSyntax? = nil,
2028+
_ unexpectedBetweenDoKeywordAndThrowsClause: RawUnexpectedNodesSyntax? = nil,
2029+
throwsClause: RawThrowsClauseSyntax?,
2030+
_ unexpectedBetweenThrowsClauseAndBody: RawUnexpectedNodesSyntax? = nil,
20292031
body: RawCodeBlockSyntax,
20302032
_ unexpectedBetweenBodyAndCatchClauses: RawUnexpectedNodesSyntax? = nil,
20312033
catchClauses: RawCatchClauseListSyntax,
20322034
_ unexpectedAfterCatchClauses: RawUnexpectedNodesSyntax? = nil,
20332035
arena: __shared SyntaxArena
20342036
) {
20352037
let raw = RawSyntax.makeLayout(
2036-
kind: .doStmt, uninitializedCount: 7, arena: arena) { layout in
2038+
kind: .doStmt, uninitializedCount: 9, arena: arena) { layout in
20372039
layout.initialize(repeating: nil)
20382040
layout[0] = unexpectedBeforeDoKeyword?.raw
20392041
layout[1] = doKeyword.raw
2040-
layout[2] = unexpectedBetweenDoKeywordAndBody?.raw
2041-
layout[3] = body.raw
2042-
layout[4] = unexpectedBetweenBodyAndCatchClauses?.raw
2043-
layout[5] = catchClauses.raw
2044-
layout[6] = unexpectedAfterCatchClauses?.raw
2042+
layout[2] = unexpectedBetweenDoKeywordAndThrowsClause?.raw
2043+
layout[3] = throwsClause?.raw
2044+
layout[4] = unexpectedBetweenThrowsClauseAndBody?.raw
2045+
layout[5] = body.raw
2046+
layout[6] = unexpectedBetweenBodyAndCatchClauses?.raw
2047+
layout[7] = catchClauses.raw
2048+
layout[8] = unexpectedAfterCatchClauses?.raw
20452049
}
20462050
self.init(unchecked: raw)
20472051
}
@@ -2054,24 +2058,32 @@ public struct RawDoStmtSyntax: RawStmtSyntaxNodeProtocol {
20542058
layoutView.children[1].map(RawTokenSyntax.init(raw:))!
20552059
}
20562060

2057-
public var unexpectedBetweenDoKeywordAndBody: RawUnexpectedNodesSyntax? {
2061+
public var unexpectedBetweenDoKeywordAndThrowsClause: RawUnexpectedNodesSyntax? {
20582062
layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:))
20592063
}
20602064

2065+
public var throwsClause: RawThrowsClauseSyntax? {
2066+
layoutView.children[3].map(RawThrowsClauseSyntax.init(raw:))
2067+
}
2068+
2069+
public var unexpectedBetweenThrowsClauseAndBody: RawUnexpectedNodesSyntax? {
2070+
layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:))
2071+
}
2072+
20612073
public var body: RawCodeBlockSyntax {
2062-
layoutView.children[3].map(RawCodeBlockSyntax.init(raw:))!
2074+
layoutView.children[5].map(RawCodeBlockSyntax.init(raw:))!
20632075
}
20642076

20652077
public var unexpectedBetweenBodyAndCatchClauses: RawUnexpectedNodesSyntax? {
2066-
layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:))
2078+
layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:))
20672079
}
20682080

20692081
public var catchClauses: RawCatchClauseListSyntax {
2070-
layoutView.children[5].map(RawCatchClauseListSyntax.init(raw:))!
2082+
layoutView.children[7].map(RawCatchClauseListSyntax.init(raw:))!
20712083
}
20722084

20732085
public var unexpectedAfterCatchClauses: RawUnexpectedNodesSyntax? {
2074-
layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:))
2086+
layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:))
20752087
}
20762088
}
20772089

Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,14 +1002,16 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
10021002
assertNoError(kind, 5, verify(layout[5], as: RawCatchClauseListSyntax.self))
10031003
assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self))
10041004
case .doStmt:
1005-
assert(layout.count == 7)
1005+
assert(layout.count == 9)
10061006
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
10071007
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.keyword("do")]))
10081008
assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self))
1009-
assertNoError(kind, 3, verify(layout[3], as: RawCodeBlockSyntax.self))
1009+
assertNoError(kind, 3, verify(layout[3], as: RawThrowsClauseSyntax?.self))
10101010
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
1011-
assertNoError(kind, 5, verify(layout[5], as: RawCatchClauseListSyntax.self))
1011+
assertNoError(kind, 5, verify(layout[5], as: RawCodeBlockSyntax.self))
10121012
assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self))
1013+
assertNoError(kind, 7, verify(layout[7], as: RawCatchClauseListSyntax.self))
1014+
assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self))
10131015
case .documentationAttributeArgumentList:
10141016
for (index, element) in layout.enumerated() {
10151017
assertNoError(kind, index, verify(element, as: RawDocumentationAttributeArgumentSyntax.self))

Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesD.swift

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3415,6 +3415,7 @@ public struct DoExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _LeafExprSyntaxN
34153415
/// ### Children
34163416
///
34173417
/// - `doKeyword`: `do`
3418+
/// - `throwsClause`: ``ThrowsClauseSyntax``?
34183419
/// - `body`: ``CodeBlockSyntax``
34193420
/// - `catchClauses`: ``CatchClauseListSyntax``
34203421
public struct DoStmtSyntax: StmtSyntaxProtocol, SyntaxHashable, _LeafStmtSyntaxNodeProtocol {
@@ -3429,12 +3430,15 @@ public struct DoStmtSyntax: StmtSyntaxProtocol, SyntaxHashable, _LeafStmtSyntaxN
34293430

34303431
/// - Parameters:
34313432
/// - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored.
3433+
/// - throwsClause: The clause specifying the type of errors thrown from the 'do' block.
34323434
/// - trailingTrivia: Trivia to be appended to the trailing trivia of the node’s last token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored.
34333435
public init(
34343436
leadingTrivia: Trivia? = nil,
34353437
_ unexpectedBeforeDoKeyword: UnexpectedNodesSyntax? = nil,
34363438
doKeyword: TokenSyntax = .keyword(.do),
3437-
_ unexpectedBetweenDoKeywordAndBody: UnexpectedNodesSyntax? = nil,
3439+
_ unexpectedBetweenDoKeywordAndThrowsClause: UnexpectedNodesSyntax? = nil,
3440+
throwsClause: ThrowsClauseSyntax? = nil,
3441+
_ unexpectedBetweenThrowsClauseAndBody: UnexpectedNodesSyntax? = nil,
34383442
body: CodeBlockSyntax,
34393443
_ unexpectedBetweenBodyAndCatchClauses: UnexpectedNodesSyntax? = nil,
34403444
catchClauses: CatchClauseListSyntax = [],
@@ -3447,7 +3451,9 @@ public struct DoStmtSyntax: StmtSyntaxProtocol, SyntaxHashable, _LeafStmtSyntaxN
34473451
self = withExtendedLifetime((SyntaxArena(), (
34483452
unexpectedBeforeDoKeyword,
34493453
doKeyword,
3450-
unexpectedBetweenDoKeywordAndBody,
3454+
unexpectedBetweenDoKeywordAndThrowsClause,
3455+
throwsClause,
3456+
unexpectedBetweenThrowsClauseAndBody,
34513457
body,
34523458
unexpectedBetweenBodyAndCatchClauses,
34533459
catchClauses,
@@ -3456,7 +3462,9 @@ public struct DoStmtSyntax: StmtSyntaxProtocol, SyntaxHashable, _LeafStmtSyntaxN
34563462
let layout: [RawSyntax?] = [
34573463
unexpectedBeforeDoKeyword?.raw,
34583464
doKeyword.raw,
3459-
unexpectedBetweenDoKeywordAndBody?.raw,
3465+
unexpectedBetweenDoKeywordAndThrowsClause?.raw,
3466+
throwsClause?.raw,
3467+
unexpectedBetweenThrowsClauseAndBody?.raw,
34603468
body.raw,
34613469
unexpectedBetweenBodyAndCatchClauses?.raw,
34623470
catchClauses.raw,
@@ -3495,7 +3503,7 @@ public struct DoStmtSyntax: StmtSyntaxProtocol, SyntaxHashable, _LeafStmtSyntaxN
34953503
}
34963504
}
34973505

3498-
public var unexpectedBetweenDoKeywordAndBody: UnexpectedNodesSyntax? {
3506+
public var unexpectedBetweenDoKeywordAndThrowsClause: UnexpectedNodesSyntax? {
34993507
get {
35003508
return Syntax(self).child(at: 2)?.cast(UnexpectedNodesSyntax.self)
35013509
}
@@ -3504,16 +3512,18 @@ public struct DoStmtSyntax: StmtSyntaxProtocol, SyntaxHashable, _LeafStmtSyntaxN
35043512
}
35053513
}
35063514

3507-
public var body: CodeBlockSyntax {
3515+
/// The clause specifying the type of errors thrown from the 'do' block.
3516+
@_spi(ExperimentalLanguageFeatures)
3517+
public var throwsClause: ThrowsClauseSyntax? {
35083518
get {
3509-
return Syntax(self).child(at: 3)!.cast(CodeBlockSyntax.self)
3519+
return Syntax(self).child(at: 3)?.cast(ThrowsClauseSyntax.self)
35103520
}
35113521
set(value) {
35123522
self = Syntax(self).replacingChild(at: 3, with: Syntax(value), arena: SyntaxArena()).cast(DoStmtSyntax.self)
35133523
}
35143524
}
35153525

3516-
public var unexpectedBetweenBodyAndCatchClauses: UnexpectedNodesSyntax? {
3526+
public var unexpectedBetweenThrowsClauseAndBody: UnexpectedNodesSyntax? {
35173527
get {
35183528
return Syntax(self).child(at: 4)?.cast(UnexpectedNodesSyntax.self)
35193529
}
@@ -3522,15 +3532,33 @@ public struct DoStmtSyntax: StmtSyntaxProtocol, SyntaxHashable, _LeafStmtSyntaxN
35223532
}
35233533
}
35243534

3525-
public var catchClauses: CatchClauseListSyntax {
3535+
public var body: CodeBlockSyntax {
35263536
get {
3527-
return Syntax(self).child(at: 5)!.cast(CatchClauseListSyntax.self)
3537+
return Syntax(self).child(at: 5)!.cast(CodeBlockSyntax.self)
35283538
}
35293539
set(value) {
35303540
self = Syntax(self).replacingChild(at: 5, with: Syntax(value), arena: SyntaxArena()).cast(DoStmtSyntax.self)
35313541
}
35323542
}
35333543

3544+
public var unexpectedBetweenBodyAndCatchClauses: UnexpectedNodesSyntax? {
3545+
get {
3546+
return Syntax(self).child(at: 6)?.cast(UnexpectedNodesSyntax.self)
3547+
}
3548+
set(value) {
3549+
self = Syntax(self).replacingChild(at: 6, with: Syntax(value), arena: SyntaxArena()).cast(DoStmtSyntax.self)
3550+
}
3551+
}
3552+
3553+
public var catchClauses: CatchClauseListSyntax {
3554+
get {
3555+
return Syntax(self).child(at: 7)!.cast(CatchClauseListSyntax.self)
3556+
}
3557+
set(value) {
3558+
self = Syntax(self).replacingChild(at: 7, with: Syntax(value), arena: SyntaxArena()).cast(DoStmtSyntax.self)
3559+
}
3560+
}
3561+
35343562
/// Adds the provided `element` to the node's `catchClauses`
35353563
/// collection.
35363564
///
@@ -3542,15 +3570,15 @@ public struct DoStmtSyntax: StmtSyntaxProtocol, SyntaxHashable, _LeafStmtSyntaxN
35423570
public func addCatchClause(_ element: CatchClauseSyntax) -> DoStmtSyntax {
35433571
var collection: RawSyntax
35443572
let arena = SyntaxArena()
3545-
if let col = raw.layoutView!.children[5] {
3573+
if let col = raw.layoutView!.children[7] {
35463574
collection = col.layoutView!.appending(element.raw, arena: arena)
35473575
} else {
35483576
collection = RawSyntax.makeLayout(kind: SyntaxKind.catchClauseList,
35493577
from: [element.raw], arena: arena)
35503578
}
35513579
return Syntax(self)
35523580
.replacingChild(
3553-
at: 5,
3581+
at: 7,
35543582
with: collection,
35553583
rawNodeArena: arena,
35563584
allocationArena: arena
@@ -3560,18 +3588,20 @@ public struct DoStmtSyntax: StmtSyntaxProtocol, SyntaxHashable, _LeafStmtSyntaxN
35603588

35613589
public var unexpectedAfterCatchClauses: UnexpectedNodesSyntax? {
35623590
get {
3563-
return Syntax(self).child(at: 6)?.cast(UnexpectedNodesSyntax.self)
3591+
return Syntax(self).child(at: 8)?.cast(UnexpectedNodesSyntax.self)
35643592
}
35653593
set(value) {
3566-
self = Syntax(self).replacingChild(at: 6, with: Syntax(value), arena: SyntaxArena()).cast(DoStmtSyntax.self)
3594+
self = Syntax(self).replacingChild(at: 8, with: Syntax(value), arena: SyntaxArena()).cast(DoStmtSyntax.self)
35673595
}
35683596
}
35693597

35703598
public static var structure: SyntaxNodeStructure {
35713599
return .layout([
35723600
\Self.unexpectedBeforeDoKeyword,
35733601
\Self.doKeyword,
3574-
\Self.unexpectedBetweenDoKeywordAndBody,
3602+
\Self.unexpectedBetweenDoKeywordAndThrowsClause,
3603+
\Self.throwsClause,
3604+
\Self.unexpectedBetweenThrowsClauseAndBody,
35753605
\Self.body,
35763606
\Self.unexpectedBetweenBodyAndCatchClauses,
35773607
\Self.catchClauses,

Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesTUVWXYZ.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ public struct ThrowStmtSyntax: StmtSyntaxProtocol, SyntaxHashable, _LeafStmtSynt
480480
/// ### Contained in
481481
///
482482
/// - ``AccessorEffectSpecifiersSyntax``.``AccessorEffectSpecifiersSyntax/throwsClause``
483+
/// - ``DoStmtSyntax``.``DoStmtSyntax/throwsClause``
483484
/// - ``FunctionEffectSpecifiersSyntax``.``FunctionEffectSpecifiersSyntax/throwsClause``
484485
/// - ``TypeEffectSpecifiersSyntax``.``TypeEffectSpecifiersSyntax/throwsClause``
485486
public struct ThrowsClauseSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxNodeProtocol {

Sources/SwiftSyntaxBuilder/generated/BuildableNodes.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,9 @@ extension DoStmtSyntax {
381381
leadingTrivia: Trivia? = nil,
382382
unexpectedBeforeDoKeyword: UnexpectedNodesSyntax? = nil,
383383
doKeyword: TokenSyntax = .keyword(.do),
384-
unexpectedBetweenDoKeywordAndBody: UnexpectedNodesSyntax? = nil,
384+
unexpectedBetweenDoKeywordAndThrowsClause: UnexpectedNodesSyntax? = nil,
385+
throwsClause: ThrowsClauseSyntax? = nil,
386+
unexpectedBetweenThrowsClauseAndBody: UnexpectedNodesSyntax? = nil,
385387
unexpectedBetweenBodyAndCatchClauses: UnexpectedNodesSyntax? = nil,
386388
catchClauses: CatchClauseListSyntax = [],
387389
unexpectedAfterCatchClauses: UnexpectedNodesSyntax? = nil,
@@ -392,7 +394,9 @@ extension DoStmtSyntax {
392394
leadingTrivia: leadingTrivia,
393395
unexpectedBeforeDoKeyword,
394396
doKeyword: doKeyword,
395-
unexpectedBetweenDoKeywordAndBody,
397+
unexpectedBetweenDoKeywordAndThrowsClause,
398+
throwsClause: throwsClause,
399+
unexpectedBetweenThrowsClauseAndBody,
396400
body: CodeBlockSyntax(statements: bodyBuilder()),
397401
unexpectedBetweenBodyAndCatchClauses,
398402
catchClauses: catchClauses,

0 commit comments

Comments
 (0)