Skip to content

Commit fdd2779

Browse files
fixed: force unwrapping content in the macro not expanding properly
1 parent 0b9beea commit fdd2779

File tree

2 files changed

+63
-8
lines changed

2 files changed

+63
-8
lines changed

Sources/HTMLKitUtilities/ParseData.swift

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,9 @@ public extension HTMLKitUtilities {
259259
remaining_interpolation -= string.ranges(of: target).count
260260
string.replace(target, with: fix)
261261
} else {
262+
//if let decl:DeclReferenceExprSyntax = expression.declRef {
263+
// TODO: lookup and try to promote | need to wait for swift-syntax to update to access SwiftLexicalLookup
264+
//}
262265
//string = "\\(\"\(string)\".escapingHTML(escapeAttributes: true))"
263266
warn_interpolation(context: context, node: expr, string: &string, remaining_interpolation: &remaining_interpolation, lookupFiles: lookupFiles)
264267
}
@@ -273,6 +276,9 @@ extension HTMLKitUtilities {
273276
expression: ExprSyntax,
274277
lookupFiles: Set<String>
275278
) -> LiteralReturnType? {
279+
if let _:NilLiteralExprSyntax = expression.as(NilLiteralExprSyntax.self) {
280+
return nil
281+
}
276282
if let stringLiteral:StringLiteralExprSyntax = expression.stringLiteral {
277283
let string:String = stringLiteral.string
278284
if stringLiteral.segments.count(where: { $0.is(ExpressionSegmentSyntax.self) }) == 0 {
@@ -343,6 +349,10 @@ extension HTMLKitUtilities {
343349
return .string(string)
344350
}
345351
}
352+
if let unwrap:ForceUnwrapExprSyntax = expression.as(ForceUnwrapExprSyntax.self) {
353+
let merged:String = merge_force_unwrap_into_single_line(unwrap)
354+
return .interpolation("\\(" + merged + ")")
355+
}
346356
return nil
347357
}
348358

@@ -391,6 +401,20 @@ extension HTMLKitUtilities {
391401
}
392402

393403
// MARK: Merge
404+
static func merge_into_single_line(_ expression: ExprSyntax) -> String {
405+
if let function:FunctionCallExprSyntax = expression.functionCall {
406+
return merge_func_into_single_line(function)
407+
} else if let member:MemberAccessExprSyntax = expression.memberAccess {
408+
return merge_member_into_single_line(member)
409+
} else if let force_unwrap:ForceUnwrapExprSyntax = expression.as(ForceUnwrapExprSyntax.self) {
410+
return merge_force_unwrap_into_single_line(force_unwrap) + "!"
411+
} else {
412+
return "\(expression)"
413+
}
414+
}
415+
static func merge_force_unwrap_into_single_line(_ force_unwrap: ForceUnwrapExprSyntax) -> String {
416+
return merge_into_single_line(force_unwrap.expression) + "!"
417+
}
394418
static func merge_member_into_single_line(_ member: MemberAccessExprSyntax) -> String {
395419
var string:String = "\(member)"
396420
string.removeAll { $0.isWhitespace }
@@ -412,14 +436,7 @@ extension HTMLKitUtilities {
412436
arg.insert(",", at: arg.startIndex)
413437
}
414438
arg += ": "
415-
var expr:String
416-
if let f:FunctionCallExprSyntax = argument.expression.functionCall {
417-
expr = merge_func_into_single_line(f)
418-
} else if let m:MemberAccessExprSyntax = argument.expression.memberAccess {
419-
expr = merge_member_into_single_line(m)
420-
} else {
421-
expr = "\(argument.expression)"
422-
}
439+
var expr:String = merge_into_single_line(argument.expression)
423440
while expr.first?.isWhitespace ?? false {
424441
expr.removeFirst()
425442
}

Tests/HTMLKitTests/InterpolationTests.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,38 @@ struct InterpolationTests {
109109
#expect(string == "<div>Shrek isLove, Shrek isLife</div>")
110110
}
111111

112+
@Test func inferred_type_interpolation() {
113+
var array:[String] = ["toothless", "hiccup"]
114+
var string:String = array.map({
115+
#html(option(value: $0))
116+
}).joined()
117+
#expect(string == "<option value=\"toothless\"></option><option value=\"hiccup\"></option>")
118+
119+
array = ["cloudjumper", "light fury"]
120+
string = array.map({ dragon in
121+
#html(option(value: dragon))
122+
}).joined()
123+
#expect(string == "<option value=\"cloudjumper\"></option><option value=\"light fury\"></option>")
124+
}
125+
126+
@Test func force_unwrap_interpolation() {
127+
let optionals:[String?] = ["stormfly", "sneaky"]
128+
var string:String = optionals.map({
129+
#html(option(value: $0!))
130+
}).joined()
131+
#expect(string == "<option value=\"stormfly\"></option><option value=\"sneaky\"></option>")
132+
133+
let array:[String] = ["sharpshot", "thornshade"]
134+
string = #html(option(value: array.get(0)!))
135+
#expect(string == "<option value=\"sharpshot\"></option>")
136+
137+
string = #html(option(value: array
138+
.get(
139+
1
140+
)!))
141+
#expect(string == "<option value=\"thornshade\"></option>")
142+
}
143+
112144
@Test func flatten() {
113145
let title:String = "flattening"
114146
var string:String = #html(meta(content: "\("interpolation \(title)")", name: "description"))
@@ -136,6 +168,12 @@ struct InterpolationTests {
136168
}
137169
}
138170

171+
fileprivate extension Array {
172+
func get(_ index: Index) -> Element? {
173+
return index < endIndex ? self[index] : nil
174+
}
175+
}
176+
139177
// MARK: 3rd party tests
140178
extension InterpolationTests {
141179
enum Shrek : String {

0 commit comments

Comments
 (0)