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: super.x in a loop #15948

Merged
merged 6 commits into from Oct 23, 2023
Merged

fix: super.x in a loop #15948

merged 6 commits into from Oct 23, 2023

Conversation

liuxingbaoyu
Copy link
Member

@liuxingbaoyu liuxingbaoyu commented Sep 8, 2023

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

@liuxingbaoyu liuxingbaoyu added the PR: Bug Fix 🐛 A type of pull request used for our changelog categories label Sep 8, 2023
@babel-bot
Copy link
Collaborator

babel-bot commented Sep 8, 2023

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

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.

I think it's ok to start emitting let for the loop case even if it's ES6, given that anybody using super will also be compiling let/const anyway. However, would it be possible to only emit let if we are actually in a loop, to reduce risk?

path.scope.push({
id: t.cloneNode(objectRef),
kind: scopePath.parentPath?.isLoop() ? "let" : "var",
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Checking direct parent is not sufficient. For example, wrap the loop body in if (true) { ... } and you get a var again.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed, thank you!

@lightmare
Copy link
Contributor

lightmare commented Sep 10, 2023

Found another issue, probably related to plugin order. plugin-transform-block-scoping will simply rewrite the let to a var, unless it's already capturing the scope because of something else.

This fails, but if you uncomment the bar() method, it passes: REPL

//---

const objects = [];

for (const proto of [{x: 0}, {x: 1}])
  if (true) {
    objects.push({
      __proto__: proto,
      p: proto,
      foo() {
        return super.x
      },
/*
      bar() {
        return proto.x
      },
//*/
    });
  }

for (const o of objects) {
  console.log(o.p.x === o.foo(), o.p.x, o.foo());
}
for (const o of objects) {
  console.assert(o.p.x === o.foo(), o.p.x, o.foo());
}

@liuxingbaoyu
Copy link
Member Author

Amazing find, thank you!
This is actually a bug in plugin-transform-block-scoping, it's probably a regression, I'm surprised no one has reported it. :)
I will investigate.

old babel

var objects = [];
var i = 0;
for (var proto of [0, 1 ,2]) if (true) {
  let _obj = i;
  i++;
  
  objects.push({
    foo() {
      return _obj;
    }
  });
}

console.assert(objects[0].foo()===0,objects[0].foo());

repl

@nicolo-ribaudo
Copy link
Member

Awesome, thanks @lightmare for the review :)

@liuxingbayou Do you mind splitting 8eda7f0 into a separate PR so that we have to separate changelog entries? 🙏

@nicolo-ribaudo
Copy link
Member

Could you rebase? :)

@nicolo-ribaudo
Copy link
Member

I opened #16058 to keep track of the other regression.

@nicolo-ribaudo nicolo-ribaudo merged commit 7a35330 into babel:main Oct 23, 2023
47 checks passed
@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 Jan 23, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 23, 2024
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.

[Bug]: plugin-transform-object-super incorrect output where object created in a loop
5 participants