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

Mark class prototype as read-only #12115

Merged
merged 7 commits into from Dec 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -14,6 +14,9 @@
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
Object.defineProperty(Constructor, "prototype", {
writable: false
Copy link
Contributor

Choose a reason for hiding this comment

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

The writable defaults to false when a property is defined by Object.defineProperty. Since helper is shipped in user code. We can just call
Object.defineProperty(Constructor, "prototype", {}).

Copy link
Member

Choose a reason for hiding this comment

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

Given that this function can be shimmed, and writability might not be supported (in es5-sham, it throws), this is a good change.

Copy link
Member

Choose a reason for hiding this comment

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

It defaults to false only if the property does not exist yet:

function F() {}
Object.defineProperty(F, "prototype", {});
Object.getOwnPropertyDescriptor(F, "prototype").writable; // true

});
return Constructor;
}

Expand Down
Expand Up @@ -16,5 +16,5 @@ var Foo = /*#__PURE__*/function (_Bar) {
return _super.call(this, parentOptions);
}

return Foo;
return babelHelpers.createClass(Foo);
}(Bar);
16 changes: 10 additions & 6 deletions packages/babel-helpers/src/helpers.ts
Expand Up @@ -223,6 +223,7 @@ helpers.createClass = helper("7.0.0-beta.0")`
export default function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
Object.defineProperty(Constructor, "prototype", { writable: false });
return Constructor;
}
`;
Expand Down Expand Up @@ -334,12 +335,15 @@ helpers.inherits = helper("7.0.0-beta.0")`
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
Object.defineProperty(subClass, "prototype", {
value: Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
}),
writable: false,
});
if (superClass) setPrototypeOf(subClass, superClass);
}
Expand Down
Expand Up @@ -18,5 +18,5 @@ var Child = /*#__PURE__*/function (_Parent) {
return _this;
}

return Child;
return babelHelpers.createClass(Child);
}(Parent);
Expand Up @@ -5,14 +5,14 @@ function dec() {} // Create a local function binding so babel has to change the

function _defineProperty() {}

let A = (_class = function A() {
let A = (_class = /*#__PURE__*/babelHelpers.createClass(function A() {
"use strict";

babelHelpers.classCallCheck(this, A);
babelHelpers.initializerDefineProperty(this, "a", _descriptor, this);
babelHelpers.initializerDefineProperty(this, "b", _descriptor2, this);
babelHelpers.defineProperty(this, "c", 456);
}, (_descriptor = babelHelpers.applyDecoratedDescriptor(_class.prototype, "a", [dec], {
}), (_descriptor = babelHelpers.applyDecoratedDescriptor(_class.prototype, "a", [dec], {
configurable: true,
enumerable: true,
writable: true,
Expand Down
Expand Up @@ -2,14 +2,14 @@ var _class, _descriptor, _descriptor2;

function dec() {}

let A = (_class = function A() {
let A = (_class = /*#__PURE__*/babelHelpers.createClass(function A() {
"use strict";

babelHelpers.classCallCheck(this, A);
babelHelpers.initializerDefineProperty(this, "a", _descriptor, this);
babelHelpers.initializerDefineProperty(this, "b", _descriptor2, this);
this.c = 456;
}, (_descriptor = babelHelpers.applyDecoratedDescriptor(_class.prototype, "a", [dec], {
}), (_descriptor = babelHelpers.applyDecoratedDescriptor(_class.prototype, "a", [dec], {
configurable: true,
enumerable: true,
writable: true,
Expand Down
Expand Up @@ -2,14 +2,14 @@ var _class, _descriptor, _descriptor2;

function dec() {}

let A = (_class = function A() {
let A = (_class = /*#__PURE__*/babelHelpers.createClass(function A() {
"use strict";

babelHelpers.classCallCheck(this, A);
babelHelpers.initializerDefineProperty(this, "a", _descriptor, this);
babelHelpers.initializerDefineProperty(this, "b", _descriptor2, this);
babelHelpers.defineProperty(this, "c", 456);
}, (_descriptor = babelHelpers.applyDecoratedDescriptor(_class.prototype, "a", [dec], {
}), (_descriptor = babelHelpers.applyDecoratedDescriptor(_class.prototype, "a", [dec], {
configurable: true,
enumerable: true,
writable: true,
Expand Down
@@ -1,14 +1,14 @@
"use strict";

let Hello = function Hello() {
let Hello = /*#__PURE__*/babelHelpers.createClass(function Hello() {
babelHelpers.classCallCheck(this, Hello);
return {
toString() {
return 'hello';
}

};
};
});

let Outer = /*#__PURE__*/function (_Hello) {
babelHelpers.inherits(Outer, _Hello);
Expand All @@ -22,16 +22,14 @@ let Outer = /*#__PURE__*/function (_Hello) {

babelHelpers.classCallCheck(this, Outer);
_this2 = _this = _super.call(this);

let Inner = function Inner() {
let Inner = /*#__PURE__*/babelHelpers.createClass(function Inner() {
babelHelpers.classCallCheck(this, Inner);
babelHelpers.defineProperty(this, _this2, "hello");
};

});
return babelHelpers.possibleConstructorReturn(_this, new Inner());
}

return Outer;
return babelHelpers.createClass(Outer);
}(Hello);

expect(new Outer().hello).toBe('hello');
Expand Up @@ -27,16 +27,14 @@ let Outer = /*#__PURE__*/function (_Hello) {
babelHelpers.classCallCheck(this, Outer);
_this = _super.call(this);
_babelHelpers$get$cal = babelHelpers.get((_thisSuper = babelHelpers.assertThisInitialized(_this), babelHelpers.getPrototypeOf(Outer.prototype)), "toString", _thisSuper).call(_thisSuper);

let Inner = function Inner() {
let Inner = /*#__PURE__*/babelHelpers.createClass(function Inner() {
babelHelpers.classCallCheck(this, Inner);
babelHelpers.defineProperty(this, _babelHelpers$get$cal, 'hello');
};

});
return babelHelpers.possibleConstructorReturn(_this, new Inner());
}

return Outer;
return babelHelpers.createClass(Outer);
}(Hello);

expect(new Outer().hello).toBe('hello');
Expand Up @@ -2,7 +2,7 @@ var foo = "bar";

var _bar = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("bar");

var Foo = function Foo() {
var Foo = /*#__PURE__*/babelHelpers.createClass(function Foo() {
"use strict";

babelHelpers.classCallCheck(this, Foo);
Expand All @@ -11,4 +11,4 @@ var Foo = function Foo() {
value: foo
});
var _foo = "foo";
};
});
@@ -1,6 +1,6 @@
var _x = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("x");

var C = function C() {
var C = /*#__PURE__*/babelHelpers.createClass(function C() {
"use strict";

babelHelpers.classCallCheck(this, C);
Expand All @@ -9,8 +9,7 @@ var C = function C() {
writable: true,
value: void 0
});
};

});
expect(() => {
new C();
}).toThrow();
Expand Up @@ -29,5 +29,5 @@ var Foo = /*#__PURE__*/function (_Bar) {
return babelHelpers.possibleConstructorReturn(_this);
}

return Foo;
return babelHelpers.createClass(Foo);
}(Bar);
@@ -1,14 +1,14 @@
var _prop = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("prop");

var Foo = function Foo() {
var Foo = /*#__PURE__*/babelHelpers.createClass(function Foo() {
"use strict";

babelHelpers.classCallCheck(this, Foo);
Object.defineProperty(this, _prop, {
writable: true,
value: "foo"
});
};
});

var _prop2 = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("prop");

Expand All @@ -31,5 +31,5 @@ var Bar = /*#__PURE__*/function (_Foo) {
return _this;
}

return Bar;
return babelHelpers.createClass(Bar);
}(Foo);
@@ -1,6 +1,6 @@
var _client = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("client");

var Foo = function Foo(props) {
var Foo = /*#__PURE__*/babelHelpers.createClass(function Foo(props) {
"use strict";

babelHelpers.classCallCheck(this, Foo);
Expand All @@ -10,4 +10,4 @@ var Foo = function Foo(props) {
});
babelHelpers.classPrivateFieldLooseBase(this, _client)[_client] = 1;
[this.x = babelHelpers.classPrivateFieldLooseBase(this, _client)[_client], babelHelpers.classPrivateFieldLooseBase(this, _client)[_client], this.y = babelHelpers.classPrivateFieldLooseBase(this, _client)[_client]] = props;
};
});
@@ -1,6 +1,6 @@
var _client = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("client");

var Foo = function Foo(props) {
var Foo = /*#__PURE__*/babelHelpers.createClass(function Foo(props) {
"use strict";

babelHelpers.classCallCheck(this, Foo);
Expand All @@ -9,4 +9,4 @@ var Foo = function Foo(props) {
value: void 0
});
[x, ...babelHelpers.classPrivateFieldLooseBase(this, _client)[_client]] = props;
};
});
@@ -1,6 +1,6 @@
var _client = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("client");

var Foo = function Foo(props) {
var Foo = /*#__PURE__*/babelHelpers.createClass(function Foo(props) {
"use strict";

babelHelpers.classCallCheck(this, Foo);
Expand All @@ -9,4 +9,4 @@ var Foo = function Foo(props) {
value: void 0
});
[babelHelpers.classPrivateFieldLooseBase(this, _client)[_client] = 5] = props;
};
});
@@ -1,12 +1,11 @@
var _client = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("client");

var Foo = function Foo(props) {
var Foo = /*#__PURE__*/babelHelpers.createClass(function Foo(props) {
"use strict";

babelHelpers.classCallCheck(this, Foo);
[babelHelpers.classPrivateFieldLooseBase(Foo, _client)[_client]] = props;
};

});
Object.defineProperty(Foo, _client, {
writable: true,
value: void 0
Expand Down
@@ -1,6 +1,6 @@
var _client = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("client");

var Foo = function Foo(props) {
var Foo = /*#__PURE__*/babelHelpers.createClass(function Foo(props) {
"use strict";

babelHelpers.classCallCheck(this, Foo);
Expand All @@ -9,4 +9,4 @@ var Foo = function Foo(props) {
value: void 0
});
[babelHelpers.classPrivateFieldLooseBase(this, _client)[_client]] = props;
};
});
@@ -1,6 +1,6 @@
var _client = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("client");

var Foo = function Foo(props) {
var Foo = /*#__PURE__*/babelHelpers.createClass(function Foo(props) {
"use strict";

babelHelpers.classCallCheck(this, Foo);
Expand All @@ -14,4 +14,4 @@ var Foo = function Foo(props) {
y: babelHelpers.classPrivateFieldLooseBase(this, _client)[_client],
z: this.z = babelHelpers.classPrivateFieldLooseBase(this, _client)[_client]
} = props);
};
});
@@ -1,6 +1,6 @@
var _client = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("client");

var Foo = function Foo(props) {
var Foo = /*#__PURE__*/babelHelpers.createClass(function Foo(props) {
"use strict";

babelHelpers.classCallCheck(this, Foo);
Expand All @@ -12,4 +12,4 @@ var Foo = function Foo(props) {
x,
...babelHelpers.classPrivateFieldLooseBase(this, _client)[_client]
} = props);
};
});
@@ -1,6 +1,6 @@
var _client = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("client");

var Foo = function Foo(props) {
var Foo = /*#__PURE__*/babelHelpers.createClass(function Foo(props) {
"use strict";

babelHelpers.classCallCheck(this, Foo);
Expand All @@ -11,4 +11,4 @@ var Foo = function Foo(props) {
({
client: babelHelpers.classPrivateFieldLooseBase(this, _client)[_client] = 5
} = props);
};
});
@@ -1,14 +1,13 @@
var _client = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("client");

var Foo = function Foo(props) {
var Foo = /*#__PURE__*/babelHelpers.createClass(function Foo(props) {
"use strict";

babelHelpers.classCallCheck(this, Foo);
({
client: babelHelpers.classPrivateFieldLooseBase(Foo, _client)[_client]
} = props);
};

});
Object.defineProperty(Foo, _client, {
writable: true,
value: void 0
Expand Down
@@ -1,6 +1,6 @@
var _client = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("client");

var Foo = function Foo(props) {
var Foo = /*#__PURE__*/babelHelpers.createClass(function Foo(props) {
"use strict";

babelHelpers.classCallCheck(this, Foo);
Expand All @@ -11,4 +11,4 @@ var Foo = function Foo(props) {
({
client: babelHelpers.classPrivateFieldLooseBase(this, _client)[_client]
} = props);
};
});
Expand Up @@ -4,7 +4,7 @@ var _bar = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("bar");

var _baz = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("baz");

var Foo = function Foo(_foo) {
var Foo = /*#__PURE__*/babelHelpers.createClass(function Foo(_foo) {
"use strict";

babelHelpers.classCallCheck(this, Foo);
Expand All @@ -16,4 +16,4 @@ var Foo = function Foo(_foo) {
writable: true,
value: foo
});
};
});
Expand Up @@ -21,5 +21,5 @@ let Child = /*#__PURE__*/function (_Parent) {
return _this;
}

return Child;
return babelHelpers.createClass(Child);
}(Parent);