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
fix(ts): allow trailing comma after rest parameter in TSDeclareFunction
#13101
Conversation
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/45030/ |
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 fd7dbcc:
|
checkCommaAfterRest(close) { | ||
if (this.match(tt.comma)) { | ||
if (this.lookaheadCharCode() === close) { | ||
if (!this.state.isDeclareContext) { |
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.
Is this.state.isDeclareContext
true in d.ts
files?
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 is true if there is the declare
keyword before the function declaration.
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.
In that case this PR doesn't fully fix #13100
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 don't have a separate parsing goal for .d.ts
files I think, since any code that is valid in .d.ts
files was valid in normal .ts
files (before we learned about 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.
(Q: Do you know if I can use the .d.ts
parse goal on the TS playground?)
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.
any code that is valid in .d.ts files was valid in normal .ts
class Foo {
foo(): any;
}
is invalid in .ts
unless it's nested in declare namespace
.
As for function foo(...args: any[], )
without the body, it can be used for two different things:
- for overloads
- for type-only declarations (inside
declare namespace
,declare global
,declare module "name" { ... }
, and probably something else)
In the first case, the rest parameter trailing comma isn't allowed. In the latter, it's allowed as it's an "ambient context".
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.
Do you know if I can use the .d.ts parse goal on the TS playground
I believe if you wrap you code e.g. in declare module 'foo' { ... }
, it'll be the same as if it were a d.ts file.
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 we can start by fixing the "easy" case (which is what this PR does), but we'll eventually need to add a { dts: boolean }
option to the typescript parser plugin.
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.
From Prettier's perspective, making the error recoverable would suffice.
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've created a new issue so we don't forget #13108
} | ||
this.eat(tt.comma); | ||
} else { | ||
this.raiseRestNotLast(this.state.start); |
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 is need to add tests to check raising this error.
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 method is inherited from here adding some adjustments:
babel/packages/babel-parser/src/parser/lval.js
Lines 526 to 535 in 7bc72bb
checkCommaAfterRest(close: $Values<typeof charCodes>): void { | |
if (this.match(tt.comma)) { | |
if (this.lookaheadCharCode() === close) { | |
this.raiseTrailingCommaAfterRest(this.state.start); | |
} else { | |
this.raiseRestNotLast(this.state.start); | |
} | |
} | |
} | |
That branch is already tested in "ES" parser, I don't know if it is necessary to repeat 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.
Then I'd prefer to do something like this rather than copy-pasting the code:
checkCommaAfterRest(close) {
if (
this.state.isDeclareContext &&
this.match(tt.comma) &&
this.lookaheadCharCode() === close
) {
this.next(); // tt.comma
} else {
super.checkCommaAfterRest(close);
}
}
by doing so, if we'll make any change to checkCommaAfterRest
we don't risk forgetting to also update this second implementation.
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.
Don't we risk to call twice lookaheadCharCode
by doing so?
edit: I confused it with lookahead()
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 thinking, maybe we can add some parser contributing.md section (or somewhere) mentioning that for plugins (TS/Flow) we would prefer overwritten methods to use super? Not sure if that's worth making a lint thing either though
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.
Not sure if that's worth making a lint thing either though
It's hard to do so, because we need to know which methods shadow methods on the superclass. Maybe it's doable with tslint, but not with eslint.
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 yeah I was thinking of a simple heuristic of methods that don't start with ts
since it seems we do that? Not a big deal
Co-Authored-By: Nicolò Ribaudo <7000710+nicolo-ribaudo@users.noreply.github.com>
* Build(deps): Bump @babel/parser from 7.13.13 to 7.13.15 Bumps [@babel/parser](https://github.com/babel/babel/tree/HEAD/packages/babel-parser) from 7.13.13 to 7.13.15. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.13.15/packages/babel-parser) Signed-off-by: dependabot[bot] <support@github.com> * Add test for babel/babel#13099 * Test babel/babel#13049 * Test babel/babel#13101 * Add long name test * Style * Print necessary parens in `{ a: (b as any) = 2000 }` Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: fisker Cheung <lionkay@gmail.com> Co-authored-by: Georgii Dolzhykov <thorn.mailbox@gmail.com>
If in declare context we can allow a comma after a function rest parameter.