UNPKG

ember-material-icons

Version:

Google Material icons for your ember-cli app

327 lines (276 loc) 11.1 kB
import { Opaque, Option, Dict, Slice as ListSlice, initializeGuid, fillNulls } from '@glimmer/util'; import { RevisionTag, VersionedPathReference } from '@glimmer/reference'; import { VM, UpdatingVM } from './vm'; import { CompiledExpression, CompiledArgs } from './compiled/expressions'; import { NULL_REFERENCE, UNDEFINED_REFERENCE } from './references'; import { InlineBlock } from './scanner'; import { Opcode } from './environment'; export interface OpcodeJSON { type: number | string; guid?: Option<number>; deopted?: boolean; args?: string[]; details?: Dict<Option<string>>; children?: OpcodeJSON[]; } export function pretty(json: OpcodeJSON): string { return `${json.type}(${json.args ? json.args.join(', ') : ''})`; } export const enum OpcodeName { PushChildScope, // () PopScope, // () PushDynamicScope, // () PopDynamicScope, // () Put, // (ConstantReference) EvaluatePut, // (ConstantExpression) PutArgs, // (ConstantExpression) BindPositionalArgs, // BindNamedArgs, // (ConstantArray<string>, ConstantArray<number>) BindBlocks, // (ConstantArray<string>, ConstantArray<number>) BindPartialArgs, // (number) BindCallerScope, // () BindDynamicScope, // (ConstantArray<string>) Enter, // (ConstantSlice) Exit, // () Evaluate, // (ConstantBlock) Jump, // (number) JumpIf, // (number) JumpUnless, // (number) Test, // (ConstantFunction) OpenBlock, // (Other<CompiledGetBlock>, ConstantExpression) CloseBlock, // () PutDynamicComponent, // () PutComponent, // (Other<ComponentDefinition>) OpenComponent, // (ConstantExpression, ConstantBlock) DidCreateElement, // ShadowAttributes, // () DidRenderLayout, // () CloseComponent, // () Text, // (ConstantString) Comment, // (ConstantString) DynamicContent, // (Other<AppendDynamicOpcode>) OpenElement, // (ConstantString) PushRemoteElement, // () PopRemoteElement, // () OpenComponentElement, // (ConstantString) OpenDynamicElement, // () FlushElement, // () CloseElement, // () PopElement, // () StaticAttr, // (ConstantString, ConstantString, ConstantString) Modifier, // (ConstantString, ConstantOther<ModifierManager>, ConstantExpression) DynamicAttrNS, // (ConstantString, ConstantString, number) DynamicAttr, // (ConstantString, number) PutIterator, // () EnterList, // (ConstantSlice) ExitList, // () EnterWithKey, // (ConstantSlice) NextIter, // (number) PutDynamicPartial, // (Other<SymbolTable>) PutPartial, // (Other<PartialDefinition>) EvaluatePartial // (Other<SymbolTable>, Other<Dict<PartialBlock>>) } // export type OpcodeName = // "PushChildScope" // () // | "PopScope" // () // | "PushDynamicScope" // () // | "PopDynamicScope" // () // | "Put" // (ConstantReference) // | "EvaluatePut" // (ConstantExpression) // | "PutArgs" // (ConstantExpression) // | "BindPositionalArgs" // // | "BindNamedArgs" // (ConstantArray<string>, ConstantArray<number>) // | "BindBlocks" // (ConstantArray<string>, ConstantArray<number>) // | "BindPartialArgs" // (number) // | "BindCallerScope" // () // | "BindDynamicScope" // (ConstantArray<string>) // | "Enter" // (ConstantSlice) // | "Exit" // () // | "Evaluate" // (ConstantBlock) // | "Jump" // (number) // | "JumpIf" // (number) // | "JumpUnless" // (number) // | "Test" // (ConstantFunction) // | "OpenBlock" // (Other<CompiledGetBlock>, ConstantExpression) // | "CloseBlock" // () // | "PutDynamicComponent" // () // | "PutComponent" // (Other<ComponentDefinition>) // | "OpenComponent" // (ConstantExpression, ConstantBlock) // | "DidCreateElement" // // | "ShadowAttributes" // () // | "DidRenderLayout" // () // | "CloseComponent" // () // | "Text" // (ConstantString) // | "Comment" // (ConstantString) // | "DynamicContent" // (Other<AppendDynamicOpcode>) // | "OpenElement" // (ConstantString) // | "PushRemoteElement" // () // | "PopRemoteElement" // () // | "OpenComponentElement" // (ConstantString) // | "OpenDynamicElement" // () // | "FlushElement" // () // | "CloseElement" // () // | "PopElement" // () // | "StaticAttr" // (ConstantString, ConstantString, ConstantString) // | "Modifier" // (ConstantString, ConstantOther<ModifierManager>, ConstantExpression) // | "DynamicAttrNS" // (ConstantString, ConstantString, number) // | "DynamicAttr" // (ConstantString, number) // | "PutIterator" // () // | "EnterList" // (ConstantSlice) // | "ExitList" // () // | "EnterWithKey" // (ConstantSlice) // | "NextIter" // (number) // | "PutDynamicPartial" // (Other<SymbolTable>) // | "PutPartial" // (Other<PartialDefinition>) // | "EvaluatePartial" // (Other<SymbolTable>, Other<Dict<PartialBlock>>) // ; export type ConstantType = 'slice' | 'block' | 'reference' | 'string' | 'number' | 'expression'; export type ConstantReference = number; export type ConstantString = number; export type ConstantExpression = number; export type ConstantSlice = number; export type ConstantBlock = number; export type ConstantFunction = number; export type ConstantArray = number; export type ConstantOther = number; export class Constants { // `0` means NULL private references: VersionedPathReference<Opaque>[] = []; private strings: string[] = []; private expressions: Opaque[] = []; private arrays: number[][] = []; private blocks: InlineBlock[] = []; private functions: Function[] = []; private others: Opaque[] = []; public NULL_REFERENCE: number; public UNDEFINED_REFERENCE: number; constructor() { this.NULL_REFERENCE = this.reference(NULL_REFERENCE); this.UNDEFINED_REFERENCE = this.reference(UNDEFINED_REFERENCE); } getReference<T extends Opaque>(value: ConstantReference): VersionedPathReference<T> { return this.references[value - 1] as VersionedPathReference<T>; } reference(value: VersionedPathReference<Opaque>): ConstantReference { let index = this.references.length; this.references.push(value); return index + 1; } getString(value: ConstantString): string { return this.strings[value - 1]; } string(value: string): ConstantString { let index = this.strings.length; this.strings.push(value); return index + 1; } getExpression<T>(value: ConstantExpression): T { return this.expressions[value - 1] as T; } expression(value: CompiledExpression<Opaque> | CompiledArgs): ConstantExpression { let index = this.expressions.length; this.expressions.push(value); return index + 1; } getArray(value: ConstantArray): number[] { return this.arrays[value - 1]; } array(values: number[]): ConstantArray { let index = this.arrays.length; this.arrays.push(values); return index + 1; } getBlock(value: ConstantBlock): InlineBlock { return this.blocks[value - 1]; } block(block: InlineBlock): ConstantBlock { let index = this.blocks.length; this.blocks.push(block); return index + 1; } getFunction<T extends Function>(value: ConstantFunction): T { return this.functions[value - 1] as T; } function(f: Function): ConstantFunction { let index = this.functions.length; this.functions.push(f); return index + 1; } getOther<T>(value: ConstantOther): T { return this.others[value - 1] as T; } other(other: Opaque): ConstantOther { let index = this.others.length; this.others.push(other); return index + 1; } } export type Operand1 = number; export type Operand2 = number; export type Operand3 = number; export type EvaluateOpcode = (vm: VM, opcode: Opcode) => void; export class AppendOpcodes { private evaluateOpcode: EvaluateOpcode[] = fillNulls<EvaluateOpcode>(OpcodeName.EvaluatePartial + 1); add<Name extends OpcodeName>(name: Name, evaluate: EvaluateOpcode): void { this.evaluateOpcode[name as number] = evaluate; } evaluate(vm: VM, opcode: Opcode) { let func = this.evaluateOpcode[opcode.type]; func(vm, opcode); } } export const APPEND_OPCODES = new AppendOpcodes(); export abstract class AbstractOpcode { public type: string; public _guid: number; constructor() { initializeGuid(this); } toJSON(): OpcodeJSON { return { guid: this._guid, type: this.type }; } } export abstract class UpdatingOpcode extends AbstractOpcode { public tag: RevisionTag; next: Option<UpdatingOpcode> = null; prev: Option<UpdatingOpcode> = null; abstract evaluate(vm: UpdatingVM): void; } export type UpdatingOpSeq = ListSlice<UpdatingOpcode>; export function inspect(opcodes: ReadonlyArray<AbstractOpcode>): string { let buffer: string[] = []; opcodes.forEach((opcode, i) => { _inspect(opcode.toJSON(), buffer, 0, i); }); return buffer.join(''); } function _inspect(opcode: OpcodeJSON, buffer: string[], level: number, index: number) { let indentation: string[] = []; for (let i=0; i<level; i++) { indentation.push(' '); } buffer.push(...indentation); buffer.push(`${index}. ${opcode.type}`); if (opcode.args || opcode.details) { buffer.push('('); if (opcode.args) { buffer.push(opcode.args.join(', ')); } if (opcode.details) { let keys = Object.keys(opcode.details); if (keys.length) { if (opcode.args && opcode.args.length) { buffer.push(', '); } buffer.push(keys.map(key => `${key}=${opcode.details && opcode.details[key]}`).join(', ')); } } buffer.push(')'); } buffer.push('\n'); if (opcode.children && opcode.children.length) { for (let i=0; i<opcode.children.length; i++) { _inspect(opcode.children[i], buffer, level+1, i); } } }