-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Disable pessimistic object deoptimization for calls when the called function doesn't ref this #4011
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
Conversation
…unction doesn't ref this Issue #3989
Codecov Report
@@ Coverage Diff @@
## master #4011 +/- ##
==========================================
+ Coverage 97.21% 97.44% +0.22%
==========================================
Files 192 192
Lines 6762 6762
Branches 1973 1981 +8
==========================================
+ Hits 6574 6589 +15
+ Misses 101 85 -16
- Partials 87 88 +1
Continue to review full report at Codecov.
|
I'm frankly not terribly interested in writing a bunch of extra tests that make sure that all the |
I would not focus on the values first but rather the loss in coverage for |
For me the details of the code coverage report look like those changes are covered (and they should be, since they will be exercised by just about every method call). I was thinking a refactor of values.ts might be a good idea anyway, to avoid duplication (I had to add identical copies of the new method in eight different places), and that might magically solve the code coverage thing. I'll give that a shot later. |
You are right, it is just some sub-cases which are not covered and it might be ok to skip them (though the ones in LocalVariable DO cover relevant situations, at least the "reassigned" and "no init" cases. The one in Identifier is likely impossible to trigger and one could actually use a TypeScript A refactoring of |
And thank you for bearing with me a little here. I know the tests are usually a real pain, but it gives us the ability to do fundamental refactorings of the code base with a high level of safety, and this has happened before and will happen again. |
To avoid duplicating all ExpressionEntity methods for every object.
Attached patch does the refactor, but code coverage bot still isn't quite happy. Let me know if you want me to test those |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! I will see if I can add a test for multi-expression. I like what you did with the values. Two very minor suggestions remaining, but in general this looks sound to me.
@@ -38,6 +39,12 @@ export default class ThisExpression extends NodeBase { | |||
this.start | |||
); | |||
} | |||
for (let parent = this.parent; parent instanceof NodeBase; parent = parent.parent) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I like this use of a for loop.
src/ast/nodes/shared/FunctionNode.ts
Outdated
scope!: FunctionScope; | ||
|
||
private isPrototypeDeoptimized = false; | ||
|
||
createScope(parentScope: FunctionScope) { | ||
this.scope = new FunctionScope(parentScope, this.context); | ||
// Initialized here because child nodes will update it before | ||
// `this.initialize` even runs. | ||
this.referencesThis = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see. Maybe move it rather into parseNode
, which is where "initialisation before initialise" usually happens. I.e. parseNode
is guaranteed to run before child nodes are even created.
src/ast/values.ts
Outdated
toString: () => '[[UNKNOWN STRING]]' | ||
includeAll(context, args); | ||
} | ||
toString() { return '[[UNKNOWN STRING]]' } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually these "toString" are only here for debugging and I do not think they turned out to be any useful. We should just remove them all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should definitely include arrow functions as well! Those do not derive from FunctionNode.
As I am on the code if you do not mind I would push the changes myself. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If CI passes, this looks good to be merged from my side
Fun fact: Looking at the tests there are a lot of variables that are called removedX. Which are now removed again! |
Good point, thanks for catching that. |
Coverage is unhappy again. How do we proceed here? Should I add a test with some expressions like |
Na, let's leave it. |
…unction doesn't ref this (#4011) * Disable pessimistic object deoptimization for calls when the called function doesn't ref this Issue #3989 * Use a base class for special-purpose value objects To avoid duplicating all ExpressionEntity methods for every object. * Remove toString for values * Move function Node initialization to parseNode * Also handle arrow functions Co-authored-by: Lukas Taegert-Atkinson <lukas.taegert-atkinson@tngtech.com> Co-authored-by: Lukas Taegert-Atkinson <lukastaegert@users.noreply.github.com>
Adds a
referencesThis
flag toFunctionNode
and uses it to avoid the deoptimization around method calls, as discussed in #3989Instead of new tests, this reverts some of the test changes made by 3e0aa46.
Let me know if the
FunctionNode.createScope
kludge is within the limits of kludginess accepted in this project. We could also do a conditional initialization of the property ininitialize
, but that'll lead to different object shapes for no real good reason.This PR contains:
Are tests included?
Breaking Changes?
List any relevant issue numbers: #3989