Skip to content
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

Correctly track thisContainer for this-property-assignments in JS nested containers #22779

Merged
merged 5 commits into from
Mar 22, 2018

Conversation

sandersn
Copy link
Member

Previously thisContainer (previously called containerContainer) would update on every block, not just those that could bind this.

In addition, if the constructor symbol still can't be found, then no binding happens. This is usually OK because people don't add new properties in methods too often.

Fixes #22774

Previously it would update on every block, not just those that could
bind `this`.

In addition, if the constructor symbol still can't be found, then no
binding happens. This is usually OK because people don't add new
properties in methods too often.
@sandersn sandersn requested review from a user and weswigham March 21, 2018 23:04
// Extend that DOM!
Event.prototype.removeChildren = function () {
~~~~~
!!! error TS2304: Cannot find name 'Event'.
Copy link
Member

Choose a reason for hiding this comment

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

Maybe add @lib: dom to this test?

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

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

We'll also want a ts2.8 port

@@ -479,11 +479,9 @@ namespace ts {
// and block-container. Then after we pop out of processing the children, we restore
// these saved values.
const saveContainer = container;
const saveContainerContainer = containerContainer;
const saveContainerContainer = thisParentContainer;
Copy link

Choose a reason for hiding this comment

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

Rename this too

// @noEmit: true
// @Filename: bluebird.js

!function outer (f) { return f }(
Copy link

Choose a reason for hiding this comment

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

Could this be made simpler? Why are we applying identity and then negating it?

Copy link
Member Author

Choose a reason for hiding this comment

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

(I'm doing some digging to find out why all these pieces appear to be required.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Here's a simpler repro that fails on batch compilation:

function Async() {
    this._trampolineEnabled = true;
}

Async.prototype.disableTrampolineIfNecessary = function dtin(b) {
    if (b) {
        this._trampolineEnabled = false;
    }
};

I was testing on the language service, and I can't get this repro to crash consistently like I can the more complex one -- you just have to request diagnostics for that one.

this._trampolineEnabled = false;
}
};
var a = new Async()
Copy link

Choose a reason for hiding this comment

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

Are these 3 lines necessary to the test?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, this really only checks (1) lack of crashes and (2) symbol correctness. Removed.

// ArrowFunction isn't treated as a this-container
(args) => {
this.args = args
this.newProperty = 1
Copy link

Choose a reason for hiding this comment

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

Include a test that new Installer().newProperty is number | undefined?
Also, fix indents

Copy link
Member Author

Choose a reason for hiding this comment

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

Hm. Turns out newProperty: number | undefined but args: number even when it's initialized with this.args = 0. I'll have to find out why.

Copy link
Member Author

@sandersn sandersn Mar 22, 2018

Choose a reason for hiding this comment

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

Ah. The assignment in loadArgMetadata acts as a second declaration, so we union the types together. This is not ideal — we shouldn't redeclare properties that we know are in the constructor — but I'll fix it separately.

Copy link
Member Author

Choose a reason for hiding this comment

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

Opened #22792 to track this; there are couple of things to consider before changing this.

// @checkJs: true
// @noEmit: true
// @Filename: npm-install.js
function Installer (where, dryrun, args, opts) {
Copy link

Choose a reason for hiding this comment

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

Would be simpler to just write this.args = 0 and take no parameters?

@mhegazy
Copy link
Contributor

mhegazy commented Mar 22, 2018

@sandersn please port to release-2.8 as well.

@sandersn
Copy link
Member Author

@mhegazy @andy-ms The break introduced in #22643 is not in 2.8, so this fix does not apply to 2.8.

To port to 2.8, I'd have to port #22643 too, and it's a complex fix to a subtle problem. (The problem is that there are too many symbols created from this-assignments, which breaks rename and find-all-refs.)

@@ -479,7 +479,7 @@ namespace ts {
// and block-container. Then after we pop out of processing the children, we restore
// these saved values.
const saveContainer = container;
const saveContainerContainer = thisParentContainer;
const saveThisContainer = thisParentContainer;
Copy link

Choose a reason for hiding this comment

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

Nit: saveThisParentContainer, since the thisContainer would just be container usually.

@mhegazy
Copy link
Contributor

mhegazy commented Mar 22, 2018

thanks for the clarification. if the break is not in 2.8 we do not need to port anything.

@sandersn sandersn merged commit 4462c15 into master Mar 22, 2018
@sandersn sandersn deleted the js/fix-this-assignments-in-nested-containers branch March 22, 2018 17:37
@microsoft microsoft locked and limited conversation to collaborators Jul 25, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants