Skip to content

Commit dbd6bbb

Browse files
committed
Emit trailing commas in initializers of Element List types
This affects code produced by ResultBuilders as well Test coverage is added for ResultBuilders
1 parent 7bceeb0 commit dbd6bbb

File tree

12 files changed

+437
-85
lines changed

12 files changed

+437
-85
lines changed

Sources/SwiftSyntaxBuilder/BuildableCollectionNodes.swift.gyb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ 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+
let lastIndex = elements.count - 1
40+
self.elements = elements.enumerated().map({ index, element in
41+
element.create${element_type.buildable_base_name()}().withTrailingComma(index < lastIndex)
42+
})
3843
% else:
3944
self.elements = elements.map { $0.create${element_type.buildable_base_name()}() }
4045
% end

Sources/SwiftSyntaxBuilder/BuildableNodes.swift.gyb

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,15 @@ import SwiftSyntax
2323
% for node in [SyntaxBuildableNode(syntax_node) for syntax_node in SYNTAX_NODES if syntax_node.is_buildable()]:
2424
% type = node.type()
2525
% base_type = node.base_type()
26+
% additionalConformance = ""
27+
% has_with_trailing_comma_trait = node.node.traits and 'WithTrailingComma' in node.node.traits
28+
% if has_with_trailing_comma_trait:
29+
% additionalConformance = ", HasTrailingComma"
30+
% end
2631
% if node.documentation():
2732
/// ${node.documentation()}
2833
% end
29-
public struct ${type.buildable()}: ${base_type.buildable()}, ${type.expressible_as()} {
34+
public struct ${type.buildable()}: ${base_type.buildable()}, ${type.expressible_as()}${additionalConformance} {
3035
% children = node.children()
3136
% for child in children:
3237
let ${child.name()}: ${child.type().buildable()}
@@ -114,6 +119,24 @@ public struct ${type.buildable()}: ${base_type.buildable()}, ${type.expressible_
114119
public func create${type.buildable_base_name()}() -> ${type.buildable()} {
115120
return self
116121
}
122+
%{
123+
trailing_comma_init_args = []
124+
if has_with_trailing_comma_trait:
125+
for child in children:
126+
if child.name() == 'trailingComma':
127+
trailing_comma_init_args.append('%s: withComma ? .comma : nil' % (child.name()))
128+
else:
129+
trailing_comma_init_args.append('%s: %s' % (child.name(), child.name()))
130+
}%
131+
% if trailing_comma_init_args:
132+
133+
/// Conformance to `HasTrailingComma`.
134+
public func withTrailingComma(_ withComma: Bool) -> Self {
135+
return Self.init(
136+
${',\n '.join(trailing_comma_init_args)}
137+
)
138+
}
139+
% end
117140

118141
/// `${type.buildable()}` might conform to `${base_type.expressible_as()}` via different `ExpressibleAs*` paths.
119142
/// Thus, there are multiple default implementations for `create${base_type.buildable_base_name()}`, some of which perform conversions through `ExpressibleAs*` protocols.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
public protocol HasTrailingComma {
14+
/// Returns this node overriding presence of the trailing comma
15+
func withTrailingComma(_ withComma: Bool) -> Self
16+
}

Sources/SwiftSyntaxBuilder/gyb_generated/BuildableCollectionNodes.swift

Lines changed: 76 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ 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+
let lastIndex = elements.count - 1
69+
self.elements = elements.enumerated().map({ index, element in
70+
element.createTupleExprElement().withTrailingComma(index < lastIndex)
71+
})
6972
}
7073

7174
public init(arrayLiteral elements: ExpressibleAsTupleExprElement...) {
@@ -108,7 +111,10 @@ public struct ArrayElementList: ExpressibleByArrayLiteral, SyntaxBuildable, Expr
108111
/// - Parameters:
109112
/// - elements: A list of `ExpressibleAsArrayElement`
110113
public init(_ elements: [ExpressibleAsArrayElement]) {
111-
self.elements = elements.map { $0.createArrayElement() }
114+
let lastIndex = elements.count - 1
115+
self.elements = elements.enumerated().map({ index, element in
116+
element.createArrayElement().withTrailingComma(index < lastIndex)
117+
})
112118
}
113119

114120
public init(arrayLiteral elements: ExpressibleAsArrayElement...) {
@@ -151,7 +157,10 @@ public struct DictionaryElementList: ExpressibleByArrayLiteral, SyntaxBuildable,
151157
/// - Parameters:
152158
/// - elements: A list of `ExpressibleAsDictionaryElement`
153159
public init(_ elements: [ExpressibleAsDictionaryElement]) {
154-
self.elements = elements.map { $0.createDictionaryElement() }
160+
let lastIndex = elements.count - 1
161+
self.elements = elements.enumerated().map({ index, element in
162+
element.createDictionaryElement().withTrailingComma(index < lastIndex)
163+
})
155164
}
156165

157166
public init(arrayLiteral elements: ExpressibleAsDictionaryElement...) {
@@ -323,7 +332,10 @@ public struct ClosureCaptureItemList: ExpressibleByArrayLiteral, SyntaxBuildable
323332
/// - Parameters:
324333
/// - elements: A list of `ExpressibleAsClosureCaptureItem`
325334
public init(_ elements: [ExpressibleAsClosureCaptureItem]) {
326-
self.elements = elements.map { $0.createClosureCaptureItem() }
335+
let lastIndex = elements.count - 1
336+
self.elements = elements.enumerated().map({ index, element in
337+
element.createClosureCaptureItem().withTrailingComma(index < lastIndex)
338+
})
327339
}
328340

329341
public init(arrayLiteral elements: ExpressibleAsClosureCaptureItem...) {
@@ -366,7 +378,10 @@ public struct ClosureParamList: ExpressibleByArrayLiteral, SyntaxBuildable, Expr
366378
/// - Parameters:
367379
/// - elements: A list of `ExpressibleAsClosureParam`
368380
public init(_ elements: [ExpressibleAsClosureParam]) {
369-
self.elements = elements.map { $0.createClosureParam() }
381+
let lastIndex = elements.count - 1
382+
self.elements = elements.enumerated().map({ index, element in
383+
element.createClosureParam().withTrailingComma(index < lastIndex)
384+
})
370385
}
371386

372387
public init(arrayLiteral elements: ExpressibleAsClosureParam...) {
@@ -495,7 +510,10 @@ public struct FunctionParameterList: ExpressibleByArrayLiteral, SyntaxBuildable,
495510
/// - Parameters:
496511
/// - elements: A list of `ExpressibleAsFunctionParameter`
497512
public init(_ elements: [ExpressibleAsFunctionParameter]) {
498-
self.elements = elements.map { $0.createFunctionParameter() }
513+
let lastIndex = elements.count - 1
514+
self.elements = elements.enumerated().map({ index, element in
515+
element.createFunctionParameter().withTrailingComma(index < lastIndex)
516+
})
499517
}
500518

501519
public init(arrayLiteral elements: ExpressibleAsFunctionParameter...) {
@@ -581,7 +599,10 @@ public struct InheritedTypeList: ExpressibleByArrayLiteral, SyntaxBuildable, Exp
581599
/// - Parameters:
582600
/// - elements: A list of `ExpressibleAsInheritedType`
583601
public init(_ elements: [ExpressibleAsInheritedType]) {
584-
self.elements = elements.map { $0.createInheritedType() }
602+
let lastIndex = elements.count - 1
603+
self.elements = elements.enumerated().map({ index, element in
604+
element.createInheritedType().withTrailingComma(index < lastIndex)
605+
})
585606
}
586607

587608
public init(arrayLiteral elements: ExpressibleAsInheritedType...) {
@@ -796,7 +817,10 @@ public struct PatternBindingList: ExpressibleByArrayLiteral, SyntaxBuildable, Ex
796817
/// - Parameters:
797818
/// - elements: A list of `ExpressibleAsPatternBinding`
798819
public init(_ elements: [ExpressibleAsPatternBinding]) {
799-
self.elements = elements.map { $0.createPatternBinding() }
820+
let lastIndex = elements.count - 1
821+
self.elements = elements.enumerated().map({ index, element in
822+
element.createPatternBinding().withTrailingComma(index < lastIndex)
823+
})
800824
}
801825

802826
public init(arrayLiteral elements: ExpressibleAsPatternBinding...) {
@@ -839,7 +863,10 @@ public struct EnumCaseElementList: ExpressibleByArrayLiteral, SyntaxBuildable, E
839863
/// - Parameters:
840864
/// - elements: A list of `ExpressibleAsEnumCaseElement`
841865
public init(_ elements: [ExpressibleAsEnumCaseElement]) {
842-
self.elements = elements.map { $0.createEnumCaseElement() }
866+
let lastIndex = elements.count - 1
867+
self.elements = elements.enumerated().map({ index, element in
868+
element.createEnumCaseElement().withTrailingComma(index < lastIndex)
869+
})
843870
}
844871

845872
public init(arrayLiteral elements: ExpressibleAsEnumCaseElement...) {
@@ -1220,7 +1247,10 @@ public struct DifferentiabilityParamList: ExpressibleByArrayLiteral, SyntaxBuild
12201247
/// - Parameters:
12211248
/// - elements: A list of `ExpressibleAsDifferentiabilityParam`
12221249
public init(_ elements: [ExpressibleAsDifferentiabilityParam]) {
1223-
self.elements = elements.map { $0.createDifferentiabilityParam() }
1250+
let lastIndex = elements.count - 1
1251+
self.elements = elements.enumerated().map({ index, element in
1252+
element.createDifferentiabilityParam().withTrailingComma(index < lastIndex)
1253+
})
12241254
}
12251255

12261256
public init(arrayLiteral elements: ExpressibleAsDifferentiabilityParam...) {
@@ -1392,7 +1422,10 @@ public struct CaseItemList: ExpressibleByArrayLiteral, SyntaxBuildable, Expressi
13921422
/// - Parameters:
13931423
/// - elements: A list of `ExpressibleAsCaseItem`
13941424
public init(_ elements: [ExpressibleAsCaseItem]) {
1395-
self.elements = elements.map { $0.createCaseItem() }
1425+
let lastIndex = elements.count - 1
1426+
self.elements = elements.enumerated().map({ index, element in
1427+
element.createCaseItem().withTrailingComma(index < lastIndex)
1428+
})
13961429
}
13971430

13981431
public init(arrayLiteral elements: ExpressibleAsCaseItem...) {
@@ -1435,7 +1468,10 @@ public struct CatchItemList: ExpressibleByArrayLiteral, SyntaxBuildable, Express
14351468
/// - Parameters:
14361469
/// - elements: A list of `ExpressibleAsCatchItem`
14371470
public init(_ elements: [ExpressibleAsCatchItem]) {
1438-
self.elements = elements.map { $0.createCatchItem() }
1471+
let lastIndex = elements.count - 1
1472+
self.elements = elements.enumerated().map({ index, element in
1473+
element.createCatchItem().withTrailingComma(index < lastIndex)
1474+
})
14391475
}
14401476

14411477
public init(arrayLiteral elements: ExpressibleAsCatchItem...) {
@@ -1478,7 +1514,10 @@ public struct ConditionElementList: ExpressibleByArrayLiteral, SyntaxBuildable,
14781514
/// - Parameters:
14791515
/// - elements: A list of `ExpressibleAsConditionElement`
14801516
public init(_ elements: [ExpressibleAsConditionElement]) {
1481-
self.elements = elements.map { $0.createConditionElement() }
1517+
let lastIndex = elements.count - 1
1518+
self.elements = elements.enumerated().map({ index, element in
1519+
element.createConditionElement().withTrailingComma(index < lastIndex)
1520+
})
14821521
}
14831522

14841523
public init(arrayLiteral elements: ExpressibleAsConditionElement...) {
@@ -1521,7 +1560,10 @@ public struct GenericRequirementList: ExpressibleByArrayLiteral, SyntaxBuildable
15211560
/// - Parameters:
15221561
/// - elements: A list of `ExpressibleAsGenericRequirement`
15231562
public init(_ elements: [ExpressibleAsGenericRequirement]) {
1524-
self.elements = elements.map { $0.createGenericRequirement() }
1563+
let lastIndex = elements.count - 1
1564+
self.elements = elements.enumerated().map({ index, element in
1565+
element.createGenericRequirement().withTrailingComma(index < lastIndex)
1566+
})
15251567
}
15261568

15271569
public init(arrayLiteral elements: ExpressibleAsGenericRequirement...) {
@@ -1564,7 +1606,10 @@ public struct GenericParameterList: ExpressibleByArrayLiteral, SyntaxBuildable,
15641606
/// - Parameters:
15651607
/// - elements: A list of `ExpressibleAsGenericParameter`
15661608
public init(_ elements: [ExpressibleAsGenericParameter]) {
1567-
self.elements = elements.map { $0.createGenericParameter() }
1609+
let lastIndex = elements.count - 1
1610+
self.elements = elements.enumerated().map({ index, element in
1611+
element.createGenericParameter().withTrailingComma(index < lastIndex)
1612+
})
15681613
}
15691614

15701615
public init(arrayLiteral elements: ExpressibleAsGenericParameter...) {
@@ -1607,7 +1652,10 @@ public struct PrimaryAssociatedTypeList: ExpressibleByArrayLiteral, SyntaxBuilda
16071652
/// - Parameters:
16081653
/// - elements: A list of `ExpressibleAsPrimaryAssociatedType`
16091654
public init(_ elements: [ExpressibleAsPrimaryAssociatedType]) {
1610-
self.elements = elements.map { $0.createPrimaryAssociatedType() }
1655+
let lastIndex = elements.count - 1
1656+
self.elements = elements.enumerated().map({ index, element in
1657+
element.createPrimaryAssociatedType().withTrailingComma(index < lastIndex)
1658+
})
16111659
}
16121660

16131661
public init(arrayLiteral elements: ExpressibleAsPrimaryAssociatedType...) {
@@ -1693,7 +1741,10 @@ public struct TupleTypeElementList: ExpressibleByArrayLiteral, SyntaxBuildable,
16931741
/// - Parameters:
16941742
/// - elements: A list of `ExpressibleAsTupleTypeElement`
16951743
public init(_ elements: [ExpressibleAsTupleTypeElement]) {
1696-
self.elements = elements.map { $0.createTupleTypeElement() }
1744+
let lastIndex = elements.count - 1
1745+
self.elements = elements.enumerated().map({ index, element in
1746+
element.createTupleTypeElement().withTrailingComma(index < lastIndex)
1747+
})
16971748
}
16981749

16991750
public init(arrayLiteral elements: ExpressibleAsTupleTypeElement...) {
@@ -1736,7 +1787,10 @@ public struct GenericArgumentList: ExpressibleByArrayLiteral, SyntaxBuildable, E
17361787
/// - Parameters:
17371788
/// - elements: A list of `ExpressibleAsGenericArgument`
17381789
public init(_ elements: [ExpressibleAsGenericArgument]) {
1739-
self.elements = elements.map { $0.createGenericArgument() }
1790+
let lastIndex = elements.count - 1
1791+
self.elements = elements.enumerated().map({ index, element in
1792+
element.createGenericArgument().withTrailingComma(index < lastIndex)
1793+
})
17401794
}
17411795

17421796
public init(arrayLiteral elements: ExpressibleAsGenericArgument...) {
@@ -1779,7 +1833,10 @@ public struct TuplePatternElementList: ExpressibleByArrayLiteral, SyntaxBuildabl
17791833
/// - Parameters:
17801834
/// - elements: A list of `ExpressibleAsTuplePatternElement`
17811835
public init(_ elements: [ExpressibleAsTuplePatternElement]) {
1782-
self.elements = elements.map { $0.createTuplePatternElement() }
1836+
let lastIndex = elements.count - 1
1837+
self.elements = elements.enumerated().map({ index, element in
1838+
element.createTuplePatternElement().withTrailingComma(index < lastIndex)
1839+
})
17831840
}
17841841

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

0 commit comments

Comments
 (0)