Fix bugs in the _wrapNativeSuper helper (#7533)
* Remove second wrapper from _wrapNativeSuper * Fix tests on node 4 I DON'T KNOW WHY IT WORKS. * Update fixtures * Use Reflect.construct * Parens * Fix things * Fix things * Undo changes * Fix with sham * Typo
This commit is contained in:
parent
bc6f0f989d
commit
2351a638b5
@ -433,14 +433,39 @@ helpers.setPrototypeOf = () => template.program.ast`
|
|||||||
helpers.construct = () => template.program.ast`
|
helpers.construct = () => template.program.ast`
|
||||||
import setPrototypeOf from "setPrototypeOf";
|
import setPrototypeOf from "setPrototypeOf";
|
||||||
|
|
||||||
|
function isNativeReflectConstruct() {
|
||||||
|
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
|
||||||
|
|
||||||
|
// core-js@3
|
||||||
|
if (Reflect.construct.sham) return false;
|
||||||
|
|
||||||
|
// Proxy can't be polyfilled. Every browser implemented
|
||||||
|
// proxies before or at the same time of Reflect.construct,
|
||||||
|
// so if they support Proxy they also support Reflect.construct.
|
||||||
|
if (typeof Proxy === "function") return true;
|
||||||
|
|
||||||
|
// Since Reflect.construct can't be properly polyfilled, some
|
||||||
|
// implementations (e.g. core-js@2) don't set the correct internal slots.
|
||||||
|
// Those polyfills don't allow us to subclass built-ins, so we need to
|
||||||
|
// use our fallback implementation.
|
||||||
|
try {
|
||||||
|
// If the internal slots aren't set, this throws an error similar to
|
||||||
|
// TypeError: this is not a Date object.
|
||||||
|
Date.prototype.toString.call(Reflect.construct(Date, [], function() {}));
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default function _construct(Parent, args, Class) {
|
export default function _construct(Parent, args, Class) {
|
||||||
if (typeof Reflect !== "undefined" && Reflect.construct) {
|
if (isNativeReflectConstruct()) {
|
||||||
_construct = Reflect.construct;
|
_construct = Reflect.construct;
|
||||||
} else {
|
} else {
|
||||||
_construct = function _construct(Parent, args, Class) {
|
_construct = function _construct(Parent, args, Class) {
|
||||||
var a = [null];
|
var a = [null];
|
||||||
a.push.apply(a, args);
|
a.push.apply(a, args);
|
||||||
var Constructor = Parent.bind.apply(Parent, a);
|
var Constructor = Function.bind.apply(Parent, a);
|
||||||
var instance = new Constructor();
|
var instance = new Constructor();
|
||||||
if (Class) setPrototypeOf(instance, Class.prototype);
|
if (Class) setPrototypeOf(instance, Class.prototype);
|
||||||
return instance;
|
return instance;
|
||||||
@ -462,6 +487,7 @@ helpers.wrapNativeSuper = () => template.program.ast`
|
|||||||
var _cache = typeof Map === "function" ? new Map() : undefined;
|
var _cache = typeof Map === "function" ? new Map() : undefined;
|
||||||
|
|
||||||
_wrapNativeSuper = function _wrapNativeSuper(Class) {
|
_wrapNativeSuper = function _wrapNativeSuper(Class) {
|
||||||
|
if (Class === null) return null;
|
||||||
if (typeof Class !== "function") {
|
if (typeof Class !== "function") {
|
||||||
throw new TypeError("Super expression must either be null or a function");
|
throw new TypeError("Super expression must either be null or a function");
|
||||||
}
|
}
|
||||||
@ -469,7 +495,9 @@ helpers.wrapNativeSuper = () => template.program.ast`
|
|||||||
if (_cache.has(Class)) return _cache.get(Class);
|
if (_cache.has(Class)) return _cache.get(Class);
|
||||||
_cache.set(Class, Wrapper);
|
_cache.set(Class, Wrapper);
|
||||||
}
|
}
|
||||||
function Wrapper() {}
|
function Wrapper() {
|
||||||
|
return _construct(Class, arguments, _gPO(this).constructor)
|
||||||
|
}
|
||||||
Wrapper.prototype = Object.create(Class.prototype, {
|
Wrapper.prototype = Object.create(Class.prototype, {
|
||||||
constructor: {
|
constructor: {
|
||||||
value: Wrapper,
|
value: Wrapper,
|
||||||
@ -478,15 +506,8 @@ helpers.wrapNativeSuper = () => template.program.ast`
|
|||||||
configurable: true,
|
configurable: true,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return _sPO(
|
|
||||||
Wrapper,
|
return _sPO(Wrapper, Class);
|
||||||
_sPO(
|
|
||||||
function Super() {
|
|
||||||
return construct(Class, arguments, _gPO(this).constructor);
|
|
||||||
},
|
|
||||||
Class
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _wrapNativeSuper(Class)
|
return _wrapNativeSuper(Class)
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
function _inheritsLoose(subClass, superClass) { subClass.prototype.__proto__ = superClass && superClass.prototype; subClass.__proto__ = superClass; }
|
function _inheritsLoose(subClass, superClass) { subClass.prototype.__proto__ = superClass && superClass.prototype; subClass.__proto__ = superClass; }
|
||||||
|
|
||||||
function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = 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, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, _setPrototypeOf(function Super() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); }, Class)); }; return _wrapNativeSuper(Class); }
|
function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null) return null; 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() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
|
||||||
|
|
||||||
function _construct(Parent, args, Class) { if (typeof Reflect !== "undefined" && Reflect.construct) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Parent.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
|
function isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
|
||||||
|
|
||||||
|
function _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
|
||||||
|
|
||||||
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
var env = {
|
||||||
|
Array: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Wee need to use "with" to avoid leaking the modified Array to other tests.
|
||||||
|
with (env) {
|
||||||
|
class List extends Array {}
|
||||||
|
expect(List.prototype.__proto__).toBeUndefined();
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["transform-classes", "transform-block-scoping"]
|
||||||
|
}
|
||||||
@ -6,9 +6,11 @@ function _possibleConstructorReturn(self, call) { if (call && (typeof call === "
|
|||||||
|
|
||||||
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
||||||
|
|
||||||
function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = 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, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, _setPrototypeOf(function Super() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); }, Class)); }; return _wrapNativeSuper(Class); }
|
function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null) return null; 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() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
|
||||||
|
|
||||||
function _construct(Parent, args, Class) { if (typeof Reflect !== "undefined" && Reflect.construct) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Parent.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
|
function isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
|
||||||
|
|
||||||
|
function _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
|
||||||
|
|
||||||
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
||||||
|
|
||||||
|
|||||||
15
packages/babel-plugin-transform-classes/test/fixtures/extend-builtins/super-called/exec.js
vendored
Normal file
15
packages/babel-plugin-transform-classes/test/fixtures/extend-builtins/super-called/exec.js
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
var called = false;
|
||||||
|
|
||||||
|
var env = {
|
||||||
|
Array: function Array() {
|
||||||
|
called = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Wee need to use "with" to avoid leaking the modified Array to other tests.
|
||||||
|
with (env) {
|
||||||
|
class List extends Array {};
|
||||||
|
new List();
|
||||||
|
|
||||||
|
expect(called).toBe(true);
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["transform-classes","transform-block-scoping"]
|
||||||
|
}
|
||||||
@ -4,3 +4,6 @@ class MyDate extends Date {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let myDate = new MyDate();
|
let myDate = new MyDate();
|
||||||
|
|
||||||
|
expect(myDate.toString).toBe(Date.prototype.toString);
|
||||||
|
expect(typeof myDate.toString()).toBe("string");
|
||||||
|
|||||||
@ -10,9 +10,11 @@ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) ===
|
|||||||
|
|
||||||
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
||||||
|
|
||||||
function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = 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, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, _setPrototypeOf(function Super() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); }, Class)); }; return _wrapNativeSuper(Class); }
|
function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null) return null; 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() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
|
||||||
|
|
||||||
function _construct(Parent, args, Class) { if (typeof Reflect !== "undefined" && Reflect.construct) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Parent.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
|
function isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
|
||||||
|
|
||||||
|
function _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
|
||||||
|
|
||||||
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user