From aa4f987af4d7ffec372747da07b0e7499c3c35ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Tue, 15 Aug 2017 18:56:26 +0200 Subject: [PATCH] constant-folding: Use `path.evaluate()` on array elements. --- .../__tests__/constant-folding-test.js | 2 +- .../src/index.js | 16 +++--- .../src/replacements.js | 54 ++++++++----------- 3 files changed, 30 insertions(+), 42 deletions(-) diff --git a/packages/babel-plugin-minify-constant-folding/__tests__/constant-folding-test.js b/packages/babel-plugin-minify-constant-folding/__tests__/constant-folding-test.js index 5786c641b..7e7178ba2 100644 --- a/packages/babel-plugin-minify-constant-folding/__tests__/constant-folding-test.js +++ b/packages/babel-plugin-minify-constant-folding/__tests__/constant-folding-test.js @@ -139,7 +139,7 @@ describe("constant-folding-plugin", () => { "a,b,c"; "a@b@c"; "/1"; - "/xyz/imabctrue"; + [/xyz/im, true].join("abc"); [\`a\${xyz}\`].join("1"); "abc"; diff --git a/packages/babel-plugin-minify-constant-folding/src/index.js b/packages/babel-plugin-minify-constant-folding/src/index.js index 729919d01..4f0253861 100644 --- a/packages/babel-plugin-minify-constant-folding/src/index.js +++ b/packages/babel-plugin-minify-constant-folding/src/index.js @@ -19,7 +19,7 @@ function getName(member) { } function swap(path, member, handlers, ...args) { - const key = getName(member); + const key = getName(member.node); if (key === undefined) return; let handler = handlers[key]; if ( @@ -27,12 +27,12 @@ function swap(path, member, handlers, ...args) { !Object.hasOwnProperty.call(handlers, key) ) { if (typeof handlers[FALLBACK_HANDLER] === "function") { - handler = handlers[FALLBACK_HANDLER].bind(member.object, key); + handler = handlers[FALLBACK_HANDLER].bind(member.get('object'), key); } else { return false; } } - const replacement = handler.apply(member.object, args); + const replacement = handler.apply(member.get('object'), args); if (replacement) { path.replaceWith(replacement); return true; @@ -168,18 +168,18 @@ module.exports = babel => { }, CallExpression(path) { const { node } = path; - const { callee: member } = node; + const member = path.get('callee'); if (t.isMemberExpression(member)) { - const helpers = replacements[member.object.type]; + const helpers = replacements[member.node.object.type]; if (!helpers || !helpers.calls) return; swap(path, member, helpers.calls, ...node.arguments); } }, MemberExpression(path) { - const { node: member } = path; - const helpers = replacements[member.object.type]; + const { node } = path; + const helpers = replacements[node.object.type]; if (!helpers || !helpers.members) return; - swap(path, member, helpers.members); + swap(path, path, helpers.members); } } }; diff --git a/packages/babel-plugin-minify-constant-folding/src/replacements.js b/packages/babel-plugin-minify-constant-folding/src/replacements.js index fba3dd3e5..3464f5e97 100644 --- a/packages/babel-plugin-minify-constant-folding/src/replacements.js +++ b/packages/babel-plugin-minify-constant-folding/src/replacements.js @@ -14,7 +14,7 @@ module.exports = ({ types: t }) => { function defaultZero(cb) { return function(i = t.numericLiteral(0), ...args) { if (t.isNumericLiteral(i)) { - return cb.call(this, this, i.value, ...args); + return cb.call(this.node, this.node, i.value, ...args); } }; } @@ -23,17 +23,17 @@ module.exports = ({ types: t }) => { ArrayExpression: { members: { length() { - if (this.elements.some(el => t.isSpreadElement(el))) { + if (this.node.elements.some(el => t.isSpreadElement(el))) { return; } - return t.numericLiteral(this.elements.length); + return t.numericLiteral(this.node.elements.length); }, [FALLBACK_HANDLER](i) { - if (this.elements.some(el => t.isSpreadElement(el))) { + if (this.node.elements.some(el => t.isSpreadElement(el))) { return; } if (typeof i === "number" || i.match(/^\d+$/)) { - return this.elements[i] || undef; + return this.node.elements[i] || undef; } } }, @@ -41,52 +41,40 @@ module.exports = ({ types: t }) => { join(sep = t.stringLiteral(",")) { if (!t.isStringLiteral(sep)) return; let bad = false; - const str = this.elements + const str = this.get('elements') .map(el => { - if (t.isRegExpLiteral(el)) { - return `/${el.pattern}/${el.flags}`; + const evaled = el.evaluate(); + if (!evaled.confident) { + bad = true; + return; } - if (t.isNullLiteral(el)) { - return null; - } - if ( - t.isStringLiteral(el) || - t.isBooleanLiteral(el) || - t.isNumericLiteral(el) - ) { - return el.value; - } - if (t.isTemplateLiteral(el) && el.expressions.length === 0) { - return el.quasis[0].value.cooked; - } - bad = true; - return; + return evaled.value; }) .join(sep.value); return bad ? undefined : t.stringLiteral(str); }, push(...args) { - return t.numericLiteral(this.elements.length + args.length); + return t.numericLiteral(this.node.elements.length + args.length); }, shift() { - if (this.elements.length === 0) { + if (this.node.elements.length === 0) { return undef; } - return t.numericLiteral(this.elements.length - 1); + return t.numericLiteral(this.node.elements.length - 1); }, slice(start = t.numericLiteral(0), end) { if (!t.isNumericLiteral(start) || (end && !t.isNumericLiteral(end))) { return; } return t.arrayExpression( - this.elements.slice(start.value, end && end.value) + this.node.elements.slice(start.value, end && end.value) ); }, pop() { - return this.elements[this.elements.length - 1] || undef; + return this.node.elements[this.node.elements.length - 1] || undef; }, reverse() { - return t.arrayExpression(this.elements.reverse()); + return t.arrayExpression(this.node.elements.reverse()); }, splice(start, end, ...args) { if (!t.isNumericLiteral(start) || (end && !t.isNumericLiteral(end))) { @@ -96,7 +84,7 @@ module.exports = ({ types: t }) => { args.unshift(end.value); } return t.arrayExpression( - this.elements.slice().splice(start.value, ...args) + this.node.elements.slice().splice(start.value, ...args) ); } } @@ -104,11 +92,11 @@ module.exports = ({ types: t }) => { StringLiteral: { members: { length() { - return t.numericLiteral(this.value.length); + return t.numericLiteral(this.node.value.length); }, [FALLBACK_HANDLER](i) { if (typeof i === "number" || i.match(/^\d+$/)) { - const ch = this.value[i]; + const ch = this.node.value[i]; return ch ? t.stringLiteral(ch) : undef; } } @@ -124,7 +112,7 @@ module.exports = ({ types: t }) => { } if (realSep !== null) { return t.arrayExpression( - this.value.split(realSep).map(str => t.stringLiteral(str)) + this.node.value.split(realSep).map(str => t.stringLiteral(str)) ); } },