150 lines
4.0 KiB
JavaScript
150 lines
4.0 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 id(token) {
|
|
if (/^\[.*\]$/.test(token)) {
|
|
return token.substr(1, token.length - 2);
|
|
} else {
|
|
return token;
|
|
}
|
|
}
|
|
|
|
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) {
|
|
locInfo = this.locInfo(locInfo);
|
|
|
|
let original = data ? '@' : '',
|
|
dig = [],
|
|
depth = 0,
|
|
depthString = '';
|
|
|
|
for (let i = 0, l = parts.length; i < l; i++) {
|
|
let part = parts[i].part,
|
|
// If we have [] syntax then we do not treat path references as operators,
|
|
// i.e. foo.[this] resolves to approximately context.foo['this']
|
|
isLiteral = parts[i].original !== part;
|
|
original += (parts[i].separator || '') + part;
|
|
|
|
if (!isLiteral && (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) {
|
|
// Must use charAt to support IE pre-10
|
|
let 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, contents, close, locInfo) {
|
|
if (openRawBlock.path.original !== close) {
|
|
let errorNode = {loc: openRawBlock.path.loc};
|
|
|
|
throw new Exception(openRawBlock.path.original + " doesn't match " + close, errorNode);
|
|
}
|
|
|
|
locInfo = this.locInfo(locInfo);
|
|
let program = new this.Program(contents, null, {}, locInfo);
|
|
|
|
return new this.BlockStatement(
|
|
openRawBlock.path, openRawBlock.params, openRawBlock.hash,
|
|
program, undefined,
|
|
{}, {}, {},
|
|
locInfo);
|
|
}
|
|
|
|
export function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) {
|
|
// When we are chaining inverse calls, we will not have a close path
|
|
if (close && close.path && openBlock.path.original !== close.path.original) {
|
|
let errorNode = {loc: openBlock.path.loc};
|
|
|
|
throw new Exception(openBlock.path.original + ' doesn\'t match ' + close.path.original, errorNode);
|
|
}
|
|
|
|
program.blockParams = openBlock.blockParams;
|
|
|
|
let 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));
|
|
}
|
|
|
|
export function prepareProgram(statements, loc) {
|
|
if (!loc && statements.length) {
|
|
const firstLoc = statements[0].loc,
|
|
lastLoc = statements[statements.length - 1].loc;
|
|
|
|
/* istanbul ignore else */
|
|
if (firstLoc && lastLoc) {
|
|
loc = {
|
|
source: firstLoc.source,
|
|
start: {
|
|
line: firstLoc.start.line,
|
|
column: firstLoc.start.column
|
|
},
|
|
end: {
|
|
line: lastLoc.end.line,
|
|
column: lastLoc.end.column
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
return new this.Program(statements, null, {}, loc);
|
|
}
|
|
|
|
|