Skip to content

Commit

Permalink
Update statement node ASTs
Browse files Browse the repository at this point in the history
  • Loading branch information
kpdecker committed Nov 27, 2014
1 parent 5cfe6a0 commit 2a4819d
Show file tree
Hide file tree
Showing 10 changed files with 179 additions and 199 deletions.
81 changes: 35 additions & 46 deletions lib/handlebars/compiler/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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";
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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;
}
};

Expand Down
99 changes: 50 additions & 49 deletions lib/handlebars/compiler/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -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);

Expand All @@ -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],
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 });
Expand Down Expand Up @@ -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
Expand All @@ -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);
}
Expand Down
22 changes: 11 additions & 11 deletions lib/handlebars/compiler/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
Expand Down Expand Up @@ -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);
}
}
Expand All @@ -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);
}
}
Expand All @@ -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.
Expand All @@ -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;
}
Loading

0 comments on commit 2a4819d

Please sign in to comment.