'use strict';
|
|
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
|
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
|
|
var _require = require('./object'),
|
Obj = _require.Obj;
|
|
function traverseAndCheck(obj, type, results) {
|
if (obj instanceof type) {
|
results.push(obj);
|
}
|
|
if (obj instanceof Node) {
|
obj.findAll(type, results);
|
}
|
}
|
|
var Node =
|
/*#__PURE__*/
|
function (_Obj) {
|
_inheritsLoose(Node, _Obj);
|
|
function Node() {
|
return _Obj.apply(this, arguments) || this;
|
}
|
|
var _proto = Node.prototype;
|
|
_proto.init = function init(lineno, colno) {
|
var _this = this,
|
_arguments = arguments;
|
|
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
args[_key - 2] = arguments[_key];
|
}
|
|
this.lineno = lineno;
|
this.colno = colno;
|
this.fields.forEach(function (field, i) {
|
// The first two args are line/col numbers, so offset by 2
|
var val = _arguments[i + 2]; // Fields should never be undefined, but null. It makes
|
// testing easier to normalize values.
|
|
if (val === undefined) {
|
val = null;
|
}
|
|
_this[field] = val;
|
});
|
};
|
|
_proto.findAll = function findAll(type, results) {
|
var _this2 = this;
|
|
results = results || [];
|
|
if (this instanceof NodeList) {
|
this.children.forEach(function (child) {
|
return traverseAndCheck(child, type, results);
|
});
|
} else {
|
this.fields.forEach(function (field) {
|
return traverseAndCheck(_this2[field], type, results);
|
});
|
}
|
|
return results;
|
};
|
|
_proto.iterFields = function iterFields(func) {
|
var _this3 = this;
|
|
this.fields.forEach(function (field) {
|
func(_this3[field], field);
|
});
|
};
|
|
return Node;
|
}(Obj); // Abstract nodes
|
|
|
var Value =
|
/*#__PURE__*/
|
function (_Node) {
|
_inheritsLoose(Value, _Node);
|
|
function Value() {
|
return _Node.apply(this, arguments) || this;
|
}
|
|
_createClass(Value, [{
|
key: "typename",
|
get: function get() {
|
return 'Value';
|
}
|
}, {
|
key: "fields",
|
get: function get() {
|
return ['value'];
|
}
|
}]);
|
|
return Value;
|
}(Node); // Concrete nodes
|
|
|
var NodeList =
|
/*#__PURE__*/
|
function (_Node2) {
|
_inheritsLoose(NodeList, _Node2);
|
|
function NodeList() {
|
return _Node2.apply(this, arguments) || this;
|
}
|
|
var _proto2 = NodeList.prototype;
|
|
_proto2.init = function init(lineno, colno, nodes) {
|
_Node2.prototype.init.call(this, lineno, colno, nodes || []);
|
};
|
|
_proto2.addChild = function addChild(node) {
|
this.children.push(node);
|
};
|
|
_createClass(NodeList, [{
|
key: "typename",
|
get: function get() {
|
return 'NodeList';
|
}
|
}, {
|
key: "fields",
|
get: function get() {
|
return ['children'];
|
}
|
}]);
|
|
return NodeList;
|
}(Node);
|
|
var Root = NodeList.extend('Root');
|
var Literal = Value.extend('Literal');
|
var Symbol = Value.extend('Symbol');
|
var Group = NodeList.extend('Group');
|
var ArrayNode = NodeList.extend('Array');
|
var Pair = Node.extend('Pair', {
|
fields: ['key', 'value']
|
});
|
var Dict = NodeList.extend('Dict');
|
var LookupVal = Node.extend('LookupVal', {
|
fields: ['target', 'val']
|
});
|
var If = Node.extend('If', {
|
fields: ['cond', 'body', 'else_']
|
});
|
var IfAsync = If.extend('IfAsync');
|
var InlineIf = Node.extend('InlineIf', {
|
fields: ['cond', 'body', 'else_']
|
});
|
var For = Node.extend('For', {
|
fields: ['arr', 'name', 'body', 'else_']
|
});
|
var AsyncEach = For.extend('AsyncEach');
|
var AsyncAll = For.extend('AsyncAll');
|
var Macro = Node.extend('Macro', {
|
fields: ['name', 'args', 'body']
|
});
|
var Caller = Macro.extend('Caller');
|
var Import = Node.extend('Import', {
|
fields: ['template', 'target', 'withContext']
|
});
|
|
var FromImport =
|
/*#__PURE__*/
|
function (_Node3) {
|
_inheritsLoose(FromImport, _Node3);
|
|
function FromImport() {
|
return _Node3.apply(this, arguments) || this;
|
}
|
|
var _proto3 = FromImport.prototype;
|
|
_proto3.init = function init(lineno, colno, template, names, withContext) {
|
_Node3.prototype.init.call(this, lineno, colno, template, names || new NodeList(), withContext);
|
};
|
|
_createClass(FromImport, [{
|
key: "typename",
|
get: function get() {
|
return 'FromImport';
|
}
|
}, {
|
key: "fields",
|
get: function get() {
|
return ['template', 'names', 'withContext'];
|
}
|
}]);
|
|
return FromImport;
|
}(Node);
|
|
var FunCall = Node.extend('FunCall', {
|
fields: ['name', 'args']
|
});
|
var Filter = FunCall.extend('Filter');
|
var FilterAsync = Filter.extend('FilterAsync', {
|
fields: ['name', 'args', 'symbol']
|
});
|
var KeywordArgs = Dict.extend('KeywordArgs');
|
var Block = Node.extend('Block', {
|
fields: ['name', 'body']
|
});
|
var Super = Node.extend('Super', {
|
fields: ['blockName', 'symbol']
|
});
|
var TemplateRef = Node.extend('TemplateRef', {
|
fields: ['template']
|
});
|
var Extends = TemplateRef.extend('Extends');
|
var Include = Node.extend('Include', {
|
fields: ['template', 'ignoreMissing']
|
});
|
var Set = Node.extend('Set', {
|
fields: ['targets', 'value']
|
});
|
var Switch = Node.extend('Switch', {
|
fields: ['expr', 'cases', 'default']
|
});
|
var Case = Node.extend('Case', {
|
fields: ['cond', 'body']
|
});
|
var Output = NodeList.extend('Output');
|
var Capture = Node.extend('Capture', {
|
fields: ['body']
|
});
|
var TemplateData = Literal.extend('TemplateData');
|
var UnaryOp = Node.extend('UnaryOp', {
|
fields: ['target']
|
});
|
var BinOp = Node.extend('BinOp', {
|
fields: ['left', 'right']
|
});
|
var In = BinOp.extend('In');
|
var Is = BinOp.extend('Is');
|
var Or = BinOp.extend('Or');
|
var And = BinOp.extend('And');
|
var Not = UnaryOp.extend('Not');
|
var Add = BinOp.extend('Add');
|
var Concat = BinOp.extend('Concat');
|
var Sub = BinOp.extend('Sub');
|
var Mul = BinOp.extend('Mul');
|
var Div = BinOp.extend('Div');
|
var FloorDiv = BinOp.extend('FloorDiv');
|
var Mod = BinOp.extend('Mod');
|
var Pow = BinOp.extend('Pow');
|
var Neg = UnaryOp.extend('Neg');
|
var Pos = UnaryOp.extend('Pos');
|
var Compare = Node.extend('Compare', {
|
fields: ['expr', 'ops']
|
});
|
var CompareOperand = Node.extend('CompareOperand', {
|
fields: ['expr', 'type']
|
});
|
var CallExtension = Node.extend('CallExtension', {
|
init: function init(ext, prop, args, contentArgs) {
|
this.parent();
|
this.extName = ext.__name || ext;
|
this.prop = prop;
|
this.args = args || new NodeList();
|
this.contentArgs = contentArgs || [];
|
this.autoescape = ext.autoescape;
|
},
|
fields: ['extName', 'prop', 'args', 'contentArgs']
|
});
|
var CallExtensionAsync = CallExtension.extend('CallExtensionAsync'); // This is hacky, but this is just a debugging function anyway
|
|
function print(str, indent, inline) {
|
var lines = str.split('\n');
|
lines.forEach(function (line, i) {
|
if (line && (inline && i > 0 || !inline)) {
|
process.stdout.write(' '.repeat(indent));
|
}
|
|
var nl = i === lines.length - 1 ? '' : '\n';
|
process.stdout.write("" + line + nl);
|
});
|
} // Print the AST in a nicely formatted tree format for debuggin
|
|
|
function printNodes(node, indent) {
|
indent = indent || 0;
|
print(node.typename + ': ', indent);
|
|
if (node instanceof NodeList) {
|
print('\n');
|
node.children.forEach(function (n) {
|
printNodes(n, indent + 2);
|
});
|
} else if (node instanceof CallExtension) {
|
print(node.extName + "." + node.prop + "\n");
|
|
if (node.args) {
|
printNodes(node.args, indent + 2);
|
}
|
|
if (node.contentArgs) {
|
node.contentArgs.forEach(function (n) {
|
printNodes(n, indent + 2);
|
});
|
}
|
} else {
|
var nodes = [];
|
var props = null;
|
node.iterFields(function (val, fieldName) {
|
if (val instanceof Node) {
|
nodes.push([fieldName, val]);
|
} else {
|
props = props || {};
|
props[fieldName] = val;
|
}
|
});
|
|
if (props) {
|
print(JSON.stringify(props, null, 2) + '\n', null, true);
|
} else {
|
print('\n');
|
}
|
|
nodes.forEach(function (_ref) {
|
var fieldName = _ref[0],
|
n = _ref[1];
|
print("[" + fieldName + "] =>", indent + 2);
|
printNodes(n, indent + 4);
|
});
|
}
|
}
|
|
module.exports = {
|
Node: Node,
|
Root: Root,
|
NodeList: NodeList,
|
Value: Value,
|
Literal: Literal,
|
Symbol: Symbol,
|
Group: Group,
|
Array: ArrayNode,
|
Pair: Pair,
|
Dict: Dict,
|
Output: Output,
|
Capture: Capture,
|
TemplateData: TemplateData,
|
If: If,
|
IfAsync: IfAsync,
|
InlineIf: InlineIf,
|
For: For,
|
AsyncEach: AsyncEach,
|
AsyncAll: AsyncAll,
|
Macro: Macro,
|
Caller: Caller,
|
Import: Import,
|
FromImport: FromImport,
|
FunCall: FunCall,
|
Filter: Filter,
|
FilterAsync: FilterAsync,
|
KeywordArgs: KeywordArgs,
|
Block: Block,
|
Super: Super,
|
Extends: Extends,
|
Include: Include,
|
Set: Set,
|
Switch: Switch,
|
Case: Case,
|
LookupVal: LookupVal,
|
BinOp: BinOp,
|
In: In,
|
Is: Is,
|
Or: Or,
|
And: And,
|
Not: Not,
|
Add: Add,
|
Concat: Concat,
|
Sub: Sub,
|
Mul: Mul,
|
Div: Div,
|
FloorDiv: FloorDiv,
|
Mod: Mod,
|
Pow: Pow,
|
Neg: Neg,
|
Pos: Pos,
|
Compare: Compare,
|
CompareOperand: CompareOperand,
|
CallExtension: CallExtension,
|
CallExtensionAsync: CallExtensionAsync,
|
printNodes: printNodes
|
};
|