expression-language
Version:
Javascript implementation of symfony/expression-language
149 lines (146 loc) • 5.58 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _Node = _interopRequireDefault(require("./Node"));
var _range = require("../lib/range");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
class BinaryNode extends _Node.default {
constructor(_operator, _left, _right) {
super({
left: _left,
right: _right
}, {
operator: _operator
});
_defineProperty(this, "compile", compiler => {
let operator = this.attributes.operator;
if ('matches' === operator) {
compiler.compile(this.nodes.right).raw(".test(").compile(this.nodes.left).raw(")");
return;
} else if ('contains' === operator) {
compiler.raw('(').compile(this.nodes.left).raw(".toString().toLowerCase().includes(").compile(this.nodes.right).raw(".toString().toLowerCase())");
return;
} else if ('starts with' === operator) {
compiler.raw('(').compile(this.nodes.left).raw(".toString().toLowerCase().startsWith(").compile(this.nodes.right).raw(".toString().toLowerCase())");
return;
} else if ('ends with' === operator) {
compiler.raw('(').compile(this.nodes.left).raw(".toString().toLowerCase().endsWith(").compile(this.nodes.right).raw(".toString().toLowerCase())");
return;
}
if (BinaryNode.functions[operator] !== undefined) {
compiler.raw(`${BinaryNode.functions[operator]}(`).compile(this.nodes.left).raw(", ").compile(this.nodes.right).raw(")");
return;
}
if (BinaryNode.operators[operator] !== undefined) {
operator = BinaryNode.operators[operator];
}
compiler.raw("(").compile(this.nodes.left).raw(' ').raw(operator).raw(' ').compile(this.nodes.right).raw(")");
});
_defineProperty(this, "evaluate", (functions, values) => {
let operator = this.attributes.operator,
left = this.nodes.left.evaluate(functions, values);
//console.log("Evaluating: ", left, operator, right);
if (BinaryNode.functions[operator] !== undefined) {
let right = this.nodes.right.evaluate(functions, values);
switch (operator) {
case 'not in':
return right.indexOf(left) === -1;
case 'in':
return right.indexOf(left) >= 0;
case '..':
return (0, _range.range)(left, right);
case '**':
return Math.pow(left, right);
}
}
let right = null;
switch (operator) {
case 'or':
case '||':
if (!left) {
right = this.nodes.right.evaluate(functions, values);
}
return left || right;
case 'and':
case '&&':
if (left) {
right = this.nodes.right.evaluate(functions, values);
}
return left && right;
}
right = this.nodes.right.evaluate(functions, values);
switch (operator) {
case '|':
return left | right;
case '^':
return left ^ right;
case '&':
return left & right;
case '==':
return left == right;
case '===':
return left === right;
case '!=':
return left != right;
case '!==':
return left !== right;
case '<':
return left < right;
case '>':
return left > right;
case '>=':
return left >= right;
case '<=':
return left <= right;
case 'not in':
return right.indexOf(left) === -1;
case 'in':
return right.indexOf(left) >= 0;
case '+':
return left + right;
case '-':
return left - right;
case '~':
return left.toString() + right.toString();
case '*':
return left * right;
case '/':
return left / right;
case '%':
return left % right;
case 'matches':
let res = right.match(BinaryNode.regex_expression);
let regexp = new RegExp(res[1], res[2]);
return regexp.test(left);
case 'contains':
return left.toString().toLowerCase().includes(right.toString().toLowerCase());
case 'starts with':
return left.toString().toLowerCase().startsWith(right.toString().toLowerCase());
case 'ends with':
return left.toString().toLowerCase().endsWith(right.toString().toLowerCase());
}
});
this.name = "BinaryNode";
}
toArray() {
return ["(", this.nodes.left, ' ' + this.attributes.operator + ' ', this.nodes.right, ")"];
}
}
exports.default = BinaryNode;
_defineProperty(BinaryNode, "regex_expression", /\/(.+)\/(.*)/);
_defineProperty(BinaryNode, "operators", {
'~': '.',
'and': '&&',
'or': '||'
});
_defineProperty(BinaryNode, "functions", {
'**': 'Math.pow',
'..': 'range',
'in': 'includes',
'not in': '!includes'
});