Skip to content
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

Correctly transform spreads to use proper concat method #9108

Merged
merged 2 commits into from Dec 14, 2018
Merged

Conversation

danez
Copy link
Member

@danez danez commented Dec 1, 2018

Q                       A
Fixed Issues? Fixes #8907
Patch: Bug Fix? y
Major: Breaking Change? n
Minor: New Feature? n
Tests Added + Pass? Yes
Documentation PR Link
Any Dependency Changes?
License MIT

This reverts some of the optimizations of #6763.

Transforming a spread to this

// [...arr, b]
arr.concat(b)

is dangerous as we do not know what arr is exactly. It might be a subclass of Array with changed behavior of its concat function.

Instead I changed it to use

Array.prototype.concat(arr, b);

Other option would be to use what was there before #6763

[].concat(arr, b);

which is smaller, but needs to create an additional array.

Also added comments to hopefully make the logic understandable.

@danez danez added the PR: Bug Fix 🐛 A type of pull request used for our changelog categories label Dec 1, 2018
@babel-bot
Copy link
Collaborator

babel-bot commented Dec 1, 2018

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/9551/

@danez danez merged commit 47da5cf into master Dec 14, 2018
@danez danez deleted the Fix-8907 branch December 14, 2018 07:24
@smashercosmo
Copy link

smashercosmo commented Dec 18, 2018

One bad thing about this PR is that before it if somebody tried to spread Set in loose mode, clear error was thrown, but now he will get wrong output of [Set()], which will be harder to spot.

@rubennorte
Copy link
Contributor

I agree with @smashercosmo. This also allows to spread non-iterable values again, which is wrong (e.g.: [...null]). I know this is for loose mode but IMO having a subset of the semantics (only accepting arrays) is better than changing the semantics.

@fdanielsen
Copy link

Sorry if this is the wrong place to comment, but this has references to a lot of related history.

In a modern browser that supports the spread operator natively, [...el.querySelectorAll('.foo')] correctly converts the iterable NodeList to an array of elements. But [].concat(el.querySelectorAll('.foo') gives an array of a single item which is the NodeList.

This doesn't seem like the intended result with Babels support of the spread operator?

@calebeby
Copy link
Contributor

@fdanielsen I'm seeing the same thing as you, with DOMTokenList as well (from "spreading" element.classList

@jridgewell
Copy link
Member

The loose transform only handles Arrays. You'll have to use the spec transform (as well as polyfilling Symbol.iterator methods for the iterable) if you want this to be done correctly.

@calebeby
Copy link
Contributor

calebeby commented Jul 29, 2019

I don't see a spec option here: https://babeljs.io/docs/en/babel-plugin-transform-spread

Are the docs out of date? Happy to send a PR if that is the case 😃

Edit: oops, I didn't realize I had preset-env configured with loose: true

@jridgewell
Copy link
Member

Spec in this case is the default. We only add an explicit spec option if the doing it by default would cause a large performance regression or something else undesirable.

@calebeby
Copy link
Contributor

Got it. Thanks for the clarification 👍

NMinhNguyen pushed a commit to NMinhNguyen/babel-plugin-transform-destructuring that referenced this pull request Aug 9, 2019
* Correctly transform spreads to use proper concat method

* Add tests to ensure array spread clones elements
@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Oct 28, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 28, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue PR: Bug Fix 🐛 A type of pull request used for our changelog categories
Projects
None yet
Development

Successfully merging this pull request may close these issues.

@babel/plugin-transform-spread regression of spread array
9 participants