884bf15536
This allows us to avoid creating unnecessary AST nodes and avoids things like isHelper. Side effect of these changes is that @data functions can now have data parameters passed to them.
117 lines
3.1 KiB
JavaScript
117 lines
3.1 KiB
JavaScript
import Exception from "../exception";
|
|
|
|
export function SourceLocation(source, locInfo) {
|
|
this.source = source;
|
|
this.start = {
|
|
line: locInfo.first_line,
|
|
column: locInfo.first_column
|
|
};
|
|
this.end = {
|
|
line: locInfo.last_line,
|
|
column: locInfo.last_column
|
|
};
|
|
}
|
|
|
|
export function stripFlags(open, close) {
|
|
return {
|
|
open: open.charAt(2) === '~',
|
|
close: close.charAt(close.length-3) === '~'
|
|
};
|
|
}
|
|
|
|
export function stripComment(comment) {
|
|
return comment.replace(/^\{\{~?\!-?-?/, '')
|
|
.replace(/-?-?~?\}\}$/, '');
|
|
}
|
|
|
|
export function preparePath(data, parts, locInfo) {
|
|
/*jshint -W040 */
|
|
locInfo = this.locInfo(locInfo);
|
|
|
|
var original = data ? '@' : '',
|
|
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, {loc: locInfo});
|
|
} else if (part === '..') {
|
|
depth++;
|
|
depthString += '../';
|
|
}
|
|
} else {
|
|
dig.push(part);
|
|
}
|
|
}
|
|
|
|
return new this.PathExpression(data, depth, dig, original, locInfo);
|
|
}
|
|
|
|
export function prepareMustache(path, params, hash, open, strip, locInfo) {
|
|
/*jshint -W040 */
|
|
// Must use charAt to support IE pre-10
|
|
var escapeFlag = open.charAt(3) || open.charAt(2),
|
|
escaped = escapeFlag !== '{' && escapeFlag !== '&';
|
|
|
|
return new this.MustacheStatement(path, params, hash, escaped, strip, this.locInfo(locInfo));
|
|
}
|
|
|
|
export function prepareRawBlock(openRawBlock, content, close, locInfo) {
|
|
/*jshint -W040 */
|
|
if (openRawBlock.path.original !== close) {
|
|
var errorNode = {loc: openRawBlock.path.loc};
|
|
|
|
throw new Exception(openRawBlock.path.original + " doesn't match " + close, errorNode);
|
|
}
|
|
|
|
locInfo = this.locInfo(locInfo);
|
|
var program = new this.Program([content], null, {}, locInfo);
|
|
|
|
return new this.BlockStatement(
|
|
openRawBlock.path, openRawBlock.params, openRawBlock.hash,
|
|
program, undefined,
|
|
{}, {}, {},
|
|
locInfo);
|
|
}
|
|
|
|
export function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) {
|
|
/*jshint -W040 */
|
|
// When we are chaining inverse calls, we will not have a close path
|
|
if (close && close.path && openBlock.path.original !== close.path.original) {
|
|
var errorNode = {loc: openBlock.path.loc};
|
|
|
|
throw new Exception(openBlock.path.original + ' doesn\'t match ' + close.path.original, errorNode);
|
|
}
|
|
|
|
program.blockParams = openBlock.blockParams;
|
|
|
|
var inverse,
|
|
inverseStrip;
|
|
|
|
if (inverseAndProgram) {
|
|
if (inverseAndProgram.chain) {
|
|
inverseAndProgram.program.body[0].closeStrip = close.strip;
|
|
}
|
|
|
|
inverseStrip = inverseAndProgram.strip;
|
|
inverse = inverseAndProgram.program;
|
|
}
|
|
|
|
if (inverted) {
|
|
inverted = inverse;
|
|
inverse = program;
|
|
program = inverted;
|
|
}
|
|
|
|
return new this.BlockStatement(
|
|
openBlock.path, openBlock.params, openBlock.hash,
|
|
program, inverse,
|
|
openBlock.strip, inverseStrip, close && close.strip,
|
|
this.locInfo(locInfo));
|
|
}
|