fix(parser): forbid type parameters on quoted constructors (#25696)

Quoted constructor methods bypassed the AST-based constructor validation. Validate type parameters after resolving the method key, preserving the AST shape.

Validation: `just ready`, parser conformance, and allocation checks.

Closes #25692.

AI-assisted with Codex.
This commit is contained in:
Boshen committed 2026-08-15 05:02:23 +00:00
1 parent b0e6c2574c
commit ae9be8f8bd
3 files changed
+39 -6

No files matched your search

+6 -5
View File
@@ -829,7 +829,9 @@ impl<'a, C: Config> ParserImpl<'a, C> {
self.error(diagnostics::static_prototype(span));
}
} else if name == "constructor" {
if matches!(method.kind, MethodDefinitionKind::Get | MethodDefinitionKind::Set) {
let is_accessor =
matches!(method.kind, MethodDefinitionKind::Get | MethodDefinitionKind::Set);
if is_accessor {
self.error(diagnostics::constructor_getter_setter(span));
}
if method.value.r#async {
@@ -841,6 +843,9 @@ impl<'a, C: Config> ParserImpl<'a, C> {
if method.r#type.is_abstract() {
self.error(diagnostics::illegal_abstract_modifier(span));
}
if !is_accessor && let Some(type_parameters) = &method.value.type_parameters {
self.error(diagnostics::ts_constructor_type_parameter(type_parameters.span));
}
}
}
@@ -881,10 +886,6 @@ impl<'a, C: Config> ParserImpl<'a, C> {
// class Foo { constructor(this: number) {} }
self.error(diagnostics::ts_constructor_this_parameter(this_param.span));
}
if let Some(type_sig) = &method.value.type_parameters {
// class Foo { constructor<T>(param: T ) {} }
self.error(diagnostics::ts_constructor_type_parameter(type_sig.span));
}
if method.value.body.is_some()
&& let Some(return_type) = &method.value.return_type
{
+7
View File
@@ -0,0 +1,7 @@
class A {
'constructor'<T>() {}
}
class B {
get 'constructor'<T>() {}
}
+26 -1
View File
@@ -1,7 +1,7 @@
parser_misc Summary:
AST Parsed : 78/78 (100.00%)
Positive Passed: 78/78 (100.00%)
Negative Passed: 161/161 (100.00%)
Negative Passed: 162/162 (100.00%)
× Cannot assign to 'arguments' in strict mode
╭─[misc/fail/arguments-eval-ambient.ts:2:13]
@@ -3941,6 +3941,31 @@ Negative Passed: 161/161 (100.00%)
╰────
help: Allowed modifiers are: private, protected, public, static, abstract, override
× TS(1092): Type parameters cannot appear on a constructor declaration
╭─[misc/fail/oxc-25692.ts:2:16]
1 │ class A {
2 │ 'constructor'<T>() {}
· ───
3 │ }
╰────
help: Instead, add type parameters to the class itself
× Constructor can't have get/set modifier
╭─[misc/fail/oxc-25692.ts:6:7]
5 │ class B {
6 │ get 'constructor'<T>() {}
· ─────────────
7 │ }
╰────
× TS(1094): An accessor cannot have type parameters.
╭─[misc/fail/oxc-25692.ts:6:20]
5 │ class B {
6 │ get 'constructor'<T>() {}
· ───
7 │ }
╰────
× Expected `:` but found `[`
╭─[misc/fail/oxc-3320.tsx:1:8]
1 │ m< $<{3[ $<{3[ $<{3[ m< m$<{3[ m< mm< $<{3[ $<{3[ $<{3[ m< m$<{3[ m< m$<{3[ $<{3[ m< m$<{3[