Skip to content

Commit 8b5df29

Browse files
committed
Parse method and initializer keypaths.
1 parent 9b5dc51 commit 8b5df29

File tree

2 files changed

+405
-4
lines changed

2 files changed

+405
-4
lines changed

Sources/SwiftParser/Expressions.swift

+46-4
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#if compiler(>=6)
14-
@_spi(RawSyntax) internal import SwiftSyntax
14+
@_spi(RawSyntax) @_spi(ExperimentalLanguageFeatures) internal import SwiftSyntax
1515
#else
16-
@_spi(RawSyntax) import SwiftSyntax
16+
@_spi(RawSyntax) @_spi(ExperimentalLanguageFeatures) import SwiftSyntax
1717
#endif
1818

1919
extension TokenConsumer {
@@ -1115,11 +1115,54 @@ extension Parser {
11151115
continue
11161116
}
11171117

1118-
// Check for a .name or .1 suffix.
1118+
// Check for a .name, .1, .name(), .name("Kiwi"), .name(fruit:),
1119+
// .name(_:), .name(fruit: "Kiwi) suffix.
11191120
if self.at(.period) {
11201121
let (unexpectedPeriod, period, declName, generics) = parseDottedExpressionSuffix(
11211122
previousNode: components.last?.raw ?? rootType?.raw ?? backslash.raw
11221123
)
1124+
1125+
// If fully applied method component, parse as a keypath method.
1126+
if self.experimentalFeatures.contains(.keypathWithMethodMembers)
1127+
&& self.at(.leftParen)
1128+
{
1129+
var (unexpectedBeforeLParen, leftParen) = self.expect(.leftParen)
1130+
if let generics = generics {
1131+
unexpectedBeforeLParen = RawUnexpectedNodesSyntax(
1132+
(unexpectedBeforeLParen?.elements ?? []) + [RawSyntax(generics)],
1133+
arena: self.arena
1134+
)
1135+
}
1136+
let args = self.parseArgumentListElements(
1137+
pattern: pattern,
1138+
allowTrailingComma: true
1139+
)
1140+
let (unexpectedBeforeRParen, rightParen) = self.expect(.rightParen)
1141+
1142+
components.append(
1143+
RawKeyPathComponentSyntax(
1144+
unexpectedPeriod,
1145+
period: period,
1146+
component: .method(
1147+
RawKeyPathMethodComponentSyntax(
1148+
declName: declName,
1149+
unexpectedBeforeLParen,
1150+
leftParen: leftParen,
1151+
arguments: RawLabeledExprListSyntax(
1152+
elements: args,
1153+
arena: self.arena
1154+
),
1155+
unexpectedBeforeRParen,
1156+
rightParen: rightParen,
1157+
arena: self.arena
1158+
)
1159+
),
1160+
arena: self.arena
1161+
)
1162+
)
1163+
continue
1164+
}
1165+
// Else, parse as a property.
11231166
components.append(
11241167
RawKeyPathComponentSyntax(
11251168
unexpectedPeriod,
@@ -1140,7 +1183,6 @@ extension Parser {
11401183
// No more postfix expressions.
11411184
break
11421185
}
1143-
11441186
return RawKeyPathExprSyntax(
11451187
unexpectedBeforeBackslash,
11461188
backslash: backslash,

0 commit comments

Comments
 (0)