Skip to content

Per-property super accessors in async functions. #26707

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 6, 2018

Conversation

mprobst
Copy link
Contributor

@mprobst mprobst commented Aug 28, 2018

TypeScript must hoist accessors for super properties when converting
async method bodies to the __awaiter pattern for targets before
ES2016.

Previously, TypeScript would reify all property accesses into element
accesses, i.e. convert the property name into a string parameter and
pass it to super[...]. That breaks optimizers like Closure Compiler or
Uglify in advanced mode, when property renaming is enabled, as it mixes
quoted and un-quoted property access (super['x'] vs just x at the
declaration site).

This change creates a specific accessor for each property access on
super, which fixes the quoted/unquoted confusion. It keeps the generic
accessor for element access statements.

Fixes #21088.

@mprobst
Copy link
Contributor Author

mprobst commented Aug 28, 2018

Might be worth noting: this change disables the early exit in the esnext & ES2017 transformers, here:
dcf2f7e#diff-b0af6bd9d1d8b206a6b9ac13af6deab3L56

It'd be possible to special case further and use a specific visitor when traversing an async method's body. I'm not sure it's worth the complication - any advice?

The other thing I'm not 100% clear on is the scope for the substitutedSuperAccessors array. It's currently per transformer invocation. It might be possible to remove it by moving to a property on the node, but this seems to match the general design better.

return __awaiter(this, void 0, void 0, function* () {
const _super = null;
const f = () => { };
// call with property access
_super_1("x").value.call(this);
_super_x().value.call(this);
Copy link
Contributor

@AlCalzone AlCalzone Aug 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm missing something, but looking at the way _super_x is defined in line 91 (an object), shouldn't this be

_super_x.value.call(this);
//      ^ no parentheses

instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thanks!

I've fixed this by moving to the implementation that @rbuckton suggested in #21088, i.e. creating a single object _superProps that contains configured properties for each named property.

@mprobst mprobst force-pushed the async-super-rename-safe branch 2 times, most recently from 4034cf9 to bce7cfd Compare August 29, 2018 12:03
@RyanCavanaugh RyanCavanaugh requested a review from rbuckton August 29, 2018 20:55
@mprobst mprobst force-pushed the async-super-rename-safe branch from bce7cfd to f784d8a Compare August 31, 2018 09:03
@mprobst
Copy link
Contributor Author

mprobst commented Sep 10, 2018

@rbuckton please take another look.

@RyanCavanaugh RyanCavanaugh added this to the Community milestone Sep 17, 2018
@mprobst
Copy link
Contributor Author

mprobst commented Oct 2, 2018

Friendly ping.

@sandersn sandersn self-requested a review October 2, 2018 16:59
Copy link
Member

@sandersn sandersn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good except for a couple of typos in comments.

Copy link
Contributor

@rbuckton rbuckton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor change needed for tests.

TypeScript must hoist accessors for super properties when converting
async method bodies to the `__awaiter` pattern for targets before
ES2016.

Previously, TypeScript would reify all property accesses into element
accesses, i.e. convert the property name into a string parameter and
pass it to `super[...]`. That breaks optimizers like Closure Compiler or
Uglify in advanced mode, when property renaming is enabled, as it mixes
quoted and un-quoted property access (`super['x']` vs just `x` at the
declaration site).

This change creates a variable `_superProps` that contains accessors for
each property accessed on super within the async method. This allows
accessing the properties by name (instead of quoted string), which fixes
the quoted/unquoted confusion. The change keeps the generic accessor for
element access statements to match quoting behaviour.

Fixes microsoft#21088.
* rename _super to _superIndex and _superProps to _super.
* reinstate early exit for transformers by marking super accesses as
  esnext/es2017 in `binder.ts`.
* adjust comment in `checker.ts` to new emit.
@mprobst mprobst force-pushed the async-super-rename-safe branch 2 times, most recently from c7e8a99 to 57d922a Compare October 3, 2018 13:51
@mprobst
Copy link
Contributor Author

mprobst commented Oct 3, 2018

Done, please take another look.

Copy link
Member

@sandersn sandersn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you added a few git submodules under src/ by mistake.

Change-Id: I30af09343446126ba73ed40199ecc3f0ed515b3e
@mprobst mprobst force-pushed the async-super-rename-safe branch from 57d922a to 539c455 Compare October 4, 2018 06:08
@mprobst
Copy link
Contributor Author

mprobst commented Oct 4, 2018

Fixed. Must have been VS Code doing something in my working directory? Odd.

@sandersn
Copy link
Member

sandersn commented Oct 5, 2018

@rbuckton Does it look good to you? If so, you can merge, or I will after the weekend.

@rbuckton
Copy link
Contributor

rbuckton commented Oct 6, 2018

Looks good!

@rbuckton rbuckton merged commit 85a3475 into microsoft:master Oct 6, 2018
@mprobst
Copy link
Contributor Author

mprobst commented Oct 6, 2018 via email

@mprobst mprobst deleted the async-super-rename-safe branch March 9, 2020 08:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ES6 transpilation of async + super call moves properties from unquoted->quoted
5 participants