@@ -119,6 +119,18 @@ extension SyntaxStringInterpolation: StringInterpolationProtocol {
119
119
format: format
120
120
)
121
121
}
122
+
123
+ // This overload is technically redundant with the previous one, except that
124
+ // it silences a warning about interpolating Optionals.
125
+ public mutating func appendInterpolation< Literal: ExpressibleByLiteralSyntax > (
126
+ literal value: Literal ? ,
127
+ format: BasicFormat = BasicFormat ( )
128
+ ) {
129
+ self . appendInterpolation (
130
+ ExprSyntax ( fromProtocol: value. makeLiteralSyntax ( ) ) ,
131
+ format: format
132
+ )
133
+ }
122
134
}
123
135
124
136
/// Syntax nodes that can be formed by a string interpolation involve source
@@ -346,3 +358,47 @@ extension Dictionary: ExpressibleByLiteralSyntax where Key: ExpressibleByLiteral
346
358
}
347
359
}
348
360
361
+ extension Optional : ExpressibleByLiteralSyntax where Wrapped: ExpressibleByLiteralSyntax {
362
+ public func makeLiteralSyntax( ) -> ExprSyntaxProtocol {
363
+ func containsNil( _ expr: ExprSyntaxProtocol ) -> Bool {
364
+ if expr. is ( NilLiteralExpr . self) {
365
+ return true
366
+ }
367
+
368
+ if let call = expr. as ( FunctionCallExpr . self) ,
369
+ let memberAccess = call. calledExpression. as ( MemberAccessExpr . self) ,
370
+ memberAccess. name. text == " some " ,
371
+ let argument = call. argumentList. first? . expression {
372
+ return containsNil ( argument)
373
+ }
374
+
375
+ return false
376
+ }
377
+
378
+ switch self {
379
+ case nil :
380
+ return NilLiteralExpr ( )
381
+
382
+ case let wrapped? :
383
+ let wrappedExpr = wrapped. makeLiteralSyntax ( )
384
+
385
+ // If this is a nested optional type, and the wrapped value is `nil` or
386
+ // e.g. `.some(nil)`, add a layer of `.some(_:)` around it to preserve the
387
+ // depth of the data structure.
388
+ if containsNil ( wrappedExpr) {
389
+ // TODO: Can't we have something nicer than this? `MemberAccessExpr(name: "some").makeCall(wrapped)`?
390
+ return FunctionCallExpr (
391
+ calledExpression: MemberAccessExpr ( name: " some " ) ,
392
+ leftParen: . leftParen,
393
+ argumentList: TupleExprElementList {
394
+ TupleExprElement ( expression: wrappedExpr)
395
+ } ,
396
+ rightParen: . rightParen
397
+ )
398
+ }
399
+
400
+ return wrappedExpr
401
+ }
402
+ }
403
+ }
404
+
0 commit comments