Skip to content

Commit f22ca51

Browse files
better interpolation flattening; better globalAttributeAlreadyDefined error msg
1 parent 4dcd8d4 commit f22ca51

File tree

2 files changed

+159
-88
lines changed

2 files changed

+159
-88
lines changed

Sources/HTMLKitMacros/HTMLElement.swift

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ private extension HTMLElement {
108108
context.diagnose(Diagnostic(node: key_element, message: DiagnosticMsg(id: "spacesNotAllowedInAttributeDeclaration", message: "Spaces are not allowed in attribute declaration.")))
109109
} else if let value:String = value {
110110
if keys.contains(key) {
111-
context.diagnose(Diagnostic(node: key_element, message: DiagnosticMsg(id: "globalAttributeAlreadyDefined", message: "Global attribute is already defined.")))
111+
context.diagnose(Diagnostic(node: key_element, message: DiagnosticMsg(id: "globalAttributeAlreadyDefined", message: "Global attribute \"" + key + "\" is already defined.")))
112112
} else {
113113
attributes.append(key + (value.isEmpty ? "" : "=\\\"" + value + "\\\""))
114114
keys.insert(key)
@@ -265,16 +265,10 @@ private extension HTMLElement {
265265
//context.diagnose(Diagnostic(node: expression, message: DiagnosticMsg(id: "somethingWentWrong", message: "Something went wrong. (" + expression.debugDescription + ")", severity: .warning)))
266266
return nil
267267
}
268-
var remaining_interpolation:Int = 0
269-
if let list:StringLiteralSegmentListSyntax = expression.stringLiteral?.segments {
270-
for segment in list {
271-
if let expr:ExpressionSegmentSyntax = segment.as(ExpressionSegmentSyntax.self) {
272-
remaining_interpolation += 1
273-
if flatten_interpolation(string: &string, remaining_interpolation: &remaining_interpolation, expr: expr) {
274-
remaining_interpolation -= 1
275-
}
276-
}
277-
}
268+
let interpolation:[ExpressionSegmentSyntax] = expression.stringLiteral?.segments.compactMap({ $0.as(ExpressionSegmentSyntax.self) }) ?? []
269+
var remaining_interpolation:Int = interpolation.count
270+
for expr in interpolation {
271+
string = flatten_interpolation(remaining_interpolation: &remaining_interpolation, expr: expr)
278272
}
279273
if returnType == .interpolation || remaining_interpolation > 0 {
280274
if !string.contains("\\(") {
@@ -285,26 +279,32 @@ private extension HTMLElement {
285279
}
286280
return (string, returnType)
287281
}
288-
static func flatten_interpolation(string: inout String, remaining_interpolation: inout Int, expr: ExpressionSegmentSyntax) -> Bool { // TODO: can still be improved ("\(description \(title))" doesn't get flattened)
282+
static func flatten_interpolation(remaining_interpolation: inout Int, expr: ExpressionSegmentSyntax) -> String {
289283
let expression:ExprSyntax = expr.expressions.first!.expression
290-
if let list:StringLiteralSegmentListSyntax = expression.stringLiteral?.segments {
291-
for segment in list {
292-
if let expr:ExpressionSegmentSyntax = segment.as(ExpressionSegmentSyntax.self) {
293-
remaining_interpolation += 1
294-
if flatten_interpolation(string: &string, remaining_interpolation: &remaining_interpolation, expr: expr) {
295-
remaining_interpolation -= 1
284+
var string:String = "\(expr)"
285+
if let stringLiteral:StringLiteralExprSyntax = expression.stringLiteral {
286+
let segments:StringLiteralSegmentListSyntax = stringLiteral.segments
287+
if segments.count(where: { $0.is(StringSegmentSyntax.self) }) == segments.count {
288+
remaining_interpolation = 0
289+
string = segments.map({ $0.as(StringSegmentSyntax.self)!.content.text }).joined()
290+
} else {
291+
var values:[String] = []
292+
for segment in segments {
293+
if let literal:String = segment.as(StringSegmentSyntax.self)?.content.text {
294+
values.append(literal)
295+
} else if let interpolation:ExpressionSegmentSyntax = segment.as(ExpressionSegmentSyntax.self) {
296+
values.append(flatten_interpolation(remaining_interpolation: &remaining_interpolation, expr: interpolation))
297+
} else {
298+
values.append("\(segment)")
296299
}
297-
} else if let fix:String = segment.as(StringSegmentSyntax.self)?.content.text {
298-
string.replace("\(expr)", with: fix)
299-
remaining_interpolation -= 1
300300
}
301+
string = values.joined()
301302
}
302-
}
303-
if let fix:String = expression.integerLiteral?.literal.text ?? expression.floatLiteral?.literal.text {
303+
} else if let fix:String = expression.integerLiteral?.literal.text ?? expression.floatLiteral?.literal.text {
304+
remaining_interpolation -= string.ranges(of: "\(expr)").count
304305
string.replace("\(expr)", with: fix)
305-
return true
306306
}
307-
return false
307+
return string
308308
}
309309
}
310310

0 commit comments

Comments
 (0)