-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathESParser.js
82 lines (69 loc) · 1.8 KB
/
ESParser.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
72
73
74
75
76
77
78
79
80
81
82
const acorn = require("acorn");
function atomFromAcorn(node) {
if (node.raw) {
return node.raw;
}
if (node.type === "Identifier") {
return node.name;
}
if (node.type === "CallExpression") {
return `${node.callee.name}(${node.arguments.map(atomFromAcorn)})`;
}
if (node.type === "LogicalExpression") {
return `${atomFromAcorn(node.left)} ${node.operator} ${atomFromAcorn(
node.right
)}`;
}
if (node.type === "MemberExpression") {
return `${atomFromAcorn(node.object)}.${atomFromAcorn(node.property)}`;
}
if (node.type === "BinaryExpression") {
return `${atomFromAcorn(node.left)} ${node.operator} ${atomFromAcorn(
node.right
)}`;
}
return `?${node.type}?`;
}
module.exports = class AcornTransformer {
parse(expression) {
return this.fromAcorn(acorn.parse(expression));
}
fromAcorn(node) {
if (node.type === "Program") {
return this.fromAcorn(node.body[0]);
}
if (node.type === "ExpressionStatement") {
return this.fromAcorn(node.expression);
}
if (node.type === "LogicalExpression") {
return {
type: node.operator === "||" ? "or" : "and",
left: this.fromAcorn(node.left),
right: this.fromAcorn(node.right)
};
}
if (node.type === "UnaryExpression" && node.operator === "!") {
return {
type: "not",
argument: this.fromAcorn(node.argument)
};
}
if (node.type === "Identifier") {
return {
type: "atom",
name: node.name
};
}
if (
node.type === "CallExpression" ||
node.type === "BinaryExpression" ||
node.type === "MemberExpression"
) {
return {
type: "atom",
name: atomFromAcorn(node)
};
}
throw new Error(`Unrecognized node type: ${node.type}`);
}
};