Skip to content

Commit 0772ed3

Browse files
authored
Merge pull request #454 from evnik/ResultBuilders
Override trailing comma for elements in ResultBuilders
2 parents 5d039e7 + e77ce51 commit 0772ed3

File tree

12 files changed

+460
-86
lines changed

12 files changed

+460
-86
lines changed

Sources/SwiftSyntaxBuilder/BuildableNodes.swift.gyb

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
%{
22
from gyb_syntax_support import SYNTAX_NODES
3-
from gyb_helpers import SyntaxBuildableNode
3+
from gyb_helpers import SyntaxBuildableNode, conformance_clause
44
# -*- mode: Swift -*-
55
# Ignore the following admonition it applies to the resulting .swift file only
66
}%
@@ -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+
% conformances = [base_type.buildable(), type.expressible_as()]
27+
% has_with_trailing_comma_trait = node.node.traits and 'WithTrailingComma' in node.node.traits
28+
% if has_with_trailing_comma_trait:
29+
% conformances.append("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()}${conformance_clause(conformances)} {
3035
% children = node.children()
3136
% for child in children:
3237
let ${child.name()}: ${child.type().buildable()}
@@ -114,6 +119,23 @@ public struct ${type.buildable()}: ${base_type.buildable()}, ${type.expressible_
114119
public func create${type.buildable_base_name()}() -> ${type.buildable()} {
115120
return self
116121
}
122+
% if has_with_trailing_comma_trait:
123+
% trailing_comma_init_args = []
124+
% for child in children:
125+
% if child.name() == 'trailingComma':
126+
% trailing_comma_init_args.append('%s: withComma ? .comma : nil' % (child.name()))
127+
% else:
128+
% trailing_comma_init_args.append('%s: %s' % (child.name(), child.name()))
129+
% end
130+
% end
131+
132+
/// Conformance to `HasTrailingComma`.
133+
public func withTrailingComma(_ withComma: Bool) -> Self {
134+
return Self.init(
135+
${',\n '.join(trailing_comma_init_args)}
136+
)
137+
}
138+
% end
117139

118140
/// `${type.buildable()}` might conform to `${base_type.expressible_as()}` via different `ExpressibleAs*` paths.
119141
/// 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/ResultBuilders.swift.gyb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ 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+
let lastIndex = component.count - 1
90+
return .init(component.enumerated().map({ index, source in
91+
let element = source.create${element_type.buildable_base_name()}()
92+
return index < lastIndex ? element.withTrailingComma(true) : element
93+
}))
8894
% else:
8995
return .init(component.map { $0.create${element_type.buildable()}() })
9096
% end

0 commit comments

Comments
 (0)