Skip to content

Commit 453e9bc

Browse files
committed
Emit trailing commas in ResultBuilders
1 parent 9efbb3f commit 453e9bc

File tree

10 files changed

+545
-103
lines changed

10 files changed

+545
-103
lines changed

Sources/SwiftSyntaxBuilder/BuildableCollectionNodes.swift.gyb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ public struct ${type.buildable()}: ExpressibleByArrayLiteral, SyntaxBuildable, $
3535
public init(_ elements: [${element_type.expressible_as()}]) {
3636
% if element_type.is_token():
3737
self.elements = elements
38+
% elif element_type.has_with_trailing_comma_trait():
39+
if let last = elements.last {
40+
self.elements =
41+
elements.dropLast(1).map({ $0.create${element_type.buildable_base_name()}(isLastElement: false) })
42+
+ [last.create${element_type.buildable_base_name()}(isLastElement: true)]
43+
} else {
44+
self.elements = []
45+
}
3846
% else:
3947
self.elements = elements.map { $0.create${element_type.buildable_base_name()}() }
4048
% end

Sources/SwiftSyntaxBuilder/BuildableNodes.swift.gyb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,27 @@ public struct ${type.buildable()}: ${base_type.buildable()}, ${type.expressible_
111111
}
112112

113113
/// Conformance to `${type.expressible_as()}`.
114+
%{
115+
create_trailing_comma_init = False
116+
trailing_comma_init_args = []
117+
if node.node.traits and 'WithTrailingComma' in node.node.traits:
118+
create_trailing_comma_init = True
119+
for child in children:
120+
if child.name() == 'trailingComma':
121+
trailing_comma_init_args.append('%s: isLastElement ? nil : .comma' % (child.name()))
122+
else:
123+
trailing_comma_init_args.append('%s: %s' % (child.name(), child.name()))
124+
}%
125+
% if create_trailing_comma_init:
126+
public func create${type.buildable_base_name()}(isLastElement: Bool?) -> ${type.buildable()} {
127+
if let isLastElement = isLastElement {
128+
return Self.init(
129+
${',\n '.join(trailing_comma_init_args)}
130+
)
131+
}
132+
% else:
114133
public func create${type.buildable_base_name()}() -> ${type.buildable()} {
134+
% end
115135
return self
116136
}
117137

Sources/SwiftSyntaxBuilder/ExpressibleAsProtocols.swift.gyb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ import SwiftSyntax
2929
% conformances = type.generated_expressible_as_conformances()
3030
% implied_conformances = type.implied_expressible_as_conformances() # Exclude conformances that are already implied because otherwise Swift throws a warning.
3131
public protocol ${type.expressible_as()}${conformance_clause([conforming_to.expressible_as() for conforming_to in conformances if conforming_to not in implied_conformances])} {
32+
% if type.has_with_trailing_comma_trait():
33+
func create${type.buildable_base_name()}(isLastElement: Bool?) -> ${type.buildable()}
34+
% else:
3235
func create${type.buildable_base_name()}() -> ${type.buildable()}
36+
% end
3337
}
3438

3539
% if conformances:
@@ -43,13 +47,22 @@ public extension ${type.expressible_as()} {
4347
% for conformance in type.convertible_to_types():
4448
% param = SyntaxBuildableNode(conformance).single_non_defaulted_child()
4549
/// Conformance to `${conformance.expressible_as()}`.
50+
% if conformance.has_with_trailing_comma_trait():
51+
func create${conformance.buildable_base_name()}(isLastElement: Bool?) -> ${conformance.buildable()} {
52+
return ${conformance.buildable()}(${param.name()}: self)
53+
% else:
4654
func create${conformance.buildable_base_name()}() -> ${conformance.buildable()} {
4755
return ${conformance.buildable()}(${param.name()}: self)
56+
% end
4857
}
4958
% end
5059
% if base_type and base_type.base_name() != 'SyntaxCollection':
5160
func create${base_type.buildable_base_name()}() -> ${base_type.buildable()} {
61+
% if type.has_with_trailing_comma_trait():
62+
return self.create${type.buildable_base_name()}(isLastElement: nil)
63+
% else:
5264
return self.create${type.buildable_base_name()}()
65+
% end
5366
}
5467
% end
5568
}

Sources/SwiftSyntaxBuilder/ResultBuilders.swift.gyb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@ public struct ${type.result_builder()} {
8585
public static func buildFinalResult(_ component: Component) -> FinalResult {
8686
% if element_type.is_token():
8787
return .init(component)
88+
% elif element_type.has_with_trailing_comma_trait():
89+
guard let last = component.last else {
90+
return .init([])
91+
}
92+
return .init(
93+
component.dropLast(1).map({ $0.create${element_type.buildable()}(isLastElement: false) })
94+
+ [last.create${element_type.buildable()}(isLastElement: true)])
8895
% else:
8996
return .init(component.map { $0.create${element_type.buildable()}() })
9097
% end

Sources/SwiftSyntaxBuilder/gyb_generated/BuildableCollectionNodes.swift

Lines changed: 133 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,13 @@ public struct TupleExprElementList: ExpressibleByArrayLiteral, SyntaxBuildable,
6565
/// - Parameters:
6666
/// - elements: A list of `ExpressibleAsTupleExprElement`
6767
public init(_ elements: [ExpressibleAsTupleExprElement]) {
68-
self.elements = elements.map { $0.createTupleExprElement() }
68+
if let last = elements.last {
69+
self.elements =
70+
elements.dropLast(1).map({ $0.createTupleExprElement(isLastElement: false) })
71+
+ [last.createTupleExprElement(isLastElement: true)]
72+
} else {
73+
self.elements = []
74+
}
6975
}
7076

7177
public init(arrayLiteral elements: ExpressibleAsTupleExprElement...) {
@@ -108,7 +114,13 @@ public struct ArrayElementList: ExpressibleByArrayLiteral, SyntaxBuildable, Expr
108114
/// - Parameters:
109115
/// - elements: A list of `ExpressibleAsArrayElement`
110116
public init(_ elements: [ExpressibleAsArrayElement]) {
111-
self.elements = elements.map { $0.createArrayElement() }
117+
if let last = elements.last {
118+
self.elements =
119+
elements.dropLast(1).map({ $0.createArrayElement(isLastElement: false) })
120+
+ [last.createArrayElement(isLastElement: true)]
121+
} else {
122+
self.elements = []
123+
}
112124
}
113125

114126
public init(arrayLiteral elements: ExpressibleAsArrayElement...) {
@@ -151,7 +163,13 @@ public struct DictionaryElementList: ExpressibleByArrayLiteral, SyntaxBuildable,
151163
/// - Parameters:
152164
/// - elements: A list of `ExpressibleAsDictionaryElement`
153165
public init(_ elements: [ExpressibleAsDictionaryElement]) {
154-
self.elements = elements.map { $0.createDictionaryElement() }
166+
if let last = elements.last {
167+
self.elements =
168+
elements.dropLast(1).map({ $0.createDictionaryElement(isLastElement: false) })
169+
+ [last.createDictionaryElement(isLastElement: true)]
170+
} else {
171+
self.elements = []
172+
}
155173
}
156174

157175
public init(arrayLiteral elements: ExpressibleAsDictionaryElement...) {
@@ -323,7 +341,13 @@ public struct ClosureCaptureItemList: ExpressibleByArrayLiteral, SyntaxBuildable
323341
/// - Parameters:
324342
/// - elements: A list of `ExpressibleAsClosureCaptureItem`
325343
public init(_ elements: [ExpressibleAsClosureCaptureItem]) {
326-
self.elements = elements.map { $0.createClosureCaptureItem() }
344+
if let last = elements.last {
345+
self.elements =
346+
elements.dropLast(1).map({ $0.createClosureCaptureItem(isLastElement: false) })
347+
+ [last.createClosureCaptureItem(isLastElement: true)]
348+
} else {
349+
self.elements = []
350+
}
327351
}
328352

329353
public init(arrayLiteral elements: ExpressibleAsClosureCaptureItem...) {
@@ -366,7 +390,13 @@ public struct ClosureParamList: ExpressibleByArrayLiteral, SyntaxBuildable, Expr
366390
/// - Parameters:
367391
/// - elements: A list of `ExpressibleAsClosureParam`
368392
public init(_ elements: [ExpressibleAsClosureParam]) {
369-
self.elements = elements.map { $0.createClosureParam() }
393+
if let last = elements.last {
394+
self.elements =
395+
elements.dropLast(1).map({ $0.createClosureParam(isLastElement: false) })
396+
+ [last.createClosureParam(isLastElement: true)]
397+
} else {
398+
self.elements = []
399+
}
370400
}
371401

372402
public init(arrayLiteral elements: ExpressibleAsClosureParam...) {
@@ -495,7 +525,13 @@ public struct FunctionParameterList: ExpressibleByArrayLiteral, SyntaxBuildable,
495525
/// - Parameters:
496526
/// - elements: A list of `ExpressibleAsFunctionParameter`
497527
public init(_ elements: [ExpressibleAsFunctionParameter]) {
498-
self.elements = elements.map { $0.createFunctionParameter() }
528+
if let last = elements.last {
529+
self.elements =
530+
elements.dropLast(1).map({ $0.createFunctionParameter(isLastElement: false) })
531+
+ [last.createFunctionParameter(isLastElement: true)]
532+
} else {
533+
self.elements = []
534+
}
499535
}
500536

501537
public init(arrayLiteral elements: ExpressibleAsFunctionParameter...) {
@@ -581,7 +617,13 @@ public struct InheritedTypeList: ExpressibleByArrayLiteral, SyntaxBuildable, Exp
581617
/// - Parameters:
582618
/// - elements: A list of `ExpressibleAsInheritedType`
583619
public init(_ elements: [ExpressibleAsInheritedType]) {
584-
self.elements = elements.map { $0.createInheritedType() }
620+
if let last = elements.last {
621+
self.elements =
622+
elements.dropLast(1).map({ $0.createInheritedType(isLastElement: false) })
623+
+ [last.createInheritedType(isLastElement: true)]
624+
} else {
625+
self.elements = []
626+
}
585627
}
586628

587629
public init(arrayLiteral elements: ExpressibleAsInheritedType...) {
@@ -796,7 +838,13 @@ public struct PatternBindingList: ExpressibleByArrayLiteral, SyntaxBuildable, Ex
796838
/// - Parameters:
797839
/// - elements: A list of `ExpressibleAsPatternBinding`
798840
public init(_ elements: [ExpressibleAsPatternBinding]) {
799-
self.elements = elements.map { $0.createPatternBinding() }
841+
if let last = elements.last {
842+
self.elements =
843+
elements.dropLast(1).map({ $0.createPatternBinding(isLastElement: false) })
844+
+ [last.createPatternBinding(isLastElement: true)]
845+
} else {
846+
self.elements = []
847+
}
800848
}
801849

802850
public init(arrayLiteral elements: ExpressibleAsPatternBinding...) {
@@ -839,7 +887,13 @@ public struct EnumCaseElementList: ExpressibleByArrayLiteral, SyntaxBuildable, E
839887
/// - Parameters:
840888
/// - elements: A list of `ExpressibleAsEnumCaseElement`
841889
public init(_ elements: [ExpressibleAsEnumCaseElement]) {
842-
self.elements = elements.map { $0.createEnumCaseElement() }
890+
if let last = elements.last {
891+
self.elements =
892+
elements.dropLast(1).map({ $0.createEnumCaseElement(isLastElement: false) })
893+
+ [last.createEnumCaseElement(isLastElement: true)]
894+
} else {
895+
self.elements = []
896+
}
843897
}
844898

845899
public init(arrayLiteral elements: ExpressibleAsEnumCaseElement...) {
@@ -1220,7 +1274,13 @@ public struct DifferentiabilityParamList: ExpressibleByArrayLiteral, SyntaxBuild
12201274
/// - Parameters:
12211275
/// - elements: A list of `ExpressibleAsDifferentiabilityParam`
12221276
public init(_ elements: [ExpressibleAsDifferentiabilityParam]) {
1223-
self.elements = elements.map { $0.createDifferentiabilityParam() }
1277+
if let last = elements.last {
1278+
self.elements =
1279+
elements.dropLast(1).map({ $0.createDifferentiabilityParam(isLastElement: false) })
1280+
+ [last.createDifferentiabilityParam(isLastElement: true)]
1281+
} else {
1282+
self.elements = []
1283+
}
12241284
}
12251285

12261286
public init(arrayLiteral elements: ExpressibleAsDifferentiabilityParam...) {
@@ -1392,7 +1452,13 @@ public struct CaseItemList: ExpressibleByArrayLiteral, SyntaxBuildable, Expressi
13921452
/// - Parameters:
13931453
/// - elements: A list of `ExpressibleAsCaseItem`
13941454
public init(_ elements: [ExpressibleAsCaseItem]) {
1395-
self.elements = elements.map { $0.createCaseItem() }
1455+
if let last = elements.last {
1456+
self.elements =
1457+
elements.dropLast(1).map({ $0.createCaseItem(isLastElement: false) })
1458+
+ [last.createCaseItem(isLastElement: true)]
1459+
} else {
1460+
self.elements = []
1461+
}
13961462
}
13971463

13981464
public init(arrayLiteral elements: ExpressibleAsCaseItem...) {
@@ -1435,7 +1501,13 @@ public struct CatchItemList: ExpressibleByArrayLiteral, SyntaxBuildable, Express
14351501
/// - Parameters:
14361502
/// - elements: A list of `ExpressibleAsCatchItem`
14371503
public init(_ elements: [ExpressibleAsCatchItem]) {
1438-
self.elements = elements.map { $0.createCatchItem() }
1504+
if let last = elements.last {
1505+
self.elements =
1506+
elements.dropLast(1).map({ $0.createCatchItem(isLastElement: false) })
1507+
+ [last.createCatchItem(isLastElement: true)]
1508+
} else {
1509+
self.elements = []
1510+
}
14391511
}
14401512

14411513
public init(arrayLiteral elements: ExpressibleAsCatchItem...) {
@@ -1478,7 +1550,13 @@ public struct ConditionElementList: ExpressibleByArrayLiteral, SyntaxBuildable,
14781550
/// - Parameters:
14791551
/// - elements: A list of `ExpressibleAsConditionElement`
14801552
public init(_ elements: [ExpressibleAsConditionElement]) {
1481-
self.elements = elements.map { $0.createConditionElement() }
1553+
if let last = elements.last {
1554+
self.elements =
1555+
elements.dropLast(1).map({ $0.createConditionElement(isLastElement: false) })
1556+
+ [last.createConditionElement(isLastElement: true)]
1557+
} else {
1558+
self.elements = []
1559+
}
14821560
}
14831561

14841562
public init(arrayLiteral elements: ExpressibleAsConditionElement...) {
@@ -1521,7 +1599,13 @@ public struct GenericRequirementList: ExpressibleByArrayLiteral, SyntaxBuildable
15211599
/// - Parameters:
15221600
/// - elements: A list of `ExpressibleAsGenericRequirement`
15231601
public init(_ elements: [ExpressibleAsGenericRequirement]) {
1524-
self.elements = elements.map { $0.createGenericRequirement() }
1602+
if let last = elements.last {
1603+
self.elements =
1604+
elements.dropLast(1).map({ $0.createGenericRequirement(isLastElement: false) })
1605+
+ [last.createGenericRequirement(isLastElement: true)]
1606+
} else {
1607+
self.elements = []
1608+
}
15251609
}
15261610

15271611
public init(arrayLiteral elements: ExpressibleAsGenericRequirement...) {
@@ -1564,7 +1648,13 @@ public struct GenericParameterList: ExpressibleByArrayLiteral, SyntaxBuildable,
15641648
/// - Parameters:
15651649
/// - elements: A list of `ExpressibleAsGenericParameter`
15661650
public init(_ elements: [ExpressibleAsGenericParameter]) {
1567-
self.elements = elements.map { $0.createGenericParameter() }
1651+
if let last = elements.last {
1652+
self.elements =
1653+
elements.dropLast(1).map({ $0.createGenericParameter(isLastElement: false) })
1654+
+ [last.createGenericParameter(isLastElement: true)]
1655+
} else {
1656+
self.elements = []
1657+
}
15681658
}
15691659

15701660
public init(arrayLiteral elements: ExpressibleAsGenericParameter...) {
@@ -1607,7 +1697,13 @@ public struct PrimaryAssociatedTypeList: ExpressibleByArrayLiteral, SyntaxBuilda
16071697
/// - Parameters:
16081698
/// - elements: A list of `ExpressibleAsPrimaryAssociatedType`
16091699
public init(_ elements: [ExpressibleAsPrimaryAssociatedType]) {
1610-
self.elements = elements.map { $0.createPrimaryAssociatedType() }
1700+
if let last = elements.last {
1701+
self.elements =
1702+
elements.dropLast(1).map({ $0.createPrimaryAssociatedType(isLastElement: false) })
1703+
+ [last.createPrimaryAssociatedType(isLastElement: true)]
1704+
} else {
1705+
self.elements = []
1706+
}
16111707
}
16121708

16131709
public init(arrayLiteral elements: ExpressibleAsPrimaryAssociatedType...) {
@@ -1693,7 +1789,13 @@ public struct TupleTypeElementList: ExpressibleByArrayLiteral, SyntaxBuildable,
16931789
/// - Parameters:
16941790
/// - elements: A list of `ExpressibleAsTupleTypeElement`
16951791
public init(_ elements: [ExpressibleAsTupleTypeElement]) {
1696-
self.elements = elements.map { $0.createTupleTypeElement() }
1792+
if let last = elements.last {
1793+
self.elements =
1794+
elements.dropLast(1).map({ $0.createTupleTypeElement(isLastElement: false) })
1795+
+ [last.createTupleTypeElement(isLastElement: true)]
1796+
} else {
1797+
self.elements = []
1798+
}
16971799
}
16981800

16991801
public init(arrayLiteral elements: ExpressibleAsTupleTypeElement...) {
@@ -1736,7 +1838,13 @@ public struct GenericArgumentList: ExpressibleByArrayLiteral, SyntaxBuildable, E
17361838
/// - Parameters:
17371839
/// - elements: A list of `ExpressibleAsGenericArgument`
17381840
public init(_ elements: [ExpressibleAsGenericArgument]) {
1739-
self.elements = elements.map { $0.createGenericArgument() }
1841+
if let last = elements.last {
1842+
self.elements =
1843+
elements.dropLast(1).map({ $0.createGenericArgument(isLastElement: false) })
1844+
+ [last.createGenericArgument(isLastElement: true)]
1845+
} else {
1846+
self.elements = []
1847+
}
17401848
}
17411849

17421850
public init(arrayLiteral elements: ExpressibleAsGenericArgument...) {
@@ -1779,7 +1887,13 @@ public struct TuplePatternElementList: ExpressibleByArrayLiteral, SyntaxBuildabl
17791887
/// - Parameters:
17801888
/// - elements: A list of `ExpressibleAsTuplePatternElement`
17811889
public init(_ elements: [ExpressibleAsTuplePatternElement]) {
1782-
self.elements = elements.map { $0.createTuplePatternElement() }
1890+
if let last = elements.last {
1891+
self.elements =
1892+
elements.dropLast(1).map({ $0.createTuplePatternElement(isLastElement: false) })
1893+
+ [last.createTuplePatternElement(isLastElement: true)]
1894+
} else {
1895+
self.elements = []
1896+
}
17831897
}
17841898

17851899
public init(arrayLiteral elements: ExpressibleAsTuplePatternElement...) {

0 commit comments

Comments
 (0)