Skip to content

Commit 27bf06e

Browse files
milsemannatecook1000
authored andcommitted
Simplify capture representations (swiftlang#360)
Introduce CaptureList, make CaptureStructure semi-vestigial
1 parent 59cc357 commit 27bf06e

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

Sources/_StringProcessing/Regex/DSLTree.swift

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,88 @@ public struct CaptureTransform: Hashable, CustomStringConvertible {
451451
// These wrapper types are required because even @_spi-marked public APIs can't
452452
// include symbols from implementation-only dependencies.
453453

454+
extension DSLTree.Node {
455+
func _addCaptures(
456+
to list: inout CaptureList,
457+
optionalNesting nesting: Int
458+
) {
459+
let addOptional = nesting+1
460+
switch self {
461+
case let .orderedChoice(children):
462+
for child in children {
463+
child._addCaptures(to: &list, optionalNesting: addOptional)
464+
}
465+
466+
case let .concatenation(children):
467+
for child in children {
468+
child._addCaptures(to: &list, optionalNesting: nesting)
469+
}
470+
471+
case let .capture(name, _, child):
472+
list.append(.init(
473+
name: name,
474+
type: child.valueCaptureType?.base,
475+
optionalDepth: nesting))
476+
child._addCaptures(to: &list, optionalNesting: nesting)
477+
478+
case let .nonCapturingGroup(kind, child):
479+
assert(!kind.ast.isCapturing)
480+
child._addCaptures(to: &list, optionalNesting: nesting)
481+
482+
case let .conditional(cond, trueBranch, falseBranch):
483+
switch cond.ast {
484+
case .group(let g):
485+
AST.Node.group(g)._addCaptures(to: &list, optionalNesting: nesting)
486+
default:
487+
break
488+
}
489+
490+
trueBranch._addCaptures(to: &list, optionalNesting: addOptional)
491+
falseBranch._addCaptures(to: &list, optionalNesting: addOptional)
492+
493+
494+
case let .quantification(amount, _, child):
495+
var optNesting = nesting
496+
if amount.ast.bounds.atLeast == 0 {
497+
optNesting += 1
498+
}
499+
child._addCaptures(to: &list, optionalNesting: optNesting)
500+
501+
case let .regexLiteral(re):
502+
return re.ast._addCaptures(to: &list, optionalNesting: nesting)
503+
504+
case let .absentFunction(abs):
505+
switch abs.ast.kind {
506+
case .expression(_, _, let child):
507+
child._addCaptures(to: &list, optionalNesting: nesting)
508+
case .clearer, .repeater, .stopper:
509+
break
510+
@unknown default:
511+
fatalError()
512+
}
513+
514+
case let .convertedRegexLiteral(n, _):
515+
return n._addCaptures(to: &list, optionalNesting: nesting)
516+
517+
case .matcher:
518+
break
519+
520+
case .transform(_, let child):
521+
child._addCaptures(to: &list, optionalNesting: nesting)
522+
523+
case .customCharacterClass, .atom, .trivia, .empty,
524+
.quotedLiteral, .consumer, .characterPredicate:
525+
break
526+
}
527+
}
528+
529+
var _captureList: CaptureList {
530+
var list = CaptureList()
531+
self._addCaptures(to: &list, optionalNesting: 0)
532+
return list
533+
}
534+
}
535+
454536
extension DSLTree {
455537
/// Presents a wrapped version of `DSLTree.Node` that can provide an internal
456538
/// `_TreeNode` conformance.

0 commit comments

Comments
 (0)