From ff2d7223861ba17063546eddc206e0e8ed2cbe9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Sun, 2 Jul 2017 17:03:19 +0200 Subject: [PATCH 1/4] constant-folding: Fix some literal types used in `.join()` --- .../__tests__/constant-folding-test.js | 6 ++++++ .../src/replacements.js | 18 ++++++++++++++---- 2 files changed, 20 insertions(+), 4 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 2cacfd768..3ddbea7f8 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 @@ -103,6 +103,9 @@ describe("constant-folding-plugin", () => { [1, 2, 3].join(); ["a", "b", "c"].join(); ["a", "b", "c"].join("@"); + [null, 1].join("/"); + [/xyz/im, true].join("abc"); + [\`a\${xyz}\`].join("1"); [1, 2, 3].length; [1, 2, 3][1]; @@ -134,6 +137,9 @@ describe("constant-folding-plugin", () => { "1,2,3"; "a,b,c"; "a@b@c"; + "/1"; + "/xyz/imabctrue"; + [\`a\${xyz}\`].join("1"); 3; 2; diff --git a/packages/babel-plugin-minify-constant-folding/src/replacements.js b/packages/babel-plugin-minify-constant-folding/src/replacements.js index 0cbc591b0..429683746 100644 --- a/packages/babel-plugin-minify-constant-folding/src/replacements.js +++ b/packages/babel-plugin-minify-constant-folding/src/replacements.js @@ -43,11 +43,21 @@ module.exports = ({ types: t }) => { let bad = false; const str = this.elements .map(el => { - if (!t.isLiteral(el)) { - bad = true; - return; + if (t.isRegExpLiteral(el)) { + return `/${el.pattern}/${el.flags}`; } - return el.value; + if (t.isNullLiteral(el)) { + return null; + } + if ( + t.isStringLiteral(el) || + t.isBooleanLiteral(el) || + t.isNumericLiteral(el) + ) { + return el.value; + } + bad = true; + return; }) .join(sep.value); return bad ? undefined : t.stringLiteral(str); From f45656b260e06a61fa1459c712a08487e8a703ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Sun, 2 Jul 2017 17:47:38 +0200 Subject: [PATCH 2/4] constant-folding: Handle simple template strings in `.join()`s --- .../__tests__/constant-folding-test.js | 2 ++ .../babel-plugin-minify-constant-folding/src/replacements.js | 3 +++ 2 files changed, 5 insertions(+) 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 3ddbea7f8..5786c641b 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 @@ -106,6 +106,7 @@ describe("constant-folding-plugin", () => { [null, 1].join("/"); [/xyz/im, true].join("abc"); [\`a\${xyz}\`].join("1"); + [\`a\`, \`c\`].join('b'); [1, 2, 3].length; [1, 2, 3][1]; @@ -140,6 +141,7 @@ describe("constant-folding-plugin", () => { "/1"; "/xyz/imabctrue"; [\`a\${xyz}\`].join("1"); + "abc"; 3; 2; diff --git a/packages/babel-plugin-minify-constant-folding/src/replacements.js b/packages/babel-plugin-minify-constant-folding/src/replacements.js index 429683746..fba3dd3e5 100644 --- a/packages/babel-plugin-minify-constant-folding/src/replacements.js +++ b/packages/babel-plugin-minify-constant-folding/src/replacements.js @@ -56,6 +56,9 @@ module.exports = ({ types: t }) => { ) { return el.value; } + if (t.isTemplateLiteral(el) && el.expressions.length === 0) { + return el.quasis[0].value.cooked; + } bad = true; return; }) 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 3/4] 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)) ); } }, From c12a4af3616811710ffffb2a6e065fd0ba440121 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Tue, 15 Aug 2017 19:54:59 +0200 Subject: [PATCH 4/4] Fix quote style --- packages/babel-plugin-minify-constant-folding/src/index.js | 6 +++--- .../src/replacements.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/babel-plugin-minify-constant-folding/src/index.js b/packages/babel-plugin-minify-constant-folding/src/index.js index 4f0253861..8b15665b1 100644 --- a/packages/babel-plugin-minify-constant-folding/src/index.js +++ b/packages/babel-plugin-minify-constant-folding/src/index.js @@ -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.get('object'), key); + handler = handlers[FALLBACK_HANDLER].bind(member.get("object"), key); } else { return false; } } - const replacement = handler.apply(member.get('object'), args); + const replacement = handler.apply(member.get("object"), args); if (replacement) { path.replaceWith(replacement); return true; @@ -168,7 +168,7 @@ module.exports = babel => { }, CallExpression(path) { const { node } = path; - const member = path.get('callee'); + const member = path.get("callee"); if (t.isMemberExpression(member)) { const helpers = replacements[member.node.object.type]; if (!helpers || !helpers.calls) return; diff --git a/packages/babel-plugin-minify-constant-folding/src/replacements.js b/packages/babel-plugin-minify-constant-folding/src/replacements.js index 3464f5e97..ae52887d4 100644 --- a/packages/babel-plugin-minify-constant-folding/src/replacements.js +++ b/packages/babel-plugin-minify-constant-folding/src/replacements.js @@ -41,7 +41,7 @@ module.exports = ({ types: t }) => { join(sep = t.stringLiteral(",")) { if (!t.isStringLiteral(sep)) return; let bad = false; - const str = this.get('elements') + const str = this.get("elements") .map(el => { const evaled = el.evaluate(); if (!evaled.confident) {