in Sources/VariadicsGenerator/VariadicsGenerator.swift [208:275]
func emitConcatenation(permutation: Permutation) {
let arity = permutation.arity
func emitGenericParameters(withConstraints: Bool) {
outputForEach(0..<arity, separator: ", ") {
var base = "T\($0)"
if withConstraints {
base += ": \(patternProtocolName)"
}
return base
}
}
// Emit concatenation type declarations.
// public struct Concatenation{n}_{perm}<...>: RegexProtocol {
// public typealias Match = ...
// public let regex: Regex<Match>
// public init(...) { ... }
// }
let typeName =
"\(concatenationStructTypeBaseName)\(arity)_\(permutation.identifier)"
output("public struct \(typeName)<\n ")
emitGenericParameters(withConstraints: true)
output("\n>: \(patternProtocolName)")
if permutation.hasCaptureless {
output(" where ")
outputForEach(permutation.capturelessIndices, separator: ", ") {
"T\($0).\(matchAssociatedTypeName).\(captureAssociatedTypeName): \(emptyProtocolName)"
}
}
output(" {\n")
let captureIndices = permutation.captureIndices
output(" public typealias \(matchAssociatedTypeName) = ")
let captureElements = captureIndices
.map { "T\($0).\(matchAssociatedTypeName).\(captureAssociatedTypeName)" }
if captureElements.isEmpty {
output(baseMatchTypeName)
} else {
let count = captureElements.count + 1
output("Tuple\(count)<\(baseMatchTypeName), \(captureElements.joined(separator: ", "))>")
}
output("\n")
output(" public let \(patternProtocolRequirementName): \(PatternTypeBaseName)<\(matchAssociatedTypeName)>\n")
output(" init(")
outputForEach(0..<arity, separator: ", ") { "_ x\($0): T\($0)" }
output(") {\n")
output(" \(patternProtocolRequirementName) = .init(ast: concat(\n ")
outputForEach(
0..<arity, separator: ", ", lineTerminator: ""
) { i in
"x\(i).\(patternProtocolRequirementName).ast.root"
}
output("))\n")
output(" }\n}\n\n")
// Emit concatenation builders.
output("extension \(patternBuilderTypeName) {\n")
output(" public static func buildBlock<")
emitGenericParameters(withConstraints: true)
output(">(\n ")
outputForEach(0..<arity, separator: ", ") { "_ x\($0): T\($0)" }
output("\n ) -> \(typeName)<")
emitGenericParameters(withConstraints: false)
output("> {\n")
output(" \(typeName)(")
outputForEach(0..<arity, separator: ", ") { "x\($0)" }
output(")\n }\n}\n\n")
}