Skip to content

Commit 547a134

Browse files
authored
Fix nested extend with sugar (#127)
When nesting an `#extend` with two parameters, the second parameter was ignored instead of being used as context. Fixes #126
1 parent 728dd3d commit 547a134

File tree

3 files changed

+38
-7
lines changed

3 files changed

+38
-7
lines changed

Sources/LeafKit/LeafAST.swift

+1-7
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,7 @@ public struct LeafAST: Hashable {
6262
}
6363

6464
// replace the original Syntax with the results of inlining, potentially 1...n
65-
let replacementSyntax: [Syntax]
66-
if case .extend(let extend) = ast[pos], let context = extend.context {
67-
let inner = ast[pos].inlineRefs(providedExts, [:])
68-
replacementSyntax = [.with(.init(context: context, body: inner))]
69-
} else {
70-
replacementSyntax = ast[pos].inlineRefs(providedExts, [:])
71-
}
65+
let replacementSyntax = ast[pos].inlineRefs(providedExts, [:])
7266
ast.replaceSubrange(pos...pos, with: replacementSyntax)
7367
// any returned new inlined syntaxes can't be further resolved at this point
7468
// but we need to add their unresolvable references to the global set

Sources/LeafKit/LeafSyntax/LeafSyntax.swift

+4
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ extension Syntax: BodiedSyntax {
105105
}
106106

107107
internal func inlineRefs(_ externals: [String: LeafAST], _ imports: [String: Export]) -> [Syntax] {
108+
if case .extend(let extend) = self, let context = extend.context {
109+
let inner = extend.inlineRefs(externals, imports)
110+
return [.with(.init(context: context, body: inner))]
111+
}
108112
var result = [Syntax]()
109113
switch self {
110114
case .import(let im):

Tests/LeafKitTests/LeafTests.swift

+33
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,39 @@ final class LeafTests: XCTestCase {
252252
XCTAssertEqual(str, expected)
253253
}
254254

255+
func testNestedExtendWithSugar() throws {
256+
let layout = """
257+
<body>#import("content")</body>
258+
"""
259+
260+
let header = """
261+
<h1>#(child)</h1>
262+
"""
263+
264+
let base = """
265+
#extend("layout"):#export("content"):<main>#extend("header", parent)</main>#endexport#endextend
266+
"""
267+
268+
let expected = """
269+
<body><main><h1>Elizabeth</h1></main></body>
270+
"""
271+
272+
let layoutAST = try LeafAST(name: "layout", ast: parse(layout))
273+
let headerAST = try LeafAST(name: "header", ast: parse(header))
274+
let baseAST = try LeafAST(name: "base", ast: parse(base))
275+
276+
let baseResolved = LeafAST(from: baseAST, referencing: ["layout": layoutAST, "header": headerAST])
277+
278+
var serializer = LeafSerializer(
279+
ast: baseResolved.ast,
280+
ignoreUnfoundImports: false
281+
)
282+
let view = try serializer.serialize(context: ["parent": ["child": "Elizabeth"]])
283+
let str = view.getString(at: view.readerIndex, length: view.readableBytes) ?? ""
284+
285+
XCTAssertEqual(str, expected)
286+
}
287+
255288
func testEmptyForLoop() throws {
256289
let template = """
257290
#for(category in categories):

0 commit comments

Comments
 (0)