Update ProgramNode to better match SpiderMonkey
This commit is contained in:
@@ -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;
|
||||
},
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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--;
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user