You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
*During the review process, add the following fields as needed:*
9
-
10
-
* Implementation: [apple/swift#NNNNN](https://github.com/apple/swift/pull/NNNNN) or [apple/swift-evolution-staging#NNNNN](https://github.com/apple/swift-evolution-staging/pull/NNNNN)
@@ -340,36 +333,43 @@ public enum RegexComponentBuilder {
340
333
line: Int=#line,
341
334
column: Int=#column
342
335
) -> Component<R>
343
-
344
-
/// Provides support for “if” statements in multi-statement closures, producing
345
-
/// conditional content for the “then” branch.
346
-
publicstaticfuncbuildEither<R: RegexComponent>(
347
-
firstcomponent: Component<R>
348
-
) -> Regex<R.Output> {
349
-
component
350
-
}
351
-
352
-
/// Provides support for “if-else” statements in multi-statement closures,
353
-
/// producing conditional content for the “else” branch.
354
-
publicstaticfuncbuildEither<R: RegexComponent>(
355
-
secondcomponent: Component<R>
356
-
) -> Regex<R.Output> {
357
-
component
358
-
}
359
336
}
360
337
```
361
338
362
339
When it comes to concatenation, `RegexComponentBuilder` utilizes the [recently proposed `buildPartialBlock` feature](https://forums.swift.org/t/pitch-buildpartialblock-for-result-builders/55561/1) to be able to concatenate all components' capture types to a single result tuple. `buildPartialBlock(first:)` provides support for creating a regex from a single component, and `buildPartialBlock(accumulated:next:)` support for creating a regex from multiple results.
363
340
364
-
Before Swift supports variadic generics, `buildPartialBlock(accumulated:next:)` must be overloaded to support concatenating regexes of supported capture quantities (arities). Due to the need for concatenating any pair of regexes that make up 10 captures, `buildPartialBlock(accumulated:next:)` is overloaded up to `arity^2` times.
341
+
Before Swift supports variadic generics, `buildPartialBlock(first:)` and `buildPartialBlock(accumulated:next:)` must be overloaded to support concatenating regexes of supported capture quantities (arities).
342
+
-`buildPartialBlock(first:)` is overloaded `arity` times such that a unary block with a component of any supported capture arity will produce a regex with capture type `Substring` followed by the component's capture types. The base overload, `buildPartialBlock<R>(first:) -> Regex<Substring>`, must be marked with `@_disfavoredOverload` to prevent it from shadowing other overloads.
343
+
-`buildPartialBlock(accumulated:next:)` is overloaded up to `arity^2` times to account for all possible pairs of regexes that make up 10 captures.
365
344
366
-
In the initial version of the DSL, we plan to support regexes with up to 10 captures, as 10 captures are sufficient for most use cases. These overloads can be superceded by a variadic version of `buildPartialBlock(accumulated:next:)` in a future release.
345
+
In the initial version of the DSL, we plan to support regexes with up to 10 captures, as 10 captures are sufficient for most use cases. These overloads can be superceded by variadic versions of`buildPartialBlock(first:)` and`buildPartialBlock(accumulated:next:)` in a future release.
367
346
368
347
```swift
369
348
extensionRegexComponentBuilder {
349
+
// The following builder methods implement what would be possible with
350
+
// variadic generics (using imaginary syntax) as a single method:
351
+
//
352
+
// public static func buildPartialBlock<
353
+
// R, WholeMatch, Capture...
354
+
// >(
355
+
// first component: Component<R>
356
+
// ) -> Regex<(Substring, Capture...)>
357
+
// where Component.Output == (WholeMatch, Capture...),
To support `if` statements, `buildOptional(_:)`is defined with overloads to support up to 10 captures because each capture type needs to be transformed to an optional. The overload for non-capturing regexes, due to the lack of generic constraints, must be annotated with `@_disfavoredOverload` in order not to become the default choice by the compiler. We expect that a variadic-generic version of this method will eventually superceded all of these overloads.
403
+
To support `if` statements, `buildEither(first:)`, `buildEither(second:)` and `buildOptional(_:)`are defined with overloads to support up to 10 captures because each capture type needs to be transformed to an optional. The overload for non-capturing regexes, due to the lack of generic constraints, must be annotated with `@_disfavoredOverload` in order not shadow other overloads. We expect that a variadic-generic version of this method will eventually superseded all of these overloads.
404
404
405
405
```swift
406
406
extensionRegexComponentBuilder {
407
+
// The following builder methods implement what would be possible with
408
+
// variadic generics (using imaginary syntax) as a single method:
409
+
//
410
+
// public static func buildEither<
411
+
// Component, WholeMatch, Capture...
412
+
// >(
413
+
// first component: Component
414
+
// ) -> Regex<(Substring, Capture...)>
415
+
// where Component.Output == (WholeMatch, Capture...)
Variants of `capture` and `tryCapture` accept a `Reference` argument. References can be used to achieve named captures and named backreferences from textual regexes.
1189
+
Variants of `Capture` and `TryCapture` accept a `Reference` argument. References can be used to achieve named captures and named backreferences from textual regexes.
1129
1190
1130
1191
```swift
1131
1192
publicstructReference<Capture>: RegexComponent {
@@ -1160,7 +1221,7 @@ A regex is considered invalid when it contains a use of reference without it eve
1160
1221
In textual regex, one can refer to a subpattern to avoid duplicating the subpattern, for example:
1161
1222
1162
1223
```
1163
-
(you|I) say (goodbye|hello); (?0) say (?1)
1224
+
(you|I) say (goodbye|hello); (?1) say (?2)
1164
1225
```
1165
1226
1166
1227
The above regex is equivalent to
@@ -1238,7 +1299,7 @@ The proposed feature relies heavily upon overloads of `buildBlock` and `buildPar
1238
1299
1239
1300
## Alternatives considered
1240
1301
1241
-
### Operators for quantification and alterantion
1302
+
### Operators for quantification and alternation
1242
1303
1243
1304
While `ChoiceOf` and quantifier functions provide a general way of creating alternations and quantifications, we recognize that some synctactic sugar can be useful for creating one-liners like in textual regexes, e.g. infix operator `|`, postfix operator `*`, etc.
1244
1305
@@ -1373,7 +1434,7 @@ However, given that one-or-more (`+`), zero-or-more (`*`) and optional (`?`) are
1373
1434
1374
1435
One could argue that type such as `OneOrMore<Output>` could be defined as a top-level function that returns `Regex`. While it is entirely possible to do so, it would lose the name scoping benefits of a type and pollute the top-level namespace with `O(arity^2)` overloads of quantifiers, `capture`, `tryCapture`, etc. This could be detrimental to the usefulness of code completion.
1375
1436
1376
-
Another reason to use types instead of free functions is consistency with existing result-buidler-based DSLs such as SwiftUI.
1437
+
Another reason to use types instead of free functions is consistency with existing result-builder-based DSLs such as SwiftUI.
0 commit comments