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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -2779,6 +2779,20 @@ export default (superClass: Class<Parser>): Class<Parser> => | |||||||||||||||||||||
return super.parseMaybeDecoratorArguments(expr); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
checkCommaAfterRest(close) { | ||||||||||||||||||||||
if (this.match(tt.comma)) { | ||||||||||||||||||||||
if (this.lookaheadCharCode() === close) { | ||||||||||||||||||||||
if (!this.state.isDeclareContext) { | ||||||||||||||||||||||
this.raiseTrailingCommaAfterRest(this.state.start); | ||||||||||||||||||||||
return; | ||||||||||||||||||||||
fedeci marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
} | ||||||||||||||||||||||
this.eat(tt.comma); | ||||||||||||||||||||||
} else { | ||||||||||||||||||||||
this.raiseRestNotLast(this.state.start); | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe 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
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 commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more.
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 commentThe 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 |
||||||||||||||||||||||
} | ||||||||||||||||||||||
} | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
// === === === === === === === === === === === === === === === === | ||||||||||||||||||||||
// Note: All below methods are duplicates of something in flow.js. | ||||||||||||||||||||||
// Not sure what the best way to combine these is. | ||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
declare function foo(...args: any[], ) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
{ | ||
"type": "File", | ||
"start":0,"end":38,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":38}}, | ||
"program": { | ||
"type": "Program", | ||
"start":0,"end":38,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":38}}, | ||
"sourceType": "module", | ||
"interpreter": null, | ||
"body": [ | ||
{ | ||
"type": "TSDeclareFunction", | ||
"start":0,"end":38,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":38}}, | ||
"declare": true, | ||
"id": { | ||
"type": "Identifier", | ||
"start":17,"end":20,"loc":{"start":{"line":1,"column":17},"end":{"line":1,"column":20},"identifierName":"foo"}, | ||
"name": "foo" | ||
}, | ||
"generator": false, | ||
"async": false, | ||
"params": [ | ||
{ | ||
"type": "RestElement", | ||
"start":21,"end":35,"loc":{"start":{"line":1,"column":21},"end":{"line":1,"column":35}}, | ||
"argument": { | ||
"type": "Identifier", | ||
"start":24,"end":28,"loc":{"start":{"line":1,"column":24},"end":{"line":1,"column":28},"identifierName":"args"}, | ||
"name": "args" | ||
}, | ||
"typeAnnotation": { | ||
"type": "TSTypeAnnotation", | ||
"start":28,"end":35,"loc":{"start":{"line":1,"column":28},"end":{"line":1,"column":35}}, | ||
"typeAnnotation": { | ||
"type": "TSArrayType", | ||
"start":30,"end":35,"loc":{"start":{"line":1,"column":30},"end":{"line":1,"column":35}}, | ||
"elementType": { | ||
"type": "TSAnyKeyword", | ||
"start":30,"end":33,"loc":{"start":{"line":1,"column":30},"end":{"line":1,"column":33}} | ||
} | ||
} | ||
} | ||
} | ||
] | ||
} | ||
], | ||
"directives": [] | ||
} | ||
} |
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 ind.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.
is invalid in
.ts
unless it's nested indeclare namespace
.As for
function foo(...args: any[], )
without the body, it can be used for two different things: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.
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