@@ -16,12 +16,65 @@ import SyntaxSupport
16
16
import Utils
17
17
18
18
extension LayoutNode {
19
- func generateInitializerDeclHeader( useDeprecatedChildName: Bool = false ) -> SyntaxNodeString {
19
+ /// Generates a memberwise SyntaxNode initializer `SyntaxNodeString`.
20
+ ///
21
+ /// - parameters:
22
+ /// - 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.
23
+ /// - useDeprecatedChildName: Whether to use the deprecated child name for the initializer parameter.
24
+ func generateInitializerDeclHeader( for rule: NodeInitRule ? = nil , useDeprecatedChildName: Bool = false ) -> SyntaxNodeString {
20
25
if children. isEmpty {
21
26
return " public init() "
22
27
}
23
28
24
- func createFunctionParameterSyntax( for child: Child ) -> FunctionParameterSyntax {
29
+ func childParameterName( for child: Child ) -> TokenSyntax {
30
+ let parameterName : TokenSyntax
31
+
32
+ if useDeprecatedChildName, let deprecatedVarName = child. deprecatedVarName {
33
+ parameterName = deprecatedVarName
34
+ } else {
35
+ parameterName = child. varOrCaseName
36
+ }
37
+ return parameterName
38
+ }
39
+
40
+ func ruleBasedChildIsOptional( for child: Child , with rule: NodeInitRule ? ) -> Bool ? {
41
+ if let rule = rule {
42
+ if rule. nonOptionalChildName == child. name {
43
+ return false
44
+ } else {
45
+ return child. isOptional
46
+ }
47
+ } else {
48
+ return nil
49
+ }
50
+ }
51
+
52
+ func ruleBasedChildDefaultValue( for child: Child , with rule: NodeInitRule ? ) -> InitializerClauseSyntax ? {
53
+ if let rule, let defaultValue = rule. childDefaultValues [ child. name] {
54
+ return InitializerClauseSyntax (
55
+ equal: . equalToken( leadingTrivia: . space, trailingTrivia: . space) ,
56
+ value: ExprSyntax ( " . \( defaultValue. spec. varOrCaseName) Token() " )
57
+ )
58
+ } else {
59
+ return nil
60
+ }
61
+ }
62
+
63
+ func ruleBasedShouldOverrideDefault( for child: Child , with rule: NodeInitRule ? ) -> Bool {
64
+ if let rule {
65
+ // If the rule provides a default for this child, override it and set the rule-based default.
66
+ if rule. childDefaultValues [ child. name] != nil {
67
+ return true
68
+ }
69
+
70
+ // For the non-optional rule-based parameter, strip the default value (override, but there will be no default)
71
+ return rule. nonOptionalChildName == child. name
72
+ } else {
73
+ return false
74
+ }
75
+ }
76
+
77
+ func createFunctionParameterSyntax( for child: Child , overrideOptional: Bool ? = nil , shouldOverrideDefault: Bool = false , overrideDefaultValue: InitializerClauseSyntax ? = nil ) -> FunctionParameterSyntax {
25
78
var paramType : TypeSyntax
26
79
if !child. kind. isNodeChoicesEmpty {
27
80
paramType = " \( child. syntaxChoicesType) "
@@ -31,37 +84,34 @@ extension LayoutNode {
31
84
paramType = child. syntaxNodeKind. syntaxType
32
85
}
33
86
34
- if child. isOptional {
87
+ if overrideOptional ?? child. isOptional {
35
88
if paramType. is ( SomeOrAnyTypeSyntax . self) {
36
89
paramType = " ( \( paramType) )? "
37
90
} else {
38
91
paramType = " \( paramType) ? "
39
92
}
40
93
}
41
94
42
- let parameterName : TokenSyntax
43
-
44
- if useDeprecatedChildName, let deprecatedVarName = child. deprecatedVarName {
45
- parameterName = deprecatedVarName
46
- } else {
47
- parameterName = child. varOrCaseName
48
- }
95
+ let parameterName = childParameterName ( for: child)
49
96
50
97
return FunctionParameterSyntax (
51
98
leadingTrivia: . newline,
52
99
firstName: child. isUnexpectedNodes ? . wildcardToken( trailingTrivia: . space) : parameterName,
53
100
secondName: child. isUnexpectedNodes ? parameterName : nil ,
54
101
colon: . colonToken( ) ,
55
102
type: paramType,
56
- defaultValue: child. defaultInitialization
103
+ defaultValue: shouldOverrideDefault ? overrideDefaultValue : child. defaultInitialization
57
104
)
58
105
}
59
106
60
107
let params = FunctionParameterListSyntax {
61
108
FunctionParameterSyntax ( " leadingTrivia: Trivia? = nil " )
62
109
63
110
for child in children {
64
- createFunctionParameterSyntax ( for: child)
111
+ createFunctionParameterSyntax ( for: child,
112
+ overrideOptional: ruleBasedChildIsOptional ( for: child, with: rule) ,
113
+ shouldOverrideDefault: ruleBasedShouldOverrideDefault ( for: child, with: rule) ,
114
+ overrideDefaultValue: ruleBasedChildDefaultValue ( for: child, with: rule) )
65
115
}
66
116
67
117
FunctionParameterSyntax ( " trailingTrivia: Trivia? = nil " )
@@ -75,6 +125,14 @@ extension LayoutNode {
75
125
"""
76
126
}
77
127
128
+ func generateRuleBasedDefaultValuesDocComment( for rule: NodeInitRule ) -> SwiftSyntax . Trivia {
129
+ var params = " "
130
+ for (childName, defaultValue) in rule. childDefaultValues {
131
+ params += " - ` \( childName) `: `TokenSyntax. \( defaultValue. spec. varOrCaseName) Token()` \n "
132
+ }
133
+ return docCommentTrivia ( from: params)
134
+ }
135
+
78
136
func generateInitializerDocComment( ) -> SwiftSyntax . Trivia {
79
137
func generateParamDocComment( for child: Child ) -> String ? {
80
138
if child. documentationAbstract. isEmpty {
0 commit comments