Skip to content

Commit eb5eb98

Browse files
committed
Skip parsing trailing closures after literals
Postfix parsing should skip trailing closure if the base expression is a literal (which is not callable).
1 parent 598e191 commit eb5eb98

File tree

4 files changed

+74
-6
lines changed

4 files changed

+74
-6
lines changed

Sources/SwiftParser/Expressions.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,7 @@ extension Parser {
790790
}
791791

792792
// Check for a trailing closure, if allowed.
793-
if self.at(.leftBrace) && self.withLookahead({ $0.atValidTrailingClosure(flavor: flavor) }) {
793+
if self.at(.leftBrace) && !leadingExpr.raw.kind.isLiteral && self.withLookahead({ $0.atValidTrailingClosure(flavor: flavor) }) {
794794
// FIXME: if Result has a trailing closure, break out.
795795
// Add dummy blank argument list to the call expression syntax.
796796
let list = RawLabeledExprListSyntax(elements: [], arena: self.arena)
@@ -2543,3 +2543,14 @@ extension Parser.Lookahead {
25432543
}
25442544
}
25452545
}
2546+
2547+
extension SyntaxKind {
2548+
fileprivate var isLiteral: Bool {
2549+
switch self {
2550+
case .arrayExpr, .booleanLiteralExpr, .dictionaryExpr, .floatLiteralExpr, .integerLiteralExpr, .nilLiteralExpr, .regexLiteralExpr, .stringLiteralExpr:
2551+
return true
2552+
default:
2553+
return false
2554+
}
2555+
}
2556+
}

Tests/SwiftParserTest/DeclarationTests.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3059,4 +3059,11 @@ final class DeclarationTests: ParserTestCase {
30593059
"""
30603060
)
30613061
}
3062+
3063+
func testLiteralInitializerWithTrailingClosure() {
3064+
assertParse(
3065+
"let foo = 1 { return 1 }",
3066+
substructure: AccessorBlockSyntax(accessors: .getter([CodeBlockItemSyntax("return 1")]))
3067+
)
3068+
}
30623069
}

Tests/SwiftParserTest/ExpressionTests.swift

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,12 +1463,53 @@ final class ExpressionTests: ParserTestCase {
14631463
)
14641464
}
14651465

1466-
func testNulCharacterInSourceFile() {
1466+
func testLiteralWithTrailingClosure() {
1467+
let expectedDiagnostics = [
1468+
DiagnosticSpec(
1469+
message: "consecutive statements on a line must be separated by newline or ';'",
1470+
fixIts: ["insert newline", "insert ';'"]
1471+
)
1472+
]
1473+
14671474
assertParse(
1468-
"let a = 1️⃣\u{0}1",
1469-
diagnostics: [
1470-
DiagnosticSpec(message: "nul character embedded in middle of file", severity: .warning)
1471-
]
1475+
"_ = true1️⃣ { return true }",
1476+
diagnostics: expectedDiagnostics,
1477+
fixedSource: "_ = true\n{ return true }"
1478+
)
1479+
assertParse(
1480+
"_ = nil1️⃣ { return nil }",
1481+
diagnostics: expectedDiagnostics,
1482+
fixedSource: "_ = nil\n{ return nil }"
1483+
)
1484+
assertParse(
1485+
"_ = 11️⃣ { return 1 }",
1486+
diagnostics: expectedDiagnostics,
1487+
fixedSource: "_ = 1\n{ return 1 }"
1488+
)
1489+
assertParse(
1490+
"_ = 1.01️⃣ { return 1.0 }",
1491+
diagnostics: expectedDiagnostics,
1492+
fixedSource: "_ = 1.0\n{ return 1.0 }"
1493+
)
1494+
assertParse(
1495+
#"_ = "foo"1️⃣ { return "foo" }"#,
1496+
diagnostics: expectedDiagnostics,
1497+
fixedSource: #"_ = "foo"\#n{ return "foo" }"#
1498+
)
1499+
assertParse(
1500+
#"_ = /foo/1️⃣ { return /foo/ }"#,
1501+
diagnostics: expectedDiagnostics,
1502+
fixedSource: #"_ = /foo/\#n{ return /foo/ }"#
1503+
)
1504+
assertParse(
1505+
"_ = [1]1️⃣ { return [1] }",
1506+
diagnostics: expectedDiagnostics,
1507+
fixedSource: "_ = [1]\n{ return [1] }"
1508+
)
1509+
assertParse(
1510+
"_ = [1: 1]1️⃣ { return [1: 1] }",
1511+
diagnostics: expectedDiagnostics,
1512+
fixedSource: "_ = [1: 1]\n{ return [1: 1] }"
14721513
)
14731514
}
14741515
}

Tests/SwiftParserTest/LexerTests.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,4 +1495,13 @@ public class LexerTests: ParserTestCase {
14951495
]
14961496
)
14971497
}
1498+
1499+
func testNulCharacterInSourceFile() {
1500+
assertParse(
1501+
"let a = 1️⃣\u{0}1",
1502+
diagnostics: [
1503+
DiagnosticSpec(message: "nul character embedded in middle of file", severity: .warning)
1504+
]
1505+
)
1506+
}
14981507
}

0 commit comments

Comments
 (0)