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

Allow context type annotation on getters/setters #9641

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 12 additions & 2 deletions packages/babel-parser/src/parser/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -1552,15 +1552,25 @@ export default class ExpressionParser extends LValParser {
checkGetterSetterParams(method: N.ObjectMethod | N.ClassMethod): void {
const paramCount = method.kind === "get" ? 0 : 1;
const start = method.start;
if (method.params.length !== paramCount) {
// Allow `this` type annotation in TypeScript
if (
method.params.length === paramCount + 1 &&
method.params[0].type === "Identifier" &&
method.params[0].name === "this"
) {
this.expectPlugin("typescript");
Copy link
Member

Choose a reason for hiding this comment

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

When the first parameter is this the new implementation doesn't check the parameters count because the } else if (method.params.length !== paramCount) { branch is skipped: (EDIT: I was wrong)

//get prop(this: {}, foo, bar) {}

If we parsed this as a function parameter, then this plugin is already enabled (no need to assert). I would prefer to have as few as possible TypeScript-specific logic in the parser/* files. WDYT about extractions method.kind === "get" ? 0 : 1 to a new getAccessorsExpectedParamCount(method) function and overwrite it in the typescript plugin?

Copy link
Member

Choose a reason for hiding this comment

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

method.params.length === paramCount + 1 wouldn't be true in that case I guess?

Copy link
Member

Choose a reason for hiding this comment

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

Oh right 🤦‍♂️

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@nicolo-ribaudo I have pushed a change for getGetterSetterExpectedParamCount. Thanks for suggesting the separation. I hadn't noticed I had the first usage of this.expectPlugin("typescript").

At first, it felt a little odd that the error messages directly reference the required number of params despite that number being abstracted away. I considered extracting a checkGetterSetterExpectedParamCount method instead, but didn't find a good way to do so without duplicating logic in the TypeScript plugin. However, I found that there's less of a dissonance if I look at it as the error messages being based on target language and getGetterSetterExpectedParamCount being based on the source language, so I'm on board now 😄

} else if (method.params.length !== paramCount) {
if (method.kind === "get") {
this.raise(start, "getter must not have any formal parameters");
} else {
this.raise(start, "setter must have exactly one formal parameter");
}
}

if (method.kind === "set" && method.params[0].type === "RestElement") {
if (
method.kind === "set" &&
method.params[method.params.length - 1].type === "RestElement"
) {
this.raise(
start,
"setter function argument must not be a rest parameter",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const g = {
get m(this: {}) {}
};
const s = {
set m(this: {}, value) {}
};