-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathrearrangeSwitches.js
71 lines (68 loc) · 2.04 KB
/
rearrangeSwitches.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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import {getDescendants} from '../utils/getDescendants.js';
const maxRepetition = 50;
/**
*
* @param {Arborist} arb
* @param {Function} candidateFilter (optional) a filter to apply on the candidates list
* @return {Arborist}
*/
function rearrangeSwitches(arb, candidateFilter = () => true) {
const relevantNodes = [
...(arb.ast[0].typeMap.SwitchStatement || []),
];
for (let i = 0; i < relevantNodes.length; i++) {
const n = relevantNodes[i];
if (n.discriminant.type === 'Identifier' &&
n?.discriminant.declNode?.parentNode?.init?.type === 'Literal' &&
candidateFilter(n)) {
let ordered = [];
const cases = n.cases;
let currentVal = n.discriminant.declNode.parentNode.init.value;
let counter = 0;
while (currentVal !== undefined && counter < maxRepetition) {
// A matching case or the default case
let currentCase;
for (let j = 0; j < cases.length; j++) {
if (cases[j].test?.value === currentVal || !cases[j].test) {
currentCase = cases[j];
break;
}
}
if (!currentCase) break;
for (let j = 0; j < currentCase.consequent.length; j++) {
if (currentCase.consequent[j].type !== 'BreakStatement') {
ordered.push(currentCase.consequent[j]);
}
}
let allDescendants = [];
for (let j = 0; j < currentCase.consequent.length; j++) {
allDescendants.push(...getDescendants(currentCase.consequent[j]));
}
const assignments2Next = [];
for (let j = 0; j < allDescendants.length; j++) {
const d = allDescendants[j];
if (d.declNode === n.discriminant.declNode &&
d.parentKey === 'left' &&
d.parentNode.type === 'AssignmentExpression') {
assignments2Next.push(d);
}
}
if (assignments2Next.length === 1) {
currentVal = assignments2Next[0].parentNode.right.value;
} else {
// TODO: Handle more complex cases
currentVal = undefined;
}
++counter;
}
if (ordered.length) {
arb.markNode(n, {
type: 'BlockStatement',
body: ordered,
});
}
}
}
return arb;
}
export default rearrangeSwitches;