Skip to content

Commit 67248ed

Browse files
committed
fix: abstract constructor checks
1 parent a84b487 commit 67248ed

File tree

2 files changed

+28
-16
lines changed

2 files changed

+28
-16
lines changed

crates/oxc_semantic/src/checker/typescript.rs

+27-15
Original file line numberDiff line numberDiff line change
@@ -224,24 +224,36 @@ fn abstract_accessor_cannot_have_implementation(accessor_name: &str, span: Span)
224224
)
225225
}
226226

227+
/// 'abstract' modifier can only appear on a class, method, or property declaration. (1242)
228+
fn illegal_abstract_modifier(span: Span) -> OxcDiagnostic {
229+
OxcDiagnostic::error("TS(1242): 'abstract' modifier can only appear on a class, method, or property declaration.")
230+
.with_label(span)
231+
}
232+
227233
pub fn check_method_definition<'a>(method: &MethodDefinition<'a>, ctx: &SemanticBuilder<'a>) {
228-
if method.r#type.is_abstract() && method.value.body.is_some() {
229-
let (method_name, span) = method.key.prop_name().unwrap_or_else(|| {
230-
let key_span = method.key.span();
231-
(&ctx.source_text[key_span], key_span)
232-
});
233-
match method.kind {
234-
MethodDefinitionKind::Method => {
235-
ctx.error(abstract_method_cannot_have_implementation(method_name, span));
236-
}
237-
MethodDefinitionKind::Get | MethodDefinitionKind::Set => {
238-
ctx.error(abstract_accessor_cannot_have_implementation(method_name, span));
234+
if method.r#type.is_abstract() {
235+
// constructors cannot be abstract, no matter what
236+
if method.kind.is_constructor() {
237+
ctx.error(illegal_abstract_modifier(method.key.span()));
238+
} else if method.value.body.is_some() {
239+
// abstract class elements cannot have bodies or initializers
240+
let (method_name, span) = method.key.prop_name().unwrap_or_else(|| {
241+
let key_span = method.key.span();
242+
(&ctx.source_text[key_span], key_span)
243+
});
244+
match method.kind {
245+
MethodDefinitionKind::Method => {
246+
ctx.error(abstract_method_cannot_have_implementation(method_name, span));
247+
}
248+
MethodDefinitionKind::Get | MethodDefinitionKind::Set => {
249+
ctx.error(abstract_accessor_cannot_have_implementation(method_name, span));
250+
}
251+
// abstract classes can have concrete methods. Constructors cannot
252+
// have abstract modifiers, but this gets checked during parsing
253+
MethodDefinitionKind::Constructor => {}
239254
}
240-
// abstract classes can have concrete methods. Constructors cannot
241-
// have abstract modifiers, but this gets checked during parsing
242-
MethodDefinitionKind::Constructor => {}
255+
ctx.error(abstract_method_cannot_have_implementation(method_name, span));
243256
}
244-
ctx.error(abstract_method_cannot_have_implementation(method_name, span));
245257
}
246258
}
247259

tasks/coverage/parser_typescript.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -11101,7 +11101,7 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
1110111101
6 │ }
1110211102
╰────
1110311103

11104-
× TS(1245): Method 'constructor' cannot have an implementation because it is marked abstract.
11104+
× TS(1242): 'abstract' modifier can only appear on a class, method, or property declaration.
1110511105
╭─[conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructor.ts:2:14]
1110611106
1 │ abstract class A {
1110711107
2 │ abstract constructor() {}

0 commit comments

Comments
 (0)