react / wstein / node_modules / jest-cli / node_modules / istanbul / node_modules / handlebars / dist / amd / handlebars / compiler / javascript-compiler.js
80738 viewsdefine(1["../base","../exception","../utils","./code-gen","exports"],2function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {3"use strict";4var COMPILER_REVISION = __dependency1__.COMPILER_REVISION;5var REVISION_CHANGES = __dependency1__.REVISION_CHANGES;6var Exception = __dependency2__["default"];7var isArray = __dependency3__.isArray;8var CodeGen = __dependency4__["default"];910function Literal(value) {11this.value = value;12}1314function JavaScriptCompiler() {}1516JavaScriptCompiler.prototype = {17// PUBLIC API: You can override these methods in a subclass to provide18// alternative compiled forms for name lookup and buffering semantics19nameLookup: function(parent, name /* , type*/) {20if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {21return [parent, ".", name];22} else {23return [parent, "['", name, "']"];24}25},26depthedLookup: function(name) {27return [this.aliasable('this.lookup'), '(depths, "', name, '")'];28},2930compilerInfo: function() {31var revision = COMPILER_REVISION,32versions = REVISION_CHANGES[revision];33return [revision, versions];34},3536appendToBuffer: function(source, location, explicit) {37// Force a source as this simplifies the merge logic.38if (!isArray(source)) {39source = [source];40}41source = this.source.wrap(source, location);4243if (this.environment.isSimple) {44return ['return ', source, ';'];45} else if (explicit) {46// This is a case where the buffer operation occurs as a child of another47// construct, generally braces. We have to explicitly output these buffer48// operations to ensure that the emitted code goes in the correct location.49return ['buffer += ', source, ';'];50} else {51source.appendToBuffer = true;52return source;53}54},5556initializeBuffer: function() {57return this.quotedString("");58},59// END PUBLIC API6061compile: function(environment, options, context, asObject) {62this.environment = environment;63this.options = options;64this.stringParams = this.options.stringParams;65this.trackIds = this.options.trackIds;66this.precompile = !asObject;6768this.name = this.environment.name;69this.isChild = !!context;70this.context = context || {71programs: [],72environments: []73};7475this.preamble();7677this.stackSlot = 0;78this.stackVars = [];79this.aliases = {};80this.registers = { list: [] };81this.hashes = [];82this.compileStack = [];83this.inlineStack = [];84this.blockParams = [];8586this.compileChildren(environment, options);8788this.useDepths = this.useDepths || environment.useDepths || this.options.compat;89this.useBlockParams = this.useBlockParams || environment.useBlockParams;9091var opcodes = environment.opcodes,92opcode,93firstLoc,94i,95l;9697for (i = 0, l = opcodes.length; i < l; i++) {98opcode = opcodes[i];99100this.source.currentLocation = opcode.loc;101firstLoc = firstLoc || opcode.loc;102this[opcode.opcode].apply(this, opcode.args);103}104105// Flush any trailing content that might be pending.106this.source.currentLocation = firstLoc;107this.pushSource('');108109/* istanbul ignore next */110if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {111throw new Exception('Compile completed with content left on stack');112}113114var fn = this.createFunctionContext(asObject);115if (!this.isChild) {116var ret = {117compiler: this.compilerInfo(),118main: fn119};120var programs = this.context.programs;121for (i = 0, l = programs.length; i < l; i++) {122if (programs[i]) {123ret[i] = programs[i];124}125}126127if (this.environment.usePartial) {128ret.usePartial = true;129}130if (this.options.data) {131ret.useData = true;132}133if (this.useDepths) {134ret.useDepths = true;135}136if (this.useBlockParams) {137ret.useBlockParams = true;138}139if (this.options.compat) {140ret.compat = true;141}142143if (!asObject) {144ret.compiler = JSON.stringify(ret.compiler);145146this.source.currentLocation = {start: {line: 1, column: 0}};147ret = this.objectLiteral(ret);148149if (options.srcName) {150ret = ret.toStringWithSourceMap({file: options.destName});151ret.map = ret.map && ret.map.toString();152} else {153ret = ret.toString();154}155} else {156ret.compilerOptions = this.options;157}158159return ret;160} else {161return fn;162}163},164165preamble: function() {166// track the last context pushed into place to allow skipping the167// getContext opcode when it would be a noop168this.lastContext = 0;169this.source = new CodeGen(this.options.srcName);170},171172createFunctionContext: function(asObject) {173var varDeclarations = '';174175var locals = this.stackVars.concat(this.registers.list);176if(locals.length > 0) {177varDeclarations += ", " + locals.join(", ");178}179180// Generate minimizer alias mappings181//182// When using true SourceNodes, this will update all references to the given alias183// as the source nodes are reused in situ. For the non-source node compilation mode,184// aliases will not be used, but this case is already being run on the client and185// we aren't concern about minimizing the template size.186var aliasCount = 0;187for (var alias in this.aliases) {188var node = this.aliases[alias];189190if (this.aliases.hasOwnProperty(alias) && node.children && node.referenceCount > 1) {191varDeclarations += ', alias' + (++aliasCount) + '=' + alias;192node.children[0] = 'alias' + aliasCount;193}194}195196var params = ["depth0", "helpers", "partials", "data"];197198if (this.useBlockParams || this.useDepths) {199params.push('blockParams');200}201if (this.useDepths) {202params.push('depths');203}204205// Perform a second pass over the output to merge content when possible206var source = this.mergeSource(varDeclarations);207208if (asObject) {209params.push(source);210211return Function.apply(this, params);212} else {213return this.source.wrap(['function(', params.join(','), ') {\n ', source, '}']);214}215},216mergeSource: function(varDeclarations) {217var isSimple = this.environment.isSimple,218appendOnly = !this.forceBuffer,219appendFirst,220221sourceSeen,222bufferStart,223bufferEnd;224this.source.each(function(line) {225if (line.appendToBuffer) {226if (bufferStart) {227line.prepend(' + ');228} else {229bufferStart = line;230}231bufferEnd = line;232} else {233if (bufferStart) {234if (!sourceSeen) {235appendFirst = true;236} else {237bufferStart.prepend('buffer += ');238}239bufferEnd.add(';');240bufferStart = bufferEnd = undefined;241}242243sourceSeen = true;244if (!isSimple) {245appendOnly = false;246}247}248});249250251if (appendOnly) {252if (bufferStart) {253bufferStart.prepend('return ');254bufferEnd.add(';');255} else if (!sourceSeen) {256this.source.push('return "";');257}258} else {259varDeclarations += ", buffer = " + (appendFirst ? '' : this.initializeBuffer());260261if (bufferStart) {262bufferStart.prepend('return buffer + ');263bufferEnd.add(';');264} else {265this.source.push('return buffer;');266}267}268269if (varDeclarations) {270this.source.prepend('var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n'));271}272273return this.source.merge();274},275276// [blockValue]277//278// On stack, before: hash, inverse, program, value279// On stack, after: return value of blockHelperMissing280//281// The purpose of this opcode is to take a block of the form282// `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and283// replace it on the stack with the result of properly284// invoking blockHelperMissing.285blockValue: function(name) {286var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),287params = [this.contextName(0)];288this.setupHelperArgs(name, 0, params);289290var blockName = this.popStack();291params.splice(1, 0, blockName);292293this.push(this.source.functionCall(blockHelperMissing, 'call', params));294},295296// [ambiguousBlockValue]297//298// On stack, before: hash, inverse, program, value299// Compiler value, before: lastHelper=value of last found helper, if any300// On stack, after, if no lastHelper: same as [blockValue]301// On stack, after, if lastHelper: value302ambiguousBlockValue: function() {303// We're being a bit cheeky and reusing the options value from the prior exec304var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),305params = [this.contextName(0)];306this.setupHelperArgs('', 0, params, true);307308this.flushInline();309310var current = this.topStack();311params.splice(1, 0, current);312313this.pushSource([314'if (!', this.lastHelper, ') { ',315current, ' = ', this.source.functionCall(blockHelperMissing, 'call', params),316'}']);317},318319// [appendContent]320//321// On stack, before: ...322// On stack, after: ...323//324// Appends the string value of `content` to the current buffer325appendContent: function(content) {326if (this.pendingContent) {327content = this.pendingContent + content;328} else {329this.pendingLocation = this.source.currentLocation;330}331332this.pendingContent = content;333},334335// [append]336//337// On stack, before: value, ...338// On stack, after: ...339//340// Coerces `value` to a String and appends it to the current buffer.341//342// If `value` is truthy, or 0, it is coerced into a string and appended343// Otherwise, the empty string is appended344append: function() {345if (this.isInline()) {346this.replaceStack(function(current) {347return [' != null ? ', current, ' : ""'];348});349350this.pushSource(this.appendToBuffer(this.popStack()));351} else {352var local = this.popStack();353this.pushSource(['if (', local, ' != null) { ', this.appendToBuffer(local, undefined, true), ' }']);354if (this.environment.isSimple) {355this.pushSource(['else { ', this.appendToBuffer("''", undefined, true), ' }']);356}357}358},359360// [appendEscaped]361//362// On stack, before: value, ...363// On stack, after: ...364//365// Escape `value` and append it to the buffer366appendEscaped: function() {367this.pushSource(this.appendToBuffer(368[this.aliasable('this.escapeExpression'), '(', this.popStack(), ')']));369},370371// [getContext]372//373// On stack, before: ...374// On stack, after: ...375// Compiler value, after: lastContext=depth376//377// Set the value of the `lastContext` compiler value to the depth378getContext: function(depth) {379this.lastContext = depth;380},381382// [pushContext]383//384// On stack, before: ...385// On stack, after: currentContext, ...386//387// Pushes the value of the current context onto the stack.388pushContext: function() {389this.pushStackLiteral(this.contextName(this.lastContext));390},391392// [lookupOnContext]393//394// On stack, before: ...395// On stack, after: currentContext[name], ...396//397// Looks up the value of `name` on the current context and pushes398// it onto the stack.399lookupOnContext: function(parts, falsy, scoped) {400var i = 0;401402if (!scoped && this.options.compat && !this.lastContext) {403// The depthed query is expected to handle the undefined logic for the root level that404// is implemented below, so we evaluate that directly in compat mode405this.push(this.depthedLookup(parts[i++]));406} else {407this.pushContext();408}409410this.resolvePath('context', parts, i, falsy);411},412413// [lookupBlockParam]414//415// On stack, before: ...416// On stack, after: blockParam[name], ...417//418// Looks up the value of `parts` on the given block param and pushes419// it onto the stack.420lookupBlockParam: function(blockParamId, parts) {421this.useBlockParams = true;422423this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']);424this.resolvePath('context', parts, 1);425},426427// [lookupData]428//429// On stack, before: ...430// On stack, after: data, ...431//432// Push the data lookup operator433lookupData: function(depth, parts) {434/*jshint -W083 */435if (!depth) {436this.pushStackLiteral('data');437} else {438this.pushStackLiteral('this.data(data, ' + depth + ')');439}440441this.resolvePath('data', parts, 0, true);442},443444resolvePath: function(type, parts, i, falsy) {445/*jshint -W083 */446if (this.options.strict || this.options.assumeObjects) {447this.push(strictLookup(this.options.strict, this, parts, type));448return;449}450451var len = parts.length;452for (; i < len; i++) {453this.replaceStack(function(current) {454var lookup = this.nameLookup(current, parts[i], type);455// We want to ensure that zero and false are handled properly if the context (falsy flag)456// needs to have the special handling for these values.457if (!falsy) {458return [' != null ? ', lookup, ' : ', current];459} else {460// Otherwise we can use generic falsy handling461return [' && ', lookup];462}463});464}465},466467// [resolvePossibleLambda]468//469// On stack, before: value, ...470// On stack, after: resolved value, ...471//472// If the `value` is a lambda, replace it on the stack by473// the return value of the lambda474resolvePossibleLambda: function() {475this.push([this.aliasable('this.lambda'), '(', this.popStack(), ', ', this.contextName(0), ')']);476},477478// [pushStringParam]479//480// On stack, before: ...481// On stack, after: string, currentContext, ...482//483// This opcode is designed for use in string mode, which484// provides the string value of a parameter along with its485// depth rather than resolving it immediately.486pushStringParam: function(string, type) {487this.pushContext();488this.pushString(type);489490// If it's a subexpression, the string result491// will be pushed after this opcode.492if (type !== 'SubExpression') {493if (typeof string === 'string') {494this.pushString(string);495} else {496this.pushStackLiteral(string);497}498}499},500501emptyHash: function(omitEmpty) {502if (this.trackIds) {503this.push('{}'); // hashIds504}505if (this.stringParams) {506this.push('{}'); // hashContexts507this.push('{}'); // hashTypes508}509this.pushStackLiteral(omitEmpty ? 'undefined' : '{}');510},511pushHash: function() {512if (this.hash) {513this.hashes.push(this.hash);514}515this.hash = {values: [], types: [], contexts: [], ids: []};516},517popHash: function() {518var hash = this.hash;519this.hash = this.hashes.pop();520521if (this.trackIds) {522this.push(this.objectLiteral(hash.ids));523}524if (this.stringParams) {525this.push(this.objectLiteral(hash.contexts));526this.push(this.objectLiteral(hash.types));527}528529this.push(this.objectLiteral(hash.values));530},531532// [pushString]533//534// On stack, before: ...535// On stack, after: quotedString(string), ...536//537// Push a quoted version of `string` onto the stack538pushString: function(string) {539this.pushStackLiteral(this.quotedString(string));540},541542// [pushLiteral]543//544// On stack, before: ...545// On stack, after: value, ...546//547// Pushes a value onto the stack. This operation prevents548// the compiler from creating a temporary variable to hold549// it.550pushLiteral: function(value) {551this.pushStackLiteral(value);552},553554// [pushProgram]555//556// On stack, before: ...557// On stack, after: program(guid), ...558//559// Push a program expression onto the stack. This takes560// a compile-time guid and converts it into a runtime-accessible561// expression.562pushProgram: function(guid) {563if (guid != null) {564this.pushStackLiteral(this.programExpression(guid));565} else {566this.pushStackLiteral(null);567}568},569570// [invokeHelper]571//572// On stack, before: hash, inverse, program, params..., ...573// On stack, after: result of helper invocation574//575// Pops off the helper's parameters, invokes the helper,576// and pushes the helper's return value onto the stack.577//578// If the helper is not found, `helperMissing` is called.579invokeHelper: function(paramSize, name, isSimple) {580var nonHelper = this.popStack();581var helper = this.setupHelper(paramSize, name);582var simple = isSimple ? [helper.name, ' || '] : '';583584var lookup = ['('].concat(simple, nonHelper);585if (!this.options.strict) {586lookup.push(' || ', this.aliasable('helpers.helperMissing'));587}588lookup.push(')');589590this.push(this.source.functionCall(lookup, 'call', helper.callParams));591},592593// [invokeKnownHelper]594//595// On stack, before: hash, inverse, program, params..., ...596// On stack, after: result of helper invocation597//598// This operation is used when the helper is known to exist,599// so a `helperMissing` fallback is not required.600invokeKnownHelper: function(paramSize, name) {601var helper = this.setupHelper(paramSize, name);602this.push(this.source.functionCall(helper.name, 'call', helper.callParams));603},604605// [invokeAmbiguous]606//607// On stack, before: hash, inverse, program, params..., ...608// On stack, after: result of disambiguation609//610// This operation is used when an expression like `{{foo}}`611// is provided, but we don't know at compile-time whether it612// is a helper or a path.613//614// This operation emits more code than the other options,615// and can be avoided by passing the `knownHelpers` and616// `knownHelpersOnly` flags at compile-time.617invokeAmbiguous: function(name, helperCall) {618this.useRegister('helper');619620var nonHelper = this.popStack();621622this.emptyHash();623var helper = this.setupHelper(0, name, helperCall);624625var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');626627var lookup = ['(', '(helper = ', helperName, ' || ', nonHelper, ')'];628if (!this.options.strict) {629lookup[0] = '(helper = ';630lookup.push(631' != null ? helper : ',632this.aliasable('helpers.helperMissing')633);634}635636this.push([637'(', lookup,638(helper.paramsInit ? ['),(', helper.paramsInit] : []), '),',639'(typeof helper === ', this.aliasable('"function"'), ' ? ',640this.source.functionCall('helper','call', helper.callParams), ' : helper))'641]);642},643644// [invokePartial]645//646// On stack, before: context, ...647// On stack after: result of partial invocation648//649// This operation pops off a context, invokes a partial with that context,650// and pushes the result of the invocation back.651invokePartial: function(isDynamic, name, indent) {652var params = [],653options = this.setupParams(name, 1, params, false);654655if (isDynamic) {656name = this.popStack();657delete options.name;658}659660if (indent) {661options.indent = JSON.stringify(indent);662}663options.helpers = 'helpers';664options.partials = 'partials';665666if (!isDynamic) {667params.unshift(this.nameLookup('partials', name, 'partial'));668} else {669params.unshift(name);670}671672if (this.options.compat) {673options.depths = 'depths';674}675options = this.objectLiteral(options);676params.push(options);677678this.push(this.source.functionCall('this.invokePartial', '', params));679},680681// [assignToHash]682//683// On stack, before: value, ..., hash, ...684// On stack, after: ..., hash, ...685//686// Pops a value off the stack and assigns it to the current hash687assignToHash: function(key) {688var value = this.popStack(),689context,690type,691id;692693if (this.trackIds) {694id = this.popStack();695}696if (this.stringParams) {697type = this.popStack();698context = this.popStack();699}700701var hash = this.hash;702if (context) {703hash.contexts[key] = context;704}705if (type) {706hash.types[key] = type;707}708if (id) {709hash.ids[key] = id;710}711hash.values[key] = value;712},713714pushId: function(type, name, child) {715if (type === 'BlockParam') {716this.pushStackLiteral(717'blockParams[' + name[0] + '].path[' + name[1] + ']'718+ (child ? ' + ' + JSON.stringify('.' + child) : ''));719} else if (type === 'PathExpression') {720this.pushString(name);721} else if (type === 'SubExpression') {722this.pushStackLiteral('true');723} else {724this.pushStackLiteral('null');725}726},727728// HELPERS729730compiler: JavaScriptCompiler,731732compileChildren: function(environment, options) {733var children = environment.children, child, compiler;734735for(var i=0, l=children.length; i<l; i++) {736child = children[i];737compiler = new this.compiler();738739var index = this.matchExistingProgram(child);740741if (index == null) {742this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children743index = this.context.programs.length;744child.index = index;745child.name = 'program' + index;746this.context.programs[index] = compiler.compile(child, options, this.context, !this.precompile);747this.context.environments[index] = child;748749this.useDepths = this.useDepths || compiler.useDepths;750this.useBlockParams = this.useBlockParams || compiler.useBlockParams;751} else {752child.index = index;753child.name = 'program' + index;754755this.useDepths = this.useDepths || child.useDepths;756this.useBlockParams = this.useBlockParams || child.useBlockParams;757}758}759},760matchExistingProgram: function(child) {761for (var i = 0, len = this.context.environments.length; i < len; i++) {762var environment = this.context.environments[i];763if (environment && environment.equals(child)) {764return i;765}766}767},768769programExpression: function(guid) {770var child = this.environment.children[guid],771programParams = [child.index, 'data', child.blockParams];772773if (this.useBlockParams || this.useDepths) {774programParams.push('blockParams');775}776if (this.useDepths) {777programParams.push('depths');778}779780return 'this.program(' + programParams.join(', ') + ')';781},782783useRegister: function(name) {784if(!this.registers[name]) {785this.registers[name] = true;786this.registers.list.push(name);787}788},789790push: function(expr) {791if (!(expr instanceof Literal)) {792expr = this.source.wrap(expr);793}794795this.inlineStack.push(expr);796return expr;797},798799pushStackLiteral: function(item) {800this.push(new Literal(item));801},802803pushSource: function(source) {804if (this.pendingContent) {805this.source.push(806this.appendToBuffer(this.source.quotedString(this.pendingContent), this.pendingLocation));807this.pendingContent = undefined;808}809810if (source) {811this.source.push(source);812}813},814815replaceStack: function(callback) {816var prefix = ['('],817stack,818createdStack,819usedLiteral;820821/* istanbul ignore next */822if (!this.isInline()) {823throw new Exception('replaceStack on non-inline');824}825826// We want to merge the inline statement into the replacement statement via ','827var top = this.popStack(true);828829if (top instanceof Literal) {830// Literals do not need to be inlined831stack = [top.value];832prefix = ['(', stack];833usedLiteral = true;834} else {835// Get or create the current stack name for use by the inline836createdStack = true;837var name = this.incrStack();838839prefix = ['((', this.push(name), ' = ', top, ')'];840stack = this.topStack();841}842843var item = callback.call(this, stack);844845if (!usedLiteral) {846this.popStack();847}848if (createdStack) {849this.stackSlot--;850}851this.push(prefix.concat(item, ')'));852},853854incrStack: function() {855this.stackSlot++;856if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }857return this.topStackName();858},859topStackName: function() {860return "stack" + this.stackSlot;861},862flushInline: function() {863var inlineStack = this.inlineStack;864this.inlineStack = [];865for (var i = 0, len = inlineStack.length; i < len; i++) {866var entry = inlineStack[i];867/* istanbul ignore if */868if (entry instanceof Literal) {869this.compileStack.push(entry);870} else {871var stack = this.incrStack();872this.pushSource([stack, ' = ', entry, ';']);873this.compileStack.push(stack);874}875}876},877isInline: function() {878return this.inlineStack.length;879},880881popStack: function(wrapped) {882var inline = this.isInline(),883item = (inline ? this.inlineStack : this.compileStack).pop();884885if (!wrapped && (item instanceof Literal)) {886return item.value;887} else {888if (!inline) {889/* istanbul ignore next */890if (!this.stackSlot) {891throw new Exception('Invalid stack pop');892}893this.stackSlot--;894}895return item;896}897},898899topStack: function() {900var stack = (this.isInline() ? this.inlineStack : this.compileStack),901item = stack[stack.length - 1];902903/* istanbul ignore if */904if (item instanceof Literal) {905return item.value;906} else {907return item;908}909},910911contextName: function(context) {912if (this.useDepths && context) {913return 'depths[' + context + ']';914} else {915return 'depth' + context;916}917},918919quotedString: function(str) {920return this.source.quotedString(str);921},922923objectLiteral: function(obj) {924return this.source.objectLiteral(obj);925},926927aliasable: function(name) {928var ret = this.aliases[name];929if (ret) {930ret.referenceCount++;931return ret;932}933934ret = this.aliases[name] = this.source.wrap(name);935ret.aliasable = true;936ret.referenceCount = 1;937938return ret;939},940941setupHelper: function(paramSize, name, blockHelper) {942var params = [],943paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);944var foundHelper = this.nameLookup('helpers', name, 'helper');945946return {947params: params,948paramsInit: paramsInit,949name: foundHelper,950callParams: [this.contextName(0)].concat(params)951};952},953954setupParams: function(helper, paramSize, params) {955var options = {}, contexts = [], types = [], ids = [], param;956957options.name = this.quotedString(helper);958options.hash = this.popStack();959960if (this.trackIds) {961options.hashIds = this.popStack();962}963if (this.stringParams) {964options.hashTypes = this.popStack();965options.hashContexts = this.popStack();966}967968var inverse = this.popStack(),969program = this.popStack();970971// Avoid setting fn and inverse if neither are set. This allows972// helpers to do a check for `if (options.fn)`973if (program || inverse) {974options.fn = program || 'this.noop';975options.inverse = inverse || 'this.noop';976}977978// The parameters go on to the stack in order (making sure that they are evaluated in order)979// so we need to pop them off the stack in reverse order980var i = paramSize;981while (i--) {982param = this.popStack();983params[i] = param;984985if (this.trackIds) {986ids[i] = this.popStack();987}988if (this.stringParams) {989types[i] = this.popStack();990contexts[i] = this.popStack();991}992}993994if (this.trackIds) {995options.ids = this.source.generateArray(ids);996}997if (this.stringParams) {998options.types = this.source.generateArray(types);999options.contexts = this.source.generateArray(contexts);1000}10011002if (this.options.data) {1003options.data = 'data';1004}1005if (this.useBlockParams) {1006options.blockParams = 'blockParams';1007}1008return options;1009},10101011setupHelperArgs: function(helper, paramSize, params, useRegister) {1012var options = this.setupParams(helper, paramSize, params, true);1013options = this.objectLiteral(options);1014if (useRegister) {1015this.useRegister('options');1016params.push('options');1017return ['options=', options];1018} else {1019params.push(options);1020return '';1021}1022}1023};102410251026var reservedWords = (1027"break else new var" +1028" case finally return void" +1029" catch for switch while" +1030" continue function this with" +1031" default if throw" +1032" delete in try" +1033" do instanceof typeof" +1034" abstract enum int short" +1035" boolean export interface static" +1036" byte extends long super" +1037" char final native synchronized" +1038" class float package throws" +1039" const goto private transient" +1040" debugger implements protected volatile" +1041" double import public let yield await" +1042" null true false"1043).split(" ");10441045var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};10461047for(var i=0, l=reservedWords.length; i<l; i++) {1048compilerWords[reservedWords[i]] = true;1049}10501051JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {1052return !JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name);1053};10541055function strictLookup(requireTerminal, compiler, parts, type) {1056var stack = compiler.popStack();10571058var i = 0,1059len = parts.length;1060if (requireTerminal) {1061len--;1062}10631064for (; i < len; i++) {1065stack = compiler.nameLookup(stack, parts[i], type);1066}10671068if (requireTerminal) {1069return [compiler.aliasable('this.strict'), '(', stack, ', ', compiler.quotedString(parts[i]), ')'];1070} else {1071return stack;1072}1073}10741075__exports__["default"] = JavaScriptCompiler;1076});10771078