diff --git a/packages/babel-helpers/src/helpers.js b/packages/babel-helpers/src/helpers.js index ffccbdd6373e..a972027af172 100644 --- a/packages/babel-helpers/src/helpers.js +++ b/packages/babel-helpers/src/helpers.js @@ -1011,3 +1011,12 @@ helpers.classPrivateFieldSet = () => template.program.ast` return value; } `; + +helpers.classStaticPrivateFieldBase = () => template.program.ast` + export default function _classStaticPrivateFieldBase(receiver, classConstructor, privateClass) { + if (receiver !== classConstructor && receiver.constructor !== classConstructor) { + throw new TypeError("Private static access of wrong provenance"); + } + return privateClass; + } +`; diff --git a/packages/babel-plugin-proposal-class-properties/src/index.js b/packages/babel-plugin-proposal-class-properties/src/index.js index d3c833c5e580..62ea9ec1ecfe 100644 --- a/packages/babel-plugin-proposal-class-properties/src/index.js +++ b/packages/babel-plugin-proposal-class-properties/src/index.js @@ -83,6 +83,18 @@ export default declare((api, options) => { }, }; + // Traverses the class scope, handling private static name references. + const staticPrivatePropertyVisitor = { + PrivateName(path) { + const { name } = this; + const { node, parentPath } = path; + if (node.id.name !== name) return; + if (parentPath.isMemberExpression({ property: node })) { + this.handle(parentPath); + } + }, + }; + // Traverses the outer portion of a class, without touching the class's inner // scope, for private names. const privateNameInnerVisitor = traverse.visitors.merge([ @@ -157,6 +169,23 @@ export default declare((api, options) => { }, }; + const staticPrivatePropertyHandler = { + handle(member) { + const { file, privateId, privateClassId, classRef } = this; + member.replaceWith( + template.expression`BASE(RECEIVER, CLASS, PRIVATE_CLASS_ID).PRIVATE_ID`( + { + BASE: file.addHelper("classStaticPrivateFieldBase"), + RECEIVER: member.node.object, + CLASS: classRef, + PRIVATE_CLASS_ID: privateClassId, + PRIVATE_ID: privateId, + }, + ), + ); + }, + }; + function buildClassPropertySpec(ref, path, state) { const { scope } = path; const { key, value, computed } = path.node; @@ -245,6 +274,64 @@ export default declare((api, options) => { }); } + function buildClassStaticPrivatePropertySpec( + ref, + path, + privateClassId, + state, + ) { + const { scope, parentPath } = path; + const { key, value } = path.node; + const { name } = key.id; + const privateId = scope.generateUidIdentifier(name); + + parentPath.traverse(staticPrivatePropertyVisitor, { + name, + privateId, + privateClassId, + classRef: ref, + file: state, + ...staticPrivatePropertyHandler, + }); + + return t.expressionStatement( + t.callExpression(state.addHelper("defineProperty"), [ + privateClassId, + t.stringLiteral(privateId.name), + value || scope.buildUndefinedNode(), + ]), + ); + } + + function buildClassStaticPrivatePropertyLoose( + ref, + path, + privateClassId, + state, + ) { + const { scope, parentPath } = path; + const { key, value } = path.node; + const { name } = key.id; + const privateId = scope.generateUidIdentifier(name); + + parentPath.traverse(staticPrivatePropertyVisitor, { + name, + privateId, + privateClassId, + classRef: ref, + file: state, + ...staticPrivatePropertyHandler, + }); + + return t.expressionStatement( + t.assignmentExpression( + "=", + t.memberExpression(privateClassId, privateId), + value || scope.buildUndefinedNode(), + ), + ); + } + const buildClassProperty = loose ? buildClassPropertyLoose : buildClassPropertySpec; @@ -253,6 +340,10 @@ export default declare((api, options) => { ? buildClassPrivatePropertyLoose : buildClassPrivatePropertySpec; + const buildClassStaticPrivateProperty = loose + ? buildClassStaticPrivatePropertyLoose + : buildClassStaticPrivatePropertySpec; + return { inherits: syntaxClassProperties, @@ -263,6 +354,7 @@ export default declare((api, options) => { const props = []; const computedPaths = []; const privateNames = new Set(); + const privateStaticNames = new Set(); const body = path.get("body"); for (const path of body.get("body")) { @@ -277,22 +369,21 @@ export default declare((api, options) => { } if (path.isClassPrivateProperty()) { - const { - static: isStatic, - key: { - id: { name }, - }, - } = path.node; + const { static: isStatic, key: { id: { name } } } = path.node; if (isStatic) { - throw path.buildCodeFrameError( - "Static class fields are not spec'ed yet.", - ); + if (privateStaticNames.has(name)) { + throw path.buildCodeFrameError( + "Duplicate static private field", + ); + } + privateStaticNames.add(name); + } else { + if (privateNames.has(name)) { + throw path.buildCodeFrameError("Duplicate private field"); + } + privateNames.add(name); } - if (privateNames.has(name)) { - throw path.buildCodeFrameError("Duplicate private field"); - } - privateNames.add(name); } if (path.isProperty()) { @@ -344,7 +435,7 @@ export default declare((api, options) => { const privateMaps = []; const privateMapInits = []; for (const prop of props) { - if (prop.isPrivate()) { + if (prop.isPrivate() && !prop.node.static) { const inits = []; privateMapInits.push(inits); @@ -354,10 +445,35 @@ export default declare((api, options) => { } } + // Create a private static "host" object + const privateClassId = path.scope.generateUidIdentifier( + ref.name + "Statics", + ); + if (privateStaticNames.size > 0) { + staticNodes.push( + template.statement`const PRIVATE_CLASS_ID = {};`({ + PRIVATE_CLASS_ID: privateClassId, + }), + ); + } + let p = 0; for (const prop of props) { if (prop.node.static) { - staticNodes.push(buildClassProperty(t.cloneNode(ref), prop, state)); + if (prop.isPrivate()) { + staticNodes.push( + buildClassStaticPrivateProperty( + t.cloneNode(ref), + prop, + privateClassId, + state, + ), + ); + } else { + staticNodes.push( + buildClassProperty(t.cloneNode(ref), prop, state), + ); + } } else if (prop.isPrivate()) { instanceBody.push(privateMaps[p]()); staticNodes.push(...privateMapInits[p]); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/output.js index b5e753c18619..9ce10ac3f049 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/output.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/output.js @@ -1,18 +1,37 @@ -var _foo, _bar; +var Foo = +/*#__PURE__*/ +function () { + "use strict"; -class Foo { - constructor() { + function Foo() { + babelHelpers.classCallCheck(this, Foo); Object.defineProperty(this, _bar, { writable: true, value: "bar" }); } -} + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test() { + return babelHelpers.classPrivateFieldLooseBase(this, _bar)[_bar]; + } + }], [{ + key: "test", + value: function test() { + return babelHelpers.classStaticPrivateFieldBase(Foo, Foo, _FooStatics)._foo; + } + }]); + return Foo; +}(); -_foo = babelHelpers.classPrivateFieldKey("foo"); -Object.defineProperty(Foo, _foo, { - writable: true, - value: "foo" -}); -_bar = babelHelpers.classPrivateFieldKey("bar"); +var _FooStatics = {}; +_FooStatics._foo = "foo"; + +var _bar = babelHelpers.classPrivateFieldLooseKey("bar"); + +var f = new Foo(); +expect("foo" in Foo).toBe(false); +expect("bar" in f).toBe(false); +expect(Foo.test()).toBe("foo"); +expect(f.test()).toBe("bar"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/output.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/output.mjs index 784e0909f55c..dab17c34e142 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/output.mjs +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/output.mjs @@ -1,25 +1,28 @@ export default (param => { - var _props, _class, _temp; + var _class, _temp; - return _temp = _class = - /*#__PURE__*/ - function () { - function App() { - babelHelpers.classCallCheck(this, App); - } - - babelHelpers.createClass(App, [{ - key: "getParam", - value: function getParam() { - return param; + return function () { + _temp = _class = + /*#__PURE__*/ + function () { + function App() { + babelHelpers.classCallCheck(this, App); } - }]); - return App; - }(), _props = babelHelpers.classPrivateFieldKey("props"), Object.defineProperty(_class, _props, { - writable: true, - value: { + + babelHelpers.createClass(App, [{ + key: "getParam", + value: function getParam() { + return param; + } + }]); + return App; + }(); + + var _classStatics = {}; + _classStatics._props = { prop1: 'prop1', prop2: 'prop2' - } - }), _temp; + }; + return _temp; + }(); }); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/output.js index 87651fcca894..72970d1f6fd0 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/output.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/output.js @@ -1,18 +1,66 @@ function classFactory() { - var _bar, _foo; + var _class, _temp; - var Foo = function Foo() { - babelHelpers.classCallCheck(this, Foo); - Object.defineProperty(this, _foo, { - writable: true, - value: "foo" - }); - }; + return function () { + _temp = _class = + /*#__PURE__*/ + function () { + "use strict"; - _bar = babelHelpers.classPrivateFieldKey("bar"); - Object.defineProperty(Foo, _bar, { - writable: true, - value: "bar" - }); - _foo = babelHelpers.classPrivateFieldKey("foo"); + function Foo() { + babelHelpers.classCallCheck(this, Foo); + Object.defineProperty(this, _foo, { + writable: true, + value: "foo" + }); + } + + babelHelpers.createClass(Foo, [{ + key: "instance", + value: function instance() { + return babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo]; + } + }, { + key: "static", + value: function _static() { + return babelHelpers.classStaticPrivateFieldBase(Foo, _class, _classStatics)._bar; + } + }], [{ + key: "instance", + value: function instance(inst) { + return babelHelpers.classPrivateFieldLooseBase(inst, _foo)[_foo]; + } + }, { + key: "static", + value: function _static() { + return babelHelpers.classStaticPrivateFieldBase(Foo, _class, _classStatics)._bar; + } + }]); + return Foo; + }(); + + var _classStatics = {}; + + var _foo = babelHelpers.classPrivateFieldLooseKey("foo"); + + _classStatics._bar = "bar"; + return _temp; + }(); } + +var Foo1 = classFactory(); +var Foo2 = classFactory(); +var f1 = new Foo1(); +var f2 = new Foo2(); +expect(f1.instance()).toBe("foo"); +expect(f1.static()).toBe("bar"); +expect(f2.instance()).toBe("foo"); +expect(f2.static()).toBe("bar"); +expect(Foo1.instance(f1)).toBe("foo"); +expect(Foo1.static()).toBe("bar"); +expect(Foo2.instance(f2)).toBe("foo"); +expect(Foo2.static()).toBe("bar"); +assert.throws(() => f1.instance.call(f2)); +assert.throws(() => f2.instance.call(f1)); +assert.throws(() => Foo1.instance(f2)); +assert.throws(() => Foo2.instance(f1)); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/output.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/output.mjs index 133132192bb5..1eaf18f61439 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/output.mjs +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/output.mjs @@ -1,21 +1,13 @@ -var _property, _property2; - export var MyClass = function MyClass() { babelHelpers.classCallCheck(this, MyClass); }; -_property = babelHelpers.classPrivateFieldKey("property"); -Object.defineProperty(MyClass, _property, { - writable: true, - value: value -}); +var _MyClassStatics = {}; +_MyClassStatics._property = value; var MyClass2 = function MyClass2() { babelHelpers.classCallCheck(this, MyClass2); }; -_property2 = babelHelpers.classPrivateFieldKey("property"); -Object.defineProperty(MyClass2, _property2, { - writable: true, - value: value -}); +var _MyClass2Statics = {}; +_MyClass2Statics._property2 = value; export { MyClass2 as default }; diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/output.js index 4b8ed2958b76..82d3b289207b 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/output.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/output.js @@ -1,8 +1,13 @@ -var _num, _class, _temp; +var _class, _temp; -var Foo = (_temp = _class = function Foo() { - babelHelpers.classCallCheck(this, Foo); -}, _num = babelHelpers.classPrivateFieldKey("num"), Object.defineProperty(_class, _num, { - writable: true, - value: 0 -}), _temp); +var Foo = function () { + _temp = _class = function Foo() { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + }; + + var _classStatics = {}; + _classStatics._num = 0; + return _temp; +}(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/exec.js new file mode 100644 index 000000000000..e8dd45d17f3d --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/exec.js @@ -0,0 +1,70 @@ +class Base { + static #foo = 1; + + static getThis() { + return this.#foo; + } + + static updateThis(val) { + return this.#foo = val; + } + + static getClass() { + return Base.#foo; + } + + static updateClass(val) { + return Base.#foo = val; + } +} + +class Sub1 extends Base { + static #foo = 2; + + static update(val) { + return this.#foo = val; + } +} + +class Sub2 extends Base { +} + +expect(Base.getThis()).toBe(1); +expect(Base.getClass()).toBe(1); +expect(() => Sub1.getThis()).toThrow(); +expect(Sub1.getClass()).toBe(1); +expect(() => Sub2.getThis()).toThrow(); +expect(Sub2.getClass()).toBe(1); + +expect(Sub1.update(3)).toBe(3); +expect(Base.getThis()).toBe(1); +expect(Base.getClass()).toBe(1); +expect(() => Sub1.getThis()).toThrow(); +expect(Sub1.getClass()).toBe(1); +expect(() => Sub2.getThis()).toThrow(); +expect(Sub2.getClass()).toBe(1); + +expect(Base.updateThis(4)).toBe(4); +expect(Base.getThis()).toBe(4); +expect(Base.getClass()).toBe(4); +expect(() => Sub1.getThis()).toThrow(); +expect(Sub1.getClass()).toBe(4); +expect(() => Sub2.getThis()).toThrow(); +expect(Sub2.getClass()).toBe(4); + +expect(Base.updateClass(5)).toBe(5); +expect(Base.getThis()).toBe(5); +expect(Base.getClass()).toBe(5); +expect(() => Sub1.getThis()).toThrow(); +expect(Sub1.getClass()).toBe(5); +expect(() => Sub2.getThis()).toThrow(); +expect(Sub2.getClass()).toBe(5); + +expect(() => Sub2.updateThis(6)).toThrow(); +expect(Sub2.updateClass(7)).toBe(7); +expect(Base.getThis()).toBe(7); +expect(Base.getClass()).toBe(7); +expect(() => Sub1.getThis()).toThrow(); +expect(Sub1.getClass()).toBe(7); +expect(() => Sub2.getThis()).toThrow(); +expect(Sub2.getClass()).toBe(7); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/input.js index 66202d9f9d4f..f7b5406571b9 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/input.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/input.js @@ -28,43 +28,3 @@ class Sub1 extends Base { class Sub2 extends Base { } - -expect(Base.getThis()).toBe(1); -expect(Base.getClass()).toBe(1); -assert.throws(() => Sub1.getThis()); -expect(Sub1.getClass()).toBe(1); -assert.throws(() => Sub2.getThis()); -expect(Sub2.getClass()).toBe(1); - -expect(Sub1.update(3)).toBe(3); -expect(Base.getThis()).toBe(1); -expect(Base.getClass()).toBe(1); -assert.throws(() => Sub1.getThis()); -expect(Sub1.getClass()).toBe(1); -assert.throws(() => Sub2.getThis()); -expect(Sub2.getClass()).toBe(1); - -expect(Base.updateThis(4)).toBe(4); -expect(Base.getThis()).toBe(4); -expect(Base.getClass()).toBe(4); -assert.throws(() => Sub1.getThis()); -expect(Sub1.getClass()).toBe(4); -assert.throws(() => Sub2.getThis()); -expect(Sub2.getClass()).toBe(4); - -expect(Base.updateClass(5)).toBe(5); -expect(Base.getThis()).toBe(5); -expect(Base.getClass()).toBe(5); -assert.throws(() => Sub1.getThis()); -expect(Sub1.getClass()).toBe(5); -assert.throws(() => Sub2.getThis()); -expect(Sub2.getClass()).toBe(5); - -assert.throws(() => Sub2.updateThis(6)); -expect(Sub2.updateClass(7)).toBe(7); -expect(Base.getThis()).toBe(7); -expect(Base.getClass()).toBe(7); -assert.throws(() => Sub1.getThis()); -expect(Sub1.getClass()).toBe(7); -assert.throws(() => Sub2.getThis()); -expect(Sub2.getClass()).toBe(7); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/output.js index 5510c2aa9e60..b9986bfdf6bb 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/output.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/output.js @@ -1,54 +1,73 @@ -var _foo, _foo2; - var Base = /*#__PURE__*/ function () { + "use strict"; + function Base() { babelHelpers.classCallCheck(this, Base); } babelHelpers.createClass(Base, null, [{ - key: "m", - value: function m() { - return babelHelpers.classPrivateFieldBase(this, _foo)[_foo]; + key: "getThis", + value: function getThis() { + return babelHelpers.classStaticPrivateFieldBase(this, Base, _BaseStatics)._foo; + } + }, { + key: "updateThis", + value: function updateThis(val) { + return babelHelpers.classStaticPrivateFieldBase(this, Base, _BaseStatics)._foo = val; + } + }, { + key: "getClass", + value: function getClass() { + return babelHelpers.classStaticPrivateFieldBase(Base, Base, _BaseStatics)._foo; + } + }, { + key: "updateClass", + value: function updateClass(val) { + return babelHelpers.classStaticPrivateFieldBase(Base, Base, _BaseStatics)._foo = val; } }]); return Base; }(); -_foo = babelHelpers.classPrivateFieldKey("foo"); -Object.defineProperty(Base, _foo, { - writable: true, - value: 1 -}); +var _BaseStatics = {}; +_BaseStatics._foo = 1; var Sub1 = /*#__PURE__*/ function (_Base) { + "use strict"; + babelHelpers.inherits(Sub1, _Base); function Sub1() { babelHelpers.classCallCheck(this, Sub1); - return babelHelpers.possibleConstructorReturn(this, (Sub1.__proto__ || Object.getPrototypeOf(Sub1)).apply(this, arguments)); + return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Sub1).apply(this, arguments)); } + babelHelpers.createClass(Sub1, null, [{ + key: "update", + value: function update(val) { + return babelHelpers.classStaticPrivateFieldBase(this, Sub1, _Sub1Statics)._foo2 = val; + } + }]); return Sub1; }(Base); -_foo2 = babelHelpers.classPrivateFieldKey("foo"); -Object.defineProperty(Sub1, _foo2, { - writable: true, - value: 2 -}); +var _Sub1Statics = {}; +_Sub1Statics._foo2 = 2; var Sub2 = /*#__PURE__*/ function (_Base2) { + "use strict"; + babelHelpers.inherits(Sub2, _Base2); function Sub2() { babelHelpers.classCallCheck(this, Sub2); - return babelHelpers.possibleConstructorReturn(this, (Sub2.__proto__ || Object.getPrototypeOf(Sub2)).apply(this, arguments)); + return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Sub2).apply(this, arguments)); } return Sub2; diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/exec.js new file mode 100644 index 000000000000..d63968889855 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/exec.js @@ -0,0 +1,15 @@ +class Foo { + static #bar; + + static test() { + return Foo.#bar; + } + + test() { + return Foo.#bar; + } +} + +expect("bar" in Foo).toBe(false) +expect(Foo.test()).toBe(undefined) +expect(Foo.test()).toBe(undefined) diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/input.js index d63968889855..1f475fcdab1e 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/input.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/input.js @@ -9,7 +9,3 @@ class Foo { return Foo.#bar; } } - -expect("bar" in Foo).toBe(false) -expect(Foo.test()).toBe(undefined) -expect(Foo.test()).toBe(undefined) diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/output.js index 4db5076cd4ca..360d5835b48b 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/output.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/output.js @@ -1,11 +1,25 @@ -var _bar; +var Foo = +/*#__PURE__*/ +function () { + "use strict"; -var Foo = function Foo() { - babelHelpers.classCallCheck(this, Foo); -}; + function Foo() { + babelHelpers.classCallCheck(this, Foo); + } -_bar = babelHelpers.classPrivateFieldKey("bar"); -Object.defineProperty(Foo, _bar, { - writable: true, - value: void 0 -}); + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test() { + return babelHelpers.classStaticPrivateFieldBase(Foo, Foo, _FooStatics)._bar; + } + }], [{ + key: "test", + value: function test() { + return babelHelpers.classStaticPrivateFieldBase(Foo, Foo, _FooStatics)._bar; + } + }]); + return Foo; +}(); + +var _FooStatics = {}; +_FooStatics._bar = void 0; diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/exec.js new file mode 100644 index 000000000000..c905fa85d589 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/exec.js @@ -0,0 +1,15 @@ +class Foo { + static #bar = "foo"; + + static test() { + return Foo.#bar; + } + + test() { + return Foo.#bar; + } +} + +expect("bar" in Foo).toBe(false) +expect(Foo.test()).toBe("foo") +expect(Foo.test()).toBe("foo") diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/input.js index c905fa85d589..3497e0c62cda 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/input.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/input.js @@ -9,7 +9,3 @@ class Foo { return Foo.#bar; } } - -expect("bar" in Foo).toBe(false) -expect(Foo.test()).toBe("foo") -expect(Foo.test()).toBe("foo") diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/output.js index 5ef62d69ad8c..1ce788f31667 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/output.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/output.js @@ -1,8 +1,8 @@ -var _bar; - var Foo = /*#__PURE__*/ function () { + "use strict"; + function Foo() { babelHelpers.classCallCheck(this, Foo); } @@ -10,19 +10,16 @@ function () { babelHelpers.createClass(Foo, [{ key: "test", value: function test() { - return babelHelpers.classPrivateFieldBase(Foo, _bar)[_bar]; + return babelHelpers.classStaticPrivateFieldBase(Foo, Foo, _FooStatics)._bar; } }], [{ key: "test", value: function test() { - return babelHelpers.classPrivateFieldBase(Foo, _bar)[_bar]; + return babelHelpers.classStaticPrivateFieldBase(Foo, Foo, _FooStatics)._bar; } }]); return Foo; }(); -_bar = babelHelpers.classPrivateFieldKey("bar"); -Object.defineProperty(Foo, _bar, { - writable: true, - value: "foo" -}); +var _FooStatics = {}; +_FooStatics._bar = "foo"; diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/exec.js new file mode 100644 index 000000000000..f89f5d052243 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/exec.js @@ -0,0 +1,18 @@ +class Foo { + static #foo = "foo"; + #bar = "bar"; + + static test() { + return Foo.#foo; + } + + test() { + return this.#bar; + } +} + +const f = new Foo(); +expect("foo" in Foo).toBe(false); +expect("bar" in f).toBe(false); +expect(Foo.test()).toBe("foo"); +expect(f.test()).toBe("bar"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/input.js index e0c4dfe70b3b..38d90873400b 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/input.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/input.js @@ -10,9 +10,3 @@ class Foo { return this.#bar; } } - -const f = new Foo(); -expect("foo" in Foo).toBe(false) -expect("bar" in f).toBe(false) -expect(Foo.test()).toBe("foo") -expect(f.test()).toBe("bar") diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/output.js index f90dee5679a6..4a7bed122b54 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/output.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/output.js @@ -1,14 +1,29 @@ -var _foo, _bar; +var Foo = +/*#__PURE__*/ +function () { + "use strict"; + + function Foo() { + babelHelpers.classCallCheck(this, Foo); -class Foo { - constructor() { _bar.set(this, "bar"); } -} - -_foo = new WeakMap(); + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test() { + return babelHelpers.classPrivateFieldGet(this, _bar); + } + }], [{ + key: "test", + value: function test() { + return babelHelpers.classStaticPrivateFieldBase(Foo, Foo, _FooStatics)._foo; + } + }]); + return Foo; +}(); -_foo.set(Foo, "foo"); +var _FooStatics = {}; +babelHelpers.defineProperty(_FooStatics, "_foo", "foo"); -_bar = new WeakMap(); +var _bar = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/output.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/output.mjs index e69c069b88bf..daf61178ef25 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/output.mjs +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/output.mjs @@ -1,22 +1,28 @@ export default (param => { - var _props, _class, _temp; + var _class, _temp; - return _temp = _class = - /*#__PURE__*/ - function () { - function App() { - babelHelpers.classCallCheck(this, App); - } - - babelHelpers.createClass(App, [{ - key: "getParam", - value: function getParam() { - return param; + return function () { + _temp = _class = + /*#__PURE__*/ + function () { + function App() { + babelHelpers.classCallCheck(this, App); } - }]); - return App; - }(), _props = new WeakMap(), _props.set(_class, { - prop1: 'prop1', - prop2: 'prop2' - }), _temp; + + babelHelpers.createClass(App, [{ + key: "getParam", + value: function getParam() { + return param; + } + }]); + return App; + }(); + + var _classStatics = {}; + babelHelpers.defineProperty(_classStatics, "_props", { + prop1: 'prop1', + prop2: 'prop2' + }); + return _temp; + }(); }); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/exec.js new file mode 100644 index 000000000000..d570ad6bad56 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/exec.js @@ -0,0 +1,51 @@ +function classFactory() { + return class Foo { + #foo = "foo"; + static #bar = "bar"; + + instance() { + return this.#foo; + } + + static() { + return Foo.#bar; + } + + static instance(inst) { + return inst.#foo; + } + + static static() { + return Foo.#bar; + } + }; +} + +const Foo1 = classFactory(); +const Foo2 = classFactory(); + +const f1 = new Foo1(); +const f2 = new Foo2(); + +expect(f1.instance()).toBe("foo"); +expect(f1.static()).toBe("bar"); +expect(f2.instance()).toBe("foo"); +expect(f2.static()).toBe("bar"); + +expect(Foo1.instance(f1)).toBe("foo"); +expect(Foo1.static()).toBe("bar"); +expect(Foo2.instance(f2)).toBe("foo"); +expect(Foo2.static()).toBe("bar"); + +expect(() => { + f1.instance.call(f2), undefined; +}).toThrow(); +expect(() => { + f2.instance.call(f1), undefined; +}).toThrow(); +expect(() => { + Foo1.instance(f2), undefined; +}); +expect(() => { + Foo2.instance(f1), undefined; +}).toThrow(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/input.js index 9e8222eb71ba..1adebbee2793 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/input.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/input.js @@ -18,34 +18,5 @@ function classFactory() { static static() { return Foo.#bar; } - } + }; } - -const Foo1 = classFactory(); -const Foo2 = classFactory(); - -const f1 = new Foo1; -const f2 = new Foo2; - -expect(f1.instance()).toBe("foo"); -expect(f1.static()).toBe("bar"); -expect(f2.instance()).toBe("foo"); -expect(f2.static()).toBe("bar"); - -expect(Foo1.instance(f1)).toBe("foo"); -expect(Foo1.static()).toBe("bar"); -expect(Foo2.instance(f2)).toBe("foo"); -expect(Foo2.static()).toBe("bar"); - -assert.throws(() => { - f1.instance.call(f2), undefined; -}); -assert.throws(() => { - f2.instance.call(f1), undefined; -}); -assert.throws(() => { - Foo1.instance(f2), undefined; -}); -assert.throws(() => { - Foo2.instance(f1), undefined; -}); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/output.js index abfb86e72fff..250af0c7b0e7 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/output.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/output.js @@ -1,15 +1,47 @@ function classFactory() { - var _bar, _foo; + var _class, _temp; - var Foo = function Foo() { - babelHelpers.classCallCheck(this, Foo); + return function () { + _temp = _class = + /*#__PURE__*/ + function () { + "use strict"; - _foo.set(this, "foo"); - }; + function Foo() { + babelHelpers.classCallCheck(this, Foo); - _bar = new WeakMap(); + _foo.set(this, "foo"); + } - _bar.set(Foo, "bar"); + babelHelpers.createClass(Foo, [{ + key: "instance", + value: function instance() { + return babelHelpers.classPrivateFieldGet(this, _foo); + } + }, { + key: "static", + value: function _static() { + return babelHelpers.classStaticPrivateFieldBase(Foo, _class, _classStatics)._bar; + } + }], [{ + key: "instance", + value: function instance(inst) { + return babelHelpers.classPrivateFieldGet(inst, _foo); + } + }, { + key: "static", + value: function _static() { + return babelHelpers.classStaticPrivateFieldBase(Foo, _class, _classStatics)._bar; + } + }]); + return Foo; + }(); - _foo = new WeakMap(); + var _classStatics = {}; + + var _foo = new WeakMap(); + + babelHelpers.defineProperty(_classStatics, "_bar", "bar"); + return _temp; + }(); } diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/output.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/output.mjs index ea8020b0beab..36b879b8e186 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/output.mjs +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/output.mjs @@ -1,16 +1,20 @@ -var _test, _class, _temp, _test2; +var _class, _temp; -call((_temp = _class = function _class() { - babelHelpers.classCallCheck(this, _class); -}, _test = new WeakMap(), _test.set(_class, true), _temp)); +call(function () { + _temp = _class = function _class() { + babelHelpers.classCallCheck(this, _class); + }; + + var _classStatics = {}; + babelHelpers.defineProperty(_classStatics, "_test", true); + return _temp; +}()); var _default = function _default() { babelHelpers.classCallCheck(this, _default); }; -_test2 = new WeakMap(); - -_test2.set(_default, true); - +var _defaultStatics = {}; +babelHelpers.defineProperty(_defaultStatics, "_test2", true); export { _default as default }; ; diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/output.js index 553fcaf28ae6..36a67f66241f 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/output.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/output.js @@ -1,22 +1,30 @@ function withContext(ComposedComponent) { - var _propTypes, _class, _temp; + var _class, _temp; - return _temp = _class = - /*#__PURE__*/ - function (_Component) { - babelHelpers.inherits(WithContext, _Component); + return function () { + _temp = _class = + /*#__PURE__*/ + function (_Component) { + "use strict"; - function WithContext() { - babelHelpers.classCallCheck(this, WithContext); - return babelHelpers.possibleConstructorReturn(this, (WithContext.__proto__ || Object.getPrototypeOf(WithContext)).apply(this, arguments)); - } + babelHelpers.inherits(WithContext, _Component); - return WithContext; - }(Component), _propTypes = new WeakMap(), _propTypes.set(_class, { - context: PropTypes.shape({ - addCss: PropTypes.func, - setTitle: PropTypes.func, - setMeta: PropTypes.func - }) - }), _temp; -} \ No newline at end of file + function WithContext() { + babelHelpers.classCallCheck(this, WithContext); + return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(WithContext).apply(this, arguments)); + } + + return WithContext; + }(Component); + + var _classStatics = {}; + babelHelpers.defineProperty(_classStatics, "_propTypes", { + context: PropTypes.shape({ + addCss: PropTypes.func, + setTitle: PropTypes.func, + setMeta: PropTypes.func + }) + }); + return _temp; + }(); +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/output.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/output.mjs index 39d6c7cdd5ea..082adc8df211 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/output.mjs +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/output.mjs @@ -1,18 +1,13 @@ -var _property, _property2; - export var MyClass = function MyClass() { babelHelpers.classCallCheck(this, MyClass); }; -_property = new WeakMap(); - -_property.set(MyClass, value); +var _MyClassStatics = {}; +babelHelpers.defineProperty(_MyClassStatics, "_property", value); var MyClass2 = function MyClass2() { babelHelpers.classCallCheck(this, MyClass2); }; -_property2 = new WeakMap(); - -_property2.set(MyClass2, value); - +var _MyClass2Statics = {}; +babelHelpers.defineProperty(_MyClass2Statics, "_property2", value); export { MyClass2 as default }; diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/output.js index 16272497af40..0140c2a01456 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/output.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/output.js @@ -1,5 +1,13 @@ -var _num, _class, _temp; +var _class, _temp; -var Foo = (_temp = _class = function Foo() { - babelHelpers.classCallCheck(this, Foo); -}, _num = new WeakMap(), _num.set(_class, 0), _temp); +var Foo = function () { + _temp = _class = function Foo() { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + }; + + var _classStatics = {}; + babelHelpers.defineProperty(_classStatics, "_num", 0); + return _temp; +}(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/exec.js new file mode 100644 index 000000000000..e8dd45d17f3d --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/exec.js @@ -0,0 +1,70 @@ +class Base { + static #foo = 1; + + static getThis() { + return this.#foo; + } + + static updateThis(val) { + return this.#foo = val; + } + + static getClass() { + return Base.#foo; + } + + static updateClass(val) { + return Base.#foo = val; + } +} + +class Sub1 extends Base { + static #foo = 2; + + static update(val) { + return this.#foo = val; + } +} + +class Sub2 extends Base { +} + +expect(Base.getThis()).toBe(1); +expect(Base.getClass()).toBe(1); +expect(() => Sub1.getThis()).toThrow(); +expect(Sub1.getClass()).toBe(1); +expect(() => Sub2.getThis()).toThrow(); +expect(Sub2.getClass()).toBe(1); + +expect(Sub1.update(3)).toBe(3); +expect(Base.getThis()).toBe(1); +expect(Base.getClass()).toBe(1); +expect(() => Sub1.getThis()).toThrow(); +expect(Sub1.getClass()).toBe(1); +expect(() => Sub2.getThis()).toThrow(); +expect(Sub2.getClass()).toBe(1); + +expect(Base.updateThis(4)).toBe(4); +expect(Base.getThis()).toBe(4); +expect(Base.getClass()).toBe(4); +expect(() => Sub1.getThis()).toThrow(); +expect(Sub1.getClass()).toBe(4); +expect(() => Sub2.getThis()).toThrow(); +expect(Sub2.getClass()).toBe(4); + +expect(Base.updateClass(5)).toBe(5); +expect(Base.getThis()).toBe(5); +expect(Base.getClass()).toBe(5); +expect(() => Sub1.getThis()).toThrow(); +expect(Sub1.getClass()).toBe(5); +expect(() => Sub2.getThis()).toThrow(); +expect(Sub2.getClass()).toBe(5); + +expect(() => Sub2.updateThis(6)).toThrow(); +expect(Sub2.updateClass(7)).toBe(7); +expect(Base.getThis()).toBe(7); +expect(Base.getClass()).toBe(7); +expect(() => Sub1.getThis()).toThrow(); +expect(Sub1.getClass()).toBe(7); +expect(() => Sub2.getThis()).toThrow(); +expect(Sub2.getClass()).toBe(7); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/output.js index e395c0915fee..a53df2564062 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/output.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/output.js @@ -1,51 +1,110 @@ -var _foo, _foo2; - var Base = /*#__PURE__*/ function () { + "use strict"; + function Base() { babelHelpers.classCallCheck(this, Base); } babelHelpers.createClass(Base, null, [{ - key: "m", - value: function m() { - return babelHelpers.classPrivateFieldGet(this, _foo); + key: "getThis", + value: function getThis() { + return babelHelpers.classStaticPrivateFieldBase(this, Base, _BaseStatics)._foo; + } + }, { + key: "updateThis", + value: function updateThis(val) { + return babelHelpers.classStaticPrivateFieldBase(this, Base, _BaseStatics)._foo = val; + } + }, { + key: "getClass", + value: function getClass() { + return babelHelpers.classStaticPrivateFieldBase(Base, Base, _BaseStatics)._foo; + } + }, { + key: "updateClass", + value: function updateClass(val) { + return babelHelpers.classStaticPrivateFieldBase(Base, Base, _BaseStatics)._foo = val; } }]); return Base; }(); -_foo = new WeakMap(); - -_foo.set(Base, 1); +var _BaseStatics = {}; +babelHelpers.defineProperty(_BaseStatics, "_foo", 1); var Sub1 = /*#__PURE__*/ function (_Base) { + "use strict"; + babelHelpers.inherits(Sub1, _Base); function Sub1() { babelHelpers.classCallCheck(this, Sub1); - return babelHelpers.possibleConstructorReturn(this, (Sub1.__proto__ || Object.getPrototypeOf(Sub1)).apply(this, arguments)); + return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Sub1).apply(this, arguments)); } + babelHelpers.createClass(Sub1, null, [{ + key: "update", + value: function update(val) { + return babelHelpers.classStaticPrivateFieldBase(this, Sub1, _Sub1Statics)._foo2 = val; + } + }]); return Sub1; }(Base); -_foo2 = new WeakMap(); - -_foo2.set(Sub1, 2); +var _Sub1Statics = {}; +babelHelpers.defineProperty(_Sub1Statics, "_foo2", 2); var Sub2 = /*#__PURE__*/ function (_Base2) { + "use strict"; + babelHelpers.inherits(Sub2, _Base2); function Sub2() { babelHelpers.classCallCheck(this, Sub2); - return babelHelpers.possibleConstructorReturn(this, (Sub2.__proto__ || Object.getPrototypeOf(Sub2)).apply(this, arguments)); + return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Sub2).apply(this, arguments)); } return Sub2; }(Base); + +expect(Base.getThis()).toBe(1); +expect(Base.getClass()).toBe(1); +assert.throws(() => Sub1.getThis()); +expect(Sub1.getClass()).toBe(1); +assert.throws(() => Sub2.getThis()); +expect(Sub2.getClass()).toBe(1); +expect(Sub1.update(3)).toBe(3); +expect(Base.getThis()).toBe(1); +expect(Base.getClass()).toBe(1); +assert.throws(() => Sub1.getThis()); +expect(Sub1.getClass()).toBe(1); +assert.throws(() => Sub2.getThis()); +expect(Sub2.getClass()).toBe(1); +expect(Base.updateThis(4)).toBe(4); +expect(Base.getThis()).toBe(4); +expect(Base.getClass()).toBe(4); +assert.throws(() => Sub1.getThis()); +expect(Sub1.getClass()).toBe(4); +assert.throws(() => Sub2.getThis()); +expect(Sub2.getClass()).toBe(4); +expect(Base.updateClass(5)).toBe(5); +expect(Base.getThis()).toBe(5); +expect(Base.getClass()).toBe(5); +assert.throws(() => Sub1.getThis()); +expect(Sub1.getClass()).toBe(5); +assert.throws(() => Sub2.getThis()); +expect(Sub2.getClass()).toBe(5); +assert.throws(() => Sub2.updateThis(6)); +expect(Sub2.updateClass(7)).toBe(7); +expect(Base.getThis()).toBe(7); +expect(Base.getClass()).toBe(7); +assert.throws(() => Sub1.getThis()); +expect(Sub1.getClass()).toBe(7); +assert.throws(() => Sub2.getThis()); +expect(Sub2.getClass()).toBe(7); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/exec.js new file mode 100644 index 000000000000..d63968889855 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/exec.js @@ -0,0 +1,15 @@ +class Foo { + static #bar; + + static test() { + return Foo.#bar; + } + + test() { + return Foo.#bar; + } +} + +expect("bar" in Foo).toBe(false) +expect(Foo.test()).toBe(undefined) +expect(Foo.test()).toBe(undefined) diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/input.js index d63968889855..1f475fcdab1e 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/input.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/input.js @@ -9,7 +9,3 @@ class Foo { return Foo.#bar; } } - -expect("bar" in Foo).toBe(false) -expect(Foo.test()).toBe(undefined) -expect(Foo.test()).toBe(undefined) diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/output.js index 18919169845f..af55e6bfd131 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/output.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/output.js @@ -1,9 +1,25 @@ -var _bar; +var Foo = +/*#__PURE__*/ +function () { + "use strict"; -var Foo = function Foo() { - babelHelpers.classCallCheck(this, Foo); -}; + function Foo() { + babelHelpers.classCallCheck(this, Foo); + } -_bar = new WeakMap(); + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test() { + return babelHelpers.classStaticPrivateFieldBase(Foo, Foo, _FooStatics)._bar; + } + }], [{ + key: "test", + value: function test() { + return babelHelpers.classStaticPrivateFieldBase(Foo, Foo, _FooStatics)._bar; + } + }]); + return Foo; +}(); -_bar.set(Foo, void 0); +var _FooStatics = {}; +babelHelpers.defineProperty(_FooStatics, "_bar", void 0); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/options.json deleted file mode 100644 index 03872554afb3..000000000000 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Static class fields are not spec'ed yet." -} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/output.js index 47430af8afbf..fcb0181bf91b 100644 --- a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/output.js +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/output.js @@ -1,8 +1,8 @@ -var _bar; - var Foo = /*#__PURE__*/ function () { + "use strict"; + function Foo() { babelHelpers.classCallCheck(this, Foo); } @@ -10,17 +10,19 @@ function () { babelHelpers.createClass(Foo, [{ key: "test", value: function test() { - return babelHelpers.classPrivateFieldGet(Foo, _bar); + return babelHelpers.classStaticPrivateFieldBase(Foo, Foo, _FooStatics)._bar; } }], [{ key: "test", value: function test() { - return babelHelpers.classPrivateFieldGet(Foo, _bar); + return babelHelpers.classStaticPrivateFieldBase(Foo, Foo, _FooStatics)._bar; } }]); return Foo; }(); -_bar = new WeakMap(); - -_bar.set(Foo, "foo"); +var _FooStatics = {}; +babelHelpers.defineProperty(_FooStatics, "_bar", "foo"); +expect("bar" in Foo).toBe(false); +expect(Foo.test()).toBe("foo"); +expect(Foo.test()).toBe("foo");