Skip to content

Commit 182da3b

Browse files
natecook1000rxwei
andauthored
Untangle _RegexParser from RegexBuilder (#299)
This makes the changes necessary for _RegexParser to be imported as an implementation-only dependency. The change provides _StringProcessing wrappers for all `AST` types that need to be publicly visible via SPI, and a DSLTree.Node wrapper for internal conformance to _TreeNode. Co-authored-by: Richard Wei <[email protected]>
1 parent 9ccde19 commit 182da3b

File tree

14 files changed

+399
-239
lines changed

14 files changed

+399
-239
lines changed

Sources/RegexBuilder/Anchor.swift

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//
1010
//===----------------------------------------------------------------------===//
1111

12-
import _RegexParser
12+
@_implementationOnly import _RegexParser
1313
@_spi(RegexBuilder) import _StringProcessing
1414

1515
@available(SwiftStdlib 5.7, *)
@@ -31,34 +31,21 @@ public struct Anchor {
3131

3232
@available(SwiftStdlib 5.7, *)
3333
extension Anchor: RegexComponent {
34-
var astAssertion: AST.Atom.AssertionKind {
35-
if !isInverted {
36-
switch kind {
37-
case .startOfSubject: return .startOfSubject
38-
case .endOfSubjectBeforeNewline: return .endOfSubjectBeforeNewline
39-
case .endOfSubject: return .endOfSubject
40-
case .firstMatchingPositionInSubject: return .firstMatchingPositionInSubject
41-
case .textSegmentBoundary: return .textSegment
42-
case .startOfLine: return .startOfLine
43-
case .endOfLine: return .endOfLine
44-
case .wordBoundary: return .wordBoundary
45-
}
46-
} else {
47-
switch kind {
48-
case .startOfSubject: fatalError("Not yet supported")
49-
case .endOfSubjectBeforeNewline: fatalError("Not yet supported")
50-
case .endOfSubject: fatalError("Not yet supported")
51-
case .firstMatchingPositionInSubject: fatalError("Not yet supported")
52-
case .textSegmentBoundary: return .notTextSegment
53-
case .startOfLine: fatalError("Not yet supported")
54-
case .endOfLine: fatalError("Not yet supported")
55-
case .wordBoundary: return .notWordBoundary
56-
}
34+
var baseAssertion: DSLTree._AST.AssertionKind {
35+
switch kind {
36+
case .startOfSubject: return .startOfSubject(isInverted)
37+
case .endOfSubjectBeforeNewline: return .endOfSubjectBeforeNewline(isInverted)
38+
case .endOfSubject: return .endOfSubject(isInverted)
39+
case .firstMatchingPositionInSubject: return .firstMatchingPositionInSubject(isInverted)
40+
case .textSegmentBoundary: return .textSegmentBoundary(isInverted)
41+
case .startOfLine: return .startOfLine(isInverted)
42+
case .endOfLine: return .endOfLine(isInverted)
43+
case .wordBoundary: return .wordBoundary(isInverted)
5744
}
5845
}
5946

6047
public var regex: Regex<Substring> {
61-
Regex(node: .atom(.assertion(astAssertion)))
48+
Regex(node: .atom(.assertion(baseAssertion)))
6249
}
6350
}
6451

Sources/RegexBuilder/CharacterClass.swift

Lines changed: 5 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//
1010
//===----------------------------------------------------------------------===//
1111

12-
import _RegexParser
12+
@_implementationOnly import _RegexParser
1313
@_spi(RegexBuilder) import _StringProcessing
1414

1515
@available(SwiftStdlib 5.7, *)
@@ -21,19 +21,10 @@ public struct CharacterClass {
2121
}
2222

2323
init(unconverted model: _CharacterClassModel) {
24-
// FIXME: Implement in DSLTree instead of wrapping an AST atom
25-
switch model.makeAST() {
26-
case .atom(let atom):
27-
self.ccc = .init(members: [.atom(.unconverted(atom))])
28-
default:
29-
fatalError("Unsupported _CharacterClassModel")
24+
guard let ccc = model.makeDSLTreeCharacterClass() else {
25+
fatalError("Unsupported character class")
3026
}
31-
}
32-
33-
init(property: AST.Atom.CharacterProperty) {
34-
// FIXME: Implement in DSLTree instead of wrapping an AST atom
35-
let astAtom = AST.Atom(.property(property), .fake)
36-
self.ccc = .init(members: [.atom(.unconverted(astAtom))])
27+
self.ccc = ccc
3728
}
3829
}
3930

@@ -119,11 +110,7 @@ extension RegexComponent where Self == CharacterClass {
119110
@available(SwiftStdlib 5.7, *)
120111
extension CharacterClass {
121112
public static func generalCategory(_ category: Unicode.GeneralCategory) -> CharacterClass {
122-
guard let extendedCategory = category.extendedGeneralCategory else {
123-
fatalError("Unexpected general category")
124-
}
125-
return CharacterClass(property:
126-
.init(.generalCategory(extendedCategory), isInverted: false, isPOSIX: false))
113+
return CharacterClass(.generalCategory(category))
127114
}
128115
}
129116

@@ -144,44 +131,6 @@ public func ...(lhs: UnicodeScalar, rhs: UnicodeScalar) -> CharacterClass {
144131
return CharacterClass(ccc)
145132
}
146133

147-
extension Unicode.GeneralCategory {
148-
var extendedGeneralCategory: Unicode.ExtendedGeneralCategory? {
149-
switch self {
150-
case .uppercaseLetter: return .uppercaseLetter
151-
case .lowercaseLetter: return .lowercaseLetter
152-
case .titlecaseLetter: return .titlecaseLetter
153-
case .modifierLetter: return .modifierLetter
154-
case .otherLetter: return .otherLetter
155-
case .nonspacingMark: return .nonspacingMark
156-
case .spacingMark: return .spacingMark
157-
case .enclosingMark: return .enclosingMark
158-
case .decimalNumber: return .decimalNumber
159-
case .letterNumber: return .letterNumber
160-
case .otherNumber: return .otherNumber
161-
case .connectorPunctuation: return .connectorPunctuation
162-
case .dashPunctuation: return .dashPunctuation
163-
case .openPunctuation: return .openPunctuation
164-
case .closePunctuation: return .closePunctuation
165-
case .initialPunctuation: return .initialPunctuation
166-
case .finalPunctuation: return .finalPunctuation
167-
case .otherPunctuation: return .otherPunctuation
168-
case .mathSymbol: return .mathSymbol
169-
case .currencySymbol: return .currencySymbol
170-
case .modifierSymbol: return .modifierSymbol
171-
case .otherSymbol: return .otherSymbol
172-
case .spaceSeparator: return .spaceSeparator
173-
case .lineSeparator: return .lineSeparator
174-
case .paragraphSeparator: return .paragraphSeparator
175-
case .control: return .control
176-
case .format: return .format
177-
case .surrogate: return .surrogate
178-
case .privateUse: return .privateUse
179-
case .unassigned: return .unassigned
180-
@unknown default: return nil
181-
}
182-
}
183-
}
184-
185134
// MARK: - Set algebra methods
186135

187136
@available(SwiftStdlib 5.7, *)

Sources/RegexBuilder/DSL.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//
1010
//===----------------------------------------------------------------------===//
1111

12-
import _RegexParser
12+
@_implementationOnly import _RegexParser
1313
@_spi(RegexBuilder) import _StringProcessing
1414

1515
@available(SwiftStdlib 5.7, *)
@@ -105,7 +105,7 @@ public struct QuantificationBehavior {
105105

106106
var kind: Kind
107107

108-
internal var astKind: AST.Quantification.Kind {
108+
internal var astKind: DSLTree._AST.QuantificationKind {
109109
switch kind {
110110
case .eagerly: return .eager
111111
case .reluctantly: return .reluctant
@@ -136,13 +136,13 @@ extension DSLTree.Node {
136136
return .quantification(.oneOrMore, kind, node)
137137
case _ where range.count == 1: // ..<1 or ...0 or any range with count == 1
138138
// Note: `behavior` is ignored in this case
139-
return .quantification(.exactly(.init(faking: range.lowerBound)), .default, node)
139+
return .quantification(.exactly(range.lowerBound), .default, node)
140140
case (0, _): // 0..<n or 0...n or ..<n or ...n
141-
return .quantification(.upToN(.init(faking: range.upperBound)), kind, node)
141+
return .quantification(.upToN(range.upperBound), kind, node)
142142
case (_, Int.max): // n...
143-
return .quantification(.nOrMore(.init(faking: range.lowerBound)), kind, node)
143+
return .quantification(.nOrMore(range.lowerBound), kind, node)
144144
default: // any other range
145-
return .quantification(.range(.init(faking: range.lowerBound), .init(faking: range.upperBound)), kind, node)
145+
return .quantification(.range(range.lowerBound, range.upperBound), kind, node)
146146
}
147147
}
148148
}

Sources/RegexBuilder/Variadics.swift

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
// BEGIN AUTO-GENERATED CONTENT
1313

14-
import _RegexParser
1514
@_spi(RegexBuilder) import _StringProcessing
1615

1716
@available(SwiftStdlib 5.7, *)
@@ -709,7 +708,7 @@ extension Repeat {
709708
) where RegexOutput == Substring {
710709
assert(count > 0, "Must specify a positive count")
711710
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
712-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root))
711+
self.init(node: .quantification(.exactly(count), .default, component.regex.root))
713712
}
714713

715714
@available(SwiftStdlib 5.7, *)
@@ -720,7 +719,7 @@ extension Repeat {
720719
) where RegexOutput == Substring {
721720
assert(count > 0, "Must specify a positive count")
722721
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
723-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root))
722+
self.init(node: .quantification(.exactly(count), .default, component().regex.root))
724723
}
725724

726725
@available(SwiftStdlib 5.7, *)
@@ -835,7 +834,7 @@ extension Repeat {
835834
) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0) {
836835
assert(count > 0, "Must specify a positive count")
837836
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
838-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root))
837+
self.init(node: .quantification(.exactly(count), .default, component.regex.root))
839838
}
840839

841840
@available(SwiftStdlib 5.7, *)
@@ -845,7 +844,7 @@ extension Repeat {
845844
) where RegexOutput == (Substring, C0?), Component.RegexOutput == (W, C0) {
846845
assert(count > 0, "Must specify a positive count")
847846
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
848-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root))
847+
self.init(node: .quantification(.exactly(count), .default, component().regex.root))
849848
}
850849

851850
@available(SwiftStdlib 5.7, *)
@@ -958,7 +957,7 @@ extension Repeat {
958957
) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1) {
959958
assert(count > 0, "Must specify a positive count")
960959
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
961-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root))
960+
self.init(node: .quantification(.exactly(count), .default, component.regex.root))
962961
}
963962

964963
@available(SwiftStdlib 5.7, *)
@@ -968,7 +967,7 @@ extension Repeat {
968967
) where RegexOutput == (Substring, C0?, C1?), Component.RegexOutput == (W, C0, C1) {
969968
assert(count > 0, "Must specify a positive count")
970969
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
971-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root))
970+
self.init(node: .quantification(.exactly(count), .default, component().regex.root))
972971
}
973972

974973
@available(SwiftStdlib 5.7, *)
@@ -1081,7 +1080,7 @@ extension Repeat {
10811080
) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2) {
10821081
assert(count > 0, "Must specify a positive count")
10831082
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
1084-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root))
1083+
self.init(node: .quantification(.exactly(count), .default, component.regex.root))
10851084
}
10861085

10871086
@available(SwiftStdlib 5.7, *)
@@ -1091,7 +1090,7 @@ extension Repeat {
10911090
) where RegexOutput == (Substring, C0?, C1?, C2?), Component.RegexOutput == (W, C0, C1, C2) {
10921091
assert(count > 0, "Must specify a positive count")
10931092
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
1094-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root))
1093+
self.init(node: .quantification(.exactly(count), .default, component().regex.root))
10951094
}
10961095

10971096
@available(SwiftStdlib 5.7, *)
@@ -1204,7 +1203,7 @@ extension Repeat {
12041203
) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3) {
12051204
assert(count > 0, "Must specify a positive count")
12061205
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
1207-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root))
1206+
self.init(node: .quantification(.exactly(count), .default, component.regex.root))
12081207
}
12091208

12101209
@available(SwiftStdlib 5.7, *)
@@ -1214,7 +1213,7 @@ extension Repeat {
12141213
) where RegexOutput == (Substring, C0?, C1?, C2?, C3?), Component.RegexOutput == (W, C0, C1, C2, C3) {
12151214
assert(count > 0, "Must specify a positive count")
12161215
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
1217-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root))
1216+
self.init(node: .quantification(.exactly(count), .default, component().regex.root))
12181217
}
12191218

12201219
@available(SwiftStdlib 5.7, *)
@@ -1327,7 +1326,7 @@ extension Repeat {
13271326
) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4) {
13281327
assert(count > 0, "Must specify a positive count")
13291328
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
1330-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root))
1329+
self.init(node: .quantification(.exactly(count), .default, component.regex.root))
13311330
}
13321331

13331332
@available(SwiftStdlib 5.7, *)
@@ -1337,7 +1336,7 @@ extension Repeat {
13371336
) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?), Component.RegexOutput == (W, C0, C1, C2, C3, C4) {
13381337
assert(count > 0, "Must specify a positive count")
13391338
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
1340-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root))
1339+
self.init(node: .quantification(.exactly(count), .default, component().regex.root))
13411340
}
13421341

13431342
@available(SwiftStdlib 5.7, *)
@@ -1450,7 +1449,7 @@ extension Repeat {
14501449
) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) {
14511450
assert(count > 0, "Must specify a positive count")
14521451
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
1453-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root))
1452+
self.init(node: .quantification(.exactly(count), .default, component.regex.root))
14541453
}
14551454

14561455
@available(SwiftStdlib 5.7, *)
@@ -1460,7 +1459,7 @@ extension Repeat {
14601459
) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5) {
14611460
assert(count > 0, "Must specify a positive count")
14621461
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
1463-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root))
1462+
self.init(node: .quantification(.exactly(count), .default, component().regex.root))
14641463
}
14651464

14661465
@available(SwiftStdlib 5.7, *)
@@ -1573,7 +1572,7 @@ extension Repeat {
15731572
) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) {
15741573
assert(count > 0, "Must specify a positive count")
15751574
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
1576-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root))
1575+
self.init(node: .quantification(.exactly(count), .default, component.regex.root))
15771576
}
15781577

15791578
@available(SwiftStdlib 5.7, *)
@@ -1583,7 +1582,7 @@ extension Repeat {
15831582
) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6) {
15841583
assert(count > 0, "Must specify a positive count")
15851584
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
1586-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root))
1585+
self.init(node: .quantification(.exactly(count), .default, component().regex.root))
15871586
}
15881587

15891588
@available(SwiftStdlib 5.7, *)
@@ -1696,7 +1695,7 @@ extension Repeat {
16961695
) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) {
16971696
assert(count > 0, "Must specify a positive count")
16981697
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
1699-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root))
1698+
self.init(node: .quantification(.exactly(count), .default, component.regex.root))
17001699
}
17011700

17021701
@available(SwiftStdlib 5.7, *)
@@ -1706,7 +1705,7 @@ extension Repeat {
17061705
) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7) {
17071706
assert(count > 0, "Must specify a positive count")
17081707
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
1709-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root))
1708+
self.init(node: .quantification(.exactly(count), .default, component().regex.root))
17101709
}
17111710

17121711
@available(SwiftStdlib 5.7, *)
@@ -1819,7 +1818,7 @@ extension Repeat {
18191818
) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) {
18201819
assert(count > 0, "Must specify a positive count")
18211820
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
1822-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root))
1821+
self.init(node: .quantification(.exactly(count), .default, component.regex.root))
18231822
}
18241823

18251824
@available(SwiftStdlib 5.7, *)
@@ -1829,7 +1828,7 @@ extension Repeat {
18291828
) where RegexOutput == (Substring, C0?, C1?, C2?, C3?, C4?, C5?, C6?, C7?, C8?), Component.RegexOutput == (W, C0, C1, C2, C3, C4, C5, C6, C7, C8) {
18301829
assert(count > 0, "Must specify a positive count")
18311830
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
1832-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root))
1831+
self.init(node: .quantification(.exactly(count), .default, component().regex.root))
18331832
}
18341833

18351834
@available(SwiftStdlib 5.7, *)
@@ -1942,7 +1941,7 @@ extension Repeat {
19421941
) 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) {
19431942
assert(count > 0, "Must specify a positive count")
19441943
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
1945-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component.regex.root))
1944+
self.init(node: .quantification(.exactly(count), .default, component.regex.root))
19461945
}
19471946

19481947
@available(SwiftStdlib 5.7, *)
@@ -1952,7 +1951,7 @@ extension Repeat {
19521951
) 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) {
19531952
assert(count > 0, "Must specify a positive count")
19541953
// TODO: Emit a warning about `repeatMatch(count: 0)` or `repeatMatch(count: 1)`
1955-
self.init(node: .quantification(.exactly(.init(faking: count)), .default, component().regex.root))
1954+
self.init(node: .quantification(.exactly(count), .default, component().regex.root))
19561955
}
19571956

19581957
@available(SwiftStdlib 5.7, *)

0 commit comments

Comments
 (0)