fix: ensure (a?.b)() has proper this (#11623)
* fix: ensure (a?.b)() has proper this * let test be more restrictive * fix: transformed member call should preserve computed * chore: revamp test files * refactor: simplify * fix: unwrap parthenthesizedExpression * add loose test cases * add `(a?.#b)()` support * add with-transform test cases * Update packages/babel-plugin-proposal-optional-chaining/src/index.js Co-authored-by: Justin Ridgewell <justin@ridgewell.name> * address review comments * update test fixtures Co-authored-by: Justin Ridgewell <justin@ridgewell.name>
This commit is contained in:
parent
3a3457d808
commit
1e115aed33
@ -241,6 +241,15 @@ const privateNameHandlerSpec = {
|
||||
]);
|
||||
},
|
||||
|
||||
boundGet(member) {
|
||||
this.memoise(member, 1);
|
||||
|
||||
return t.callExpression(
|
||||
t.memberExpression(this.get(member), t.identifier("bind")),
|
||||
[this.receiver(member)],
|
||||
);
|
||||
},
|
||||
|
||||
set(member, value) {
|
||||
const { classRef, privateNamesMap, file } = this;
|
||||
const { name } = member.node.property.id;
|
||||
@ -323,6 +332,13 @@ const privateNameHandlerLoose = {
|
||||
});
|
||||
},
|
||||
|
||||
boundGet(member) {
|
||||
return t.callExpression(
|
||||
t.memberExpression(this.get(member), t.identifier("bind")),
|
||||
[t.cloneNode(member.node.object)],
|
||||
);
|
||||
},
|
||||
|
||||
simpleSet(member) {
|
||||
return this.get(member);
|
||||
},
|
||||
|
||||
@ -167,6 +167,9 @@ const handle = {
|
||||
const parentIsOptionalCall = parentPath.isOptionalCallExpression({
|
||||
callee: node,
|
||||
});
|
||||
const isParenthesizedMemberCall =
|
||||
parentPath.isCallExpression({ callee: node }) &&
|
||||
node.extra?.parenthesized;
|
||||
startingOptional.replaceWith(toNonOptional(startingOptional, baseRef));
|
||||
if (parentIsOptionalCall) {
|
||||
if (parent.optional) {
|
||||
@ -174,6 +177,9 @@ const handle = {
|
||||
} else {
|
||||
parentPath.replaceWith(this.call(member, parent.arguments));
|
||||
}
|
||||
} else if (isParenthesizedMemberCall) {
|
||||
// `(a?.#b)()` to `(a == null ? void 0 : a.#b.bind(a))()`
|
||||
member.replaceWith(this.boundGet(member));
|
||||
} else {
|
||||
member.replaceWith(this.get(member));
|
||||
}
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
class Foo {
|
||||
static #x = 1;
|
||||
|
||||
static self = Foo;
|
||||
static #m = function() { return this.#x; };
|
||||
static getSelf() { return Foo }
|
||||
|
||||
test() {
|
||||
const o = { Foo: Foo };
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
expect((Foo?.#m)()).toEqual(1);
|
||||
expect((Foo?.#m)().toString).toEqual(1..toString);
|
||||
expect((Foo?.#m)().toString()).toEqual('1');
|
||||
|
||||
expect((o?.Foo.#m)()).toEqual(1);
|
||||
expect((o?.Foo.#m)().toString).toEqual(1..toString);
|
||||
expect((o?.Foo.#m)().toString()).toEqual('1');
|
||||
|
||||
expect((((o.Foo?.self.getSelf)())?.#m)()).toEqual(1);
|
||||
expect((((o.Foo.self?.getSelf)())?.#m)()).toEqual(1);
|
||||
|
||||
expect((((fn()?.Foo?.self.getSelf)())?.#m)()).toEqual(1);
|
||||
expect((((fn?.().Foo.self?.getSelf)())?.#m)()).toEqual(1);
|
||||
}
|
||||
|
||||
testNull() {
|
||||
const o = null;
|
||||
const fn = function () {
|
||||
return { o };
|
||||
}
|
||||
|
||||
expect(() => { (o?.Foo.#m)() }).toThrow();
|
||||
expect(() => { (o?.Foo.#m)().toString }).toThrow();
|
||||
expect(() => { (o?.Foo.#m)().toString() }).toThrow();
|
||||
|
||||
expect(() => { (((o.Foo?.self.getSelf)())?.#m)() }).toThrow();
|
||||
expect(() => { (((o.Foo.self?.getSelf)())?.#m)() }).toThrow();
|
||||
|
||||
expect(() => (((fn()?.Foo?.self.getSelf)())?.#m)()).toThrow();
|
||||
expect(() => (((fn?.().Foo.self?.getSelf)())?.#m)()).toThrow();
|
||||
}
|
||||
}
|
||||
|
||||
(new Foo).test();
|
||||
(new Foo).testNull();
|
||||
@ -0,0 +1,30 @@
|
||||
class Foo {
|
||||
static #x = 1;
|
||||
|
||||
static self = Foo;
|
||||
static #m = function() { return this.#x; };
|
||||
static getSelf() { return Foo }
|
||||
|
||||
test() {
|
||||
const o = { Foo: Foo };
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
(Foo?.#m)();
|
||||
(Foo?.#m)().toString;
|
||||
(Foo?.#m)().toString();
|
||||
|
||||
(o?.Foo.#m)();
|
||||
(o?.Foo.#m)().toString;
|
||||
(o?.Foo.#m)().toString();
|
||||
|
||||
(((o.Foo?.self.getSelf)())?.#m)();
|
||||
(((o.Foo.self?.getSelf)())?.#m)();
|
||||
|
||||
(((fn()?.Foo?.self.getSelf)())?.#m)();
|
||||
(((fn?.().Foo.self?.getSelf)())?.#m)();
|
||||
}
|
||||
}
|
||||
|
||||
(new Foo).test();
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugins": [
|
||||
["external-helpers", { "helperVersion": "7.100.0" }],
|
||||
["proposal-class-properties", { "loose": true }],
|
||||
["proposal-optional-chaining", { "loose": true }]
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
class Foo {
|
||||
static getSelf() {
|
||||
return Foo;
|
||||
}
|
||||
|
||||
test() {
|
||||
var _o$Foo$self$getSelf, _o$Foo$self$getSelf2, _fn$Foo$self$getSelf, _fn$Foo$self$getSelf2, _o$Foo, _o$Foo$self, _fn, _fn$Foo, _fn$Foo$self, _fn$Foo$self2;
|
||||
|
||||
const o = {
|
||||
Foo: Foo
|
||||
};
|
||||
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
(Foo === null || Foo === void 0 ? void 0 : babelHelpers.classPrivateFieldLooseBase(Foo, _m)[_m].bind(Foo))();
|
||||
(Foo === null || Foo === void 0 ? void 0 : babelHelpers.classPrivateFieldLooseBase(Foo, _m)[_m].bind(Foo))().toString;
|
||||
(Foo === null || Foo === void 0 ? void 0 : babelHelpers.classPrivateFieldLooseBase(Foo, _m)[_m].bind(Foo))().toString();
|
||||
(o === null || o === void 0 ? void 0 : babelHelpers.classPrivateFieldLooseBase(o.Foo, _m)[_m].bind(o.Foo))();
|
||||
(o === null || o === void 0 ? void 0 : babelHelpers.classPrivateFieldLooseBase(o.Foo, _m)[_m].bind(o.Foo))().toString;
|
||||
(o === null || o === void 0 ? void 0 : babelHelpers.classPrivateFieldLooseBase(o.Foo, _m)[_m].bind(o.Foo))().toString();
|
||||
((_o$Foo$self$getSelf = ((_o$Foo = o.Foo) == null ? void 0 : _o$Foo.self.getSelf.bind(_o$Foo.self))()) === null || _o$Foo$self$getSelf === void 0 ? void 0 : babelHelpers.classPrivateFieldLooseBase(_o$Foo$self$getSelf, _m)[_m].bind(_o$Foo$self$getSelf))();
|
||||
((_o$Foo$self$getSelf2 = ((_o$Foo$self = o.Foo.self) == null ? void 0 : _o$Foo$self.getSelf.bind(_o$Foo$self))()) === null || _o$Foo$self$getSelf2 === void 0 ? void 0 : babelHelpers.classPrivateFieldLooseBase(_o$Foo$self$getSelf2, _m)[_m].bind(_o$Foo$self$getSelf2))();
|
||||
((_fn$Foo$self$getSelf = ((_fn = fn()) == null ? void 0 : (_fn$Foo = _fn.Foo) == null ? void 0 : _fn$Foo.self.getSelf.bind(_fn.Foo.self))()) === null || _fn$Foo$self$getSelf === void 0 ? void 0 : babelHelpers.classPrivateFieldLooseBase(_fn$Foo$self$getSelf, _m)[_m].bind(_fn$Foo$self$getSelf))();
|
||||
((_fn$Foo$self$getSelf2 = (fn == null ? void 0 : (_fn$Foo$self2 = _fn$Foo$self = fn().Foo.self) == null ? void 0 : _fn$Foo$self2.getSelf.bind(_fn$Foo$self))()) === null || _fn$Foo$self$getSelf2 === void 0 ? void 0 : babelHelpers.classPrivateFieldLooseBase(_fn$Foo$self$getSelf2, _m)[_m].bind(_fn$Foo$self$getSelf2))();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var _x = babelHelpers.classPrivateFieldLooseKey("x");
|
||||
|
||||
var _m = babelHelpers.classPrivateFieldLooseKey("m");
|
||||
|
||||
Object.defineProperty(Foo, _x, {
|
||||
writable: true,
|
||||
value: 1
|
||||
});
|
||||
Foo.self = Foo;
|
||||
Object.defineProperty(Foo, _m, {
|
||||
writable: true,
|
||||
value: function () {
|
||||
return babelHelpers.classPrivateFieldLooseBase(this, _x)[_x];
|
||||
}
|
||||
});
|
||||
new Foo().test();
|
||||
@ -0,0 +1,48 @@
|
||||
class Foo {
|
||||
static #x = 1;
|
||||
|
||||
static self = Foo;
|
||||
static #m = function() { return this.#x; };
|
||||
static getSelf() { return Foo }
|
||||
|
||||
test() {
|
||||
const o = { Foo: Foo };
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
expect((Foo?.#m)()).toEqual(1);
|
||||
expect((Foo?.#m)().toString).toEqual(1..toString);
|
||||
expect((Foo?.#m)().toString()).toEqual('1');
|
||||
|
||||
expect((o?.Foo.#m)()).toEqual(1);
|
||||
expect((o?.Foo.#m)().toString).toEqual(1..toString);
|
||||
expect((o?.Foo.#m)().toString()).toEqual('1');
|
||||
|
||||
expect((((o.Foo?.self.getSelf)())?.#m)()).toEqual(1);
|
||||
expect((((o.Foo.self?.getSelf)())?.#m)()).toEqual(1);
|
||||
|
||||
expect((((fn()?.Foo?.self.getSelf)())?.#m)()).toEqual(1);
|
||||
expect((((fn?.().Foo.self?.getSelf)())?.#m)()).toEqual(1);
|
||||
}
|
||||
|
||||
testNull() {
|
||||
const o = null;
|
||||
const fn = function () {
|
||||
return { o };
|
||||
}
|
||||
|
||||
expect(() => { (o?.Foo.#m)() }).toThrow();
|
||||
expect(() => { (o?.Foo.#m)().toString }).toThrow();
|
||||
expect(() => { (o?.Foo.#m)().toString() }).toThrow();
|
||||
|
||||
expect(() => { (((o.Foo?.self.getSelf)())?.#m)() }).toThrow();
|
||||
expect(() => { (((o.Foo.self?.getSelf)())?.#m)() }).toThrow();
|
||||
|
||||
expect(() => (((fn()?.Foo?.self.getSelf)())?.#m)()).toThrow();
|
||||
expect(() => (((fn?.().Foo.self?.getSelf)())?.#m)()).toThrow();
|
||||
}
|
||||
}
|
||||
|
||||
(new Foo).test();
|
||||
(new Foo).testNull();
|
||||
@ -0,0 +1,30 @@
|
||||
class Foo {
|
||||
static #x = 1;
|
||||
|
||||
static self = Foo;
|
||||
static #m = function() { return this.#x; };
|
||||
static getSelf() { return Foo }
|
||||
|
||||
test() {
|
||||
const o = { Foo: Foo };
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
(Foo?.#m)();
|
||||
(Foo?.#m)().toString;
|
||||
(Foo?.#m)().toString();
|
||||
|
||||
(o?.Foo.#m)();
|
||||
(o?.Foo.#m)().toString;
|
||||
(o?.Foo.#m)().toString();
|
||||
|
||||
(((o.Foo?.self.getSelf)())?.#m)();
|
||||
(((o.Foo.self?.getSelf)())?.#m)();
|
||||
|
||||
(((fn()?.Foo?.self.getSelf)())?.#m)();
|
||||
(((fn?.().Foo.self?.getSelf)())?.#m)();
|
||||
}
|
||||
}
|
||||
|
||||
(new Foo).test();
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugins": [
|
||||
["external-helpers", { "helperVersion": "7.100.0" }],
|
||||
"proposal-class-properties"
|
||||
],
|
||||
"minNodeVersion": "14.0.0"
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
class Foo {
|
||||
static getSelf() {
|
||||
return Foo;
|
||||
}
|
||||
|
||||
test() {
|
||||
var _o$Foo, _o$Foo2, _o$Foo3, _o$Foo$self$getSelf, _o$Foo$self$getSelf2, _fn$Foo$self$getSelf, _fn$Foo$self$getSelf2;
|
||||
|
||||
const o = {
|
||||
Foo: Foo
|
||||
};
|
||||
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
(Foo === null || Foo === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _m).bind(Foo))();
|
||||
(Foo === null || Foo === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _m).bind(Foo))().toString;
|
||||
(Foo === null || Foo === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _m).bind(Foo))().toString();
|
||||
(o === null || o === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$Foo = o.Foo, Foo, _m).bind(_o$Foo))();
|
||||
(o === null || o === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$Foo2 = o.Foo, Foo, _m).bind(_o$Foo2))().toString;
|
||||
(o === null || o === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$Foo3 = o.Foo, Foo, _m).bind(_o$Foo3))().toString();
|
||||
((_o$Foo$self$getSelf = (o.Foo?.self.getSelf)()) === null || _o$Foo$self$getSelf === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$Foo$self$getSelf, Foo, _m).bind(_o$Foo$self$getSelf))();
|
||||
((_o$Foo$self$getSelf2 = (o.Foo.self?.getSelf)()) === null || _o$Foo$self$getSelf2 === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$Foo$self$getSelf2, Foo, _m).bind(_o$Foo$self$getSelf2))();
|
||||
((_fn$Foo$self$getSelf = (fn()?.Foo?.self.getSelf)()) === null || _fn$Foo$self$getSelf === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_fn$Foo$self$getSelf, Foo, _m).bind(_fn$Foo$self$getSelf))();
|
||||
((_fn$Foo$self$getSelf2 = (fn?.().Foo.self?.getSelf)()) === null || _fn$Foo$self$getSelf2 === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_fn$Foo$self$getSelf2, Foo, _m).bind(_fn$Foo$self$getSelf2))();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var _x = {
|
||||
writable: true,
|
||||
value: 1
|
||||
};
|
||||
babelHelpers.defineProperty(Foo, "self", Foo);
|
||||
var _m = {
|
||||
writable: true,
|
||||
value: function () {
|
||||
return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _x);
|
||||
}
|
||||
};
|
||||
new Foo().test();
|
||||
@ -0,0 +1,48 @@
|
||||
class Foo {
|
||||
static #x = 1;
|
||||
|
||||
static self = Foo;
|
||||
static #m = function() { return this.#x; };
|
||||
static getSelf() { return Foo }
|
||||
|
||||
test() {
|
||||
const o = { Foo: Foo };
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
expect((Foo?.#m)()).toEqual(1);
|
||||
expect((Foo?.#m)().toString).toEqual(1..toString);
|
||||
expect((Foo?.#m)().toString()).toEqual('1');
|
||||
|
||||
expect((o?.Foo.#m)()).toEqual(1);
|
||||
expect((o?.Foo.#m)().toString).toEqual(1..toString);
|
||||
expect((o?.Foo.#m)().toString()).toEqual('1');
|
||||
|
||||
expect((((o.Foo?.self.getSelf)())?.#m)()).toEqual(1);
|
||||
expect((((o.Foo.self?.getSelf)())?.#m)()).toEqual(1);
|
||||
|
||||
expect((((fn()?.Foo?.self.getSelf)())?.#m)()).toEqual(1);
|
||||
expect((((fn?.().Foo.self?.getSelf)())?.#m)()).toEqual(1);
|
||||
}
|
||||
|
||||
testNull() {
|
||||
const o = null;
|
||||
const fn = function () {
|
||||
return { o };
|
||||
}
|
||||
|
||||
expect(() => { (o?.Foo.#m)() }).toThrow();
|
||||
expect(() => { (o?.Foo.#m)().toString }).toThrow();
|
||||
expect(() => { (o?.Foo.#m)().toString() }).toThrow();
|
||||
|
||||
expect(() => { (((o.Foo?.self.getSelf)())?.#m)() }).toThrow();
|
||||
expect(() => { (((o.Foo.self?.getSelf)())?.#m)() }).toThrow();
|
||||
|
||||
expect(() => (((fn()?.Foo?.self.getSelf)())?.#m)()).toThrow();
|
||||
expect(() => (((fn?.().Foo.self?.getSelf)())?.#m)()).toThrow();
|
||||
}
|
||||
}
|
||||
|
||||
(new Foo).test();
|
||||
(new Foo).testNull();
|
||||
@ -0,0 +1,30 @@
|
||||
class Foo {
|
||||
static #x = 1;
|
||||
|
||||
static self = Foo;
|
||||
static #m = function() { return this.#x; };
|
||||
static getSelf() { return Foo }
|
||||
|
||||
test() {
|
||||
const o = { Foo: Foo };
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
(Foo?.#m)();
|
||||
(Foo?.#m)().toString;
|
||||
(Foo?.#m)().toString();
|
||||
|
||||
(o?.Foo.#m)();
|
||||
(o?.Foo.#m)().toString;
|
||||
(o?.Foo.#m)().toString();
|
||||
|
||||
(((o.Foo?.self.getSelf)())?.#m)();
|
||||
(((o.Foo.self?.getSelf)())?.#m)();
|
||||
|
||||
(((fn()?.Foo?.self.getSelf)())?.#m)();
|
||||
(((fn?.().Foo.self?.getSelf)())?.#m)();
|
||||
}
|
||||
}
|
||||
|
||||
(new Foo).test();
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugins": [
|
||||
["external-helpers", { "helperVersion": "7.100.0" }],
|
||||
"proposal-class-properties",
|
||||
"proposal-optional-chaining"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
class Foo {
|
||||
static getSelf() {
|
||||
return Foo;
|
||||
}
|
||||
|
||||
test() {
|
||||
var _o$Foo, _o$Foo2, _o$Foo3, _o$Foo$self$getSelf, _o$Foo$self$getSelf2, _fn$Foo$self$getSelf, _fn$Foo$self$getSelf2, _o$Foo4, _o$Foo4$self, _o$Foo$self, _fn, _fn$Foo$self, _fn$Foo, _fn$Foo$self2, _fn$Foo$self3;
|
||||
|
||||
const o = {
|
||||
Foo: Foo
|
||||
};
|
||||
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
(Foo === null || Foo === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _m).bind(Foo))();
|
||||
(Foo === null || Foo === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _m).bind(Foo))().toString;
|
||||
(Foo === null || Foo === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _m).bind(Foo))().toString();
|
||||
(o === null || o === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$Foo = o.Foo, Foo, _m).bind(_o$Foo))();
|
||||
(o === null || o === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$Foo2 = o.Foo, Foo, _m).bind(_o$Foo2))().toString;
|
||||
(o === null || o === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$Foo3 = o.Foo, Foo, _m).bind(_o$Foo3))().toString();
|
||||
((_o$Foo$self$getSelf = ((_o$Foo4 = o.Foo) === null || _o$Foo4 === void 0 ? void 0 : (_o$Foo4$self = _o$Foo4.self).getSelf.bind(_o$Foo4$self))()) === null || _o$Foo$self$getSelf === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$Foo$self$getSelf, Foo, _m).bind(_o$Foo$self$getSelf))();
|
||||
((_o$Foo$self$getSelf2 = ((_o$Foo$self = o.Foo.self) === null || _o$Foo$self === void 0 ? void 0 : _o$Foo$self.getSelf.bind(_o$Foo$self))()) === null || _o$Foo$self$getSelf2 === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$Foo$self$getSelf2, Foo, _m).bind(_o$Foo$self$getSelf2))();
|
||||
((_fn$Foo$self$getSelf = ((_fn = fn()) === null || _fn === void 0 ? void 0 : (_fn$Foo = _fn.Foo) === null || _fn$Foo === void 0 ? void 0 : (_fn$Foo$self = _fn$Foo.self).getSelf.bind(_fn$Foo$self))()) === null || _fn$Foo$self$getSelf === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_fn$Foo$self$getSelf, Foo, _m).bind(_fn$Foo$self$getSelf))();
|
||||
((_fn$Foo$self$getSelf2 = (fn === null || fn === void 0 ? void 0 : (_fn$Foo$self3 = _fn$Foo$self2 = fn().Foo.self) === null || _fn$Foo$self3 === void 0 ? void 0 : _fn$Foo$self3.getSelf.bind(_fn$Foo$self2))()) === null || _fn$Foo$self$getSelf2 === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_fn$Foo$self$getSelf2, Foo, _m).bind(_fn$Foo$self$getSelf2))();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var _x = {
|
||||
writable: true,
|
||||
value: 1
|
||||
};
|
||||
babelHelpers.defineProperty(Foo, "self", Foo);
|
||||
var _m = {
|
||||
writable: true,
|
||||
value: function () {
|
||||
return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _x);
|
||||
}
|
||||
};
|
||||
new Foo().test();
|
||||
@ -0,0 +1,48 @@
|
||||
class Foo {
|
||||
static #x = 1;
|
||||
|
||||
static self = Foo;
|
||||
static #m = function() { return this.#x; };
|
||||
static getSelf() { return Foo }
|
||||
|
||||
test() {
|
||||
const o = { Foo: Foo };
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
expect((Foo?.#m)()).toEqual(1);
|
||||
expect((Foo?.#m)().toString).toEqual(1..toString);
|
||||
expect((Foo?.#m)().toString()).toEqual('1');
|
||||
|
||||
expect((o?.Foo.#m)()).toEqual(1);
|
||||
expect((o?.Foo.#m)().toString).toEqual(1..toString);
|
||||
expect((o?.Foo.#m)().toString()).toEqual('1');
|
||||
|
||||
expect((((o.Foo?.self.getSelf)())?.#m)()).toEqual(1);
|
||||
expect((((o.Foo.self?.getSelf)())?.#m)()).toEqual(1);
|
||||
|
||||
expect((((fn()?.Foo?.self.getSelf)())?.#m)()).toEqual(1);
|
||||
expect((((fn?.().Foo.self?.getSelf)())?.#m)()).toEqual(1);
|
||||
}
|
||||
|
||||
testNull() {
|
||||
const o = null;
|
||||
const fn = function () {
|
||||
return { o };
|
||||
}
|
||||
|
||||
expect(() => { (o?.Foo.#m)() }).toThrow();
|
||||
expect(() => { (o?.Foo.#m)().toString }).toThrow();
|
||||
expect(() => { (o?.Foo.#m)().toString() }).toThrow();
|
||||
|
||||
expect(() => { (((o.Foo?.self.getSelf)())?.#m)() }).toThrow();
|
||||
expect(() => { (((o.Foo.self?.getSelf)())?.#m)() }).toThrow();
|
||||
|
||||
expect(() => (((fn()?.Foo?.self.getSelf)())?.#m)()).toThrow();
|
||||
expect(() => (((fn?.().Foo.self?.getSelf)())?.#m)()).toThrow();
|
||||
}
|
||||
}
|
||||
|
||||
(new Foo).test();
|
||||
(new Foo).testNull();
|
||||
@ -0,0 +1,30 @@
|
||||
class Foo {
|
||||
static #x = 1;
|
||||
|
||||
static self = Foo;
|
||||
static #m = function() { return this.#x; };
|
||||
static getSelf() { return Foo }
|
||||
|
||||
test() {
|
||||
const o = { Foo: Foo };
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
(Foo?.#m)();
|
||||
(Foo?.#m)().toString;
|
||||
(Foo?.#m)().toString();
|
||||
|
||||
(o?.Foo.#m)();
|
||||
(o?.Foo.#m)().toString;
|
||||
(o?.Foo.#m)().toString();
|
||||
|
||||
(((o.Foo?.self.getSelf)())?.#m)();
|
||||
(((o.Foo.self?.getSelf)())?.#m)();
|
||||
|
||||
(((fn()?.Foo?.self.getSelf)())?.#m)();
|
||||
(((fn?.().Foo.self?.getSelf)())?.#m)();
|
||||
}
|
||||
}
|
||||
|
||||
(new Foo).test();
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"plugins": [
|
||||
["external-helpers", { "helperVersion": "7.100.0" }],
|
||||
"proposal-class-properties"
|
||||
],
|
||||
"minNodeVersion": "14.0.0"
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
class Foo {
|
||||
static getSelf() {
|
||||
return Foo;
|
||||
}
|
||||
|
||||
test() {
|
||||
var _o$Foo, _o$Foo2, _o$Foo3, _o$Foo$self$getSelf, _o$Foo$self$getSelf2, _fn$Foo$self$getSelf, _fn$Foo$self$getSelf2;
|
||||
|
||||
const o = {
|
||||
Foo: Foo
|
||||
};
|
||||
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
(Foo === null || Foo === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _m).bind(Foo))();
|
||||
(Foo === null || Foo === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _m).bind(Foo))().toString;
|
||||
(Foo === null || Foo === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _m).bind(Foo))().toString();
|
||||
(o === null || o === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$Foo = o.Foo, Foo, _m).bind(_o$Foo))();
|
||||
(o === null || o === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$Foo2 = o.Foo, Foo, _m).bind(_o$Foo2))().toString;
|
||||
(o === null || o === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$Foo3 = o.Foo, Foo, _m).bind(_o$Foo3))().toString();
|
||||
((_o$Foo$self$getSelf = (o.Foo?.self.getSelf)()) === null || _o$Foo$self$getSelf === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$Foo$self$getSelf, Foo, _m).bind(_o$Foo$self$getSelf))();
|
||||
((_o$Foo$self$getSelf2 = (o.Foo.self?.getSelf)()) === null || _o$Foo$self$getSelf2 === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$Foo$self$getSelf2, Foo, _m).bind(_o$Foo$self$getSelf2))();
|
||||
((_fn$Foo$self$getSelf = (fn()?.Foo?.self.getSelf)()) === null || _fn$Foo$self$getSelf === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_fn$Foo$self$getSelf, Foo, _m).bind(_fn$Foo$self$getSelf))();
|
||||
((_fn$Foo$self$getSelf2 = (fn?.().Foo.self?.getSelf)()) === null || _fn$Foo$self$getSelf2 === void 0 ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_fn$Foo$self$getSelf2, Foo, _m).bind(_fn$Foo$self$getSelf2))();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var _x = {
|
||||
writable: true,
|
||||
value: 1
|
||||
};
|
||||
babelHelpers.defineProperty(Foo, "self", Foo);
|
||||
var _m = {
|
||||
writable: true,
|
||||
value: function () {
|
||||
return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _x);
|
||||
}
|
||||
};
|
||||
new Foo().test();
|
||||
@ -23,14 +23,17 @@ export default declare((api, options) => {
|
||||
|
||||
visitor: {
|
||||
"OptionalCallExpression|OptionalMemberExpression"(path) {
|
||||
const { parentPath, scope } = path;
|
||||
const { scope } = path;
|
||||
const parentPath = path.findParent(p => !p.isParenthesizedExpression());
|
||||
let isDeleteOperation = false;
|
||||
const optionals = [];
|
||||
|
||||
let optionalPath = path;
|
||||
while (
|
||||
optionalPath.isOptionalMemberExpression() ||
|
||||
optionalPath.isOptionalCallExpression()
|
||||
optionalPath.isOptionalCallExpression() ||
|
||||
optionalPath.isParenthesizedExpression() ||
|
||||
optionalPath.isTSNonNullExpression()
|
||||
) {
|
||||
const { node } = optionalPath;
|
||||
if (node.optional) {
|
||||
@ -43,10 +46,8 @@ export default declare((api, options) => {
|
||||
} else if (optionalPath.isOptionalCallExpression()) {
|
||||
optionalPath.node.type = "CallExpression";
|
||||
optionalPath = optionalPath.get("callee");
|
||||
}
|
||||
|
||||
// unwrap a TSNonNullExpression if need
|
||||
if (optionalPath.isTSNonNullExpression()) {
|
||||
} else {
|
||||
// unwrap TSNonNullExpression/ParenthesizedExpression if needed
|
||||
optionalPath = optionalPath.get("expression");
|
||||
}
|
||||
}
|
||||
@ -113,7 +114,36 @@ export default declare((api, options) => {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let replacement = replacementPath.node;
|
||||
// Ensure (a?.b)() has proper `this`
|
||||
if (
|
||||
t.isMemberExpression(replacement) &&
|
||||
(replacement.extra?.parenthesized ||
|
||||
// if replacementPath.parentPath does not equal parentPath,
|
||||
// it must be unwrapped from parenthesized expression.
|
||||
replacementPath.parentPath !== parentPath) &&
|
||||
parentPath.isCallExpression()
|
||||
) {
|
||||
// `(a?.b)()` to `(a == null ? undefined : a.b.bind(a))()`
|
||||
const { object } = replacement;
|
||||
let baseRef;
|
||||
if (!loose || !isSimpleMemberExpression(object)) {
|
||||
// memoize the context object in non-loose mode
|
||||
// `(a?.b.c)()` to `(a == null ? undefined : (_a$b = a.b).c.bind(_a$b))()`
|
||||
baseRef = scope.maybeGenerateMemoised(object);
|
||||
if (baseRef) {
|
||||
replacement.object = t.assignmentExpression(
|
||||
"=",
|
||||
baseRef,
|
||||
object,
|
||||
);
|
||||
}
|
||||
}
|
||||
replacement = t.callExpression(
|
||||
t.memberExpression(replacement, t.identifier("bind")),
|
||||
[t.cloneNode(baseRef ?? object)],
|
||||
);
|
||||
}
|
||||
replacementPath.replaceWith(
|
||||
t.conditionalExpression(
|
||||
loose
|
||||
@ -134,7 +164,7 @@ export default declare((api, options) => {
|
||||
isDeleteOperation
|
||||
? t.booleanLiteral(true)
|
||||
: scope.buildUndefinedNode(),
|
||||
replacementPath.node,
|
||||
replacement,
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
class Foo {
|
||||
constructor() {
|
||||
this.x = 1;
|
||||
this.self = this;
|
||||
}
|
||||
m() { return this.x; };
|
||||
getSelf() { return this }
|
||||
|
||||
test() {
|
||||
const Foo = this;
|
||||
const o = { Foo: Foo };
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
expect((Foo?.["m"])()).toEqual(1);
|
||||
expect((Foo?.["m"])().toString).toEqual(1..toString);
|
||||
expect((Foo?.["m"])().toString()).toEqual('1');
|
||||
|
||||
expect(((Foo?.["m"]))()).toEqual(1);
|
||||
expect(((Foo?.["m"]))().toString).toEqual(1..toString);
|
||||
expect(((Foo?.["m"]))().toString()).toEqual('1');
|
||||
|
||||
expect((o?.Foo.m)()).toEqual(1);
|
||||
expect((o?.Foo.m)().toString).toEqual(1..toString);
|
||||
expect((o?.Foo.m)().toString()).toEqual('1');
|
||||
|
||||
expect((((o.Foo?.self.getSelf)())?.m)()).toEqual(1);
|
||||
expect((((o.Foo.self?.getSelf)())?.m)()).toEqual(1);
|
||||
|
||||
expect((((fn()?.Foo?.self.getSelf)())?.m)()).toEqual(1);
|
||||
expect((((fn?.().Foo.self?.getSelf)())?.m)()).toEqual(1);
|
||||
}
|
||||
|
||||
testNull() {
|
||||
const o = null;
|
||||
|
||||
expect(() => { (o?.Foo.m)() }).toThrow();
|
||||
expect(() => { (o?.Foo.m)().toString }).toThrow();
|
||||
expect(() => { (o?.Foo.m)().toString() }).toThrow();
|
||||
|
||||
expect(() => { (((o.Foo?.self.getSelf)())?.m)() }).toThrow();
|
||||
expect(() => { (((o.Foo.self?.getSelf)())?.m)() }).toThrow();
|
||||
|
||||
expect(() => (((fn()?.Foo?.self.getSelf)())?.m)()).toThrow();
|
||||
expect(() => (((fn?.().Foo.self?.getSelf)())?.m)()).toThrow();
|
||||
}
|
||||
}
|
||||
|
||||
(new Foo).test();
|
||||
(new Foo).testNull();
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"plugins": [["proposal-optional-chaining", { "loose": true }]],
|
||||
"parserOpts": {
|
||||
"createParenthesizedExpressions": true
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
class Foo {
|
||||
constructor() {
|
||||
this.x = 1;
|
||||
this.self = this;
|
||||
}
|
||||
m() { return this.x; };
|
||||
getSelf() { return this }
|
||||
|
||||
test() {
|
||||
const Foo = this;
|
||||
const o = { Foo: Foo };
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
expect((Foo?.["m"])()).toEqual(1);
|
||||
expect((Foo?.["m"])().toString).toEqual(1..toString);
|
||||
expect((Foo?.["m"])().toString()).toEqual('1');
|
||||
|
||||
expect(((Foo?.["m"]))()).toEqual(1);
|
||||
expect(((Foo?.["m"]))().toString).toEqual(1..toString);
|
||||
expect(((Foo?.["m"]))().toString()).toEqual('1');
|
||||
|
||||
expect((o?.Foo.m)()).toEqual(1);
|
||||
expect((o?.Foo.m)().toString).toEqual(1..toString);
|
||||
expect((o?.Foo.m)().toString()).toEqual('1');
|
||||
|
||||
expect((((o.Foo?.self.getSelf)())?.m)()).toEqual(1);
|
||||
expect((((o.Foo.self?.getSelf)())?.m)()).toEqual(1);
|
||||
|
||||
expect((((fn()?.Foo?.self.getSelf)())?.m)()).toEqual(1);
|
||||
expect((((fn?.().Foo.self?.getSelf)())?.m)()).toEqual(1);
|
||||
}
|
||||
|
||||
testNull() {
|
||||
const o = null;
|
||||
|
||||
expect(() => { (o?.Foo.m)() }).toThrow();
|
||||
expect(() => { (o?.Foo.m)().toString }).toThrow();
|
||||
expect(() => { (o?.Foo.m)().toString() }).toThrow();
|
||||
|
||||
expect(() => { (((o.Foo?.self.getSelf)())?.m)() }).toThrow();
|
||||
expect(() => { (((o.Foo.self?.getSelf)())?.m)() }).toThrow();
|
||||
|
||||
expect(() => (((fn()?.Foo?.self.getSelf)())?.m)()).toThrow();
|
||||
expect(() => (((fn?.().Foo.self?.getSelf)())?.m)()).toThrow();
|
||||
}
|
||||
}
|
||||
|
||||
(new Foo).test();
|
||||
(new Foo).testNull();
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"plugins": ["proposal-optional-chaining"],
|
||||
"parserOpts": {
|
||||
"createParenthesizedExpressions": true
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
class Foo {
|
||||
constructor() {
|
||||
this.x = 1;
|
||||
this.self = this;
|
||||
}
|
||||
m() { return this.x; };
|
||||
getSelf() { return this }
|
||||
|
||||
test() {
|
||||
const Foo = this;
|
||||
const o = { Foo: Foo };
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
expect((Foo?.["m"])()).toEqual(1);
|
||||
expect((Foo?.["m"])().toString).toEqual(1..toString);
|
||||
expect((Foo?.["m"])().toString()).toEqual('1');
|
||||
|
||||
expect((o?.Foo.m)()).toEqual(1);
|
||||
expect((o?.Foo.m)().toString).toEqual(1..toString);
|
||||
expect((o?.Foo.m)().toString()).toEqual('1');
|
||||
|
||||
expect((((o.Foo?.self.getSelf)())?.m)()).toEqual(1);
|
||||
expect((((o.Foo.self?.getSelf)())?.m)()).toEqual(1);
|
||||
|
||||
expect((((fn()?.Foo?.self.getSelf)())?.m)()).toEqual(1);
|
||||
expect((((fn?.().Foo.self?.getSelf)())?.m)()).toEqual(1);
|
||||
}
|
||||
|
||||
testNull() {
|
||||
const o = null;
|
||||
|
||||
expect(() => { (o?.Foo.m)() }).toThrow();
|
||||
expect(() => { (o?.Foo.m)().toString }).toThrow();
|
||||
expect(() => { (o?.Foo.m)().toString() }).toThrow();
|
||||
|
||||
expect(() => { (((o.Foo?.self.getSelf)())?.m)() }).toThrow();
|
||||
expect(() => { (((o.Foo.self?.getSelf)())?.m)() }).toThrow();
|
||||
|
||||
expect(() => (((fn()?.Foo?.self.getSelf)())?.m)()).toThrow();
|
||||
expect(() => (((fn?.().Foo.self?.getSelf)())?.m)()).toThrow();
|
||||
}
|
||||
}
|
||||
|
||||
(new Foo).test();
|
||||
(new Foo).testNull();
|
||||
@ -0,0 +1,32 @@
|
||||
class Foo {
|
||||
constructor() {
|
||||
this.x = 1;
|
||||
this.self = this;
|
||||
}
|
||||
m() { return this.x; };
|
||||
getSelf() { return this }
|
||||
|
||||
test() {
|
||||
const Foo = this;
|
||||
const o = { Foo: Foo };
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
(Foo?.["m"])();
|
||||
(Foo?.["m"])().toString;
|
||||
(Foo?.["m"])().toString();
|
||||
|
||||
(o?.Foo.m)();
|
||||
(o?.Foo.m)().toString;
|
||||
(o?.Foo.m)().toString();
|
||||
|
||||
(((o.Foo?.self.getSelf)())?.m)();
|
||||
(((o.Foo.self?.getSelf)())?.m)();
|
||||
|
||||
(((fn()?.Foo?.self.getSelf)())?.m)();
|
||||
(((fn?.().Foo.self?.getSelf)())?.m)();
|
||||
}
|
||||
}
|
||||
|
||||
(new Foo).test();
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": [["proposal-optional-chaining", { "loose": true }]]
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
class Foo {
|
||||
constructor() {
|
||||
this.x = 1;
|
||||
this.self = this;
|
||||
}
|
||||
|
||||
m() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
getSelf() {
|
||||
return this;
|
||||
}
|
||||
|
||||
test() {
|
||||
var _o$Foo$self$getSelf, _o$Foo, _o$Foo$self$getSelf2, _o$Foo$self, _fn$Foo$self$getSelf, _fn, _fn$Foo, _fn$Foo$self$getSelf2, _fn$Foo$self, _fn$Foo$self2;
|
||||
|
||||
const Foo = this;
|
||||
const o = {
|
||||
Foo: Foo
|
||||
};
|
||||
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
(Foo == null ? void 0 : Foo["m"].bind(Foo))();
|
||||
(Foo == null ? void 0 : Foo["m"].bind(Foo))().toString;
|
||||
(Foo == null ? void 0 : Foo["m"].bind(Foo))().toString();
|
||||
(o == null ? void 0 : o.Foo.m.bind(o.Foo))();
|
||||
(o == null ? void 0 : o.Foo.m.bind(o.Foo))().toString;
|
||||
(o == null ? void 0 : o.Foo.m.bind(o.Foo))().toString();
|
||||
((_o$Foo$self$getSelf = ((_o$Foo = o.Foo) == null ? void 0 : _o$Foo.self.getSelf.bind(_o$Foo.self))()) == null ? void 0 : _o$Foo$self$getSelf.m.bind(_o$Foo$self$getSelf))();
|
||||
((_o$Foo$self$getSelf2 = ((_o$Foo$self = o.Foo.self) == null ? void 0 : _o$Foo$self.getSelf.bind(_o$Foo$self))()) == null ? void 0 : _o$Foo$self$getSelf2.m.bind(_o$Foo$self$getSelf2))();
|
||||
((_fn$Foo$self$getSelf = ((_fn = fn()) == null ? void 0 : (_fn$Foo = _fn.Foo) == null ? void 0 : _fn$Foo.self.getSelf.bind(_fn.Foo.self))()) == null ? void 0 : _fn$Foo$self$getSelf.m.bind(_fn$Foo$self$getSelf))();
|
||||
((_fn$Foo$self$getSelf2 = (fn == null ? void 0 : (_fn$Foo$self2 = _fn$Foo$self = fn().Foo.self) == null ? void 0 : _fn$Foo$self2.getSelf.bind(_fn$Foo$self))()) == null ? void 0 : _fn$Foo$self$getSelf2.m.bind(_fn$Foo$self$getSelf2))();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
new Foo().test();
|
||||
@ -0,0 +1,47 @@
|
||||
class Foo {
|
||||
constructor() {
|
||||
this.x = 1;
|
||||
this.self = this;
|
||||
}
|
||||
m() { return this.x; };
|
||||
getSelf() { return this }
|
||||
|
||||
test() {
|
||||
const Foo = this;
|
||||
const o = { Foo: Foo };
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
expect((Foo?.["m"])()).toEqual(1);
|
||||
expect((Foo?.["m"])().toString).toEqual(1..toString);
|
||||
expect((Foo?.["m"])().toString()).toEqual('1');
|
||||
|
||||
expect((o?.Foo.m)()).toEqual(1);
|
||||
expect((o?.Foo.m)().toString).toEqual(1..toString);
|
||||
expect((o?.Foo.m)().toString()).toEqual('1');
|
||||
|
||||
expect((((o.Foo?.self.getSelf)())?.m)()).toEqual(1);
|
||||
expect((((o.Foo.self?.getSelf)())?.m)()).toEqual(1);
|
||||
|
||||
expect((((fn()?.Foo?.self.getSelf)())?.m)()).toEqual(1);
|
||||
expect((((fn?.().Foo.self?.getSelf)())?.m)()).toEqual(1);
|
||||
}
|
||||
|
||||
testNull() {
|
||||
const o = null;
|
||||
|
||||
expect(() => { (o?.Foo.m)() }).toThrow();
|
||||
expect(() => { (o?.Foo.m)().toString }).toThrow();
|
||||
expect(() => { (o?.Foo.m)().toString() }).toThrow();
|
||||
|
||||
expect(() => { (((o.Foo?.self.getSelf)())?.m)() }).toThrow();
|
||||
expect(() => { (((o.Foo.self?.getSelf)())?.m)() }).toThrow();
|
||||
|
||||
expect(() => (((fn()?.Foo?.self.getSelf)())?.m)()).toThrow();
|
||||
expect(() => (((fn?.().Foo.self?.getSelf)())?.m)()).toThrow();
|
||||
}
|
||||
}
|
||||
|
||||
(new Foo).test();
|
||||
(new Foo).testNull();
|
||||
@ -0,0 +1,32 @@
|
||||
class Foo {
|
||||
constructor() {
|
||||
this.x = 1;
|
||||
this.self = this;
|
||||
}
|
||||
m() { return this.x; };
|
||||
getSelf() { return this }
|
||||
|
||||
test() {
|
||||
const Foo = this;
|
||||
const o = { Foo: Foo };
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
(Foo?.["m"])();
|
||||
(Foo?.["m"])().toString;
|
||||
(Foo?.["m"])().toString();
|
||||
|
||||
(o?.Foo.m)();
|
||||
(o?.Foo.m)().toString;
|
||||
(o?.Foo.m)().toString();
|
||||
|
||||
(((o.Foo?.self.getSelf)())?.m)();
|
||||
(((o.Foo.self?.getSelf)())?.m)();
|
||||
|
||||
(((fn()?.Foo?.self.getSelf)())?.m)();
|
||||
(((fn?.().Foo.self?.getSelf)())?.m)();
|
||||
}
|
||||
}
|
||||
|
||||
(new Foo).test();
|
||||
@ -0,0 +1,41 @@
|
||||
class Foo {
|
||||
constructor() {
|
||||
this.x = 1;
|
||||
this.self = this;
|
||||
}
|
||||
|
||||
m() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
getSelf() {
|
||||
return this;
|
||||
}
|
||||
|
||||
test() {
|
||||
var _o$Foo, _o$Foo2, _o$Foo3, _o$Foo$self$getSelf, _o$Foo4, _o$Foo4$self, _o$Foo$self$getSelf2, _o$Foo$self, _fn$Foo$self$getSelf, _fn, _fn$Foo$self, _fn$Foo, _fn$Foo$self$getSelf2, _fn$Foo$self2, _fn$Foo$self3;
|
||||
|
||||
const Foo = this;
|
||||
const o = {
|
||||
Foo: Foo
|
||||
};
|
||||
|
||||
const fn = function () {
|
||||
return o;
|
||||
};
|
||||
|
||||
(Foo === null || Foo === void 0 ? void 0 : Foo["m"].bind(Foo))();
|
||||
(Foo === null || Foo === void 0 ? void 0 : Foo["m"].bind(Foo))().toString;
|
||||
(Foo === null || Foo === void 0 ? void 0 : Foo["m"].bind(Foo))().toString();
|
||||
(o === null || o === void 0 ? void 0 : (_o$Foo = o.Foo).m.bind(_o$Foo))();
|
||||
(o === null || o === void 0 ? void 0 : (_o$Foo2 = o.Foo).m.bind(_o$Foo2))().toString;
|
||||
(o === null || o === void 0 ? void 0 : (_o$Foo3 = o.Foo).m.bind(_o$Foo3))().toString();
|
||||
((_o$Foo$self$getSelf = ((_o$Foo4 = o.Foo) === null || _o$Foo4 === void 0 ? void 0 : (_o$Foo4$self = _o$Foo4.self).getSelf.bind(_o$Foo4$self))()) === null || _o$Foo$self$getSelf === void 0 ? void 0 : _o$Foo$self$getSelf.m.bind(_o$Foo$self$getSelf))();
|
||||
((_o$Foo$self$getSelf2 = ((_o$Foo$self = o.Foo.self) === null || _o$Foo$self === void 0 ? void 0 : _o$Foo$self.getSelf.bind(_o$Foo$self))()) === null || _o$Foo$self$getSelf2 === void 0 ? void 0 : _o$Foo$self$getSelf2.m.bind(_o$Foo$self$getSelf2))();
|
||||
((_fn$Foo$self$getSelf = ((_fn = fn()) === null || _fn === void 0 ? void 0 : (_fn$Foo = _fn.Foo) === null || _fn$Foo === void 0 ? void 0 : (_fn$Foo$self = _fn$Foo.self).getSelf.bind(_fn$Foo$self))()) === null || _fn$Foo$self$getSelf === void 0 ? void 0 : _fn$Foo$self$getSelf.m.bind(_fn$Foo$self$getSelf))();
|
||||
((_fn$Foo$self$getSelf2 = (fn === null || fn === void 0 ? void 0 : (_fn$Foo$self3 = _fn$Foo$self2 = fn().Foo.self) === null || _fn$Foo$self3 === void 0 ? void 0 : _fn$Foo$self3.getSelf.bind(_fn$Foo$self2))()) === null || _fn$Foo$self$getSelf2 === void 0 ? void 0 : _fn$Foo$self$getSelf2.m.bind(_fn$Foo$self$getSelf2))();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
new Foo().test();
|
||||
Loading…
x
Reference in New Issue
Block a user