From ddaeac7e1005bf9d3729a0b7a03b005a0b5039e3 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Sun, 5 May 2019 21:08:48 -0700 Subject: [PATCH] Shake exports with pure property assignments (#2909) --- .../scope-hoisting/es6/pure-assignment/a.js | 3 ++ .../scope-hoisting/es6/pure-assignment/b.js | 4 +++ packages/shared/scope-hoisting/src/shake.js | 31 +++++++++---------- 3 files changed, 22 insertions(+), 16 deletions(-) create mode 100644 packages/core/integration-tests/test/integration/scope-hoisting/es6/pure-assignment/a.js create mode 100644 packages/core/integration-tests/test/integration/scope-hoisting/es6/pure-assignment/b.js diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/pure-assignment/a.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/pure-assignment/a.js new file mode 100644 index 00000000000..229761a608f --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/pure-assignment/a.js @@ -0,0 +1,3 @@ +import {foo} from './b'; + +output = foo; diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/pure-assignment/b.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/pure-assignment/b.js new file mode 100644 index 00000000000..919f23d1fca --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/pure-assignment/b.js @@ -0,0 +1,4 @@ +export const foo = 2; + +export function bar() {} +bar.displayName = 'hello'; diff --git a/packages/shared/scope-hoisting/src/shake.js b/packages/shared/scope-hoisting/src/shake.js index fcbdef43ade..b5847fe734a 100644 --- a/packages/shared/scope-hoisting/src/shake.js +++ b/packages/shared/scope-hoisting/src/shake.js @@ -1,7 +1,5 @@ import * as t from '@babel/types'; -const EXPORTS_RE = /^\$([^$]+)\$exports$/; - /** * This is a small small implementation of dead code removal specialized to handle * removing unused exports. All other dead code removal happens in workers on each @@ -42,31 +40,24 @@ function getUnusedBinding(path, name) { return null; } - if (isPure(binding)) { + let pure = isPure(binding); + if (!binding.referenced && pure) { return binding; } - if (!EXPORTS_RE.test(name)) { - return null; - } - // Is there any references which aren't simple assignments? let bailout = binding.referencePaths.some( path => !isExportAssignment(path) && !isUnusedWildcard(path) ); - if (bailout) { - return null; - } else { + if (!bailout && pure) { return binding; } + + return null; } function isPure(binding) { - if (binding.referenced) { - return false; - } - if ( binding.path.isVariableDeclarator() && binding.path.get('id').isIdentifier() @@ -83,7 +74,8 @@ function isExportAssignment(path) { // match "path.any = any;" path.parentPath.isMemberExpression() && path.parentPath.parentPath.isAssignmentExpression() && - path.parentPath.parentPath.node.left === path.parentPath.node + path.parentPath.parentPath.node.left === path.parentPath.node && + path.parentPath.parentPath.get('right').isPure() ); } @@ -118,6 +110,13 @@ function remove(path) { } else if (isUnusedWildcard(path)) { remove(path.parentPath); } else if (!path.removed) { - path.remove(); + if ( + path.parentPath.isSequenceExpression() && + path.parent.expressions.length === 1 + ) { + path.parentPath.remove(); + } else { + path.remove(); + } } }