|
12 | 12 |
|
13 | 13 | #if swift(>=6)
|
14 | 14 | public import SwiftSyntax
|
| 15 | +internal import SwiftParser |
15 | 16 | #else
|
16 | 17 | import SwiftSyntax
|
| 18 | +import SwiftParser |
17 | 19 | #endif
|
18 | 20 |
|
19 | 21 | // MARK: - PartialSyntaxNode
|
@@ -124,7 +126,22 @@ extension WithOptionalCodeBlockSyntax where Self: DeclSyntaxProtocol {
|
124 | 126 | _ header: SyntaxNodeString,
|
125 | 127 | @CodeBlockItemListBuilder bodyBuilder: () throws -> CodeBlockItemListSyntax
|
126 | 128 | ) throws {
|
127 |
| - let decl = DeclSyntax("\(header) {}") |
| 129 | + // If the type provides a custom `SyntaxParseable` implementation, use that. Otherwise construct it as a |
| 130 | + // `DeclSyntax`. |
| 131 | + // We cannot use normal string interpolation here because the conformance to `ExpressibleByStringInterpolation` is |
| 132 | + // not implied by `SyntaxParsable` but generated for each type by |
| 133 | + // `SyntaxExpressibleByStringInterpolationConformances.swift`. And we can’t use that protocol in the `as?` check |
| 134 | + // because then the compiler complains that `parsableType` is not instantiable. So, manually do the same work that |
| 135 | + // a string literal with interpolation segments would do. |
| 136 | + let decl: DeclSyntax |
| 137 | + var stringInterpolation = SyntaxStringInterpolation(literalCapacity: 1, interpolationCount: 1) |
| 138 | + stringInterpolation.appendInterpolation(header) |
| 139 | + stringInterpolation.appendLiteral(" {}") |
| 140 | + if let parsableType = Self.self as? SyntaxParseable.Type { |
| 141 | + decl = parsableType.init(stringInterpolation: stringInterpolation).cast(DeclSyntax.self) |
| 142 | + } else { |
| 143 | + decl = DeclSyntax(stringInterpolation: stringInterpolation) |
| 144 | + } |
128 | 145 | guard let castedDecl = decl.as(Self.self) else {
|
129 | 146 | throw SyntaxStringInterpolationInvalidNodeTypeError(expectedType: Self.self, actualNode: decl)
|
130 | 147 | }
|
@@ -170,7 +187,17 @@ extension HasTrailingMemberDeclBlock where Self: DeclSyntaxProtocol {
|
170 | 187 | _ header: SyntaxNodeString,
|
171 | 188 | @MemberBlockItemListBuilder membersBuilder: () throws -> MemberBlockItemListSyntax
|
172 | 189 | ) throws {
|
173 |
| - let decl = DeclSyntax("\(header) {}") |
| 190 | + // If the type provides a custom `SyntaxParseable` implementation, use that. Otherwise construct it as a |
| 191 | + // `DeclSyntax`. |
| 192 | + let decl: DeclSyntax |
| 193 | + var stringInterpolation = SyntaxStringInterpolation(literalCapacity: 1, interpolationCount: 1) |
| 194 | + stringInterpolation.appendInterpolation(header) |
| 195 | + stringInterpolation.appendLiteral(" {}") |
| 196 | + if let parsableType = Self.self as? SyntaxParseable.Type { |
| 197 | + decl = parsableType.init(stringInterpolation: stringInterpolation).cast(DeclSyntax.self) |
| 198 | + } else { |
| 199 | + decl = DeclSyntax(stringInterpolation: stringInterpolation) |
| 200 | + } |
174 | 201 | guard let castedDecl = decl.as(Self.self) else {
|
175 | 202 | throw SyntaxStringInterpolationInvalidNodeTypeError(expectedType: Self.self, actualNode: decl)
|
176 | 203 | }
|
|
0 commit comments