summaryrefslogtreecommitdiffstats
path: root/lib/handlebars/compiler/compiler.js
diff options
context:
space:
mode:
authorkpdecker <kpdecker@gmail.com>2011-07-31 16:17:39 -0500
committerkpdecker <kpdecker@gmail.com>2011-07-31 16:17:39 -0500
commitd044ada7aac87f7c5741fc3f0ba7c570ed2eef76 (patch)
tree9aac963260d4f77dd08a8606b09c8a8fbe90b1eb /lib/handlebars/compiler/compiler.js
parent77a20a3a9fc82fec6c5ef6f93d239c1f1b9c7ee5 (diff)
downloadhandlebars.js-d044ada7aac87f7c5741fc3f0ba7c570ed2eef76.zip
handlebars.js-d044ada7aac87f7c5741fc3f0ba7c570ed2eef76.tar.gz
handlebars.js-d044ada7aac87f7c5741fc3f0ba7c570ed2eef76.tar.bz2
Convert children to nested functions. Reuse identifiers by closure where possible.
Diffstat (limited to 'lib/handlebars/compiler/compiler.js')
-rw-r--r--lib/handlebars/compiler/compiler.js95
1 files changed, 43 insertions, 52 deletions
diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js
index 3a48c16..4a60c05 100644
--- a/lib/handlebars/compiler/compiler.js
+++ b/lib/handlebars/compiler/compiler.js
@@ -315,12 +315,14 @@ Handlebars.JavaScriptCompiler = function() {};
},
// END PUBLIC API
- compile: function(environment, options, asObject) {
+ compile: function(environment, options, context, asObject) {
this.environment = environment;
this.options = options || {};
- this.context = {
- aliases: {},
+ this.name = this.environment.name;
+ this.isChild = !!context;
+ this.context = context || {
+ programs: [],
aliases: { self: 'this' },
registers: {list: []}
};
@@ -330,7 +332,7 @@ Handlebars.JavaScriptCompiler = function() {};
this.stackSlot = 0;
this.stackVars = [];
- this.compileChildren(environment, options, asObject);
+ this.compileChildren(environment, options);
var opcodes = environment.opcodes, opcode, name, declareName, declareVal;
@@ -380,9 +382,13 @@ Handlebars.JavaScriptCompiler = function() {};
preamble: function() {
var out = [];
- var copies = "helpers = helpers || Handlebars.helpers;";
- if(this.environment.usePartial) { copies = copies + " partials = partials || Handlebars.partials;"; }
- out.push(copies);
+ if (!this.isChild) {
+ var copies = "helpers = helpers || Handlebars.helpers;";
+ if(this.environment.usePartial) { copies = copies + " partials = partials || Handlebars.partials;"; }
+ out.push(copies);
+ } else {
+ out.push('');
+ }
out.push("var buffer = " + this.initializeBuffer() + ", currentContext = context");
@@ -393,25 +399,33 @@ Handlebars.JavaScriptCompiler = function() {};
},
createFunctionContext: function(asObject) {
- var locals = this.stackVars.concat(this.context.registers.list);
+ var locals = this.stackVars;
+ if (!this.isChild) {
+ locals = locals.concat(this.context.registers.list);
+ }
if(locals.length > 0) {
this.source[1] = this.source[1] + ", " + locals.join(", ");
}
// Generate minimizer alias mappings
- var aliases = []
- for (var alias in this.context.aliases) {
- this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
+ if (!this.isChild) {
+ var aliases = []
+ for (var alias in this.context.aliases) {
+ this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
+ }
}
this.source[1] = this.source[1] + ";";
- this.source.push("return buffer;");
+ // Merge children
+ if (!this.isChild) {
+ this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
+ }
- var params = ["Handlebars", "context", "helpers", "partials"];
+ this.source.push("return buffer;");
- if(this.options.data) { params.push("data"); }
+ var params = this.isChild ? ["context", "data"] : ["Handlebars", "context", "helpers", "partials", "data"];
for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
params.push("depth" + this.environment.depths.list[i]);
@@ -422,24 +436,11 @@ Handlebars.JavaScriptCompiler = function() {};
if (asObject) {
params.push(this.source.join("\n "));
- return {
- fn: Function.apply(this, params),
- children: this.environment.children
- };
+ return Function.apply(this, params);
} else {
- var functionSource = 'function(' + params.join(',') + ') {\n ' + this.source.join("\n ") + '}';
-
+ var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + this.source.join("\n ") + '}';
Handlebars.log(Handlebars.logger.DEBUG, functionSource + "\n\n");
-
- var script = ['{\n fn: ', functionSource, ',\n children: [\n '],
- children = this.environment.children;
- for (var i = 0, len = children.length; i < len; i++) {
- script.push(children[i]);
- if (i < len-1) { script.push(',\n'); }
- }
- script.push('\n ]\n}');
-
- return script.join('');
+ return functionSource;
}
},
@@ -582,7 +583,7 @@ Handlebars.JavaScriptCompiler = function() {};
},
invokePartial: function(context) {
- this.pushStack("this.invokePartial(" + this.nameLookup('partials', context, 'partial') + ", '" + context + "', " + this.popStack() + ", helpers, partials);");
+ this.pushStack("self.invokePartial(" + this.nameLookup('partials', context, 'partial') + ", '" + context + "', " + this.popStack() + ", helpers, partials);");
},
assignToHash: function(key) {
@@ -596,29 +597,27 @@ Handlebars.JavaScriptCompiler = function() {};
compiler: JavaScriptCompiler,
- compileChildren: function(environment, options, asObject) {
+ compileChildren: function(environment, options) {
var children = environment.children, child, compiler;
- var compiled = [];
for(var i=0, l=children.length; i<l; i++) {
child = children[i];
compiler = new this.compiler();
- compiled[i] = compiler.compile(child, options, asObject);
+ this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
+ var index = this.context.programs.length;
+ child.index = index;
+ child.name = 'program' + index;
+ this.context.programs[index] = compiler.compile(child, options, this.context);
}
-
- environment.rawChildren = children;
- environment.children = compiled;
},
programExpression: function(guid) {
-
- var programParams = [guid, "helpers", "partials"];
if(guid == null) { return "self.noop"; }
- var depths = this.environment.rawChildren[guid].depths.list;
-
- if(this.options.data) { programParams.push("data"); }
+ var child = this.environment.children[guid],
+ depths = child.depths.list;
+ var programParams = [child.index, child.name, "data"];
for(var i=0, l = depths.length; i<l; i++) {
depth = depths[i];
@@ -627,18 +626,10 @@ Handlebars.JavaScriptCompiler = function() {};
else { programParams.push("depth" + (depth - 1)); }
}
- if(!this.environment.usePartial) {
- if(programParams[3]) {
- programParams[2] = "null";
- } else {
- programParams.pop();
- }
- }
-
if(depths.length === 0) {
return "self.program(" + programParams.join(", ") + ")";
} else {
- programParams[0] = "this.children[" + guid + "]";
+ programParams.shift();
return "self.programWithDepth(" + programParams.join(", ") + ")";
}
},
@@ -704,7 +695,7 @@ Handlebars.precompile = function(string, options) {
Handlebars.compile = function(string, options) {
var ast = Handlebars.parse(string);
var environment = new Handlebars.Compiler().compile(ast, options);
- var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, true);
+ var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
return Handlebars.template(templateSpec);
};