@@ -199,81 +199,16 @@ extension SyntaxExpressibleByStringInterpolation {
199
199
200
200
// MARK: ExpressibleByLiteralSyntax conformances
201
201
202
- extension Collection {
203
- fileprivate func allIndices( where predicate: @escaping ( Element ) -> Bool ) -> UnfoldSequence < Index , Index > {
204
- sequence ( state: startIndex) { i in
205
- guard let newI = self [ i... ] . firstIndex ( where: predicate) else {
206
- return nil
207
- }
208
- i = index ( after: newI)
209
- return newI
210
- }
211
- }
212
- }
213
-
214
202
extension Substring : ExpressibleByLiteralSyntax {
215
203
public func makeLiteralSyntax( ) -> ExprSyntaxProtocol {
216
- // TODO: Choose whether to use a single-line or multi-line literal.
217
- let quote = TokenSyntax . stringQuote
218
-
219
- // Select a raw delimiter long enough that we won't need to escape quotes or backslashes.
220
- // Locate backslashes and quotes...
221
- let problemIndices = allIndices ( where: #"\""# . contains ( _: ) )
222
- // Count adjacent hashes and compute the largest number (-1 = no problem chars)...
223
- let maxPoundCount = problemIndices. reduce ( - 1 ) { prevCount, i in
224
- // Technically we don't need to check leading pounds for a backslash, but this is easier.
225
- Swift . max (
226
- prevCount,
227
- self [ index ( after: i) ... ] . prefix ( while: { $0 == " # " } ) . count,
228
- self [ ..< i] . reversed ( ) . prefix ( while: { $0 == " # " } ) . count
229
- )
230
- }
231
- // And create the delimiter.
232
- let rawDelimiter = String ( repeating: " # " , count: maxPoundCount + 1 )
233
-
234
- // Assemble the string with newlines escaped.
235
- var segment = " "
236
- var previousStart = startIndex
237
-
238
- // Scan for next newline; if found, append text up to newline, then an escape sequence for the newline, then continue at the next character.
239
- for i in allIndices ( where: \. isNewline) {
240
- segment += self [ previousStart..< i]
241
-
242
- for scalar in self [ i] . unicodeScalars {
243
- segment += " \\ " + rawDelimiter
244
- switch scalar {
245
- case " \r " :
246
- segment += " r "
247
- case " \n " :
248
- segment += " n "
249
- default :
250
- segment += " u{ \( String ( scalar. value, radix: 16 ) ) } "
251
- }
252
- }
253
-
254
- previousStart = index ( after: i)
255
- }
256
-
257
- // Append remainder of string.
258
- segment += self [ previousStart... ]
259
-
260
- // Now make these into syntax nodes.
261
- let optRawDelimiter = rawDelimiter. isEmpty ? nil : rawDelimiter
262
- return StringLiteralExpr (
263
- openDelimiter: optRawDelimiter,
264
- openQuote: quote,
265
- segments: StringLiteralSegments {
266
- StringSegment ( content: segment)
267
- } ,
268
- closeQuote: quote,
269
- closeDelimiter: optRawDelimiter
270
- )
204
+ String ( self ) . makeLiteralSyntax ( )
271
205
}
272
206
}
273
207
274
208
extension String : ExpressibleByLiteralSyntax {
275
209
public func makeLiteralSyntax( ) -> ExprSyntaxProtocol {
276
- self [ ... ] . makeLiteralSyntax ( )
210
+ // TODO: Use a multi-line literal if there are more than N inner newlines.
211
+ StringLiteralExpr ( content: self )
277
212
}
278
213
}
279
214
0 commit comments