(
ce: ComputeEngine,
rule: Rule | BoxedRule,
options?: { canonical?: boolean; purpose?: RulePurpose }
)
| 721 | } |
| 722 | |
| 723 | return boxRule( |
| 724 | ce, |
| 725 | { match, replace, condition: condFn, id: rule }, |
| 726 | options |
| 727 | ); |
| 728 | } finally { |
| 729 | // Pop the clean scope AFTER canonicalization to avoid pollution |
| 730 | if (systemScope) { |
| 731 | ce.popScope(); |
| 732 | } |
| 733 | } |
| 734 | } |
| 735 | |
| 736 | function boxRule( |
| 737 | ce: ComputeEngine, |
| 738 | rule: Rule | BoxedRule, |
| 739 | options?: { canonical?: boolean; purpose?: RulePurpose } |
| 740 | ): BoxedRule { |
| 741 | if (rule === undefined || rule === null) |
| 742 | throw new Error('Expected a rule, not ' + rule); |
| 743 | |
| 744 | if (isBoxedRule(rule)) { |
| 745 | // Apply the default purpose to already-boxed rules that don't carry |
| 746 | // their own tag (a per-rule tag takes precedence). |
| 747 | if (options?.purpose !== undefined && rule.purpose === undefined) |
| 748 | return { ...rule, purpose: options.purpose }; |
| 749 | return rule; |
| 750 | } |
| 751 | |
| 752 | // If the rule is defined as a single string, parse it |
| 753 | // e.g. `|x| -> x; x > 0` |
| 754 | if (typeof rule === 'string') return parseRule(ce, rule, options); |
| 755 | |
| 756 | // If the rule is defined as a function, the function will be called |
| 757 | // on every expression to process it. |
| 758 | if (typeof rule === 'function') |
| 759 | return { |
| 760 | _tag: 'boxed-rule', |
| 761 | match: undefined, |
| 762 | replace: rule, |
| 763 | condition: undefined, |
| 764 | purpose: options?.purpose, |
| 765 | id: rule.toString().replace(/\n/g, ' '), |
| 766 | }; |
| 767 | |
| 768 | // eslint-disable-next-line prefer-const |
| 769 | let { match, replace, condition, id, onMatch, onBeforeMatch, operators } = |
| 770 | rule; |
| 771 | |
| 772 | // The per-rule purpose tag takes precedence over the per-ruleset default |
| 773 | const purpose = rule.purpose ?? options?.purpose; |
| 774 | |
| 775 | if (replace === undefined) |
| 776 | throw new Error( |
| 777 | `Invalid rule "${ |
| 778 | id ?? JSON.stringify(rule, undefined, 4) |
| 779 | }"\n| A rule must include at least a replace property` |
| 780 | ); |
no test coverage detected