Skip to content

Commit 884ab29

Browse files
committed
Hoist "try" and "await" expressions during folding.
When folding an expression such as `try x + y`, instead of producing `(try x) + y`, hoist the `try` up to produce `try (x + y)`.
1 parent c89d323 commit 884ab29

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

Sources/SwiftOperators/OperatorTable+Folding.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,34 @@ extension OperatorTable {
9494
public static func makeBinaryOperationExpr(
9595
lhs: ExprSyntax, op: ExprSyntax, rhs: ExprSyntax
9696
) -> ExprSyntax {
97+
// If the left-hand side is a "try" or "await", hoist it up to encompass
98+
// the right-hand side as well.
99+
if let tryExpr = lhs.as(TryExprSyntax.self) {
100+
return ExprSyntax(
101+
TryExprSyntax(
102+
tryExpr.unexpectedBeforeTryKeyword,
103+
tryKeyword: tryExpr.tryKeyword,
104+
tryExpr.unexpectedBetweenTryKeywordAndQuestionOrExclamationMark,
105+
questionOrExclamationMark: tryExpr.questionOrExclamationMark,
106+
tryExpr.unexpectedBetweenQuestionOrExclamationMarkAndExpression,
107+
expression: makeBinaryOperationExpr(
108+
lhs: tryExpr.expression, op: op, rhs: rhs)
109+
)
110+
)
111+
}
112+
113+
if let awaitExpr = lhs.as(AwaitExprSyntax.self) {
114+
return ExprSyntax(
115+
AwaitExprSyntax(
116+
awaitExpr.unexpectedBeforeAwaitKeyword,
117+
awaitKeyword: awaitExpr.awaitKeyword,
118+
awaitExpr.unexpectedBetweenAwaitKeywordAndExpression,
119+
expression: makeBinaryOperationExpr(
120+
lhs: awaitExpr.expression, op: op, rhs: rhs)
121+
)
122+
)
123+
}
124+
97125
// The form of the binary operation depends on the operator itself,
98126
// which will be one of the unresolved infix operators.
99127

Tests/SwiftOperatorsTest/OperatorTableTests.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,4 +381,11 @@ public class OperatorPrecedenceTests: XCTestCase {
381381
"b + c ? y : z ? z2 : z3",
382382
"((b + c) ? y : (z ? z2 : z3))")
383383
}
384+
385+
func testTryAwait() throws {
386+
let opPrecedence = OperatorTable.standardOperators
387+
try opPrecedence.assertExpectedFold("try x + y", "try (x + y)")
388+
try opPrecedence.assertExpectedFold(
389+
"await x + y + z", "await ((x + y) + z)")
390+
}
384391
}

0 commit comments

Comments
 (0)