UNPKG

@adguard/agtree

Version:
93 lines (90 loc) 3.48 kB
/* * AGTree v3.4.3 (build date: Thu, 11 Dec 2025 13:43:19 GMT) * (c) 2025 Adguard Software Ltd. * Released under the MIT license * https://github.com/AdguardTeam/tsurlfilter/tree/master/packages/agtree#readme */ import { OperatorValue } from '../nodes/index.js'; import { NodeType } from '../parser/misc/logical-expression-parser.js'; /** * @file Utility functions for logical expression node. */ const ERROR_PREFIX = { UNEXPECTED_NODE_TYPE: 'Unexpected node type', UNEXPECTED_OPERATOR: 'Unexpected operator', }; /** * Utility functions for logical expression node. */ class LogicalExpressionUtils { /** * Get all variables in the expression. * * @param node Logical expression node * @returns List of variables in the expression (nodes) * @example * If the expression is `a && b || c`, the returned list will be * nodes for `a`, `b`, and `c`. */ static getVariables(node) { if (node.type === NodeType.Variable) { return [node]; } if (node.type === NodeType.Operator) { const leftVars = LogicalExpressionUtils.getVariables(node.left); const rightVars = node.right ? LogicalExpressionUtils.getVariables(node.right) : []; return [...leftVars, ...rightVars]; } if (node.type === NodeType.Parenthesis) { return LogicalExpressionUtils.getVariables(node.expression); } throw new Error(ERROR_PREFIX.UNEXPECTED_NODE_TYPE); } /** * Evaluate the parsed logical expression. You'll need to provide a * variable table. * * @param node Logical expression node * @param table Variable table (key: variable name, value: boolean) * @returns Evaluation result * @example * If the expression is `a && b`, and the variable table is * `{ a: true, b: false }`, the result will be `false`. * * Example code: * ```js * LogicalExpressionUtils.evaluate( * LogicalExpressionParser.parse('a && b'), * { a: true, b: false } * ); * ``` */ static evaluate(node, table) { if (node.type === NodeType.Variable) { return !!table[node.name]; } if (node.type === NodeType.Operator) { if (node.operator === OperatorValue.And || node.operator === OperatorValue.Or) { if (!node.right) { throw new Error(`${ERROR_PREFIX.UNEXPECTED_OPERATOR} '${node.operator}'`); } if (node.operator === OperatorValue.And) { // eslint-disable-next-line max-len return LogicalExpressionUtils.evaluate(node.left, table) && LogicalExpressionUtils.evaluate(node.right, table); } if (node.operator === OperatorValue.Or) { // eslint-disable-next-line max-len return LogicalExpressionUtils.evaluate(node.left, table) || LogicalExpressionUtils.evaluate(node.right, table); } } else if (node.operator === OperatorValue.Not) { return !LogicalExpressionUtils.evaluate(node.left, table); } } else if (node.type === NodeType.Parenthesis) { return LogicalExpressionUtils.evaluate(node.expression, table); } throw new Error(`${ERROR_PREFIX.UNEXPECTED_NODE_TYPE} '${node.type}'`); } } export { LogicalExpressionUtils };