mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(parser): reject generators in ambient contexts and overload signatures (TS1221/TS1222) (#22848)
A generator (`function*` / `*method`) is not allowed in an ambient context
(TS1221), and a generator overload signature with no body is not allowed
(TS1222). Mirrors tsc's `checkGrammarForGenerator`:
declare function* f(): any; // now TS1221
declare namespace N { function* g(); } // now TS1221
declare class C { *m(); } // now TS1221
function* f(): any; // overload → now TS1222
function* f() { yield 1; }
function* f() { yield 1; } // normal generator → still valid
The check lives in `parse_function` next to the TS1183 implementation-in-ambient
check and keys off `ctx.has_ambient()` / `body.is_none()`. Class methods are
covered too (`class.rs` does not check generators, so there is no duplicate
diagnostic).
Also fixes a latent bug: `parse_ts_declare_function` hard-coded `generator: false`
and never consumed the `*`, so `declare function* f()` silently dropped the
generator flag. It now eats the `*` and threads the flag through (which is what
lets TS1221 fire there).
parser_typescript +7 negative-pass (generatorInAmbientContext1-4, generatorOverloads1-3);
positive/AST stay 100%.
This commit is contained in:
5 files changed
+134
-17
No files matched your search
@@ -1228,6 +1228,16 @@ pub fn implementation_in_ambient(span: Span) -> OxcDiagnostic {
|
||||
ts_error("1183", "An implementation cannot be declared in ambient contexts.").with_label(span)
|
||||
}
|
||||
|
||||
#[cold]
|
||||
pub fn generator_in_ambient_context(span: Span) -> OxcDiagnostic {
|
||||
ts_error("1221", "Generators are not allowed in an ambient context.").with_label(span)
|
||||
}
|
||||
|
||||
#[cold]
|
||||
pub fn overload_signature_generator(span: Span) -> OxcDiagnostic {
|
||||
ts_error("1222", "An overload signature cannot be declared as a generator.").with_label(span)
|
||||
}
|
||||
|
||||
#[cold]
|
||||
pub fn initializers_not_allowed_in_ambient_contexts(span: Span) -> OxcDiagnostic {
|
||||
ts_error("1039", "Initializers are not allowed in ambient contexts.").with_label(span)
|
||||
|
||||
@@ -302,6 +302,14 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
{
|
||||
self.error(diagnostics::implementation_in_ambient(Span::empty(body.span.start)));
|
||||
}
|
||||
|
||||
if generator {
|
||||
if ctx.has_ambient() {
|
||||
self.error(diagnostics::generator_in_ambient_context(self.end_span(span)));
|
||||
} else if body.is_none() {
|
||||
self.error(diagnostics::overload_signature_generator(self.end_span(span)));
|
||||
}
|
||||
}
|
||||
self.verify_modifiers(
|
||||
modifiers,
|
||||
ModifierKinds::new([ModifierKind::Declare, ModifierKind::Async]),
|
||||
|
||||
@@ -583,13 +583,14 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
) -> Box<'a, Function<'a>> {
|
||||
let r#async = modifiers.contains(ModifierKind::Async);
|
||||
self.expect(Kind::Function);
|
||||
let generator = self.eat(Kind::Star);
|
||||
let func_kind = FunctionKind::TSDeclaration;
|
||||
let id = self.parse_function_id(func_kind, r#async, false);
|
||||
let id = self.parse_function_id(func_kind, r#async, generator);
|
||||
self.parse_function(
|
||||
start_span,
|
||||
id,
|
||||
r#async,
|
||||
false,
|
||||
generator,
|
||||
func_kind,
|
||||
FormalParameterKind::FormalParameter,
|
||||
modifiers,
|
||||
|
||||
@@ -12788,6 +12788,14 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
|
||||
╰────
|
||||
help: Allowed modifiers are: private, protected, public, static, abstract, override, async
|
||||
|
||||
× TS(1221): Generators are not allowed in an ambient context.
|
||||
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/generator-method-with-modifiers/input.ts:7:13]
|
||||
6 │ readonly *e() {}
|
||||
7 │ declare *f() {}
|
||||
· ─────
|
||||
8 │ protected *g() {}
|
||||
╰────
|
||||
|
||||
× TS(1183): An implementation cannot be declared in ambient contexts.
|
||||
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/generator-method-with-modifiers/input.ts:7:16]
|
||||
6 │ readonly *e() {}
|
||||
@@ -13085,6 +13093,14 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
|
||||
╰────
|
||||
help: Allowed modifiers are: private, protected, public, static, abstract, override, async
|
||||
|
||||
× TS(1221): Generators are not allowed in an ambient context.
|
||||
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/optional-generator-method-with-invalid-modifiers/input.ts:4:14]
|
||||
3 │ readonly *e?() { }
|
||||
4 │ declare *f?() { }
|
||||
· ──────
|
||||
5 │ }
|
||||
╰────
|
||||
|
||||
× TS(1183): An implementation cannot be declared in ambient contexts.
|
||||
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/optional-generator-method-with-invalid-modifiers/input.ts:4:17]
|
||||
3 │ readonly *e?() { }
|
||||
@@ -13119,6 +13135,14 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
|
||||
╰────
|
||||
help: Allowed modifiers are: private, protected, public, static, abstract, override, async
|
||||
|
||||
× TS(1221): Generators are not allowed in an ambient context.
|
||||
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/optional-generator-method-with-invalid-modifiers/input.ts:10:19]
|
||||
9 │ readonly *[e?.e]?() { }
|
||||
10 │ declare *[f?.f]?() { }
|
||||
· ──────
|
||||
11 │ }
|
||||
╰────
|
||||
|
||||
× TS(1183): An implementation cannot be declared in ambient contexts.
|
||||
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/optional-generator-method-with-invalid-modifiers/input.ts:10:22]
|
||||
9 │ readonly *[e?.e]?() { }
|
||||
|
||||
@@ -3,7 +3,7 @@ commit: e5509e21
|
||||
parser_typescript Summary:
|
||||
AST Parsed : 9779/9779 (100.00%)
|
||||
Positive Passed: 9779/9779 (100.00%)
|
||||
Negative Passed: 1621/2640 (61.40%)
|
||||
Negative Passed: 1628/2640 (61.67%)
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/FunctionDeclaration3.ts
|
||||
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/FunctionDeclaration4.ts
|
||||
@@ -1302,20 +1302,6 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yield
|
||||
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/YieldStarExpression1_es6.ts
|
||||
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/generatorInAmbientContext1.ts
|
||||
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/generatorInAmbientContext2.ts
|
||||
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/generatorInAmbientContext3.d.ts
|
||||
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/generatorInAmbientContext4.d.ts
|
||||
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/generatorOverloads1.ts
|
||||
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/generatorOverloads2.ts
|
||||
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/generatorOverloads3.ts
|
||||
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck9.ts
|
||||
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCanBeAssigned1.ts
|
||||
@@ -19988,6 +19974,94 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/types/wit
|
||||
3 │ }
|
||||
╰────
|
||||
|
||||
× TS(1221): Generators are not allowed in an ambient context.
|
||||
╭─[typescript/tests/cases/conformance/es6/yieldExpressions/generatorInAmbientContext1.ts:2:15]
|
||||
1 │ declare class C {
|
||||
2 │ *generator(): any;
|
||||
· ────────
|
||||
3 │ }
|
||||
╰────
|
||||
|
||||
× TS(1221): Generators are not allowed in an ambient context.
|
||||
╭─[typescript/tests/cases/conformance/es6/yieldExpressions/generatorInAmbientContext2.ts:2:5]
|
||||
1 │ declare namespace M {
|
||||
2 │ function *generator(): any;
|
||||
· ───────────────────────────
|
||||
3 │ }
|
||||
╰────
|
||||
|
||||
× TS(1221): Generators are not allowed in an ambient context.
|
||||
╭─[typescript/tests/cases/conformance/es6/yieldExpressions/generatorInAmbientContext3.d.ts:2:15]
|
||||
1 │ declare class C {
|
||||
2 │ *generator(): any;
|
||||
· ────────
|
||||
3 │ }
|
||||
╰────
|
||||
|
||||
× TS(1221): Generators are not allowed in an ambient context.
|
||||
╭─[typescript/tests/cases/conformance/es6/yieldExpressions/generatorInAmbientContext4.d.ts:2:5]
|
||||
1 │ declare namespace M {
|
||||
2 │ function *generator(): any;
|
||||
· ───────────────────────────
|
||||
3 │ }
|
||||
╰────
|
||||
|
||||
× TS(1222): An overload signature cannot be declared as a generator.
|
||||
╭─[typescript/tests/cases/conformance/es6/yieldExpressions/generatorOverloads1.ts:2:5]
|
||||
1 │ namespace M {
|
||||
2 │ function* f(s: string): Iterable<any>;
|
||||
· ──────────────────────────────────────
|
||||
3 │ function* f(s: number): Iterable<any>;
|
||||
╰────
|
||||
|
||||
× TS(1222): An overload signature cannot be declared as a generator.
|
||||
╭─[typescript/tests/cases/conformance/es6/yieldExpressions/generatorOverloads1.ts:3:5]
|
||||
2 │ function* f(s: string): Iterable<any>;
|
||||
3 │ function* f(s: number): Iterable<any>;
|
||||
· ──────────────────────────────────────
|
||||
4 │ function* f(s: any): Iterable<any> { }
|
||||
╰────
|
||||
|
||||
× TS(1221): Generators are not allowed in an ambient context.
|
||||
╭─[typescript/tests/cases/conformance/es6/yieldExpressions/generatorOverloads2.ts:2:5]
|
||||
1 │ declare namespace M {
|
||||
2 │ function* f(s: string): Iterable<any>;
|
||||
· ──────────────────────────────────────
|
||||
3 │ function* f(s: number): Iterable<any>;
|
||||
╰────
|
||||
|
||||
× TS(1221): Generators are not allowed in an ambient context.
|
||||
╭─[typescript/tests/cases/conformance/es6/yieldExpressions/generatorOverloads2.ts:3:5]
|
||||
2 │ function* f(s: string): Iterable<any>;
|
||||
3 │ function* f(s: number): Iterable<any>;
|
||||
· ──────────────────────────────────────
|
||||
4 │ function* f(s: any): Iterable<any>;
|
||||
╰────
|
||||
|
||||
× TS(1221): Generators are not allowed in an ambient context.
|
||||
╭─[typescript/tests/cases/conformance/es6/yieldExpressions/generatorOverloads2.ts:4:5]
|
||||
3 │ function* f(s: number): Iterable<any>;
|
||||
4 │ function* f(s: any): Iterable<any>;
|
||||
· ───────────────────────────────────
|
||||
5 │ }
|
||||
╰────
|
||||
|
||||
× TS(1222): An overload signature cannot be declared as a generator.
|
||||
╭─[typescript/tests/cases/conformance/es6/yieldExpressions/generatorOverloads3.ts:2:7]
|
||||
1 │ class C {
|
||||
2 │ *f(s: string): Iterable<any>;
|
||||
· ───────────────────────────
|
||||
3 │ *f(s: number): Iterable<any>;
|
||||
╰────
|
||||
|
||||
× TS(1222): An overload signature cannot be declared as a generator.
|
||||
╭─[typescript/tests/cases/conformance/es6/yieldExpressions/generatorOverloads3.ts:3:7]
|
||||
2 │ *f(s: string): Iterable<any>;
|
||||
3 │ *f(s: number): Iterable<any>;
|
||||
· ───────────────────────────
|
||||
4 │ *f(s: any): Iterable<any> { }
|
||||
╰────
|
||||
|
||||
× A 'yield' expression is only allowed in a generator body.
|
||||
╭─[typescript/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck32.ts:2:29]
|
||||
1 │ var s: string;
|
||||
|
||||
Reference in new issue
Block a user