Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
1 parent
3a3457d
commit 1e115ae
Showing
30 changed files
with
929 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
...ies/test/fixtures/private-loose/parenthesized-optional-member-call-with-transform/exec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); |
30 changes: 30 additions & 0 deletions
30
...es/test/fixtures/private-loose/parenthesized-optional-member-call-with-transform/input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); |
7 changes: 7 additions & 0 deletions
7
...est/fixtures/private-loose/parenthesized-optional-member-call-with-transform/options.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"plugins": [ | ||
["external-helpers", { "helperVersion": "7.100.0" }], | ||
["proposal-class-properties", { "loose": true }], | ||
["proposal-optional-chaining", { "loose": true }] | ||
] | ||
} |
46 changes: 46 additions & 0 deletions
46
...s/test/fixtures/private-loose/parenthesized-optional-member-call-with-transform/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); |
48 changes: 48 additions & 0 deletions
48
...l-class-properties/test/fixtures/private-loose/parenthesized-optional-member-call/exec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); |
30 changes: 30 additions & 0 deletions
30
...-class-properties/test/fixtures/private-loose/parenthesized-optional-member-call/input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); |
7 changes: 7 additions & 0 deletions
7
...ss-properties/test/fixtures/private-loose/parenthesized-optional-member-call/options.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"plugins": [ | ||
["external-helpers", { "helperVersion": "7.100.0" }], | ||
"proposal-class-properties" | ||
], | ||
"minNodeVersion": "14.0.0" | ||
} |
42 changes: 42 additions & 0 deletions
42
...class-properties/test/fixtures/private-loose/parenthesized-optional-member-call/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); |
48 changes: 48 additions & 0 deletions
48
...roperties/test/fixtures/private/parenthesized-optional-member-call-with-transform/exec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); |
30 changes: 30 additions & 0 deletions
30
...operties/test/fixtures/private/parenthesized-optional-member-call-with-transform/input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); |
Oops, something went wrong.