Remove unneeded code and add docs
There were a few operations that are no longer needed, so remove them. Also document all operations.
This commit is contained in:
+213
-169
@@ -240,21 +240,7 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
ID: function(id) {
|
||||
this.addDepth(id.depth);
|
||||
this.opcode('getContext', id.depth);
|
||||
|
||||
var name = id.parts[0];
|
||||
|
||||
if (!name) {
|
||||
this.opcode('pushContext');
|
||||
} else if (!id.isScoped && this.options.knownHelpers[name]) {
|
||||
this.declare('usingKnownHelper', true);
|
||||
this.opcode('knownHelper', name);
|
||||
} else if (id.isScoped || this.options.knownHelpersOnly) {
|
||||
this.declare('usingKnownHelper', false);
|
||||
this.opcode('lookupOnContext', name);
|
||||
} else {
|
||||
this.declare('usingKnownHelper', false);
|
||||
this.opcode('lookupWithHelpers', name);
|
||||
}
|
||||
this.opcode('lookupOnContext', id.parts[0]);
|
||||
|
||||
for(var i=1, l=id.parts.length; i<l; i++) {
|
||||
this.opcode('lookup', id.parts[i]);
|
||||
@@ -360,14 +346,6 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
this.opcode('pushLiteral', '{}');
|
||||
}
|
||||
|
||||
return params;
|
||||
},
|
||||
|
||||
setupStackForMustache: function(mustache) {
|
||||
var params = this.setupMustacheParams(mustache);
|
||||
|
||||
this.ID(mustache.id);
|
||||
|
||||
return params;
|
||||
}
|
||||
};
|
||||
@@ -525,6 +503,15 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
}
|
||||
},
|
||||
|
||||
// [blockValue]
|
||||
//
|
||||
// On stack, before: hash, inverse, program, value
|
||||
// On stack, after: return value of blockHelperMissing
|
||||
//
|
||||
// The purpose of this opcode is to take a block of the form
|
||||
// `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
|
||||
// replace it on the stack with the result of properly
|
||||
// invoking blockHelperMissing.
|
||||
blockValue: function() {
|
||||
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||
|
||||
@@ -537,6 +524,12 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
});
|
||||
},
|
||||
|
||||
// [ambiguousBlockValue]
|
||||
//
|
||||
// On stack, before: hash, inverse, program, value
|
||||
// Compiler value, before: lastHelper=value of last found helper, if any
|
||||
// On stack, after, if no lastHelper: same as [blockValue]
|
||||
// On stack, after, if lastHelper: value
|
||||
ambiguousBlockValue: function() {
|
||||
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||
|
||||
@@ -549,10 +542,25 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
this.source.push("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
|
||||
},
|
||||
|
||||
// [appendContent]
|
||||
//
|
||||
// On stack, before: ...
|
||||
// On stack, after: ...
|
||||
//
|
||||
// Appends the string value of `content` to the current buffer
|
||||
appendContent: function(content) {
|
||||
this.source.push(this.appendToBuffer(this.quotedString(content)));
|
||||
},
|
||||
|
||||
// [append]
|
||||
//
|
||||
// On stack, before: value, ...
|
||||
// On stack, after: ...
|
||||
//
|
||||
// Coerces `value` to a String and appends it to the current buffer.
|
||||
//
|
||||
// If `value` is truthy, or 0, it is coerced into a string and appended
|
||||
// Otherwise, the empty string is appended
|
||||
append: function() {
|
||||
var local = this.popStack();
|
||||
this.source.push("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
|
||||
@@ -561,6 +569,12 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
}
|
||||
},
|
||||
|
||||
// [appendEscaped]
|
||||
//
|
||||
// On stack, before: value, ...
|
||||
// On stack, after: ...
|
||||
//
|
||||
// Escape `value` and append it to the buffer
|
||||
appendEscaped: function() {
|
||||
var opcode = this.nextOpcode(), extra = "";
|
||||
this.context.aliases.escapeExpression = 'this.escapeExpression';
|
||||
@@ -573,24 +587,47 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
this.source.push(this.appendToBuffer("escapeExpression(" + this.popStack() + ")" + extra));
|
||||
},
|
||||
|
||||
// [getContext]
|
||||
//
|
||||
// On stack, before: ...
|
||||
// On stack, after: ...
|
||||
// Compiler value, after: lastContext=depth
|
||||
//
|
||||
// Set the value of the `lastContext` compiler value to the depth
|
||||
getContext: function(depth) {
|
||||
if(this.lastContext !== depth) {
|
||||
this.lastContext = depth;
|
||||
}
|
||||
},
|
||||
|
||||
knownHelper: function(name) {
|
||||
this.pushStackLiteral(this.nameLookup('helpers', name, 'helper'));
|
||||
},
|
||||
|
||||
// [lookupOnContext]
|
||||
//
|
||||
// On stack, before: ...
|
||||
// On stack, after: currentContext[name], ...
|
||||
//
|
||||
// Looks up the value of `name` on the current context and pushes
|
||||
// it onto the stack.
|
||||
lookupOnContext: function(name) {
|
||||
this.pushStack(this.nameLookup('depth' + this.lastContext, name, 'context'));
|
||||
},
|
||||
|
||||
// [pushContext]
|
||||
//
|
||||
// On stack, before: ...
|
||||
// On stack, after: currentContext, ...
|
||||
//
|
||||
// Pushes the value of the current context onto the stack.
|
||||
pushContext: function() {
|
||||
this.pushStackLiteral('depth' + this.lastContext);
|
||||
},
|
||||
|
||||
// [resolvePossibleLambda]
|
||||
//
|
||||
// On stack, before: value, ...
|
||||
// On stack, after: resolved value, ...
|
||||
//
|
||||
// If the `value` is a lambda, replace it on the stack by
|
||||
// the return value of the lambda
|
||||
resolvePossibleLambda: function() {
|
||||
this.context.aliases.functionType = '"function"';
|
||||
|
||||
@@ -599,57 +636,72 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
});
|
||||
},
|
||||
|
||||
lookupWithHelpers: function(name) {
|
||||
var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
|
||||
this.register('foundHelper', helperName);
|
||||
this.pushStack("foundHelper || " + this.nameLookup('depth' + this.lastContext, name, 'context'));
|
||||
},
|
||||
|
||||
// [lookup]
|
||||
//
|
||||
// On stack, before: value, ...
|
||||
// On stack, after: value[name], ...
|
||||
//
|
||||
// Replace the value on the stack with the result of looking
|
||||
// up `name` on `value`
|
||||
lookup: function(name) {
|
||||
this.replaceStack(function(current) {
|
||||
return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
|
||||
});
|
||||
},
|
||||
|
||||
// [pushStringParam]
|
||||
//
|
||||
// On stack, before: ...
|
||||
// On stack, after: string, currentContext, ...
|
||||
//
|
||||
// This opcode is designed for use in string mode, which
|
||||
// provides the string value of a parameter along with its
|
||||
// depth rather than resolving it immediately.
|
||||
pushStringParam: function(string) {
|
||||
this.pushStackLiteral('depth' + this.lastContext);
|
||||
this.pushString(string);
|
||||
},
|
||||
|
||||
// [pushString]
|
||||
//
|
||||
// On stack, before: ...
|
||||
// On stack, after: quotedString(string), ...
|
||||
//
|
||||
// Push a quoted version of `string` onto the stack
|
||||
pushString: function(string) {
|
||||
this.pushStackLiteral(this.quotedString(string));
|
||||
},
|
||||
|
||||
push: function(name) {
|
||||
this.pushStack(name);
|
||||
// [push]
|
||||
//
|
||||
// On stack, before: ...
|
||||
// On stack, after: expr, ...
|
||||
//
|
||||
// Push an expression onto the stack
|
||||
push: function(expr) {
|
||||
this.pushStack(expr);
|
||||
},
|
||||
|
||||
// [pushLiteral]
|
||||
//
|
||||
// On stack, before: ...
|
||||
// On stack, after: value, ...
|
||||
//
|
||||
// Pushes a value onto the stack. This operation prevents
|
||||
// the compiler from creating a temporary variable to hold
|
||||
// it.
|
||||
pushLiteral: function(value) {
|
||||
this.pushStackLiteral(value);
|
||||
},
|
||||
|
||||
// The rules for mustaches containing a block are:
|
||||
// [pushProgram]
|
||||
//
|
||||
// If the first parameter resolves to a function, call the function with the remaining parameters
|
||||
// Otherwise, invoke blockHelperMissing with the string form of the first parameter and the
|
||||
// remaining parameters.
|
||||
invokeProgram: function(guid, paramSize) {
|
||||
var options = [], program, inverse;
|
||||
|
||||
if (inverse = this.programExpression(this.inverse)) {
|
||||
options.push("inverse:" + inverse);
|
||||
}
|
||||
|
||||
if (program = this.programExpression(guid)) {
|
||||
options.push("fn:" + program);
|
||||
}
|
||||
|
||||
this.populateParams(paramSize, null, options, false, function(nextStack, helperMissingString) {
|
||||
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||
this.source.push("else { " + nextStack + " = blockHelperMissing.call(" + helperMissingString + "); }");
|
||||
});
|
||||
},
|
||||
|
||||
// On stack, before: ...
|
||||
// On stack, after: program(guid), ...
|
||||
//
|
||||
// Push a program expression onto the stack. This takes
|
||||
// a compile-time guid and converts it into a runtime-accessible
|
||||
// expression.
|
||||
pushProgram: function(guid) {
|
||||
if (guid != null) {
|
||||
this.pushStackLiteral(this.programExpression(guid));
|
||||
@@ -658,6 +710,15 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
}
|
||||
},
|
||||
|
||||
// [invokeHelper]
|
||||
//
|
||||
// On stack, before: hash, inverse, program, params..., ...
|
||||
// On stack, after: result of helper invocation
|
||||
//
|
||||
// Pops off the helper's parameters, invokes the helper,
|
||||
// and pushes the helper's return value onto the stack.
|
||||
//
|
||||
// If the helper is not found, `helperMissing` is called.
|
||||
invokeHelper: function(paramSize, name) {
|
||||
this.context.aliases.helperMissing = 'helpers.helperMissing';
|
||||
|
||||
@@ -669,11 +730,30 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
helper.helperMissingParams + ")");
|
||||
},
|
||||
|
||||
// [invokeKnownHelper]
|
||||
//
|
||||
// On stack, before: hash, inverse, program, params..., ...
|
||||
// On stack, after: result of helper invocation
|
||||
//
|
||||
// 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);
|
||||
this.pushStack(helper.name + ".call(" + helper.callParams + ")");
|
||||
},
|
||||
|
||||
// [invokeAmbiguous]
|
||||
//
|
||||
// On stack, before: hash, inverse, program, params..., ...
|
||||
// On stack, after: result of disambiguation
|
||||
//
|
||||
// This operation is used when an expression like `{{foo}}`
|
||||
// is provided, but we don't know at compile-time whether it
|
||||
// is a helper or a path.
|
||||
//
|
||||
// This operation emits more code than the other options,
|
||||
// and can be avoided by passing the `knownHelpers` and
|
||||
// `knownHelpersOnly` flags at compile-time.
|
||||
invokeAmbiguous: function(name) {
|
||||
this.context.aliases.functionType = '"function"';
|
||||
|
||||
@@ -690,119 +770,15 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
this.source.push('else { ' + nextStack + ' = ' + nonHelper + '; ' + nextStack + ' = typeof ' + nextStack + ' === functionType ? ' + nextStack + '() : ' + nextStack + '; }');
|
||||
},
|
||||
|
||||
setupHelper: function(paramSize, name) {
|
||||
var params = [];
|
||||
this.setupParams(paramSize, params);
|
||||
var foundHelper = this.nameLookup('helpers', name, 'helper');
|
||||
|
||||
return {
|
||||
params: params,
|
||||
name: foundHelper,
|
||||
callParams: ["depth0"].concat(params).join(", "),
|
||||
helperMissingParams: ["depth0", this.quotedString(name)].concat(params).join(", ")
|
||||
};
|
||||
},
|
||||
|
||||
// the params and contexts arguments are passed in arrays
|
||||
// to fill in
|
||||
setupParams: function(paramSize, params) {
|
||||
var options = [], contexts = [], param, inverse, program;
|
||||
|
||||
options.push("hash:" + this.popStack());
|
||||
|
||||
inverse = this.popStack();
|
||||
program = this.popStack();
|
||||
|
||||
// Avoid setting fn and inverse if neither are set. This allows
|
||||
// helpers to do a check for `if (options.fn)`
|
||||
if (program || inverse) {
|
||||
if (!program) {
|
||||
this.context.aliases.self = "this";
|
||||
program = "self.noop";
|
||||
}
|
||||
|
||||
if (!inverse) {
|
||||
this.context.aliases.self = "this";
|
||||
inverse = "self.noop";
|
||||
}
|
||||
|
||||
options.push("inverse:" + inverse);
|
||||
options.push("fn:" + program);
|
||||
}
|
||||
|
||||
for(var i=0; i<paramSize; i++) {
|
||||
param = this.popStack();
|
||||
params.push(param);
|
||||
|
||||
if(this.options.stringParams) {
|
||||
contexts.push(this.popStack());
|
||||
}
|
||||
}
|
||||
|
||||
if (this.options.stringParams) {
|
||||
options.push("contexts:[" + contexts.join(",") + "]");
|
||||
}
|
||||
|
||||
if(this.options.data) {
|
||||
options.push("data:data");
|
||||
}
|
||||
|
||||
params.push("{" + options.join(",") + "}");
|
||||
return params.join(", ");
|
||||
},
|
||||
|
||||
populateParams: function(paramSize, helperId, options, resolveLambdas, callback) {
|
||||
var id = this.popStack(), nextStack;
|
||||
var params = [], contexts = [], param, paramString, stringOptions;
|
||||
|
||||
options.push("hash:" + this.popStack());
|
||||
|
||||
for(var i=0; i<paramSize; i++) {
|
||||
param = this.popStack();
|
||||
params.push(param);
|
||||
|
||||
if(this.options.stringParams) {
|
||||
contexts.push(this.popStack());
|
||||
}
|
||||
}
|
||||
|
||||
if (this.options.stringParams) {
|
||||
options.push("contexts:[" + contexts.join(",") + "]");
|
||||
}
|
||||
|
||||
if(this.options.data) {
|
||||
options.push("data:data");
|
||||
}
|
||||
|
||||
this.register("params", "{" + options.join(",") + "}");
|
||||
|
||||
params.push("params");
|
||||
|
||||
if (this.usingKnownHelper) {
|
||||
this.pushStack(id + ".call(" + ["depth0"].concat(params).join(", ") + ")");
|
||||
} else {
|
||||
this.findAndCallHelper(params, id, helperId || id, resolveLambdas, callback);
|
||||
}
|
||||
},
|
||||
|
||||
findAndCallHelper: function(params, id, helperId, resolveLambdas, callback) {
|
||||
this.useRegister('foundHelper');
|
||||
this.context.aliases.functionType = '"function"';
|
||||
|
||||
var paramString = ["depth0"].concat(params).join(", "), nextStack;
|
||||
var helperMissingString = ["depth0"].concat(helperId).concat(params).join(", ");
|
||||
|
||||
nextStack = this.nextStack();
|
||||
var condition = resolveLambdas ? "" : "foundHelper && ";
|
||||
|
||||
this.source.push("if(" + condition + "typeof " + id + " === functionType) { " +
|
||||
nextStack + " = " + id + ".call(" + paramString + "); }");
|
||||
|
||||
callback.call(this, nextStack, helperMissingString, id);
|
||||
},
|
||||
|
||||
invokePartial: function(context) {
|
||||
var params = [this.nameLookup('partials', context, 'partial'), "'" + context + "'", this.popStack(), "helpers", "partials"];
|
||||
// [invokePartial]
|
||||
//
|
||||
// On stack, before: context, ...
|
||||
// On stack after: result of partial invocation
|
||||
//
|
||||
// This operation pops off a context, invokes a partial with that context,
|
||||
// and pushes the result of the invocation back.
|
||||
invokePartial: function(name) {
|
||||
var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];
|
||||
|
||||
if (this.options.data) {
|
||||
params.push("data");
|
||||
@@ -812,6 +788,13 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
this.pushStack("self.invokePartial(" + params.join(", ") + ");");
|
||||
},
|
||||
|
||||
// [assignToHash]
|
||||
//
|
||||
// On stack, before: value, hash, ...
|
||||
// On stack, after: hash, ...
|
||||
//
|
||||
// Pops a value and hash off the stack, assigns `hash[key] = value`
|
||||
// and pushes the hash back onto the stack.
|
||||
assignToHash: function(key) {
|
||||
var value = this.popStack();
|
||||
var hash = this.topStack();
|
||||
@@ -934,6 +917,67 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
.replace(/"/g, '\\"')
|
||||
.replace(/\n/g, '\\n')
|
||||
.replace(/\r/g, '\\r') + '"';
|
||||
},
|
||||
|
||||
setupHelper: function(paramSize, name) {
|
||||
var params = [];
|
||||
this.setupParams(paramSize, params);
|
||||
var foundHelper = this.nameLookup('helpers', name, 'helper');
|
||||
|
||||
return {
|
||||
params: params,
|
||||
name: foundHelper,
|
||||
callParams: ["depth0"].concat(params).join(", "),
|
||||
helperMissingParams: ["depth0", this.quotedString(name)].concat(params).join(", ")
|
||||
};
|
||||
},
|
||||
|
||||
// the params and contexts arguments are passed in arrays
|
||||
// to fill in
|
||||
setupParams: function(paramSize, params) {
|
||||
var options = [], contexts = [], param, inverse, program;
|
||||
|
||||
options.push("hash:" + this.popStack());
|
||||
|
||||
inverse = this.popStack();
|
||||
program = this.popStack();
|
||||
|
||||
// Avoid setting fn and inverse if neither are set. This allows
|
||||
// helpers to do a check for `if (options.fn)`
|
||||
if (program || inverse) {
|
||||
if (!program) {
|
||||
this.context.aliases.self = "this";
|
||||
program = "self.noop";
|
||||
}
|
||||
|
||||
if (!inverse) {
|
||||
this.context.aliases.self = "this";
|
||||
inverse = "self.noop";
|
||||
}
|
||||
|
||||
options.push("inverse:" + inverse);
|
||||
options.push("fn:" + program);
|
||||
}
|
||||
|
||||
for(var i=0; i<paramSize; i++) {
|
||||
param = this.popStack();
|
||||
params.push(param);
|
||||
|
||||
if(this.options.stringParams) {
|
||||
contexts.push(this.popStack());
|
||||
}
|
||||
}
|
||||
|
||||
if (this.options.stringParams) {
|
||||
options.push("contexts:[" + contexts.join(",") + "]");
|
||||
}
|
||||
|
||||
if(this.options.data) {
|
||||
options.push("data:data");
|
||||
}
|
||||
|
||||
params.push("{" + options.join(",") + "}");
|
||||
return params.join(", ");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user