Skip to content

Commit

Permalink
fix: unwrap parthenthesizedExpression
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung committed May 27, 2020
1 parent 3672f7f commit fe7cd9e
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 8 deletions.
24 changes: 16 additions & 8 deletions packages/babel-plugin-proposal-optional-chaining/src/index.js
Expand Up @@ -23,14 +23,23 @@ export default declare((api, options) => {

visitor: {
"OptionalCallExpression|OptionalMemberExpression"(path) {
const { parentPath, scope } = path;
const { scope } = path;
let parentPath;
// unwrap parenthesis around parent path
for (
{ parentPath } = path;
parentPath.type === "ParenthesizedExpression";
{ parentPath } = parentPath
);
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) {
Expand All @@ -43,10 +52,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");
}
}
Expand Down Expand Up @@ -117,8 +124,9 @@ export default declare((api, options) => {
// Ensure (a?.b)() has proper `this`
if (
t.isMemberExpression(replacement) &&
replacement.extra?.parenthesized &&
replacementPath.parentPath.isCallExpression()
(replacement.extra?.parenthesized ||
replacementPath.parentPath !== parentPath) &&
parentPath.isCallExpression()
) {
// `(a?.b)()` to `(a == null ? undefined : a.b.bind(a))()`
const { object } = replacement;
Expand Down
@@ -0,0 +1,45 @@
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 deep = { very: { o } };
function fn() {
return o;
}
function fnDeep() {
return deep;
}

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);
}

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();
}
}

(new Foo).test();
(new Foo).testNull();
@@ -0,0 +1,6 @@
{
"plugins": ["proposal-optional-chaining"],
"parserOpts": {
"createParenthesizedExpressions": true
}
}

0 comments on commit fe7cd9e

Please sign in to comment.