Skip to content

Commit 12c7e6e

Browse files
committed
Switch back to Swift tuples for typed captures.
1 parent 76b6fb6 commit 12c7e6e

File tree

9 files changed

+337
-726
lines changed

9 files changed

+337
-726
lines changed

Sources/Exercises/Participants/RegexParticipant.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ struct RegexLiteralParticipant: Participant {
4646
// MARK: - Regex literal
4747

4848
private func extractFromCaptures(
49-
_ match: Tuple4<Substring, Substring, Substring?, Substring>
49+
_ match: (Substring, Substring, Substring?, Substring)
5050
) -> GraphemeBreakEntry? {
5151
guard let lowerScalar = Unicode.Scalar(hex: match.1),
5252
let upperScalar = match.2.map(Unicode.Scalar.init(hex:)) ?? lowerScalar,
@@ -61,7 +61,7 @@ private func extractFromCaptures(
6161
private func graphemeBreakPropertyData<RP: RegexProtocol>(
6262
forLine line: String,
6363
using regex: RP
64-
) -> GraphemeBreakEntry? where RP.Match == Tuple4<Substring, Substring, Substring?, Substring> {
64+
) -> GraphemeBreakEntry? where RP.Match == (Substring, Substring, Substring?, Substring) {
6565
line.match(regex).map(\.match).flatMap(extractFromCaptures)
6666
}
6767

@@ -71,7 +71,7 @@ private func graphemeBreakPropertyDataLiteral(
7171
return graphemeBreakPropertyData(
7272
forLine: line,
7373
using: r(#"([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s+;\s+(\w+).*"#,
74-
matching: Tuple4<Substring, Substring, Substring?, Substring>.self))
74+
matching: (Substring, Substring, Substring?, Substring).self))
7575
}
7676

7777
// MARK: - Builder DSL
@@ -91,7 +91,7 @@ private func graphemeBreakPropertyData(
9191
oneOrMore(.word).tryCapture(Unicode.GraphemeBreakProperty.init)
9292
many(.any)
9393
}.map {
94-
let (_, lower, upper, property) = $0.match.tuple
94+
let (_, lower, upper, property) = $0.match
9595
return GraphemeBreakEntry(lower...(upper ?? lower), property)
9696
}
9797
}

Sources/VariadicsGenerator/VariadicsGenerator.swift

Lines changed: 36 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ let captureAssociatedTypeName = "Capture"
9797
let patternBuilderTypeName = "RegexBuilder"
9898
let patternProtocolRequirementName = "regex"
9999
let PatternTypeBaseName = "Regex"
100-
let emptyProtocolName = "EmptyCaptureProtocol"
101100
let baseMatchTypeName = "Substring"
102101

103102
@main
@@ -128,12 +127,17 @@ struct VariadicsGenerator: ParsableCommand {
128127
129128
""")
130129

131-
for arity in 2...maxArity+1 {
132-
emitTupleStruct(arity: arity)
130+
print("Generating 'buildBlock(_:)' overloads...", to: &standardError)
131+
for arity in 1..<maxArity {
132+
print(" Capture arity: \(arity)", to: &standardError)
133+
emitUnaryBuildBlock(arity: arity)
133134
}
134135

135136
print("Generating concatenation overloads...", to: &standardError)
136137
for (leftArity, rightArity) in Permutations(totalArity: maxArity) {
138+
guard rightArity != 0 else {
139+
continue
140+
}
137141
print(
138142
" Left arity: \(leftArity) Right arity: \(rightArity)",
139143
to: &standardError)
@@ -168,73 +172,22 @@ struct VariadicsGenerator: ParsableCommand {
168172
if arity == 0 {
169173
return genericParameters()
170174
}
171-
return "Tuple\(arity)<\(genericParameters())>"
175+
return "(\(genericParameters()))"
172176
}
173177

174-
func emitTupleStruct(arity: Int) {
175-
output("""
176-
@frozen @dynamicMemberLookup
177-
public struct Tuple\(arity)<
178-
""")
179-
outputForEach(0..<arity, separator: ", ") {
180-
"_\($0)"
181-
}
182-
output("> {")
183-
// `public typealias Tuple = (_0, ...)`
184-
output("\n public typealias Tuple = (")
185-
outputForEach(0..<arity, separator: ", ") { "_\($0)" }
186-
output(")")
187-
// `public var tuple: Tuple`
188-
output("\n public var tuple: Tuple\n")
189-
// `subscript(dynamicMember:)`
178+
func emitUnaryBuildBlock(arity: Int) {
179+
assert(arity > 0)
180+
let captureTypes = (0..<arity).map { "C\($0)" }.joined(separator: ", ")
190181
output("""
191-
public subscript<T>(dynamicMember keyPath: WritableKeyPath<Tuple, T>) -> T {
192-
get { tuple[keyPath: keyPath] }
193-
_modify { yield &tuple[keyPath: keyPath] }
182+
extension RegexBuilder {
183+
public static func buildBlock<R: RegexProtocol, W, \(captureTypes)>(_ regex: R) -> R
184+
where R.Match == (W, \(captureTypes))
185+
{
186+
regex
194187
}
195-
""")
196-
output("\n}\n")
197-
output("extension Tuple\(arity): \(emptyProtocolName) where ")
198-
outputForEach(1..<arity, separator: ", ") {
199-
"_\($0): \(emptyProtocolName)"
200-
}
201-
output(" {}\n")
202-
output("extension Tuple\(arity): MatchProtocol {\n")
203-
output(" public typealias Capture = ")
204-
if arity == 2 {
205-
output("_1")
206-
} else {
207-
output("Tuple\(arity-1)<")
208-
outputForEach(1..<arity, separator: ", ") {
209-
"_\($0)"
210188
}
211-
output(">")
212-
}
213-
output("\n public init(_ tuple: Tuple) { self.tuple = tuple }")
214-
// `public init(_0: _0, ...) { ... }`
215-
output("\n public init(")
216-
outputForEach(0..<arity, separator: ", ") {
217-
"_ _\($0): _\($0)"
218-
}
219-
output(") {\n")
220-
output(" self.init((")
221-
outputForEach(0..<arity, separator: ", ") { "_\($0)" }
222-
output("))\n")
223-
output(" }")
224-
output("\n}\n")
225-
// Equatable
226-
output("extension Tuple\(arity): Equatable where ")
227-
outputForEach(0..<arity, separator: ", ") {
228-
"_\($0): Equatable"
229-
}
230-
output(" {\n")
231-
output(" public static func == (lhs: Self, rhs: Self) -> Bool {\n")
232-
output(" ")
233-
outputForEach(0..<arity, separator: " && ") {
234-
"lhs.tuple.\($0) == rhs.tuple.\($0)"
235-
}
236-
output("\n }\n")
237-
output("}\n")
189+
190+
""")
238191
}
239192

240193
func emitConcatenation(leftArity: Int, rightArity: Int) {
@@ -254,11 +207,11 @@ struct VariadicsGenerator: ParsableCommand {
254207
// Emit concatenation type declaration.
255208

256209
// public struct Concatenation2<W0, W1, C0, C1, R0: RegexProtocol, R1: RegexProtocol>: RegexProtocol
257-
// where R0.Match == Tuple2<W0, C0>, R1.Match == Tuple2<W1, C1>
210+
// where R0.Match == (W0, C0), R1.Match == (W1, C1)
258211
// {
259-
// public typealias Match = Tuple3<Substring, C0, C1>
212+
// public typealias Match = (Substring, C0, C1)
260213
//
261-
// public let regex: Regex<Tuple3<Substring, C0, C1>>
214+
// public let regex: Regex<(Substring, C0, C1)>
262215
//
263216
// public init(_ r0: R0, _ r1: R1) {
264217
// self.regex = .init(ast: append(r1.regex.ast, to: r0.regex.ast))
@@ -288,32 +241,32 @@ struct VariadicsGenerator: ParsableCommand {
288241
if leftArity == 0 {
289242
output("W0")
290243
} else {
291-
output("Tuple\(leftArity+1)<W0")
244+
output("(W0")
292245
outputForEach(0..<leftArity) {
293246
", C\($0)"
294247
}
295-
output(">")
248+
output(")")
296249
}
297250
output(", R1.Match == ")
298251
if rightArity == 0 {
299252
output("W1")
300253
} else {
301-
output("Tuple\(rightArity+1)<W1")
254+
output("(W1")
302255
outputForEach(leftArity..<leftArity+rightArity) {
303256
", C\($0)"
304257
}
305-
output(">")
258+
output(")")
306259
}
307260
output(" {\n")
308261
output(" public typealias \(matchAssociatedTypeName) = ")
309262
if leftArity+rightArity == 0 {
310263
output(baseMatchTypeName)
311264
} else {
312-
output("Tuple\(leftArity+rightArity+1)<\(baseMatchTypeName), ")
265+
output("(\(baseMatchTypeName), ")
313266
outputForEach(0..<leftArity+rightArity, separator: ", ") {
314267
"C\($0)"
315268
}
316-
output(">")
269+
output(")")
317270
}
318271
output("\n")
319272
output(" public let \(patternProtocolRequirementName): \(PatternTypeBaseName)<\(matchAssociatedTypeName)>\n")
@@ -351,6 +304,7 @@ struct VariadicsGenerator: ParsableCommand {
351304
// T + () = T
352305
output("""
353306
extension RegexBuilder {
307+
@_disfavoredOverload
354308
public static func buildBlock<W0
355309
""")
356310
outputForEach(0..<leftArity) {
@@ -364,24 +318,24 @@ struct VariadicsGenerator: ParsableCommand {
364318
if leftArity == 0 {
365319
output(baseMatchTypeName)
366320
} else {
367-
output("Tuple\(leftArity+1)<\(baseMatchTypeName)")
321+
output("(\(baseMatchTypeName)")
368322
outputForEach(0..<leftArity) {
369323
", C\($0)"
370324
}
371-
output(">")
325+
output(")")
372326
}
373327
output("> where R0.\(matchAssociatedTypeName) == ")
374328
if leftArity == 0 {
375329
output("W0")
376330
} else {
377-
output("Tuple\(leftArity+1)<W0")
331+
output("(W0")
378332
outputForEach(0..<leftArity) {
379333
", C\($0)"
380334
}
381-
output(">")
335+
output(")")
382336
}
383337
output("""
384-
, R1.\(matchAssociatedTypeName): \(emptyProtocolName) {
338+
{
385339
.init(ast: append(next.regex.ast, to: combined.regex.ast))
386340
}
387341
}
@@ -435,9 +389,9 @@ struct VariadicsGenerator: ParsableCommand {
435389
return result
436390
}
437391
let captures = (0..<arity).map { "C\($0)" }.joined(separator: ", ")
438-
let capturesTupled = arity == 1 ? captures : "Tuple\(arity)<\(captures)>"
392+
let capturesTupled = arity == 1 ? captures : "(\(captures))"
439393
let componentConstraint: String = arity == 0 ? "" :
440-
"where Component.Match == Tuple\(arity+1)<W, \(captures)>"
394+
"where Component.Match == (W, \(captures))"
441395
let quantifiedCaptures: String = {
442396
switch kind {
443397
case .zeroOrOne:
@@ -446,7 +400,7 @@ struct VariadicsGenerator: ParsableCommand {
446400
return "[\(capturesTupled)]"
447401
}
448402
}()
449-
let matchType = arity == 0 ? baseMatchTypeName : "Tuple2<\(baseMatchTypeName), \(quantifiedCaptures)>"
403+
let matchType = arity == 0 ? baseMatchTypeName : "(\(baseMatchTypeName), \(quantifiedCaptures))"
450404
output("""
451405
public struct \(kind.typeName)_\(arity)<\(genericParameters(withConstraints: true))>: \(regexProtocolName) \(componentConstraint) {
452406
public typealias \(matchAssociatedTypeName) = \(matchType)

Sources/_StringProcessing/RegexDSL/Builder.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,6 @@ public enum RegexBuilder {
1616
r0
1717
}
1818

19-
public static func buildBlock<R0: RegexProtocol>(
20-
_ r0: R0
21-
) -> Regex<Substring> where R0.Match: EmptyCaptureProtocol {
22-
.init(ast: r0.regex.ast)
23-
}
24-
2519
public static func buildExpression<R: RegexProtocol>(_ regex: R) -> R {
2620
regex
2721
}

0 commit comments

Comments
 (0)