summaryrefslogtreecommitdiffstats
path: root/lib/handlebars/compiler/ast.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/handlebars/compiler/ast.js')
-rw-r--r--lib/handlebars/compiler/ast.js222
1 files changed, 69 insertions, 153 deletions
diff --git a/lib/handlebars/compiler/ast.js b/lib/handlebars/compiler/ast.js
index 0bc70e9..72a56aa 100644
--- a/lib/handlebars/compiler/ast.js
+++ b/lib/handlebars/compiler/ast.js
@@ -1,195 +1,111 @@
import Exception from "../exception";
-function LocationInfo(locInfo) {
- locInfo = locInfo || {};
- this.firstLine = locInfo.first_line;
- this.firstColumn = locInfo.first_column;
- this.lastColumn = locInfo.last_column;
- this.lastLine = locInfo.last_line;
-}
-
var AST = {
- ProgramNode: function(statements, blockParams, strip, locInfo) {
- LocationInfo.call(this, locInfo);
- this.type = "program";
- this.statements = statements;
+ Program: function(statements, blockParams, strip, locInfo) {
+ this.loc = locInfo;
+ this.type = 'Program';
+ this.body = statements;
+
this.blockParams = blockParams;
this.strip = strip;
},
- MustacheNode: function(rawParams, hash, open, strip, locInfo) {
- LocationInfo.call(this, locInfo);
- this.type = "mustache";
- this.strip = strip;
-
- // Open may be a string parsed from the parser or a passed boolean flag
- if (open != null && open.charAt) {
- // Must use charAt to support IE pre-10
- var escapeFlag = open.charAt(3) || open.charAt(2);
- this.escaped = escapeFlag !== '{' && escapeFlag !== '&';
- } else {
- this.escaped = !!open;
- }
-
- if (rawParams instanceof AST.SexprNode) {
- this.sexpr = rawParams;
- } else {
- // Support old AST API
- this.sexpr = new AST.SexprNode(rawParams, hash);
- }
-
- // Support old AST API that stored this info in MustacheNode
- this.id = this.sexpr.id;
- this.params = this.sexpr.params;
- this.hash = this.sexpr.hash;
- this.eligibleHelper = this.sexpr.eligibleHelper;
- this.isHelper = this.sexpr.isHelper;
- },
-
- SexprNode: function(rawParams, hash, locInfo) {
- LocationInfo.call(this, locInfo);
-
- this.type = "sexpr";
- this.hash = hash;
-
- var id = this.id = rawParams[0];
- var params = this.params = rawParams.slice(1);
+ MustacheStatement: function(sexpr, escaped, strip, locInfo) {
+ this.loc = locInfo;
+ this.type = 'MustacheStatement';
- // a mustache is definitely a helper if:
- // * it is an eligible helper, and
- // * it has at least one parameter or hash segment
- this.isHelper = !!(params.length || hash);
-
- // a mustache is an eligible helper if:
- // * its id is simple (a single part, not `this` or `..`)
- this.eligibleHelper = this.isHelper || id.isSimple;
-
- // if a mustache is an eligible helper but not a definite
- // helper, it is ambiguous, and will be resolved in a later
- // pass or at runtime.
- },
+ this.sexpr = sexpr;
+ this.escaped = escaped;
- PartialNode: function(partialName, context, hash, strip, locInfo) {
- LocationInfo.call(this, 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) {
- LocationInfo.call(this, locInfo);
+ BlockStatement: function(sexpr, program, inverse, openStrip, inverseStrip, closeStrip, locInfo) {
+ this.loc = locInfo;
- this.type = 'block';
+ this.type = 'BlockStatement';
this.sexpr = sexpr;
this.program = program;
this.inverse = inverse;
- this.strip = strip;
- if (inverse && !program) {
- this.isInverse = true;
- }
+ this.openStrip = openStrip;
+ this.inverseStrip = inverseStrip;
+ this.closeStrip = closeStrip;
},
- ContentNode: function(string, locInfo) {
- LocationInfo.call(this, locInfo);
- this.type = "content";
- this.original = this.string = string;
+ PartialStatement: function(sexpr, strip, locInfo) {
+ this.loc = locInfo;
+ this.type = 'PartialStatement';
+ this.sexpr = sexpr;
+ this.indent = '';
+
+ this.strip = strip;
},
- HashNode: function(pairs, locInfo) {
- LocationInfo.call(this, locInfo);
- this.type = "hash";
- this.pairs = pairs;
+ ContentStatement: function(string, locInfo) {
+ this.loc = locInfo;
+ this.type = 'ContentStatement';
+ this.original = this.value = string;
},
- IdNode: function(parts, locInfo) {
- LocationInfo.call(this, locInfo);
- this.type = "ID";
-
- var original = "",
- dig = [],
- depth = 0,
- depthString = '';
-
- for(var i=0,l=parts.length; i<l; i++) {
- var part = parts[i].part;
- original += (parts[i].separator || '') + part;
-
- if (part === ".." || part === "." || part === "this") {
- if (dig.length > 0) {
- throw new Exception("Invalid path: " + original, this);
- } else if (part === "..") {
- depth++;
- depthString += '../';
- } else {
- this.isScoped = true;
- }
- } else {
- dig.push(part);
- }
- }
+ CommentStatement: function(comment, strip, locInfo) {
+ this.loc = locInfo;
+ this.type = 'CommentStatement';
+ this.value = comment;
- this.original = original;
- this.parts = dig;
- this.string = dig.join('.');
- this.depth = depth;
- this.idName = depthString + this.string;
+ this.strip = strip;
+ },
- // 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;
+ SubExpression: function(path, params, hash, locInfo) {
+ this.loc = locInfo;
- this.stringModeValue = this.string;
+ this.type = 'SubExpression';
+ this.path = path;
+ this.params = params || [];
+ this.hash = hash;
},
- PartialNameNode: function(name, locInfo) {
- LocationInfo.call(this, locInfo);
- this.type = "PARTIAL_NAME";
- this.name = name.original;
- },
+ PathExpression: function(data, depth, parts, original, locInfo) {
+ this.loc = locInfo;
+ this.type = 'PathExpression';
- DataNode: function(id, locInfo) {
- LocationInfo.call(this, locInfo);
- this.type = "DATA";
- this.id = id;
- this.stringModeValue = id.stringModeValue;
- this.idName = '@' + id.stringModeValue;
+ this.data = data;
+ this.original = original;
+ this.parts = parts;
+ this.depth = depth;
},
- StringNode: function(string, locInfo) {
- LocationInfo.call(this, locInfo);
- this.type = "STRING";
+ StringLiteral: function(string, locInfo) {
+ this.loc = locInfo;
+ this.type = 'StringLiteral';
this.original =
- this.string =
- this.stringModeValue = string;
+ this.value = string;
},
- NumberNode: function(number, locInfo) {
- LocationInfo.call(this, locInfo);
- this.type = "NUMBER";
+ NumberLiteral: function(number, locInfo) {
+ this.loc = locInfo;
+ this.type = 'NumberLiteral';
this.original =
- this.number = number;
- this.stringModeValue = Number(number);
+ this.value = Number(number);
},
- BooleanNode: function(bool, locInfo) {
- LocationInfo.call(this, locInfo);
- this.type = "BOOLEAN";
- this.bool = bool;
- this.stringModeValue = bool === "true";
+ BooleanLiteral: function(bool, locInfo) {
+ this.loc = locInfo;
+ this.type = 'BooleanLiteral';
+ this.original =
+ this.value = bool === 'true';
},
- CommentNode: function(comment, strip, locInfo) {
- LocationInfo.call(this, locInfo);
- this.type = "comment";
- this.comment = comment;
-
- this.strip = strip;
- strip.inlineStandalone = true;
+ Hash: function(pairs, locInfo) {
+ this.loc = locInfo;
+ this.type = 'Hash';
+ this.pairs = pairs;
+ },
+ HashPair: function(key, value, locInfo) {
+ this.loc = locInfo;
+ this.type = 'HashPair';
+ this.key = key;
+ this.value = value;
}
};