UNPKG

ember-legacy-class-transform

Version:
91 lines 3.93 kB
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); }