Add trackIds compiler flag

Allows helpers that care about where a particular field came from derive this data while maintaining backward compatibility with existing helpers.
This commit is contained in:
kpdecker
2014-01-17 19:14:36 -06:00
parent 9df919083d
commit ace2896ec8
4 changed files with 151 additions and 8 deletions
+5 -1
View File
@@ -149,7 +149,8 @@ var AST = {
var original = "",
dig = [],
depth = 0;
depth = 0,
depthString = '';
for(var i=0,l=parts.length; i<l; i++) {
var part = parts[i].part;
@@ -160,6 +161,7 @@ var AST = {
throw new Exception("Invalid path: " + original, this);
} else if (part === "..") {
depth++;
depthString += '../';
} else {
this.isScoped = true;
}
@@ -172,6 +174,7 @@ var AST = {
this.parts = dig;
this.string = dig.join('.');
this.depth = depth;
this.idName = depthString + this.string;
// an ID is simple if it only has one part, and that part is not
// `..` or `this`.
@@ -191,6 +194,7 @@ var AST = {
this.type = "DATA";
this.id = id;
this.stringModeValue = id.stringModeValue;
this.idName = '@' + id.stringModeValue;
},
StringNode: function(string, locInfo) {
+4
View File
@@ -74,6 +74,7 @@ Compiler.prototype = {
this.depths = {list: []};
this.options = options;
this.stringParams = options.stringParams;
this.trackIds = options.trackIds;
// These changes will propagate to the other compiler components
var knownHelpers = this.options.knownHelpers;
@@ -395,6 +396,9 @@ Compiler.prototype = {
this.sexpr(val);
}
} else {
if (this.trackIds) {
this.opcode('pushId', val.type, val.idName || val.stringModeValue);
}
this.accept(val);
}
},
+36 -3
View File
@@ -61,6 +61,7 @@ JavaScriptCompiler.prototype = {
this.environment = environment;
this.options = options || {};
this.stringParams = this.options.stringParams;
this.trackIds = this.options.trackIds;
log('debug', this.environment.disassemble() + "\n\n");
@@ -418,6 +419,9 @@ JavaScriptCompiler.prototype = {
emptyHash: function() {
this.pushStackLiteral('{}');
if (this.trackIds) {
this.push('{}'); // hashIds
}
if (this.stringParams) {
this.push('{}'); // hashContexts
this.push('{}'); // hashTypes
@@ -427,12 +431,15 @@ JavaScriptCompiler.prototype = {
if (this.hash) {
this.hashes.push(this.hash);
}
this.hash = {values: [], types: [], contexts: []};
this.hash = {values: [], types: [], contexts: [], ids: []};
},
popHash: function() {
var hash = this.hash;
this.hash = this.hashes.pop();
if (this.trackIds) {
this.push('{' + hash.ids.join(',') + '}');
}
if (this.stringParams) {
this.push('{' + hash.contexts.join(',') + '}');
this.push('{' + hash.types.join(',') + '}');
@@ -589,8 +596,12 @@ JavaScriptCompiler.prototype = {
assignToHash: function(key) {
var value = this.popStack(),
context,
type;
type,
id;
if (this.trackIds) {
id = this.popStack();
}
if (this.stringParams) {
type = this.popStack();
context = this.popStack();
@@ -603,9 +614,22 @@ JavaScriptCompiler.prototype = {
if (type) {
hash.types.push("'" + key + "': " + type);
}
if (id) {
hash.ids.push("'" + key + "': " + id);
}
hash.values.push("'" + key + "': (" + value + ")");
},
pushId: function(type, name) {
if (type === 'ID' || type === 'DATA') {
this.pushString(name);
} else if (type === 'sexpr') {
this.pushStackLiteral('true');
} else {
this.pushStackLiteral('null');
}
},
// HELPERS
compiler: JavaScriptCompiler,
@@ -844,11 +868,14 @@ JavaScriptCompiler.prototype = {
},
setupOptions: function(helper, paramSize, params) {
var options = {}, contexts = [], types = [], param, inverse, program;
var options = {}, contexts = [], types = [], ids = [], param, inverse, program;
options.name = this.quotedString(helper);
options.hash = this.popStack();
if (this.trackIds) {
options.hashIds = this.popStack();
}
if (this.stringParams) {
options.hashTypes = this.popStack();
options.hashContexts = this.popStack();
@@ -878,12 +905,18 @@ JavaScriptCompiler.prototype = {
param = this.popStack();
params.push(param);
if (this.trackIds) {
ids.push(this.popStack());
}
if (this.stringParams) {
types.push(this.popStack());
contexts.push(this.popStack());
}
}
if (this.trackIds) {
options.ids = "[" + ids.join(",") + "]";
}
if (this.stringParams) {
options.types = "[" + types.join(",") + "]";
options.contexts = "[" + contexts.join(",") + "]";