Skip to content

Commit 6abde11

Browse files
committed
Use DeclReferenceExprSyntax in MemberAccessExprSyntax and KeyPathPropertyComponentSyntax
1 parent 86589a5 commit 6abde11

File tree

16 files changed

+252
-317
lines changed

16 files changed

+252
-317
lines changed

CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,7 @@ public let EXPR_NODES: [Node] = [
851851
.keyword(text: "init"),
852852
.token(tokenKind: "DollarIdentifierToken"),
853853
.token(tokenKind: "BinaryOperatorToken"),
854+
.token(tokenKind: "IntegerLiteralToken"),
854855
])
855856
),
856857
Child(
@@ -1091,22 +1092,9 @@ public let EXPR_NODES: [Node] = [
10911092
nameForDiagnostics: "key path property component",
10921093
children: [
10931094
Child(
1094-
name: "Property",
1095+
name: "DeclName",
10951096
deprecatedName: "Identifier",
1096-
kind: .token(choices: [
1097-
.token(tokenKind: "IdentifierToken"),
1098-
.keyword(text: "self"),
1099-
.keyword(text: "Self"),
1100-
.keyword(text: "init"),
1101-
.token(tokenKind: "DollarIdentifierToken"),
1102-
.token(tokenKind: "BinaryOperatorToken"),
1103-
.token(tokenKind: "IntegerLiteralToken"),
1104-
])
1105-
),
1106-
Child(
1107-
name: "DeclNameArguments",
1108-
kind: .node(kind: .declNameArguments),
1109-
isOptional: true
1097+
kind: .node(kind: .declReferenceExpr)
11101098
),
11111099
Child(
11121100
name: "GenericArgumentClause",
@@ -1213,15 +1201,10 @@ public let EXPR_NODES: [Node] = [
12131201
kind: .token(choices: [.token(tokenKind: "PeriodToken")])
12141202
),
12151203
Child(
1216-
name: "Name",
1217-
kind: .node(kind: .token),
1204+
name: "DeclName",
1205+
kind: .node(kind: .declReferenceExpr),
12181206
nameForDiagnostics: "name"
12191207
),
1220-
Child(
1221-
name: "DeclNameArguments",
1222-
kind: .node(kind: .declNameArguments),
1223-
isOptional: true
1224-
),
12251208
]
12261209
),
12271210

Sources/SwiftParser/Expressions.swift

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -595,31 +595,38 @@ extension Parser {
595595
mutating func parseDottedExpressionSuffix(previousNode: (some RawSyntaxNodeProtocol)?) -> (
596596
unexpectedPeriod: RawUnexpectedNodesSyntax?,
597597
period: RawTokenSyntax,
598-
name: RawTokenSyntax,
599-
declNameArgs: RawDeclNameArgumentsSyntax?,
598+
declName: RawDeclReferenceExprSyntax,
600599
generics: RawGenericArgumentClauseSyntax?
601600
) {
602601
precondition(self.at(.period))
603602
let (unexpectedPeriod, period, skipMemberName) = self.consumeMemberPeriod(previousNode: previousNode)
604603
if skipMemberName {
605604
let missingIdentifier = missingToken(.identifier)
606-
return (unexpectedPeriod, period, missingIdentifier, nil, nil)
605+
let declName = RawDeclReferenceExprSyntax(
606+
baseName: missingIdentifier,
607+
argumentNames: nil,
608+
arena: self.arena
609+
)
610+
return (unexpectedPeriod, period, declName, nil)
607611
}
608612

609613
// Parse the name portion.
610-
let name: RawTokenSyntax
611-
let declNameArgs: RawDeclNameArgumentsSyntax?
612-
if let index = self.consume(if: .integerLiteral) {
614+
let declName: RawDeclReferenceExprSyntax
615+
if let indexOrSelf = self.consume(if: .integerLiteral, .keyword(.self)) {
613616
// Handle "x.42" - a tuple index.
614-
name = index
615-
declNameArgs = nil
616-
} else if let selfKeyword = self.consume(if: .keyword(.self)) {
617-
// Handle "x.self" expr.
618-
name = selfKeyword
619-
declNameArgs = nil
617+
declName = RawDeclReferenceExprSyntax(
618+
baseName: indexOrSelf,
619+
argumentNames: nil,
620+
arena: self.arena
621+
)
620622
} else {
621623
// Handle an arbitrary declaration name.
622-
(name, declNameArgs) = self.parseDeclNameRef([.keywords, .compoundNames])
624+
let (name, declNameArgs) = self.parseDeclNameRef([.keywords, .compoundNames])
625+
declName = RawDeclReferenceExprSyntax(
626+
baseName: name,
627+
argumentNames: declNameArgs,
628+
arena: self.arena
629+
)
623630
}
624631

625632
// Parse the generic arguments, if any.
@@ -630,18 +637,17 @@ extension Parser {
630637
generics = nil
631638
}
632639

633-
return (unexpectedPeriod, period, name, declNameArgs, generics)
640+
return (unexpectedPeriod, period, declName, generics)
634641
}
635642

636643
mutating func parseDottedExpressionSuffix(_ start: RawExprSyntax?) -> RawExprSyntax {
637-
let (unexpectedPeriod, period, name, declNameArgs, generics) = parseDottedExpressionSuffix(previousNode: start)
644+
let (unexpectedPeriod, period, declName, generics) = parseDottedExpressionSuffix(previousNode: start)
638645

639646
let memberAccess = RawMemberAccessExprSyntax(
640647
base: start,
641648
unexpectedPeriod,
642649
period: period,
643-
name: name,
644-
declNameArguments: declNameArgs,
650+
declName: declName,
645651
arena: self.arena
646652
)
647653

@@ -1036,7 +1042,7 @@ extension Parser {
10361042

10371043
// Check for a .name or .1 suffix.
10381044
if self.at(.period) {
1039-
let (unexpectedPeriod, period, name, declNameArgs, generics) = parseDottedExpressionSuffix(
1045+
let (unexpectedPeriod, period, declName, generics) = parseDottedExpressionSuffix(
10401046
previousNode: components.last?.raw ?? rootType?.raw ?? backslash.raw
10411047
)
10421048
components.append(
@@ -1045,8 +1051,7 @@ extension Parser {
10451051
period: period,
10461052
component: .property(
10471053
RawKeyPathPropertyComponentSyntax(
1048-
property: name,
1049-
declNameArguments: declNameArgs,
1054+
declName: declName,
10501055
genericArgumentClause: generics,
10511056
arena: self.arena
10521057
)
@@ -1203,12 +1208,16 @@ extension Parser {
12031208
}
12041209

12051210
let (name, args) = self.parseDeclNameRef([.keywords, .compoundNames])
1211+
let declName = RawDeclReferenceExprSyntax(
1212+
baseName: name,
1213+
argumentNames: args,
1214+
arena: self.arena
1215+
)
12061216
return RawExprSyntax(
12071217
RawMemberAccessExprSyntax(
12081218
base: nil,
12091219
period: period,
1210-
name: name,
1211-
declNameArguments: args,
1220+
declName: declName,
12121221
arena: self.arena
12131222
)
12141223
)

Sources/SwiftParser/generated/Parser+TokenSpecSet.swift

Lines changed: 5 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,7 @@ extension DeclReferenceExprSyntax {
660660
case `init`
661661
case dollarIdentifier
662662
case binaryOperator
663+
case integerLiteral
663664

664665
init?(lexeme: Lexer.Lexeme) {
665666
switch PrepareForKeywordMatch(lexeme) {
@@ -675,6 +676,8 @@ extension DeclReferenceExprSyntax {
675676
self = .dollarIdentifier
676677
case TokenSpec(.binaryOperator):
677678
self = .binaryOperator
679+
case TokenSpec(.integerLiteral):
680+
self = .integerLiteral
678681
default:
679682
return nil
680683
}
@@ -694,6 +697,8 @@ extension DeclReferenceExprSyntax {
694697
return .dollarIdentifier
695698
case .binaryOperator:
696699
return .binaryOperator
700+
case .integerLiteral:
701+
return .integerLiteral
697702
}
698703
}
699704
}
@@ -1307,58 +1312,6 @@ extension KeyPathOptionalComponentSyntax {
13071312
}
13081313
}
13091314

1310-
extension KeyPathPropertyComponentSyntax {
1311-
enum PropertyOptions: TokenSpecSet {
1312-
case identifier
1313-
case `self`
1314-
case `Self`
1315-
case `init`
1316-
case dollarIdentifier
1317-
case binaryOperator
1318-
case integerLiteral
1319-
1320-
init?(lexeme: Lexer.Lexeme) {
1321-
switch PrepareForKeywordMatch(lexeme) {
1322-
case TokenSpec(.identifier):
1323-
self = .identifier
1324-
case TokenSpec(.`self`):
1325-
self = .`self`
1326-
case TokenSpec(.`Self`):
1327-
self = .`Self`
1328-
case TokenSpec(.`init`):
1329-
self = .`init`
1330-
case TokenSpec(.dollarIdentifier):
1331-
self = .dollarIdentifier
1332-
case TokenSpec(.binaryOperator):
1333-
self = .binaryOperator
1334-
case TokenSpec(.integerLiteral):
1335-
self = .integerLiteral
1336-
default:
1337-
return nil
1338-
}
1339-
}
1340-
1341-
var spec: TokenSpec {
1342-
switch self {
1343-
case .identifier:
1344-
return .identifier
1345-
case .`self`:
1346-
return .keyword(.`self`)
1347-
case .`Self`:
1348-
return .keyword(.`Self`)
1349-
case .`init`:
1350-
return .keyword(.`init`)
1351-
case .dollarIdentifier:
1352-
return .dollarIdentifier
1353-
case .binaryOperator:
1354-
return .binaryOperator
1355-
case .integerLiteral:
1356-
return .integerLiteral
1357-
}
1358-
}
1359-
}
1360-
}
1361-
13621315
extension LabeledExprSyntax {
13631316
enum LabelOptions: TokenSpecSet {
13641317
case identifier

Sources/SwiftParserDiagnostics/generated/ChildNameForDiagnostics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? {
236236
return "modifiers"
237237
case \MemberAccessExprSyntax.base:
238238
return "base"
239-
case \MemberAccessExprSyntax.name:
239+
case \MemberAccessExprSyntax.declName:
240240
return "name"
241241
case \MemberTypeSyntax.baseType:
242242
return "base type"

Sources/SwiftSyntax/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ add_swift_host_library(SwiftSyntax
1111
Assert.swift
1212
BumpPtrAllocator.swift
1313
CommonAncestor.swift
14+
Convenience.swift
1415
MemoryLayout.swift
1516
MissingNodeInitializers.swift
1617
Trivia.swift

Sources/SwiftSyntax/Convenience.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
extension MemberAccessExprSyntax {
14+
/// Creates a new ``MemberAccessExprSyntax`` where the accessed member is represented by
15+
/// an identifier without specifying argument labels.
16+
///
17+
/// A member access can specify function argument labels, which is required
18+
/// when the name would be ambiguous otherwise. For example, given multiple overloads
19+
/// ```swift
20+
/// struct Person {
21+
/// func consume(drink: Drink) {}
22+
/// func consume(food: Food) {}
23+
/// }
24+
/// ```
25+
///
26+
/// `consume(drink:)` is required to explicitly reference the consume function
27+
/// that takes a drink.
28+
///
29+
/// Given how common it is to not need the argument names, this initializer is
30+
/// provided as a convenience to avoid having to create a ``DeclReferenceExpr``
31+
/// for the member name.
32+
public init(
33+
leadingTrivia: Trivia? = nil,
34+
base: (some ExprSyntaxProtocol)? = ExprSyntax?.none,
35+
period: TokenSyntax = .periodToken(),
36+
name: TokenSyntax,
37+
trailingTrivia: Trivia? = nil
38+
) {
39+
self.init(
40+
leadingTrivia: leadingTrivia,
41+
base: base,
42+
period: period,
43+
declName: DeclReferenceExprSyntax(baseName: name),
44+
trailingTrivia: trailingTrivia
45+
)
46+
}
47+
}

Sources/SwiftSyntax/SwiftSyntaxCompatibility.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,51 @@ extension IdentifiedDeclSyntax where Self: NamedDeclSyntax {
7777
}
7878
}
7979

80+
extension MemberAccessExprSyntax {
81+
@available(*, deprecated, renamed: "declName.baseName")
82+
public var name: TokenSyntax {
83+
return declName.baseName
84+
}
85+
86+
@available(*, deprecated, renamed: "declName.argumentNames")
87+
public var declNameArguments: DeclNameArgumentsSyntax? {
88+
return declName.argumentNames
89+
}
90+
91+
@available(*, deprecated, message: "Use initializer taking `DeclReferenceExprSyntax` instead")
92+
@_disfavoredOverload
93+
public init(
94+
leadingTrivia: Trivia? = nil,
95+
_ unexpectedBeforeBase: UnexpectedNodesSyntax? = nil,
96+
base: (some ExprSyntaxProtocol)? = ExprSyntax?.none,
97+
_ unexpectedBetweenBaseAndPeriod: UnexpectedNodesSyntax? = nil,
98+
dot: TokenSyntax = .periodToken(),
99+
_ unexpectedBetweenPeriodAndName: UnexpectedNodesSyntax? = nil,
100+
name: TokenSyntax,
101+
_ unexpectedBetweenNameAndDeclNameArguments: UnexpectedNodesSyntax? = nil,
102+
declNameArguments: DeclNameArgumentsSyntax? = nil,
103+
_ unexpectedAfterDeclNameArguments: UnexpectedNodesSyntax? = nil,
104+
trailingTrivia: Trivia? = nil
105+
) {
106+
let declName = DeclReferenceExprSyntax(
107+
baseName: name,
108+
unexpectedBetweenNameAndDeclNameArguments,
109+
argumentNames: declNameArguments
110+
)
111+
self.init(
112+
leadingTrivia: leadingTrivia,
113+
unexpectedBeforeBase,
114+
base: base,
115+
unexpectedBetweenBaseAndPeriod,
116+
period: dot,
117+
unexpectedBetweenPeriodAndName,
118+
declName: declName,
119+
unexpectedAfterDeclNameArguments,
120+
trailingTrivia: trailingTrivia
121+
)
122+
}
123+
}
124+
80125
public extension SyntaxProtocol {
81126
@available(*, deprecated, message: "Use detached computed property instead.")
82127
func detach() -> Self {

0 commit comments

Comments
 (0)