New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement try-statement-deoptimization for feature detection, tree-shake unused arguments #2892
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very pleased to see work in these directions, and agreed its about matching the common feature detection forms here.
It would be good to see some tests on try-catch dynamic require / non-analyzed dynamic import cases that are passed through to the built environment, although in theory that would be no different right?
At the moment it would not make a difference for dynamic imports. Except to make sure that dynamic imports inside try-blocks are always included if the try-block is included. |
It’d be great to test this on es5-shim, es6-shim, and all of airbnb-browser-shims, since that would catch the bug referenced in #2540. |
You can try it out by installing rollup via |
at least es6-shim should be fine, |
Any help here is welcome, a simple way to test it could be to write an entry point that contains the shim, e.g. npx rollup/rollup#try-block-deoptimization main.js --format esm > output.js
npx rollup/rollup#try-block-deoptimization main.js --format esm --no-treeshake > full-output.js and diff the two files |
This PR contains:
Are tests included?
Breaking Changes?
List any relevant issue numbers:
resolves #2891
resolves #2869
resolves #2540
resolves #2273
resolves #1771
Description
This PR adds a heuristic around try-catch blocks that allows for feature detection workflows, or workflows that depend on uncommonly thrown errors such as checking if
class test extends someVar {}
throws an error to see ifsomeVar
is a valid constructor.I checked that with this modification, all feature detections of
core-js
should work as intended. Besides the try-catch deoptimization, this PR will also tree-shake unused function arguments.Try-statement deoptimization
This PR adds a heuristic based on the idea that in order to detect an uncommonly thrown error, you will probably put it into the try-statement of a try-catch construct (alternatively promises would work as well but the heuristic will not cover those).
Therefore:
Tree-shaking will be disabled inside try-statements, i.e. code directly nested inside a try-statement will be retained.
If a variable is
myVar()
and not e.g.(myVar || otherVar)()
.then tree-shaking will also be disabled in that function; however, other variables called from such a function will NOT be deoptimized to contain the infectious nature of this feature.
If a parameter of a function is called inside a try-statement, this parameter is marked in a special way. In all places this function is called, the argument provided for this parameter will be treated the same way as if it was called from within the try-statement. This is to allow
core-js
style feature detection:Unused argument tree-shaking
To use some of the logic built for this feature for other cool stuff, this PR will not also tree-shake unused arguments from function calls. To that end, each time the call target of a call can be uniquely resolved, unused arguments will be removed from the call. More precisely:
A parameter that is either
is "unused" unless
arguments
is accessed inside that function.Call arguments corresponding to "unused" parameters will be removed if
Parameters themselves will not be removed even if they are unused to avoid difficult edge-cases when some logic relies on
functionName.length
to determine the number of parameters for e.g. currying.This enables tree-shaking in scenarios such as