-
-
Notifications
You must be signed in to change notification settings - Fork 514
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
feat(lint): implement noFloatingPromises
rule for reguler async
function
#4911
Conversation
CodSpeed Performance ReportMerging #4911 will not alter performanceComparing Summary
|
return false; | ||
}; | ||
|
||
let AnyJsBindingDeclaration::JsFunctionDeclaration(func_decl) = any_js_binding_decl |
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.
- For now, only checking a function declaration
- Not considering reassigned variables like this
async function returnsPromise(): Promise<string> {
return 'value';
}
let reassigned = returnsPromise;
reassigned();
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 have AnyFunctionLike
that you can use for detecting other kinds of function/method declarations. I understand without further type-level inference there will be few situations where you can use this for now, so feel free to leave methods for a future improvement, although I think at least all the AnyJsFunction
cases can be handled already.
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.
Thank you for letting me know!
I’ll revisit this when I work on implementing support for other functions or methods
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 work! Just left a few comments.
crates/biome_js_analyze/src/lint/nursery/no_floating_promises.rs
Outdated
Show resolved
Hide resolved
crates/biome_js_analyze/src/lint/nursery/no_floating_promises.rs
Outdated
Show resolved
Hide resolved
crates/biome_js_analyze/src/lint/nursery/no_floating_promises.rs
Outdated
Show resolved
Hide resolved
crates/biome_js_analyze/src/lint/nursery/no_floating_promises.rs
Outdated
Show resolved
Hide resolved
ctx.metadata().applicability(), | ||
markup! { "Add await operator." }.to_owned(), | ||
mutation, | ||
)) |
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 this may potentially create invalid syntax if it's done inside a non-async
function. Can we check for that?
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.
@arendjr thank you for the review!
That's a valid point. Applying the change inside a non-async function could indeed lead to invalid syntax.
Is there an easy way to handle this in Biome?
For typeScript-eslint
, it offers 2 fixes:
- Add a void operator to safely ignore the result.
- Add an await operator to make it asynchronous.
see: playground example
Providing two fixes seems like a reasonable and user-friendly approach.
Is it possible to provide multiple fixes using the action() function in Biome?
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 lint rules can only offer a single fix mechanism, but we have assists which might be better to what you're trying to do. What do you think is better here, @ematipico ?
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.
When you say 'assists,' do you mean they are another kind of note or suggestion that the diagnostic function can generate? Or is there a separate mechanism for assists altogether?
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.
At the moment our infrastructure doesn't offer multiple fixes from a single rule, that's valid for the whole analyzer infrastructure (linter and assist).
Some rules change their fix based on a situational need, maybe it's something we could evaluate.
I believe this is the first time we are in need of such a case. We could definitely evaluate adding such a feature, but not in this PR, as it requires some thoughts about how they should behave.
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 see, so you’d like me to traverse up the tree from the expression node to find the nearest function and check if it is async, correct?
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.
Yeah, that’s probably the easiest solution.
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.
For
typeScript-eslint
, it offers 2 fixes: ... see: playground example
Sorry if I'm butting in annoyingly, but just to answer about what ESLint / typescript-eslint is doing:
- We intentionally don't have adding
await
as a fix, because that's not a safe fix to apply in code - even if it would be syntactically valid- Example: the code might have been relying on Promise to float, like in a fire-and-forget pattern
- ESLint / typescript-eslint doesn't have the ability to provide multiple fixes. Those two "fix" buttons are to apply suggestions, which are not surfaced in the CLI - only in integrations such as editors.
I do think it's kind of confusing that the typescript-eslint playground phrases a suggestion as "fix". Filed typescript-eslint/typescript-eslint#10700. Thanks! 💙
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 for the great advice! I think the suggestions you speak of indeed map best to Biome’s assists, although we support unsafe fixes too, so I wouldn’t mind if the rule offered the await
fix as an unsafe one.
If it gets too hairy, I also don’t mind merging this PR without any fixes/assists, so we can focus on improving the analysis part first.
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.
@arendjr
I have added a check to determine whether an expression is in an async function before suggesting an unsafe fix
return false; | ||
}; | ||
|
||
let AnyJsBindingDeclaration::JsFunctionDeclaration(func_decl) = any_js_binding_decl |
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 have AnyFunctionLike
that you can use for detecting other kinds of function/method declarations. I understand without further type-level inference there will be few situations where you can use this for now, so feel free to leave methods for a future improvement, although I think at least all the AnyJsFunction
cases can be handled already.
This PR should go against the Also, the instructions for providing a changelog are different there, can you please follow them? |
93549da
to
a56a19d
Compare
noFloatingPromises
rule for reguler async
function
3c411a0
to
c9ca841
Compare
Thank you! |
@arendjr |
@kaykdm can you create an issue task to keep track of these works? |
Summary
related: #3187 and #4956
This pull request introduces the initial implementation of the no-floating-promises rule.
The rule reports Promise-valued statements that are not treated in one of the following ways:
Note
Current Scope:
Example of invalid code:
Example of valid code:
Remaining TODOs for Future PRs