From 1a96ea852aa96470063f73da1b7c564b2f12047d Mon Sep 17 00:00:00 2001 From: Nate Cook Date: Thu, 7 Apr 2022 15:12:27 -0500 Subject: [PATCH 01/17] Fill out remainder of options API (#246) This adds methods to RegexComponent for the remainder of the regex options, and passes the current MatchingOptions further down into the consumers so that the correct behavior can be used. --- Sources/_StringProcessing/ByteCodeGen.swift | 31 ++-- .../_StringProcessing/CharacterClass.swift | 74 +++++--- .../_StringProcessing/ConsumerInterface.swift | 2 +- .../_StringProcessing/MatchingOptions.swift | 27 ++- Sources/_StringProcessing/Regex/Options.swift | 164 +++++++++++++++++- Tests/RegexBuilderTests/RegexDSLTests.swift | 54 +++--- Tests/RegexTests/MatchTests.swift | 99 ++++++++++- 7 files changed, 379 insertions(+), 72 deletions(-) diff --git a/Sources/_StringProcessing/ByteCodeGen.swift b/Sources/_StringProcessing/ByteCodeGen.swift index d03a1e382..d6d6c3c5e 100644 --- a/Sources/_StringProcessing/ByteCodeGen.swift +++ b/Sources/_StringProcessing/ByteCodeGen.swift @@ -111,30 +111,41 @@ extension Compiler.ByteCodeGen { } case .startOfLine: - builder.buildAssert { (input, pos, bounds) in - pos == input.startIndex || - input[input.index(before: pos)].isNewline + if options.anchorsMatchNewlines { + builder.buildAssert { (input, pos, bounds) in + pos == input.startIndex || input[input.index(before: pos)].isNewline + } + } else { + builder.buildAssert { (input, pos, bounds) in + pos == input.startIndex + } } - + case .endOfLine: - builder.buildAssert { (input, pos, bounds) in - pos == input.endIndex || input[pos].isNewline + if options.anchorsMatchNewlines { + builder.buildAssert { (input, pos, bounds) in + pos == input.endIndex || input[pos].isNewline + } + } else { + builder.buildAssert { (input, pos, bounds) in + pos == input.endIndex + } } case .wordBoundary: // TODO: May want to consider Unicode level - builder.buildAssert { (input, pos, bounds) in + builder.buildAssert { [options] (input, pos, bounds) in // TODO: How should we handle bounds? CharacterClass.word.isBoundary( - input, at: pos, bounds: bounds) + input, at: pos, bounds: bounds, with: options) } case .notWordBoundary: // TODO: May want to consider Unicode level - builder.buildAssert { (input, pos, bounds) in + builder.buildAssert { [options] (input, pos, bounds) in // TODO: How should we handle bounds? !CharacterClass.word.isBoundary( - input, at: pos, bounds: bounds) + input, at: pos, bounds: bounds, with: options) } } } diff --git a/Sources/_StringProcessing/CharacterClass.swift b/Sources/_StringProcessing/CharacterClass.swift index d44fa9fb2..bdf34d0a7 100644 --- a/Sources/_StringProcessing/CharacterClass.swift +++ b/Sources/_StringProcessing/CharacterClass.swift @@ -59,14 +59,14 @@ public struct CharacterClass: Hashable { var op: SetOperator var rhs: CharacterSetComponent - public func matches(_ c: Character) -> Bool { + public func matches(_ c: Character, with options: MatchingOptions) -> Bool { switch op { case .intersection: - return lhs.matches(c) && rhs.matches(c) + return lhs.matches(c, with: options) && rhs.matches(c, with: options) case .subtraction: - return lhs.matches(c) && !rhs.matches(c) + return lhs.matches(c, with: options) && !rhs.matches(c, with: options) case .symmetricDifference: - return lhs.matches(c) != rhs.matches(c) + return lhs.matches(c, with: options) != rhs.matches(c, with: options) } } } @@ -87,14 +87,28 @@ public struct CharacterClass: Hashable { .setOperation(.init(lhs: lhs, op: op, rhs: rhs)) } - public func matches(_ character: Character) -> Bool { + public func matches(_ character: Character, with options: MatchingOptions) -> Bool { switch self { - case .character(let c): return c == character - case .range(let range): return range.contains(character) + case .character(let c): + if options.isCaseInsensitive { + return c.lowercased() == character.lowercased() + } else { + return c == character + } + case .range(let range): + if options.isCaseInsensitive { + let newLower = range.lowerBound.lowercased() + let newUpper = range.upperBound.lowercased() + // FIXME: Is failing this possible? Is this the right behavior if so? + guard newLower <= newUpper else { return false } + return (newLower...newUpper).contains(character.lowercased()) + } else { + return range.contains(character) + } case .characterClass(let custom): let str = String(character) - return custom.matches(in: str, at: str.startIndex) != nil - case .setOperation(let op): return op.matches(character) + return custom.matches(in: str, at: str.startIndex, with: options) != nil + case .setOperation(let op): return op.matches(character, with: options) } } } @@ -135,21 +149,26 @@ public struct CharacterClass: Hashable { /// Returns the end of the match of this character class in `str`, if /// it matches. - public func matches(in str: String, at i: String.Index) -> String.Index? { + public func matches(in str: String, at i: String.Index, with options: MatchingOptions) -> String.Index? { switch matchLevel { case .graphemeCluster: let c = str[i] var matched: Bool switch cc { case .any, .anyGrapheme: matched = true - case .digit: matched = c.isNumber - case .hexDigit: matched = c.isHexDigit + case .digit: + matched = c.isNumber && (c.isASCII || !options.usesASCIIDigits) + case .hexDigit: + matched = c.isHexDigit && (c.isASCII || !options.usesASCIIDigits) case .horizontalWhitespace: fatalError("Not implemented") - case .newlineSequence: matched = c.isNewline + case .newlineSequence: + matched = c.isNewline && (c.isASCII || !options.usesASCIISpaces) case .verticalWhitespace: fatalError("Not implemented") - case .whitespace: matched = c.isWhitespace - case .word: matched = c.isWordCharacter - case .custom(let set): matched = set.any { $0.matches(c) } + case .whitespace: + matched = c.isWhitespace && (c.isASCII || !options.usesASCIISpaces) + case .word: + matched = c.isWordCharacter && (c.isASCII || !options.usesASCIIWord) + case .custom(let set): matched = set.any { $0.matches(c, with: options) } } if isInverted { matched.toggle() @@ -161,13 +180,17 @@ public struct CharacterClass: Hashable { switch cc { case .any: matched = true case .anyGrapheme: fatalError("Not matched in this mode") - case .digit: matched = c.properties.numericType != nil - case .hexDigit: matched = Character(c).isHexDigit + case .digit: + matched = c.properties.numericType != nil && (c.isASCII || !options.usesASCIIDigits) + case .hexDigit: + matched = Character(c).isHexDigit && (c.isASCII || !options.usesASCIIDigits) case .horizontalWhitespace: fatalError("Not implemented") case .newlineSequence: fatalError("Not implemented") case .verticalWhitespace: fatalError("Not implemented") - case .whitespace: matched = c.properties.isWhitespace - case .word: matched = c.properties.isAlphabetic || c == "_" + case .whitespace: + matched = c.properties.isWhitespace && (c.isASCII || !options.usesASCIISpaces) + case .word: + matched = (c.properties.isAlphabetic || c == "_") && (c.isASCII || !options.usesASCIIWord) case .custom: fatalError("Not supported") } if isInverted { @@ -495,21 +518,22 @@ extension CharacterClass { func isBoundary( _ input: String, at pos: String.Index, - bounds: Range + bounds: Range, + with options: MatchingOptions ) -> Bool { // FIXME: How should we handle bounds? // We probably need two concepts if input.isEmpty { return false } if pos == input.startIndex { - return self.matches(in: input, at: pos) != nil + return self.matches(in: input, at: pos, with: options) != nil } let priorIdx = input.index(before: pos) if pos == input.endIndex { - return self.matches(in: input, at: priorIdx) != nil + return self.matches(in: input, at: priorIdx, with: options) != nil } - let prior = self.matches(in: input, at: priorIdx) != nil - let current = self.matches(in: input, at: pos) != nil + let prior = self.matches(in: input, at: priorIdx, with: options) != nil + let current = self.matches(in: input, at: pos, with: options) != nil return prior != current } diff --git a/Sources/_StringProcessing/ConsumerInterface.swift b/Sources/_StringProcessing/ConsumerInterface.swift index 0a2d93ff1..987cbea96 100644 --- a/Sources/_StringProcessing/ConsumerInterface.swift +++ b/Sources/_StringProcessing/ConsumerInterface.swift @@ -136,7 +136,7 @@ extension AST.Atom { ) { return { input, bounds in // FIXME: should we worry about out of bounds? - cc.matches(in: input, at: bounds.lowerBound) + cc.matches(in: input, at: bounds.lowerBound, with: opts) } } diff --git a/Sources/_StringProcessing/MatchingOptions.swift b/Sources/_StringProcessing/MatchingOptions.swift index 899891184..c4b2b8de7 100644 --- a/Sources/_StringProcessing/MatchingOptions.swift +++ b/Sources/_StringProcessing/MatchingOptions.swift @@ -13,7 +13,7 @@ import _RegexParser /// A type that represents the current state of regex matching options, with /// stack-based scoping. -struct MatchingOptions { +public struct MatchingOptions { fileprivate var stack: [Representation] fileprivate func _invariantCheck() { @@ -67,11 +67,32 @@ extension MatchingOptions { stack.last!.contains(.singleLine) } + var anchorsMatchNewlines: Bool { + stack.last!.contains(.multiline) + } + + var usesASCIIWord: Bool { + stack.last!.contains(.asciiOnlyWord) + || stack.last!.contains(.asciiOnlyPOSIXProps) + } + + var usesASCIIDigits: Bool { + stack.last!.contains(.asciiOnlyDigit) + || stack.last!.contains(.asciiOnlyPOSIXProps) + } + + var usesASCIISpaces: Bool { + stack.last!.contains(.asciiOnlySpace) + || stack.last!.contains(.asciiOnlyPOSIXProps) + } + + var usesSimpleUnicodeBoundaries: Bool { + !stack.last!.contains(.unicodeWordBoundaries) + } + enum SemanticLevel { case graphemeCluster case unicodeScalar - // TODO: include? - // case byte } var semanticLevel: SemanticLevel { diff --git a/Sources/_StringProcessing/Regex/Options.swift b/Sources/_StringProcessing/Regex/Options.swift index 04be79c6e..38fba02d6 100644 --- a/Sources/_StringProcessing/Regex/Options.swift +++ b/Sources/_StringProcessing/Regex/Options.swift @@ -12,17 +12,163 @@ import _RegexParser extension RegexComponent { - public func caseSensitive(_ isCaseSensitive: Bool) -> Regex { - // The API is "case sensitive = true or false", so as to avoid the - // double negatives inherent in setting "case insensitive" to a Boolean - // value. The internal version of this option, on the other hand, is - // `.caseInsensitive`, derived from the `(?i)` regex literal option. - let sequence = isCaseSensitive - ? AST.MatchingOptionSequence(removing: [.init(.caseInsensitive, location: .fake)]) - : AST.MatchingOptionSequence(adding: [.init(.caseInsensitive, location: .fake)]) + /// Returns a regular expression that ignores casing when matching. + public func ignoringCase(_ ignoreCase: Bool = true) -> Regex { + wrapInOption(.caseInsensitive, addingIf: ignoreCase) + } + + /// Returns a regular expression that only matches ASCII characters as "word + /// characters". + public func usingASCIIWordCharacters(_ useASCII: Bool = true) -> Regex { + wrapInOption(.asciiOnlyDigit, addingIf: useASCII) + } + + /// Returns a regular expression that only matches ASCII characters as digits. + public func usingASCIIDigits(_ useASCII: Bool = true) -> Regex { + wrapInOption(.asciiOnlyDigit, addingIf: useASCII) + } + + /// Returns a regular expression that only matches ASCII characters as space + /// characters. + public func usingASCIISpaces(_ useASCII: Bool = true) -> Regex { + wrapInOption(.asciiOnlySpace, addingIf: useASCII) + } + + /// Returns a regular expression that only matches ASCII characters when + /// matching character classes. + public func usingASCIICharacterClasses(_ useASCII: Bool = true) -> Regex { + wrapInOption(.asciiOnlyPOSIXProps, addingIf: useASCII) + } + + /// Returns a regular expression that uses the Unicode word boundary + /// algorithm. + /// + /// This option is enabled by default; pass `false` to disable use of + /// Unicode's word boundary algorithm. + public func usingUnicodeWordBoundaries(_ useUnicodeWordBoundaries: Bool = true) -> Regex { + wrapInOption(.unicodeWordBoundaries, addingIf: useUnicodeWordBoundaries) + } + + /// Returns a regular expression where the start and end of input + /// anchors (`^` and `$`) also match against the start and end of a line. + /// + /// - Parameter dotMatchesNewlines: A Boolean value indicating whether `.` + /// should match a newline character. + public func dotMatchesNewlines(_ dotMatchesNewlines: Bool = true) -> Regex { + wrapInOption(.singleLine, addingIf: dotMatchesNewlines) + } + + /// Returns a regular expression that matches with the specified semantic + /// level. + /// + /// When matching with grapheme cluster semantics (the default), + /// metacharacters like `.` and `\w`, custom character classes, and character + /// class instances like `.any` match a grapheme cluster when possible, + /// corresponding with the default string representation. In addition, + /// matching with grapheme cluster semantics compares characters using their + /// canonical representation, corresponding with how strings comparison works. + /// + /// When matching with Unicode scalar semantics, metacharacters and character + /// classes always match a single Unicode scalar value, even if that scalar + /// comprises part of a grapheme cluster. + /// + /// These semantic levels can lead to different results, especially when + /// working with strings that have decomposed characters. In the following + /// example, `queRegex` matches any 3-character string that begins with `"q"`. + /// + /// let composed = "qué" + /// let decomposed = "que\u{301}" + /// + /// let queRegex = /^q..$/ + /// + /// print(composed.contains(queRegex)) + /// // Prints "true" + /// print(decomposed.contains(queRegex)) + /// // Prints "true" + /// + /// When using Unicode scalar semantics, however, the regular expression only + /// matches the composed version of the string, because each `.` matches a + /// single Unicode scalar value. + /// + /// let queRegexScalar = queRegex.matchingSemantics(.unicodeScalar) + /// print(composed.contains(queRegexScalar)) + /// // Prints "true" + /// print(decomposed.contains(queRegexScalar)) + /// // Prints "false" + public func matchingSemantics(_ semanticLevel: RegexSemanticLevel) -> Regex { + switch semanticLevel.base { + case .graphemeCluster: + return wrapInOption(.graphemeClusterSemantics, addingIf: true) + case .unicodeScalar: + return wrapInOption(.unicodeScalarSemantics, addingIf: true) + } + } +} + +public struct RegexSemanticLevel: Hashable { + internal enum Representation { + case graphemeCluster + case unicodeScalar + } + + internal var base: Representation + + /// Match at the default semantic level of a string, where each matched + /// element is a `Character`. + public static var graphemeCluster: RegexSemanticLevel { + .init(base: .graphemeCluster) + } + + /// Match at the semantic level of a string's `UnicodeScalarView`, where each + /// matched element is a `UnicodeScalar` value. + public static var unicodeScalar: RegexSemanticLevel { + .init(base: .unicodeScalar) + } +} + +// Options that only affect literals +extension RegexComponent { + /// Returns a regular expression where the start and end of input + /// anchors (`^` and `$`) also match against the start and end of a line. + /// + /// This method corresponds to applying the `m` option in a regular + /// expression literal, and only applies to regular expressions specified as + /// literals. For this behavior in the `RegexBuilder` syntax, see + /// ``Anchor.startOfLine``, ``Anchor.endOfLine``, ``Anchor.startOfInput``, + /// and ``Anchor.endOfInput``. + /// + /// - Parameter matchLineEndings: A Boolean value indicating whether `^` and + /// `$` should match the start and end of lines, respectively. + public func anchorsMatchLineEndings(_ matchLineEndings: Bool = true) -> Regex { + wrapInOption(.multiline, addingIf: matchLineEndings) + } + + /// Returns a regular expression where quantifiers are reluctant by default + /// instead of eager. + /// + /// This method corresponds to applying the `U` option in a regular + /// expression literal, and only applies to regular expressions specified as + /// literals. In the `RegexBuilder` syntax, pass a ``QuantificationBehavior`` + /// value to any quantification method to change its behavior. + /// + /// - Parameter useReluctantCaptures: A Boolean value indicating whether + /// quantifiers should be reluctant by default. + public func reluctantCaptures(_ useReluctantCaptures: Bool = true) -> Regex { + wrapInOption(.reluctantByDefault, addingIf: useReluctantCaptures) + } +} + +// MARK: - Helper method +extension RegexComponent { + fileprivate func wrapInOption( + _ option: AST.MatchingOption.Kind, + addingIf shouldAdd: Bool) -> Regex + { + let sequence = shouldAdd + ? AST.MatchingOptionSequence(adding: [.init(option, location: .fake)]) + : AST.MatchingOptionSequence(removing: [.init(option, location: .fake)]) return Regex(node: .nonCapturingGroup( .changeMatchingOptions(sequence, isIsolated: false), regex.root)) } } - diff --git a/Tests/RegexBuilderTests/RegexDSLTests.swift b/Tests/RegexBuilderTests/RegexDSLTests.swift index 50358734d..a414e7938 100644 --- a/Tests/RegexBuilderTests/RegexDSLTests.swift +++ b/Tests/RegexBuilderTests/RegexDSLTests.swift @@ -175,7 +175,7 @@ class RegexDSLTests: XCTestCase { matchType: Substring.self, ==) { OneOrMore { "abc" - }.caseSensitive(false) + }.ignoringCase(true) } // Multiple options on one component wrap successively, but do not @@ -189,8 +189,8 @@ class RegexDSLTests: XCTestCase { OneOrMore { "abc" } - .caseSensitive(false) - .caseSensitive(true) + .ignoringCase(true) + .ignoringCase(false) } // An option on an outer component doesn't override an option set on an @@ -204,10 +204,10 @@ class RegexDSLTests: XCTestCase { ("abcdeABCdeaBcde", "abcdeABCdeaBcde"), matchType: Substring.self, ==) { OneOrMore { - "abc".caseSensitive(false) + "abc".ignoringCase(true) Optionally("de") } - .caseSensitive(true) + .ignoringCase(false) } } @@ -216,32 +216,44 @@ class RegexDSLTests: XCTestCase { ("abc1def2", ("abc1def2", "2")), matchType: (Substring, Substring).self, ==) { - OneOrMore { - OneOrMore(.word) - Capture(.digit) - } + OneOrMore(.word) + Capture(.digit) + ZeroOrMore(.any) } try _testDSLCaptures( - ("abc1def2", ("abc1def2", "2")), + ("abc1def2", ("abc1def2", "1")), matchType: (Substring, Substring).self, ==) { - OneOrMore { - OneOrMore(.word, .reluctantly) - Capture(.digit) - } + OneOrMore(.word, .reluctantly) + Capture(.digit) + ZeroOrMore(.any) } - + +#if os(macOS) + try XCTExpectFailure("'relucantCaptures()' API should only affect regex literals") { + try _testDSLCaptures( + ("abc1def2", ("abc1def2", "2")), + matchType: (Substring, Substring).self, ==) + { + Regex { + OneOrMore(.word) + Capture(.digit) + ZeroOrMore(.any) + }.reluctantCaptures() + } + } +#endif + try _testDSLCaptures( - ("abc1def2", ("abc1def2", "2")), + ("abc1def2", ("abc1def2", "1")), matchType: (Substring, Substring).self, ==) { - OneOrMore { - OneOrMore(.reluctantly) { - .word - } - Capture(.digit) + OneOrMore(.reluctantly) { + .word } + Capture(.digit) + ZeroOrMore(.any) } try _testDSLCaptures( diff --git a/Tests/RegexTests/MatchTests.swift b/Tests/RegexTests/MatchTests.swift index 67412d262..494af4c7c 100644 --- a/Tests/RegexTests/MatchTests.swift +++ b/Tests/RegexTests/MatchTests.swift @@ -869,15 +869,15 @@ extension RegexTests { ("123", "123"), (" 123", nil), ("123 456", "123"), - (" 123 \n456", "456"), - (" \n123 \n456", "123")) + (" 123 \n456", nil), + (" \n123 \n456", nil)) firstMatchTests( #"\d+$"#, ("123", "123"), (" 123", "123"), (" 123 \n456", "456"), - (" 123\n456", "123"), + (" 123\n456", "456"), ("123 456", "456")) firstMatchTests( @@ -1197,6 +1197,89 @@ extension RegexTests { ("cafe", true), ("CaFe", true), ("EfAc", true)) + matchTest( + #"(?i)[a-f]{4}"#, + ("cafe", true), + ("CaFe", true), + ("EfAc", true)) + } + + func testASCIIClasses() { + // 'D' ASCII-only digits + matchTest( + #"\d+"#, + ("123", true), + ("¹೨¾", true)) + matchTest( + #"(?D)\d+"#, + ("123", true), + ("¹೨¾", false)) + matchTest( + #"(?P)\d+"#, + ("123", true), + ("¹೨¾", false)) + + // 'W' ASCII-only word characters (and word boundaries) + matchTest( + #"\w+"#, + ("aeiou", true), + ("åe\u{301}ïôú", true)) + matchTest( + #"(?W)\w+"#, + ("aeiou", true), + ("åe\u{301}ïôú", false)) + matchTest( + #"(?P)\w+"#, + ("aeiou", true), + ("åe\u{301}ïôú", false)) + + matchTest( + #"abcd\b.+"#, + ("abcd ef", true), + ("abcdef", false), + ("abcdéf", false)) + matchTest( + #"(?W)abcd\b.+"#, + ("abcd ef", true), + ("abcdef", false), + ("abcdéf", true)) // "dé" matches /d\b./ because "é" isn't ASCII + matchTest( + #"(?P)abcd\b.+"#, + ("abcd ef", true), + ("abcdef", false), + ("abcdéf", true)) // "dé" matches /d\b./ because "é" isn't ASCII + + // 'S' ASCII-only spaces + matchTest( + #"a\sb"#, + ("a\tb", true), + ("a\u{202f}b", true)) // NARROW NO-BREAK SPACE + matchTest( + #"(?S)a\sb"#, + ("a\tb", true), + ("a\u{202f}b", false)) + matchTest( + #"(?P)a\sb"#, + ("a\tb", true), + ("a\u{202f}b", false)) + } + + func testAnchorMatching() throws { + let string = """ + 01: Alabama + 02: Alaska + 03: Arizona + 04: Arkansas + 05: California + """ + XCTAssertTrue(string.contains(try Regex(compiling: #"^\d+"#))) + XCTAssertEqual(string.ranges(of: try Regex(compiling: #"^\d+"#)).count, 1) + XCTAssertEqual(string.ranges(of: try Regex(compiling: #"(?m)^\d+"#)).count, 5) + + let regex = try Regex(compiling: #"^\d+: [\w ]+$"#) + XCTAssertFalse(string.contains(regex)) + let allRanges = string.ranges(of: regex.anchorsMatchLineEndings()) + XCTAssertEqual(allRanges.count, 5) } func testMatchingOptionsScope() { @@ -1220,6 +1303,16 @@ extension RegexTests { firstMatchTest(#"(?s)((?-s)((?i)a)).b"#, input: "a\nb", match: "a\nb") } + func testOptionMethods() throws { + let regex = try Regex(compiling: "c.f.") + XCTAssertTrue ("cafe".contains(regex)) + XCTAssertFalse("CaFe".contains(regex)) + + let caseInsensitiveRegex = regex.ignoringCase() + XCTAssertTrue("cafe".contains(caseInsensitiveRegex)) + XCTAssertTrue("CaFe".contains(caseInsensitiveRegex)) + } + // MARK: Character Semantics var eComposed: String { "é" } From d34daf6e637c6c19602c1a2168ccdf23bbf1f246 Mon Sep 17 00:00:00 2001 From: Tina Liu <49205802+itingliu@users.noreply.github.com> Date: Thu, 7 Apr 2022 12:47:23 -0700 Subject: [PATCH 02/17] Clean up based on the String Processing Algorithms proposal (#247) * Clean up based on the String Processing Algorithms proposal - Move functions and types that have not been proposed from public to internal - Add doc comments for public API - Add FIXME for API awaiting SE-0346 - Replace `_MatchResult` with `Regex.Match` and update tests Co-authored-by: Richard Wei --- .../Algorithms/Algorithms/Contains.swift | 14 ++- .../Algorithms/Algorithms/FirstRange.swift | 21 ++++- .../Algorithms/Algorithms/Ranges.swift | 26 +++--- .../Algorithms/Algorithms/Replace.swift | 71 ++++++++++++--- .../Algorithms/Algorithms/Split.swift | 40 ++++++--- .../Algorithms/Algorithms/StartsWith.swift | 15 ++-- .../Algorithms/Algorithms/Trim.swift | 78 ++++++++++------ .../Consumers/CollectionConsumer.swift | 12 +-- .../Algorithms/Matching/FirstMatch.swift | 19 +++- .../Algorithms/Matching/MatchReplace.swift | 90 +++++++++++++++++-- .../Algorithms/Matching/MatchResult.swift | 16 ++-- .../Algorithms/Matching/Matches.swift | 43 ++++++--- .../Matching/MatchingCollectionConsumer.swift | 8 +- .../Matching/MatchingCollectionSearcher.swift | 20 ++--- .../Searchers/CollectionSearcher.swift | 18 ++-- .../Algorithms/Searchers/PatternOrEmpty.swift | 10 +-- Tests/RegexBuilderTests/AlgorithmsTests.swift | 20 +++-- Tests/RegexBuilderTests/CustomTests.swift | 12 +-- Tests/RegexBuilderTests/RegexDSLTests.swift | 8 +- 19 files changed, 387 insertions(+), 154 deletions(-) diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/Contains.swift b/Sources/_StringProcessing/Algorithms/Algorithms/Contains.swift index dbe7923ec..46568192f 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/Contains.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/Contains.swift @@ -12,7 +12,7 @@ // MARK: `CollectionSearcher` algorithms extension Collection { - public func contains( + func contains( _ searcher: Searcher ) -> Bool where Searcher.Searched == Self { firstRange(of: searcher) != nil @@ -22,6 +22,11 @@ extension Collection { // MARK: Fixed pattern algorithms extension Collection where Element: Equatable { + /// Returns a Boolean value indicating whether the collection contains the + /// given sequence. + /// - Parameter other: A sequence to search for within this collection. + /// - Returns: `true` if the collection contains the specified sequence, + /// otherwise `false`. public func contains(_ other: S) -> Bool where S.Element == Element { @@ -30,7 +35,7 @@ extension Collection where Element: Equatable { } extension BidirectionalCollection where Element: Comparable { - public func contains(_ other: S) -> Bool + func contains(_ other: S) -> Bool where S.Element == Element { firstRange(of: other) != nil @@ -40,6 +45,11 @@ extension BidirectionalCollection where Element: Comparable { // MARK: Regex algorithms extension BidirectionalCollection where SubSequence == Substring { + /// Returns a Boolean value indicating whether the collection contains the + /// given regex. + /// - Parameter regex: A regex to search for within this collection. + /// - Returns: `true` if the regex was found in the collection, otherwise + /// `false`. public func contains(_ regex: R) -> Bool { contains(RegexConsumer(regex)) } diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/FirstRange.swift b/Sources/_StringProcessing/Algorithms/Algorithms/FirstRange.swift index 40d5b9950..405fe47ef 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/FirstRange.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/FirstRange.swift @@ -12,7 +12,7 @@ // MARK: `CollectionSearcher` algorithms extension Collection { - public func firstRange( + func firstRange( of searcher: S ) -> Range? where S.Searched == Self { var state = searcher.state(for: self, in: startIndex..( + func lastRange( of searcher: S ) -> Range? where S.BackwardSearched == Self { var state = searcher.backwardState(for: self, in: startIndex..( of sequence: S ) -> Range? where S.Element == Element { @@ -42,6 +47,11 @@ extension Collection where Element: Equatable { } extension BidirectionalCollection where Element: Comparable { + /// Finds and returns the range of the first occurrence of a given sequence + /// within the collection. + /// - Parameter other: The sequence to search for. + /// - Returns: A range in the collection of the first occurrence of `sequence`. + /// Returns `nil` if `sequence` is not found. public func firstRange( of other: S ) -> Range? where S.Element == Element { @@ -56,11 +66,16 @@ extension BidirectionalCollection where Element: Comparable { // MARK: Regex algorithms extension BidirectionalCollection where SubSequence == Substring { + /// Finds and returns the range of the first occurrence of a given regex + /// within the collection. + /// - Parameter regex: The regex to search for. + /// - Returns: A range in the collection of the first occurrence of `regex`. + /// Returns `nil` if `regex` is not found. public func firstRange(of regex: R) -> Range? { firstRange(of: RegexConsumer(regex)) } - public func lastRange(of regex: R) -> Range? { + func lastRange(of regex: R) -> Range? { lastRange(of: RegexConsumer(regex)) } } diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/Ranges.swift b/Sources/_StringProcessing/Algorithms/Algorithms/Ranges.swift index e56e35e72..3a45b86a2 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/Ranges.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/Ranges.swift @@ -11,7 +11,7 @@ // MARK: `RangesCollection` -public struct RangesCollection { +struct RangesCollection { public typealias Base = Searcher.Searched let base: Base @@ -33,7 +33,7 @@ public struct RangesCollection { } } -public struct RangesIterator: IteratorProtocol { +struct RangesIterator: IteratorProtocol { public typealias Base = Searcher.Searched let base: Base @@ -92,7 +92,7 @@ extension RangesCollection: Collection { } extension RangesCollection.Index: Comparable { - public static func == (lhs: Self, rhs: Self) -> Bool { + static func == (lhs: Self, rhs: Self) -> Bool { switch (lhs.range, rhs.range) { case (nil, nil): return true @@ -103,7 +103,7 @@ extension RangesCollection.Index: Comparable { } } - public static func < (lhs: Self, rhs: Self) -> Bool { + static func < (lhs: Self, rhs: Self) -> Bool { switch (lhs.range, rhs.range) { case (nil, _): return false @@ -117,8 +117,8 @@ extension RangesCollection.Index: Comparable { // MARK: `ReversedRangesCollection` -public struct ReversedRangesCollection { - public typealias Base = Searcher.BackwardSearched +struct ReversedRangesCollection { + typealias Base = Searcher.BackwardSearched let base: Base let searcher: Searcher @@ -157,7 +157,7 @@ extension ReversedRangesCollection: Sequence { // MARK: `CollectionSearcher` algorithms extension Collection { - public func ranges( + func ranges( of searcher: S ) -> RangesCollection where S.Searched == Self { RangesCollection(base: self, searcher: searcher) @@ -165,7 +165,7 @@ extension Collection { } extension BidirectionalCollection { - public func rangesFromBack( + func rangesFromBack( of searcher: S ) -> ReversedRangesCollection where S.BackwardSearched == Self { ReversedRangesCollection(base: self, searcher: searcher) @@ -175,7 +175,8 @@ extension BidirectionalCollection { // MARK: Fixed pattern algorithms extension Collection where Element: Equatable { - public func ranges( + // FIXME: Replace `RangesCollection` when SE-0346 is enabled + func ranges( of other: S ) -> RangesCollection> where S.Element == Element { ranges(of: ZSearcher(pattern: Array(other), by: ==)) @@ -194,7 +195,7 @@ extension BidirectionalCollection where Element: Equatable { } extension BidirectionalCollection where Element: Comparable { - public func ranges( + func ranges( of other: S ) -> RangesCollection>> where S.Element == Element @@ -216,13 +217,14 @@ extension BidirectionalCollection where Element: Comparable { // MARK: Regex algorithms extension BidirectionalCollection where SubSequence == Substring { - public func ranges( + // FIXME: Replace `RangesCollection` when SE-0346 is enabled + func ranges( of regex: R ) -> RangesCollection> { ranges(of: RegexConsumer(regex)) } - public func rangesFromBack( + func rangesFromBack( of regex: R ) -> ReversedRangesCollection> { rangesFromBack(of: RegexConsumer(regex)) diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/Replace.swift b/Sources/_StringProcessing/Algorithms/Algorithms/Replace.swift index e2c9d78a4..bc23a284c 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/Replace.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/Replace.swift @@ -12,7 +12,7 @@ // MARK: `CollectionSearcher` algorithms extension RangeReplaceableCollection { - public func replacing( + func replacing( _ searcher: Searcher, with replacement: Replacement, subrange: Range, @@ -36,7 +36,7 @@ extension RangeReplaceableCollection { return result } - public func replacing( + func replacing( _ searcher: Searcher, with replacement: Replacement, maxReplacements: Int = .max @@ -50,7 +50,7 @@ extension RangeReplaceableCollection { maxReplacements: maxReplacements) } - public mutating func replace< + mutating func replace< Searcher: CollectionSearcher, Replacement: Collection >( _ searcher: Searcher, @@ -67,6 +67,16 @@ extension RangeReplaceableCollection { // MARK: Fixed pattern algorithms extension RangeReplaceableCollection where Element: Equatable { + /// Returns a new collection in which all occurrences of a target sequence + /// are replaced by another collection. + /// - Parameters: + /// - other: The sequence to replace. + /// - replacement: The new elements to add to the collection. + /// - subrange: The range in the collection in which to search for `other`. + /// - maxReplacements: A number specifying how many occurrences of `other` + /// to replace. Default is `Int.max`. + /// - Returns: A new collection in which all occurrences of `other` in + /// `subrange` of the collection are replaced by `replacement`. public func replacing( _ other: S, with replacement: Replacement, @@ -79,7 +89,16 @@ extension RangeReplaceableCollection where Element: Equatable { subrange: subrange, maxReplacements: maxReplacements) } - + + /// Returns a new collection in which all occurrences of a target sequence + /// are replaced by another collection. + /// - Parameters: + /// - other: The sequence to replace. + /// - replacement: The new elements to add to the collection. + /// - maxReplacements: A number specifying how many occurrences of `other` + /// to replace. Default is `Int.max`. + /// - Returns: A new collection in which all occurrences of `other` in + /// `subrange` of the collection are replaced by `replacement`. public func replacing( _ other: S, with replacement: Replacement, @@ -91,7 +110,13 @@ extension RangeReplaceableCollection where Element: Equatable { subrange: startIndex..( _ other: S, with replacement: Replacement, @@ -108,7 +133,7 @@ extension RangeReplaceableCollection where Element: Equatable { extension RangeReplaceableCollection where Self: BidirectionalCollection, Element: Comparable { - public func replacing( + func replacing( _ other: S, with replacement: Replacement, subrange: Range, @@ -121,7 +146,7 @@ extension RangeReplaceableCollection maxReplacements: maxReplacements) } - public func replacing( + func replacing( _ other: S, with replacement: Replacement, maxReplacements: Int = .max @@ -133,7 +158,7 @@ extension RangeReplaceableCollection maxReplacements: maxReplacements) } - public mutating func replace( + mutating func replace( _ other: S, with replacement: Replacement, maxReplacements: Int = .max @@ -149,6 +174,16 @@ extension RangeReplaceableCollection // MARK: Regex algorithms extension RangeReplaceableCollection where SubSequence == Substring { + /// Returns a new collection in which all occurrences of a sequence matching + /// the given regex are replaced by another collection. + /// - Parameters: + /// - regex: A regex describing the sequence to replace. + /// - replacement: The new elements to add to the collection. + /// - subrange: The range in the collection in which to search for `regex`. + /// - maxReplacements: A number specifying how many occurrences of the + /// sequence matching `regex` to replace. Default is `Int.max`. + /// - Returns: A new collection in which all occurrences of subsequence + /// matching `regex` in `subrange` are replaced by `replacement`. public func replacing( _ regex: R, with replacement: Replacement, @@ -161,7 +196,16 @@ extension RangeReplaceableCollection where SubSequence == Substring { subrange: subrange, maxReplacements: maxReplacements) } - + + /// Returns a new collection in which all occurrences of a sequence matching + /// the given regex are replaced by another collection. + /// - Parameters: + /// - regex: A regex describing the sequence to replace. + /// - replacement: The new elements to add to the collection. + /// - maxReplacements: A number specifying how many occurrences of the + /// sequence matching `regex` to replace. Default is `Int.max`. + /// - Returns: A new collection in which all occurrences of subsequence + /// matching `regex` are replaced by `replacement`. public func replacing( _ regex: R, with replacement: Replacement, @@ -173,7 +217,14 @@ extension RangeReplaceableCollection where SubSequence == Substring { subrange: startIndex..( _ regex: R, with replacement: Replacement, diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/Split.swift b/Sources/_StringProcessing/Algorithms/Algorithms/Split.swift index 15c946ca2..898f93048 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/Split.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/Split.swift @@ -11,7 +11,7 @@ // MARK: `SplitCollection` -public struct SplitCollection { +struct SplitCollection { public typealias Base = Searcher.Searched let ranges: RangesCollection @@ -101,7 +101,7 @@ extension SplitCollection: Collection { } extension SplitCollection.Index: Comparable { - public static func == (lhs: Self, rhs: Self) -> Bool { + static func == (lhs: Self, rhs: Self) -> Bool { switch (lhs.isEndIndex, rhs.isEndIndex) { case (false, false): return lhs.start == rhs.start @@ -110,7 +110,7 @@ extension SplitCollection.Index: Comparable { } } - public static func < (lhs: Self, rhs: Self) -> Bool { + static func < (lhs: Self, rhs: Self) -> Bool { switch (lhs.isEndIndex, rhs.isEndIndex) { case (true, _): return false @@ -124,7 +124,7 @@ extension SplitCollection.Index: Comparable { // MARK: `ReversedSplitCollection` -public struct ReversedSplitCollection { +struct ReversedSplitCollection { public typealias Base = Searcher.BackwardSearched let ranges: ReversedRangesCollection @@ -175,7 +175,7 @@ extension ReversedSplitCollection: Sequence { // MARK: `CollectionSearcher` algorithms extension Collection { - public func split( + func split( by separator: Searcher ) -> SplitCollection where Searcher.Searched == Self { // TODO: `maxSplits`, `omittingEmptySubsequences`? @@ -184,7 +184,7 @@ extension Collection { } extension BidirectionalCollection { - public func splitFromBack( + func splitFromBack( by separator: Searcher ) -> ReversedSplitCollection where Searcher.BackwardSearched == Self @@ -197,7 +197,7 @@ extension BidirectionalCollection { extension Collection { // TODO: Non-escaping and throwing - public func split( + func split( whereSeparator predicate: @escaping (Element) -> Bool ) -> SplitCollection> { split(by: PredicateConsumer(predicate: predicate)) @@ -205,7 +205,7 @@ extension Collection { } extension BidirectionalCollection where Element: Equatable { - public func splitFromBack( + func splitFromBack( whereSeparator predicate: @escaping (Element) -> Bool ) -> ReversedSplitCollection> { splitFromBack(by: PredicateConsumer(predicate: predicate)) @@ -215,7 +215,7 @@ extension BidirectionalCollection where Element: Equatable { // MARK: Single element algorithms extension Collection where Element: Equatable { - public func split( + func split( by separator: Element ) -> SplitCollection> { split(whereSeparator: { $0 == separator }) @@ -223,7 +223,7 @@ extension Collection where Element: Equatable { } extension BidirectionalCollection where Element: Equatable { - public func splitFromBack( + func splitFromBack( by separator: Element ) -> ReversedSplitCollection> { splitFromBack(whereSeparator: { $0 == separator }) @@ -233,7 +233,13 @@ extension BidirectionalCollection where Element: Equatable { // MARK: Fixed pattern algorithms extension Collection where Element: Equatable { - public func split( + // FIXME: Replace `SplitCollection` when SE-0346 is enabled + /// Returns the longest possible subsequences of the collection, in order, + /// around elements equal to the given separator. + /// - Parameter separator: The element to be split upon. + /// - Returns: A collection of subsequences, split from this collection's + /// elements. + func split( by separator: S ) -> SplitCollection> where S.Element == Element { split(by: ZSearcher(pattern: Array(separator), by: ==)) @@ -252,7 +258,7 @@ extension BidirectionalCollection where Element: Equatable { } extension BidirectionalCollection where Element: Comparable { - public func split( + func split( by separator: S ) -> SplitCollection>> where S.Element == Element @@ -275,13 +281,19 @@ extension BidirectionalCollection where Element: Comparable { // MARK: Regex algorithms extension BidirectionalCollection where SubSequence == Substring { - public func split( + // FIXME: Replace `SplitCollection` when SE-0346 is enabled + /// Returns the longest possible subsequences of the collection, in order, + /// around elements equal to the given separator. + /// - Parameter separator: A regex describing elements to be split upon. + /// - Returns: A collection of substrings, split from this collection's + /// elements. + func split( by separator: R ) -> SplitCollection> { split(by: RegexConsumer(separator)) } - public func splitFromBack( + func splitFromBack( by separator: R ) -> ReversedSplitCollection> { splitFromBack(by: RegexConsumer(separator)) diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/StartsWith.swift b/Sources/_StringProcessing/Algorithms/Algorithms/StartsWith.swift index 75c6e1133..346094f9e 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/StartsWith.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/StartsWith.swift @@ -12,7 +12,7 @@ // MARK: `CollectionConsumer` algorithms extension Collection { - public func starts(with consumer: C) -> Bool + func starts(with consumer: C) -> Bool where C.Consumed == SubSequence { consumer.consuming(self[...]) != nil @@ -20,7 +20,7 @@ extension Collection { } extension BidirectionalCollection { - public func ends(with consumer: C) -> Bool + func ends(with consumer: C) -> Bool where C.Consumed == SubSequence { consumer.consumingBack(self[...]) != nil @@ -30,7 +30,7 @@ extension BidirectionalCollection { // MARK: Fixed pattern algorithms extension Collection where Element: Equatable { - public func starts(with prefix: C) -> Bool + func starts(with prefix: C) -> Bool where C.Element == Element { starts(with: FixedPatternConsumer(pattern: prefix)) @@ -38,7 +38,7 @@ extension Collection where Element: Equatable { } extension BidirectionalCollection where Element: Equatable { - public func ends(with suffix: C) -> Bool + func ends(with suffix: C) -> Bool where C.Element == Element { ends(with: FixedPatternConsumer(pattern: suffix)) @@ -48,11 +48,16 @@ extension BidirectionalCollection where Element: Equatable { // MARK: Regex algorithms extension BidirectionalCollection where SubSequence == Substring { + /// Returns a Boolean value indicating whether the initial elements of the + /// sequence are the same as the elements in the specified regex. + /// - Parameter regex: A regex to compare to this sequence. + /// - Returns: `true` if the initial elements of the sequence matches the + /// beginning of `regex`; otherwise, `false`. public func starts(with regex: R) -> Bool { starts(with: RegexConsumer(regex)) } - public func ends(with regex: R) -> Bool { + func ends(with regex: R) -> Bool { ends(with: RegexConsumer(regex)) } } diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/Trim.swift b/Sources/_StringProcessing/Algorithms/Algorithms/Trim.swift index 65a71e1b7..ed7cd7bc4 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/Trim.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/Trim.swift @@ -12,7 +12,7 @@ // MARK: `CollectionConsumer` algorithms extension Collection { - public func trimmingPrefix( + func trimmingPrefix( _ consumer: Consumer ) -> SubSequence where Consumer.Consumed == Self { let start = consumer.consuming(self) ?? startIndex @@ -21,7 +21,7 @@ extension Collection { } extension Collection where SubSequence == Self { - public mutating func trimPrefix( + mutating func trimPrefix( _ consumer: Consumer ) where Consumer.Consumed == Self { _ = consumer.consume(&self) @@ -32,7 +32,7 @@ extension RangeReplaceableCollection { // NOTE: Disfavored because the `Collection with SubSequence == Self` overload // should be preferred whenever both are available @_disfavoredOverload - public mutating func trimPrefix( + mutating func trimPrefix( _ consumer: Consumer ) where Consumer.Consumed == Self { if let start = consumer.consuming(self) { @@ -42,7 +42,7 @@ extension RangeReplaceableCollection { } extension BidirectionalCollection { - public func trimmingSuffix( + func trimmingSuffix( _ consumer: Consumer ) -> SubSequence where Consumer.Consumed == Self @@ -51,7 +51,7 @@ extension BidirectionalCollection { return self[..( + func trimming( _ consumer: Consumer ) -> SubSequence where Consumer.Consumed == Self { // NOTE: Might give different results than trimming the suffix before @@ -64,7 +64,7 @@ extension BidirectionalCollection { } extension BidirectionalCollection where SubSequence == Self { - public mutating func trimSuffix( + mutating func trimSuffix( _ consumer: Consumer ) where Consumer.Consumed == SubSequence { @@ -81,7 +81,7 @@ extension BidirectionalCollection where SubSequence == Self { extension RangeReplaceableCollection where Self: BidirectionalCollection { @_disfavoredOverload - public mutating func trimSuffix( + mutating func trimSuffix( _ consumer: Consumer ) where Consumer.Consumed == Self { @@ -103,7 +103,7 @@ extension RangeReplaceableCollection where Self: BidirectionalCollection { extension Collection { // TODO: Non-escaping and throwing - public func trimmingPrefix( + func trimmingPrefix( while predicate: @escaping (Element) -> Bool ) -> SubSequence { trimmingPrefix(ManyConsumer(base: PredicateConsumer(predicate: predicate))) @@ -129,13 +129,13 @@ extension RangeReplaceableCollection { } extension BidirectionalCollection { - public func trimmingSuffix( + func trimmingSuffix( while predicate: @escaping (Element) -> Bool ) -> SubSequence { trimmingSuffix(ManyConsumer(base: PredicateConsumer(predicate: predicate))) } - public func trimming( + func trimming( while predicate: @escaping (Element) -> Bool ) -> SubSequence { trimming(ManyConsumer(base: PredicateConsumer(predicate: predicate))) @@ -143,14 +143,14 @@ extension BidirectionalCollection { } extension BidirectionalCollection where SubSequence == Self { - public mutating func trimSuffix( + mutating func trimSuffix( while predicate: @escaping (Element) -> Bool ) { trimSuffix(ManyConsumer( base: PredicateConsumer(predicate: predicate))) } - public mutating func trim(while predicate: @escaping (Element) -> Bool) { + mutating func trim(while predicate: @escaping (Element) -> Bool) { let consumer = ManyConsumer( base: PredicateConsumer(predicate: predicate)) trimPrefix(consumer) @@ -160,14 +160,14 @@ extension BidirectionalCollection where SubSequence == Self { extension RangeReplaceableCollection where Self: BidirectionalCollection { @_disfavoredOverload - public mutating func trimSuffix( + mutating func trimSuffix( while predicate: @escaping (Element) -> Bool ) { trimSuffix(ManyConsumer(base: PredicateConsumer(predicate: predicate))) } @_disfavoredOverload - public mutating func trim(while predicate: @escaping (Element) -> Bool) { + mutating func trim(while predicate: @escaping (Element) -> Bool) { let consumer = ManyConsumer( base: PredicateConsumer(predicate: predicate)) trimPrefix(consumer) @@ -178,6 +178,13 @@ extension RangeReplaceableCollection where Self: BidirectionalCollection { // MARK: Fixed pattern algorithms extension Collection where Element: Equatable { + /// Returns a new collection of the same type by removing initial elements + /// that satisfy the given predicate from the start. + /// - Parameter predicate: A closure that takes an element of the sequence + /// as its argument and returns a Boolean value indicating whether the + /// element should be removed from the collection. + /// - Returns: A collection containing the elements of the collection that are + /// not removed by `predicate`. public func trimmingPrefix( _ prefix: Prefix ) -> SubSequence where Prefix.Element == Element { @@ -186,6 +193,11 @@ extension Collection where Element: Equatable { } extension Collection where SubSequence == Self, Element: Equatable { + /// Removes the initial elements that satisfy the given predicate from the + /// start of the sequence. + /// - Parameter predicate: A closure that takes an element of the sequence + /// as its argument and returns a Boolean value indicating whether the + /// element should be removed from the collection. public mutating func trimPrefix( _ prefix: Prefix ) where Prefix.Element == Element { @@ -195,6 +207,11 @@ extension Collection where SubSequence == Self, Element: Equatable { extension RangeReplaceableCollection where Element: Equatable { @_disfavoredOverload + /// Removes the initial elements that satisfy the given predicate from the + /// start of the sequence. + /// - Parameter predicate: A closure that takes an element of the sequence + /// as its argument and returns a Boolean value indicating whether the + /// element should be removed from the collection. public mutating func trimPrefix( _ prefix: Prefix ) where Prefix.Element == Element { @@ -203,13 +220,13 @@ extension RangeReplaceableCollection where Element: Equatable { } extension BidirectionalCollection where Element: Equatable { - public func trimmingSuffix( + func trimmingSuffix( _ suffix: Suffix ) -> SubSequence where Suffix.Element == Element { trimmingSuffix(FixedPatternConsumer(pattern: suffix)) } - public func trimming( + func trimming( _ pattern: Pattern ) -> SubSequence where Pattern.Element == Element { trimming(FixedPatternConsumer(pattern: pattern)) @@ -219,13 +236,13 @@ extension BidirectionalCollection where Element: Equatable { extension BidirectionalCollection where SubSequence == Self, Element: Equatable { - public mutating func trimSuffix( + mutating func trimSuffix( _ suffix: Suffix ) where Suffix.Element == Element { trimSuffix(FixedPatternConsumer(pattern: suffix)) } - public mutating func trim( + mutating func trim( _ pattern: Pattern ) where Pattern.Element == Element { let consumer = FixedPatternConsumer(pattern: pattern) @@ -238,14 +255,14 @@ extension RangeReplaceableCollection where Self: BidirectionalCollection, Element: Equatable { @_disfavoredOverload - public mutating func trimSuffix( + mutating func trimSuffix( _ prefix: Suffix ) where Suffix.Element == Element { trimSuffix(FixedPatternConsumer(pattern: prefix)) } @_disfavoredOverload - public mutating func trim( + mutating func trim( _ pattern: Pattern ) where Pattern.Element == Element { let consumer = FixedPatternConsumer(pattern: pattern) @@ -257,15 +274,20 @@ extension RangeReplaceableCollection // MARK: Regex algorithms extension BidirectionalCollection where SubSequence == Substring { + /// Returns a new collection of the same type by removing `prefix` from the + /// start. + /// - Parameter prefix: The collection to remove from this collection. + /// - Returns: A collection containing the elements that does not match + /// `prefix` from the start. public func trimmingPrefix(_ regex: R) -> SubSequence { trimmingPrefix(RegexConsumer(regex)) } - public func trimmingSuffix(_ regex: R) -> SubSequence { + func trimmingSuffix(_ regex: R) -> SubSequence { trimmingSuffix(RegexConsumer(regex)) } - public func trimming(_ regex: R) -> SubSequence { + func trimming(_ regex: R) -> SubSequence { trimming(RegexConsumer(regex)) } } @@ -273,15 +295,17 @@ extension BidirectionalCollection where SubSequence == Substring { extension RangeReplaceableCollection where Self: BidirectionalCollection, SubSequence == Substring { + /// Removes the initial elements that matches the given regex. + /// - Parameter regex: The regex to remove from this collection. public mutating func trimPrefix(_ regex: R) { trimPrefix(RegexConsumer(regex)) } - public mutating func trimSuffix(_ regex: R) { + mutating func trimSuffix(_ regex: R) { trimSuffix(RegexConsumer(regex)) } - public mutating func trim(_ regex: R) { + mutating func trim(_ regex: R) { let consumer = RegexConsumer(regex) trimPrefix(consumer) trimSuffix(consumer) @@ -289,15 +313,15 @@ extension RangeReplaceableCollection } extension Substring { - public mutating func trimPrefix(_ regex: R) { + mutating func trimPrefix(_ regex: R) { trimPrefix(RegexConsumer(regex)) } - public mutating func trimSuffix(_ regex: R) { + mutating func trimSuffix(_ regex: R) { trimSuffix(RegexConsumer(regex)) } - public mutating func trim(_ regex: R) { + mutating func trim(_ regex: R) { let consumer = RegexConsumer(regex) trimPrefix(consumer) trimSuffix(consumer) diff --git a/Sources/_StringProcessing/Algorithms/Consumers/CollectionConsumer.swift b/Sources/_StringProcessing/Algorithms/Consumers/CollectionConsumer.swift index 95f772d7b..b71af470e 100644 --- a/Sources/_StringProcessing/Algorithms/Consumers/CollectionConsumer.swift +++ b/Sources/_StringProcessing/Algorithms/Consumers/CollectionConsumer.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -public protocol CollectionConsumer { +protocol CollectionConsumer { associatedtype Consumed: Collection func consuming( _ consumed: Consumed, @@ -18,13 +18,13 @@ public protocol CollectionConsumer { } extension CollectionConsumer { - public func consuming(_ consumed: Consumed) -> Consumed.Index? { + func consuming(_ consumed: Consumed) -> Consumed.Index? { consuming(consumed, in: consumed.startIndex.. Bool + func consume(_ consumed: inout Consumed) -> Bool where Consumed.SubSequence == Consumed { guard let index = consuming(consumed) else { return false } @@ -35,7 +35,7 @@ extension CollectionConsumer { // MARK: Consuming from the back -public protocol BidirectionalCollectionConsumer: CollectionConsumer +protocol BidirectionalCollectionConsumer: CollectionConsumer where Consumed: BidirectionalCollection { func consumingBack( @@ -45,11 +45,11 @@ public protocol BidirectionalCollectionConsumer: CollectionConsumer } extension BidirectionalCollectionConsumer { - public func consumingBack(_ consumed: Consumed) -> Consumed.Index? { + func consumingBack(_ consumed: Consumed) -> Consumed.Index? { consumingBack(consumed, in: consumed.startIndex.. Bool + func consumeBack(_ consumed: inout Consumed) -> Bool where Consumed.SubSequence == Consumed { guard let index = consumingBack(consumed) else { return false } diff --git a/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift b/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift index c0699b805..2aea0f342 100644 --- a/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift +++ b/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift @@ -12,7 +12,7 @@ // MARK: `CollectionSearcher` algorithms extension Collection { - public func firstMatch( + func firstMatch( of searcher: S ) -> _MatchResult? where S.Searched == Self { var state = searcher.state(for: self, in: startIndex..( + func lastMatch( of searcher: S ) -> _BackwardMatchResult? where S.BackwardSearched == Self @@ -38,15 +38,26 @@ extension BidirectionalCollection { // MARK: Regex algorithms extension BidirectionalCollection where SubSequence == Substring { - public func firstMatch( + func firstMatch( of regex: R ) -> _MatchResult>? { firstMatch(of: RegexConsumer(regex)) } - public func lastMatch( + func lastMatch( of regex: R ) -> _BackwardMatchResult>? { lastMatch(of: RegexConsumer(regex)) } + + /// Returns the first match of the specified regex within the collection. + /// - Parameter regex: The regex to search for. + /// - Returns: The first match of `regex` in the collection, or `nil` if + /// there isn't a match. + public func firstMatch( + of regex: R + ) -> Regex.Match? { + let slice = self[...] + return try? regex.firstMatch(in: slice.base) + } } diff --git a/Sources/_StringProcessing/Algorithms/Matching/MatchReplace.swift b/Sources/_StringProcessing/Algorithms/Matching/MatchReplace.swift index f99e525b5..74ab48839 100644 --- a/Sources/_StringProcessing/Algorithms/Matching/MatchReplace.swift +++ b/Sources/_StringProcessing/Algorithms/Matching/MatchReplace.swift @@ -12,7 +12,7 @@ // MARK: `MatchingCollectionSearcher` algorithms extension RangeReplaceableCollection { - public func replacing< + func replacing< Searcher: MatchingCollectionSearcher, Replacement: Collection >( _ searcher: Searcher, @@ -40,7 +40,7 @@ extension RangeReplaceableCollection { return result } - public func replacing< + func replacing< Searcher: MatchingCollectionSearcher, Replacement: Collection >( _ searcher: Searcher, @@ -56,7 +56,7 @@ extension RangeReplaceableCollection { maxReplacements: maxReplacements) } - public mutating func replace< + mutating func replace< Searcher: MatchingCollectionSearcher, Replacement: Collection >( _ searcher: Searcher, @@ -75,7 +75,7 @@ extension RangeReplaceableCollection { // MARK: Regex algorithms extension RangeReplaceableCollection where SubSequence == Substring { - public func replacing( + func replacing( _ regex: R, with replacement: (_MatchResult>) throws -> Replacement, subrange: Range, @@ -88,7 +88,7 @@ extension RangeReplaceableCollection where SubSequence == Substring { maxReplacements: maxReplacements) } - public func replacing( + func replacing( _ regex: R, with replacement: (_MatchResult>) throws -> Replacement, maxReplacements: Int = .max @@ -100,7 +100,7 @@ extension RangeReplaceableCollection where SubSequence == Substring { maxReplacements: maxReplacements) } - public mutating func replace( + mutating func replace( _ regex: R, with replacement: (_MatchResult>) throws -> Replacement, maxReplacements: Int = .max @@ -110,4 +110,82 @@ extension RangeReplaceableCollection where SubSequence == Substring { with: replacement, maxReplacements: maxReplacements) } + + /// Returns a new collection in which all occurrences of a sequence matching + /// the given regex are replaced by another regex match. + /// - Parameters: + /// - regex: A regex describing the sequence to replace. + /// - replacement: A closure that receives the full match information, + /// including captures, and returns a replacement collection. + /// - subrange: The range in the collection in which to search for `regex`. + /// - maxReplacements: A number specifying how many occurrences of the + /// sequence matching `regex` to replace. Default is `Int.max`. + /// - Returns: A new collection in which all occurrences of subsequence + /// matching `regex` are replaced by `replacement`. + public func replacing( + _ regex: R, + with replacement: (Regex.Match) throws -> Replacement, + subrange: Range, + maxReplacements: Int = .max + ) rethrows -> Self where Replacement.Element == Element { + + precondition(maxReplacements >= 0) + + var index = subrange.lowerBound + var result = Self() + result.append(contentsOf: self[..( + _ regex: R, + with replacement: (Regex.Match) throws -> Replacement, + maxReplacements: Int = .max + ) rethrows -> Self where Replacement.Element == Element { + try replacing( + regex, + with: replacement, + subrange: startIndex..( + _ regex: R, + with replacement: (Regex.Match) throws -> Replacement, + maxReplacements: Int = .max + ) rethrows where Replacement.Element == Element { + self = try replacing( + regex, + with: replacement, + subrange: startIndex.. { - public let match: S.Searched.SubSequence - public let result: S.Match +struct _MatchResult { + let match: S.Searched.SubSequence + let result: S.Match - public var range: Range { + var range: Range { match.startIndex.. { - public let match: S.BackwardSearched.SubSequence - public let result: S.Match +struct _BackwardMatchResult { + let match: S.BackwardSearched.SubSequence + let result: S.Match - public var range: Range { + var range: Range { match.startIndex.. { +struct MatchesCollection { public typealias Base = Searcher.Searched let base: Base @@ -33,7 +33,7 @@ public struct MatchesCollection { } } -public struct MatchesIterator< +struct MatchesIterator< Searcher: MatchingCollectionSearcher >: IteratorProtocol { public typealias Base = Searcher.Searched @@ -64,7 +64,7 @@ extension MatchesCollection: Sequence { extension MatchesCollection: Collection { // TODO: Custom `SubSequence` for the sake of more efficient slice iteration - public struct Index { + struct Index { var match: (range: Range, match: Searcher.Match)? var state: Searcher.State } @@ -122,7 +122,7 @@ extension MatchesCollection.Index: Comparable { // MARK: `ReversedMatchesCollection` // TODO: reversed matches -public struct ReversedMatchesCollection< +struct ReversedMatchesCollection< Searcher: BackwardMatchingCollectionSearcher > { public typealias Base = Searcher.BackwardSearched @@ -137,7 +137,7 @@ public struct ReversedMatchesCollection< } extension ReversedMatchesCollection: Sequence { - public struct Iterator: IteratorProtocol { + struct Iterator: IteratorProtocol { let base: Base let searcher: Searcher var state: Searcher.BackwardState @@ -166,7 +166,7 @@ extension ReversedMatchesCollection: Sequence { // MARK: `CollectionSearcher` algorithms extension Collection { - public func matches( + func matches( of searcher: S ) -> MatchesCollection where S.Searched == Self { MatchesCollection(base: self, searcher: searcher) @@ -174,7 +174,7 @@ extension Collection { } extension BidirectionalCollection { - public func matchesFromBack( + func matchesFromBack( of searcher: S ) -> ReversedMatchesCollection where S.BackwardSearched == Self { ReversedMatchesCollection(base: self, searcher: searcher) @@ -184,15 +184,38 @@ extension BidirectionalCollection { // MARK: Regex algorithms extension BidirectionalCollection where SubSequence == Substring { - public func matches( + // FIXME: Replace `MatchesCollection` when SE-0346 is enabled + /// Returns a collection containing all matches of the specified regex. + /// - Parameter regex: The regex to search for. + /// - Returns: A collection of matches of `regex`. + func matches( of regex: R ) -> MatchesCollection> { matches(of: RegexConsumer(regex)) } - - public func matchesFromBack( + + func matchesFromBack( of regex: R ) -> ReversedMatchesCollection> { matchesFromBack(of: RegexConsumer(regex)) } + + // FIXME: Replace the returned value as `some Collection.Match> + // when SE-0346 is enabled + func _matches(of regex: R) -> [Regex.Match] { + let slice = self[...] + var start = self.startIndex + let end = self.endIndex + + var result = [Regex.Match]() + while start < end { + guard let match = try? regex._firstMatch(slice.base, in: start.. ) -> Consumed.Index? { @@ -28,7 +28,7 @@ extension MatchingCollectionConsumer { // MARK: Consuming from the back -public protocol BidirectionalMatchingCollectionConsumer: +protocol BidirectionalMatchingCollectionConsumer: MatchingCollectionConsumer, BidirectionalCollectionConsumer { func matchingConsumingBack( @@ -38,7 +38,7 @@ public protocol BidirectionalMatchingCollectionConsumer: } extension BidirectionalMatchingCollectionConsumer { - public func consumingBack( + func consumingBack( _ consumed: Consumed, in range: Range ) -> Consumed.Index? { diff --git a/Sources/_StringProcessing/Algorithms/Matching/MatchingCollectionSearcher.swift b/Sources/_StringProcessing/Algorithms/Matching/MatchingCollectionSearcher.swift index eadb46f9e..902d94591 100644 --- a/Sources/_StringProcessing/Algorithms/Matching/MatchingCollectionSearcher.swift +++ b/Sources/_StringProcessing/Algorithms/Matching/MatchingCollectionSearcher.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -public protocol MatchingCollectionSearcher: CollectionSearcher { +protocol MatchingCollectionSearcher: CollectionSearcher { associatedtype Match func matchingSearch( _ searched: Searched, @@ -18,7 +18,7 @@ public protocol MatchingCollectionSearcher: CollectionSearcher { } extension MatchingCollectionSearcher { - public func search( + func search( _ searched: Searched, _ state: inout State ) -> Range? { @@ -26,7 +26,7 @@ extension MatchingCollectionSearcher { } } -public protocol MatchingStatelessCollectionSearcher: +protocol MatchingStatelessCollectionSearcher: MatchingCollectionSearcher, StatelessCollectionSearcher { func matchingSearch( @@ -38,14 +38,14 @@ public protocol MatchingStatelessCollectionSearcher: extension MatchingStatelessCollectionSearcher { // for disambiguation between the `MatchingCollectionSearcher` and // `StatelessCollectionSearcher` overloads - public func search( + func search( _ searched: Searched, _ state: inout State ) -> Range? { matchingSearch(searched, &state)?.range } - public func matchingSearch( + func matchingSearch( _ searched: Searched, _ state: inout State ) -> (range: Range, match: Match)? { @@ -69,7 +69,7 @@ extension MatchingStatelessCollectionSearcher { return (range, value) } - public func search( + func search( _ searched: Searched, in range: Range ) -> Range? { @@ -79,7 +79,7 @@ extension MatchingStatelessCollectionSearcher { // MARK: Searching from the back -public protocol BackwardMatchingCollectionSearcher: BackwardCollectionSearcher { +protocol BackwardMatchingCollectionSearcher: BackwardCollectionSearcher { associatedtype Match func matchingSearchBack( _ searched: BackwardSearched, @@ -87,7 +87,7 @@ public protocol BackwardMatchingCollectionSearcher: BackwardCollectionSearcher { ) -> (range: Range, match: Match)? } -public protocol BackwardMatchingStatelessCollectionSearcher: +protocol BackwardMatchingStatelessCollectionSearcher: BackwardMatchingCollectionSearcher, BackwardStatelessCollectionSearcher { func matchingSearchBack( @@ -97,14 +97,14 @@ public protocol BackwardMatchingStatelessCollectionSearcher: } extension BackwardMatchingStatelessCollectionSearcher { - public func searchBack( + func searchBack( _ searched: BackwardSearched, in range: Range ) -> Range? { matchingSearchBack(searched, in: range)?.range } - public func matchingSearchBack( + func matchingSearchBack( _ searched: BackwardSearched, _ state: inout BackwardState) -> (range: Range, match: Match)? { diff --git a/Sources/_StringProcessing/Algorithms/Searchers/CollectionSearcher.swift b/Sources/_StringProcessing/Algorithms/Searchers/CollectionSearcher.swift index 78e4fc925..5eb199086 100644 --- a/Sources/_StringProcessing/Algorithms/Searchers/CollectionSearcher.swift +++ b/Sources/_StringProcessing/Algorithms/Searchers/CollectionSearcher.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -public struct DefaultSearcherState { +struct DefaultSearcherState { enum Position { case index(Searched.Index) case done @@ -19,7 +19,7 @@ public struct DefaultSearcherState { let end: Searched.Index } -public protocol CollectionSearcher { +protocol CollectionSearcher { associatedtype Searched: Collection associatedtype State @@ -30,7 +30,7 @@ public protocol CollectionSearcher { ) -> Range? } -public protocol StatelessCollectionSearcher: CollectionSearcher +protocol StatelessCollectionSearcher: CollectionSearcher where State == DefaultSearcherState { func search( @@ -39,14 +39,14 @@ public protocol StatelessCollectionSearcher: CollectionSearcher } extension StatelessCollectionSearcher { - public func state( + func state( for searched: Searched, in range: Range ) -> State { State(position: .index(range.lowerBound), end: range.upperBound) } - public func search( + func search( _ searched: Searched, _ state: inout State ) -> Range? { @@ -71,7 +71,7 @@ extension StatelessCollectionSearcher { // MARK: Searching from the back -public protocol BackwardCollectionSearcher { +protocol BackwardCollectionSearcher { associatedtype BackwardSearched: BidirectionalCollection associatedtype BackwardState @@ -84,7 +84,7 @@ public protocol BackwardCollectionSearcher { ) -> Range? } -public protocol BackwardStatelessCollectionSearcher: BackwardCollectionSearcher +protocol BackwardStatelessCollectionSearcher: BackwardCollectionSearcher where BackwardState == DefaultSearcherState { func searchBack( @@ -94,14 +94,14 @@ public protocol BackwardStatelessCollectionSearcher: BackwardCollectionSearcher } extension BackwardStatelessCollectionSearcher { - public func backwardState( + func backwardState( for searched: BackwardSearched, in range: Range ) -> BackwardState { BackwardState(position: .index(range.upperBound), end: range.lowerBound) } - public func searchBack( + func searchBack( _ searched: BackwardSearched, _ state: inout BackwardState) -> Range? { guard diff --git a/Sources/_StringProcessing/Algorithms/Searchers/PatternOrEmpty.swift b/Sources/_StringProcessing/Algorithms/Searchers/PatternOrEmpty.swift index ee1b04adf..3b3fe22f9 100644 --- a/Sources/_StringProcessing/Algorithms/Searchers/PatternOrEmpty.swift +++ b/Sources/_StringProcessing/Algorithms/Searchers/PatternOrEmpty.swift @@ -10,14 +10,14 @@ //===----------------------------------------------------------------------===// /// Wraps a searcher that searches for a given pattern. If the pattern is empty, falls back on matching every empty index range exactly once. -public struct PatternOrEmpty { +struct PatternOrEmpty { let searcher: Searcher? } extension PatternOrEmpty: CollectionSearcher { - public typealias Searched = Searcher.Searched + typealias Searched = Searcher.Searched - public struct State { + struct State { enum Representation { case state(Searcher.State) case empty(index: Searched.Index, end: Searched.Index) @@ -27,7 +27,7 @@ extension PatternOrEmpty: CollectionSearcher { let representation: Representation } - public func state( + func state( for searched: Searcher.Searched, in range: Range ) -> State { @@ -40,7 +40,7 @@ extension PatternOrEmpty: CollectionSearcher { } } - public func search( + func search( _ searched: Searched, _ state: inout State ) -> Range? { diff --git a/Tests/RegexBuilderTests/AlgorithmsTests.swift b/Tests/RegexBuilderTests/AlgorithmsTests.swift index 183d247a7..7625af385 100644 --- a/Tests/RegexBuilderTests/AlgorithmsTests.swift +++ b/Tests/RegexBuilderTests/AlgorithmsTests.swift @@ -14,18 +14,20 @@ import _StringProcessing @testable import RegexBuilder class RegexConsumerTests: XCTestCase { - func testMatches() { - let regex = Capture(OneOrMore(.digit)) { 2 * Int($0)! } - let str = "foo 160 bar 99 baz" - XCTAssertEqual(str.matches(of: regex).map(\.result.1), [320, 198]) - } + // FIXME: enable this test when we update the return type of `matches(of:)` + // when SE-0346 is available + // func testMatches() { + // let regex = Capture(OneOrMore(.digit)) { 2 * Int($0)! } + // let str = "foo 160 bar 99 baz" + // XCTAssertEqual(str.matches(of: regex).map(\.result.1), [320, 198]) + // } func testMatchReplace() { func replaceTest( _ regex: R, input: String, result: String, - _ replace: (_MatchResult>) -> String, + _ replace: (Regex.Match) -> String, file: StaticString = #file, line: UInt = #line ) { @@ -38,13 +40,13 @@ class RegexConsumerTests: XCTestCase { int, input: "foo 160 bar 99 baz", result: "foo 240 bar 143 baz", - { match in String(match.result.1, radix: 8) }) + { match in String(match.output.1, radix: 8) }) replaceTest( Regex { int; "+"; int }, input: "9+16, 0+3, 5+5, 99+1", result: "25, 3, 10, 100", - { match in "\(match.result.1 + match.result.2)" }) + { match in "\(match.output.1 + match.output.2)" }) // TODO: Need to support capture history // replaceTest( @@ -57,6 +59,6 @@ class RegexConsumerTests: XCTestCase { Regex { int; "x"; int; Optionally { "x"; int } }, input: "2x3 5x4x3 6x0 1x2x3x4", result: "6 60 0 6x4", - { match in "\(match.result.1 * match.result.2 * (match.result.3 ?? 1))" }) + { match in "\(match.output.1 * match.output.2 * (match.output.3 ?? 1))" }) } } diff --git a/Tests/RegexBuilderTests/CustomTests.swift b/Tests/RegexBuilderTests/CustomTests.swift index 7be95c28c..19c4a3896 100644 --- a/Tests/RegexBuilderTests/CustomTests.swift +++ b/Tests/RegexBuilderTests/CustomTests.swift @@ -64,7 +64,7 @@ func customTest( case .match: result = input.matchWhole(regex)?.output case .firstMatch: - result = input.firstMatch(of: regex)?.result + result = input.firstMatch(of: regex)?.output } XCTAssertEqual(result, match) } @@ -120,9 +120,9 @@ class CustomRegexComponentTests: XCTestCase { return } - XCTAssertEqual(res3.match, "123") - XCTAssertEqual(res3.result.0, "123") - XCTAssertEqual(res3.result.1, "123") + XCTAssertEqual(res3.range, "ab123c".index(atOffset: 2)..<"ab123c".index(atOffset: 5)) + XCTAssertEqual(res3.output.0, "123") + XCTAssertEqual(res3.output.1, "123") let regex4 = Regex { OneOrMore { @@ -135,7 +135,7 @@ class CustomRegexComponentTests: XCTestCase { return } - XCTAssertEqual(res4.result.0, "123") - XCTAssertEqual(res4.result.1, 3) + XCTAssertEqual(res4.output.0, "123") + XCTAssertEqual(res4.output.1, 3) } } diff --git a/Tests/RegexBuilderTests/RegexDSLTests.swift b/Tests/RegexBuilderTests/RegexDSLTests.swift index a414e7938..2044c8859 100644 --- a/Tests/RegexBuilderTests/RegexDSLTests.swift +++ b/Tests/RegexBuilderTests/RegexDSLTests.swift @@ -716,10 +716,10 @@ class RegexDSLTests: XCTestCase { else { return nil } let result = SemanticVersion( - major: match.result.1, - minor: match.result.2, - patch: match.result.3 ?? 0, - dev: match.result.4.map(String.init)) + major: match.output.1, + minor: match.output.2, + patch: match.output.3 ?? 0, + dev: match.output.4.map(String.init)) return (match.range.upperBound, result) } } From 5f31de8349a285d5b7287f95a6b0f2cc05dc52f2 Mon Sep 17 00:00:00 2001 From: Nate Cook Date: Thu, 7 Apr 2022 21:24:25 -0500 Subject: [PATCH 03/17] Move `CharacterClass` API into RegexBuilder (#254) Makes the existing CharacterClass model type SPI, and adds a public CharacterClass type to the RegexBuilder module, which uses a DSLTree char class instead of the AST's version. RegexBuilder.CharacterClass is a more limited API than we need for the internal character class model, giving us room to expand on it as necessary in the future. --- Sources/RegexBuilder/CharacterClass.swift | 215 ++++++++++++++++++ Sources/_StringProcessing/ByteCodeGen.swift | 14 +- .../_StringProcessing/MatchingOptions.swift | 2 +- Sources/_StringProcessing/Regex/DSLTree.swift | 25 +- ...Class.swift => _CharacterClassModel.swift} | 64 +++--- Tests/RegexBuilderTests/RegexDSLTests.swift | 53 +++++ 6 files changed, 338 insertions(+), 35 deletions(-) create mode 100644 Sources/RegexBuilder/CharacterClass.swift rename Sources/_StringProcessing/{CharacterClass.swift => _CharacterClassModel.swift} (90%) diff --git a/Sources/RegexBuilder/CharacterClass.swift b/Sources/RegexBuilder/CharacterClass.swift new file mode 100644 index 000000000..78ebd49a2 --- /dev/null +++ b/Sources/RegexBuilder/CharacterClass.swift @@ -0,0 +1,215 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2021-2022 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// +//===----------------------------------------------------------------------===// + +import _RegexParser +@_spi(RegexBuilder) import _StringProcessing + +public struct CharacterClass { + internal var ccc: DSLTree.CustomCharacterClass + + init(_ ccc: DSLTree.CustomCharacterClass) { + self.ccc = ccc + } + + init(unconverted model: _CharacterClassModel) { + // FIXME: Implement in DSLTree instead of wrapping an AST atom + switch model.makeAST() { + case .atom(let atom): + self.ccc = .init(members: [.atom(.unconverted(atom))]) + default: + fatalError("Unsupported _CharacterClassModel") + } + } + + init(property: AST.Atom.CharacterProperty) { + // FIXME: Implement in DSLTree instead of wrapping an AST atom + let astAtom = AST.Atom(.property(property), .fake) + self.ccc = .init(members: [.atom(.unconverted(astAtom))]) + } +} + +extension CharacterClass: RegexComponent { + public var regex: Regex { + return Regex(node: DSLTree.Node.customCharacterClass(ccc)) + } +} + +extension CharacterClass { + public var inverted: CharacterClass { + CharacterClass(ccc.inverted) + } +} + +extension RegexComponent where Self == CharacterClass { + public static var any: CharacterClass { + .init(DSLTree.CustomCharacterClass(members: [.atom(.any)])) + } + + public static var anyGrapheme: CharacterClass { + .init(unconverted: .anyGrapheme) + } + + public static var whitespace: CharacterClass { + .init(unconverted: .whitespace) + } + + public static var digit: CharacterClass { + .init(unconverted: .digit) + } + + public static var hexDigit: CharacterClass { + .init(DSLTree.CustomCharacterClass(members: [ + .range(.char("A"), .char("F")), + .range(.char("a"), .char("f")), + .range(.char("0"), .char("9")), + ])) + } + + public static var horizontalWhitespace: CharacterClass { + .init(unconverted: .horizontalWhitespace) + } + + public static var newlineSequence: CharacterClass { + .init(unconverted: .newlineSequence) + } + + public static var verticalWhitespace: CharacterClass { + .init(unconverted: .verticalWhitespace) + } + + public static var word: CharacterClass { + .init(unconverted: .word) + } +} + +extension RegexComponent where Self == CharacterClass { + /// Returns a character class that matches any character in the given string + /// or sequence. + public static func anyOf(_ s: S) -> CharacterClass + where S.Element == Character + { + CharacterClass(DSLTree.CustomCharacterClass( + members: s.map { .atom(.char($0)) })) + } + + /// Returns a character class that matches any unicode scalar in the given + /// sequence. + public static func anyOf(_ s: S) -> CharacterClass + where S.Element == UnicodeScalar + { + CharacterClass(DSLTree.CustomCharacterClass( + members: s.map { .atom(.scalar($0)) })) + } +} + +// Unicode properties +extension CharacterClass { + public static func generalCategory(_ category: Unicode.GeneralCategory) -> CharacterClass { + guard let extendedCategory = category.extendedGeneralCategory else { + fatalError("Unexpected general category") + } + return CharacterClass(property: + .init(.generalCategory(extendedCategory), isInverted: false, isPOSIX: false)) + } +} + +/// Range syntax for characters in `CharacterClass`es. +public func ...(lhs: Character, rhs: Character) -> CharacterClass { + let range: DSLTree.CustomCharacterClass.Member = .range(.char(lhs), .char(rhs)) + let ccc = DSLTree.CustomCharacterClass(members: [range], isInverted: false) + return CharacterClass(ccc) +} + +/// Range syntax for unicode scalars in `CharacterClass`es. +@_disfavoredOverload +public func ...(lhs: UnicodeScalar, rhs: UnicodeScalar) -> CharacterClass { + let range: DSLTree.CustomCharacterClass.Member = .range(.scalar(lhs), .scalar(rhs)) + let ccc = DSLTree.CustomCharacterClass(members: [range], isInverted: false) + return CharacterClass(ccc) +} + +extension Unicode.GeneralCategory { + var extendedGeneralCategory: Unicode.ExtendedGeneralCategory? { + switch self { + case .uppercaseLetter: return .uppercaseLetter + case .lowercaseLetter: return .lowercaseLetter + case .titlecaseLetter: return .titlecaseLetter + case .modifierLetter: return .modifierLetter + case .otherLetter: return .otherLetter + case .nonspacingMark: return .nonspacingMark + case .spacingMark: return .spacingMark + case .enclosingMark: return .enclosingMark + case .decimalNumber: return .decimalNumber + case .letterNumber: return .letterNumber + case .otherNumber: return .otherNumber + case .connectorPunctuation: return .connectorPunctuation + case .dashPunctuation: return .dashPunctuation + case .openPunctuation: return .openPunctuation + case .closePunctuation: return .closePunctuation + case .initialPunctuation: return .initialPunctuation + case .finalPunctuation: return .finalPunctuation + case .otherPunctuation: return .otherPunctuation + case .mathSymbol: return .mathSymbol + case .currencySymbol: return .currencySymbol + case .modifierSymbol: return .modifierSymbol + case .otherSymbol: return .otherSymbol + case .spaceSeparator: return .spaceSeparator + case .lineSeparator: return .lineSeparator + case .paragraphSeparator: return .paragraphSeparator + case .control: return .control + case .format: return .format + case .surrogate: return .surrogate + case .privateUse: return .privateUse + case .unassigned: return .unassigned + @unknown default: return nil + } + } +} + +// MARK: - Set algebra methods + +extension RegexComponent where Self == CharacterClass { + public init(_ first: CharacterClass, _ rest: CharacterClass...) { + if rest.isEmpty { + self.init(first.ccc) + } else { + let members: [DSLTree.CustomCharacterClass.Member] = + (CollectionOfOne(first) + rest).map { .custom($0.ccc) } + self.init(.init(members: members)) + } + } +} + +extension CharacterClass { + public func union(_ other: CharacterClass) -> CharacterClass { + CharacterClass(.init(members: [ + .custom(self.ccc), + .custom(other.ccc)])) + } + + public func intersection(_ other: CharacterClass) -> CharacterClass { + CharacterClass(.init(members: [ + .intersection(self.ccc, other.ccc) + ])) + } + + public func subtracting(_ other: CharacterClass) -> CharacterClass { + CharacterClass(.init(members: [ + .subtraction(self.ccc, other.ccc) + ])) + } + + public func symmetricDifference(_ other: CharacterClass) -> CharacterClass { + CharacterClass(.init(members: [ + .symmetricDifference(self.ccc, other.ccc) + ])) + } +} diff --git a/Sources/_StringProcessing/ByteCodeGen.swift b/Sources/_StringProcessing/ByteCodeGen.swift index d6d6c3c5e..ed84fadbd 100644 --- a/Sources/_StringProcessing/ByteCodeGen.swift +++ b/Sources/_StringProcessing/ByteCodeGen.swift @@ -136,7 +136,7 @@ extension Compiler.ByteCodeGen { // TODO: May want to consider Unicode level builder.buildAssert { [options] (input, pos, bounds) in // TODO: How should we handle bounds? - CharacterClass.word.isBoundary( + _CharacterClassModel.word.isBoundary( input, at: pos, bounds: bounds, with: options) } @@ -144,7 +144,7 @@ extension Compiler.ByteCodeGen { // TODO: May want to consider Unicode level builder.buildAssert { [options] (input, pos, bounds) in // TODO: How should we handle bounds? - !CharacterClass.word.isBoundary( + !_CharacterClassModel.word.isBoundary( input, at: pos, bounds: bounds, with: options) } } @@ -595,7 +595,15 @@ extension Compiler.ByteCodeGen { try emitQuantification(amt, kind, child) case let .customCharacterClass(ccc): - try emitCustomCharacterClass(ccc) + if ccc.containsAny { + if !ccc.isInverted { + emitAny() + } else { + throw Unsupported("Inverted any") + } + } else { + try emitCustomCharacterClass(ccc) + } case let .atom(a): try emitAtom(a) diff --git a/Sources/_StringProcessing/MatchingOptions.swift b/Sources/_StringProcessing/MatchingOptions.swift index c4b2b8de7..cafb07da0 100644 --- a/Sources/_StringProcessing/MatchingOptions.swift +++ b/Sources/_StringProcessing/MatchingOptions.swift @@ -105,7 +105,7 @@ extension MatchingOptions { // Deprecated CharacterClass.MatchLevel API extension MatchingOptions { @available(*, deprecated) - var matchLevel: CharacterClass.MatchLevel { + var matchLevel: _CharacterClassModel.MatchLevel { switch semanticLevel { case .graphemeCluster: return .graphemeCluster diff --git a/Sources/_StringProcessing/Regex/DSLTree.swift b/Sources/_StringProcessing/Regex/DSLTree.swift index bd3b37a3d..59ebd38af 100644 --- a/Sources/_StringProcessing/Regex/DSLTree.swift +++ b/Sources/_StringProcessing/Regex/DSLTree.swift @@ -107,8 +107,31 @@ extension DSLTree { public struct CustomCharacterClass { var members: [Member] var isInverted: Bool + + var containsAny: Bool { + members.contains { member in + switch member { + case .atom(.any): return true + case .custom(let ccc): return ccc.containsAny + default: + return false + } + } + } + + public init(members: [DSLTree.CustomCharacterClass.Member], isInverted: Bool = false) { + self.members = members + self.isInverted = isInverted + } + + public var inverted: CustomCharacterClass { + var result = self + result.isInverted.toggle() + return result + } - enum Member { + @_spi(RegexBuilder) + public enum Member { case atom(Atom) case range(Atom, Atom) case custom(CustomCharacterClass) diff --git a/Sources/_StringProcessing/CharacterClass.swift b/Sources/_StringProcessing/_CharacterClassModel.swift similarity index 90% rename from Sources/_StringProcessing/CharacterClass.swift rename to Sources/_StringProcessing/_CharacterClassModel.swift index bdf34d0a7..94a42b549 100644 --- a/Sources/_StringProcessing/CharacterClass.swift +++ b/Sources/_StringProcessing/_CharacterClassModel.swift @@ -15,7 +15,8 @@ import _RegexParser // an AST, but this isn't a natural thing to produce in the context // of parsing or to store in an AST -public struct CharacterClass: Hashable { +@_spi(RegexBuilder) +public struct _CharacterClassModel: Hashable { /// The actual character class to match. var cc: Representation @@ -54,6 +55,7 @@ public struct CharacterClass: Hashable { public typealias SetOperator = AST.CustomCharacterClass.SetOp /// A binary set operation that forms a character class component. + @_spi(RegexBuilder) public struct SetOperation: Hashable { var lhs: CharacterSetComponent var op: SetOperator @@ -71,12 +73,13 @@ public struct CharacterClass: Hashable { } } + @_spi(RegexBuilder) public enum CharacterSetComponent: Hashable { case character(Character) case range(ClosedRange) /// A nested character class. - case characterClass(CharacterClass) + case characterClass(_CharacterClassModel) /// A binary set operation of character class components. indirect case setOperation(SetOperation) @@ -201,7 +204,7 @@ public struct CharacterClass: Hashable { } } -extension CharacterClass: RegexComponent { +extension _CharacterClassModel: RegexComponent { public typealias Output = Substring public var regex: Regex { @@ -212,51 +215,52 @@ extension CharacterClass: RegexComponent { } } -extension RegexComponent where Self == CharacterClass { - public static var any: CharacterClass { +@_spi(RegexBuilder) +extension _CharacterClassModel { + public static var any: _CharacterClassModel { .init(cc: .any, matchLevel: .graphemeCluster) } - public static var anyGrapheme: CharacterClass { + public static var anyGrapheme: _CharacterClassModel { .init(cc: .anyGrapheme, matchLevel: .graphemeCluster) } - public static var whitespace: CharacterClass { + public static var whitespace: _CharacterClassModel { .init(cc: .whitespace, matchLevel: .graphemeCluster) } - public static var digit: CharacterClass { + public static var digit: _CharacterClassModel { .init(cc: .digit, matchLevel: .graphemeCluster) } - public static var hexDigit: CharacterClass { + public static var hexDigit: _CharacterClassModel { .init(cc: .hexDigit, matchLevel: .graphemeCluster) } - public static var horizontalWhitespace: CharacterClass { + public static var horizontalWhitespace: _CharacterClassModel { .init(cc: .horizontalWhitespace, matchLevel: .graphemeCluster) } - public static var newlineSequence: CharacterClass { + public static var newlineSequence: _CharacterClassModel { .init(cc: .newlineSequence, matchLevel: .graphemeCluster) } - public static var verticalWhitespace: CharacterClass { + public static var verticalWhitespace: _CharacterClassModel { .init(cc: .verticalWhitespace, matchLevel: .graphemeCluster) } - public static var word: CharacterClass { + public static var word: _CharacterClassModel { .init(cc: .word, matchLevel: .graphemeCluster) } public static func custom( - _ components: [CharacterClass.CharacterSetComponent] - ) -> CharacterClass { + _ components: [_CharacterClassModel.CharacterSetComponent] + ) -> _CharacterClassModel { .init(cc: .custom(components), matchLevel: .graphemeCluster) } } -extension CharacterClass.CharacterSetComponent: CustomStringConvertible { +extension _CharacterClassModel.CharacterSetComponent: CustomStringConvertible { public var description: String { switch self { case .range(let range): return "" @@ -267,7 +271,7 @@ extension CharacterClass.CharacterSetComponent: CustomStringConvertible { } } -extension CharacterClass.Representation: CustomStringConvertible { +extension _CharacterClassModel.Representation: CustomStringConvertible { public var description: String { switch self { case .any: return "" @@ -284,13 +288,13 @@ extension CharacterClass.Representation: CustomStringConvertible { } } -extension CharacterClass: CustomStringConvertible { +extension _CharacterClassModel: CustomStringConvertible { public var description: String { return "\(isInverted ? "not " : "")\(cc)" } } -extension CharacterClass { +extension _CharacterClassModel { public func makeAST() -> AST.Node? { let inv = isInverted @@ -343,7 +347,7 @@ extension CharacterClass { } extension DSLTree.Node { - var characterClass: CharacterClass? { + var characterClass: _CharacterClassModel? { switch self { case let .customCharacterClass(ccc): return ccc.modelCharacterClass @@ -358,10 +362,10 @@ extension DSLTree.Node { } } -extension CharacterClass { +extension _CharacterClassModel { public func withMatchLevel( - _ level: CharacterClass.MatchLevel - ) -> CharacterClass { + _ level: _CharacterClassModel.MatchLevel + ) -> _CharacterClassModel { var cc = self cc.matchLevel = level return cc @@ -369,7 +373,7 @@ extension CharacterClass { } extension DSLTree.Atom { - var characterClass: CharacterClass? { + var characterClass: _CharacterClassModel? { switch self { case let .unconverted(a): return a.characterClass @@ -380,7 +384,7 @@ extension DSLTree.Atom { } extension AST.Atom { - var characterClass: CharacterClass? { + var characterClass: _CharacterClassModel? { switch kind { case let .escaped(b): return b.characterClass @@ -406,7 +410,7 @@ extension AST.Atom { } extension AST.Atom.EscapedBuiltin { - var characterClass: CharacterClass? { + var characterClass: _CharacterClassModel? { switch self { case .decimalDigit: return .digit case .notDecimalDigit: return .digit.inverted @@ -437,9 +441,9 @@ extension AST.Atom.EscapedBuiltin { extension DSLTree.CustomCharacterClass { // TODO: Refactor a bit, and... can we drop this type? - var modelCharacterClass: CharacterClass? { + var modelCharacterClass: _CharacterClassModel? { var result = - Array() + Array<_CharacterClassModel.CharacterSetComponent>() for m in members { switch m { case let .atom(a): @@ -505,12 +509,12 @@ extension DSLTree.CustomCharacterClass { break } } - let cc = CharacterClass.custom(result) + let cc = _CharacterClassModel.custom(result) return isInverted ? cc.inverted : cc } } -extension CharacterClass { +extension _CharacterClassModel { // FIXME: Calling on inverted sets wont be the same as the // inverse of a boundary if at the start or end of the // string. (Think through what we want: do it ourselves or diff --git a/Tests/RegexBuilderTests/RegexDSLTests.swift b/Tests/RegexBuilderTests/RegexDSLTests.swift index 2044c8859..aaa3f6886 100644 --- a/Tests/RegexBuilderTests/RegexDSLTests.swift +++ b/Tests/RegexBuilderTests/RegexDSLTests.swift @@ -70,6 +70,59 @@ class RegexDSLTests: XCTestCase { Capture(.whitespace) // Substring Capture("c") // Substring } + + try _testDSLCaptures( + ("abc1def2", "abc1def2"), + matchType: Substring.self, ==) + { + // First group + OneOrMore { + CharacterClass("a"..."z", .digit) + } + + // Second group + OneOrMore { + ChoiceOf { + "a"..."z" + CharacterClass.hexDigit + } + } + } + + try _testDSLCaptures( + ("abc1def2", ("abc1def2", "abc1")), + matchType: (Substring, Substring).self, ==) + { + Capture { + OneOrMore(.digit.inverted) + ("a"..."z").inverted + } + + OneOrMore { + CharacterClass.whitespace.inverted + } + } + } + + func testCharacterClassOperations() throws { + try _testDSLCaptures( + ("bcdefn1a", "bcdefn1a"), + ("nbcdef1a", nil), // fails symmetric difference lookahead + ("abcdef1a", nil), // fails union + ("bcdef3a", nil), // fails subtraction + ("bcdef1z", nil), // fails intersection + matchType: Substring.self, ==) + { + let disallowedChars = CharacterClass.hexDigit + .symmetricDifference("a"..."z") + Lookahead(disallowedChars, negative: true) // No: 0-9 + g-z + + OneOrMore(("b"..."g").union("d"..."n")) // b-n + + CharacterClass.digit.subtracting("3"..."9") // 1, 2, non-ascii digits + + CharacterClass.hexDigit.intersection("a"..."z") // a-f + } } func testMatchResultDotZeroWithoutCapture() throws { From cc91315bddac7d206a8cdd14771e39edd9537763 Mon Sep 17 00:00:00 2001 From: Nate Cook Date: Fri, 8 Apr 2022 14:04:59 -0500 Subject: [PATCH 04/17] Eliminate extra public API (#256) These were mostly leftover bits from testing :wave: --- Package.swift | 1 + .../Participants/RegexParticipant.swift | 8 +++---- .../PatternConverter/PatternConverter.swift | 2 +- .../Consumers/PredicateConsumer.swift | 8 +++---- .../Algorithms/Consumers/RegexConsumer.swift | 18 ++++++++-------- .../Algorithms/Searchers/TwoWaySearcher.swift | 8 +++---- .../Algorithms/Searchers/ZSearcher.swift | 6 +++--- .../_StringProcessing/MatchingOptions.swift | 2 +- .../_StringProcessing/PrintAsPattern.swift | 1 + Sources/_StringProcessing/Regex/Core.swift | 21 ------------------- .../Utility/ASTBuilder.swift | 8 +++---- .../_CharacterClassModel.swift | 16 +++++++------- Tests/RegexBuilderTests/RegexDSLTests.swift | 6 +++--- 13 files changed, 43 insertions(+), 62 deletions(-) diff --git a/Package.swift b/Package.swift index e95d98b67..47a73ca72 100644 --- a/Package.swift +++ b/Package.swift @@ -22,6 +22,7 @@ let package = Package( ], dependencies: [ .package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0"), + .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. diff --git a/Sources/Exercises/Participants/RegexParticipant.swift b/Sources/Exercises/Participants/RegexParticipant.swift index a40de3953..71018d8a7 100644 --- a/Sources/Exercises/Participants/RegexParticipant.swift +++ b/Sources/Exercises/Participants/RegexParticipant.swift @@ -69,10 +69,10 @@ private func graphemeBreakPropertyData( private func graphemeBreakPropertyDataLiteral( forLine line: String ) -> GraphemeBreakEntry? { - return graphemeBreakPropertyData( - forLine: line, - using: r(#"([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s+;\s+(\w+).*"#, - matching: (Substring, Substring, Substring?, Substring).self)) + let regex = try! Regex( + compiling: #"([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s+;\s+(\w+).*"#, + as: (Substring, Substring, Substring?, Substring).self) + return graphemeBreakPropertyData(forLine: line, using: regex) } // MARK: - Builder DSL diff --git a/Sources/PatternConverter/PatternConverter.swift b/Sources/PatternConverter/PatternConverter.swift index ff47e4be2..f66204884 100644 --- a/Sources/PatternConverter/PatternConverter.swift +++ b/Sources/PatternConverter/PatternConverter.swift @@ -13,7 +13,7 @@ import ArgumentParser import _RegexParser -import _StringProcessing +@_spi(PatternConverter) import _StringProcessing @main struct PatternConverter: ParsableCommand { diff --git a/Sources/_StringProcessing/Algorithms/Consumers/PredicateConsumer.swift b/Sources/_StringProcessing/Algorithms/Consumers/PredicateConsumer.swift index c9b92b9ec..caf523d1c 100644 --- a/Sources/_StringProcessing/Algorithms/Consumers/PredicateConsumer.swift +++ b/Sources/_StringProcessing/Algorithms/Consumers/PredicateConsumer.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -public struct PredicateConsumer { +struct PredicateConsumer { let predicate: (Consumed.Element) -> Bool } @@ -29,7 +29,7 @@ extension PredicateConsumer: CollectionConsumer { extension PredicateConsumer: BidirectionalCollectionConsumer where Consumed: BidirectionalCollection { - public func consumingBack( + func consumingBack( _ consumed: Consumed, in range: Range ) -> Consumed.Index? { @@ -59,9 +59,9 @@ extension PredicateConsumer: BackwardCollectionSearcher, BackwardStatelessCollectionSearcher where Searched: BidirectionalCollection { - public typealias BackwardSearched = Consumed + typealias BackwardSearched = Consumed - public func searchBack( + func searchBack( _ searched: BackwardSearched, in range: Range ) -> Range? { diff --git a/Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift b/Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift index 3ab1e579d..dcc5d9f2b 100644 --- a/Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift +++ b/Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift @@ -9,13 +9,13 @@ // //===----------------------------------------------------------------------===// -public struct RegexConsumer< +struct RegexConsumer< R: RegexComponent, Consumed: BidirectionalCollection > where Consumed.SubSequence == Substring { // TODO: Should `Regex` itself implement these protocols? let regex: R - public init(_ regex: R) { + init(_ regex: R) { self.regex = regex } } @@ -36,9 +36,9 @@ extension RegexConsumer { // well, taking advantage of the fact that the captures can be ignored extension RegexConsumer: MatchingCollectionConsumer { - public typealias Match = R.Output + typealias Match = R.Output - public func matchingConsuming( + func matchingConsuming( _ consumed: Consumed, in range: Range ) -> (upperBound: String.Index, match: Match)? { _matchingConsuming(consumed[...], in: range) @@ -47,7 +47,7 @@ extension RegexConsumer: MatchingCollectionConsumer { // TODO: We'll want to bake backwards into the engine extension RegexConsumer: BidirectionalMatchingCollectionConsumer { - public func matchingConsumingBack( + func matchingConsumingBack( _ consumed: Consumed, in range: Range ) -> (lowerBound: String.Index, match: Match)? { var i = range.lowerBound @@ -67,12 +67,12 @@ extension RegexConsumer: BidirectionalMatchingCollectionConsumer { } extension RegexConsumer: MatchingStatelessCollectionSearcher { - public typealias Searched = Consumed + typealias Searched = Consumed // TODO: We'll want to bake search into the engine so it can // take advantage of the structure of the regex itself and // its own internal state - public func matchingSearch( + func matchingSearch( _ searched: Searched, in range: Range ) -> (range: Range, match: Match)? { ConsumerSearcher(consumer: self).matchingSearch(searched, in: range) @@ -81,9 +81,9 @@ extension RegexConsumer: MatchingStatelessCollectionSearcher { // TODO: Bake in search-back to engine too extension RegexConsumer: BackwardMatchingStatelessCollectionSearcher { - public typealias BackwardSearched = Consumed + typealias BackwardSearched = Consumed - public func matchingSearchBack( + func matchingSearchBack( _ searched: BackwardSearched, in range: Range ) -> (range: Range, match: Match)? { ConsumerSearcher(consumer: self).matchingSearchBack(searched, in: range) diff --git a/Sources/_StringProcessing/Algorithms/Searchers/TwoWaySearcher.swift b/Sources/_StringProcessing/Algorithms/Searchers/TwoWaySearcher.swift index 11184f856..5530b4421 100644 --- a/Sources/_StringProcessing/Algorithms/Searchers/TwoWaySearcher.swift +++ b/Sources/_StringProcessing/Algorithms/Searchers/TwoWaySearcher.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -public struct TwoWaySearcher +struct TwoWaySearcher where Searched.Element: Comparable { // TODO: Be generic over the pattern? @@ -36,14 +36,14 @@ public struct TwoWaySearcher } extension TwoWaySearcher: CollectionSearcher { - public struct State { + struct State { let end: Searched.Index var index: Searched.Index var criticalIndex: Searched.Index var memory: (offset: Int, index: Searched.Index)? } - public func state( + func state( for searched: Searched, in range: Range ) -> State { @@ -57,7 +57,7 @@ extension TwoWaySearcher: CollectionSearcher { memory: nil) } - public func search( + func search( _ searched: Searched, _ state: inout State ) -> Range? { diff --git a/Sources/_StringProcessing/Algorithms/Searchers/ZSearcher.swift b/Sources/_StringProcessing/Algorithms/Searchers/ZSearcher.swift index a541dcb7d..e06796e72 100644 --- a/Sources/_StringProcessing/Algorithms/Searchers/ZSearcher.swift +++ b/Sources/_StringProcessing/Algorithms/Searchers/ZSearcher.swift @@ -9,12 +9,12 @@ // //===----------------------------------------------------------------------===// -public struct ZSearcher { +struct ZSearcher { let pattern: [Searched.Element] let z: [Int] let areEquivalent: (Searched.Element, Searched.Element) -> Bool - public init( + init( pattern: [Searched.Element], by areEquivalent: @escaping (Searched.Element, Searched.Element ) -> Bool) { @@ -25,7 +25,7 @@ public struct ZSearcher { } extension ZSearcher: StatelessCollectionSearcher { - public func search( + func search( _ searched: Searched, in range: Range ) -> Range? { diff --git a/Sources/_StringProcessing/MatchingOptions.swift b/Sources/_StringProcessing/MatchingOptions.swift index cafb07da0..0f244f1b8 100644 --- a/Sources/_StringProcessing/MatchingOptions.swift +++ b/Sources/_StringProcessing/MatchingOptions.swift @@ -13,7 +13,7 @@ import _RegexParser /// A type that represents the current state of regex matching options, with /// stack-based scoping. -public struct MatchingOptions { +struct MatchingOptions { fileprivate var stack: [Representation] fileprivate func _invariantCheck() { diff --git a/Sources/_StringProcessing/PrintAsPattern.swift b/Sources/_StringProcessing/PrintAsPattern.swift index 0cf16ab05..1998aa75b 100644 --- a/Sources/_StringProcessing/PrintAsPattern.swift +++ b/Sources/_StringProcessing/PrintAsPattern.swift @@ -19,6 +19,7 @@ import _RegexParser extension AST { /// Render as a Pattern DSL + @_spi(PatternConverter) public func renderAsBuilderDSL( maxTopDownLevels: Int? = nil, minBottomUpLevels: Int? = nil diff --git a/Sources/_StringProcessing/Regex/Core.swift b/Sources/_StringProcessing/Regex/Core.swift index 265a7868c..96d0f3a68 100644 --- a/Sources/_StringProcessing/Regex/Core.swift +++ b/Sources/_StringProcessing/Regex/Core.swift @@ -129,24 +129,3 @@ extension UnicodeScalar: RegexComponent { .init(node: .atom(.scalar(self))) } } - -// MARK: - Testing - -public struct MockRegexLiteral: RegexComponent { - public typealias MatchValue = Substring - public let regex: Regex - - public init( - _ string: String, - _ syntax: SyntaxOptions = .traditional, - matching: Output.Type = Output.self - ) throws { - regex = Regex(ast: try parse(string, syntax)) - } -} - -public func r( - _ s: String, matching matchType: Output.Type = Output.self -) -> MockRegexLiteral { - try! MockRegexLiteral(s, matching: matchType) -} diff --git a/Sources/_StringProcessing/Utility/ASTBuilder.swift b/Sources/_StringProcessing/Utility/ASTBuilder.swift index 8a9af8111..7a8edcd24 100644 --- a/Sources/_StringProcessing/Utility/ASTBuilder.swift +++ b/Sources/_StringProcessing/Utility/ASTBuilder.swift @@ -106,16 +106,16 @@ func negativeLookahead(_ child: AST.Node) -> AST.Node { func negativeLookbehind(_ child: AST.Node) -> AST.Node { group(.negativeLookbehind, child) } -public func nonAtomicLookahead(_ child: AST.Node) -> AST.Node { +func nonAtomicLookahead(_ child: AST.Node) -> AST.Node { group(.nonAtomicLookahead, child) } -public func nonAtomicLookbehind(_ child: AST.Node) -> AST.Node { +func nonAtomicLookbehind(_ child: AST.Node) -> AST.Node { group(.nonAtomicLookbehind, child) } -public func scriptRun(_ child: AST.Node) -> AST.Node { +func scriptRun(_ child: AST.Node) -> AST.Node { group(.scriptRun, child) } -public func atomicScriptRun(_ child: AST.Node) -> AST.Node { +func atomicScriptRun(_ child: AST.Node) -> AST.Node { group(.atomicScriptRun, child) } func changeMatchingOptions( diff --git a/Sources/_StringProcessing/_CharacterClassModel.swift b/Sources/_StringProcessing/_CharacterClassModel.swift index 94a42b549..e184689f1 100644 --- a/Sources/_StringProcessing/_CharacterClassModel.swift +++ b/Sources/_StringProcessing/_CharacterClassModel.swift @@ -61,7 +61,7 @@ public struct _CharacterClassModel: Hashable { var op: SetOperator var rhs: CharacterSetComponent - public func matches(_ c: Character, with options: MatchingOptions) -> Bool { + func matches(_ c: Character, with options: MatchingOptions) -> Bool { switch op { case .intersection: return lhs.matches(c, with: options) && rhs.matches(c, with: options) @@ -90,7 +90,7 @@ public struct _CharacterClassModel: Hashable { .setOperation(.init(lhs: lhs, op: op, rhs: rhs)) } - public func matches(_ character: Character, with options: MatchingOptions) -> Bool { + func matches(_ character: Character, with options: MatchingOptions) -> Bool { switch self { case .character(let c): if options.isCaseInsensitive { @@ -116,20 +116,20 @@ public struct _CharacterClassModel: Hashable { } } - public enum MatchLevel { + enum MatchLevel { /// Match at the extended grapheme cluster level. case graphemeCluster /// Match at the Unicode scalar level. case unicodeScalar } - public var scalarSemantic: Self { + var scalarSemantic: Self { var result = self result.matchLevel = .unicodeScalar return result } - public var graphemeClusterSemantic: Self { + var graphemeClusterSemantic: Self { var result = self result.matchLevel = .graphemeCluster return result @@ -137,7 +137,7 @@ public struct _CharacterClassModel: Hashable { /// Returns an inverted character class if true is passed, otherwise the /// same character class is returned. - public func withInversion(_ invertion: Bool) -> Self { + func withInversion(_ invertion: Bool) -> Self { var copy = self if invertion { copy.isInverted.toggle() @@ -152,7 +152,7 @@ public struct _CharacterClassModel: Hashable { /// Returns the end of the match of this character class in `str`, if /// it matches. - public func matches(in str: String, at i: String.Index, with options: MatchingOptions) -> String.Index? { + func matches(in str: String, at i: String.Index, with options: MatchingOptions) -> String.Index? { switch matchLevel { case .graphemeCluster: let c = str[i] @@ -363,7 +363,7 @@ extension DSLTree.Node { } extension _CharacterClassModel { - public func withMatchLevel( + func withMatchLevel( _ level: _CharacterClassModel.MatchLevel ) -> _CharacterClassModel { var cc = self diff --git a/Tests/RegexBuilderTests/RegexDSLTests.swift b/Tests/RegexBuilderTests/RegexDSLTests.swift index aaa3f6886..1f5305c59 100644 --- a/Tests/RegexBuilderTests/RegexDSLTests.swift +++ b/Tests/RegexBuilderTests/RegexDSLTests.swift @@ -611,9 +611,9 @@ class RegexDSLTests: XCTestCase { } do { - let regexLiteral = try MockRegexLiteral( - #"([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s+;\s+(\w+).*"#, - matching: (Substring, Substring, Substring?, Substring).self) + let regexLiteral = try Regex( + compiling: #"([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s+;\s+(\w+).*"#, + as: (Substring, Substring, Substring?, Substring).self) let maybeMatchResult = line.matchWhole(regexLiteral) let matchResult = try XCTUnwrap(maybeMatchResult) let (wholeMatch, lower, upper, propertyString) = matchResult.output From b86ca7072113338f66e5f48ae7e3064279b37fff Mon Sep 17 00:00:00 2001 From: Michael Ilseman Date: Fri, 8 Apr 2022 08:29:31 -0600 Subject: [PATCH 05/17] Update regex syntax pitch (#258) * Update regex syntax pitch * Rename file --- ...x.md => RegexSyntaxRunTimeConstruction.md} | 137 ++++++++++++++++-- .../Regex/AnyRegexOutput.swift | 29 ++++ 2 files changed, 153 insertions(+), 13 deletions(-) rename Documentation/Evolution/{RegexSyntax.md => RegexSyntaxRunTimeConstruction.md} (89%) diff --git a/Documentation/Evolution/RegexSyntax.md b/Documentation/Evolution/RegexSyntaxRunTimeConstruction.md similarity index 89% rename from Documentation/Evolution/RegexSyntax.md rename to Documentation/Evolution/RegexSyntaxRunTimeConstruction.md index faa327176..de1cf22ad 100644 --- a/Documentation/Evolution/RegexSyntax.md +++ b/Documentation/Evolution/RegexSyntaxRunTimeConstruction.md @@ -2,7 +2,7 @@ Hello, we want to issue an update to [Regular Expression Literals](https://forums.swift.org/t/pitch-regular-expression-literals/52820) and prepare for a formal proposal. The great delimiter deliberation continues to unfold, so in the meantime, we have a significant amount of surface area to present for review/feedback: the syntax _inside_ a regex literal. Additionally, this is the syntax accepted from a string used for run-time regex construction, so we're devoting an entire pitch/proposal to the topic of _regex syntax_, distinct from the result builder DSL or the choice of delimiters for literals. --> -# Run-time Regex Construction +# Regex Syntax and Run-time Construction - Authors: [Hamish Knight](https://github.com/hamishknight), [Michael Ilseman](https://github.com/milseman) @@ -16,11 +16,33 @@ The overall story is laid out in [Regex Type and Overview](https://github.com/ap Swift aims to be a pragmatic programming language, striking a balance between familiarity, interoperability, and advancing the art. Swift's `String` presents a uniquely Unicode-forward model of string, but currently suffers from limited processing facilities. - +`NSRegularExpression` can construct a processing pipeline from a string containing [ICU regular expression syntax][icu-syntax]. However, it is inherently tied to ICU's engine and thus it operates over a fundamentally different model of string than Swift's `String`. It is also limited in features and carries a fair amount of Objective-C baggage, such as the need to translate between `NSRange` and `Range`. + +```swift +let pattern = #"(\w+)\s\s+(\S+)\s\s+((?:(?!\s\s).)*)\s\s+(.*)"# +let nsRegEx = try! NSRegularExpression(pattern: pattern) + +func processEntry(_ line: String) -> Transaction? { + let range = NSRange(line.startIndex.. +We propose run-time construction of `Regex` from a best-in-class treatment of familiar regular expression syntax. A `Regex` is generic over its `Output`, which includes capture information. This may be an existential `AnyRegexOutput`, or a concrete type provided by the user. + +```swift +let pattern = #"(\w+)\s\s+(\S+)\s\s+((?:(?!\s\s).)*)\s\s+(.*)"# +let regex = try! Regex(compiling: pattern) +// regex: Regex + +let regex: Regex<(Substring, Substring, Substring, Substring, Substring)> = + try! Regex(compiling: pattern) +``` ### Syntax @@ -51,11 +80,87 @@ Regex syntax will be part of Swift's source-compatibility story as well as its b ## Detailed Design - +We propose initializers to declare and compile a regex from syntax. Upon failure, these initializers throw compilation errors, such as for syntax or type errors. API for retrieving error information is future work. + +```swift +extension Regex { + /// Parse and compile `pattern`, resulting in a strongly-typed capture list. + public init(compiling pattern: String, as: Output.Type = Output.self) throws +} +extension Regex where Output == AnyRegexOutput { + /// Parse and compile `pattern`, resulting in an existentially-typed capture list. + public init(compiling pattern: String) throws +} +``` + +We propose `AnyRegexOutput` for capture types not known at compilation time, alongside casting API to convert to a strongly-typed capture list. + +```swift +/// A type-erased regex output +public struct AnyRegexOutput { + /// Creates a type-erased regex output from an existing output. + /// + /// Use this initializer to fit a regex with strongly typed captures into the + /// use site of a dynamic regex, i.e. one that was created from a string. + public init(_ match: Regex.Match) -We propose the following syntax for regex. + /// Returns a typed output by converting the underlying value to the specified + /// type. + /// + /// - Parameter type: The expected output type. + /// - Returns: The output, if the underlying value can be converted to the + /// output type, or nil otherwise. + public func `as`(_ type: Output.Type) -> Output? +} +extension AnyRegexOutput: RandomAccessCollection { + public struct Element { + /// The range over which a value was captured. `nil` for no-capture. + public var range: Range? + + /// The slice of the input over which a value was captured. `nil` for no-capture. + public var substring: Substring? + + /// The captured value. `nil` for no-capture. + public var value: Any? + } + + // Trivial collection conformance requirements + + public var startIndex: Int { get } + + public var endIndex: Int { get } + + public var count: Int { get } + + public func index(after i: Int) -> Int + + public func index(before i: Int) -> Int + + public subscript(position: Int) -> Element +} +``` + +We propose adding an API to `Regex.Match` to cast the output type to a concrete one. A regex match will lazily create a `Substring` on demand, so casting the match itself saves ARC traffic vs extracting and casting the output. + +```swift +extension Regex.Match where Output == AnyRegexOutput { + /// Creates a type-erased regex match from an existing match. + /// + /// Use this initializer to fit a regex match with strongly typed captures into the + /// use site of a dynamic regex match, i.e. one that was created from a string. + public init(_ match: Regex.Match) + + /// Returns a typed match by converting the underlying values to the specified + /// types. + /// + /// - Parameter type: The expected output type. + /// - Returns: A match generic over the output type if the underlying values can be converted to the + /// output type. Returns `nil` otherwise. + public func `as`(_ type: Output.Type) -> Regex.Match? +} +``` + +The rest of this proposal will be a detailed and exhaustive definition of our proposed regex syntax.
Grammar Notation @@ -827,6 +932,12 @@ We are deferring runtime support for callouts from regex literals as future work ## Alternatives Considered +### Failalbe inits + +There are many ways for compilation to fail, from syntactic errors to unsupported features to type mismatches. In the general case, run-time compilation errors are not recoverable by a tool without modifying the user's input. Even then, the thrown errors contain valuable information as to why compilation failed. For example, swiftpm presents any errors directly to the user. + +As proposed, the errors thrown will be the same errors presented to the Swift compiler, tracking fine-grained source locations with specific reasons why compilation failed. Defining a rich error API is future work, as these errors are rapidly evolving and it is too early to lock in the ABI. + ### Skip the syntax diff --git a/Sources/_StringProcessing/Regex/AnyRegexOutput.swift b/Sources/_StringProcessing/Regex/AnyRegexOutput.swift index cac0e46c3..bd0fc47c9 100644 --- a/Sources/_StringProcessing/Regex/AnyRegexOutput.swift +++ b/Sources/_StringProcessing/Regex/AnyRegexOutput.swift @@ -37,6 +37,7 @@ extension Regex.Match where Output == AnyRegexOutput { } } +/// A type-erased regex output public struct AnyRegexOutput { let input: String fileprivate let _elements: [ElementRepresentation] @@ -70,6 +71,7 @@ extension AnyRegexOutput { /// Returns a typed output by converting the underlying value to the specified /// type. + /// /// - Parameter type: The expected output type. /// - Returns: The output, if the underlying value can be converted to the /// output type, or nil otherwise. @@ -119,13 +121,20 @@ extension AnyRegexOutput: RandomAccessCollection { fileprivate let representation: ElementRepresentation let input: String + /// The range over which a value was captured. `nil` for no-capture. public var range: Range? { representation.bounds } + /// The slice of the input over which a value was captured. `nil` for no-capture. public var substring: Substring? { range.map { input[$0] } } + + /// The captured value, `nil` for no-capture + public var value: Any? { + fatalError() + } } public var startIndex: Int { @@ -152,3 +161,23 @@ extension AnyRegexOutput: RandomAccessCollection { .init(representation: _elements[position], input: input) } } + +extension Regex.Match where Output == AnyRegexOutput { + /// Creates a type-erased regex match from an existing match. + /// + /// Use this initializer to fit a regex match with strongly typed captures into the + /// use site of a dynamic regex match, i.e. one that was created from a string. + public init(_ match: Regex.Match) { + fatalError("FIXME: Not implemented") + } + + /// Returns a typed match by converting the underlying values to the specified + /// types. + /// + /// - Parameter type: The expected output type. + /// - Returns: A match generic over the output type if the underlying values can be converted to the + /// output type. Returns `nil` otherwise. + public func `as`(_ type: Output.Type) -> Regex.Match? { + fatalError("FIXME: Not implemented") + } +} From e2e3d63765108d93a85d179428d48acf637c8299 Mon Sep 17 00:00:00 2001 From: Michael Ilseman Date: Sun, 10 Apr 2022 11:07:22 -0600 Subject: [PATCH 06/17] Throwing customization hooks (#261) * Throwing customization hooks * Adds test to try out throwing custom code. * Adds processor support. * Add throws to capture transform API, plumbing * Remove non-failable try-capture overloads --- Sources/RegexBuilder/Variadics.swift | 822 +++--------------- .../VariadicsGenerator.swift | 78 +- Sources/_RegexParser/Regex/AST/AST.swift | 75 -- Sources/_StringProcessing/ByteCodeGen.swift | 2 +- .../_StringProcessing/Engine/Consume.swift | 1 + .../_StringProcessing/Engine/MEProgram.swift | 6 +- .../_StringProcessing/Engine/Processor.swift | 53 +- Sources/_StringProcessing/Executor.swift | 3 + Sources/_StringProcessing/Regex/DSLTree.swift | 63 +- Sources/_StringProcessing/Regex/Match.swift | 2 +- Tests/RegexBuilderTests/CustomTests.swift | 85 ++ 11 files changed, 339 insertions(+), 851 deletions(-) diff --git a/Sources/RegexBuilder/Variadics.swift b/Sources/RegexBuilder/Variadics.swift index 989e5d463..2f4a6240a 100644 --- a/Sources/RegexBuilder/Variadics.swift +++ b/Sources/RegexBuilder/Variadics.swift @@ -2255,35 +2255,6 @@ extension Capture { self.init(node: .capture(reference: reference.id, component.regex.root)) } - @_disfavoredOverload - public init( - _ component: R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture), R.Output == W { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } - - @_disfavoredOverload - public init( - _ component: R, - as reference: Reference, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture), R.Output == W { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } -} - -extension TryCapture { @_disfavoredOverload public init( _ component: R, @@ -2310,15 +2281,17 @@ extension TryCapture { }, component.regex.root))) } +} +extension TryCapture { @_disfavoredOverload public init( _ component: R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture), R.Output == W { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -2327,13 +2300,13 @@ extension TryCapture { public init( _ component: R, as reference: Reference, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture), R.Output == W { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -2359,35 +2332,6 @@ extension Capture { component().regex.root)) } - @_disfavoredOverload - public init( - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture), R.Output == W { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } - - @_disfavoredOverload - public init( - as reference: Reference, - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture), R.Output == W { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } -} - -extension TryCapture { @_disfavoredOverload public init( @RegexComponentBuilder _ component: () -> R, @@ -2414,15 +2358,17 @@ extension TryCapture { }, component().regex.root))) } +} +extension TryCapture { @_disfavoredOverload public init( @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture), R.Output == W { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -2431,13 +2377,13 @@ extension TryCapture { public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture), R.Output == W { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -2458,33 +2404,6 @@ extension Capture { self.init(node: .capture(reference: reference.id, component.regex.root)) } - public init( - _ component: R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0), R.Output == (W, C0) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } - - public init( - _ component: R, - as reference: Reference, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0), R.Output == (W, C0) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } -} - -extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -2509,14 +2428,16 @@ extension TryCapture { }, component.regex.root))) } +} +extension TryCapture { public init( _ component: R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0), R.Output == (W, C0) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -2524,13 +2445,13 @@ extension TryCapture { public init( _ component: R, as reference: Reference, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0), R.Output == (W, C0) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -2554,33 +2475,6 @@ extension Capture { component().regex.root)) } - public init( - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0), R.Output == (W, C0) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } - - public init( - as reference: Reference, - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0), R.Output == (W, C0) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } -} - -extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -2605,14 +2499,16 @@ extension TryCapture { }, component().regex.root))) } +} +extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0), R.Output == (W, C0) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -2620,13 +2516,13 @@ extension TryCapture { public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0), R.Output == (W, C0) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -2647,33 +2543,6 @@ extension Capture { self.init(node: .capture(reference: reference.id, component.regex.root)) } - public init( - _ component: R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1), R.Output == (W, C0, C1) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } - - public init( - _ component: R, - as reference: Reference, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1), R.Output == (W, C0, C1) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } -} - -extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -2698,14 +2567,16 @@ extension TryCapture { }, component.regex.root))) } +} +extension TryCapture { public init( _ component: R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1), R.Output == (W, C0, C1) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -2713,13 +2584,13 @@ extension TryCapture { public init( _ component: R, as reference: Reference, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1), R.Output == (W, C0, C1) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -2743,33 +2614,6 @@ extension Capture { component().regex.root)) } - public init( - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1), R.Output == (W, C0, C1) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } - - public init( - as reference: Reference, - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1), R.Output == (W, C0, C1) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } -} - -extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -2794,14 +2638,16 @@ extension TryCapture { }, component().regex.root))) } +} +extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1), R.Output == (W, C0, C1) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -2809,13 +2655,13 @@ extension TryCapture { public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1), R.Output == (W, C0, C1) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -2836,33 +2682,6 @@ extension Capture { self.init(node: .capture(reference: reference.id, component.regex.root)) } - public init( - _ component: R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2), R.Output == (W, C0, C1, C2) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } - - public init( - _ component: R, - as reference: Reference, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2), R.Output == (W, C0, C1, C2) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } -} - -extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -2887,14 +2706,16 @@ extension TryCapture { }, component.regex.root))) } +} +extension TryCapture { public init( _ component: R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2), R.Output == (W, C0, C1, C2) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -2902,13 +2723,13 @@ extension TryCapture { public init( _ component: R, as reference: Reference, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2), R.Output == (W, C0, C1, C2) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -2932,33 +2753,6 @@ extension Capture { component().regex.root)) } - public init( - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2), R.Output == (W, C0, C1, C2) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } - - public init( - as reference: Reference, - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2), R.Output == (W, C0, C1, C2) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } -} - -extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -2983,14 +2777,16 @@ extension TryCapture { }, component().regex.root))) } +} +extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2), R.Output == (W, C0, C1, C2) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -2998,13 +2794,13 @@ extension TryCapture { public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2), R.Output == (W, C0, C1, C2) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -3025,33 +2821,6 @@ extension Capture { self.init(node: .capture(reference: reference.id, component.regex.root)) } - public init( - _ component: R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } - - public init( - _ component: R, - as reference: Reference, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } -} - -extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -3076,14 +2845,16 @@ extension TryCapture { }, component.regex.root))) } +} +extension TryCapture { public init( _ component: R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -3091,13 +2862,13 @@ extension TryCapture { public init( _ component: R, as reference: Reference, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -3121,33 +2892,6 @@ extension Capture { component().regex.root)) } - public init( - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } - - public init( - as reference: Reference, - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } -} - -extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -3172,14 +2916,16 @@ extension TryCapture { }, component().regex.root))) } +} +extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -3187,13 +2933,13 @@ extension TryCapture { public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -3214,33 +2960,6 @@ extension Capture { self.init(node: .capture(reference: reference.id, component.regex.root)) } - public init( - _ component: R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } - - public init( - _ component: R, - as reference: Reference, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } -} - -extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -3265,14 +2984,16 @@ extension TryCapture { }, component.regex.root))) } +} +extension TryCapture { public init( _ component: R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -3280,13 +3001,13 @@ extension TryCapture { public init( _ component: R, as reference: Reference, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -3306,37 +3027,10 @@ extension Capture { @RegexComponentBuilder _ component: () -> R ) where Output == (Substring, W, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { self.init(node: .capture( - reference: reference.id, - component().regex.root)) - } - - public init( - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } - - public init( - as reference: Reference, - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) + reference: reference.id, + component().regex.root)) } -} -extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -3361,14 +3055,16 @@ extension TryCapture { }, component().regex.root))) } +} +extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -3376,13 +3072,13 @@ extension TryCapture { public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -3403,33 +3099,6 @@ extension Capture { self.init(node: .capture(reference: reference.id, component.regex.root)) } - public init( - _ component: R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } - - public init( - _ component: R, - as reference: Reference, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } -} - -extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -3454,14 +3123,16 @@ extension TryCapture { }, component.regex.root))) } +} +extension TryCapture { public init( _ component: R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -3469,13 +3140,13 @@ extension TryCapture { public init( _ component: R, as reference: Reference, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -3499,33 +3170,6 @@ extension Capture { component().regex.root)) } - public init( - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } - - public init( - as reference: Reference, - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } -} - -extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -3550,14 +3194,16 @@ extension TryCapture { }, component().regex.root))) } +} +extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -3565,13 +3211,13 @@ extension TryCapture { public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -3592,33 +3238,6 @@ extension Capture { self.init(node: .capture(reference: reference.id, component.regex.root)) } - public init( - _ component: R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } - - public init( - _ component: R, - as reference: Reference, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } -} - -extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -3643,14 +3262,16 @@ extension TryCapture { }, component.regex.root))) } +} +extension TryCapture { public init( _ component: R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -3658,13 +3279,13 @@ extension TryCapture { public init( _ component: R, as reference: Reference, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -3688,33 +3309,6 @@ extension Capture { component().regex.root)) } - public init( - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } - - public init( - as reference: Reference, - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } -} - -extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -3739,14 +3333,16 @@ extension TryCapture { }, component().regex.root))) } +} +extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -3754,13 +3350,13 @@ extension TryCapture { public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -3781,33 +3377,6 @@ extension Capture { self.init(node: .capture(reference: reference.id, component.regex.root)) } - public init( - _ component: R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } - - public init( - _ component: R, - as reference: Reference, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } -} - -extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -3832,14 +3401,16 @@ extension TryCapture { }, component.regex.root))) } +} +extension TryCapture { public init( _ component: R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -3847,13 +3418,13 @@ extension TryCapture { public init( _ component: R, as reference: Reference, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -3877,33 +3448,6 @@ extension Capture { component().regex.root)) } - public init( - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } - - public init( - as reference: Reference, - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } -} - -extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -3928,14 +3472,16 @@ extension TryCapture { }, component().regex.root))) } +} +extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -3943,13 +3489,13 @@ extension TryCapture { public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -3970,33 +3516,6 @@ extension Capture { self.init(node: .capture(reference: reference.id, component.regex.root)) } - public init( - _ component: R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } - - public init( - _ component: R, - as reference: Reference, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } -} - -extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -4021,14 +3540,16 @@ extension TryCapture { }, component.regex.root))) } +} +extension TryCapture { public init( _ component: R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -4036,13 +3557,13 @@ extension TryCapture { public init( _ component: R, as reference: Reference, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -4066,33 +3587,6 @@ extension Capture { component().regex.root)) } - public init( - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } - - public init( - as reference: Reference, - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } -} - -extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -4117,14 +3611,16 @@ extension TryCapture { }, component().regex.root))) } +} +extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -4132,13 +3628,13 @@ extension TryCapture { public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -4159,33 +3655,6 @@ extension Capture { self.init(node: .capture(reference: reference.id, component.regex.root)) } - public init( - _ component: R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } - - public init( - _ component: R, - as reference: Reference, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } -} - -extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -4210,14 +3679,16 @@ extension TryCapture { }, component.regex.root))) } +} +extension TryCapture { public init( _ component: R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -4225,13 +3696,13 @@ extension TryCapture { public init( _ component: R, as reference: Reference, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -4255,33 +3726,6 @@ extension Capture { component().regex.root)) } - public init( - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } - - public init( - as reference: Reference, - @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } -} - -extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -4306,14 +3750,16 @@ extension TryCapture { }, component().regex.root))) } +} +extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -4321,13 +3767,13 @@ extension TryCapture { public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } diff --git a/Sources/VariadicsGenerator/VariadicsGenerator.swift b/Sources/VariadicsGenerator/VariadicsGenerator.swift index dbeff818c..5fbd2bf2d 100644 --- a/Sources/VariadicsGenerator/VariadicsGenerator.swift +++ b/Sources/VariadicsGenerator/VariadicsGenerator.swift @@ -615,35 +615,6 @@ struct VariadicsGenerator: ParsableCommand { self.init(node: .capture(reference: reference.id, component.regex.root)) } - \(disfavored)\ - public init<\(genericParams), NewCapture>( - _ component: R, - transform: @escaping (Substring) -> NewCapture - ) \(whereClauseTransformed) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } - - \(disfavored)\ - public init<\(genericParams), NewCapture>( - _ component: R, - as reference: Reference, - transform: @escaping (Substring) -> NewCapture - ) \(whereClauseTransformed) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component.regex.root))) - } - } - - extension TryCapture { \(disfavored)\ public init<\(genericParams), NewCapture>( _ component: R, @@ -670,15 +641,17 @@ struct VariadicsGenerator: ParsableCommand { }, component.regex.root))) } + } + extension TryCapture { \(disfavored)\ public init<\(genericParams), NewCapture>( _ component: R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) \(whereClauseTransformed) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -687,13 +660,13 @@ struct VariadicsGenerator: ParsableCommand { public init<\(genericParams), NewCapture>( _ component: R, as reference: Reference, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) \(whereClauseTransformed) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component.regex.root))) } @@ -719,35 +692,6 @@ struct VariadicsGenerator: ParsableCommand { component().regex.root)) } - \(disfavored)\ - public init<\(genericParams), NewCapture>( - @\(concatBuilderName) _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) \(whereClauseTransformed) { - self.init(node: .capture(.transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } - - \(disfavored)\ - public init<\(genericParams), NewCapture>( - as reference: Reference, - @\(concatBuilderName) _ component: () -> R, - transform: @escaping (Substring) -> NewCapture - ) \(whereClauseTransformed) { - self.init(node: .capture( - reference: reference.id, - .transform( - CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any - }, - component().regex.root))) - } - } - - extension TryCapture { \(disfavored)\ public init<\(genericParams), NewCapture>( @\(concatBuilderName) _ component: () -> R, @@ -774,15 +718,17 @@ struct VariadicsGenerator: ParsableCommand { }, component().regex.root))) } + } + extension TryCapture { \(disfavored)\ public init<\(genericParams), NewCapture>( @\(concatBuilderName) _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) \(whereClauseTransformed) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } @@ -791,13 +737,13 @@ struct VariadicsGenerator: ParsableCommand { public init<\(genericParams), NewCapture>( as reference: Reference, @\(concatBuilderName) _ component: () -> R, - transform: @escaping (Substring) -> NewCapture? + transform: @escaping (Substring) throws -> NewCapture? ) \(whereClauseTransformed) { self.init(node: .capture( reference: reference.id, .transform( CaptureTransform(resultType: NewCapture.self) { - transform($0) as Any? + try transform($0) as Any? }, component().regex.root))) } diff --git a/Sources/_RegexParser/Regex/AST/AST.swift b/Sources/_RegexParser/Regex/AST/AST.swift index ba37b6d62..409d5a7ee 100644 --- a/Sources/_RegexParser/Regex/AST/AST.swift +++ b/Sources/_RegexParser/Regex/AST/AST.swift @@ -304,78 +304,3 @@ extension AST { } } } - -// FIXME: Get this out of here -public struct CaptureTransform: Equatable, Hashable, CustomStringConvertible { - public enum Closure { - case nonfailable((Substring) -> Any) - case failable((Substring) -> Any?) - case throwing((Substring) throws -> Any) - } - public let resultType: Any.Type - public let closure: Closure - - public init(resultType: Any.Type, closure: Closure) { - self.resultType = resultType - self.closure = closure - } - - public init( - resultType: Any.Type, - _ closure: @escaping (Substring) -> Any - ) { - self.init(resultType: resultType, closure: .nonfailable(closure)) - } - - public init( - resultType: Any.Type, - _ closure: @escaping (Substring) -> Any? - ) { - self.init(resultType: resultType, closure: .failable(closure)) - } - - public init( - resultType: Any.Type, - _ closure: @escaping (Substring) throws -> Any - ) { - self.init(resultType: resultType, closure: .throwing(closure)) - } - - public func callAsFunction(_ input: Substring) -> Any? { - switch closure { - case .nonfailable(let closure): - let result = closure(input) - assert(type(of: result) == resultType) - return result - case .failable(let closure): - guard let result = closure(input) else { - return nil - } - assert(type(of: result) == resultType) - return result - case .throwing(let closure): - do { - let result = try closure(input) - assert(type(of: result) == resultType) - return result - } catch { - return nil - } - } - } - - public static func == (lhs: CaptureTransform, rhs: CaptureTransform) -> Bool { - unsafeBitCast(lhs.closure, to: (Int, Int).self) == - unsafeBitCast(rhs.closure, to: (Int, Int).self) - } - - public func hash(into hasher: inout Hasher) { - let (fn, ctx) = unsafeBitCast(closure, to: (Int, Int).self) - hasher.combine(fn) - hasher.combine(ctx) - } - - public var description: String { - "" - } -} diff --git a/Sources/_StringProcessing/ByteCodeGen.swift b/Sources/_StringProcessing/ByteCodeGen.swift index ed84fadbd..70233cf4f 100644 --- a/Sources/_StringProcessing/ByteCodeGen.swift +++ b/Sources/_StringProcessing/ByteCodeGen.swift @@ -317,7 +317,7 @@ extension Compiler.ByteCodeGen { ) throws { let transform = builder.makeTransformFunction { input, range in - t(input[range]) + try t(input[range]) } builder.buildBeginCapture(cap) try emitNode(child) diff --git a/Sources/_StringProcessing/Engine/Consume.swift b/Sources/_StringProcessing/Engine/Consume.swift index 4e00a34b4..bc60ba260 100644 --- a/Sources/_StringProcessing/Engine/Consume.swift +++ b/Sources/_StringProcessing/Engine/Consume.swift @@ -25,6 +25,7 @@ extension Engine { } extension Processor where Input == String { + // TODO: Should we throw here? mutating func consume() -> Input.Index? { while true { switch self.state { diff --git a/Sources/_StringProcessing/Engine/MEProgram.swift b/Sources/_StringProcessing/Engine/MEProgram.swift index a31134cc9..ecd67d4ba 100644 --- a/Sources/_StringProcessing/Engine/MEProgram.swift +++ b/Sources/_StringProcessing/Engine/MEProgram.swift @@ -14,11 +14,11 @@ import _RegexParser struct MEProgram where Input.Element: Equatable { typealias ConsumeFunction = (Input, Range) -> Input.Index? typealias AssertionFunction = - (Input, Input.Index, Range) -> Bool + (Input, Input.Index, Range) throws -> Bool typealias TransformFunction = - (Input, Range) -> Any? + (Input, Range) throws -> Any? typealias MatcherFunction = - (Input, Input.Index, Range) -> (Input.Index, Any)? + (Input, Input.Index, Range) throws -> (Input.Index, Any)? var instructions: InstructionList diff --git a/Sources/_StringProcessing/Engine/Processor.swift b/Sources/_StringProcessing/Engine/Processor.swift index 343b02c92..8f777ad33 100644 --- a/Sources/_StringProcessing/Engine/Processor.swift +++ b/Sources/_StringProcessing/Engine/Processor.swift @@ -51,6 +51,8 @@ struct Processor< var state: State = .inProgress + var failureReason: Error? = nil + var isTracingEnabled: Bool var storedCaptures: Array<_StoredCapture> @@ -181,6 +183,13 @@ extension Processor { registers.ints = intRegisters } + mutating func abort(_ e: Error? = nil) { + if let e = e { + self.failureReason = e + } + self.state = .fail + } + mutating func tryAccept() { switch (currentPosition, matchMode) { // When reaching the end of the match bounds or when we are only doing a @@ -355,8 +364,13 @@ extension Processor { case .assertBy: let reg = payload.assertion let assertion = registers[reg] - guard assertion(input, currentPosition, bounds) else { - signalFailure() + do { + guard try assertion(input, currentPosition, bounds) else { + signalFailure() + return + } + } catch { + abort(error) return } controller.step() @@ -364,15 +378,20 @@ extension Processor { case .matchBy: let (matcherReg, valReg) = payload.pairedMatcherValue let matcher = registers[matcherReg] - guard let (nextIdx, val) = matcher( - input, currentPosition, bounds - ) else { - signalFailure() + do { + guard let (nextIdx, val) = try matcher( + input, currentPosition, bounds + ) else { + signalFailure() + return + } + registers[valReg] = val + advance(to: nextIdx) + controller.step() + } catch { + abort(error) return } - registers[valReg] = val - advance(to: nextIdx) - controller.step() case .print: // TODO: Debug stream @@ -431,14 +450,18 @@ extension Processor { fatalError( "Unreachable: transforming without a capture") } - // FIXME: Pass input or the slice? - guard let value = transform(input, range) else { - signalFailure() + do { + // FIXME: Pass input or the slice? + guard let value = try transform(input, range) else { + signalFailure() + return + } + storedCaptures[capNum].registerValue(value) + controller.step() + } catch { + abort(error) return } - storedCaptures[capNum].registerValue(value) - - controller.step() case .captureValue: let (val, cap) = payload.pairedValueCapture diff --git a/Sources/_StringProcessing/Executor.swift b/Sources/_StringProcessing/Executor.swift index 148ddf468..563e90970 100644 --- a/Sources/_StringProcessing/Executor.swift +++ b/Sources/_StringProcessing/Executor.swift @@ -28,6 +28,9 @@ struct Executor { input: input, bounds: inputRange, matchMode: mode) guard let endIdx = cpu.consume() else { + if let e = cpu.failureReason { + throw e + } return nil } diff --git a/Sources/_StringProcessing/Regex/DSLTree.swift b/Sources/_StringProcessing/Regex/DSLTree.swift index 59ebd38af..f37505cb4 100644 --- a/Sources/_StringProcessing/Regex/DSLTree.swift +++ b/Sources/_StringProcessing/Regex/DSLTree.swift @@ -164,14 +164,14 @@ extension DSLTree { @_spi(RegexBuilder) public typealias _ConsumerInterface = ( String, Range -) -> String.Index? +) throws -> String.Index? // Type producing consume // TODO: better name @_spi(RegexBuilder) public typealias _MatcherInterface = ( String, String.Index, Range -) -> (String.Index, Any)? +) throws -> (String.Index, Any)? // Character-set (post grapheme segmentation) @_spi(RegexBuilder) @@ -384,3 +384,62 @@ public struct ReferenceID: Hashable, Equatable { Self.counter += 1 } } + +@_spi(RegexBuilder) +public struct CaptureTransform: Hashable, CustomStringConvertible { + public enum Closure { + case failable((Substring) throws -> Any?) + case nonfailable((Substring) throws -> Any) + } + public let resultType: Any.Type + public let closure: Closure + + public init(resultType: Any.Type, closure: Closure) { + self.resultType = resultType + self.closure = closure + } + + public init( + resultType: Any.Type, + _ closure: @escaping (Substring) throws -> Any + ) { + self.init(resultType: resultType, closure: .nonfailable(closure)) + } + + public init( + resultType: Any.Type, + _ closure: @escaping (Substring) throws -> Any? + ) { + self.init(resultType: resultType, closure: .failable(closure)) + } + + public func callAsFunction(_ input: Substring) throws -> Any? { + switch closure { + case .nonfailable(let closure): + let result = try closure(input) + assert(type(of: result) == resultType) + return result + case .failable(let closure): + guard let result = try closure(input) else { + return nil + } + assert(type(of: result) == resultType) + return result + } + } + + public static func == (lhs: CaptureTransform, rhs: CaptureTransform) -> Bool { + unsafeBitCast(lhs.closure, to: (Int, Int).self) == + unsafeBitCast(rhs.closure, to: (Int, Int).self) + } + + public func hash(into hasher: inout Hasher) { + let (fn, ctx) = unsafeBitCast(closure, to: (Int, Int).self) + hasher.combine(fn) + hasher.combine(ctx) + } + + public var description: String { + "" + } +} diff --git a/Sources/_StringProcessing/Regex/Match.swift b/Sources/_StringProcessing/Regex/Match.swift index 45d33f03e..5c846c0fd 100644 --- a/Sources/_StringProcessing/Regex/Match.swift +++ b/Sources/_StringProcessing/Regex/Match.swift @@ -130,7 +130,7 @@ extension RegexComponent { mode: MatchMode = .wholeString ) throws -> Regex.Match? { let executor = Executor(program: regex.program.loweredProgram) - return try executor.match(input, in: inputRange, mode) + return try executor.match(input, in: inputRange, mode) } func _firstMatch( diff --git a/Tests/RegexBuilderTests/CustomTests.swift b/Tests/RegexBuilderTests/CustomTests.swift index 19c4a3896..79ebc2693 100644 --- a/Tests/RegexBuilderTests/CustomTests.swift +++ b/Tests/RegexBuilderTests/CustomTests.swift @@ -138,4 +138,89 @@ class CustomRegexComponentTests: XCTestCase { XCTAssertEqual(res4.output.0, "123") XCTAssertEqual(res4.output.1, 3) } + + func testRegexAbort() { + + enum Radix: Hashable { + case dot + case comma + } + struct Abort: Error, Hashable {} + + let hexRegex = Regex { + Capture { OneOrMore(.hexDigit) } + TryCapture { CharacterClass.any } transform: { c -> Radix? in + switch c { + case ".": return Radix.dot + case ",": return Radix.comma + case "❗️": + // Malicious! Toxic levels of emphasis detected. + throw Abort() + default: + // Not a radix + return nil + } + } + Capture { OneOrMore(.hexDigit) } + } + // hexRegex: Regex<(Substring, Substring, Radix?, Substring)> + // TODO: Why is Radix optional? + + do { + guard let m = try hexRegex.matchWhole("123aef.345") else { + XCTFail() + return + } + XCTAssertEqual(m.0, "123aef.345") + XCTAssertEqual(m.1, "123aef") + XCTAssertEqual(m.2, .dot) + XCTAssertEqual(m.3, "345") + } catch { + XCTFail() + } + + do { + _ = try hexRegex.matchWhole("123aef❗️345") + XCTFail() + } catch let e as Abort { + XCTAssertEqual(e, Abort()) + } catch { + XCTFail() + } + + struct Poison: Error, Hashable {} + + let addressRegex = Regex { + "0x" + Capture(Repeat(.hexDigit, count: 8)) { hex -> Int in + let i = Int(hex, radix: 16)! + if i == 0xdeadbeef { + throw Poison() + } + return i + } + } + + do { + guard let m = try addressRegex.matchWhole("0x1234567f") else { + XCTFail() + return + } + XCTAssertEqual(m.0, "0x1234567f") + XCTAssertEqual(m.1, 0x1234567f) + } catch { + XCTFail() + } + + do { + _ = try addressRegex.matchWhole("0xdeadbeef") + XCTFail() + } catch let e as Poison { + XCTAssertEqual(e, Poison()) + } catch { + XCTFail() + } + + + } } From 57d8db7c47a09ebc260c64c785fc8cf3587ad60e Mon Sep 17 00:00:00 2001 From: Michael Ilseman Date: Tue, 12 Apr 2022 15:21:05 -0600 Subject: [PATCH 07/17] Nominalize API names (#271) Go from matchWhole -> wholeMatch(in:), which is more consistent with firstMatch etc. --- Documentation/Evolution/RegexTypeOverview.md | 32 ++++++---- .../Participants/RegexParticipant.swift | 4 +- Sources/RegexBuilder/Match.swift | 24 ++++---- .../Algorithms/Consumers/RegexConsumer.swift | 3 +- .../Algorithms/Matching/FirstMatch.swift | 4 +- .../Algorithms/Matching/Matches.swift | 7 ++- Sources/_StringProcessing/Regex/Match.swift | 36 ++++++----- Tests/RegexBuilderTests/CustomTests.swift | 10 ++-- Tests/RegexBuilderTests/MotivationTests.swift | 2 +- Tests/RegexBuilderTests/RegexDSLTests.swift | 60 +++++++++---------- 10 files changed, 100 insertions(+), 82 deletions(-) diff --git a/Documentation/Evolution/RegexTypeOverview.md b/Documentation/Evolution/RegexTypeOverview.md index 504111181..5f50f5116 100644 --- a/Documentation/Evolution/RegexTypeOverview.md +++ b/Documentation/Evolution/RegexTypeOverview.md @@ -1,4 +1,3 @@ - # Regex Type and Overview - Authors: [Michael Ilseman](https://github.com/milseman) and the Standard Library Team @@ -225,7 +224,7 @@ func processEntry(_ line: String) -> Transaction? { The result builder allows for inline failable value construction, which participates in the overall string processing algorithm: returning `nil` signals a local failure and the engine backtracks to try an alternative. This not only relieves the use site from post-processing, it enables new kinds of processing algorithms, allows for search-space pruning, and enhances debuggability. -Swift regexes describe an unambiguous algorithm, were choice is ordered and effects can be reliably observed. For example, a `print()` statement inside the `TryCapture`'s transform function will run whenever the overall algorithm naturally dictates an attempt should be made. Optimizations can only elide such calls if they can prove it is behavior-preserving (e.g. "pure"). +Swift regexes describe an unambiguous algorithm, where choice is ordered and effects can be reliably observed. For example, a `print()` statement inside the `TryCapture`'s transform function will run whenever the overall algorithm naturally dictates an attempt should be made. Optimizations can only elide such calls if they can prove it is behavior-preserving (e.g. "pure"). `CustomMatchingRegexComponent`, discussed in [String Processing Algorithms][pitches], allows industrial-strength parsers to be used a regex components. This allows us to drop the overly-permissive pre-parsing step: @@ -278,14 +277,14 @@ func processEntry(_ line: String) -> Transaction? { *Note*: Details on how references work is discussed in [Regex Builders][pitches]. `Regex.Match` supports referring to _all_ captures by position (`match.1`, etc.) whether named or referenced or neither. Due to compiler limitations, result builders do not support forming labeled tuples for named captures. -### Algorithms, algorithms everywhere +### Regex-powered algorithms Regexes can be used right out of the box with a variety of powerful and convenient algorithms, including trimming, splitting, and finding/replacing all matches within a string. These algorithms are discussed in [String Processing Algorithms][pitches]. -### Onward Unicode +### Unicode handling A regex describes an algorithm to be ran over some model of string, and Swift's `String` has a rather unique Unicode-forward model. `Character` is an [extended grapheme cluster](https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries) and equality is determined under [canonical equivalence](https://www.unicode.org/reports/tr15/#Canon_Compat_Equivalence). @@ -310,12 +309,12 @@ public struct Regex { /// Match a string in its entirety. /// /// Returns `nil` if no match and throws on abort - public func matchWhole(_ s: String) throws -> Regex.Match? + public func wholeMatch(in s: String) throws -> Regex.Match? /// Match part of the string, starting at the beginning. /// /// Returns `nil` if no match and throws on abort - public func matchPrefix(_ s: String) throws -> Regex.Match? + public func prefixMatch(in s: String) throws -> Regex.Match? /// Find the first match in a string /// @@ -325,17 +324,17 @@ public struct Regex { /// Match a substring in its entirety. /// /// Returns `nil` if no match and throws on abort - public func matchWhole(_ s: Substring) throws -> Regex.Match? + public func wholeMatch(in s: Substring) throws -> Regex.Match? /// Match part of the string, starting at the beginning. /// /// Returns `nil` if no match and throws on abort - public func matchPrefix(_ s: Substring) throws -> Regex.Match? + public func prefixMatch(in s: Substring) throws -> Regex.Match? /// Find the first match in a substring /// /// Returns `nil` if no match is found and throws on abort - public func firstMatch(_ s: Substring) throws -> Regex.Match? + public func firstMatch(in s: Substring) throws -> Regex.Match? /// The result of matching a regex against a string. /// @@ -344,19 +343,19 @@ public struct Regex { @dynamicMemberLookup public struct Match { /// The range of the overall match - public let range: Range + public var range: Range { get } /// The produced output from the match operation - public var output: Output + public var output: Output { get } /// Lookup a capture by name or number - public subscript(dynamicMember keyPath: KeyPath) -> T + public subscript(dynamicMember keyPath: KeyPath) -> T { get } /// Lookup a capture by number @_disfavoredOverload public subscript( dynamicMember keyPath: KeyPath<(Output, _doNotUse: ()), Output> - ) -> Output + ) -> Output { get } // Note: this allows `.0` when `Match` is not a tuple. } @@ -482,6 +481,13 @@ We're also looking for more community discussion on what the default type system The actual `Match` struct just stores ranges: the `Substrings` are lazily created on demand. This avoids unnecessary ARC traffic and memory usage. + +### `Regex` instead of `Regex` + +The generic parameter `Output` is proposed to contain both the whole match (the `.0` element if `Output` is a tuple) and captures. One alternative we have considered is separating `Output` into the entire match and the captures, i.e. `Regex`, and using `Void` for for `Captures` when there are no captures. + +The biggest issue with this alternative design is that the numbering of `Captures` elements misaligns with the numbering of captures in textual regexes, where backreference `\0` refers to the entire match and captures start at `\1`. This design would sacrifice familarity and have the pitfall of introducing off-by-one errors. + ### Future work: static optimization and compilation Swift's support for static compilation is still developing, and future work here is leveraging that to compile regex when profitable. Many regex describe simple [DFAs](https://en.wikipedia.org/wiki/Deterministic_finite_automaton) and can be statically compiled into very efficient programs. Full static compilation needs to be balanced with code size concerns, as a matching-specific bytecode is typically far smaller than a corresponding program (especially since the bytecode interpreter is shared). diff --git a/Sources/Exercises/Participants/RegexParticipant.swift b/Sources/Exercises/Participants/RegexParticipant.swift index 71018d8a7..6fddc0914 100644 --- a/Sources/Exercises/Participants/RegexParticipant.swift +++ b/Sources/Exercises/Participants/RegexParticipant.swift @@ -63,7 +63,7 @@ private func graphemeBreakPropertyData( forLine line: String, using regex: RP ) -> GraphemeBreakEntry? where RP.Output == (Substring, Substring, Substring?, Substring) { - line.matchWhole(regex).map(\.output).flatMap(extractFromCaptures) + line.wholeMatch(of: regex).map(\.output).flatMap(extractFromCaptures) } private func graphemeBreakPropertyDataLiteral( @@ -80,7 +80,7 @@ private func graphemeBreakPropertyDataLiteral( private func graphemeBreakPropertyData( forLine line: String ) -> GraphemeBreakEntry? { - line.matchWhole { + line.wholeMatch { TryCapture(OneOrMore(.hexDigit)) { Unicode.Scalar(hex: $0) } Optionally { ".." diff --git a/Sources/RegexBuilder/Match.swift b/Sources/RegexBuilder/Match.swift index ac07ec0b8..e6718d96b 100644 --- a/Sources/RegexBuilder/Match.swift +++ b/Sources/RegexBuilder/Match.swift @@ -12,29 +12,29 @@ import _StringProcessing extension String { - public func matchWhole( - @RegexComponentBuilder _ content: () -> R + public func wholeMatch( + @RegexComponentBuilder of content: () -> R ) -> Regex.Match? { - matchWhole(content()) + wholeMatch(of: content()) } - public func matchPrefix( - @RegexComponentBuilder _ content: () -> R + public func prefixMatch( + @RegexComponentBuilder of content: () -> R ) -> Regex.Match? { - matchPrefix(content()) + prefixMatch(of: content()) } } extension Substring { - public func matchWhole( - @RegexComponentBuilder _ content: () -> R + public func wholeMatch( + @RegexComponentBuilder of content: () -> R ) -> Regex.Match? { - matchWhole(content()) + wholeMatch(of: content()) } - public func matchPrefix( - @RegexComponentBuilder _ content: () -> R + public func prefixMatch( + @RegexComponentBuilder of content: () -> R ) -> Regex.Match? { - matchPrefix(content()) + prefixMatch(of: content()) } } diff --git a/Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift b/Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift index dcc5d9f2b..2718d520a 100644 --- a/Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift +++ b/Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift @@ -9,6 +9,7 @@ // //===----------------------------------------------------------------------===// +// FIXME: What even is this? Can we delete this whole thing? struct RegexConsumer< R: RegexComponent, Consumed: BidirectionalCollection > where Consumed.SubSequence == Substring { @@ -24,7 +25,7 @@ extension RegexConsumer { func _matchingConsuming( _ consumed: Substring, in range: Range ) -> (upperBound: String.Index, match: Match)? { - guard let result = try! regex._match( + guard let result = try! regex.regex._match( consumed.base, in: range, mode: .partialFromFront ) else { return nil } diff --git a/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift b/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift index 2aea0f342..1ad555e7d 100644 --- a/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift +++ b/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift @@ -55,9 +55,9 @@ extension BidirectionalCollection where SubSequence == Substring { /// - Returns: The first match of `regex` in the collection, or `nil` if /// there isn't a match. public func firstMatch( - of regex: R + of r: R ) -> Regex.Match? { let slice = self[...] - return try? regex.firstMatch(in: slice.base) + return try? r.regex.firstMatch(in: slice.base) } } diff --git a/Sources/_StringProcessing/Algorithms/Matching/Matches.swift b/Sources/_StringProcessing/Algorithms/Matching/Matches.swift index 6453fccb0..24cdbee0f 100644 --- a/Sources/_StringProcessing/Algorithms/Matching/Matches.swift +++ b/Sources/_StringProcessing/Algorithms/Matching/Matches.swift @@ -202,14 +202,17 @@ extension BidirectionalCollection where SubSequence == Substring { // FIXME: Replace the returned value as `some Collection.Match> // when SE-0346 is enabled - func _matches(of regex: R) -> [Regex.Match] { + func _matches(of r: R) -> [Regex.Match] { let slice = self[...] var start = self.startIndex let end = self.endIndex + let regex = r.regex var result = [Regex.Match]() while start < end { - guard let match = try? regex._firstMatch(slice.base, in: start.. Regex.Match? { + public func wholeMatch(in s: String) throws -> Regex.Match? { try _match(s, in: s.startIndex.. Regex.Match? { + public func prefixMatch(in s: String) throws -> Regex.Match? { try _match(s, in: s.startIndex.. Regex.Match? { + public func wholeMatch(in s: Substring) throws -> Regex.Match? { try _match(s.base, in: s.startIndex.. Regex.Match? { + public func prefixMatch(in s: Substring) throws -> Regex.Match? { try _match(s.base, in: s.startIndex..(_ regex: R) -> Regex.Match? { - try? regex.matchWhole(self) + public func wholeMatch( + of r: R + ) -> Regex.Match? { + try? r.regex.wholeMatch(in: self) } - public func matchPrefix(_ regex: R) -> Regex.Match? { - try? regex.matchPrefix(self) + public func prefixMatch( + of r: R + ) -> Regex.Match? { + try? r.regex.prefixMatch(in: self) } } extension Substring { - public func matchWhole(_ regex: R) -> Regex.Match? { - try? regex.matchWhole(self) - } - public func matchPrefix(_ regex: R) -> Regex.Match? { - try? regex.matchPrefix(self) + public func wholeMatch( + of r: R + ) -> Regex.Match? { + try? r.regex.wholeMatch(in: self) + } + public func prefixMatch( + of r: R + ) -> Regex.Match? { + try? r.regex.prefixMatch(in: self) } } diff --git a/Tests/RegexBuilderTests/CustomTests.swift b/Tests/RegexBuilderTests/CustomTests.swift index 79ebc2693..555ecb8ca 100644 --- a/Tests/RegexBuilderTests/CustomTests.swift +++ b/Tests/RegexBuilderTests/CustomTests.swift @@ -62,7 +62,7 @@ func customTest( let result: Match? switch call { case .match: - result = input.matchWhole(regex)?.output + result = input.wholeMatch(of: regex)?.output case .firstMatch: result = input.firstMatch(of: regex)?.output } @@ -167,7 +167,7 @@ class CustomRegexComponentTests: XCTestCase { // TODO: Why is Radix optional? do { - guard let m = try hexRegex.matchWhole("123aef.345") else { + guard let m = try hexRegex.wholeMatch(in: "123aef.345") else { XCTFail() return } @@ -180,7 +180,7 @@ class CustomRegexComponentTests: XCTestCase { } do { - _ = try hexRegex.matchWhole("123aef❗️345") + _ = try hexRegex.wholeMatch(in: "123aef❗️345") XCTFail() } catch let e as Abort { XCTAssertEqual(e, Abort()) @@ -202,7 +202,7 @@ class CustomRegexComponentTests: XCTestCase { } do { - guard let m = try addressRegex.matchWhole("0x1234567f") else { + guard let m = try addressRegex.wholeMatch(in: "0x1234567f") else { XCTFail() return } @@ -213,7 +213,7 @@ class CustomRegexComponentTests: XCTestCase { } do { - _ = try addressRegex.matchWhole("0xdeadbeef") + _ = try addressRegex.wholeMatch(in: "0xdeadbeef") XCTFail() } catch let e as Poison { XCTAssertEqual(e, Poison()) diff --git a/Tests/RegexBuilderTests/MotivationTests.swift b/Tests/RegexBuilderTests/MotivationTests.swift index 882ba6448..1927b9ae4 100644 --- a/Tests/RegexBuilderTests/MotivationTests.swift +++ b/Tests/RegexBuilderTests/MotivationTests.swift @@ -199,7 +199,7 @@ private func process( _ line: String, using regex: Regex<(Substring, Substring, Substring, Substring, Substring)> ) -> Transaction? { - guard let output = try? regex.matchWhole(line), + guard let output = try? regex.wholeMatch(in: line), let kind = Transaction.Kind(output.1) else { return nil diff --git a/Tests/RegexBuilderTests/RegexDSLTests.swift b/Tests/RegexBuilderTests/RegexDSLTests.swift index 1f5305c59..0c0bf7c8f 100644 --- a/Tests/RegexBuilderTests/RegexDSLTests.swift +++ b/Tests/RegexBuilderTests/RegexDSLTests.swift @@ -24,7 +24,7 @@ class RegexDSLTests: XCTestCase { ) throws { let regex = content() for (input, maybeExpectedCaptures) in tests { - let maybeMatch = input.matchWhole(regex) + let maybeMatch = input.wholeMatch(of: regex) if let expectedCaptures = maybeExpectedCaptures { let match = try XCTUnwrap(maybeMatch, file: file, line: line) XCTAssertTrue( @@ -52,12 +52,12 @@ class RegexDSLTests: XCTestCase { } // Assert the inferred capture type. let _: (Substring, Substring, Int).Type = type(of: regex).Output.self - let maybeMatch = "ab1".matchWhole(regex) + let maybeMatch = "ab1".wholeMatch(of: regex) let match = try XCTUnwrap(maybeMatch) XCTAssertTrue(match.output == ("ab1", "b", 1)) let substring = "ab1"[...] - let substringMatch = try XCTUnwrap(substring.matchWhole(regex)) + let substringMatch = try XCTUnwrap(substring.wholeMatch(of: regex)) XCTAssertTrue(match.output == substringMatch.output) } @@ -126,7 +126,7 @@ class RegexDSLTests: XCTestCase { } func testMatchResultDotZeroWithoutCapture() throws { - let match = try XCTUnwrap("aaa".matchWhole { OneOrMore { "a" } }) + let match = try XCTUnwrap("aaa".wholeMatch { OneOrMore { "a" } }) XCTAssertEqual(match.0, "aaa") } @@ -135,8 +135,8 @@ class RegexDSLTests: XCTestCase { let regex = ChoiceOf { "aaa" } - XCTAssertTrue("aaa".matchWhole(regex)?.output == "aaa") - XCTAssertNil("aab".matchWhole(regex)?.output) + XCTAssertTrue("aaa".wholeMatch(of: regex)?.output == "aaa") + XCTAssertNil("aab".wholeMatch(of: regex)?.output) } do { let regex = ChoiceOf { @@ -144,10 +144,10 @@ class RegexDSLTests: XCTestCase { "bbb" "ccc" } - XCTAssertTrue("aaa".matchWhole(regex)?.output == "aaa") - XCTAssertNil("aab".matchWhole(regex)?.output) - XCTAssertTrue("bbb".matchWhole(regex)?.output == "bbb") - XCTAssertTrue("ccc".matchWhole(regex)?.output == "ccc") + XCTAssertTrue("aaa".wholeMatch(of: regex)?.output == "aaa") + XCTAssertNil("aab".wholeMatch(of: regex)?.output) + XCTAssertTrue("bbb".wholeMatch(of: regex)?.output == "bbb") + XCTAssertTrue("ccc".wholeMatch(of: regex)?.output == "ccc") } do { let regex = Regex { @@ -162,7 +162,7 @@ class RegexDSLTests: XCTestCase { } } XCTAssertTrue( - try XCTUnwrap("abc".matchWhole(regex)?.output) == ("abc", "c")) + try XCTUnwrap("abc".wholeMatch(of: regex)?.output) == ("abc", "c")) } do { let regex = ChoiceOf { @@ -170,18 +170,18 @@ class RegexDSLTests: XCTestCase { "bbb" "ccc" } - XCTAssertTrue("aaa".matchWhole(regex)?.output == "aaa") - XCTAssertNil("aab".matchWhole(regex)?.output) - XCTAssertTrue("bbb".matchWhole(regex)?.output == "bbb") - XCTAssertTrue("ccc".matchWhole(regex)?.output == "ccc") + XCTAssertTrue("aaa".wholeMatch(of: regex)?.output == "aaa") + XCTAssertNil("aab".wholeMatch(of: regex)?.output) + XCTAssertTrue("bbb".wholeMatch(of: regex)?.output == "bbb") + XCTAssertTrue("ccc".wholeMatch(of: regex)?.output == "ccc") } do { let regex = ChoiceOf { Capture("aaa") } XCTAssertTrue( - try XCTUnwrap("aaa".matchWhole(regex)?.output) == ("aaa", "aaa")) - XCTAssertNil("aab".matchWhole(regex)?.output) + try XCTUnwrap("aaa".wholeMatch(of: regex)?.output) == ("aaa", "aaa")) + XCTAssertNil("aab".wholeMatch(of: regex)?.output) } do { let regex = ChoiceOf { @@ -190,12 +190,12 @@ class RegexDSLTests: XCTestCase { Capture("ccc") } XCTAssertTrue( - try XCTUnwrap("aaa".matchWhole(regex)?.output) == ("aaa", "aaa", nil, nil)) + try XCTUnwrap("aaa".wholeMatch(of: regex)?.output) == ("aaa", "aaa", nil, nil)) XCTAssertTrue( - try XCTUnwrap("bbb".matchWhole(regex)?.output) == ("bbb", nil, "bbb", nil)) + try XCTUnwrap("bbb".wholeMatch(of: regex)?.output) == ("bbb", nil, "bbb", nil)) XCTAssertTrue( - try XCTUnwrap("ccc".matchWhole(regex)?.output) == ("ccc", nil, nil, "ccc")) - XCTAssertNil("aab".matchWhole(regex)?.output) + try XCTUnwrap("ccc".wholeMatch(of: regex)?.output) == ("ccc", nil, nil, "ccc")) + XCTAssertNil("aab".wholeMatch(of: regex)?.output) } } @@ -407,7 +407,7 @@ class RegexDSLTests: XCTestCase { // Assert the inferred capture type. let _: Substring.Type = type(of: regex).Output.self let input = "123123" - let match = try XCTUnwrap(input.matchWhole(regex)?.output) + let match = try XCTUnwrap(input.wholeMatch(of: regex)?.output) XCTAssertTrue(match == input) } @@ -534,7 +534,7 @@ class RegexDSLTests: XCTestCase { let unicodeLine = "1BCA0..1BCA3 ; Control # Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP" - let match = try XCTUnwrap(unicodeLine.matchWhole(unicodeData)) + let match = try XCTUnwrap(unicodeLine.wholeMatch(of: unicodeData)) XCTAssertEqual(match.0, Substring(unicodeLine)) XCTAssertEqual(match.1, "Control") } @@ -566,7 +566,7 @@ class RegexDSLTests: XCTestCase { Substring, Unicode.Scalar?, Unicode.Scalar??, Substring ) let _: ExpectedMatch.Type = type(of: regexWithCapture).Output.self - let maybeMatchResult = line.matchWhole(regexWithCapture) + let maybeMatchResult = line.wholeMatch(of: regexWithCapture) let matchResult = try XCTUnwrap(maybeMatchResult) let (wholeMatch, lower, upper, propertyString) = matchResult.output XCTAssertEqual(wholeMatch, Substring(line)) @@ -601,7 +601,7 @@ class RegexDSLTests: XCTestCase { Substring, Unicode.Scalar, Unicode.Scalar?, Substring ) let _: ExpectedMatch.Type = type(of: regexWithTryCapture).Output.self - let maybeMatchResult = line.matchWhole(regexWithTryCapture) + let maybeMatchResult = line.wholeMatch(of: regexWithTryCapture) let matchResult = try XCTUnwrap(maybeMatchResult) let (wholeMatch, lower, upper, propertyString) = matchResult.output XCTAssertEqual(wholeMatch, Substring(line)) @@ -614,7 +614,7 @@ class RegexDSLTests: XCTestCase { let regexLiteral = try Regex( compiling: #"([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s+;\s+(\w+).*"#, as: (Substring, Substring, Substring?, Substring).self) - let maybeMatchResult = line.matchWhole(regexLiteral) + let maybeMatchResult = line.wholeMatch(of: regexLiteral) let matchResult = try XCTUnwrap(maybeMatchResult) let (wholeMatch, lower, upper, propertyString) = matchResult.output XCTAssertEqual(wholeMatch, Substring(line)) @@ -628,7 +628,7 @@ class RegexDSLTests: XCTestCase { do { let regex = try Regex(compiling: "aabcc.") let line = "aabccd" - let match = try XCTUnwrap(line.matchWhole(regex)) + let match = try XCTUnwrap(line.wholeMatch(of: regex)) XCTAssertEqual(match.0, line[...]) let output = match.output XCTAssertEqual(output[0].substring, line[...]) @@ -640,7 +640,7 @@ class RegexDSLTests: XCTestCase { A6F0..A6F1 ; Extend # Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM \ COMBINING MARK TUKWENTIS """ - let match = try XCTUnwrap(line.matchWhole(regex)) + let match = try XCTUnwrap(line.wholeMatch(of: regex)) XCTAssertEqual(match.0, line[...]) let output = match.output XCTAssertEqual(output[0].substring, line[...]) @@ -705,7 +705,7 @@ class RegexDSLTests: XCTestCase { } } let input = "abc#41#42abc#42#42" - let result = try XCTUnwrap(input.matchWhole(regex)) + let result = try XCTUnwrap(input.wholeMatch(of: regex)) XCTAssertEqual(result[a], "abc") XCTAssertEqual(result[b], 42) } @@ -785,7 +785,7 @@ class RegexDSLTests: XCTestCase { let parser = SemanticVersionParser() for (str, version) in versions { - XCTAssertEqual(str.matchWhole(parser)?.output, version) + XCTAssertEqual(str.wholeMatch(of: parser)?.output, version) } } } From 3f632652f3acd74d519c2bfbf5376bb1619ea4ce Mon Sep 17 00:00:00 2001 From: Richard Wei Date: Thu, 14 Apr 2022 11:04:10 -0700 Subject: [PATCH 08/17] Add SwiftStdlib 5.7 availability (#276) Add availability to public, SPI, and test symbols. --- Package.swift | 33 ++++++++++++++----- Sources/RegexBuilder/Anchor.swift | 2 ++ Sources/RegexBuilder/Builder.swift | 1 + Sources/RegexBuilder/CharacterClass.swift | 3 ++ Sources/RegexBuilder/DSL.swift | 11 +++++++ Sources/RegexBuilder/Match.swift | 4 +++ .../Algorithms/Algorithms/Contains.swift | 2 ++ .../Algorithms/Algorithms/FirstRange.swift | 3 ++ .../Algorithms/Algorithms/Replace.swift | 6 ++++ .../Algorithms/Algorithms/StartsWith.swift | 1 + .../Algorithms/Algorithms/Trim.swift | 7 ++++ .../Algorithms/Matching/MatchReplace.swift | 3 ++ .../Regex/AnyRegexOutput.swift | 1 + Sources/_StringProcessing/Regex/Core.swift | 2 ++ .../Regex/DSLConsumers.swift | 1 + Sources/_StringProcessing/Regex/DSLTree.swift | 6 ++++ .../_CharacterClassModel.swift | 1 + Tests/RegexBuilderTests/AlgorithmsTests.swift | 1 + 18 files changed, 79 insertions(+), 9 deletions(-) diff --git a/Package.swift b/Package.swift index 47a73ca72..cbec5f6a8 100644 --- a/Package.swift +++ b/Package.swift @@ -3,6 +3,13 @@ import PackageDescription +let availabilityDefinition = PackageDescription.SwiftSetting.unsafeFlags([ + "-Xfrontend", + "-define-availability", + "-Xfrontend", + #""SwiftStdlib 5.7:macOS 9999, iOS 9999, watchOS 9999, tvOS 9999""# +]) + let package = Package( name: "swift-experimental-string-processing", products: [ @@ -31,12 +38,14 @@ let package = Package( name: "_RegexParser", dependencies: [], swiftSettings: [ - .unsafeFlags(["-enable-library-evolution"]) + .unsafeFlags(["-enable-library-evolution"]), + availabilityDefinition ]), .testTarget( name: "MatchingEngineTests", dependencies: [ - "_RegexParser", "_StringProcessing"]), + "_RegexParser", "_StringProcessing" + ]), .target( name: "_CUnicode", dependencies: []), @@ -45,26 +54,31 @@ let package = Package( dependencies: ["_RegexParser", "_CUnicode"], swiftSettings: [ .unsafeFlags(["-enable-library-evolution"]), + availabilityDefinition ]), .target( name: "RegexBuilder", dependencies: ["_StringProcessing", "_RegexParser"], swiftSettings: [ .unsafeFlags(["-enable-library-evolution"]), - .unsafeFlags(["-Xfrontend", "-enable-experimental-pairwise-build-block"]) + .unsafeFlags(["-Xfrontend", "-enable-experimental-pairwise-build-block"]), + availabilityDefinition ]), .testTarget( name: "RegexTests", - dependencies: ["_StringProcessing"]), + dependencies: ["_StringProcessing"], + swiftSettings: [availabilityDefinition]), .testTarget( name: "RegexBuilderTests", dependencies: ["_StringProcessing", "RegexBuilder"], swiftSettings: [ - .unsafeFlags(["-Xfrontend", "-enable-experimental-pairwise-build-block"]) + .unsafeFlags(["-Xfrontend", "-enable-experimental-pairwise-build-block"]), + availabilityDefinition ]), .target( name: "Prototypes", - dependencies: ["_RegexParser", "_StringProcessing"]), + dependencies: ["_RegexParser", "_StringProcessing"], + swiftSettings: [availabilityDefinition]), // MARK: Scripts .executableTarget( @@ -85,11 +99,12 @@ let package = Package( name: "Exercises", dependencies: ["_RegexParser", "Prototypes", "_StringProcessing", "RegexBuilder"], swiftSettings: [ - .unsafeFlags(["-Xfrontend", "-enable-experimental-pairwise-build-block"]) + .unsafeFlags(["-Xfrontend", "-enable-experimental-pairwise-build-block"]), + availabilityDefinition ]), .testTarget( name: "ExercisesTests", - dependencies: ["Exercises"]), + dependencies: ["Exercises"], + swiftSettings: [availabilityDefinition]), ] ) - diff --git a/Sources/RegexBuilder/Anchor.swift b/Sources/RegexBuilder/Anchor.swift index ba910bd30..7933b987a 100644 --- a/Sources/RegexBuilder/Anchor.swift +++ b/Sources/RegexBuilder/Anchor.swift @@ -12,6 +12,7 @@ import _RegexParser @_spi(RegexBuilder) import _StringProcessing +@available(SwiftStdlib 5.7, *) public struct Anchor { internal enum Kind { case startOfSubject @@ -107,6 +108,7 @@ extension Anchor { } } +@available(SwiftStdlib 5.7, *) public struct Lookahead: _BuiltinRegexComponent { public var regex: Regex diff --git a/Sources/RegexBuilder/Builder.swift b/Sources/RegexBuilder/Builder.swift index 8921c8f25..be9a48e36 100644 --- a/Sources/RegexBuilder/Builder.swift +++ b/Sources/RegexBuilder/Builder.swift @@ -11,6 +11,7 @@ @_spi(RegexBuilder) import _StringProcessing +@available(SwiftStdlib 5.7, *) @resultBuilder public enum RegexComponentBuilder { public static func buildBlock() -> Regex { diff --git a/Sources/RegexBuilder/CharacterClass.swift b/Sources/RegexBuilder/CharacterClass.swift index 78ebd49a2..99e981d33 100644 --- a/Sources/RegexBuilder/CharacterClass.swift +++ b/Sources/RegexBuilder/CharacterClass.swift @@ -12,6 +12,7 @@ import _RegexParser @_spi(RegexBuilder) import _StringProcessing +@available(SwiftStdlib 5.7, *) public struct CharacterClass { internal var ccc: DSLTree.CustomCharacterClass @@ -122,6 +123,7 @@ extension CharacterClass { } /// Range syntax for characters in `CharacterClass`es. +@available(SwiftStdlib 5.7, *) public func ...(lhs: Character, rhs: Character) -> CharacterClass { let range: DSLTree.CustomCharacterClass.Member = .range(.char(lhs), .char(rhs)) let ccc = DSLTree.CustomCharacterClass(members: [range], isInverted: false) @@ -130,6 +132,7 @@ public func ...(lhs: Character, rhs: Character) -> CharacterClass { /// Range syntax for unicode scalars in `CharacterClass`es. @_disfavoredOverload +@available(SwiftStdlib 5.7, *) public func ...(lhs: UnicodeScalar, rhs: UnicodeScalar) -> CharacterClass { let range: DSLTree.CustomCharacterClass.Member = .range(.scalar(lhs), .scalar(rhs)) let ccc = DSLTree.CustomCharacterClass(members: [range], isInverted: false) diff --git a/Sources/RegexBuilder/DSL.swift b/Sources/RegexBuilder/DSL.swift index 80662be41..717e172b0 100644 --- a/Sources/RegexBuilder/DSL.swift +++ b/Sources/RegexBuilder/DSL.swift @@ -54,6 +54,7 @@ extension _BuiltinRegexComponent { // Note: Quantifiers are currently gyb'd. /// Specifies how much to attempt to match when using a quantifier. +@available(SwiftStdlib 5.7, *) public struct QuantificationBehavior { internal enum Kind { case eagerly @@ -121,6 +122,7 @@ extension QuantificationBehavior { } } +@available(SwiftStdlib 5.7, *) public struct OneOrMore: _BuiltinRegexComponent { public var regex: Regex @@ -132,6 +134,7 @@ public struct OneOrMore: _BuiltinRegexComponent { // Variadics.swift. } +@available(SwiftStdlib 5.7, *) public struct ZeroOrMore: _BuiltinRegexComponent { public var regex: Regex @@ -143,6 +146,7 @@ public struct ZeroOrMore: _BuiltinRegexComponent { // Variadics.swift. } +@available(SwiftStdlib 5.7, *) public struct Optionally: _BuiltinRegexComponent { public var regex: Regex @@ -154,6 +158,7 @@ public struct Optionally: _BuiltinRegexComponent { // Variadics.swift. } +@available(SwiftStdlib 5.7, *) public struct Repeat: _BuiltinRegexComponent { public var regex: Regex @@ -179,6 +184,7 @@ public struct Repeat: _BuiltinRegexComponent { // ) -> R where R.Match == (W, C...) // } +@available(SwiftStdlib 5.7, *) @resultBuilder public struct AlternationBuilder { @_disfavoredOverload @@ -201,6 +207,7 @@ public struct AlternationBuilder { } } +@available(SwiftStdlib 5.7, *) public struct ChoiceOf: _BuiltinRegexComponent { public var regex: Regex @@ -215,6 +222,7 @@ public struct ChoiceOf: _BuiltinRegexComponent { // MARK: - Capture +@available(SwiftStdlib 5.7, *) public struct Capture: _BuiltinRegexComponent { public var regex: Regex @@ -225,6 +233,7 @@ public struct Capture: _BuiltinRegexComponent { // Note: Public initializers are currently gyb'd. See Variadics.swift. } +@available(SwiftStdlib 5.7, *) public struct TryCapture: _BuiltinRegexComponent { public var regex: Regex @@ -239,6 +248,7 @@ public struct TryCapture: _BuiltinRegexComponent { /// An atomic group, i.e. opens a local backtracking scope which, upon successful exit, /// discards any remaining backtracking points from within the scope +@available(SwiftStdlib 5.7, *) public struct Local: _BuiltinRegexComponent { public var regex: Regex @@ -249,6 +259,7 @@ public struct Local: _BuiltinRegexComponent { // MARK: - Backreference +@available(SwiftStdlib 5.7, *) public struct Reference: RegexComponent { let id = ReferenceID() diff --git a/Sources/RegexBuilder/Match.swift b/Sources/RegexBuilder/Match.swift index e6718d96b..32dc889d9 100644 --- a/Sources/RegexBuilder/Match.swift +++ b/Sources/RegexBuilder/Match.swift @@ -12,12 +12,14 @@ import _StringProcessing extension String { + @available(SwiftStdlib 5.7, *) public func wholeMatch( @RegexComponentBuilder of content: () -> R ) -> Regex.Match? { wholeMatch(of: content()) } + @available(SwiftStdlib 5.7, *) public func prefixMatch( @RegexComponentBuilder of content: () -> R ) -> Regex.Match? { @@ -26,12 +28,14 @@ extension String { } extension Substring { + @available(SwiftStdlib 5.7, *) public func wholeMatch( @RegexComponentBuilder of content: () -> R ) -> Regex.Match? { wholeMatch(of: content()) } + @available(SwiftStdlib 5.7, *) public func prefixMatch( @RegexComponentBuilder of content: () -> R ) -> Regex.Match? { diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/Contains.swift b/Sources/_StringProcessing/Algorithms/Algorithms/Contains.swift index 46568192f..2f38095d8 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/Contains.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/Contains.swift @@ -27,6 +27,7 @@ extension Collection where Element: Equatable { /// - Parameter other: A sequence to search for within this collection. /// - Returns: `true` if the collection contains the specified sequence, /// otherwise `false`. + @available(SwiftStdlib 5.7, *) public func contains(_ other: S) -> Bool where S.Element == Element { @@ -50,6 +51,7 @@ extension BidirectionalCollection where SubSequence == Substring { /// - Parameter regex: A regex to search for within this collection. /// - Returns: `true` if the regex was found in the collection, otherwise /// `false`. + @available(SwiftStdlib 5.7, *) public func contains(_ regex: R) -> Bool { contains(RegexConsumer(regex)) } diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/FirstRange.swift b/Sources/_StringProcessing/Algorithms/Algorithms/FirstRange.swift index 405fe47ef..e75cdbdc4 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/FirstRange.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/FirstRange.swift @@ -37,6 +37,7 @@ extension Collection where Element: Equatable { /// - Parameter sequence: The sequence to search for. /// - Returns: A range in the collection of the first occurrence of `sequence`. /// Returns nil if `sequence` is not found. + @available(SwiftStdlib 5.7, *) public func firstRange( of sequence: S ) -> Range? where S.Element == Element { @@ -52,6 +53,7 @@ extension BidirectionalCollection where Element: Comparable { /// - Parameter other: The sequence to search for. /// - Returns: A range in the collection of the first occurrence of `sequence`. /// Returns `nil` if `sequence` is not found. + @available(SwiftStdlib 5.7, *) public func firstRange( of other: S ) -> Range? where S.Element == Element { @@ -71,6 +73,7 @@ extension BidirectionalCollection where SubSequence == Substring { /// - Parameter regex: The regex to search for. /// - Returns: A range in the collection of the first occurrence of `regex`. /// Returns `nil` if `regex` is not found. + @available(SwiftStdlib 5.7, *) public func firstRange(of regex: R) -> Range? { firstRange(of: RegexConsumer(regex)) } diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/Replace.swift b/Sources/_StringProcessing/Algorithms/Algorithms/Replace.swift index bc23a284c..4a6da6c10 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/Replace.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/Replace.swift @@ -77,6 +77,7 @@ extension RangeReplaceableCollection where Element: Equatable { /// to replace. Default is `Int.max`. /// - Returns: A new collection in which all occurrences of `other` in /// `subrange` of the collection are replaced by `replacement`. + @available(SwiftStdlib 5.7, *) public func replacing( _ other: S, with replacement: Replacement, @@ -99,6 +100,7 @@ extension RangeReplaceableCollection where Element: Equatable { /// to replace. Default is `Int.max`. /// - Returns: A new collection in which all occurrences of `other` in /// `subrange` of the collection are replaced by `replacement`. + @available(SwiftStdlib 5.7, *) public func replacing( _ other: S, with replacement: Replacement, @@ -117,6 +119,7 @@ extension RangeReplaceableCollection where Element: Equatable { /// - replacement: The new elements to add to the collection. /// - maxReplacements: A number specifying how many occurrences of `other` /// to replace. Default is `Int.max`. + @available(SwiftStdlib 5.7, *) public mutating func replace( _ other: S, with replacement: Replacement, @@ -184,6 +187,7 @@ extension RangeReplaceableCollection where SubSequence == Substring { /// sequence matching `regex` to replace. Default is `Int.max`. /// - Returns: A new collection in which all occurrences of subsequence /// matching `regex` in `subrange` are replaced by `replacement`. + @available(SwiftStdlib 5.7, *) public func replacing( _ regex: R, with replacement: Replacement, @@ -206,6 +210,7 @@ extension RangeReplaceableCollection where SubSequence == Substring { /// sequence matching `regex` to replace. Default is `Int.max`. /// - Returns: A new collection in which all occurrences of subsequence /// matching `regex` are replaced by `replacement`. + @available(SwiftStdlib 5.7, *) public func replacing( _ regex: R, with replacement: Replacement, @@ -225,6 +230,7 @@ extension RangeReplaceableCollection where SubSequence == Substring { /// - replacement: The new elements to add to the collection. /// - maxReplacements: A number specifying how many occurrences of the /// sequence matching `regex` to replace. Default is `Int.max`. + @available(SwiftStdlib 5.7, *) public mutating func replace( _ regex: R, with replacement: Replacement, diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/StartsWith.swift b/Sources/_StringProcessing/Algorithms/Algorithms/StartsWith.swift index 346094f9e..01572fe49 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/StartsWith.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/StartsWith.swift @@ -53,6 +53,7 @@ extension BidirectionalCollection where SubSequence == Substring { /// - Parameter regex: A regex to compare to this sequence. /// - Returns: `true` if the initial elements of the sequence matches the /// beginning of `regex`; otherwise, `false`. + @available(SwiftStdlib 5.7, *) public func starts(with regex: R) -> Bool { starts(with: RegexConsumer(regex)) } diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/Trim.swift b/Sources/_StringProcessing/Algorithms/Algorithms/Trim.swift index ed7cd7bc4..fd0dbefdb 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/Trim.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/Trim.swift @@ -111,6 +111,7 @@ extension Collection { } extension Collection where SubSequence == Self { + @available(SwiftStdlib 5.7, *) public mutating func trimPrefix( while predicate: @escaping (Element) -> Bool ) { @@ -121,6 +122,7 @@ extension Collection where SubSequence == Self { extension RangeReplaceableCollection { @_disfavoredOverload + @available(SwiftStdlib 5.7, *) public mutating func trimPrefix( while predicate: @escaping (Element) -> Bool ) { @@ -185,6 +187,7 @@ extension Collection where Element: Equatable { /// element should be removed from the collection. /// - Returns: A collection containing the elements of the collection that are /// not removed by `predicate`. + @available(SwiftStdlib 5.7, *) public func trimmingPrefix( _ prefix: Prefix ) -> SubSequence where Prefix.Element == Element { @@ -198,6 +201,7 @@ extension Collection where SubSequence == Self, Element: Equatable { /// - Parameter predicate: A closure that takes an element of the sequence /// as its argument and returns a Boolean value indicating whether the /// element should be removed from the collection. + @available(SwiftStdlib 5.7, *) public mutating func trimPrefix( _ prefix: Prefix ) where Prefix.Element == Element { @@ -212,6 +216,7 @@ extension RangeReplaceableCollection where Element: Equatable { /// - Parameter predicate: A closure that takes an element of the sequence /// as its argument and returns a Boolean value indicating whether the /// element should be removed from the collection. + @available(SwiftStdlib 5.7, *) public mutating func trimPrefix( _ prefix: Prefix ) where Prefix.Element == Element { @@ -279,6 +284,7 @@ extension BidirectionalCollection where SubSequence == Substring { /// - Parameter prefix: The collection to remove from this collection. /// - Returns: A collection containing the elements that does not match /// `prefix` from the start. + @available(SwiftStdlib 5.7, *) public func trimmingPrefix(_ regex: R) -> SubSequence { trimmingPrefix(RegexConsumer(regex)) } @@ -297,6 +303,7 @@ extension RangeReplaceableCollection { /// Removes the initial elements that matches the given regex. /// - Parameter regex: The regex to remove from this collection. + @available(SwiftStdlib 5.7, *) public mutating func trimPrefix(_ regex: R) { trimPrefix(RegexConsumer(regex)) } diff --git a/Sources/_StringProcessing/Algorithms/Matching/MatchReplace.swift b/Sources/_StringProcessing/Algorithms/Matching/MatchReplace.swift index 74ab48839..82ca00797 100644 --- a/Sources/_StringProcessing/Algorithms/Matching/MatchReplace.swift +++ b/Sources/_StringProcessing/Algorithms/Matching/MatchReplace.swift @@ -122,6 +122,7 @@ extension RangeReplaceableCollection where SubSequence == Substring { /// sequence matching `regex` to replace. Default is `Int.max`. /// - Returns: A new collection in which all occurrences of subsequence /// matching `regex` are replaced by `replacement`. + @available(SwiftStdlib 5.7, *) public func replacing( _ regex: R, with replacement: (Regex.Match) throws -> Replacement, @@ -157,6 +158,7 @@ extension RangeReplaceableCollection where SubSequence == Substring { /// sequence matching `regex` to replace. Default is `Int.max`. /// - Returns: A new collection in which all occurrences of subsequence /// matching `regex` are replaced by `replacement`. + @available(SwiftStdlib 5.7, *) public func replacing( _ regex: R, with replacement: (Regex.Match) throws -> Replacement, @@ -177,6 +179,7 @@ extension RangeReplaceableCollection where SubSequence == Substring { /// including captures, and returns a replacement collection. /// - maxReplacements: A number specifying how many occurrences of the /// sequence matching `regex` to replace. Default is `Int.max`. + @available(SwiftStdlib 5.7, *) public mutating func replace( _ regex: R, with replacement: (Regex.Match) throws -> Replacement, diff --git a/Sources/_StringProcessing/Regex/AnyRegexOutput.swift b/Sources/_StringProcessing/Regex/AnyRegexOutput.swift index bd0fc47c9..ea9659faf 100644 --- a/Sources/_StringProcessing/Regex/AnyRegexOutput.swift +++ b/Sources/_StringProcessing/Regex/AnyRegexOutput.swift @@ -38,6 +38,7 @@ extension Regex.Match where Output == AnyRegexOutput { } /// A type-erased regex output +@available(SwiftStdlib 5.7, *) public struct AnyRegexOutput { let input: String fileprivate let _elements: [ElementRepresentation] diff --git a/Sources/_StringProcessing/Regex/Core.swift b/Sources/_StringProcessing/Regex/Core.swift index 96d0f3a68..b77ee7ece 100644 --- a/Sources/_StringProcessing/Regex/Core.swift +++ b/Sources/_StringProcessing/Regex/Core.swift @@ -13,6 +13,7 @@ import _RegexParser /// A type that represents a regular expression. +@available(SwiftStdlib 5.7, *) public protocol RegexComponent { associatedtype Output var regex: Regex { get } @@ -25,6 +26,7 @@ public protocol RegexComponent { /// print(match.0) // "axb" /// print(match.1) // "x" /// +@available(SwiftStdlib 5.7, *) public struct Regex: RegexComponent { let program: Program diff --git a/Sources/_StringProcessing/Regex/DSLConsumers.swift b/Sources/_StringProcessing/Regex/DSLConsumers.swift index 8d64f8355..8bca244c2 100644 --- a/Sources/_StringProcessing/Regex/DSLConsumers.swift +++ b/Sources/_StringProcessing/Regex/DSLConsumers.swift @@ -9,6 +9,7 @@ // //===----------------------------------------------------------------------===// +@available(SwiftStdlib 5.7, *) public protocol CustomRegexComponent: RegexComponent { func match( _ input: String, diff --git a/Sources/_StringProcessing/Regex/DSLTree.swift b/Sources/_StringProcessing/Regex/DSLTree.swift index f37505cb4..6ae4804e5 100644 --- a/Sources/_StringProcessing/Regex/DSLTree.swift +++ b/Sources/_StringProcessing/Regex/DSLTree.swift @@ -12,6 +12,7 @@ import _RegexParser @_spi(RegexBuilder) +@available(SwiftStdlib 5.7, *) public struct DSLTree { var root: Node var options: Options? @@ -162,6 +163,7 @@ extension DSLTree { // CollectionConsumer @_spi(RegexBuilder) +@available(SwiftStdlib 5.7, *) public typealias _ConsumerInterface = ( String, Range ) throws -> String.Index? @@ -169,12 +171,14 @@ public typealias _ConsumerInterface = ( // Type producing consume // TODO: better name @_spi(RegexBuilder) +@available(SwiftStdlib 5.7, *) public typealias _MatcherInterface = ( String, String.Index, Range ) throws -> (String.Index, Any)? // Character-set (post grapheme segmentation) @_spi(RegexBuilder) +@available(SwiftStdlib 5.7, *) public typealias _CharacterPredicateInterface = ( (Character) -> Bool ) @@ -375,6 +379,7 @@ extension DSLTree.Node { } @_spi(RegexBuilder) +@available(SwiftStdlib 5.7, *) public struct ReferenceID: Hashable, Equatable { private static var counter: Int = 0 var base: Int @@ -386,6 +391,7 @@ public struct ReferenceID: Hashable, Equatable { } @_spi(RegexBuilder) +@available(SwiftStdlib 5.7, *) public struct CaptureTransform: Hashable, CustomStringConvertible { public enum Closure { case failable((Substring) throws -> Any?) diff --git a/Sources/_StringProcessing/_CharacterClassModel.swift b/Sources/_StringProcessing/_CharacterClassModel.swift index e184689f1..0c45d2b6c 100644 --- a/Sources/_StringProcessing/_CharacterClassModel.swift +++ b/Sources/_StringProcessing/_CharacterClassModel.swift @@ -16,6 +16,7 @@ import _RegexParser // of parsing or to store in an AST @_spi(RegexBuilder) +@available(SwiftStdlib 5.7, *) public struct _CharacterClassModel: Hashable { /// The actual character class to match. var cc: Representation diff --git a/Tests/RegexBuilderTests/AlgorithmsTests.swift b/Tests/RegexBuilderTests/AlgorithmsTests.swift index 7625af385..fed584ff7 100644 --- a/Tests/RegexBuilderTests/AlgorithmsTests.swift +++ b/Tests/RegexBuilderTests/AlgorithmsTests.swift @@ -13,6 +13,7 @@ import XCTest import _StringProcessing @testable import RegexBuilder +@available(SwiftStdlib 5.7, *) class RegexConsumerTests: XCTestCase { // FIXME: enable this test when we update the return type of `matches(of:)` // when SE-0346 is available From f144abc08afcbe007d4e3e245658f138786f879e Mon Sep 17 00:00:00 2001 From: Nate Cook Date: Thu, 14 Apr 2022 18:16:41 -0500 Subject: [PATCH 09/17] Rename RegexComponent.Output (#281) --- .../Participants/RegexParticipant.swift | 2 +- Sources/RegexBuilder/Anchor.swift | 4 +- Sources/RegexBuilder/DSL.swift | 6 +- Sources/RegexBuilder/Match.swift | 8 +- Sources/RegexBuilder/Variadics.swift | 828 +++++++++--------- .../VariadicsGenerator.swift | 2 +- .../Algorithms/Consumers/RegexConsumer.swift | 2 +- .../Algorithms/Matching/FirstMatch.swift | 2 +- .../Algorithms/Matching/MatchReplace.swift | 6 +- .../Algorithms/Matching/Matches.swift | 4 +- Sources/_StringProcessing/Regex/Core.swift | 4 +- .../Regex/DSLConsumers.swift | 6 +- Sources/_StringProcessing/Regex/Match.swift | 8 +- Sources/_StringProcessing/Regex/Options.swift | 22 +- .../_CharacterClassModel.swift | 4 +- Tests/RegexBuilderTests/AlgorithmsTests.swift | 2 +- Tests/RegexBuilderTests/CustomTests.swift | 8 +- Tests/RegexBuilderTests/RegexDSLTests.swift | 24 +- 18 files changed, 471 insertions(+), 471 deletions(-) diff --git a/Sources/Exercises/Participants/RegexParticipant.swift b/Sources/Exercises/Participants/RegexParticipant.swift index 6fddc0914..6c53b3adf 100644 --- a/Sources/Exercises/Participants/RegexParticipant.swift +++ b/Sources/Exercises/Participants/RegexParticipant.swift @@ -62,7 +62,7 @@ private func extractFromCaptures( private func graphemeBreakPropertyData( forLine line: String, using regex: RP -) -> GraphemeBreakEntry? where RP.Output == (Substring, Substring, Substring?, Substring) { +) -> GraphemeBreakEntry? where RP.RegexOutput == (Substring, Substring, Substring?, Substring) { line.wholeMatch(of: regex).map(\.output).flatMap(extractFromCaptures) } diff --git a/Sources/RegexBuilder/Anchor.swift b/Sources/RegexBuilder/Anchor.swift index 7933b987a..50129b94d 100644 --- a/Sources/RegexBuilder/Anchor.swift +++ b/Sources/RegexBuilder/Anchor.swift @@ -119,7 +119,7 @@ public struct Lookahead: _BuiltinRegexComponent { public init( _ component: R, negative: Bool = false - ) where R.Output == Output { + ) where R.RegexOutput == Output { self.init(node: .nonCapturingGroup( negative ? .negativeLookahead : .lookahead, component.regex.root)) } @@ -127,7 +127,7 @@ public struct Lookahead: _BuiltinRegexComponent { public init( negative: Bool = false, @RegexComponentBuilder _ component: () -> R - ) where R.Output == Output { + ) where R.RegexOutput == Output { self.init(node: .nonCapturingGroup( negative ? .negativeLookahead : .lookahead, component().regex.root)) } diff --git a/Sources/RegexBuilder/DSL.swift b/Sources/RegexBuilder/DSL.swift index 717e172b0..28393bc1c 100644 --- a/Sources/RegexBuilder/DSL.swift +++ b/Sources/RegexBuilder/DSL.swift @@ -15,7 +15,7 @@ import _RegexParser extension Regex { public init( @RegexComponentBuilder _ content: () -> Content - ) where Content.Output == Output { + ) where Content.RegexOutput == Output { self = content().regex } } @@ -23,7 +23,7 @@ extension Regex { // A convenience protocol for builtin regex components that are initialized with // a `DSLTree` node. internal protocol _BuiltinRegexComponent: RegexComponent { - init(_ regex: Regex) + init(_ regex: Regex) } extension _BuiltinRegexComponent { @@ -190,7 +190,7 @@ public struct AlternationBuilder { @_disfavoredOverload public static func buildPartialBlock( first component: R - ) -> ChoiceOf { + ) -> ChoiceOf { .init(component.regex) } diff --git a/Sources/RegexBuilder/Match.swift b/Sources/RegexBuilder/Match.swift index 32dc889d9..1b4b3951b 100644 --- a/Sources/RegexBuilder/Match.swift +++ b/Sources/RegexBuilder/Match.swift @@ -15,14 +15,14 @@ extension String { @available(SwiftStdlib 5.7, *) public func wholeMatch( @RegexComponentBuilder of content: () -> R - ) -> Regex.Match? { + ) -> Regex.Match? { wholeMatch(of: content()) } @available(SwiftStdlib 5.7, *) public func prefixMatch( @RegexComponentBuilder of content: () -> R - ) -> Regex.Match? { + ) -> Regex.Match? { prefixMatch(of: content()) } } @@ -31,14 +31,14 @@ extension Substring { @available(SwiftStdlib 5.7, *) public func wholeMatch( @RegexComponentBuilder of content: () -> R - ) -> Regex.Match? { + ) -> Regex.Match? { wholeMatch(of: content()) } @available(SwiftStdlib 5.7, *) public func prefixMatch( @RegexComponentBuilder of content: () -> R - ) -> Regex.Match? { + ) -> Regex.Match? { prefixMatch(of: content()) } } diff --git a/Sources/RegexBuilder/Variadics.swift b/Sources/RegexBuilder/Variadics.swift index 2f4a6240a..e7bf02237 100644 --- a/Sources/RegexBuilder/Variadics.swift +++ b/Sources/RegexBuilder/Variadics.swift @@ -17,462 +17,462 @@ import _RegexParser extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0)> where R0.Output == W0, R1.Output == (W1, C0) { + ) -> Regex<(Substring, C0)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1)> where R0.Output == W0, R1.Output == (W1, C0, C1) { + ) -> Regex<(Substring, C0, C1)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2)> where R0.Output == W0, R1.Output == (W1, C0, C1, C2) { + ) -> Regex<(Substring, C0, C1, C2)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1, C2) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3)> where R0.Output == W0, R1.Output == (W1, C0, C1, C2, C3) { + ) -> Regex<(Substring, C0, C1, C2, C3)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1, C2, C3) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.Output == W0, R1.Output == (W1, C0, C1, C2, C3, C4) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1, C2, C3, C4) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.Output == W0, R1.Output == (W1, C0, C1, C2, C3, C4, C5) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.Output == W0, R1.Output == (W1, C0, C1, C2, C3, C4, C5, C6) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.Output == W0, R1.Output == (W1, C0, C1, C2, C3, C4, C5, C6, C7) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.Output == W0, R1.Output == (W1, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.Output == W0, R1.Output == (W1, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1)> where R0.Output == (W0, C0), R1.Output == (W1, C1) { + ) -> Regex<(Substring, C0, C1)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2)> where R0.Output == (W0, C0), R1.Output == (W1, C1, C2) { + ) -> Regex<(Substring, C0, C1, C2)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3)> where R0.Output == (W0, C0), R1.Output == (W1, C1, C2, C3) { + ) -> Regex<(Substring, C0, C1, C2, C3)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.Output == (W0, C0), R1.Output == (W1, C1, C2, C3, C4) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.Output == (W0, C0), R1.Output == (W1, C1, C2, C3, C4, C5) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.Output == (W0, C0), R1.Output == (W1, C1, C2, C3, C4, C5, C6) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.Output == (W0, C0), R1.Output == (W1, C1, C2, C3, C4, C5, C6, C7) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.Output == (W0, C0), R1.Output == (W1, C1, C2, C3, C4, C5, C6, C7, C8) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.Output == (W0, C0), R1.Output == (W1, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2)> where R0.Output == (W0, C0, C1), R1.Output == (W1, C2) { + ) -> Regex<(Substring, C0, C1, C2)> where R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3)> where R0.Output == (W0, C0, C1), R1.Output == (W1, C2, C3) { + ) -> Regex<(Substring, C0, C1, C2, C3)> where R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.Output == (W0, C0, C1), R1.Output == (W1, C2, C3, C4) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.Output == (W0, C0, C1), R1.Output == (W1, C2, C3, C4, C5) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.Output == (W0, C0, C1), R1.Output == (W1, C2, C3, C4, C5, C6) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.Output == (W0, C0, C1), R1.Output == (W1, C2, C3, C4, C5, C6, C7) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.Output == (W0, C0, C1), R1.Output == (W1, C2, C3, C4, C5, C6, C7, C8) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.Output == (W0, C0, C1), R1.Output == (W1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3)> where R0.Output == (W0, C0, C1, C2), R1.Output == (W1, C3) { + ) -> Regex<(Substring, C0, C1, C2, C3)> where R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.Output == (W0, C0, C1, C2), R1.Output == (W1, C3, C4) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.Output == (W0, C0, C1, C2), R1.Output == (W1, C3, C4, C5) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.Output == (W0, C0, C1, C2), R1.Output == (W1, C3, C4, C5, C6) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.Output == (W0, C0, C1, C2), R1.Output == (W1, C3, C4, C5, C6, C7) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.Output == (W0, C0, C1, C2), R1.Output == (W1, C3, C4, C5, C6, C7, C8) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.Output == (W0, C0, C1, C2), R1.Output == (W1, C3, C4, C5, C6, C7, C8, C9) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.Output == (W0, C0, C1, C2, C3), R1.Output == (W1, C4) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.Output == (W0, C0, C1, C2, C3), R1.Output == (W1, C4, C5) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.Output == (W0, C0, C1, C2, C3), R1.Output == (W1, C4, C5, C6) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5, C6) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.Output == (W0, C0, C1, C2, C3), R1.Output == (W1, C4, C5, C6, C7) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.Output == (W0, C0, C1, C2, C3), R1.Output == (W1, C4, C5, C6, C7, C8) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.Output == (W0, C0, C1, C2, C3), R1.Output == (W1, C4, C5, C6, C7, C8, C9) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.Output == (W0, C0, C1, C2, C3, C4), R1.Output == (W1, C5) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.Output == (W0, C0, C1, C2, C3, C4), R1.Output == (W1, C5, C6) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5, C6) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.Output == (W0, C0, C1, C2, C3, C4), R1.Output == (W1, C5, C6, C7) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5, C6, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.Output == (W0, C0, C1, C2, C3, C4), R1.Output == (W1, C5, C6, C7, C8) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.Output == (W0, C0, C1, C2, C3, C4), R1.Output == (W1, C5, C6, C7, C8, C9) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.Output == (W0, C0, C1, C2, C3, C4, C5), R1.Output == (W1, C6) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5), R1.RegexOutput == (W1, C6) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.Output == (W0, C0, C1, C2, C3, C4, C5), R1.Output == (W1, C6, C7) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5), R1.RegexOutput == (W1, C6, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.Output == (W0, C0, C1, C2, C3, C4, C5), R1.Output == (W1, C6, C7, C8) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5), R1.RegexOutput == (W1, C6, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.Output == (W0, C0, C1, C2, C3, C4, C5), R1.Output == (W1, C6, C7, C8, C9) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5), R1.RegexOutput == (W1, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6), R1.Output == (W1, C7) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6), R1.RegexOutput == (W1, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6), R1.Output == (W1, C7, C8) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6), R1.RegexOutput == (W1, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6), R1.Output == (W1, C7, C8, C9) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6), R1.RegexOutput == (W1, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6, C7), R1.Output == (W1, C8) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7), R1.RegexOutput == (W1, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6, C7), R1.Output == (W1, C8, C9) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7), R1.RegexOutput == (W1, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6, C7, C8), R1.Output == (W1, C9) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7, C8), R1.RegexOutput == (W1, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex where R0.Output == W0 { + ) -> Regex where R0.RegexOutput == W0 { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0)> where R0.Output == (W0, C0) { + ) -> Regex<(Substring, C0)> where R0.RegexOutput == (W0, C0) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1)> where R0.Output == (W0, C0, C1) { + ) -> Regex<(Substring, C0, C1)> where R0.RegexOutput == (W0, C0, C1) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2)> where R0.Output == (W0, C0, C1, C2) { + ) -> Regex<(Substring, C0, C1, C2)> where R0.RegexOutput == (W0, C0, C1, C2) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3)> where R0.Output == (W0, C0, C1, C2, C3) { + ) -> Regex<(Substring, C0, C1, C2, C3)> where R0.RegexOutput == (W0, C0, C1, C2, C3) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.Output == (W0, C0, C1, C2, C3, C4) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.Output == (W0, C0, C1, C2, C3, C4, C5) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6, C7) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } extension RegexComponentBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } @@ -483,7 +483,7 @@ extension Optionally { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == Substring { + ) where RegexOutput == Substring { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) } } @@ -493,7 +493,7 @@ extension Optionally { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == Substring { + ) where RegexOutput == Substring { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) } } @@ -510,7 +510,7 @@ extension ZeroOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == Substring { + ) where RegexOutput == Substring { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) } } @@ -520,7 +520,7 @@ extension ZeroOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == Substring { + ) where RegexOutput == Substring { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) } } @@ -531,7 +531,7 @@ extension OneOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == Substring { + ) where RegexOutput == Substring { self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) } } @@ -541,7 +541,7 @@ extension OneOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == Substring { + ) where RegexOutput == Substring { self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) } } @@ -552,7 +552,7 @@ extension Repeat { public init( _ component: Component, count: Int - ) where Output == Substring { + ) where RegexOutput == Substring { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) @@ -562,7 +562,7 @@ extension Repeat { public init( count: Int, @RegexComponentBuilder _ component: () -> Component - ) where Output == Substring { + ) where RegexOutput == Substring { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) @@ -573,7 +573,7 @@ extension Repeat { _ component: Component, _ expression: R, _ behavior: QuantificationBehavior = .eagerly - ) where Output == Substring, R.Bound == Int { + ) where RegexOutput == Substring, R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0.. Component - ) where Output == Substring, R.Bound == Int { + ) where RegexOutput == Substring, R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?), Component.Output == (W, C0) { + ) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) } } @@ -599,7 +599,7 @@ extension Optionally { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?), Component.Output == (W, C0) { + ) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) } } @@ -607,7 +607,7 @@ extension Optionally { extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component - ) -> Regex<(Substring, C0?)> where Component.Output == (W, C0) { + ) -> Regex<(Substring, C0?)> where Component.RegexOutput == (W, C0) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } @@ -615,7 +615,7 @@ extension ZeroOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?), Component.Output == (W, C0) { + ) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) } } @@ -624,7 +624,7 @@ extension ZeroOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?), Component.Output == (W, C0) { + ) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) } } @@ -634,7 +634,7 @@ extension OneOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0), Component.Output == (W, C0) { + ) where RegexOutput == (Substring, C0), Component.RegexOutput == (W, C0) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) } } @@ -643,7 +643,7 @@ extension OneOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0), Component.Output == (W, C0) { + ) where RegexOutput == (Substring, C0), Component.RegexOutput == (W, C0) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) } } @@ -653,7 +653,7 @@ extension Repeat { public init( _ component: Component, count: Int - ) where Output == (Substring, C0?), Component.Output == (W, C0) { + ) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) @@ -662,7 +662,7 @@ extension Repeat { public init( count: Int, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?), Component.Output == (W, C0) { + ) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) @@ -672,7 +672,7 @@ extension Repeat { _ component: Component, _ expression: R, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?), Component.Output == (W, C0), R.Bound == Int { + ) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0.. Component - ) where Output == (Substring, C0?), Component.Output == (W, C0), R.Bound == Int { + ) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?), Component.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) } } @@ -697,7 +697,7 @@ extension Optionally { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?), Component.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) } } @@ -705,7 +705,7 @@ extension Optionally { extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component - ) -> Regex<(Substring, C0?, C1?)> where Component.Output == (W, C0, C1) { + ) -> Regex<(Substring, C0?, C1?)> where Component.RegexOutput == (W, C0, C1) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } @@ -713,7 +713,7 @@ extension ZeroOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?), Component.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) } } @@ -722,7 +722,7 @@ extension ZeroOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?), Component.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) } } @@ -732,7 +732,7 @@ extension OneOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0, C1), Component.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, C0, C1), Component.RegexOutput == (W, C0, C1) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) } } @@ -741,7 +741,7 @@ extension OneOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1), Component.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, C0, C1), Component.RegexOutput == (W, C0, C1) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) } } @@ -751,7 +751,7 @@ extension Repeat { public init( _ component: Component, count: Int - ) where Output == (Substring, C0?, C1?), Component.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) @@ -760,7 +760,7 @@ extension Repeat { public init( count: Int, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?), Component.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) @@ -770,7 +770,7 @@ extension Repeat { _ component: Component, _ expression: R, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?), Component.Output == (W, C0, C1), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0.. Component - ) where Output == (Substring, C0?, C1?), Component.Output == (W, C0, C1), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?), Component.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) } } @@ -795,7 +795,7 @@ extension Optionally { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?), Component.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) } } @@ -803,7 +803,7 @@ extension Optionally { extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component - ) -> Regex<(Substring, C0?, C1?, C2?)> where Component.Output == (W, C0, C1, C2) { + ) -> Regex<(Substring, C0?, C1?, C2?)> where Component.RegexOutput == (W, C0, C1, C2) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } @@ -811,7 +811,7 @@ extension ZeroOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?), Component.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) } } @@ -820,7 +820,7 @@ extension ZeroOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?), Component.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) } } @@ -830,7 +830,7 @@ extension OneOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0, C1, C2), Component.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, C0, C1, C2), Component.RegexOutput == (W, C0, C1, C2) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) } } @@ -839,7 +839,7 @@ extension OneOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1, C2), Component.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, C0, C1, C2), Component.RegexOutput == (W, C0, C1, C2) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) } } @@ -849,7 +849,7 @@ extension Repeat { public init( _ component: Component, count: Int - ) where Output == (Substring, C0?, C1?, C2?), Component.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) @@ -858,7 +858,7 @@ extension Repeat { public init( count: Int, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?), Component.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) @@ -868,7 +868,7 @@ extension Repeat { _ component: Component, _ expression: R, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?), Component.Output == (W, C0, C1, C2), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0.. Component - ) where Output == (Substring, C0?, C1?, C2?), Component.Output == (W, C0, C1, C2), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?), Component.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) } } @@ -893,7 +893,7 @@ extension Optionally { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?), Component.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) } } @@ -901,7 +901,7 @@ extension Optionally { extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component - ) -> Regex<(Substring, C0?, C1?, C2?, C3?)> where Component.Output == (W, C0, C1, C2, C3) { + ) -> Regex<(Substring, C0?, C1?, C2?, C3?)> where Component.RegexOutput == (W, C0, C1, C2, C3) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } @@ -909,7 +909,7 @@ extension ZeroOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?), Component.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) } } @@ -918,7 +918,7 @@ extension ZeroOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?), Component.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) } } @@ -928,7 +928,7 @@ extension OneOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0, C1, C2, C3), Component.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, C0, C1, C2, C3), Component.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) } } @@ -937,7 +937,7 @@ extension OneOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1, C2, C3), Component.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, C0, C1, C2, C3), Component.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) } } @@ -947,7 +947,7 @@ extension Repeat { public init( _ component: Component, count: Int - ) where Output == (Substring, C0?, C1?, C2?, C3?), Component.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) @@ -956,7 +956,7 @@ extension Repeat { public init( count: Int, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?), Component.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) @@ -966,7 +966,7 @@ extension Repeat { _ component: Component, _ expression: R, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?), Component.Output == (W, C0, C1, C2, C3), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0.. Component - ) where Output == (Substring, C0?, C1?, C2?, C3?), Component.Output == (W, C0, C1, C2, C3), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?), Component.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) } } @@ -991,7 +991,7 @@ extension Optionally { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?), Component.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) } } @@ -999,7 +999,7 @@ extension Optionally { extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component - ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?)> where Component.Output == (W, C0, C1, C2, C3, C4) { + ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } @@ -1007,7 +1007,7 @@ extension ZeroOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?), Component.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) } } @@ -1016,7 +1016,7 @@ extension ZeroOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?), Component.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) } } @@ -1026,7 +1026,7 @@ extension OneOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0, C1, C2, C3, C4), Component.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) } } @@ -1035,7 +1035,7 @@ extension OneOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1, C2, C3, C4), Component.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) } } @@ -1045,7 +1045,7 @@ extension Repeat { public init( _ component: Component, count: Int - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?), Component.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) @@ -1054,7 +1054,7 @@ extension Repeat { public init( count: Int, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?), Component.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) @@ -1064,7 +1064,7 @@ extension Repeat { _ component: Component, _ expression: R, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?), Component.Output == (W, C0, C1, C2, C3, C4), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0.. Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?), Component.Output == (W, C0, C1, C2, C3, C4), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) } } @@ -1089,7 +1089,7 @@ extension Optionally { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) } } @@ -1097,7 +1097,7 @@ extension Optionally { extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component - ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?)> where Component.Output == (W, C0, C1, C2, C3, C4, C5) { + ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } @@ -1105,7 +1105,7 @@ extension ZeroOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) } } @@ -1114,7 +1114,7 @@ extension ZeroOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) } } @@ -1124,7 +1124,7 @@ extension OneOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0, C1, C2, C3, C4, C5), Component.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) } } @@ -1133,7 +1133,7 @@ extension OneOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1, C2, C3, C4, C5), Component.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) } } @@ -1143,7 +1143,7 @@ extension Repeat { public init( _ component: Component, count: Int - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) @@ -1152,7 +1152,7 @@ extension Repeat { public init( count: Int, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) @@ -1162,7 +1162,7 @@ extension Repeat { _ component: Component, _ expression: R, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.Output == (W, C0, C1, C2, C3, C4, C5), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0.. Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.Output == (W, C0, C1, C2, C3, C4, C5), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) } } @@ -1187,7 +1187,7 @@ extension Optionally { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) } } @@ -1195,7 +1195,7 @@ extension Optionally { extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component - ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?)> where Component.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } @@ -1203,7 +1203,7 @@ extension ZeroOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) } } @@ -1212,7 +1212,7 @@ extension ZeroOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) } } @@ -1222,7 +1222,7 @@ extension OneOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0, C1, C2, C3, C4, C5, C6), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) } } @@ -1231,7 +1231,7 @@ extension OneOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1, C2, C3, C4, C5, C6), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) } } @@ -1241,7 +1241,7 @@ extension Repeat { public init( _ component: Component, count: Int - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) @@ -1250,7 +1250,7 @@ extension Repeat { public init( count: Int, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) @@ -1260,7 +1260,7 @@ extension Repeat { _ component: Component, _ expression: R, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0.. Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) } } @@ -1285,7 +1285,7 @@ extension Optionally { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) } } @@ -1293,7 +1293,7 @@ extension Optionally { extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component - ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?)> where Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } @@ -1301,7 +1301,7 @@ extension ZeroOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) } } @@ -1310,7 +1310,7 @@ extension ZeroOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) } } @@ -1320,7 +1320,7 @@ extension OneOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0, C1, C2, C3, C4, C5, C6, C7), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) } } @@ -1329,7 +1329,7 @@ extension OneOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1, C2, C3, C4, C5, C6, C7), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) } } @@ -1339,7 +1339,7 @@ extension Repeat { public init( _ component: Component, count: Int - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) @@ -1348,7 +1348,7 @@ extension Repeat { public init( count: Int, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) @@ -1358,7 +1358,7 @@ extension Repeat { _ component: Component, _ expression: R, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0.. Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) } } @@ -1383,7 +1383,7 @@ extension Optionally { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) } } @@ -1391,7 +1391,7 @@ extension Optionally { extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component - ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?)> where Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } @@ -1399,7 +1399,7 @@ extension ZeroOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) } } @@ -1408,7 +1408,7 @@ extension ZeroOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) } } @@ -1418,7 +1418,7 @@ extension OneOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) } } @@ -1427,7 +1427,7 @@ extension OneOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) } } @@ -1437,7 +1437,7 @@ extension Repeat { public init( _ component: Component, count: Int - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) @@ -1446,7 +1446,7 @@ extension Repeat { public init( count: Int, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) @@ -1456,7 +1456,7 @@ extension Repeat { _ component: Component, _ expression: R, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0.. Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) } } @@ -1481,7 +1481,7 @@ extension Optionally { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) } } @@ -1489,7 +1489,7 @@ extension Optionally { extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component - ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } @@ -1497,7 +1497,7 @@ extension ZeroOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) } } @@ -1506,7 +1506,7 @@ extension ZeroOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) } } @@ -1516,7 +1516,7 @@ extension OneOrMore { public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) } } @@ -1525,7 +1525,7 @@ extension OneOrMore { public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) } } @@ -1535,7 +1535,7 @@ extension Repeat { public init( _ component: Component, count: Int - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) @@ -1544,7 +1544,7 @@ extension Repeat { public init( count: Int, @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) @@ -1554,7 +1554,7 @@ extension Repeat { _ component: Component, _ expression: R, _ behavior: QuantificationBehavior = .eagerly - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0.. Component - ) where Output == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Bound == Int { + ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component - ) where Output == Substring { + ) where RegexOutput == Substring { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component.regex.root)) } } @@ -1579,14 +1579,14 @@ extension Local { @_disfavoredOverload public init( @RegexComponentBuilder _ component: () -> Component - ) where Output == Substring { + ) where RegexOutput == Substring { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } extension Local { public init( _ component: Component - ) where Output == (Substring, C0), Component.Output == (W, C0) { + ) where RegexOutput == (Substring, C0), Component.RegexOutput == (W, C0) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component.regex.root)) } } @@ -1594,14 +1594,14 @@ extension Local { extension Local { public init( @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0), Component.Output == (W, C0) { + ) where RegexOutput == (Substring, C0), Component.RegexOutput == (W, C0) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } extension Local { public init( _ component: Component - ) where Output == (Substring, C0, C1), Component.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, C0, C1), Component.RegexOutput == (W, C0, C1) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component.regex.root)) } } @@ -1609,14 +1609,14 @@ extension Local { extension Local { public init( @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1), Component.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, C0, C1), Component.RegexOutput == (W, C0, C1) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } extension Local { public init( _ component: Component - ) where Output == (Substring, C0, C1, C2), Component.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, C0, C1, C2), Component.RegexOutput == (W, C0, C1, C2) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component.regex.root)) } } @@ -1624,14 +1624,14 @@ extension Local { extension Local { public init( @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1, C2), Component.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, C0, C1, C2), Component.RegexOutput == (W, C0, C1, C2) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } extension Local { public init( _ component: Component - ) where Output == (Substring, C0, C1, C2, C3), Component.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, C0, C1, C2, C3), Component.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component.regex.root)) } } @@ -1639,14 +1639,14 @@ extension Local { extension Local { public init( @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1, C2, C3), Component.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, C0, C1, C2, C3), Component.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } extension Local { public init( _ component: Component - ) where Output == (Substring, C0, C1, C2, C3, C4), Component.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component.regex.root)) } } @@ -1654,14 +1654,14 @@ extension Local { extension Local { public init( @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1, C2, C3, C4), Component.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } extension Local { public init( _ component: Component - ) where Output == (Substring, C0, C1, C2, C3, C4, C5), Component.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component.regex.root)) } } @@ -1669,14 +1669,14 @@ extension Local { extension Local { public init( @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1, C2, C3, C4, C5), Component.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } extension Local { public init( _ component: Component - ) where Output == (Substring, C0, C1, C2, C3, C4, C5, C6), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component.regex.root)) } } @@ -1684,14 +1684,14 @@ extension Local { extension Local { public init( @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1, C2, C3, C4, C5, C6), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } extension Local { public init( _ component: Component - ) where Output == (Substring, C0, C1, C2, C3, C4, C5, C6, C7), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component.regex.root)) } } @@ -1699,14 +1699,14 @@ extension Local { extension Local { public init( @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1, C2, C3, C4, C5, C6, C7), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } extension Local { public init( _ component: Component - ) where Output == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component.regex.root)) } } @@ -1714,14 +1714,14 @@ extension Local { extension Local { public init( @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } extension Local { public init( _ component: Component - ) where Output == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component.regex.root)) } } @@ -1729,7 +1729,7 @@ extension Local { extension Local { public init( @RegexComponentBuilder _ component: () -> Component - ) where Output == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), Component.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } @@ -1743,498 +1743,498 @@ extension AlternationBuilder { extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0?)> where R0: RegexComponent, R1: RegexComponent, R1.Output == (W1, C0) { + ) -> ChoiceOf<(Substring, C0?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0?, C1?)> where R0: RegexComponent, R1: RegexComponent, R1.Output == (W1, C0, C1) { + ) -> ChoiceOf<(Substring, C0?, C1?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0?, C1?, C2?)> where R0: RegexComponent, R1: RegexComponent, R1.Output == (W1, C0, C1, C2) { + ) -> ChoiceOf<(Substring, C0?, C1?, C2?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1, C2) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?)> where R0: RegexComponent, R1: RegexComponent, R1.Output == (W1, C0, C1, C2, C3) { + ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1, C2, C3) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?)> where R0: RegexComponent, R1: RegexComponent, R1.Output == (W1, C0, C1, C2, C3, C4) { + ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1, C2, C3, C4) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?, C5?)> where R0: RegexComponent, R1: RegexComponent, R1.Output == (W1, C0, C1, C2, C3, C4, C5) { + ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?, C5?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R1.Output == (W1, C0, C1, C2, C3, C4, C5, C6) { + ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R1.Output == (W1, C0, C1, C2, C3, C4, C5, C6, C7) { + ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R1.Output == (W1, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R1.Output == (W1, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0) { + ) -> ChoiceOf<(Substring, C0)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0), R1.Output == (W1, C1) { + ) -> ChoiceOf<(Substring, C0, C1?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1?, C2?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0), R1.Output == (W1, C1, C2) { + ) -> ChoiceOf<(Substring, C0, C1?, C2?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0), R1.Output == (W1, C1, C2, C3) { + ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0), R1.Output == (W1, C1, C2, C3, C4) { + ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?, C5?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0), R1.Output == (W1, C1, C2, C3, C4, C5) { + ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?, C5?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0), R1.Output == (W1, C1, C2, C3, C4, C5, C6) { + ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0), R1.Output == (W1, C1, C2, C3, C4, C5, C6, C7) { + ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0), R1.Output == (W1, C1, C2, C3, C4, C5, C6, C7, C8) { + ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0), R1.Output == (W1, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1) { + ) -> ChoiceOf<(Substring, C0, C1)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1), R1.Output == (W1, C2) { + ) -> ChoiceOf<(Substring, C0, C1, C2?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1), R1.Output == (W1, C2, C3) { + ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1), R1.Output == (W1, C2, C3, C4) { + ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?, C5?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1), R1.Output == (W1, C2, C3, C4, C5) { + ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?, C5?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1), R1.Output == (W1, C2, C3, C4, C5, C6) { + ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1), R1.Output == (W1, C2, C3, C4, C5, C6, C7) { + ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1), R1.Output == (W1, C2, C3, C4, C5, C6, C7, C8) { + ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1), R1.Output == (W1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2) { + ) -> ChoiceOf<(Substring, C0, C1, C2)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2), R1.Output == (W1, C3) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2), R1.Output == (W1, C3, C4) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?, C5?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2), R1.Output == (W1, C3, C4, C5) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?, C5?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2), R1.Output == (W1, C3, C4, C5, C6) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2), R1.Output == (W1, C3, C4, C5, C6, C7) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2), R1.Output == (W1, C3, C4, C5, C6, C7, C8) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2), R1.Output == (W1, C3, C4, C5, C6, C7, C8, C9) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3), R1.Output == (W1, C4) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?, C5?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3), R1.Output == (W1, C4, C5) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?, C5?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3), R1.Output == (W1, C4, C5, C6) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5, C6) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3), R1.Output == (W1, C4, C5, C6, C7) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3), R1.Output == (W1, C4, C5, C6, C7, C8) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3), R1.Output == (W1, C4, C5, C6, C7, C8, C9) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4), R1.Output == (W1, C5) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4), R1.Output == (W1, C5, C6) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5, C6) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4), R1.Output == (W1, C5, C6, C7) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5, C6, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4), R1.Output == (W1, C5, C6, C7, C8) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4), R1.Output == (W1, C5, C6, C7, C8, C9) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4, C5) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4, C5), R1.Output == (W1, C6) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5), R1.RegexOutput == (W1, C6) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4, C5), R1.Output == (W1, C6, C7) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5), R1.RegexOutput == (W1, C6, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4, C5), R1.Output == (W1, C6, C7, C8) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5), R1.RegexOutput == (W1, C6, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4, C5), R1.Output == (W1, C6, C7, C8, C9) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5), R1.RegexOutput == (W1, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6), R1.Output == (W1, C7) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6), R1.RegexOutput == (W1, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6), R1.Output == (W1, C7, C8) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6), R1.RegexOutput == (W1, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6), R1.Output == (W1, C7, C8, C9) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6), R1.RegexOutput == (W1, C7, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6, C7) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6, C7), R1.Output == (W1, C8) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7), R1.RegexOutput == (W1, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6, C7), R1.Output == (W1, C8, C9) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7), R1.RegexOutput == (W1, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { public static func buildPartialBlock( accumulated: R0, next: R1 - ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.Output == (W0, C0, C1, C2, C3, C4, C5, C6, C7, C8), R1.Output == (W1, C9) { + ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7, C8), R1.RegexOutput == (W1, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } extension AlternationBuilder { - public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?)> where R: RegexComponent, R.Output == (W, C0) { + public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?)> where R: RegexComponent, R.RegexOutput == (W, C0) { .init(node: .orderedChoice([regex.regex.root])) } } extension AlternationBuilder { - public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?)> where R: RegexComponent, R.Output == (W, C0, C1) { + public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1) { .init(node: .orderedChoice([regex.regex.root])) } } extension AlternationBuilder { - public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?)> where R: RegexComponent, R.Output == (W, C0, C1, C2) { + public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1, C2) { .init(node: .orderedChoice([regex.regex.root])) } } extension AlternationBuilder { - public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?)> where R: RegexComponent, R.Output == (W, C0, C1, C2, C3) { + public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1, C2, C3) { .init(node: .orderedChoice([regex.regex.root])) } } extension AlternationBuilder { - public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?)> where R: RegexComponent, R.Output == (W, C0, C1, C2, C3, C4) { + public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1, C2, C3, C4) { .init(node: .orderedChoice([regex.regex.root])) } } extension AlternationBuilder { - public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?, C5?)> where R: RegexComponent, R.Output == (W, C0, C1, C2, C3, C4, C5) { + public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?, C5?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { .init(node: .orderedChoice([regex.regex.root])) } } extension AlternationBuilder { - public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?, C5?, C6?)> where R: RegexComponent, R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?, C5?, C6?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { .init(node: .orderedChoice([regex.regex.root])) } } extension AlternationBuilder { - public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?)> where R: RegexComponent, R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { .init(node: .orderedChoice([regex.regex.root])) } } extension AlternationBuilder { - public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?)> where R: RegexComponent, R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { .init(node: .orderedChoice([regex.regex.root])) } } extension AlternationBuilder { - public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where R: RegexComponent, R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: .orderedChoice([regex.regex.root])) } } @@ -2244,14 +2244,14 @@ extension Capture { @_disfavoredOverload public init( _ component: R - ) where Output == (Substring, W), R.Output == W { + ) where RegexOutput == (Substring, W), R.RegexOutput == W { self.init(node: .capture(component.regex.root)) } @_disfavoredOverload public init( _ component: R, as reference: Reference - ) where Output == (Substring, W), R.Output == W { + ) where RegexOutput == (Substring, W), R.RegexOutput == W { self.init(node: .capture(reference: reference.id, component.regex.root)) } @@ -2259,7 +2259,7 @@ extension Capture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture), R.Output == W { + ) where RegexOutput == (Substring, NewCapture), R.RegexOutput == W { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -2272,7 +2272,7 @@ extension Capture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture), R.Output == W { + ) where RegexOutput == (Substring, NewCapture), R.RegexOutput == W { self.init(node: .capture( reference: reference.id, .transform( @@ -2288,7 +2288,7 @@ extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture), R.Output == W { + ) where RegexOutput == (Substring, NewCapture), R.RegexOutput == W { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -2301,7 +2301,7 @@ extension TryCapture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture), R.Output == W { + ) where RegexOutput == (Substring, NewCapture), R.RegexOutput == W { self.init(node: .capture( reference: reference.id, .transform( @@ -2318,7 +2318,7 @@ extension Capture { @_disfavoredOverload public init( @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W), R.Output == W { + ) where RegexOutput == (Substring, W), R.RegexOutput == W { self.init(node: .capture(component().regex.root)) } @@ -2326,7 +2326,7 @@ extension Capture { public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W), R.Output == W { + ) where RegexOutput == (Substring, W), R.RegexOutput == W { self.init(node: .capture( reference: reference.id, component().regex.root)) @@ -2336,7 +2336,7 @@ extension Capture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture), R.Output == W { + ) where RegexOutput == (Substring, NewCapture), R.RegexOutput == W { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -2349,7 +2349,7 @@ extension Capture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture), R.Output == W { + ) where RegexOutput == (Substring, NewCapture), R.RegexOutput == W { self.init(node: .capture( reference: reference.id, .transform( @@ -2365,7 +2365,7 @@ extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture), R.Output == W { + ) where RegexOutput == (Substring, NewCapture), R.RegexOutput == W { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -2378,7 +2378,7 @@ extension TryCapture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture), R.Output == W { + ) where RegexOutput == (Substring, NewCapture), R.RegexOutput == W { self.init(node: .capture( reference: reference.id, .transform( @@ -2394,20 +2394,20 @@ extension TryCapture { extension Capture { public init( _ component: R - ) where Output == (Substring, W, C0), R.Output == (W, C0) { + ) where RegexOutput == (Substring, W, C0), R.RegexOutput == (W, C0) { self.init(node: .capture(component.regex.root)) } public init( _ component: R, as reference: Reference - ) where Output == (Substring, W, C0), R.Output == (W, C0) { + ) where RegexOutput == (Substring, W, C0), R.RegexOutput == (W, C0) { self.init(node: .capture(reference: reference.id, component.regex.root)) } public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0), R.Output == (W, C0) { + ) where RegexOutput == (Substring, NewCapture, C0), R.RegexOutput == (W, C0) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -2419,7 +2419,7 @@ extension Capture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0), R.Output == (W, C0) { + ) where RegexOutput == (Substring, NewCapture, C0), R.RegexOutput == (W, C0) { self.init(node: .capture( reference: reference.id, .transform( @@ -2434,7 +2434,7 @@ extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0), R.Output == (W, C0) { + ) where RegexOutput == (Substring, NewCapture, C0), R.RegexOutput == (W, C0) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -2446,7 +2446,7 @@ extension TryCapture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0), R.Output == (W, C0) { + ) where RegexOutput == (Substring, NewCapture, C0), R.RegexOutput == (W, C0) { self.init(node: .capture( reference: reference.id, .transform( @@ -2462,14 +2462,14 @@ extension TryCapture { extension Capture { public init( @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0), R.Output == (W, C0) { + ) where RegexOutput == (Substring, W, C0), R.RegexOutput == (W, C0) { self.init(node: .capture(component().regex.root)) } public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0), R.Output == (W, C0) { + ) where RegexOutput == (Substring, W, C0), R.RegexOutput == (W, C0) { self.init(node: .capture( reference: reference.id, component().regex.root)) @@ -2478,7 +2478,7 @@ extension Capture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0), R.Output == (W, C0) { + ) where RegexOutput == (Substring, NewCapture, C0), R.RegexOutput == (W, C0) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -2490,7 +2490,7 @@ extension Capture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0), R.Output == (W, C0) { + ) where RegexOutput == (Substring, NewCapture, C0), R.RegexOutput == (W, C0) { self.init(node: .capture( reference: reference.id, .transform( @@ -2505,7 +2505,7 @@ extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0), R.Output == (W, C0) { + ) where RegexOutput == (Substring, NewCapture, C0), R.RegexOutput == (W, C0) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -2517,7 +2517,7 @@ extension TryCapture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0), R.Output == (W, C0) { + ) where RegexOutput == (Substring, NewCapture, C0), R.RegexOutput == (W, C0) { self.init(node: .capture( reference: reference.id, .transform( @@ -2533,20 +2533,20 @@ extension TryCapture { extension Capture { public init( _ component: R - ) where Output == (Substring, W, C0, C1), R.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, W, C0, C1), R.RegexOutput == (W, C0, C1) { self.init(node: .capture(component.regex.root)) } public init( _ component: R, as reference: Reference - ) where Output == (Substring, W, C0, C1), R.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, W, C0, C1), R.RegexOutput == (W, C0, C1) { self.init(node: .capture(reference: reference.id, component.regex.root)) } public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1), R.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, NewCapture, C0, C1), R.RegexOutput == (W, C0, C1) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -2558,7 +2558,7 @@ extension Capture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1), R.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, NewCapture, C0, C1), R.RegexOutput == (W, C0, C1) { self.init(node: .capture( reference: reference.id, .transform( @@ -2573,7 +2573,7 @@ extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1), R.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, NewCapture, C0, C1), R.RegexOutput == (W, C0, C1) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -2585,7 +2585,7 @@ extension TryCapture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1), R.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, NewCapture, C0, C1), R.RegexOutput == (W, C0, C1) { self.init(node: .capture( reference: reference.id, .transform( @@ -2601,14 +2601,14 @@ extension TryCapture { extension Capture { public init( @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1), R.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, W, C0, C1), R.RegexOutput == (W, C0, C1) { self.init(node: .capture(component().regex.root)) } public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1), R.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, W, C0, C1), R.RegexOutput == (W, C0, C1) { self.init(node: .capture( reference: reference.id, component().regex.root)) @@ -2617,7 +2617,7 @@ extension Capture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1), R.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, NewCapture, C0, C1), R.RegexOutput == (W, C0, C1) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -2629,7 +2629,7 @@ extension Capture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1), R.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, NewCapture, C0, C1), R.RegexOutput == (W, C0, C1) { self.init(node: .capture( reference: reference.id, .transform( @@ -2644,7 +2644,7 @@ extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1), R.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, NewCapture, C0, C1), R.RegexOutput == (W, C0, C1) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -2656,7 +2656,7 @@ extension TryCapture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1), R.Output == (W, C0, C1) { + ) where RegexOutput == (Substring, NewCapture, C0, C1), R.RegexOutput == (W, C0, C1) { self.init(node: .capture( reference: reference.id, .transform( @@ -2672,20 +2672,20 @@ extension TryCapture { extension Capture { public init( _ component: R - ) where Output == (Substring, W, C0, C1, C2), R.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, W, C0, C1, C2), R.RegexOutput == (W, C0, C1, C2) { self.init(node: .capture(component.regex.root)) } public init( _ component: R, as reference: Reference - ) where Output == (Substring, W, C0, C1, C2), R.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, W, C0, C1, C2), R.RegexOutput == (W, C0, C1, C2) { self.init(node: .capture(reference: reference.id, component.regex.root)) } public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2), R.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2), R.RegexOutput == (W, C0, C1, C2) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -2697,7 +2697,7 @@ extension Capture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2), R.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2), R.RegexOutput == (W, C0, C1, C2) { self.init(node: .capture( reference: reference.id, .transform( @@ -2712,7 +2712,7 @@ extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2), R.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2), R.RegexOutput == (W, C0, C1, C2) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -2724,7 +2724,7 @@ extension TryCapture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2), R.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2), R.RegexOutput == (W, C0, C1, C2) { self.init(node: .capture( reference: reference.id, .transform( @@ -2740,14 +2740,14 @@ extension TryCapture { extension Capture { public init( @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1, C2), R.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, W, C0, C1, C2), R.RegexOutput == (W, C0, C1, C2) { self.init(node: .capture(component().regex.root)) } public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1, C2), R.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, W, C0, C1, C2), R.RegexOutput == (W, C0, C1, C2) { self.init(node: .capture( reference: reference.id, component().regex.root)) @@ -2756,7 +2756,7 @@ extension Capture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2), R.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2), R.RegexOutput == (W, C0, C1, C2) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -2768,7 +2768,7 @@ extension Capture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2), R.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2), R.RegexOutput == (W, C0, C1, C2) { self.init(node: .capture( reference: reference.id, .transform( @@ -2783,7 +2783,7 @@ extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2), R.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2), R.RegexOutput == (W, C0, C1, C2) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -2795,7 +2795,7 @@ extension TryCapture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2), R.Output == (W, C0, C1, C2) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2), R.RegexOutput == (W, C0, C1, C2) { self.init(node: .capture( reference: reference.id, .transform( @@ -2811,20 +2811,20 @@ extension TryCapture { extension Capture { public init( _ component: R - ) where Output == (Substring, W, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3), R.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .capture(component.regex.root)) } public init( _ component: R, as reference: Reference - ) where Output == (Substring, W, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3), R.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .capture(reference: reference.id, component.regex.root)) } public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3), R.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -2836,7 +2836,7 @@ extension Capture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3), R.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .capture( reference: reference.id, .transform( @@ -2851,7 +2851,7 @@ extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3), R.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -2863,7 +2863,7 @@ extension TryCapture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3), R.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .capture( reference: reference.id, .transform( @@ -2879,14 +2879,14 @@ extension TryCapture { extension Capture { public init( @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3), R.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .capture(component().regex.root)) } public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3), R.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .capture( reference: reference.id, component().regex.root)) @@ -2895,7 +2895,7 @@ extension Capture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3), R.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -2907,7 +2907,7 @@ extension Capture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3), R.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .capture( reference: reference.id, .transform( @@ -2922,7 +2922,7 @@ extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3), R.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -2934,7 +2934,7 @@ extension TryCapture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3), R.Output == (W, C0, C1, C2, C3) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3), R.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .capture( reference: reference.id, .transform( @@ -2950,20 +2950,20 @@ extension TryCapture { extension Capture { public init( _ component: R - ) where Output == (Substring, W, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4), R.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .capture(component.regex.root)) } public init( _ component: R, as reference: Reference - ) where Output == (Substring, W, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4), R.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .capture(reference: reference.id, component.regex.root)) } public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4), R.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -2975,7 +2975,7 @@ extension Capture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4), R.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .capture( reference: reference.id, .transform( @@ -2990,7 +2990,7 @@ extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4), R.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -3002,7 +3002,7 @@ extension TryCapture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4), R.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .capture( reference: reference.id, .transform( @@ -3018,14 +3018,14 @@ extension TryCapture { extension Capture { public init( @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4), R.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .capture(component().regex.root)) } public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4), R.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .capture( reference: reference.id, component().regex.root)) @@ -3034,7 +3034,7 @@ extension Capture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4), R.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -3046,7 +3046,7 @@ extension Capture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4), R.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .capture( reference: reference.id, .transform( @@ -3061,7 +3061,7 @@ extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4), R.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -3073,7 +3073,7 @@ extension TryCapture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4), R.Output == (W, C0, C1, C2, C3, C4) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4), R.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .capture( reference: reference.id, .transform( @@ -3089,20 +3089,20 @@ extension TryCapture { extension Capture { public init( _ component: R - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture(component.regex.root)) } public init( _ component: R, as reference: Reference - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture(reference: reference.id, component.regex.root)) } public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -3114,7 +3114,7 @@ extension Capture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture( reference: reference.id, .transform( @@ -3129,7 +3129,7 @@ extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -3141,7 +3141,7 @@ extension TryCapture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture( reference: reference.id, .transform( @@ -3157,14 +3157,14 @@ extension TryCapture { extension Capture { public init( @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture(component().regex.root)) } public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture( reference: reference.id, component().regex.root)) @@ -3173,7 +3173,7 @@ extension Capture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -3185,7 +3185,7 @@ extension Capture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture( reference: reference.id, .transform( @@ -3200,7 +3200,7 @@ extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -3212,7 +3212,7 @@ extension TryCapture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.Output == (W, C0, C1, C2, C3, C4, C5) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture( reference: reference.id, .transform( @@ -3228,20 +3228,20 @@ extension TryCapture { extension Capture { public init( _ component: R - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture(component.regex.root)) } public init( _ component: R, as reference: Reference - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture(reference: reference.id, component.regex.root)) } public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -3253,7 +3253,7 @@ extension Capture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture( reference: reference.id, .transform( @@ -3268,7 +3268,7 @@ extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -3280,7 +3280,7 @@ extension TryCapture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture( reference: reference.id, .transform( @@ -3296,14 +3296,14 @@ extension TryCapture { extension Capture { public init( @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture(component().regex.root)) } public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture( reference: reference.id, component().regex.root)) @@ -3312,7 +3312,7 @@ extension Capture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -3324,7 +3324,7 @@ extension Capture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture( reference: reference.id, .transform( @@ -3339,7 +3339,7 @@ extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -3351,7 +3351,7 @@ extension TryCapture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.Output == (W, C0, C1, C2, C3, C4, C5, C6) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture( reference: reference.id, .transform( @@ -3367,20 +3367,20 @@ extension TryCapture { extension Capture { public init( _ component: R - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture(component.regex.root)) } public init( _ component: R, as reference: Reference - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture(reference: reference.id, component.regex.root)) } public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -3392,7 +3392,7 @@ extension Capture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture( reference: reference.id, .transform( @@ -3407,7 +3407,7 @@ extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -3419,7 +3419,7 @@ extension TryCapture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture( reference: reference.id, .transform( @@ -3435,14 +3435,14 @@ extension TryCapture { extension Capture { public init( @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture(component().regex.root)) } public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture( reference: reference.id, component().regex.root)) @@ -3451,7 +3451,7 @@ extension Capture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -3463,7 +3463,7 @@ extension Capture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture( reference: reference.id, .transform( @@ -3478,7 +3478,7 @@ extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -3490,7 +3490,7 @@ extension TryCapture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture( reference: reference.id, .transform( @@ -3506,20 +3506,20 @@ extension TryCapture { extension Capture { public init( _ component: R - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture(component.regex.root)) } public init( _ component: R, as reference: Reference - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture(reference: reference.id, component.regex.root)) } public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -3531,7 +3531,7 @@ extension Capture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture( reference: reference.id, .transform( @@ -3546,7 +3546,7 @@ extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -3558,7 +3558,7 @@ extension TryCapture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture( reference: reference.id, .transform( @@ -3574,14 +3574,14 @@ extension TryCapture { extension Capture { public init( @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture(component().regex.root)) } public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture( reference: reference.id, component().regex.root)) @@ -3590,7 +3590,7 @@ extension Capture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -3602,7 +3602,7 @@ extension Capture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture( reference: reference.id, .transform( @@ -3617,7 +3617,7 @@ extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -3629,7 +3629,7 @@ extension TryCapture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture( reference: reference.id, .transform( @@ -3645,20 +3645,20 @@ extension TryCapture { extension Capture { public init( _ component: R - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture(component.regex.root)) } public init( _ component: R, as reference: Reference - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture(reference: reference.id, component.regex.root)) } public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -3670,7 +3670,7 @@ extension Capture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture( reference: reference.id, .transform( @@ -3685,7 +3685,7 @@ extension TryCapture { public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -3697,7 +3697,7 @@ extension TryCapture { _ component: R, as reference: Reference, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture( reference: reference.id, .transform( @@ -3713,14 +3713,14 @@ extension TryCapture { extension Capture { public init( @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture(component().regex.root)) } public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R - ) where Output == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture( reference: reference.id, component().regex.root)) @@ -3729,7 +3729,7 @@ extension Capture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any @@ -3741,7 +3741,7 @@ extension Capture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture( reference: reference.id, .transform( @@ -3756,7 +3756,7 @@ extension TryCapture { public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture(.transform( CaptureTransform(resultType: NewCapture.self) { try transform($0) as Any? @@ -3768,7 +3768,7 @@ extension TryCapture { as reference: Reference, @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? - ) where Output == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Output == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { + ) where RegexOutput == (Substring, NewCapture, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture( reference: reference.id, .transform( diff --git a/Sources/VariadicsGenerator/VariadicsGenerator.swift b/Sources/VariadicsGenerator/VariadicsGenerator.swift index 5fbd2bf2d..1a0742f20 100644 --- a/Sources/VariadicsGenerator/VariadicsGenerator.swift +++ b/Sources/VariadicsGenerator/VariadicsGenerator.swift @@ -90,7 +90,7 @@ var standardError = StandardErrorStream() typealias Counter = Int64 let regexComponentProtocolName = "RegexComponent" -let outputAssociatedTypeName = "Output" +let outputAssociatedTypeName = "RegexOutput" let patternProtocolRequirementName = "regex" let regexTypeName = "Regex" let baseMatchTypeName = "Substring" diff --git a/Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift b/Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift index 2718d520a..81f3ebb3e 100644 --- a/Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift +++ b/Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift @@ -37,7 +37,7 @@ extension RegexConsumer { // well, taking advantage of the fact that the captures can be ignored extension RegexConsumer: MatchingCollectionConsumer { - typealias Match = R.Output + typealias Match = R.RegexOutput func matchingConsuming( _ consumed: Consumed, in range: Range diff --git a/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift b/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift index 1ad555e7d..093a47b71 100644 --- a/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift +++ b/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift @@ -56,7 +56,7 @@ extension BidirectionalCollection where SubSequence == Substring { /// there isn't a match. public func firstMatch( of r: R - ) -> Regex.Match? { + ) -> Regex.Match? { let slice = self[...] return try? r.regex.firstMatch(in: slice.base) } diff --git a/Sources/_StringProcessing/Algorithms/Matching/MatchReplace.swift b/Sources/_StringProcessing/Algorithms/Matching/MatchReplace.swift index 82ca00797..461c08e02 100644 --- a/Sources/_StringProcessing/Algorithms/Matching/MatchReplace.swift +++ b/Sources/_StringProcessing/Algorithms/Matching/MatchReplace.swift @@ -125,7 +125,7 @@ extension RangeReplaceableCollection where SubSequence == Substring { @available(SwiftStdlib 5.7, *) public func replacing( _ regex: R, - with replacement: (Regex.Match) throws -> Replacement, + with replacement: (Regex.Match) throws -> Replacement, subrange: Range, maxReplacements: Int = .max ) rethrows -> Self where Replacement.Element == Element { @@ -161,7 +161,7 @@ extension RangeReplaceableCollection where SubSequence == Substring { @available(SwiftStdlib 5.7, *) public func replacing( _ regex: R, - with replacement: (Regex.Match) throws -> Replacement, + with replacement: (Regex.Match) throws -> Replacement, maxReplacements: Int = .max ) rethrows -> Self where Replacement.Element == Element { try replacing( @@ -182,7 +182,7 @@ extension RangeReplaceableCollection where SubSequence == Substring { @available(SwiftStdlib 5.7, *) public mutating func replace( _ regex: R, - with replacement: (Regex.Match) throws -> Replacement, + with replacement: (Regex.Match) throws -> Replacement, maxReplacements: Int = .max ) rethrows where Replacement.Element == Element { self = try replacing( diff --git a/Sources/_StringProcessing/Algorithms/Matching/Matches.swift b/Sources/_StringProcessing/Algorithms/Matching/Matches.swift index 24cdbee0f..484737f05 100644 --- a/Sources/_StringProcessing/Algorithms/Matching/Matches.swift +++ b/Sources/_StringProcessing/Algorithms/Matching/Matches.swift @@ -202,13 +202,13 @@ extension BidirectionalCollection where SubSequence == Substring { // FIXME: Replace the returned value as `some Collection.Match> // when SE-0346 is enabled - func _matches(of r: R) -> [Regex.Match] { + func _matches(of r: R) -> [Regex.Match] { let slice = self[...] var start = self.startIndex let end = self.endIndex let regex = r.regex - var result = [Regex.Match]() + var result = [Regex.Match]() while start < end { guard let match = try? regex._firstMatch( slice.base, in: start.. { get } + associatedtype RegexOutput + var regex: Regex { get } } /// A regex represents a string processing algorithm. diff --git a/Sources/_StringProcessing/Regex/DSLConsumers.swift b/Sources/_StringProcessing/Regex/DSLConsumers.swift index 8bca244c2..c3dc6d88c 100644 --- a/Sources/_StringProcessing/Regex/DSLConsumers.swift +++ b/Sources/_StringProcessing/Regex/DSLConsumers.swift @@ -15,12 +15,12 @@ public protocol CustomRegexComponent: RegexComponent { _ input: String, startingAt index: String.Index, in bounds: Range - ) -> (upperBound: String.Index, output: Output)? + ) -> (upperBound: String.Index, output: RegexOutput)? } extension CustomRegexComponent { - public var regex: Regex { - Regex(node: .matcher(.init(Output.self), { input, index, bounds in + public var regex: Regex { + Regex(node: .matcher(.init(RegexOutput.self), { input, index, bounds in match(input, startingAt: index, in: bounds) })) } diff --git a/Sources/_StringProcessing/Regex/Match.swift b/Sources/_StringProcessing/Regex/Match.swift index 8b37837e6..73ae62b7e 100644 --- a/Sources/_StringProcessing/Regex/Match.swift +++ b/Sources/_StringProcessing/Regex/Match.swift @@ -155,24 +155,24 @@ extension Regex { extension String { public func wholeMatch( of r: R - ) -> Regex.Match? { + ) -> Regex.Match? { try? r.regex.wholeMatch(in: self) } public func prefixMatch( of r: R - ) -> Regex.Match? { + ) -> Regex.Match? { try? r.regex.prefixMatch(in: self) } } extension Substring { public func wholeMatch( of r: R - ) -> Regex.Match? { + ) -> Regex.Match? { try? r.regex.wholeMatch(in: self) } public func prefixMatch( of r: R - ) -> Regex.Match? { + ) -> Regex.Match? { try? r.regex.prefixMatch(in: self) } } diff --git a/Sources/_StringProcessing/Regex/Options.swift b/Sources/_StringProcessing/Regex/Options.swift index 38fba02d6..3131bd89a 100644 --- a/Sources/_StringProcessing/Regex/Options.swift +++ b/Sources/_StringProcessing/Regex/Options.swift @@ -13,30 +13,30 @@ import _RegexParser extension RegexComponent { /// Returns a regular expression that ignores casing when matching. - public func ignoringCase(_ ignoreCase: Bool = true) -> Regex { + public func ignoringCase(_ ignoreCase: Bool = true) -> Regex { wrapInOption(.caseInsensitive, addingIf: ignoreCase) } /// Returns a regular expression that only matches ASCII characters as "word /// characters". - public func usingASCIIWordCharacters(_ useASCII: Bool = true) -> Regex { + public func usingASCIIWordCharacters(_ useASCII: Bool = true) -> Regex { wrapInOption(.asciiOnlyDigit, addingIf: useASCII) } /// Returns a regular expression that only matches ASCII characters as digits. - public func usingASCIIDigits(_ useASCII: Bool = true) -> Regex { + public func usingASCIIDigits(_ useASCII: Bool = true) -> Regex { wrapInOption(.asciiOnlyDigit, addingIf: useASCII) } /// Returns a regular expression that only matches ASCII characters as space /// characters. - public func usingASCIISpaces(_ useASCII: Bool = true) -> Regex { + public func usingASCIISpaces(_ useASCII: Bool = true) -> Regex { wrapInOption(.asciiOnlySpace, addingIf: useASCII) } /// Returns a regular expression that only matches ASCII characters when /// matching character classes. - public func usingASCIICharacterClasses(_ useASCII: Bool = true) -> Regex { + public func usingASCIICharacterClasses(_ useASCII: Bool = true) -> Regex { wrapInOption(.asciiOnlyPOSIXProps, addingIf: useASCII) } @@ -45,7 +45,7 @@ extension RegexComponent { /// /// This option is enabled by default; pass `false` to disable use of /// Unicode's word boundary algorithm. - public func usingUnicodeWordBoundaries(_ useUnicodeWordBoundaries: Bool = true) -> Regex { + public func usingUnicodeWordBoundaries(_ useUnicodeWordBoundaries: Bool = true) -> Regex { wrapInOption(.unicodeWordBoundaries, addingIf: useUnicodeWordBoundaries) } @@ -54,7 +54,7 @@ extension RegexComponent { /// /// - Parameter dotMatchesNewlines: A Boolean value indicating whether `.` /// should match a newline character. - public func dotMatchesNewlines(_ dotMatchesNewlines: Bool = true) -> Regex { + public func dotMatchesNewlines(_ dotMatchesNewlines: Bool = true) -> Regex { wrapInOption(.singleLine, addingIf: dotMatchesNewlines) } @@ -95,7 +95,7 @@ extension RegexComponent { /// // Prints "true" /// print(decomposed.contains(queRegexScalar)) /// // Prints "false" - public func matchingSemantics(_ semanticLevel: RegexSemanticLevel) -> Regex { + public func matchingSemantics(_ semanticLevel: RegexSemanticLevel) -> Regex { switch semanticLevel.base { case .graphemeCluster: return wrapInOption(.graphemeClusterSemantics, addingIf: true) @@ -139,7 +139,7 @@ extension RegexComponent { /// /// - Parameter matchLineEndings: A Boolean value indicating whether `^` and /// `$` should match the start and end of lines, respectively. - public func anchorsMatchLineEndings(_ matchLineEndings: Bool = true) -> Regex { + public func anchorsMatchLineEndings(_ matchLineEndings: Bool = true) -> Regex { wrapInOption(.multiline, addingIf: matchLineEndings) } @@ -153,7 +153,7 @@ extension RegexComponent { /// /// - Parameter useReluctantCaptures: A Boolean value indicating whether /// quantifiers should be reluctant by default. - public func reluctantCaptures(_ useReluctantCaptures: Bool = true) -> Regex { + public func reluctantCaptures(_ useReluctantCaptures: Bool = true) -> Regex { wrapInOption(.reluctantByDefault, addingIf: useReluctantCaptures) } } @@ -162,7 +162,7 @@ extension RegexComponent { extension RegexComponent { fileprivate func wrapInOption( _ option: AST.MatchingOption.Kind, - addingIf shouldAdd: Bool) -> Regex + addingIf shouldAdd: Bool) -> Regex { let sequence = shouldAdd ? AST.MatchingOptionSequence(adding: [.init(option, location: .fake)]) diff --git a/Sources/_StringProcessing/_CharacterClassModel.swift b/Sources/_StringProcessing/_CharacterClassModel.swift index 0c45d2b6c..e63423f8f 100644 --- a/Sources/_StringProcessing/_CharacterClassModel.swift +++ b/Sources/_StringProcessing/_CharacterClassModel.swift @@ -206,9 +206,9 @@ public struct _CharacterClassModel: Hashable { } extension _CharacterClassModel: RegexComponent { - public typealias Output = Substring + public typealias RegexOutput = Substring - public var regex: Regex { + public var regex: Regex { guard let ast = self.makeAST() else { fatalError("FIXME: extended AST?") } diff --git a/Tests/RegexBuilderTests/AlgorithmsTests.swift b/Tests/RegexBuilderTests/AlgorithmsTests.swift index fed584ff7..cf117690a 100644 --- a/Tests/RegexBuilderTests/AlgorithmsTests.swift +++ b/Tests/RegexBuilderTests/AlgorithmsTests.swift @@ -28,7 +28,7 @@ class RegexConsumerTests: XCTestCase { _ regex: R, input: String, result: String, - _ replace: (Regex.Match) -> String, + _ replace: (Regex.Match) -> String, file: StaticString = #file, line: UInt = #line ) { diff --git a/Tests/RegexBuilderTests/CustomTests.swift b/Tests/RegexBuilderTests/CustomTests.swift index 555ecb8ca..0ac6b46c5 100644 --- a/Tests/RegexBuilderTests/CustomTests.swift +++ b/Tests/RegexBuilderTests/CustomTests.swift @@ -15,7 +15,7 @@ import _StringProcessing // A nibbler processes a single character from a string private protocol Nibbler: CustomRegexComponent { - func nibble(_: Character) -> Output? + func nibble(_: Character) -> RegexOutput? } extension Nibbler { @@ -24,7 +24,7 @@ extension Nibbler { _ input: String, startingAt index: String.Index, in bounds: Range - ) -> (upperBound: String.Index, output: Output)? { + ) -> (upperBound: String.Index, output: RegexOutput)? { guard index != bounds.upperBound, let res = nibble(input[index]) else { return nil } @@ -35,7 +35,7 @@ extension Nibbler { // A number nibbler private struct Numbler: Nibbler { - typealias Output = Int + typealias RegexOutput = Int func nibble(_ c: Character) -> Int? { c.wholeNumberValue } @@ -43,7 +43,7 @@ private struct Numbler: Nibbler { // An ASCII value nibbler private struct Asciibbler: Nibbler { - typealias Output = UInt8 + typealias RegexOutput = UInt8 func nibble(_ c: Character) -> UInt8? { c.asciiValue } diff --git a/Tests/RegexBuilderTests/RegexDSLTests.swift b/Tests/RegexBuilderTests/RegexDSLTests.swift index 0c0bf7c8f..b38b82a33 100644 --- a/Tests/RegexBuilderTests/RegexDSLTests.swift +++ b/Tests/RegexBuilderTests/RegexDSLTests.swift @@ -28,10 +28,10 @@ class RegexDSLTests: XCTestCase { if let expectedCaptures = maybeExpectedCaptures { let match = try XCTUnwrap(maybeMatch, file: file, line: line) XCTAssertTrue( - type(of: regex).Output.self == MatchType.self, + type(of: regex).RegexOutput.self == MatchType.self, """ Expected match type: \(MatchType.self) - Actual match type: \(type(of: regex).Output.self) + Actual match type: \(type(of: regex).RegexOutput.self) """) let captures = try XCTUnwrap(match.output as? MatchType, file: file, line: line) XCTAssertTrue( @@ -51,7 +51,7 @@ class RegexDSLTests: XCTestCase { TryCapture("1") { Int($0) } // Int } // Assert the inferred capture type. - let _: (Substring, Substring, Int).Type = type(of: regex).Output.self + let _: (Substring, Substring, Int).Type = type(of: regex).RegexOutput.self let maybeMatch = "ab1".wholeMatch(of: regex) let match = try XCTUnwrap(maybeMatch) XCTAssertTrue(match.output == ("ab1", "b", 1)) @@ -405,7 +405,7 @@ class RegexDSLTests: XCTestCase { // void. let regex = ZeroOrMore(.digit) // Assert the inferred capture type. - let _: Substring.Type = type(of: regex).Output.self + let _: Substring.Type = type(of: regex).RegexOutput.self let input = "123123" let match = try XCTUnwrap(input.wholeMatch(of: regex)?.output) XCTAssertTrue(match == input) @@ -454,7 +454,7 @@ class RegexDSLTests: XCTestCase { } } let _: (Substring, Substring, Substring).Type - = type(of: regex1).Output.self + = type(of: regex1).RegexOutput.self let regex2 = Regex { OneOrMore("a") Capture { @@ -465,7 +465,7 @@ class RegexDSLTests: XCTestCase { } } let _: (Substring, Substring, Int?).Type - = type(of: regex2).Output.self + = type(of: regex2).RegexOutput.self let regex3 = Regex { OneOrMore("a") Capture { @@ -477,7 +477,7 @@ class RegexDSLTests: XCTestCase { } } let _: (Substring, Substring, Int, Double?).Type - = type(of: regex3).Output.self + = type(of: regex3).RegexOutput.self let regex4 = Regex { OneOrMore("a") Capture { @@ -491,7 +491,7 @@ class RegexDSLTests: XCTestCase { } let _: ( Substring, Substring, Substring, Substring, Substring?).Type - = type(of: regex4).Output.self + = type(of: regex4).RegexOutput.self } func testUnicodeScalarPostProcessing() throws { @@ -530,7 +530,7 @@ class RegexDSLTests: XCTestCase { } // Assert the inferred capture type. - let _: (Substring, Substring).Type = type(of: unicodeData).Output.self + let _: (Substring, Substring).Type = type(of: unicodeData).RegexOutput.self let unicodeLine = "1BCA0..1BCA3 ; Control # Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP" @@ -565,7 +565,7 @@ class RegexDSLTests: XCTestCase { typealias ExpectedMatch = ( Substring, Unicode.Scalar?, Unicode.Scalar??, Substring ) - let _: ExpectedMatch.Type = type(of: regexWithCapture).Output.self + let _: ExpectedMatch.Type = type(of: regexWithCapture).RegexOutput.self let maybeMatchResult = line.wholeMatch(of: regexWithCapture) let matchResult = try XCTUnwrap(maybeMatchResult) let (wholeMatch, lower, upper, propertyString) = matchResult.output @@ -600,7 +600,7 @@ class RegexDSLTests: XCTestCase { typealias ExpectedMatch = ( Substring, Unicode.Scalar, Unicode.Scalar?, Substring ) - let _: ExpectedMatch.Type = type(of: regexWithTryCapture).Output.self + let _: ExpectedMatch.Type = type(of: regexWithTryCapture).RegexOutput.self let maybeMatchResult = line.wholeMatch(of: regexWithTryCapture) let matchResult = try XCTUnwrap(maybeMatchResult) let (wholeMatch, lower, upper, propertyString) = matchResult.output @@ -744,7 +744,7 @@ class RegexDSLTests: XCTestCase { var dev: String? } struct SemanticVersionParser: CustomRegexComponent { - typealias Output = SemanticVersion + typealias RegexOutput = SemanticVersion func match( _ input: String, startingAt index: String.Index, From 315c41816f3e0a58c42d0c8545f8a94d9c518961 Mon Sep 17 00:00:00 2001 From: Nate Cook Date: Thu, 14 Apr 2022 14:24:00 -0500 Subject: [PATCH 10/17] Move RegexComponent conformances to RegexBuilder (#279) --- Sources/RegexBuilder/DSL.swift | 34 ++++++++++++++++++++++ Sources/_StringProcessing/Regex/Core.swift | 34 ---------------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/Sources/RegexBuilder/DSL.swift b/Sources/RegexBuilder/DSL.swift index 28393bc1c..39a62984f 100644 --- a/Sources/RegexBuilder/DSL.swift +++ b/Sources/RegexBuilder/DSL.swift @@ -32,6 +32,40 @@ extension _BuiltinRegexComponent { } } +// MARK: - Primitive regex components + +extension String: RegexComponent { + public typealias Output = Substring + + public var regex: Regex { + .init(node: .quotedLiteral(self)) + } +} + +extension Substring: RegexComponent { + public typealias Output = Substring + + public var regex: Regex { + .init(node: .quotedLiteral(String(self))) + } +} + +extension Character: RegexComponent { + public typealias Output = Substring + + public var regex: Regex { + .init(node: .atom(.char(self))) + } +} + +extension UnicodeScalar: RegexComponent { + public typealias Output = Substring + + public var regex: Regex { + .init(node: .atom(.scalar(self))) + } +} + // MARK: - Combinators // MARK: Concatenation diff --git a/Sources/_StringProcessing/Regex/Core.swift b/Sources/_StringProcessing/Regex/Core.swift index 25375a2a6..e2d222eba 100644 --- a/Sources/_StringProcessing/Regex/Core.swift +++ b/Sources/_StringProcessing/Regex/Core.swift @@ -97,37 +97,3 @@ extension Regex { } } - -// MARK: - Primitive regex components - -extension String: RegexComponent { - public typealias Output = Substring - - public var regex: Regex { - .init(node: .quotedLiteral(self)) - } -} - -extension Substring: RegexComponent { - public typealias Output = Substring - - public var regex: Regex { - .init(node: .quotedLiteral(String(self))) - } -} - -extension Character: RegexComponent { - public typealias Output = Substring - - public var regex: Regex { - .init(node: .atom(.char(self))) - } -} - -extension UnicodeScalar: RegexComponent { - public typealias Output = Substring - - public var regex: Regex { - .init(node: .atom(.scalar(self))) - } -} From ba032b6998db6f1042dbeccc69d758caf0eb5e8c Mon Sep 17 00:00:00 2001 From: Richard Wei Date: Fri, 15 Apr 2022 00:02:27 -0700 Subject: [PATCH 11/17] Merge pull request #283 from rxwei/fix-availability Add remaining availability annotations. --- Package.swift | 40 +- Sources/RegexBuilder/Anchor.swift | 2 + Sources/RegexBuilder/CharacterClass.swift | 7 + Sources/RegexBuilder/DSL.swift | 10 + Sources/RegexBuilder/Match.swift | 1 + Sources/RegexBuilder/Variadics.swift | 711 ++++++++++++++++++ .../VariadicsGenerator.swift | 48 +- .../Algorithms/Algorithms/Contains.swift | 5 +- .../Algorithms/Algorithms/FirstRange.swift | 3 +- .../Algorithms/Algorithms/Ranges.swift | 4 +- .../Algorithms/Algorithms/Split.swift | 1 + .../Algorithms/Algorithms/StartsWith.swift | 2 +- .../Algorithms/Algorithms/Trim.swift | 19 +- .../Algorithms/Consumers/RegexConsumer.swift | 6 + .../Algorithms/Matching/FirstMatch.swift | 5 +- .../Algorithms/Matching/MatchReplace.swift | 7 +- .../Algorithms/Matching/Matches.swift | 3 + Sources/_StringProcessing/Executor.swift | 2 + .../Regex/AnyRegexOutput.swift | 8 + Sources/_StringProcessing/Regex/Core.swift | 3 +- .../Regex/DSLConsumers.swift | 1 + Sources/_StringProcessing/Regex/DSLTree.swift | 6 - Sources/_StringProcessing/Regex/Match.swift | 8 + Sources/_StringProcessing/Regex/Options.swift | 5 + .../_CharacterClassModel.swift | 16 +- 25 files changed, 873 insertions(+), 50 deletions(-) diff --git a/Package.swift b/Package.swift index cbec5f6a8..e4a0fb945 100644 --- a/Package.swift +++ b/Package.swift @@ -7,7 +7,7 @@ let availabilityDefinition = PackageDescription.SwiftSetting.unsafeFlags([ "-Xfrontend", "-define-availability", "-Xfrontend", - #""SwiftStdlib 5.7:macOS 9999, iOS 9999, watchOS 9999, tvOS 9999""# + #"SwiftStdlib 5.7:macOS 9999, iOS 9999, watchOS 9999, tvOS 9999"#, ]) let package = Package( @@ -67,44 +67,50 @@ let package = Package( .testTarget( name: "RegexTests", dependencies: ["_StringProcessing"], - swiftSettings: [availabilityDefinition]), + swiftSettings: [ + .unsafeFlags(["-Xfrontend", "-disable-availability-checking"]) + ]), .testTarget( name: "RegexBuilderTests", dependencies: ["_StringProcessing", "RegexBuilder"], swiftSettings: [ .unsafeFlags(["-Xfrontend", "-enable-experimental-pairwise-build-block"]), - availabilityDefinition + .unsafeFlags(["-Xfrontend", "-disable-availability-checking"]) ]), .target( name: "Prototypes", dependencies: ["_RegexParser", "_StringProcessing"], - swiftSettings: [availabilityDefinition]), + swiftSettings: [ + .unsafeFlags(["-Xfrontend", "-disable-availability-checking"]) + ]), // MARK: Scripts .executableTarget( name: "VariadicsGenerator", dependencies: [ - .product(name: "ArgumentParser", package: "swift-argument-parser") + .product(name: "ArgumentParser", package: "swift-argument-parser") ]), .executableTarget( name: "PatternConverter", dependencies: [ - .product(name: "ArgumentParser", package: "swift-argument-parser"), - "_RegexParser", - "_StringProcessing" + .product(name: "ArgumentParser", package: "swift-argument-parser"), + "_RegexParser", + "_StringProcessing" ]), // MARK: Exercises .target( - name: "Exercises", - dependencies: ["_RegexParser", "Prototypes", "_StringProcessing", "RegexBuilder"], - swiftSettings: [ - .unsafeFlags(["-Xfrontend", "-enable-experimental-pairwise-build-block"]), - availabilityDefinition - ]), + name: "Exercises", + dependencies: ["_RegexParser", "Prototypes", "_StringProcessing", "RegexBuilder"], + swiftSettings: [ + .unsafeFlags(["-Xfrontend", "-enable-experimental-pairwise-build-block"]), + .unsafeFlags(["-Xfrontend", "-disable-availability-checking"]) + ]), .testTarget( - name: "ExercisesTests", - dependencies: ["Exercises"], - swiftSettings: [availabilityDefinition]), + name: "ExercisesTests", + dependencies: ["Exercises"], + swiftSettings: [ + .unsafeFlags(["-Xfrontend", "-disable-availability-checking"]) + ]) ] ) diff --git a/Sources/RegexBuilder/Anchor.swift b/Sources/RegexBuilder/Anchor.swift index 50129b94d..55b554aea 100644 --- a/Sources/RegexBuilder/Anchor.swift +++ b/Sources/RegexBuilder/Anchor.swift @@ -29,6 +29,7 @@ public struct Anchor { var isInverted: Bool = false } +@available(SwiftStdlib 5.7, *) extension Anchor: RegexComponent { var astAssertion: AST.Atom.AssertionKind { if !isInverted { @@ -63,6 +64,7 @@ extension Anchor: RegexComponent { // MARK: - Public API +@available(SwiftStdlib 5.7, *) extension Anchor { public static var startOfSubject: Anchor { Anchor(kind: .startOfSubject) diff --git a/Sources/RegexBuilder/CharacterClass.swift b/Sources/RegexBuilder/CharacterClass.swift index 99e981d33..d163c336b 100644 --- a/Sources/RegexBuilder/CharacterClass.swift +++ b/Sources/RegexBuilder/CharacterClass.swift @@ -37,18 +37,21 @@ public struct CharacterClass { } } +@available(SwiftStdlib 5.7, *) extension CharacterClass: RegexComponent { public var regex: Regex { return Regex(node: DSLTree.Node.customCharacterClass(ccc)) } } +@available(SwiftStdlib 5.7, *) extension CharacterClass { public var inverted: CharacterClass { CharacterClass(ccc.inverted) } } +@available(SwiftStdlib 5.7, *) extension RegexComponent where Self == CharacterClass { public static var any: CharacterClass { .init(DSLTree.CustomCharacterClass(members: [.atom(.any)])) @@ -91,6 +94,7 @@ extension RegexComponent where Self == CharacterClass { } } +@available(SwiftStdlib 5.7, *) extension RegexComponent where Self == CharacterClass { /// Returns a character class that matches any character in the given string /// or sequence. @@ -112,6 +116,7 @@ extension RegexComponent where Self == CharacterClass { } // Unicode properties +@available(SwiftStdlib 5.7, *) extension CharacterClass { public static func generalCategory(_ category: Unicode.GeneralCategory) -> CharacterClass { guard let extendedCategory = category.extendedGeneralCategory else { @@ -179,6 +184,7 @@ extension Unicode.GeneralCategory { // MARK: - Set algebra methods +@available(SwiftStdlib 5.7, *) extension RegexComponent where Self == CharacterClass { public init(_ first: CharacterClass, _ rest: CharacterClass...) { if rest.isEmpty { @@ -191,6 +197,7 @@ extension RegexComponent where Self == CharacterClass { } } +@available(SwiftStdlib 5.7, *) extension CharacterClass { public func union(_ other: CharacterClass) -> CharacterClass { CharacterClass(.init(members: [ diff --git a/Sources/RegexBuilder/DSL.swift b/Sources/RegexBuilder/DSL.swift index 39a62984f..3c5f5ab5f 100644 --- a/Sources/RegexBuilder/DSL.swift +++ b/Sources/RegexBuilder/DSL.swift @@ -12,6 +12,7 @@ import _RegexParser @_spi(RegexBuilder) import _StringProcessing +@available(SwiftStdlib 5.7, *) extension Regex { public init( @RegexComponentBuilder _ content: () -> Content @@ -22,10 +23,12 @@ extension Regex { // A convenience protocol for builtin regex components that are initialized with // a `DSLTree` node. +@available(SwiftStdlib 5.7, *) internal protocol _BuiltinRegexComponent: RegexComponent { init(_ regex: Regex) } +@available(SwiftStdlib 5.7, *) extension _BuiltinRegexComponent { init(node: DSLTree.Node) { self.init(Regex(node: node)) @@ -34,6 +37,7 @@ extension _BuiltinRegexComponent { // MARK: - Primitive regex components +@available(SwiftStdlib 5.7, *) extension String: RegexComponent { public typealias Output = Substring @@ -42,6 +46,7 @@ extension String: RegexComponent { } } +@available(SwiftStdlib 5.7, *) extension Substring: RegexComponent { public typealias Output = Substring @@ -50,6 +55,7 @@ extension Substring: RegexComponent { } } +@available(SwiftStdlib 5.7, *) extension Character: RegexComponent { public typealias Output = Substring @@ -58,6 +64,7 @@ extension Character: RegexComponent { } } +@available(SwiftStdlib 5.7, *) extension UnicodeScalar: RegexComponent { public typealias Output = Substring @@ -110,6 +117,7 @@ public struct QuantificationBehavior { extension DSLTree.Node { /// Generates a DSLTree node for a repeated range of the given DSLTree node. /// Individual public API functions are in the generated Variadics.swift file. + @available(SwiftStdlib 5.7, *) static func repeating( _ range: Range, _ behavior: QuantificationBehavior, @@ -137,6 +145,7 @@ extension DSLTree.Node { } } +@available(SwiftStdlib 5.7, *) extension QuantificationBehavior { /// Match as much of the input string as possible, backtracking when /// necessary. @@ -304,6 +313,7 @@ public struct Reference: RegexComponent { } } +@available(SwiftStdlib 5.7, *) extension Regex.Match { public subscript(_ reference: Reference) -> Capture { self[reference.id] diff --git a/Sources/RegexBuilder/Match.swift b/Sources/RegexBuilder/Match.swift index 1b4b3951b..78a466a18 100644 --- a/Sources/RegexBuilder/Match.swift +++ b/Sources/RegexBuilder/Match.swift @@ -11,6 +11,7 @@ import _StringProcessing +@available(SwiftStdlib 5.7, *) extension String { @available(SwiftStdlib 5.7, *) public func wholeMatch( diff --git a/Sources/RegexBuilder/Variadics.swift b/Sources/RegexBuilder/Variadics.swift index e7bf02237..2ac5b3231 100644 --- a/Sources/RegexBuilder/Variadics.swift +++ b/Sources/RegexBuilder/Variadics.swift @@ -14,462 +14,594 @@ import _RegexParser @_spi(RegexBuilder) import _StringProcessing +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1, C2) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1, C2, C3) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1, C2, C3, C4) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == W0, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2)> where R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3)> where R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3)> where R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5, C6) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5, C6) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5, C6, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5), R1.RegexOutput == (W1, C6) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5), R1.RegexOutput == (W1, C6, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5), R1.RegexOutput == (W1, C6, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5), R1.RegexOutput == (W1, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6), R1.RegexOutput == (W1, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6), R1.RegexOutput == (W1, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6), R1.RegexOutput == (W1, C7, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7), R1.RegexOutput == (W1, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7), R1.RegexOutput == (W1, C8, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7, C8), R1.RegexOutput == (W1, C9) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex where R0.RegexOutput == W0 { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0)> where R0.RegexOutput == (W0, C0) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1)> where R0.RegexOutput == (W0, C0, C1) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2)> where R0.RegexOutput == (W0, C0, C1, C2) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3)> where R0.RegexOutput == (W0, C0, C1, C2, C3) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appending(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> Regex<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { @@ -478,7 +610,9 @@ extension RegexComponentBuilder { } +@available(SwiftStdlib 5.7, *) extension Optionally { + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( _ component: Component, @@ -488,7 +622,9 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension Optionally { + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( _ behavior: QuantificationBehavior = .eagerly, @@ -498,14 +634,18 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildLimitedAvailability( _ component: Component ) -> Regex { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( _ component: Component, @@ -515,7 +655,9 @@ extension ZeroOrMore { } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( _ behavior: QuantificationBehavior = .eagerly, @@ -526,7 +668,9 @@ extension ZeroOrMore { } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( _ component: Component, @@ -536,7 +680,9 @@ extension OneOrMore { } } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( _ behavior: QuantificationBehavior = .eagerly, @@ -547,7 +693,9 @@ extension OneOrMore { } +@available(SwiftStdlib 5.7, *) extension Repeat { + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( _ component: Component, @@ -558,6 +706,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) } + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( count: Int, @@ -568,6 +717,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) } + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( _ component: Component, @@ -577,6 +727,7 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, @@ -586,7 +737,9 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -595,7 +748,9 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension Optionally { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -604,14 +759,18 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?)> where Component.RegexOutput == (W, C0) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -620,7 +779,9 @@ extension ZeroOrMore { } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -630,7 +791,9 @@ extension ZeroOrMore { } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -639,7 +802,9 @@ extension OneOrMore { } } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -649,7 +814,9 @@ extension OneOrMore { } +@available(SwiftStdlib 5.7, *) extension Repeat { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, count: Int @@ -659,6 +826,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( count: Int, @RegexComponentBuilder _ component: () -> Component @@ -668,6 +836,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, @@ -676,6 +845,7 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, _ behavior: QuantificationBehavior = .eagerly, @@ -684,7 +854,9 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -693,7 +865,9 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension Optionally { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -702,14 +876,18 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?)> where Component.RegexOutput == (W, C0, C1) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -718,7 +896,9 @@ extension ZeroOrMore { } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -728,7 +908,9 @@ extension ZeroOrMore { } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -737,7 +919,9 @@ extension OneOrMore { } } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -747,7 +931,9 @@ extension OneOrMore { } +@available(SwiftStdlib 5.7, *) extension Repeat { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, count: Int @@ -757,6 +943,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( count: Int, @RegexComponentBuilder _ component: () -> Component @@ -766,6 +953,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, @@ -774,6 +962,7 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, _ behavior: QuantificationBehavior = .eagerly, @@ -782,7 +971,9 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -791,7 +982,9 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension Optionally { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -800,14 +993,18 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?, C2?)> where Component.RegexOutput == (W, C0, C1, C2) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -816,7 +1013,9 @@ extension ZeroOrMore { } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -826,7 +1025,9 @@ extension ZeroOrMore { } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -835,7 +1036,9 @@ extension OneOrMore { } } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -845,7 +1048,9 @@ extension OneOrMore { } +@available(SwiftStdlib 5.7, *) extension Repeat { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, count: Int @@ -855,6 +1060,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( count: Int, @RegexComponentBuilder _ component: () -> Component @@ -864,6 +1070,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, @@ -872,6 +1079,7 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, _ behavior: QuantificationBehavior = .eagerly, @@ -880,7 +1088,9 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -889,7 +1099,9 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension Optionally { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -898,14 +1110,18 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?, C2?, C3?)> where Component.RegexOutput == (W, C0, C1, C2, C3) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -914,7 +1130,9 @@ extension ZeroOrMore { } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -924,7 +1142,9 @@ extension ZeroOrMore { } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -933,7 +1153,9 @@ extension OneOrMore { } } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -943,7 +1165,9 @@ extension OneOrMore { } +@available(SwiftStdlib 5.7, *) extension Repeat { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, count: Int @@ -953,6 +1177,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( count: Int, @RegexComponentBuilder _ component: () -> Component @@ -962,6 +1187,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, @@ -970,6 +1196,7 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, _ behavior: QuantificationBehavior = .eagerly, @@ -978,7 +1205,9 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -987,7 +1216,9 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension Optionally { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -996,14 +1227,18 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1012,7 +1247,9 @@ extension ZeroOrMore { } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1022,7 +1259,9 @@ extension ZeroOrMore { } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1031,7 +1270,9 @@ extension OneOrMore { } } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1041,7 +1282,9 @@ extension OneOrMore { } +@available(SwiftStdlib 5.7, *) extension Repeat { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, count: Int @@ -1051,6 +1294,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( count: Int, @RegexComponentBuilder _ component: () -> Component @@ -1060,6 +1304,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, @@ -1068,6 +1313,7 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, _ behavior: QuantificationBehavior = .eagerly, @@ -1076,7 +1322,9 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1085,7 +1333,9 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension Optionally { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1094,14 +1344,18 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1110,7 +1364,9 @@ extension ZeroOrMore { } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1120,7 +1376,9 @@ extension ZeroOrMore { } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1129,7 +1387,9 @@ extension OneOrMore { } } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1139,7 +1399,9 @@ extension OneOrMore { } +@available(SwiftStdlib 5.7, *) extension Repeat { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, count: Int @@ -1149,6 +1411,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( count: Int, @RegexComponentBuilder _ component: () -> Component @@ -1158,6 +1421,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, @@ -1166,6 +1430,7 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, _ behavior: QuantificationBehavior = .eagerly, @@ -1174,7 +1439,9 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1183,7 +1450,9 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension Optionally { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1192,14 +1461,18 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1208,7 +1481,9 @@ extension ZeroOrMore { } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1218,7 +1493,9 @@ extension ZeroOrMore { } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1227,7 +1504,9 @@ extension OneOrMore { } } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1237,7 +1516,9 @@ extension OneOrMore { } +@available(SwiftStdlib 5.7, *) extension Repeat { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, count: Int @@ -1247,6 +1528,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( count: Int, @RegexComponentBuilder _ component: () -> Component @@ -1256,6 +1538,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, @@ -1264,6 +1547,7 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, _ behavior: QuantificationBehavior = .eagerly, @@ -1272,7 +1556,9 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1281,7 +1567,9 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension Optionally { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1290,14 +1578,18 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1306,7 +1598,9 @@ extension ZeroOrMore { } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1316,7 +1610,9 @@ extension ZeroOrMore { } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1325,7 +1621,9 @@ extension OneOrMore { } } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1335,7 +1633,9 @@ extension OneOrMore { } +@available(SwiftStdlib 5.7, *) extension Repeat { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, count: Int @@ -1345,6 +1645,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( count: Int, @RegexComponentBuilder _ component: () -> Component @@ -1354,6 +1655,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, @@ -1362,6 +1664,7 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, _ behavior: QuantificationBehavior = .eagerly, @@ -1370,7 +1673,9 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1379,7 +1684,9 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension Optionally { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1388,14 +1695,18 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1404,7 +1715,9 @@ extension ZeroOrMore { } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1414,7 +1727,9 @@ extension ZeroOrMore { } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1423,7 +1738,9 @@ extension OneOrMore { } } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1433,7 +1750,9 @@ extension OneOrMore { } +@available(SwiftStdlib 5.7, *) extension Repeat { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, count: Int @@ -1443,6 +1762,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( count: Int, @RegexComponentBuilder _ component: () -> Component @@ -1452,6 +1772,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, @@ -1460,6 +1781,7 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, _ behavior: QuantificationBehavior = .eagerly, @@ -1468,7 +1790,9 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1477,7 +1801,9 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension Optionally { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1486,14 +1812,18 @@ extension Optionally { } } +@available(SwiftStdlib 5.7, *) extension RegexComponentBuilder { + @available(SwiftStdlib 5.7, *) public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1502,7 +1832,9 @@ extension ZeroOrMore { } } +@available(SwiftStdlib 5.7, *) extension ZeroOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1512,7 +1844,9 @@ extension ZeroOrMore { } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ behavior: QuantificationBehavior = .eagerly @@ -1521,7 +1855,9 @@ extension OneOrMore { } } +@available(SwiftStdlib 5.7, *) extension OneOrMore { + @available(SwiftStdlib 5.7, *) public init( _ behavior: QuantificationBehavior = .eagerly, @RegexComponentBuilder _ component: () -> Component @@ -1531,7 +1867,9 @@ extension OneOrMore { } +@available(SwiftStdlib 5.7, *) extension Repeat { + @available(SwiftStdlib 5.7, *) public init( _ component: Component, count: Int @@ -1541,6 +1879,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( count: Int, @RegexComponentBuilder _ component: () -> Component @@ -1550,6 +1889,7 @@ extension Repeat { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, @@ -1558,6 +1898,7 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, _ behavior: QuantificationBehavior = .eagerly, @@ -1566,7 +1907,9 @@ extension Repeat { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component @@ -1575,7 +1918,9 @@ extension Local { } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( @RegexComponentBuilder _ component: () -> Component @@ -1583,7 +1928,9 @@ extension Local { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( _ component: Component ) where RegexOutput == (Substring, C0), Component.RegexOutput == (W, C0) { @@ -1591,14 +1938,18 @@ extension Local { } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0), Component.RegexOutput == (W, C0) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( _ component: Component ) where RegexOutput == (Substring, C0, C1), Component.RegexOutput == (W, C0, C1) { @@ -1606,14 +1957,18 @@ extension Local { } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1), Component.RegexOutput == (W, C0, C1) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( _ component: Component ) where RegexOutput == (Substring, C0, C1, C2), Component.RegexOutput == (W, C0, C1, C2) { @@ -1621,14 +1976,18 @@ extension Local { } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1, C2), Component.RegexOutput == (W, C0, C1, C2) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( _ component: Component ) where RegexOutput == (Substring, C0, C1, C2, C3), Component.RegexOutput == (W, C0, C1, C2, C3) { @@ -1636,14 +1995,18 @@ extension Local { } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1, C2, C3), Component.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( _ component: Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { @@ -1651,14 +2014,18 @@ extension Local { } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( _ component: Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { @@ -1666,14 +2033,18 @@ extension Local { } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( _ component: Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { @@ -1681,14 +2052,18 @@ extension Local { } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( _ component: Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { @@ -1696,14 +2071,18 @@ extension Local { } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( _ component: Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { @@ -1711,14 +2090,18 @@ extension Local { } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( _ component: Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { @@ -1726,521 +2109,675 @@ extension Local { } } +@available(SwiftStdlib 5.7, *) extension Local { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .nonCapturingGroup(.atomicNonCapturing, component().regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf where R0: RegexComponent, R1: RegexComponent { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0?, C1?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0?, C1?, C2?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1, C2) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1, C2, C3) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1, C2, C3, C4) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?, C5?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R1.RegexOutput == (W1, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1?, C2?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?, C5?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0), R1.RegexOutput == (W1, C1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?, C5?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1), R1.RegexOutput == (W1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?, C5?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2), R1.RegexOutput == (W1, C3, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?, C5?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5, C6) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4?, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3), R1.RegexOutput == (W1, C4, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5?, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5, C6) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5?, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5, C6, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5?, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5?, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4), R1.RegexOutput == (W1, C5, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5), R1.RegexOutput == (W1, C6) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6?, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5), R1.RegexOutput == (W1, C6, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6?, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5), R1.RegexOutput == (W1, C6, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6?, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5), R1.RegexOutput == (W1, C6, C7, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6), R1.RegexOutput == (W1, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7?, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6), R1.RegexOutput == (W1, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7?, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6), R1.RegexOutput == (W1, C7, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7), R1.RegexOutput == (W1, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8?, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7), R1.RegexOutput == (W1, C8, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7, C8) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock( accumulated: R0, next: R1 ) -> ChoiceOf<(Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9?)> where R0: RegexComponent, R1: RegexComponent, R0.RegexOutput == (W0, C0, C1, C2, C3, C4, C5, C6, C7, C8), R1.RegexOutput == (W1, C9) { .init(node: accumulated.regex.root.appendingAlternationCase(next.regex.root)) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?)> where R: RegexComponent, R.RegexOutput == (W, C0) { .init(node: .orderedChoice([regex.regex.root])) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1) { .init(node: .orderedChoice([regex.regex.root])) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1, C2) { .init(node: .orderedChoice([regex.regex.root])) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1, C2, C3) { .init(node: .orderedChoice([regex.regex.root])) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1, C2, C3, C4) { .init(node: .orderedChoice([regex.regex.root])) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?, C5?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { .init(node: .orderedChoice([regex.regex.root])) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?, C5?, C6?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { .init(node: .orderedChoice([regex.regex.root])) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { .init(node: .orderedChoice([regex.regex.root])) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { .init(node: .orderedChoice([regex.regex.root])) } } +@available(SwiftStdlib 5.7, *) extension AlternationBuilder { + @available(SwiftStdlib 5.7, *) public static func buildPartialBlock(first regex: R) -> ChoiceOf<(W, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where R: RegexComponent, R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { .init(node: .orderedChoice([regex.regex.root])) } } // MARK: - Non-builder capture arity 0 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( _ component: R @@ -2248,6 +2785,7 @@ extension Capture { self.init(node: .capture(component.regex.root)) } + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( _ component: R, as reference: Reference @@ -2255,6 +2793,7 @@ extension Capture { self.init(node: .capture(reference: reference.id, component.regex.root)) } + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( _ component: R, @@ -2267,6 +2806,7 @@ extension Capture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( _ component: R, @@ -2283,7 +2823,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( _ component: R, @@ -2296,6 +2838,7 @@ extension TryCapture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( _ component: R, @@ -2314,7 +2857,9 @@ extension TryCapture { // MARK: - Builder capture arity 0 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( @RegexComponentBuilder _ component: () -> R @@ -2322,6 +2867,7 @@ extension Capture { self.init(node: .capture(component().regex.root)) } + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( as reference: Reference, @@ -2332,6 +2878,7 @@ extension Capture { component().regex.root)) } + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( @RegexComponentBuilder _ component: () -> R, @@ -2344,6 +2891,7 @@ extension Capture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( as reference: Reference, @@ -2360,7 +2908,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( @RegexComponentBuilder _ component: () -> R, @@ -2373,6 +2923,7 @@ extension TryCapture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( as reference: Reference, @@ -2391,19 +2942,23 @@ extension TryCapture { // MARK: - Non-builder capture arity 1 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( _ component: R ) where RegexOutput == (Substring, W, C0), R.RegexOutput == (W, C0) { self.init(node: .capture(component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference ) where RegexOutput == (Substring, W, C0), R.RegexOutput == (W, C0) { self.init(node: .capture(reference: reference.id, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -2415,6 +2970,7 @@ extension Capture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -2430,7 +2986,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? @@ -2442,6 +3000,7 @@ extension TryCapture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -2459,13 +3018,16 @@ extension TryCapture { // MARK: - Builder capture arity 1 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R ) where RegexOutput == (Substring, W, C0), R.RegexOutput == (W, C0) { self.init(node: .capture(component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R @@ -2475,6 +3037,7 @@ extension Capture { component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -2486,6 +3049,7 @@ extension Capture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -2501,7 +3065,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? @@ -2513,6 +3079,7 @@ extension TryCapture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -2530,19 +3097,23 @@ extension TryCapture { // MARK: - Non-builder capture arity 2 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( _ component: R ) where RegexOutput == (Substring, W, C0, C1), R.RegexOutput == (W, C0, C1) { self.init(node: .capture(component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference ) where RegexOutput == (Substring, W, C0, C1), R.RegexOutput == (W, C0, C1) { self.init(node: .capture(reference: reference.id, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -2554,6 +3125,7 @@ extension Capture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -2569,7 +3141,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? @@ -2581,6 +3155,7 @@ extension TryCapture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -2598,13 +3173,16 @@ extension TryCapture { // MARK: - Builder capture arity 2 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R ) where RegexOutput == (Substring, W, C0, C1), R.RegexOutput == (W, C0, C1) { self.init(node: .capture(component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R @@ -2614,6 +3192,7 @@ extension Capture { component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -2625,6 +3204,7 @@ extension Capture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -2640,7 +3220,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? @@ -2652,6 +3234,7 @@ extension TryCapture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -2669,19 +3252,23 @@ extension TryCapture { // MARK: - Non-builder capture arity 3 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( _ component: R ) where RegexOutput == (Substring, W, C0, C1, C2), R.RegexOutput == (W, C0, C1, C2) { self.init(node: .capture(component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference ) where RegexOutput == (Substring, W, C0, C1, C2), R.RegexOutput == (W, C0, C1, C2) { self.init(node: .capture(reference: reference.id, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -2693,6 +3280,7 @@ extension Capture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -2708,7 +3296,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? @@ -2720,6 +3310,7 @@ extension TryCapture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -2737,13 +3328,16 @@ extension TryCapture { // MARK: - Builder capture arity 3 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R ) where RegexOutput == (Substring, W, C0, C1, C2), R.RegexOutput == (W, C0, C1, C2) { self.init(node: .capture(component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R @@ -2753,6 +3347,7 @@ extension Capture { component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -2764,6 +3359,7 @@ extension Capture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -2779,7 +3375,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? @@ -2791,6 +3389,7 @@ extension TryCapture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -2808,19 +3407,23 @@ extension TryCapture { // MARK: - Non-builder capture arity 4 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( _ component: R ) where RegexOutput == (Substring, W, C0, C1, C2, C3), R.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .capture(component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference ) where RegexOutput == (Substring, W, C0, C1, C2, C3), R.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .capture(reference: reference.id, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -2832,6 +3435,7 @@ extension Capture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -2847,7 +3451,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? @@ -2859,6 +3465,7 @@ extension TryCapture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -2876,13 +3483,16 @@ extension TryCapture { // MARK: - Builder capture arity 4 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R ) where RegexOutput == (Substring, W, C0, C1, C2, C3), R.RegexOutput == (W, C0, C1, C2, C3) { self.init(node: .capture(component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R @@ -2892,6 +3502,7 @@ extension Capture { component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -2903,6 +3514,7 @@ extension Capture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -2918,7 +3530,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? @@ -2930,6 +3544,7 @@ extension TryCapture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -2947,19 +3562,23 @@ extension TryCapture { // MARK: - Non-builder capture arity 5 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( _ component: R ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4), R.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .capture(component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4), R.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .capture(reference: reference.id, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -2971,6 +3590,7 @@ extension Capture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -2986,7 +3606,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? @@ -2998,6 +3620,7 @@ extension TryCapture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -3015,13 +3638,16 @@ extension TryCapture { // MARK: - Builder capture arity 5 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4), R.RegexOutput == (W, C0, C1, C2, C3, C4) { self.init(node: .capture(component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R @@ -3031,6 +3657,7 @@ extension Capture { component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -3042,6 +3669,7 @@ extension Capture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -3057,7 +3685,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? @@ -3069,6 +3699,7 @@ extension TryCapture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -3086,19 +3717,23 @@ extension TryCapture { // MARK: - Non-builder capture arity 6 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( _ component: R ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture(component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture(reference: reference.id, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -3110,6 +3745,7 @@ extension Capture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -3125,7 +3761,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? @@ -3137,6 +3775,7 @@ extension TryCapture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -3154,13 +3793,16 @@ extension TryCapture { // MARK: - Builder capture arity 6 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { self.init(node: .capture(component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R @@ -3170,6 +3812,7 @@ extension Capture { component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -3181,6 +3824,7 @@ extension Capture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -3196,7 +3840,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? @@ -3208,6 +3854,7 @@ extension TryCapture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -3225,19 +3872,23 @@ extension TryCapture { // MARK: - Non-builder capture arity 7 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( _ component: R ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture(component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture(reference: reference.id, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -3249,6 +3900,7 @@ extension Capture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -3264,7 +3916,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? @@ -3276,6 +3930,7 @@ extension TryCapture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -3293,13 +3948,16 @@ extension TryCapture { // MARK: - Builder capture arity 7 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { self.init(node: .capture(component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R @@ -3309,6 +3967,7 @@ extension Capture { component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -3320,6 +3979,7 @@ extension Capture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -3335,7 +3995,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? @@ -3347,6 +4009,7 @@ extension TryCapture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -3364,19 +4027,23 @@ extension TryCapture { // MARK: - Non-builder capture arity 8 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( _ component: R ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture(component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture(reference: reference.id, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -3388,6 +4055,7 @@ extension Capture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -3403,7 +4071,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? @@ -3415,6 +4085,7 @@ extension TryCapture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -3432,13 +4103,16 @@ extension TryCapture { // MARK: - Builder capture arity 8 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { self.init(node: .capture(component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R @@ -3448,6 +4122,7 @@ extension Capture { component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -3459,6 +4134,7 @@ extension Capture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -3474,7 +4150,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? @@ -3486,6 +4164,7 @@ extension TryCapture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -3503,19 +4182,23 @@ extension TryCapture { // MARK: - Non-builder capture arity 9 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( _ component: R ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture(component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture(reference: reference.id, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -3527,6 +4210,7 @@ extension Capture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -3542,7 +4226,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? @@ -3554,6 +4240,7 @@ extension TryCapture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -3571,13 +4258,16 @@ extension TryCapture { // MARK: - Builder capture arity 9 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { self.init(node: .capture(component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R @@ -3587,6 +4277,7 @@ extension Capture { component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -3598,6 +4289,7 @@ extension Capture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -3613,7 +4305,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? @@ -3625,6 +4319,7 @@ extension TryCapture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -3642,19 +4337,23 @@ extension TryCapture { // MARK: - Non-builder capture arity 10 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( _ component: R ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture(component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture(reference: reference.id, component.regex.root)) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture @@ -3666,6 +4365,7 @@ extension Capture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -3681,7 +4381,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( _ component: R, transform: @escaping (Substring) throws -> NewCapture? @@ -3693,6 +4395,7 @@ extension TryCapture { component.regex.root))) } + @available(SwiftStdlib 5.7, *) public init( _ component: R, as reference: Reference, @@ -3710,13 +4413,16 @@ extension TryCapture { // MARK: - Builder capture arity 10 +@available(SwiftStdlib 5.7, *) extension Capture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R ) where RegexOutput == (Substring, W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { self.init(node: .capture(component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R @@ -3726,6 +4432,7 @@ extension Capture { component().regex.root)) } + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture @@ -3737,6 +4444,7 @@ extension Capture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, @@ -3752,7 +4460,9 @@ extension Capture { } } +@available(SwiftStdlib 5.7, *) extension TryCapture { + @available(SwiftStdlib 5.7, *) public init( @RegexComponentBuilder _ component: () -> R, transform: @escaping (Substring) throws -> NewCapture? @@ -3764,6 +4474,7 @@ extension TryCapture { component().regex.root))) } + @available(SwiftStdlib 5.7, *) public init( as reference: Reference, @RegexComponentBuilder _ component: () -> R, diff --git a/Sources/VariadicsGenerator/VariadicsGenerator.swift b/Sources/VariadicsGenerator/VariadicsGenerator.swift index 1a0742f20..2df2f7c96 100644 --- a/Sources/VariadicsGenerator/VariadicsGenerator.swift +++ b/Sources/VariadicsGenerator/VariadicsGenerator.swift @@ -96,6 +96,7 @@ let regexTypeName = "Regex" let baseMatchTypeName = "Substring" let concatBuilderName = "RegexComponentBuilder" let altBuilderName = "AlternationBuilder" +let defaultAvailableAttr = "@available(SwiftStdlib 5.7, *)" @main struct VariadicsGenerator: ParsableCommand { @@ -240,8 +241,10 @@ struct VariadicsGenerator: ParsableCommand { }() // Emit concatenation builder. - output("extension \(concatBuilderName) {\n") output(""" + \(defaultAvailableAttr) + extension \(concatBuilderName) { + \(defaultAvailableAttr) public static func buildPartialBlock<\(genericParams)>( accumulated: R0, next: R1 ) -> \(regexTypeName)<\(matchType)> \(whereClause) { @@ -255,9 +258,11 @@ struct VariadicsGenerator: ParsableCommand { func emitConcatenationWithEmpty(leftArity: Int) { // T + () = T output(""" - extension \(concatBuilderName) { - public static func buildPartialBlock= 0) let params = QuantifierParameters(kind: kind, arity: arity) output(""" + \(defaultAvailableAttr) extension \(kind.rawValue) { + \(defaultAvailableAttr) \(params.disfavored)\ public init<\(params.genericParams)>( _ component: Component, @@ -377,7 +384,9 @@ struct VariadicsGenerator: ParsableCommand { } } + \(defaultAvailableAttr) extension \(kind.rawValue) { + \(defaultAvailableAttr) \(params.disfavored)\ public init<\(params.genericParams)>( _ behavior: QuantificationBehavior = .eagerly, @@ -389,7 +398,9 @@ struct VariadicsGenerator: ParsableCommand { \(kind == .zeroOrOne ? """ + \(defaultAvailableAttr) extension \(concatBuilderName) { + \(defaultAvailableAttr) public static func buildLimitedAvailability<\(params.genericParams)>( _ component: Component ) -> \(regexTypeName)<\(params.matchType)> \(params.whereClause) { @@ -433,7 +444,9 @@ struct VariadicsGenerator: ParsableCommand { (arity == 0 ? "" : ", Component.\(outputAssociatedTypeName) == (W, \(capturesJoined))") output(""" + \(defaultAvailableAttr) extension \(groupName) { + \(defaultAvailableAttr) \(disfavored)\ public init<\(genericParams)>( _ component: Component @@ -442,7 +455,9 @@ struct VariadicsGenerator: ParsableCommand { } } + \(defaultAvailableAttr) extension \(groupName) { + \(defaultAvailableAttr) \(disfavored)\ public init<\(genericParams)>( @\(concatBuilderName) _ component: () -> Component @@ -463,7 +478,9 @@ struct VariadicsGenerator: ParsableCommand { // We would need to prohibit `repeat(count: 0)`; can only happen at runtime output(""" + \(defaultAvailableAttr) extension Repeat { + \(defaultAvailableAttr) \(params.disfavored)\ public init<\(params.genericParams)>( _ component: Component, @@ -474,6 +491,7 @@ struct VariadicsGenerator: ParsableCommand { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) } + \(defaultAvailableAttr) \(params.disfavored)\ public init<\(params.genericParams)>( count: Int, @@ -484,6 +502,7 @@ struct VariadicsGenerator: ParsableCommand { self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) } + \(defaultAvailableAttr) \(params.disfavored)\ public init<\(params.genericParams), R: RangeExpression>( _ component: Component, @@ -493,6 +512,7 @@ struct VariadicsGenerator: ParsableCommand { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, @@ -545,7 +565,9 @@ struct VariadicsGenerator: ParsableCommand { return "(\(baseMatchTypeName), \(resultCaptures))" }() output(""" + \(defaultAvailableAttr) extension \(altBuilderName) { + \(defaultAvailableAttr) public static func buildPartialBlock<\(genericParams)>( accumulated: R0, next: R1 ) -> ChoiceOf<\(matchType)> \(whereClause) { @@ -571,7 +593,9 @@ struct VariadicsGenerator: ParsableCommand { """ let resultCaptures = (0..(first regex: R) -> ChoiceOf<(W, \(resultCaptures))> \(whereClause) { .init(node: .orderedChoice([regex.regex.root])) } @@ -600,7 +624,9 @@ struct VariadicsGenerator: ParsableCommand { output(""" // MARK: - Non-builder capture arity \(arity) + \(defaultAvailableAttr) extension Capture { + \(defaultAvailableAttr) \(disfavored)\ public init<\(genericParams)>( _ component: R @@ -608,6 +634,7 @@ struct VariadicsGenerator: ParsableCommand { self.init(node: .capture(component.regex.root)) } + \(defaultAvailableAttr) \(disfavored)\ public init<\(genericParams)>( _ component: R, as reference: Reference @@ -615,6 +642,7 @@ struct VariadicsGenerator: ParsableCommand { self.init(node: .capture(reference: reference.id, component.regex.root)) } + \(defaultAvailableAttr) \(disfavored)\ public init<\(genericParams), NewCapture>( _ component: R, @@ -627,6 +655,7 @@ struct VariadicsGenerator: ParsableCommand { component.regex.root))) } + \(defaultAvailableAttr) \(disfavored)\ public init<\(genericParams), NewCapture>( _ component: R, @@ -643,7 +672,9 @@ struct VariadicsGenerator: ParsableCommand { } } + \(defaultAvailableAttr) extension TryCapture { + \(defaultAvailableAttr) \(disfavored)\ public init<\(genericParams), NewCapture>( _ component: R, @@ -656,6 +687,7 @@ struct VariadicsGenerator: ParsableCommand { component.regex.root))) } + \(defaultAvailableAttr) \(disfavored)\ public init<\(genericParams), NewCapture>( _ component: R, @@ -674,7 +706,9 @@ struct VariadicsGenerator: ParsableCommand { // MARK: - Builder capture arity \(arity) + \(defaultAvailableAttr) extension Capture { + \(defaultAvailableAttr) \(disfavored)\ public init<\(genericParams)>( @\(concatBuilderName) _ component: () -> R @@ -682,6 +716,7 @@ struct VariadicsGenerator: ParsableCommand { self.init(node: .capture(component().regex.root)) } + \(defaultAvailableAttr) \(disfavored)\ public init<\(genericParams)>( as reference: Reference, @@ -692,6 +727,7 @@ struct VariadicsGenerator: ParsableCommand { component().regex.root)) } + \(defaultAvailableAttr) \(disfavored)\ public init<\(genericParams), NewCapture>( @\(concatBuilderName) _ component: () -> R, @@ -704,6 +740,7 @@ struct VariadicsGenerator: ParsableCommand { component().regex.root))) } + \(defaultAvailableAttr) \(disfavored)\ public init<\(genericParams), NewCapture>( as reference: Reference, @@ -720,7 +757,9 @@ struct VariadicsGenerator: ParsableCommand { } } + \(defaultAvailableAttr) extension TryCapture { + \(defaultAvailableAttr) \(disfavored)\ public init<\(genericParams), NewCapture>( @\(concatBuilderName) _ component: () -> R, @@ -733,6 +772,7 @@ struct VariadicsGenerator: ParsableCommand { component().regex.root))) } + \(defaultAvailableAttr) \(disfavored)\ public init<\(genericParams), NewCapture>( as reference: Reference, diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/Contains.swift b/Sources/_StringProcessing/Algorithms/Algorithms/Contains.swift index 2f38095d8..1d4332ad0 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/Contains.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/Contains.swift @@ -39,7 +39,10 @@ extension BidirectionalCollection where Element: Comparable { func contains(_ other: S) -> Bool where S.Element == Element { - firstRange(of: other) != nil + if #available(SwiftStdlib 5.7, *) { + return firstRange(of: other) != nil + } + fatalError() } } diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/FirstRange.swift b/Sources/_StringProcessing/Algorithms/Algorithms/FirstRange.swift index e75cdbdc4..508c04663 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/FirstRange.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/FirstRange.swift @@ -77,7 +77,8 @@ extension BidirectionalCollection where SubSequence == Substring { public func firstRange(of regex: R) -> Range? { firstRange(of: RegexConsumer(regex)) } - + + @available(SwiftStdlib 5.7, *) func lastRange(of regex: R) -> Range? { lastRange(of: RegexConsumer(regex)) } diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/Ranges.swift b/Sources/_StringProcessing/Algorithms/Algorithms/Ranges.swift index 3a45b86a2..f1861fcf2 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/Ranges.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/Ranges.swift @@ -218,12 +218,14 @@ extension BidirectionalCollection where Element: Comparable { extension BidirectionalCollection where SubSequence == Substring { // FIXME: Replace `RangesCollection` when SE-0346 is enabled + @available(SwiftStdlib 5.7, *) func ranges( of regex: R ) -> RangesCollection> { ranges(of: RegexConsumer(regex)) } - + + @available(SwiftStdlib 5.7, *) func rangesFromBack( of regex: R ) -> ReversedRangesCollection> { diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/Split.swift b/Sources/_StringProcessing/Algorithms/Algorithms/Split.swift index 898f93048..485bc3b7f 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/Split.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/Split.swift @@ -280,6 +280,7 @@ extension BidirectionalCollection where Element: Comparable { // MARK: Regex algorithms +@available(SwiftStdlib 5.7, *) extension BidirectionalCollection where SubSequence == Substring { // FIXME: Replace `SplitCollection` when SE-0346 is enabled /// Returns the longest possible subsequences of the collection, in order, diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/StartsWith.swift b/Sources/_StringProcessing/Algorithms/Algorithms/StartsWith.swift index 01572fe49..0dd91f360 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/StartsWith.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/StartsWith.swift @@ -47,13 +47,13 @@ extension BidirectionalCollection where Element: Equatable { // MARK: Regex algorithms +@available(SwiftStdlib 5.7, *) extension BidirectionalCollection where SubSequence == Substring { /// Returns a Boolean value indicating whether the initial elements of the /// sequence are the same as the elements in the specified regex. /// - Parameter regex: A regex to compare to this sequence. /// - Returns: `true` if the initial elements of the sequence matches the /// beginning of `regex`; otherwise, `false`. - @available(SwiftStdlib 5.7, *) public func starts(with regex: R) -> Bool { starts(with: RegexConsumer(regex)) } diff --git a/Sources/_StringProcessing/Algorithms/Algorithms/Trim.swift b/Sources/_StringProcessing/Algorithms/Algorithms/Trim.swift index fd0dbefdb..73a5cd554 100644 --- a/Sources/_StringProcessing/Algorithms/Algorithms/Trim.swift +++ b/Sources/_StringProcessing/Algorithms/Algorithms/Trim.swift @@ -288,11 +288,13 @@ extension BidirectionalCollection where SubSequence == Substring { public func trimmingPrefix(_ regex: R) -> SubSequence { trimmingPrefix(RegexConsumer(regex)) } - + + @available(SwiftStdlib 5.7, *) func trimmingSuffix(_ regex: R) -> SubSequence { trimmingSuffix(RegexConsumer(regex)) } - + + @available(SwiftStdlib 5.7, *) func trimming(_ regex: R) -> SubSequence { trimming(RegexConsumer(regex)) } @@ -307,11 +309,13 @@ extension RangeReplaceableCollection public mutating func trimPrefix(_ regex: R) { trimPrefix(RegexConsumer(regex)) } - + + @available(SwiftStdlib 5.7, *) mutating func trimSuffix(_ regex: R) { trimSuffix(RegexConsumer(regex)) } - + + @available(SwiftStdlib 5.7, *) mutating func trim(_ regex: R) { let consumer = RegexConsumer(regex) trimPrefix(consumer) @@ -320,14 +324,17 @@ extension RangeReplaceableCollection } extension Substring { + @available(SwiftStdlib 5.7, *) mutating func trimPrefix(_ regex: R) { trimPrefix(RegexConsumer(regex)) } - + + @available(SwiftStdlib 5.7, *) mutating func trimSuffix(_ regex: R) { trimSuffix(RegexConsumer(regex)) } - + + @available(SwiftStdlib 5.7, *) mutating func trim(_ regex: R) { let consumer = RegexConsumer(regex) trimPrefix(consumer) diff --git a/Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift b/Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift index 81f3ebb3e..4956406da 100644 --- a/Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift +++ b/Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift @@ -10,6 +10,7 @@ //===----------------------------------------------------------------------===// // FIXME: What even is this? Can we delete this whole thing? +@available(SwiftStdlib 5.7, *) struct RegexConsumer< R: RegexComponent, Consumed: BidirectionalCollection > where Consumed.SubSequence == Substring { @@ -21,6 +22,7 @@ struct RegexConsumer< } } +@available(SwiftStdlib 5.7, *) extension RegexConsumer { func _matchingConsuming( _ consumed: Substring, in range: Range @@ -36,6 +38,7 @@ extension RegexConsumer { // TODO: Explicitly implement the non-matching consumer/searcher protocols as // well, taking advantage of the fact that the captures can be ignored +@available(SwiftStdlib 5.7, *) extension RegexConsumer: MatchingCollectionConsumer { typealias Match = R.RegexOutput @@ -47,6 +50,7 @@ extension RegexConsumer: MatchingCollectionConsumer { } // TODO: We'll want to bake backwards into the engine +@available(SwiftStdlib 5.7, *) extension RegexConsumer: BidirectionalMatchingCollectionConsumer { func matchingConsumingBack( _ consumed: Consumed, in range: Range @@ -67,6 +71,7 @@ extension RegexConsumer: BidirectionalMatchingCollectionConsumer { } } +@available(SwiftStdlib 5.7, *) extension RegexConsumer: MatchingStatelessCollectionSearcher { typealias Searched = Consumed @@ -81,6 +86,7 @@ extension RegexConsumer: MatchingStatelessCollectionSearcher { } // TODO: Bake in search-back to engine too +@available(SwiftStdlib 5.7, *) extension RegexConsumer: BackwardMatchingStatelessCollectionSearcher { typealias BackwardSearched = Consumed diff --git a/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift b/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift index 093a47b71..a4dce19b7 100644 --- a/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift +++ b/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift @@ -38,12 +38,14 @@ extension BidirectionalCollection { // MARK: Regex algorithms extension BidirectionalCollection where SubSequence == Substring { + @available(SwiftStdlib 5.7, *) func firstMatch( of regex: R ) -> _MatchResult>? { firstMatch(of: RegexConsumer(regex)) } - + + @available(SwiftStdlib 5.7, *) func lastMatch( of regex: R ) -> _BackwardMatchResult>? { @@ -54,6 +56,7 @@ extension BidirectionalCollection where SubSequence == Substring { /// - Parameter regex: The regex to search for. /// - Returns: The first match of `regex` in the collection, or `nil` if /// there isn't a match. + @available(SwiftStdlib 5.7, *) public func firstMatch( of r: R ) -> Regex.Match? { diff --git a/Sources/_StringProcessing/Algorithms/Matching/MatchReplace.swift b/Sources/_StringProcessing/Algorithms/Matching/MatchReplace.swift index 461c08e02..8485182de 100644 --- a/Sources/_StringProcessing/Algorithms/Matching/MatchReplace.swift +++ b/Sources/_StringProcessing/Algorithms/Matching/MatchReplace.swift @@ -75,6 +75,7 @@ extension RangeReplaceableCollection { // MARK: Regex algorithms extension RangeReplaceableCollection where SubSequence == Substring { + @available(SwiftStdlib 5.7, *) func replacing( _ regex: R, with replacement: (_MatchResult>) throws -> Replacement, @@ -87,7 +88,8 @@ extension RangeReplaceableCollection where SubSequence == Substring { subrange: subrange, maxReplacements: maxReplacements) } - + + @available(SwiftStdlib 5.7, *) func replacing( _ regex: R, with replacement: (_MatchResult>) throws -> Replacement, @@ -99,7 +101,8 @@ extension RangeReplaceableCollection where SubSequence == Substring { subrange: startIndex..( _ regex: R, with replacement: (_MatchResult>) throws -> Replacement, diff --git a/Sources/_StringProcessing/Algorithms/Matching/Matches.swift b/Sources/_StringProcessing/Algorithms/Matching/Matches.swift index 484737f05..6736e3033 100644 --- a/Sources/_StringProcessing/Algorithms/Matching/Matches.swift +++ b/Sources/_StringProcessing/Algorithms/Matching/Matches.swift @@ -188,12 +188,14 @@ extension BidirectionalCollection where SubSequence == Substring { /// Returns a collection containing all matches of the specified regex. /// - Parameter regex: The regex to search for. /// - Returns: A collection of matches of `regex`. + @available(SwiftStdlib 5.7, *) func matches( of regex: R ) -> MatchesCollection> { matches(of: RegexConsumer(regex)) } + @available(SwiftStdlib 5.7, *) func matchesFromBack( of regex: R ) -> ReversedMatchesCollection> { @@ -202,6 +204,7 @@ extension BidirectionalCollection where SubSequence == Substring { // FIXME: Replace the returned value as `some Collection.Match> // when SE-0346 is enabled + @available(SwiftStdlib 5.7, *) func _matches(of r: R) -> [Regex.Match] { let slice = self[...] var start = self.startIndex diff --git a/Sources/_StringProcessing/Executor.swift b/Sources/_StringProcessing/Executor.swift index 563e90970..d911c3512 100644 --- a/Sources/_StringProcessing/Executor.swift +++ b/Sources/_StringProcessing/Executor.swift @@ -19,6 +19,7 @@ struct Executor { self.engine = Engine(program, enableTracing: enablesTracing) } + @available(SwiftStdlib 5.7, *) func match( _ input: String, in inputRange: Range, @@ -64,6 +65,7 @@ struct Executor { value: value) } + @available(SwiftStdlib 5.7, *) func dynamicMatch( _ input: String, in inputRange: Range, diff --git a/Sources/_StringProcessing/Regex/AnyRegexOutput.swift b/Sources/_StringProcessing/Regex/AnyRegexOutput.swift index ea9659faf..16829ff78 100644 --- a/Sources/_StringProcessing/Regex/AnyRegexOutput.swift +++ b/Sources/_StringProcessing/Regex/AnyRegexOutput.swift @@ -11,6 +11,7 @@ import _RegexParser +@available(SwiftStdlib 5.7, *) extension Regex where Output == AnyRegexOutput { /// Parse and compile `pattern`, resulting in an existentially-typed capture list. public init(compiling pattern: String) throws { @@ -18,6 +19,7 @@ extension Regex where Output == AnyRegexOutput { } } +@available(SwiftStdlib 5.7, *) extension Regex { /// Parse and compile `pattern`, resulting in a strongly-typed capture list. public init( @@ -28,6 +30,7 @@ extension Regex { } } +@available(SwiftStdlib 5.7, *) extension Regex.Match where Output == AnyRegexOutput { // Ensures `.0` always refers to the whole match. public subscript( @@ -54,6 +57,7 @@ public struct AnyRegexOutput { } } +@available(SwiftStdlib 5.7, *) extension AnyRegexOutput { /// Creates a type-erased regex output from an existing output. /// @@ -87,6 +91,7 @@ extension AnyRegexOutput { } } +@available(SwiftStdlib 5.7, *) extension AnyRegexOutput { internal init( input: String, elements: C @@ -95,6 +100,7 @@ extension AnyRegexOutput { } } +@available(SwiftStdlib 5.7, *) extension AnyRegexOutput.ElementRepresentation { init(_ element: StructuredCapture) { self.init( @@ -117,6 +123,7 @@ extension AnyRegexOutput.ElementRepresentation { } } +@available(SwiftStdlib 5.7, *) extension AnyRegexOutput: RandomAccessCollection { public struct Element { fileprivate let representation: ElementRepresentation @@ -163,6 +170,7 @@ extension AnyRegexOutput: RandomAccessCollection { } } +@available(SwiftStdlib 5.7, *) extension Regex.Match where Output == AnyRegexOutput { /// Creates a type-erased regex match from an existing match. /// diff --git a/Sources/_StringProcessing/Regex/Core.swift b/Sources/_StringProcessing/Regex/Core.swift index e2d222eba..a2cf76cd2 100644 --- a/Sources/_StringProcessing/Regex/Core.swift +++ b/Sources/_StringProcessing/Regex/Core.swift @@ -61,6 +61,7 @@ public struct Regex: RegexComponent { } } +@available(SwiftStdlib 5.7, *) extension Regex { /// A program representation that caches any lowered representation for /// execution. @@ -85,6 +86,7 @@ extension Regex { } } +@available(SwiftStdlib 5.7, *) extension Regex { @_spi(RegexBuilder) public var root: DSLTree.Node { @@ -95,5 +97,4 @@ extension Regex { public init(node: DSLTree.Node) { self.program = Program(tree: .init(node, options: nil)) } - } diff --git a/Sources/_StringProcessing/Regex/DSLConsumers.swift b/Sources/_StringProcessing/Regex/DSLConsumers.swift index c3dc6d88c..e1a69d74b 100644 --- a/Sources/_StringProcessing/Regex/DSLConsumers.swift +++ b/Sources/_StringProcessing/Regex/DSLConsumers.swift @@ -18,6 +18,7 @@ public protocol CustomRegexComponent: RegexComponent { ) -> (upperBound: String.Index, output: RegexOutput)? } +@available(SwiftStdlib 5.7, *) extension CustomRegexComponent { public var regex: Regex { Regex(node: .matcher(.init(RegexOutput.self), { input, index, bounds in diff --git a/Sources/_StringProcessing/Regex/DSLTree.swift b/Sources/_StringProcessing/Regex/DSLTree.swift index 6ae4804e5..f37505cb4 100644 --- a/Sources/_StringProcessing/Regex/DSLTree.swift +++ b/Sources/_StringProcessing/Regex/DSLTree.swift @@ -12,7 +12,6 @@ import _RegexParser @_spi(RegexBuilder) -@available(SwiftStdlib 5.7, *) public struct DSLTree { var root: Node var options: Options? @@ -163,7 +162,6 @@ extension DSLTree { // CollectionConsumer @_spi(RegexBuilder) -@available(SwiftStdlib 5.7, *) public typealias _ConsumerInterface = ( String, Range ) throws -> String.Index? @@ -171,14 +169,12 @@ public typealias _ConsumerInterface = ( // Type producing consume // TODO: better name @_spi(RegexBuilder) -@available(SwiftStdlib 5.7, *) public typealias _MatcherInterface = ( String, String.Index, Range ) throws -> (String.Index, Any)? // Character-set (post grapheme segmentation) @_spi(RegexBuilder) -@available(SwiftStdlib 5.7, *) public typealias _CharacterPredicateInterface = ( (Character) -> Bool ) @@ -379,7 +375,6 @@ extension DSLTree.Node { } @_spi(RegexBuilder) -@available(SwiftStdlib 5.7, *) public struct ReferenceID: Hashable, Equatable { private static var counter: Int = 0 var base: Int @@ -391,7 +386,6 @@ public struct ReferenceID: Hashable, Equatable { } @_spi(RegexBuilder) -@available(SwiftStdlib 5.7, *) public struct CaptureTransform: Hashable, CustomStringConvertible { public enum Closure { case failable((Substring) throws -> Any?) diff --git a/Sources/_StringProcessing/Regex/Match.swift b/Sources/_StringProcessing/Regex/Match.swift index 73ae62b7e..251febc87 100644 --- a/Sources/_StringProcessing/Regex/Match.swift +++ b/Sources/_StringProcessing/Regex/Match.swift @@ -9,6 +9,7 @@ // //===----------------------------------------------------------------------===// +@available(SwiftStdlib 5.7, *) extension Regex { /// The result of matching a regex against a string. /// @@ -29,6 +30,7 @@ extension Regex { } } +@available(SwiftStdlib 5.7, *) extension Regex.Match { /// The produced output from the match operation public var output: Output { @@ -81,6 +83,7 @@ extension Regex.Match { } } +@available(SwiftStdlib 5.7, *) extension Regex { /// Match a string in its entirety. /// @@ -152,24 +155,29 @@ extension Regex { } } +@available(SwiftStdlib 5.7, *) extension String { public func wholeMatch( of r: R ) -> Regex.Match? { try? r.regex.wholeMatch(in: self) } + public func prefixMatch( of r: R ) -> Regex.Match? { try? r.regex.prefixMatch(in: self) } } + +@available(SwiftStdlib 5.7, *) extension Substring { public func wholeMatch( of r: R ) -> Regex.Match? { try? r.regex.wholeMatch(in: self) } + public func prefixMatch( of r: R ) -> Regex.Match? { diff --git a/Sources/_StringProcessing/Regex/Options.swift b/Sources/_StringProcessing/Regex/Options.swift index 3131bd89a..2b192491e 100644 --- a/Sources/_StringProcessing/Regex/Options.swift +++ b/Sources/_StringProcessing/Regex/Options.swift @@ -11,6 +11,7 @@ import _RegexParser +@available(SwiftStdlib 5.7, *) extension RegexComponent { /// Returns a regular expression that ignores casing when matching. public func ignoringCase(_ ignoreCase: Bool = true) -> Regex { @@ -105,6 +106,7 @@ extension RegexComponent { } } +@available(SwiftStdlib 5.7, *) public struct RegexSemanticLevel: Hashable { internal enum Representation { case graphemeCluster @@ -127,6 +129,7 @@ public struct RegexSemanticLevel: Hashable { } // Options that only affect literals +@available(SwiftStdlib 5.7, *) extension RegexComponent { /// Returns a regular expression where the start and end of input /// anchors (`^` and `$`) also match against the start and end of a line. @@ -159,6 +162,8 @@ extension RegexComponent { } // MARK: - Helper method + +@available(SwiftStdlib 5.7, *) extension RegexComponent { fileprivate func wrapInOption( _ option: AST.MatchingOption.Kind, diff --git a/Sources/_StringProcessing/_CharacterClassModel.swift b/Sources/_StringProcessing/_CharacterClassModel.swift index e63423f8f..d160abc81 100644 --- a/Sources/_StringProcessing/_CharacterClassModel.swift +++ b/Sources/_StringProcessing/_CharacterClassModel.swift @@ -16,7 +16,6 @@ import _RegexParser // of parsing or to store in an AST @_spi(RegexBuilder) -@available(SwiftStdlib 5.7, *) public struct _CharacterClassModel: Hashable { /// The actual character class to match. var cc: Representation @@ -29,7 +28,7 @@ public struct _CharacterClassModel: Hashable { var isInverted: Bool = false // TODO: Split out builtin character classes into their own type? - public enum Representation: Hashable { + public enum Representation: Hashable { /// Any character case any /// Any grapheme cluster @@ -56,8 +55,7 @@ public struct _CharacterClassModel: Hashable { public typealias SetOperator = AST.CustomCharacterClass.SetOp /// A binary set operation that forms a character class component. - @_spi(RegexBuilder) - public struct SetOperation: Hashable { + public struct SetOperation: Hashable { var lhs: CharacterSetComponent var op: SetOperator var rhs: CharacterSetComponent @@ -74,8 +72,7 @@ public struct _CharacterClassModel: Hashable { } } - @_spi(RegexBuilder) - public enum CharacterSetComponent: Hashable { + public enum CharacterSetComponent: Hashable { case character(Character) case range(ClosedRange) @@ -205,6 +202,7 @@ public struct _CharacterClassModel: Hashable { } } +@available(SwiftStdlib 5.7, *) extension _CharacterClassModel: RegexComponent { public typealias RegexOutput = Substring @@ -374,7 +372,7 @@ extension _CharacterClassModel { } extension DSLTree.Atom { - var characterClass: _CharacterClassModel? { + var characterClass: _CharacterClassModel? { switch self { case let .unconverted(a): return a.characterClass @@ -385,7 +383,7 @@ extension DSLTree.Atom { } extension AST.Atom { - var characterClass: _CharacterClassModel? { + var characterClass: _CharacterClassModel? { switch kind { case let .escaped(b): return b.characterClass @@ -411,7 +409,7 @@ extension AST.Atom { } extension AST.Atom.EscapedBuiltin { - var characterClass: _CharacterClassModel? { + var characterClass: _CharacterClassModel? { switch self { case .decimalDigit: return .digit case .notDecimalDigit: return .digit.inverted From fde4c582058ce6956c01617ab0ed043ce215c822 Mon Sep 17 00:00:00 2001 From: Nate Cook Date: Mon, 18 Apr 2022 10:46:43 -0500 Subject: [PATCH 12/17] Add Substring algorithms tests (#289) `firstMatch(of:)` was ignoring the start/endIndex when searching in substrings; this change fixes that issue. Also adds the 'in' label to `Regex.firstMatch(in:Substring)` to match the rest of the related APIs. --- .../Algorithms/Matching/FirstMatch.swift | 2 +- Sources/_StringProcessing/Regex/Match.swift | 2 +- Tests/RegexTests/AlgorithmsTests.swift | 47 +++++++++++++++---- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift b/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift index a4dce19b7..cb527f948 100644 --- a/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift +++ b/Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift @@ -61,6 +61,6 @@ extension BidirectionalCollection where SubSequence == Substring { of r: R ) -> Regex.Match? { let slice = self[...] - return try? r.regex.firstMatch(in: slice.base) + return try? r.regex.firstMatch(in: slice) } } diff --git a/Sources/_StringProcessing/Regex/Match.swift b/Sources/_StringProcessing/Regex/Match.swift index 251febc87..a86899041 100644 --- a/Sources/_StringProcessing/Regex/Match.swift +++ b/Sources/_StringProcessing/Regex/Match.swift @@ -123,7 +123,7 @@ extension Regex { /// Find the first match in a substring /// /// Returns `nil` if no match is found and throws on abort - public func firstMatch(_ s: Substring) throws -> Regex.Match? { + public func firstMatch(in s: Substring) throws -> Regex.Match? { try _firstMatch(s.base, in: s.startIndex..] = string[...].ranges(of: regex).map { - let start = string.offset(ofIndex: $0.lowerBound) - let end = string.offset(ofIndex: $0.upperBound) - return start..] = string[...].ranges(of: regex).map(string.offsets(of:)) XCTAssertEqual(actualSeq, expected, file: file, line: line) // `IndexingIterator` tests the collection conformance - let actualCol: [Range] = string[...].ranges(of: regex)[...].map { - let start = string.offset(ofIndex: $0.lowerBound) - let end = string.offset(ofIndex: $0.upperBound) - return start..] = string[...].ranges(of: regex)[...].map(string.offsets(of:)) XCTAssertEqual(actualCol, expected, file: file, line: line) } @@ -145,4 +137,39 @@ class RegexConsumerTests: XCTestCase { XCTAssertEqual("x", "axb".trimming(r)) XCTAssertEqual("x", "axbb".trimming(r)) } + + func testSubstring() throws { + let s = "aaa | aaaaaa | aaaaaaaaaa" + let s1 = s.dropFirst(6) // "aaaaaa | aaaaaaaaaa" + let s2 = s1.dropLast(17) // "aa" + let regex = try! Regex(compiling: "a+") + + XCTAssertEqual(s.firstMatch(of: regex)?.0, "aaa") + XCTAssertEqual(s1.firstMatch(of: regex)?.0, "aaaaaa") + XCTAssertEqual(s2.firstMatch(of: regex)?.0, "aa") + + XCTAssertEqual( + s.ranges(of: regex).map(s.offsets(of:)), + [0..<3, 6..<12, 15..<25]) + XCTAssertEqual( + s1.ranges(of: regex).map(s.offsets(of:)), + [6..<12, 15..<25]) + XCTAssertEqual( + s2.ranges(of: regex).map(s.offsets(of:)), + [6..<8]) + + XCTAssertEqual(s.replacing(regex, with: ""), " | | ") + XCTAssertEqual(s1.replacing(regex, with: ""), " | ") + XCTAssertEqual(s2.replacing(regex, with: ""), "") + + XCTAssertEqual( + s._matches(of: regex).map(\.0), + ["aaa", "aaaaaa", "aaaaaaaaaa"]) + XCTAssertEqual( + s1._matches(of: regex).map(\.0), + ["aaaaaa", "aaaaaaaaaa"]) + XCTAssertEqual( + s2._matches(of: regex).map(\.0), + ["aa"]) + } } From d002466e7e4aa72224ea525fb0118a5853dbcae0 Mon Sep 17 00:00:00 2001 From: Richard Wei Date: Mon, 18 Apr 2022 11:31:13 -0700 Subject: [PATCH 13/17] Merge pull request #273 from itingliu/throwing-hooks Throwing matches and update to CustomMatchingRegexComponent --- .../Evolution/StringProcessingAlgorithms.md | 2 +- Sources/_StringProcessing/ByteCodeGen.swift | 4 +- .../Regex/DSLConsumers.swift | 14 +- Tests/RegexBuilderTests/CustomTests.swift | 249 +++++++++++++++++- Tests/RegexBuilderTests/RegexDSLTests.swift | 8 +- 5 files changed, 263 insertions(+), 14 deletions(-) diff --git a/Documentation/Evolution/StringProcessingAlgorithms.md b/Documentation/Evolution/StringProcessingAlgorithms.md index 9454396ce..b976c562e 100644 --- a/Documentation/Evolution/StringProcessingAlgorithms.md +++ b/Documentation/Evolution/StringProcessingAlgorithms.md @@ -187,7 +187,7 @@ public protocol CustomMatchingRegexComponent : RegexComponent { _ input: String, startingAt index: String.Index, in bounds: Range - ) -> (upperBound: String.Index, match: Match)? + ) throws -> (upperBound: String.Index, match: Match)? } ``` diff --git a/Sources/_StringProcessing/ByteCodeGen.swift b/Sources/_StringProcessing/ByteCodeGen.swift index 70233cf4f..29d23a842 100644 --- a/Sources/_StringProcessing/ByteCodeGen.swift +++ b/Sources/_StringProcessing/ByteCodeGen.swift @@ -299,7 +299,9 @@ extension Compiler.ByteCodeGen { // not captured. This may mean we should store // an existential instead of a closure... - let matcher = builder.makeMatcherFunction(matcher) + let matcher = builder.makeMatcherFunction { input, start, range in + try matcher(input, start, range) + } let valReg = builder.makeValueRegister() builder.buildMatcher(matcher, into: valReg) diff --git a/Sources/_StringProcessing/Regex/DSLConsumers.swift b/Sources/_StringProcessing/Regex/DSLConsumers.swift index e1a69d74b..ea46c789b 100644 --- a/Sources/_StringProcessing/Regex/DSLConsumers.swift +++ b/Sources/_StringProcessing/Regex/DSLConsumers.swift @@ -10,19 +10,21 @@ //===----------------------------------------------------------------------===// @available(SwiftStdlib 5.7, *) -public protocol CustomRegexComponent: RegexComponent { +public protocol CustomMatchingRegexComponent: RegexComponent { func match( _ input: String, startingAt index: String.Index, in bounds: Range - ) -> (upperBound: String.Index, output: RegexOutput)? + ) throws -> (upperBound: String.Index, output: RegexOutput)? } @available(SwiftStdlib 5.7, *) -extension CustomRegexComponent { +extension CustomMatchingRegexComponent { public var regex: Regex { - Regex(node: .matcher(.init(RegexOutput.self), { input, index, bounds in - match(input, startingAt: index, in: bounds) - })) + + let node: DSLTree.Node = .matcher(.init(RegexOutput.self), { input, index, bounds in + try match(input, startingAt: index, in: bounds) + }) + return Regex(node: node) } } diff --git a/Tests/RegexBuilderTests/CustomTests.swift b/Tests/RegexBuilderTests/CustomTests.swift index 0ac6b46c5..0a7d6fc59 100644 --- a/Tests/RegexBuilderTests/CustomTests.swift +++ b/Tests/RegexBuilderTests/CustomTests.swift @@ -14,7 +14,7 @@ import _StringProcessing @testable import RegexBuilder // A nibbler processes a single character from a string -private protocol Nibbler: CustomRegexComponent { +private protocol Nibbler: CustomMatchingRegexComponent { func nibble(_: Character) -> RegexOutput? } @@ -24,7 +24,7 @@ extension Nibbler { _ input: String, startingAt index: String.Index, in bounds: Range - ) -> (upperBound: String.Index, output: RegexOutput)? { + ) throws -> (upperBound: String.Index, output: RegexOutput)? { guard index != bounds.upperBound, let res = nibble(input[index]) else { return nil } @@ -49,6 +49,69 @@ private struct Asciibbler: Nibbler { } } +private struct IntParser: CustomMatchingRegexComponent { + struct ParseError: Error, Hashable {} + typealias RegexOutput = Int + func match(_ input: String, + startingAt index: String.Index, + in bounds: Range + ) throws -> (upperBound: String.Index, output: Int)? { + guard index != bounds.upperBound else { return nil } + + let r = Regex { + Capture(OneOrMore(.digit)) { Int($0) } + } + + guard let match = input[index.. + ) throws -> (upperBound: String.Index, output: Currency)? { + + guard index != bounds.upperBound else { return nil } + + let substr = input[index..( + _ regex: Regex, + _ tests: (input: String, match: Match?, expectError: E?)..., + file: StaticString = #file, + line: UInt = #line + ) { + for (input, match, expectError) in tests { + do { + let result = try regex.wholeMatch(in: input)?.output + XCTAssertEqual(result, match) + } catch let e as E { + XCTAssertEqual(e, expectError) + } catch { + XCTFail() + } + } + } + + func customTest( + _ regex: Regex, + _ tests: (input: String, match: Match?, expectError1: Error1?, expectError2: Error2?)..., + file: StaticString = #file, + line: UInt = #line + ) { + for (input, match, expectError1, expectError2) in tests { + do { + let result = try regex.wholeMatch(in: input)?.output + XCTAssertEqual(result, match) + } catch let e as Error1 { + XCTAssertEqual(e, expectError1, input, file: file, line: line) + } catch let e as Error2 { + XCTAssertEqual(e, expectError2, input, file: file, line: line) + } catch { + XCTFail("caught error: \(error.localizedDescription)") + } + } + } + + func customTest( + _ regex: Regex<(Substring, Capture)>, + _ tests: (input: String, match: (Substring, Capture)?, expectError1: Error1?, expectError2: Error2?)..., + file: StaticString = #file, + line: UInt = #line + ) { + for (input, match, expectError1, expectError2) in tests { + do { + let result = try regex.wholeMatch(in: input)?.output + XCTAssertEqual(result?.0, match?.0, file: file, line: line) + XCTAssertEqual(result?.1, match?.1, file: file, line: line) + } catch let e as Error1 { + XCTAssertEqual(e, expectError1, input, file: file, line: line) + } catch let e as Error2 { + XCTAssertEqual(e, expectError2, input, file: file, line: line) + } catch { + XCTFail("caught error: \(error.localizedDescription)") + } + } + } + + func customTest( + _ regex: Regex<(Substring, Capture1, Capture2)>, + _ tests: (input: String, match: (Substring, Capture1, Capture2)?, expectError1: Error1?, expectError2: Error2?)..., + file: StaticString = #file, + line: UInt = #line + ) { + for (input, match, expectError1, expectError2) in tests { + do { + let result = try regex.wholeMatch(in: input)?.output + XCTAssertEqual(result?.0, match?.0, file: file, line: line) + XCTAssertEqual(result?.1, match?.1, file: file, line: line) + XCTAssertEqual(result?.2, match?.2, file: file, line: line) + } catch let e as Error1 { + XCTAssertEqual(e, expectError1, input, file: file, line: line) + } catch let e as Error2 { + XCTAssertEqual(e, expectError2, input, file: file, line: line) + } catch { + XCTFail("caught error: \(error.localizedDescription)") + } + } + } + + // No capture, one error + customTest( + Regex { + IntParser() + }, + ("zzz", nil, IntParser.ParseError()), + ("x10x", nil, IntParser.ParseError()), + ("30", 30, nil) + ) + + customTest( + Regex { + CurrencyParser() + }, + ("USD", .usd, nil), + ("NTD", .ntd, nil), + ("NTD USD", nil, nil), + ("DEM", nil, CurrencyParser.ParseError.deprecated), + ("XXX", nil, CurrencyParser.ParseError.unrecognized) + ) + + // No capture, two errors + customTest( + Regex { + IntParser() + " " + IntParser() + }, + ("20304 100", "20304 100", nil, nil), + ("20304.445 200", nil, IntParser.ParseError(), nil), + ("20304 200.123", nil, nil, IntParser.ParseError()), + ("20304.445 200.123", nil, IntParser.ParseError(), IntParser.ParseError()) + ) + + customTest( + Regex { + CurrencyParser() + IntParser() + }, + ("USD100", "USD100", nil, nil), + ("XXX100", nil, CurrencyParser.ParseError.unrecognized, nil), + ("USD100.000", nil, nil, IntParser.ParseError()), + ("XXX100.0000", nil, CurrencyParser.ParseError.unrecognized, IntParser.ParseError()) + ) + + // One capture, two errors: One error is thrown from inside a capture, + // while the other one is thrown from outside + customTest( + Regex { + Capture { CurrencyParser() } + IntParser() + }, + ("USD100", ("USD100", .usd), nil, nil), + ("NTD305.5", nil, nil, IntParser.ParseError()), + ("DEM200", ("DEM200", .dem), CurrencyParser.ParseError.deprecated, nil), + ("XXX", nil, CurrencyParser.ParseError.unrecognized, IntParser.ParseError()) + ) + + customTest( + Regex { + CurrencyParser() + Capture { IntParser() } + }, + ("USD100", ("USD100", 100), nil, nil), + ("NTD305.5", nil, nil, IntParser.ParseError()), + ("DEM200", ("DEM200", 200), CurrencyParser.ParseError.deprecated, nil), + ("XXX", nil, CurrencyParser.ParseError.unrecognized, IntParser.ParseError()) + ) + + // One capture, two errors: Both errors are thrown from inside the capture + customTest( + Regex { + Capture { + CurrencyParser() + IntParser() + } + }, + ("USD100", ("USD100", "USD100"), nil, nil), + ("NTD305.5", nil, nil, IntParser.ParseError()), + ("DEM200", ("DEM200", "DEM200"), CurrencyParser.ParseError.deprecated, nil), + ("XXX", nil, CurrencyParser.ParseError.unrecognized, IntParser.ParseError()) + ) + + // Two captures, two errors: Different erros are thrown from inside captures + customTest( + Regex { + Capture(CurrencyParser()) + Capture(IntParser()) + }, + ("USD100", ("USD100", .usd, 100), nil, nil), + ("NTD500", ("NTD500", .ntd, 500), nil, nil), + ("XXX20", nil, CurrencyParser.ParseError.unrecognized, IntParser.ParseError()), + ("DEM500", nil, CurrencyParser.ParseError.deprecated, nil), + ("DEM500.345", nil, CurrencyParser.ParseError.deprecated, IntParser.ParseError()), + ("NTD100.345", nil, nil, IntParser.ParseError()) + ) + + } } diff --git a/Tests/RegexBuilderTests/RegexDSLTests.swift b/Tests/RegexBuilderTests/RegexDSLTests.swift index b38b82a33..8159ba8ae 100644 --- a/Tests/RegexBuilderTests/RegexDSLTests.swift +++ b/Tests/RegexBuilderTests/RegexDSLTests.swift @@ -743,13 +743,13 @@ class RegexDSLTests: XCTestCase { var patch: Int var dev: String? } - struct SemanticVersionParser: CustomRegexComponent { + struct SemanticVersionParser: CustomMatchingRegexComponent { typealias RegexOutput = SemanticVersion func match( _ input: String, startingAt index: String.Index, in bounds: Range - ) -> (upperBound: String.Index, output: SemanticVersion)? { + ) throws -> (upperBound: String.Index, output: SemanticVersion)? { let regex = Regex { TryCapture(OneOrMore(.digit)) { Int($0) } "." @@ -776,13 +776,13 @@ class RegexDSLTests: XCTestCase { return (match.range.upperBound, result) } } - + let versions = [ ("1.0", SemanticVersion(major: 1, minor: 0, patch: 0)), ("1.0.1", SemanticVersion(major: 1, minor: 0, patch: 1)), ("12.100.5-dev", SemanticVersion(major: 12, minor: 100, patch: 5, dev: "dev")), ] - + let parser = SemanticVersionParser() for (str, version) in versions { XCTAssertEqual(str.wholeMatch(of: parser)?.output, version) From 3c432863d42723cb226cf2f1a634512b8225335d Mon Sep 17 00:00:00 2001 From: Nate Cook Date: Mon, 18 Apr 2022 14:47:39 -0500 Subject: [PATCH 14/17] RegexBuilder quantifiers take an optional behavior (#293) --- Sources/RegexBuilder/DSL.swift | 16 +- Sources/RegexBuilder/Variadics.swift | 440 ++++++++++-------- .../VariadicsGenerator.swift | 20 +- Sources/_StringProcessing/ByteCodeGen.swift | 18 +- .../_StringProcessing/PrintAsPattern.swift | 11 + .../Regex/ASTConversion.swift | 2 +- Sources/_StringProcessing/Regex/DSLTree.swift | 12 +- Sources/_StringProcessing/Regex/Options.swift | 59 ++- Tests/RegexBuilderTests/RegexDSLTests.swift | 20 +- 9 files changed, 355 insertions(+), 243 deletions(-) diff --git a/Sources/RegexBuilder/DSL.swift b/Sources/RegexBuilder/DSL.swift index 3c5f5ab5f..86ec0bee5 100644 --- a/Sources/RegexBuilder/DSL.swift +++ b/Sources/RegexBuilder/DSL.swift @@ -120,27 +120,29 @@ extension DSLTree.Node { @available(SwiftStdlib 5.7, *) static func repeating( _ range: Range, - _ behavior: QuantificationBehavior, + _ behavior: QuantificationBehavior?, _ node: DSLTree.Node ) -> DSLTree.Node { // TODO: Throw these as errors assert(range.lowerBound >= 0, "Cannot specify a negative lower bound") assert(!range.isEmpty, "Cannot specify an empty range") + + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default switch (range.lowerBound, range.upperBound) { case (0, Int.max): // 0... - return .quantification(.zeroOrMore, behavior.astKind, node) + return .quantification(.zeroOrMore, kind, node) case (1, Int.max): // 1... - return .quantification(.oneOrMore, behavior.astKind, node) + return .quantification(.oneOrMore, kind, node) case _ where range.count == 1: // ..<1 or ...0 or any range with count == 1 // Note: `behavior` is ignored in this case - return .quantification(.exactly(.init(faking: range.lowerBound)), .eager, node) + return .quantification(.exactly(.init(faking: range.lowerBound)), .default, node) case (0, _): // 0..( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == Substring { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component.regex.root)) } } @@ -627,10 +628,11 @@ extension Optionally { @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == Substring { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component().regex.root)) } } @@ -640,7 +642,7 @@ extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component ) -> Regex { - .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) + .init(node: .quantification(.zeroOrOne, .default, component.regex.root)) } } @available(SwiftStdlib 5.7, *) @@ -649,9 +651,10 @@ extension ZeroOrMore { @_disfavoredOverload public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == Substring { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component.regex.root)) } } @@ -660,10 +663,11 @@ extension ZeroOrMore { @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == Substring { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component().regex.root)) } } @@ -674,9 +678,10 @@ extension OneOrMore { @_disfavoredOverload public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == Substring { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component.regex.root)) } } @@ -685,10 +690,11 @@ extension OneOrMore { @available(SwiftStdlib 5.7, *) @_disfavoredOverload public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == Substring { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component().regex.root)) } } @@ -703,7 +709,7 @@ extension Repeat { ) where RegexOutput == Substring { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root)) } @available(SwiftStdlib 5.7, *) @@ -714,7 +720,7 @@ extension Repeat { ) where RegexOutput == Substring { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root)) } @available(SwiftStdlib 5.7, *) @@ -722,7 +728,7 @@ extension Repeat { public init( _ component: Component, _ expression: R, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == Substring, R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == Substring, R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component.regex.root)) } } @@ -752,10 +759,11 @@ extension Optionally { extension Optionally { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component().regex.root)) } } @@ -765,7 +773,7 @@ extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?)> where Component.RegexOutput == (W, C0) { - .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) + .init(node: .quantification(.zeroOrOne, .default, component.regex.root)) } } @available(SwiftStdlib 5.7, *) @@ -773,9 +781,10 @@ extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component.regex.root)) } } @@ -783,10 +792,11 @@ extension ZeroOrMore { extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component().regex.root)) } } @@ -796,9 +806,10 @@ extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0), Component.RegexOutput == (W, C0) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component.regex.root)) } } @@ -806,10 +817,11 @@ extension OneOrMore { extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0), Component.RegexOutput == (W, C0) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component().regex.root)) } } @@ -823,7 +835,7 @@ extension Repeat { ) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root)) } @available(SwiftStdlib 5.7, *) @@ -833,14 +845,14 @@ extension Repeat { ) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root)) } @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component.regex.root)) } } @@ -869,10 +882,11 @@ extension Optionally { extension Optionally { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component().regex.root)) } } @@ -882,7 +896,7 @@ extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?)> where Component.RegexOutput == (W, C0, C1) { - .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) + .init(node: .quantification(.zeroOrOne, .default, component.regex.root)) } } @available(SwiftStdlib 5.7, *) @@ -890,9 +904,10 @@ extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component.regex.root)) } } @@ -900,10 +915,11 @@ extension ZeroOrMore { extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component().regex.root)) } } @@ -913,9 +929,10 @@ extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0, C1), Component.RegexOutput == (W, C0, C1) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component.regex.root)) } } @@ -923,10 +940,11 @@ extension OneOrMore { extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1), Component.RegexOutput == (W, C0, C1) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component().regex.root)) } } @@ -940,7 +958,7 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root)) } @available(SwiftStdlib 5.7, *) @@ -950,14 +968,14 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root)) } @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component.regex.root)) } } @@ -986,10 +1005,11 @@ extension Optionally { extension Optionally { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component().regex.root)) } } @@ -999,7 +1019,7 @@ extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?, C2?)> where Component.RegexOutput == (W, C0, C1, C2) { - .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) + .init(node: .quantification(.zeroOrOne, .default, component.regex.root)) } } @available(SwiftStdlib 5.7, *) @@ -1007,9 +1027,10 @@ extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component.regex.root)) } } @@ -1017,10 +1038,11 @@ extension ZeroOrMore { extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component().regex.root)) } } @@ -1030,9 +1052,10 @@ extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0, C1, C2), Component.RegexOutput == (W, C0, C1, C2) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component.regex.root)) } } @@ -1040,10 +1063,11 @@ extension OneOrMore { extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1, C2), Component.RegexOutput == (W, C0, C1, C2) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component().regex.root)) } } @@ -1057,7 +1081,7 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root)) } @available(SwiftStdlib 5.7, *) @@ -1067,14 +1091,14 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root)) } @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component.regex.root)) } } @@ -1103,10 +1128,11 @@ extension Optionally { extension Optionally { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component().regex.root)) } } @@ -1116,7 +1142,7 @@ extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?, C2?, C3?)> where Component.RegexOutput == (W, C0, C1, C2, C3) { - .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) + .init(node: .quantification(.zeroOrOne, .default, component.regex.root)) } } @available(SwiftStdlib 5.7, *) @@ -1124,9 +1150,10 @@ extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component.regex.root)) } } @@ -1134,10 +1161,11 @@ extension ZeroOrMore { extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component().regex.root)) } } @@ -1147,9 +1175,10 @@ extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0, C1, C2, C3), Component.RegexOutput == (W, C0, C1, C2, C3) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component.regex.root)) } } @@ -1157,10 +1186,11 @@ extension OneOrMore { extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1, C2, C3), Component.RegexOutput == (W, C0, C1, C2, C3) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component().regex.root)) } } @@ -1174,7 +1204,7 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root)) } @available(SwiftStdlib 5.7, *) @@ -1184,14 +1214,14 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root)) } @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component.regex.root)) } } @@ -1220,10 +1251,11 @@ extension Optionally { extension Optionally { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component().regex.root)) } } @@ -1233,7 +1265,7 @@ extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4) { - .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) + .init(node: .quantification(.zeroOrOne, .default, component.regex.root)) } } @available(SwiftStdlib 5.7, *) @@ -1241,9 +1273,10 @@ extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component.regex.root)) } } @@ -1251,10 +1284,11 @@ extension ZeroOrMore { extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component().regex.root)) } } @@ -1264,9 +1298,10 @@ extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0, C1, C2, C3, C4), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component.regex.root)) } } @@ -1274,10 +1309,11 @@ extension OneOrMore { extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component().regex.root)) } } @@ -1291,7 +1327,7 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root)) } @available(SwiftStdlib 5.7, *) @@ -1301,14 +1337,14 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root)) } @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component.regex.root)) } } @@ -1337,10 +1374,11 @@ extension Optionally { extension Optionally { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component().regex.root)) } } @@ -1350,7 +1388,7 @@ extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { - .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) + .init(node: .quantification(.zeroOrOne, .default, component.regex.root)) } } @available(SwiftStdlib 5.7, *) @@ -1358,9 +1396,10 @@ extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component.regex.root)) } } @@ -1368,10 +1407,11 @@ extension ZeroOrMore { extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component().regex.root)) } } @@ -1381,9 +1421,10 @@ extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component.regex.root)) } } @@ -1391,10 +1432,11 @@ extension OneOrMore { extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component().regex.root)) } } @@ -1408,7 +1450,7 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root)) } @available(SwiftStdlib 5.7, *) @@ -1418,14 +1460,14 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root)) } @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component.regex.root)) } } @@ -1454,10 +1497,11 @@ extension Optionally { extension Optionally { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component().regex.root)) } } @@ -1467,7 +1511,7 @@ extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { - .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) + .init(node: .quantification(.zeroOrOne, .default, component.regex.root)) } } @available(SwiftStdlib 5.7, *) @@ -1475,9 +1519,10 @@ extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component.regex.root)) } } @@ -1485,10 +1530,11 @@ extension ZeroOrMore { extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component().regex.root)) } } @@ -1498,9 +1544,10 @@ extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component.regex.root)) } } @@ -1508,10 +1555,11 @@ extension OneOrMore { extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component().regex.root)) } } @@ -1525,7 +1573,7 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root)) } @available(SwiftStdlib 5.7, *) @@ -1535,14 +1583,14 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root)) } @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component.regex.root)) } } @@ -1571,10 +1620,11 @@ extension Optionally { extension Optionally { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component().regex.root)) } } @@ -1584,7 +1634,7 @@ extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { - .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) + .init(node: .quantification(.zeroOrOne, .default, component.regex.root)) } } @available(SwiftStdlib 5.7, *) @@ -1592,9 +1642,10 @@ extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component.regex.root)) } } @@ -1602,10 +1653,11 @@ extension ZeroOrMore { extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component().regex.root)) } } @@ -1615,9 +1667,10 @@ extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component.regex.root)) } } @@ -1625,10 +1678,11 @@ extension OneOrMore { extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component().regex.root)) } } @@ -1642,7 +1696,7 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root)) } @available(SwiftStdlib 5.7, *) @@ -1652,14 +1706,14 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root)) } @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component.regex.root)) } } @@ -1688,10 +1743,11 @@ extension Optionally { extension Optionally { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component().regex.root)) } } @@ -1701,7 +1757,7 @@ extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { - .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) + .init(node: .quantification(.zeroOrOne, .default, component.regex.root)) } } @available(SwiftStdlib 5.7, *) @@ -1709,9 +1765,10 @@ extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component.regex.root)) } } @@ -1719,10 +1776,11 @@ extension ZeroOrMore { extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component().regex.root)) } } @@ -1732,9 +1790,10 @@ extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component.regex.root)) } } @@ -1742,10 +1801,11 @@ extension OneOrMore { extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component().regex.root)) } } @@ -1759,7 +1819,7 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root)) } @available(SwiftStdlib 5.7, *) @@ -1769,14 +1829,14 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root)) } @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component.regex.root)) } } @@ -1805,10 +1866,11 @@ extension Optionally { extension Optionally { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { - self.init(node: .quantification(.zeroOrOne, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrOne, kind, component().regex.root)) } } @@ -1818,7 +1880,7 @@ extension RegexComponentBuilder { public static func buildLimitedAvailability( _ component: Component ) -> Regex<(Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?)> where Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { - .init(node: .quantification(.zeroOrOne, .eager, component.regex.root)) + .init(node: .quantification(.zeroOrOne, .default, component.regex.root)) } } @available(SwiftStdlib 5.7, *) @@ -1826,9 +1888,10 @@ extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component.regex.root)) } } @@ -1836,10 +1899,11 @@ extension ZeroOrMore { extension ZeroOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { - self.init(node: .quantification(.zeroOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.zeroOrMore, kind, component().regex.root)) } } @@ -1849,9 +1913,10 @@ extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component.regex.root)) } } @@ -1859,10 +1924,11 @@ extension OneOrMore { extension OneOrMore { @available(SwiftStdlib 5.7, *) public init( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { - self.init(node: .quantification(.oneOrMore, behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.oneOrMore, kind, component().regex.root)) } } @@ -1876,7 +1942,7 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root)) } @available(SwiftStdlib 5.7, *) @@ -1886,14 +1952,14 @@ extension Repeat { ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root)) } @available(SwiftStdlib 5.7, *) public init( _ component: Component, _ expression: R, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @RegexComponentBuilder _ component: () -> Component ) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?, C9?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), R.Bound == Int { self.init(node: .repeating(expression.relative(to: 0..( _ component: Component, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) \(params.whereClauseForInit) { - self.init(node: .quantification(.\(kind.astQuantifierAmount), behavior.astKind, component.regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.\(kind.astQuantifierAmount), kind, component.regex.root)) } } @@ -389,10 +390,11 @@ struct VariadicsGenerator: ParsableCommand { \(defaultAvailableAttr) \(params.disfavored)\ public init<\(params.genericParams)>( - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @\(concatBuilderName) _ component: () -> Component ) \(params.whereClauseForInit) { - self.init(node: .quantification(.\(kind.astQuantifierAmount), behavior.astKind, component().regex.root)) + let kind: DSLTree.QuantificationKind = behavior.map { .explicit($0.astKind) } ?? .default + self.init(node: .quantification(.\(kind.astQuantifierAmount), kind, component().regex.root)) } } @@ -404,7 +406,7 @@ struct VariadicsGenerator: ParsableCommand { public static func buildLimitedAvailability<\(params.genericParams)>( _ component: Component ) -> \(regexTypeName)<\(params.matchType)> \(params.whereClause) { - .init(node: .quantification(.\(kind.astQuantifierAmount), .eager, component.regex.root)) + .init(node: .quantification(.\(kind.astQuantifierAmount), .default, component.regex.root)) } } """ : "") @@ -488,7 +490,7 @@ struct VariadicsGenerator: ParsableCommand { ) \(params.whereClauseForInit) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component.regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root)) } \(defaultAvailableAttr) @@ -499,7 +501,7 @@ struct VariadicsGenerator: ParsableCommand { ) \(params.whereClauseForInit) { assert(count > 0, "Must specify a positive count") // TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)` - self.init(node: .quantification(.exactly(.init(faking: count)), .eager, component().regex.root)) + self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root)) } \(defaultAvailableAttr) @@ -507,7 +509,7 @@ struct VariadicsGenerator: ParsableCommand { public init<\(params.genericParams), R: RangeExpression>( _ component: Component, _ expression: R, - _ behavior: QuantificationBehavior = .eagerly + _ behavior: QuantificationBehavior? = nil ) \(params.repeatingWhereClause) { self.init(node: .repeating(expression.relative(to: 0..( _ expression: R, - _ behavior: QuantificationBehavior = .eagerly, + _ behavior: QuantificationBehavior? = nil, @\(concatBuilderName) _ component: () -> Component ) \(params.repeatingWhereClause) { self.init(node: .repeating(expression.relative(to: 0.. Regex { + wrapInOption(.multiline, addingIf: matchLineEndings) + } + + /// Returns a regular expression where quantifiers are reluctant by default + /// instead of eager. + /// + /// This method corresponds to applying the `U` option in a regular + /// expression literal. + /// + /// - Parameter useReluctantQuantifiers: A Boolean value indicating whether + /// quantifiers should be reluctant by default. + public func reluctantQuantifiers(_ useReluctantQuantifiers: Bool = true) -> Regex { + wrapInOption(.reluctantByDefault, addingIf: useReluctantQuantifiers) + } + /// Returns a regular expression that matches with the specified semantic /// level. /// @@ -128,39 +154,6 @@ public struct RegexSemanticLevel: Hashable { } } -// Options that only affect literals -@available(SwiftStdlib 5.7, *) -extension RegexComponent { - /// Returns a regular expression where the start and end of input - /// anchors (`^` and `$`) also match against the start and end of a line. - /// - /// This method corresponds to applying the `m` option in a regular - /// expression literal, and only applies to regular expressions specified as - /// literals. For this behavior in the `RegexBuilder` syntax, see - /// ``Anchor.startOfLine``, ``Anchor.endOfLine``, ``Anchor.startOfInput``, - /// and ``Anchor.endOfInput``. - /// - /// - Parameter matchLineEndings: A Boolean value indicating whether `^` and - /// `$` should match the start and end of lines, respectively. - public func anchorsMatchLineEndings(_ matchLineEndings: Bool = true) -> Regex { - wrapInOption(.multiline, addingIf: matchLineEndings) - } - - /// Returns a regular expression where quantifiers are reluctant by default - /// instead of eager. - /// - /// This method corresponds to applying the `U` option in a regular - /// expression literal, and only applies to regular expressions specified as - /// literals. In the `RegexBuilder` syntax, pass a ``QuantificationBehavior`` - /// value to any quantification method to change its behavior. - /// - /// - Parameter useReluctantCaptures: A Boolean value indicating whether - /// quantifiers should be reluctant by default. - public func reluctantCaptures(_ useReluctantCaptures: Bool = true) -> Regex { - wrapInOption(.reluctantByDefault, addingIf: useReluctantCaptures) - } -} - // MARK: - Helper method @available(SwiftStdlib 5.7, *) diff --git a/Tests/RegexBuilderTests/RegexDSLTests.swift b/Tests/RegexBuilderTests/RegexDSLTests.swift index 8159ba8ae..3d8c4fc2c 100644 --- a/Tests/RegexBuilderTests/RegexDSLTests.swift +++ b/Tests/RegexBuilderTests/RegexDSLTests.swift @@ -262,6 +262,24 @@ class RegexDSLTests: XCTestCase { } .ignoringCase(false) } + + try _testDSLCaptures( + ("abcdef123", ("abcdef123", "a", "123")), + matchType: (Substring, Substring, Substring).self, ==) { + Capture { + // Reluctant behavior due to option + OneOrMore(.anyOf("abcd")) + .reluctantQuantifiers() + } + ZeroOrMore("a"..."z") + + Capture { + // Eager behavior due to explicit parameter, despite option + OneOrMore(.digit, .eagerly) + .reluctantQuantifiers() + } + ZeroOrMore(.digit) + } } func testQuantificationBehavior() throws { @@ -293,7 +311,7 @@ class RegexDSLTests: XCTestCase { OneOrMore(.word) Capture(.digit) ZeroOrMore(.any) - }.reluctantCaptures() + }.reluctantQuantifiers() } } #endif From 0d41bb221f341fd2963d30527df2e90bd0c59e1c Mon Sep 17 00:00:00 2001 From: Nate Cook Date: Mon, 18 Apr 2022 15:46:21 -0500 Subject: [PATCH 15/17] Nominalize option methods (#295) --- Sources/_StringProcessing/Regex/Options.swift | 57 ++++++++++++++----- Tests/RegexBuilderTests/RegexDSLTests.swift | 46 +++++++++++++-- Tests/RegexTests/MatchTests.swift | 2 +- 3 files changed, 85 insertions(+), 20 deletions(-) diff --git a/Sources/_StringProcessing/Regex/Options.swift b/Sources/_StringProcessing/Regex/Options.swift index 4f017685f..9642fa3f2 100644 --- a/Sources/_StringProcessing/Regex/Options.swift +++ b/Sources/_StringProcessing/Regex/Options.swift @@ -14,40 +14,36 @@ import _RegexParser @available(SwiftStdlib 5.7, *) extension RegexComponent { /// Returns a regular expression that ignores casing when matching. - public func ignoringCase(_ ignoreCase: Bool = true) -> Regex { - wrapInOption(.caseInsensitive, addingIf: ignoreCase) + public func ignoresCase(_ ignoresCase: Bool = true) -> Regex { + wrapInOption(.caseInsensitive, addingIf: ignoresCase) } /// Returns a regular expression that only matches ASCII characters as "word /// characters". - public func usingASCIIWordCharacters(_ useASCII: Bool = true) -> Regex { - wrapInOption(.asciiOnlyDigit, addingIf: useASCII) + public func asciiOnlyWordCharacters(_ useASCII: Bool = true) -> Regex { + wrapInOption(.asciiOnlyWord, addingIf: useASCII) } /// Returns a regular expression that only matches ASCII characters as digits. - public func usingASCIIDigits(_ useASCII: Bool = true) -> Regex { + public func asciiOnlyDigits(_ useASCII: Bool = true) -> Regex { wrapInOption(.asciiOnlyDigit, addingIf: useASCII) } /// Returns a regular expression that only matches ASCII characters as space /// characters. - public func usingASCIISpaces(_ useASCII: Bool = true) -> Regex { + public func asciiOnlyWhitespace(_ useASCII: Bool = true) -> Regex { wrapInOption(.asciiOnlySpace, addingIf: useASCII) } /// Returns a regular expression that only matches ASCII characters when /// matching character classes. - public func usingASCIICharacterClasses(_ useASCII: Bool = true) -> Regex { + public func asciiOnlyCharacterClasses(_ useASCII: Bool = true) -> Regex { wrapInOption(.asciiOnlyPOSIXProps, addingIf: useASCII) } - /// Returns a regular expression that uses the Unicode word boundary - /// algorithm. - /// - /// This option is enabled by default; pass `false` to disable use of - /// Unicode's word boundary algorithm. - public func usingUnicodeWordBoundaries(_ useUnicodeWordBoundaries: Bool = true) -> Regex { - wrapInOption(.unicodeWordBoundaries, addingIf: useUnicodeWordBoundaries) + /// Returns a regular expression that uses the specified word boundary algorithm. + public func wordBoundaryKind(_ wordBoundaryKind: RegexWordBoundaryKind) -> Regex { + wrapInOption(.unicodeWordBoundaries, addingIf: wordBoundaryKind == .unicodeLevel2) } /// Returns a regular expression where the start and end of input @@ -133,6 +129,7 @@ extension RegexComponent { } @available(SwiftStdlib 5.7, *) +/// A semantic level to use during regex matching. public struct RegexSemanticLevel: Hashable { internal enum Representation { case graphemeCluster @@ -154,6 +151,38 @@ public struct RegexSemanticLevel: Hashable { } } +@available(SwiftStdlib 5.7, *) +/// A word boundary algorithm to use during regex matching. +public struct RegexWordBoundaryKind: Hashable { + internal enum Representation { + case unicodeLevel1 + case unicodeLevel2 + } + + internal var base: Representation + + /// A word boundary algorithm that implements the "simple word boundary" + /// Unicode recommendation. + /// + /// A simple word boundary is a position in the input between two characters + /// that match `/\w\W/` or `/\W\w/`, or between the start or end of the input + /// and a `\w` character. Word boundaries therefore depend on the option- + /// defined behavior of `\w`. + public static var unicodeLevel1: Self { + .init(base: .unicodeLevel1) + } + + /// A word boundary algorithm that implements the "default word boundary" + /// Unicode recommendation. + /// + /// Default word boundaries use a Unicode algorithm that handles some cases + /// better than simple word boundaries, such as words with internal + /// punctuation, changes in script, and Emoji. + public static var unicodeLevel2: Self { + .init(base: .unicodeLevel2) + } +} + // MARK: - Helper method @available(SwiftStdlib 5.7, *) diff --git a/Tests/RegexBuilderTests/RegexDSLTests.swift b/Tests/RegexBuilderTests/RegexDSLTests.swift index 3d8c4fc2c..897bca8f7 100644 --- a/Tests/RegexBuilderTests/RegexDSLTests.swift +++ b/Tests/RegexBuilderTests/RegexDSLTests.swift @@ -228,7 +228,7 @@ class RegexDSLTests: XCTestCase { matchType: Substring.self, ==) { OneOrMore { "abc" - }.ignoringCase(true) + }.ignoresCase(true) } // Multiple options on one component wrap successively, but do not @@ -242,8 +242,8 @@ class RegexDSLTests: XCTestCase { OneOrMore { "abc" } - .ignoringCase(true) - .ignoringCase(false) + .ignoresCase(true) + .ignoresCase(false) } // An option on an outer component doesn't override an option set on an @@ -257,12 +257,36 @@ class RegexDSLTests: XCTestCase { ("abcdeABCdeaBcde", "abcdeABCdeaBcde"), matchType: Substring.self, ==) { OneOrMore { - "abc".ignoringCase(true) + "abc".ignoresCase(true) Optionally("de") } - .ignoringCase(false) + .ignoresCase(false) } +#if os(macOS) + try XCTExpectFailure("Implement level 2 word boundaries") { + try _testDSLCaptures( + ("can't stop won't stop", ("can't stop won't stop", "can't", "won")), + matchType: (Substring, Substring, Substring).self, ==) { + Capture { + OneOrMore(.word) + Anchor.wordBoundary + } + OneOrMore(.any, .reluctantly) + "stop" + " " + + Capture { + OneOrMore(.word) + Anchor.wordBoundary + } + .wordBoundaryKind(.unicodeLevel1) + OneOrMore(.any, .reluctantly) + "stop" + } + } +#endif + try _testDSLCaptures( ("abcdef123", ("abcdef123", "a", "123")), matchType: (Substring, Substring, Substring).self, ==) { @@ -280,6 +304,18 @@ class RegexDSLTests: XCTestCase { } ZeroOrMore(.digit) } + + try _testDSLCaptures( + ("abcdefg", ("abcdefg", "abcdefg")), + ("abcdéfg", ("abcdéfg", "abcd")), + matchType: (Substring, Substring).self, ==) { + Capture { + OneOrMore(.word) + } + .asciiOnlyWordCharacters() + + ZeroOrMore(.any) + } } func testQuantificationBehavior() throws { diff --git a/Tests/RegexTests/MatchTests.swift b/Tests/RegexTests/MatchTests.swift index 494af4c7c..25218fad1 100644 --- a/Tests/RegexTests/MatchTests.swift +++ b/Tests/RegexTests/MatchTests.swift @@ -1308,7 +1308,7 @@ extension RegexTests { XCTAssertTrue ("cafe".contains(regex)) XCTAssertFalse("CaFe".contains(regex)) - let caseInsensitiveRegex = regex.ignoringCase() + let caseInsensitiveRegex = regex.ignoresCase() XCTAssertTrue("cafe".contains(caseInsensitiveRegex)) XCTAssertTrue("CaFe".contains(caseInsensitiveRegex)) } From 3cd65cd5237ad01245fe550d240fd36008522a4f Mon Sep 17 00:00:00 2001 From: Richard Wei Date: Fri, 15 Apr 2022 14:31:25 -0700 Subject: [PATCH 16/17] Merge pull request #287 from apple/impl-import Import _RegexParser as implementation only --- Sources/_StringProcessing/ByteCodeGen.swift | 2 +- Sources/_StringProcessing/Capture.swift | 2 +- Sources/_StringProcessing/Compiler.swift | 2 +- Sources/_StringProcessing/ConsumerInterface.swift | 2 +- Sources/_StringProcessing/Engine/MEBuilder.swift | 2 +- Sources/_StringProcessing/Engine/MECapture.swift | 2 +- Sources/_StringProcessing/Engine/MEProgram.swift | 2 +- Sources/_StringProcessing/Engine/Registers.swift | 2 +- Sources/_StringProcessing/Engine/Structuralize.swift | 2 +- Sources/_StringProcessing/Executor.swift | 2 +- Sources/_StringProcessing/MatchingOptions.swift | 2 +- Sources/_StringProcessing/PrintAsPattern.swift | 3 ++- Sources/_StringProcessing/Regex/ASTConversion.swift | 2 +- Sources/_StringProcessing/Regex/AnyRegexOutput.swift | 2 +- Sources/_StringProcessing/Regex/Core.swift | 2 +- Sources/_StringProcessing/Regex/DSLTree.swift | 2 +- Sources/_StringProcessing/Regex/Options.swift | 2 +- Sources/_StringProcessing/Utility/ASTBuilder.swift | 2 +- Sources/_StringProcessing/_CharacterClassModel.swift | 2 +- 19 files changed, 20 insertions(+), 19 deletions(-) diff --git a/Sources/_StringProcessing/ByteCodeGen.swift b/Sources/_StringProcessing/ByteCodeGen.swift index 4f8a0d22d..3cc2d4039 100644 --- a/Sources/_StringProcessing/ByteCodeGen.swift +++ b/Sources/_StringProcessing/ByteCodeGen.swift @@ -1,4 +1,4 @@ -import _RegexParser +@_implementationOnly import _RegexParser extension Compiler { struct ByteCodeGen { diff --git a/Sources/_StringProcessing/Capture.swift b/Sources/_StringProcessing/Capture.swift index f7dff424e..51428acee 100644 --- a/Sources/_StringProcessing/Capture.swift +++ b/Sources/_StringProcessing/Capture.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -import _RegexParser +@_implementationOnly import _RegexParser /// A structured capture struct StructuredCapture { diff --git a/Sources/_StringProcessing/Compiler.swift b/Sources/_StringProcessing/Compiler.swift index 90192bdaf..96476f42b 100644 --- a/Sources/_StringProcessing/Compiler.swift +++ b/Sources/_StringProcessing/Compiler.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -import _RegexParser +@_implementationOnly import _RegexParser class Compiler { let tree: DSLTree diff --git a/Sources/_StringProcessing/ConsumerInterface.swift b/Sources/_StringProcessing/ConsumerInterface.swift index 987cbea96..600234e0d 100644 --- a/Sources/_StringProcessing/ConsumerInterface.swift +++ b/Sources/_StringProcessing/ConsumerInterface.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -import _RegexParser +@_implementationOnly import _RegexParser extension DSLTree.Node { /// Attempt to generate a consumer from this AST node diff --git a/Sources/_StringProcessing/Engine/MEBuilder.swift b/Sources/_StringProcessing/Engine/MEBuilder.swift index 2b849874b..7cf94f6ef 100644 --- a/Sources/_StringProcessing/Engine/MEBuilder.swift +++ b/Sources/_StringProcessing/Engine/MEBuilder.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -import _RegexParser // For errors +@_implementationOnly import _RegexParser // For errors extension MEProgram where Input.Element: Hashable { struct Builder { diff --git a/Sources/_StringProcessing/Engine/MECapture.swift b/Sources/_StringProcessing/Engine/MECapture.swift index 301212736..390af7d66 100644 --- a/Sources/_StringProcessing/Engine/MECapture.swift +++ b/Sources/_StringProcessing/Engine/MECapture.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -import _RegexParser +@_implementationOnly import _RegexParser /* diff --git a/Sources/_StringProcessing/Engine/MEProgram.swift b/Sources/_StringProcessing/Engine/MEProgram.swift index ecd67d4ba..b0f2e6a79 100644 --- a/Sources/_StringProcessing/Engine/MEProgram.swift +++ b/Sources/_StringProcessing/Engine/MEProgram.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -import _RegexParser +@_implementationOnly import _RegexParser struct MEProgram where Input.Element: Equatable { typealias ConsumeFunction = (Input, Range) -> Input.Index? diff --git a/Sources/_StringProcessing/Engine/Registers.swift b/Sources/_StringProcessing/Engine/Registers.swift index a2a5be104..bc17f1215 100644 --- a/Sources/_StringProcessing/Engine/Registers.swift +++ b/Sources/_StringProcessing/Engine/Registers.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -import _RegexParser +@_implementationOnly import _RegexParser struct SentinelValue: Hashable, CustomStringConvertible { var description: String { "" } diff --git a/Sources/_StringProcessing/Engine/Structuralize.swift b/Sources/_StringProcessing/Engine/Structuralize.swift index 02a03c09c..12d2e1242 100644 --- a/Sources/_StringProcessing/Engine/Structuralize.swift +++ b/Sources/_StringProcessing/Engine/Structuralize.swift @@ -1,4 +1,4 @@ -import _RegexParser +@_implementationOnly import _RegexParser extension CaptureStructure { var optionalCount: Int { diff --git a/Sources/_StringProcessing/Executor.swift b/Sources/_StringProcessing/Executor.swift index d911c3512..c7d4527a5 100644 --- a/Sources/_StringProcessing/Executor.swift +++ b/Sources/_StringProcessing/Executor.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -import _RegexParser +@_implementationOnly import _RegexParser struct Executor { // TODO: consider let, for now lets us toggle tracing diff --git a/Sources/_StringProcessing/MatchingOptions.swift b/Sources/_StringProcessing/MatchingOptions.swift index 0f244f1b8..8213185c1 100644 --- a/Sources/_StringProcessing/MatchingOptions.swift +++ b/Sources/_StringProcessing/MatchingOptions.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -import _RegexParser +@_implementationOnly import _RegexParser /// A type that represents the current state of regex matching options, with /// stack-based scoping. diff --git a/Sources/_StringProcessing/PrintAsPattern.swift b/Sources/_StringProcessing/PrintAsPattern.swift index 5b9b5ee38..3afc19836 100644 --- a/Sources/_StringProcessing/PrintAsPattern.swift +++ b/Sources/_StringProcessing/PrintAsPattern.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -import _RegexParser +@_implementationOnly import _RegexParser // TODO: Add an expansion level, both from top to bottom. // After `printAsCanonical` is fleshed out, these two @@ -17,6 +17,7 @@ import _RegexParser // incremental conversion, such that leaves remain // as canonical regex literals. +@_spi(PatternConverter) extension AST { /// Render as a Pattern DSL @_spi(PatternConverter) diff --git a/Sources/_StringProcessing/Regex/ASTConversion.swift b/Sources/_StringProcessing/Regex/ASTConversion.swift index 9041eea78..e00dcd806 100644 --- a/Sources/_StringProcessing/Regex/ASTConversion.swift +++ b/Sources/_StringProcessing/Regex/ASTConversion.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -import _RegexParser +@_implementationOnly import _RegexParser extension AST { var dslTree: DSLTree { diff --git a/Sources/_StringProcessing/Regex/AnyRegexOutput.swift b/Sources/_StringProcessing/Regex/AnyRegexOutput.swift index 16829ff78..06241c7ea 100644 --- a/Sources/_StringProcessing/Regex/AnyRegexOutput.swift +++ b/Sources/_StringProcessing/Regex/AnyRegexOutput.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -import _RegexParser +@_implementationOnly import _RegexParser @available(SwiftStdlib 5.7, *) extension Regex where Output == AnyRegexOutput { diff --git a/Sources/_StringProcessing/Regex/Core.swift b/Sources/_StringProcessing/Regex/Core.swift index a2cf76cd2..56a14da51 100644 --- a/Sources/_StringProcessing/Regex/Core.swift +++ b/Sources/_StringProcessing/Regex/Core.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -import _RegexParser +@_implementationOnly import _RegexParser /// A type that represents a regular expression. diff --git a/Sources/_StringProcessing/Regex/DSLTree.swift b/Sources/_StringProcessing/Regex/DSLTree.swift index b9ebdfd21..7b2ecd515 100644 --- a/Sources/_StringProcessing/Regex/DSLTree.swift +++ b/Sources/_StringProcessing/Regex/DSLTree.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -import _RegexParser +@_implementationOnly import _RegexParser @_spi(RegexBuilder) public struct DSLTree { diff --git a/Sources/_StringProcessing/Regex/Options.swift b/Sources/_StringProcessing/Regex/Options.swift index 9642fa3f2..6f38956e7 100644 --- a/Sources/_StringProcessing/Regex/Options.swift +++ b/Sources/_StringProcessing/Regex/Options.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -import _RegexParser +@_implementationOnly import _RegexParser @available(SwiftStdlib 5.7, *) extension RegexComponent { diff --git a/Sources/_StringProcessing/Utility/ASTBuilder.swift b/Sources/_StringProcessing/Utility/ASTBuilder.swift index 7a8edcd24..be9f61517 100644 --- a/Sources/_StringProcessing/Utility/ASTBuilder.swift +++ b/Sources/_StringProcessing/Utility/ASTBuilder.swift @@ -25,7 +25,7 @@ AST. */ -import _RegexParser +@_implementationOnly import _RegexParser func alt(_ asts: [AST.Node]) -> AST.Node { return .alternation( diff --git a/Sources/_StringProcessing/_CharacterClassModel.swift b/Sources/_StringProcessing/_CharacterClassModel.swift index d160abc81..c9762f00e 100644 --- a/Sources/_StringProcessing/_CharacterClassModel.swift +++ b/Sources/_StringProcessing/_CharacterClassModel.swift @@ -9,7 +9,7 @@ // //===----------------------------------------------------------------------===// -import _RegexParser +@_implementationOnly import _RegexParser // NOTE: This is a model type. We want to be able to get one from // an AST, but this isn't a natural thing to produce in the context From 51756fba608823f29f610f0ab7a5d3b4b9a7b0f8 Mon Sep 17 00:00:00 2001 From: Michael Ilseman Date: Wed, 20 Apr 2022 16:13:31 -0600 Subject: [PATCH 17/17] Remove compiling argument label --- .../Evolution/RegexSyntaxRunTimeConstruction.md | 4 ++-- Documentation/Evolution/RegexTypeOverview.md | 6 +++--- Sources/Exercises/Participants/RegexParticipant.swift | 2 +- Sources/_StringProcessing/Regex/AnyRegexOutput.swift | 4 ++-- Sources/_StringProcessing/Regex/Core.swift | 2 +- Tests/RegexBuilderTests/MotivationTests.swift | 4 ++-- Tests/RegexBuilderTests/RegexDSLTests.swift | 6 +++--- Tests/RegexTests/AlgorithmsTests.swift | 10 +++++----- Tests/RegexTests/MatchTests.swift | 10 +++++----- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Documentation/Evolution/RegexSyntaxRunTimeConstruction.md b/Documentation/Evolution/RegexSyntaxRunTimeConstruction.md index de1cf22ad..f3dda59ba 100644 --- a/Documentation/Evolution/RegexSyntaxRunTimeConstruction.md +++ b/Documentation/Evolution/RegexSyntaxRunTimeConstruction.md @@ -54,11 +54,11 @@ We propose run-time construction of `Regex` from a best-in-class treatment of fa ```swift let pattern = #"(\w+)\s\s+(\S+)\s\s+((?:(?!\s\s).)*)\s\s+(.*)"# -let regex = try! Regex(compiling: pattern) +let regex = try! Regex(pattern) // regex: Regex let regex: Regex<(Substring, Substring, Substring, Substring, Substring)> = - try! Regex(compiling: pattern) + try! Regex(pattern) ``` ### Syntax diff --git a/Documentation/Evolution/RegexTypeOverview.md b/Documentation/Evolution/RegexTypeOverview.md index 5f50f5116..cf2fb9265 100644 --- a/Documentation/Evolution/RegexTypeOverview.md +++ b/Documentation/Evolution/RegexTypeOverview.md @@ -134,11 +134,11 @@ Regexes can be created at run time from a string containing familiar regex synta ```swift let pattern = #"(\w+)\s\s+(\S+)\s\s+((?:(?!\s\s).)*)\s\s+(.*)"# -let regex = try! Regex(compiling: pattern) +let regex = try! Regex(pattern) // regex: Regex let regex: Regex<(Substring, Substring, Substring, Substring, Substring)> = - try! Regex(compiling: pattern) + try! Regex(pattern) ``` *Note*: The syntax accepted and further details on run-time compilation, including `AnyRegexOutput` and extended syntaxes, are discussed in [Run-time Regex Construction][pitches]. @@ -300,7 +300,7 @@ Regex targets [UTS\#18 Level 2](https://www.unicode.org/reports/tr18/#Extended_U ```swift /// A regex represents a string processing algorithm. /// -/// let regex = try Regex(compiling: "a(.*)b") +/// let regex = try Regex("a(.*)b") /// let match = "cbaxb".firstMatch(of: regex) /// print(match.0) // "axb" /// print(match.1) // "x" diff --git a/Sources/Exercises/Participants/RegexParticipant.swift b/Sources/Exercises/Participants/RegexParticipant.swift index 6c53b3adf..627f9583b 100644 --- a/Sources/Exercises/Participants/RegexParticipant.swift +++ b/Sources/Exercises/Participants/RegexParticipant.swift @@ -70,7 +70,7 @@ private func graphemeBreakPropertyDataLiteral( forLine line: String ) -> GraphemeBreakEntry? { let regex = try! Regex( - compiling: #"([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s+;\s+(\w+).*"#, + #"([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s+;\s+(\w+).*"#, as: (Substring, Substring, Substring?, Substring).self) return graphemeBreakPropertyData(forLine: line, using: regex) } diff --git a/Sources/_StringProcessing/Regex/AnyRegexOutput.swift b/Sources/_StringProcessing/Regex/AnyRegexOutput.swift index 06241c7ea..7b8a5ff32 100644 --- a/Sources/_StringProcessing/Regex/AnyRegexOutput.swift +++ b/Sources/_StringProcessing/Regex/AnyRegexOutput.swift @@ -14,7 +14,7 @@ @available(SwiftStdlib 5.7, *) extension Regex where Output == AnyRegexOutput { /// Parse and compile `pattern`, resulting in an existentially-typed capture list. - public init(compiling pattern: String) throws { + public init(_ pattern: String) throws { self.init(ast: try parse(pattern, .traditional)) } } @@ -23,7 +23,7 @@ extension Regex where Output == AnyRegexOutput { extension Regex { /// Parse and compile `pattern`, resulting in a strongly-typed capture list. public init( - compiling pattern: String, + _ pattern: String, as: Output.Type = Output.self ) throws { self.init(ast: try parse(pattern, .traditional)) diff --git a/Sources/_StringProcessing/Regex/Core.swift b/Sources/_StringProcessing/Regex/Core.swift index 56a14da51..d77784df4 100644 --- a/Sources/_StringProcessing/Regex/Core.swift +++ b/Sources/_StringProcessing/Regex/Core.swift @@ -21,7 +21,7 @@ public protocol RegexComponent { /// A regex represents a string processing algorithm. /// -/// let regex = try Regex(compiling: "a(.*)b") +/// let regex = try Regex("a(.*)b") /// let match = "cbaxb".firstMatch(of: regex) /// print(match.0) // "axb" /// print(match.1) // "x" diff --git a/Tests/RegexBuilderTests/MotivationTests.swift b/Tests/RegexBuilderTests/MotivationTests.swift index 1927b9ae4..22e790e2d 100644 --- a/Tests/RegexBuilderTests/MotivationTests.swift +++ b/Tests/RegexBuilderTests/MotivationTests.swift @@ -139,7 +139,7 @@ private func processWithRuntimeDynamicRegex( _ line: String ) -> Transaction? { // FIXME: Shouldn't this init throw? - let regex = try! Regex(compiling: pattern) + let regex = try! Regex(pattern) // guard let result = line.match(regex) else { return nil } // @@ -156,7 +156,7 @@ private func processWithRuntimeDynamicRegex( @available(macOS 12.0, *) private func processWithRuntimeStaticRegex(_ line: String) -> Transaction? { let regex: Regex<(Substring, Substring, Substring, Substring, Substring)> - = try! Regex(compiling: pattern) + = try! Regex(pattern) return process(line, using: regex) } diff --git a/Tests/RegexBuilderTests/RegexDSLTests.swift b/Tests/RegexBuilderTests/RegexDSLTests.swift index 897bca8f7..03fc21d49 100644 --- a/Tests/RegexBuilderTests/RegexDSLTests.swift +++ b/Tests/RegexBuilderTests/RegexDSLTests.swift @@ -666,7 +666,7 @@ class RegexDSLTests: XCTestCase { do { let regexLiteral = try Regex( - compiling: #"([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s+;\s+(\w+).*"#, + #"([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s+;\s+(\w+).*"#, as: (Substring, Substring, Substring?, Substring).self) let maybeMatchResult = line.wholeMatch(of: regexLiteral) let matchResult = try XCTUnwrap(maybeMatchResult) @@ -680,7 +680,7 @@ class RegexDSLTests: XCTestCase { func testDynamicCaptures() throws { do { - let regex = try Regex(compiling: "aabcc.") + let regex = try Regex("aabcc.") let line = "aabccd" let match = try XCTUnwrap(line.wholeMatch(of: regex)) XCTAssertEqual(match.0, line[...]) @@ -689,7 +689,7 @@ class RegexDSLTests: XCTestCase { } do { let regex = try Regex( - compiling: #"([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s+;\s+(\w+).*"#) + #"([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s+;\s+(\w+).*"#) let line = """ A6F0..A6F1 ; Extend # Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM \ COMBINING MARK TUKWENTIS diff --git a/Tests/RegexTests/AlgorithmsTests.swift b/Tests/RegexTests/AlgorithmsTests.swift index 8e77a8977..5c3c34f89 100644 --- a/Tests/RegexTests/AlgorithmsTests.swift +++ b/Tests/RegexTests/AlgorithmsTests.swift @@ -32,7 +32,7 @@ class RegexConsumerTests: XCTestCase { _ expected: [Range], file: StaticString = #file, line: UInt = #line ) { - let regex = try! Regex(compiling: regex) + let regex = try! Regex(regex) let actualSeq: [Range] = string[...].ranges(of: regex).map(string.offsets(of:)) XCTAssertEqual(actualSeq, expected, file: file, line: line) @@ -69,7 +69,7 @@ class RegexConsumerTests: XCTestCase { _ expected: [Substring], file: StaticString = #file, line: UInt = #line ) { - let regex = try! Regex(compiling: regex) + let regex = try! Regex(regex) let actual = Array(string.split(by: regex)) XCTAssertEqual(actual, expected, file: file, line: line) } @@ -89,7 +89,7 @@ class RegexConsumerTests: XCTestCase { _ expected: String, file: StaticString = #file, line: UInt = #line ) { - let regex = try! Regex(compiling: regex) + let regex = try! Regex(regex) let actual = string.replacing(regex, with: replacement) XCTAssertEqual(actual, expected, file: file, line: line) } @@ -108,7 +108,7 @@ class RegexConsumerTests: XCTestCase { } func testAdHoc() { - let r = try! Regex(compiling: "a|b+") + let r = try! Regex("a|b+") XCTAssert("palindrome".contains(r)) XCTAssert("botany".contains(r)) @@ -142,7 +142,7 @@ class RegexConsumerTests: XCTestCase { let s = "aaa | aaaaaa | aaaaaaaaaa" let s1 = s.dropFirst(6) // "aaaaaa | aaaaaaaaaa" let s2 = s1.dropLast(17) // "aa" - let regex = try! Regex(compiling: "a+") + let regex = try! Regex("a+") XCTAssertEqual(s.firstMatch(of: regex)?.0, "aaa") XCTAssertEqual(s1.firstMatch(of: regex)?.0, "aaaaaa") diff --git a/Tests/RegexTests/MatchTests.swift b/Tests/RegexTests/MatchTests.swift index 25218fad1..b1287fc8b 100644 --- a/Tests/RegexTests/MatchTests.swift +++ b/Tests/RegexTests/MatchTests.swift @@ -1272,11 +1272,11 @@ extension RegexTests { 04: Arkansas 05: California """ - XCTAssertTrue(string.contains(try Regex(compiling: #"^\d+"#))) - XCTAssertEqual(string.ranges(of: try Regex(compiling: #"^\d+"#)).count, 1) - XCTAssertEqual(string.ranges(of: try Regex(compiling: #"(?m)^\d+"#)).count, 5) + XCTAssertTrue(string.contains(try Regex(#"^\d+"#))) + XCTAssertEqual(string.ranges(of: try Regex(#"^\d+"#)).count, 1) + XCTAssertEqual(string.ranges(of: try Regex(#"(?m)^\d+"#)).count, 5) - let regex = try Regex(compiling: #"^\d+: [\w ]+$"#) + let regex = try Regex(#"^\d+: [\w ]+$"#) XCTAssertFalse(string.contains(regex)) let allRanges = string.ranges(of: regex.anchorsMatchLineEndings()) XCTAssertEqual(allRanges.count, 5) @@ -1304,7 +1304,7 @@ extension RegexTests { } func testOptionMethods() throws { - let regex = try Regex(compiling: "c.f.") + let regex = try Regex("c.f.") XCTAssertTrue ("cafe".contains(regex)) XCTAssertFalse("CaFe".contains(regex))