UNPKG

ember-material-icons

Version:

Google Material icons for your ember-cli app

210 lines (171 loc) 5.06 kB
import { Scope, Environment, Opcode } from '../environment'; import { Reference, PathReference, ReferenceIterator } from '@glimmer/reference'; import { Option, unwrap } from '@glimmer/util'; import { InlineBlock } from '../scanner'; import { EvaluatedArgs } from '../compiled/expressions/args'; import { Component, ComponentManager } from '../component/interfaces'; export class CapturedFrame { constructor( public operand: Option<PathReference<any>>, public args: Option<EvaluatedArgs>, public condition: Option<Reference<boolean>> ) {} } class Frame { ip: number; operand: Option<PathReference<any>> = null; immediate: any = null; args: Option<EvaluatedArgs> = null; callerScope: Option<Scope> = null; blocks: Option<Blocks> = null; condition: Option<Reference<boolean>> = null; iterator: Option<ReferenceIterator> = null; key: Option<string> = null; constructor( public start: number, public end: number, public component = <Component>null, public manager: Option<ComponentManager<Component>> = null, public shadow: Option<InlineBlock> = null ) { this.ip = start; } capture(): CapturedFrame { return new CapturedFrame(this.operand, this.args, this.condition); } restore(frame: CapturedFrame) { this.operand = frame.operand; this.args = frame.args; this.condition = frame.condition; } } export interface Blocks { default: Option<InlineBlock>; inverse: Option<InlineBlock>; } export class FrameStack { private frames: Frame[] = []; private frame: number = -1; private get currentFrame(): Frame { return this.frames[this.frame]; } push(start: number, end: number, component = <Component>null, manager: Option<ComponentManager<Component>> = null, shadow: Option<InlineBlock> = null) { let pos = ++this.frame; if (pos < this.frames.length) { let frame = this.frames[pos]; frame.start = frame.ip = start; frame.end = end; frame.component = component; frame.manager = manager; frame.shadow = shadow; frame.operand = null; frame.immediate = null; frame.args = null; frame.callerScope = null; frame.blocks = null; frame.condition = null; frame.iterator = null; frame.key = null; } else { this.frames[pos] = new Frame(start, end, component, manager, shadow); } } pop() { this.frame--; } capture(): CapturedFrame { return this.currentFrame.capture(); } restore(frame: CapturedFrame) { this.currentFrame.restore(frame); } getStart(): number { return this.currentFrame.start; } getEnd(): number { return this.currentFrame.end; } getCurrent(): number { return this.currentFrame.ip; } setCurrent(ip: number): number { return this.currentFrame.ip = ip; } getOperand<T>(): PathReference<T> { return unwrap(this.currentFrame.operand); } setOperand<T>(operand: PathReference<T>): PathReference<T> { return this.currentFrame.operand = operand; } getImmediate<T>(): T { return this.currentFrame.immediate; } setImmediate<T>(value: T): T { return this.currentFrame.immediate = value; } // FIXME: These options are required in practice by the existing code, but // figure out why. getArgs(): Option<EvaluatedArgs> { return this.currentFrame.args; } setArgs(args: EvaluatedArgs): EvaluatedArgs { return this.currentFrame.args = args; } getCondition(): Reference<boolean> { return unwrap(this.currentFrame.condition); } setCondition(condition: Reference<boolean>): Reference<boolean> { return this.currentFrame.condition = condition; } getIterator(): ReferenceIterator { return unwrap(this.currentFrame.iterator); } setIterator(iterator: ReferenceIterator): ReferenceIterator { return this.currentFrame.iterator = iterator; } getKey(): Option<string> { return this.currentFrame.key; } setKey(key: string): string { return this.currentFrame.key = key; } getBlocks(): Blocks { return unwrap(this.currentFrame.blocks); } setBlocks(blocks: Blocks): Blocks { return this.currentFrame.blocks = blocks; } getCallerScope(): Scope { return unwrap(this.currentFrame.callerScope); } setCallerScope(callerScope: Scope): Scope { return this.currentFrame.callerScope = callerScope; } getComponent(): Component { return unwrap(this.currentFrame.component); } getManager(): ComponentManager<Component> { return unwrap(this.currentFrame.manager); } getShadow(): Option<InlineBlock> { return this.currentFrame.shadow; } goto(ip: number) { this.setCurrent(ip); } nextStatement(env: Environment): Option<Opcode> { while (this.frame !== -1) { let frame = this.frames[this.frame]; let ip = frame.ip; let end = frame.end; if (ip < end) { let program = env.program; frame.ip += 4; return program.opcode(ip); } else { this.pop(); } } return null; } }