Skip to content

Refactor call handling - #1624

Merged
Rich-Harris merged 33 commits into
rollup:masterfrom
lukastaegert:refactor-call-handling
Sep 16, 2017
Merged

Refactor call handling#1624
Rich-Harris merged 33 commits into
rollup:masterfrom
lukastaegert:refactor-call-handling

Conversation

@lukastaegert

@lukastaegert lukastaegert commented Sep 11, 2017

Copy link
Copy Markdown
Member

So it here is, my second huge refactoring PR. This time, the focus is on refactoring the side-effect detection for calls and instantiations, something I had left out of the previous PR. Besides, quite a few issues will be fixed as well: #674, #677, #1187, #1235, #1289, #1391, #1615, #1622

Improved results

This time the list of tests that have been added/changed and now produce different (and correct) results is REALLY long, so instead I will just list the highlights and you may check for yourself:

  • Call expression handling now re-uses the same logic as the rest of rollup to determine if a function body has side-effects. An immediate result is that in namespace-optimization-computed-string, the several times re-exported but side-effect free function is now properly removed so the test needed to be adapted :)
  • Class declarations and expressions are now properly removed unless there are computed keys in the body that cause side-effects or retrieving the super class has a side-effect
  • Class instantiations are now removed if there is no constructor in the class or any super class or the relevant constructor has no side-effects
  • Except for import and export declarations for which this remains to be done, all other kinds of declarations have been separated from their concept of a "variable", which is what is stored in the scope now
  • This made it possible, that variable re-declarations with "var" or "function" are now recognized properly! See e.g. the test redeclarations
  • Also, "this"-handling has been refactored. Now, "this" is actually a pseudo-variable on the scope. For now, it only assumes one of two pseudo-values, UNKNOWN_LITERAL and UNKNOWN_ASSIGNMENT but in the future we might start putting much more information here. The values of "this" are set during .bind() time.
  • This also means that we can now properly remove nested mutations of "this" expressions if they do not have an effect!
  • Generator functions without side-effects are removed as long as iteration has not started yet, see side-effects-generators
  • New types of scopes like the FunctionScope have been added. Now functions actually create two new scopes: one for their parameters and one for their body. This resolves some elusive bugs.
  • In the no-treeshake test, the namespace import is now properly replaced. This is handled by actually including ALL nodes when tree-shaking is off which should also resolve other problems related to tree-shaking being disabled.
  • A crash with cyclic assignments has been resolved (also fixes Rollup 0.49.3 regression bundling React #1631)
  • Side-effects in default parameter values are now detected properly. Also, there have been many small fixes and improvements to the side-effect detection in pattern assignments and pattern defaults.
  • Now if a for-in/of loop uses a global loop variable, this will be properly noted as an effect
  • Tree-shaking inside LabeledStatements now works properly

Other refactorings

  • Node now has JSDoc comments describing the parameter types, return values and how and when to overwrite the individual methods. This should help others in determining what needs to be changed if they want to fix something via PR.
  • hasEffects options have been refactored to be handled via a class that ensures immutability
  • Node.hasEffectsWhenCalled is implemented
  • VariableDeclarators no longer generate ProxyDeclarations for their children; instead, this has been moved to the individual Identifiers
  • Variables on the scope are now usually declared by Identifiers and linked to Identifiers
  • All kinds of variables are now derived from Variable; variables can be tested for certain effects
  • callHasEffects and gatherPossibleValues could finally be removed
  • All calls to a function are collected during bind time. For now, this is only used to detect "this" values. In the future, we might want to start collecting call parameters here to determine if a function does not have side-effects for specific parameters. E.g., if a Literal is passed as a parameter it is not a side-effect to mutate it.
  • This time, there are many more small commits if anyone wants to follow the refactoring flow…
  • And many more!

Have fun & I hope this works for everyone!

  future) that make immutability easier to handle
* Properly tree-shake generator functions without side-effects that have
  been called to provide an iterator at least as long as iteration has
  not yet started
…ements

* Fix an issue when tree-shaking is of where namespace imports were not
  replaced properly
* Move the job of declaring variables on the scope to the individual
  Identifiers
* Extract Variable types and refactor
* In order to find out if a variable has an effect when mutated, ask it!
* Now var statements should be correctly associated (test pending)
* For nodes: includeDeclaration -> includeWithAllDeclarations
* Scope.findDeclaration -> findVariable
* No special handling for this-values for now
* Finally eliminate callHasEffects and gatherPossibleValues
* Side-effects across namespace imports are now properly detected!
  (dedicated test is pending)
  to make clear these are meant to be called during .bind()
* Create dedicated FunctionBodyScope for non-ArrowFunctions that adds
  arguments and will in the future handle "this" values
@lukastaegert

lukastaegert commented Sep 11, 2017

Copy link
Copy Markdown
Member Author

For some reason when rebasing/merging, some commits were added twice so the list of commits might look a little bloated...
Update: Some stashing, resetting, interactive rebasing, unstashing and force-pushing seem to have fixed that ;) Now you can read the commits properly from top to bottom

@TimvdLippe

Copy link
Copy Markdown
Contributor

Besides, quite a few issues will be fixed as well:

For GitHub to automatically close these issues, you need to explicitly add the keyword Fixes in the PR description for each issue number. E.g. Fixes #674, Fixes #677, etc...

@lukastaegert

Copy link
Copy Markdown
Member Author

Actually, "resolve" and "close" also work quite well but I prefer to do it via the individual commits, that way the commit gets linked to the issue 😉

@lukastaegert

Copy link
Copy Markdown
Member Author

But good point, added a comment for #1631.

@Rich-Harris
Rich-Harris merged commit 7c1f987 into rollup:master Sep 16, 2017
@Rich-Harris

Copy link
Copy Markdown
Contributor

🎉🎉🎉🎉🎉

amazing work as ever, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rollup 0.49.3 regression bundling React

3 participants