feat(linter): check await in class static block

This commit is contained in:
Boshen 2023-03-14 07:46:11 +08:00
parent 78bd76e8d0
commit 7add71c9dd
No known key found for this signature in database
GPG key ID: 6AC90C77AAAA6ABC
5 changed files with 108 additions and 5 deletions

View file

@ -48,6 +48,8 @@ bitflags! {
/// Decorator context does not parse computed member expressions, e.g.
/// `class C { @dec() ["method"]() {} }`
const Decorator = 1 << 6;
const ClassStaticBlock = 1 << 7;
}
}
@ -100,6 +102,12 @@ impl Context {
self.contains(Self::Decorator)
}
#[must_use]
#[inline]
pub fn has_class_static_block(self) -> bool {
self.contains(Self::ClassStaticBlock)
}
#[must_use]
#[inline]
pub fn union_await_if(self, include: bool) -> Self {
@ -160,6 +168,12 @@ impl Context {
self.and(Self::Decorator, include)
}
#[must_use]
#[inline]
pub fn and_class_static_block(self, include: bool) -> Self {
self.and(Self::ClassStaticBlock, include)
}
#[must_use]
#[inline]
fn and(self, flag: Self, set: bool) -> Self {

View file

@ -458,9 +458,19 @@ impl<'a> Parser<'a> {
let has_await = self.ctx.has_await();
let has_yield = self.ctx.has_yield();
let has_return = self.ctx.has_return();
self.ctx = self.ctx.and_await(true).and_yield(false).and_return(false);
self.ctx = self
.ctx
.and_await(true)
.and_yield(false)
.and_return(false)
.and_class_static_block(true);
let block = self.parse_block()?;
self.ctx = self.ctx.and_await(has_await).and_yield(has_yield).and_return(has_return);
self.ctx = self
.ctx
.and_await(has_await)
.and_yield(has_yield)
.and_return(has_return)
.and_class_static_block(false);
Ok(self.ast.static_block(self.end_span(span), block.unbox().body))
}

View file

@ -999,7 +999,7 @@ impl<'a> Parser<'a> {
let span = self.start_span();
self.bump_any();
let has_await = self.ctx.has_await();
if !has_await {
if !has_await || self.ctx.has_class_static_block() {
self.error(diagnostics::AwaitExpression(Span::new(span.start, span.start + 5)));
}
self.ctx = self.ctx.and_await(true);

View file

@ -1,7 +1,7 @@
Test262 Summary:
AST Parsed : 44015/44034 (99.96%)
Positive Passed: 44015/44034 (99.96%)
Negative Passed: 3903/3917 (99.64%)
Negative Passed: 3904/3917 (99.67%)
Expect Syntax Error: "language/global-code/export.js"
Expect Syntax Error: "language/global-code/import.js"
Expect Syntax Error: "language/import/dup-bound-names.js"
@ -14,7 +14,6 @@ Expect Syntax Error: "language/module-code/early-dup-export-id.js"
Expect Syntax Error: "language/module-code/early-dup-export-star-as-dflt.js"
Expect Syntax Error: "language/module-code/early-export-global.js"
Expect Syntax Error: "language/module-code/early-export-unresolvable.js"
Expect Syntax Error: "language/statements/class/static-init-invalid-await.js"
Expect Syntax Error: "language/statements/variable/dstr/obj-ptrn-elem-id-static-init-await-invalid.js"
Expect to Parse: "language/block-scope/syntax/redeclaration-global/allowed-to-redeclare-function-declaration-with-var.js"
@ -2414,6 +2413,14 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js"
17 │ }
╰────
× `await` is only allowed within async functions and at the top levels of modules
╭─[language/expressions/arrow-function/static-init-await-reference.js:15:1]
15 │ static {
16 │ ((x = await) => 0);
· ─────
17 │ }
╰────
× Unexpected token
╭─[language/expressions/arrow-function/static-init-await-reference.js:15:1]
15 │ static {
@ -18080,6 +18087,14 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js"
· ─────
╰────
× `await` is only allowed within async functions and at the top levels of modules
╭─[language/identifier-resolution/static-init-invalid-await.js:22:1]
22 │ static {
23 │ await;
· ─────
24 │ }
╰────
× Unexpected token
╭─[language/identifier-resolution/static-init-invalid-await.js:22:1]
22 │ static {
@ -29429,6 +29444,14 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js"
22 │ }
╰────
× `await` is only allowed within async functions and at the top levels of modules
╭─[language/statements/class/static-init-invalid-await.js:29:1]
29 │ static {
30 │ await 0;
· ─────
31 │ }
╰────
× Identifier `x` has already been declared
╭─[language/statements/class/static-init-invalid-label-dup.js:20:1]
20 │ static {
@ -34026,6 +34049,14 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js"
╰────
help: Wrap this declaration in a block statement
× `await` is only allowed within async functions and at the top levels of modules
╭─[language/statements/labeled/static-init-invalid-await.js:22:1]
22 │ static {
23 │ await: 0;
· ─────
24 │ }
╰────
× Unexpected token
╭─[language/statements/labeled/static-init-invalid-await.js:22:1]
22 │ static {

View file

@ -2777,6 +2777,14 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts"
22 │ }
╰────
× `await` is only allowed within async functions and at the top levels of modules
╭─[classes/classStaticBlock/classStaticBlock22.ts:26:1]
26 │ await = 1; // legal
27 │ x = await; // legal (initializers have an implicit function boundary)
· ─────
28 │ };
╰────
× Unexpected token
╭─[classes/classStaticBlock/classStaticBlock22.ts:26:1]
26 │ await = 1; // legal
@ -2785,6 +2793,14 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts"
28 │ };
╰────
× `await` is only allowed within async functions and at the top levels of modules
╭─[classes/classStaticBlock/classStaticBlock26.ts:4:1]
4 │ static {
5 │ await; // illegal
· ─────
6 │ }
╰────
× Unexpected token
╭─[classes/classStaticBlock/classStaticBlock26.ts:4:1]
4 │ static {
@ -2801,6 +2817,14 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts"
8 │ let arguments = 1;
╰────
× `await` is only allowed within async functions and at the top levels of modules
╭─[classes/classStaticBlock/classStaticBlock6.ts:12:1]
12 │ static {
13 │ await: if (true) {
· ─────
14 │
╰────
× Unexpected token
╭─[classes/classStaticBlock/classStaticBlock6.ts:12:1]
12 │ static {
@ -2809,6 +2833,14 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts"
14 │
╰────
× `await` is only allowed within async functions and at the top levels of modules
╭─[classes/classStaticBlock/classStaticBlock7.ts:2:1]
2 │ static {
3 │ await 1;
· ─────
4 │ yield 1;
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[classes/classStaticBlock/classStaticBlock7.ts:3:1]
3 │ await 1;
@ -2826,6 +2858,22 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts"
6 │ }
╰────
× `await` is only allowed within async functions and at the top levels of modules
╭─[classes/classStaticBlock/classStaticBlock7.ts:11:1]
11 │ static {
12 │ await 1;
· ─────
13 │
╰────
× `await` is only allowed within async functions and at the top levels of modules
╭─[classes/classStaticBlock/classStaticBlock7.ts:14:1]
14 │ async function ff () {
15 │ await 1;
· ─────
16 │ }
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[classes/classStaticBlock/classStaticBlock7.ts:23:1]
23 │ static {