Skip to content

Commit 2bfb64a

Browse files
committed
Parse method and initializer keypaths.
1 parent 14dcd7b commit 2bfb64a

File tree

2 files changed

+377
-3
lines changed

2 files changed

+377
-3
lines changed

Sources/SwiftParser/Expressions.swift

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
#else
1616
@_spi(RawSyntax) import SwiftSyntax
1717
#endif
18-
18+
#if compiler(>=5.8)
19+
@_spi(RawSyntax) @_spi(ExperimentalLanguageFeatures) internal import SwiftSyntax
20+
#endif
1921
extension TokenConsumer {
2022
mutating func atStartOfExpression() -> Bool {
2123
switch self.at(anyIn: ExpressionStart.self) {
@@ -1103,11 +1105,54 @@ extension Parser {
11031105
continue
11041106
}
11051107

1106-
// Check for a .name or .1 suffix.
1108+
// Check for a .name, .1, .name(), .name("Kiwi"), .name(fruit:),
1109+
// .name(_:), .name(fruit: "Kiwi) suffix.
11071110
if self.at(.period) {
11081111
let (unexpectedPeriod, period, declName, generics) = parseDottedExpressionSuffix(
11091112
previousNode: components.last?.raw ?? rootType?.raw ?? backslash.raw
11101113
)
1114+
1115+
// If fully applied method component, parse as a keypath method.
1116+
if self.experimentalFeatures.contains(.keypathWithMethodMembers)
1117+
&& self.at(.leftParen)
1118+
{
1119+
var (unexpectedBeforeLParen, leftParen) = self.expect(.leftParen)
1120+
if let generics = generics {
1121+
unexpectedBeforeLParen = RawUnexpectedNodesSyntax(
1122+
(unexpectedBeforeLParen?.elements ?? []) + [RawSyntax(generics)],
1123+
arena: self.arena
1124+
)
1125+
}
1126+
let args = self.parseArgumentListElements(
1127+
pattern: pattern,
1128+
allowTrailingComma: true
1129+
)
1130+
let (unexpectedBeforeRParen, rightParen) = self.expect(.rightParen)
1131+
1132+
components.append(
1133+
RawKeyPathComponentSyntax(
1134+
unexpectedPeriod,
1135+
period: period,
1136+
component: .method(
1137+
RawKeyPathMethodComponentSyntax(
1138+
declName: declName,
1139+
unexpectedBeforeLParen,
1140+
leftParen: leftParen,
1141+
arguments: RawLabeledExprListSyntax(
1142+
elements: args,
1143+
arena: self.arena
1144+
),
1145+
unexpectedBeforeRParen,
1146+
rightParen: rightParen,
1147+
arena: self.arena
1148+
)
1149+
),
1150+
arena: self.arena
1151+
)
1152+
)
1153+
continue
1154+
}
1155+
// Else, parse as a property.
11111156
components.append(
11121157
RawKeyPathComponentSyntax(
11131158
unexpectedPeriod,
@@ -1128,7 +1173,6 @@ extension Parser {
11281173
// No more postfix expressions.
11291174
break
11301175
}
1131-
11321176
return RawKeyPathExprSyntax(
11331177
unexpectedBeforeBackslash,
11341178
backslash: backslash,

0 commit comments

Comments
 (0)