diff options
author | kpdecker <kpdecker@gmail.com> | 2013-01-21 00:26:08 -0600 |
---|---|---|
committer | kpdecker <kpdecker@gmail.com> | 2013-01-21 00:49:28 -0600 |
commit | b66197796615f49f3009800b401df2597f118e58 (patch) | |
tree | e7bbcf7358425cc6d4b0767ac61ad821a8db7be9 /lib/handlebars/compiler/compiler.js | |
parent | 969b418291af1fa4f32820ee0d36ab00b4b55db1 (diff) | |
download | handlebars.js-b66197796615f49f3009800b401df2597f118e58.zip handlebars.js-b66197796615f49f3009800b401df2597f118e58.tar.gz handlebars.js-b66197796615f49f3009800b401df2597f118e58.tar.bz2 |
Merge duplicate programs
Diffstat (limited to 'lib/handlebars/compiler/compiler.js')
-rw-r--r-- | lib/handlebars/compiler/compiler.js | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js index d4b7d0f..7541051 100644 --- a/lib/handlebars/compiler/compiler.js +++ b/lib/handlebars/compiler/compiler.js @@ -38,6 +38,26 @@ Handlebars.JavaScriptCompiler = function() {}; return out.join("\n"); }, + equals: function(other) { + var len = this.opcodes.length; + if (other.opcodes.length !== len) { + return false; + } + + for (var i = 0; i < len; i++) { + var opcode = this.opcodes[i], + otherOpcode = other.opcodes[i]; + if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) { + return false; + } + for (var j = 0; j < opcode.args.length; j++) { + if (opcode.args[j] !== otherOpcode.args[j]) { + return false; + } + } + } + return true; + }, guid: 0, @@ -417,6 +437,7 @@ Handlebars.JavaScriptCompiler = function() {}; this.isChild = !!context; this.context = context || { programs: [], + environments: [], aliases: { } }; @@ -452,7 +473,7 @@ Handlebars.JavaScriptCompiler = function() {}; return opcodes[this.i + 1]; }, - eat: function(opcode) { + eat: function() { this.i = this.i + 1; }, @@ -905,11 +926,27 @@ Handlebars.JavaScriptCompiler = function() {}; child = children[i]; compiler = new this.compiler(); - 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); + var index = this.matchExistingProgram(child); + + if (index == null) { + this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children + index = this.context.programs.length; + child.index = index; + child.name = 'program' + index; + this.context.programs[index] = compiler.compile(child, options, this.context); + this.context.environments[index] = child; + } else { + child.index = index; + child.name = 'program' + index; + } + } + }, + matchExistingProgram: function(child) { + for (var i = 0, len = this.context.environments.length; i < len; i++) { + var environment = this.context.environments[i]; + if (environment && environment.equals(child)) { + return i; + } } }, |