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 access shadowed class binding in super.* #12544

Merged
merged 9 commits into from Jan 12, 2021

Conversation

Zzzen
Copy link
Contributor

@Zzzen Zzzen commented Dec 22, 2020

#11994

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

@babel-bot
Copy link
Collaborator

babel-bot commented Dec 22, 2020

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

return;
}

if (path.scope.hasOwnBinding(classState.classRef.name)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copied from https://github.com/babel/babel/blob/17d62c3743ca7c529bc14ddcb890a6a31ed956b1/packages/babel-plugin-transform-classes/src/transformClass.js#L499,L502

  /**
   * Replace the constructor body of our class.
   */
  function pushConstructor(
    superReturns,
    method: { type: "ClassMethod" },
    path: NodePath,
  ) {
    // https://github.com/babel/babel/issues/1077
    if (path.scope.hasOwnBinding(classState.classRef.name)) {
      path.scope.rename(classState.classRef.name);
    }
    // ...
  }

Copy link
Contributor Author

@Zzzen Zzzen Dec 22, 2020

Choose a reason for hiding this comment

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

We need to traverse here because super may appear anywhere in methods.

Edit: Ooops, super may appear anywhere in constructors too.

@codesandbox-ci
Copy link

codesandbox-ci bot commented Dec 22, 2020

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 79395d9:

Sandbox Source
babel-repl-custom-plugin Configuration
babel-plugin-multi-config Configuration

@Zzzen Zzzen marked this pull request as draft December 22, 2020 15:23
@nicolo-ribaudo nicolo-ribaudo added the PR: Bug Fix 🐛 A type of pull request used for our changelog categories label Dec 22, 2020
@Zzzen Zzzen marked this pull request as ready for review December 22, 2020 15:39
@JLHwung JLHwung self-requested a review January 6, 2021 15:44
@nicolo-ribaudo
Copy link
Member

I think that we need to move this logic in ReplaceSupers, so that it works for example with

class A extends B {
  method() {
    let A;
    super.#foo();
  }
}

@Zzzen
Copy link
Contributor Author

Zzzen commented Jan 9, 2021

I agree on moving logic in ReplaceSupers but can't see why the example should work: derived classes should have no access to private methods of Base classes, right? Only public and protected methods are accessible.

@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Jan 9, 2021

It can work in cases like

class B {
  #foo = 3;

  static getA() {
    class A extends B {
      method() {
        let A;
        super.#foo();
      }
    }
  }
}

@Zzzen
Copy link
Contributor Author

Zzzen commented Jan 9, 2021

Really? Tried it on chrome 87, got: Uncaught SyntaxError: Unexpected private field

@nicolo-ribaudo
Copy link
Member

Sorry, I was completely wrong 🙃

ReplaceSupers in the helper-create-class-features-plugin package is used for cases like this:

class A extends B {
  #foo() {
    let A;
    super.x;
  }
}

Which on main is (wrongly) transformed to

class A extends B {
  constructor(...args) {
    super(...args);

    _foo.add(this);
  }

}

var _foo2 = function _foo2() {
  let A;

  _get(_getPrototypeOf(A.prototype), "x", this);
};

@Zzzen
Copy link
Contributor Author

Zzzen commented Jan 9, 2021

👌👌 updated

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!

I've renamed the PR title so that it's clear what it does in the changelog.

@nicolo-ribaudo nicolo-ribaudo changed the title rename own binding inside methods if it collides with class ref. fix … Correctly access shadowed class binding in super.* Jan 10, 2021
@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 Apr 13, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 13, 2021
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.

Invalid class transform
4 participants