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
18 changes: 18 additions & 0 deletions crates/oxc_parser/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,13 +543,31 @@ pub fn accessibility_modifier_already_seen(modifier: &Modifier) -> OxcDiagnostic
.with_help("Remove the duplicate modifier.")
}

#[cold]
pub fn export_modifier_must_precede_declare(modifier: &Modifier) -> OxcDiagnostic {
ts_error("1029", "'export' modifier must precede 'declare' modifier.").with_label(modifier.span)
}

#[cold]
pub fn modifier_already_seen(modifier: &Modifier) -> OxcDiagnostic {
ts_error("1030", format!("'{}' modifier already seen.", modifier.kind))
.with_label(modifier.span)
.with_help("Remove the duplicate modifier.")
}

pub fn cannot_appear_on_class_elements(modifier: &Modifier) -> OxcDiagnostic {
ts_error(
"1031",
format!("'{}' modifier cannot appear on class elements of this kind.", modifier.kind),
)
.with_label(modifier.span)
}

pub fn cannot_appear_on_a_type_member(modifier: &Modifier) -> OxcDiagnostic {
ts_error("1070", format!("'{}' modifier cannot appear on a type member.", modifier.kind))
.with_label(modifier.span)
}

#[cold]
pub fn cannot_appear_on_a_type_parameter(modifier: &Modifier) -> OxcDiagnostic {
ts_error("1273", format!("'{}' modifier cannot be used on a type parameter.", modifier.kind))
Expand Down
7 changes: 6 additions & 1 deletion crates/oxc_parser/src/js/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ impl<'a> ParserImpl<'a> {
/* permit_const_as_modifier */ true,
/* stop_on_start_of_class_static_block */ true,
);
self.verify_modifiers(
&modifiers,
ModifierFlags::all() - ModifierFlags::EXPORT,
diagnostics::cannot_appear_on_class_elements,
);

// static { block }
if self.at(Kind::Static) && self.lexer.peek_token().kind() == Kind::LCurly {
Expand Down Expand Up @@ -415,7 +420,7 @@ impl<'a> ParserImpl<'a> {
let value = self.parse_method(
modifiers.contains(ModifierKind::Async),
false,
FunctionKind::ClassMethod,
FunctionKind::Constructor,
);
let method_definition = self.ast.alloc_method_definition(
self.end_span(span),
Expand Down
20 changes: 15 additions & 5 deletions crates/oxc_parser/src/js/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,15 @@ impl<'a> ParserImpl<'a> {
let decorators = self.parse_decorators();
let modifiers = self.parse_modifiers(false, false);
if self.is_ts {
let mut allowed_modifiers = ModifierFlags::READONLY;
if func_kind == FunctionKind::Constructor {
allowed_modifiers = allowed_modifiers
.union(ModifierFlags::ACCESSIBILITY)
.union(ModifierFlags::OVERRIDE);
}
self.verify_modifiers(
&modifiers,
ModifierFlags::ACCESSIBILITY
.union(ModifierFlags::READONLY)
.union(ModifierFlags::OVERRIDE),
allowed_modifiers,
diagnostics::cannot_appear_on_a_parameter,
);
} else {
Expand All @@ -87,7 +91,10 @@ impl<'a> ParserImpl<'a> {
);
}
let pattern = self.parse_binding_pattern_with_initializer();
if func_kind != FunctionKind::ClassMethod || !self.is_ts {
let are_decorators_allowed =
matches!(func_kind, FunctionKind::ClassMethod | FunctionKind::Constructor)
&& self.is_ts;
if !are_decorators_allowed {
for decorator in &decorators {
self.error(diagnostics::decorators_are_not_valid_here(decorator.span));
}
Expand Down Expand Up @@ -131,7 +138,10 @@ impl<'a> ParserImpl<'a> {
FunctionType::FunctionDeclaration
}
}
FunctionKind::Expression | FunctionKind::ClassMethod | FunctionKind::ObjectMethod => {
FunctionKind::Expression
| FunctionKind::ClassMethod
| FunctionKind::Constructor
| FunctionKind::ObjectMethod => {
if body.is_none() {
FunctionType::TSEmptyBodyFunctionExpression
} else {
Expand Down
1 change: 1 addition & 0 deletions crates/oxc_parser/src/js/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub enum Tristate {

#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum FunctionKind {
Constructor,
ClassMethod,
ObjectMethod,
Declaration,
Expand Down
1 change: 1 addition & 0 deletions crates/oxc_parser/src/lexer/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ impl Kind {
self,
Abstract | Accessor | Async | Const | Declare
| In | Out | Public | Private | Protected | Readonly | Static | Override
| Default | Export
)
}

Expand Down
15 changes: 14 additions & 1 deletion crates/oxc_parser/src/modifiers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ bitflags! {
const OUT = 1 << 11;
const DEFAULT = 1 << 13;
const ACCESSOR = 1 << 14;
const EXPORT = 1 << 15;
const ACCESSIBILITY = Self::PRIVATE.bits() | Self::PROTECTED.bits() | Self::PUBLIC.bits();
// NOTE: `export` and `default` are not handled here, they are parsed explicitly in the parser.
}
}

Expand All @@ -52,6 +52,8 @@ impl From<Kind> for ModifierFlags {
Kind::In => Self::IN,
Kind::Out => Self::OUT,
Kind::Accessor => Self::ACCESSOR,
Kind::Default => Self::DEFAULT,
Kind::Export => Self::EXPORT,
_ => unreachable!(),
}
}
Expand All @@ -73,6 +75,8 @@ impl From<ModifierKind> for ModifierFlags {
ModifierKind::In => Self::IN,
ModifierKind::Out => Self::OUT,
ModifierKind::Accessor => Self::ACCESSOR,
ModifierKind::Default => Self::DEFAULT,
ModifierKind::Export => Self::EXPORT,
}
}
}
Expand Down Expand Up @@ -235,6 +239,8 @@ pub enum ModifierKind {
Static,
Out,
Override,
Default,
Export,
}

impl ModifierKind {
Expand All @@ -253,6 +259,8 @@ impl ModifierKind {
Self::Static => "static",
Self::Out => "out",
Self::Override => "override",
Self::Default => "default",
Self::Export => "export",
}
}
}
Expand All @@ -274,6 +282,8 @@ impl TryFrom<Kind> for ModifierKind {
Kind::In => Ok(Self::In),
Kind::Out => Ok(Self::Out),
Kind::Accessor => Ok(Self::Accessor),
Kind::Default => Ok(Self::Default),
Kind::Export => Ok(Self::Export),
_ => Err(()),
}
}
Expand All @@ -298,6 +308,9 @@ impl<'a> ParserImpl<'a> {
let kind = self.cur_kind();
self.bump_any();
let modifier = self.modifier(kind, self.end_span(span));
if modifier.kind == ModifierKind::Export {
self.error(diagnostics::export_modifier_must_precede_declare(&modifier));
}
self.check_for_duplicate_modifiers(flags, &modifier);
flags.set(modifier_flags, true);
modifiers.push(modifier);
Expand Down
7 changes: 6 additions & 1 deletion crates/oxc_parser/src/ts/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,14 @@ impl<'a> ParserImpl<'a> {
}

let modifiers = self.parse_modifiers(
/* permit_const_as_modifier */ false,
/* permit_const_as_modifier */ true,
/* stop_on_start_of_class_static_block */ false,
);
self.verify_modifiers(
&modifiers,
ModifierFlags::READONLY,
diagnostics::cannot_appear_on_a_type_member,
);

if self.parse_contextual_modifier(Kind::Get) {
return self.parse_getter_setter_signature_member(span, TSMethodSignatureKind::Get);
Expand Down
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Foo {
abstract method();
}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-10.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Foo {
async property;
}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-11.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Foo {
const method();
}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-12.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Foo {
const property;
}
2 changes: 2 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-13.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const [index: string]: number
}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-14.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const foo: {
const [index: string] : string
} = {};
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-15.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Foo {
declare method();
}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-16.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Foo {
declare property;
}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-17.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Foo {
default method();
}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-18.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Foo {
default property;
}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-19.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Foo {
default [index: string]: number
}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type Foo = {
static bar;
}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-20.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const foo: {
default [index: string] : string
} = {};
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-21.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Foo {
export method();
}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-22.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Foo {
export property;
}
1 change: 1 addition & 0 deletions tasks/coverage/misc/fail/oxc-11713-3.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
function foo(private parameter) {}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-4.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Foo {
declare get getter() {}
}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-5.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Foo {
abstract method();
}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-6.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Foo {
abstract property;
}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-7.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Foo {
accessor method();
}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-8.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Foo {
accessor property;
}
3 changes: 3 additions & 0 deletions tasks/coverage/misc/fail/oxc-11713-9.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Foo {
async method();
}
Loading
Loading