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
11 changes: 5 additions & 6 deletions crates/oxc_parser/src/js/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,11 @@ 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);
}
let allowed_modifiers = if func_kind == FunctionKind::Constructor {
ModifierFlags::ACCESSIBILITY | ModifierFlags::OVERRIDE | ModifierFlags::READONLY
} else {
ModifierFlags::empty()
};
self.verify_modifiers(
&modifiers,
allowed_modifiers,
Expand Down
17 changes: 2 additions & 15 deletions crates/oxc_semantic/src/checker/typescript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,32 +77,19 @@ fn required_parameter_after_optional_parameter(span: Span) -> OxcDiagnostic {
.with_label(span)
}

fn parameter_property_outside_constructor(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("A parameter property is only allowed in a constructor implementation.")
.with_label(span)
}

pub fn check_formal_parameters(params: &FormalParameters, ctx: &SemanticBuilder<'_>) {
if params.kind == FormalParameterKind::Signature && params.items.len() > 1 {
check_duplicate_bound_names(params, ctx);
}

let is_inside_constructor =
!params.kind.is_signature() && ctx.current_scope_flags().is_constructor();
let mut has_optional = false;

for param in &params.items {
// function a(optional?: number, required: number) { }
if has_optional && !param.pattern.optional && !param.pattern.kind.is_assignment_pattern() {
ctx.error(required_parameter_after_optional_parameter(param.span));
}
if param.pattern.optional {
has_optional = true;
}

// function a(public x: number) { }
if !is_inside_constructor && param.has_modifier() {
ctx.error(parameter_property_outside_constructor(param.span));
} else if has_optional && !param.pattern.kind.is_assignment_pattern() {
ctx.error(required_parameter_after_optional_parameter(param.span));
}
}
}
Expand Down
156 changes: 46 additions & 110 deletions tasks/coverage/snapshots/parser_babel.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12870,6 +12870,14 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
9 │ readonly *[e?.e]?() { }
╰────

× TS(1090): 'readonly' modifier cannot appear on a parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/parameter-properties-not-constructor/input.ts:3:9]
2 │ not_constructor(
3 │ readonly r,
· ────────
4 │ public pu: number,
╰────

× TS(1090): 'public' modifier cannot appear on a parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/parameter-properties-not-constructor/input.ts:4:9]
3 │ readonly r,
Expand Down Expand Up @@ -12902,78 +12910,38 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
8 │ // Also works on AssignmentPattern
╰────

× TS(1090): 'public' modifier cannot appear on a parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/parameter-properties-not-constructor/input.ts:10:9]
9 │ readonly x = 0,
10 │ public y?: number = 0) {}
· ──────
11 │ }
╰────

× A parameter property is only allowed in a constructor implementation.
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/parameter-properties-not-constructor/input.ts:3:9]
2 │ not_constructor(
3 │ readonly r,
· ──────────
4 │ public pu: number,
╰────

× A parameter property is only allowed in a constructor implementation.
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/parameter-properties-not-constructor/input.ts:4:9]
3 │ readonly r,
4 │ public pu: number,
· ─────────────────
5 │ protected po?,
╰────

× A parameter property is only allowed in a constructor implementation.
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/parameter-properties-not-constructor/input.ts:5:9]
4 │ public pu: number,
5 │ protected po?,
· ─────────────
6 │ private pi?: number,
╰────

× A parameter property is only allowed in a constructor implementation.
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/parameter-properties-not-constructor/input.ts:6:9]
5 │ protected po?,
6 │ private pi?: number,
· ───────────────────
7 │ public readonly pur,
╰────

× A required parameter cannot follow an optional parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/parameter-properties-not-constructor/input.ts:7:9]
× TS(1090): 'readonly' modifier cannot appear on a parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/parameter-properties-not-constructor/input.ts:7:16]
6 │ private pi?: number,
7 │ public readonly pur,
· ───────────────────
8 │ // Also works on AssignmentPattern
╰────

× A parameter property is only allowed in a constructor implementation.
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/parameter-properties-not-constructor/input.ts:7:9]
6 │ private pi?: number,
7 │ public readonly pur,
· ───────────────────
· ────────
8 │ // Also works on AssignmentPattern
╰────

× A parameter property is only allowed in a constructor implementation.
× TS(1090): 'readonly' modifier cannot appear on a parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/parameter-properties-not-constructor/input.ts:9:9]
8 │ // Also works on AssignmentPattern
9 │ readonly x = 0,
· ──────────────
· ────────
10 │ public y?: number = 0) {}
╰────

× A parameter property is only allowed in a constructor implementation.
× TS(1090): 'public' modifier cannot appear on a parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/parameter-properties-not-constructor/input.ts:10:9]
9 │ readonly x = 0,
10 │ public y?: number = 0) {}
· ─────────────────────
· ──────
11 │ }
╰────

× A required parameter cannot follow an optional parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/parameter-properties-not-constructor/input.ts:7:9]
6 │ private pi?: number,
7 │ public readonly pur,
· ───────────────────
8 │ // Also works on AssignmentPattern
╰────

× TS(18010): An accessibility modifier cannot be used with a private identifier.
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/private-fields-modifier-private/input.ts:2:3]
1 │ class A {
Expand Down Expand Up @@ -13158,6 +13126,14 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
· ──
╰────

× TS(1090): 'readonly' modifier cannot appear on a parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/function/parameter-properties/input.ts:2:3]
1 │ function foo(
2 │ readonly r,
· ────────
3 │ public pu: number,
╰────

× TS(1090): 'public' modifier cannot appear on a parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/function/parameter-properties/input.ts:3:3]
2 │ readonly r,
Expand Down Expand Up @@ -13190,78 +13166,38 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
7 │ readonly x = 0,
╰────

× TS(1090): 'public' modifier cannot appear on a parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/function/parameter-properties/input.ts:8:3]
7 │ readonly x = 0,
8 │ public y?: number = 0
· ──────
9 │ ) {}
╰────

× A parameter property is only allowed in a constructor implementation.
╭─[babel/packages/babel-parser/test/fixtures/typescript/function/parameter-properties/input.ts:2:3]
1 │ function foo(
2 │ readonly r,
· ──────────
3 │ public pu: number,
╰────

× A parameter property is only allowed in a constructor implementation.
╭─[babel/packages/babel-parser/test/fixtures/typescript/function/parameter-properties/input.ts:3:3]
2 │ readonly r,
3 │ public pu: number,
· ─────────────────
4 │ protected po?,
╰────

× A parameter property is only allowed in a constructor implementation.
╭─[babel/packages/babel-parser/test/fixtures/typescript/function/parameter-properties/input.ts:4:3]
3 │ public pu: number,
4 │ protected po?,
· ─────────────
5 │ private pi?: number,
╰────

× A parameter property is only allowed in a constructor implementation.
╭─[babel/packages/babel-parser/test/fixtures/typescript/function/parameter-properties/input.ts:5:3]
4 │ protected po?,
5 │ private pi?: number,
· ───────────────────
6 │ public readonly pur,
╰────

× A required parameter cannot follow an optional parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/function/parameter-properties/input.ts:6:3]
5 │ private pi?: number,
6 │ public readonly pur,
· ───────────────────
7 │ readonly x = 0,
╰────

× A parameter property is only allowed in a constructor implementation.
╭─[babel/packages/babel-parser/test/fixtures/typescript/function/parameter-properties/input.ts:6:3]
× TS(1090): 'readonly' modifier cannot appear on a parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/function/parameter-properties/input.ts:6:10]
5 │ private pi?: number,
6 │ public readonly pur,
· ───────────────────
· ────────
7 │ readonly x = 0,
╰────

× A parameter property is only allowed in a constructor implementation.
× TS(1090): 'readonly' modifier cannot appear on a parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/function/parameter-properties/input.ts:7:3]
6 │ public readonly pur,
7 │ readonly x = 0,
· ──────────────
· ────────
8 │ public y?: number = 0
╰────

× A parameter property is only allowed in a constructor implementation.
× TS(1090): 'public' modifier cannot appear on a parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/function/parameter-properties/input.ts:8:3]
7 │ readonly x = 0,
8 │ public y?: number = 0
· ─────────────────────
· ──────
9 │ ) {}
╰────

× A required parameter cannot follow an optional parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/function/parameter-properties/input.ts:6:3]
5 │ private pi?: number,
6 │ public readonly pur,
· ───────────────────
7 │ readonly x = 0,
╰────

× A required parameter cannot follow an optional parameter.
╭─[babel/packages/babel-parser/test/fixtures/typescript/function/pattern-optional-parameters/input.ts:1:17]
1 │ function f([]?, {}) {}
Expand Down
14 changes: 4 additions & 10 deletions tasks/coverage/snapshots/parser_misc.snap
Original file line number Diff line number Diff line change
Expand Up @@ -309,16 +309,16 @@ Negative Passed: 90/90 (100.00%)
3 │ }
╰────

× A parameter property is only allowed in a constructor implementation.
× TS(1090): 'readonly' modifier cannot appear on a parameter.
╭─[misc/fail/oxc-11713-26.ts:1:14]
1 │ function foo(readonly parameter) {}
· ──────────────────
· ────────
╰────

× A parameter property is only allowed in a constructor implementation.
× TS(1090): 'readonly' modifier cannot appear on a parameter.
╭─[misc/fail/oxc-11713-27.ts:1:20]
1 │ class Foo { method(readonly parameter) {} }
· ──────────────────
· ────────
╰────

× TS(1090): 'private' modifier cannot appear on a parameter.
Expand All @@ -327,12 +327,6 @@ Negative Passed: 90/90 (100.00%)
· ───────
╰────

× A parameter property is only allowed in a constructor implementation.
╭─[misc/fail/oxc-11713-3.ts:1:14]
1 │ function foo(private parameter) {}
· ─────────────────
╰────

× 'declare' modifier cannot be used here.
╭─[misc/fail/oxc-11713-4.ts:2:2]
1 │ class Foo {
Expand Down
Loading
Loading