File tree Expand file tree Collapse file tree 3 files changed +41
-11
lines changed Expand file tree Collapse file tree 3 files changed +41
-11
lines changed Original file line number Diff line number Diff line change @@ -208,14 +208,17 @@ fileprivate struct DelimiterLexer {
208
208
/// Drop a set of regex delimiters from the input string, returning the contents
209
209
/// and the delimiter used. The input string must have valid delimiters.
210
210
func droppingRegexDelimiters( _ str: String ) -> ( String , Delimiter ) {
211
- let utf8 = str. utf8
212
211
func stripDelimiter( _ delim: Delimiter ) -> String ? {
213
- let prefix = delim. opening. utf8
214
- let suffix = delim. closing. utf8
215
- guard utf8. prefix ( prefix. count) . elementsEqual ( prefix) ,
216
- utf8. suffix ( suffix. count) . elementsEqual ( suffix) else { return nil }
217
-
218
- return String ( utf8. dropFirst ( prefix. count) . dropLast ( suffix. count) )
212
+ // The opening delimiter must match.
213
+ guard var slice = str. utf8. tryDropPrefix ( delim. opening. utf8)
214
+ else { return nil }
215
+
216
+ // The closing delimiter may optionally match, as it may not be present in
217
+ // invalid code.
218
+ if let newSlice = slice. tryDropSuffix ( delim. closing. utf8) {
219
+ slice = newSlice
220
+ }
221
+ return String ( slice)
219
222
}
220
223
for d in Delimiter . allCases {
221
224
if let contents = stripDelimiter ( d) {
Original file line number Diff line number Diff line change @@ -61,10 +61,16 @@ func libswiftLexRegexLiteral(
61
61
errOut. pointee = copyCString ( " \( error) " )
62
62
curPtrPtr. pointee = error. resumePtr. assumingMemoryBound ( to: CChar . self)
63
63
64
- // For now, treat every error as unrecoverable.
65
- // TODO: We should ideally be able to recover from a regex with missing
66
- // closing delimiters, which would help with code completion.
67
- return true
64
+ switch error. kind {
65
+ case . endOfString:
66
+ // Missing closing delimiter can be recovered from.
67
+ return false
68
+ case . unprintableASCII, . invalidUTF8:
69
+ // We don't currently have good recovery behavior for these.
70
+ return true
71
+ case . unknownDelimiter:
72
+ fatalError ( " Already handled " )
73
+ }
68
74
} catch {
69
75
fatalError ( " Should be a DelimiterLexError " )
70
76
}
Original file line number Diff line number Diff line change @@ -108,7 +108,28 @@ extension Collection {
108
108
> ( _ idx: Index , in c: C ) -> C . Index {
109
109
c. index ( atOffset: offset ( of: idx) )
110
110
}
111
+ }
111
112
113
+ extension Collection where Element: Equatable {
114
+ /// Attempt to drop a given prefix from the collection, returning the
115
+ /// resulting subsequence, or `nil` if the prefix does not match.
116
+ public func tryDropPrefix< C : Collection > (
117
+ _ other: C
118
+ ) -> SubSequence ? where C. Element == Element {
119
+ let prefixCount = other. count
120
+ guard prefix ( prefixCount) . elementsEqual ( other) else { return nil }
121
+ return dropFirst ( prefixCount)
122
+ }
123
+
124
+ /// Attempt to drop a given suffix from the collection, returning the
125
+ /// resulting subsequence, or `nil` if the suffix does not match.
126
+ public func tryDropSuffix< C : Collection > (
127
+ _ other: C
128
+ ) -> SubSequence ? where C. Element == Element {
129
+ let suffixCount = other. count
130
+ guard suffix ( suffixCount) . elementsEqual ( other) else { return nil }
131
+ return dropLast ( suffixCount)
132
+ }
112
133
}
113
134
114
135
extension UnsafeMutableRawPointer {
You can’t perform that action at this time.
0 commit comments