Closed
Description
This one will be a bit more involved, I think.
I'm trying to use this trivial result builder for convenience when outputting dynamic HTML.
@resultBuilder
struct StringBuilder {
static func buildBlock(_ components: String...) -> String {
components.joined()
}
static func buildBlock(_ components: CustomStringConvertible...) -> String {
components.map(\.description).joined()
}
static func buildExpression(_ expression: String) -> String {
expression
}
static func buildExpression(_ expression: CustomStringConvertible) -> String {
expression.description
}
static func buildOptional(_ components: String?) -> String {
components ?? ""
}
static func buildOptional(_ components: CustomStringConvertible?) -> String {
components?.description ?? ""
}
static func buildEither(first components: String) -> String {
components
}
static func buildEither(first components: CustomStringConvertible) -> String {
components.description
}
static func buildEither(second components: String) -> String {
components
}
static func buildEither(second components: CustomStringConvertible) -> String {
components.description
}
static func buildArray(_ components: [String]) -> String {
components.joined()
}
static func buildArray(_ components: [CustomStringConvertible]) -> String {
components.map(\.description).joined()
}
}
func str(@StringBuilder _ body: () -> String) -> String {
body()
}
This will expand correctly:
let e: String = #html(div(str({ "d"; "e" })))
"<div>\(str({ "d"; "e" }))</div>"
(Okay)
This will cause SourceKitService and swift-frontend to infinite-loop:
let e: String = #html(div(str({
"d"
"e"
})))