Update for let and optional parameters

This commit is contained in:
kpdecker
2015-04-20 02:38:28 -05:00
parent 0263aa48bc
commit 4bed826d0e
15 changed files with 236 additions and 239 deletions
+66 -69
View File
@@ -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--;