1 | "use strict";
|
2 |
|
3 | function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
4 |
|
5 | var evaluate = require("babel-helper-evaluate-path");
|
6 |
|
7 | var _require = require("./replacements"),
|
8 | FALLBACK_HANDLER = _require.FALLBACK_HANDLER;
|
9 |
|
10 | function getName(member) {
|
11 | if (member.computed) {
|
12 | switch (member.property.type) {
|
13 | case "StringLiteral":
|
14 | case "NumericLiteral":
|
15 | return member.property.value;
|
16 | case "TemplateLiteral":
|
17 | return;
|
18 | }
|
19 | } else {
|
20 | return member.property.name;
|
21 | }
|
22 | }
|
23 |
|
24 | function swap(path, member, handlers) {
|
25 | var key = getName(member);
|
26 | if (key === undefined) return;
|
27 | var handler = handlers[key];
|
28 | if (typeof handler !== "function") {
|
29 | if (typeof handlers[FALLBACK_HANDLER] === "function") {
|
30 | handler = handlers[FALLBACK_HANDLER].bind(member.object, key);
|
31 | } else {
|
32 | return false;
|
33 | }
|
34 | }
|
35 |
|
36 | for (var _len = arguments.length, args = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {
|
37 | args[_key - 3] = arguments[_key];
|
38 | }
|
39 |
|
40 | var replacement = handler.apply(member.object, args);
|
41 | if (replacement) {
|
42 | path.replaceWith(replacement);
|
43 | return true;
|
44 | }
|
45 | return false;
|
46 | }
|
47 |
|
48 | module.exports = function (babel) {
|
49 | var replacements = require("./replacements.js")(babel);
|
50 | var seen = Symbol("seen");
|
51 | var t = babel.types,
|
52 | traverse = babel.traverse;
|
53 |
|
54 |
|
55 | return {
|
56 | name: "minify-constant-folding",
|
57 | visitor: {
|
58 |
|
59 |
|
60 |
|
61 | BinaryExpression(path) {
|
62 | var literal = void 0,
|
63 | bin = void 0;
|
64 | if (path.get("right").isStringLiteral()) {
|
65 | literal = path.get("right");
|
66 | if (path.get("left").isBinaryExpression({ operator: "+" })) {
|
67 | bin = path.get("left");
|
68 | } else {
|
69 | return;
|
70 | }
|
71 | } else if (path.get("left").isStringLiteral()) {
|
72 | literal = path.get("left");
|
73 | if (path.get("right").isBinaryExpression({ operator: "+" })) {
|
74 | bin = path.get("right");
|
75 | } else {
|
76 | return;
|
77 | }
|
78 | } else {
|
79 | return;
|
80 | }
|
81 |
|
82 | var relevant = getLeaf(bin, literal.key);
|
83 |
|
84 | if (!relevant) {
|
85 | return;
|
86 | }
|
87 |
|
88 | var value = literal.key === "right" ? relevant.node.value + literal.node.value : literal.node.value + relevant.node.value;
|
89 |
|
90 | relevant.replaceWith(t.stringLiteral(value));
|
91 | path.replaceWith(bin.node);
|
92 |
|
93 | function getLeaf(path, direction) {
|
94 | if (path.isStringLiteral()) {
|
95 | return path;
|
96 | } else if (path.isBinaryExpression({ operator: "+" })) {
|
97 | return getLeaf(path.get(direction), direction);
|
98 | }
|
99 | }
|
100 | },
|
101 |
|
102 |
|
103 | Expression(path) {
|
104 | var node = path.node;
|
105 |
|
106 |
|
107 | if (node[seen]) {
|
108 | return;
|
109 | }
|
110 |
|
111 | if (path.isLiteral()) {
|
112 | return;
|
113 | }
|
114 |
|
115 | if (!path.isPure()) {
|
116 | return;
|
117 | }
|
118 |
|
119 | if (traverse.hasType(node, path.scope, "Identifier", t.FUNCTION_TYPES)) {
|
120 | return;
|
121 | }
|
122 |
|
123 |
|
124 |
|
125 | if (t.isUnaryExpression(node, { operator: "-" }) && t.isNumericLiteral(node.argument)) {
|
126 | return;
|
127 | }
|
128 |
|
129 |
|
130 | if (t.isUnaryExpression(node, { operator: "!" }) && t.isNumericLiteral(node.argument)) {
|
131 | if (node.argument.value === 0 || node.argument.value === 1) {
|
132 | return;
|
133 | }
|
134 | }
|
135 |
|
136 |
|
137 | if (t.isUnaryExpression(node, { operator: "void" }) && t.isNumericLiteral(node.argument, { value: 0 })) {
|
138 | return;
|
139 | }
|
140 |
|
141 | var res = evaluate(path);
|
142 | if (res.confident) {
|
143 |
|
144 |
|
145 | if (typeof res.value === "number" && !Number.isInteger(res.value)) {
|
146 | return;
|
147 | }
|
148 |
|
149 |
|
150 | if (typeof res.value === "number" && res.value === 0) {
|
151 | if (1 / res.value === -Infinity) {
|
152 | var _node2 = t.unaryExpression("-", t.numericLiteral(0), true);
|
153 | _node2[seen] = true;
|
154 | path.replaceWith(_node2);
|
155 | return;
|
156 | }
|
157 | }
|
158 |
|
159 | var _node = t.valueToNode(res.value);
|
160 | _node[seen] = true;
|
161 | path.replaceWith(_node);
|
162 | }
|
163 | },
|
164 | CallExpression(path) {
|
165 | var node = path.node;
|
166 | var member = node.callee;
|
167 |
|
168 | if (t.isMemberExpression(member)) {
|
169 | var helpers = replacements[member.object.type];
|
170 | if (!helpers || !helpers.calls) return;
|
171 | swap.apply(undefined, [path, member, helpers.calls].concat(_toConsumableArray(node.arguments)));
|
172 | }
|
173 | },
|
174 | MemberExpression(path) {
|
175 | var member = path.node;
|
176 |
|
177 | var helpers = replacements[member.object.type];
|
178 | if (!helpers || !helpers.members) return;
|
179 | swap(path, member, helpers.members);
|
180 | }
|
181 | }
|
182 | };
|
183 | }; |
\ | No newline at end of file |