Skip to content

Commit

Permalink
feat: transform ?.#x and ?.#m()
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung committed May 22, 2020
1 parent 0742d99 commit 9635a42
Show file tree
Hide file tree
Showing 11 changed files with 739 additions and 183 deletions.
Expand Up @@ -125,12 +125,6 @@ const handle = {
throw member.buildCodeFrameError(`can't handle delete`);
}

if (node.optional) {
throw member.buildCodeFrameError(
`can't handle '?.' directly before ${node.property.type}`,
);
}

// Now, we're looking for the start of this optional chain, which is
// optional to the left of this member.
//
Expand All @@ -150,6 +144,8 @@ const handle = {
startingOptional = startingOptional.get("callee");
continue;
}
// prevent infinite loop: unreachable if the AST is well-formed
throw new Error("Internal error");
}

const { scope } = member;
Expand All @@ -160,8 +156,13 @@ const handle = {
const baseRef = scope.generateUidIdentifierBasedOnNode(startingNode);
scope.push({ id: baseRef });

// Compute parentIsOptionalCall before `startingOptional` is replaced
// as `node` may refer to `startingOptional.node` before replaced.
const parentIsOptionalCall = parentPath.isOptionalCallExpression({
callee: node,
});
startingOptional.replaceWith(toNonOptional(startingOptional, baseRef));
if (parentPath.isOptionalCallExpression({ callee: node })) {
if (parentIsOptionalCall) {
parentPath.replaceWith(this.call(member, parent.arguments));
} else {
member.replaceWith(this.get(member));
Expand Down
Expand Up @@ -15,20 +15,38 @@ class Foo {
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?.#m()).toEqual(1);
expect(o?.Foo?.#m().toString).toEqual(1..toString);
expect(o?.Foo?.#m().toString()).toEqual('1');

expect(deep?.very.o?.Foo.#m()).toEqual(1);
expect(deep?.very.o?.Foo.#m().toString).toEqual(1..toString);
expect(deep?.very.o?.Foo.#m().toString()).toEqual('1');

expect(deep?.very.o?.Foo?.#m()).toEqual(1);
expect(deep?.very.o?.Foo?.#m().toString).toEqual(1..toString);
expect(deep?.very.o?.Foo?.#m().toString()).toEqual('1');

expect(o?.Foo.#self.#m()).toEqual(1);
expect(o?.Foo.#self.self.#m()).toEqual(1);
expect(o?.Foo.#self?.self.#m()).toEqual(1);
expect(o?.Foo.#self.self?.self.#m()).toEqual(1);
expect(o?.Foo.#self?.self?.self.#m()).toEqual(1);

expect(o?.Foo.#self?.#m()).toEqual(1);
expect(o?.Foo.#self.self?.#m()).toEqual(1);
expect(o?.Foo.#self?.self?.#m()).toEqual(1);
expect(o?.Foo.#self.self?.self?.#m()).toEqual(1);
expect(o?.Foo.#self?.self?.self?.#m()).toEqual(1);

expect(o?.Foo.#self.getSelf().#m()).toEqual(1);
expect(o?.Foo.#self.getSelf?.().#m()).toEqual(1);
expect(o?.Foo.#self?.getSelf().#m()).toEqual(1);
Expand All @@ -38,20 +56,43 @@ class Foo {
expect(o?.Foo.#self?.getSelf()?.self.#m()).toEqual(1);
expect(o?.Foo.#self?.getSelf?.()?.self.#m()).toEqual(1);

expect(o?.Foo.#self.getSelf()?.#m()).toEqual(1);
expect(o?.Foo.#self.getSelf?.()?.#m()).toEqual(1);
expect(o?.Foo.#self?.getSelf()?.#m()).toEqual(1);
expect(o?.Foo.#self?.getSelf?.()?.#m()).toEqual(1);
expect(o?.Foo.#self.getSelf()?.self?.#m()).toEqual(1);
expect(o?.Foo.#self.getSelf?.()?.self?.#m()).toEqual(1);
expect(o?.Foo.#self?.getSelf()?.self?.#m()).toEqual(1);
expect(o?.Foo.#self?.getSelf?.()?.self?.#m()).toEqual(1)

expect(fn?.().Foo.#m()).toEqual(1);
expect(fn?.().Foo.#m().toString).toEqual(1..toString);
expect(fn?.().Foo.#m().toString()).toEqual('1');

expect(fn?.().Foo?.#m()).toEqual(1);
expect(fn?.().Foo?.#m().toString).toEqual(1..toString);
expect(fn?.().Foo?.#m().toString()).toEqual('1');

expect(fnDeep?.().very.o?.Foo.#m()).toEqual(1);
expect(fnDeep?.().very.o?.Foo.#m().toString).toEqual(1..toString);
expect(fnDeep?.().very.o?.Foo.#m().toString()).toEqual('1');

expect(fnDeep?.().very.o?.Foo?.#m()).toEqual(1);
expect(fnDeep?.().very.o?.Foo?.#m().toString).toEqual(1..toString);
expect(fnDeep?.().very.o?.Foo?.#m().toString()).toEqual('1');

expect(fn?.().Foo.#self.#m()).toEqual(1);
expect(fn?.().Foo.#self.self.#m()).toEqual(1);
expect(fn?.().Foo.#self?.self.#m()).toEqual(1);
expect(fn?.().Foo.#self.self?.self.#m()).toEqual(1);
expect(fn?.().Foo.#self?.self?.self.#m()).toEqual(1);

expect(fn?.().Foo.#self?.#m()).toEqual(1);
expect(fn?.().Foo.#self.self?.#m()).toEqual(1);
expect(fn?.().Foo.#self?.self?.#m()).toEqual(1);
expect(fn?.().Foo.#self.self?.self?.#m()).toEqual(1);
expect(fn?.().Foo.#self?.self?.self?.#m()).toEqual(1);

expect(fn?.().Foo.#self.getSelf().#m()).toEqual(1);
expect(fn?.().Foo.#self.getSelf?.().#m()).toEqual(1);
expect(fn?.().Foo.#self?.getSelf().#m()).toEqual(1);
Expand All @@ -60,6 +101,15 @@ class Foo {
expect(fn?.().Foo.#self.getSelf?.()?.self.#m()).toEqual(1);
expect(fn?.().Foo.#self?.getSelf()?.self.#m()).toEqual(1);
expect(fn?.().Foo.#self?.getSelf?.()?.self.#m()).toEqual(1);

expect(fn?.().Foo.#self.getSelf()?.#m()).toEqual(1);
expect(fn?.().Foo.#self.getSelf?.()?.#m()).toEqual(1);
expect(fn?.().Foo.#self?.getSelf()?.#m()).toEqual(1);
expect(fn?.().Foo.#self?.getSelf?.()?.#m()).toEqual(1);
expect(fn?.().Foo.#self.getSelf()?.self?.#m()).toEqual(1);
expect(fn?.().Foo.#self.getSelf?.()?.self?.#m()).toEqual(1);
expect(fn?.().Foo.#self?.getSelf()?.self?.#m()).toEqual(1);
expect(fn?.().Foo.#self?.getSelf?.()?.self?.#m()).toEqual(1);
}

static testNull() {
Expand All @@ -70,51 +120,97 @@ class Foo {
return deep;
}

expect(o?.Foo.#m()).toEqual(undefined);
expect(o?.Foo.#m().toString).toEqual(undefined);
expect(o?.Foo.#m().toString()).toEqual(undefined);

expect(deep?.very.o?.Foo.#m()).toEqual(undefined);
expect(deep?.very.o?.Foo.#m().toString).toEqual(undefined);
expect(deep?.very.o?.Foo.#m().toString()).toEqual(undefined);

expect(o?.Foo.#self.#m()).toEqual(undefined);
expect(o?.Foo.#self.self.#m()).toEqual(undefined);
expect(o?.Foo.#self?.self.#m()).toEqual(undefined);
expect(o?.Foo.#self.self?.self.#m()).toEqual(undefined);
expect(o?.Foo.#self?.self?.self.#m()).toEqual(undefined);

expect(o?.Foo.#self.getSelf().#m()).toEqual(undefined);
expect(o?.Foo.#self.getSelf?.().#m()).toEqual(undefined);
expect(o?.Foo.#self?.getSelf().#m()).toEqual(undefined);
expect(o?.Foo.#self?.getSelf?.().#m()).toEqual(undefined);
expect(o?.Foo.#self.getSelf()?.self.#m()).toEqual(undefined);
expect(o?.Foo.#self.getSelf?.()?.self.#m()).toEqual(undefined);
expect(o?.Foo.#self?.getSelf()?.self.#m()).toEqual(undefined);
expect(o?.Foo.#self?.getSelf?.()?.self.#m()).toEqual(undefined);

expect(fn?.().Foo.#m()).toEqual(undefined);
expect(fn?.().Foo.#m().toString).toEqual(undefined);
expect(fn?.().Foo.#m().toString()).toEqual(undefined);

expect(fnDeep?.().very.o?.Foo.#m()).toEqual(undefined);
expect(fnDeep?.().very.o?.Foo.#m().toString).toEqual(undefined);
expect(fnDeep?.().very.o?.Foo.#m().toString()).toEqual(undefined);

expect(fn?.().Foo.#self.#m()).toEqual(undefined);
expect(fn?.().Foo.#self.self.#m()).toEqual(undefined);
expect(fn?.().Foo.#self?.self.#m()).toEqual(undefined);
expect(fn?.().Foo.#self.self?.self.#m()).toEqual(undefined);
expect(fn?.().Foo.#self?.self?.self.#m()).toEqual(undefined);

expect(fn?.().Foo.#self.getSelf().#m()).toEqual(undefined);
expect(fn?.().Foo.#self.getSelf?.().#m()).toEqual(undefined);
expect(fn?.().Foo.#self?.getSelf().#m()).toEqual(undefined);
expect(fn?.().Foo.#self?.getSelf?.().#m()).toEqual(undefined);
expect(fn?.().Foo.#self.getSelf()?.self.#m()).toEqual(undefined);
expect(fn?.().Foo.#self.getSelf?.()?.self.#m()).toEqual(undefined);
expect(fn?.().Foo.#self?.getSelf()?.self.#m()).toEqual(undefined);
expect(fn?.().Foo.#self?.getSelf?.()?.self.#m()).toEqual(undefined);
expect(o?.Foo.#m()).toBeUndefined();
expect(o?.Foo.#m().toString).toBeUndefined();
expect(o?.Foo.#m().toString()).toBeUndefined();

expect(o?.Foo?.#m()).toBeUndefined();
expect(o?.Foo?.#m().toString).toBeUndefined();
expect(o?.Foo?.#m().toString()).toBeUndefined();

expect(deep?.very.o?.Foo.#m()).toBeUndefined();
expect(deep?.very.o?.Foo.#m().toString).toBeUndefined();
expect(deep?.very.o?.Foo.#m().toString()).toBeUndefined();

expect(deep?.very.o?.Foo?.#m()).toBeUndefined();
expect(deep?.very.o?.Foo?.#m().toString).toBeUndefined();
expect(deep?.very.o?.Foo?.#m().toString()).toBeUndefined();

expect(o?.Foo.#self.#m()).toBeUndefined();
expect(o?.Foo.#self.self.#m()).toBeUndefined();
expect(o?.Foo.#self?.self.#m()).toBeUndefined();
expect(o?.Foo.#self.self?.self.#m()).toBeUndefined();
expect(o?.Foo.#self?.self?.self.#m()).toBeUndefined();

expect(o?.Foo.#self?.#m()).toBeUndefined();
expect(o?.Foo.#self.self?.#m()).toBeUndefined();
expect(o?.Foo.#self?.self?.#m()).toBeUndefined();
expect(o?.Foo.#self.self?.self?.#m()).toBeUndefined();
expect(o?.Foo.#self?.self?.self?.#m()).toBeUndefined();

expect(o?.Foo.#self.getSelf().#m()).toBeUndefined();
expect(o?.Foo.#self.getSelf?.().#m()).toBeUndefined();
expect(o?.Foo.#self?.getSelf().#m()).toBeUndefined();
expect(o?.Foo.#self?.getSelf?.().#m()).toBeUndefined();
expect(o?.Foo.#self.getSelf()?.self.#m()).toBeUndefined();
expect(o?.Foo.#self.getSelf?.()?.self.#m()).toBeUndefined();
expect(o?.Foo.#self?.getSelf()?.self.#m()).toBeUndefined();
expect(o?.Foo.#self?.getSelf?.()?.self.#m()).toBeUndefined();

expect(o?.Foo.#self.getSelf()?.#m()).toBeUndefined();
expect(o?.Foo.#self.getSelf?.()?.#m()).toBeUndefined();
expect(o?.Foo.#self?.getSelf()?.#m()).toBeUndefined();
expect(o?.Foo.#self?.getSelf?.()?.#m()).toBeUndefined();
expect(o?.Foo.#self.getSelf()?.self?.#m()).toBeUndefined();
expect(o?.Foo.#self.getSelf?.()?.self?.#m()).toBeUndefined();
expect(o?.Foo.#self?.getSelf()?.self?.#m()).toBeUndefined();
expect(o?.Foo.#self?.getSelf?.()?.self?.#m()).toBeUndefined()

expect(fn?.().Foo.#m()).toBeUndefined();
expect(fn?.().Foo.#m().toString).toBeUndefined();
expect(fn?.().Foo.#m().toString()).toBeUndefined();

expect(fn?.().Foo?.#m()).toBeUndefined();
expect(fn?.().Foo?.#m().toString).toBeUndefined();
expect(fn?.().Foo?.#m().toString()).toBeUndefined();

expect(fnDeep?.().very.o?.Foo.#m()).toBeUndefined();
expect(fnDeep?.().very.o?.Foo.#m().toString).toBeUndefined();
expect(fnDeep?.().very.o?.Foo.#m().toString()).toBeUndefined();

expect(fnDeep?.().very.o?.Foo?.#m()).toBeUndefined();
expect(fnDeep?.().very.o?.Foo?.#m().toString).toBeUndefined();
expect(fnDeep?.().very.o?.Foo?.#m().toString()).toBeUndefined();

expect(fn?.().Foo.#self.#m()).toBeUndefined();
expect(fn?.().Foo.#self.self.#m()).toBeUndefined();
expect(fn?.().Foo.#self?.self.#m()).toBeUndefined();
expect(fn?.().Foo.#self.self?.self.#m()).toBeUndefined();
expect(fn?.().Foo.#self?.self?.self.#m()).toBeUndefined();

expect(fn?.().Foo.#self?.#m()).toBeUndefined();
expect(fn?.().Foo.#self.self?.#m()).toBeUndefined();
expect(fn?.().Foo.#self?.self?.#m()).toBeUndefined();
expect(fn?.().Foo.#self.self?.self?.#m()).toBeUndefined();
expect(fn?.().Foo.#self?.self?.self?.#m()).toBeUndefined();

expect(fn?.().Foo.#self.getSelf().#m()).toBeUndefined();
expect(fn?.().Foo.#self.getSelf?.().#m()).toBeUndefined();
expect(fn?.().Foo.#self?.getSelf().#m()).toBeUndefined();
expect(fn?.().Foo.#self?.getSelf?.().#m()).toBeUndefined();
expect(fn?.().Foo.#self.getSelf()?.self.#m()).toBeUndefined();
expect(fn?.().Foo.#self.getSelf?.()?.self.#m()).toBeUndefined();
expect(fn?.().Foo.#self?.getSelf()?.self.#m()).toBeUndefined();
expect(fn?.().Foo.#self?.getSelf?.()?.self.#m()).toBeUndefined();

expect(fn?.().Foo.#self.getSelf()?.#m()).toBeUndefined();
expect(fn?.().Foo.#self.getSelf?.()?.#m()).toBeUndefined();
expect(fn?.().Foo.#self?.getSelf()?.#m()).toBeUndefined();
expect(fn?.().Foo.#self?.getSelf?.()?.#m()).toBeUndefined();
expect(fn?.().Foo.#self.getSelf()?.self?.#m()).toBeUndefined();
expect(fn?.().Foo.#self.getSelf?.()?.self?.#m()).toBeUndefined();
expect(fn?.().Foo.#self?.getSelf()?.self?.#m()).toBeUndefined();
expect(fn?.().Foo.#self?.getSelf?.()?.self?.#m()).toBeUndefined();
}
}

Expand Down
Expand Up @@ -15,20 +15,38 @@ class Foo {
return deep;
}

Foo?.#m();
Foo?.#m().toString;
Foo?.#m().toString();

o?.Foo.#m();
o?.Foo.#m().toString;
o?.Foo.#m().toString();

o?.Foo?.#m();
o?.Foo?.#m().toString;
o?.Foo?.#m().toString();

deep?.very.o?.Foo.#m();
deep?.very.o?.Foo.#m().toString;
deep?.very.o?.Foo.#m().toString();

deep?.very.o?.Foo?.#m();
deep?.very.o?.Foo?.#m().toString;
deep?.very.o?.Foo?.#m().toString();

o?.Foo.#self.#m();
o?.Foo.#self.self.#m();
o?.Foo.#self?.self.#m();
o?.Foo.#self.self?.self.#m();
o?.Foo.#self?.self?.self.#m();

o?.Foo.#self?.#m();
o?.Foo.#self.self?.#m();
o?.Foo.#self?.self?.#m();
o?.Foo.#self.self?.self?.#m();
o?.Foo.#self?.self?.self?.#m();

o?.Foo.#self.getSelf().#m();
o?.Foo.#self.getSelf?.().#m();
o?.Foo.#self?.getSelf().#m();
Expand All @@ -38,20 +56,43 @@ class Foo {
o?.Foo.#self?.getSelf()?.self.#m();
o?.Foo.#self?.getSelf?.()?.self.#m();

o?.Foo.#self.getSelf()?.#m();
o?.Foo.#self.getSelf?.()?.#m();
o?.Foo.#self?.getSelf()?.#m();
o?.Foo.#self?.getSelf?.()?.#m();
o?.Foo.#self.getSelf()?.self?.#m();
o?.Foo.#self.getSelf?.()?.self?.#m();
o?.Foo.#self?.getSelf()?.self?.#m();
o?.Foo.#self?.getSelf?.()?.self?.#m()

fn?.().Foo.#m();
fn?.().Foo.#m().toString;
fn?.().Foo.#m().toString();

fn?.().Foo?.#m();
fn?.().Foo?.#m().toString;
fn?.().Foo?.#m().toString();

fnDeep?.().very.o?.Foo.#m();
fnDeep?.().very.o?.Foo.#m().toString;
fnDeep?.().very.o?.Foo.#m().toString();

fnDeep?.().very.o?.Foo?.#m();
fnDeep?.().very.o?.Foo?.#m().toString;
fnDeep?.().very.o?.Foo?.#m().toString();

fn?.().Foo.#self.#m();
fn?.().Foo.#self.self.#m();
fn?.().Foo.#self?.self.#m();
fn?.().Foo.#self.self?.self.#m();
fn?.().Foo.#self?.self?.self.#m();

fn?.().Foo.#self?.#m();
fn?.().Foo.#self.self?.#m();
fn?.().Foo.#self?.self?.#m();
fn?.().Foo.#self.self?.self?.#m();
fn?.().Foo.#self?.self?.self?.#m();

fn?.().Foo.#self.getSelf().#m();
fn?.().Foo.#self.getSelf?.().#m();
fn?.().Foo.#self?.getSelf().#m();
Expand All @@ -60,6 +101,15 @@ class Foo {
fn?.().Foo.#self.getSelf?.()?.self.#m();
fn?.().Foo.#self?.getSelf()?.self.#m();
fn?.().Foo.#self?.getSelf?.()?.self.#m();

fn?.().Foo.#self.getSelf()?.#m();
fn?.().Foo.#self.getSelf?.()?.#m();
fn?.().Foo.#self?.getSelf()?.#m();
fn?.().Foo.#self?.getSelf?.()?.#m();
fn?.().Foo.#self.getSelf()?.self?.#m();
fn?.().Foo.#self.getSelf?.()?.self?.#m();
fn?.().Foo.#self?.getSelf()?.self?.#m();
fn?.().Foo.#self?.getSelf?.()?.self?.#m();
}
}

Expand Down

0 comments on commit 9635a42

Please sign in to comment.