Skip to content

Commit c28f994

Browse files
authored
Merge pull request #1731 from hborla/init-accessors
Parse `init` accessors.
2 parents b950ac0 + e0a253b commit c28f994

24 files changed

+1463
-25
lines changed

CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,74 @@ public let DECL_NODES: [Node] = [
6565
]
6666
),
6767

68+
Node(
69+
kind: .accessesEffect,
70+
base: .syntax,
71+
nameForDiagnostics: "accesses effect",
72+
children: [
73+
Child(
74+
name: "AccessesKeyword",
75+
kind: .token(choices: [.keyword(text: "accesses")])
76+
),
77+
Child(
78+
name: "LeftParen",
79+
kind: .token(choices: [.token(tokenKind: "LeftParenToken")])
80+
),
81+
Child(
82+
name: "PropertyList",
83+
kind: .collection(kind: .tupleExprElementList, collectionElementName: "Property"),
84+
nameForDiagnostics: "properties"
85+
),
86+
Child(
87+
name: "RightParen",
88+
kind: .token(choices: [.token(tokenKind: "RightParenToken")])
89+
),
90+
]
91+
),
92+
93+
Node(
94+
kind: .initializesEffect,
95+
base: .syntax,
96+
nameForDiagnostics: "initializes effect",
97+
children: [
98+
Child(
99+
name: "InitializesKeyword",
100+
kind: .token(choices: [.keyword(text: "initializes")])
101+
),
102+
Child(
103+
name: "LeftParen",
104+
kind: .token(choices: [.token(tokenKind: "LeftParenToken")])
105+
),
106+
Child(
107+
name: "PropertyList",
108+
kind: .collection(kind: .tupleExprElementList, collectionElementName: "Property"),
109+
nameForDiagnostics: "properties"
110+
),
111+
Child(
112+
name: "RightParen",
113+
kind: .token(choices: [.token(tokenKind: "RightParenToken")])
114+
),
115+
]
116+
),
117+
118+
Node(
119+
kind: .accessorInitEffects,
120+
base: .syntax,
121+
nameForDiagnostics: "init accessor effects",
122+
children: [
123+
Child(
124+
name: "InitializesEffect",
125+
kind: .node(kind: .initializesEffect),
126+
isOptional: true
127+
),
128+
Child(
129+
name: "AccessesEffect",
130+
kind: .node(kind: .accessesEffect),
131+
isOptional: true
132+
),
133+
]
134+
),
135+
68136
Node(
69137
kind: .accessorDecl,
70138
base: .decl,
@@ -99,6 +167,7 @@ public let DECL_NODES: [Node] = [
99167
.keyword(text: "mutableAddressWithNativeOwner"),
100168
.keyword(text: "_read"),
101169
.keyword(text: "_modify"),
170+
.keyword(text: "init"),
102171
])
103172
),
104173
Child(
@@ -112,6 +181,11 @@ public let DECL_NODES: [Node] = [
112181
kind: .node(kind: .accessorEffectSpecifiers),
113182
isOptional: true
114183
),
184+
Child(
185+
name: "InitEffects",
186+
kind: .node(kind: .accessorInitEffects),
187+
isOptional: true
188+
),
115189
Child(
116190
name: "Body",
117191
kind: .node(kind: .codeBlock),

CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ public let KEYWORDS: [KeywordSpec] = [
8585
KeywordSpec("_underlyingVersion"),
8686
KeywordSpec("_UnknownLayout"),
8787
KeywordSpec("_version"),
88+
KeywordSpec("accesses"),
8889
KeywordSpec("actor"),
8990
KeywordSpec("addressWithNativeOwner"),
9091
KeywordSpec("addressWithOwner"),
@@ -152,6 +153,7 @@ public let KEYWORDS: [KeywordSpec] = [
152153
KeywordSpec("indirect"),
153154
KeywordSpec("infix"),
154155
KeywordSpec("init", isLexerClassified: true),
156+
KeywordSpec("initializes"),
155157
KeywordSpec("inline"),
156158
KeywordSpec("inout", isLexerClassified: true, requiresTrailingSpace: true),
157159
KeywordSpec("internal", isLexerClassified: true, requiresTrailingSpace: true),

CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ import SwiftSyntaxBuilder
2020
public enum SyntaxNodeKind: String, CaseIterable {
2121
// Please keep this list sorted alphabetically
2222

23+
case accessesEffect
2324
case accessorBlock
2425
case accessorDecl
2526
case accessorEffectSpecifiers
27+
case accessorInitEffects
2628
case accessorList
2729
case accessorParameter
2830
case actorDecl
@@ -168,6 +170,7 @@ public enum SyntaxNodeKind: String, CaseIterable {
168170
case inheritedType
169171
case initializerClause
170172
case initializerDecl
173+
case initializesEffect
171174
case integerLiteralExpr
172175
case isExpr
173176
case isTypePattern

Sources/SwiftParser/Declarations.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,7 +1410,7 @@ extension Parser {
14101410
}
14111411

14121412
let accessor: RawPatternBindingSyntax.Accessor?
1413-
if self.at(.leftBrace) || (inMemberDeclList && self.at(anyIn: AccessorKind.self) != nil) {
1413+
if self.at(.leftBrace) || (inMemberDeclList && self.at(anyIn: AccessorKind.self) != nil && !self.at(.keyword(.`init`))) {
14141414
switch self.parseGetSet() {
14151415
case .accessors(let accessors):
14161416
accessor = .accessors(accessors)
@@ -1522,7 +1522,7 @@ extension Parser {
15221522
//
15231523
// set-name ::= '(' identifier ')'
15241524
let parameter: RawAccessorParameterSyntax?
1525-
if [AccessorKind.set, .willSet, .didSet].contains(introducer.kind), let lparen = self.consume(if: .leftParen) {
1525+
if [AccessorKind.set, .willSet, .didSet, .`init`].contains(introducer.kind), let lparen = self.consume(if: .leftParen) {
15261526
let (unexpectedBeforeName, name) = self.expectIdentifier()
15271527
let (unexpectedBeforeRParen, rparen) = self.expect(.rightParen)
15281528
parameter = RawAccessorParameterSyntax(
@@ -1538,6 +1538,7 @@ extension Parser {
15381538
}
15391539

15401540
let effectSpecifiers = self.parseAccessorEffectSpecifiers()
1541+
let initEffects = self.parseInitAccessorEffects()
15411542

15421543
let body = self.parseOptionalCodeBlock()
15431544
return RawAccessorDeclSyntax(
@@ -1547,6 +1548,7 @@ extension Parser {
15471548
accessorKind: introducer.token,
15481549
parameter: parameter,
15491550
effectSpecifiers: effectSpecifiers,
1551+
initEffects: initEffects,
15501552
body: body,
15511553
arena: self.arena
15521554
)

Sources/SwiftParser/Specifiers.swift

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,3 +572,74 @@ extension Parser {
572572
return RawUnexpectedNodesSyntax(unexpected, arena: self.arena)
573573
}
574574
}
575+
576+
// MARK: - Parsing `initializes` and `accesses` specifiers in init accessors
577+
578+
extension Parser {
579+
mutating func parseInitAccessorEffects() -> RawAccessorInitEffectsSyntax? {
580+
let initializes = self.parseInitializesSpecifier()
581+
let accesses = self.parseAccessesSpecifier()
582+
583+
if initializes == nil, accesses == nil {
584+
return nil
585+
}
586+
587+
return RawAccessorInitEffectsSyntax(
588+
initializesEffect: initializes,
589+
accessesEffect: accesses,
590+
arena: self.arena
591+
)
592+
}
593+
594+
mutating func parseInitializesSpecifier() -> RawInitializesEffectSyntax? {
595+
guard let keyword = self.consume(if: .keyword(.initializes)) else {
596+
return nil
597+
}
598+
599+
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
600+
601+
let args = parseArgumentListElements(pattern: .none)
602+
let argumentList = RawTupleExprElementListSyntax(
603+
elements: args,
604+
arena: self.arena
605+
)
606+
607+
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
608+
609+
return RawInitializesEffectSyntax(
610+
initializesKeyword: keyword,
611+
unexpectedBeforeLeftParen,
612+
leftParen: leftParen,
613+
propertyList: argumentList,
614+
unexpectedBeforeRightParen,
615+
rightParen: rightParen,
616+
arena: self.arena
617+
)
618+
}
619+
620+
mutating func parseAccessesSpecifier() -> RawAccessesEffectSyntax? {
621+
guard let keyword = self.consume(if: .keyword(.accesses)) else {
622+
return nil
623+
}
624+
625+
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
626+
627+
let args = parseArgumentListElements(pattern: .none)
628+
let argumentList = RawTupleExprElementListSyntax(
629+
elements: args,
630+
arena: self.arena
631+
)
632+
633+
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
634+
635+
return RawAccessesEffectSyntax(
636+
accessesKeyword: keyword,
637+
unexpectedBeforeLeftParen,
638+
leftParen: leftParen,
639+
propertyList: argumentList,
640+
unexpectedBeforeRightParen,
641+
rightParen: rightParen,
642+
arena: self.arena
643+
)
644+
}
645+
}

Sources/SwiftParser/TokenSpecSet.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ enum AccessorKind: TokenSpecSet {
2828
case `set`
2929
case `didSet`
3030
case `willSet`
31+
case `init`
3132
case unsafeAddress
3233
case addressWithOwner
3334
case addressWithNativeOwner
@@ -43,6 +44,7 @@ enum AccessorKind: TokenSpecSet {
4344
case TokenSpec(.set): self = .set
4445
case TokenSpec(.didSet): self = .didSet
4546
case TokenSpec(.willSet): self = .willSet
47+
case TokenSpec(.`init`): self = .`init`
4648
case TokenSpec(.unsafeAddress): self = .unsafeAddress
4749
case TokenSpec(.addressWithOwner): self = .addressWithOwner
4850
case TokenSpec(.addressWithNativeOwner): self = .addressWithNativeOwner
@@ -61,6 +63,7 @@ enum AccessorKind: TokenSpecSet {
6163
case .set: return .keyword(.set)
6264
case .didSet: return .keyword(.didSet)
6365
case .willSet: return .keyword(.willSet)
66+
case .`init`: return .keyword(.`init`)
6467
case .unsafeAddress: return .keyword(.unsafeAddress)
6568
case .addressWithOwner: return .keyword(.addressWithOwner)
6669
case .addressWithNativeOwner: return .keyword(.addressWithNativeOwner)

Sources/SwiftParserDiagnostics/generated/ChildNameForDiagnostics.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import SwiftSyntax
1616

1717
private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? {
1818
switch keyPath {
19+
case \AccessesEffectSyntax.propertyList:
20+
return "properties"
1921
case \AccessorDeclSyntax.attributes:
2022
return "attributes"
2123
case \AccessorDeclSyntax.modifier:
@@ -208,6 +210,8 @@ private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? {
208210
return "function signature"
209211
case \InitializerDeclSyntax.genericWhereClause:
210212
return "generic where clause"
213+
case \InitializesEffectSyntax.propertyList:
214+
return "properties"
211215
case \KeyPathExprSyntax.root:
212216
return "root"
213217
case \KeyPathSubscriptComponentSyntax.argumentList:

Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,14 @@ extension SyntaxKind {
1919
switch self {
2020
case .token:
2121
return "token"
22+
case .accessesEffect:
23+
return "accesses effect"
2224
case .accessorDecl:
2325
return "accessor"
2426
case .accessorEffectSpecifiers:
2527
return "accessor specifiers"
28+
case .accessorInitEffects:
29+
return "init accessor effects"
2630
case .actorDecl:
2731
return "actor"
2832
case .arrayElement:
@@ -225,6 +229,8 @@ extension SyntaxKind {
225229
return "inherited type"
226230
case .initializerDecl:
227231
return "initializer"
232+
case .initializesEffect:
233+
return "initializes effect"
228234
case .integerLiteralExpr:
229235
return "integer literal"
230236
case .isExpr:

Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,10 @@ These articles are intended for developers wishing to contribute to SwiftSyntax
305305

306306
### Miscellaneous Syntax
307307

308+
- <doc:SwiftSyntax/AccessesEffectSyntax>
308309
- <doc:SwiftSyntax/AccessorBlockSyntax>
309310
- <doc:SwiftSyntax/AccessorEffectSpecifiersSyntax>
311+
- <doc:SwiftSyntax/AccessorInitEffectsSyntax>
310312
- <doc:SwiftSyntax/AccessorParameterSyntax>
311313
- <doc:SwiftSyntax/AvailabilityConditionSyntax>
312314
- <doc:SwiftSyntax/AvailabilityLabeledArgumentSyntax>
@@ -336,6 +338,7 @@ These articles are intended for developers wishing to contribute to SwiftSyntax
336338
- <doc:SwiftSyntax/GenericParameterClauseSyntax>
337339
- <doc:SwiftSyntax/ImplementsAttributeArgumentsSyntax>
338340
- <doc:SwiftSyntax/InitializerClauseSyntax>
341+
- <doc:SwiftSyntax/InitializesEffectSyntax>
339342
- <doc:SwiftSyntax/KeyPathOptionalComponentSyntax>
340343
- <doc:SwiftSyntax/KeyPathPropertyComponentSyntax>
341344
- <doc:SwiftSyntax/KeyPathSubscriptComponentSyntax>

0 commit comments

Comments
 (0)