Skip to content

Commit

Permalink
Support parsing of key path subscripts on metatypes
Browse files Browse the repository at this point in the history
  • Loading branch information
ahoppen committed Oct 2, 2024
1 parent f4acb89 commit 1dc6bad
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Sources/SwiftParser/Expressions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,7 @@ extension Parser {
// the token is an operator starts with '.', or the following token is '['.
let rootType: RawTypeSyntax?
if !self.at(prefix: ".") {
rootType = self.parseSimpleType(stopAtFirstPeriod: true)
rootType = self.parseSimpleType(allowMemberTypes: false)
} else {
rootType = nil
}
Expand Down
7 changes: 4 additions & 3 deletions Sources/SwiftParser/Types.swift
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,8 @@ extension Parser {
return parseSimpleType(forAttributeName: true)
}

/// Parse a "simple" type
mutating func parseSimpleType(
stopAtFirstPeriod: Bool = false,
allowMemberTypes: Bool = true,
forAttributeName: Bool = false
) -> RawTypeSyntax {
enum TypeBaseStart: TokenSpecSet {
Expand Down Expand Up @@ -260,7 +259,9 @@ extension Parser {

var loopProgress = LoopProgressCondition()
while self.hasProgressed(&loopProgress) {
if !stopAtFirstPeriod, self.at(.period) {
if allowMemberTypes || (self.at(.period) && self.peek(isAt: .keyword(.Type), .keyword(.Protocol))),
self.at(.period)
{
let (unexpectedPeriod, period, skipMemberName) = self.consumeMemberPeriod(previousNode: base)
if skipMemberName {
let missingIdentifier = missingToken(.identifier)
Expand Down
21 changes: 21 additions & 0 deletions Tests/SwiftParserTest/ExpressionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,27 @@ final class ExpressionTests: ParserTestCase {
)
}

func testKeyPathSubscriptOnType() {
assertParse(
#"\Foo.Type.[2]"#,
substructure: KeyPathExprSyntax(
root: TypeSyntax(
MetatypeTypeSyntax(baseType: TypeSyntax("Foo"), metatypeSpecifier: .keyword(.Type))
),
components: KeyPathComponentListSyntax([
KeyPathComponentSyntax(
period: .periodToken(),
component: KeyPathComponentSyntax.Component(
KeyPathSubscriptComponentSyntax(
arguments: LabeledExprListSyntax([LabeledExprSyntax(expression: ExprSyntax("2"))])
)
)
)
])
)
)
}

func testKeypathExpressionWithSugaredRoot() {
let cases: [UInt: String] = [
// Identifiers
Expand Down

0 comments on commit 1dc6bad

Please sign in to comment.