Skip to content

Commit fa3596e

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

File tree

2 files changed

+409
-4
lines changed

2 files changed

+409
-4
lines changed

Sources/SwiftParser/Expressions.swift

+50-4
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#if compiler(>=6)
14-
@_spi(RawSyntax) internal import SwiftSyntax
13+
#if swift(>=6)
14+
@_spi(RawSyntax) @_spi(ExperimentalLanguageFeatures) internal import SwiftSyntax
15+
#else
16+
#if swift(>=5.8)
17+
@_spi(RawSyntax) @_spi(ExperimentalLanguageFeatures) import SwiftSyntax
1518
#else
1619
@_spi(RawSyntax) import SwiftSyntax
1720
#endif
21+
#endif
1822

1923
extension TokenConsumer {
2024
mutating func atStartOfExpression() -> Bool {
@@ -1103,11 +1107,54 @@ extension Parser {
11031107
continue
11041108
}
11051109

1106-
// Check for a .name or .1 suffix.
1110+
// Check for a .name, .1, .name(), .name("Kiwi"), .name(fruit:),
1111+
// .name(_:), .name(fruit: "Kiwi) suffix.
11071112
if self.at(.period) {
11081113
let (unexpectedPeriod, period, declName, generics) = parseDottedExpressionSuffix(
11091114
previousNode: components.last?.raw ?? rootType?.raw ?? backslash.raw
11101115
)
1116+
1117+
// If fully applied method component, parse as a keypath method.
1118+
if self.experimentalFeatures.contains(.keypathWithMethodMembers)
1119+
&& self.at(.leftParen)
1120+
{
1121+
var (unexpectedBeforeLParen, leftParen) = self.expect(.leftParen)
1122+
if let generics = generics {
1123+
unexpectedBeforeLParen = RawUnexpectedNodesSyntax(
1124+
(unexpectedBeforeLParen?.elements ?? []) + [RawSyntax(generics)],
1125+
arena: self.arena
1126+
)
1127+
}
1128+
let args = self.parseArgumentListElements(
1129+
pattern: pattern,
1130+
allowTrailingComma: true
1131+
)
1132+
let (unexpectedBeforeRParen, rightParen) = self.expect(.rightParen)
1133+
1134+
components.append(
1135+
RawKeyPathComponentSyntax(
1136+
unexpectedPeriod,
1137+
period: period,
1138+
component: .method(
1139+
RawKeyPathMethodComponentSyntax(
1140+
declName: declName,
1141+
unexpectedBeforeLParen,
1142+
leftParen: leftParen,
1143+
arguments: RawLabeledExprListSyntax(
1144+
elements: args,
1145+
arena: self.arena
1146+
),
1147+
unexpectedBeforeRParen,
1148+
rightParen: rightParen,
1149+
arena: self.arena
1150+
)
1151+
),
1152+
arena: self.arena
1153+
)
1154+
)
1155+
continue
1156+
}
1157+
// Else, parse as a property.
11111158
components.append(
11121159
RawKeyPathComponentSyntax(
11131160
unexpectedPeriod,
@@ -1128,7 +1175,6 @@ extension Parser {
11281175
// No more postfix expressions.
11291176
break
11301177
}
1131-
11321178
return RawKeyPathExprSyntax(
11331179
unexpectedBeforeBackslash,
11341180
backslash: backslash,

0 commit comments

Comments
 (0)