Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ export function toTree(source, options = {}) {
}

let parseResults = preprocessor.parse(source);
// content-tag reports a class's own template before a template that sits
// earlier in its heritage clause (`class A extends mixin(<template/>) {
// <template/> }`); `toPlaceholderJS` walks the source forward, so it needs
// them in source order.
parseResults.sort((a, b) => a.range.startUtf16Codepoint - b.range.startUtf16Codepoint);
let js = toPlaceholderJS(source, parseResults);

const useCustomParser = !!options.parser;
Expand Down
24 changes: 24 additions & 0 deletions tests/parse.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,30 @@ describe("parse", () => {
expect(mustache).toBeTruthy();
});

it("handles a template in a heritage clause before the class body template", () => {
// content-tag reports these two templates in the opposite order from
// their position in the source.
const source = [
"const mixin = (base, t) => base;",
"export class Both extends mixin(Object, <template>heritage</template>) {",
" <template>own</template>",
"}",
"const after = 1;",
].join("\n");
const ast = parse(source);

expect(ast.program.body.map((node) => node.type)).toEqual([
"VariableDeclaration",
"ExportNamedDeclaration",
"VariableDeclaration",
]);
const templates = findAllNodes(ast, "GlimmerTemplate");
expect(templates.map((t) => source.slice(t.start, t.end))).toEqual([
"<template>heritage</template>",
"<template>own</template>",
]);
});

it("handles multiple classes with templates", () => {
const source = `class A extends Component {
<template><div>A</div></template>
Expand Down
Loading