diff --git a/packages/babel-helper-define-polyfill-provider/src/visitors/usage.ts b/packages/babel-helper-define-polyfill-provider/src/visitors/usage.ts index 9fdbe3bc..29c2b22e 100644 --- a/packages/babel-helper-define-polyfill-provider/src/visitors/usage.ts +++ b/packages/babel-helper-define-polyfill-provider/src/visitors/usage.ts @@ -16,26 +16,72 @@ function isRemoved(path: NodePath) { } export default (callProvider: CallProvider) => { + const polyfilled = new WeakSet(); + function property(object, key, placement, path) { return callProvider({ kind: "property", object, key, placement }, path); } function handleReferencedIdentifier(path) { - const { - node: { name }, - scope, - } = path; + const { node, scope } = path; + const { name } = node; if (scope.getBindingIdentifier(name)) return; callProvider({ kind: "global", name }, path); + + if (path.node !== node) polyfilled.add(path.node); } function analyzeMemberExpression(path: NodePath) { const key = resolveKey(path.get("property"), path.node.computed); return { key, handleAsMemberExpression: !!key && key !== "prototype" }; } - return { + LogicalExpression: { + exit(path: NodePath) { + const { node } = path; + if (node.operator !== "||") return; + if (polyfilled.has(node.left)) { + path.get("right").remove(); + } else if ( + t.isUnaryExpression(node.left) && + node.left.operator === "!" && + polyfilled.has(node.left.argument) + ) { + path.replaceWith(node.right); + } + }, + }, + IfStatement: { + exit(path: NodePath) { + const { node } = path; + if (polyfilled.has(node.test)) { + path.replaceWith(node.consequent); + } else if ( + t.isUnaryExpression(node.test) && + node.test.operator === "!" + ) { + if (polyfilled.has(node.test.argument)) { + path.replaceWith(node.alternate); + } + } + }, + }, + ConditionalExpression: { + exit(path: NodePath) { + const { node } = path; + if (polyfilled.has(node.test)) { + path.replaceWith(node.consequent); + } else if ( + t.isUnaryExpression(node.test) && + node.test.operator === "!" + ) { + if (polyfilled.has(node.test.argument)) { + path.replaceWith(node.alternate); + } + } + }, + }, // Symbol(), new Promise ReferencedIdentifier(path: NodePath) { const { parentPath } = path; @@ -65,7 +111,12 @@ export default (callProvider: CallProvider) => { } const source = resolveSource(object); + const { node } = path; let skipObject = property(source.id, key, source.placement, path); + if (node !== path.node && !path.isCallExpression()) { + polyfilled.add(path.node); + } + skipObject ||= !objectIsGlobalIdentifier || path.shouldSkip || diff --git a/packages/babel-plugin-polyfill-corejs3/test/fixtures/usage-pure/dead-branch/input.mjs b/packages/babel-plugin-polyfill-corejs3/test/fixtures/usage-pure/dead-branch/input.mjs new file mode 100644 index 00000000..7d93070e --- /dev/null +++ b/packages/babel-plugin-polyfill-corejs3/test/fixtures/usage-pure/dead-branch/input.mjs @@ -0,0 +1,55 @@ +Reflect.construct || err; +!Reflect.construct || ok; + + +Reflect.construct ? ok : err; +!Reflect.construct ? err : ok; + +if (Reflect.construct) { + ok; +} else { + err; +} +if (!Reflect.construct) { + err; +} else { + ok; +} + + +Symbol.dispose || err; +!Symbol.dispose || ok; + + +Symbol.dispose ? ok : err; +!Symbol.dispose ? err : ok; + +if (Symbol.dispose) { + ok; +} else { + err; +} +if (!Symbol.dispose) { + err; +} else { + ok; +} + + +a.padStart || err; +!a.padStart || ok; + + +a.padStart ? ok : err; +!a.padStart ? err : ok; + +if (a.padStart) { + ok; +} else { + err; +} +if (!a.padStart) { + err; +} else { + ok; +} diff --git a/packages/babel-plugin-polyfill-corejs3/test/fixtures/usage-pure/dead-branch/options.json b/packages/babel-plugin-polyfill-corejs3/test/fixtures/usage-pure/dead-branch/options.json new file mode 100644 index 00000000..6cbc6409 --- /dev/null +++ b/packages/babel-plugin-polyfill-corejs3/test/fixtures/usage-pure/dead-branch/options.json @@ -0,0 +1,11 @@ +{ + "plugins": [ + [ + "@@/polyfill-corejs3", + { + "method": "usage-pure", + "version": "3.34" + } + ] + ] +} diff --git a/packages/babel-plugin-polyfill-corejs3/test/fixtures/usage-pure/dead-branch/output.mjs b/packages/babel-plugin-polyfill-corejs3/test/fixtures/usage-pure/dead-branch/output.mjs new file mode 100644 index 00000000..966ad8dd --- /dev/null +++ b/packages/babel-plugin-polyfill-corejs3/test/fixtures/usage-pure/dead-branch/output.mjs @@ -0,0 +1,41 @@ +import _Reflect$construct from "core-js-pure/stable/reflect/construct.js"; +import _Symbol from "core-js-pure/stable/symbol/index.js"; +import _padStartInstanceProperty from "core-js-pure/stable/instance/pad-start.js"; +_Reflect$construct; +ok; +ok; +ok; +{ + ok; +} +{ + ok; +} +_Symbol.dispose || err; +!_Symbol.dispose || ok; +_Symbol.dispose ? ok : err; +!_Symbol.dispose ? err : ok; +if (_Symbol.dispose) { + ok; +} else { + err; +} +if (!_Symbol.dispose) { + err; +} else { + ok; +} +_padStartInstanceProperty(a) || err; +!_padStartInstanceProperty(a) || ok; +_padStartInstanceProperty(a) ? ok : err; +!_padStartInstanceProperty(a) ? err : ok; +if (_padStartInstanceProperty(a)) { + ok; +} else { + err; +} +if (!_padStartInstanceProperty(a)) { + err; +} else { + ok; +} diff --git a/yarn.lock b/yarn.lock index bec21829..e5b66d21 100644 --- a/yarn.lock +++ b/yarn.lock @@ -224,7 +224,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-define-polyfill-provider@workspace:^0.6.1, @babel/helper-define-polyfill-provider@workspace:packages/babel-helper-define-polyfill-provider": +"@babel/helper-define-polyfill-provider@workspace:^0.6.2, @babel/helper-define-polyfill-provider@workspace:packages/babel-helper-define-polyfill-provider": version: 0.0.0-use.local resolution: "@babel/helper-define-polyfill-provider@workspace:packages/babel-helper-define-polyfill-provider" dependencies: @@ -4482,7 +4482,7 @@ __metadata: dependencies: "@babel/compat-data": ^7.22.6 "@babel/core": ^7.22.6 - "@babel/helper-define-polyfill-provider": "workspace:^0.6.1" + "@babel/helper-define-polyfill-provider": "workspace:^0.6.2" "@babel/helper-plugin-test-runner": ^7.22.5 "@babel/plugin-transform-for-of": ^7.22.5 "@babel/plugin-transform-modules-commonjs": ^7.22.5 @@ -4509,7 +4509,7 @@ __metadata: resolution: "babel-plugin-polyfill-corejs3@workspace:packages/babel-plugin-polyfill-corejs3" dependencies: "@babel/core": ^7.22.6 - "@babel/helper-define-polyfill-provider": "workspace:^0.6.1" + "@babel/helper-define-polyfill-provider": "workspace:^0.6.2" "@babel/helper-plugin-test-runner": ^7.22.5 "@babel/plugin-proposal-decorators": ^7.22.15 "@babel/plugin-transform-class-properties": ^7.22.5 @@ -4531,7 +4531,7 @@ __metadata: resolution: "babel-plugin-polyfill-es-shims@workspace:packages/babel-plugin-polyfill-es-shims" dependencies: "@babel/core": ^7.22.6 - "@babel/helper-define-polyfill-provider": "workspace:^0.6.1" + "@babel/helper-define-polyfill-provider": "workspace:^0.6.2" "@babel/helper-plugin-test-runner": ^7.22.5 array.from: ^1.1.0 math.clz32: ^1.0.0 @@ -4556,7 +4556,7 @@ __metadata: resolution: "babel-plugin-polyfill-regenerator@workspace:packages/babel-plugin-polyfill-regenerator" dependencies: "@babel/core": ^7.17.8 - "@babel/helper-define-polyfill-provider": "workspace:^0.6.1" + "@babel/helper-define-polyfill-provider": "workspace:^0.6.2" "@babel/helper-plugin-test-runner": ^7.16.7 "@babel/plugin-transform-regenerator": ~7.14.0 peerDependencies: