Skip to content

Commit 65178f9

Browse files
authored
Merge pull request swiftlang#552 from hamishknight/flatpak-5.7
2 parents 6a62ebd + 581c317 commit 65178f9

File tree

10 files changed

+307
-185
lines changed

10 files changed

+307
-185
lines changed

Sources/_RegexParser/Regex/Parse/CaptureList.swift

Lines changed: 68 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -57,63 +57,105 @@ extension CaptureList {
5757
}
5858
}
5959

60+
extension CaptureList {
61+
public struct Builder {
62+
public var captures = CaptureList()
63+
64+
public init() {}
65+
66+
public struct OptionalNesting {
67+
// We maintain two depths, inner and outer. These allow e.g the nesting
68+
// of a regex literal in a DSL, where outside of the scope of the literal,
69+
// nesting is allowed, but inside the literal at most one extra layer of
70+
// optionality may be added.
71+
public var outerDepth: Int
72+
public var canNest: Bool
73+
public var innerDepth: Int
74+
75+
internal init(outerDepth: Int, canNest: Bool) {
76+
self.outerDepth = outerDepth
77+
self.canNest = canNest
78+
self.innerDepth = 0
79+
}
80+
81+
public init(canNest: Bool) {
82+
self.init(outerDepth: 0, canNest: canNest)
83+
}
84+
85+
public var depth: Int { outerDepth + innerDepth }
86+
87+
public var disablingNesting: Self {
88+
// If we are currently able to nest, store the current depth as the
89+
// outer depth, and disable nesting for an inner scope.
90+
guard canNest else { return self }
91+
return .init(outerDepth: depth, canNest: false)
92+
}
93+
94+
public var addingOptional: Self {
95+
var result = self
96+
result.innerDepth = canNest ? innerDepth + 1 : 1
97+
return result
98+
}
99+
}
100+
}
101+
}
102+
60103
// MARK: Generating from AST
61104

62-
extension AST.Node {
63-
public func _addCaptures(
64-
to list: inout CaptureList,
65-
optionalNesting nesting: Int
105+
extension CaptureList.Builder {
106+
public mutating func addCaptures(
107+
of node: AST.Node, optionalNesting nesting: OptionalNesting
66108
) {
67-
let addOptional = nesting+1
68-
switch self {
109+
switch node {
69110
case let .alternation(a):
70111
for child in a.children {
71-
child._addCaptures(to: &list, optionalNesting: addOptional)
112+
addCaptures(of: child, optionalNesting: nesting.addingOptional)
72113
}
73114

74115
case let .concatenation(c):
75116
for child in c.children {
76-
child._addCaptures(to: &list, optionalNesting: nesting)
117+
addCaptures(of: child, optionalNesting: nesting)
77118
}
78119

79120
case let .group(g):
80121
switch g.kind.value {
81122
case .capture:
82-
list.append(.init(optionalDepth: nesting, g.location))
123+
captures.append(.init(optionalDepth: nesting.depth, g.location))
83124

84125
case .namedCapture(let name):
85-
list.append(.init(name: name.value, optionalDepth: nesting, g.location))
126+
captures.append(.init(
127+
name: name.value, optionalDepth: nesting.depth, g.location))
86128

87129
case .balancedCapture(let b):
88-
list.append(.init(name: b.name?.value, optionalDepth: nesting,
89-
g.location))
130+
captures.append(.init(
131+
name: b.name?.value, optionalDepth: nesting.depth, g.location))
90132

91133
default: break
92134
}
93-
g.child._addCaptures(to: &list, optionalNesting: nesting)
135+
addCaptures(of: g.child, optionalNesting: nesting)
94136

95137
case .conditional(let c):
96138
switch c.condition.kind {
97139
case .group(let g):
98-
AST.Node.group(g)._addCaptures(to: &list, optionalNesting: nesting)
140+
addCaptures(of: .group(g), optionalNesting: nesting)
99141
default:
100142
break
101143
}
102144

103-
c.trueBranch._addCaptures(to: &list, optionalNesting: addOptional)
104-
c.falseBranch._addCaptures(to: &list, optionalNesting: addOptional)
145+
addCaptures(of: c.trueBranch, optionalNesting: nesting.addingOptional)
146+
addCaptures(of: c.falseBranch, optionalNesting: nesting.addingOptional)
105147

106148
case .quantification(let q):
107149
var optNesting = nesting
108150
if q.amount.value.bounds.atLeast == 0 {
109-
optNesting += 1
151+
optNesting = optNesting.addingOptional
110152
}
111-
q.child._addCaptures(to: &list, optionalNesting: optNesting)
153+
addCaptures(of: q.child, optionalNesting: optNesting)
112154

113155
case .absentFunction(let abs):
114156
switch abs.kind {
115157
case .expression(_, _, let child):
116-
child._addCaptures(to: &list, optionalNesting: nesting)
158+
addCaptures(of: child, optionalNesting: nesting)
117159
case .clearer, .repeater, .stopper:
118160
break
119161
}
@@ -122,16 +164,17 @@ extension AST.Node {
122164
break
123165
}
124166
}
167+
public static func build(_ ast: AST) -> CaptureList {
168+
var builder = Self()
169+
builder.captures.append(.init(optionalDepth: 0, .fake))
170+
builder.addCaptures(of: ast.root, optionalNesting: .init(canNest: false))
171+
return builder.captures
172+
}
125173
}
126174

127175
extension AST {
128176
/// The capture list (including the whole match) of this AST.
129-
public var captureList: CaptureList {
130-
var caps = CaptureList()
131-
caps.append(.init(optionalDepth: 0, .fake))
132-
root._addCaptures(to: &caps, optionalNesting: 0)
133-
return caps
134-
}
177+
public var captureList: CaptureList { .Builder.build(self) }
135178
}
136179

137180
// MARK: Convenience for testing and inspection

Sources/_RegexParser/Regex/Parse/CaptureStructure.swift

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -225,33 +225,27 @@ extension CaptureStructure: CustomStringConvertible {
225225
extension AST {
226226
/// The capture structure of this AST for compiler communication.
227227
var captureStructure: CaptureStructure {
228-
captureList._captureStructure(nestOptionals: true)
228+
captureList._captureStructure
229229
}
230230
}
231231

232232
// MARK: Convert CaptureList into CaptureStructure
233233

234234
extension CaptureList {
235-
func _captureStructure(nestOptionals: Bool) -> CaptureStructure {
235+
var _captureStructure: CaptureStructure {
236236
if captures.isEmpty { return .empty }
237237
if captures.count == 1 {
238-
return captures.first!._captureStructure(nestOptionals: nestOptionals)
238+
return captures.first!._captureStructure
239239
}
240-
return .tuple(captures.map {
241-
$0._captureStructure(nestOptionals: nestOptionals)
242-
})
240+
return .tuple(captures.map(\._captureStructure))
243241
}
244242
}
245243

246244
extension CaptureList.Capture {
247-
func _captureStructure(nestOptionals: Bool) -> CaptureStructure {
248-
if optionalDepth == 0 {
249-
return .atom(name: name, type: type == Substring.self ? nil : .init(type))
250-
}
251-
var copy = self
252-
copy.optionalDepth = 0
253-
var base = copy._captureStructure(nestOptionals: false)
254-
for _ in 0..<(nestOptionals ? optionalDepth : 1) {
245+
var _captureStructure: CaptureStructure {
246+
var base = CaptureStructure.atom(
247+
name: name, type: type == Substring.self ? nil : .init(type))
248+
for _ in 0 ..< optionalDepth {
255249
base = .optional(base)
256250
}
257251
return base

Sources/_StringProcessing/ByteCodeGen.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -812,9 +812,6 @@ fileprivate extension Compiler.ByteCodeGen {
812812
}
813813
}
814814

815-
case let .regexLiteral(l):
816-
return try emitNode(l.ast.dslTreeNode)
817-
818815
case let .convertedRegexLiteral(n, _):
819816
return try emitNode(n)
820817

Sources/_StringProcessing/Capture.swift

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,24 @@ func constructExistentialOutputComponent(
1717
component: (range: Range<String.Index>, value: Any?)?,
1818
optionalCount: Int
1919
) -> Any {
20-
let someCount: Int
21-
var underlying: Any
2220
if let component = component {
23-
underlying = component.value ?? input[component.range]
24-
someCount = optionalCount
21+
var underlying = component.value ?? input[component.range]
22+
for _ in 0 ..< optionalCount {
23+
func wrap<T>(_ x: T) {
24+
underlying = Optional(x) as Any
25+
}
26+
_openExistential(underlying, do: wrap)
27+
}
28+
return underlying
2529
} else {
26-
// Ok since we Any-box every step up the ladder
27-
underlying = Optional<Any>(nil) as Any
28-
someCount = optionalCount - 1
29-
}
30-
for _ in 0..<someCount {
31-
func wrap<T>(_ x: T) {
32-
underlying = Optional(x) as Any
30+
precondition(optionalCount > 0, "Must have optional type")
31+
func makeNil<T>(_ x: T.Type) -> Any {
32+
T?.none as Any
3333
}
34-
_openExistential(underlying, do: wrap)
34+
let underlyingTy = TypeConstruction.optionalType(
35+
of: Substring.self, depth: optionalCount - 1)
36+
return _openExistential(underlyingTy, do: makeNil)
3537
}
36-
return underlying
3738
}
3839

3940
@available(SwiftStdlib 5.7, *)

Sources/_StringProcessing/ConsumerInterface.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ extension DSLTree.Node {
2929
// TODO: Should we handle this here?
3030
return nil
3131

32-
case .regexLiteral:
33-
fatalError(
34-
"unreachable: We should only ask atoms")
35-
3632
case let .convertedRegexLiteral(n, _):
3733
return try n.generateConsumer(opts)
3834

Sources/_StringProcessing/PrintAsPattern.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,6 @@ extension PrettyPrinter {
258258
case let .quotedLiteral(v):
259259
print(v._quoted)
260260

261-
case .regexLiteral:
262-
printBackoff(node)
263-
264261
case let .convertedRegexLiteral(n, _):
265262
// FIXME: This recursion coordinates with back-off
266263
// check above, so it should work out. Need a

0 commit comments

Comments
 (0)