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
Skip TSAsExpression when transforming spread in CallExpression #11404
Skip TSAsExpression when transforming spread in CallExpression #11404
Conversation
Not sure if there's a better solution here. It feels like the ideal would be passing the entire path to a "get me this without the TypeScript" function. |
Other tests: class A {
#x;
fn() {
(this.#x as any)();
}
} (a.b as any)?.() And also with Flow type casts ( Also, it would be nice to make it work when the
I agree! Missing the correct this with type casts is a common pitfall and a shared function would be useful. What about a new |
44027e1
to
e090927
Compare
Thanks for the feedback @nicolo-ribaudo! I've created the package, and added a bunch of extra tests - let me know what you think. I wasn't able to test I have two quick tweaks which I will make tomorrow morning:
|
Made changes as promised. |
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit e6c3a4c:
|
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/26343/ |
@oliverdunk The tests I proposed in #11404 (comment) where without spread 😛 The caller is also needed by the optional chaining plugin. |
} | ||
|
||
fn() { | ||
_classPrivateFieldGet(this, _x)(); |
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.
This still call still doesn't have the correct this
!
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.
Thanks, admittedly I didn't look close enough and thought it was right! That's a tough one, because we're going in the opposite direction. The transformation is done by babel-helper-member-expressions-to-functions
, which takes a member, and then checks to see if its parent is a call expression.
I was able to fix it with the following diff: https://hastebin.com/onotaqusiw.diff
It seems like this would be an issue for the entire helper. Maybe the helper should be a type stripper, instead of just something for calls? It would export a function for each direction.
The final tricky bit would be things like this:
if (parentPath.isAssignmentExpression({ left: node })) {
We could probably change that to this?
if (parentPath.isAssignmentExpression({ left: previousParent })) {
With previousParent set to node initially, and then the last parent each time we go a level up?
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.
It crossed my mind that if we move the logic to a plugin, we can't keep track of the previous parent. Maybe this logic has to be duplicated in this case.
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.
Maybe we could keep this for a follow-up PR then
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.
Sounds good. I have a first draft, so I'll open a WIP MR with that once this is merged.
I'm not sure if I missed something when adding my new package as a dependency. I thought Lerna would find it, but the tests are failing and |
We should probably strip types from optional member expressions, too! 😅 Does replacing |
What do you mean? Btw, for some other PRs (e.g. #11552) it might be useful to add a function to this package that, give the callee, returns the call (the opposite of the one introduced by this PR). |
I'm thinking of this case: |
Thanks for the feedback! Found some time to take a look at it. @nicolo-ribaudo, I've hopefully addressed all of your comments. Would love for you to take another look. @JLHwung, I need to fix the helper call where I wrongly pass an ASTNode. I'll ping you when that's done. In the meantime, I did leave a response to another bit of feedback you left. Also changed the base branch to |
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.
Just a small nit, but otherwise LGTM, nice work @oliverdunk!
Thanks for the reviews @existentialism and @kaicataldo! I went ahead and pushed the rename. |
The changelog comes from the PR title, right? If so, we might want something broader:
|
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.
LGTM with some comments.
packages/babel-helper-skip-transparent-expression-wrappers/package.json
Outdated
Show resolved
Hide resolved
packages/babel-helper-skip-transparent-expression-wrappers/package.json
Outdated
Show resolved
Hide resolved
import * as t from "@babel/types"; | ||
import type { NodePath } from "@babel/traverse"; | ||
|
||
export function getCallContext(callPath: NodePath): NodePath { |
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.
I think getCallContext
is a consumer of helper-skip-transparent-expression-wrappers
and it should not be in this package.
Do we have a test case on Expected type "CallExpression" or "OptionalCallExpression"
? I think we can go with skipTransparentExprWrappers(path.get("callee"))
and not worry about path.type
, they should be validated by transformers or implied by how the path
is filtered. i.e. "CallExpression|OptionalCallExpression"(path)
.
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.
I'm alright with that. I think it made more sense when the scope of the package was smaller.
@JLHwung All sorted 😄 |
packages/babel-plugin-transform-spread/test/fixtures/call-context/flow-type-cast/options.json
Outdated
Show resolved
Hide resolved
packages/babel-plugin-transform-spread/test/fixtures/call-context/flow-type-cast/options.json
Outdated
Show resolved
Hide resolved
@JLHwung Removed the inline helper functions! This should be good for another look. I'm happy to keep tweaking this, but at the same time, I won't be offended if you want to jump in with a few commits. If you still have some tidy up in mind it might be quicker :) |
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.
Awesome!
@JLHwung Thanks for the merge! |
@oliverdunk Thank you for all the efforts! |
In babel-plugin-transform-spread, when transforming spreaded arguments in a CallExpression, we weren't handling the case where the callee was a TSAsExpression. This meant we incorrectly determined the this of our apply call, transforming:
(dog.bark as any)(...args)
... into ...
dog.bark.apply(void 0, args)
I've fixed that by exploring deeper, into the expression of the TSAsExpression.