ember-legacy-class-transform
Version:
The default blueprint for ember-cli addons.
91 lines • 3.93 kB
JavaScript
import { EMPTY_ARRAY } from '@glimmer/util';
import * as WireFormat from '@glimmer/wire-format';
import * as ClientSide from './syntax/client-side';
import CompilableTemplate from './syntax/compilable-template';
import { ATTRS_BLOCK } from './syntax/functions';
var Ops = WireFormat.Ops;
export default class Scanner {
constructor(block, env) {
this.block = block;
this.env = env;
}
scanEntryPoint(meta) {
let { block } = this;
let { statements, symbols, hasEval } = block;
return new CompilableTemplate(statements, { meta, symbols, hasEval });
}
scanBlock(meta) {
let { block } = this;
let { statements } = block;
return new CompilableTemplate(statements, { meta, parameters: EMPTY_ARRAY });
}
scanLayout(meta, attrs, componentName) {
let { block } = this;
let { statements, symbols, hasEval } = block;
let symbolTable = { meta, hasEval, symbols };
let newStatements = [];
let toplevel;
let inTopLevel = false;
for (let i = 0; i < statements.length; i++) {
let statement = statements[i];
if (WireFormat.Statements.isComponent(statement)) {
let tagName = statement[1];
if (!this.env.hasComponentDefinition(tagName, meta.templateMeta)) {
if (toplevel !== undefined) {
newStatements.push([Ops.OpenElement, tagName]);
} else {
toplevel = tagName;
decorateTopLevelElement(tagName, symbols, attrs, newStatements);
}
addFallback(statement, newStatements);
} else {
if (toplevel === undefined && tagName === componentName) {
toplevel = tagName;
decorateTopLevelElement(tagName, symbols, attrs, newStatements);
addFallback(statement, newStatements);
} else {
newStatements.push(statement);
}
}
} else {
if (toplevel === undefined && WireFormat.Statements.isOpenElement(statement)) {
toplevel = statement[1];
inTopLevel = true;
decorateTopLevelElement(toplevel, symbols, attrs, newStatements);
} else {
if (inTopLevel) {
if (WireFormat.Statements.isFlushElement(statement)) {
inTopLevel = false;
} else if (WireFormat.Statements.isModifier(statement)) {
throw Error(`Found modifier "${statement[1]}" on the top-level element of "${componentName}"\. Modifiers cannot be on the top-level element`);
}
}
newStatements.push(statement);
}
}
}
newStatements.push([Ops.ClientSideStatement, ClientSide.Ops.DidRenderLayout]);
return new CompilableTemplate(newStatements, symbolTable);
}
}
function addFallback(statement, buffer) {
let [,, attrs,, block] = statement;
for (let i = 0; i < attrs.length; i++) {
buffer.push(attrs[i]);
}
buffer.push([Ops.FlushElement]);
if (block) {
let { statements } = block;
for (let i = 0; i < statements.length; i++) {
buffer.push(statements[i]);
}
}
buffer.push([Ops.CloseElement]);
}
function decorateTopLevelElement(tagName, symbols, attrs, buffer) {
let attrsSymbol = symbols.push(ATTRS_BLOCK);
buffer.push([Ops.ClientSideStatement, ClientSide.Ops.OpenComponentElement, tagName]);
buffer.push([Ops.ClientSideStatement, ClientSide.Ops.DidCreateElement]);
buffer.push([Ops.Yield, attrsSymbol, EMPTY_ARRAY]);
buffer.push(...attrs);
}