@@ -16,12 +16,65 @@ import SyntaxSupport
1616import Utils
1717
1818extension 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 {
2025 if children. isEmpty {
2126 return " public init() "
2227 }
2328
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 {
2578 var paramType : TypeSyntax
2679 if !child. kind. isNodeChoicesEmpty {
2780 paramType = " \( child. syntaxChoicesType) "
@@ -31,37 +84,34 @@ extension LayoutNode {
3184 paramType = child. syntaxNodeKind. syntaxType
3285 }
3386
34- if child. isOptional {
87+ if overrideOptional ?? child. isOptional {
3588 if paramType. is ( SomeOrAnyTypeSyntax . self) {
3689 paramType = " ( \( paramType) )? "
3790 } else {
3891 paramType = " \( paramType) ? "
3992 }
4093 }
4194
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)
4996
5097 return FunctionParameterSyntax (
5198 leadingTrivia: . newline,
5299 firstName: child. isUnexpectedNodes ? . wildcardToken( trailingTrivia: . space) : parameterName,
53100 secondName: child. isUnexpectedNodes ? parameterName : nil ,
54101 colon: . colonToken( ) ,
55102 type: paramType,
56- defaultValue: child. defaultInitialization
103+ defaultValue: shouldOverrideDefault ? overrideDefaultValue : child. defaultInitialization
57104 )
58105 }
59106
60107 let params = FunctionParameterListSyntax {
61108 FunctionParameterSyntax ( " leadingTrivia: Trivia? = nil " )
62109
63110 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) )
65115 }
66116
67117 FunctionParameterSyntax ( " trailingTrivia: Trivia? = nil " )
@@ -75,6 +125,14 @@ extension LayoutNode {
75125 """
76126 }
77127
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+
78136 func generateInitializerDocComment( ) -> SwiftSyntax . Trivia {
79137 func generateParamDocComment( for child: Child ) -> String ? {
80138 if child. documentationAbstract. isEmpty {
0 commit comments