handlebars-compiler-compiler.js revision abdaa6ad2027c0c8fe48867813c314c400a83e3d
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove/* THIS FILE IS GENERATED BY A BUILD SCRIPT - DO NOT EDIT! */
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove// BEGIN(BROWSER)
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove return Compiler.MULTI_PARAM_OPCODES[Compiler.DISASSEMBLE_MAP[code]];
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var extraParams = Compiler.multiParamSize(opcode);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove nextCode = "\"" + nextCode.replace("\n", "\\n") + "\"";
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove // These changes will propagate to the other compiler components
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove 'helperMissing': true,
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove 'blockHelperMissing': true,
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove 'each': true,
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove 'unless': true,
abdaa6ad2027c0c8fe48867813c314c400a83e3dRyan Grove 'with': true,
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.options.knownHelpers[name] = knownHelpers[name];
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.depths.list = this.depths.list.sort(function(a, b) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove return a - b;
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove return this;
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var result = new this.compiler().compile(program, this.options);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.usePartial = this.usePartial || result.usePartial;
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove for(var i=0, l=result.depths.list.length; i<l; i++) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var params = this.setupStackForMustache(mustache);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var programGuid = this.compileProgram(block.program);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove inverseGuid = this.compileProgram(block.program.inverse);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.opcode('invokeProgram', programGuid, params.length, !!mustache.hash);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var params = this.setupStackForMustache(block.mustache);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var programGuid = this.compileProgram(block.program);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.opcode('invokeProgram', null, params.length, !!block.mustache.hash);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var params = this.setupStackForMustache(mustache);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.opcode('invokeMustache', params.length, mustache.id.original, !!mustache.hash);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.opcode('lookupWithHelpers', id.parts[0] || null, id.isScoped || false);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove comment: function() {},
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove while(i--) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove if(val1 !== undefined) { this.opcodes.push(val1); }
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove if(val2 !== undefined) { this.opcodes.push(val2); }
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove if(val3 !== undefined) { this.opcodes.push(val3); }
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove // PUBLIC API: You can override these methods in a subclass to provide
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove // alternative compiled forms for name lookup and buffering semantics
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove // END PUBLIC API
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove compile: function(environment, options, context, asObject) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.i = this.i + 2;
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove nextOpcode: function(n) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var opcodes = this.environment.opcodes, opcode = opcodes[this.i + n], name, val;
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove preamble: function() {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var copies = "helpers = helpers || Handlebars.helpers;";
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove if(this.environment.usePartial) { copies = copies + " partials = partials || Handlebars.partials;"; }
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove out.push(", buffer = " + this.initializeBuffer());
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove // track the last context pushed into place to allow skipping the
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove // getContext opcode when it would be a noop
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove locals = locals.concat(this.context.registers.list);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source[1] = this.source[1] + ", " + locals.join(", ");
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove // Generate minimizer alias mappings
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source[1] = "var " + this.source[1].substring(2) + ";";
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove // Merge children
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove params.push("depth" + this.environment.depths.list[i]);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove if(params.length === 4 && !this.environment.usePartial) { params.pop(); }
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + this.source.join("\n ") + '}';
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove Handlebars.log(Handlebars.logger.DEBUG, functionSource + "\n\n");
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source.push(this.appendToBuffer(this.quotedString(content)));
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove append: function() {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source.push("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source.push("else { " + this.appendToBuffer("''") + " }");
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.context.aliases.escapeExpression = 'this.escapeExpression';
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source.push(this.appendToBuffer("escapeExpression(" + this.popStack() + ")" + extra));
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove if (!isScoped && this.options.knownHelpers[name]) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove toPush = topStack + " = " + this.nameLookup('helpers', name, 'helper');
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove } else if (isScoped || this.options.knownHelpersOnly) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove toPush = topStack + " = " + this.nameLookup('depth' + this.lastContext, name, 'context');
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove + this.nameLookup('depth' + this.lastContext, name, 'context');
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source.push(topStack + " = (" + topStack + " === null || " + topStack + " === undefined || " + topStack + " === false ? " +
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove topStack + " : " + this.nameLookup(topStack, name, 'context') + ");");
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove invokeMustache: function(paramSize, original, hasHash) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.populateParams(paramSize, this.quotedString(original), "{}", null, hasHash, function(nextStack, helperMissingString, id) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.context.aliases.helperMissing = 'helpers.helperMissing';
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source.push("else if(" + id + "=== undef) { " + nextStack + " = helperMissing.call(" + helperMissingString + "); }");
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source.push("else { " + nextStack + " = " + id + "; }");
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove invokeProgram: function(guid, paramSize, hasHash) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var inverse = this.programExpression(this.inverse);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.populateParams(paramSize, null, mainProgram, inverse, hasHash, function(nextStack, helperMissingString, id) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source.push("else { " + nextStack + " = blockHelperMissing.call(" + helperMissingString + "); }");
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove populateParams: function(paramSize, helperId, program, inverse, hasHash, fn) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var needsRegister = hasHash || this.options.stringParams || inverse || this.options.data;
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var params = [], param, stringParam, stringOptions;
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source.push('tmp1.contexts.push(' + this.popStack() + ');');
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source.push('tmp1.inverse = ' + inverse + ';');
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.populateCall(params, id, helperId || id, fn);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove populateCall: function(params, id, helperId, fn) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var paramString = ["depth0"].concat(params).join(", ");
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var helperMissingString = ["depth0"].concat(helperId).concat(params).join(", ");
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source.push(nextStack + " = " + id + ".call(" + paramString + ");");
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.context.aliases.functionType = '"function"';
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source.push("if(typeof " + id + " === functionType) { " + nextStack + " = " + id + ".call(" + paramString + "); }");
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove fn.call(this, nextStack, helperMissingString, id);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.pushStack("self.invokePartial(" + this.nameLookup('partials', context, 'partial') + ", '" + context + "', " + this.popStack() + ", helpers, partials);");
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source.push(hash + "['" + key + "'] = " + value + ";");
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove compileChildren: function(environment, options) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var children = environment.children, child, compiler;
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.context.programs[index] = compiler.compile(child, options, this.context);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var programParams = [child.index, child.name, "data"];
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove if(depth === 1) { programParams.push("depth0"); }
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove else { programParams.push("depth" + (depth - 1)); }
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove return "self.program(" + programParams.join(", ") + ")";
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove return "self.programWithDepth(" + programParams.join(", ") + ")";
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove this.source.push(this.nextStack() + " = " + item + ";");
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove nextStack: function() {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove popStack: function() {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove topStack: function() {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var reservedWords = ("break case catch continue default delete do else finally " +
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove "for function if in instanceof new return switch this throw " +
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove "try typeof var void while with null true false").split(" ");
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove for(var i=0, l=reservedWords.length; i<l; i++) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove compilerWords[reservedWords[i]] = true;
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]+$/.test(name)) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove return true;
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove return false;
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove})(Handlebars.Compiler, Handlebars.JavaScriptCompiler);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan GroveHandlebars.precompile = function(string, options) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove options = options || {};
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var ast = Handlebars.parse(string);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove var environment = new Handlebars.Compiler().compile(ast, options);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove return new Handlebars.JavaScriptCompiler().compile(environment, options);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan GroveHandlebars.compile = function(string, options) {
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove options = options || {};
abdaa6ad2027c0c8fe48867813c314c400a83e3dRyan Grove var compiled;
abdaa6ad2027c0c8fe48867813c314c400a83e3dRyan Grove function compile() {
abdaa6ad2027c0c8fe48867813c314c400a83e3dRyan Grove var ast = Handlebars.parse(string);
abdaa6ad2027c0c8fe48867813c314c400a83e3dRyan Grove var environment = new Handlebars.Compiler().compile(ast, options);
abdaa6ad2027c0c8fe48867813c314c400a83e3dRyan Grove var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
abdaa6ad2027c0c8fe48867813c314c400a83e3dRyan Grove return Handlebars.template(templateSpec);
abdaa6ad2027c0c8fe48867813c314c400a83e3dRyan Grove // Template is only compiled on first use and cached after that point.
abdaa6ad2027c0c8fe48867813c314c400a83e3dRyan Grove return function(context, options) {
abdaa6ad2027c0c8fe48867813c314c400a83e3dRyan Grove if (!compiled) {
abdaa6ad2027c0c8fe48867813c314c400a83e3dRyan Grove compiled = compile();
abdaa6ad2027c0c8fe48867813c314c400a83e3dRyan Grove return compiled.call(this, context, options);
c5eeeb5cc5fdca25f16cb4f2fd3e59dd0f937debRyan Grove// END(BROWSER)