From df89c491f1ea9584550112a6f79e81497417285d Mon Sep 17 00:00:00 2001 From: Justin Ridgewell Date: Wed, 15 Apr 2020 00:02:39 -0400 Subject: [PATCH] Fix redeclaringing private in nested class's superClass If a nested class's `superClass` redeclares the outer class's private field and access it in a computed key, that should fail. Follow up to #11405. --- .../src/fields.js | 3 +- .../nested-class-computed-redeclared/exec.js | 19 ++++++ .../nested-class-computed/exec.js | 17 ++++++ .../exec.js | 18 ++++++ .../input.js | 12 ++++ .../output.js | 56 +++++++++++++++++ .../nested-class-extends-computed/exec.js | 18 ++++++ .../nested-class-extends-computed/input.js | 11 ++++ .../nested-class-extends-computed/output.js | 52 ++++++++++++++++ .../nested-class-computed-redeclared/exec.js | 19 ++++++ .../private/nested-class-computed/exec.js | 17 ++++++ .../exec.js | 18 ++++++ .../input.js | 12 ++++ .../output.js | 61 +++++++++++++++++++ .../nested-class-extends-computed/exec.js | 18 ++++++ .../nested-class-extends-computed/input.js | 11 ++++ .../nested-class-extends-computed/output.js | 55 +++++++++++++++++ 17 files changed, 415 insertions(+), 2 deletions(-) create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-computed-redeclared/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-computed/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed-redeclared/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed-redeclared/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed-redeclared/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-computed-redeclared/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-computed/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed-redeclared/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed-redeclared/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed-redeclared/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed/output.js diff --git a/packages/babel-helper-create-class-features-plugin/src/fields.js b/packages/babel-helper-create-class-features-plugin/src/fields.js index 083d35056bc0..504cf807e68f 100644 --- a/packages/babel-helper-create-class-features-plugin/src/fields.js +++ b/packages/babel-helper-create-class-features-plugin/src/fields.js @@ -103,7 +103,6 @@ const privateNameVisitor = { // This class redeclares some private field. We need to process the outer // environment with access to all the outer privates, then we can process // the inner environment with only the still-visible outer privates. - path.get("superClass").traverse(privateNameVisitor, this); path.get("body").traverse(privateNameNestedVisitor, { ...this, redeclared, @@ -115,7 +114,7 @@ const privateNameVisitor = { // We'll eventually hit this class node again with the overall Class // Features visitor, which'll process the redeclared privates. - path.skip(); + path.skipKey("body"); }, }; diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-computed-redeclared/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-computed-redeclared/exec.js new file mode 100644 index 000000000000..b42463f45085 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-computed-redeclared/exec.js @@ -0,0 +1,19 @@ +class Foo { + #foo = 1; + + test() { + class Nested { + #foo = 2; + + [this.#foo]() { + } + } + + return new Nested(); + } +} + +const f = new Foo(); +expect(() => { + f.test(); +}).toThrow(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-computed/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-computed/exec.js new file mode 100644 index 000000000000..937d281a8ecd --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-computed/exec.js @@ -0,0 +1,17 @@ +class Foo { + #foo = 1; + + test() { + class Nested { + [this.#foo]() { + } + } + + return new Nested(); + } +} + +const f = new Foo(); +expect(() => { + f.test(); +}).not.toThrow(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed-redeclared/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed-redeclared/exec.js new file mode 100644 index 000000000000..e6ecc61d0c65 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed-redeclared/exec.js @@ -0,0 +1,18 @@ +class Foo { + #foo = 1; + + test() { + class Nested extends class { + #foo = 2; + + [this.#foo] = 2; + } { + #foo = 3; + } + } +} + +const f = new Foo(); +expect(() => { + f.test(); +}).toThrow(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed-redeclared/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed-redeclared/input.js new file mode 100644 index 000000000000..8a57bd3eed55 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed-redeclared/input.js @@ -0,0 +1,12 @@ +class Foo { + #foo = 1; + + test() { + class Nested extends class { + #foo = 2; + [this.#foo] = 2; + } { + #foo = 3; + } + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed-redeclared/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed-redeclared/output.js new file mode 100644 index 000000000000..e5a3d47e0354 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed-redeclared/output.js @@ -0,0 +1,56 @@ +var Foo = /*#__PURE__*/function () { + "use strict"; + + function Foo() { + babelHelpers.classCallCheck(this, Foo); + Object.defineProperty(this, _foo, { + writable: true, + value: 1 + }); + } + + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test() { + var _temp, _foo3; + + var _babelHelpers$classPr; + + var Nested = /*#__PURE__*/function (_ref) { + babelHelpers.inherits(Nested, _ref); + + var _super = babelHelpers.createSuper(Nested); + + function Nested(...args) { + var _this; + + babelHelpers.classCallCheck(this, Nested); + _this = _super.call(this, ...args); + Object.defineProperty(babelHelpers.assertThisInitialized(_this), _foo2, { + writable: true, + value: 3 + }); + return _this; + } + + return Nested; + }((_temp = (_babelHelpers$classPr = babelHelpers.classPrivateFieldLooseBase(this, _foo3)[_foo3], /*#__PURE__*/function () { + function _class2() { + babelHelpers.classCallCheck(this, _class2); + Object.defineProperty(this, _foo3, { + writable: true, + value: 2 + }); + this[_babelHelpers$classPr] = 2; + } + + return _class2; + }()), _foo3 = babelHelpers.classPrivateFieldLooseKey("foo"), _temp)); + + var _foo2 = babelHelpers.classPrivateFieldLooseKey("foo"); + } + }]); + return Foo; +}(); + +var _foo = babelHelpers.classPrivateFieldLooseKey("foo"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed/exec.js new file mode 100644 index 000000000000..ab86e53ad557 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed/exec.js @@ -0,0 +1,18 @@ +class Foo { + #foo = 1; + + test() { + class Nested extends class { + [this.#foo] = 2; + } { + #foo = 3; + } + + return new Nested(); + } +} + +const f = new Foo(); +expect(() => { + f.test(); +}).not.toThrow(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed/input.js new file mode 100644 index 000000000000..80c5199085fd --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed/input.js @@ -0,0 +1,11 @@ +class Foo { + #foo = 1; + + test() { + class Nested extends class { + [this.#foo] = 2; + } { + #foo = 3; + } + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed/output.js new file mode 100644 index 000000000000..8dd6e4eda055 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/nested-class-extends-computed/output.js @@ -0,0 +1,52 @@ +var Foo = /*#__PURE__*/function () { + "use strict"; + + function Foo() { + babelHelpers.classCallCheck(this, Foo); + Object.defineProperty(this, _foo, { + writable: true, + value: 1 + }); + } + + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test() { + var _temp; + + var _babelHelpers$classPr; + + var Nested = /*#__PURE__*/function (_ref) { + babelHelpers.inherits(Nested, _ref); + + var _super = babelHelpers.createSuper(Nested); + + function Nested(...args) { + var _this; + + babelHelpers.classCallCheck(this, Nested); + _this = _super.call(this, ...args); + Object.defineProperty(babelHelpers.assertThisInitialized(_this), _foo2, { + writable: true, + value: 3 + }); + return _this; + } + + return Nested; + }((_temp = (_babelHelpers$classPr = babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo], /*#__PURE__*/function () { + function _class2() { + babelHelpers.classCallCheck(this, _class2); + this[_babelHelpers$classPr] = 2; + } + + return _class2; + }()), _temp)); + + var _foo2 = babelHelpers.classPrivateFieldLooseKey("foo"); + } + }]); + return Foo; +}(); + +var _foo = babelHelpers.classPrivateFieldLooseKey("foo"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-computed-redeclared/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-computed-redeclared/exec.js new file mode 100644 index 000000000000..b42463f45085 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-computed-redeclared/exec.js @@ -0,0 +1,19 @@ +class Foo { + #foo = 1; + + test() { + class Nested { + #foo = 2; + + [this.#foo]() { + } + } + + return new Nested(); + } +} + +const f = new Foo(); +expect(() => { + f.test(); +}).toThrow(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-computed/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-computed/exec.js new file mode 100644 index 000000000000..937d281a8ecd --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-computed/exec.js @@ -0,0 +1,17 @@ +class Foo { + #foo = 1; + + test() { + class Nested { + [this.#foo]() { + } + } + + return new Nested(); + } +} + +const f = new Foo(); +expect(() => { + f.test(); +}).not.toThrow(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed-redeclared/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed-redeclared/exec.js new file mode 100644 index 000000000000..e6ecc61d0c65 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed-redeclared/exec.js @@ -0,0 +1,18 @@ +class Foo { + #foo = 1; + + test() { + class Nested extends class { + #foo = 2; + + [this.#foo] = 2; + } { + #foo = 3; + } + } +} + +const f = new Foo(); +expect(() => { + f.test(); +}).toThrow(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed-redeclared/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed-redeclared/input.js new file mode 100644 index 000000000000..8a57bd3eed55 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed-redeclared/input.js @@ -0,0 +1,12 @@ +class Foo { + #foo = 1; + + test() { + class Nested extends class { + #foo = 2; + [this.#foo] = 2; + } { + #foo = 3; + } + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed-redeclared/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed-redeclared/output.js new file mode 100644 index 000000000000..4048382eea90 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed-redeclared/output.js @@ -0,0 +1,61 @@ +var Foo = /*#__PURE__*/function () { + "use strict"; + + function Foo() { + babelHelpers.classCallCheck(this, Foo); + + _foo.set(this, { + writable: true, + value: 1 + }); + } + + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test() { + var _temp, _foo3; + + var _babelHelpers$classPr; + + var Nested = /*#__PURE__*/function (_ref) { + babelHelpers.inherits(Nested, _ref); + + var _super = babelHelpers.createSuper(Nested); + + function Nested(...args) { + var _this; + + babelHelpers.classCallCheck(this, Nested); + _this = _super.call(this, ...args); + + _foo2.set(babelHelpers.assertThisInitialized(_this), { + writable: true, + value: 3 + }); + + return _this; + } + + return Nested; + }((_temp = (_babelHelpers$classPr = babelHelpers.classPrivateFieldGet(this, _foo3), /*#__PURE__*/function () { + function _class2() { + babelHelpers.classCallCheck(this, _class2); + + _foo3.set(this, { + writable: true, + value: 2 + }); + + babelHelpers.defineProperty(this, _babelHelpers$classPr, 2); + } + + return _class2; + }()), _foo3 = new WeakMap(), _temp)); + + var _foo2 = new WeakMap(); + } + }]); + return Foo; +}(); + +var _foo = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed/exec.js new file mode 100644 index 000000000000..ab86e53ad557 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed/exec.js @@ -0,0 +1,18 @@ +class Foo { + #foo = 1; + + test() { + class Nested extends class { + [this.#foo] = 2; + } { + #foo = 3; + } + + return new Nested(); + } +} + +const f = new Foo(); +expect(() => { + f.test(); +}).not.toThrow(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed/input.js new file mode 100644 index 000000000000..80c5199085fd --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed/input.js @@ -0,0 +1,11 @@ +class Foo { + #foo = 1; + + test() { + class Nested extends class { + [this.#foo] = 2; + } { + #foo = 3; + } + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed/output.js new file mode 100644 index 000000000000..6f17afe6bbd3 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/nested-class-extends-computed/output.js @@ -0,0 +1,55 @@ +var Foo = /*#__PURE__*/function () { + "use strict"; + + function Foo() { + babelHelpers.classCallCheck(this, Foo); + + _foo.set(this, { + writable: true, + value: 1 + }); + } + + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test() { + var _temp; + + var _babelHelpers$classPr; + + var Nested = /*#__PURE__*/function (_ref) { + babelHelpers.inherits(Nested, _ref); + + var _super = babelHelpers.createSuper(Nested); + + function Nested(...args) { + var _this; + + babelHelpers.classCallCheck(this, Nested); + _this = _super.call(this, ...args); + + _foo2.set(babelHelpers.assertThisInitialized(_this), { + writable: true, + value: 3 + }); + + return _this; + } + + return Nested; + }((_temp = (_babelHelpers$classPr = babelHelpers.classPrivateFieldGet(this, _foo), /*#__PURE__*/function () { + function _class2() { + babelHelpers.classCallCheck(this, _class2); + babelHelpers.defineProperty(this, _babelHelpers$classPr, 2); + } + + return _class2; + }()), _temp)); + + var _foo2 = new WeakMap(); + } + }]); + return Foo; +}(); + +var _foo = new WeakMap();