"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spread = (this && this.__spread) || function () { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CallExpression = exports.Expression = void 0; var parser_1 = __importDefault(require("./parser")); var utils_1 = require("./utils"); var Expression = /** @class */ (function () { function Expression(start, end, expression) { if (start === void 0) { start = 0; } if (end === void 0) { end = 0; } if (expression === void 0) { expression = ''; } this.start = start; this.end = end; this.expression = expression; } return Expression; }()); exports.Expression = Expression; var CallExpression = /** @class */ (function (_super) { __extends(CallExpression, _super); function CallExpression(start, end, expression, functionNameStart, functionNameEnd, parameters, childFunctionExpressions) { if (start === void 0) { start = 0; } if (end === void 0) { end = 0; } if (expression === void 0) { expression = ''; } if (functionNameStart === void 0) { functionNameStart = 0; } if (functionNameEnd === void 0) { functionNameEnd = 0; } if (parameters === void 0) { parameters = ''; } if (childFunctionExpressions === void 0) { childFunctionExpressions = []; } var _this = _super.call(this, start, end, expression) || this; _this.functionNameStart = functionNameStart; _this.functionNameEnd = functionNameEnd; _this.parameters = parameters; _this.childFunctionExpressions = childFunctionExpressions; return _this; } return CallExpression; }(Expression)); exports.CallExpression = CallExpression; /** * ExpressionParser helps parsing expressions inside wxml interpolation block */ var ExpressionParser = /** @class */ (function (_super) { __extends(ExpressionParser, _super); function ExpressionParser(source, fileName) { if (fileName === void 0) { fileName = ''; } var _this = _super.call(this, source, fileName) || this; _this.source = source; _this.fileName = fileName; _this.blockStart = -1; _this.expressions = []; _this.callExpressions = []; return _this; } ExpressionParser.prototype.parse = function () { try { var expr = this._parse(); return expr; } catch (e) { if (this.fileName) { e.message += "\nfile: " + this.fileName; } e.message += "\nline: " + this.line + ", column: " + this.column + "\n\n" + this.currentContext(); throw e; } }; ExpressionParser.prototype._parse = function () { while (!this.eof()) { if (this.match(123 /* LEFT_CURLY_BRACE */) && this.match(123 /* LEFT_CURLY_BRACE */, this.pos + 1)) { this.advance(2); this.enterInterpolationBlock(); // TODO: parse function calls and pass it to transfomers this.parseInterpolationExpression(); continue; } this.advance(); } return { expression: this.expressions, callExpressions: this.callExpressions }; }; /** * Parse expressions in wxml, it only cares about function calls * and ignore other expressions since it's trivial for i18n */ ExpressionParser.prototype.parseInterpolationExpression = function () { while (!this.eof()) { this.consumeQuoteString(); if (this.match(125 /* RIGHT_CURLY_BRACE */) && this.match(125 /* RIGHT_CURLY_BRACE */, this.pos + 1)) { var _a = this.exitInterpolationBlock(), start = _a.start, end = _a.end, block = _a.block; this.advance(2); if (end > start && start !== -1) { this.expressions.push(new Expression(start, end, block)); } return; } // maybe function call expression if (this.match(40 /* LEFT_PAREN */)) { var start = this.isFunctionCallExpression(this.pos); if (start !== -1) { var exprs = this.parseFunctionCallExpression(start); this.callExpressions.push(exprs); continue; } } this.advance(); } }; ExpressionParser.prototype.parseObjectDecl = function () { var callFunctions = []; while (!this.eof()) { this.consumeQuoteString(); if (this.match(125 /* RIGHT_CURLY_BRACE */)) { this.advance(); return callFunctions; } if (this.match(40 /* LEFT_PAREN */)) { var start = this.isFunctionCallExpression(this.pos); if (start !== -1) { var expr = this.parseFunctionCallExpression(start); callFunctions.push(expr); } } if (this.match(123 /* LEFT_CURLY_BRACE */)) { this.advance(); callFunctions.push.apply(callFunctions, __spread(this.parseObjectDecl())); continue; } this.advance(); } return callFunctions; }; ExpressionParser.prototype.parseFunctionCallExpression = function (start) { var childFunctions = []; var functionNameEnd = this.pos; if (this.consumeChar() !== 40 /* LEFT_PAREN */) { throw new Error('expected a left paren for a function call'); } while (!this.eof()) { this.consumeQuoteString(); if (this.match(123 /* LEFT_CURLY_BRACE */)) { // JavaScript block should be ignored this.advance(); var expr = this.parseObjectDecl(); childFunctions.push.apply(childFunctions, __spread(expr)); } if (this.consumeChar() === 41 /* RIGHT_PAREN */) { break; } } return new CallExpression(start, this.pos, this.source.substring(start, functionNameEnd), start, functionNameEnd, this.source.substring(functionNameEnd + 1, this.pos - 1).trim(), childFunctions); }; ExpressionParser.prototype.enterInterpolationBlock = function () { // Already in an translation block, this must not be // valid translation block if (this.blockStart !== -1) return; this.blockStart = this.pos; }; ExpressionParser.prototype.exitInterpolationBlock = function () { var start = this.blockStart; var end = this.pos; var block = this.source.substring(start, end); this.blockStart = -1; return { start: start, end: end, block: block }; }; ExpressionParser.prototype.matchNextChar = function (code) { return this.source.charCodeAt(++this.pos) === code; }; ExpressionParser.prototype.isFunctionCallExpression = function (pos) { while (--pos >= 0) { // maybe wxs call {{ a.b() }} if (this.match(46 /* DOT */, pos)) return -1; if (!utils_1.isValidFunctionLiteralChar(this.source.charCodeAt(pos))) break; } return pos + 1; }; return ExpressionParser; }(parser_1.default)); exports.default = ExpressionParser;