1'use strict'; 2 3function _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, _toPropertyKey(descriptor.key), descriptor); } } 4function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } 5function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); } 6function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } 7function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } 8function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } 9var _require = require('./object'), 10 Obj = _require.Obj; 11function traverseAndCheck(obj, type, results) { 12 if (obj instanceof type) { 13 results.push(obj); 14 } 15 if (obj instanceof Node) { 16 obj.findAll(type, results); 17 } 18} 19var Node = /*#__PURE__*/function (_Obj) { 20 _inheritsLoose(Node, _Obj); 21 function Node() { 22 return _Obj.apply(this, arguments) || this; 23 } 24 var _proto = Node.prototype; 25 _proto.init = function init(lineno, colno) { 26 var _arguments = arguments, 27 _this = this; 28 for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { 29 args[_key - 2] = arguments[_key]; 30 } 31 this.lineno = lineno; 32 this.colno = colno; 33 this.fields.forEach(function (field, i) { 34 // The first two args are line/col numbers, so offset by 2 35 var val = _arguments[i + 2]; 36 37 // Fields should never be undefined, but null. It makes 38 // testing easier to normalize values. 39 if (val === undefined) { 40 val = null; 41 } 42 _this[field] = val; 43 }); 44 }; 45 _proto.findAll = function findAll(type, results) { 46 var _this2 = this; 47 results = results || []; 48 if (this instanceof NodeList) { 49 this.children.forEach(function (child) { 50 return traverseAndCheck(child, type, results); 51 }); 52 } else { 53 this.fields.forEach(function (field) { 54 return traverseAndCheck(_this2[field], type, results); 55 }); 56 } 57 return results; 58 }; 59 _proto.iterFields = function iterFields(func) { 60 var _this3 = this; 61 this.fields.forEach(function (field) { 62 func(_this3[field], field); 63 }); 64 }; 65 return Node; 66}(Obj); // Abstract nodes 67var Value = /*#__PURE__*/function (_Node) { 68 _inheritsLoose(Value, _Node); 69 function Value() { 70 return _Node.apply(this, arguments) || this; 71 } 72 _createClass(Value, [{ 73 key: "typename", 74 get: function get() { 75 return 'Value'; 76 } 77 }, { 78 key: "fields", 79 get: function get() { 80 return ['value']; 81 } 82 }]); 83 return Value; 84}(Node); // Concrete nodes 85var NodeList = /*#__PURE__*/function (_Node2) { 86 _inheritsLoose(NodeList, _Node2); 87 function NodeList() { 88 return _Node2.apply(this, arguments) || this; 89 } 90 var _proto2 = NodeList.prototype; 91 _proto2.init = function init(lineno, colno, nodes) { 92 _Node2.prototype.init.call(this, lineno, colno, nodes || []); 93 }; 94 _proto2.addChild = function addChild(node) { 95 this.children.push(node); 96 }; 97 _createClass(NodeList, [{ 98 key: "typename", 99 get: function get() { 100 return 'NodeList'; 101 } 102 }, { 103 key: "fields", 104 get: function get() { 105 return ['children']; 106 } 107 }]); 108 return NodeList; 109}(Node); 110var Root = NodeList.extend('Root'); 111var Literal = Value.extend('Literal'); 112var _Symbol = Value.extend('Symbol'); 113var Group = NodeList.extend('Group'); 114var ArrayNode = NodeList.extend('Array'); 115var Pair = Node.extend('Pair', { 116 fields: ['key', 'value'] 117}); 118var Dict = NodeList.extend('Dict'); 119var LookupVal = Node.extend('LookupVal', { 120 fields: ['target', 'val'] 121}); 122var If = Node.extend('If', { 123 fields: ['cond', 'body', 'else_'] 124}); 125var IfAsync = If.extend('IfAsync'); 126var InlineIf = Node.extend('InlineIf', { 127 fields: ['cond', 'body', 'else_'] 128}); 129var For = Node.extend('For', { 130 fields: ['arr', 'name', 'body', 'else_'] 131}); 132var AsyncEach = For.extend('AsyncEach'); 133var AsyncAll = For.extend('AsyncAll'); 134var Macro = Node.extend('Macro', { 135 fields: ['name', 'args', 'body'] 136}); 137var Caller = Macro.extend('Caller'); 138var Import = Node.extend('Import', { 139 fields: ['template', 'target', 'withContext'] 140}); 141var FromImport = /*#__PURE__*/function (_Node3) { 142 _inheritsLoose(FromImport, _Node3); 143 function FromImport() { 144 return _Node3.apply(this, arguments) || this; 145 } 146 var _proto3 = FromImport.prototype; 147 _proto3.init = function init(lineno, colno, template, names, withContext) { 148 _Node3.prototype.init.call(this, lineno, colno, template, names || new NodeList(), withContext); 149 }; 150 _createClass(FromImport, [{ 151 key: "typename", 152 get: function get() { 153 return 'FromImport'; 154 } 155 }, { 156 key: "fields", 157 get: function get() { 158 return ['template', 'names', 'withContext']; 159 } 160 }]); 161 return FromImport; 162}(Node); 163var FunCall = Node.extend('FunCall', { 164 fields: ['name', 'args'] 165}); 166var Filter = FunCall.extend('Filter'); 167var FilterAsync = Filter.extend('FilterAsync', { 168 fields: ['name', 'args', 'symbol'] 169}); 170var KeywordArgs = Dict.extend('KeywordArgs'); 171var Block = Node.extend('Block', { 172 fields: ['name', 'body'] 173}); 174var Super = Node.extend('Super', { 175 fields: ['blockName', 'symbol'] 176}); 177var TemplateRef = Node.extend('TemplateRef', { 178 fields: ['template'] 179}); 180var Extends = TemplateRef.extend('Extends'); 181var Include = Node.extend('Include', { 182 fields: ['template', 'ignoreMissing'] 183}); 184var Set = Node.extend('Set', { 185 fields: ['targets', 'value'] 186}); 187var Switch = Node.extend('Switch', { 188 fields: ['expr', 'cases', 'default'] 189}); 190var Case = Node.extend('Case', { 191 fields: ['cond', 'body'] 192}); 193var Output = NodeList.extend('Output'); 194var Capture = Node.extend('Capture', { 195 fields: ['body'] 196}); 197var TemplateData = Literal.extend('TemplateData'); 198var UnaryOp = Node.extend('UnaryOp', { 199 fields: ['target'] 200}); 201var BinOp = Node.extend('BinOp', { 202 fields: ['left', 'right'] 203}); 204var In = BinOp.extend('In'); 205var Is = BinOp.extend('Is'); 206var Or = BinOp.extend('Or'); 207var And = BinOp.extend('And'); 208var Not = UnaryOp.extend('Not'); 209var Add = BinOp.extend('Add'); 210var Concat = BinOp.extend('Concat'); 211var Sub = BinOp.extend('Sub'); 212var Mul = BinOp.extend('Mul'); 213var Div = BinOp.extend('Div'); 214var FloorDiv = BinOp.extend('FloorDiv'); 215var Mod = BinOp.extend('Mod'); 216var Pow = BinOp.extend('Pow'); 217var Neg = UnaryOp.extend('Neg'); 218var Pos = UnaryOp.extend('Pos'); 219var Compare = Node.extend('Compare', { 220 fields: ['expr', 'ops'] 221}); 222var CompareOperand = Node.extend('CompareOperand', { 223 fields: ['expr', 'type'] 224}); 225var CallExtension = Node.extend('CallExtension', { 226 init: function init(ext, prop, args, contentArgs) { 227 this.parent(); 228 this.extName = ext.__name || ext; 229 this.prop = prop; 230 this.args = args || new NodeList(); 231 this.contentArgs = contentArgs || []; 232 this.autoescape = ext.autoescape; 233 }, 234 fields: ['extName', 'prop', 'args', 'contentArgs'] 235}); 236var CallExtensionAsync = CallExtension.extend('CallExtensionAsync'); 237 238// This is hacky, but this is just a debugging function anyway 239function print(str, indent, inline) { 240 var lines = str.split('\n'); 241 lines.forEach(function (line, i) { 242 if (line && (inline && i > 0 || !inline)) { 243 process.stdout.write(' '.repeat(indent)); 244 } 245 var nl = i === lines.length - 1 ? '' : '\n'; 246 process.stdout.write("" + line + nl); 247 }); 248} 249 250// Print the AST in a nicely formatted tree format for debuggin 251function printNodes(node, indent) { 252 indent = indent || 0; 253 print(node.typename + ': ', indent); 254 if (node instanceof NodeList) { 255 print('\n'); 256 node.children.forEach(function (n) { 257 printNodes(n, indent + 2); 258 }); 259 } else if (node instanceof CallExtension) { 260 print(node.extName + "." + node.prop + "\n"); 261 if (node.args) { 262 printNodes(node.args, indent + 2); 263 } 264 if (node.contentArgs) { 265 node.contentArgs.forEach(function (n) { 266 printNodes(n, indent + 2); 267 }); 268 } 269 } else { 270 var nodes = []; 271 var props = null; 272 node.iterFields(function (val, fieldName) { 273 if (val instanceof Node) { 274 nodes.push([fieldName, val]); 275 } else { 276 props = props || {}; 277 props[fieldName] = val; 278 } 279 }); 280 if (props) { 281 print(JSON.stringify(props, null, 2) + '\n', null, true); 282 } else { 283 print('\n'); 284 } 285 nodes.forEach(function (_ref) { 286 var fieldName = _ref[0], 287 n = _ref[1]; 288 print("[" + fieldName + "] =>", indent + 2); 289 printNodes(n, indent + 4); 290 }); 291 } 292} 293module.exports = { 294 Node: Node, 295 Root: Root, 296 NodeList: NodeList, 297 Value: Value, 298 Literal: Literal, 299 Symbol: _Symbol, 300 Group: Group, 301 Array: ArrayNode, 302 Pair: Pair, 303 Dict: Dict, 304 Output: Output, 305 Capture: Capture, 306 TemplateData: TemplateData, 307 If: If, 308 IfAsync: IfAsync, 309 InlineIf: InlineIf, 310 For: For, 311 AsyncEach: AsyncEach, 312 AsyncAll: AsyncAll, 313 Macro: Macro, 314 Caller: Caller, 315 Import: Import, 316 FromImport: FromImport, 317 FunCall: FunCall, 318 Filter: Filter, 319 FilterAsync: FilterAsync, 320 KeywordArgs: KeywordArgs, 321 Block: Block, 322 Super: Super, 323 Extends: Extends, 324 Include: Include, 325 Set: Set, 326 Switch: Switch, 327 Case: Case, 328 LookupVal: LookupVal, 329 BinOp: BinOp, 330 In: In, 331 Is: Is, 332 Or: Or, 333 And: And, 334 Not: Not, 335 Add: Add, 336 Concat: Concat, 337 Sub: Sub, 338 Mul: Mul, 339 Div: Div, 340 FloorDiv: FloorDiv, 341 Mod: Mod, 342 Pow: Pow, 343 Neg: Neg, 344 Pos: Pos, 345 Compare: Compare, 346 CompareOperand: CompareOperand, 347 CallExtension: CallExtension, 348 CallExtensionAsync: CallExtensionAsync, 349 printNodes: printNodes 350};