Skip to content

Commit 56bbacf

Browse files
committed
Merge all convenience initializers into one file
1 parent 429b742 commit 56bbacf

18 files changed

+297
-496
lines changed

Sources/SwiftSyntaxBuilder/CMakeLists.txt

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,13 @@
77
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
88

99
add_library(SwiftSyntaxBuilder STATIC
10+
ConvenienceInitializers.swift
1011
HasTrailingComma.swift
1112
Indenter.swift
1213
ResultBuilderExtensions.swift
1314
Syntax+StringInterpolation.swift
15+
SyntaxNodeWithBody.swift
1416

15-
ConvenienceInitializers/BinaryOperatorExprConvenienceInitializers.swift
16-
ConvenienceInitializers/BooleanLiteralExprConvenienceInitializers.swift
17-
ConvenienceInitializers/CatchClauseConvenienceInitializer.swift
18-
ConvenienceInitializers/CustomAttributeConvenienceInitializers.swift
19-
ConvenienceInitializers/DictionaryExprConvenienceInitializers.swift
20-
ConvenienceInitializers/FloatLiteralExprConvenienceInitializers.swift
21-
ConvenienceInitializers/FunctionCallExprConvenienceInitializers.swift
22-
ConvenienceInitializers/IfStmtConvenienceInitializers.swift
23-
ConvenienceInitializers/IntegerLiteralExprConvenienceInitializers.swift
24-
ConvenienceInitializers/MemberAccessExprConvenienceInitializers.swift
25-
ConvenienceInitializers/SwitchCaseConvenienceInitializers.swift
26-
ConvenienceInitializers/SyntaxNodeWithBody.swift
27-
ConvenienceInitializers/StringLiteralExprConvenienceInitializers.swift
28-
ConvenienceInitializers/TernaryExprConvenienceInitializers.swift
29-
ConvenienceInitializers/TupleExprElementConvenienceInitializers.swift
30-
ConvenienceInitializers/VariableDeclConvenienceInitializers.swift
3117

3218
generated/BuildableCollectionNodes.swift
3319
generated/BuildableNodes.swift
Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
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+
import Foundation
14+
import SwiftSyntax
15+
16+
extension BinaryOperatorExpr {
17+
public init(text: String) {
18+
self.init(operatorToken: .spacedBinaryOperator(text))
19+
}
20+
}
21+
22+
extension BooleanLiteralExpr: ExpressibleByBooleanLiteral {
23+
public init(_ value: Bool) {
24+
self.init(booleanLiteral: value ? .true : .false)
25+
}
26+
27+
public init(booleanLiteral value: Bool) {
28+
self.init(value)
29+
}
30+
}
31+
32+
extension CatchClause {
33+
/// A convenience initializer that calculates spacing around the `catch` keyword.
34+
public init(
35+
leadingTrivia: Trivia = [],
36+
_ catchItems: CatchItemList,
37+
@CodeBlockItemListBuilder bodyBuilder: () -> CodeBlockItemListSyntax
38+
) {
39+
self.init(
40+
leadingTrivia: leadingTrivia,
41+
catchKeyword: .catch.withTrailingTrivia(catchItems.isEmpty ? [] : .space),
42+
catchItems: catchItems,
43+
body: CodeBlockSyntax(statements: bodyBuilder())
44+
)
45+
}
46+
}
47+
48+
extension CustomAttribute {
49+
/// A convenience initializer that allows passing in arguments using a result builder
50+
/// and automatically adds parentheses as needed, similar to the convenience
51+
/// initializer for ``FunctionCallExpr``.
52+
public init(
53+
_ attributeName: TypeSyntax,
54+
@TupleExprElementListBuilder argumentList: () -> TupleExprElementList? = { nil }
55+
) {
56+
let argumentList = argumentList()
57+
self.init(
58+
attributeName: attributeName,
59+
leftParen: argumentList != nil ? .leftParen : nil,
60+
argumentList: argumentList,
61+
rightParen: argumentList != nil ? .rightParen : nil
62+
)
63+
}
64+
}
65+
66+
extension DictionaryExpr {
67+
/// A convenience initializer that allows passing in members using a result builder
68+
/// instead of having to wrap them in a `DictionaryElementList`.
69+
public init(
70+
leftSquare: Token = .`leftSquareBracket`,
71+
rightSquare: Token = .`rightSquareBracket`,
72+
@DictionaryElementListBuilder contentBuilder: () -> DictionaryElementListSyntax = { DictionaryElementList([]) }
73+
) {
74+
let elementList = contentBuilder()
75+
self.init(
76+
leftSquare: leftSquare,
77+
content: elementList.isEmpty ? .colon(Token.colon.withTrailingTrivia([])) : .elements(elementList),
78+
rightSquare: rightSquare
79+
)
80+
}
81+
}
82+
83+
extension FloatLiteralExprSyntax: ExpressibleByFloatLiteral {
84+
public init(_ value: Float) {
85+
self.init(floatingDigits: String(value))
86+
}
87+
88+
public init(floatLiteral value: Float) {
89+
self.init(value)
90+
}
91+
}
92+
93+
extension FunctionCallExpr {
94+
/// A convenience initializer that allows passing in arguments using a result builder
95+
/// instead of having to wrap them in a `TupleExprElementList`.
96+
/// The presence of the parenthesis will be inferred based on the presence of arguments and the trailing closure.
97+
public init(
98+
calledExpression: ExprSyntaxProtocol,
99+
trailingClosure: ClosureExprSyntax? = nil,
100+
additionalTrailingClosures: MultipleTrailingClosureElementList? = nil,
101+
@TupleExprElementListBuilder argumentList: () -> TupleExprElementList = { [] }
102+
) {
103+
let argumentList = argumentList()
104+
let shouldOmitParens = argumentList.isEmpty && trailingClosure != nil
105+
self.init(
106+
calledExpression: calledExpression,
107+
leftParen: shouldOmitParens ? nil : .leftParen,
108+
argumentList: argumentList,
109+
rightParen: shouldOmitParens ? nil : .rightParen,
110+
trailingClosure: trailingClosure,
111+
additionalTrailingClosures: additionalTrailingClosures
112+
)
113+
}
114+
}
115+
116+
extension IfStmt {
117+
/// A convenience initializer that uses builder closures to express an
118+
/// if body, potentially with a second trailing builder closure for an else
119+
/// body.
120+
public init(
121+
leadingTrivia: Trivia = [],
122+
conditions: ConditionElementList,
123+
@CodeBlockItemListBuilder body: () -> CodeBlockItemList,
124+
@CodeBlockItemListBuilder elseBody: () -> CodeBlockItemList? = { nil }
125+
) {
126+
let generatedElseBody = elseBody()
127+
self.init(
128+
leadingTrivia: leadingTrivia,
129+
conditions: conditions,
130+
body: CodeBlockSyntax(statements: body()),
131+
elseKeyword: generatedElseBody == nil ? nil : Token.else.withLeadingTrivia(.space).withTrailingTrivia([]),
132+
elseBody: generatedElseBody.map { .codeBlock(CodeBlock(statements: $0)) }
133+
)
134+
}
135+
}
136+
137+
138+
extension IntegerLiteralExpr: ExpressibleByIntegerLiteral {
139+
public init(_ value: Int) {
140+
self.init(digits: String(value))
141+
}
142+
143+
public init(integerLiteral value: Int) {
144+
self.init(value)
145+
}
146+
}
147+
148+
extension MemberAccessExpr {
149+
/// Creates a `MemberAccessExpr` using the provided parameters.
150+
public init(
151+
base: ExprSyntax? = nil,
152+
dot: Token = .period,
153+
name: String,
154+
declNameArguments: DeclNameArgumentsSyntax? = nil
155+
) {
156+
self.init(base: base, dot: dot, name: TokenSyntax.identifier(name), declNameArguments: declNameArguments)
157+
}
158+
}
159+
160+
extension StringLiteralExpr {
161+
/// A regular expression matching sequences of `#`s with an adjacent quote or
162+
/// interpolation. Used to determine the number of `#`s for a raw string literal.
163+
private static let rawStringPotentialEscapesPattern = try! NSRegularExpression(
164+
pattern: [
165+
#""(#*)"#, // Match potential opening delimiters
166+
#"(#*)""#, // Match potential closing delimiters
167+
#"\\(#*)"#, // Match potential interpolations
168+
].joined(separator: "|")
169+
)
170+
171+
/// Creates a string literal, optionally specifying quotes and delimiters.
172+
/// If `openDelimiter` and `closeDelimiter` are `nil`, automatically determines
173+
/// the number of `#`s needed to express the string as-is without any escapes.
174+
public init(
175+
openDelimiter: Token? = nil,
176+
openQuote: Token = .stringQuote,
177+
content: String,
178+
closeQuote: Token = .stringQuote,
179+
closeDelimiter: Token? = nil
180+
) {
181+
let contentToken = Token.stringSegment(content)
182+
let segment = StringSegment(content: contentToken)
183+
let segments = StringLiteralSegments([.stringSegment(segment)])
184+
185+
var openDelimiter = openDelimiter
186+
var closeDelimiter = closeDelimiter
187+
if openDelimiter == nil, closeDelimiter == nil {
188+
// Match potential escapes in the string
189+
let matches = Self.rawStringPotentialEscapesPattern.matches(in: content, range: NSRange(content.startIndex..., in: content))
190+
191+
// Find longest sequence of `#`s by taking the maximum length over all captures
192+
let poundCount = matches
193+
.compactMap { match in (1..<match.numberOfRanges).map { match.range(at: $0).length + 1 }.max() }
194+
.max() ?? 0
195+
196+
// Use a delimiter that is exactly one longer
197+
openDelimiter = Token.rawStringDelimiter(String(repeating: "#", count: poundCount))
198+
closeDelimiter = openDelimiter
199+
}
200+
201+
self.init(
202+
openDelimiter: openDelimiter,
203+
openQuote: openQuote,
204+
segments: segments,
205+
closeQuote: closeQuote,
206+
closeDelimiter: closeDelimiter
207+
)
208+
}
209+
}
210+
211+
extension SwitchCase {
212+
public init(_ label: String, @CodeBlockItemListBuilder statementsBuilder: () -> CodeBlockItemListSyntax) {
213+
self.init("\(label)")
214+
self.statements = statementsBuilder()
215+
}
216+
}
217+
218+
extension TernaryExpr {
219+
public init(
220+
if condition: ExprSyntaxProtocol,
221+
then firstChoice: ExprSyntaxProtocol,
222+
else secondChoice: ExprSyntaxProtocol
223+
) {
224+
self.init(
225+
conditionExpression: condition,
226+
questionMark: .infixQuestionMark.withLeadingTrivia(.space).withTrailingTrivia(.space),
227+
firstChoice: firstChoice,
228+
colonMark: .colon.withLeadingTrivia(.space),
229+
secondChoice: secondChoice
230+
)
231+
}
232+
}
233+
234+
extension TupleExprElement {
235+
/// A convenience initializer that allows passing in label as an optional string.
236+
/// The presence of the colon will be inferred based on the presence of the label.
237+
public init(label: String? = nil, expression: ExprSyntax) {
238+
self.init(
239+
label: label.map { Token.identifier($0) }, colon: label == nil ? nil : Token.colon, expression: expression, trailingComma: nil)
240+
}
241+
}
242+
243+
extension VariableDecl {
244+
/// Creates an optionally initialized property.
245+
public init(
246+
leadingTrivia: Trivia = [],
247+
attributes: AttributeList? = nil,
248+
modifiers: ModifierList? = nil,
249+
_ letOrVarKeyword: Token,
250+
name: IdentifierPattern,
251+
type: TypeAnnotation? = nil,
252+
initializer: InitializerClause? = nil
253+
) {
254+
self.init(
255+
leadingTrivia: leadingTrivia,
256+
attributes: attributes?.withTrailingTrivia(.space),
257+
modifiers: modifiers,
258+
letOrVarKeyword: letOrVarKeyword
259+
) {
260+
PatternBinding(
261+
pattern: name,
262+
typeAnnotation: type,
263+
initializer: initializer
264+
)
265+
}
266+
}
267+
268+
/// Creates a computed property with the given accessor.
269+
public init(
270+
leadingTrivia: Trivia = [],
271+
attributes: AttributeList? = nil,
272+
modifiers: ModifierList? = nil,
273+
name: IdentifierPattern,
274+
type: TypeAnnotation,
275+
@CodeBlockItemListBuilder accessor: () -> CodeBlockItemList
276+
) {
277+
self.init(
278+
leadingTrivia: leadingTrivia,
279+
attributes: attributes?.withTrailingTrivia(.space),
280+
modifiers: modifiers,
281+
letOrVarKeyword: .var
282+
) {
283+
PatternBinding(
284+
pattern: name,
285+
typeAnnotation: type,
286+
accessor: .codeBlock(CodeBlock(statements: accessor()))
287+
)
288+
}
289+
}
290+
}
291+
292+
//==========================================================================//
293+
// IMPORTANT: If you are tempted to add an extension here, please insert //
294+
// it in alphabetical order above //
295+
//==========================================================================//

Sources/SwiftSyntaxBuilder/ConvenienceInitializers/BinaryOperatorExprConvenienceInitializers.swift

Lines changed: 0 additions & 19 deletions
This file was deleted.

Sources/SwiftSyntaxBuilder/ConvenienceInitializers/BooleanLiteralExprConvenienceInitializers.swift

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)