@@ -17,7 +17,8 @@ import Utils
17
17
18
18
extension LayoutNode {
19
19
20
- func makeChildParamType( for child: Child , isOptional: Bool = false ) -> TypeSyntax {
20
+ /// Returns Child parameter type as a ``TypeSyntax``.
21
+ func generateChildParameterType( for child: Child , isOptional: Bool = false ) -> TypeSyntax {
21
22
var paramType : TypeSyntax
22
23
23
24
if !child. kind. isNodeChoicesEmpty {
@@ -39,17 +40,21 @@ extension LayoutNode {
39
40
return paramType
40
41
}
41
42
42
- /// Generates a memberwise SyntaxNode initializer `SyntaxNodeString`.
43
+ /// Generates a convenience memberwise SyntaxNode initializer based on a
44
+ /// given ``NodeInitRule``.
43
45
///
44
46
/// - parameters:
45
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.
46
48
/// - useDeprecatedChildName: Whether to use the deprecated child name for the initializer parameter.
49
+ /// - returns:
50
+ /// - ``SyntaxNodeString``: The generated initializer.
47
51
func generateInitializerDeclHeader( for rule: NodeInitRule ? = nil , useDeprecatedChildName: Bool = false ) -> SyntaxNodeString {
48
52
if children. isEmpty {
49
53
return " public init() "
50
54
}
51
55
52
- func childParameterName( for child: Child ) -> TokenSyntax {
56
+ /// Returns the child paramter name.
57
+ func generateChildParameterName( for child: Child ) -> TokenSyntax {
53
58
let parameterName : TokenSyntax
54
59
55
60
if useDeprecatedChildName, let deprecatedVarName = child. deprecatedVarName {
@@ -60,29 +65,52 @@ extension LayoutNode {
60
65
return parameterName
61
66
}
62
67
63
- func ruleBasedChildIsOptional( for child: Child , with rule: NodeInitRule ? ) -> Bool ? {
68
+ /// Returns whether a given child should be optional in the initializer,
69
+ /// based on a provided ``NodeInitRule``.
70
+ ///
71
+ /// If the rule is `nil`, this func will return `nil` as well, which means
72
+ /// that you should fall back to whether child is optional in the ``Node``
73
+ /// definition.
74
+ ///
75
+ func ruleBasedChildIsOptional( for child: Child , with rule: NodeInitRule ? ) -> Bool {
64
76
if let rule = rule {
65
77
if rule. nonOptionalChildName == child. name {
66
78
return false
67
79
} else {
68
80
return child. isOptional
69
81
}
70
82
} else {
71
- return nil
83
+ return child . isOptional
72
84
}
73
85
}
74
86
87
+ /// Returns a default value for a given child, based on a provided
88
+ /// ``NodeInitRule``.
89
+ ///
90
+ /// If the rule should not affect this child, the
91
+ /// `child.defualtInitialization` will be returned.
75
92
func ruleBasedChildDefaultValue( for child: Child , with rule: NodeInitRule ? ) -> InitializerClauseSyntax ? {
76
- if let rule, let defaultValue = rule. childDefaultValues [ child. name] {
77
- return InitializerClauseSyntax (
78
- equal: . equalToken( leadingTrivia: . space, trailingTrivia: . space) ,
79
- value: ExprSyntax ( " . \( defaultValue. spec. varOrCaseName) Token() " )
80
- )
93
+ if ruleBasedShouldOverrideDefault ( for: child, with: rule) {
94
+ if let rule, let defaultValue = rule. childDefaultValues [ child. name] {
95
+ return InitializerClauseSyntax (
96
+ equal: . equalToken( leadingTrivia: . space, trailingTrivia: . space) ,
97
+ value: ExprSyntax ( " . \( defaultValue. spec. varOrCaseName) Token() " )
98
+ )
99
+ } else {
100
+ return nil
101
+ }
81
102
} else {
82
- return nil
103
+ return child . defaultInitialization
83
104
}
105
+
84
106
}
85
107
108
+ /// Should the convenience initializer override the default value of a given
109
+ /// child?
110
+ ///
111
+ /// Returns `true` if there is a default value in the rule, or if the rule
112
+ /// requires this parameter to be non-optional.
113
+ /// If the rule is `nil`, it will return false.
86
114
func ruleBasedShouldOverrideDefault( for child: Child , with rule: NodeInitRule ? ) -> Bool {
87
115
if let rule {
88
116
// If the rule provides a default for this child, override it and set the rule-based default.
@@ -97,33 +125,47 @@ extension LayoutNode {
97
125
}
98
126
}
99
127
100
- func createFunctionParameterSyntax( for child: Child , overrideOptional: Bool ? = nil , shouldOverrideDefault: Bool = false , overrideDefaultValue: InitializerClauseSyntax ? = nil ) -> FunctionParameterSyntax {
101
128
102
- let parameterName = childParameterName ( for: child)
129
+ /// Generates a ``FunctionParameterSyntax`` for a given ``Child`` of this node.
130
+ ///
131
+ /// - parameters:
132
+ /// - child: The ``Child`` to generate the parameter for.
133
+ /// - isOptional: Is the parameter optional?
134
+ ///
135
+ func generateInitFunctionParameterSyntax(
136
+ for child: Child ,
137
+ isOptional: Bool ,
138
+ defaultValue: InitializerClauseSyntax ? = nil
139
+ ) -> FunctionParameterSyntax {
140
+ let parameterName = generateChildParameterName ( for: child)
103
141
104
142
return FunctionParameterSyntax (
105
143
leadingTrivia: . newline,
106
144
firstName: child. isUnexpectedNodes ? . wildcardToken( trailingTrivia: . space) : parameterName,
107
145
secondName: child. isUnexpectedNodes ? parameterName : nil ,
108
146
colon: . colonToken( ) ,
109
- type: makeChildParamType ( for: child, isOptional: overrideOptional ?? child . isOptional) ,
110
- defaultValue: shouldOverrideDefault ? overrideDefaultValue : child . defaultInitialization
147
+ type: generateChildParameterType ( for: child, isOptional: isOptional) ,
148
+ defaultValue: defaultValue
111
149
)
112
150
}
113
151
152
+ // Iterate over all children including unexpected, or only over expected children of the Node.
153
+ //
114
154
// For convenience initializers, we don't need unexpected tokens in the arguments list
115
155
// because convenience initializers are meant to be used bo developers manually
116
- // hence there should be no unexpected tokens
156
+ // hence there should be no unexpected tokens.
117
157
let childrenToIterate = rule != nil ? nonUnexpectedChildren : children
118
158
159
+ // Iterate over the selected children, and make FunctionParameterSyntax for each of them.
119
160
let params = FunctionParameterListSyntax {
120
161
FunctionParameterSyntax ( " leadingTrivia: Trivia? = nil " )
121
162
122
163
for child in childrenToIterate {
123
- createFunctionParameterSyntax ( for: child,
124
- overrideOptional: ruleBasedChildIsOptional ( for: child, with: rule) ,
125
- shouldOverrideDefault: ruleBasedShouldOverrideDefault ( for: child, with: rule) ,
126
- overrideDefaultValue: ruleBasedChildDefaultValue ( for: child, with: rule) )
164
+ generateInitFunctionParameterSyntax (
165
+ for: child,
166
+ isOptional: ruleBasedChildIsOptional ( for: child, with: rule) ,
167
+ defaultValue: ruleBasedChildDefaultValue ( for: child, with: rule)
168
+ )
127
169
}
128
170
129
171
FunctionParameterSyntax ( " trailingTrivia: Trivia? = nil " )
@@ -137,14 +179,18 @@ extension LayoutNode {
137
179
"""
138
180
}
139
181
140
- func generateRuleBasedDefaultValuesDocComment( for rule: NodeInitRule ) -> SwiftSyntax . Trivia {
182
+ /// Returns a DccC comment for the parameters that get a default value,
183
+ /// with their corresponding default values, for a rule-based convenience initializer
184
+ /// for a node.
185
+ func generateRuleBasedInitParamsDocComment( for rule: NodeInitRule ) -> SwiftSyntax . Trivia {
141
186
var params = " "
142
187
for (childName, defaultValue) in rule. childDefaultValues {
143
188
params += " - ` \( childName) `: `TokenSyntax. \( defaultValue. spec. varOrCaseName) Token()` \n "
144
189
}
145
190
return docCommentTrivia ( from: params)
146
191
}
147
192
193
+ /// Returns a DocC comment for the full memberwise initializer for this node.
148
194
func generateInitializerDocComment( ) -> SwiftSyntax . Trivia {
149
195
func generateParamDocComment( for child: Child ) -> String ? {
150
196
if child. documentationAbstract. isEmpty {
0 commit comments