Skip to content

Commit

Permalink
feat: add no-await-in-sync-fn rule
Browse files Browse the repository at this point in the history
  • Loading branch information
marvinhagemeister committed Jul 12, 2023
1 parent 23f15ca commit 5f240b7
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 0 deletions.
35 changes: 35 additions & 0 deletions docs/rules/no_await_in_sync_fn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
Disallow `await` keyword inside a non-async function

Using the `await` keyword inside a non-async function is a syntax error. To be able to use `await` inside a function, the function needs to be marked as async via the `async` keyword

### Invalid:

```javascript
function foo() {
await bar();
}

const fooFn = function foo() {
await bar();
};

const fooFn = () => {
await bar();
};
```

### Valid:

```javascript
async function foo() {
await bar();
}

const fooFn = async function foo() {
await bar();
};

const fooFn = async () => {
await bar();
};
```
2 changes: 2 additions & 0 deletions src/rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub mod guard_for_in;
pub mod no_array_constructor;
pub mod no_async_promise_executor;
pub mod no_await_in_loop;
pub mod no_await_in_sync_fn;
pub mod no_case_declarations;
pub mod no_class_assign;
pub mod no_compare_neg_zero;
Expand Down Expand Up @@ -244,6 +245,7 @@ fn get_all_rules_raw() -> Vec<&'static dyn LintRule> {
&no_array_constructor::NoArrayConstructor,
&no_async_promise_executor::NoAsyncPromiseExecutor,
&no_await_in_loop::NoAwaitInLoop,
&no_await_in_sync_fn::NoAwaitInSyncFn,
&no_case_declarations::NoCaseDeclarations,
&no_class_assign::NoClassAssign,
&no_compare_neg_zero::NoCompareNegZero,
Expand Down
123 changes: 123 additions & 0 deletions src/rules/no_await_in_sync_fn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright 2020-2021 the Deno authors. All rights reserved. MIT license.
use super::{Context, LintRule};
use crate::handler::{Handler, Traverse};
use crate::Program;
use deno_ast::view::NodeTrait;
use deno_ast::{view as ast_view, SourceRanged};

#[derive(Debug)]
pub struct NoAwaitInSyncFn;

const CODE: &str = "no-await-in-sync-fn";
const MESSAGE: &str = "Unexpected `await` inside a non-async function.";
const HINT: &str = "Remove `await` in the function body or change the function to an async function.";

impl LintRule for NoAwaitInSyncFn {
fn code(&self) -> &'static str {
CODE
}

fn lint_program_with_ast_view(
&self,
context: &mut Context,
program: Program<'_>,
) {
NoAwaitInSyncFnHandler.traverse(program, context);
}

#[cfg(feature = "docs")]
fn docs(&self) -> &'static str {
include_str!("../../docs/rules/no_await_in_sync_fn.md")
}
}

struct NoAwaitInSyncFnHandler;

impl Handler for NoAwaitInSyncFnHandler {
fn await_expr(
&mut self,
await_expr: &ast_view::AwaitExpr,
ctx: &mut Context,
) {
fn inside_sync_fn(
await_expr: &ast_view::AwaitExpr,
node: ast_view::Node,
) -> bool {
use deno_ast::view::Node::*;
match node {
FnDecl(decl) => return !decl.function.is_async(),
FnExpr(decl) => return !decl.function.is_async(),
ArrowExpr(decl) => return !decl.is_async(),
_ => {
let parent = match node.parent() {
Some(p) => p,
None => return false,
};
inside_sync_fn(await_expr, parent)
}
}
}

if inside_sync_fn(await_expr, await_expr.as_node()) {
ctx.add_diagnostic_with_hint(await_expr.range(), CODE, MESSAGE, HINT);
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn no_await_in_sync_fn_valid() {
assert_lint_ok! {
NoAwaitInSyncFn,
r#"
async function foo(things) {
await bar();
}
"#,
r#"
const foo = async (things) => {
await bar();
}
"#,
r#"
const foo = async function(things) {
await bar();
}
"#,
r#"
class Foo {
async foo(things) {
await bar();
}
}
"#,
}
}

#[test]
fn no_await_in_sync_fn_invalid() {
assert_lint_err! {
NoAwaitInSyncFn,
MESSAGE,
HINT,
r#"
function foo(things) {
await bar();
}
"#: [{ line: 3, col: 8 }],
r#"
const foo = things => {
await bar();
}
"#: [{ line: 3, col: 8 }],
r#"
const foo = function (things) {
await bar();
}
"#: [{ line: 3, col: 8 }],
}
}
}

0 comments on commit 5f240b7

Please sign in to comment.