diff options
author | kpdecker <kpdecker@gmail.com> | 2014-11-26 09:18:33 -0600 |
---|---|---|
committer | kpdecker <kpdecker@gmail.com> | 2014-11-26 09:18:33 -0600 |
commit | df421f1e4b43773c61bc7c2c3cd06e0ff9ec4905 (patch) | |
tree | 8323023702dba63dece9a62707849669e376592c | |
parent | 61dd721ca2a9055036d0f350970d033ca5227411 (diff) | |
download | handlebars.js-df421f1e4b43773c61bc7c2c3cd06e0ff9ec4905.zip handlebars.js-df421f1e4b43773c61bc7c2c3cd06e0ff9ec4905.tar.gz handlebars.js-df421f1e4b43773c61bc7c2c3cd06e0ff9ec4905.tar.bz2 |
Update ProgramNode to better match SpiderMonkey
-rw-r--r-- | lib/handlebars/compiler/ast.js | 5 | ||||
-rw-r--r-- | lib/handlebars/compiler/base.js | 2 | ||||
-rw-r--r-- | lib/handlebars/compiler/compiler.js | 14 | ||||
-rw-r--r-- | lib/handlebars/compiler/helpers.js | 78 | ||||
-rw-r--r-- | lib/handlebars/compiler/printer.js | 16 | ||||
-rw-r--r-- | lib/handlebars/compiler/visitor.js | 8 | ||||
-rw-r--r-- | spec/ast.js | 112 | ||||
-rw-r--r-- | src/handlebars.yy | 2 |
8 files changed, 119 insertions, 118 deletions
diff --git a/lib/handlebars/compiler/ast.js b/lib/handlebars/compiler/ast.js index 363c252..a0ed42e 100644 --- a/lib/handlebars/compiler/ast.js +++ b/lib/handlebars/compiler/ast.js @@ -3,8 +3,9 @@ import Exception from "../exception"; var AST = { ProgramNode: function(statements, blockParams, strip, locInfo) { this.loc = locInfo; - this.type = "program"; - this.statements = statements; + this.type = 'Program'; + this.body = statements; + this.blockParams = blockParams; this.strip = strip; }, diff --git a/lib/handlebars/compiler/base.js b/lib/handlebars/compiler/base.js index df6b928..786c37e 100644 --- a/lib/handlebars/compiler/base.js +++ b/lib/handlebars/compiler/base.js @@ -10,7 +10,7 @@ extend(yy, Helpers, AST); export function parse(input, options) { // Just return if an already-compile AST was passed in. - if (input.constructor === AST.ProgramNode) { return input; } + if (input.type === 'Program') { return input; } parser.yy = yy; diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js index d80bfac..683e3e5 100644 --- a/lib/handlebars/compiler/compiler.js +++ b/lib/handlebars/compiler/compiler.js @@ -74,12 +74,12 @@ Compiler.prototype = { return this[node.type](node); }, - program: function(program) { - var statements = program.statements; - - for(var i=0, l=statements.length; i<l; i++) { - this.accept(statements[i]); + Program: function(program) { + var body = program.body; + for(var i=0, l=body.length; i<l; i++) { + this.accept(body[i]); } + this.isSimple = l === 1; this.depths.list = this.depths.list.sort(function(a, b) { @@ -377,7 +377,7 @@ Compiler.prototype = { }; export function precompile(input, options, env) { - if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) { + if (input == null || (typeof input !== 'string' && input.type !== 'Program')) { throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input); } @@ -395,7 +395,7 @@ export function precompile(input, options, env) { } export function compile(input, options, env) { - if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) { + if (input == null || (typeof input !== 'string' && input.type !== 'Program')) { throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input); } diff --git a/lib/handlebars/compiler/helpers.js b/lib/handlebars/compiler/helpers.js index 3a3ece6..2685f45 100644 --- a/lib/handlebars/compiler/helpers.js +++ b/lib/handlebars/compiler/helpers.js @@ -59,11 +59,11 @@ export function prepareBlock(openBlock, program, inverseAndProgram, close, inver firstInverse = inverse, lastInverse = inverse; if (inverse && inverse.inverse) { - firstInverse = inverse.statements[0].program; + firstInverse = inverse.body[0].program; // Walk the inverse chain to find the last inverse that is actually in the chain. while (lastInverse.inverse) { - lastInverse = lastInverse.statements[lastInverse.statements.length-1].program; + lastInverse = lastInverse.body[lastInverse.body.length-1].program; } } @@ -73,38 +73,38 @@ export function prepareBlock(openBlock, program, inverseAndProgram, close, inver // Determine the standalone candiacy. Basically flag our content as being possibly standalone // so our parent can determine if we actually are standalone - openStandalone: isNextWhitespace(program.statements), - closeStandalone: isPrevWhitespace((firstInverse || program).statements) + openStandalone: isNextWhitespace(program.body), + closeStandalone: isPrevWhitespace((firstInverse || program).body) }; if (openBlock.strip.right) { - omitRight(program.statements, null, true); + omitRight(program.body, null, true); } if (inverse) { var inverseStrip = inverseAndProgram.strip; if (inverseStrip.left) { - omitLeft(program.statements, null, true); + omitLeft(program.body, null, true); } if (inverseStrip.right) { - omitRight(firstInverse.statements, null, true); + omitRight(firstInverse.body, null, true); } if (close.strip.left) { - omitLeft(lastInverse.statements, null, true); + omitLeft(lastInverse.body, null, true); } // Find standalone else statments - if (isPrevWhitespace(program.statements) - && isNextWhitespace(firstInverse.statements)) { + if (isPrevWhitespace(program.body) + && isNextWhitespace(firstInverse.body)) { - omitLeft(program.statements); - omitRight(firstInverse.statements); + omitLeft(program.body); + omitRight(firstInverse.body); } } else { if (close.strip.left) { - omitLeft(program.statements, null, true); + omitLeft(program.body, null, true); } } @@ -116,66 +116,66 @@ export function prepareBlock(openBlock, program, inverseAndProgram, close, inver } -export function prepareProgram(statements, isRoot) { - for (var i = 0, l = statements.length; i < l; i++) { - var current = statements[i], +export function prepareProgram(body, isRoot) { + for (var i = 0, l = body.length; i < l; i++) { + var current = body[i], strip = current.strip; if (!strip) { continue; } - var _isPrevWhitespace = isPrevWhitespace(statements, i, isRoot, current.type === 'partial'), - _isNextWhitespace = isNextWhitespace(statements, i, isRoot), + var _isPrevWhitespace = isPrevWhitespace(body, i, isRoot, current.type === 'partial'), + _isNextWhitespace = isNextWhitespace(body, i, isRoot), openStandalone = strip.openStandalone && _isPrevWhitespace, closeStandalone = strip.closeStandalone && _isNextWhitespace, inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace; if (strip.right) { - omitRight(statements, i, true); + omitRight(body, i, true); } if (strip.left) { - omitLeft(statements, i, true); + omitLeft(body, i, true); } if (inlineStandalone) { - omitRight(statements, i); + omitRight(body, i); - if (omitLeft(statements, i)) { + if (omitLeft(body, i)) { // If we are on a standalone node, save the indent info for partials if (current.type === 'partial') { // Pull out the whitespace from the final line - current.indent = (/([ \t]+$)/).exec(statements[i-1].original)[1]; + current.indent = (/([ \t]+$)/).exec(body[i-1].original)[1]; } } } if (openStandalone) { - omitRight((current.program || current.inverse).statements); + omitRight((current.program || current.inverse).body); // Strip out the previous content node if it's whitespace only - omitLeft(statements, i); + omitLeft(body, i); } if (closeStandalone) { // Always strip the next node - omitRight(statements, i); + omitRight(body, i); - omitLeft((current.inverse || current.program).statements); + omitLeft((current.inverse || current.program).body); } } - return statements; + return body; } -function isPrevWhitespace(statements, i, isRoot) { +function isPrevWhitespace(body, i, isRoot) { if (i === undefined) { - i = statements.length; + i = body.length; } // Nodes that end with newlines are considered whitespace (but are special // cased for strip operations) - var prev = statements[i-1], - sibling = statements[i-2]; + var prev = body[i-1], + sibling = body[i-2]; if (!prev) { return isRoot; } @@ -184,13 +184,13 @@ function isPrevWhitespace(statements, i, isRoot) { return (sibling || !isRoot ? (/\r?\n\s*?$/) : (/(^|\r?\n)\s*?$/)).test(prev.original); } } -function isNextWhitespace(statements, i, isRoot) { +function isNextWhitespace(body, i, isRoot) { if (i === undefined) { i = -1; } - var next = statements[i+1], - sibling = statements[i+2]; + var next = body[i+1], + sibling = body[i+2]; if (!next) { return isRoot; } @@ -207,8 +207,8 @@ function isNextWhitespace(statements, i, isRoot) { // // If mulitple is truthy then all whitespace will be stripped out until non-whitespace // content is met. -function omitRight(statements, i, multiple) { - var current = statements[i == null ? 0 : i + 1]; +function omitRight(body, i, multiple) { + var current = body[i == null ? 0 : i + 1]; if (!current || current.type !== 'content' || (!multiple && current.rightStripped)) { return; } @@ -225,8 +225,8 @@ function omitRight(statements, i, multiple) { // // If mulitple is truthy then all whitespace will be stripped out until non-whitespace // content is met. -function omitLeft(statements, i, multiple) { - var current = statements[i == null ? statements.length - 1 : i - 1]; +function omitLeft(body, i, multiple) { + var current = body[i == null ? body.length - 1 : i - 1]; if (!current || current.type !== 'content' || (!multiple && current.leftStripped)) { return; } diff --git a/lib/handlebars/compiler/printer.js b/lib/handlebars/compiler/printer.js index e93652c..8c2346e 100644 --- a/lib/handlebars/compiler/printer.js +++ b/lib/handlebars/compiler/printer.js @@ -21,22 +21,22 @@ PrintVisitor.prototype.pad = function(string) { return out; }; -PrintVisitor.prototype.program = function(program) { - var out = "", - statements = program.statements, +PrintVisitor.prototype.Program = function(program) { + var out = '', + body = program.body, i, l; if (program.blockParams) { - var blockParams = "BLOCK PARAMS: ["; + var blockParams = 'BLOCK PARAMS: ['; for(i=0, l=program.blockParams.length; i<l; i++) { - blockParams += " " + program.blockParams[i]; + blockParams += ' ' + program.blockParams[i]; } - blockParams += " ]"; + blockParams += ' ]'; out += this.pad(blockParams); } - for(i=0, l=statements.length; i<l; i++) { - out = out + this.accept(statements[i]); + for(i=0, l=body.length; i<l; i++) { + out = out + this.accept(body[i]); } this.padding--; diff --git a/lib/handlebars/compiler/visitor.js b/lib/handlebars/compiler/visitor.js index a4eb2b4..12d822c 100644 --- a/lib/handlebars/compiler/visitor.js +++ b/lib/handlebars/compiler/visitor.js @@ -7,12 +7,12 @@ Visitor.prototype = { return object && this[object.type] && this[object.type](object); }, - program: function(program) { - var statements = program.statements, + Program: function(program) { + var body = program.body, i, l; - for(i=0, l=statements.length; i<l; i++) { - this.accept(statements[i]); + for(i=0, l=body.length; i<l; i++) { + this.accept(body[i]); } }, diff --git a/spec/ast.js b/spec/ast.js index 83b24b9..e13e956 100644 --- a/spec/ast.js +++ b/spec/ast.js @@ -77,7 +77,7 @@ describe('ast', function() { var sexprNode = new handlebarsEnv.AST.SexprNode([{ original: 'foo'}], null); var mustacheNode = new handlebarsEnv.AST.MustacheNode(sexprNode, null, '{{', {}); var block = new handlebarsEnv.AST.BlockNode(mustacheNode, - {statements: [], strip: {}}, {statements: [], strip: {}}, + {body: [], strip: {}}, {body: [], strip: {}}, { strip: {}, path: {original: 'foo'} @@ -197,7 +197,7 @@ describe('ast', function() { }); describe("Line Numbers", function(){ - var ast, statements; + var ast, body; function testColumns(node, firstLine, lastLine, firstColumn, lastColumn){ equals(node.loc.start.line, firstLine); @@ -208,41 +208,41 @@ describe('ast', function() { ast = Handlebars.parse("line 1 {{line1Token}}\n line 2 {{line2token}}\n line 3 {{#blockHelperOnLine3}}\nline 4{{line4token}}\n" + "line5{{else}}\n{{line6Token}}\n{{/blockHelperOnLine3}}"); - statements = ast.statements; + body = ast.body; it('gets ContentNode line numbers', function(){ - var contentNode = statements[0]; + var contentNode = body[0]; testColumns(contentNode, 1, 1, 0, 7); }); it('gets MustacheNode line numbers', function(){ - var mustacheNode = statements[1]; + var mustacheNode = body[1]; testColumns(mustacheNode, 1, 1, 7, 21); }); it('gets line numbers correct when newlines appear', function(){ - testColumns(statements[2], 1, 2, 21, 8); + testColumns(body[2], 1, 2, 21, 8); }); it('gets MustacheNode line numbers correct across newlines', function(){ - var secondMustacheNode = statements[3]; + var secondMustacheNode = body[3]; testColumns(secondMustacheNode, 2, 2, 8, 22); }); it('gets the block helper information correct', function(){ - var blockHelperNode = statements[5]; + var blockHelperNode = body[5]; testColumns(blockHelperNode, 3, 7, 8, 23); }); it('correctly records the line numbers the program of a block helper', function(){ - var blockHelperNode = statements[5], + var blockHelperNode = body[5], program = blockHelperNode.program; testColumns(program, 3, 5, 8, 5); }); it('correctly records the line numbers of an inverse of a block helper', function(){ - var blockHelperNode = statements[5], + var blockHelperNode = body[5], inverse = blockHelperNode.inverse; testColumns(inverse, 5, 7, 5, 0); @@ -253,118 +253,118 @@ describe('ast', function() { describe('mustache', function() { it('does not mark mustaches as standalone', function() { var ast = Handlebars.parse(' {{comment}} '); - equals(!!ast.statements[0].string, true); - equals(!!ast.statements[2].string, true); + equals(!!ast.body[0].string, true); + equals(!!ast.body[2].string, true); }); }); describe('blocks', function() { it('marks block mustaches as standalone', function() { var ast = Handlebars.parse(' {{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} '), - block = ast.statements[1]; + block = ast.body[1]; - equals(ast.statements[0].string, ''); + equals(ast.body[0].string, ''); - equals(block.program.statements[0].string, 'foo\n'); - equals(block.inverse.statements[0].string, ' bar \n'); + equals(block.program.body[0].string, 'foo\n'); + equals(block.inverse.body[0].string, ' bar \n'); - equals(ast.statements[2].string, ''); + equals(ast.body[2].string, ''); }); it('marks initial block mustaches as standalone', function() { var ast = Handlebars.parse('{{# comment}} \nfoo\n {{/comment}}'), - block = ast.statements[0]; + block = ast.body[0]; - equals(block.program.statements[0].string, 'foo\n'); + equals(block.program.body[0].string, 'foo\n'); }); it('marks mustaches with children as standalone', function() { var ast = Handlebars.parse('{{# comment}} \n{{foo}}\n {{/comment}}'), - block = ast.statements[0]; + block = ast.body[0]; - equals(block.program.statements[0].string, ''); - equals(block.program.statements[1].id.original, 'foo'); - equals(block.program.statements[2].string, '\n'); + equals(block.program.body[0].string, ''); + equals(block.program.body[1].id.original, 'foo'); + equals(block.program.body[2].string, '\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}}'), - statements = ast.statements[0].program.statements, - block = statements[1]; + body = ast.body[0].program.body, + block = body[1]; - equals(statements[0].string, ''); + equals(body[0].string, ''); - equals(block.program.statements[0].string, 'foo\n'); - equals(block.inverse.statements[0].string, ' bar \n'); + equals(block.program.body[0].string, 'foo\n'); + equals(block.inverse.body[0].string, ' bar \n'); - equals(statements[0].string, ''); + equals(body[0].string, ''); }); it('does not mark nested block mustaches as standalone', function() { var ast = Handlebars.parse('{{#foo}} {{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} {{/foo}}'), - statements = ast.statements[0].program.statements, - block = statements[1]; + body = ast.body[0].program.body, + block = body[1]; - equals(statements[0].omit, undefined); + equals(body[0].omit, undefined); - equals(block.program.statements[0].string, ' \nfoo\n'); - equals(block.inverse.statements[0].string, ' bar \n '); + equals(block.program.body[0].string, ' \nfoo\n'); + equals(block.inverse.body[0].string, ' bar \n '); - equals(statements[0].omit, undefined); + equals(body[0].omit, undefined); }); it('does not mark nested initial block mustaches as standalone', function() { var ast = Handlebars.parse('{{#foo}}{{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}}{{/foo}}'), - statements = ast.statements[0].program.statements, - block = statements[0]; + body = ast.body[0].program.body, + block = body[0]; - equals(block.program.statements[0].string, ' \nfoo\n'); - equals(block.inverse.statements[0].string, ' bar \n '); + equals(block.program.body[0].string, ' \nfoo\n'); + equals(block.inverse.body[0].string, ' bar \n '); - equals(statements[0].omit, undefined); + equals(body[0].omit, undefined); }); it('marks column 0 block mustaches as standalone', function() { var ast = Handlebars.parse('test\n{{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} '), - block = ast.statements[1]; + block = ast.body[1]; - equals(ast.statements[0].omit, undefined); + equals(ast.body[0].omit, undefined); - equals(block.program.statements[0].string, 'foo\n'); - equals(block.inverse.statements[0].string, ' bar \n'); + equals(block.program.body[0].string, 'foo\n'); + equals(block.inverse.body[0].string, ' bar \n'); - equals(ast.statements[2].string, ''); + equals(ast.body[2].string, ''); }); }); describe('partials', function() { it('marks partial as standalone', function() { var ast = Handlebars.parse('{{> partial }} '); - equals(ast.statements[1].string, ''); + equals(ast.body[1].string, ''); }); it('marks indented partial as standalone', function() { var ast = Handlebars.parse(' {{> partial }} '); - equals(ast.statements[0].string, ''); - equals(ast.statements[1].indent, ' '); - equals(ast.statements[2].string, ''); + equals(ast.body[0].string, ''); + equals(ast.body[1].indent, ' '); + equals(ast.body[2].string, ''); }); it('marks those around content as not standalone', function() { var ast = Handlebars.parse('a{{> partial }}'); - equals(ast.statements[0].omit, undefined); + equals(ast.body[0].omit, undefined); ast = Handlebars.parse('{{> partial }}a'); - equals(ast.statements[1].omit, undefined); + equals(ast.body[1].omit, undefined); }); }); describe('comments', function() { it('marks comment as standalone', function() { var ast = Handlebars.parse('{{! comment }} '); - equals(ast.statements[1].string, ''); + equals(ast.body[1].string, ''); }); it('marks indented comment as standalone', function() { var ast = Handlebars.parse(' {{! comment }} '); - equals(ast.statements[0].string, ''); - equals(ast.statements[2].string, ''); + equals(ast.body[0].string, ''); + equals(ast.body[2].string, ''); }); it('marks those around content as not standalone', function() { var ast = Handlebars.parse('a{{! comment }}'); - equals(ast.statements[0].omit, undefined); + equals(ast.body[0].omit, undefined); ast = Handlebars.parse('{{! comment }}a'); - equals(ast.statements[1].omit, undefined); + equals(ast.body[1].omit, undefined); }); }); }); diff --git a/src/handlebars.yy b/src/handlebars.yy index f5c69ff..27d12e5 100644 --- a/src/handlebars.yy +++ b/src/handlebars.yy @@ -5,7 +5,7 @@ %% root - : program EOF { yy.prepareProgram($1.statements, true); return $1; } + : program EOF { yy.prepareProgram($1.body, true); return $1; } ; program |