Add support for extending builtins (#7020)

This commit is contained in:
Nicolò Ribaudo
2017-12-20 20:46:00 +01:00
committed by Henry Zhu
parent 148fe7d3ff
commit 0c885b3200
22 changed files with 244 additions and 7 deletions

View File

@@ -0,0 +1,23 @@
function B() {}
B.b = function() {
return 'B.b';
};
class C extends B {}
assert.equal(Object.getPrototypeOf(C), B);
assert.equal(Object.getPrototypeOf(C.prototype), B.prototype);
assert.equal(C.b(), 'B.b');
class D extends Object {}
assert.ok(D instanceof Object)
assert.ok(D.prototype instanceof Object);
assert.equal(D.keys, Object.keys);
class E {}
assert.equal(Object.getPrototypeOf(E), Function.prototype);
assert.equal(Object.getPrototypeOf(E.prototype), Object.prototype);
assert.isFalse('keys' in E);

View File

@@ -0,0 +1,4 @@
// JSON is wrapped because it starts with an uppercase letter, but it
// should not be possible to extend it anyway.
assert.throws(() => class BetterJSON extends JSON {});

View File

@@ -0,0 +1,3 @@
{
"plugins": ["transform-classes", "transform-block-scoping"]
}

View File

@@ -0,0 +1,34 @@
// Imported from
// https://github.com/WebReflection/babel-plugin-transform-builtin-classes/blob/85efe1374e1c59a8323c7eddd4326f6c93d9f64f/test/test.js
class List extends Array {
constructor(value) {
super().push(value);
}
push(value) {
super.push(value);
return this;
}
}
assert.ok(new List(1) instanceof List, 'new List is an instanceof List');
assert.ok(new List(2) instanceof Array, 'new List is an instanceof Array');
var l = new List(3);
assert.ok(l.length === 1 && l[0] === 3, 'constructor pushes an entry');
assert.ok(l.push(4) === l && l.length === 2 && l.join() === '3,4', 'method override works');
class SecondLevel extends List {
method() {
return this;
}
}
assert.ok(new SecondLevel(1) instanceof SecondLevel, 'new SecondLevel is an instanceof SecondLevel');
assert.ok(new SecondLevel(2) instanceof List, 'new SecondLevel is an instanceof List');
assert.ok(new SecondLevel(3) instanceof Array, 'new SecondLevel is an instanceof Array');
var s = new SecondLevel(4);
assert.ok(s.length === 1 && s[0] === 4, 'constructor pushes an entry');
assert.ok(s.push(5) === s && s.length === 2 && s.join() === '4,5', 'inherited override works');
assert.ok(s.method() === s, 'new method works');

View File

@@ -0,0 +1,3 @@
{
"plugins": ["transform-classes","transform-block-scoping"]
}

View File

@@ -0,0 +1 @@
class List extends Array {}

View File

@@ -0,0 +1,4 @@
class List extends Array {}
assert.ok(new List instanceof List);
assert.ok(new List instanceof Array);

View File

@@ -0,0 +1,23 @@
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
var _gPO = Object.getPrototypeOf || function _gPO(o) { return o.__proto__; };
var _sPO = Object.setPrototypeOf || function _sPO(o, p) { o.__proto__ = p; };
var _construct = typeof Reflect === "object" && Reflect.construct || function _construct(Parent, args, Class) { var Constructor, a = [null]; a.push.apply(a, args); Constructor = Parent.bind.apply(Parent, a); return _sPO(new Constructor(), Class.prototype); };
var _cache = typeof Map === "function" && new Map();
function _wrapNativeSuper(Class) { if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() {} Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writeable: true, configurable: true } }); return _sPO(Wrapper, _sPO(function Super() { return _construct(Class, arguments, _gPO(this).constructor); }, Class)); }
var List =
/*#__PURE__*/
function (_Array) {
_inheritsLoose(List, _Array);
function List() {
return _Array.apply(this, arguments) || this;
}
return List;
}(_wrapNativeSuper(Array));

View File

@@ -0,0 +1,6 @@
{
"plugins": [
["transform-classes", { "loose": true }],
"transform-block-scoping"
]
}

View File

@@ -0,0 +1,3 @@
class Array {}
class List extends Array {}

View File

@@ -0,0 +1,16 @@
let Array = function Array() {
babelHelpers.classCallCheck(this, Array);
};
let List =
/*#__PURE__*/
function (_Array) {
babelHelpers.inherits(List, _Array);
function List() {
babelHelpers.classCallCheck(this, List);
return babelHelpers.possibleConstructorReturn(this, (List.__proto__ || Object.getPrototypeOf(List)).apply(this, arguments));
}
return List;
}(Array);

View File

@@ -0,0 +1,3 @@
{
"plugins": ["transform-classes", "external-helpers"]
}

View File

@@ -0,0 +1 @@
class List extends Array {}

View File

@@ -0,0 +1,4 @@
class List extends Array {}
assert.ok(new List instanceof List);
assert.ok(new List instanceof Array);

View File

@@ -0,0 +1,29 @@
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inherits(subClass, superClass) { 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, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var _gPO = Object.getPrototypeOf || function _gPO(o) { return o.__proto__; };
var _sPO = Object.setPrototypeOf || function _sPO(o, p) { o.__proto__ = p; };
var _construct = typeof Reflect === "object" && Reflect.construct || function _construct(Parent, args, Class) { var Constructor, a = [null]; a.push.apply(a, args); Constructor = Parent.bind.apply(Parent, a); return _sPO(new Constructor(), Class.prototype); };
var _cache = typeof Map === "function" && new Map();
function _wrapNativeSuper(Class) { if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() {} Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writeable: true, configurable: true } }); return _sPO(Wrapper, _sPO(function Super() { return _construct(Class, arguments, _gPO(this).constructor); }, Class)); }
var List =
/*#__PURE__*/
function (_Array) {
_inherits(List, _Array);
function List() {
_classCallCheck(this, List);
return _possibleConstructorReturn(this, (List.__proto__ || Object.getPrototypeOf(List)).apply(this, arguments));
}
return List;
}(_wrapNativeSuper(Array));

View File

@@ -0,0 +1,3 @@
{
"plugins": ["transform-classes", "transform-block-scoping"]
}