-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathreplaceBooleanExpressionsWithIf.js
46 lines (45 loc) · 1.36 KB
/
replaceBooleanExpressionsWithIf.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**
* Logical expressions which only consist of && and || will be replaced with an if statement.
* E.g. x && y(); -> if (x) y();
* x || y(); -> if (!x) y();
* @param {Arborist} arb
* @param {Function} candidateFilter (optional) a filter to apply on the candidates list
* @return {Arborist}
*/
function replaceBooleanExpressionsWithIf(arb, candidateFilter = () => true) {
const relevantNodes = [
...(arb.ast[0].typeMap.ExpressionStatement || []),
];
for (let i = 0; i < relevantNodes.length; i++) {
const n = relevantNodes[i];
if (['&&', '||'].includes(n.expression.operator) && candidateFilter(n)) {
// || requires inverted logic (only execute the consequent if all operands are false)
const testExpression =
n.expression.operator === '||'
? {
type: 'UnaryExpression',
operator: '!',
argument: n.expression.left,
}
: n.expression.left;
// wrap expression in block statement so it results in e.g. if (x) { y(); } instead of if (x) (y());
const consequentStatement = {
type: 'BlockStatement',
body: [
{
type: 'ExpressionStatement',
expression: n.expression.right
}
],
};
const ifStatement = {
type: 'IfStatement',
test: testExpression,
consequent: consequentStatement,
};
arb.markNode(n, ifStatement);
}
}
return arb;
}
export default replaceBooleanExpressionsWithIf;