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

Fix export bindings not updated by 'for ... in' and 'for ... of' #11074

Merged
merged 13 commits into from Feb 9, 2020
Merged

Fix export bindings not updated by 'for ... in' and 'for ... of' #11074

merged 13 commits into from Feb 9, 2020

Conversation

vedantroy
Copy link
Contributor

@vedantroy vedantroy commented Jan 30, 2020

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

This PR makes Babel correctly transform exported variables in for of and for in loops.

@vedantroy vedantroy changed the title Fix 10941 (Draft) Fix export bindings not updated by for ... in and ' Jan 31, 2020
@vedantroy vedantroy changed the title Fix export bindings not updated by for ... in and ' Fix export bindings not updated by 'for ... in' and 'for ... of' Jan 31, 2020
Copy link
Member

@nicolo-ribaudo nicolo-ribaudo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be easier if we transform

for (PATTERN in {}) {}

to

for (let _foo in {}) {
  PATTERN = _foo
}

Then all the existing logic would work for this case, without needing to distinguish the case when PATTERN is a simple identifier or when it's using destructuring.

@nicolo-ribaudo nicolo-ribaudo added area: modules PR: Bug Fix 🐛 A type of pull request used for our changelog categories labels Jan 31, 2020
@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Jan 31, 2020

Btw, you can use t.getOuterBindingIdentifiers(left) to get all the bindings updated by the destructuring pattern, and then rename the bindings declared in the nested scope. By doing so, you don't need the custom transformArrayPattern (which currently would also be needed for object patterns).

@vedantroy
Copy link
Contributor Author

vedantroy commented Jan 31, 2020

@nicolo-ribaudo I think moving PATTERN into the loop body would break the following case:

for ({foo} of [{foo: 1}]) {
  let foo;
}

because this would be transformed into

for (let _foo of [{foo: 1}]) {
  ({foo} = _foo)
  let foo;
}

and Babel would transform that into

for (let _foo of [{foo: 1}]) {
  ({ foo } = _foo);
  exports.foo = foo;
  let foo;
}

which results in an error, since you are assigning to foo before it has been declared.

@nicolo-ribaudo
Copy link
Member

I was proposing to do something like this:

  1. Let bindings be t.getOuterBindingIdentifiers(left)
  2. For each binding in bindings,
    a. If the inner scope declares binding, call rename(binding) on the inner scope
  3. Move PATTERN to PATTERN = _foo inside the loop body.

@vedantroy
Copy link
Contributor Author

vedantroy commented Jan 31, 2020

@nicolo-ribaudo

I changed the code to use your method, it's a lot better now!

Co-Authored-By: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
Copy link
Member

@nicolo-ribaudo nicolo-ribaudo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@nicolo-ribaudo nicolo-ribaudo merged commit 3c86b05 into babel:master Feb 9, 2020
nicolo-ribaudo added a commit that referenced this pull request Feb 9, 2020
* Correctly transpile export bindings for some for-of loops

* Correctly transform non-destructured for of loops to update exported variables

* Add tests

* Don't replace entire for of loop

* Correctly transform destructured for-of/for-in exports

* Update exported variables in array pattern and more fixes

* Refresh test output

* Update tests and rebase on master

* Refactor ForOf|ForIn visitor

* Don't transform re-declared exported vars

* Generate better name for loop id

Co-Authored-By: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>

* Idiomatically generate UidIdentifier

* Update scope after replacing loop declaration

Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
@vedantroy vedantroy deleted the fix-10941 branch February 9, 2020 19:32
rajasekarm pushed a commit to rajasekarm/babel that referenced this pull request Feb 17, 2020
…1074)

* Correctly transpile export bindings for some for-of loops

* Correctly transform non-destructured for of loops to update exported variables

* Add tests

* Don't replace entire for of loop

* Correctly transform destructured for-of/for-in exports

* Update exported variables in array pattern and more fixes

* Refresh test output

* Update tests and rebase on master

* Refactor ForOf|ForIn visitor

* Don't transform re-declared exported vars

* Generate better name for loop id

Co-Authored-By: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>

* Idiomatically generate UidIdentifier

* Update scope after replacing loop declaration

Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label May 11, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 11, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: modules 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.

plugin-transform-modules-commonjs: export binding not updated by 'for...in' and 'for...of'
4 participants