diff options
Diffstat (limited to 'lib/handlebars/compiler/ast.js')
-rw-r--r-- | lib/handlebars/compiler/ast.js | 222 |
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; } }; |