summaryrefslogtreecommitdiffstats
path: root/lib/handlebars/compiler
diff options
context:
space:
mode:
authorkpdecker <kpdecker@gmail.com>2014-11-26 20:35:33 -0600
committerkpdecker <kpdecker@gmail.com>2014-11-26 20:36:36 -0600
commit5c921cafebee438fa27d417ae701b24323373a30 (patch)
treeb83b875444816351d3e45f13e8ddf3769294cad1 /lib/handlebars/compiler
parent697bbe59cad06bc74a945f7e26fc0af333a01d47 (diff)
downloadhandlebars.js-5c921cafebee438fa27d417ae701b24323373a30.zip
handlebars.js-5c921cafebee438fa27d417ae701b24323373a30.tar.gz
handlebars.js-5c921cafebee438fa27d417ae701b24323373a30.tar.bz2
Replace DataNode and IdNode with PathNode
This is a breaking change for string mode users as there is no longer a distinct type for data parameters. Instead data consumers should look for the @ prefix value.
Diffstat (limited to 'lib/handlebars/compiler')
-rw-r--r--lib/handlebars/compiler/ast.js27
-rw-r--r--lib/handlebars/compiler/compiler.js39
-rw-r--r--lib/handlebars/compiler/javascript-compiler.js2
-rw-r--r--lib/handlebars/compiler/printer.js20
-rw-r--r--lib/handlebars/compiler/visitor.js9
5 files changed, 42 insertions, 55 deletions
diff --git a/lib/handlebars/compiler/ast.js b/lib/handlebars/compiler/ast.js
index 44b26ec..287a9e5 100644
--- a/lib/handlebars/compiler/ast.js
+++ b/lib/handlebars/compiler/ast.js
@@ -92,11 +92,11 @@ var AST = {
this.pairs = pairs;
},
- IdNode: function(parts, locInfo) {
+ PathNode: function(data, parts, locInfo) {
this.loc = locInfo;
- this.type = "ID";
+ this.type = 'PathExpression';
- var original = "",
+ var original = '',
dig = [],
depth = 0,
depthString = '';
@@ -105,10 +105,10 @@ var AST = {
var part = parts[i].part;
original += (parts[i].separator || '') + part;
- if (part === ".." || part === "." || part === "this") {
+ if (part === '..' || part === '.' || part === 'this') {
if (dig.length > 0) {
- throw new Exception("Invalid path: " + original, this);
- } else if (part === "..") {
+ throw new Exception('Invalid path: ' + original, this);
+ } else if (part === '..') {
depth++;
depthString += '../';
} else {
@@ -119,25 +119,14 @@ var AST = {
}
}
- this.original = original;
+ this.data = data;
+ this.original = (data ? '@' : '') + original;
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`.
this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
-
- this.stringModeValue = this.string;
- },
-
- DataNode: function(id, locInfo) {
- this.loc = locInfo;
- this.type = "DATA";
- this.id = id;
- this.stringModeValue = id.stringModeValue;
- this.idName = '@' + id.stringModeValue;
},
StringNode: function(string, locInfo) {
diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js
index a5acb64..ea65583 100644
--- a/lib/handlebars/compiler/compiler.js
+++ b/lib/handlebars/compiler/compiler.js
@@ -212,7 +212,7 @@ Compiler.prototype = {
this.opcode('pushProgram', sexpr, program);
this.opcode('pushProgram', sexpr, inverse);
- this.ID(id);
+ this.accept(id);
this.opcode('invokeAmbiguous', sexpr, name, isBlock);
},
@@ -220,10 +220,8 @@ Compiler.prototype = {
simpleSexpr: function(sexpr) {
var id = sexpr.id;
- if (id.type === 'DATA') {
- this.DATA(id);
- } else if (id.parts.length) {
- this.ID(id);
+ if (id.parts.length) {
+ this.accept(id);
} else {
// Simplified ID for `this`
this.addDepth(id.depth);
@@ -246,7 +244,7 @@ Compiler.prototype = {
} else {
id.falsy = true;
- this.ID(id);
+ this.accept(id);
this.opcode('invokeHelper', sexpr, params.length, id.original, id.isSimple);
}
},
@@ -265,7 +263,7 @@ Compiler.prototype = {
this.opcode('popHash', hash);
},
- ID: function(id) {
+ PathExpression: function(id) {
this.addDepth(id.depth);
this.opcode('getContext', id, id.depth);
@@ -273,16 +271,14 @@ Compiler.prototype = {
if (!name) {
// Context reference, i.e. `{{foo .}}` or `{{foo ..}}`
this.opcode('pushContext', id);
+ } else if (id.data) {
+ this.options.data = true;
+ this.opcode('lookupData', id, id.depth, id.parts);
} else {
this.opcode('lookupOnContext', id, id.parts, id.falsy, id.isScoped);
}
},
- DATA: function(data) {
- this.options.data = true;
- this.opcode('lookupData', data, data.id.depth, data.id.parts);
- },
-
StringLiteral: function(string) {
this.opcode('pushString', string, string.value);
},
@@ -338,14 +334,20 @@ Compiler.prototype = {
},
pushParam: function(val) {
- var stringModeValue = val.stringModeValue || (val.value != null ? val.value : '');
+ var value = val.value != null ? val.value : val.original || '';
if (this.stringParams) {
+ if (value.replace) {
+ value = value
+ .replace(/^(\.?\.\/)*/g, '')
+ .replace(/\//g, '.');
+ }
+
if(val.depth) {
this.addDepth(val.depth);
}
this.opcode('getContext', val, val.depth || 0);
- this.opcode('pushStringParam', val, stringModeValue, val.type);
+ this.opcode('pushStringParam', val, value, val.type);
if (val.type === 'sexpr') {
// Subexpressions get evaluated and passed in
@@ -354,7 +356,14 @@ Compiler.prototype = {
}
} else {
if (this.trackIds) {
- this.opcode('pushId', val, val.type, val.idName || stringModeValue);
+ value = val.original || value;
+ if (value.replace) {
+ value = value
+ .replace(/^\.\//g, '')
+ .replace(/^\.$/g, '');
+ }
+
+ this.opcode('pushId', val, val.type, value);
}
this.accept(val);
}
diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js
index 639aa41..2916a32 100644
--- a/lib/handlebars/compiler/javascript-compiler.js
+++ b/lib/handlebars/compiler/javascript-compiler.js
@@ -659,7 +659,7 @@ JavaScriptCompiler.prototype = {
},
pushId: function(type, name) {
- if (type === 'ID' || type === 'DATA') {
+ if (type === 'PathExpression') {
this.pushString(name);
} else if (type === 'sexpr') {
this.pushStackLiteral('true');
diff --git a/lib/handlebars/compiler/printer.js b/lib/handlebars/compiler/printer.js
index c86f7fa..05e8ee7 100644
--- a/lib/handlebars/compiler/printer.js
+++ b/lib/handlebars/compiler/printer.js
@@ -107,6 +107,12 @@ PrintVisitor.prototype.sexpr = function(sexpr) {
return this.accept(sexpr.id) + " " + params + hash;
};
+PrintVisitor.prototype.PathExpression = function(id) {
+ var path = id.parts.join('/');
+ return (id.data ? '@' : '') + 'PATH:' + path;
+};
+
+
PrintVisitor.prototype.hash = function(hash) {
var pairs = hash.pairs;
var joinedPairs = [], left, right;
@@ -131,17 +137,3 @@ PrintVisitor.prototype.NumberLiteral = function(number) {
PrintVisitor.prototype.BooleanLiteral = function(bool) {
return "BOOLEAN{" + bool.value + "}";
};
-
-PrintVisitor.prototype.ID = function(id) {
- var path = id.parts.join("/");
- if(id.parts.length > 1) {
- return "PATH:" + path;
- } else {
- return "ID:" + path;
- }
-};
-
-PrintVisitor.prototype.DATA = function(data) {
- return "@" + this.accept(data.id);
-};
-
diff --git a/lib/handlebars/compiler/visitor.js b/lib/handlebars/compiler/visitor.js
index a2ad7bb..e191bbd 100644
--- a/lib/handlebars/compiler/visitor.js
+++ b/lib/handlebars/compiler/visitor.js
@@ -45,6 +45,8 @@ Visitor.prototype = {
this.accept(sexpr.hash);
},
+ PathExpression: function(id) {},
+
hash: function(hash) {
var pairs = hash.pairs;
@@ -53,14 +55,9 @@ Visitor.prototype = {
}
},
- DATA: function(data) {
- this.accept(data.id);
- },
-
StringLiteral: function(string) {},
NumberLiteral: function(number) {},
- BooleanLiteral: function(bool) {},
- ID: function(id) {}
+ BooleanLiteral: function(bool) {}
};
export default Visitor;