Skip to content

Commit 6eacdba

Browse files
committed
More examples of autogenerating convenience inits
1 parent 8a30b2d commit 6eacdba

File tree

10 files changed

+131
-79
lines changed

10 files changed

+131
-79
lines changed

CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ public let ATTRIBUTE_NODES: [Node] = [
5050
documentation: "An `@` attribute.",
5151
parserFunction: "parseAttribute",
5252
rules: [
53-
NodeInitRule(
53+
ConvenienceInitRule(
5454
nonOptionalChildName: "arguments",
55-
childDefaultValues: [
55+
defaults: [
5656
"leftParen": .leftParen,
5757
"rightParen": .rightParen
5858
])

CodeGeneration/Sources/SyntaxSupport/NodeInitRule.swift renamed to CodeGeneration/Sources/SyntaxSupport/ConvenienceInitRule.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,18 @@ import SwiftSyntax
2020
///
2121
/// The convenience initializer will take a non-optional parameter
2222
/// `nonOptionalChildName`, and when a non-optional value is passed, it'll call
23-
/// the full memberwise initializer with the provided `childDefaultValues`.
23+
/// the full memberwise initializer with the provided `defaults`.
2424
///
2525
/// For example, when initializing an `EnumCaseParameterSyntax`, the convenience
2626
/// initializer will take a non-optional `firstName` parameter, and when it's
2727
/// passed, it'll call the full memberwise initializer with
2828
/// `colon = .colonToken()`.
29-
public struct NodeInitRule {
29+
public struct ConvenienceInitRule {
3030
/// The name of the parameter that is required to be present for
3131
/// this conveniece initializer rule to apply.
3232
public let nonOptionalChildName: String
3333

3434
/// A dicrionary of parameter names to their respective default values
3535
/// to apply when the `nonOptionalChildName` is passed as concrete value.
36-
public let childDefaultValues: [String: Token]
36+
public let defaults: [String: Token]
3737
}

CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,14 @@ public let DECL_NODES: [Node] = [
639639
nameForDiagnostics: "parameter",
640640
parserFunction: "parseEnumCaseParameter",
641641
traits: ["WithTrailingComma", "WithModifiers"],
642+
rules: [
643+
ConvenienceInitRule(
644+
nonOptionalChildName: "firstName",
645+
defaults: [
646+
"colon": .colon
647+
]
648+
)
649+
],
642650
children: [
643651
Child(
644652
name: "modifiers",

CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,14 @@ public let EXPR_NODES: [Node] = [
314314
traits: [
315315
"WithTrailingComma"
316316
],
317+
rules: [
318+
ConvenienceInitRule(
319+
nonOptionalChildName: "name",
320+
defaults: [
321+
"equal": .equal
322+
]
323+
)
324+
],
317325
children: [
318326
Child(
319327
name: "specifier",
@@ -794,6 +802,15 @@ public let EXPR_NODES: [Node] = [
794802
kind: .functionCallExpr,
795803
base: .expr,
796804
nameForDiagnostics: "function call",
805+
rules: [
806+
ConvenienceInitRule(
807+
nonOptionalChildName: "arguments",
808+
defaults: [
809+
"leftParen": .leftParen,
810+
"rightParen": .rightParen
811+
]
812+
)
813+
],
797814
children: [
798815
Child(
799816
name: "calledExpression",

CodeGeneration/Sources/SyntaxSupport/Node.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public class Node {
6565

6666
/// List of convenience initializer rules for this node. CodeGeneration will
6767
/// generate a convenience initializer for each rule.
68-
public let rules: [NodeInitRule]
68+
public let rules: [ConvenienceInitRule]
6969

7070
/// If this is a layout node, return a view of the node that provides access
7171
/// to the layout-node specific properties.
@@ -116,7 +116,7 @@ public class Node {
116116
documentation: String? = nil,
117117
parserFunction: TokenSyntax? = nil,
118118
traits: [String] = [],
119-
rules: [NodeInitRule] = [],
119+
rules: [ConvenienceInitRule] = [],
120120
children: [Child] = []
121121
) {
122122
precondition(base != .syntaxCollection)
@@ -235,7 +235,7 @@ public class Node {
235235
isExperimental: Bool = false,
236236
nameForDiagnostics: String?,
237237
documentation: String? = nil,
238-
rules: [NodeInitRule] = [],
238+
rules: [ConvenienceInitRule] = [],
239239
parserFunction: TokenSyntax? = nil,
240240
elementChoices: [SyntaxNodeKind]
241241
) {

CodeGeneration/Sources/generate-swift-syntax/LayoutNode+Extensions.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ extension LayoutNode {
4141
}
4242

4343
/// Generates a convenience memberwise SyntaxNode initializer based on a
44-
/// given ``NodeInitRule``.
44+
/// given ``ConvenienceInitRule``.
4545
///
4646
/// - parameters:
47-
/// - rule: The ``NodeInitRule`` to use for generating the initializer. Applying a rule will make some children non-optional, and set default values for other children.
47+
/// - rule: The ``ConvenienceInitRule`` to use for generating the initializer. Applying a rule will make some children non-optional, and set default values for other children.
4848
/// - useDeprecatedChildName: Whether to use the deprecated child name for the initializer parameter.
4949
/// - returns:
5050
/// - ``SyntaxNodeString``: The generated initializer.
51-
func generateInitializerDeclHeader(for rule: NodeInitRule? = nil, useDeprecatedChildName: Bool = false) -> SyntaxNodeString {
51+
func generateInitializerDeclHeader(for rule: ConvenienceInitRule? = nil, useDeprecatedChildName: Bool = false) -> SyntaxNodeString {
5252
if children.isEmpty {
5353
return "public init()"
5454
}
@@ -66,13 +66,13 @@ extension LayoutNode {
6666
}
6767

6868
/// Returns whether a given child should be optional in the initializer,
69-
/// based on a provided ``NodeInitRule``.
69+
/// based on a provided ``ConvenienceInitRule``.
7070
///
7171
/// If the rule is `nil`, this func will return `nil` as well, which means
7272
/// that you should fall back to whether child is optional in the ``Node``
7373
/// definition.
7474
///
75-
func ruleBasedChildIsOptional(for child: Child, with rule: NodeInitRule?) -> Bool {
75+
func ruleBasedChildIsOptional(for child: Child, with rule: ConvenienceInitRule?) -> Bool {
7676
if let rule = rule {
7777
if rule.nonOptionalChildName == child.name {
7878
return false
@@ -85,13 +85,13 @@ extension LayoutNode {
8585
}
8686

8787
/// Returns a default value for a given child, based on a provided
88-
/// ``NodeInitRule``.
88+
/// ``ConvenienceInitRule``.
8989
///
9090
/// If the rule should not affect this child, the
9191
/// `child.defualtInitialization` will be returned.
92-
func ruleBasedChildDefaultValue(for child: Child, with rule: NodeInitRule?) -> InitializerClauseSyntax? {
92+
func ruleBasedChildDefaultValue(for child: Child, with rule: ConvenienceInitRule?) -> InitializerClauseSyntax? {
9393
if ruleBasedShouldOverrideDefault(for: child, with: rule) {
94-
if let rule, let defaultValue = rule.childDefaultValues[child.name] {
94+
if let rule, let defaultValue = rule.defaults[child.name] {
9595
return InitializerClauseSyntax(
9696
equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space),
9797
value: ExprSyntax(".\(defaultValue.spec.varOrCaseName)Token()")
@@ -111,10 +111,10 @@ extension LayoutNode {
111111
/// Returns `true` if there is a default value in the rule, or if the rule
112112
/// requires this parameter to be non-optional.
113113
/// If the rule is `nil`, it will return false.
114-
func ruleBasedShouldOverrideDefault(for child: Child, with rule: NodeInitRule?) -> Bool {
114+
func ruleBasedShouldOverrideDefault(for child: Child, with rule: ConvenienceInitRule?) -> Bool {
115115
if let rule {
116116
// If the rule provides a default for this child, override it and set the rule-based default.
117-
if rule.childDefaultValues[child.name] != nil {
117+
if rule.defaults[child.name] != nil {
118118
return true
119119
}
120120

@@ -182,9 +182,9 @@ extension LayoutNode {
182182
/// Returns a DccC comment for the parameters that get a default value,
183183
/// with their corresponding default values, for a rule-based convenience initializer
184184
/// for a node.
185-
func generateRuleBasedInitParamsDocComment(for rule: NodeInitRule) -> SwiftSyntax.Trivia {
185+
func generateRuleBasedInitParamsDocComment(for rule: ConvenienceInitRule) -> SwiftSyntax.Trivia {
186186
var params = ""
187-
for (childName, defaultValue) in rule.childDefaultValues {
187+
for (childName, defaultValue) in rule.defaults {
188188
params += " - `\(childName)`: `TokenSyntax.\(defaultValue.spec.varOrCaseName)Token()`\n"
189189
}
190190
return docCommentTrivia(from: params)

Sources/SwiftSyntax/Convenience.swift

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -10,64 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
extension ClosureCaptureSyntax {
14-
15-
/// Creates a ``ClosureCaptureSyntax`` with a `name`, and automatically adds an `equal` token to it since the name is non-optional.
16-
///
17-
/// - SeeAlso: ``ClosureCaptureSyntax/init(leadingTrivia:_:specifier:_:name:_:equal:_:expression:_:trailingComma:_:trailingTrivia:)``.
18-
///
19-
public init(
20-
leadingTrivia: Trivia? = nil,
21-
specifier: ClosureCaptureSpecifierSyntax? = nil,
22-
name: TokenSyntax,
23-
equal: TokenSyntax = TokenSyntax.equalToken(),
24-
expression: some ExprSyntaxProtocol,
25-
trailingComma: TokenSyntax? = nil,
26-
trailingTrivia: Trivia? = nil
27-
) {
28-
self.init(
29-
leadingTrivia: leadingTrivia,
30-
specifier: specifier,
31-
name: name as TokenSyntax?,
32-
equal: equal,
33-
expression: expression,
34-
trailingComma: trailingComma,
35-
trailingTrivia: trailingTrivia
36-
)
37-
}
38-
}
39-
40-
extension EnumCaseParameterSyntax {
41-
42-
/// Creates an ``EnumCaseParameterSyntax`` with a `firstName`, and automatically adds a `colon` to it.
43-
///
44-
/// - SeeAlso: For more information on the arguments, see ``EnumCaseParameterSyntax/init(leadingTrivia:_:modifiers:_:firstName:_:secondName:_:colon:_:type:_:defaultArgument:_:trailingComma:_:trailingTrivia:)``
45-
///
46-
public init(
47-
leadingTrivia: Trivia? = nil,
48-
modifiers: DeclModifierListSyntax = [],
49-
firstName: TokenSyntax,
50-
secondName: TokenSyntax? = nil,
51-
colon: TokenSyntax = TokenSyntax.colonToken(),
52-
type: some TypeSyntaxProtocol,
53-
defaultValue: InitializerClauseSyntax? = nil,
54-
trailingComma: TokenSyntax? = nil,
55-
trailingTrivia: Trivia? = nil
56-
) {
57-
self.init(
58-
leadingTrivia: leadingTrivia,
59-
modifiers: modifiers,
60-
firstName: firstName as TokenSyntax?,
61-
secondName: secondName,
62-
colon: colon,
63-
type: type,
64-
defaultValue: defaultValue,
65-
trailingComma: trailingComma,
66-
trailingTrivia: trailingTrivia
67-
)
68-
}
69-
}
70-
7113
extension MemberAccessExprSyntax {
7214
/// Creates a new ``MemberAccessExprSyntax`` where the accessed member is represented by
7315
/// an identifier without specifying argument labels.

Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesAB.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2578,8 +2578,8 @@ public struct AttributeSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxNodePr
25782578
/// A convenience initializer for ``AttributeSyntax``
25792579
/// that takes a non-optional value for `arguments` parameter,
25802580
/// and adds the following default values:
2581-
/// - `rightParen`: `TokenSyntax.rightParenToken()`
25822581
/// - `leftParen`: `TokenSyntax.leftParenToken()`
2582+
/// - `rightParen`: `TokenSyntax.rightParenToken()`
25832583
///
25842584
public init(
25852585
leadingTrivia: Trivia? = nil,

Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesC.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1585,6 +1585,32 @@ public struct ClosureCaptureSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxN
15851585
self._syntaxNode = Syntax(data)
15861586
}
15871587

1588+
/// A convenience initializer for ``ClosureCaptureSyntax``
1589+
/// that takes a non-optional value for `name` parameter,
1590+
/// and adds the following default values:
1591+
/// - `equal`: `TokenSyntax.equalToken()`
1592+
///
1593+
public init(
1594+
leadingTrivia: Trivia? = nil,
1595+
specifier: ClosureCaptureSpecifierSyntax? = nil,
1596+
name: TokenSyntax,
1597+
equal: TokenSyntax? = .equalToken(),
1598+
expression: some ExprSyntaxProtocol,
1599+
trailingComma: TokenSyntax? = nil,
1600+
trailingTrivia: Trivia? = nil
1601+
1602+
) {
1603+
self.init(
1604+
leadingTrivia: leadingTrivia,
1605+
specifier: specifier,
1606+
name: name as TokenSyntax?,
1607+
equal: equal,
1608+
expression: expression,
1609+
trailingComma: trailingComma,
1610+
trailingTrivia: trailingTrivia
1611+
)
1612+
}
1613+
15881614
/// - Parameters:
15891615
/// - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored.
15901616
/// - trailingTrivia: Trivia to be appended to the trailing trivia of the node’s last token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored.

Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesEF.swift

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,36 @@ public struct EnumCaseParameterSyntax: SyntaxProtocol, SyntaxHashable, _LeafSynt
982982
self._syntaxNode = Syntax(data)
983983
}
984984

985+
/// A convenience initializer for ``EnumCaseParameterSyntax``
986+
/// that takes a non-optional value for `firstName` parameter,
987+
/// and adds the following default values:
988+
/// - `colon`: `TokenSyntax.colonToken()`
989+
///
990+
public init(
991+
leadingTrivia: Trivia? = nil,
992+
modifiers: DeclModifierListSyntax = [],
993+
firstName: TokenSyntax,
994+
secondName: TokenSyntax? = nil,
995+
colon: TokenSyntax? = .colonToken(),
996+
type: some TypeSyntaxProtocol,
997+
defaultValue: InitializerClauseSyntax? = nil,
998+
trailingComma: TokenSyntax? = nil,
999+
trailingTrivia: Trivia? = nil
1000+
1001+
) {
1002+
self.init(
1003+
leadingTrivia: leadingTrivia,
1004+
modifiers: modifiers,
1005+
firstName: firstName as TokenSyntax?,
1006+
secondName: secondName,
1007+
colon: colon,
1008+
type: type,
1009+
defaultValue: defaultValue,
1010+
trailingComma: trailingComma,
1011+
trailingTrivia: trailingTrivia
1012+
)
1013+
}
1014+
9851015
/// - Parameters:
9861016
/// - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored.
9871017
/// - colon: If the parameter has a label, the colon separating the label from the type.
@@ -3128,6 +3158,35 @@ public struct FunctionCallExprSyntax: ExprSyntaxProtocol, SyntaxHashable, _LeafE
31283158
self._syntaxNode = Syntax(data)
31293159
}
31303160

3161+
/// A convenience initializer for ``FunctionCallExprSyntax``
3162+
/// that takes a non-optional value for `arguments` parameter,
3163+
/// and adds the following default values:
3164+
/// - `rightParen`: `TokenSyntax.rightParenToken()`
3165+
/// - `leftParen`: `TokenSyntax.leftParenToken()`
3166+
///
3167+
public init(
3168+
leadingTrivia: Trivia? = nil,
3169+
calledExpression: some ExprSyntaxProtocol,
3170+
leftParen: TokenSyntax? = .leftParenToken(),
3171+
arguments: LabeledExprListSyntax,
3172+
rightParen: TokenSyntax? = .rightParenToken(),
3173+
trailingClosure: ClosureExprSyntax? = nil,
3174+
additionalTrailingClosures: MultipleTrailingClosureElementListSyntax = [],
3175+
trailingTrivia: Trivia? = nil
3176+
3177+
) {
3178+
self.init(
3179+
leadingTrivia: leadingTrivia,
3180+
calledExpression: calledExpression,
3181+
leftParen: leftParen,
3182+
arguments: arguments as LabeledExprListSyntax?,
3183+
rightParen: rightParen,
3184+
trailingClosure: trailingClosure,
3185+
additionalTrailingClosures: additionalTrailingClosures,
3186+
trailingTrivia: trailingTrivia
3187+
)
3188+
}
3189+
31313190
/// - Parameters:
31323191
/// - leadingTrivia: Trivia to be prepended to the leading trivia of the node’s first token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored.
31333192
/// - trailingTrivia: Trivia to be appended to the trailing trivia of the node’s last token. If the node is empty, there is no token to attach the trivia to and the parameter is ignored.

0 commit comments

Comments
 (0)