mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
feat(parser): better handling of invalid modifiers (#6482)
## What This PR Does
1. Recover on, and provide a better message for, invalid `export` modifier on constructor parameters. Before, an `unexpected token` error would be produced and the parser would panic. Now, the parser recovers and produces a message saying `'export' modifier cannot appear on a parameter.`
```ts
class Foo {
constructor(export x: number) {}
}
```
2. Recover on, and provide a better message for, invalid modifiers on index signatures. Same recovery/message characteristics as above.
```ts
class Foo {
public [x: string]: string;
}
```
This commit is contained in:
parent
8ea6b721b8
commit
58467a53a1
4 changed files with 38 additions and 16 deletions
|
|
@ -471,6 +471,12 @@ pub fn cannot_appear_on_a_parameter(modifier: &Modifier) -> OxcDiagnostic {
|
|||
.with_label(modifier.span)
|
||||
}
|
||||
|
||||
/// TS(1071)
|
||||
pub fn cannot_appear_on_an_index_signature(modifier: &Modifier) -> OxcDiagnostic {
|
||||
ts_error("1071", format!("'{}' modifier cannot appear on an index signature.", modifier.kind))
|
||||
.with_label(modifier.span)
|
||||
}
|
||||
|
||||
/// TS(18010)
|
||||
#[cold]
|
||||
pub fn accessibility_modifier_on_private_property(modifier: &Modifier) -> OxcDiagnostic {
|
||||
|
|
|
|||
|
|
@ -255,6 +255,7 @@ impl<'a> ParserImpl<'a> {
|
|||
| Kind::Readonly
|
||||
| Kind::Declare
|
||||
| Kind::Override
|
||||
| Kind::Export
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1269,14 +1269,14 @@ impl<'a> ParserImpl<'a> {
|
|||
|
||||
pub(crate) fn parse_ts_index_signature_member(&mut self) -> Result<TSSignature<'a>> {
|
||||
let span = self.start_span();
|
||||
let mut readonly = false;
|
||||
while self.is_nth_at_modifier(0, false) {
|
||||
if self.eat(Kind::Readonly) {
|
||||
readonly = true;
|
||||
} else {
|
||||
return Err(self.unexpected());
|
||||
}
|
||||
}
|
||||
|
||||
let modifiers = self.parse_class_element_modifiers(false);
|
||||
self.verify_modifiers(
|
||||
&modifiers,
|
||||
ModifierFlags::READONLY,
|
||||
diagnostics::cannot_appear_on_an_index_signature,
|
||||
);
|
||||
let readonly = modifiers.contains(ModifierKind::Readonly);
|
||||
|
||||
self.bump(Kind::LBrack);
|
||||
let index_name = self.parse_ts_index_signature_name()?;
|
||||
|
|
|
|||
|
|
@ -6629,7 +6629,7 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private
|
|||
3 │ }
|
||||
╰────
|
||||
|
||||
× Identifier expected. 'export' is a reserved word that cannot be used here.
|
||||
× TS(1090): 'export' modifier cannot appear on a parameter.
|
||||
╭─[typescript/tests/cases/compiler/constructorArgsErrors5.ts:2:18]
|
||||
1 │ class foo {
|
||||
2 │ constructor (export a: number) {
|
||||
|
|
@ -9223,7 +9223,7 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private
|
|||
6 │ };
|
||||
╰────
|
||||
|
||||
× Unexpected token
|
||||
× TS(1071): 'public' modifier cannot appear on an index signature.
|
||||
╭─[typescript/tests/cases/compiler/modifiersOnInterfaceIndexSignature1.ts:2:3]
|
||||
1 │ interface I {
|
||||
2 │ public [a: string]: number;
|
||||
|
|
@ -15079,7 +15079,7 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private
|
|||
9 │ }
|
||||
╰────
|
||||
|
||||
× Unexpected token
|
||||
× TS(1071): 'static' modifier cannot appear on an index signature.
|
||||
╭─[typescript/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts:12:5]
|
||||
11 │ interface IB {
|
||||
12 │ static [s: string]: number;
|
||||
|
|
@ -15087,7 +15087,15 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private
|
|||
13 │ static [s: number]: 42 | 233;
|
||||
╰────
|
||||
|
||||
× Unexpected token
|
||||
× TS(1071): 'static' modifier cannot appear on an index signature.
|
||||
╭─[typescript/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts:13:5]
|
||||
12 │ static [s: string]: number;
|
||||
13 │ static [s: number]: 42 | 233;
|
||||
· ──────
|
||||
14 │ }
|
||||
╰────
|
||||
|
||||
× TS(1071): 'static' modifier cannot appear on an index signature.
|
||||
╭─[typescript/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature5.ts:7:5]
|
||||
6 │ interface I {
|
||||
7 │ static readonly [s: string]: number;
|
||||
|
|
@ -15095,6 +15103,14 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private
|
|||
8 │ static readonly [s: number]: 42 | 233
|
||||
╰────
|
||||
|
||||
× TS(1071): 'static' modifier cannot appear on an index signature.
|
||||
╭─[typescript/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature5.ts:8:5]
|
||||
7 │ static readonly [s: string]: number;
|
||||
8 │ static readonly [s: number]: 42 | 233
|
||||
· ──────
|
||||
9 │ }
|
||||
╰────
|
||||
|
||||
× Expected `,` but found `is`
|
||||
╭─[typescript/tests/cases/conformance/controlFlow/assertionTypePredicates1.ts:163:20]
|
||||
162 │ get p1(): this is string;
|
||||
|
|
@ -20758,14 +20774,13 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private
|
|||
· ─
|
||||
╰────
|
||||
|
||||
× Expected a semicolon or an implicit semicolon after a statement, but found none
|
||||
╭─[typescript/tests/cases/conformance/parser/ecmascript5/IndexMemberDeclarations/parserIndexMemberDeclaration9.ts:2:10]
|
||||
× TS(1071): 'export' modifier cannot appear on an index signature.
|
||||
╭─[typescript/tests/cases/conformance/parser/ecmascript5/IndexMemberDeclarations/parserIndexMemberDeclaration9.ts:2:4]
|
||||
1 │ class C {
|
||||
2 │ export [x: string]: string;
|
||||
· ▲
|
||||
· ──────
|
||||
3 │ }
|
||||
╰────
|
||||
help: Try insert a semicolon here
|
||||
|
||||
× Unexpected token
|
||||
╭─[typescript/tests/cases/conformance/parser/ecmascript5/IndexSignatures/parserIndexSignature1.ts:2:4]
|
||||
|
|
|
|||
Loading…
Reference in a new issue