summaryrefslogtreecommitdiffstats
path: root/lib/handlebars/compiler/javascript-compiler.js
diff options
context:
space:
mode:
authorkpdecker <kpdecker@gmail.com>2015-04-20 02:38:28 -0500
committerkpdecker <kpdecker@gmail.com>2015-04-20 02:38:28 -0500
commit4bed826d0e210c336fb9e500835b1c1926562da5 (patch)
treeafd32d4dc7b4c2fcf6c38d0355def38ddaffdcc0 /lib/handlebars/compiler/javascript-compiler.js
parent0263aa48bc8c8cdcd332edd01a644a9a0fd1cc81 (diff)
downloadhandlebars.js-4bed826d0e210c336fb9e500835b1c1926562da5.zip
handlebars.js-4bed826d0e210c336fb9e500835b1c1926562da5.tar.gz
handlebars.js-4bed826d0e210c336fb9e500835b1c1926562da5.tar.bz2
Update for let and optional parameters
Diffstat (limited to 'lib/handlebars/compiler/javascript-compiler.js')
-rw-r--r--lib/handlebars/compiler/javascript-compiler.js135
1 files changed, 66 insertions, 69 deletions
diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js
index e278162..75e50d2 100644
--- a/lib/handlebars/compiler/javascript-compiler.js
+++ b/lib/handlebars/compiler/javascript-compiler.js
@@ -24,8 +24,8 @@ JavaScriptCompiler.prototype = {
},
compilerInfo: function() {
- var revision = COMPILER_REVISION,
- versions = REVISION_CHANGES[revision];
+ const revision = COMPILER_REVISION,
+ versions = REVISION_CHANGES[revision];
return [revision, versions];
},
@@ -84,7 +84,7 @@ JavaScriptCompiler.prototype = {
this.useDepths = this.useDepths || environment.useDepths || this.options.compat;
this.useBlockParams = this.useBlockParams || environment.useBlockParams;
- var opcodes = environment.opcodes,
+ let opcodes = environment.opcodes,
opcode,
firstLoc,
i,
@@ -107,13 +107,13 @@ JavaScriptCompiler.prototype = {
throw new Exception('Compile completed with content left on stack');
}
- var fn = this.createFunctionContext(asObject);
+ let fn = this.createFunctionContext(asObject);
if (!this.isChild) {
- var ret = {
+ let ret = {
compiler: this.compilerInfo(),
main: fn
};
- var programs = this.context.programs;
+ let programs = this.context.programs;
for (i = 0, l = programs.length; i < l; i++) {
if (programs[i]) {
ret[i] = programs[i];
@@ -166,9 +166,9 @@ JavaScriptCompiler.prototype = {
},
createFunctionContext: function(asObject) {
- var varDeclarations = '';
+ let varDeclarations = '';
- var locals = this.stackVars.concat(this.registers.list);
+ let locals = this.stackVars.concat(this.registers.list);
if (locals.length > 0) {
varDeclarations += ', ' + locals.join(', ');
}
@@ -179,9 +179,9 @@ JavaScriptCompiler.prototype = {
// as the source nodes are reused in situ. For the non-source node compilation mode,
// aliases will not be used, but this case is already being run on the client and
// we aren't concern about minimizing the template size.
- var aliasCount = 0;
- for (var alias in this.aliases) { // eslint-disable-line guard-for-in
- var node = this.aliases[alias];
+ let aliasCount = 0;
+ for (let alias in this.aliases) { // eslint-disable-line guard-for-in
+ let node = this.aliases[alias];
if (this.aliases.hasOwnProperty(alias) && node.children && node.referenceCount > 1) {
varDeclarations += ', alias' + (++aliasCount) + '=' + alias;
@@ -189,7 +189,7 @@ JavaScriptCompiler.prototype = {
}
}
- var params = ['depth0', 'helpers', 'partials', 'data'];
+ let params = ['depth0', 'helpers', 'partials', 'data'];
if (this.useBlockParams || this.useDepths) {
params.push('blockParams');
@@ -199,7 +199,7 @@ JavaScriptCompiler.prototype = {
}
// Perform a second pass over the output to merge content when possible
- var source = this.mergeSource(varDeclarations);
+ let source = this.mergeSource(varDeclarations);
if (asObject) {
params.push(source);
@@ -210,14 +210,14 @@ JavaScriptCompiler.prototype = {
}
},
mergeSource: function(varDeclarations) {
- var isSimple = this.environment.isSimple,
+ let isSimple = this.environment.isSimple,
appendOnly = !this.forceBuffer,
appendFirst,
sourceSeen,
bufferStart,
bufferEnd;
- this.source.each(function(line) {
+ this.source.each((line) => {
if (line.appendToBuffer) {
if (bufferStart) {
line.prepend(' + ');
@@ -279,11 +279,11 @@ JavaScriptCompiler.prototype = {
// replace it on the stack with the result of properly
// invoking blockHelperMissing.
blockValue: function(name) {
- var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),
+ let blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),
params = [this.contextName(0)];
this.setupHelperArgs(name, 0, params);
- var blockName = this.popStack();
+ let blockName = this.popStack();
params.splice(1, 0, blockName);
this.push(this.source.functionCall(blockHelperMissing, 'call', params));
@@ -297,13 +297,13 @@ JavaScriptCompiler.prototype = {
// On stack, after, if lastHelper: value
ambiguousBlockValue: function() {
// We're being a bit cheeky and reusing the options value from the prior exec
- var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),
+ let blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),
params = [this.contextName(0)];
this.setupHelperArgs('', 0, params, true);
this.flushInline();
- var current = this.topStack();
+ let current = this.topStack();
params.splice(1, 0, current);
this.pushSource([
@@ -339,13 +339,11 @@ JavaScriptCompiler.prototype = {
// Otherwise, the empty string is appended
append: function() {
if (this.isInline()) {
- this.replaceStack(function(current) {
- return [' != null ? ', current, ' : ""'];
- });
+ this.replaceStack((current) => [' != null ? ', current, ' : ""']);
this.pushSource(this.appendToBuffer(this.popStack()));
} else {
- var local = this.popStack();
+ let local = this.popStack();
this.pushSource(['if (', local, ' != null) { ', this.appendToBuffer(local, undefined, true), ' }']);
if (this.environment.isSimple) {
this.pushSource(['else { ', this.appendToBuffer("''", undefined, true), ' }']);
@@ -393,7 +391,7 @@ JavaScriptCompiler.prototype = {
// Looks up the value of `name` on the current context and pushes
// it onto the stack.
lookupOnContext: function(parts, falsy, scoped) {
- var i = 0;
+ let i = 0;
if (!scoped && this.options.compat && !this.lastContext) {
// The depthed query is expected to handle the undefined logic for the root level that
@@ -444,11 +442,11 @@ JavaScriptCompiler.prototype = {
return;
}
- var len = parts.length;
+ let len = parts.length;
for (; i < len; i++) {
/*eslint-disable no-loop-func */
- this.replaceStack(function(current) {
- var lookup = this.nameLookup(current, parts[i], type);
+ this.replaceStack((current) => {
+ let lookup = this.nameLookup(current, parts[i], type);
// We want to ensure that zero and false are handled properly if the context (falsy flag)
// needs to have the special handling for these values.
if (!falsy) {
@@ -513,7 +511,7 @@ JavaScriptCompiler.prototype = {
this.hash = {values: [], types: [], contexts: [], ids: []};
},
popHash: function() {
- var hash = this.hash;
+ let hash = this.hash;
this.hash = this.hashes.pop();
if (this.trackIds) {
@@ -575,11 +573,11 @@ JavaScriptCompiler.prototype = {
//
// If the helper is not found, `helperMissing` is called.
invokeHelper: function(paramSize, name, isSimple) {
- var nonHelper = this.popStack();
- var helper = this.setupHelper(paramSize, name);
- var simple = isSimple ? [helper.name, ' || '] : '';
+ let nonHelper = this.popStack(),
+ helper = this.setupHelper(paramSize, name),
+ simple = isSimple ? [helper.name, ' || '] : '';
- var lookup = ['('].concat(simple, nonHelper);
+ let lookup = ['('].concat(simple, nonHelper);
if (!this.options.strict) {
lookup.push(' || ', this.aliasable('helpers.helperMissing'));
}
@@ -596,7 +594,7 @@ JavaScriptCompiler.prototype = {
// This operation is used when the helper is known to exist,
// so a `helperMissing` fallback is not required.
invokeKnownHelper: function(paramSize, name) {
- var helper = this.setupHelper(paramSize, name);
+ let helper = this.setupHelper(paramSize, name);
this.push(this.source.functionCall(helper.name, 'call', helper.callParams));
},
@@ -615,14 +613,14 @@ JavaScriptCompiler.prototype = {
invokeAmbiguous: function(name, helperCall) {
this.useRegister('helper');
- var nonHelper = this.popStack();
+ let nonHelper = this.popStack();
this.emptyHash();
- var helper = this.setupHelper(0, name, helperCall);
+ let helper = this.setupHelper(0, name, helperCall);
- var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
+ let helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
- var lookup = ['(', '(helper = ', helperName, ' || ', nonHelper, ')'];
+ let lookup = ['(', '(helper = ', helperName, ' || ', nonHelper, ')'];
if (!this.options.strict) {
lookup[0] = '(helper = ';
lookup.push(
@@ -647,7 +645,7 @@ JavaScriptCompiler.prototype = {
// This operation pops off a context, invokes a partial with that context,
// and pushes the result of the invocation back.
invokePartial: function(isDynamic, name, indent) {
- var params = [],
+ let params = [],
options = this.setupParams(name, 1, params, false);
if (isDynamic) {
@@ -683,7 +681,7 @@ JavaScriptCompiler.prototype = {
//
// Pops a value off the stack and assigns it to the current hash
assignToHash: function(key) {
- var value = this.popStack(),
+ let value = this.popStack(),
context,
type,
id;
@@ -696,7 +694,7 @@ JavaScriptCompiler.prototype = {
context = this.popStack();
}
- var hash = this.hash;
+ let hash = this.hash;
if (context) {
hash.contexts[key] = context;
}
@@ -728,13 +726,13 @@ JavaScriptCompiler.prototype = {
compiler: JavaScriptCompiler,
compileChildren: function(environment, options) {
- var children = environment.children, child, compiler;
+ let children = environment.children, child, compiler;
- for (var i = 0, l = children.length; i < l; i++) {
+ for (let i = 0, l = children.length; i < l; i++) {
child = children[i];
compiler = new this.compiler(); // eslint-disable-line new-cap
- var index = this.matchExistingProgram(child);
+ let index = this.matchExistingProgram(child);
if (index == null) {
this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
@@ -756,8 +754,8 @@ JavaScriptCompiler.prototype = {
}
},
matchExistingProgram: function(child) {
- for (var i = 0, len = this.context.environments.length; i < len; i++) {
- var environment = this.context.environments[i];
+ for (let i = 0, len = this.context.environments.length; i < len; i++) {
+ let environment = this.context.environments[i];
if (environment && environment.equals(child)) {
return i;
}
@@ -765,7 +763,7 @@ JavaScriptCompiler.prototype = {
},
programExpression: function(guid) {
- var child = this.environment.children[guid],
+ let child = this.environment.children[guid],
programParams = [child.index, 'data', child.blockParams];
if (this.useBlockParams || this.useDepths) {
@@ -811,7 +809,7 @@ JavaScriptCompiler.prototype = {
},
replaceStack: function(callback) {
- var prefix = ['('],
+ let prefix = ['('],
stack,
createdStack,
usedLiteral;
@@ -822,7 +820,7 @@ JavaScriptCompiler.prototype = {
}
// We want to merge the inline statement into the replacement statement via ','
- var top = this.popStack(true);
+ let top = this.popStack(true);
if (top instanceof Literal) {
// Literals do not need to be inlined
@@ -832,13 +830,13 @@ JavaScriptCompiler.prototype = {
} else {
// Get or create the current stack name for use by the inline
createdStack = true;
- var name = this.incrStack();
+ let name = this.incrStack();
prefix = ['((', this.push(name), ' = ', top, ')'];
stack = this.topStack();
}
- var item = callback.call(this, stack);
+ let item = callback.call(this, stack);
if (!usedLiteral) {
this.popStack();
@@ -858,15 +856,15 @@ JavaScriptCompiler.prototype = {
return 'stack' + this.stackSlot;
},
flushInline: function() {
- var inlineStack = this.inlineStack;
+ let inlineStack = this.inlineStack;
this.inlineStack = [];
- for (var i = 0, len = inlineStack.length; i < len; i++) {
- var entry = inlineStack[i];
+ for (let i = 0, len = inlineStack.length; i < len; i++) {
+ let entry = inlineStack[i];
/* istanbul ignore if */
if (entry instanceof Literal) {
this.compileStack.push(entry);
} else {
- var stack = this.incrStack();
+ let stack = this.incrStack();
this.pushSource([stack, ' = ', entry, ';']);
this.compileStack.push(stack);
}
@@ -877,7 +875,7 @@ JavaScriptCompiler.prototype = {
},
popStack: function(wrapped) {
- var inline = this.isInline(),
+ let inline = this.isInline(),
item = (inline ? this.inlineStack : this.compileStack).pop();
if (!wrapped && (item instanceof Literal)) {
@@ -895,7 +893,7 @@ JavaScriptCompiler.prototype = {
},
topStack: function() {
- var stack = (this.isInline() ? this.inlineStack : this.compileStack),
+ let stack = (this.isInline() ? this.inlineStack : this.compileStack),
item = stack[stack.length - 1];
/* istanbul ignore if */
@@ -923,7 +921,7 @@ JavaScriptCompiler.prototype = {
},
aliasable: function(name) {
- var ret = this.aliases[name];
+ let ret = this.aliases[name];
if (ret) {
ret.referenceCount++;
return ret;
@@ -937,9 +935,9 @@ JavaScriptCompiler.prototype = {
},
setupHelper: function(paramSize, name, blockHelper) {
- var params = [],
+ let params = [],
paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);
- var foundHelper = this.nameLookup('helpers', name, 'helper');
+ let foundHelper = this.nameLookup('helpers', name, 'helper');
return {
params: params,
@@ -950,7 +948,7 @@ JavaScriptCompiler.prototype = {
},
setupParams: function(helper, paramSize, params) {
- var options = {}, contexts = [], types = [], ids = [], param;
+ let options = {}, contexts = [], types = [], ids = [], param;
options.name = this.quotedString(helper);
options.hash = this.popStack();
@@ -963,7 +961,7 @@ JavaScriptCompiler.prototype = {
options.hashContexts = this.popStack();
}
- var inverse = this.popStack(),
+ let inverse = this.popStack(),
program = this.popStack();
// Avoid setting fn and inverse if neither are set. This allows
@@ -975,7 +973,7 @@ JavaScriptCompiler.prototype = {
// The parameters go on to the stack in order (making sure that they are evaluated in order)
// so we need to pop them off the stack in reverse order
- var i = paramSize;
+ let i = paramSize;
while (i--) {
param = this.popStack();
params[i] = param;
@@ -1007,7 +1005,7 @@ JavaScriptCompiler.prototype = {
},
setupHelperArgs: function(helper, paramSize, params, useRegister) {
- var options = this.setupParams(helper, paramSize, params, true);
+ let options = this.setupParams(helper, paramSize, params, true);
options = this.objectLiteral(options);
if (useRegister) {
this.useRegister('options');
@@ -1022,7 +1020,7 @@ JavaScriptCompiler.prototype = {
(function() {
- var reservedWords = (
+ const reservedWords = (
'break else new var' +
' case finally return void' +
' catch for switch while' +
@@ -1041,9 +1039,9 @@ JavaScriptCompiler.prototype = {
' null true false'
).split(' ');
- var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
+ const compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
- for (var i = 0, l = reservedWords.length; i < l; i++) {
+ for (let i = 0, l = reservedWords.length; i < l; i++) {
compilerWords[reservedWords[i]] = true;
}
}());
@@ -1053,9 +1051,8 @@ JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
};
function strictLookup(requireTerminal, compiler, parts, type) {
- var stack = compiler.popStack();
-
- var i = 0,
+ let stack = compiler.popStack(),
+ i = 0,
len = parts.length;
if (requireTerminal) {
len--;