Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/oxc_parser/src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,10 +445,10 @@ impl<'a> ParserImpl<'a> {
close: Kind,
separator: Kind,
opening_span: Span,
f: F,
mut f: F,
) -> (Vec<'a, T>, Option<u32>)
where
F: Fn(&mut Self) -> T,
F: FnMut(&mut Self) -> T,
{
let mut list = self.ast.vec();
// Cache cur_kind() to avoid redundant calls in compound checks
Expand Down
26 changes: 18 additions & 8 deletions crates/oxc_parser/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,14 +302,6 @@ pub fn class_declaration(span: Span) -> OxcDiagnostic {
.with_label(span)
}

/// A class member cannot have the 'const' keyword. ts(1248)
#[cold]
pub fn const_class_member(span: Span) -> OxcDiagnostic {
ts_error("1248", "A class member cannot have the 'const' keyword.")
.with_help("Did you mean `readonly`?")
.with_label(span)
}

// 'extends' clause already seen. ts(1172)
#[cold]
pub fn extends_clause_already_seen(span: Span) -> OxcDiagnostic {
Expand Down Expand Up @@ -343,6 +335,24 @@ pub fn implements_clause_already_seen(span: Span, seen_span: Span) -> OxcDiagnos
.with_help("Merge the two 'implements' clauses into one by a ','")
}

/// A class member cannot have the 'const' keyword. ts(1248)
#[cold]
pub fn const_class_member(span: Span) -> OxcDiagnostic {
ts_error("1248", "A class member cannot have the 'const' keyword.")
.with_help("Did you mean `readonly`?")
.with_label(span)
}

/// A rest element cannot follow another rest element. ts(1265)
#[cold]
pub fn rest_element_cannot_follow_another_rest_element(
seen_span: Span,
span: Span,
) -> OxcDiagnostic {
ts_error("1265", "A rest element cannot follow another rest element.")
.with_labels([span.label("Second rest element here"), seen_span.label("First seen here")])
}

// A type-only import can specify a default import or named bindings, but not both. ts(1363)
#[cold]
pub fn type_only_import_default_and_named(specifier_span: Span) -> OxcDiagnostic {
Expand Down
36 changes: 30 additions & 6 deletions crates/oxc_parser/src/ts/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -898,12 +898,36 @@ impl<'a> ParserImpl<'a> {
let span = self.start_span();
let opening_span = self.cur_token().span();
self.expect(Kind::LBrack);
let (elements, _) = self.parse_delimited_list(
Kind::RBrack,
Kind::Comma,
opening_span,
Self::parse_tuple_element,
);

let mut seen_type_span: Option<Span> = None;
let (elements, _) =
self.parse_delimited_list(Kind::RBrack, Kind::Comma, opening_span, |me| {
let tuple = me.parse_tuple_element();
// check for array type, because unknown types can be destructed, example of valid code:
// type C<T extends unknown[]> = [...string[], ...T];
// example of invalid code:
// type C<T extends unknown[]> = [...string[], ...T[]];
if let TSTupleElement::TSRestType(rest) = &tuple
&& match &rest.type_annotation {
TSType::TSArrayType(_) => true,
// Check for `Array<...>` type
TSType::TSTypeReference(ts_ref) => match &ts_ref.type_name {
TSTypeName::IdentifierReference(id_ref) => id_ref.name == "Array",
_ => false,
},
_ => false,
}
{
if let Some(seen_span) = seen_type_span {
me.error(diagnostics::rest_element_cannot_follow_another_rest_element(
seen_span,
tuple.span(),
));
}
seen_type_span = Some(tuple.span());
}
tuple
});
self.expect(Kind::RBrack);
self.ast.ts_type_tuple_type(self.end_span(span), elements)
}
Expand Down
54 changes: 51 additions & 3 deletions tasks/coverage/snapshots/parser_typescript.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ commit: f5ccf434
parser_typescript Summary:
AST Parsed : 9844/9845 (99.99%)
Positive Passed: 9836/9845 (99.91%)
Negative Passed: 1495/2549 (58.65%)
Negative Passed: 1496/2549 (58.69%)
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/FunctionDeclaration3.ts

Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/FunctionDeclaration4.ts
Expand Down Expand Up @@ -2076,8 +2076,6 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/types/tup

Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts

Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/types/tuple/variadicTuples2.ts

Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/types/typeAliases/intrinsicKeyword.ts

Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/types/typeAliases/intrinsicTypes.ts
Expand Down Expand Up @@ -26506,6 +26504,56 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/statements/Va
13 │
╰────

× TS(1265): A rest element cannot follow another rest element.
╭─[typescript/tests/cases/conformance/types/tuple/variadicTuples2.ts:7:21]
6 │
7 │ type V10 = [number, ...string[], ...boolean[]]; // Error
· ─────┬───── ──────┬─────
· │ ╰── Second rest element here
· ╰── First seen here
8 │ type V11 = [number, ...string[], boolean?]; // Error
╰────

× TS(1265): A rest element cannot follow another rest element.
╭─[typescript/tests/cases/conformance/types/tuple/variadicTuples2.ts:11:13]
10 │
11 │ type V15 = [...string[], ...number[]]; // Error
· ─────┬───── ─────┬─────
· │ ╰── Second rest element here
· ╰── First seen here
12 │ type V16 = [...string[], ...Array<number>]; // Error
╰────

× TS(1265): A rest element cannot follow another rest element.
╭─[typescript/tests/cases/conformance/types/tuple/variadicTuples2.ts:12:13]
11 │ type V15 = [...string[], ...number[]]; // Error
12 │ type V16 = [...string[], ...Array<number>]; // Error
· ─────┬───── ────────┬───────
· │ ╰── Second rest element here
· ╰── First seen here
13 │ type V17 = [...Array<string>, ...number[]]; // Error
╰────

× TS(1265): A rest element cannot follow another rest element.
╭─[typescript/tests/cases/conformance/types/tuple/variadicTuples2.ts:13:13]
12 │ type V16 = [...string[], ...Array<number>]; // Error
13 │ type V17 = [...Array<string>, ...number[]]; // Error
· ────────┬─────── ─────┬─────
· │ ╰── Second rest element here
· ╰── First seen here
14 │ type V18 = [...Array<string>, ...Array<number>]; // Error
╰────

× TS(1265): A rest element cannot follow another rest element.
╭─[typescript/tests/cases/conformance/types/tuple/variadicTuples2.ts:14:13]
13 │ type V17 = [...Array<string>, ...number[]]; // Error
14 │ type V18 = [...Array<string>, ...Array<number>]; // Error
· ────────┬─────── ────────┬───────
· │ ╰── Second rest element here
· ╰── First seen here
15 │
╰────

× Expected a semicolon or an implicit semicolon after a statement, but found none
╭─[typescript/tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts:6:5]
5 │ type string = I;
Expand Down
Loading