summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkpdecker <kpdecker@gmail.com>2014-11-26 12:46:38 -0600
committerkpdecker <kpdecker@gmail.com>2014-11-26 19:04:18 -0600
commit2a4819d75cba7513946af5cf28ee22881561814f (patch)
tree6f88ee441e493e1d1f928598112a158400d500c8
parent5cfe6a0be16a912a5f00af251753a3d5746a6577 (diff)
downloadhandlebars.js-2a4819d75cba7513946af5cf28ee22881561814f.zip
handlebars.js-2a4819d75cba7513946af5cf28ee22881561814f.tar.gz
handlebars.js-2a4819d75cba7513946af5cf28ee22881561814f.tar.bz2
Update statement node ASTs
-rw-r--r--lib/handlebars/compiler/ast.js81
-rw-r--r--lib/handlebars/compiler/compiler.js99
-rw-r--r--lib/handlebars/compiler/helpers.js22
-rw-r--r--lib/handlebars/compiler/printer.js51
-rw-r--r--lib/handlebars/compiler/visitor.js27
-rw-r--r--spec/ast.js63
-rw-r--r--spec/parser.js2
-rw-r--r--spec/partials.js6
-rw-r--r--spec/visitor.js14
-rw-r--r--src/handlebars.yy13
10 files changed, 179 insertions, 199 deletions
diff --git a/lib/handlebars/compiler/ast.js b/lib/handlebars/compiler/ast.js
index 2f95cfb..26ea4ab 100644
--- a/lib/handlebars/compiler/ast.js
+++ b/lib/handlebars/compiler/ast.js
@@ -28,6 +28,41 @@ var AST = {
this.strip = strip;
},
+ BlockNode: function(sexpr, program, inverse, strip, locInfo) {
+ this.loc = locInfo;
+
+ this.type = 'BlockStatement';
+ this.sexpr = sexpr;
+ this.program = program;
+ this.inverse = inverse;
+ this.strip = strip;
+ },
+
+ PartialNode: function(sexpr, strip, locInfo) {
+ this.loc = locInfo;
+ this.type = 'PartialStatement';
+ this.sexpr = sexpr;
+ this.indent = '';
+
+ this.strip = strip;
+ this.strip.inlineStandalone = true;
+ },
+
+ ContentNode: function(string, locInfo) {
+ this.loc = locInfo;
+ this.type = 'ContentStatement';
+ this.original = this.value = string;
+ },
+
+ CommentNode: function(comment, strip, locInfo) {
+ this.loc = locInfo;
+ this.type = 'CommentStatement';
+ this.value = comment;
+
+ this.strip = strip;
+ strip.inlineStandalone = true;
+ },
+
SexprNode: function(rawParams, hash, locInfo) {
this.loc = locInfo;
@@ -51,37 +86,6 @@ var AST = {
// pass or at runtime.
},
- PartialNode: function(partialName, context, hash, strip, locInfo) {
- this.loc = locInfo;
- this.type = "partial";
- this.partialName = partialName;
- this.context = context;
- this.hash = hash;
- this.strip = strip;
-
- this.strip.inlineStandalone = true;
- },
-
- BlockNode: function(sexpr, program, inverse, strip, locInfo) {
- this.loc = locInfo;
-
- this.type = 'block';
- this.sexpr = sexpr;
- this.program = program;
- this.inverse = inverse;
- this.strip = strip;
-
- if (inverse && !program) {
- this.isInverse = true;
- }
- },
-
- ContentNode: function(string, locInfo) {
- this.loc = locInfo;
- this.type = "content";
- this.original = this.string = string;
- },
-
HashNode: function(pairs, locInfo) {
this.loc = locInfo;
this.type = "hash";
@@ -128,12 +132,6 @@ var AST = {
this.stringModeValue = this.string;
},
- PartialNameNode: function(name, locInfo) {
- this.loc = locInfo;
- this.type = "PARTIAL_NAME";
- this.name = name.original;
- },
-
DataNode: function(id, locInfo) {
this.loc = locInfo;
this.type = "DATA";
@@ -163,15 +161,6 @@ var AST = {
this.type = "BOOLEAN";
this.bool = bool;
this.stringModeValue = bool === "true";
- },
-
- CommentNode: function(comment, strip, locInfo) {
- this.loc = locInfo;
- this.type = "comment";
- this.comment = comment;
-
- this.strip = strip;
- strip.inlineStandalone = true;
}
};
diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js
index 69937a5..ea2272a 100644
--- a/lib/handlebars/compiler/compiler.js
+++ b/lib/handlebars/compiler/compiler.js
@@ -107,24 +107,19 @@ Compiler.prototype = {
return guid;
},
- block: function(block) {
+ BlockStatement: function(block) {
var sexpr = block.sexpr,
program = block.program,
inverse = block.inverse;
- if (program) {
- program = this.compileProgram(program);
- }
-
- if (inverse) {
- inverse = this.compileProgram(inverse);
- }
+ program = program && this.compileProgram(program);
+ inverse = inverse && this.compileProgram(inverse);
var type = this.classifySexpr(sexpr);
- if (type === "helper") {
+ if (type === 'helper') {
this.helperSexpr(sexpr, program, inverse);
- } else if (type === "simple") {
+ } else if (type === 'simple') {
this.simpleSexpr(sexpr);
// now that the simple mustache is resolved, we need to
@@ -147,32 +142,23 @@ Compiler.prototype = {
this.opcode('append', block);
},
- hash: function(hash) {
- var pairs = hash.pairs, i, l;
-
- this.opcode('pushHash', hash);
-
- for(i=0, l=pairs.length; i<l; i++) {
- this.pushParam(pairs[i][1]);
- }
- while(i--) {
- this.opcode('assignToHash', hash, pairs[i][0]);
- }
- this.opcode('popHash', hash);
- },
-
- partial: function(partial) {
- var partialName = partial.partialName;
+ PartialStatement: function(partial) {
+ var partialName = partial.sexpr.id.original;
this.usePartial = true;
- if (partial.hash) {
- this.accept(partial.hash);
+ if (partial.sexpr.hash) {
+ this.accept(partial.sexpr.hash);
} else {
this.opcode('pushLiteral', partial, 'undefined');
}
- if (partial.context) {
- this.accept(partial.context);
+ var params = partial.sexpr.params;
+ if (params.length) {
+ if (params.length > 1) {
+ throw new Exception('Unsupported number of partial arguments: ' + params.length, partial);
+ }
+
+ this.pushParam(params[0]);
} else {
this.opcode('getContext', partial, 0);
this.opcode('pushContext', partial);
@@ -183,16 +169,10 @@ Compiler.prototype = {
this.opcode('appendContent', partial, indent);
indent = '';
}
- this.opcode('invokePartial', partial, partialName.name, indent);
+ this.opcode('invokePartial', partial, partialName, indent);
this.opcode('append', partial);
},
- content: function(content) {
- if (content.string) {
- this.opcode('appendContent', content, content.string);
- }
- },
-
MustacheStatement: function(mustache) {
this.sexpr(mustache.sexpr);
@@ -203,6 +183,25 @@ Compiler.prototype = {
}
},
+ ContentStatement: function(content) {
+ if (content.value) {
+ this.opcode('appendContent', content, content.value);
+ }
+ },
+
+ CommentStatement: function() {},
+
+ sexpr: function(sexpr) {
+ var type = this.classifySexpr(sexpr);
+
+ if (type === "simple") {
+ this.simpleSexpr(sexpr);
+ } else if (type === "helper") {
+ this.helperSexpr(sexpr);
+ } else {
+ this.ambiguousSexpr(sexpr);
+ }
+ },
ambiguousSexpr: function(sexpr, program, inverse) {
var id = sexpr.id,
name = id.parts[0],
@@ -252,16 +251,18 @@ Compiler.prototype = {
}
},
- sexpr: function(sexpr) {
- var type = this.classifySexpr(sexpr);
+ hash: function(hash) {
+ var pairs = hash.pairs, i, l;
- if (type === "simple") {
- this.simpleSexpr(sexpr);
- } else if (type === "helper") {
- this.helperSexpr(sexpr);
- } else {
- this.ambiguousSexpr(sexpr);
+ this.opcode('pushHash', hash);
+
+ for(i=0, l=pairs.length; i<l; i++) {
+ this.pushParam(pairs[i][1]);
+ }
+ while(i--) {
+ this.opcode('assignToHash', hash, pairs[i][0]);
}
+ this.opcode('popHash', hash);
},
ID: function(id) {
@@ -294,8 +295,6 @@ Compiler.prototype = {
this.opcode('pushLiteral', bool, bool.bool);
},
- comment: function() {},
-
// HELPERS
opcode: function(name, node) {
this.opcodes.push({ opcode: name, args: slice.call(arguments, 2), loc: node.loc });
@@ -339,12 +338,14 @@ Compiler.prototype = {
},
pushParam: function(val) {
+ var stringModeValue = val.stringModeValue != null ? val.stringModeValue : '';
+
if (this.stringParams) {
if(val.depth) {
this.addDepth(val.depth);
}
this.opcode('getContext', val, val.depth || 0);
- this.opcode('pushStringParam', val, val.stringModeValue, val.type);
+ this.opcode('pushStringParam', val, stringModeValue, val.type);
if (val.type === 'sexpr') {
// Subexpressions get evaluated and passed in
@@ -353,7 +354,7 @@ Compiler.prototype = {
}
} else {
if (this.trackIds) {
- this.opcode('pushId', val, val.type, val.idName || val.stringModeValue);
+ this.opcode('pushId', val, val.type, val.idName || stringModeValue);
}
this.accept(val);
}
diff --git a/lib/handlebars/compiler/helpers.js b/lib/handlebars/compiler/helpers.js
index 2685f45..023566b 100644
--- a/lib/handlebars/compiler/helpers.js
+++ b/lib/handlebars/compiler/helpers.js
@@ -144,7 +144,7 @@ export function prepareProgram(body, isRoot) {
if (omitLeft(body, i)) {
// If we are on a standalone node, save the indent info for partials
- if (current.type === 'partial') {
+ if (current.type === 'PartialStatement') {
// Pull out the whitespace from the final line
current.indent = (/([ \t]+$)/).exec(body[i-1].original)[1];
}
@@ -180,7 +180,7 @@ function isPrevWhitespace(body, i, isRoot) {
return isRoot;
}
- if (prev.type === 'content') {
+ if (prev.type === 'ContentStatement') {
return (sibling || !isRoot ? (/\r?\n\s*?$/) : (/(^|\r?\n)\s*?$/)).test(prev.original);
}
}
@@ -195,7 +195,7 @@ function isNextWhitespace(body, i, isRoot) {
return isRoot;
}
- if (next.type === 'content') {
+ if (next.type === 'ContentStatement') {
return (sibling || !isRoot ? (/^\s*?\r?\n/) : (/^\s*?(\r?\n|$)/)).test(next.original);
}
}
@@ -209,13 +209,13 @@ function isNextWhitespace(body, i, isRoot) {
// content is met.
function omitRight(body, i, multiple) {
var current = body[i == null ? 0 : i + 1];
- if (!current || current.type !== 'content' || (!multiple && current.rightStripped)) {
+ if (!current || current.type !== 'ContentStatement' || (!multiple && current.rightStripped)) {
return;
}
- var original = current.string;
- current.string = current.string.replace(multiple ? (/^\s+/) : (/^[ \t]*\r?\n?/), '');
- current.rightStripped = current.string !== original;
+ var original = current.value;
+ current.value = current.value.replace(multiple ? (/^\s+/) : (/^[ \t]*\r?\n?/), '');
+ current.rightStripped = current.value !== original;
}
// Marks the node to the left of the position as omitted.
@@ -227,13 +227,13 @@ function omitRight(body, i, multiple) {
// content is met.
function omitLeft(body, i, multiple) {
var current = body[i == null ? body.length - 1 : i - 1];
- if (!current || current.type !== 'content' || (!multiple && current.leftStripped)) {
+ if (!current || current.type !== 'ContentStatement' || (!multiple && current.leftStripped)) {
return;
}
// We omit the last node if it's whitespace only and not preceeded by a non-content node.
- var original = current.string;
- current.string = current.string.replace(multiple ? (/\s+$/) : (/[ \t]+$/), '');
- current.leftStripped = current.string !== original;
+ var original = current.value;
+ current.value = current.value.replace(multiple ? (/\s+$/) : (/[ \t]+$/), '');
+ current.leftStripped = current.value !== original;
return current.leftStripped;
}
diff --git a/lib/handlebars/compiler/printer.js b/lib/handlebars/compiler/printer.js
index 481c7be..dac8ec2 100644
--- a/lib/handlebars/compiler/printer.js
+++ b/lib/handlebars/compiler/printer.js
@@ -48,21 +48,21 @@ PrintVisitor.prototype.MustacheStatement = function(mustache) {
return this.pad('{{ ' + this.accept(mustache.sexpr) + ' }}');
};
-PrintVisitor.prototype.block = function(block) {
+PrintVisitor.prototype.BlockStatement = function(block) {
var out = "";
- out = out + this.pad("BLOCK:");
+ out = out + this.pad('BLOCK:');
this.padding++;
out = out + this.pad(this.accept(block.sexpr));
if (block.program) {
- out = out + this.pad("PROGRAM:");
+ out = out + this.pad('PROGRAM:');
this.padding++;
out = out + this.accept(block.program);
this.padding--;
}
if (block.inverse) {
if (block.program) { this.padding++; }
- out = out + this.pad("{{^}}");
+ out = out + this.pad('{{^}}');
this.padding++;
out = out + this.accept(block.inverse);
this.padding--;
@@ -73,6 +73,26 @@ PrintVisitor.prototype.block = function(block) {
return out;
};
+PrintVisitor.prototype.PartialStatement = function(partial) {
+ var sexpr = partial.sexpr,
+ content = 'PARTIAL:' + sexpr.id.original;
+ if(sexpr.params[0]) {
+ content += ' ' + this.accept(sexpr.params[0]);
+ }
+ if (sexpr.hash) {
+ content += ' ' + this.accept(sexpr.hash);
+ }
+ return this.pad('{{> ' + content + ' }}');
+};
+
+PrintVisitor.prototype.ContentStatement = function(content) {
+ return this.pad("CONTENT[ '" + content.value + "' ]");
+};
+
+PrintVisitor.prototype.CommentStatement = function(comment) {
+ return this.pad("{{! '" + comment.value + "' }}");
+};
+
PrintVisitor.prototype.sexpr = function(sexpr) {
var params = sexpr.params, paramStrings = [], hash;
@@ -87,17 +107,6 @@ PrintVisitor.prototype.sexpr = function(sexpr) {
return this.accept(sexpr.id) + " " + params + hash;
};
-PrintVisitor.prototype.partial = function(partial) {
- var content = this.accept(partial.partialName);
- if(partial.context) {
- content += " " + this.accept(partial.context);
- }
- if (partial.hash) {
- content += " " + this.accept(partial.hash);
- }
- return this.pad("{{> " + content + " }}");
-};
-
PrintVisitor.prototype.hash = function(hash) {
var pairs = hash.pairs;
var joinedPairs = [], left, right;
@@ -132,19 +141,7 @@ PrintVisitor.prototype.ID = function(id) {
}
};
-PrintVisitor.prototype.PARTIAL_NAME = function(partialName) {
- return "PARTIAL:" + partialName.name;
-};
-
PrintVisitor.prototype.DATA = function(data) {
return "@" + this.accept(data.id);
};
-PrintVisitor.prototype.content = function(content) {
- return this.pad("CONTENT[ '" + content.string + "' ]");
-};
-
-PrintVisitor.prototype.comment = function(comment) {
- return this.pad("{{! '" + comment.comment + "' }}");
-};
-
diff --git a/lib/handlebars/compiler/visitor.js b/lib/handlebars/compiler/visitor.js
index dc7f527..e48c9bc 100644
--- a/lib/handlebars/compiler/visitor.js
+++ b/lib/handlebars/compiler/visitor.js
@@ -4,7 +4,7 @@ Visitor.prototype = {
constructor: Visitor,
accept: function(object) {
- return object && this[object.type] && this[object.type](object);
+ return object && this[object.type](object);
},
Program: function(program) {
@@ -20,12 +20,21 @@ Visitor.prototype = {
this.accept(mustache.sexpr);
},
- block: function(block) {
- this.accept(block.mustache);
+ BlockStatement: function(block) {
+ this.accept(block.sexpr);
this.accept(block.program);
this.accept(block.inverse);
},
+ PartialStatement: function(partial) {
+ this.accept(partial.partialName);
+ this.accept(partial.context);
+ this.accept(partial.hash);
+ },
+
+ ContentStatement: function(content) {},
+ CommentStatement: function(comment) {},
+
sexpr: function(sexpr) {
var params = sexpr.params, paramStrings = [], hash;
@@ -44,13 +53,6 @@ Visitor.prototype = {
}
},
- partial: function(partial) {
- this.accept(partial.partialName);
- this.accept(partial.context);
- this.accept(partial.hash);
- },
- PARTIAL_NAME: function(partialName) {},
-
DATA: function(data) {
this.accept(data.id);
},
@@ -58,10 +60,7 @@ Visitor.prototype = {
STRING: function(string) {},
NUMBER: function(number) {},
BOOLEAN: function(bool) {},
- ID: function(id) {},
-
- content: function(content) {},
- comment: function(comment) {}
+ ID: function(id) {}
};
export default Visitor;
diff --git a/spec/ast.js b/spec/ast.js
index d41a591..dc6e136 100644
--- a/spec/ast.js
+++ b/spec/ast.js
@@ -168,18 +168,9 @@ describe('ast', function() {
});
});
- describe("PartialNameNode", function(){
-
- it('stores location info', function(){
- var pnn = new handlebarsEnv.AST.PartialNameNode({original: "YES"}, LOCATION_INFO);
- testLocationInfoStorage(pnn);
- });
- });
-
describe("PartialNode", function(){
-
it('stores location info', function(){
- var pn = new handlebarsEnv.AST.PartialNode("so_partial", {}, {}, {}, LOCATION_INFO);
+ var pn = new handlebarsEnv.AST.PartialNode('so_partial', {}, LOCATION_INFO);
testLocationInfoStorage(pn);
});
});
@@ -248,8 +239,8 @@ describe('ast', function() {
describe('mustache', function() {
it('does not mark mustaches as standalone', function() {
var ast = Handlebars.parse(' {{comment}} ');
- equals(!!ast.body[0].string, true);
- equals(!!ast.body[2].string, true);
+ equals(!!ast.body[0].value, true);
+ equals(!!ast.body[2].value, true);
});
});
describe('blocks', function() {
@@ -257,38 +248,38 @@ describe('ast', function() {
var ast = Handlebars.parse(' {{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} '),
block = ast.body[1];
- equals(ast.body[0].string, '');
+ equals(ast.body[0].value, '');
- equals(block.program.body[0].string, 'foo\n');
- equals(block.inverse.body[0].string, ' bar \n');
+ equals(block.program.body[0].value, 'foo\n');
+ equals(block.inverse.body[0].value, ' bar \n');
- equals(ast.body[2].string, '');
+ equals(ast.body[2].value, '');
});
it('marks initial block mustaches as standalone', function() {
var ast = Handlebars.parse('{{# comment}} \nfoo\n {{/comment}}'),
block = ast.body[0];
- equals(block.program.body[0].string, 'foo\n');
+ equals(block.program.body[0].value, 'foo\n');
});
it('marks mustaches with children as standalone', function() {
var ast = Handlebars.parse('{{# comment}} \n{{foo}}\n {{/comment}}'),
block = ast.body[0];
- equals(block.program.body[0].string, '');
+ equals(block.program.body[0].value, '');
equals(block.program.body[1].sexpr.id.original, 'foo');
- equals(block.program.body[2].string, '\n');
+ equals(block.program.body[2].value, '\n');
});
it('marks nested block mustaches as standalone', function() {
var ast = Handlebars.parse('{{#foo}} \n{{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} \n{{/foo}}'),
body = ast.body[0].program.body,
block = body[1];
- equals(body[0].string, '');
+ equals(body[0].value, '');
- equals(block.program.body[0].string, 'foo\n');
- equals(block.inverse.body[0].string, ' bar \n');
+ equals(block.program.body[0].value, 'foo\n');
+ equals(block.inverse.body[0].value, ' bar \n');
- equals(body[0].string, '');
+ equals(body[0].value, '');
});
it('does not mark nested block mustaches as standalone', function() {
var ast = Handlebars.parse('{{#foo}} {{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} {{/foo}}'),
@@ -297,8 +288,8 @@ describe('ast', function() {
equals(body[0].omit, undefined);
- equals(block.program.body[0].string, ' \nfoo\n');
- equals(block.inverse.body[0].string, ' bar \n ');
+ equals(block.program.body[0].value, ' \nfoo\n');
+ equals(block.inverse.body[0].value, ' bar \n ');
equals(body[0].omit, undefined);
});
@@ -307,8 +298,8 @@ describe('ast', function() {
body = ast.body[0].program.body,
block = body[0];
- equals(block.program.body[0].string, ' \nfoo\n');
- equals(block.inverse.body[0].string, ' bar \n ');
+ equals(block.program.body[0].value, ' \nfoo\n');
+ equals(block.inverse.body[0].value, ' bar \n ');
equals(body[0].omit, undefined);
});
@@ -319,22 +310,22 @@ describe('ast', function() {
equals(ast.body[0].omit, undefined);
- equals(block.program.body[0].string, 'foo\n');
- equals(block.inverse.body[0].string, ' bar \n');
+ equals(block.program.body[0].value, 'foo\n');
+ equals(block.inverse.body[0].value, ' bar \n');
- equals(ast.body[2].string, '');
+ equals(ast.body[2].value, '');
});
});
describe('partials', function() {
it('marks partial as standalone', function() {
var ast = Handlebars.parse('{{> partial }} ');
- equals(ast.body[1].string, '');
+ equals(ast.body[1].value, '');
});
it('marks indented partial as standalone', function() {
var ast = Handlebars.parse(' {{> partial }} ');
- equals(ast.body[0].string, '');
+ equals(ast.body[0].value, '');
equals(ast.body[1].indent, ' ');
- equals(ast.body[2].string, '');
+ equals(ast.body[2].value, '');
});
it('marks those around content as not standalone', function() {
var ast = Handlebars.parse('a{{> partial }}');
@@ -347,12 +338,12 @@ describe('ast', function() {
describe('comments', function() {
it('marks comment as standalone', function() {
var ast = Handlebars.parse('{{! comment }} ');
- equals(ast.body[1].string, '');
+ equals(ast.body[1].value, '');
});
it('marks indented comment as standalone', function() {
var ast = Handlebars.parse(' {{! comment }} ');
- equals(ast.body[0].string, '');
- equals(ast.body[2].string, '');
+ equals(ast.body[0].value, '');
+ equals(ast.body[2].value, '');
});
it('marks those around content as not standalone', function() {
var ast = Handlebars.parse('a{{! comment }}');
diff --git a/spec/parser.js b/spec/parser.js
index 0569229..f2b6e41 100644
--- a/spec/parser.js
+++ b/spec/parser.js
@@ -82,6 +82,8 @@ describe('parser', function() {
it('parses a partial', function() {
equals(ast_for("{{> foo }}"), "{{> PARTIAL:foo }}\n");
+ equals(ast_for("{{> 'foo' }}"), "{{> PARTIAL:foo }}\n");
+ equals(ast_for("{{> 1 }}"), "{{> PARTIAL:1 }}\n");
});
it('parses a partial with context', function() {
diff --git a/spec/partials.js b/spec/partials.js
index a1e0538..b150942 100644
--- a/spec/partials.js
+++ b/spec/partials.js
@@ -23,6 +23,12 @@ describe('partials', function() {
shouldCompileToWithPartials(string, [hash, {}, {dude: partial}], true, "Dudes: Empty");
});
+ it('partials with duplicate parameters', function() {
+ shouldThrow(function() {
+ CompilerContext.compile('Dudes: {{>dude dudes foo bar=baz}}');
+ }, Error, 'Unsupported number of partial arguments: 2 - 1:7');
+ });
+
it("partials with parameters", function() {
var string = "Dudes: {{#dudes}}{{> dude others=..}}{{/dudes}}";
var partial = "{{others.foo}}{{name}} ({{url}}) ";
diff --git a/spec/visitor.js b/spec/visitor.js
index b64dc56..15a0f02 100644
--- a/spec/visitor.js
+++ b/spec/visitor.js
@@ -14,16 +14,12 @@ describe('Visitor', function() {
// Simply run the thing and make sure it does not fail and that all of the
// stub methods are executed
var visitor = new Handlebars.Visitor();
- visitor.accept(Handlebars.parse('{{#foo (bar 1 "1" true) foo=@data}}{{!comment}}{{> bar }} {{/foo}}'));
+ visitor.accept(Handlebars.parse('{{foo}}{{#foo (bar 1 "1" true) foo=@data}}{{!comment}}{{> bar }} {{/foo}}'));
});
it('should traverse to stubs', function() {
var visitor = new Handlebars.Visitor();
- visitor.PARTIAL_NAME = function(partialName) {
- equal(partialName.name, 'bar');
- };
-
visitor.STRING = function(string) {
equal(string.string, '2');
};
@@ -36,11 +32,11 @@ describe('Visitor', function() {
visitor.ID = function(id) {
equal(id.original, 'foo.bar');
};
- visitor.content = function(content) {
- equal(content.string, ' ');
+ visitor.ContentStatement = function(content) {
+ equal(content.value, ' ');
};
- visitor.comment = function(comment) {
- equal(comment.comment, 'comment');
+ visitor.CommentStatement = function(comment) {
+ equal(comment.value, 'comment');
};
visitor.accept(Handlebars.parse('{{#foo.bar (foo.bar 1 "2" true) foo=@foo.bar}}{{!comment}}{{> bar }} {{/foo.bar}}'));
diff --git a/src/handlebars.yy b/src/handlebars.yy
index d7d117c..0bd6fde 100644
--- a/src/handlebars.yy
+++ b/src/handlebars.yy
@@ -78,12 +78,11 @@ mustache
;
partial
- : OPEN_PARTIAL partialName param hash? CLOSE -> new yy.PartialNode($2, $3, $4, yy.stripFlags($1, $5), yy.locInfo(@$))
- | OPEN_PARTIAL partialName hash? CLOSE -> new yy.PartialNode($2, undefined, $3, yy.stripFlags($1, $4), yy.locInfo(@$))
+ : OPEN_PARTIAL sexpr CLOSE -> new yy.PartialNode($2, yy.stripFlags($1, $3), yy.locInfo(@$))
;
sexpr
- : path param* hash? -> new yy.SexprNode([$1].concat($2), $3, yy.locInfo(@$))
+ : helperName param* hash? -> new yy.SexprNode([$1].concat($2), $3, yy.locInfo(@$))
| dataName -> new yy.SexprNode([$1], null, yy.locInfo(@$))
;
@@ -108,10 +107,10 @@ blockParams
: OPEN_BLOCK_PARAMS ID+ CLOSE_BLOCK_PARAMS -> $2
;
-partialName
- : path -> new yy.PartialNameNode($1, yy.locInfo(@$))
- | STRING -> new yy.PartialNameNode(new yy.StringNode($1, yy.locInfo(@$)), yy.locInfo(@$))
- | NUMBER -> new yy.PartialNameNode(new yy.NumberNode($1, yy.locInfo(@$)))
+helperName
+ : path -> $1
+ | STRING -> new yy.StringNode($1, yy.locInfo(@$)), yy.locInfo(@$)
+ | NUMBER -> new yy.NumberNode($1, yy.locInfo(@$))
;
dataName