feat(parser): check YieldExpression

This commit is contained in:
Boshen 2023-03-12 23:41:27 +08:00
parent 88fd0a05ec
commit fce6e1ec73
No known key found for this signature in database
GPG key ID: 6AC90C77AAAA6ABC
5 changed files with 152 additions and 24 deletions

View file

@ -282,9 +282,7 @@ pub struct AwaitExpression(#[label] pub Span);
#[derive(Debug, Error, Diagnostic)]
#[error("A 'yield' expression is only allowed in a generator body.")]
#[diagnostic()]
pub struct YieldExpression(
#[label("A 'yield' expression is only allowed in a generator body.")] pub Span,
);
pub struct YieldExpression(#[label] pub Span);
#[derive(Debug, Error, Diagnostic)]
#[error("Invalid class declaration")]

View file

@ -306,6 +306,11 @@ impl<'a> Parser<'a> {
let span = self.start_span();
self.bump_any(); // advance `yield`
let has_yield = self.ctx.has_yield();
if !has_yield {
self.error(diagnostics::YieldExpression(Span::new(span.start, span.start + 5)));
}
let mut delegate = false;
let mut argument = None;
@ -322,7 +327,6 @@ impl<'a> Parser<'a> {
| Kind::Comma
);
if !not_assignment_expr || delegate {
let has_yield = self.ctx.has_yield();
self.ctx = self.ctx.union_yield_if(true);
argument = Some(self.parse_assignment_expression_base()?);
self.ctx = self.ctx.and_yield(has_yield);

View file

@ -1,7 +1,7 @@
Babel Summary:
AST Parsed : 2051/2069 (99.13%)
Positive Passed: 2051/2069 (99.13%)
Negative Passed: 1068/1502 (71.11%)
Negative Passed: 1077/1502 (71.70%)
Expect Syntax Error: "annex-b/disabled/1.1-html-comments-close/input.js"
Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions-if-body/input.js"
Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions-multiple-labels/input.js"
@ -110,7 +110,6 @@ Expect Syntax Error: "es2015/object/disallow-duplicate-method-params/input.js"
Expect Syntax Error: "es2015/shorthand/reserved-word-strict/input.js"
Expect Syntax Error: "es2015/statements/label-invalid-func-strict/input.js"
Expect Syntax Error: "es2015/uncategorised/.191/input.js"
Expect Syntax Error: "es2015/uncategorised/.260/input.js"
Expect Syntax Error: "es2015/uncategorised/.335/input.js"
Expect Syntax Error: "es2015/uncategorised/.343/input.js"
Expect Syntax Error: "es2015/uncategorised/166/input.js"
@ -137,8 +136,6 @@ Expect Syntax Error: "es2015/yield/function-name-function-declaration-inside-gen
Expect Syntax Error: "es2015/yield/function-name-generator-expression/input.js"
Expect Syntax Error: "es2015/yield/function-name-strict-body/input.js"
Expect Syntax Error: "es2015/yield/function-name-strict/input.js"
Expect Syntax Error: "es2015/yield/in-global-scope/input.js"
Expect Syntax Error: "es2015/yield/in-plain-function/input.js"
Expect Syntax Error: "es2015/yield/parameter-default-inside-arrow-inside-generator-1/input.js"
Expect Syntax Error: "es2015/yield/parameter-default-inside-arrow-inside-generator-2/input.js"
Expect Syntax Error: "es2015/yield/parameter-default-inside-arrow-inside-generator-3/input.js"
@ -191,10 +188,6 @@ Expect Syntax Error: "esprima/es2015-arrow-function/invalid-duplicated-params/in
Expect Syntax Error: "esprima/es2015-arrow-function/invalid-param-strict-mode/input.js"
Expect Syntax Error: "esprima/es2015-export-declaration/invalid-export-named-default/input.js"
Expect Syntax Error: "esprima/es2015-generator/.generator-parameter-binding-property-reserved/input.js"
Expect Syntax Error: "esprima/es2015-generator/generator-method-with-invalid-computed-name/input.js"
Expect Syntax Error: "esprima/es2015-generator/generator-parameter-binding-element/input.js"
Expect Syntax Error: "esprima/es2015-generator/generator-parameter-binding-property/input.js"
Expect Syntax Error: "esprima/es2015-generator/generator-parameter-computed-property-name/input.js"
Expect Syntax Error: "esprima/es2015-generator/generator-parameter-invalid-binding-element/input.js"
Expect Syntax Error: "esprima/es2015-generator/generator-parameter-invalid-binding-property/input.js"
Expect Syntax Error: "esprima/es2015-generator/generator-parameter-invalid-computed-property-name/input.js"
@ -203,8 +196,6 @@ Expect Syntax Error: "esprima/es2015-identifier/invalid_expression_await/input.j
Expect Syntax Error: "esprima/es2015-identifier/invalid_var_await/input.js"
Expect Syntax Error: "esprima/es2015-meta-property/invalid-new-target/input.js"
Expect Syntax Error: "esprima/es2015-meta-property/unknown-property/input.js"
Expect Syntax Error: "esprima/es2015-yield/invalid-yield-binding-property/input.js"
Expect Syntax Error: "esprima/es2015-yield/invalid-yield-expression/input.js"
Expect Syntax Error: "esprima/es2015-yield/invalid-yield-generator-arrow-default/input.js"
Expect Syntax Error: "esprima/es2015-yield/invalid-yield-generator-declaration/input.js"
Expect Syntax Error: "esprima/es2015-yield/invalid-yield-generator-expression-name/input.js"
@ -2919,6 +2910,12 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
3 │ `;
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[es2015/uncategorised/.260/input.js:1:1]
1 │ (function() { "use strict"; f(yield v) })
· ─────
╰────
× A 'get' accessor must not have any formal parameters.
╭─[es2015/uncategorised/.345/input.js:1:1]
1 │ class A { get prop(x) {} }
@ -3736,6 +3733,12 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── Expect `{` here, but found `Identifier`
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[es2015/yield/in-global-scope/input.js:1:1]
1 │ yield 10
· ─────
╰────
× Unexpected token
╭─[es2015/yield/in-iterator-stmt/input.js:1:1]
1 │ function* g() {
@ -3744,6 +3747,12 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
3 │ }
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[es2015/yield/in-plain-function/input.js:1:1]
1 │ (function () { yield 10 })
· ─────
╰────
× Cannot use `yield` as an identifier in a generator context
╭─[es2015/yield/parameter-default-inside-arrow-inside-generator-5/input.js:1:1]
1 │ function* fn() {
@ -6285,6 +6294,36 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── Expect `;` here, but found `decimal`
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[esprima/es2015-generator/generator-method-with-invalid-computed-name/input.js:1:1]
1 │ ({ *[yield iter]() {} })
· ─────
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[esprima/es2015-generator/generator-parameter-binding-element/input.js:1:1]
1 │ (function*() {
2 │ function(x = yield 3) {}
· ─────
3 │ })
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[esprima/es2015-generator/generator-parameter-binding-property/input.js:1:1]
1 │ (function*() {
2 │ function({x: y = yield 3}) {}
· ─────
3 │ })
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[esprima/es2015-generator/generator-parameter-computed-property-name/input.js:1:1]
1 │ (function*() {
2 │ function({[yield 3]: y}) {}
· ─────
3 │ })
╰────
× Unexpected token
╭─[esprima/es2015-generator/incomplete-yield-delegate/input.js:1:1]
1 │ (function*() { yield* })
@ -6622,6 +6661,18 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── Unterminated string
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[esprima/es2015-yield/invalid-yield-binding-property/input.js:1:1]
1 │ var {x: y = yield 3} = z;
· ─────
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[esprima/es2015-yield/invalid-yield-expression/input.js:1:1]
1 │ (function() { yield 3; })
· ─────
╰────
× Cannot use `yield` as an identifier in a generator context
╭─[esprima/es2015-yield/invalid-yield-generator-arrow-parameter/input.js:1:1]
1 │ function *g(){ (yield) => 42 }

View file

@ -1,7 +1,7 @@
Test262 Summary:
AST Parsed : 44015/44034 (99.96%)
Positive Passed: 44015/44034 (99.96%)
Negative Passed: 3319/3917 (84.73%)
Negative Passed: 3320/3917 (84.76%)
Expect Syntax Error: "language/block-scope/syntax/function-declarations/in-statement-position-do-statement-while-expression.js"
Expect Syntax Error: "language/block-scope/syntax/function-declarations/in-statement-position-for-statement.js"
Expect Syntax Error: "language/block-scope/syntax/function-declarations/in-statement-position-if-expression-statement-else-statement.js"
@ -43,7 +43,6 @@ Expect Syntax Error: "language/expressions/arrow-function/syntax/early-errors/ar
Expect Syntax Error: "language/expressions/arrow-function/syntax/early-errors/arrowparameters-cover-no-duplicates-rest.js"
Expect Syntax Error: "language/expressions/arrow-function/syntax/early-errors/arrowparameters-cover-no-duplicates.js"
Expect Syntax Error: "language/expressions/arrow-function/syntax/early-errors/use-strict-with-non-simple-param.js"
Expect Syntax Error: "language/expressions/assignmenttargettype/direct-yieldexpression-0.js"
Expect Syntax Error: "language/expressions/async-arrow-function/array-destructuring-param-strict-body.js"
Expect Syntax Error: "language/expressions/async-arrow-function/await-as-param-nested-arrow-body-position.js"
Expect Syntax Error: "language/expressions/async-arrow-function/dflt-params-duplicates.js"
@ -4723,6 +4722,13 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js"
· ╰── Cannot assign to this expression
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[language/expressions/assignmenttargettype/direct-yieldexpression-0.js:19:1]
19 │
20 │ yield x = 1;
· ─────
╰────
× Invalid assignment
╭─[language/expressions/assignmenttargettype/direct-yieldexpression-1.js:19:1]
19 │
@ -5928,6 +5934,13 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js"
· ╰── Cannot assign to this expression
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[language/expressions/assignmenttargettype/parenthesized-yieldexpression-0.js:22:1]
22 │
23 │ (yield x) = 1;
· ─────
╰────
× Invalid assignment
╭─[language/expressions/assignmenttargettype/parenthesized-yieldexpression-0.js:22:1]
22 │

View file

@ -1,7 +1,7 @@
TypeScript Summary:
AST Parsed : 2305/2338 (98.59%)
Positive Passed: 2305/2338 (98.59%)
Negative Passed: 645/2532 (25.47%)
Negative Passed: 652/2532 (25.75%)
Expect Syntax Error: "Symbols/ES5SymbolProperty2.ts"
Expect Syntax Error: "Symbols/ES5SymbolProperty6.ts"
Expect Syntax Error: "additionalChecks/noPropertyAccessFromIndexSignature1.ts"
@ -614,14 +614,8 @@ Expect Syntax Error: "es6/templates/templateStringsWithTypeErrorInFunctionExpres
Expect Syntax Error: "es6/templates/templateStringsWithTypeErrorInFunctionExpressionsInSubstitutionExpressionES6.ts"
Expect Syntax Error: "es6/yieldExpressions/YieldExpression10_es6.ts"
Expect Syntax Error: "es6/yieldExpressions/YieldExpression11_es6.ts"
Expect Syntax Error: "es6/yieldExpressions/YieldExpression12_es6.ts"
Expect Syntax Error: "es6/yieldExpressions/YieldExpression14_es6.ts"
Expect Syntax Error: "es6/yieldExpressions/YieldExpression15_es6.ts"
Expect Syntax Error: "es6/yieldExpressions/YieldExpression16_es6.ts"
Expect Syntax Error: "es6/yieldExpressions/YieldExpression17_es6.ts"
Expect Syntax Error: "es6/yieldExpressions/YieldExpression18_es6.ts"
Expect Syntax Error: "es6/yieldExpressions/YieldExpression1_es6.ts"
Expect Syntax Error: "es6/yieldExpressions/YieldExpression2_es6.ts"
Expect Syntax Error: "es6/yieldExpressions/YieldExpression6_es6.ts"
Expect Syntax Error: "es6/yieldExpressions/YieldExpression8_es6.ts"
Expect Syntax Error: "es6/yieldExpressions/YieldExpression9_es6.ts"
@ -638,7 +632,6 @@ Expect Syntax Error: "es6/yieldExpressions/generatorTypeCheck20.ts"
Expect Syntax Error: "es6/yieldExpressions/generatorTypeCheck21.ts"
Expect Syntax Error: "es6/yieldExpressions/generatorTypeCheck25.ts"
Expect Syntax Error: "es6/yieldExpressions/generatorTypeCheck31.ts"
Expect Syntax Error: "es6/yieldExpressions/generatorTypeCheck32.ts"
Expect Syntax Error: "es6/yieldExpressions/generatorTypeCheck39.ts"
Expect Syntax Error: "es6/yieldExpressions/generatorTypeCheck48.ts"
Expect Syntax Error: "es6/yieldExpressions/generatorTypeCheck50.ts"
@ -2821,6 +2814,14 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts"
14 │
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[classes/classStaticBlock/classStaticBlock7.ts:3:1]
3 │ await 1;
4 │ yield 1;
· ─────
5 │ return 1;
╰────
× TS1108: A 'return' statement can only be used within a function body
╭─[classes/classStaticBlock/classStaticBlock7.ts:4:1]
4 │ yield 1;
@ -2830,6 +2831,14 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts"
6 │ }
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[classes/classStaticBlock/classStaticBlock7.ts:23:1]
23 │ static {
24 │ yield 1;
· ─────
25 │
╰────
× TS1108: A 'return' statement can only be used within a function body
╭─[classes/classStaticBlock/classStaticBlock7.ts:35:1]
35 │ static {
@ -5760,6 +5769,52 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts"
· ─
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[es6/yieldExpressions/YieldExpression12_es6.ts:3:1]
3 │ constructor() {
4 │ yield foo
· ─────
5 │ }
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[es6/yieldExpressions/YieldExpression14_es6.ts:3:1]
3 │ foo() {
4 │ yield foo
· ─────
5 │ }
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[es6/yieldExpressions/YieldExpression15_es6.ts:2:1]
2 │ var v = () => {
3 │ yield foo
· ─────
4 │ }
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[es6/yieldExpressions/YieldExpression16_es6.ts:3:1]
3 │ function bar() {
4 │ yield foo;
· ─────
5 │ }
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[es6/yieldExpressions/YieldExpression17_es6.ts:1:1]
1 │ // @target: es6
2 │ var v = { get foo() { yield foo; } }
· ─────
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[es6/yieldExpressions/YieldExpression2_es6.ts:1:1]
1 │ // @target: es6
2 │ yield foo;
· ─────
╰────
× Unexpected token
╭─[es6/yieldExpressions/YieldExpression5_es6.ts:3:1]
3 │ yield*
@ -5782,6 +5837,13 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts"
4 │ }
╰────
× A 'yield' expression is only allowed in a generator body.
╭─[es6/yieldExpressions/generatorTypeCheck32.ts:2:1]
2 │ var s: string;
3 │ var f: () => number = () => yield s;
· ─────
╰────
× Invalid assignment
╭─[es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts:7:1]
7 │ constructor() {